diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000000000..433b370d93d9b1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,25 @@ +--- +name: Bug report +about: Create a report to help us improve openpilot +title: '' +labels: 'bug' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**How to reproduce or log data** +Steps to reproduce the behavior, or a explorer/cabana link to the exact drive and timestamp of when the bug occurred. + +**Expected behavior** +A clear and concise description of what you expected to happen. + +** Device/Version information (please complete the following information):** + - Device: [e.g. EON/EON Gold] + - Version: [e.g. 0.6.4], or commit hash when on devel + - Car make/model [e.g. Toyota Prius 2016] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000000000..72e1845d7e124f --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,21 @@ +Choose one of the templates below: + +# Fingerprint +This pull requests adds a fingerprint for . + +This is an explorer link to a drive with the stock system enabled: ... + +# Car support +This pull requests adds support for . + +This is an explorer link to a drive with the stock system enabled: ... +This is an explorer link to a drive with openpilot system enabled: ... + +# Feature +This pull requests adds feature X + +## Description +Explain what the feature does + +## Testing +Explain how the feature was tested. Either by the added unit tests, or what tests were performed while driving. diff --git a/.gitignore b/.gitignore index 623c45d79ebd3e..09e8fbde7cc9f0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ +venv/ .DS_Store .tags .ipynb_checkpoints .idea .sconsign.dblite +.vscode model2.png a.out @@ -29,8 +31,18 @@ selfdrive/logcatd/logcatd selfdrive/mapd/default_speeds_by_region.json selfdrive/proclogd/proclogd selfdrive/ui/ui -selfdrive/test/tests/plant/out +selfdrive/test/longitudinal_maneuvers/out selfdrive/visiond/visiond +selfdrive/loggerd/loggerd +selfdrive/sensord/gpsd +selfdrive/sensord/sensord /src/ one +openpilot +notebooks +xx + +.coverage* +htmlcov + diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 00000000000000..64a55daf8fabb3 --- /dev/null +++ b/.pylintrc @@ -0,0 +1,585 @@ +[MASTER] + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code +extension-pkg-whitelist=scipy + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS + +# Add files or directories matching the regex patterns to the blacklist. The +# regex matches against base names, not paths. +ignore-patterns= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Use multiple processes to speed up Pylint. +jobs=4 + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + +# Pickle collected data for later comparisons. +persistent=yes + +# Specify a configuration file. +#rcfile= + +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages +suggestion-mode=yes + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED +confidence= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once).You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use"--disable=all --enable=classes +# --disable=W" +disable=print-statement, + parameter-unpacking, + unpacking-in-except, + old-raise-syntax, + backtick, + long-suffix, + old-ne-operator, + old-octal-literal, + import-star-module-level, + non-ascii-bytes-literal, + raw-checker-failed, + bad-inline-option, + locally-disabled, + locally-enabled, + file-ignored, + suppressed-message, + useless-suppression, + deprecated-pragma, + apply-builtin, + basestring-builtin, + buffer-builtin, + cmp-builtin, + coerce-builtin, + execfile-builtin, + file-builtin, + long-builtin, + raw_input-builtin, + reduce-builtin, + standarderror-builtin, + unicode-builtin, + xrange-builtin, + coerce-method, + delslice-method, + getslice-method, + setslice-method, + no-absolute-import, + old-division, + dict-iter-method, + dict-view-method, + next-method-called, + metaclass-assignment, + indexing-exception, + raising-string, + reload-builtin, + oct-method, + hex-method, + nonzero-method, + cmp-method, + input-builtin, + round-builtin, + intern-builtin, + unichr-builtin, + map-builtin-not-iterating, + zip-builtin-not-iterating, + range-builtin-not-iterating, + filter-builtin-not-iterating, + using-cmp-argument, + eq-without-hash, + div-method, + idiv-method, + rdiv-method, + exception-message-attribute, + invalid-str-codec, + sys-max-int, + bad-python3-import, + deprecated-string-function, + deprecated-str-translate-call, + deprecated-itertools-function, + deprecated-types-field, + next-method-defined, + dict-items-not-iterating, + dict-keys-not-iterating, + dict-values-not-iterating, + bad-indentation, + line-too-long, + missing-docstring, + multiple-statements, + bad-continuation, + invalid-name, + too-many-arguments, + too-many-locals, + superfluous-parens, + bad-whitespace, + too-many-instance-attributes, + wrong-import-position, + ungrouped-imports, + wrong-import-order, + protected-access, + trailing-whitespace, + too-many-branches, + too-few-public-methods, + too-many-statements, + trailing-newlines, + attribute-defined-outside-init, + too-many-return-statements, + too-many-public-methods, + unused-argument, + old-style-class, + no-init, + len-as-condition, + unneeded-not, + no-self-use, + multiple-imports, + no-else-return, + logging-not-lazy, + fixme, + redefined-outer-name, + unused-variable, + unsubscriptable-object, + expression-not-assigned, + too-many-boolean-expressions, + consider-using-ternary, + invalid-unary-operand-type, + relative-import, + deprecated-lambda + + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable=c-extension-no-member + + +[REPORTS] + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details +#msg-template= + +# Set the output format. Available formats are text, parseable, colorized, json +# and msvs (visual studio).You can also give a reporter class, eg +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Tells whether to display a full report or only the messages +reports=no + +# Activate the evaluation score. +score=yes + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=optparse.Values,sys.exit + + +[LOGGING] + +# Logging modules to check that the string format arguments are in logging +# function parameter format +logging-modules=logging + + +[SPELLING] + +# Limits count of emitted suggestions for spelling mistakes +max-spelling-suggestions=4 + +# Spelling dictionary name. Available dictionaries: none. To make it working +# install python-enchant package. +spelling-dict= + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to indicated private dictionary in +# --spelling-private-dict-file option instead of raising a message. +spelling-store-unknown-words=no + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME, + XXX, + TODO + + +[SIMILARITIES] + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + +# Minimum lines number of a similarity. +min-similarity-lines=4 + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members=capnp.* cereal.* pygame.* zmq.* setproctitle.* smbus2.* usb1.* serial.* cv2.* + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis. It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules=flask setproctitle usb1 flask.ext.socketio smbus2 usb1.* + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + + +[VARIABLES] + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb + +# A regular expression matching the name of dummy variables (i.e. expectedly +# not used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore +ignored-argument-names=_.*|^ignored_|^unused_ + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins + + +[FORMAT] + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Maximum number of characters on a single line. +max-line-length=100 + +# Maximum number of lines in a module +max-module-lines=1000 + +# List of optional constructs for which whitespace checking is disabled. `dict- +# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. +# `trailing-comma` allows a space between comma and closing bracket: (a, ). +# `empty-line` allows space-only lines. +no-space-check=trailing-comma, + dict-separator + +# Allow the body of a class to be on the same line as the declaration if body +# contains single statement. +single-line-class-stmt=no + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + + +[BASIC] + +# Naming style matching correct argument names +argument-naming-style=snake_case + +# Regular expression matching correct argument names. Overrides argument- +# naming-style +#argument-rgx= + +# Naming style matching correct attribute names +attr-naming-style=snake_case + +# Regular expression matching correct attribute names. Overrides attr-naming- +# style +#attr-rgx= + +# Bad variable names which should always be refused, separated by a comma +bad-names=foo, + bar, + baz, + toto, + tutu, + tata + +# Naming style matching correct class attribute names +class-attribute-naming-style=any + +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style +#class-attribute-rgx= + +# Naming style matching correct class names +class-naming-style=PascalCase + +# Regular expression matching correct class names. Overrides class-naming-style +#class-rgx= + +# Naming style matching correct constant names +const-naming-style=UPPER_CASE + +# Regular expression matching correct constant names. Overrides const-naming- +# style +#const-rgx= + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + +# Naming style matching correct function names +function-naming-style=snake_case + +# Regular expression matching correct function names. Overrides function- +# naming-style +#function-rgx= + +# Good variable names which should always be accepted, separated by a comma +good-names=i, + j, + k, + ex, + Run, + _ + +# Include a hint for the correct naming format with invalid-name +include-naming-hint=no + +# Naming style matching correct inline iteration names +inlinevar-naming-style=any + +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style +#inlinevar-rgx= + +# Naming style matching correct method names +method-naming-style=snake_case + +# Regular expression matching correct method names. Overrides method-naming- +# style +#method-rgx= + +# Naming style matching correct module names +module-naming-style=snake_case + +# Regular expression matching correct module names. Overrides module-naming- +# style +#module-rgx= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +property-classes=abc.abstractproperty + +# Naming style matching correct variable names +variable-naming-style=snake_case + +# Regular expression matching correct variable names. Overrides variable- +# naming-style +#variable-rgx= + + +[DESIGN] + +# Maximum number of arguments for function / method +max-args=5 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in a if statement +max-bool-expr=5 + +# Maximum number of branch for function / method body +max-branches=12 + +# Maximum number of locals for function / method body +max-locals=15 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of return / yield for function / method body +max-returns=6 + +# Maximum number of statements in function / method body +max-statements=50 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[CLASSES] + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=mcs + + +[IMPORTS] + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub, + TERMIOS, + Bastion, + rexec + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled) +import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled) +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception" +overgeneral-exceptions=Exception diff --git a/.travis.yml b/.travis.yml index 3dfe3382392e92..8683d8bee015be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,12 +3,5 @@ sudo: required services: - docker -install: - - docker build -t tmppilot -f Dockerfile.openpilot . - script: - - docker run - -v "$(pwd)"/selfdrive/test/tests/plant/out:/tmp/openpilot/selfdrive/test/tests/plant/out - tmppilot /bin/sh -c 'cd /tmp/openpilot/selfdrive/test/tests/plant && OPTEST=1 ./test_longitudinal.py' - - docker run - tmppilot /bin/sh -c 'cd /tmp/openpilot/selfdrive/test/ && ./test_fingerprints.py' + - ./run_docker_tests.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5305a72237ddb3..738679aca5d5e6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,9 +10,22 @@ Most open source development activity is coordinated through our [Discord](https * Make sure you have a [GitHub account](https://github.com/signup/free) * Fork [our repositories](https://github.com/commaai) on GitHub +## Testing + +### Local Testing + +You can test your changes on your machine by running `run_docker_tests.sh`. This will run some automated tests in docker against your code. + +### Automated Testing + +All PRs are automatically checked by travis. Check out `.travis.yml` for what travis runs. Any new tests sould be added to travis. + +### Code Style and Linting + +Code is automatically check for style by travis as part of the automated tests. You can also run these yourself by running `check_code_quality.sh`. + ## Car Ports (openpilot) We've released a [Model Port guide](https://medium.com/@comma_ai/openpilot-port-guide-for-toyota-models-e5467f4b5fe6) for porting to Toyota/Lexus models. If you port openpilot to a substantially new car brand, see this more generic [Brand Port guide](https://medium.com/@comma_ai/how-to-write-a-car-port-for-openpilot-7ce0785eda84). You might also be eligible for a bounty. See our bounties at [comma.ai/bounties.html](https://comma.ai/bounties.html) - diff --git a/Dockerfile.openpilot b/Dockerfile.openpilot index de602f3bca96c7..c49bd576b18433 100644 --- a/Dockerfile.openpilot +++ b/Dockerfile.openpilot @@ -2,38 +2,78 @@ FROM ubuntu:16.04 ENV PYTHONUNBUFFERED 1 RUN apt-get update && apt-get install -y \ + autoconf \ build-essential \ - clang \ - vim \ - screen \ - wget \ bzip2 \ + clang \ + cmake \ + curl \ + ffmpeg \ git \ - libglib2.0-0 \ - python-pip \ - capnproto \ - libcapnp-dev \ - libzmq5-dev \ + libarchive-dev \ + libbz2-dev \ + libcurl4-openssl-dev \ + libeigen3-dev \ libffi-dev \ - libusb-1.0-0 \ + libglew-dev \ + libglib2.0-0 \ + liblzma-dev \ + libmysqlclient-dev \ + libomp-dev \ + libopencv-dev \ libssl-dev \ + libtool \ + libusb-1.0-0 \ + libzmq5-dev \ + locales \ ocl-icd-libopencl1 \ ocl-icd-opencl-dev \ - opencl-headers + opencl-headers \ + python-dev \ + python-pip \ + screen \ + sudo \ + vim \ + wget + + +RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash + +ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}" +RUN pyenv install 3.7.3 +RUN pyenv global 3.7.3 +RUN pyenv rehash + +RUN pip install pipenv==2018.11.26 + +COPY Pipfile /tmp/ +COPY Pipfile.lock /tmp/ + +RUN python --version +RUN cd /tmp && pipenv install --system --deploy -RUN pip install numpy==1.11.2 scipy==0.18.1 matplotlib==2.1.2 +# Install subset of dev dependencies needed for CI +RUN pip install matplotlib==3.1.1 dictdiffer==0.8.0 fastcluster==1.1.25 aenum==2.2.1 scipy==1.3.1 lru-dict==1.1.6 tenacity==5.1.1 azure-common==1.1.23 azure-nspkg==3.0.2 azure-storage-blob==2.1.0 azure-storage-common==2.1.0 azure-storage-nspkg==3.1.0 pycurl==7.43.0.3 -COPY requirements_openpilot.txt /tmp/ -RUN pip install -r /tmp/requirements_openpilot.txt +COPY phonelibs/install_capnp.sh /tmp/install_capnp.sh +RUN /tmp/install_capnp.sh -ENV PYTHONPATH /tmp/openpilot:$PYTHONPATH +RUN git clone --branch v0.6.5 https://github.com/commaai/openpilot-tools.git /tmp/openpilot/tools +ENV PYTHONPATH /tmp/openpilot:${PYTHONPATH} +COPY ./.pylintrc /tmp/openpilot/.pylintrc COPY ./common /tmp/openpilot/common COPY ./cereal /tmp/openpilot/cereal COPY ./opendbc /tmp/openpilot/opendbc COPY ./selfdrive /tmp/openpilot/selfdrive COPY ./phonelibs /tmp/openpilot/phonelibs COPY ./pyextra /tmp/openpilot/pyextra +COPY ./panda /tmp/openpilot/panda RUN mkdir -p /tmp/openpilot/selfdrive/test/out RUN make -C /tmp/openpilot/selfdrive/controls/lib/longitudinal_mpc clean diff --git a/Pipfile b/Pipfile new file mode 100644 index 00000000000000..888275b2d18ca9 --- /dev/null +++ b/Pipfile @@ -0,0 +1,146 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] +opencv-python= "==3.4.2.17" +PyQt5 = "*" +ipython = "*" +networkx = "*" +azure-common = "*" +azure-nspkg = "*" +azure-storage-blob = "*" +azure-storage-common = "*" +azure-storage-nspkg = "*" +bincopy = "*" +bleach = "*" +boto = "*" +"boto3" = "*" +celery = "*" +control = "*" +datadog = "*" +decorator = "*" +dlib = "*" +dominate = "*" +elasticsearch = "*" +fasteners = "*" +future = "*" +futures = "*" +gevent = "*" +pycocotools = {git = "https://github.com/cocodataset/cocoapi.git",subdirectory = "PythonAPI"} +gunicorn = "*" +"h5py" = "*" +hexdump = "*" +"html5lib" = "*" +imageio = "*" +intervaltree = "*" +ipykernel = "*" +joblib = "*" +json-logging-py = "*" +jupyter = "*" +libarchive = "*" +lru-dict = "*" +lxml = "*" +"mpld3" = "*" +msgpack-python = "*" +nbstripout = "*" +nose-parameterized = "*" +numpy = "*" +osmium = "*" +pbr = "*" +percache = "*" +pprofile = "*" +psutil = "*" +pycurl = "*" +git-pylint-commit-hook = "*" +pymongo = "*" +"pynmea2" = "*" +pypolyline = "*" +pysendfile = "*" +python-logstash = "*" +pyvcd = "*" +redis = "*" +redlock = "*" +"s2sphere" = "*" +scikit-image = "*" +"subprocess32" = "*" +supervisor = "*" +tenacity = "*" +tensorflow-gpu = "" +utm = "*" +"v4l2" = "*" +PyJWT = "==1.4.1" +PyMySQL = "==0.9.2" +Theano = "*" +Werkzeug = "*" +"backports.lzma" = "*" +Flask-Cors = "*" +Flask-SocketIO = "*" +"GeoAlchemy2" = "*" +Pygments = "*" +PyNaCl = "*" +"PySDL2" = "*" +reverse_geocoder = "*" +Shapely = "*" +SQLAlchemy = "*" +uWSGI = "*" +scipy = "*" +fastcluster = "*" +backports-abc = "*" +pygame = "*" +simplejson = "*" +python-logstash-async = "*" +seaborn = "*" +tensorflow-estimator = "*" +pyproj = "*" +mock = "*" +blinker = "*" +gast = "==0.2.2" +matplotlib = "*" +dictdiffer = "*" +aenum = "*" +coverage = "*" + +[packages] +overpy = {git = "https://github.com/commaai/python-overpy.git",ref = "f86529af402d4642e1faeb146671c40284007323"} +atomicwrites = "*" +cffi = "*" +crcmod = "*" +hexdump = "*" +libusb1 = "*" +numpy = "*" +psutil = "*" +pycapnp = "*" +cryptography = "*" +pyserial = "*" +python-dateutil = "*" +pyzmq = "*" +raven = "*" +requests = "*" +setproctitle = "*" +six = "*" +smbus2 = "*" +sympy = "*" +tqdm = "*" +Cython = "*" +PyYAML = "*" +websocket_client = "*" +Logentries = {git = "https://github.com/commaai/le_python.git",ref = "feaeacb48f7f4bdb02c0a8fc092326d4e101b7f2"} +urllib3 = "*" +chardet = "*" +idna = "*" +gunicorn = "*" +utm = "*" +json-rpc = "*" +Flask = "*" +PyJWT = "*" +"Jinja2" = "*" +nose = "*" +flake8 = "*" +pylint = "*" +pycryptodome = "*" +pillow = "*" + +[requires] +python_version = "3.7.3" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 00000000000000..c99cbdfa5b71ef --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,2815 @@ +{ + "_meta": { + "hash": { + "sha256": "5bcd9143fb723dcf4cbecdc3fa38c325e706d67073dab42fb3d966619ee591df" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.7.3" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "astroid": { + "hashes": [ + "sha256:09a3fba616519311f1af8a461f804b68f0370e100c9264a035aa7846d7852e33", + "sha256:5a79c9b4bd6c4be777424593f957c996e20beb5f74e0bc332f47713c6f675efe" + ], + "markers": "python_version >= '3.5'", + "version": "==2.3.2" + }, + "atomicwrites": { + "hashes": [ + "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", + "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6" + ], + "index": "pypi", + "version": "==1.3.0" + }, + "certifi": { + "hashes": [ + "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50", + "sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef" + ], + "version": "==2019.9.11" + }, + "cffi": { + "hashes": [ + "sha256:00d890313797d9fe4420506613384b43099ad7d2b905c0752dbcc3a6f14d80fa", + "sha256:0cf9e550ac6c5e57b713437e2f4ac2d7fd0cd10336525a27224f5fc1ec2ee59a", + "sha256:0ea23c9c0cdd6778146a50d867d6405693ac3b80a68829966c98dd5e1bbae400", + "sha256:193697c2918ecdb3865acf6557cddf5076bb39f1f654975e087b67efdff83365", + "sha256:1ae14b542bf3b35e5229439c35653d2ef7d8316c1fffb980f9b7647e544baa98", + "sha256:1e389e069450609c6ffa37f21f40cce36f9be7643bbe5051ab1de99d5a779526", + "sha256:263242b6ace7f9cd4ea401428d2d45066b49a700852334fd55311bde36dcda14", + "sha256:33142ae9807665fa6511cfa9857132b2c3ee6ddffb012b3f0933fc11e1e830d5", + "sha256:364f8404034ae1b232335d8c7f7b57deac566f148f7222cef78cf8ae28ef764e", + "sha256:47368f69fe6529f8f49a5d146ddee713fc9057e31d61e8b6dc86a6a5e38cecc1", + "sha256:4895640844f17bec32943995dc8c96989226974dfeb9dd121cc45d36e0d0c434", + "sha256:558b3afef987cf4b17abd849e7bedf64ee12b28175d564d05b628a0f9355599b", + "sha256:5ba86e1d80d458b338bda676fd9f9d68cb4e7a03819632969cf6d46b01a26730", + "sha256:63424daa6955e6b4c70dc2755897f5be1d719eabe71b2625948b222775ed5c43", + "sha256:6381a7d8b1ebd0bc27c3bc85bc1bfadbb6e6f756b4d4db0aa1425c3719ba26b4", + "sha256:6381ab708158c4e1639da1f2a7679a9bbe3e5a776fc6d1fd808076f0e3145331", + "sha256:6fd58366747debfa5e6163ada468a90788411f10c92597d3b0a912d07e580c36", + "sha256:728ec653964655d65408949b07f9b2219df78badd601d6c49e28d604efe40599", + "sha256:7cfcfda59ef1f95b9f729c56fe8a4041899f96b72685d36ef16a3440a0f85da8", + "sha256:819f8d5197c2684524637f940445c06e003c4a541f9983fd30d6deaa2a5487d8", + "sha256:825ecffd9574557590e3225560a8a9d751f6ffe4a49e3c40918c9969b93395fa", + "sha256:9009e917d8f5ef780c2626e29b6bc126f4cb2a4d43ca67aa2b40f2a5d6385e78", + "sha256:9c77564a51d4d914ed5af096cd9843d90c45b784b511723bd46a8a9d09cf16fc", + "sha256:a19089fa74ed19c4fe96502a291cfdb89223a9705b1d73b3005df4256976142e", + "sha256:a40ed527bffa2b7ebe07acc5a3f782da072e262ca994b4f2085100b5a444bbb2", + "sha256:bb75ba21d5716abc41af16eac1145ab2e471deedde1f22c6f99bd9f995504df0", + "sha256:e22a00c0c81ffcecaf07c2bfb3672fa372c50e2bd1024ffee0da191c1b27fc71", + "sha256:e55b5a746fb77f10c83e8af081979351722f6ea48facea79d470b3731c7b2891", + "sha256:ec2fa3ee81707a5232bf2dfbd6623fdb278e070d596effc7e2d788f2ada71a05", + "sha256:fd82eb4694be712fcae03c717ca2e0fc720657ac226b80bbb597e971fc6928c2" + ], + "index": "pypi", + "version": "==1.13.1" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "index": "pypi", + "version": "==3.0.4" + }, + "click": { + "hashes": [ + "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", + "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==7.0" + }, + "crcmod": { + "hashes": [ + "sha256:50586ab48981f11e5b117523d97bb70864a2a1af246cf6e4f5c4a21ef4611cd1", + "sha256:69a2e5c6c36d0f096a7beb4cd34e5f882ec5fd232efb710cdb85d4ff196bd52e", + "sha256:737fb308fa2ce9aed2e29075f0d5980d4a89bfbec48a368c607c5c63b3efb90e", + "sha256:dc7051a0db5f2bd48665a990d3ec1cc305a466a77358ca4492826f41f283601e" + ], + "index": "pypi", + "version": "==1.7" + }, + "cryptography": { + "hashes": [ + "sha256:02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c", + "sha256:1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595", + "sha256:369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad", + "sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651", + "sha256:44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2", + "sha256:4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff", + "sha256:58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d", + "sha256:6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42", + "sha256:7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d", + "sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e", + "sha256:7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912", + "sha256:90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793", + "sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13", + "sha256:a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7", + "sha256:b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0", + "sha256:b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879", + "sha256:d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f", + "sha256:de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9", + "sha256:df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2", + "sha256:ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf", + "sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8" + ], + "index": "pypi", + "version": "==2.8" + }, + "cython": { + "hashes": [ + "sha256:07efba7b32c082c519b75e3b03821c2f32848e2b3e9986c784bbd8ffaf0666d7", + "sha256:08db41daf18fabf7b7a85e39aa26954f6246994540043194af026c0df65a4942", + "sha256:19bbe3caf885a1d2e2c30eacc10d1e45dbbefb156493fe1d5d1adc1668cc1269", + "sha256:1c574f2f2ba760b82b2bcf6262e77e75589247dc5ef796a3ff1b2213e50ee452", + "sha256:1dfe672c686e34598bdbaa93c3b30acb3720ae9258232a4f68ba04ee9969063d", + "sha256:283faea84e6c4e54c3f5c8ff89aa2b6c1c3a813aad4f6d48ed3b9cc9043ef9f9", + "sha256:2a145888d0942e7c36e86a7b7c7e2923cb9f7055805a3b72dcb137e3efdb0979", + "sha256:3f75065936e16569d6e13dfd76de988f5eabeae460aa54770c9b961ab6f747fc", + "sha256:4d78124f5f281f1d5d5b7919cbbc65a7073ff93562def81ee78a8307e6e72494", + "sha256:5ba4d088b8e5d59b8a5911ca9c72952acf3c83296b57daf75af92fb2af1e8423", + "sha256:6b19daeda1d5d1dfc973b291246f6a63a663b20c33980724d6d073c562719536", + "sha256:790c7dc80fd1c3e38acefe06027e2f5a8466c128c7e47c6e140fd5316132574d", + "sha256:7f8c4e648881454ba3ba0bcf3b21a9e1878a67d20ea2b8d9ec1c4c628592ab6b", + "sha256:8bcd3f597290f9902548d6355898d7e376e7f3762f89db9cd50b2b58429df9e8", + "sha256:8ffb18f71972a5c718a8600d9f52e3507f0d6fb72a978e03270d34a7035c98fb", + "sha256:92f025df1cb391e09f65775598c7dfb7efad72d74713775db54e267f62ca94a1", + "sha256:93cf1c72472a2fd0ef4c52f6074dab08fc28d475b9c824ba73a52701f7a48ae1", + "sha256:9a7fa692cdc967fdbf6a053c1975137d01f6935dede2ef222c71840b290caf79", + "sha256:a68eb0c1375f2401de881692b30370a51e550052b8e346b2f71bbdbdc74a214f", + "sha256:ac3b7a12ddd52ea910ee3a041e6bc65df7a52f0ba7bd10fb7123502af482c152", + "sha256:b402b700edaf571a0bae18ec35d5b71c266873a6616412b672435c10b6d8f041", + "sha256:c29d069a4a30f472482343c866f7486731ad638ef9af92bfe5fca9c7323d638e", + "sha256:d822311498f185db449b687336b4e5db7638c8d8b03bdf10ae91d74e23c7cc0c", + "sha256:dccc8df9e1ac158b06777bbaaeb4516f245f9b147701ae25e6023960e4a0c2a3", + "sha256:e31f4b946c2765b2f35440fdb4b00c496dfc5babc53c7ae61966b41171d1d59f", + "sha256:eb43f9e582cc221ee2832e25ea6fe5c06f2acc9da6353c562e922f107db12af8", + "sha256:f07822248110fd6213db8bc2745fdbbccef6f2b3d18ac91a7fba29c6bc575da5", + "sha256:ff69854f123b959d4ae14bd5330714bb9ee4360052992dc0fbd0a3dee4261f95" + ], + "index": "pypi", + "version": "==0.29.13" + }, + "entrypoints": { + "hashes": [ + "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", + "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451" + ], + "markers": "python_version >= '2.7'", + "version": "==0.3" + }, + "flake8": { + "hashes": [ + "sha256:19241c1cbc971b9962473e4438a2ca19749a7dd002dd1a946eaba171b4114548", + "sha256:8e9dfa3cecb2400b3738a42c54c3043e821682b9c840b0448c0503f781130696" + ], + "index": "pypi", + "version": "==3.7.8" + }, + "flask": { + "hashes": [ + "sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52", + "sha256:45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6" + ], + "index": "pypi", + "version": "==1.1.1" + }, + "gunicorn": { + "hashes": [ + "sha256:aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471", + "sha256:fa2662097c66f920f53f70621c6c58ca4a3c4d3434205e608e121b5b3b71f4f3" + ], + "index": "pypi", + "version": "==19.9.0" + }, + "hexdump": { + "hashes": [ + "sha256:d781a43b0c16ace3f9366aade73e8ad3a7bd5137d58f0b45ab2d3f54876f20db" + ], + "index": "pypi", + "version": "==3.3" + }, + "idna": { + "hashes": [ + "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", + "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + ], + "index": "pypi", + "version": "==2.8" + }, + "isort": { + "hashes": [ + "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", + "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==4.3.21" + }, + "itsdangerous": { + "hashes": [ + "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", + "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.1.0" + }, + "jinja2": { + "hashes": [ + "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f", + "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de" + ], + "index": "pypi", + "version": "==2.10.3" + }, + "json-rpc": { + "hashes": [ + "sha256:bc84451268b48a576d3138744322a8ce673eccadf7424edf4d446b1ddb59e58c", + "sha256:d6ed3dae670a12e4caa738d309807357d22e2f6e222bb34e8ef019e8b5b1228b" + ], + "index": "pypi", + "version": "==1.12.1" + }, + "lazy-object-proxy": { + "hashes": [ + "sha256:02b260c8deb80db09325b99edf62ae344ce9bc64d68b7a634410b8e9a568edbf", + "sha256:18f9c401083a4ba6e162355873f906315332ea7035803d0fd8166051e3d402e3", + "sha256:1f2c6209a8917c525c1e2b55a716135ca4658a3042b5122d4e3413a4030c26ce", + "sha256:2f06d97f0ca0f414f6b707c974aaf8829c2292c1c497642f63824119d770226f", + "sha256:616c94f8176808f4018b39f9638080ed86f96b55370b5a9463b2ee5c926f6c5f", + "sha256:63b91e30ef47ef68a30f0c3c278fbfe9822319c15f34b7538a829515b84ca2a0", + "sha256:77b454f03860b844f758c5d5c6e5f18d27de899a3db367f4af06bec2e6013a8e", + "sha256:83fe27ba321e4cfac466178606147d3c0aa18e8087507caec78ed5a966a64905", + "sha256:84742532d39f72df959d237912344d8a1764c2d03fe58beba96a87bfa11a76d8", + "sha256:874ebf3caaf55a020aeb08acead813baf5a305927a71ce88c9377970fe7ad3c2", + "sha256:9f5caf2c7436d44f3cec97c2fa7791f8a675170badbfa86e1992ca1b84c37009", + "sha256:a0c8758d01fcdfe7ae8e4b4017b13552efa7f1197dd7358dc9da0576f9d0328a", + "sha256:a4def978d9d28cda2d960c279318d46b327632686d82b4917516c36d4c274512", + "sha256:ad4f4be843dace866af5fc142509e9b9817ca0c59342fdb176ab6ad552c927f5", + "sha256:ae33dd198f772f714420c5ab698ff05ff900150486c648d29951e9c70694338e", + "sha256:b4a2b782b8a8c5522ad35c93e04d60e2ba7f7dcb9271ec8e8c3e08239be6c7b4", + "sha256:c462eb33f6abca3b34cdedbe84d761f31a60b814e173b98ede3c81bb48967c4f", + "sha256:fd135b8d35dfdcdb984828c84d695937e58cc5f49e1c854eb311c4d6aa03f4f1" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.4.2" + }, + "libusb1": { + "hashes": [ + "sha256:adf64a4f3f5c94643a1286f8153bcf4bc787c348b38934aacd7fe17fbeebc571" + ], + "index": "pypi", + "version": "==1.7.1" + }, + "logentries": { + "git": "https://github.com/commaai/le_python.git", + "ref": "feaeacb48f7f4bdb02c0a8fc092326d4e101b7f2", + "version": "==0.8" + }, + "markupsafe": { + "hashes": [ + "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", + "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", + "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", + "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", + "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", + "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", + "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", + "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", + "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", + "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", + "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", + "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", + "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", + "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", + "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", + "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", + "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", + "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", + "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", + "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", + "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", + "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", + "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", + "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", + "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", + "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", + "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", + "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.1.1" + }, + "mccabe": { + "hashes": [ + "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", + "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + ], + "version": "==0.6.1" + }, + "mpmath": { + "hashes": [ + "sha256:fc17abe05fbab3382b61a123c398508183406fa132e0223874578e20946499f6" + ], + "version": "==1.1.0" + }, + "nose": { + "hashes": [ + "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac", + "sha256:dadcddc0aefbf99eea214e0f1232b94f2fa9bd98fa8353711dacb112bfcbbb2a", + "sha256:f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" + ], + "index": "pypi", + "version": "==1.3.7" + }, + "numpy": { + "hashes": [ + "sha256:0b0dd8f47fb177d00fa6ef2d58783c4f41ad3126b139c91dd2f7c4b3fdf5e9a5", + "sha256:25ffe71f96878e1da7e014467e19e7db90ae7d4e12affbc73101bcf61785214e", + "sha256:26efd7f7d755e6ca966a5c0ac5a930a87dbbaab1c51716ac26a38f42ecc9bc4b", + "sha256:28b1180c758abf34a5c3fea76fcee66a87def1656724c42bb14a6f9717a5bdf7", + "sha256:2e418f0a59473dac424f888dd57e85f77502a593b207809211c76e5396ae4f5c", + "sha256:30c84e3a62cfcb9e3066f25226e131451312a044f1fe2040e69ce792cb7de418", + "sha256:4650d94bb9c947151737ee022b934b7d9a845a7c76e476f3e460f09a0c8c6f39", + "sha256:4dd830a11e8724c9c9379feed1d1be43113f8bcce55f47ea7186d3946769ce26", + "sha256:4f2a2b279efde194877aff1f76cf61c68e840db242a5c7169f1ff0fd59a2b1e2", + "sha256:62d22566b3e3428dfc9ec972014c38ed9a4db4f8969c78f5414012ccd80a149e", + "sha256:669795516d62f38845c7033679c648903200980d68935baaa17ac5c7ae03ae0c", + "sha256:75fcd60d682db3e1f8fbe2b8b0c6761937ad56d01c1dc73edf4ef2748d5b6bc4", + "sha256:9395b0a41e8b7e9a284e3be7060db9d14ad80273841c952c83a5afc241d2bd98", + "sha256:9e37c35fc4e9410093b04a77d11a34c64bf658565e30df7cbe882056088a91c1", + "sha256:a0678793096205a4d784bd99f32803ba8100f639cf3b932dc63b21621390ea7e", + "sha256:b46554ad4dafb2927f88de5a1d207398c5385edbb5c84d30b3ef187c4a3894d8", + "sha256:c867eeccd934920a800f65c6068acdd6b87e80d45cd8c8beefff783b23cdc462", + "sha256:dd0667f5be56fb1b570154c2c0516a528e02d50da121bbbb2cbb0b6f87f59bc2", + "sha256:de2b1c20494bdf47f0160bd88ed05f5e48ae5dc336b8de7cfade71abcc95c0b9", + "sha256:f1df7b2b7740dd777571c732f98adb5aad5450aee32772f1b39249c8a50386f6", + "sha256:ffca69e29079f7880c5392bf675eb8b4146479d976ae1924d01cd92b04cccbcc" + ], + "index": "pypi", + "version": "==1.17.3" + }, + "overpy": { + "git": "https://github.com/commaai/python-overpy.git", + "ref": "f86529af402d4642e1faeb146671c40284007323", + "version": "==0.4" + }, + "pillow": { + "hashes": [ + "sha256:047d9473cf68af50ac85f8ee5d5f21a60f849bc17d348da7fc85711287a75031", + "sha256:0f66dc6c8a3cc319561a633b6aa82c44107f12594643efa37210d8c924fc1c71", + "sha256:12c9169c4e8fe0a7329e8658c7e488001f6b4c8e88740e76292c2b857af2e94c", + "sha256:248cffc168896982f125f5c13e9317c059f74fffdb4152893339f3be62a01340", + "sha256:27faf0552bf8c260a5cee21a76e031acaea68babb64daf7e8f2e2540745082aa", + "sha256:285edafad9bc60d96978ed24d77cdc0b91dace88e5da8c548ba5937c425bca8b", + "sha256:384b12c9aa8ef95558abdcb50aada56d74bc7cc131dd62d28c2d0e4d3aadd573", + "sha256:38950b3a707f6cef09cd3cbb142474357ad1a985ceb44d921bdf7b4647b3e13e", + "sha256:4aad1b88933fd6dc2846552b89ad0c74ddbba2f0884e2c162aa368374bf5abab", + "sha256:4ac6148008c169603070c092e81f88738f1a0c511e07bd2bb0f9ef542d375da9", + "sha256:4deb1d2a45861ae6f0b12ea0a786a03d19d29edcc7e05775b85ec2877cb54c5e", + "sha256:59aa2c124df72cc75ed72c8d6005c442d4685691a30c55321e00ed915ad1a291", + "sha256:5a47d2123a9ec86660fe0e8d0ebf0aa6bc6a17edc63f338b73ea20ba11713f12", + "sha256:5cc901c2ab9409b4b7ac7b5bcc3e86ac14548627062463da0af3b6b7c555a871", + "sha256:6c1db03e8dff7b9f955a0fb9907eb9ca5da75b5ce056c0c93d33100a35050281", + "sha256:7ce80c0a65a6ea90ef9c1f63c8593fcd2929448613fc8da0adf3e6bfad669d08", + "sha256:809c19241c14433c5d6135e1b6c72da4e3b56d5c865ad5736ab99af8896b8f41", + "sha256:83792cb4e0b5af480588601467c0764242b9a483caea71ef12d22a0d0d6bdce2", + "sha256:846fa202bd7ee0f6215c897a1d33238ef071b50766339186687bd9b7a6d26ac5", + "sha256:9f5529fc02009f96ba95bea48870173426879dc19eec49ca8e08cd63ecd82ddb", + "sha256:a423c2ea001c6265ed28700df056f75e26215fd28c001e93ef4380b0f05f9547", + "sha256:ac4428094b42907aba5879c7c000d01c8278d451a3b7cccd2103e21f6397ea75", + "sha256:b1ae48d87f10d1384e5beecd169c77502fcc04a2c00a4c02b85f0a94b419e5f9", + "sha256:bf4e972a88f8841d8fdc6db1a75e0f8d763e66e3754b03006cbc3854d89f1cb1", + "sha256:c6414f6aad598364aaf81068cabb077894eb88fed99c6a65e6e8217bab62ae7a", + "sha256:c710fcb7ee32f67baf25aa9ffede4795fd5d93b163ce95fdc724383e38c9df96", + "sha256:c7be4b8a09852291c3c48d3c25d1b876d2494a0a674980089ac9d5e0d78bd132", + "sha256:c9e5ffb910b14f090ac9c38599063e354887a5f6d7e6d26795e916b4514f2c1a", + "sha256:e0697b826da6c2472bb6488db4c0a7fa8af0d52fa08833ceb3681358914b14e5", + "sha256:e9a3edd5f714229d41057d56ac0f39ad9bdba6767e8c888c951869f0bdd129b0" + ], + "index": "pypi", + "version": "==6.2.1" + }, + "psutil": { + "hashes": [ + "sha256:028a1ec3c6197eadd11e7b46e8cc2f0720dc18ac6d7aabdb8e8c0d6c9704f000", + "sha256:12542c3642909f4cd1928a2fba59e16fa27e47cbeea60928ebb62a8cbd1ce123", + "sha256:503e4b20fa9d3342bcf58191bbc20a4a5ef79ca7df8972e6197cc14c5513e73d", + "sha256:863a85c1c0a5103a12c05a35e59d336e1d665747e531256e061213e2e90f63f3", + "sha256:954f782608bfef9ae9f78e660e065bd8ffcfaea780f9f2c8a133bb7cb9e826d7", + "sha256:b6e08f965a305cd84c2d07409bc16fbef4417d67b70c53b299116c5b895e3f45", + "sha256:bc96d437dfbb8865fc8828cf363450001cb04056bbdcdd6fc152c436c8a74c61", + "sha256:cf49178021075d47c61c03c0229ac0c60d5e2830f8cab19e2d88e579b18cdb76", + "sha256:d5350cb66690915d60f8b233180f1e49938756fb2d501c93c44f8fb5b970cc63", + "sha256:eba238cf1989dfff7d483c029acb0ac4fcbfc15de295d682901f0e2497e6781a" + ], + "index": "pypi", + "version": "==5.6.3" + }, + "pycapnp": { + "hashes": [ + "sha256:44e14a5ace399cf1753acb8bbce558b8c895c48fd2102d266c34eaff286824cf" + ], + "index": "pypi", + "version": "==0.6.4" + }, + "pycodestyle": { + "hashes": [ + "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", + "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.5.0" + }, + "pycparser": { + "hashes": [ + "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3" + ], + "version": "==2.19" + }, + "pycryptodome": { + "hashes": [ + "sha256:023c294367d7189ae224fb61bc8d49a2347704087c1c78dbd5ab114dd5b97761", + "sha256:0f29e1238ad3b6b6e2acd7ea1d8e8b382978a56503f2c48b67d5dc144d143cb0", + "sha256:18f376698e3ddcb1d3b312512ca78c9eed132e68ac6d0bf2e72452dfe213e96f", + "sha256:1de815b847982f909dc2e5e2ca641b85cde80d95cc7e6a359c03d4b42cd21568", + "sha256:1ff619b8e4050799ca5ca0ffdf8eb0dbccba6997997866755f37e6aa7dde23fe", + "sha256:233a04bb7bdd4b07e14d61d5166150942d872802daa4f049d49a453fe0659e94", + "sha256:33c07e1e36ec84524b49f99f11804d5e4d2188c643e84d914cb1e0a277ed3c79", + "sha256:3701822a085dbebf678bfbdfbd6ebd92ffa80d5a544c9979984bf16a67c9790b", + "sha256:3f8e6851c0a45429f9b86c1597d3b831b0cff140b3e170a891fce55ef8dac2bb", + "sha256:4f6cdddf1fe72e7f173e9734aa19b94cbd046b61a8559d650ff222e36021d5c1", + "sha256:52d20b22c5b1fc952b4c686b99a6c55c3b0b0a673bec30570f156a72198f66ff", + "sha256:5452b534fecf8bf57cf9106d00877f5f4ab7264e7a5e1f5ea8d15b04517d1255", + "sha256:5a7a9a4a7f8f0990fa97fee71c7f7e0c412925c515cfc6d4996961e92c9be8e5", + "sha256:600bf9dd5fbed0feee83950e2a8baacaa1f38b56c237fff270d31e47f8da9e52", + "sha256:6840c9881e528224ebf72b3f73b3d11baf399e265106c9f4d9bae4f09615a93a", + "sha256:71b041d43fe13004abc36ca720ac64ea489ee8a3407a25116481d0faf9d62494", + "sha256:7252498b427c421e306473ed344e58235eedd95c15fec2e1b33d333aefa1ea10", + "sha256:8d2135c941d38f241e0e62dbdfc1ca5d9240527e61316126797f50b6f3e49825", + "sha256:a0962aea03933b99cf391c3e10dfef32f77915d5553464264cfbc6711f31d254", + "sha256:a117047a220b3911d425affcd1cbc97a1af7ea7eb5d985d9964d42b4f0558489", + "sha256:a35a5c588248ba00eb976a8554211e584a55de286783bc69b12bdd7954052b4a", + "sha256:c1a4f3f651471b9bf60b0d98fa8a994b8a73ff8ab4edc691e23243c853aaff9f", + "sha256:c419943306756ddd1a1997120bb073733bc223365909c68185106d5521cbc0ef", + "sha256:c453ad968b67d66448543420ec39770c30bd16d986058255f058ab87c4f6cc1f", + "sha256:d2d78644655629c7d1b9bf28e479d29facc0949d9ff095103ca9c2314b329ee0", + "sha256:d7be60dc2126ee350ac7191549f5ab05c2dd76a5d5a3022249f395a401c6ea37", + "sha256:dbeb08ad850056747aa7d5f33273b7ce0b9a77910604a1be7b7a6f2ef076213f", + "sha256:f02382dc1bf91fb7123f2a3851fb1b526c871fa9359f387f2bcc847efc74ae52" + ], + "index": "pypi", + "version": "==3.9.0" + }, + "pyflakes": { + "hashes": [ + "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0", + "sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.1.1" + }, + "pyjwt": { + "hashes": [ + "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e", + "sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96" + ], + "index": "pypi", + "version": "==1.7.1" + }, + "pylint": { + "hashes": [ + "sha256:7b76045426c650d2b0f02fc47c14d7934d17898779da95288a74c2a7ec440702", + "sha256:856476331f3e26598017290fd65bebe81c960e806776f324093a46b76fb2d1c0" + ], + "index": "pypi", + "version": "==2.4.3" + }, + "pyserial": { + "hashes": [ + "sha256:6e2d401fdee0eab996cf734e67773a0143b932772ca8b42451440cfed942c627", + "sha256:e0770fadba80c31013896c7e6ef703f72e7834965954a78e71a3049488d4d7d8" + ], + "index": "pypi", + "version": "==3.4" + }, + "python-dateutil": { + "hashes": [ + "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", + "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" + ], + "index": "pypi", + "version": "==2.8.0" + }, + "pyyaml": { + "hashes": [ + "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9", + "sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4", + "sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8", + "sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696", + "sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34", + "sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9", + "sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73", + "sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299", + "sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b", + "sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae", + "sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681", + "sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41", + "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8" + ], + "index": "pypi", + "version": "==5.1.2" + }, + "pyzmq": { + "hashes": [ + "sha256:01636e95a88d60118479041c6aaaaf5419c6485b7b1d37c9c4dd424b7b9f1121", + "sha256:021dba0d1436516092c624359e5da51472b11ba8edffa334218912f7e8b65467", + "sha256:0463bd941b6aead494d4035f7eebd70035293dd6caf8425993e85ad41de13fa3", + "sha256:05fd51edd81eed798fccafdd49c936b6c166ffae7b32482e4d6d6a2e196af4e6", + "sha256:1fadc8fbdf3d22753c36d4172169d184ee6654f8d6539e7af25029643363c490", + "sha256:22efa0596cf245a78a99060fe5682c4cd00c58bb7614271129215c889062db80", + "sha256:260c70b7c018905ec3659d0f04db735ac830fe27236e43b9dc0532cf7c9873ef", + "sha256:2762c45e289732d4450406cedca35a9d4d71e449131ba2f491e0bf473e3d2ff2", + "sha256:2fc6cada8dc53521c1189596f1898d45c5f68603194d3a6453d6db4b27f4e12e", + "sha256:343b9710a61f2b167673bea1974e70b5dccfe64b5ed10626798f08c1f7227e72", + "sha256:41bf96d5f554598a0632c3ec28e3026f1d6591a50f580df38eff0b8067efb9e7", + "sha256:856b2cdf7a1e2cbb84928e1e8db0ea4018709b39804103d3a409e5584f553f57", + "sha256:85b869abc894672de9aecdf032158ea8ad01e2f0c3b09ef60e3687fb79418096", + "sha256:93f44739db69234c013a16990e43db1aa0af3cf5a4b8b377d028ff24515fbeb3", + "sha256:98fa3e75ccb22c0dc99654e3dd9ff693b956861459e8c8e8734dd6247b89eb29", + "sha256:9a22c94d2e93af8bebd4fcf5fa38830f5e3b1ff0d4424e2912b07651eb1bafb4", + "sha256:a7d3f4b4bbb5d7866ae727763268b5c15797cbd7b63ea17f3b0ec1067da8994b", + "sha256:b645a49376547b3816433a7e2d2a99135c8e651e50497e7ecac3bd126e4bea16", + "sha256:cf0765822e78cf9e45451647a346d443f66792aba906bc340f4e0ac7870c169c", + "sha256:dc398e1e047efb18bfab7a8989346c6921a847feae2cad69fedf6ca12fb99e2c", + "sha256:dd5995ae2e80044e33b5077fb4bc2b0c1788ac6feaf15a6b87a00c14b4bdd682", + "sha256:e03fe5e07e70f245dc9013a9d48ae8cc4b10c33a1968039c5a3b64b5d01d083d", + "sha256:ea09a306144dff2795e48439883349819bef2c53c0ee62a3c2fae429451843bb", + "sha256:f4e37f33da282c3c319849877e34f97f0a3acec09622ec61b7333205bdd13b52", + "sha256:fa4bad0d1d173dee3e8ef3c3eb6b2bb6c723fc7a661eeecc1ecb2fa99860dd45" + ], + "index": "pypi", + "version": "==18.1.0" + }, + "raven": { + "hashes": [ + "sha256:3fa6de6efa2493a7c827472e984ce9b020797d0da16f1db67197bcc23c8fae54", + "sha256:44a13f87670836e153951af9a3c80405d36b43097db869a36e92809673692ce4" + ], + "index": "pypi", + "version": "==6.10.0" + }, + "requests": { + "hashes": [ + "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", + "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" + ], + "index": "pypi", + "version": "==2.22.0" + }, + "setproctitle": { + "hashes": [ + "sha256:6283b7a58477dd8478fbb9e76defb37968ee4ba47b05ec1c053cb39638bd7398", + "sha256:6a035eddac62898786aed2c2eee7334c28cfc8106e8eb29fdd117cac56c6cdf0" + ], + "index": "pypi", + "version": "==1.1.10" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "index": "pypi", + "version": "==1.12.0" + }, + "smbus2": { + "hashes": [ + "sha256:210e66eebe4d0b1fe836b3ec2751841942e1c4918c0b429b20a0e20a222228b4" + ], + "index": "pypi", + "version": "==0.3.0" + }, + "sympy": { + "hashes": [ + "sha256:71a11e5686ae7ab6cb8feb5bd2651ef4482f8fd43a7c27e645a165e4353b23e1", + "sha256:f9b00ec76151c98470e84f1da2d7d03633180b71fb318428ddccce1c867d3eaa" + ], + "index": "pypi", + "version": "==1.4" + }, + "tqdm": { + "hashes": [ + "sha256:abc25d0ce2397d070ef07d8c7e706aede7920da163c64997585d42d3537ece3d", + "sha256:dd3fcca8488bb1d416aa7469d2f277902f26260c45aa86b667b074cd44b3b115" + ], + "index": "pypi", + "version": "==4.36.1" + }, + "typed-ast": { + "hashes": [ + "sha256:1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", + "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", + "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", + "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", + "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", + "sha256:48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", + "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", + "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", + "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", + "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", + "sha256:7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", + "sha256:838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", + "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", + "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", + "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", + "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", + "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", + "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", + "sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", + "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12" + ], + "markers": "python_version < '3.8' and implementation_name == 'cpython'", + "version": "==1.4.0" + }, + "urllib3": { + "hashes": [ + "sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398", + "sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86" + ], + "index": "pypi", + "version": "==1.25.6" + }, + "utm": { + "hashes": [ + "sha256:07e55707ed660eec1ae983bd54a406c437962618a6261b38d70592fe30f5f508" + ], + "index": "pypi", + "version": "==0.5.0" + }, + "websocket-client": { + "hashes": [ + "sha256:1151d5fb3a62dc129164292e1227655e4bbc5dd5340a5165dfae61128ec50aa9", + "sha256:1fd5520878b68b84b5748bb30e592b10d0a91529d5383f74f4964e72b297fd3a" + ], + "index": "pypi", + "version": "==0.56.0" + }, + "werkzeug": { + "hashes": [ + "sha256:7280924747b5733b246fe23972186c6b348f9ae29724135a6dfc1e53cea433e7", + "sha256:e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.16.0" + }, + "wrapt": { + "hashes": [ + "sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1" + ], + "version": "==1.11.2" + } + }, + "develop": { + "absl-py": { + "hashes": [ + "sha256:d9129186431e150d7fe455f1cb1ecbb92bb5dba9da9bc3ef7b012d98c4db2526" + ], + "version": "==0.8.1" + }, + "aenum": { + "hashes": [ + "sha256:0e3589654ef090784971f7778dcb74b08c9b4ef80b33267c00f82ddeedac179a", + "sha256:b12a7be3d89b270f266f8643aaa126404e5cdc0929bd6f09548b8eaed85e2aa1", + "sha256:e4dab068cbe00295bbc3660cd562221b008687d0f7a4c40fc2dd7a80002126a7" + ], + "index": "pypi", + "version": "==2.2.1" + }, + "amqp": { + "hashes": [ + "sha256:19a917e260178b8d410122712bac69cb3e6db010d68f6101e7307508aded5e68", + "sha256:19d851b879a471fcfdcf01df9936cff924f422baa77653289f7095dedd5fb26a" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.5.1" + }, + "astor": { + "hashes": [ + "sha256:0e41295809baf43ae8303350e031aff81ae52189b6f881f36d623fa8b2f1960e", + "sha256:37a6eed8b371f1228db08234ed7f6cfdc7817a3ed3824797e20cbb11dc2a7862" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.8.0" + }, + "astroid": { + "hashes": [ + "sha256:09a3fba616519311f1af8a461f804b68f0370e100c9264a035aa7846d7852e33", + "sha256:5a79c9b4bd6c4be777424593f957c996e20beb5f74e0bc332f47713c6f675efe" + ], + "markers": "python_version >= '3.5'", + "version": "==2.3.2" + }, + "attrs": { + "hashes": [ + "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", + "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==19.3.0" + }, + "azure-common": { + "hashes": [ + "sha256:53b1195b8f20943ccc0e71a17849258f7781bc6db1c72edc7d6c055f79bd54e3", + "sha256:99ef36e74b6395329aada288764ce80504da16ecc8206cb9a72f55fb02e8b484" + ], + "index": "pypi", + "version": "==1.1.23" + }, + "azure-nspkg": { + "hashes": [ + "sha256:1d0bbb2157cf57b1bef6c8c8e5b41133957364456c43b0a43599890023cca0a8", + "sha256:31a060caca00ed1ebd369fc7fe01a56768c927e404ebc92268f4d9d636435e28", + "sha256:e7d3cea6af63e667d87ba1ca4f8cd7cb4dfca678e4c55fc1cedb320760e39dd0" + ], + "index": "pypi", + "version": "==3.0.2" + }, + "azure-storage-blob": { + "hashes": [ + "sha256:a8e91a51d4f62d11127c7fd8ba0077385c5b11022f0269f8a2a71b9fc36bef31", + "sha256:b90323aad60f207f9f90a0c4cf94c10acc313c20b39403398dfba51f25f7b454" + ], + "index": "pypi", + "version": "==2.1.0" + }, + "azure-storage-common": { + "hashes": [ + "sha256:b01a491a18839b9d05a4fe3421458a0ddb5ab9443c14e487f40d16f9a1dc2fbe", + "sha256:ccedef5c67227bc4d6670ffd37cec18fb529a1b7c3a5e53e4096eb0cf23dc73f" + ], + "index": "pypi", + "version": "==2.1.0" + }, + "azure-storage-nspkg": { + "hashes": [ + "sha256:6f3bbe8652d5f542767d8433e7f96b8df7f518774055ac7c92ed7ca85f653811", + "sha256:7da3bd6c73b8c464a57f53ae9af8328490d2267c66430d8a7621997e52a9703e" + ], + "index": "pypi", + "version": "==3.1.0" + }, + "backcall": { + "hashes": [ + "sha256:38ecd85be2c1e78f77fd91700c76e14667dc21e2713b63876c0eb901196e01e4", + "sha256:bbbf4b1e5cd2bdb08f915895b51081c041bac22394fdfcfdfbe9f14b77c08bf2" + ], + "version": "==0.1.0" + }, + "backports-abc": { + "hashes": [ + "sha256:033be54514a03e255df75c5aee8f9e672f663f93abb723444caec8fe43437bde", + "sha256:52089f97fe7a9aa0d3277b220c1d730a85aefd64e1b2664696fe35317c5470a7" + ], + "index": "pypi", + "version": "==0.5" + }, + "backports.lzma": { + "hashes": [ + "sha256:16d8b68e4d3cd4e6c9ddb059850452946da3914c8a8e197a7f2b0954559f2df4" + ], + "index": "pypi", + "version": "==0.0.14" + }, + "billiard": { + "hashes": [ + "sha256:01afcb4e7c4fd6480940cfbd4d9edc19d7a7509d6ada533984d0d0f49901ec82", + "sha256:b8809c74f648dfe69b973c8e660bcec00603758c9db8ba89d7719f88d5f01f26" + ], + "version": "==3.6.1.0" + }, + "bincopy": { + "hashes": [ + "sha256:1b4c7219e01042cd8217fb6c12b66f6b0ff01d1986d27b0cb18fcdcf1ea3dcb7", + "sha256:3ba5fe82fc07cb1be40e5ff668a9869aabb5b264a9223b3ff4ded77273260c8c" + ], + "index": "pypi", + "version": "==16.1.3" + }, + "bleach": { + "hashes": [ + "sha256:213336e49e102af26d9cde77dd2d0397afabc5a6bf2fed985dc35b5d1e285a16", + "sha256:3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa" + ], + "index": "pypi", + "version": "==3.1.0" + }, + "blinker": { + "hashes": [ + "sha256:471aee25f3992bd325afa3772f1063dbdbbca947a041b8b89466dc00d606f8b6" + ], + "index": "pypi", + "version": "==1.4" + }, + "boto": { + "hashes": [ + "sha256:147758d41ae7240dc989f0039f27da8ca0d53734be0eb869ef16e3adcfa462e8", + "sha256:ea0d3b40a2d852767be77ca343b58a9e3a4b00d9db440efb8da74b4e58025e5a" + ], + "index": "pypi", + "version": "==2.49.0" + }, + "boto3": { + "hashes": [ + "sha256:7fc97cb2c9cdff905e950750c8e8b23b872a84696158a28852355dc4b712ba3a", + "sha256:818c56a317c176142dbf1dca3f5b4366c80460c6cc3c4efe22f0bde736571283" + ], + "index": "pypi", + "version": "==1.10.2" + }, + "botocore": { + "hashes": [ + "sha256:8223485841ef4731a5d4943a733295ba69d0005c4ae64c468308cc07f6960d39", + "sha256:f8e12dc6e536ea512f0ad25b74e7eecdf5d9e09ae92b5de236b535bee7804d5b" + ], + "version": "==1.13.2" + }, + "celery": { + "hashes": [ + "sha256:4c4532aa683f170f40bd76f928b70bc06ff171a959e06e71bf35f2f9d6031ef9", + "sha256:528e56767ae7e43a16cfef24ee1062491f5754368d38fcfffa861cdb9ef219be" + ], + "index": "pypi", + "version": "==4.3.0" + }, + "certifi": { + "hashes": [ + "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50", + "sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef" + ], + "version": "==2019.9.11" + }, + "cffi": { + "hashes": [ + "sha256:00d890313797d9fe4420506613384b43099ad7d2b905c0752dbcc3a6f14d80fa", + "sha256:0cf9e550ac6c5e57b713437e2f4ac2d7fd0cd10336525a27224f5fc1ec2ee59a", + "sha256:0ea23c9c0cdd6778146a50d867d6405693ac3b80a68829966c98dd5e1bbae400", + "sha256:193697c2918ecdb3865acf6557cddf5076bb39f1f654975e087b67efdff83365", + "sha256:1ae14b542bf3b35e5229439c35653d2ef7d8316c1fffb980f9b7647e544baa98", + "sha256:1e389e069450609c6ffa37f21f40cce36f9be7643bbe5051ab1de99d5a779526", + "sha256:263242b6ace7f9cd4ea401428d2d45066b49a700852334fd55311bde36dcda14", + "sha256:33142ae9807665fa6511cfa9857132b2c3ee6ddffb012b3f0933fc11e1e830d5", + "sha256:364f8404034ae1b232335d8c7f7b57deac566f148f7222cef78cf8ae28ef764e", + "sha256:47368f69fe6529f8f49a5d146ddee713fc9057e31d61e8b6dc86a6a5e38cecc1", + "sha256:4895640844f17bec32943995dc8c96989226974dfeb9dd121cc45d36e0d0c434", + "sha256:558b3afef987cf4b17abd849e7bedf64ee12b28175d564d05b628a0f9355599b", + "sha256:5ba86e1d80d458b338bda676fd9f9d68cb4e7a03819632969cf6d46b01a26730", + "sha256:63424daa6955e6b4c70dc2755897f5be1d719eabe71b2625948b222775ed5c43", + "sha256:6381a7d8b1ebd0bc27c3bc85bc1bfadbb6e6f756b4d4db0aa1425c3719ba26b4", + "sha256:6381ab708158c4e1639da1f2a7679a9bbe3e5a776fc6d1fd808076f0e3145331", + "sha256:6fd58366747debfa5e6163ada468a90788411f10c92597d3b0a912d07e580c36", + "sha256:728ec653964655d65408949b07f9b2219df78badd601d6c49e28d604efe40599", + "sha256:7cfcfda59ef1f95b9f729c56fe8a4041899f96b72685d36ef16a3440a0f85da8", + "sha256:819f8d5197c2684524637f940445c06e003c4a541f9983fd30d6deaa2a5487d8", + "sha256:825ecffd9574557590e3225560a8a9d751f6ffe4a49e3c40918c9969b93395fa", + "sha256:9009e917d8f5ef780c2626e29b6bc126f4cb2a4d43ca67aa2b40f2a5d6385e78", + "sha256:9c77564a51d4d914ed5af096cd9843d90c45b784b511723bd46a8a9d09cf16fc", + "sha256:a19089fa74ed19c4fe96502a291cfdb89223a9705b1d73b3005df4256976142e", + "sha256:a40ed527bffa2b7ebe07acc5a3f782da072e262ca994b4f2085100b5a444bbb2", + "sha256:bb75ba21d5716abc41af16eac1145ab2e471deedde1f22c6f99bd9f995504df0", + "sha256:e22a00c0c81ffcecaf07c2bfb3672fa372c50e2bd1024ffee0da191c1b27fc71", + "sha256:e55b5a746fb77f10c83e8af081979351722f6ea48facea79d470b3731c7b2891", + "sha256:ec2fa3ee81707a5232bf2dfbd6623fdb278e070d596effc7e2d788f2ada71a05", + "sha256:fd82eb4694be712fcae03c717ca2e0fc720657ac226b80bbb597e971fc6928c2" + ], + "index": "pypi", + "version": "==1.13.1" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "index": "pypi", + "version": "==3.0.4" + }, + "click": { + "hashes": [ + "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", + "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==7.0" + }, + "control": { + "hashes": [ + "sha256:726e8c36a253a54c8886df31f860d740d70de4f8b041421d5df078c3bff3aadb" + ], + "index": "pypi", + "version": "==0.8.2" + }, + "coverage": { + "hashes": [ + "sha256:08907593569fe59baca0bf152c43f3863201efb6113ecb38ce7e97ce339805a6", + "sha256:0be0f1ed45fc0c185cfd4ecc19a1d6532d72f86a2bac9de7e24541febad72650", + "sha256:141f08ed3c4b1847015e2cd62ec06d35e67a3ac185c26f7635f4406b90afa9c5", + "sha256:19e4df788a0581238e9390c85a7a09af39c7b539b29f25c89209e6c3e371270d", + "sha256:23cc09ed395b03424d1ae30dcc292615c1372bfba7141eb85e11e50efaa6b351", + "sha256:245388cda02af78276b479f299bbf3783ef0a6a6273037d7c60dc73b8d8d7755", + "sha256:331cb5115673a20fb131dadd22f5bcaf7677ef758741312bee4937d71a14b2ef", + "sha256:386e2e4090f0bc5df274e720105c342263423e77ee8826002dcffe0c9533dbca", + "sha256:3a794ce50daee01c74a494919d5ebdc23d58873747fa0e288318728533a3e1ca", + "sha256:60851187677b24c6085248f0a0b9b98d49cba7ecc7ec60ba6b9d2e5574ac1ee9", + "sha256:63a9a5fc43b58735f65ed63d2cf43508f462dc49857da70b8980ad78d41d52fc", + "sha256:6b62544bb68106e3f00b21c8930e83e584fdca005d4fffd29bb39fb3ffa03cb5", + "sha256:6ba744056423ef8d450cf627289166da65903885272055fb4b5e113137cfa14f", + "sha256:7494b0b0274c5072bddbfd5b4a6c6f18fbbe1ab1d22a41e99cd2d00c8f96ecfe", + "sha256:826f32b9547c8091679ff292a82aca9c7b9650f9fda3e2ca6bf2ac905b7ce888", + "sha256:93715dffbcd0678057f947f496484e906bf9509f5c1c38fc9ba3922893cda5f5", + "sha256:9a334d6c83dfeadae576b4d633a71620d40d1c379129d587faa42ee3e2a85cce", + "sha256:af7ed8a8aa6957aac47b4268631fa1df984643f07ef00acd374e456364b373f5", + "sha256:bf0a7aed7f5521c7ca67febd57db473af4762b9622254291fbcbb8cd0ba5e33e", + "sha256:bf1ef9eb901113a9805287e090452c05547578eaab1b62e4ad456fcc049a9b7e", + "sha256:c0afd27bc0e307a1ffc04ca5ec010a290e49e3afbe841c5cafc5c5a80ecd81c9", + "sha256:dd579709a87092c6dbee09d1b7cfa81831040705ffa12a1b248935274aee0437", + "sha256:df6712284b2e44a065097846488f66840445eb987eb81b3cc6e4149e7b6982e1", + "sha256:e07d9f1a23e9e93ab5c62902833bf3e4b1f65502927379148b6622686223125c", + "sha256:e2ede7c1d45e65e209d6093b762e98e8318ddeff95317d07a27a2140b80cfd24", + "sha256:e4ef9c164eb55123c62411f5936b5c2e521b12356037b6e1c2617cef45523d47", + "sha256:eca2b7343524e7ba246cab8ff00cab47a2d6d54ada3b02772e908a45675722e2", + "sha256:eee64c616adeff7db37cc37da4180a3a5b6177f5c46b187894e633f088fb5b28", + "sha256:ef824cad1f980d27f26166f86856efe11eff9912c4fed97d3804820d43fa550c", + "sha256:efc89291bd5a08855829a3c522df16d856455297cf35ae827a37edac45f466a7", + "sha256:fa964bae817babece5aa2e8c1af841bebb6d0b9add8e637548809d040443fee0", + "sha256:ff37757e068ae606659c28c3bd0d923f9d29a85de79bf25b2b34b148473b5025" + ], + "index": "pypi", + "version": "==4.5.4" + }, + "cryptography": { + "hashes": [ + "sha256:02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c", + "sha256:1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595", + "sha256:369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad", + "sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651", + "sha256:44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2", + "sha256:4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff", + "sha256:58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d", + "sha256:6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42", + "sha256:7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d", + "sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e", + "sha256:7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912", + "sha256:90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793", + "sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13", + "sha256:a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7", + "sha256:b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0", + "sha256:b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879", + "sha256:d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f", + "sha256:de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9", + "sha256:df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2", + "sha256:ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf", + "sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8" + ], + "index": "pypi", + "version": "==2.8" + }, + "cycler": { + "hashes": [ + "sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d", + "sha256:cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8" + ], + "version": "==0.10.0" + }, + "datadog": { + "hashes": [ + "sha256:07c053e39c6509023d69bc2f3b8e3d5d101b4e75baf2da2b9fc707391c3e773d", + "sha256:bbfd8c3a13e87b9c15fb982dff269b983ad9fb5ab610e7f17d92b0bc001fbe0f" + ], + "index": "pypi", + "version": "==0.30.0" + }, + "decorator": { + "hashes": [ + "sha256:86156361c50488b84a3f148056ea716ca587df2f0de1d34750d35c21312725de", + "sha256:f069f3a01830ca754ba5258fde2278454a0b5b79e0d7f5c13b3b97e57d4acff6" + ], + "index": "pypi", + "version": "==4.4.0" + }, + "defusedxml": { + "hashes": [ + "sha256:6687150770438374ab581bb7a1b327a847dd9c5749e396102de3fad4e8a3ef93", + "sha256:f684034d135af4c6cbb949b8a4d2ed61634515257a67299e5f940fbaa34377f5" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.6.0" + }, + "dictdiffer": { + "hashes": [ + "sha256:97cf4ef98ebc1acf737074aed41e379cf48ab5ff528c92109dfb8e2e619e6809", + "sha256:b3ad476fc9cca60302b52c50e1839342d2092aeaba586d69cbf9249f87f52463" + ], + "index": "pypi", + "version": "==0.8.0" + }, + "dlib": { + "hashes": [ + "sha256:8ca127253a0ca82a3d847148515f82ff2c504ed77a6385ec4f38c7f8e5360860" + ], + "index": "pypi", + "version": "==19.18.0" + }, + "docutils": { + "hashes": [ + "sha256:6c4f696463b79f1fb8ba0c594b63840ebd41f059e92b31957c46b74a4599b6d0", + "sha256:9e4d7ecfc600058e07ba661411a2b7de2fd0fafa17d1a7f7361cd47b1175c827", + "sha256:a2aeea129088da402665e92e0b25b04b073c04b2dce4ab65caaa38b7ce2e1a99" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.15.2" + }, + "dominate": { + "hashes": [ + "sha256:6e833aea505f0236a9fc692326bac575f8bd38ae0f3a1bdc73d20ca606ac75d5", + "sha256:a92474b4312bd8b4c1789792f3ec8c571cd8afa8e7502a2b1c64dd48cd67e59c" + ], + "index": "pypi", + "version": "==2.4.0" + }, + "elasticsearch": { + "hashes": [ + "sha256:693935914d59a517dfffdaab547ff906712a386d9e25027517464960221cbd4c", + "sha256:7644fa0a9ae524344185bda561826a781a5c6bd4d3eb98a24515c567aab88327" + ], + "index": "pypi", + "version": "==7.0.5" + }, + "entrypoints": { + "hashes": [ + "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", + "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451" + ], + "markers": "python_version >= '2.7'", + "version": "==0.3" + }, + "fastcluster": { + "hashes": [ + "sha256:0024b1304d4618a32900473b809265694bc6d0a10bfbc272407443318644d405", + "sha256:0b33b076ea98939742e0734e944c903c8c67af3eecd5a9f8b4349407c1affdd3", + "sha256:244d400a81d23b48f2b825e50e99e1ff3c7d2be2acc40942e3359b4deef68483", + "sha256:2bb3bf8e1c7af42e47ef24bc2386a1d3e6ec8dc5e6be4123a491a36b89227b49", + "sha256:539d84d43fbe541a38d94c84bf0469c430cb7cda488364941ce57f680a07b091", + "sha256:5e7d81385bbc2148c554c4aaa32e26a00fbadc1190d5bad9c8719f6432629307", + "sha256:642e4d92220c1deede1e89409c5ad366e4a3f3ed55fff0a4e325d4eb2574d65a", + "sha256:66c868fdfc161e5c45cdf399f1274216602ea82c9fc46c632c9602dbaa149840", + "sha256:6952c9d25b3ea60d6a53ee92205e7f16cc6baf7caa4776fb1e55dc6e8e2965f2", + "sha256:8606da6f6f51f81c3b4e000edeb8668711a1769a6ebf3c99ab98f9c6d2fb7534", + "sha256:8d552d29ed054ce20f5bb0445b51bd7b6b8088fdae334625b4a9950189dcc2bf", + "sha256:922735fde2848a6f0478c6968048a16a5d3d6ba6e1d1a9596d578b59dce719d7", + "sha256:9f3cd227a9ebeec090e4186a63e46cd87d121968bd1d45ea8a7c2d483bc082fb", + "sha256:a382cb411610ca06a69e7b131239f0bb02961fec762d5b6804e653a32cd5ab52", + "sha256:a986b3afe823bcaea3dad9de1485b176c6dd5b0e2f154ede71aaf6635e82e159", + "sha256:b1902ab52418c6f4c2f3f7439aea711c6b5aa9bbb4c97b6d4b0c6f5e5c894342", + "sha256:bb56f6c7343bbb68beb1ffd13abdb87ce7a84ab391b3a4e63ed5c02b2d1ce46f", + "sha256:c2e5d11f5f96e6861fd632246f18bc6592ac439f236caffd4d2a75697a6f8969", + "sha256:c61973bb16117ee16b7642ff9da8e0899fb4d5eb5d0cc9c56d3269551ccd6307", + "sha256:d2deec11a6625c5578325f4dd10980e2981d1f1d1e658c7c79f2497377f92bdf", + "sha256:e0f2feb03f67b12f25538aa05b1150c7a2c1cd1c21ad7d0bde94e8169ef46627", + "sha256:e32e7287c47291eca2c83cd5cc6a5007eff2da00c12ac21fd721a16d0c428059", + "sha256:e889ea36c4e469ff3fb2a6a868c8e557fc988a81cd1cf3d09876107e59ee9cbd", + "sha256:e96f3b65e3748f2be06aa0977a00872ddeca4f8959703126f2b103978243bbdd" + ], + "index": "pypi", + "version": "==1.1.25" + }, + "fasteners": { + "hashes": [ + "sha256:007e4d2b2d4a10093f67e932e5166722d2eab83b77724156e92ad013c6226574", + "sha256:3a176da6b70df9bb88498e1a18a9e4a8579ed5b9141207762368a1017bf8f5ef" + ], + "index": "pypi", + "version": "==0.15" + }, + "flask": { + "hashes": [ + "sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52", + "sha256:45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6" + ], + "index": "pypi", + "version": "==1.1.1" + }, + "flask-cors": { + "hashes": [ + "sha256:72170423eb4612f0847318afff8c247b38bd516b7737adfc10d1c2cdbb382d16", + "sha256:f4d97201660e6bbcff2d89d082b5b6d31abee04b1b3003ee073a6fd25ad1d69a" + ], + "index": "pypi", + "version": "==3.0.8" + }, + "flask-socketio": { + "hashes": [ + "sha256:2172dff1e42415ba480cee02c30c2fc833671ff326f1598ee3d69aa02cf768ec", + "sha256:7ff5b2f5edde23e875a8b0abf868584e5706e11741557449bc5147df2cd78268" + ], + "index": "pypi", + "version": "==4.2.1" + }, + "future": { + "hashes": [ + "sha256:858e38522e8fd0d3ce8f0c1feaf0603358e366d5403209674c7b617fa0c24093" + ], + "index": "pypi", + "version": "==0.18.1" + }, + "futures": { + "hashes": [ + "sha256:3a44f286998ae64f0cc083682fcfec16c406134a81a589a5de445d7bb7c2751b", + "sha256:51ecb45f0add83c806c68e4b06106f90db260585b25ef2abfcda0bd95c0132fd", + "sha256:c4884a65654a7c45435063e14ae85280eb1f111d94e542396717ba9828c4337f" + ], + "index": "pypi", + "version": "==3.1.1" + }, + "gast": { + "hashes": [ + "sha256:fe939df4583692f0512161ec1c880e0a10e71e6a232da045ab8edd3756fbadf0" + ], + "index": "pypi", + "version": "==0.2.2" + }, + "geoalchemy2": { + "hashes": [ + "sha256:0d1c9ea3ec13f6a522ccc3ffd2569ac524a6c6e80bab883e8805b28c48e77143", + "sha256:4dc4c6c2bda0fc82cccab4aaff185a6570e13a5351d85e29e12984a55d4138ee" + ], + "index": "pypi", + "version": "==0.6.3" + }, + "gevent": { + "hashes": [ + "sha256:0774babec518a24d9a7231d4e689931f31b332c4517a771e532002614e270a64", + "sha256:0e1e5b73a445fe82d40907322e1e0eec6a6745ca3cea19291c6f9f50117bb7ea", + "sha256:0ff2b70e8e338cf13bedf146b8c29d475e2a544b5d1fe14045aee827c073842c", + "sha256:107f4232db2172f7e8429ed7779c10f2ed16616d75ffbe77e0e0c3fcdeb51a51", + "sha256:14b4d06d19d39a440e72253f77067d27209c67e7611e352f79fe69e0f618f76e", + "sha256:1b7d3a285978b27b469c0ff5fb5a72bcd69f4306dbbf22d7997d83209a8ba917", + "sha256:1eb7fa3b9bd9174dfe9c3b59b7a09b768ecd496debfc4976a9530a3e15c990d1", + "sha256:2711e69788ddb34c059a30186e05c55a6b611cb9e34ac343e69cf3264d42fe1c", + "sha256:28a0c5417b464562ab9842dd1fb0cc1524e60494641d973206ec24d6ec5f6909", + "sha256:3249011d13d0c63bea72d91cec23a9cf18c25f91d1f115121e5c9113d753fa12", + "sha256:44089ed06a962a3a70e96353c981d628b2d4a2f2a75ea5d90f916a62d22af2e8", + "sha256:4bfa291e3c931ff3c99a349d8857605dca029de61d74c6bb82bd46373959c942", + "sha256:50024a1ee2cf04645535c5ebaeaa0a60c5ef32e262da981f4be0546b26791950", + "sha256:53b72385857e04e7faca13c613c07cab411480822ac658d97fd8a4ddbaf715c8", + "sha256:74b7528f901f39c39cdbb50cdf08f1a2351725d9aebaef212a29abfbb06895ee", + "sha256:7d0809e2991c9784eceeadef01c27ee6a33ca09ebba6154317a257353e3af922", + "sha256:896b2b80931d6b13b5d9feba3d4eebc67d5e6ec54f0cf3339d08487d55d93b0e", + "sha256:8d9ec51cc06580f8c21b41fd3f2b3465197ba5b23c00eb7d422b7ae0380510b0", + "sha256:9f7a1e96fec45f70ad364e46de32ccacab4d80de238bd3c2edd036867ccd48ad", + "sha256:ab4dc33ef0e26dc627559786a4fba0c2227f125db85d970abbf85b77506b3f51", + "sha256:d1e6d1f156e999edab069d79d890859806b555ce4e4da5b6418616322f0a3df1", + "sha256:d752bcf1b98174780e2317ada12013d612f05116456133a6acf3e17d43b71f05", + "sha256:e5bcc4270671936349249d26140c267397b7b4b1381f5ec8b13c53c5b53ab6e1" + ], + "index": "pypi", + "version": "==1.4.0" + }, + "git-pylint-commit-hook": { + "hashes": [ + "sha256:e1d39e7856b3ef0a0269121ca210dc3f5a97da158b322411e8e1185918a91b3c" + ], + "index": "pypi", + "version": "==2.5.1" + }, + "google-pasta": { + "hashes": [ + "sha256:40b4f55ba7b44823eac96d055000572c84ce48cacb3e91c100869844064b2d07", + "sha256:79d1ce28b381d68e98ef7707d19909adb58912f8dae8734402454424fc76b8fe", + "sha256:7ca8afc4cfeebf4a079cdf586333d5447cecd19a997475136138fc83c3351bc4" + ], + "version": "==0.1.7" + }, + "greenlet": { + "hashes": [ + "sha256:000546ad01e6389e98626c1367be58efa613fa82a1be98b0c6fc24b563acc6d0", + "sha256:0d48200bc50cbf498716712129eef819b1729339e34c3ae71656964dac907c28", + "sha256:23d12eacffa9d0f290c0fe0c4e81ba6d5f3a5b7ac3c30a5eaf0126bf4deda5c8", + "sha256:37c9ba82bd82eb6a23c2e5acc03055c0e45697253b2393c9a50cef76a3985304", + "sha256:51503524dd6f152ab4ad1fbd168fc6c30b5795e8c70be4410a64940b3abb55c0", + "sha256:8041e2de00e745c0e05a502d6e6db310db7faa7c979b3a5877123548a4c0b214", + "sha256:81fcd96a275209ef117e9ec91f75c731fa18dcfd9ffaa1c0adbdaa3616a86043", + "sha256:853da4f9563d982e4121fed8c92eea1a4594a2299037b3034c3c898cb8e933d6", + "sha256:8b4572c334593d449113f9dc8d19b93b7b271bdbe90ba7509eb178923327b625", + "sha256:9416443e219356e3c31f1f918a91badf2e37acf297e2fa13d24d1cc2380f8fbc", + "sha256:9854f612e1b59ec66804931df5add3b2d5ef0067748ea29dc60f0efdcda9a638", + "sha256:99a26afdb82ea83a265137a398f570402aa1f2b5dfb4ac3300c026931817b163", + "sha256:a19bf883b3384957e4a4a13e6bd1ae3d85ae87f4beb5957e35b0be287f12f4e4", + "sha256:a9f145660588187ff835c55a7d2ddf6abfc570c2651c276d3d4be8a2766db490", + "sha256:ac57fcdcfb0b73bb3203b58a14501abb7e5ff9ea5e2edfa06bb03035f0cff248", + "sha256:bcb530089ff24f6458a81ac3fa699e8c00194208a724b644ecc68422e1111939", + "sha256:beeabe25c3b704f7d56b573f7d2ff88fc99f0138e43480cecdfcaa3b87fe4f87", + "sha256:d634a7ea1fc3380ff96f9e44d8d22f38418c1c381d5fac680b272d7d90883720", + "sha256:d97b0661e1aead761f0ded3b769044bb00ed5d33e1ec865e891a8b128bf7c656" + ], + "markers": "platform_python_implementation == 'CPython'", + "version": "==0.4.15" + }, + "grpcio": { + "hashes": [ + "sha256:01cb705eafba1108e2a947ba0457da4f6a1e8142c729fc61702b5fdd11009eb1", + "sha256:0b5a79e29f167d3cd06faad6b15babbc2661066daaacf79373c3a8e67ca1fca1", + "sha256:1097a61a0e97b3580642e6e1460a3a1f1ba1815e2a70d6057173bcc495417076", + "sha256:13970e665a4ec4cec7d067d7d3504a0398c657d91d26c581144ad9044e429c9a", + "sha256:1557817cea6e0b87fad2a3e20da385170efb03a313db164e8078955add2dfa1b", + "sha256:1b0fb036a2f9dd93d9a35c57c26420eeb4b571fcb14b51cddf5b1e73ea5d882b", + "sha256:24d9e58d08e8cd545d8a3247a18654aff0e5e60414701696a8098fbb0d792b75", + "sha256:2c38b586163d2b91567fe5e6d9e7798f792012365adc838a64b66b22dce3f4d4", + "sha256:2df3ab4348507de60e1cbf75196403df1b9b4c4d4dc5bd11ac4eb63c46f691c7", + "sha256:32f70f7c90454ea568b868af2e96616743718d9233d23f62407e98caed81dfbf", + "sha256:3af2a49d576820045c9c880ff29a5a96d020fe31b35d248519bfc6ccb8be4eac", + "sha256:4ff7d63800a63db031ebac6a6f581ae84877c959401c24c28f2cc51fd36c47ad", + "sha256:502aaa8be56f0ae69cda66bc27e1fb5531ceaa27ca515ec3c34f6178b1297180", + "sha256:55358ce3ec283222e435f7dbc6603521438458f3c65f7c1cb33b8dabf56d70d8", + "sha256:5583b01c67f85fa64a2c3fb085e5517c88b9c1500a2cce12d473cd99d0ed2e49", + "sha256:58d9a5557d3eb7b734a3cea8b16c891099a522b3953a45a30bd4c034f75fc913", + "sha256:5911f042c4ab177757eec5bcb4e2e9a2e823d888835d24577321bf55f02938fa", + "sha256:5e16ea922f4e5017c04fd94e2639b1006e03097e9dd0cbb7a1c852af3ea8bf2e", + "sha256:656e19d3f1b9050ee01b457f92838a9679d7cf84c995f708780f44484048705e", + "sha256:6a1435449a82008c451c7e1a82a834387b9108f9a8d27910f86e7c482f5568e9", + "sha256:6ff02ca6cbed0ddb76e93ba0f8beb6a8c77d83a84eb7cafe2ae3399a8b9d69ea", + "sha256:76de68f60102f333bf4817f38e81ecbee68b850f5a5da9f355235e948ac40981", + "sha256:7c6d7ddd50fc6548ea1dfe09c62509c4f95b8b40082287747be05aa8feb15ee2", + "sha256:836b9d29507de729129e363276fe7c7d6a34c7961e0f155787025552b15d22c0", + "sha256:869242b2baf8a888a4fe0548f86abc47cb4b48bdfd76ae62d6456e939c202e65", + "sha256:8954b24bd08641d906ee50b2d638efc76df893fbd0913149b80484fd0eac40c9", + "sha256:8cdea65d1abb2e698420db8daf20c8d272fbd9d96a51b26a713c1c76f237d181", + "sha256:90161840b4fe9636f91ed0d3ea1e7e615e488cbea4e77594c889e5f3d7a776db", + "sha256:90fb6316b4d7d36700c40db4335902b78dcae13b5466673c21fd3b08a3c1b0c6", + "sha256:91b34f58db2611c9a93ecf751028f97fba1f06e65f49b38f272f6aa5d2977331", + "sha256:9474944a96a33eb8734fa8dc5805403d57973a3526204a5e1c1780d02e0572b6", + "sha256:9a36275db2a4774ac16c6822e7af816ee048071d5030b4c035fd53942b361935", + "sha256:9cbe26e2976b994c5f7c2d35a63354674d6ca0ce62f5b513f078bf63c1745229", + "sha256:9eaeabb3c0eecd6ddd0c16767fd12d130e2cebb8c2618f959a278b1ff336ddc3", + "sha256:a2bc7e10ebcf4be503ae427f9887e75c0cc24e88ce467a8e6eaca6bd2862406e", + "sha256:a5b42e6292ba51b8e67e09fc256963ba4ca9c04026de004d2fe59cc17e3c3776", + "sha256:bd6ec1233c86c0b9bb5d03ec30dbe3ffbfa53335790320d99a7ae9018c5450f2", + "sha256:bef57530816af54d66b1f4c70a8f851f320cb6f84d4b5a0b422b0e9811ea4e59", + "sha256:c146a63eaadc6589b732780061f3c94cd0574388d372baccbb3c1597a9ebdb7a", + "sha256:c2efd3b130dc639d615b6f58980e1bfd1b177ad821f30827afa5001aa30ddd48", + "sha256:c888b18f7392e6cc79a33a803e7ebd7890ac3318f571fca6b356526f35b53b12", + "sha256:ca30721fda297ae22f16bc37aa7ed244970ddfdcb98247570cdd26daaad4665e", + "sha256:cf5f5340dd682ab034baa52f423a0f91326489c262ac9617fa06309ec05880e9", + "sha256:d0726aa0d9b57c56985db5952e90fb1033a317074f2877db5307cdd6eede1564", + "sha256:df442945b2dd6f8ae0e20b403e0fd4548cd5c2aad69200047cc3251257b78f65", + "sha256:e08e758c31919d167c0867539bd3b2441629ef00aa595e3ea2b635273659f40a", + "sha256:e4864339deeeaefaad34dd3a432ee618a039fca28efb292949c855e00878203c", + "sha256:f4cd049cb94d9f517b1cab5668a3b345968beba093bc79a637e671000b3540ec" + ], + "version": "==1.24.3" + }, + "gunicorn": { + "hashes": [ + "sha256:aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471", + "sha256:fa2662097c66f920f53f70621c6c58ca4a3c4d3434205e608e121b5b3b71f4f3" + ], + "index": "pypi", + "version": "==19.9.0" + }, + "h5py": { + "hashes": [ + "sha256:063947eaed5f271679ed4ffa36bb96f57bc14f44dd4336a827d9a02702e6ce6b", + "sha256:13c87efa24768a5e24e360a40e0bc4c49bcb7ce1bb13a3a7f9902cec302ccd36", + "sha256:16ead3c57141101e3296ebeed79c9c143c32bdd0e82a61a2fc67e8e6d493e9d1", + "sha256:3dad1730b6470fad853ef56d755d06bb916ee68a3d8272b3bab0c1ddf83bb99e", + "sha256:51ae56894c6c93159086ffa2c94b5b3388c0400548ab26555c143e7cfa05b8e5", + "sha256:54817b696e87eb9e403e42643305f142cd8b940fe9b3b490bbf98c3b8a894cf4", + "sha256:549ad124df27c056b2e255ea1c44d30fb7a17d17676d03096ad5cd85edb32dc1", + "sha256:6998be619c695910cb0effe5eb15d3a511d3d1a5d217d4bd0bebad1151ec2262", + "sha256:6ef7ab1089e3ef53ca099038f3c0a94d03e3560e6aff0e9d6c64c55fb13fc681", + "sha256:769e141512b54dee14ec76ed354fcacfc7d97fea5a7646b709f7400cf1838630", + "sha256:79b23f47c6524d61f899254f5cd5e486e19868f1823298bc0c29d345c2447172", + "sha256:7be5754a159236e95bd196419485343e2b5875e806fe68919e087b6351f40a70", + "sha256:84412798925dc870ffd7107f045d7659e60f5d46d1c70c700375248bf6bf512d", + "sha256:86868dc07b9cc8cb7627372a2e6636cdc7a53b7e2854ad020c9e9d8a4d3fd0f5", + "sha256:8bb1d2de101f39743f91512a9750fb6c351c032e5cd3204b4487383e34da7f75", + "sha256:a5f82cd4938ff8761d9760af3274acf55afc3c91c649c50ab18fcff5510a14a5", + "sha256:aac4b57097ac29089f179bbc2a6e14102dd210618e94d77ee4831c65f82f17c0", + "sha256:bffbc48331b4a801d2f4b7dac8a72609f0b10e6e516e5c480a3e3241e091c878", + "sha256:c0d4b04bbf96c47b6d360cd06939e72def512b20a18a8547fa4af810258355d5", + "sha256:c54a2c0dd4957776ace7f95879d81582298c5daf89e77fb8bee7378f132951de", + "sha256:cbf28ae4b5af0f05aa6e7551cee304f1d317dbed1eb7ac1d827cee2f1ef97a99", + "sha256:d3c59549f90a891691991c17f8e58c8544060fdf3ccdea267100fa5f561ff62f", + "sha256:d7ae7a0576b06cb8e8a1c265a8bc4b73d05fdee6429bffc9a26a6eb531e79d72", + "sha256:ecf4d0b56ee394a0984de15bceeb97cbe1fe485f1ac205121293fc44dcf3f31f", + "sha256:f0e25bb91e7a02efccb50aba6591d3fe2c725479e34769802fcdd4076abfa917", + "sha256:f23951a53d18398ef1344c186fb04b26163ca6ce449ebd23404b153fd111ded9", + "sha256:ff7d241f866b718e4584fa95f520cb19405220c501bd3a53ee11871ba5166ea2" + ], + "index": "pypi", + "version": "==2.10.0" + }, + "hexdump": { + "hashes": [ + "sha256:d781a43b0c16ace3f9366aade73e8ad3a7bd5137d58f0b45ab2d3f54876f20db" + ], + "index": "pypi", + "version": "==3.3" + }, + "html5lib": { + "hashes": [ + "sha256:20b159aa3badc9d5ee8f5c647e5efd02ed2a66ab8d354930bd9ff139fc1dc0a3", + "sha256:66cb0dcfdbbc4f9c3ba1a63fdb511ffdbd4f513b2b6d81b80cd26ce6b3fb3736" + ], + "index": "pypi", + "version": "==1.0.1" + }, + "humanfriendly": { + "hashes": [ + "sha256:23057b10ad6f782e7bc3a20e3cb6768ab919f619bbdc0dd75691121bbde5591d", + "sha256:33ee8ceb63f1db61cce8b5c800c531e1a61023ac5488ccde2ba574a85be00a85" + ], + "version": "==4.18" + }, + "idna": { + "hashes": [ + "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", + "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + ], + "index": "pypi", + "version": "==2.8" + }, + "imageio": { + "hashes": [ + "sha256:c9763e5c187ecf74091c845626b0bdcc6130a20a0de7a86ae0108e2b5335ed3f", + "sha256:f44eb231b9df485874f2ffd22dfd0c3c711e7de076516b9374edea5c65bc67ae" + ], + "index": "pypi", + "version": "==2.6.1" + }, + "importlib-metadata": { + "hashes": [ + "sha256:aa18d7378b00b40847790e7c27e11673d7fed219354109d0e7b9e5b25dc3ad26", + "sha256:d5f18a79777f3aa179c145737780282e27b508fc8fd688cb17c7a813e8bd39af" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.23" + }, + "intervaltree": { + "hashes": [ + "sha256:cb4f61c81dcb4fea6c09903f3599015a83c9bdad1f0bbd232495e6681e19e273" + ], + "index": "pypi", + "version": "==3.0.2" + }, + "ipykernel": { + "hashes": [ + "sha256:1a7def9c986f1ee018c1138d16951932d4c9d4da01dad45f9d34e9899565a22f", + "sha256:b368ad13edb71fa2db367a01e755a925d7f75ed5e09fbd3f06c85e7a8ef108a8" + ], + "index": "pypi", + "version": "==5.1.3" + }, + "ipython": { + "hashes": [ + "sha256:c4ab005921641e40a68e405e286e7a1fcc464497e14d81b6914b4fd95e5dee9b", + "sha256:dd76831f065f17bddd7eaa5c781f5ea32de5ef217592cf019e34043b56895aa1" + ], + "index": "pypi", + "version": "==7.8.0" + }, + "ipython-genutils": { + "hashes": [ + "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8", + "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8" + ], + "version": "==0.2.0" + }, + "ipywidgets": { + "hashes": [ + "sha256:13ffeca438e0c0f91ae583dc22f50379b9d6b28390ac7be8b757140e9a771516", + "sha256:e945f6e02854a74994c596d9db83444a1850c01648f1574adf144fbbabe05c97" + ], + "version": "==7.5.1" + }, + "isort": { + "hashes": [ + "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", + "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==4.3.21" + }, + "itsdangerous": { + "hashes": [ + "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", + "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.1.0" + }, + "jedi": { + "hashes": [ + "sha256:786b6c3d80e2f06fd77162a07fed81b8baa22dde5d62896a790a331d6ac21a27", + "sha256:ba859c74fa3c966a22f2aeebe1b74ee27e2a462f56d3f5f7ca4a59af61bfe42e" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.15.1" + }, + "jinja2": { + "hashes": [ + "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f", + "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de" + ], + "index": "pypi", + "version": "==2.10.3" + }, + "jmespath": { + "hashes": [ + "sha256:3720a4b1bd659dd2eecad0666459b9788813e032b83e7ba58578e48254e0a0e6", + "sha256:bde2aef6f44302dfb30320115b17d030798de8c4110e28d5cf6cf91a7a31074c" + ], + "version": "==0.9.4" + }, + "joblib": { + "hashes": [ + "sha256:006108c7576b3eb6c5b27761ddbf188eb6e6347696325ab2027ea1ee9a4b922d", + "sha256:6fcc57aacb4e89451fd449e9412687c51817c3f48662c3d8f38ba3f8a0a193ff" + ], + "index": "pypi", + "version": "==0.14.0" + }, + "json-logging-py": { + "hashes": [ + "sha256:118b1fe1f4eacaea6370e5b9710d0f6d0c0a4599aef9d5b9875a6a579974fc9a" + ], + "index": "pypi", + "version": "==0.2" + }, + "jsonschema": { + "hashes": [ + "sha256:2fa0684276b6333ff3c0b1b27081f4b2305f0a36cf702a23db50edb141893c3f", + "sha256:94c0a13b4a0616458b42529091624e66700a17f847453e52279e35509a5b7631" + ], + "version": "==3.1.1" + }, + "jupyter": { + "hashes": [ + "sha256:3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7", + "sha256:5b290f93b98ffbc21c0c7e749f054b3267782166d72fa5e3ed1ed4eaf34a2b78", + "sha256:d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f" + ], + "index": "pypi", + "version": "==1.0.0" + }, + "jupyter-client": { + "hashes": [ + "sha256:60e6faec1031d63df57f1cc671ed673dced0ed420f4377ea33db37b1c188b910", + "sha256:d0c077c9aaa4432ad485e7733e4d91e48f87b4f4bab7d283d42bb24cbbba0a0f" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==5.3.4" + }, + "jupyter-console": { + "hashes": [ + "sha256:308ce876354924fb6c540b41d5d6d08acfc946984bf0c97777c1ddcb42e0b2f5", + "sha256:cc80a97a5c389cbd30252ffb5ce7cefd4b66bde98219edd16bf5cb6f84bb3568" + ], + "markers": "python_version >= '3.5'", + "version": "==6.0.0" + }, + "jupyter-core": { + "hashes": [ + "sha256:464769f7387d7a62a2403d067f1ddc616655b7f77f5d810c0dd62cb54bfd0fb9", + "sha256:a183e0ec2e8f6adddf62b0a3fc6a2237e3e0056d381e536d3e7c7ecc3067e244" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==4.6.1" + }, + "keras-applications": { + "hashes": [ + "sha256:5579f9a12bcde9748f4a12233925a59b93b73ae6947409ff34aa2ba258189fe5", + "sha256:df4323692b8c1174af821bf906f1e442e63fa7589bf0f1230a0b6bdc5a810c95" + ], + "version": "==1.0.8" + }, + "keras-preprocessing": { + "hashes": [ + "sha256:44aee5f2c4d80c3b29f208359fcb336df80f293a0bb6b1c738da43ca206656fb", + "sha256:5a8debe01d840de93d49e05ccf1c9b81ae30e210d34dacbcc47aeb3049b528e5" + ], + "version": "==1.1.0" + }, + "kiwisolver": { + "hashes": [ + "sha256:05b5b061e09f60f56244adc885c4a7867da25ca387376b02c1efc29cc16bcd0f", + "sha256:26f4fbd6f5e1dabff70a9ba0d2c4bd30761086454aa30dddc5b52764ee4852b7", + "sha256:3b2378ad387f49cbb328205bda569b9f87288d6bc1bf4cd683c34523a2341efe", + "sha256:400599c0fe58d21522cae0e8b22318e09d9729451b17ee61ba8e1e7c0346565c", + "sha256:47b8cb81a7d18dbaf4fed6a61c3cecdb5adec7b4ac292bddb0d016d57e8507d5", + "sha256:53eaed412477c836e1b9522c19858a8557d6e595077830146182225613b11a75", + "sha256:58e626e1f7dfbb620d08d457325a4cdac65d1809680009f46bf41eaf74ad0187", + "sha256:5a52e1b006bfa5be04fe4debbcdd2688432a9af4b207a3f429c74ad625022641", + "sha256:5c7ca4e449ac9f99b3b9d4693debb1d6d237d1542dd6a56b3305fe8a9620f883", + "sha256:682e54f0ce8f45981878756d7203fd01e188cc6c8b2c5e2cf03675390b4534d5", + "sha256:79bfb2f0bd7cbf9ea256612c9523367e5ec51d7cd616ae20ca2c90f575d839a2", + "sha256:7f4dd50874177d2bb060d74769210f3bce1af87a8c7cf5b37d032ebf94f0aca3", + "sha256:8944a16020c07b682df861207b7e0efcd2f46c7488619cb55f65882279119389", + "sha256:8aa7009437640beb2768bfd06da049bad0df85f47ff18426261acecd1cf00897", + "sha256:939f36f21a8c571686eb491acfffa9c7f1ac345087281b412d63ea39ca14ec4a", + "sha256:9733b7f64bd9f807832d673355f79703f81f0b3e52bfce420fc00d8cb28c6a6c", + "sha256:a02f6c3e229d0b7220bd74600e9351e18bc0c361b05f29adae0d10599ae0e326", + "sha256:a0c0a9f06872330d0dd31b45607197caab3c22777600e88031bfe66799e70bb0", + "sha256:acc4df99308111585121db217681f1ce0eecb48d3a828a2f9bbf9773f4937e9e", + "sha256:b64916959e4ae0ac78af7c3e8cef4becee0c0e9694ad477b4c6b3a536de6a544", + "sha256:d3fcf0819dc3fea58be1fd1ca390851bdb719a549850e708ed858503ff25d995", + "sha256:d52e3b1868a4e8fd18b5cb15055c76820df514e26aa84cc02f593d99fef6707f", + "sha256:db1a5d3cc4ae943d674718d6c47d2d82488ddd94b93b9e12d24aabdbfe48caee", + "sha256:e3a21a720791712ed721c7b95d433e036134de6f18c77dbe96119eaf7aa08004", + "sha256:e8bf074363ce2babeb4764d94f8e65efd22e6a7c74860a4f05a6947afc020ff2", + "sha256:f16814a4a96dc04bf1da7d53ee8d5b1d6decfc1a92a63349bb15d37b6a263dd9", + "sha256:f2b22153870ca5cf2ab9c940d7bc38e8e9089fa0f7e5856ea195e1cf4ff43d5a", + "sha256:f790f8b3dff3d53453de6a7b7ddd173d2e020fb160baff578d578065b108a05f" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.1.0" + }, + "kombu": { + "hashes": [ + "sha256:31edb84947996fdda065b6560c128d5673bb913ff34aa19e7b84755217a24deb", + "sha256:c9078124ce2616b29cf6607f0ac3db894c59154252dee6392cdbbe15e5c4b566" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==4.6.5" + }, + "lazy-object-proxy": { + "hashes": [ + "sha256:02b260c8deb80db09325b99edf62ae344ce9bc64d68b7a634410b8e9a568edbf", + "sha256:18f9c401083a4ba6e162355873f906315332ea7035803d0fd8166051e3d402e3", + "sha256:1f2c6209a8917c525c1e2b55a716135ca4658a3042b5122d4e3413a4030c26ce", + "sha256:2f06d97f0ca0f414f6b707c974aaf8829c2292c1c497642f63824119d770226f", + "sha256:616c94f8176808f4018b39f9638080ed86f96b55370b5a9463b2ee5c926f6c5f", + "sha256:63b91e30ef47ef68a30f0c3c278fbfe9822319c15f34b7538a829515b84ca2a0", + "sha256:77b454f03860b844f758c5d5c6e5f18d27de899a3db367f4af06bec2e6013a8e", + "sha256:83fe27ba321e4cfac466178606147d3c0aa18e8087507caec78ed5a966a64905", + "sha256:84742532d39f72df959d237912344d8a1764c2d03fe58beba96a87bfa11a76d8", + "sha256:874ebf3caaf55a020aeb08acead813baf5a305927a71ce88c9377970fe7ad3c2", + "sha256:9f5caf2c7436d44f3cec97c2fa7791f8a675170badbfa86e1992ca1b84c37009", + "sha256:a0c8758d01fcdfe7ae8e4b4017b13552efa7f1197dd7358dc9da0576f9d0328a", + "sha256:a4def978d9d28cda2d960c279318d46b327632686d82b4917516c36d4c274512", + "sha256:ad4f4be843dace866af5fc142509e9b9817ca0c59342fdb176ab6ad552c927f5", + "sha256:ae33dd198f772f714420c5ab698ff05ff900150486c648d29951e9c70694338e", + "sha256:b4a2b782b8a8c5522ad35c93e04d60e2ba7f7dcb9271ec8e8c3e08239be6c7b4", + "sha256:c462eb33f6abca3b34cdedbe84d761f31a60b814e173b98ede3c81bb48967c4f", + "sha256:fd135b8d35dfdcdb984828c84d695937e58cc5f49e1c854eb311c4d6aa03f4f1" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.4.2" + }, + "libarchive": { + "hashes": [ + "sha256:829dc298a08877f62335d528973bc034f7c1e8a03c16bfc1fa561e164e76a365" + ], + "index": "pypi", + "version": "==0.4.7" + }, + "limits": { + "hashes": [ + "sha256:9df578f4161017d79f5188609f1d65f6b639f8aad2914c3960c9252e56a0ff95", + "sha256:a017b8d9e9da6761f4574642149c337f8f540d4edfe573fb91ad2c4001a2bc76" + ], + "version": "==1.3" + }, + "lru-dict": { + "hashes": [ + "sha256:365457660e3d05b76f1aba3e0f7fedbfcd6528e97c5115a351ddd0db488354cc" + ], + "index": "pypi", + "version": "==1.1.6" + }, + "lxml": { + "hashes": [ + "sha256:02ca7bf899da57084041bb0f6095333e4d239948ad3169443f454add9f4e9cb4", + "sha256:096b82c5e0ea27ce9138bcbb205313343ee66a6e132f25c5ed67e2c8d960a1bc", + "sha256:0a920ff98cf1aac310470c644bc23b326402d3ef667ddafecb024e1713d485f1", + "sha256:17cae1730a782858a6e2758fd20dd0ef7567916c47757b694a06ffafdec20046", + "sha256:17e3950add54c882e032527795c625929613adbd2ce5162b94667334458b5a36", + "sha256:1f4f214337f6ee5825bf90a65d04d70aab05526c08191ab888cb5149501923c5", + "sha256:2e8f77db25b0a96af679e64ff9bf9dddb27d379c9900c3272f3041c4d1327c9d", + "sha256:4dffd405390a45ecb95ab5ab1c1b847553c18b0ef8ed01e10c1c8b1a76452916", + "sha256:6b899931a5648862c7b88c795eddff7588fb585e81cecce20f8d9da16eff96e0", + "sha256:726c17f3e0d7a7200718c9a890ccfeab391c9133e363a577a44717c85c71db27", + "sha256:760c12276fee05c36f95f8040180abc7fbebb9e5011447a97cdc289b5d6ab6fc", + "sha256:796685d3969815a633827c818863ee199440696b0961e200b011d79b9394bbe7", + "sha256:891fe897b49abb7db470c55664b198b1095e4943b9f82b7dcab317a19116cd38", + "sha256:a471628e20f03dcdfde00770eeaf9c77811f0c331c8805219ca7b87ac17576c5", + "sha256:a63b4fd3e2cabdcc9d918ed280bdde3e8e9641e04f3c59a2a3109644a07b9832", + "sha256:b0b84408d4eabc6de9dd1e1e0bc63e7731e890c0b378a62443e5741cfd0ae90a", + "sha256:be78485e5d5f3684e875dab60f40cddace2f5b2a8f7fede412358ab3214c3a6f", + "sha256:c27eaed872185f047bb7f7da2d21a7d8913457678c9a100a50db6da890bc28b9", + "sha256:c81cb40bff373ab7a7446d6bbca0190bccc5be3448b47b51d729e37799bb5692", + "sha256:d11874b3c33ee441059464711cd365b89fa1a9cf19ae75b0c189b01fbf735b84", + "sha256:e9c028b5897901361d81a4718d1db217b716424a0283afe9d6735fe0caf70f79", + "sha256:fe489d486cd00b739be826e8c1be188ddb74c7a1ca784d93d06fda882a6a1681" + ], + "index": "pypi", + "version": "==4.4.1" + }, + "markdown": { + "hashes": [ + "sha256:2e50876bcdd74517e7b71f3e7a76102050edec255b3983403f1a63e7c8a41e7a", + "sha256:56a46ac655704b91e5b7e6326ce43d5ef72411376588afa1dd90e881b83c7e8c" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==3.1.1" + }, + "markupsafe": { + "hashes": [ + "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", + "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", + "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", + "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", + "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", + "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", + "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", + "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", + "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", + "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", + "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", + "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", + "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", + "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", + "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", + "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", + "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", + "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", + "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", + "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", + "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", + "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", + "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", + "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", + "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", + "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", + "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", + "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.1.1" + }, + "matplotlib": { + "hashes": [ + "sha256:1febd22afe1489b13c6749ea059d392c03261b2950d1d45c17e3aed812080c93", + "sha256:31a30d03f39528c79f3a592857be62a08595dec4ac034978ecd0f814fa0eec2d", + "sha256:4442ce720907f67a79d45de9ada47be81ce17e6c2f448b3c64765af93f6829c9", + "sha256:796edbd1182cbffa7e1e7a97f1e141f875a8501ba8dd834269ae3cd45a8c976f", + "sha256:934e6243df7165aad097572abf5b6003c77c9b6c480c3c4de6f2ef1b5fdd4ec0", + "sha256:bab9d848dbf1517bc58d1f486772e99919b19efef5dd8596d4b26f9f5ee08b6b", + "sha256:c1fe1e6cdaa53f11f088b7470c2056c0df7d80ee4858dadf6cbe433fcba4323b", + "sha256:e5b8aeca9276a3a988caebe9f08366ed519fff98f77c6df5b64d7603d0e42e36", + "sha256:ec6bd0a6a58df3628ff269978f4a4b924a0d371ad8ce1f8e2b635b99e482877a" + ], + "index": "pypi", + "version": "==3.1.1" + }, + "mccabe": { + "hashes": [ + "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", + "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + ], + "version": "==0.6.1" + }, + "mistune": { + "hashes": [ + "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e", + "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4" + ], + "version": "==0.8.4" + }, + "mock": { + "hashes": [ + "sha256:83657d894c90d5681d62155c82bda9c1187827525880eda8ff5df4ec813437c3", + "sha256:d157e52d4e5b938c550f39eb2fd15610db062441a9c2747d3dbfa9298211d0f8" + ], + "index": "pypi", + "version": "==3.0.5" + }, + "monotonic": { + "hashes": [ + "sha256:23953d55076df038541e648a53676fb24980f7a1be290cdda21300b3bc21dfb0", + "sha256:552a91f381532e33cbd07c6a2655a21908088962bb8fa7239ecbcc6ad1140cc7" + ], + "version": "==1.5" + }, + "more-itertools": { + "hashes": [ + "sha256:409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832", + "sha256:92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4" + ], + "markers": "python_version >= '3.4'", + "version": "==7.2.0" + }, + "mpld3": { + "hashes": [ + "sha256:4d455884a211bf99b37ecc760759435c7bb6a5955de47d8daf4967e301878ab7" + ], + "index": "pypi", + "version": "==0.3" + }, + "msgpack-python": { + "hashes": [ + "sha256:378cc8a6d3545b532dfd149da715abae4fda2a3adb6d74e525d0d5e51f46909b" + ], + "index": "pypi", + "version": "==0.5.6" + }, + "nbconvert": { + "hashes": [ + "sha256:427a468ec26e7d68a529b95f578d5cbf018cb4c1f889e897681c2b6d11897695", + "sha256:48d3c342057a2cf21e8df820d49ff27ab9f25fc72b8f15606bd47967333b2709" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==5.6.0" + }, + "nbformat": { + "hashes": [ + "sha256:b9a0dbdbd45bb034f4f8893cafd6f652ea08c8c1674ba83f2dc55d3955743b0b", + "sha256:f7494ef0df60766b7cabe0a3651556345a963b74dbc16bc7c18479041170d402" + ], + "version": "==4.4.0" + }, + "nbstripout": { + "hashes": [ + "sha256:1960caf7d1c1e281126c6c5cb98053db89eca8aaa616b58eed381e3e1508c0f4", + "sha256:d35c553f724d3fb7ec9e9602c6e55a75101064a6bbec4f8c28e8c84d6e3dd060" + ], + "index": "pypi", + "version": "==0.3.6" + }, + "networkx": { + "hashes": [ + "sha256:cdfbf698749a5014bf2ed9db4a07a5295df1d3a53bf80bf3cbd61edf9df05fa1", + "sha256:f8f4ff0b6f96e4f9b16af6b84622597b5334bf9cae8cf9b2e42e7985d5c95c64" + ], + "index": "pypi", + "version": "==2.4" + }, + "nose": { + "hashes": [ + "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac", + "sha256:dadcddc0aefbf99eea214e0f1232b94f2fa9bd98fa8353711dacb112bfcbbb2a", + "sha256:f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" + ], + "index": "pypi", + "version": "==1.3.7" + }, + "nose-parameterized": { + "hashes": [ + "sha256:8f519b9739ac67e3d95f69c15cc80416eea4d63559530d01a37b9565eb629277", + "sha256:d35e677aba2f15135b6b7ea7feb88f792b899492ba5365ec0e269015df5214ce" + ], + "index": "pypi", + "version": "==0.6.0" + }, + "notebook": { + "hashes": [ + "sha256:660976fe4fe45c7aa55e04bf4bccb9f9566749ff637e9020af3422f9921f9a5d", + "sha256:b0a290f5cc7792d50a21bec62b3c221dd820bf00efa916ce9aeec4b5354bde20" + ], + "markers": "python_version >= '3.5'", + "version": "==6.0.1" + }, + "numpy": { + "hashes": [ + "sha256:0b0dd8f47fb177d00fa6ef2d58783c4f41ad3126b139c91dd2f7c4b3fdf5e9a5", + "sha256:25ffe71f96878e1da7e014467e19e7db90ae7d4e12affbc73101bcf61785214e", + "sha256:26efd7f7d755e6ca966a5c0ac5a930a87dbbaab1c51716ac26a38f42ecc9bc4b", + "sha256:28b1180c758abf34a5c3fea76fcee66a87def1656724c42bb14a6f9717a5bdf7", + "sha256:2e418f0a59473dac424f888dd57e85f77502a593b207809211c76e5396ae4f5c", + "sha256:30c84e3a62cfcb9e3066f25226e131451312a044f1fe2040e69ce792cb7de418", + "sha256:4650d94bb9c947151737ee022b934b7d9a845a7c76e476f3e460f09a0c8c6f39", + "sha256:4dd830a11e8724c9c9379feed1d1be43113f8bcce55f47ea7186d3946769ce26", + "sha256:4f2a2b279efde194877aff1f76cf61c68e840db242a5c7169f1ff0fd59a2b1e2", + "sha256:62d22566b3e3428dfc9ec972014c38ed9a4db4f8969c78f5414012ccd80a149e", + "sha256:669795516d62f38845c7033679c648903200980d68935baaa17ac5c7ae03ae0c", + "sha256:75fcd60d682db3e1f8fbe2b8b0c6761937ad56d01c1dc73edf4ef2748d5b6bc4", + "sha256:9395b0a41e8b7e9a284e3be7060db9d14ad80273841c952c83a5afc241d2bd98", + "sha256:9e37c35fc4e9410093b04a77d11a34c64bf658565e30df7cbe882056088a91c1", + "sha256:a0678793096205a4d784bd99f32803ba8100f639cf3b932dc63b21621390ea7e", + "sha256:b46554ad4dafb2927f88de5a1d207398c5385edbb5c84d30b3ef187c4a3894d8", + "sha256:c867eeccd934920a800f65c6068acdd6b87e80d45cd8c8beefff783b23cdc462", + "sha256:dd0667f5be56fb1b570154c2c0516a528e02d50da121bbbb2cbb0b6f87f59bc2", + "sha256:de2b1c20494bdf47f0160bd88ed05f5e48ae5dc336b8de7cfade71abcc95c0b9", + "sha256:f1df7b2b7740dd777571c732f98adb5aad5450aee32772f1b39249c8a50386f6", + "sha256:ffca69e29079f7880c5392bf675eb8b4146479d976ae1924d01cd92b04cccbcc" + ], + "index": "pypi", + "version": "==1.17.3" + }, + "opencv-python": { + "hashes": [ + "sha256:0495e9247fbbd5d88346bb4d480df27fb4000aa4799b5a15b1735968a94a5189", + "sha256:078e8ea34d06b3fa459c58a6ce966ef715cc2e913b7bd96a46beb345975aa5d6", + "sha256:0dbbd0348c8282d4e3cf472a8e2a17785f05c22a55647253fa00b539897f8fcc", + "sha256:1b302b4721ca2d55ae7e9e80acebd73499c16a82be9bebc563a7937dbd348b2d", + "sha256:1f035595ef2f296c234c2b8b9659162646b9312afd0cec7ab0217bad915ff068", + "sha256:1f7fa5433c26c637cf923c59025df12fcd56b2d205da178c7ad6954e6e50912e", + "sha256:20bd10b6f6f5de1a5e796900ab77ea57366139290f426d2039d3919d8ddf9f1c", + "sha256:2306ddd98aa52688c9667f8080349d653d465a2b838cbacb19561286046ba1e8", + "sha256:31945ea9e7324c41be925f2b21fcb523844b2399dc649010f3a3e97825dcfcd0", + "sha256:36680744ebdc66a9da0a65f1f33ec9cf5d26a98749c5701dc612b334b213997d", + "sha256:409e3a4c925accd68a5ab1cef21dd04b957c0ee2985db8f075a808dccd6e0f73", + "sha256:440a093dda50daf093d73aae2dd333c9e4a593cfe7df8cbc298b421d313e263f", + "sha256:4b0465c3df9dea074583b6b4f8cf22e5902c5c5ec213a479c6c834a8a0191cf7", + "sha256:4b5902b647e66addfa5218dbc75e7a4de2f46c253ea17b234408f5792cfc8d7f", + "sha256:4f0a5c098aad4df88ce7dc3828a857921368635e3a961e80431e60f3522a99be", + "sha256:6df586230f9146afde5b8e2f4511978f8fb6172bf0f47ba290423979baae974d", + "sha256:6e4fee2ee2bc4d911dad78e2b167da97796879aaade4be3ff42ff1993e250b15", + "sha256:70f3c6fe31af7c00c60cb91bb7351837ba6c7b3d173b855ca5dbe265b90a1606", + "sha256:78390d93834b6b7c9d9234dba68ba9c34a966f60e519efd2691e5c367dee7f8e", + "sha256:81519bba8560c68f587482c157a74cf04d5a2877d4367377d2671e66eb7a3961", + "sha256:87beeb6ad4ffcd6fbfbb464a8a75c7a1389a0642cc632ecceb504c86139567e3", + "sha256:a354096290dd57ddb2664e7b21ddb6c6c2f5297cc4d8a402ce3f6a82a24807e3", + "sha256:a4635e22637181b478d6ad337c94b596c98c16bdbae92ef90514bbf31e30ef3a", + "sha256:b23359c21c4eb84f28fbe1331723bbf1ebc34125f22480da4b16cfae989a3249", + "sha256:ba52829eafab59c5260bec012fad0e26bd05389828af0e316e278912c82dab32", + "sha256:c672596fa261766d6d0cc02377755558b92dee80a64ee8dd6f58f4e56bf7835d", + "sha256:fd6ac9a11faa5d1cbf014d059dd890ad6f0583f149e780ff7d0d3d47e68438d6" + ], + "index": "pypi", + "version": "==3.4.2.17" + }, + "opt-einsum": { + "hashes": [ + "sha256:edfada4b1d0b3b782ace8bc14e80618ff629abf53143e1e6bbf9bd00b11ece77" + ], + "markers": "python_version >= '3.5'", + "version": "==3.1.0" + }, + "osmium": { + "hashes": [ + "sha256:0178bc3dd46fd304b0a22a951df1a116d37bb0d4869bbe6c566ce1abf39be7e5", + "sha256:07f6315af25fb496125d140151e317de0486ddc20254616d2347cd5537091e07", + "sha256:090fbcf394b76c7a4e967f55977a1491efaf3276b4a27ec1262cfd13073eb497", + "sha256:0b798022ddb598ffa8c5baf979cc0fe275a9419dfdf3ca21a92ede596f99bae2", + "sha256:2170516d9c3c95432ea725ac4a0dca590fb263f80b6fc3f361a3d30eb9c41f28", + "sha256:35d9ea62e0016466eece390792644192d45dbf12c70637d293b8be408c2390cd", + "sha256:455dcd129819b1c47cfcb7c676e362c07b32dc5558bf16eddd0333f8899e331e", + "sha256:5545722ce2ead2c1e634ef23e26b694fe06f5768006195762f14ab6496fb72ed", + "sha256:68d8a9bab38657362d55ec0c2878acc40a74f4602e263c1c3b75bdfe8135c59c", + "sha256:69fd3f0da9ecb3a041075bd84702ef9237c67c09f1a0b6defb00bbb727249259", + "sha256:712910c5472726bb62a6e043179697e0a52ebb09b7e4e23dbf4a8d0e31c90e11", + "sha256:82d84dbfe437546aad4e427d9b667eb4575b35100e8ff60fd1f0752522126211", + "sha256:8475e8dc2186d0817b0254e35f502582592b8b44cd0a9478cbecd6602791ff50", + "sha256:851491cddb07e7cf25b74a29e7ceca9c0eac74c45d0a033e6085820e830e1f32", + "sha256:8ae2ce116bec61b2e51b181f61214fba06ec25ccd4d51cb42386b8b4b73ccd91", + "sha256:8ea713709267a461eaf2c6544f4fe358312558e7448480f5fd0c3fef023e996d", + "sha256:b7f774794fac9df16ad745035aa61e28a00c5a75bed3483fa77f67e34dc61920", + "sha256:bb40e3e468b47e01f759a1c5de9e5429224ca6b8fe09f690c169480afc7ea840", + "sha256:bc67305d09f391d735883efea870c37a3aa2dabf32530026a409eb506b52a2f0", + "sha256:bef1b37772b39a438c5b2e65dbc1f3417ef2a8ade829ef1f6f0179431c5bcb7c", + "sha256:df9bded041a099a72bc3bfb3732df93c36f96801c2706721d1d8623419e64321", + "sha256:e0d4a1049a5bf8445c6e8c6cbc8f247795322870a32ca63f5fdec24cbcc973c2" + ], + "index": "pypi", + "version": "==2.15.3" + }, + "pandas": { + "hashes": [ + "sha256:0f484f43658a72e7d586a74978259657839b5bd31b903e963bb1b1491ab51775", + "sha256:0ffc6f9e20e77f3a7dc8baaad9c7fd25b858b084d3a2d8ce877bc3ea804e0636", + "sha256:23e0eac646419c3057f15eb96ab821964848607bf1d4ea5a82f26565986ec5e9", + "sha256:27c0603b15b5c6fa24885253bbe49a0c289381e7759385c59308ba4f0b166cf1", + "sha256:397fe360643fffc5b26b41efdf608647e3334a618d185a07976cd2dc51c90bce", + "sha256:3dbb3aa41c01504255bff2bd56944bdb915f6c9ce4bac7e2868efbace0b2a639", + "sha256:4e07c63247c59d61c6ebdbbb50196143cec6c5044403510c4e1a9d31854a83d6", + "sha256:4fa6d9235c6d2fecbeca82c3d326abd255866cafbfd37f66a0e826544e619760", + "sha256:56cb88b3876363d410a9d7724f43641ff164e2c9902d3266a648213e2efd5e6d", + "sha256:7ce1be1614455f83710b9a5dc1fc602a755bdddbe4dda1d41515062923a37bbf", + "sha256:ae1c96ffdeec376895e533107e0b0f9da16225a2184fbb24a5abc866769db75e", + "sha256:b6f27c9231be8a23de846f2302373991467dd8e397a4804d2614e8c5aa8d5a90", + "sha256:c6056067f894f9355bedcd168dd740aa849908d41c0a74756f6e38f203e941b3", + "sha256:ca91a19d1f0a280874a24dca44aadce42da7f3a7edb7e9ab7c7baad8febee2be", + "sha256:cbe4985f5c82a173f8cff6b7fe92d551addf99fb4ea9ff4eb4b1fe606bb098ec", + "sha256:e3e9893bfe80a8b8e6d56d36ebb7afe1df77db7b4068a6e2ef3636a91f6f1caa", + "sha256:e7b218e8711910dac3fed0d19376cd1ef0e386be5175965d332fd0c65d02a43b", + "sha256:ec48d18b8b63a5dbb838e8ea7892ee1034299e03f852bd9b6dffe870310414dd", + "sha256:f4ab6280277e3208a59bfa9f2e51240304d09e69ffb65abfb4a21d678b495f74" + ], + "markers": "python_version >= '3.5.3'", + "version": "==0.25.2" + }, + "pandocfilters": { + "hashes": [ + "sha256:b3dd70e169bb5449e6bc6ff96aea89c5eea8c5f6ab5e207fc2f521a2cf4a0da9" + ], + "version": "==1.4.2" + }, + "parso": { + "hashes": [ + "sha256:63854233e1fadb5da97f2744b6b24346d2750b85965e7e399bec1620232797dc", + "sha256:666b0ee4a7a1220f65d367617f2cd3ffddff3e205f3f16a0284df30e774c2a9c" + ], + "version": "==0.5.1" + }, + "pbr": { + "hashes": [ + "sha256:2c8e420cd4ed4cec4e7999ee47409e876af575d4c35a45840d59e8b5f3155ab8", + "sha256:b32c8ccaac7b1a20c0ce00ce317642e6cf231cf038f9875e0280e28af5bf7ac9" + ], + "index": "pypi", + "version": "==5.4.3" + }, + "percache": { + "hashes": [ + "sha256:b60043937aece6d154ccd1fd7380fc01ea482335716c2bd41efb85b097bc88df" + ], + "index": "pypi", + "version": "==0.3.0" + }, + "pexpect": { + "hashes": [ + "sha256:2094eefdfcf37a1fdbfb9aa090862c1a4878e5c7e0e7e7088bdb511c558e5cd1", + "sha256:9e2c1fd0e6ee3a49b28f95d4b33bc389c89b20af6a1255906e90ff1262ce62eb" + ], + "markers": "sys_platform != 'win32'", + "version": "==4.7.0" + }, + "pickleshare": { + "hashes": [ + "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca", + "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56" + ], + "version": "==0.7.5" + }, + "pillow": { + "hashes": [ + "sha256:047d9473cf68af50ac85f8ee5d5f21a60f849bc17d348da7fc85711287a75031", + "sha256:0f66dc6c8a3cc319561a633b6aa82c44107f12594643efa37210d8c924fc1c71", + "sha256:12c9169c4e8fe0a7329e8658c7e488001f6b4c8e88740e76292c2b857af2e94c", + "sha256:248cffc168896982f125f5c13e9317c059f74fffdb4152893339f3be62a01340", + "sha256:27faf0552bf8c260a5cee21a76e031acaea68babb64daf7e8f2e2540745082aa", + "sha256:285edafad9bc60d96978ed24d77cdc0b91dace88e5da8c548ba5937c425bca8b", + "sha256:384b12c9aa8ef95558abdcb50aada56d74bc7cc131dd62d28c2d0e4d3aadd573", + "sha256:38950b3a707f6cef09cd3cbb142474357ad1a985ceb44d921bdf7b4647b3e13e", + "sha256:4aad1b88933fd6dc2846552b89ad0c74ddbba2f0884e2c162aa368374bf5abab", + "sha256:4ac6148008c169603070c092e81f88738f1a0c511e07bd2bb0f9ef542d375da9", + "sha256:4deb1d2a45861ae6f0b12ea0a786a03d19d29edcc7e05775b85ec2877cb54c5e", + "sha256:59aa2c124df72cc75ed72c8d6005c442d4685691a30c55321e00ed915ad1a291", + "sha256:5a47d2123a9ec86660fe0e8d0ebf0aa6bc6a17edc63f338b73ea20ba11713f12", + "sha256:5cc901c2ab9409b4b7ac7b5bcc3e86ac14548627062463da0af3b6b7c555a871", + "sha256:6c1db03e8dff7b9f955a0fb9907eb9ca5da75b5ce056c0c93d33100a35050281", + "sha256:7ce80c0a65a6ea90ef9c1f63c8593fcd2929448613fc8da0adf3e6bfad669d08", + "sha256:809c19241c14433c5d6135e1b6c72da4e3b56d5c865ad5736ab99af8896b8f41", + "sha256:83792cb4e0b5af480588601467c0764242b9a483caea71ef12d22a0d0d6bdce2", + "sha256:846fa202bd7ee0f6215c897a1d33238ef071b50766339186687bd9b7a6d26ac5", + "sha256:9f5529fc02009f96ba95bea48870173426879dc19eec49ca8e08cd63ecd82ddb", + "sha256:a423c2ea001c6265ed28700df056f75e26215fd28c001e93ef4380b0f05f9547", + "sha256:ac4428094b42907aba5879c7c000d01c8278d451a3b7cccd2103e21f6397ea75", + "sha256:b1ae48d87f10d1384e5beecd169c77502fcc04a2c00a4c02b85f0a94b419e5f9", + "sha256:bf4e972a88f8841d8fdc6db1a75e0f8d763e66e3754b03006cbc3854d89f1cb1", + "sha256:c6414f6aad598364aaf81068cabb077894eb88fed99c6a65e6e8217bab62ae7a", + "sha256:c710fcb7ee32f67baf25aa9ffede4795fd5d93b163ce95fdc724383e38c9df96", + "sha256:c7be4b8a09852291c3c48d3c25d1b876d2494a0a674980089ac9d5e0d78bd132", + "sha256:c9e5ffb910b14f090ac9c38599063e354887a5f6d7e6d26795e916b4514f2c1a", + "sha256:e0697b826da6c2472bb6488db4c0a7fa8af0d52fa08833ceb3681358914b14e5", + "sha256:e9a3edd5f714229d41057d56ac0f39ad9bdba6767e8c888c951869f0bdd129b0" + ], + "index": "pypi", + "version": "==6.2.1" + }, + "pprofile": { + "hashes": [ + "sha256:3469102f462f9fc2d889970afcf73d89c0d89a36c49a4c262c3edc302b4a22da" + ], + "index": "pypi", + "version": "==2.0.2" + }, + "prometheus-client": { + "hashes": [ + "sha256:71cd24a2b3eb335cb800c7159f423df1bd4dcd5171b234be15e3f31ec9f622da" + ], + "version": "==0.7.1" + }, + "prompt-toolkit": { + "hashes": [ + "sha256:46642344ce457641f28fc9d1c9ca939b63dadf8df128b86f1b9860e59c73a5e4", + "sha256:e7f8af9e3d70f514373bf41aa51bc33af12a6db3f71461ea47fea985defb2c31", + "sha256:f15af68f66e664eaa559d4ac8a928111eebd5feda0c11738b5998045224829db" + ], + "version": "==2.0.10" + }, + "protobuf": { + "hashes": [ + "sha256:125713564d8cfed7610e52444c9769b8dcb0b55e25cc7841f2290ee7bc86636f", + "sha256:1accdb7a47e51503be64d9a57543964ba674edac103215576399d2d0e34eac77", + "sha256:27003d12d4f68e3cbea9eb67427cab3bfddd47ff90670cb367fcd7a3a89b9657", + "sha256:3264f3c431a631b0b31e9db2ae8c927b79fc1a7b1b06b31e8e5bcf2af91fe896", + "sha256:3c5ab0f5c71ca5af27143e60613729e3488bb45f6d3f143dc918a20af8bab0bf", + "sha256:45dcf8758873e3f69feab075e5f3177270739f146255225474ee0b90429adef6", + "sha256:56a77d61a91186cc5676d8e11b36a5feb513873e4ae88d2ee5cf530d52bbcd3b", + "sha256:5984e4947bbcef5bd849d6244aec507d31786f2dd3344139adc1489fb403b300", + "sha256:6b0441da73796dd00821763bb4119674eaf252776beb50ae3883bed179a60b2a", + "sha256:6f6677c5ade94d4fe75a912926d6796d5c71a2a90c2aeefe0d6f211d75c74789", + "sha256:84a825a9418d7196e2acc48f8746cf1ee75877ed2f30433ab92a133f3eaf8fbe", + "sha256:b842c34fe043ccf78b4a6cf1019d7b80113707d68c88842d061fa2b8fb6ddedc", + "sha256:ca33d2f09dae149a1dcf942d2d825ebb06343b77b437198c9e2ef115cf5d5bc1", + "sha256:cc9af00df3fc9302f537a8335668c20be27916b2277e9a5eaed510266e2bb33b", + "sha256:db83b5c12c0cd30150bb568e6feb2435c49ce4e68fe2d7b903113f0e221e58fe", + "sha256:f50f3b1c5c1c1334ca7ce9cad5992f098f460ffd6388a3cabad10b66c2006b09", + "sha256:f99f127909731cafb841c52f9216e447d3e4afb99b17bebfad327a75aee206de" + ], + "version": "==3.10.0" + }, + "psutil": { + "hashes": [ + "sha256:028a1ec3c6197eadd11e7b46e8cc2f0720dc18ac6d7aabdb8e8c0d6c9704f000", + "sha256:12542c3642909f4cd1928a2fba59e16fa27e47cbeea60928ebb62a8cbd1ce123", + "sha256:503e4b20fa9d3342bcf58191bbc20a4a5ef79ca7df8972e6197cc14c5513e73d", + "sha256:863a85c1c0a5103a12c05a35e59d336e1d665747e531256e061213e2e90f63f3", + "sha256:954f782608bfef9ae9f78e660e065bd8ffcfaea780f9f2c8a133bb7cb9e826d7", + "sha256:b6e08f965a305cd84c2d07409bc16fbef4417d67b70c53b299116c5b895e3f45", + "sha256:bc96d437dfbb8865fc8828cf363450001cb04056bbdcdd6fc152c436c8a74c61", + "sha256:cf49178021075d47c61c03c0229ac0c60d5e2830f8cab19e2d88e579b18cdb76", + "sha256:d5350cb66690915d60f8b233180f1e49938756fb2d501c93c44f8fb5b970cc63", + "sha256:eba238cf1989dfff7d483c029acb0ac4fcbfc15de295d682901f0e2497e6781a" + ], + "index": "pypi", + "version": "==5.6.3" + }, + "ptyprocess": { + "hashes": [ + "sha256:923f299cc5ad920c68f2bc0bc98b75b9f838b93b599941a6b63ddbc2476394c0", + "sha256:d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f" + ], + "markers": "os_name != 'nt'", + "version": "==0.6.0" + }, + "pycocotools": { + "git": "https://github.com/cocodataset/cocoapi.git", + "ref": "636becdc73d54283b3aac6d4ec363cffbb6f9b20", + "subdirectory": "PythonAPI", + "version": "==2.0" + }, + "pycparser": { + "hashes": [ + "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3" + ], + "version": "==2.19" + }, + "pycurl": { + "hashes": [ + "sha256:6f08330c5cf79fa8ef68b9912b9901db7ffd34b63e225dce74db56bb21deda8e" + ], + "index": "pypi", + "version": "==7.43.0.3" + }, + "pygame": { + "hashes": [ + "sha256:0480fe82cd41a43e3eea497fa2c059c72ac54cb5d003d5aa2ed06a04541c384e", + "sha256:136a3b5711d9ec369a0407e4e08ffced3ba61aa41059e9280ffffa79c8614f65", + "sha256:2622b9dd95f445c887a36a57eade42c672598589f69a8052ccdb8eeeffa4dbb1", + "sha256:301c6428c0880ecd4a9e3951b80e539c33863b6ff356a443db1758de4f297957", + "sha256:398c42b605ecc514e62f68f1944a2d21e247938309f598de6cb0ad3c207324a8", + "sha256:4aaff572a273a32e70ec3593d213e59ab11c183a9916616562247930f17a5447", + "sha256:4e1065577f1b29111113be5deb2ea88553551a5e1cf33e0c08fa32768f285809", + "sha256:5f052dc2975a399aa1830c1f04c5f72856aa416bf3cd4b31375a058015a5c620", + "sha256:68ea43e51150316b9fb08e251209d4e2b4e76a340b5b6fc8cdf1a898c78f7e5b", + "sha256:698433a9fcefca0527244dc44dff9503eb26157494730b1cc80e6e4dbb246e92", + "sha256:6f714986f7987f10cb94f1be0753318e341a7ea6b12d66f37a4d5d6dd4695023", + "sha256:73cd9df328c7e72638dbcc1d18e7155225faed880a53db6bad90d1d7c0a71dfd", + "sha256:7876d1f29f66d3d7cac46479503891ee1ef409b0fbce54b0d74f3a6b33a46dba", + "sha256:854e87b8b2b76e3ed11d64985fcfdd7af919659503de99fc2b0a717b314c3cf0", + "sha256:8da13704ad45b7d5de8a8cca135a7f44c7fc6aa9f691abe7b0392468a34a8013", + "sha256:9ce22fb72298ea33dbb3a1c6c60a4a4e19d9698df6f3f5782eba4dada7b7736d", + "sha256:a37b6c59e7b8feadc51db5197052b86ceb6443f9fb2a6f7d6527620e707c558c", + "sha256:a6e8d2f99dbe1dfe72d0c019693c14d93c410f702d0b04ec9a81b36dacd55a23", + "sha256:a9ac862dd7159861f2c6443b0029089e1c0c4ec762a8074022914ec52fe4dfac", + "sha256:ae1bc3e78ed28f20878e7ca2c98663a6634e9c00d7746d39413fc18e907dc162", + "sha256:be7e70f91bd4eb35ae081062f16bf434619b3292358d9b061f8159ddc570c7f0", + "sha256:c895cf9c1b6d1cbba8cb8cc3f5427febcf8aa41a9333697741abeea1c537a350", + "sha256:f1f5714d2c23f6a64ef2ac4fcd36a2dd2689da85978d951a99a6ae5dfdf9bdbc", + "sha256:fa788f775680fc5d268ab00a2da29c9a22830032cfab732730298a2952cd87f3" + ], + "index": "pypi", + "version": "==1.9.6" + }, + "pygments": { + "hashes": [ + "sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127", + "sha256:881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297" + ], + "index": "pypi", + "version": "==2.4.2" + }, + "pyjwt": { + "hashes": [ + "sha256:5c6eca3c2940464d106b99ba83b00c6add741c9becaec087fb7ccdefea71350e", + "sha256:8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96" + ], + "index": "pypi", + "version": "==1.7.1" + }, + "pylint": { + "hashes": [ + "sha256:7b76045426c650d2b0f02fc47c14d7934d17898779da95288a74c2a7ec440702", + "sha256:856476331f3e26598017290fd65bebe81c960e806776f324093a46b76fb2d1c0" + ], + "index": "pypi", + "version": "==2.4.3" + }, + "pylogbeat": { + "hashes": [ + "sha256:11f3b1d04424151d406d8b844a8db6299442b4af1f10d5f622a6febf1ad5c41d", + "sha256:473494a0c798a560a8312ee662b333888181cf4db18cd8f87a8d7d1548beefd9" + ], + "version": "==1.0.2" + }, + "pymongo": { + "hashes": [ + "sha256:09f8196e1cb081713aa3face08d1806dc0a5dd64cb9f67fefc568519253a7ff2", + "sha256:1be549c0ce2ba8242c149156ae2064b12a5d4704448d49f630b4910606efd474", + "sha256:1f9fe869e289210250cba4ea20fbd169905b1793e1cd2737f423e107061afa98", + "sha256:3653cea82d1e35edd0a2355150daf8a27ebf12cf55182d5ad1046bfa288f5140", + "sha256:4249c6ba45587b959292a727532826c5032d59171f923f7f823788f413c2a5a3", + "sha256:4ff8f5e7c0a78983c1ee07894fff1b21c0e0ad3a122d9786cc3745fd60e4a2ce", + "sha256:56b29c638ab924716b48a3e94e3d7ac00b04acec1daa8190c36d61fc714c3629", + "sha256:56ec9358bbfe5ae3b25e785f8a14619d6799c855a44734c9098bb457174019bf", + "sha256:5b59bbde4eb417f3f9379f7b1a9de3669894f2bae9de933a836e2bffea2bbfa1", + "sha256:5dca250cbf1183c3e7b7b18c882c2b2199bfb20c74c4c68dbf11596808a296da", + "sha256:61101d1cc92881fac1f9ac7e99b033062f4c210178dc33193c8f5567feecb069", + "sha256:7b4aea184e4868ebd4f9f786ffee14a1121bda5436ad04f6bcbacfa2147f8386", + "sha256:86624c0205a403fb4fbfedef79c5b4ab27e21fd018fdb6a27cf03b3c32a9e2b9", + "sha256:88ac09e1b197c3b4531e43054d49c022a3ea1281431b2f4980abafa35d2a5ce2", + "sha256:8b0339809b12ea292d468524dd1777f1a9637d9bdc0353a9261b88f82537d606", + "sha256:93dbf7388f6bf9af48dbb32f265b75b3dbc743a7a2ce98e44c88c049c58d85d3", + "sha256:9b705daec636c560dd2d63935f428a6b3cddfe903fffc0f349e0e91007c893d6", + "sha256:a090a819fe6fefadc2901d3911c07c76c0935ec5c790a50e9f3c3c47bacd5978", + "sha256:a102b346f1921237eaa9a31ee89eda57ad3c3973d79be3a456d92524e7df8fec", + "sha256:a13363869f2f36291d6367069c65d51d7b8d1b2fb410266b0b6b1f3c90d6deb0", + "sha256:a409a43c76da50881b70cc9ee70a1744f882848e8e93a68fb434254379777fa3", + "sha256:a76475834a978058425b0163f1bad35a5f70e45929a543075633c3fc1df564c5", + "sha256:ad474e93525baa6c58d75d63a73143af24c9f93c8e26e8d382f32c4da637901a", + "sha256:b268c7fa03ac77a8662fab3b2ab0be4beecb82f60f4c24b584e69565691a107f", + "sha256:b67ec339b180acdbebcd03807ae4b1764a43e7069340fe860a60ac310b9d38be", + "sha256:cca4e1ab5ba0cd7877d3938167ee8ae9c2986cc0e10d3dcc3243d664d3a83fec", + "sha256:cef61de3f0f4441ec40266ff2ab42e5c16eaba1dc1fc6e1036f274621c52adc1", + "sha256:e28153b5d5ca33d4ba0c3bbc0e1ff161b9016e5e5f3f8ca10d6fa49106eb9e04", + "sha256:f30d7b37804daf0bab1143abc71666c630d7e270f5c14c5a7c300a6699c21108", + "sha256:f70f0133301cccf9bfd68fd20f67184ef991be578b646e78441106f9e27cc44d", + "sha256:fa75c21c1d82f20cce62f6fc4a68c2b0f33572ab406df1b17cd77a947d0b2993" + ], + "index": "pypi", + "version": "==3.9.0" + }, + "pymysql": { + "hashes": [ + "sha256:95f057328357e0e13a30e67857a8c694878b0175797a9a203ee7adbfb9b1ec5f", + "sha256:9ec760cbb251c158c19d6c88c17ca00a8632bac713890e465b2be01fdc30713f" + ], + "index": "pypi", + "version": "==0.9.2" + }, + "pynacl": { + "hashes": [ + "sha256:05c26f93964373fc0abe332676cb6735f0ecad27711035b9472751faa8521255", + "sha256:0c6100edd16fefd1557da078c7a31e7b7d7a52ce39fdca2bec29d4f7b6e7600c", + "sha256:0d0a8171a68edf51add1e73d2159c4bc19fc0718e79dec51166e940856c2f28e", + "sha256:1c780712b206317a746ace34c209b8c29dbfd841dfbc02aa27f2084dd3db77ae", + "sha256:2424c8b9f41aa65bbdbd7a64e73a7450ebb4aa9ddedc6a081e7afcc4c97f7621", + "sha256:2d23c04e8d709444220557ae48ed01f3f1086439f12dbf11976e849a4926db56", + "sha256:30f36a9c70450c7878053fa1344aca0145fd47d845270b43a7ee9192a051bf39", + "sha256:37aa336a317209f1bb099ad177fef0da45be36a2aa664507c5d72015f956c310", + "sha256:4943decfc5b905748f0756fdd99d4f9498d7064815c4cf3643820c9028b711d1", + "sha256:53126cd91356342dcae7e209f840212a58dcf1177ad52c1d938d428eebc9fee5", + "sha256:57ef38a65056e7800859e5ba9e6091053cd06e1038983016effaffe0efcd594a", + "sha256:5bd61e9b44c543016ce1f6aef48606280e45f892a928ca7068fba30021e9b786", + "sha256:6482d3017a0c0327a49dddc8bd1074cc730d45db2ccb09c3bac1f8f32d1eb61b", + "sha256:7d3ce02c0784b7cbcc771a2da6ea51f87e8716004512493a2b69016326301c3b", + "sha256:a14e499c0f5955dcc3991f785f3f8e2130ed504fa3a7f44009ff458ad6bdd17f", + "sha256:a39f54ccbcd2757d1d63b0ec00a00980c0b382c62865b61a505163943624ab20", + "sha256:aabb0c5232910a20eec8563503c153a8e78bbf5459490c49ab31f6adf3f3a415", + "sha256:bd4ecb473a96ad0f90c20acba4f0bf0df91a4e03a1f4dd6a4bdc9ca75aa3a715", + "sha256:bf459128feb543cfca16a95f8da31e2e65e4c5257d2f3dfa8c0c1031139c9c92", + "sha256:e2da3c13307eac601f3de04887624939aca8ee3c9488a0bb0eca4fb9401fc6b1", + "sha256:f67814c38162f4deb31f68d590771a29d5ae3b1bd64b75cf232308e5c74777e0" + ], + "index": "pypi", + "version": "==1.3.0" + }, + "pynmea2": { + "hashes": [ + "sha256:8b83fa7e3e668af5e182ef1c2fd4a535433ecadf60d7b627280172d695a1646b", + "sha256:fe786594299588d1bfbd346ece2c2c1e5b24e160dcb740813c34bfa70d0a141d" + ], + "index": "pypi", + "version": "==1.15.0" + }, + "pyparsing": { + "hashes": [ + "sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80", + "sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.4.2" + }, + "pypolyline": { + "hashes": [ + "sha256:09cc2192bc12063c7afa2d2718b739cd4bf3f8ec29eacde0cb728c9f5f7f7858", + "sha256:21acee0e31d867bde04583907ccb7afe4b21d33a63c23adc7cf0d82b6f2feab3", + "sha256:5e0643454b4471f4f23d38530467ee7093d3b375898d5e1b054876e5a50a6b89", + "sha256:6b0a1b573fe84c9ed0aa3a4eb9903d44864f37e405cdcc7396b61e6d00a937d6", + "sha256:6bdbc9210f29d4fd44c3e4d510ffcc1276e46a50d63365831e2e422dc0b3cb43", + "sha256:8efb93097c92c5894dcaf9e784b888f9426d170ae51d62164341bbb2b832c09a", + "sha256:9c843a35b2d02b04c1226db851834b55f0de30eef47ba057fd6f8623cdef6f2d", + "sha256:ad01fedf427536f391776b329c95e5f80f2b1a5d25c54ea7713c8cdb56947106", + "sha256:e4e4c857790f6a3067dab3ae661edda99d5cee55d107b3b4d0186159431165ef", + "sha256:f8c84f0d2aa6bd9ed14bdb671fab80f79b4ba93b4347b530ae4d3b56a3fb269a" + ], + "index": "pypi", + "version": "==0.1.17" + }, + "pyproj": { + "hashes": [ + "sha256:0f3b3280ae59c74212841c38d1df055537b4e83cbfcda4072ba6b0eeefd0b98a", + "sha256:36ad4ff82f38cdc7738da81289ec4309263ad40f3d62cb75eeef22bb70178698", + "sha256:4a26485f09052722deaa1ddc6b3133d41bd982be5b0e64e296626e71b94ee5e6", + "sha256:4b41db92d689119b57ff6fcc3ae5a75072c86a7078cb0c25434b3ab4b79ad624", + "sha256:5d1f4f2645abd05128d29bd71eb378ff0fedb9f96147356e68b87a628863bf92", + "sha256:7c05ca74d7a3c822afd933e2efb5c599475c1cb22919500cb7df8ecb1c24d04e", + "sha256:8124fe43d81a7caca43df6930110e2bfd2bd3b82b86587eefd6f6d86a81a658e", + "sha256:8e2a8fab431bc6d16a417792198813fe6b8c53aafb51f54e1e6a52cdb377b576", + "sha256:9121e2ae3eb13d32cf2c49e456e052fe88cab200cfc07e3162cdb276427040fa", + "sha256:a8462505b4fa7e7e73ac5e69f1aa3d4a31b25e93dac80a41a2ff35d996c3f173", + "sha256:c22c52ea26d318d808bdde23e2b57b85c292747971ff79d0ea578b578ff791d6", + "sha256:d25638d48af3df03c6d3c713495d62d0b9a135032b0dddafbb7f0004d052b1f5", + "sha256:d851dd9245f60871306a49af92523a8ea8d8a60f3e522bbd8b9cd512d8b825ec", + "sha256:e27a5bec46c706a343db9b218bf13abd53f1e066668b194bd48511c1773f6c1c", + "sha256:fb151507b8793acc8c622164e3cc57d0c51f3d4790dabba1daf141a780bad68a" + ], + "index": "pypi", + "version": "==2.4.0" + }, + "pyqt5": { + "hashes": [ + "sha256:6420d8c9de8746917bd2afe24f29b3722aabde36d1e9f8c34354f5b7fb7b987d", + "sha256:73f982b60819cc6d7cb0007b8b0cd11073e2546d74e0463726149e6a9d087caa", + "sha256:8e6125f110133069e8f4a085022cfc6b4a0af5b3c9009999a749007c299e965d", + "sha256:f8e76070782e68ba200eb2b67babf89ac629df5e36d2f4c680ef34ae40c8f964" + ], + "index": "pypi", + "version": "==5.13.1" + }, + "pyqt5-sip": { + "hashes": [ + "sha256:02d94786bada670ab17a2b62ce95b3cf8e3b40c99d36007593a6334d551840bb", + "sha256:06bc66b50556fb949f14875a4c224423dbf03f972497ccb883fb19b7b7c3b346", + "sha256:091fbbe10a7aebadc0e8897a9449cda08d3c3f663460d812eca3001ca1ed3526", + "sha256:0a067ade558befe4d46335b13d8b602b5044363bfd601419b556d4ec659bca18", + "sha256:1910c1cb5a388d4e59ebb2895d7015f360f3f6eeb1700e7e33e866c53137eb9e", + "sha256:1c7ad791ec86247f35243bbbdd29cd59989afbe0ab678e0a41211f4407f21dd8", + "sha256:3c330ff1f70b3eaa6f63dce9274df996dffea82ad9726aa8e3d6cbe38e986b2f", + "sha256:482a910fa73ee0e36c258d7646ef38f8061774bbc1765a7da68c65056b573341", + "sha256:7695dfafb4f5549ce1290ae643d6508dfc2646a9003c989218be3ce42a1aa422", + "sha256:8274ed50f4ffbe91d0f4cc5454394631edfecd75dc327aa01be8bc5818a57e88", + "sha256:9047d887d97663790d811ac4e0d2e895f1bf2ecac4041691487de40c30239480", + "sha256:9f6ab1417ecfa6c1ce6ce941e0cebc03e3ec9cd9925058043229a5f003ae5e40", + "sha256:b43ba2f18999d41c3df72f590348152e14cd4f6dcea2058c734d688dfb1ec61f", + "sha256:c3ab9ea1bc3f4ce8c57ebc66fb25cd044ef92ed1ca2afa3729854ecc59658905", + "sha256:da69ba17f6ece9a85617743cb19de689f2d63025bf8001e2facee2ec9bcff18f", + "sha256:ef3c7a0bf78674b0dda86ff5809d8495019903a096c128e1f160984b37848f73", + "sha256:fabff832046643cdb93920ddaa8f77344df90768930fbe6bb33d211c4dcd0b5e" + ], + "markers": "python_version >= '3.5'", + "version": "==12.7.0" + }, + "pyrsistent": { + "hashes": [ + "sha256:34b47fa169d6006b32e99d4b3c4031f155e6e68ebcc107d6454852e8e0ee6533" + ], + "version": "==0.15.4" + }, + "pysdl2": { + "hashes": [ + "sha256:b52acab5493a77b08c2afee1f385769fc2005f17cfeaf1886eff22dc78da2123" + ], + "index": "pypi", + "version": "==0.9.6" + }, + "pysendfile": { + "hashes": [ + "sha256:510a414b270986fba3c79cb76d90a4c910c701bfb43ff983a5d4e92846050e17" + ], + "index": "pypi", + "version": "==2.0.1" + }, + "python-dateutil": { + "hashes": [ + "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", + "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" + ], + "index": "pypi", + "version": "==2.8.0" + }, + "python-engineio": { + "hashes": [ + "sha256:4a13fb87c819b855c55a731fdf82559adb8311c04cfdfebd6b9ecd1c2afbb575", + "sha256:9c9a6035b4b5e5a225f426f846afa14cf627f7571d1ae02167cb703fefd134b7" + ], + "version": "==3.10.0" + }, + "python-logstash": { + "hashes": [ + "sha256:10943e5df83f592b4d61b63ad1afff855ccc8c9467f78718f0a59809ba1fe68c" + ], + "index": "pypi", + "version": "==0.4.6" + }, + "python-logstash-async": { + "hashes": [ + "sha256:994894e8b7e168e56f21e302334c08203af102c7bc760cacdb8d3d0f5aa74cea", + "sha256:ccd528a0a9c6b7aabd9944c01d628e9d6cc2149156011aafd3484c7c0abbce45" + ], + "index": "pypi", + "version": "==1.5.1" + }, + "python-socketio": { + "hashes": [ + "sha256:506b2cf7a520b40ea0b3f25e1272eff8de134dce6f471c1f6bc0de8c90fe8c57", + "sha256:d4e2c23241afa0aae2a5bcc107523b2fcc71f5020df89a093f3634eb48955967" + ], + "version": "==4.3.1" + }, + "pytz": { + "hashes": [ + "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d", + "sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be" + ], + "version": "==2019.3" + }, + "pyvcd": { + "hashes": [ + "sha256:791fd7608fb8113c9658f699cb6292d66d7fb90bcab9ebc00b05adc40da7a5ce", + "sha256:bdcb848b79cea2196ebf317178eff2c9c7d6354b85f9eb4991e9175f98e26937" + ], + "index": "pypi", + "version": "==0.1.4" + }, + "pywavelets": { + "hashes": [ + "sha256:076ca8907001fdfe4205484f719d12b4a0262dfe6652fa1cfc3c5c362d14dc84", + "sha256:18a51b3f9416a2ae6e9a35c4af32cf520dd7895f2b69714f4aa2f4342fca47f9", + "sha256:1a64b40f6acb4ffbaccce0545d7fc641744f95351f62e4c6aaa40549326008c9", + "sha256:35959c041ec014648575085a97b498eafbbaa824f86f6e4a59bfdef8a3fe6308", + "sha256:55e39ec848ceec13c9fa1598253ae9dd5c31d09dfd48059462860d2b908fb224", + "sha256:6162dc0ae04669ea04b4b51420777b9ea2d30b0a9d02901b2a3b4d61d159c2e9", + "sha256:68b5c33741d26c827074b3d8f0251de1c3019bb9567b8d303eb093c822ce28f1", + "sha256:720dbcdd3d91c6dfead79c80bf8b00a1d8aa4e5d551dc528c6d5151e4efc3403", + "sha256:7947e51ca05489b85928af52a34fe67022ab5b81d4ae32a4109a99e883a0635e", + "sha256:79f5b54f9dc353e5ee47f0c3f02bebd2c899d49780633aa771fed43fa20b3149", + "sha256:80b924edbc012ded8aa8b91cb2fd6207fb1a9a3a377beb4049b8a07445cec6f0", + "sha256:889d4c5c5205a9c90118c1980df526857929841df33e4cd1ff1eff77c6817a65", + "sha256:935ff247b8b78bdf77647fee962b1cc208c51a7b229db30b9ba5f6da3e675178", + "sha256:98b2669c5af842a70cfab33a7043fcb5e7535a690a00cd251b44c9be0be418e5", + "sha256:9e2528823ccf5a0a1d23262dfefe5034dce89cd84e4e124dc553dfcdf63ebb92", + "sha256:bc5e87b72371da87c9bebc68e54882aada9c3114e640de180f62d5da95749cd3", + "sha256:be105382961745f88d8196bba5a69ee2c4455d87ad2a2e5d1eed6bd7fda4d3fd", + "sha256:c06d2e340c7bf8b9ec71da2284beab8519a3908eab031f4ea126e8ccfc3fd567", + "sha256:cfe79844526dd92e3ecc9490b5031fca5f8ab607e1e858feba232b1b788ff0ea", + "sha256:d510aef84d9852653d079c84f2f81a82d5d09815e625f35c95714e7364570ad4", + "sha256:e02a0558e0c2ac8b8bbe6a6ac18c136767ec56b96a321e0dfde2173adfa5a504" + ], + "markers": "python_version >= '3.5'", + "version": "==1.1.1" + }, + "pyzmq": { + "hashes": [ + "sha256:01636e95a88d60118479041c6aaaaf5419c6485b7b1d37c9c4dd424b7b9f1121", + "sha256:021dba0d1436516092c624359e5da51472b11ba8edffa334218912f7e8b65467", + "sha256:0463bd941b6aead494d4035f7eebd70035293dd6caf8425993e85ad41de13fa3", + "sha256:05fd51edd81eed798fccafdd49c936b6c166ffae7b32482e4d6d6a2e196af4e6", + "sha256:1fadc8fbdf3d22753c36d4172169d184ee6654f8d6539e7af25029643363c490", + "sha256:22efa0596cf245a78a99060fe5682c4cd00c58bb7614271129215c889062db80", + "sha256:260c70b7c018905ec3659d0f04db735ac830fe27236e43b9dc0532cf7c9873ef", + "sha256:2762c45e289732d4450406cedca35a9d4d71e449131ba2f491e0bf473e3d2ff2", + "sha256:2fc6cada8dc53521c1189596f1898d45c5f68603194d3a6453d6db4b27f4e12e", + "sha256:343b9710a61f2b167673bea1974e70b5dccfe64b5ed10626798f08c1f7227e72", + "sha256:41bf96d5f554598a0632c3ec28e3026f1d6591a50f580df38eff0b8067efb9e7", + "sha256:856b2cdf7a1e2cbb84928e1e8db0ea4018709b39804103d3a409e5584f553f57", + "sha256:85b869abc894672de9aecdf032158ea8ad01e2f0c3b09ef60e3687fb79418096", + "sha256:93f44739db69234c013a16990e43db1aa0af3cf5a4b8b377d028ff24515fbeb3", + "sha256:98fa3e75ccb22c0dc99654e3dd9ff693b956861459e8c8e8734dd6247b89eb29", + "sha256:9a22c94d2e93af8bebd4fcf5fa38830f5e3b1ff0d4424e2912b07651eb1bafb4", + "sha256:a7d3f4b4bbb5d7866ae727763268b5c15797cbd7b63ea17f3b0ec1067da8994b", + "sha256:b645a49376547b3816433a7e2d2a99135c8e651e50497e7ecac3bd126e4bea16", + "sha256:cf0765822e78cf9e45451647a346d443f66792aba906bc340f4e0ac7870c169c", + "sha256:dc398e1e047efb18bfab7a8989346c6921a847feae2cad69fedf6ca12fb99e2c", + "sha256:dd5995ae2e80044e33b5077fb4bc2b0c1788ac6feaf15a6b87a00c14b4bdd682", + "sha256:e03fe5e07e70f245dc9013a9d48ae8cc4b10c33a1968039c5a3b64b5d01d083d", + "sha256:ea09a306144dff2795e48439883349819bef2c53c0ee62a3c2fae429451843bb", + "sha256:f4e37f33da282c3c319849877e34f97f0a3acec09622ec61b7333205bdd13b52", + "sha256:fa4bad0d1d173dee3e8ef3c3eb6b2bb6c723fc7a661eeecc1ecb2fa99860dd45" + ], + "index": "pypi", + "version": "==18.1.0" + }, + "qtconsole": { + "hashes": [ + "sha256:40d5d8e00d070ea266dbf6f0da74c4b9597b8b8d67cd8233c3ffd8debf923703", + "sha256:b91e7412587e6cfe1644696538f73baf5611e837be5406633218443b2827c6d9" + ], + "version": "==4.5.5" + }, + "redis": { + "hashes": [ + "sha256:3613daad9ce5951e426f460deddd5caf469e08a3af633e9578fc77d362becf62", + "sha256:8d0fc278d3f5e1249967cba2eb4a5632d19e45ce5c09442b8422d15ee2c22cc2" + ], + "index": "pypi", + "version": "==3.3.11" + }, + "redlock": { + "hashes": [ + "sha256:b718646239d300745475a76e81d350ec523e7146cf84d696b3c4a7dfdd5dd4d4", + "sha256:ce7e6ab404882b64a9c5017c7a78b1a3714f2c712635bcb22cbb74d20719bbd1" + ], + "index": "pypi", + "version": "==1.2.0" + }, + "requests": { + "hashes": [ + "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", + "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" + ], + "index": "pypi", + "version": "==2.22.0" + }, + "reverse-geocoder": { + "hashes": [ + "sha256:2a2e781b5f69376d922b78fe8978f1350c84fce0ddb07e02c834ecf98b57c75c" + ], + "index": "pypi", + "version": "==1.5.1" + }, + "s2sphere": { + "hashes": [ + "sha256:c2478c1ff7c601a59a7151a57b605435897514578fa6bdb8730721c182adbbaf", + "sha256:d2340c9cf458ddc9a89afd1d8048a4195ce6fa6b0095ab900d4be5271e537401" + ], + "index": "pypi", + "version": "==0.2.5" + }, + "s3transfer": { + "hashes": [ + "sha256:6efc926738a3cd576c2a79725fed9afde92378aa5c6a957e3af010cb019fac9d", + "sha256:b780f2411b824cb541dbcd2c713d0cb61c7d1bcadae204cdddda2b35cef493ba" + ], + "version": "==0.2.1" + }, + "scikit-image": { + "hashes": [ + "sha256:063d1c20fcd53762f82ee58c29783ae4e8f6fbed445b41b704fa33b6f355729d", + "sha256:0808ab5f8218d91a1c008036993636535a37efd67a52ab0f2e6e3f4b7e75aeda", + "sha256:2a54bea469eb1b611bee1ce36e60710f5f94f29205bc5bd67a51793909b1e62b", + "sha256:2aa962aa82d815606d7dad7f045f5d7ca55c65b4320d47e15a98fc92612c2d6c", + "sha256:2d346d49b6852cffb47cbde995e2696d5b07f688d8c057a0a4548abf3a98f920", + "sha256:3ad2efa792ab8de5fcefe6f4f5bc1ab64c411cdb5c829ce1526ab3a5a7729627", + "sha256:3af3d781ce085573ced37b2b5b9abfd32ce3d4723bd17f37e829025d189b0421", + "sha256:6786b127f33470fd843e644435522fbf43bce05c9f5527946c390ccb9e1cac27", + "sha256:8b2b768b02c6b7476f2e16ddd91f827d3817aef73f82cf28bff7a8dcdfd8c55c", + "sha256:dd7fbd32da74d4e9967dc15845f731f16e7966cee61f5dc0e12e2abb1305068c", + "sha256:e774377876cb258e8f4d63f7809863f961c98aa02263b3ff54a39483bc6f7d26" + ], + "index": "pypi", + "version": "==0.16.2" + }, + "scipy": { + "hashes": [ + "sha256:0baa64bf42592032f6f6445a07144e355ca876b177f47ad8d0612901c9375bef", + "sha256:243b04730d7223d2b844bda9500310eecc9eda0cba9ceaf0cde1839f8287dfa8", + "sha256:2643cfb46d97b7797d1dbdb6f3c23fe3402904e3c90e6facfe6a9b98d808c1b5", + "sha256:396eb4cdad421f846a1498299474f0a3752921229388f91f60dc3eda55a00488", + "sha256:3ae3692616975d3c10aca6d574d6b4ff95568768d4525f76222fb60f142075b9", + "sha256:435d19f80b4dcf67dc090cc04fde2c5c8a70b3372e64f6a9c58c5b806abfa5a8", + "sha256:46a5e55850cfe02332998b3aef481d33f1efee1960fe6cfee0202c7dd6fc21ab", + "sha256:75b513c462e58eeca82b22fc00f0d1875a37b12913eee9d979233349fce5c8b2", + "sha256:7ccfa44a08226825126c4ef0027aa46a38c928a10f0a8a8483c80dd9f9a0ad44", + "sha256:89dd6a6d329e3f693d1204d5562dd63af0fd7a17854ced17f9cbc37d5b853c8d", + "sha256:a81da2fe32f4eab8b60d56ad43e44d93d392da228a77e229e59b51508a00299c", + "sha256:a9d606d11eb2eec7ef893eb825017fbb6eef1e1d0b98a5b7fc11446ebeb2b9b1", + "sha256:ac37eb652248e2d7cbbfd89619dce5ecfd27d657e714ed049d82f19b162e8d45", + "sha256:cbc0611699e420774e945f6a4e2830f7ca2b3ee3483fca1aa659100049487dd5", + "sha256:d02d813ec9958ed63b390ded463163685af6025cb2e9a226ec2c477df90c6957", + "sha256:dd3b52e00f93fd1c86f2d78243dfb0d02743c94dd1d34ffea10055438e63b99d" + ], + "index": "pypi", + "version": "==1.3.1" + }, + "seaborn": { + "hashes": [ + "sha256:42e627b24e849c2d3bbfd059e00005f6afbc4a76e4895baf44ae23fe8a4b09a5", + "sha256:76c83f794ca320fb6b23a7c6192d5e185a5fcf4758966a0c0a54baee46d41e2f" + ], + "index": "pypi", + "version": "==0.9.0" + }, + "send2trash": { + "hashes": [ + "sha256:60001cc07d707fe247c94f74ca6ac0d3255aabcb930529690897ca2a39db28b2", + "sha256:f1691922577b6fa12821234aeb57599d887c4900b9ca537948d2dac34aea888b" + ], + "version": "==1.5.0" + }, + "shapely": { + "hashes": [ + "sha256:0378964902f89b8dbc332e5bdfa08e0bc2f7ab39fecaeb17fbb2a7699a44fe71", + "sha256:34e7c6f41fb27906ccdf2514ee44a5774b90b39a256b6511a6a57d11ffe64999", + "sha256:3ca69d4b12e2b05b549465822744b6a3a1095d8488cc27b2728a06d3c07d0eee", + "sha256:3e9388f29bd81fcd4fa5c35125e1fbd4975ee36971a87a90c093f032d0e9de24", + "sha256:3ef28e3f20a1c37f5b99ea8cf8dcb58e2f1a8762d65ed2d21fd92bf1d4811182", + "sha256:523c94403047eb6cacd7fc1863ebef06e26c04d8a4e7f8f182d49cd206fe787e", + "sha256:5d22a1a705c2f70f61ccadc696e33d922c1a92e00df8e1d58a6ade14dd7e3b4f", + "sha256:714b6680215554731389a1bbdae4cec61741aa4726921fa2b2b96a6f578a2534", + "sha256:7dfe1528650c3f0dc82f41a74cf4f72018288db9bfb75dcd08f6f04233ec7e78", + "sha256:ba58b21b9cf3c33725f7f530febff9ed6a6846f9d0bf8a120fc74683ff919f89", + "sha256:c4b87bb61fc3de59fc1f85e71a79b0c709dc68364d9584473697aad4aa13240f", + "sha256:ebb4d2bee7fac3f6c891fcdafaa17f72ab9c6480f6d00de0b2dc9a5137dfe342" + ], + "index": "pypi", + "version": "==1.6.4.post2" + }, + "simplejson": { + "hashes": [ + "sha256:067a7177ddfa32e1483ba5169ebea1bc2ea27f224853211ca669325648ca5642", + "sha256:2b8cb601d9ba0381499db719ccc9dfbb2fbd16013f5ff096b1a68a4775576a04", + "sha256:2c139daf167b96f21542248f8e0a06596c9b9a7a41c162cc5c9ee9f3833c93cd", + "sha256:2fc546e6af49fb45b93bbe878dea4c48edc34083729c0abd09981fe55bdf7f91", + "sha256:354fa32b02885e6dae925f1b5bbf842c333c1e11ea5453ddd67309dc31fdb40a", + "sha256:37e685986cf6f8144607f90340cff72d36acf654f3653a6c47b84c5c38d00df7", + "sha256:3af610ee72efbe644e19d5eaad575c73fb83026192114e5f6719f4901097fce2", + "sha256:3b919fc9cf508f13b929a9b274c40786036b31ad28657819b3b9ba44ba651f50", + "sha256:3dd289368bbd064974d9a5961101f080e939cbe051e6689a193c99fb6e9ac89b", + "sha256:491de7acc423e871a814500eb2dcea8aa66c4a4b1b4825d18f756cdf58e370cb", + "sha256:495511fe5f10ccf4e3ed4fc0c48318f533654db6c47ecbc970b4ed215c791968", + "sha256:65b41a5cda006cfa7c66eabbcf96aa704a6be2a5856095b9e2fd8c293bad2b46", + "sha256:6c3258ffff58712818a233b9737fe4be943d306c40cf63d14ddc82ba563f483a", + "sha256:75e3f0b12c28945c08f54350d91e624f8dd580ab74fd4f1bbea54bc6b0165610", + "sha256:79b129fe65fdf3765440f7a73edaffc89ae9e7885d4e2adafe6aa37913a00fbb", + "sha256:b1f329139ba647a9548aa05fb95d046b4a677643070dc2afc05fa2e975d09ca5", + "sha256:c206f47cbf9f32b573c9885f0ec813d2622976cf5effcf7e472344bc2e020ac1", + "sha256:d8e238f20bcf70063ee8691d4a72162bcec1f4c38f83c93e6851e72ad545dabb", + "sha256:ee9625fc8ee164902dfbb0ff932b26df112da9f871c32f0f9c1bcf20c350fe2a", + "sha256:fb2530b53c28f0d4d84990e945c2ebb470edb469d63e389bf02ff409012fe7c5", + "sha256:feadb95170e45f439455354904768608e356c5b174ca30b3d11b0e3f24b5c0df" + ], + "index": "pypi", + "version": "==3.16.0" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "index": "pypi", + "version": "==1.12.0" + }, + "sortedcontainers": { + "hashes": [ + "sha256:974e9a32f56b17c1bac2aebd9dcf197f3eb9cd30553c5852a3187ad162e1a03a", + "sha256:d9e96492dd51fae31e60837736b38fe42a187b5404c16606ff7ee7cd582d4c60" + ], + "version": "==2.1.0" + }, + "sqlalchemy": { + "hashes": [ + "sha256:0f0768b5db594517e1f5e1572c73d14cf295140756431270d89496dc13d5e46c" + ], + "index": "pypi", + "version": "==1.3.10" + }, + "subprocess32": { + "hashes": [ + "sha256:88e37c1aac5388df41cc8a8456bb49ebffd321a3ad4d70358e3518176de3a56b", + "sha256:eb2937c80497978d181efa1b839ec2d9622cf9600a039a79d0e108d1f9aec79d" + ], + "index": "pypi", + "version": "==3.5.4" + }, + "supervisor": { + "hashes": [ + "sha256:2dc86fe0476e945e61483d614ceb2cf4f93b95282eb243bdf792621994360383", + "sha256:a76b2f77a560f2dc411c0254a4eb15f555e99faac48621b0f1fc9ab013944f47" + ], + "index": "pypi", + "version": "==4.1.0" + }, + "tenacity": { + "hashes": [ + "sha256:6a7511a59145c2e319b7d04ddd93c12d48cc3d3c8fa42c2846d33a620ee91f57", + "sha256:a4eb168dbf55ed2cae27e7c6b2bd48ab54dabaf294177d998330cf59f294c112" + ], + "index": "pypi", + "version": "==5.1.1" + }, + "tensorboard": { + "hashes": [ + "sha256:143e8c8226e812bed1ad26e9139e7aeda70ea4984aab40ade52a02454bec84e4", + "sha256:d3559616ccad8d72e7a259bff51be61a9bf1e66e2cebdc782c33e4b588b5e943" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.0.0" + }, + "tensorflow-estimator": { + "hashes": [ + "sha256:aa8deab25d09a9730dfbae8ec58f4eb00ec2a90b5ca3dcbd8fa0717103d3bbb3" + ], + "index": "pypi", + "version": "==2.0.1" + }, + "tensorflow-gpu": { + "hashes": [ + "sha256:6bb259ceadac6f9ccba7c07903570e4b495d6230efce8f4ab8831cede87cea42", + "sha256:73943249a1059ea8344487756939539bd32d2639f1fc0f92d6395863764b683b", + "sha256:767d775cb7b0f997b584a7441f47d76ff216cf05eb902fc56d9d3f664b03412a", + "sha256:a79fcb04092afa2737a45ff81cfc74f4423d239bfe642159eb34c90233900157", + "sha256:a87701141f8836205e20ba061246bc3a14e73f07f061a91325ca297c641995d0", + "sha256:bd6ad275b05132910b9d929cf299895c1b92cd66a01271c8e33818454d88888c", + "sha256:ccaae56548ab8a8148c1735ca176d2b2da103dc4cd8603fe86692b0b3c7530fb" + ], + "index": "pypi", + "version": "==2.0.0" + }, + "termcolor": { + "hashes": [ + "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b" + ], + "version": "==1.1.0" + }, + "terminado": { + "hashes": [ + "sha256:d9d012de63acb8223ac969c17c3043337c2fcfd28f3aea1ee429b345d01ef460", + "sha256:de08e141f83c3a0798b050ecb097ab6259c3f0331b2f7b7750c9075ced2c20c2" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.8.2" + }, + "testpath": { + "hashes": [ + "sha256:46c89ebb683f473ffe2aab0ed9f12581d4d078308a3cb3765d79c6b2317b0109", + "sha256:b694b3d9288dbd81685c5d2e7140b81365d46c29f5db4bc659de5aa6b98780f8" + ], + "version": "==0.4.2" + }, + "theano": { + "hashes": [ + "sha256:35c9bbef56b61ffa299265a42a4e8f8cb5a07b2997dabaef0f8830b397086913" + ], + "index": "pypi", + "version": "==1.0.4" + }, + "tornado": { + "hashes": [ + "sha256:349884248c36801afa19e342a77cc4458caca694b0eda633f5878e458a44cb2c", + "sha256:398e0d35e086ba38a0427c3b37f4337327231942e731edaa6e9fd1865bbd6f60", + "sha256:4e73ef678b1a859f0cb29e1d895526a20ea64b5ffd510a2307b5998c7df24281", + "sha256:559bce3d31484b665259f50cd94c5c28b961b09315ccd838f284687245f416e5", + "sha256:abbe53a39734ef4aba061fca54e30c6b4639d3e1f59653f0da37a0003de148c7", + "sha256:c845db36ba616912074c5b1ee897f8e0124df269468f25e4fe21fe72f6edd7a9", + "sha256:c9399267c926a4e7c418baa5cbe91c7d1cf362d505a1ef898fde44a07c9dd8a5" + ], + "markers": "python_version >= '3.5'", + "version": "==6.0.3" + }, + "traitlets": { + "hashes": [ + "sha256:70b4c6a1d9019d7b4f6846832288f86998aa3b9207c6821f3578a6a6a467fe44", + "sha256:d023ee369ddd2763310e4c3eae1ff649689440d4ae59d7485eb4cfbbe3e359f7" + ], + "version": "==4.3.3" + }, + "typed-ast": { + "hashes": [ + "sha256:1170afa46a3799e18b4c977777ce137bb53c7485379d9706af8a59f2ea1aa161", + "sha256:18511a0b3e7922276346bcb47e2ef9f38fb90fd31cb9223eed42c85d1312344e", + "sha256:262c247a82d005e43b5b7f69aff746370538e176131c32dda9cb0f324d27141e", + "sha256:2b907eb046d049bcd9892e3076c7a6456c93a25bebfe554e931620c90e6a25b0", + "sha256:354c16e5babd09f5cb0ee000d54cfa38401d8b8891eefa878ac772f827181a3c", + "sha256:48e5b1e71f25cfdef98b013263a88d7145879fbb2d5185f2a0c79fa7ebbeae47", + "sha256:4e0b70c6fc4d010f8107726af5fd37921b666f5b31d9331f0bd24ad9a088e631", + "sha256:630968c5cdee51a11c05a30453f8cd65e0cc1d2ad0d9192819df9978984529f4", + "sha256:66480f95b8167c9c5c5c87f32cf437d585937970f3fc24386f313a4c97b44e34", + "sha256:71211d26ffd12d63a83e079ff258ac9d56a1376a25bc80b1cdcdf601b855b90b", + "sha256:7954560051331d003b4e2b3eb822d9dd2e376fa4f6d98fee32f452f52dd6ebb2", + "sha256:838997f4310012cf2e1ad3803bce2f3402e9ffb71ded61b5ee22617b3a7f6b6e", + "sha256:95bd11af7eafc16e829af2d3df510cecfd4387f6453355188342c3e79a2ec87a", + "sha256:bc6c7d3fa1325a0c6613512a093bc2a2a15aeec350451cbdf9e1d4bffe3e3233", + "sha256:cc34a6f5b426748a507dd5d1de4c1978f2eb5626d51326e43280941206c209e1", + "sha256:d755f03c1e4a51e9b24d899561fec4ccaf51f210d52abdf8c07ee2849b212a36", + "sha256:d7c45933b1bdfaf9f36c579671fec15d25b06c8398f113dab64c18ed1adda01d", + "sha256:d896919306dd0aa22d0132f62a1b78d11aaf4c9fc5b3410d3c666b818191630a", + "sha256:fdc1c9bbf79510b76408840e009ed65958feba92a88833cdceecff93ae8fff66", + "sha256:ffde2fbfad571af120fcbfbbc61c72469e72f550d676c3342492a9dfdefb8f12" + ], + "markers": "python_version < '3.8' and implementation_name == 'cpython'", + "version": "==1.4.0" + }, + "urllib3": { + "hashes": [ + "sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398", + "sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86" + ], + "index": "pypi", + "version": "==1.25.6" + }, + "utm": { + "hashes": [ + "sha256:07e55707ed660eec1ae983bd54a406c437962618a6261b38d70592fe30f5f508" + ], + "index": "pypi", + "version": "==0.5.0" + }, + "uwsgi": { + "hashes": [ + "sha256:4972ac538800fb2d421027f49b4a1869b66048839507ccf0aa2fda792d99f583" + ], + "index": "pypi", + "version": "==2.0.18" + }, + "v4l2": { + "hashes": [ + "sha256:0d8f31f9d554ded4d0b50a31a7be5590b861df9e1ba256ee757e1c09175dd4a2" + ], + "index": "pypi", + "version": "==0.2" + }, + "vine": { + "hashes": [ + "sha256:133ee6d7a9016f177ddeaf191c1f58421a1dcc6ee9a42c58b34bed40e1d2cd87", + "sha256:ea4947cc56d1fd6f2095c8d543ee25dad966f78692528e68b4fada11ba3f98af" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.3.0" + }, + "wcwidth": { + "hashes": [ + "sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e", + "sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c" + ], + "version": "==0.1.7" + }, + "webencodings": { + "hashes": [ + "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", + "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" + ], + "version": "==0.5.1" + }, + "werkzeug": { + "hashes": [ + "sha256:7280924747b5733b246fe23972186c6b348f9ae29724135a6dfc1e53cea433e7", + "sha256:e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.16.0" + }, + "wheel": { + "hashes": [ + "sha256:10c9da68765315ed98850f8e048347c3eb06dd81822dc2ab1d4fde9dc9702646", + "sha256:f4da1763d3becf2e2cd92a14a7c920f0f00eca30fdde9ea992c836685b9faf28" + ], + "markers": "python_version >= '3'", + "version": "==0.33.6" + }, + "widgetsnbextension": { + "hashes": [ + "sha256:079f87d87270bce047512400efd70238820751a11d2d8cb137a5a5bdbaf255c7", + "sha256:bd314f8ceb488571a5ffea6cc5b9fc6cba0adaf88a9d2386b93a489751938bcd" + ], + "version": "==3.5.1" + }, + "wrapt": { + "hashes": [ + "sha256:565a021fd19419476b9362b05eeaa094178de64f8361e44468f9e9d7843901e1" + ], + "version": "==1.11.2" + }, + "zipp": { + "hashes": [ + "sha256:3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e", + "sha256:f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335" + ], + "markers": "python_version >= '2.7'", + "version": "==0.6.0" + } + } +} diff --git a/README.md b/README.md index f8052b285997d3..0a01a1d1acdf7a 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -[![](https://i.imgur.com/xY2gdHv.png)](#) +[![](https://i.imgur.com/UetIFyH.jpg)](#) Welcome to openpilot ====== -[openpilot](http://github.com/commaai/openpilot) is an open source driving agent. Currently, it performs the functions of Adaptive Cruise Control (ACC) and Lane Keeping Assist System (LKAS) for selected Honda, Toyota, Acura, Lexus, Chevrolet, Hyundai, Kia. It's about on par with Tesla Autopilot and GM Super Cruise, and better than [all other manufacturers](http://www.thedrive.com/tech/5707/the-war-for-autonomous-driving-part-iii-us-vs-germany-vs-japan). +[openpilot](http://github.com/commaai/openpilot) is an open source driver assistance system. Currently, it performs the functions of Adaptive Cruise Control (ACC) and Automated Lane Centering (ALC) for selected Honda, Toyota, Acura, Lexus, Chevrolet, Hyundai, Kia, Subaru, Volkswagen. It's about on par with Tesla Autopilot and GM Super Cruise, and better than [all other manufacturers](http://www.thedrive.com/tech/5707/the-war-for-autonomous-driving-part-iii-us-vs-germany-vs-japan). The openpilot codebase has been written to be concise and to enable rapid prototyping. We look forward to your contributions - improving real vehicle automation has never been easier. @@ -29,106 +29,134 @@ Community openpilot is developed by [comma.ai](https://comma.ai/) and users like you. -We have a [Twitter you should follow](https://twitter.com/comma_ai). - -Also, we have a several thousand people community on [Discord](https://discord.comma.ai). +[Follow us on Twitter](https://twitter.com/comma_ai) and [join our Discord](https://discord.comma.ai). - - - - + + + + - - - - + + + +
Hardware ------ -At the moment openpilot supports the [EON Dashcam DevKit](https://comma.ai/shop/products/eon-dashcam-devkit). A [panda](https://shop.comma.ai/products/panda-obd-ii-dongle) and a [giraffe](https://comma.ai/shop/products/giraffe/) are recommended tools to interface the EON with the car. We'd like to support other platforms as well. +At the moment openpilot supports the [EON DevKit](https://comma.ai/shop/products/eon-dashcam-devkit). A [car harness](https://comma.ai/shop/products/car-harness) is recommended to connect the EON to the car. We'd like to support other platforms as well. Install openpilot on a neo device by entering ``https://openpilot.comma.ai`` during NEOS setup. Supported Cars ------ -| Make | Model | Supported Package | Lateral | Longitudinal | No Accel Below | No Steer Below | Giraffe | -| ---------------------| -------------------------| ---------------------| --------| ---------------| -----------------| ---------------|-------------------| -| Acura | ILX 2016-17 | AcuraWatch Plus | Yes | Yes | 25mph1| 25mph | Nidec | -| Acura | RDX 2018 | AcuraWatch Plus | Yes | Yes | 25mph1| 12mph | Nidec | -| Buick3 | Regal 2018 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | Custom7| -| Chevrolet3| Malibu 2017 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | Custom7| -| Chevrolet3| Volt 2017-18 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | Custom7| -| Cadillac3 | ATS 2018 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | Custom7| -| Chrysler | Pacifica 2018 | Adaptive Cruise | Yes | Stock | 0mph | 9mph | FCA | -| Chrysler | Pacifica Hybrid 2017-18 | Adaptive Cruise | Yes | Stock | 0mph | 9mph | FCA | -| GMC3 | Acadia Denali 2018 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | Custom7| -| Holden3 | Astra 2017 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | Custom7| -| Honda | Accord 2018 | All | Yes | Stock | 0mph | 3mph | Bosch | -| Honda | Civic Sedan/Coupe 2016-18| Honda Sensing | Yes | Yes | 0mph | 12mph | Nidec | -| Honda | Civic Sedan/Coupe 2019 | Honda Sensing | Yes | Stock | 0mph | 2mph | Bosch | -| Honda | Civic Hatchback 2017-19 | Honda Sensing | Yes | Stock | 0mph | 12mph | Bosch | -| Honda | CR-V 2015-16 | Touring | Yes | Yes | 25mph1| 12mph | Nidec | -| Honda | CR-V 2017-18 | Honda Sensing | Yes | Stock | 0mph | 12mph | Bosch | -| Honda | Odyssey 2017-19 | Honda Sensing | Yes | Yes | 25mph1| 0mph | Inverted Nidec | -| Honda | Pilot 2016-18 | Honda Sensing | Yes | Yes | 25mph1| 12mph | Nidec | -| Honda | Pilot 2019 | All | Yes | Yes | 25mph1| 12mph | Inverted Nidec | -| Honda | Ridgeline 2017-19 | Honda Sensing | Yes | Yes | 25mph1| 12mph | Nidec | -| Hyundai | Santa Fe 2019 | All | Yes | Stock | 0mph | 0mph | Custom6| -| Hyundai | Elantra 2017 | SCC + LKAS | Yes | Stock | 19mph | 34mph | Custom6| -| Hyundai | Genesis 2018 | All | Yes | Stock | 19mph | 34mph | Custom6| -| Jeep | Grand Cherokee 2017-19 | Adaptive Cruise | Yes | Stock | 0mph | 9mph | FCA | -| Kia | Optima 2019 | SCC + LKAS | Yes | Stock | 0mph | 0mph | Custom6| -| Kia | Sorento 2018 | All | Yes | Stock | 0mph | 0mph | Custom6| -| Kia | Stinger 2018 | SCC + LKAS | Yes | Stock | 0mph | 0mph | Custom6| -| Lexus | RX Hybrid 2016-18 | All | Yes | Yes2| 0mph | 0mph | Toyota | -| Toyota | Camry 20184 | All | Yes | Stock | 0mph5 | 0mph | Toyota | -| Toyota | C-HR 2017-184 | All | Yes | Stock | 0mph | 0mph | Toyota | -| Toyota | Corolla 2017-18 | All | Yes | Yes2| 20mph1| 0mph | Toyota | -| Toyota | Highlander 2017-18 | All | Yes | Yes2| 0mph | 0mph | Toyota | -| Toyota | Highlander Hybrid 2018 | All | Yes | Yes2| 0mph | 0mph | Toyota | -| Toyota | Prius 2016 | TSS-P | Yes | Yes2| 0mph | 0mph | Toyota | -| Toyota | Prius 2017-18 | All | Yes | Yes2| 0mph | 0mph | Toyota | -| Toyota | Prius Prime 2017-18 | All | Yes | Yes2| 0mph | 0mph | Toyota | -| Toyota | Rav4 2016 | TSS-P | Yes | Yes2| 20mph1| 0mph | Toyota | -| Toyota | Rav4 2017-18 | All | Yes | Yes2| 20mph1| 0mph | Toyota | -| Toyota | Rav4 Hybrid 2017-18 | All | Yes | Yes2| 0mph | 0mph | Toyota | - -1[Comma Pedal](https://community.comma.ai/wiki/index.php/Comma_Pedal) is used to provide stop-and-go capability to some of the openpilot-supported cars that don't currently support stop-and-go. Here is how to [build a Comma Pedal](https://medium.com/@jfrux/comma-pedal-building-with-macrofab-6328bea791e8). ***NOTE: The Comma Pedal is not officially supported by [comma.ai](https://comma.ai)*** -2When disconnecting the Driver Support Unit (DSU), otherwise longitudinal control is stock ACC. For DSU locations, see [Toyota Wiki page](https://community.comma.ai/wiki/index.php/Toyota) -3[GM installation guide](https://zoneos.com/volt/). -4It needs an extra 120Ohm resistor ([pic1](https://i.imgur.com/CmdKtTP.jpg), [pic2](https://i.imgur.com/s2etUo6.jpg)) on bus 3 and giraffe switches set to 01X1 (11X1 for stock LKAS), where X depends on if you have the [comma power](https://comma.ai/shop/products/power/). -528mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control. -6Open sourced [Hyundai Giraffe](https://github.com/commaai/neo/tree/master/giraffe/hyundai) is designed for the 2019 Sante Fe; pinout may differ for other Hyundais. -7Community built Giraffe, find more information [here](https://zoneos.com/shop/). +| Make | Model (US Market Reference) | Supported Package | Lateral | Longitudinal | No Accel Below | No Steer Below | +| ----------------------| -----------------------------------| ---------------------| --------| ---------------| -----------------| ---------------| +| Acura | ILX 2016-18 | AcuraWatch Plus | Yes | Yes | 25mph1| 25mph | +| Acura | RDX 2016-18 | AcuraWatch Plus | Yes | Yes | 25mph1| 12mph | +| Buick3 | Regal 20186 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | +| Chevrolet3 | Malibu 20176 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | +| Chevrolet3 | Volt 2017-186 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | +| Cadillac3 | ATS 2018 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | +| Chrysler | Pacifica 2017-187 | Adaptive Cruise | Yes | Stock | 0mph | 9mph | +| Chrysler | Pacifica Hybrid 2017-187| Adaptive Cruise | Yes | Stock | 0mph | 9mph | +| Chrysler | Pacifica Hybrid 20197 | Adaptive Cruise | Yes | Stock | 0mph | 39mph | +| Genesis | G80 2018 | All | Yes | Stock | 0mph | 0mph | +| Genesis | G90 2018 | All | Yes | Stock | 0mph | 0mph | +| GMC3 | Acadia Denali 20186 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | +| Holden3 | Astra 20176 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | +| Honda | Accord 2018-19 | All | Yes | Stock | 0mph | 3mph | +| Honda | Accord Hybrid 2018-19 | All | Yes | Stock | 0mph | 3mph | +| Honda | Civic Sedan/Coupe 2016-18 | Honda Sensing | Yes | Yes | 0mph | 12mph | +| Honda | Civic Sedan/Coupe 2019 | Honda Sensing | Yes | Stock | 0mph | 2mph | +| Honda | Civic Hatchback 2017-19 | Honda Sensing | Yes | Stock | 0mph | 12mph | +| Honda | CR-V 2015-16 | Touring | Yes | Yes | 25mph1| 12mph | +| Honda | CR-V 2017-19 | Honda Sensing | Yes | Stock | 0mph | 12mph | +| Honda | CR-V Hybrid 2017-2019 | Honda Sensing | Yes | Stock | 0mph | 12mph | +| Honda | Fit 2018-19 | Honda Sensing | Yes | Yes | 25mph1| 12mph | +| Honda | Odyssey 2018-19 | Honda Sensing | Yes | Yes | 25mph1| 0mph | +| Honda | Passport 2019 | All | Yes | Yes | 25mph1| 12mph | +| Honda | Pilot 2016-18 | Honda Sensing | Yes | Yes | 25mph1| 12mph | +| Honda | Pilot 2019 | All | Yes | Yes | 25mph1| 12mph | +| Honda | Ridgeline 2017-19 | Honda Sensing | Yes | Yes | 25mph1| 12mph | +| Hyundai | Elantra 2017-195 | SCC + LKAS | Yes | Stock | 19mph | 34mph | +| Hyundai | Elantra GT/i30 2017-19 | All | Yes | Stock | 0mph | 30mph | +| Hyundai | Genesis 2018 | All | Yes | Stock | 19mph | 34mph | +| Hyundai | Ioniq 20175 | All | Yes | Stock | 0mph | 34mph | +| Hyundai | Kona 2017-195 | LDWS | Yes | Stock | 22mph | 0mph | +| Hyundai | Santa Fe 20195 | All | Yes | Stock | 0mph | 0mph | +| Jeep | Grand Cherokee 2016-187 | Adaptive Cruise | Yes | Stock | 0mph | 9mph | +| Jeep | Grand Cherokee 20197 | Adaptive Cruise | Yes | Stock | 0mph | 39mph | +| Kia | Forte 20185 | LKAS | Yes | Stock | 0mph | 0mph | +| Kia | Optima 20175 | SCC + LKAS/LDWS | Yes | Stock | 0mph | 34mph | +| Kia | Optima 20195 | SCC + LKAS | Yes | Stock | 0mph | 0mph | +| Kia | Sorento 20185 | All | Yes | Stock | 0mph | 0mph | +| Kia | Stinger 20185 | SCC + LKAS | Yes | Stock | 0mph | 0mph | +| Lexus | CT Hybrid 2017-18 | All | Yes | Yes2| 0mph | 0mph | +| Lexus | ES Hybrid 2019 | All | Yes | Yes | 0mph | 0mph | +| Lexus | RX Hybrid 2016-19 | All | Yes | Yes2| 0mph | 0mph | +| Lexus | IS 2017-2019 | All | Yes | Stock | 22mph | 0mph | +| Lexus | IS Hybrid 2017 | All | Yes | Stock | 0mph | 0mph | +| Subaru | Crosstrek 2018-19 | EyeSight | Yes | Stock | 0mph | 0mph | +| Subaru | Impreza 2019-20 | EyeSight | Yes | Stock | 0mph | 0mph | +| Toyota | Avalon 2016 | TSS-P | Yes | Yes2| 20mph1| 0mph | +| Toyota | Avalon 2017-18 | All | Yes | Yes2| 20mph1| 0mph | +| Toyota | Camry 2018-19 | All | Yes | Stock | 0mph4 | 0mph | +| Toyota | Camry Hybrid 2018-19 | All | Yes | Stock | 0mph4 | 0mph | +| Toyota | C-HR 2017-19 | All | Yes | Stock | 0mph | 0mph | +| Toyota | C-HR Hybrid 2017-19 | All | Yes | Stock | 0mph | 0mph | +| Toyota | Corolla 2017-19 | All | Yes | Yes2| 20mph1| 0mph | +| Toyota | Corolla 2020 | All | Yes | Yes | 0mph | 0mph | +| Toyota | Corolla Hatchback 2019 | All | Yes | Yes | 0mph | 0mph | +| Toyota | Corolla Hybrid 2020 | All | Yes | Yes | 0mph | 0mph | +| Toyota | Highlander 2017-19 | All | Yes | Yes2| 0mph | 0mph | +| Toyota | Highlander Hybrid 2017-19 | All | Yes | Yes2| 0mph | 0mph | +| Toyota | Prius 2016 | TSS-P | Yes | Yes2| 0mph | 0mph | +| Toyota | Prius 2017-19 | All | Yes | Yes2| 0mph | 0mph | +| Toyota | Prius Prime 2017-20 | All | Yes | Yes2| 0mph | 0mph | +| Toyota | Rav4 2016 | TSS-P | Yes | Yes2| 20mph1| 0mph | +| Toyota | Rav4 2017-18 | All | Yes | Yes2| 20mph1| 0mph | +| Toyota | Rav4 2019 | All | Yes | Yes | 0mph | 0mph | +| Toyota | Rav4 Hybrid 2016 | TSS-P | Yes | Yes2| 0mph | 0mph | +| Toyota | Rav4 Hybrid 2017-18 | All | Yes | Yes2| 0mph | 0mph | +| Toyota | Sienna 2018 | All | Yes | Yes2| 0mph | 0mph | +| Volkswagen8| Golf 2016-19 | Driver Assistance | Yes | Stock | 0mph | 0mph | + +1[Comma Pedal](https://community.comma.ai/wiki/index.php/Comma_Pedal) is used to provide stop-and-go capability to some of the openpilot-supported cars that don't currently support stop-and-go. Here is how to [build a Comma Pedal](https://medium.com/@jfrux/comma-pedal-building-with-macrofab-6328bea791e8). ***NOTE: The Comma Pedal is not officially supported by [comma.ai](https://comma.ai).***
+2When disconnecting the Driver Support Unit (DSU), otherwise longitudinal control is stock ACC. For DSU locations, see [Toyota Wiki page](https://community.comma.ai/wiki/index.php/Toyota). ***NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).***
+3[GM installation guide](https://zoneos.com/volt/). ***NOTE: disconnecting the ASCM disables Automatic Emergency Braking (AEB).***
+428mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control.
+5Requires a [panda](https://comma.ai/shop/products/panda-obd-ii-dongle) and open sourced [Hyundai Giraffe](https://github.com/commaai/neo/tree/master/giraffe/hyundai), designed for the 2019 Sante Fe; pinout may differ for other Hyundais.
+6Requires a [panda](https://comma.ai/shop/products/panda-obd-ii-dongle) and community built giraffe, find more information [here](https://zoneos.com/shop/).
+7Requires a [panda](https://comma.ai/shop/products/panda-obd-ii-dongle) and FCA [giraffe](https://comma.ai/shop/products/giraffe)
+8Requires a [custom connector](https://community.comma.ai/wiki/index.php/Volkswagen#Integration_at_J533_Gateway) for the [car harness](https://comma.ai/shop/products/car-harness)
Community Maintained Cars ------ -| Make | Model | Supported Package | Lateral | Longitudinal | No Accel Below | No Steer Below | Giraffe | -| ---------------------| -------------------------| ---------------------| --------| ---------------| -----------------| ---------------|-------------------| -| Honda | Fit 2018 | Honda Sensing | Yes | Yes | 25mph1| 12mph | Inverted Nidec | -| Tesla | Model S 2012-13 | All | Yes | Not yet | Not applicable | 0mph | Custom8| +| Make | Model (US Market Reference) | Supported Package | Lateral | Longitudinal | No Accel Below | No Steer Below | +| ---------------------| -----------------------------------| ---------------------| --------| ---------------| -----------------| ---------------| +| Tesla | Model S 2012-139 | All | Yes | NA | NA | 0mph | -[[Honda Fit Pull Request]](https://github.com/commaai/openpilot/pull/266).
[[Tesla Model S Pull Request]](https://github.com/commaai/openpilot/pull/246)
-8Community built Giraffe, find more information here [Community Tesla Giraffe](https://github.com/jeankalud/neo/tree/tesla_giraffe/giraffe/tesla)
+9Requires a [panda](https://comma.ai/shop/products/panda-obd-ii-dongle) and community built giraffe, find more information [here](https://github.com/jeankalud/neo/tree/tesla_giraffe/giraffe/tesla).
Community Maintained Cars are not confirmed by comma.ai to meet our [safety model](https://github.com/commaai/openpilot/blob/devel/SAFETY.md). Be extra cautious using them. In Progress Cars ------ - All TSS-P Toyota with Steering Assist and LSS-P Lexus with Steering Assist or Lane Keep Assist. - - Only remaining Toyota cars with no port yet are the Avalon and the Sienna. - All Hyundai with SmartSense. -- All Kia with SCC and LKAS. +- All Kia, Genesis with SCC and LKAS. - All Chrysler, Jeep, Fiat with Adaptive Cruise Control and LaneSense. +- All Subaru with EyeSight. +- All Volkswagen, Audi, Å koda and SEAT with Adaptive Cruise Control. How can I add support for my car? ------ @@ -154,6 +182,7 @@ Directory structure ├── pyextra # Libraries used on EON └── selfdrive # Code needed to drive the car ├── assets # Fonts and images for UI + ├── athena # Allows communication with the app ├── boardd # Daemon to talk to the board ├── can # Helpers for parsing CAN messages ├── car # Car specific code to read states and control actuators @@ -163,8 +192,6 @@ Directory structure ├── locationd # Soon to be home of precise location ├── logcatd # Android logcat as a service ├── loggerd # Logger and uploader of car data - ├── mapd # Fetches map data and computes next global path - ├── orbd # Computes ORB features from frames ├── proclogd # Logs information from proc ├── sensord # IMU / GPS interface code ├── test # Car simulator running code through virtual maneuvers @@ -184,7 +211,7 @@ It logs the road facing camera, CAN, GPS, IMU, magnetometer, thermal sensors, cr The user facing camera is only logged if you explicitly opt-in in settings. It does not log the microphone. -By using it, you agree to [our privacy policy](https://community.comma.ai/privacy.html). You understand that use of this software or its related services will generate certain types of user data, which may be logged and stored at the sole discretion of comma.ai. By accepting this agreement, you grant an irrevocable, perpetual, worldwide right to comma.ai for the use of this data. +By using it, you agree to [our privacy policy](https://my.comma.ai/privacy). You understand that use of this software or its related services will generate certain types of user data, which may be logged and stored at the sole discretion of comma.ai. By accepting this agreement, you grant an irrevocable, perpetual, worldwide right to comma.ai for the use of this data. Testing on PC ------ diff --git a/RELEASES.md b/RELEASES.md index ef96e09e5a3810..7d21b52260c234 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,14 +1,133 @@ +Version 0.6.6 (2019-11-05) +======================== + * Volkswagen support thanks to jyoung8607! + * Toyota Corolla Hybrid with TSS 2.0 support thanks to u8511049! + * Lexus ES with TSS 2.0 support thanks to energee! + * Fix GM ignition detection and lock safety mode not required anymore + * Log panda firmware and dongle ID thanks to martinl! + * New driving model: improve path prediction and lead detection + * New driver monitoring model, 4x smaller and running on DSP + * Display an alert and don't start openpilot if panda has wrong firmware + * Fix bug preventing EON from terminating processes after a drive + * Remove support for Toyota giraffe without the 120Ohm resistor + +Version 0.6.5 (2019-10-07) +======================== + * NEOS update: upgrade to Python3 and new installer! + * comma Harness support! + * New driving model: improve path prediction + * New driver monitoring model: more accurate face and eye detection + * Redesign offroad screen to display updates and alerts + * Increase maximum allowed acceleration + * Prevent car 12V battery drain by cutting off EON charge after 3 days of no drive + * Lexus CT Hybrid support thanks to thomaspich! + * Louder chime for critical alerts + * Add toggle to switch to dashcam mode + * Fix "invalid vehicle params" error on DSU-less Toyota + +Version 0.6.4 (2019-09-08) +======================== + * Forward stock AEB for Honda Nidec + * Improve lane centering on banked roads + * Always-on forward collision warning + * Always-on driver monitoring, except for right hand drive countries + * Driver monitoring learns the user's normal driving position + * Honda Fit support thanks to energee! + * Lexus IS support + +Version 0.6.3 (2019-08-12) +======================== + * Alert sounds from EON: requires NEOS update + * Improve driver monitoring: eye tracking and improved awareness logic + * Improve path prediction with new driving model + * Improve lane positioning with wide lanes and exits + * Improve lateral control on RAV4 + * Slow down for turns using model + * Open sourced regression test to verify outputs against reference logs + * Open sourced regression test to sanity check all car models + +Version 0.6.2 (2019-07-29) +======================== + * New driving model! + * Improve lane tracking with double lines + * Strongly improve stationary vehicle detection + * Strongly reduce cases of braking due to false leads + * Better lead tracking around turns + * Improve cut-in prediction by using neural network + * Improve lateral control on Toyota Camry and C-HR thanks to zorrobyte! + * Fix unintended openpilot disengagements on Jeep thanks to adhintz! + * Fix delayed transition to offroad when car is turned off + +Version 0.6.1 (2019-07-21) +======================== + * Remote SSH with comma prime and [ssh.comma.ai](https://ssh.comma.ai) + * Panda code Misra-c2012 compliance, tested against cppcheck coverage + * Lockout openpilot after 3 terminal alerts for driver distracted or unresponsive + * Toyota Sienna support thanks to wocsor! + +Version 0.6 (2019-07-01) +======================== + * New model, with double the pixels and ten times the temporal context! + * Car should not take exits when in the right lane + * openpilot uses only ~65% of the CPU (down from 75%) + * Routes visible in connect/explorer after only 0.2% is uploaded (qlogs) + * loggerd and sensord are open source, every line of openpilot is now open + * Panda safety code is MISRA compliant and ships with a signed version on release2 + * New NEOS is 500MB smaller and has a reproducible usr/pipenv + * Lexus ES Hybrid support thanks to wocsor! + * Improve tuning for supported Toyota with TSS 2.0 + * Various other stability improvements + +Version 0.5.13 (2019-05-31) +========================== + * Reduce panda power consumption by 70%, down to 80mW, when car is off (not for GM) + * Reduce EON power consumption by 40%, down to 1100mW, when car is off + * Reduce CPU utilization by 20% and improve stability + * Temporarily remove mapd functionalities to improve stability + * Add openpilot record-only mode for unsupported cars + * Synchronize controlsd to boardd to reduce latency + * Remove panda support for Subaru giraffe + +Version 0.5.12 (2019-05-16) +========================== + * Improve lateral control for the Prius and Prius Prime + * Compress logs before writing to disk + * Remove old driving data when storage reaches 90% full + * Fix small offset in following distance + * Various small CPU optimizations + * Improve offroad power consumption: require NEOS Update + * Add default speed limits for Estonia thanks to martinl! + * Subaru Crosstrek support thanks to martinl! + * Toyota Avalon support thanks to njbrown09! + * Toyota Rav4 with TSS 2.0 support thanks to wocsor! + * Toyota Corolla with TSS 2.0 support thanks to wocsor! + +Version 0.5.11 (2019-04-17) +======================== + * Add support for Subaru + * Reduce panda power consumption by 60% when car is off + * Fix controlsd lag every 6 minutes. This would sometimes cause disengagements + * Fix bug in controls with new angle-offset learner in MPC + * Reduce cpu consumption of ubloxd by rewriting it in C++ + * Improve driver monitoring model and face detection + * Improve performance of visiond and ui + * Honda Passport 2019 support + * Lexus RX Hybrid 2019 support thanks to schomems! + * Improve road selection heuristic in mapd + * Add Lane Departure Warning to dashboard for Toyota thanks to arne182 + Version 0.5.10 (2019-03-19) ======================== - * Self-tuning vehicle parameters: steering offset, tires stiffness and steering ratio + * Self-tuning vehicle parameters: steering offset, tire stiffness and steering ratio * Improve longitudinal control at low speed when lead vehicle harshly decelerates * Fix panda bug going unexpectedly in DCP mode when EON is connected * Reduce white panda power consumption by 500mW when EON is disconnected by turning off WIFI * New Driver Monitoring Model * Support QR codes for login using comma connect - * Refactor comma pedal FW and use CRC-8 checksum algorithm for safety. Reflashing pedal is required. - Please see `#hw-pedal` on [discord](discord.comma.ai) for assistance updating comma pedal. + * Refactor comma pedal FW and use CRC-8 checksum algorithm for safety. Reflashing pedal is required. + Please see `#hw-pedal` on [discord](discord.comma.ai) for assistance updating comma pedal. * Additional speed limit rules for Germany thanks to arne182 + * Allow negative speed limit offsets Version 0.5.9 (2019-02-10) ======================== diff --git a/SAFETY.md b/SAFETY.md index b5800a0d507ff6..f3089c497b22ab 100644 --- a/SAFETY.md +++ b/SAFETY.md @@ -1,8 +1,8 @@ openpilot Safety ====== -openpilot is an Adaptive Cruise Control (ACC) and Lane Keeping Assist (LKA) system. -Like other ACC and LKA systems, openpilot requires the driver to be alert and to +openpilot is an Adaptive Cruise Control (ACC) and Automated Lane Centering (ALC) system. +Like other ACC and ALC systems, openpilot requires the driver to be alert and to pay attention at all times. We repeat, **driver alertness is necessary, but not sufficient, for openpilot to be used safely**. @@ -93,7 +93,7 @@ GM/Chevrolet commands outside these limits. A steering torque rate limit is enforced by the panda firmware and by openpilot, so that the commanded steering torque must rise from 0 to max value no faster than 0.75s. Commanded steering torque is gradually limited by the panda firmware and by openpilot if the driver's - torque exceeds 12 units in the opposite dicrection to ensure limited applied torque against the + torque exceeds 12 units in the opposite direction to ensure limited applied torque against the driver's will. - Brake pedal and gas pedal potentiometer signals are contained in the 0xF1 and 0x1A1 CAN messages, @@ -116,7 +116,7 @@ Hyundai/Kia (Lateral only) commands outside the values of -409 and 409. A steering torque rate limit is enforced by the panda firmware and by openpilot, so that the commanded steering torque must rise from 0 to max value no faster than 0.85s. Commanded steering torque is gradually limited by the panda firmware and by openpilot if the driver's - torque exceeds 50 units in the opposite dicrection to ensure limited applied torque against the + torque exceeds 50 units in the opposite direction to ensure limited applied torque against the driver's will. Chrysler/Jeep/Fiat (Lateral only) @@ -133,6 +133,42 @@ Chrysler/Jeep/Fiat (Lateral only) units above the actual EPS generated motor torque to ensure limited differences between commanded and actual torques. +Subaru (Lateral only) +------ + + - While the system is engaged, steer commands are subject to the same limits used by + the stock system. + + - Steering torque is controlled through the 0x122 CAN message and it's limited by the panda firmware and by + openpilot to a value between -255 and 255. In addition, the vehicle EPS unit will fault for + commands outside the values of -2047 and 2047. A steering torque rate limit is enforced by the panda firmware and by + openpilot, so that the commanded steering torque must rise from 0 to max value no faster than + 0.41s. Commanded steering torque is gradually limited by the panda firmware and by openpilot if the driver's + torque exceeds 60 units in the opposite direction to ensure limited applied torque against the + driver's will. + +Volkswagen, Audi, SEAT, Å koda (Lateral only) +------ + + - While the system is engaged, steer commands are subject to the same limits used by the stock system, and + additional limits required to meet Comma safety standards. + + - Steering torque is controlled through the CAN message 0x126, also known as HCA_01 for Heading Control Assist. + It's limited by openpilot and Panda to a value between -250 and 250, representing 2.5 Nm of torque applied + at the steering rack. The vehicle EPS unit will fault for values outside -300 and 300. + + - The vehicle EPS unit will tolerate any rate of increase or decrease, but may limit the effective rate of + change to 5.0 Nm/s. In accordance with the Comma AI safety model requirements, a rate limit is enforced by + the Panda firmware and by openpilot, so that the commanded steering torque cannot rise from 0 to maximum + faster than 1.25s. Commanded steering torque is gradually limited by the Panda firmware and by openpilot + if the driver's torque exceeds 0.8 Nm in the opposite direction to ensure limited applied torque against + the driver's will. + + - Brake and gas pedal pressed signals are contained in the ESP_05 0x106 and Motor_20 0x121 CAN messages, + respectively. A rising edge of either signals triggers a disengagement and is enforced by openpilot. + The cancellation due to the rising edge of the gas pressed signal is also enforced by the Panda firmware. + Additionally, the cruise control system disengages on the rising edge of the brake pedal pressed signal, + and it's enforced by both openpilot and the Panda firmware. **Extra note**: comma.ai strongly discourages the use of openpilot forks with safety code either missing or not fully meeting the above requirements. diff --git a/apk/ai.comma.plus.black.apk b/apk/ai.comma.plus.black.apk index b9243077f351c7..94b3a6a1915a8c 100644 Binary files a/apk/ai.comma.plus.black.apk and b/apk/ai.comma.plus.black.apk differ diff --git a/apk/ai.comma.plus.frame.apk b/apk/ai.comma.plus.frame.apk index 6df46822053c73..bb12c328ba488b 100644 Binary files a/apk/ai.comma.plus.frame.apk and b/apk/ai.comma.plus.frame.apk differ diff --git a/apk/ai.comma.plus.offroad.apk b/apk/ai.comma.plus.offroad.apk index 342f832c2a18ea..d8c84cc6bd2d25 100644 Binary files a/apk/ai.comma.plus.offroad.apk and b/apk/ai.comma.plus.offroad.apk differ diff --git a/cereal/.gitignore b/cereal/.gitignore index 57b5883f38d38d..3f6de09fb90f69 100644 --- a/cereal/.gitignore +++ b/cereal/.gitignore @@ -1,3 +1,6 @@ gen node_modules package-lock.json +*.pyc +__pycache__ + diff --git a/cereal/Makefile b/cereal/Makefile index dc6b7f9d51fa03..83318bef33d0ad 100644 --- a/cereal/Makefile +++ b/cereal/Makefile @@ -6,24 +6,24 @@ GENS := gen/cpp/car.capnp.c++ gen/cpp/log.capnp.c++ JS := gen/js/car.capnp.js gen/js/log.capnp.js UNAME_M ?= $(shell uname -m) -# only generate C++ for docker tests -ifneq ($(OPTEST),1) - GENS += gen/c/car.capnp.c gen/c/log.capnp.c gen/c/include/c++.capnp.h gen/c/include/java.capnp.h - - ifeq ($(UNAME_M),x86_64) - ifneq (, $(shell which capnpc-java)) - GENS += gen/java/Car.java gen/java/Log.java - else - $(warning capnpc-java not found, skipping java build) - endif - endif +GENS += gen/c/car.capnp.c gen/c/log.capnp.c gen/c/include/c++.capnp.h gen/c/include/java.capnp.h + +ifeq ($(UNAME_M),x86_64) + +ifneq (, $(shell which capnpc-java)) +GENS += gen/java/Car.java gen/java/Log.java +else +$(warning capnpc-java not found, skipping java build) endif +endif + + ifeq ($(UNAME_M),aarch64) - CAPNPC=PATH=$(PWD)/../phonelibs/capnp-cpp/aarch64/bin/:$$PATH capnpc +CAPNPC=PATH=$(PWD)/../phonelibs/capnp-cpp/aarch64/bin/:$$PATH capnpc else - CAPNPC=capnpc +CAPNPC=capnpc endif .PHONY: all diff --git a/cereal/car.capnp b/cereal/car.capnp index 8fb312867687cc..c38bc7d312f6eb 100644 --- a/cereal/car.capnp +++ b/cereal/car.capnp @@ -22,7 +22,7 @@ struct CarEvent @0x9b1657f34caf3ad3 { enum EventName @0xbaa8c5d505f727de { # TODO: copy from error list - commIssue @0; + canError @0; steerUnavailable @1; brakeUnavailable @2; gasUnavailable @3; @@ -37,7 +37,7 @@ struct CarEvent @0x9b1657f34caf3ad3 { buttonEnable @12; pedalPressed @13; cruiseDisabled @14; - radarCommIssue @15; + radarCanError @15; dataNeeded @16; speedTooLow @17; outOfSpace @18; @@ -49,7 +49,7 @@ struct CarEvent @0x9b1657f34caf3ad3 { pcmDisable @24; noTarget @25; radarFault @26; - modelCommIssue @27; + modelCommIssueDEPRECATED @27; brakeHold @28; parkBrake @29; manualRestart @30; @@ -73,6 +73,17 @@ struct CarEvent @0x9b1657f34caf3ad3 { lowBattery @48; invalidGiraffeHonda @49; vehicleModelInvalid @50; + controlsFailed @51; + sensorDataInvalid @52; + commIssue @53; + tooDistracted @54; + posenetInvalid @55; + soundsUnavailable @56; + preLaneChangeLeft @57; + preLaneChangeRight @58; + laneChange @59; + invalidGiraffeToyota @60; + internetConnectivityNeeded @61; } } @@ -104,6 +115,7 @@ struct CarState { steeringAngle @7 :Float32; # deg steeringRate @15 :Float32; # deg/s steeringTorque @8 :Float32; # TODO: standardize units + steeringTorqueEps @27 :Float32; # TODO: standardize units steeringPressed @9 :Bool; # if the user is using the steering wheel # cruise state @@ -121,6 +133,10 @@ struct CarState { # lock info doorOpen @24 :Bool; seatbeltUnlatched @25 :Bool; + canValid @26 :Bool; + + # clutch (manual transmission only) + clutchPressed @28 :Bool; # which packets this state came from canMonoTimes @12: List(UInt64); @@ -150,6 +166,8 @@ struct CarState { sport @5; low @6; brake @7; + eco @8; + manumatic @9; } @@ -168,13 +186,16 @@ struct CarState { altButton1 @6; altButton2 @7; altButton3 @8; + setCruise @9; + resumeCruise @10; + gapAdjustCruise @11; } } } # ******* radar state @ 20hz ******* -struct RadarState { +struct RadarData @0x888ad6581cf0aacb { errors @0 :List(Error); points @1 :List(RadarPoint); @@ -182,7 +203,7 @@ struct RadarState { canMonoTimes @2 :List(UInt64); enum Error { - commIssue @0; + canError @0; fault @1; wrongConfig @2; } @@ -247,6 +268,8 @@ struct CarControl { audibleAlert @5: AudibleAlert; rightLaneVisible @6: Bool; leftLaneVisible @7: Bool; + rightLaneDepart @8: Bool; + leftLaneDepart @9: Bool; enum VisualAlert { # these are the choices from the Honda @@ -258,6 +281,7 @@ struct CarControl { wrongGear @4; seatbeltUnbuckled @5; speedTooHigh @6; + ldw @7; } enum AudibleAlert { @@ -279,34 +303,104 @@ struct CarControl { struct CarParams { carName @0 :Text; - radarNameDEPRECATED @1 :Text; - carFingerprint @2 :Text; - - enableSteerDEPRECATED @3 :Bool; - enableGasInterceptor @4 :Bool; - enableBrakeDEPRECATED @5 :Bool; - enableCruise @6 :Bool; - enableCamera @26 :Bool; - enableDsu @27 :Bool; # driving support unit - enableApgs @28 :Bool; # advanced parking guidance system - - minEnableSpeed @17 :Float32; - minSteerSpeed @49 :Float32; - safetyModel @18 :Int16; - safetyParam @41 :Int16; - - steerMaxBP @19 :List(Float32); - steerMaxV @20 :List(Float32); - gasMaxBP @21 :List(Float32); - gasMaxV @22 :List(Float32); - brakeMaxBP @23 :List(Float32); - brakeMaxV @24 :List(Float32); - - longPidDeadzoneBP @32 :List(Float32); - longPidDeadzoneV @33 :List(Float32); - - enum SafetyModels { - # does NOT match board setting + carFingerprint @1 :Text; + + enableGasInterceptor @2 :Bool; + enableCruise @3 :Bool; + enableCamera @4 :Bool; + enableDsu @5 :Bool; # driving support unit + enableApgs @6 :Bool; # advanced parking guidance system + + minEnableSpeed @7 :Float32; + minSteerSpeed @8 :Float32; + safetyModel @9 :SafetyModel; + safetyModelPassive @42 :SafetyModel = noOutput; + safetyParam @10 :Int16; + + steerMaxBP @11 :List(Float32); + steerMaxV @12 :List(Float32); + gasMaxBP @13 :List(Float32); + gasMaxV @14 :List(Float32); + brakeMaxBP @15 :List(Float32); + brakeMaxV @16 :List(Float32); + + + # things about the car in the manual + mass @17 :Float32; # [kg] running weight + wheelbase @18 :Float32; # [m] distance from rear to front axle + centerToFront @19 :Float32; # [m] GC distance to front axle + steerRatio @20 :Float32; # [] ratio between front wheels and steering wheel angles + steerRatioRear @21 :Float32; # [] rear steering ratio wrt front steering (usually 0) + + # things we can derive + rotationalInertia @22 :Float32; # [kg*m2] body rotational inertia + tireStiffnessFront @23 :Float32; # [N/rad] front tire coeff of stiff + tireStiffnessRear @24 :Float32; # [N/rad] rear tire coeff of stiff + + longitudinalTuning @25 :LongitudinalPIDTuning; + lateralTuning :union { + pid @26 :LateralPIDTuning; + indi @27 :LateralINDITuning; + lqr @40 :LateralLQRTuning; + } + + steerLimitAlert @28 :Bool; + + vEgoStopping @29 :Float32; # Speed at which the car goes into stopping state + directAccelControl @30 :Bool; # Does the car have direct accel control or just gas/brake + stoppingControl @31 :Bool; # Does the car allows full control even at lows speeds when stopping + startAccel @32 :Float32; # Required acceleraton to overcome creep braking + steerRateCost @33 :Float32; # Lateral MPC cost on steering rate + steerControlType @34 :SteerControlType; + radarOffCan @35 :Bool; # True when radar objects aren't visible on CAN + + steerActuatorDelay @36 :Float32; # Steering wheel actuator delay in seconds + openpilotLongitudinalControl @37 :Bool; # is openpilot doing the longitudinal control? + carVin @38 :Text; # VIN number queried during fingerprinting + isPandaBlack @39: Bool; + dashcamOnly @41: Bool; + transmissionType @43 :TransmissionType; + + struct LateralPIDTuning { + kpBP @0 :List(Float32); + kpV @1 :List(Float32); + kiBP @2 :List(Float32); + kiV @3 :List(Float32); + kf @4 :Float32; + } + + struct LongitudinalPIDTuning { + kpBP @0 :List(Float32); + kpV @1 :List(Float32); + kiBP @2 :List(Float32); + kiV @3 :List(Float32); + deadzoneBP @4 :List(Float32); + deadzoneV @5 :List(Float32); + } + + + struct LateralINDITuning { + outerLoopGain @0 :Float32; + innerLoopGain @1 :Float32; + timeConstant @2 :Float32; + actuatorEffectiveness @3 :Float32; + } + + struct LateralLQRTuning { + scale @0 :Float32; + ki @1 :Float32; + dcGain @2 :Float32; + + # State space system + a @3 :List(Float32); + b @4 :List(Float32); + c @5 :List(Float32); + + k @6 :List(Float32); # LQR gain + l @7 :List(Float32); # Kalman gain + } + + enum SafetyModel { noOutput @0; honda @1; toyota @2; @@ -319,50 +413,23 @@ struct CarParams { chrysler @9; tesla @10; subaru @11; + gmPassive @12; + mazda @13; + nissan @14; + volkswagen @15; + toyotaIpas @16; + allOutput @17; + gmAscm @18; } - # things about the car in the manual - mass @7 :Float32; # [kg] running weight - wheelbase @8 :Float32; # [m] distance from rear to front axle - centerToFront @9 :Float32; # [m] GC distance to front axle - steerRatio @10 :Float32; # [] ratio between front wheels and steering wheel angles - steerRatioRear @11 :Float32; # [] rear steering ratio wrt front steering (usually 0) - - # things we can derive - rotationalInertia @12 :Float32; # [kg*m2] body rotational inertia - tireStiffnessFront @13 :Float32; # [N/rad] front tire coeff of stiff - tireStiffnessRear @14 :Float32; # [N/rad] rear tire coeff of stiff - - # Kp and Ki for the lateral control - steerKpBP @42 :List(Float32); - steerKpV @43 :List(Float32); - steerKiBP @44 :List(Float32); - steerKiV @45 :List(Float32); - steerKpDEPRECATED @15 :Float32; - steerKiDEPRECATED @16 :Float32; - steerKf @25 :Float32; - - # Kp and Ki for the longitudinal control - longitudinalKpBP @36 :List(Float32); - longitudinalKpV @37 :List(Float32); - longitudinalKiBP @38 :List(Float32); - longitudinalKiV @39 :List(Float32); - - steerLimitAlert @29 :Bool; - - vEgoStopping @30 :Float32; # Speed at which the car goes into stopping state - directAccelControl @31 :Bool; # Does the car have direct accel control or just gas/brake - stoppingControl @34 :Bool; # Does the car allows full control even at lows speeds when stopping - startAccel @35 :Float32; # Required acceleraton to overcome creep braking - steerRateCost @40 :Float32; # Lateral MPC cost on steering rate - steerControlType @46 :SteerControlType; - radarOffCan @47 :Bool; # True when radar objects aren't visible on CAN - - steerActuatorDelay @48 :Float32; # Steering wheel actuator delay in seconds - openpilotLongitudinalControl @50 :Bool; # is openpilot doing the longitudinal control? - enum SteerControlType { torque @0; angle @1; } + + enum TransmissionType { + unknown @0; + automatic @1; + manual @2; + } } diff --git a/cereal/generate_javascript.sh b/cereal/generate_javascript.sh new file mode 100755 index 00000000000000..d6525a64d95eed --- /dev/null +++ b/cereal/generate_javascript.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +rm -r gen/ts +rm -r gen/js + +mkdir gen/ts +mkdir gen/js + +echo "Installing needed npm modules" +npm i capnpc-ts capnp-ts + +capnpc -o node_modules/.bin/capnpc-ts:gen/ts log.capnp car.capnp +capnpc -o node_modules/.bin/capnpc-ts:gen/ts car.capnp + +cat log.capnp | egrep '\([a-zA-Z]*\.[^\s]+\.[^s]+\)' | sed 's/^.*([a-zA-Z]*\.\([a-zA-Z.]*\)).*/\1/' | while read line +do + TOKEN=`echo $line | sed 's/\./_/g'` + ROOT=`echo $line | sed 's/\..*$//g'` + cat gen/ts/log.capnp.ts | grep '^import.*'${TOKEN} + if [[ "$?" == "1" ]] + then + sed -i 's/^\(import {.*\)'${ROOT}'\(,*\) \(.*\)$/\1'${ROOT}', '${TOKEN}'\2 \3/' ./gen/ts/log.capnp.ts + fi +done + +tsc ./gen/ts/* --lib es2015 --outDir ./gen/js diff --git a/cereal/install_capnp.sh b/cereal/install_capnp.sh new file mode 100755 index 00000000000000..b83e1ffda1d221 --- /dev/null +++ b/cereal/install_capnp.sh @@ -0,0 +1,39 @@ +set -e +echo "Installing capnp" + +cd /tmp +VERSION=0.6.1 +wget https://capnproto.org/capnproto-c++-${VERSION}.tar.gz +tar xvf capnproto-c++-${VERSION}.tar.gz +cd capnproto-c++-${VERSION} +CXXFLAGS="-fPIC" ./configure + +make -j4 + +# manually build binaries statically +g++ -std=gnu++11 -I./src -I./src -DKJ_HEADER_WARNINGS -DCAPNP_HEADER_WARNINGS -DCAPNP_INCLUDE_DIR=\"/usr/local/include\" -pthread -O2 -DNDEBUG -pthread -pthread -o .libs/capnp src/capnp/compiler/module-loader.o src/capnp/compiler/capnp.o ./.libs/libcapnpc.a ./.libs/libcapnp.a ./.libs/libkj.a -lpthread -pthread + +g++ -std=gnu++11 -I./src -I./src -DKJ_HEADER_WARNINGS -DCAPNP_HEADER_WARNINGS -DCAPNP_INCLUDE_DIR=\"/usr/local/include\" -pthread -O2 -DNDEBUG -pthread -pthread -o .libs/capnpc-c++ src/capnp/compiler/capnpc-c++.o ./.libs/libcapnp.a ./.libs/libkj.a -lpthread -pthread + +g++ -std=gnu++11 -I./src -I./src -DKJ_HEADER_WARNINGS -DCAPNP_HEADER_WARNINGS -DCAPNP_INCLUDE_DIR=\"/usr/local/include\" -pthread -O2 -DNDEBUG -pthread -pthread -o .libs/capnpc-capnp src/capnp/compiler/capnpc-capnp.o ./.libs/libcapnp.a ./.libs/libkj.a -lpthread -pthread + +cp .libs/capnp /usr/local/bin/ +ln -s /usr/local/bin/capnp /usr/local/bin/capnpc +cp .libs/capnpc-c++ /usr/local/bin/ +cp .libs/capnpc-capnp /usr/local/bin/ +cp .libs/*.a /usr/local/lib + +cd /tmp +echo "Installing c-capnp" +git clone https://github.com/commaai/c-capnproto.git +cd c-capnproto +git submodule update --init --recursive +autoreconf -f -i -s +CXXFLAGS="-fPIC" ./configure +make -j4 + +# manually build binaries statically +gcc -fPIC -o .libs/capnpc-c compiler/capnpc-c.o compiler/schema.capnp.o compiler/str.o ./.libs/libcapnp_c.a + +cp .libs/capnpc-c /usr/local/bin/ +cp .libs/*.a /usr/local/lib diff --git a/cereal/log.capnp b/cereal/log.capnp index 3f79deefe54d33..0fd5155bf691bc 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -150,6 +150,12 @@ struct FrameData { } } +struct Thumbnail { + frameId @0 :UInt32; + timestampEof @1 :UInt64; + thumbnail @2 :Data; +} + struct GPSNMEAData { timestamp @0 :Int64; localWallTime @1 :UInt64; @@ -291,11 +297,35 @@ struct HealthData { # from can health voltage @0 :UInt32; current @1 :UInt32; - started @2 :Bool; + ignitionLine @2 :Bool; controlsAllowed @3 :Bool; gasInterceptorDetected @4 :Bool; - startedSignalDetected @5 :Bool; - isGreyPanda @6 :Bool; + startedSignalDetectedDeprecated @5 :Bool; + hasGps @6 :Bool; + canSendErrs @7 :UInt32; + canFwdErrs @8 :UInt32; + gmlanSendErrs @9 :UInt32; + hwType @10 :HwType; + fanSpeedRpm @11 :UInt16; + usbPowerMode @12 :UsbPowerMode; + ignitionCan @13 :Bool; + safetyModel @14 :Car.CarParams.SafetyModel; + + enum HwType { + unknown @0; + whitePanda @1; + greyPanda @2; + blackPanda @3; + pedal @4; + uno @5; + } + + enum UsbPowerMode { + none @0; + client @1; + cdp @2; + dcp @3; + } } struct LiveUI { @@ -305,12 +335,12 @@ struct LiveUI { awarenessStatus @3 :Float32; } -struct Live20Data { +struct RadarState @0x9a185389d6fdd05f { canMonoTimes @10 :List(UInt64); mdMonoTime @6 :UInt64; ftMonoTimeDEPRECATED @7 :UInt64; - l100MonoTime @11 :UInt64; - radarErrors @12 :List(Car.RadarState.Error); + controlsStateMonoTime @11 :UInt64; + radarErrors @12 :List(Car.RadarData.Error); # all deprecated warpMatrixDEPRECATED @0 :List(Float32); @@ -337,6 +367,8 @@ struct Live20Data { fcw @10 :Bool; status @11 :Bool; aLeadTau @12 :Float32; + modelProb @13 :Float32; + radar @14 :Bool; } } @@ -353,6 +385,8 @@ struct LiveCalibrationData { # view_frame_from_road_frame # ui's is inversed needs new extrinsicMatrix @4 :List(Float32); + # the direction of travel vector in device frame + rpyCalib @7 :List(Float32); } struct LiveTracks { @@ -368,15 +402,15 @@ struct LiveTracks { oncoming @9 :Bool; } -struct Live100Data { +struct ControlsState @0x97ff69c53601abf1 { canMonoTimeDEPRECATED @16 :UInt64; canMonoTimes @21 :List(UInt64); - l20MonoTimeDEPRECATED @17 :UInt64; + radarStateMonoTimeDEPRECATED @17 :UInt64; mdMonoTimeDEPRECATED @18 :UInt64; planMonoTime @28 :UInt64; pathPlanMonoTime @50 :UInt64; - state @31 :ControlState; + state @31 :OpenpilotState; vEgo @0 :Float32; vEgoRaw @32 :Float32; aEgoDEPRECATED @1 :Float32; @@ -388,9 +422,9 @@ struct Live100Data { ufAccelCmd @33 :Float32; yActualDEPRECATED @6 :Float32; yDesDEPRECATED @7 :Float32; - upSteer @8 :Float32; - uiSteer @9 :Float32; - ufSteer @34 :Float32; + upSteerDEPRECATED @8 :Float32; + uiSteerDEPRECATED @9 :Float32; + ufSteerDEPRECATED @34 :Float32; aTargetMinDEPRECATED @10 :Float32; aTargetMaxDEPRECATED @11 :Float32; aTarget @35 :Float32; @@ -417,9 +451,10 @@ struct Live100Data { alertSize @39 :AlertSize; alertBlinkingRate @42 :Float32; alertType @44 :Text; - alertSound @45 :Text; + alertSoundDEPRECATED @45 :Text; + alertSound @56 :Car.CarControl.HUDControl.AudibleAlert; awarenessStatus @26 :Float32; - angleModelBias @27 :Float32; + angleModelBiasDEPRECATED @27 :Float32; gpsPlannerActive @40 :Bool; engageable @41 :Bool; # can OP be engaged? driverMonitoringOn @43 :Bool; @@ -428,7 +463,15 @@ struct Live100Data { vCurvature @46 :Float32; decelForTurn @47 :Bool; - enum ControlState { + decelForModel @54 :Bool; + + lateralControlState :union { + indiState @52 :LateralINDIState; + pidState @53 :LateralPIDState; + lqrState @55 :LateralLQRState; + } + + enum OpenpilotState @0xdbe58b96d2d1ac61 { disabled @0; preEnabled @1; enabled @2; @@ -455,6 +498,40 @@ struct Live100Data { full @3; # full screen } + struct LateralINDIState { + active @0 :Bool; + steerAngle @1 :Float32; + steerRate @2 :Float32; + steerAccel @3 :Float32; + rateSetPoint @4 :Float32; + accelSetPoint @5 :Float32; + accelError @6 :Float32; + delayedOutput @7 :Float32; + delta @8 :Float32; + output @9 :Float32; + } + + struct LateralPIDState { + active @0 :Bool; + steerAngle @1 :Float32; + steerRate @2 :Float32; + angleError @3 :Float32; + p @4 :Float32; + i @5 :Float32; + f @6 :Float32; + output @7 :Float32; + saturated @8 :Bool; + } + + struct LateralLQRState { + active @0 :Bool; + steerAngle @1 :Float32; + i @2 :Float32; + output @3 :Float32; + lqrOutput @4 :Float32; + } + + } struct LiveEventData { @@ -464,6 +541,7 @@ struct LiveEventData { struct ModelData { frameId @0 :UInt32; + timestampEof @9 :UInt64; path @1 :PathData; leftLane @2 :PathData; @@ -472,17 +550,27 @@ struct ModelData { freePath @6 :List(Float32); settings @5 :ModelSettings; + leadFuture @7 :LeadData; + speed @8 :List(Float32); struct PathData { points @0 :List(Float32); prob @1 :Float32; std @2 :Float32; + stds @3 :List(Float32); + poly @4 :List(Float32); } struct LeadData { dist @0 :Float32; prob @1 :Float32; std @2 :Float32; + relVel @3 :Float32; + relVelStd @4 :Float32; + relY @5 :Float32; + relYStd @6 :Float32; + relA @7 :Float32; + relAStd @8 :Float32; } struct ModelSettings { @@ -544,8 +632,10 @@ struct LogRotate { struct Plan { mdMonoTime @9 :UInt64; - l20MonoTime @10 :UInt64; - events @13 :List(Car.CarEvent); + radarStateMonoTime @10 :UInt64; + commIssue @31 :Bool; + + eventsDEPRECATED @13 :List(Car.CarEvent); # lateral, 3rd order polynomial lateralValidDEPRECATED @0 :Bool; @@ -583,6 +673,7 @@ struct Plan { decelForTurn @22 :Bool; mapValid @25 :Bool; radarValid @28 :Bool; + radarCanError @30 :Bool; processingDelay @29 :Float32; @@ -597,6 +688,7 @@ struct Plan { mpc1 @1; mpc2 @2; mpc3 @3; + model @4; } } @@ -613,10 +705,39 @@ struct PathPlan { angleSteers @8 :Float32; # deg rateSteers @13 :Float32; # deg/s - valid @9 :Bool; + mpcSolutionValid @9 :Bool; paramsValid @10 :Bool; - modelValid @12 :Bool; + modelValidDEPRECATED @12 :Bool; angleOffset @11 :Float32; + sensorValid @14 :Bool; + commIssue @15 :Bool; + posenetValid @16 :Bool; + desire @17 :Desire; + laneChangeState @18 :LaneChangeState; + laneChangeDirection @19 :LaneChangeDirection; + + enum Desire { + none @0; + turnLeft @1; + turnRight @2; + laneChangeLeft @3; + laneChangeRight @4; + keepLeft @5; + keepRight @6; + } + + enum LaneChangeState { + off @0; + preLaneChange @1; + laneChangeStarting @2; + laneChangeFinishing @3; + } + + enum LaneChangeDirection { + none @0; + left @1; + right @2; + } } struct LiveLocationData { @@ -1595,8 +1716,16 @@ struct OrbKeyFrame { struct DriverMonitoring { frameId @0 :UInt32; - descriptor @1 :List(Float32); - std @2 :Float32; + descriptorDEPRECATED @1 :List(Float32); + stdDEPRECATED @2 :Float32; + faceOrientation @3 :List(Float32); + facePosition @4 :List(Float32); + faceProb @5 :Float32; + leftEyeProb @6 :Float32; + rightEyeProb @7 :Float32; + leftBlinkProb @8 :Float32; + rightBlinkProb @9 :Float32; + irPwr @10 :Float32; } struct Boot { @@ -1612,6 +1741,10 @@ struct LiveParametersData { angleOffsetAverage @3 :Float32; stiffnessFactor @4 :Float32; steerRatio @5 :Float32; + sensorValid @6 :Bool; + yawRate @7 :Float32; + posenetSpeed @8 :Float32; + posenetValid @9 :Bool; } struct LiveMapData { @@ -1635,6 +1768,8 @@ struct LiveMapData { } struct CameraOdometry { + frameId @4 :UInt32; + timestampEof @5 :UInt64; trans @0 :List(Float32); # m/s in device frame rot @1 :List(Float32); # rad/s in device frame transStd @2 :List(Float32); # std m/s in device frame @@ -1651,6 +1786,7 @@ struct KalmanOdometry { struct Event { # in nanoseconds? logMonoTime @0 :UInt64; + valid @67 :Bool = true; union { initData @1 :InitData; @@ -1659,13 +1795,13 @@ struct Event { sensorEventDEPRECATED @4 :SensorEventData; can @5 :List(CanData); thermal @6 :ThermalData; - live100 @7 :Live100Data; + controlsState @7 :ControlsState; liveEventDEPRECATED @8 :List(LiveEventData); model @9 :ModelData; features @10 :CalibrationFeatures; sensorEvents @11 :List(SensorEventData); health @12 :HealthData; - live20 @13 :Live20Data; + radarState @13 :RadarState; liveUIDEPRECATED @14 :LiveUI; encodeIdx @15 :EncodeIndex; liveTracks @16 :List(LiveTracks); @@ -1718,5 +1854,8 @@ struct Event { cameraOdometry @63 :CameraOdometry; pathPlan @64 :PathPlan; kalmanOdometry @65 :KalmanOdometry; + thumbnail @66: Thumbnail; + carEvents @68: List(Car.CarEvent); + carParams @69: Car.CarParams; } } diff --git a/cereal/maptile.capnp b/cereal/maptile.capnp new file mode 100644 index 00000000000000..336901392aa306 --- /dev/null +++ b/cereal/maptile.capnp @@ -0,0 +1,53 @@ +using Cxx = import "./include/c++.capnp"; +$Cxx.namespace("cereal"); + +using Java = import "./include/java.capnp"; +$Java.package("ai.comma.openpilot.cereal"); +$Java.outerClassname("Map"); + +@0xa086df597ef5d7a0; + +# Geometry +struct Point { + x @0: Float64; + y @1: Float64; + z @2: Float64; +} + +struct PolyLine { + points @0: List(Point); +} + +# Map features +struct Lane { + id @0 :Text; + + leftBoundary @1 :LaneBoundary; + rightBoundary @2 :LaneBoundary; + + leftAdjacentId @3 :Text; + rightAdjacentId @4 :Text; + + inboundIds @5 :List(Text); + outboundIds @6 :List(Text); + + struct LaneBoundary { + polyLine @0 :PolyLine; + startHeading @1 :Float32; # WRT north + } +} + +# Map tiles +struct TileSummary { + version @0 :Text; + updatedAt @1 :UInt64; # Millis since epoch + + level @2 :UInt8; + x @3 :UInt16; + y @4 :UInt16; +} + +struct MapTile { + summary @0 :TileSummary; + lanes @1 :List(Lane); +} diff --git a/check_code_quality.sh b/check_code_quality.sh new file mode 100644 index 00000000000000..aed17230eb243d --- /dev/null +++ b/check_code_quality.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +# Only pyflakes checks (--select=F) +flake8 --select=F $(find . -iname "*.py" | grep -vi "^\./pyextra.*" | grep -vi "^\./panda") +RESULT=$? +if [ $RESULT -eq 0 ]; then + pylint $(find . -iname "*.py" | grep -vi "^\./pyextra.*" | grep -vi "^\./panda") + RESULT=$? & 3 +fi + +[ $RESULT -ne 0 ] && exit 1 +exit 0 diff --git a/common/api/__init__.py b/common/api/__init__.py index 2dc2ffa990533b..b27520738e2f93 100644 --- a/common/api/__init__.py +++ b/common/api/__init__.py @@ -1,7 +1,34 @@ +import jwt import requests +from datetime import datetime, timedelta from selfdrive.version import version +class Api(): + def __init__(self, dongle_id): + self.dongle_id = dongle_id + with open('/persist/comma/id_rsa') as f: + self.private_key = f.read() + + def get(self, *args, **kwargs): + return self.request('GET', *args, **kwargs) + + def post(self, *args, **kwargs): + return self.request('POST', *args, **kwargs) + + def request(self, method, endpoint, timeout=None, access_token=None, **params): + return api_get(endpoint, method=method, timeout=timeout, access_token=access_token, **params) + + def get_token(self): + now = datetime.utcnow() + payload = { + 'identity': self.dongle_id, + 'nbf': now, + 'iat': now, + 'exp': now + timedelta(hours=1) + } + return jwt.encode(payload, self.private_key, algorithm='RS256').decode('utf8') + def api_get(endpoint, method='GET', timeout=None, access_token=None, **params): backend = "https://api.commadotai.com/" diff --git a/common/clock.pyx b/common/clock.pyx new file mode 100644 index 00000000000000..6205eca10c2d54 --- /dev/null +++ b/common/clock.pyx @@ -0,0 +1,16 @@ +from posix.time cimport clock_gettime, timespec, CLOCK_BOOTTIME, CLOCK_MONOTONIC_RAW + +cdef double readclock(int clock_id): + cdef timespec ts + cdef double current + + clock_gettime(clock_id, &ts) + current = ts.tv_sec + (ts.tv_nsec / 1000000000.) + return current + + +def monotonic_time(): + return readclock(CLOCK_MONOTONIC_RAW) + +def sec_since_boot(): + return readclock(CLOCK_BOOTTIME) diff --git a/common/cython_hacks.py b/common/cython_hacks.py new file mode 100644 index 00000000000000..d0e154746d3455 --- /dev/null +++ b/common/cython_hacks.py @@ -0,0 +1,23 @@ +import os +import sysconfig +from Cython.Distutils import build_ext + +def get_ext_filename_without_platform_suffix(filename): + name, ext = os.path.splitext(filename) + ext_suffix = sysconfig.get_config_var('EXT_SUFFIX') + + if ext_suffix == ext: + return filename + + ext_suffix = ext_suffix.replace(ext, '') + idx = name.find(ext_suffix) + + if idx == -1: + return filename + else: + return name[:idx] + ext + +class BuildExtWithoutPlatformSuffix(build_ext): + def get_ext_filename(self, ext_name): + filename = super().get_ext_filename(ext_name) + return get_ext_filename_without_platform_suffix(filename) diff --git a/common/dbc.py b/common/dbc.py index 6accad43f82bec..aa52e40671aca2 100755 --- a/common/dbc.py +++ b/common/dbc.py @@ -7,9 +7,9 @@ def int_or_float(s): # return number, trying to maintain int format - try: - return int(s) - except ValueError: + if s.isdigit(): + return int(s, 10) + else: return float(s) DBCSignal = namedtuple( @@ -17,11 +17,11 @@ def int_or_float(s): "factor", "offset", "tmin", "tmax", "units"]) -class dbc(object): +class dbc(): def __init__(self, fn): self.name, _ = os.path.splitext(os.path.basename(fn)) - with open(fn) as f: - self.txt = f.read().split("\n") + with open(fn, encoding="ascii") as f: + self.txt = f.readlines() self._warned_addresses = set() # regexps from https://github.com/ebroecker/canmatrix/blob/master/canmatrix/importdbc.py @@ -41,7 +41,7 @@ def __init__(self, fn): self.def_vals = defaultdict(list) # lookup to bit reverse each byte - self.bits_index = [(i & ~0b111) + ((-i-1) & 0b111) for i in xrange(64)] + self.bits_index = [(i & ~0b111) + ((-i-1) & 0b111) for i in range(64)] for l in self.txt: l = l.strip() @@ -51,7 +51,8 @@ def __init__(self, fn): dat = bo_regexp.match(l) if dat is None: - print "bad BO", l + print("bad BO {0}".format(l)) + name = dat.group(2) size = int(dat.group(3)) ids = int(dat.group(1), 0) # could be hex @@ -67,8 +68,9 @@ def __init__(self, fn): if dat is None: dat = sgm_regexp.match(l) go = 1 + if dat is None: - print "bad SG", l + print("bad SG {0}".format(l)) sgname = dat.group(1) start_bit = int(dat.group(go+2)) @@ -90,26 +92,22 @@ def __init__(self, fn): dat = val_regexp.match(l) if dat is None: - print "bad VAL", l + print("bad VAL {0}".format(l)) + ids = int(dat.group(1), 0) # could be hex sgname = dat.group(2) defvals = dat.group(3) - defvals = defvals.replace("?","\?") #escape sequence in C++ + defvals = defvals.replace("?",r"\?") #escape sequence in C++ defvals = defvals.split('"')[:-1] - defs = defvals[1::2] - #cleanup, convert to UPPER_CASE_WITH_UNDERSCORES - for i,d in enumerate(defs): - d = defs[i].strip().upper() - defs[i] = d.replace(" ","_") - - defvals[1::2] = defs + # convert strings to UPPER_CASE_WITH_UNDERSCORES + defvals[1::2] = [d.strip().upper().replace(" ","_") for d in defvals[1::2]] defvals = '"'+"".join(str(i) for i in defvals)+'"' self.def_vals[ids].append((sgname, defvals)) - for msg in self.msgs.viewvalues(): + for msg in self.msgs.values(): msg[1].sort(key=lambda x: x.start_bit) self.msg_name_to_address = {} @@ -149,22 +147,20 @@ def encode(self, msg_id, dd): ival = dd.get(s.name) if ival is not None: - b2 = s.size - if s.is_little_endian: - b1 = s.start_bit - else: - b1 = (s.start_bit // 8) * 8 + (-s.start_bit - 1) % 8 - bo = 64 - (b1 + s.size) - ival = (ival / s.factor) - s.offset ival = int(round(ival)) if s.is_signed and ival < 0: - ival = (1 << b2) + ival + ival = (1 << s.size) + ival - shift = b1 if s.is_little_endian else bo - mask = ((1 << b2) - 1) << shift - dat = (ival & ((1 << b2) - 1)) << shift + if s.is_little_endian: + shift = s.start_bit + else: + b1 = (s.start_bit // 8) * 8 + (-s.start_bit - 1) % 8 + shift = 64 - (b1 + s.size) + + mask = ((1 << s.size) - 1) << shift + dat = (ival & ((1 << s.size) - 1)) << shift if s.is_little_endian: mask = self.reverse_bytes(mask) @@ -208,9 +204,9 @@ def decode(self, x, arr=None, debug=False): name = msg[0][0] if debug: - print name + print(name) - st = x[2].ljust(8, '\x00') + st = x[2].ljust(8, b'\x00') le, be = None, None for s in msg[1]: @@ -224,35 +220,29 @@ def decode(self, x, arr=None, debug=False): factor = s[5] offset = s[6] - b2 = signal_size - if little_endian: - b1 = start_bit - else: - b1 = (start_bit // 8) * 8 + (-start_bit - 1) % 8 - bo = 64 - (b1 + signal_size) - if little_endian: if le is None: le = struct.unpack("Q", st)[0] - shift_amount = bo tmp = be + b1 = (start_bit // 8) * 8 + (-start_bit - 1) % 8 + shift_amount = 64 - (b1 + signal_size) if shift_amount < 0: continue - tmp = (tmp >> shift_amount) & ((1 << b2) - 1) - if signed and (tmp >> (b2 - 1)): - tmp -= (1 << b2) + tmp = (tmp >> shift_amount) & ((1 << signal_size) - 1) + if signed and (tmp >> (signal_size - 1)): + tmp -= (1 << signal_size) tmp = tmp * factor + offset # if debug: - # print "%40s %2d %2d %7.2f %s" % (s[0], s[1], s[2], tmp, s[-1]) + # print("%40s %2d %2d %7.2f %s" % (s[0], s[1], s[2], tmp, s[-1])) if arr is None: out[s[0]] = tmp diff --git a/common/ffi_wrapper.py b/common/ffi_wrapper.py index fd6b2bf7b3706e..2c169881cee7af 100644 --- a/common/ffi_wrapper.py +++ b/common/ffi_wrapper.py @@ -4,14 +4,12 @@ import hashlib from cffi import FFI -TMPDIR = "/tmp/ccache" - -def ffi_wrap(name, c_code, c_header, tmpdir=TMPDIR, cflags="", libraries=None): +def ffi_wrap(name, c_code, c_header, tmpdir="/tmp/ccache", cflags="", libraries=None): if libraries is None: libraries = [] - cache = name + "_" + hashlib.sha1(c_code).hexdigest() + cache = name + "_" + hashlib.sha1(c_code.encode('utf-8')).hexdigest() try: os.mkdir(tmpdir) except OSError: @@ -24,7 +22,7 @@ def ffi_wrap(name, c_code, c_header, tmpdir=TMPDIR, cflags="", libraries=None): try: mod = __import__(cache) except Exception: - print "cache miss", cache + print("cache miss {0}".format(cache)) compile_code(cache, c_code, c_header, tmpdir, cflags, libraries) mod = __import__(cache) finally: diff --git a/common/file_helpers.py b/common/file_helpers.py new file mode 100644 index 00000000000000..40c89fab0ead25 --- /dev/null +++ b/common/file_helpers.py @@ -0,0 +1,109 @@ +import os +import shutil +import tempfile +from atomicwrites import AtomicWriter + +def mkdirs_exists_ok(path): + try: + os.makedirs(path) + except OSError: + if not os.path.isdir(path): + raise + +def rm_not_exists_ok(path): + try: + os.remove(path) + except OSError: + if os.path.exists(path): + raise + +def rm_tree_or_link(path): + if os.path.islink(path): + os.unlink(path) + elif os.path.isdir(path): + shutil.rmtree(path) + +def get_tmpdir_on_same_filesystem(path): + normpath = os.path.normpath(path) + parts = normpath.split("/") + if len(parts) > 1 and parts[1] == "scratch": + return "/scratch/tmp" + elif len(parts) > 2 and parts[2] == "runner": + return "/{}/runner/tmp".format(parts[1]) + return "/tmp" + +class AutoMoveTempdir(): + def __init__(self, target_path, temp_dir=None): + self._target_path = target_path + self._path = tempfile.mkdtemp(dir=temp_dir) + + @property + def name(self): + return self._path + + def close(self): + os.rename(self._path, self._target_path) + + def __enter__(self): return self + + def __exit__(self, type, value, traceback): + if type is None: + self.close() + else: + shutil.rmtree(self._path) + +class NamedTemporaryDir(): + def __init__(self, temp_dir=None): + self._path = tempfile.mkdtemp(dir=temp_dir) + + @property + def name(self): + return self._path + + def close(self): + shutil.rmtree(self._path) + + def __enter__(self): return self + + def __exit__(self, type, value, traceback): + self.close() + +def _get_fileobject_func(writer, temp_dir): + def _get_fileobject(): + file_obj = writer.get_fileobject(dir=temp_dir) + os.chmod(file_obj.name, 0o644) + return file_obj + return _get_fileobject + +def atomic_write_on_fs_tmp(path, **kwargs): + """Creates an atomic writer using a temporary file in a temporary directory + on the same filesystem as path. + """ + # TODO(mgraczyk): This use of AtomicWriter relies on implementation details to set the temp + # directory. + writer = AtomicWriter(path, **kwargs) + return writer._open(_get_fileobject_func(writer, get_tmpdir_on_same_filesystem(path))) + + +def atomic_write_in_dir(path, **kwargs): + """Creates an atomic writer using a temporary file in the same directory + as the destination file. + """ + writer = AtomicWriter(path, **kwargs) + return writer._open(_get_fileobject_func(writer, os.path.dirname(path))) + +def atomic_write_in_dir_neos(path, contents, mode=None): + """ + Atomically writes contents to path using a temporary file in the same directory + as path. Useful on NEOS, where `os.link` (required by atomic_write_in_dir) is missing. + """ + + f = tempfile.NamedTemporaryFile(delete=False, prefix=".tmp", dir=os.path.dirname(path)) + f.write(contents) + f.flush() + if mode is not None: + os.fchmod(f.fileno(), mode) + os.fsync(f.fileno()) + f.close() + + os.rename(f.name, path) diff --git a/common/kalman/Makefile b/common/kalman/Makefile new file mode 100644 index 00000000000000..df748197f23cec --- /dev/null +++ b/common/kalman/Makefile @@ -0,0 +1,10 @@ +all: simple_kalman_impl.so + +simple_kalman_impl.so: simple_kalman_impl.pyx simple_kalman_impl.pxd simple_kalman_setup.py + python3 simple_kalman_setup.py build_ext --inplace + rm -rf build + rm simple_kalman_impl.c + +.PHONY: clean +clean: + rm -f simple_kalman_impl.so diff --git a/common/kalman/ekf.py b/common/kalman/ekf.py deleted file mode 100644 index fbed218f7a7b38..00000000000000 --- a/common/kalman/ekf.py +++ /dev/null @@ -1,253 +0,0 @@ -# pylint: skip-file -from __future__ import print_function -import abc -import numpy as np -# The EKF class contains the framework for an Extended Kalman Filter, but must be subclassed to use. -# A subclass must implement: -# 1) calc_transfer_fun(); see bottom of file for more info. -# 2) __init__() to initialize self.state, self.covar, and self.process_noise appropriately - -# Alternatively, the existing implementations of EKF can be used (e.g. EKF2D) - -# Sensor classes are optionally used to pass measurement information into the EKF, to keep -# sensor parameters and processing methods for a each sensor together. -# Sensor classes have a read() method which takes raw sensor data and returns -# a SensorReading object, which can be passed to the EKF update() method. - -# For usage, see run_ekf1d.py in selfdrive/new for a simple example. -# ekf.predict(dt) should be called between update cycles with the time since it was last called. -# Ideally, predict(dt) should be called at a relatively constant rate. -# update() should be called once per sensor, and can be called multiple times between predict steps. -# Access and set the state of the filter directly with ekf.state and ekf.covar. - - -class SensorReading: - # Given a perfect model and no noise, data = obs_model * state - def __init__(self, data, covar, obs_model): - self.data = data - self.obs_model = obs_model - self.covar = covar - - def __repr__(self): - return "SensorReading(data={}, covar={}, obs_model={})".format( - repr(self.data), repr(self.covar), repr(self.obs_model)) - - -# A generic sensor class that does no pre-processing of data -class SimpleSensor: - # obs_model can be - # a full observation model matrix, or - # an integer or tuple of indices into ekf.state, indicating which variables are being directly observed - # covar can be - # a full covariance matrix - # a float or tuple of individual covars for each component of the sensor reading - # dims is the number of states in the EKF - def __init__(self, obs_model, covar, dims): - # Allow for integer covar/obs_model - if not hasattr(obs_model, "__len__"): - obs_model = (obs_model, ) - if not hasattr(covar, "__len__"): - covar = (covar, ) - - # Full observation model passed - if dims in np.array(obs_model).shape: - self.obs_model = np.asmatrix(obs_model) - self.covar = np.asmatrix(covar) - # Indices of unit observations passed - else: - self.obs_model = np.matlib.zeros((len(obs_model), dims)) - self.obs_model[:, list(obs_model)] = np.identity(len(obs_model)) - if np.asarray(covar).ndim == 2: - self.covar = np.asmatrix(covar) - elif len(covar) == len(obs_model): - self.covar = np.matlib.diag(covar) - else: - self.covar = np.matlib.identity(len(obs_model)) * covar - - def read(self, data, covar=None): - if covar: - self.covar = covar - return SensorReading(data, self.covar, self.obs_model) - - -class EKF: - __metaclass__ = abc.ABCMeta - - def __init__(self, debug=False): - self.DEBUG = debug - - - def __str__(self): - return "EKF(state={}, covar={})".format(self.state, self.covar) - - # Measurement update - # Reading should be a SensorReading object with data, covar, and obs_model attributes - def update(self, reading): - # Potential improvements: - # deal with negative covars - # add noise to really low covars to ensure stability - # use mahalanobis distance to reject outliers - # wrap angles after state updates and innovation - - # y = z - H*x - innovation = reading.data - reading.obs_model * self.state - - if self.DEBUG: - print("reading:\n",reading.data) - print("innovation:\n",innovation) - - # S = H*P*H' + R - innovation_covar = reading.obs_model * self.covar * reading.obs_model.T + reading.covar - - # K = P*H'*S^-1 - kalman_gain = self.covar * reading.obs_model.T * np.linalg.inv( - innovation_covar) - - if self.DEBUG: - print("gain:\n", kalman_gain) - print("innovation_covar:\n", innovation_covar) - print("innovation: ", innovation) - print("test: ", self.covar * reading.obs_model.T * ( - reading.obs_model * self.covar * reading.obs_model.T + reading.covar * - 0).I) - - # x = x + K*y - self.state += kalman_gain*innovation - - # print "covar", np.diag(self.covar) - #self.state[(roll_vel, yaw_vel, pitch_vel),:] = reading.data - - # Standard form: P = (I - K*H)*P - # self.covar = (self.identity - kalman_gain*reading.obs_model) * self.covar - - # Use the Joseph form for numerical stability: P = (I-K*H)*P*(I - K*H)' + K*R*K' - aux_mtrx = (self.identity - kalman_gain * reading.obs_model) - self.covar = aux_mtrx * self.covar * aux_mtrx.T + kalman_gain * reading.covar * kalman_gain.T - - if self.DEBUG: - print("After update") - print("state\n", self.state) - print("covar:\n",self.covar) - - def update_scalar(self, reading): - # like update but knowing that measurement is a scalar - # this avoids matrix inversions and speeds up (surprisingly) drived.py a lot - - # innovation = reading.data - np.matmul(reading.obs_model, self.state) - # innovation_covar = np.matmul(np.matmul(reading.obs_model, self.covar), reading.obs_model.T) + reading.covar - # kalman_gain = np.matmul(self.covar, reading.obs_model.T)/innovation_covar - # self.state += np.matmul(kalman_gain, innovation) - # aux_mtrx = self.identity - np.matmul(kalman_gain, reading.obs_model) - # self.covar = np.matmul(aux_mtrx, np.matmul(self.covar, aux_mtrx.T)) + np.matmul(kalman_gain, np.matmul(reading.covar, kalman_gain.T)) - - # written without np.matmul - es = np.einsum - ABC_T = "ij,jk,lk->il" - AB_T = "ij,kj->ik" - AB = "ij,jk->ik" - innovation = reading.data - es(AB, reading.obs_model, self.state) - innovation_covar = es(ABC_T, reading.obs_model, self.covar, - reading.obs_model) + reading.covar - kalman_gain = es(AB_T, self.covar, reading.obs_model) / innovation_covar - - self.state += es(AB, kalman_gain, innovation) - aux_mtrx = self.identity - es(AB, kalman_gain, reading.obs_model) - self.covar = es(ABC_T, aux_mtrx, self.covar, aux_mtrx) + \ - es(ABC_T, kalman_gain, reading.covar, kalman_gain) - - # Prediction update - def predict(self, dt): - es = np.einsum - ABC_T = "ij,jk,lk->il" - AB = "ij,jk->ik" - - # State update - transfer_fun, transfer_fun_jacobian = self.calc_transfer_fun(dt) - - # self.state = np.matmul(transfer_fun, self.state) - # self.covar = np.matmul(np.matmul(transfer_fun_jacobian, self.covar), transfer_fun_jacobian.T) + self.process_noise * dt - - # x = f(x, u), written in the form x = A(x, u)*x - self.state = es(AB, transfer_fun, self.state) - - # P = J*P*J' + Q - self.covar = es(ABC_T, transfer_fun_jacobian, self.covar, - transfer_fun_jacobian) + self.process_noise * dt #!dt - - #! Clip covariance to avoid explosions - self.covar = np.clip(self.covar,-1e10,1e10) - - @abc.abstractmethod - def calc_transfer_fun(self, dt): - """Return a tuple with the transfer function and transfer function jacobian - The transfer function and jacobian should both be a numpy matrix of size DIMSxDIMS - - The transfer function matrix A should satisfy the state-update equation - x_(k+1) = A * x_k - - The jacobian J is the direct jacobian A*x_k. For linear systems J=A. - - Current implementations calculate A and J as functions of state. Control input - can be added trivially by adding a control parameter to predict() and calc_tranfer_update(), - and using it during calculation of A and J - """ - - -class FastEKF1D(EKF): - """Fast version of EKF for 1D problems with scalar readings.""" - - def __init__(self, dt, var_init, Q): - super(FastEKF1D, self).__init__(False) - self.state = [0, 0] - self.covar = [var_init, var_init, 0] - - # Process Noise - self.dtQ0 = dt * Q[0] - self.dtQ1 = dt * Q[1] - - def update(self, reading): - raise NotImplementedError - - def update_scalar(self, reading): - # TODO(mgraczyk): Delete this for speed. - # assert np.all(reading.obs_model == [1, 0]) - - rcov = reading.covar[0, 0] - - x = self.state - S = self.covar - - innovation = reading.data - x[0] - innovation_covar = S[0] + rcov - - k0 = S[0] / innovation_covar - k1 = S[2] / innovation_covar - - x[0] += k0 * innovation - x[1] += k1 * innovation - - mk = 1 - k0 - S[1] += k1 * (k1 * (S[0] + rcov) - 2 * S[2]) - S[2] = mk * (S[2] - k1 * S[0]) + rcov * k0 * k1 - S[0] = mk * mk * S[0] + rcov * k0 * k0 - - def predict(self, dt): - # State update - x = self.state - - x[0] += dt * x[1] - - # P = J*P*J' + Q - S = self.covar - S[0] += dt * (2 * S[2] + dt * S[1]) + self.dtQ0 - S[2] += dt * S[1] - S[1] += self.dtQ1 - - # Clip covariance to avoid explosions - S = max(-1e10, min(S, 1e10)) - - def calc_transfer_fun(self, dt): - tf = np.identity(2) - tf[0, 1] = dt - tfj = tf - return tf, tfj diff --git a/common/kalman/simple_kalman.py b/common/kalman/simple_kalman.py index 3f7d049cc55342..b6fdb7da2c829b 100644 --- a/common/kalman/simple_kalman.py +++ b/common/kalman/simple_kalman.py @@ -1,23 +1,9 @@ -import numpy as np +# pylint: skip-file +import os +import subprocess +kalman_dir = os.path.dirname(os.path.abspath(__file__)) +subprocess.check_call(["make", "simple_kalman_impl.so"], cwd=kalman_dir) -class KF1D: - # this EKF assumes constant covariance matrix, so calculations are much simpler - # the Kalman gain also needs to be precomputed using the control module - - def __init__(self, x0, A, C, K): - self.x = x0 - self.A = A - self.C = C - self.K = K - - self.A_K = self.A - np.dot(self.K, self.C) - - # K matrix needs to be pre-computed as follow: - # import control - # (x, l, K) = control.dare(np.transpose(self.A), np.transpose(self.C), Q, R) - # self.K = np.transpose(K) - - def update(self, meas): - self.x = np.dot(self.A_K, self.x) + np.dot(self.K, meas) - return self.x +from .simple_kalman_impl import KF1D as KF1D +assert KF1D diff --git a/common/kalman/simple_kalman_impl.pxd b/common/kalman/simple_kalman_impl.pxd new file mode 100644 index 00000000000000..c81f959272610f --- /dev/null +++ b/common/kalman/simple_kalman_impl.pxd @@ -0,0 +1,16 @@ +cdef class KF1D: + cdef public: + double x0_0 + double x1_0 + double K0_0 + double K1_0 + double A0_0 + double A0_1 + double A1_0 + double A1_1 + double C0_0 + double C0_1 + double A_K_0 + double A_K_1 + double A_K_2 + double A_K_3 \ No newline at end of file diff --git a/common/kalman/simple_kalman_impl.pyx b/common/kalman/simple_kalman_impl.pyx new file mode 100644 index 00000000000000..e65efd577e6b63 --- /dev/null +++ b/common/kalman/simple_kalman_impl.pyx @@ -0,0 +1,36 @@ +# cython: language_level=3 + +cdef class KF1D: + def __init__(self, x0, A, C, K): + self.x0_0 = x0[0][0] + self.x1_0 = x0[1][0] + self.A0_0 = A[0][0] + self.A0_1 = A[0][1] + self.A1_0 = A[1][0] + self.A1_1 = A[1][1] + self.C0_0 = C[0] + self.C0_1 = C[1] + self.K0_0 = K[0][0] + self.K1_0 = K[1][0] + + self.A_K_0 = self.A0_0 - self.K0_0 * self.C0_0 + self.A_K_1 = self.A0_1 - self.K0_0 * self.C0_1 + self.A_K_2 = self.A1_0 - self.K1_0 * self.C0_0 + self.A_K_3 = self.A1_1 - self.K1_0 * self.C0_1 + + def update(self, meas): + cdef double x0_0 = self.A_K_0 * self.x0_0 + self.A_K_1 * self.x1_0 + self.K0_0 * meas + cdef double x1_0 = self.A_K_2 * self.x0_0 + self.A_K_3 * self.x1_0 + self.K1_0 * meas + self.x0_0 = x0_0 + self.x1_0 = x1_0 + + return [self.x0_0, self.x1_0] + + @property + def x(self): + return [[self.x0_0], [self.x1_0]] + + @x.setter + def x(self, x): + self.x0_0 = x[0][0] + self.x1_0 = x[1][0] diff --git a/common/kalman/simple_kalman_old.py b/common/kalman/simple_kalman_old.py new file mode 100644 index 00000000000000..3f7d049cc55342 --- /dev/null +++ b/common/kalman/simple_kalman_old.py @@ -0,0 +1,23 @@ +import numpy as np + + +class KF1D: + # this EKF assumes constant covariance matrix, so calculations are much simpler + # the Kalman gain also needs to be precomputed using the control module + + def __init__(self, x0, A, C, K): + self.x = x0 + self.A = A + self.C = C + self.K = K + + self.A_K = self.A - np.dot(self.K, self.C) + + # K matrix needs to be pre-computed as follow: + # import control + # (x, l, K) = control.dare(np.transpose(self.A), np.transpose(self.C), Q, R) + # self.K = np.transpose(K) + + def update(self, meas): + self.x = np.dot(self.A_K, self.x) + np.dot(self.K, meas) + return self.x diff --git a/common/kalman/simple_kalman_setup.py b/common/kalman/simple_kalman_setup.py new file mode 100644 index 00000000000000..b7cad0ee2a27f3 --- /dev/null +++ b/common/kalman/simple_kalman_setup.py @@ -0,0 +1,9 @@ +from distutils.core import Extension, setup # pylint: disable=import-error,no-name-in-module + +from Cython.Build import cythonize + +from common.cython_hacks import BuildExtWithoutPlatformSuffix + +setup(name='Simple Kalman Implementation', + cmdclass={'build_ext': BuildExtWithoutPlatformSuffix}, + ext_modules=cythonize(Extension("simple_kalman_impl", ["simple_kalman_impl.pyx"]))) diff --git a/pyextra/gunicorn/instrument/__init__.py b/common/kalman/tests/__init__.py similarity index 100% rename from pyextra/gunicorn/instrument/__init__.py rename to common/kalman/tests/__init__.py diff --git a/common/kalman/tests/test_simple_kalman.py b/common/kalman/tests/test_simple_kalman.py new file mode 100644 index 00000000000000..c1f9f7b03cd573 --- /dev/null +++ b/common/kalman/tests/test_simple_kalman.py @@ -0,0 +1,85 @@ +import unittest +import random +import timeit +import numpy as np + +from common.kalman.simple_kalman import KF1D +from common.kalman.simple_kalman_old import KF1D as KF1D_old + + +class TestSimpleKalman(unittest.TestCase): + def setUp(self): + dt = 0.01 + x0_0 = 0.0 + x1_0 = 0.0 + A0_0 = 1.0 + A0_1 = dt + A1_0 = 0.0 + A1_1 = 1.0 + C0_0 = 1.0 + C0_1 = 0.0 + K0_0 = 0.12287673 + K1_0 = 0.29666309 + + self.kf_old = KF1D_old(x0=np.matrix([[x0_0], [x1_0]]), + A=np.matrix([[A0_0, A0_1], [A1_0, A1_1]]), + C=np.matrix([C0_0, C0_1]), + K=np.matrix([[K0_0], [K1_0]])) + + self.kf = KF1D(x0=[[x0_0], [x1_0]], + A=[[A0_0, A0_1], [A1_0, A1_1]], + C=[C0_0, C0_1], + K=[[K0_0], [K1_0]]) + + def test_getter_setter(self): + self.kf.x = [[1.0], [1.0]] + self.assertEqual(self.kf.x, [[1.0], [1.0]]) + + def update_returns_state(self): + x = self.kf.update(100) + self.assertEqual(x, self.kf.x) + + def test_old_equal_new(self): + for _ in range(1000): + v_wheel = random.uniform(0, 200) + + x_old = self.kf_old.update(v_wheel) + x = self.kf.update(v_wheel) + + # Compare the output x, verify that the error is less than 1e-4 + self.assertAlmostEqual(x_old[0], x[0]) + self.assertAlmostEqual(x_old[1], x[1]) + + + def test_new_is_faster(self): + setup = """ +import numpy as np + +from common.kalman.simple_kalman import KF1D +from common.kalman.simple_kalman_old import KF1D as KF1D_old + +dt = 0.01 +x0_0 = 0.0 +x1_0 = 0.0 +A0_0 = 1.0 +A0_1 = dt +A1_0 = 0.0 +A1_1 = 1.0 +C0_0 = 1.0 +C0_1 = 0.0 +K0_0 = 0.12287673 +K1_0 = 0.29666309 + +kf_old = KF1D_old(x0=np.matrix([[x0_0], [x1_0]]), + A=np.matrix([[A0_0, A0_1], [A1_0, A1_1]]), + C=np.matrix([C0_0, C0_1]), + K=np.matrix([[K0_0], [K1_0]])) + +kf = KF1D(x0=[[x0_0], [x1_0]], + A=[[A0_0, A0_1], [A1_0, A1_1]], + C=[C0_0, C0_1], + K=[[K0_0], [K1_0]]) + """ + kf_speed = timeit.timeit("kf.update(1234)", setup=setup, number=10000) + kf_old_speed = timeit.timeit("kf_old.update(1234)", setup=setup, number=10000) + self.assertTrue(kf_speed < kf_old_speed / 4) diff --git a/common/numpy_fast.py b/common/numpy_fast.py index eb706a908ff643..a5d5ad3f502b03 100644 --- a/common/numpy_fast.py +++ b/common/numpy_fast.py @@ -12,7 +12,10 @@ def get_interp(xv): hi += 1 low = hi - 1 return fp[-1] if hi == N and xv > xp[low] else ( - fp[0] if hi == 0 else + fp[0] if hi == 0 else (xv - xp[low]) * (fp[hi] - fp[low]) / (xp[hi] - xp[low]) + fp[low]) return [get_interp(v) for v in x] if hasattr( x, '__iter__') else get_interp(x) + +def mean(x): + return sum(x) / len(x) diff --git a/common/params.py b/common/params.py index 30ebaa0609799d..bbc66eaf977627 100755 --- a/common/params.py +++ b/common/params.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ROS has a parameter server, we have files. The parameter store is a persistent key value store, implemented as a directory with a writer lock. @@ -27,6 +27,7 @@ import shutil import fcntl import tempfile +import threading from enum import Enum @@ -41,7 +42,7 @@ def mkdirs_exists_ok(path): class TxType(Enum): PERSISTENT = 1 CLEAR_ON_MANAGER_START = 2 - CLEAR_ON_CAR_START = 3 + CLEAR_ON_PANDA_DISCONNECT = 3 class UnknownKeyName(Exception): @@ -49,32 +50,51 @@ class UnknownKeyName(Exception): keys = { - "AccessToken": TxType.PERSISTENT, - "CalibrationParams": TxType.PERSISTENT, - "CarParams": TxType.CLEAR_ON_CAR_START, - "CompletedTrainingVersion": TxType.PERSISTENT, - "ControlsParams": TxType.PERSISTENT, - "DoUninstall": TxType.CLEAR_ON_MANAGER_START, - "DongleId": TxType.PERSISTENT, - "GitBranch": TxType.PERSISTENT, - "GitCommit": TxType.PERSISTENT, - "GitRemote": TxType.PERSISTENT, - "HasAcceptedTerms": TxType.PERSISTENT, - "IsDriverMonitoringEnabled": TxType.PERSISTENT, - "IsFcwEnabled": TxType.PERSISTENT, - "IsGeofenceEnabled": TxType.PERSISTENT, - "IsMetric": TxType.PERSISTENT, - "IsUpdateAvailable": TxType.PERSISTENT, - "IsUploadVideoOverCellularEnabled": TxType.PERSISTENT, - "LimitSetSpeed": TxType.PERSISTENT, - "LiveParameters": TxType.PERSISTENT, - "LongitudinalControl": TxType.PERSISTENT, - "Passive": TxType.PERSISTENT, - "RecordFront": TxType.PERSISTENT, - "ShouldDoUpdate": TxType.CLEAR_ON_MANAGER_START, - "SpeedLimitOffset": TxType.PERSISTENT, - "TrainingVersion": TxType.PERSISTENT, - "Version": TxType.PERSISTENT, + "AccessToken": [TxType.PERSISTENT], + "AthenadPid": [TxType.PERSISTENT], + "CalibrationParams": [TxType.PERSISTENT], + "CarParams": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT], + "CarVin": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT], + "CompletedTrainingVersion": [TxType.PERSISTENT], + "ControlsParams": [TxType.PERSISTENT], + "DoUninstall": [TxType.CLEAR_ON_MANAGER_START], + "DongleId": [TxType.PERSISTENT], + "GitBranch": [TxType.PERSISTENT], + "GitCommit": [TxType.PERSISTENT], + "GitRemote": [TxType.PERSISTENT], + "GithubSshKeys": [TxType.PERSISTENT], + "HasAcceptedTerms": [TxType.PERSISTENT], + "HasCompletedSetup": [TxType.PERSISTENT], + "IsGeofenceEnabled": [TxType.PERSISTENT], + "IsMetric": [TxType.PERSISTENT], + "IsRHD": [TxType.PERSISTENT], + "IsUpdateAvailable": [TxType.PERSISTENT], + "IsUploadRawEnabled": [TxType.PERSISTENT], + "IsUploadVideoOverCellularEnabled": [TxType.PERSISTENT], + "LastUpdateTime": [TxType.PERSISTENT], + "LimitSetSpeed": [TxType.PERSISTENT], + "LimitSetSpeedNeural": [TxType.PERSISTENT], + "LiveParameters": [TxType.PERSISTENT], + "LongitudinalControl": [TxType.PERSISTENT], + "OpenpilotEnabledToggle": [TxType.PERSISTENT], + "PandaFirmware": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT], + "PandaDongleId": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT], + "Passive": [TxType.PERSISTENT], + "RecordFront": [TxType.PERSISTENT], + "ReleaseNotes": [TxType.PERSISTENT], + "ShouldDoUpdate": [TxType.CLEAR_ON_MANAGER_START], + "SpeedLimitOffset": [TxType.PERSISTENT], + "SubscriberInfo": [TxType.PERSISTENT], + "TermsVersion": [TxType.PERSISTENT], + "TrainingVersion": [TxType.PERSISTENT], + "UpdateAvailable": [TxType.CLEAR_ON_MANAGER_START], + "Version": [TxType.PERSISTENT], + "Offroad_ChargeDisabled": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT], + "Offroad_ConnectivityNeeded": [TxType.CLEAR_ON_MANAGER_START], + "Offroad_ConnectivityNeededPrompt": [TxType.CLEAR_ON_MANAGER_START], + "Offroad_TemperatureTooHigh": [TxType.CLEAR_ON_MANAGER_START], + "Offroad_PandaFirmwareMismatch": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT], + "Offroad_InvalidTime": [TxType.CLEAR_ON_MANAGER_START], } @@ -86,7 +106,7 @@ def fsync_dir(path): os.close(fd) -class FileLock(object): +class FileLock(): def __init__(self, path, create): self._path = path self._create = create @@ -102,7 +122,7 @@ def release(self): self._fd = None -class DBAccessor(object): +class DBAccessor(): def __init__(self, path): self._path = path self._vals = None @@ -272,6 +292,9 @@ def read_db(params_path, key): return None def write_db(params_path, key, value): + if isinstance(value, str): + value = value.encode('utf8') + prev_umask = os.umask(0) lock = FileLock(params_path+"/.lock", True) lock.acquire() @@ -290,7 +313,7 @@ def write_db(params_path, key, value): os.umask(prev_umask) lock.release() -class Params(object): +class Params(): def __init__(self, db='/data/params'): self.db = db @@ -308,20 +331,20 @@ def transaction(self, write=False): def _clear_keys_with_type(self, tx_type): with self.transaction(write=True) as txn: for key in keys: - if keys[key] == tx_type: + if tx_type in keys[key]: txn.delete(key) def manager_start(self): self._clear_keys_with_type(TxType.CLEAR_ON_MANAGER_START) - def car_start(self): - self._clear_keys_with_type(TxType.CLEAR_ON_CAR_START) + def panda_disconnect(self): + self._clear_keys_with_type(TxType.CLEAR_ON_PANDA_DISCONNECT) def delete(self, key): with self.transaction(write=True) as txn: txn.delete(key) - def get(self, key, block=False): + def get(self, key, block=False, encoding=None): if key not in keys: raise UnknownKeyName(key) @@ -331,14 +354,37 @@ def get(self, key, block=False): break # is polling really the best we can do? time.sleep(0.05) + + if ret is not None and encoding is not None: + ret = ret.decode(encoding) + return ret def put(self, key, dat): + """ + Warning: This function blocks until the param is written to disk! + In very rare cases this can take over a second, and your code will hang. + + Use the put_nonblocking helper function in time sensitive code, but + in general try to avoid writing params as much as possible. + """ + if key not in keys: raise UnknownKeyName(key) write_db(self.db, key, dat) + +def put_nonblocking(key, val): + def f(key, val): + params = Params() + params.put(key, val) + + t = threading.Thread(target=f, args=(key, val)) + t.start() + return t + + if __name__ == "__main__": params = Params() if len(sys.argv) > 2: diff --git a/common/profiler.py b/common/profiler.py index 7f9b1a41ffb188..eab091c7fc4502 100644 --- a/common/profiler.py +++ b/common/profiler.py @@ -1,6 +1,6 @@ import time -class Profiler(object): +class Profiler(): def __init__(self, enabled=False): self.enabled = enabled self.cp = {} diff --git a/common/realtime.py b/common/realtime.py index 7fe183fb23abca..f8e489612ac4ee 100644 --- a/common/realtime.py +++ b/common/realtime.py @@ -2,56 +2,31 @@ import os import time import platform -import threading import subprocess import multiprocessing - from cffi import FFI -ffi = FFI() -ffi.cdef(""" - -typedef int clockid_t; -struct timespec { - long tv_sec; /* Seconds. */ - long tv_nsec; /* Nanoseconds. */ -}; -int clock_gettime (clockid_t clk_id, struct timespec *tp); - -long syscall(long number, ...); - -""" -) -libc = ffi.dlopen(None) +# Build and load cython module +import pyximport +installer = pyximport.install(inplace=True, build_dir='/tmp') +from common.clock import monotonic_time, sec_since_boot # pylint: disable=no-name-in-module, import-error +pyximport.uninstall(*installer) +assert monotonic_time +assert sec_since_boot -# see -CLOCK_MONOTONIC_RAW = 4 -CLOCK_BOOTTIME = 7 -if platform.system() != 'Darwin' and hasattr(libc, 'clock_gettime'): - c_clock_gettime = libc.clock_gettime +# time step for each process +DT_CTRL = 0.01 # controlsd +DT_PLAN = 0.05 # mpc +DT_MDL = 0.05 # model +DT_RDR = 0.05 # radar +DT_DMON = 0.1 # driver monitoring +DT_TRML = 0.5 # thermald and manager - tlocal = threading.local() - def clock_gettime(clk_id): - if not hasattr(tlocal, 'ts'): - tlocal.ts = ffi.new('struct timespec *') - ts = tlocal.ts - - r = c_clock_gettime(clk_id, ts) - if r != 0: - raise OSError("clock_gettime") - return ts.tv_sec + ts.tv_nsec * 1e-9 -else: - # hack. only for OS X < 10.12 - def clock_gettime(clk_id): - return time.time() - -def monotonic_time(): - return clock_gettime(CLOCK_MONOTONIC_RAW) - -def sec_since_boot(): - return clock_gettime(CLOCK_BOOTTIME) +ffi = FFI() +ffi.cdef("long syscall(long number, ...);") +libc = ffi.dlopen(None) def set_realtime_priority(level): @@ -69,7 +44,7 @@ def set_realtime_priority(level): return subprocess.call(['chrt', '-f', '-p', str(level), str(tid)]) -class Ratekeeper(object): +class Ratekeeper(): def __init__(self, rate, print_delay_threshold=0.): """Rate in Hz for ratekeeping. print_delay_threshold must be nonnegative.""" self._interval = 1. / rate @@ -99,10 +74,9 @@ def monitor_time(self): lagged = False remaining = self._next_frame_time - sec_since_boot() self._next_frame_time += self._interval - if remaining < -self._print_delay_threshold: + if self._print_delay_threshold is not None and remaining < -self._print_delay_threshold: print("%s lagging by %.2f ms" % (self._process_name, -remaining * 1000)) lagged = True self._frame += 1 self._remaining = remaining return lagged - diff --git a/common/spinner.py b/common/spinner.py new file mode 100644 index 00000000000000..7da31a9dda9ce2 --- /dev/null +++ b/common/spinner.py @@ -0,0 +1,28 @@ +import os +import subprocess +from common.basedir import BASEDIR + +class Spinner(): + def __enter__(self): + self.spinner_proc = subprocess.Popen(["./spinner"], + stdin=subprocess.PIPE, + cwd=os.path.join(BASEDIR, "selfdrive", "ui", "spinner"), + close_fds=True) + return self + + def update(self, spinner_text): + self.spinner_proc.stdin.write(spinner_text.encode('utf8') + b"\n") + self.spinner_proc.stdin.flush() + + def __exit__(self, type, value, traceback): + self.spinner_proc.stdin.close() + self.spinner_proc.terminate() + + + +if __name__ == "__main__": + import time + with Spinner() as s: + s.update("Spinner text") + time.sleep(5.0) + diff --git a/common/stat_live.py b/common/stat_live.py new file mode 100644 index 00000000000000..f392956efd83f0 --- /dev/null +++ b/common/stat_live.py @@ -0,0 +1,73 @@ +import numpy as np + +class RunningStat(): + # tracks realtime mean and standard deviation without storing any data + def __init__(self, priors=None, max_trackable=-1): + self.max_trackable = max_trackable + if priors is not None: + # initialize from history + self.M = priors[0] + self.S = priors[1] + self.n = priors[2] + self.M_last = self.M + self.S_last = self.S + + else: + self.reset() + + def reset(self): + self.M = 0. + self.S = 0. + self.M_last = 0. + self.S_last = 0. + self.n = 0 + + def push_data(self, new_data): + # short term memory hack + if self.max_trackable < 0 or self.n < self.max_trackable: + self.n += 1 + if self.n == 0: + self.M_last = new_data + self.M = self.M_last + self.S_last = 0. + else: + self.M = self.M_last + (new_data - self.M_last) / self.n + self.S = self.S_last + (new_data - self.M_last) * (new_data - self.M); + self.M_last = self.M + self.S_last = self.S + + def mean(self): + return self.M + + def variance(self): + if self.n >= 2: + return self.S / (self.n - 1.) + else: + return 0 + + def std(self): + return np.sqrt(self.variance()) + + def params_to_save(self): + return [self.M, self.S, self.n] + +class RunningStatFilter(): + def __init__(self, raw_priors=None, filtered_priors=None, max_trackable=-1): + self.raw_stat = RunningStat(raw_priors, max_trackable) + self.filtered_stat = RunningStat(filtered_priors, max_trackable) + + def reset(self): + self.raw_stat.reset() + self.filtered_stat.reset() + + def push_and_update(self, new_data): + _std_last = self.raw_stat.std() + self.raw_stat.push_data(new_data) + _delta_std = self.raw_stat.std() - _std_last + if _delta_std<=0: + self.filtered_stat.push_data(new_data) + else: + pass + # self.filtered_stat.push_data(self.filtered_stat.mean()) + +# class SequentialBayesian(): diff --git a/common/sympy_helpers.py b/common/sympy_helpers.py index 879eb71bbf7c5f..78688a84cf284a 100644 --- a/common/sympy_helpers.py +++ b/common/sympy_helpers.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import sympy as sp import numpy as np @@ -75,7 +75,7 @@ def sympy_into_c(sympy_functions): routines.append(r) [(c_name, c_code), (h_name, c_header)] = codegen.get_code_generator('C', 'ekf', 'C99').write(routines, "ekf") - c_code = '\n'.join(filter(lambda x: len(x) > 0 and x[0] != '#', c_code.split("\n"))) - c_header = '\n'.join(filter(lambda x: len(x) > 0 and x[0] != '#', c_header.split("\n"))) + c_code = '\n'.join(x for x in c_code.split("\n") if len(x) > 0 and x[0] != '#') + c_header = '\n'.join(x for x in c_header.split("\n") if len(x) > 0 and x[0] != '#') return c_header, c_code diff --git a/common/timeout.py b/common/timeout.py new file mode 100644 index 00000000000000..c2c1f69712f208 --- /dev/null +++ b/common/timeout.py @@ -0,0 +1,28 @@ +import signal + +class TimeoutException(Exception): + pass + +class Timeout: + """ + Timeout context manager. + For example this code will raise a TimeoutException: + with Timeout(seconds=5, error_msg="Sleep was too long"): + time.sleep(10) + """ + def __init__(self, seconds, error_msg=None): + if error_msg is None: + error_msg = 'Timed out after {} seconds'.format(seconds) + self.seconds = seconds + self.error_msg = error_msg + + def handle_timeout(self, signume, frame): + raise TimeoutException(self.error_msg) + + def __enter__(self): + signal.signal(signal.SIGALRM, self.handle_timeout) + signal.alarm(self.seconds) + + def __exit__(self, exc_type, exc_val, exc_tb): + signal.alarm(0) + diff --git a/common/transformations/camera.py b/common/transformations/camera.py index 42432a7bbc7cd8..97c7c37d1b655d 100644 --- a/common/transformations/camera.py +++ b/common/transformations/camera.py @@ -1,6 +1,6 @@ import numpy as np import common.transformations.orientation as orient -import cv2 +import math FULL_FRAME_SIZE = (1164, 874) W, H = FULL_FRAME_SIZE[0], FULL_FRAME_SIZE[1] @@ -12,6 +12,17 @@ [ 0., FOCAL, H/2.], [ 0., 0., 1.]]) + +leon_dcam_intrinsics = np.array([ + [650, 0, 816//2], + [ 0, 650, 612//2], + [ 0, 0, 1]]) + +eon_dcam_intrinsics = np.array([ + [860, 0, 1152//2], + [ 0, 860, 864//2], + [ 0, 0, 1]]) + # aka 'K_inv' aka view_frame_from_camera_frame eon_intrinsics_inv = np.linalg.inv(eon_intrinsics) @@ -64,7 +75,7 @@ def normalize(img_pts, intrinsics=eon_intrinsics): input_shape = img_pts.shape img_pts = np.atleast_2d(img_pts) img_pts = np.hstack((img_pts, np.ones((img_pts.shape[0],1)))) - img_pts_normalized = intrinsics_inv.dot(img_pts.T).T + img_pts_normalized = img_pts.dot(intrinsics_inv.T) img_pts_normalized[(img_pts < 0).any(axis=1)] = np.nan return img_pts_normalized[:,:2].reshape(input_shape) @@ -76,7 +87,7 @@ def denormalize(img_pts, intrinsics=eon_intrinsics): input_shape = img_pts.shape img_pts = np.atleast_2d(img_pts) img_pts = np.hstack((img_pts, np.ones((img_pts.shape[0],1)))) - img_pts_denormalized = intrinsics.dot(img_pts.T).T + img_pts_denormalized = img_pts.dot(intrinsics.T) img_pts_denormalized[img_pts_denormalized[:,0] > W] = np.nan img_pts_denormalized[img_pts_denormalized[:,0] < 0] = np.nan img_pts_denormalized[img_pts_denormalized[:,1] > H] = np.nan @@ -114,6 +125,8 @@ def img_from_device(pt_device): #TODO please use generic img transform below def rotate_img(img, eulers, crop=None, intrinsics=eon_intrinsics): + import cv2 # pylint: disable=no-name-in-module, import-error + size = img.shape[:2] rot = orient.rot_from_euler(eulers) quadrangle = np.array([[0, 0], @@ -125,8 +138,8 @@ def rotate_img(img, eulers, crop=None, intrinsics=eon_intrinsics): warped_quadrangle = np.column_stack((warped_quadrangle_full[:,0]/warped_quadrangle_full[:,2], warped_quadrangle_full[:,1]/warped_quadrangle_full[:,2])).astype(np.float32) if crop: - W_border = (size[1] - crop[0])/2 - H_border = (size[0] - crop[1])/2 + W_border = (size[1] - crop[0])//2 + H_border = (size[0] - crop[1])//2 outside_crop = (((warped_quadrangle[:,0] < W_border) | (warped_quadrangle[:,0] >= size[1] - W_border)) & ((warped_quadrangle[:,1] < H_border) | @@ -141,34 +154,97 @@ def rotate_img(img, eulers, crop=None, intrinsics=eon_intrinsics): W_border: size[1] - W_border] +def get_camera_frame_from_calib_frame(camera_frame_from_road_frame): + camera_frame_from_ground = camera_frame_from_road_frame[:, (0, 1, 3)] + calib_frame_from_ground = np.dot(eon_intrinsics, + get_view_frame_from_road_frame(0, 0, 0, 1.22))[:, (0, 1, 3)] + ground_from_calib_frame = np.linalg.inv(calib_frame_from_ground) + camera_frame_from_calib_frame = np.dot(camera_frame_from_ground, ground_from_calib_frame) + return camera_frame_from_calib_frame + + +def pretransform_from_calib(calib): + roll, pitch, yaw, height = calib + view_frame_from_road_frame = get_view_frame_from_road_frame(roll, pitch, yaw, height) + camera_frame_from_road_frame = np.dot(eon_intrinsics, view_frame_from_road_frame) + camera_frame_from_calib_frame = get_camera_frame_from_calib_frame(camera_frame_from_road_frame) + return np.linalg.inv(camera_frame_from_calib_frame) + + def transform_img(base_img, augment_trans=np.array([0,0,0]), augment_eulers=np.array([0,0,0]), from_intr=eon_intrinsics, to_intr=eon_intrinsics, - calib_rot_view=None, - output_size=None): - cy = from_intr[1,2] + output_size=None, + pretransform=None, + top_hacks=False, + yuv=False, + alpha=1.0, + beta=0, + blur=0): + import cv2 # pylint: disable=no-name-in-module, import-error + cv2.setNumThreads(1) + + if yuv: + base_img = cv2.cvtColor(base_img, cv2.COLOR_YUV2RGB_I420) + size = base_img.shape[:2] if not output_size: output_size = size[::-1] - h = 1.22 - quadrangle = np.array([[0, cy + 20], - [size[1]-1, cy + 20], - [0, size[0]-1], - [size[1]-1, size[0]-1]], dtype=np.float32) - quadrangle_norm = np.hstack((normalize(quadrangle, intrinsics=from_intr), np.ones((4,1)))) - quadrangle_world = np.column_stack((h*quadrangle_norm[:,0]/quadrangle_norm[:,1], - h*np.ones(4), - h/quadrangle_norm[:,1])) - rot = orient.rot_from_euler(augment_eulers) - if calib_rot_view is not None: - rot = calib_rot_view.dot(rot) - to_extrinsics = np.hstack((rot.T, -augment_trans[:,None])) - to_KE = to_intr.dot(to_extrinsics) - warped_quadrangle_full = np.einsum('jk,ik->ij', to_KE, np.hstack((quadrangle_world, np.ones((4,1))))) - warped_quadrangle = np.column_stack((warped_quadrangle_full[:,0]/warped_quadrangle_full[:,2], - warped_quadrangle_full[:,1]/warped_quadrangle_full[:,2])).astype(np.float32) - M = cv2.getPerspectiveTransform(quadrangle, warped_quadrangle.astype(np.float32)) + + cy = from_intr[1,2] + def get_M(h=1.22): + quadrangle = np.array([[0, cy + 20], + [size[1]-1, cy + 20], + [0, size[0]-1], + [size[1]-1, size[0]-1]], dtype=np.float32) + quadrangle_norm = np.hstack((normalize(quadrangle, intrinsics=from_intr), np.ones((4,1)))) + quadrangle_world = np.column_stack((h*quadrangle_norm[:,0]/quadrangle_norm[:,1], + h*np.ones(4), + h/quadrangle_norm[:,1])) + rot = orient.rot_from_euler(augment_eulers) + to_extrinsics = np.hstack((rot.T, -augment_trans[:,None])) + to_KE = to_intr.dot(to_extrinsics) + warped_quadrangle_full = np.einsum('jk,ik->ij', to_KE, np.hstack((quadrangle_world, np.ones((4,1))))) + warped_quadrangle = np.column_stack((warped_quadrangle_full[:,0]/warped_quadrangle_full[:,2], + warped_quadrangle_full[:,1]/warped_quadrangle_full[:,2])).astype(np.float32) + M = cv2.getPerspectiveTransform(quadrangle, warped_quadrangle.astype(np.float32)) + return M + + M = get_M() + if pretransform is not None: + M = M.dot(pretransform) augmented_rgb = cv2.warpPerspective(base_img, M, output_size, borderMode=cv2.BORDER_REPLICATE) - return augmented_rgb + + if top_hacks: + cyy = int(math.ceil(to_intr[1,2])) + M = get_M(1000) + if pretransform is not None: + M = M.dot(pretransform) + augmented_rgb[:cyy] = cv2.warpPerspective(base_img, M, (output_size[0], cyy), borderMode=cv2.BORDER_REPLICATE) + + # brightness and contrast augment + augmented_rgb = np.clip((float(alpha)*augmented_rgb + beta), 0, 255).astype(np.uint8) + + # gaussian blur + if blur > 0: + augmented_rgb = cv2.GaussianBlur(augmented_rgb,(blur*2+1,blur*2+1),cv2.BORDER_DEFAULT) + + if yuv: + augmented_img = cv2.cvtColor(augmented_rgb, cv2.COLOR_RGB2YUV_I420) + else: + augmented_img = augmented_rgb + return augmented_img + + +def yuv_crop(frame, output_size, center=None): + # output_size in camera coordinates so u,v + # center in array coordinates so row, column + import cv2 # pylint: disable=no-name-in-module, import-error + rgb = cv2.cvtColor(frame, cv2.COLOR_YUV2RGB_I420) + if not center: + center = (rgb.shape[0]/2, rgb.shape[1]/2) + rgb_crop = rgb[center[0] - output_size[1]/2: center[0] + output_size[1]/2, + center[1] - output_size[0]/2: center[1] + output_size[0]/2] + return cv2.cvtColor(rgb_crop, cv2.COLOR_RGB2YUV_I420) diff --git a/common/transformations/coordinates.py b/common/transformations/coordinates.py index 568fb9bf2b3f4e..864bc4d807e174 100644 --- a/common/transformations/coordinates.py +++ b/common/transformations/coordinates.py @@ -65,7 +65,7 @@ def ecef2geodetic(ecef, radians=False): geodetic = np.column_stack((lat, lon, h)) return geodetic.reshape(input_shape) -class LocalCoord(object): +class LocalCoord(): """ Allows conversions to local frames. In this case NED. That is: North East Down from the start position in diff --git a/common/transformations/model.py b/common/transformations/model.py index 2d41d9cebe354d..c13cc7e38752da 100644 --- a/common/transformations/model.py +++ b/common/transformations/model.py @@ -1,9 +1,8 @@ import numpy as np -from common.transformations.camera import eon_focal_length, \ - vp_from_ke, \ - get_view_frame_from_road_frame, \ - FULL_FRAME_SIZE +from common.transformations.camera import (FULL_FRAME_SIZE, eon_focal_length, + get_view_frame_from_road_frame, + vp_from_ke) # segnet @@ -32,7 +31,7 @@ # MED model -MEDMODEL_INPUT_SIZE = (640, 240) +MEDMODEL_INPUT_SIZE = (512, 256) MEDMODEL_YUV_SIZE = (MEDMODEL_INPUT_SIZE[0], MEDMODEL_INPUT_SIZE[1] * 3 // 2) MEDMODEL_CY = 47.6 @@ -117,6 +116,16 @@ def get_camera_frame_from_model_frame(camera_frame_from_road_frame, height=model return np.dot(camera_from_model_camera, model_camera_from_model_frame) +def get_camera_frame_from_medmodel_frame(camera_frame_from_road_frame): + camera_frame_from_ground = camera_frame_from_road_frame[:, (0, 1, 3)] + medmodel_frame_from_ground = medmodel_frame_from_road_frame[:, (0, 1, 3)] + + ground_from_medmodel_frame = np.linalg.inv(medmodel_frame_from_ground) + camera_frame_from_medmodel_frame = np.dot(camera_frame_from_ground, ground_from_medmodel_frame) + + return camera_frame_from_medmodel_frame + + def get_camera_frame_from_bigmodel_frame(camera_frame_from_road_frame): camera_frame_from_ground = camera_frame_from_road_frame[:, (0, 1, 3)] bigmodel_frame_from_ground = bigmodel_frame_from_road_frame[:, (0, 1, 3)] diff --git a/common/transformations/orientation.py b/common/transformations/orientation.py index 33a822ca3fd498..acbd4a2bf3e025 100644 --- a/common/transformations/orientation.py +++ b/common/transformations/orientation.py @@ -29,7 +29,7 @@ def euler2quat(eulers): np.sin(gamma / 2) * np.sin(theta / 2) * np.cos(psi / 2) quats = array([q0, q1, q2, q3]).T - for i in xrange(len(quats)): + for i in range(len(quats)): if quats[i,0] < 0: quats[i] = -quats[i] return quats.reshape(output_shape) @@ -99,7 +99,7 @@ def rot2quat(rots): K3[:, 3, 2] = K3[:, 2, 3] K3[:, 3, 3] = (rots[:, 0, 0] + rots[:, 1, 1] + rots[:, 2, 2]) / 3.0 q = np.empty((len(rots), 4)) - for i in xrange(len(rots)): + for i in range(len(rots)): _, eigvecs = linalg.eigh(K3[i].T) eigvecs = eigvecs[:,3:] q[i, 0] = eigvecs[-1] diff --git a/installer/updater/Makefile b/installer/updater/Makefile new file mode 100644 index 00000000000000..d252fc2aa050c7 --- /dev/null +++ b/installer/updater/Makefile @@ -0,0 +1,98 @@ +CC = clang +CXX = clang++ + +PHONELIBS = ../../phonelibs + +WARN_FLAGS = -Werror=implicit-function-declaration \ + -Werror=incompatible-pointer-types \ + -Werror=int-conversion \ + -Werror=return-type \ + -Werror=format-extra-args + +CFLAGS = -std=gnu11 -g -fPIC -O2 $(WARN_FLAGS) +CXXFLAGS = -std=c++11 -g -fPIC -O2 $(WARN_FLAGS) + +CURL_FLAGS = -I$(PHONELIBS)/curl/include +CURL_LIBS = $(PHONELIBS)/curl/lib/libcurl.a \ + $(PHONELIBS)/zlib/lib/libz.a + +BORINGSSL_FLAGS = -I$(PHONELIBS)/boringssl/include +BORINGSSL_LIBS = $(PHONELIBS)/boringssl/lib/libssl_static.a \ + $(PHONELIBS)/boringssl/lib/libcrypto_static.a \ + +NANOVG_FLAGS = -I$(PHONELIBS)/nanovg + +JSON11_FLAGS = -I$(PHONELIBS)/json11 + +OPENGL_LIBS = -lGLESv3 + +FRAMEBUFFER_LIBS = -lutils -lgui -lEGL + +.PHONY: all +all: updater + +OBJS = opensans_regular.ttf.o \ + opensans_semibold.ttf.o \ + opensans_bold.ttf.o \ + ../../selfdrive/common/touch.o \ + ../../selfdrive/common/framebuffer.o \ + $(PHONELIBS)/json11/json11.o \ + $(PHONELIBS)/nanovg/nanovg.o + +DEPS := $(OBJS:.o=.d) + +updater: updater.o $(OBJS) + @echo "[ LINK ] $@" + $(CXX) $(CPPFLAGS) -fPIC -o 'updater' $^ \ + $(FRAMEBUFFER_LIBS) \ + $(CURL_LIBS) \ + $(BORINGSSL_LIBS) \ + -L/system/vendor/lib64 \ + $(OPENGL_LIBS) \ + -lcutils -lm -llog + strip updater + +opensans_regular.ttf.o: ../../selfdrive/assets/fonts/opensans_regular.ttf + @echo "[ bin2o ] $@" + cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)' + +opensans_bold.ttf.o: ../../selfdrive/assets/fonts/opensans_bold.ttf + @echo "[ bin2o ] $@" + cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)' + +opensans_semibold.ttf.o: ../../selfdrive/assets/fonts/opensans_semibold.ttf + @echo "[ bin2o ] $@" + cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)' + +%.o: %.c + mkdir -p $(@D) + @echo "[ CC ] $@" + $(CC) $(CPPFLAGS) $(CFLAGS) \ + -I../.. \ + -I$(PHONELIBS)/android_frameworks_native/include \ + -I$(PHONELIBS)/android_system_core/include \ + -I$(PHONELIBS)/android_hardware_libhardware/include \ + $(NANOVG_FLAGS) \ + -c -o '$@' '$<' + +%.o: %.cc + mkdir -p $(@D) + @echo "[ CXX ] $@" + $(CXX) $(CPPFLAGS) $(CXXFLAGS) \ + -I../../selfdrive \ + -I../../ \ + -I$(PHONELIBS)/android_frameworks_native/include \ + -I$(PHONELIBS)/android_system_core/include \ + -I$(PHONELIBS)/android_hardware_libhardware/include \ + $(NANOVG_FLAGS) \ + $(JSON11_FLAGS) \ + $(CURL_FLAGS) \ + $(BORINGSSL_FLAGS) \ + -c -o '$@' '$<' + + +.PHONY: clean +clean: + rm -f $(OBJS) $(DEPS) + +-include $(DEPS) diff --git a/installer/updater/update.json b/installer/updater/update.json new file mode 100644 index 00000000000000..2ff5690fd5bb6c --- /dev/null +++ b/installer/updater/update.json @@ -0,0 +1,7 @@ +{ + "ota_url": "https://commadist.azureedge.net/neosupdate/ota-signed-7a0117425bc4a6673958d265312994e124654a566228f3cec2f0f9bc8120a9ab.zip", + "ota_hash": "7a0117425bc4a6673958d265312994e124654a566228f3cec2f0f9bc8120a9ab", + "recovery_url": "https://commadist.azureedge.net/neosupdate/recovery-3dc234d868c29a3739f6ca3bd47b1c2d3c570d9f478b6849a4fada129ee4af76.img", + "recovery_len": 15848748, + "recovery_hash": "3dc234d868c29a3739f6ca3bd47b1c2d3c570d9f478b6849a4fada129ee4af76" +} diff --git a/installer/updater/updater b/installer/updater/updater index 0b8602b3550175..15858eabb4d66e 100755 Binary files a/installer/updater/updater and b/installer/updater/updater differ diff --git a/installer/updater/updater.cc b/installer/updater/updater.cc new file mode 100644 index 00000000000000..e2d3e7dae08fbe --- /dev/null +++ b/installer/updater/updater.cc @@ -0,0 +1,770 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "nanovg.h" +#define NANOVG_GLES3_IMPLEMENTATION +#include "nanovg_gl.h" +#include "nanovg_gl_utils.h" + +#include "json11.hpp" + +#include "common/framebuffer.h" +#include "common/touch.h" +#include "common/utilpp.h" + +#define USER_AGENT "NEOSUpdater-0.2" + +#define MANIFEST_URL_EON_STAGING "https://github.com/commaai/eon-neos/raw/master/update.staging.json" +#define MANIFEST_URL_EON_LOCAL "http://192.168.5.1:8000/neosupdate/update.local.json" +#define MANIFEST_URL_EON "https://github.com/commaai/eon-neos/raw/master/update.json" +const char *manifest_url = MANIFEST_URL_EON; + +#define RECOVERY_DEV "/dev/block/bootdevice/by-name/recovery" +#define RECOVERY_COMMAND "/cache/recovery/command" + +#define UPDATE_DIR "/data/neoupdate" + +extern const uint8_t bin_opensans_regular[] asm("_binary_opensans_regular_ttf_start"); +extern const uint8_t bin_opensans_regular_end[] asm("_binary_opensans_regular_ttf_end"); +extern const uint8_t bin_opensans_semibold[] asm("_binary_opensans_semibold_ttf_start"); +extern const uint8_t bin_opensans_semibold_end[] asm("_binary_opensans_semibold_ttf_end"); +extern const uint8_t bin_opensans_bold[] asm("_binary_opensans_bold_ttf_start"); +extern const uint8_t bin_opensans_bold_end[] asm("_binary_opensans_bold_ttf_end"); + +namespace { + +std::string sha256_file(std::string fn, size_t limit=0) { + SHA256_CTX ctx; + SHA256_Init(&ctx); + + FILE *file = fopen(fn.c_str(), "rb"); + if (!file) return ""; + + const size_t buf_size = 8192; + std::unique_ptr buffer( new char[ buf_size ] ); + + bool read_limit = (limit != 0); + while (true) { + size_t read_size = buf_size; + if (read_limit) read_size = std::min(read_size, limit); + size_t bytes_read = fread(buffer.get(), 1, read_size, file); + if (!bytes_read) break; + + SHA256_Update(&ctx, buffer.get(), bytes_read); + + if (read_limit) { + limit -= bytes_read; + if (limit == 0) break; + } + } + + uint8_t hash[SHA256_DIGEST_LENGTH]; + SHA256_Final(hash, &ctx); + + fclose(file); + + return util::tohex(hash, sizeof(hash)); +} + +size_t download_string_write(void *ptr, size_t size, size_t nmeb, void *up) { + size_t sz = size * nmeb; + ((std::string*)up)->append((char*)ptr, sz); + return sz; +} + +std::string download_string(CURL *curl, std::string url) { + std::string os; + + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT); + curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); + curl_easy_setopt(curl, CURLOPT_RESUME_FROM, 0); + + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); + + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, download_string_write); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &os); + CURLcode res = curl_easy_perform(curl); + if (res != CURLE_OK) { + return ""; + } + + return os; +} + +size_t download_file_write(void *ptr, size_t size, size_t nmeb, void *up) { + return fwrite(ptr, size, nmeb, (FILE*)up); +} + +int battery_capacity() { + std::string bat_cap_s = util::read_file("/sys/class/power_supply/battery/capacity"); + return atoi(bat_cap_s.c_str()); +} + +int battery_current() { + std::string current_now_s = util::read_file("/sys/class/power_supply/battery/current_now"); + return atoi(current_now_s.c_str()); +} + +bool check_battery() { + int bat_cap = battery_capacity(); + int current_now = battery_current(); + return bat_cap > 35 || (current_now < 0 && bat_cap > 10); +} + +bool check_space() { + struct statvfs stat; + if (statvfs("/data/", &stat) != 0) { + return false; + } + size_t space = stat.f_bsize * stat.f_bavail; + return space > 2000000000ULL; // 2GB +} + +static void start_settings_activity(const char* name) { + char launch_cmd[1024]; + snprintf(launch_cmd, sizeof(launch_cmd), + "am start -W --ez :settings:show_fragment_as_subsetting true -n 'com.android.settings/.%s'", name); + system(launch_cmd); +} + +struct Updater { + bool do_exit = false; + + TouchState touch; + + int fb_w, fb_h; + EGLDisplay display; + EGLSurface surface; + + FramebufferState *fb = NULL; + NVGcontext *vg = NULL; + int font_regular; + int font_semibold; + int font_bold; + + std::thread update_thread_handle; + + std::mutex lock; + + // i hate state machines give me coroutines already + enum UpdateState { + CONFIRMATION, + LOW_BATTERY, + RUNNING, + ERROR, + }; + UpdateState state; + + std::string progress_text; + float progress_frac; + + std::string error_text; + + std::string low_battery_text; + std::string low_battery_title; + std::string low_battery_context; + std::string battery_cap_text; + int min_battery_cap = 35; + + // button + int b_x, b_w, b_y, b_h; + int balt_x; + + CURL *curl = NULL; + + Updater() { + touch_init(&touch); + + fb = framebuffer_init("updater", 0x00001000, false, + &display, &surface, &fb_w, &fb_h); + assert(fb); + + vg = nvgCreateGLES3(NVG_ANTIALIAS | NVG_STENCIL_STROKES | NVG_DEBUG); + assert(vg); + + font_regular = nvgCreateFontMem(vg, "opensans_regular", (unsigned char*)bin_opensans_regular, (bin_opensans_regular_end - bin_opensans_regular), 0); + assert(font_regular >= 0); + + font_semibold = nvgCreateFontMem(vg, "opensans_semibold", (unsigned char*)bin_opensans_semibold, (bin_opensans_semibold_end - bin_opensans_semibold), 0); + assert(font_semibold >= 0); + + font_bold = nvgCreateFontMem(vg, "opensans_bold", (unsigned char*)bin_opensans_bold, (bin_opensans_bold_end - bin_opensans_bold), 0); + assert(font_bold >= 0); + + b_w = 640; + balt_x = 200; + b_x = fb_w-b_w-200; + b_y = 720; + b_h = 220; + + state = CONFIRMATION; + + } + + int download_file_xferinfo(curl_off_t dltotal, curl_off_t dlno, + curl_off_t ultotal, curl_off_t ulnow) { + { + std::lock_guard guard(lock); + if (dltotal != 0) { + progress_frac = (float) dlno / dltotal; + } + } + // printf("info: %ld %ld %f\n", dltotal, dlno, progress_frac); + return 0; + } + + bool download_file(std::string url, std::string out_fn) { + FILE *of = fopen(out_fn.c_str(), "ab"); + assert(of); + + CURLcode res; + long last_resume_from = 0; + + fseek(of, 0, SEEK_END); + + int tries = 4; + + bool ret = false; + + while (true) { + long resume_from = ftell(of); + + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT); + curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); + curl_easy_setopt(curl, CURLOPT_RESUME_FROM, resume_from); + + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, download_file_write); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, of); + + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); + + curl_easy_setopt(curl, CURLOPT_XFERINFODATA, this); + curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, &Updater::download_file_xferinfo); + + CURLcode res = curl_easy_perform(curl); + + long response_code = 0; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + + // double content_length = 0.0; + // curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &content_length); + + printf("download %s res %d, code %ld, resume from %ld\n", url.c_str(), res, response_code, resume_from); + if (res == CURLE_OK) { + ret = true; + break; + } else if (res == CURLE_HTTP_RETURNED_ERROR && response_code == 416) { + // failed because the file is already complete? + ret = true; + break; + } else if (resume_from == last_resume_from) { + // failed and dind't make make forward progress. only retry a couple times + tries--; + if (tries <= 0) { + break; + } + } + last_resume_from = resume_from; + } + // printf("res %d\n", res); + + // printf("- %ld %f\n", response_code, content_length); + + fclose(of); + + return ret; + } + + void set_progress(std::string text) { + std::lock_guard guard(lock); + progress_text = text; + } + + void set_error(std::string text) { + std::lock_guard guard(lock); + error_text = text; + state = ERROR; + } + + void set_battery_low() { + std::lock_guard guard(lock); + state = LOW_BATTERY; + } + + void set_running() { + std::lock_guard guard(lock); + state = RUNNING; + } + + std::string stage_download(std::string url, std::string hash, std::string name) { + std::string out_fn = UPDATE_DIR "/" + util::base_name(url); + + set_progress("Downloading " + name + "..."); + bool r = download_file(url, out_fn); + if (!r) { + set_error("failed to download " + name); + return ""; + } + + set_progress("Verifying " + name + "..."); + std::string fn_hash = sha256_file(out_fn); + printf("got %s hash: %s\n", name.c_str(), hash.c_str()); + if (fn_hash != hash) { + set_error(name + " was corrupt"); + unlink(out_fn.c_str()); + return ""; + } + + return out_fn; + } + + void run_stages() { + curl = curl_easy_init(); + assert(curl); + + if (!check_battery()) { + set_battery_low(); + int battery_cap = battery_capacity(); + while(battery_cap < min_battery_cap) { + battery_cap = battery_capacity(); + battery_cap_text = std::to_string(battery_cap); + usleep(1000000); + } + set_running(); + } + + if (!check_space()) { + set_error("2GB of free space required to update"); + return; + } + + mkdir(UPDATE_DIR, 0777); + + const int EON = (access("/EON", F_OK) != -1); + + set_progress("Finding latest version..."); + std::string manifest_s; + if (EON) { + manifest_s = download_string(curl, manifest_url); + } else { + // don't update NEO + exit(0); + } + + printf("manifest: %s\n", manifest_s.c_str()); + + std::string err; + auto manifest = json11::Json::parse(manifest_s, err); + if (manifest.is_null() || !err.empty()) { + set_error("failed to load update manifest"); + return; + } + + std::string ota_url = manifest["ota_url"].string_value(); + std::string ota_hash = manifest["ota_hash"].string_value(); + + std::string recovery_url = manifest["recovery_url"].string_value(); + std::string recovery_hash = manifest["recovery_hash"].string_value(); + int recovery_len = manifest["recovery_len"].int_value(); + + // std::string installer_url = manifest["installer_url"].string_value(); + // std::string installer_hash = manifest["installer_hash"].string_value(); + + if (ota_url.empty() || ota_hash.empty()) { + set_error("invalid update manifest"); + return; + } + + // std::string installer_fn = stage_download(installer_url, installer_hash, "installer"); + // if (installer_fn.empty()) { + // //error'd + // return; + // } + + std::string recovery_fn; + if (recovery_url.empty() || recovery_hash.empty() || recovery_len == 0) { + set_progress("Skipping recovery flash..."); + } else { + // only download the recovery if it differs from what's flashed + set_progress("Checking recovery..."); + std::string existing_recovery_hash = sha256_file(RECOVERY_DEV, recovery_len); + printf("existing recovery hash: %s\n", existing_recovery_hash.c_str()); + + if (existing_recovery_hash != recovery_hash) { + recovery_fn = stage_download(recovery_url, recovery_hash, "recovery"); + if (recovery_fn.empty()) { + // error'd + return; + } + } + } + + std::string ota_fn = stage_download(ota_url, ota_hash, "update"); + if (ota_fn.empty()) { + //error'd + return; + } + + if (!check_battery()) { + set_battery_low(); + int battery_cap = battery_capacity(); + while(battery_cap < min_battery_cap) { + battery_cap = battery_capacity(); + battery_cap_text = std::to_string(battery_cap); + usleep(1000000); + } + set_running(); + } + + if (!recovery_fn.empty()) { + // flash recovery + set_progress("Flashing recovery..."); + + FILE *flash_file = fopen(recovery_fn.c_str(), "rb"); + if (!flash_file) { + set_error("failed to flash recovery"); + return; + } + + FILE *recovery_dev = fopen(RECOVERY_DEV, "w+b"); + if (!recovery_dev) { + fclose(flash_file); + set_error("failed to flash recovery"); + return; + } + + const size_t buf_size = 4096; + std::unique_ptr buffer( new char[ buf_size ] ); + + while (true) { + size_t bytes_read = fread(buffer.get(), 1, buf_size, flash_file); + if (!bytes_read) break; + + size_t bytes_written = fwrite(buffer.get(), 1, bytes_read, recovery_dev); + if (bytes_read != bytes_written) { + fclose(recovery_dev); + fclose(flash_file); + set_error("failed to flash recovery: write failed"); + return; + } + } + + fclose(recovery_dev); + fclose(flash_file); + + set_progress("Verifying flash..."); + std::string new_recovery_hash = sha256_file(RECOVERY_DEV, recovery_len); + printf("new recovery hash: %s\n", new_recovery_hash.c_str()); + + if (new_recovery_hash != recovery_hash) { + set_error("recovery flash corrupted"); + return; + } + + } + + // write arguments to recovery + FILE *cmd_file = fopen(RECOVERY_COMMAND, "wb"); + if (!cmd_file) { + set_error("failed to reboot into recovery"); + return; + } + fprintf(cmd_file, "--update_package=%s\n", ota_fn.c_str()); + fclose(cmd_file); + + set_progress("Rebooting"); + + // remove the continue.sh so we come back into the setup. + // maybe we should go directly into the installer, but what if we don't come back with internet? :/ + //unlink("/data/data/com.termux/files/continue.sh"); + + // TODO: this should be generic between android versions + // IPowerManager.reboot(confirm=false, reason="recovery", wait=true) + system("service call power 16 i32 0 s16 recovery i32 1"); + while(1) pause(); + + // execl("/system/bin/reboot", "recovery"); + // set_error("failed to reboot into recovery"); + } + + void draw_ack_screen(const char *title, const char *message, const char *button, const char *altbutton) { + nvgFillColor(vg, nvgRGBA(255,255,255,255)); + nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); + + nvgFontFace(vg, "opensans_bold"); + nvgFontSize(vg, 120.0f); + nvgTextBox(vg, 110, 220, fb_w-240, title, NULL); + + nvgFontFace(vg, "opensans_regular"); + nvgFontSize(vg, 86.0f); + nvgTextBox(vg, 130, 380, fb_w-260, message, NULL); + + // draw button + if (button) { + nvgBeginPath(vg); + nvgFillColor(vg, nvgRGBA(8, 8, 8, 255)); + nvgRoundedRect(vg, b_x, b_y, b_w, b_h, 20); + nvgFill(vg); + + nvgFillColor(vg, nvgRGBA(255, 255, 255, 255)); + nvgFontFace(vg, "opensans_semibold"); + nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE); + nvgText(vg, b_x+b_w/2, b_y+b_h/2, button, NULL); + + nvgBeginPath(vg); + nvgStrokeColor(vg, nvgRGBA(255, 255, 255, 50)); + nvgStrokeWidth(vg, 5); + nvgRoundedRect(vg, b_x, b_y, b_w, b_h, 20); + nvgStroke(vg); + } + + // draw button + if (altbutton) { + nvgBeginPath(vg); + nvgFillColor(vg, nvgRGBA(8, 8, 8, 255)); + nvgRoundedRect(vg, balt_x, b_y, b_w, b_h, 20); + nvgFill(vg); + + nvgFillColor(vg, nvgRGBA(255, 255, 255, 255)); + nvgFontFace(vg, "opensans_semibold"); + nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE); + nvgText(vg, balt_x+b_w/2, b_y+b_h/2, altbutton, NULL); + + nvgBeginPath(vg); + nvgStrokeColor(vg, nvgRGBA(255, 255, 255, 50)); + nvgStrokeWidth(vg, 5); + nvgRoundedRect(vg, balt_x, b_y, b_w, b_h, 20); + nvgStroke(vg); + } + } + + void draw_battery_screen() { + low_battery_title = "Low Battery"; + low_battery_text = "Please connect EON to your charger. Update will continue once EON battery reaches 35%."; + low_battery_context = "Current battery charge: " + battery_cap_text + "%"; + + nvgFillColor(vg, nvgRGBA(255,255,255,255)); + nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); + + nvgFontFace(vg, "opensans_bold"); + nvgFontSize(vg, 120.0f); + nvgTextBox(vg, 110, 220, fb_w-240, low_battery_title.c_str(), NULL); + + nvgFontFace(vg, "opensans_regular"); + nvgFontSize(vg, 86.0f); + nvgTextBox(vg, 130, 380, fb_w-260, low_battery_text.c_str(), NULL); + + nvgFontFace(vg, "opensans_bold"); + nvgFontSize(vg, 86.0f); + nvgTextBox(vg, 130, 700, fb_w-260, low_battery_context.c_str(), NULL); + } + + void draw_progress_screen() { + // draw progress message + nvgFontSize(vg, 64.0f); + nvgFillColor(vg, nvgRGBA(255,255,255,255)); + nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); + nvgFontFace(vg, "opensans_bold"); + nvgFontSize(vg, 86.0f); + nvgTextBox(vg, 0, 380, fb_w, progress_text.c_str(), NULL); + + // draw progress bar + { + int progress_width = 1000; + int progress_x = fb_w/2-progress_width/2; + int progress_y = 520; + int progress_height = 50; + + int powerprompt_y = 312; + nvgFontFace(vg, "opensans_regular"); + nvgFontSize(vg, 64.0f); + nvgText(vg, fb_w/2, 740, "Ensure EON is connected to power.", NULL); + + NVGpaint paint = nvgBoxGradient( + vg, progress_x + 1, progress_y + 1, + progress_width - 2, progress_height, 3, 4, nvgRGB(27, 27, 27), nvgRGB(27, 27, 27)); + nvgBeginPath(vg); + nvgRoundedRect(vg, progress_x, progress_y, progress_width, progress_height, 12); + nvgFillPaint(vg, paint); + nvgFill(vg); + + float value = std::min(std::max(0.0f, progress_frac), 1.0f); + int bar_pos = ((progress_width - 2) * value); + + paint = nvgBoxGradient( + vg, progress_x, progress_y, + bar_pos+1.5f, progress_height-1, 3, 4, + nvgRGB(245, 245, 245), nvgRGB(105, 105, 105)); + + nvgBeginPath(vg); + nvgRoundedRect( + vg, progress_x+1, progress_y+1, + bar_pos, progress_height-2, 12); + nvgFillPaint(vg, paint); + nvgFill(vg); + } + } + + void ui_draw() { + std::lock_guard guard(lock); + + nvgBeginFrame(vg, fb_w, fb_h, 1.0f); + + switch (state) { + case CONFIRMATION: + draw_ack_screen("An update to NEOS is required.", + "Your device will now be reset and upgraded. You may want to connect to wifi as download is around 1 GB. Existing data on device should not be lost.", + "Continue", + "Connect to WiFi"); + break; + case LOW_BATTERY: + draw_battery_screen(); + break; + case RUNNING: + draw_progress_screen(); + break; + case ERROR: + draw_ack_screen("There was an error", (error_text).c_str(), NULL, "Reboot"); + break; + } + + nvgEndFrame(vg); + } + + void ui_update() { + std::lock_guard guard(lock); + + switch (state) { + case ERROR: + case CONFIRMATION: { + int touch_x = -1, touch_y = -1; + int res = touch_poll(&touch, &touch_x, &touch_y, 0); + if (res == 1 && !is_settings_active()) { + if (touch_x >= b_x && touch_x < b_x+b_w && touch_y >= b_y && touch_y < b_y+b_h) { + if (state == CONFIRMATION) { + state = RUNNING; + update_thread_handle = std::thread(&Updater::run_stages, this); + } + } + if (touch_x >= balt_x && touch_x < balt_x+b_w && touch_y >= b_y && touch_y < b_y+b_h) { + if (state == CONFIRMATION) { + start_settings_activity("Settings$WifiSettingsActivity"); + } else if (state == ERROR) { + do_exit = 1; + } + } + } + } + default: + break; + } + } + + + void go() { + while (!do_exit) { + ui_update(); + + glClearColor(0.08, 0.08, 0.08, 1.0); + glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + + // background + nvgBeginPath(vg); + NVGpaint bg = nvgLinearGradient(vg, fb_w, 0, fb_w, fb_h, + nvgRGBA(0, 0, 0, 0), nvgRGBA(0, 0, 0, 255)); + nvgFillPaint(vg, bg); + nvgRect(vg, 0, 0, fb_w, fb_h); + nvgFill(vg); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + ui_draw(); + + glDisable(GL_BLEND); + + eglSwapBuffers(display, surface); + + assert(glGetError() == GL_NO_ERROR); + + // no simple way to do 30fps vsync with surfaceflinger... + usleep(30000); + } + + if (update_thread_handle.joinable()) { + update_thread_handle.join(); + } + + system("service call power 16 i32 0 i32 0 i32 1"); + } + + bool is_settings_active() { + FILE *fp; + char sys_output[4096]; + + fp = popen("/bin/dumpsys window windows", "r"); + if (fp == NULL) { + return false; + } + + bool active = false; + while (fgets(sys_output, sizeof(sys_output), fp) != NULL) { + if (strstr(sys_output, "mCurrentFocus=null") != NULL) { + break; + } + + if (strstr(sys_output, "mCurrentFocus=Window") != NULL) { + active = true; + break; + } + } + + pclose(fp); + + return active; + } + +}; + +} +int main(int argc, char *argv[]) { + if (argc > 1) { + if (strcmp(argv[1], "local") == 0) { + manifest_url = MANIFEST_URL_EON_LOCAL; + } else if (strcmp(argv[1], "staging") == 0) { + manifest_url = MANIFEST_URL_EON_STAGING; + } else { + manifest_url = argv[1]; + } + } + printf("updating from %s\n", manifest_url); + Updater updater; + updater.go(); + + return 0; +} diff --git a/launch_chffrplus.sh b/launch_chffrplus.sh index 41f8a607cf9ca5..56c25e6ffee090 100755 --- a/launch_chffrplus.sh +++ b/launch_chffrplus.sh @@ -1,5 +1,11 @@ #!/usr/bin/bash +export OMP_NUM_THREADS=1 +export MKL_NUM_THREADS=1 +export NUMEXPR_NUM_THREADS=1 +export OPENBLAS_NUM_THREADS=1 +export VECLIB_MAXIMUM_THREADS=1 + if [ -z "$PASSIVE" ]; then export PASSIVE="1" fi @@ -7,9 +13,16 @@ fi function launch { # apply update if [ "$(git rev-parse HEAD)" != "$(git rev-parse @{u})" ]; then - git reset --hard @{u} && - git clean -xdf && - exec "${BASH_SOURCE[0]}" + git reset --hard @{u} && + git clean -xdf && + + # Touch all files on release2 after checkout to prevent rebuild + BRANCH=$(git rev-parse --abbrev-ref HEAD) + if [[ "$BRANCH" == "release2" ]]; then + touch ** + fi + + exec "${BASH_SOURCE[0]}" fi # no cpu rationing for now @@ -19,6 +32,26 @@ function launch { echo 0-3 > /dev/cpuset/foreground/cpus echo 0-3 > /dev/cpuset/android/cpus + DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" + + # Remove old NEOS update file + if [ -d /data/neoupdate ]; then + rm -rf /data/neoupdate + fi + + # Check for NEOS update + if [ $(< /VERSION) != "12" ]; then + if [ -f "$DIR/scripts/continue.sh" ]; then + cp "$DIR/scripts/continue.sh" "/data/data/com.termux/files/continue.sh" + fi + + git clean -xdf + "$DIR/installer/updater/updater" "file://$DIR/installer/updater/update.json" + fi + + + # handle pythonpath + ln -s /data/openpilot /data/pythonpath export PYTHONPATH="$PWD" # start manager diff --git a/models/driving_model.dlc b/models/driving_model.dlc index a33c1feb084a55..e04f9f93a1a0fa 100644 Binary files a/models/driving_model.dlc and b/models/driving_model.dlc differ diff --git a/models/monitoring_model.dlc b/models/monitoring_model.dlc index 0b9f8060d93d92..d252d5d158dbbc 100644 Binary files a/models/monitoring_model.dlc and b/models/monitoring_model.dlc differ diff --git a/opendbc/acura_ilx_2016_can_generated.dbc b/opendbc/acura_ilx_2016_can_generated.dbc index dd112ca32ccc41..2a2a941a59a7e9 100644 --- a/opendbc/acura_ilx_2016_can_generated.dbc +++ b/opendbc/acura_ilx_2016_can_generated.dbc @@ -78,6 +78,7 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM BO_ 420 VSA_STATUS: 8 VSA SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" EON + SG_ COMPUTER_BRAKING : 23|1@0+ (1,0) [0|1] "" EON SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" EON SG_ BRAKE_HOLD_RELATED : 52|1@0+ (1,0) [0|1] "" XXX SG_ BRAKE_HOLD_ACTIVE : 46|1@0+ (1,0) [0|1] "" EON @@ -107,21 +108,24 @@ BO_ 490 VEHICLE_DYNAMICS: 8 VSA BO_ 506 BRAKE_COMMAND: 8 ADAS SG_ COMPUTER_BRAKE : 7|10@0+ (1,0) [0|1] "" EBCM - SG_ ZEROS_BOH : 13|5@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00 : 13|5@0+ (1,0) [0|1] "" EBCM SG_ BRAKE_PUMP_REQUEST : 8|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH2 : 23|3@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_2 : 23|3@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH3 : 19|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_3 : 19|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM SG_ COMPUTER_BRAKE_REQUEST : 16|1@0+ (1,0) [0|1] "" EBCM - SG_ SET_ME_0X80 : 31|8@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_1 : 31|1@0+ (1,0) [0|1] "" EBCM + SG_ AEB_REQ_1 : 29|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_REQ_2 : 26|3@0+ (1,0) [0|7] "" XXX SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_STATES : 38|7@0+ (1,0) [0|1] "" EBCM SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM - SG_ ZEROS_BOH6 : 44|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_4 : 44|1@0+ (1,0) [0|1] "" EBCM SG_ FCW : 43|2@0+ (1,0) [0|3] "" EBCM - SG_ ZEROS_BOH4 : 55|8@0+ (1,0) [0|0] "" EBCM + SG_ AEB_STATUS : 41|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X00_5 : 55|8@0+ (1,0) [0|0] "" EBCM SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EBCM @@ -164,14 +168,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY @@ -222,6 +227,7 @@ BO_ 1029 DOORS_STATUS: 8 BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping"; +CM_ SG_ 506 AEB_REQ_1 "set for duration of suspected AEB event"; CM_ SG_ 773 PASS_AIRBAG_ON "Might just be indicator light"; CM_ SG_ 773 PASS_AIRBAG_OFF "Might just be indicator light"; CM_ SG_ 780 CRUISE_SPEED "255 = no speed"; @@ -231,6 +237,7 @@ CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc..."; VAL_ 506 FCW 3 "fcw" 2 "fcw" 1 "fcw" 0 "no_fcw" ; VAL_ 506 CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime" ; +VAL_ 506 AEB_STATUS 3 "aeb_prepare" 2 "aeb_ready" 1 "aeb_braking" 0 "no_aeb" ; VAL_ 780 CRUISE_SPEED 255 "no_speed" 252 "stopped" ; VAL_ 780 HUD_LEAD 3 "acc_off" 2 "solid_car" 1 "dashed_car" 0 "no_car" ; VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; diff --git a/opendbc/acura_rdx_2018_can_generated.dbc b/opendbc/acura_rdx_2018_can_generated.dbc index a8e69b14e6c08d..48c9b3967d12da 100644 --- a/opendbc/acura_rdx_2018_can_generated.dbc +++ b/opendbc/acura_rdx_2018_can_generated.dbc @@ -78,6 +78,7 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM BO_ 420 VSA_STATUS: 8 VSA SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" EON + SG_ COMPUTER_BRAKING : 23|1@0+ (1,0) [0|1] "" EON SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" EON SG_ BRAKE_HOLD_RELATED : 52|1@0+ (1,0) [0|1] "" XXX SG_ BRAKE_HOLD_ACTIVE : 46|1@0+ (1,0) [0|1] "" EON @@ -107,21 +108,24 @@ BO_ 490 VEHICLE_DYNAMICS: 8 VSA BO_ 506 BRAKE_COMMAND: 8 ADAS SG_ COMPUTER_BRAKE : 7|10@0+ (1,0) [0|1] "" EBCM - SG_ ZEROS_BOH : 13|5@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00 : 13|5@0+ (1,0) [0|1] "" EBCM SG_ BRAKE_PUMP_REQUEST : 8|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH2 : 23|3@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_2 : 23|3@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH3 : 19|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_3 : 19|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM SG_ COMPUTER_BRAKE_REQUEST : 16|1@0+ (1,0) [0|1] "" EBCM - SG_ SET_ME_0X80 : 31|8@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_1 : 31|1@0+ (1,0) [0|1] "" EBCM + SG_ AEB_REQ_1 : 29|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_REQ_2 : 26|3@0+ (1,0) [0|7] "" XXX SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_STATES : 38|7@0+ (1,0) [0|1] "" EBCM SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM - SG_ ZEROS_BOH6 : 44|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_4 : 44|1@0+ (1,0) [0|1] "" EBCM SG_ FCW : 43|2@0+ (1,0) [0|3] "" EBCM - SG_ ZEROS_BOH4 : 55|8@0+ (1,0) [0|0] "" EBCM + SG_ AEB_STATUS : 41|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X00_5 : 55|8@0+ (1,0) [0|0] "" EBCM SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EBCM @@ -164,14 +168,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY @@ -222,6 +227,7 @@ BO_ 1029 DOORS_STATUS: 8 BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping"; +CM_ SG_ 506 AEB_REQ_1 "set for duration of suspected AEB event"; CM_ SG_ 773 PASS_AIRBAG_ON "Might just be indicator light"; CM_ SG_ 773 PASS_AIRBAG_OFF "Might just be indicator light"; CM_ SG_ 780 CRUISE_SPEED "255 = no speed"; @@ -231,6 +237,7 @@ CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc..."; VAL_ 506 FCW 3 "fcw" 2 "fcw" 1 "fcw" 0 "no_fcw" ; VAL_ 506 CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime" ; +VAL_ 506 AEB_STATUS 3 "aeb_prepare" 2 "aeb_ready" 1 "aeb_braking" 0 "no_aeb" ; VAL_ 780 CRUISE_SPEED 255 "no_speed" 252 "stopped" ; VAL_ 780 HUD_LEAD 3 "acc_off" 2 "solid_car" 1 "dashed_car" 0 "no_car" ; VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; diff --git a/opendbc/cadillac_ct6_powertrain.dbc b/opendbc/cadillac_ct6_powertrain.dbc index f139b1dbd4a734..a91cdc14fe98d7 100644 --- a/opendbc/cadillac_ct6_powertrain.dbc +++ b/opendbc/cadillac_ct6_powertrain.dbc @@ -189,7 +189,7 @@ BO_ 1033 ASCMKeepAlive: 7 NEO SG_ ASCMKeepAliveAllZero : 7|56@0+ (1,0) [0|0] "" NEO BO_ 1217 ECMEngineCoolantTemp: 8 K20_ECM - SG_ EngineCoolantTemp : 23|8@0+ (1,-40) [0|0] "°C" NEO + SG_ EngineCoolantTemp : 23|8@0+ (1,-40) [0|0] "C" NEO BO_ 1249 VIN_Part2: 8 K20_ECM SG_ VINPart2 : 7|64@0+ (1,0) [0|0] "" NEO @@ -241,4 +241,3 @@ VAL_ 356 LKATorqueDeliveredStatus 7 "Override Fault" 6 "LKAS Fault but Responsiv VAL_ 489 BrakePedalPressed 1 "Pressed" 0 "Depressed" ; VAL_ 715 GasRegenCmdActiveInv 1 "Inactive" 0 "Active" ; VAL_ 715 GasRegenCmdActive 1 "Active" 0 "Inactive" ; - diff --git a/opendbc/chrysler_pacifica_2017_hybrid.dbc b/opendbc/chrysler_pacifica_2017_hybrid.dbc index dd5a7fe99ffd7c..a19219cbb2aedf 100644 --- a/opendbc/chrysler_pacifica_2017_hybrid.dbc +++ b/opendbc/chrysler_pacifica_2017_hybrid.dbc @@ -132,13 +132,12 @@ BO_ 705 AUTO_PARK_BUTTON: 8 XXX BO_ 719 AUTO_PARK_SIGNALS_1: 8 XXX SG_ AUTO_PARK_UNKNOWN_1 : 7|16@0+ (1,0) [0|31] "" XXX -BO_ 671 AUTO_PARK_SIGNALS_2: 8 XXX - SG_ AUTO_PARK_PARALLEL : 21|1@0+ (1,0) [0|1] "" XXX - SG_ AUTO_PARK_PERPENDICULAR_1 : 22|1@0+ (1,0) [0|1] "" XXX - SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX +BO_ 671 AUTO_PARK_REQUEST: 8 XXX SG_ AUTO_PARK_CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - SG_ AUTO_PARK_MAYBE_TURNING : 3|12@0+ (1,0) [0|1023] "" XXX - SG_ AUTO_PARK_TURNING_STATUS : 7|4@0+ (1,0) [0|15] "" XXX + SG_ AUTO_PARK_STATUS : 7|5@0+ (1,0) [0|15] "" XXX + SG_ AUTO_PARK_COUNTER : 55|4@0+ (1,0) [0|15] "" XXX + SG_ AUTO_PARK_MODE : 22|2@0+ (1,0) [0|3] "" XXX + SG_ AUTO_PARK_CMD : 2|11@0+ (1,-1024) [0|1] "NM" XXX BO_ 784 AUTO_PARK_LESS_INTERESTING: 8 XXX SG_ INCREASING_UNKNOWN : 55|8@0+ (1,0) [0|7] "" XXX @@ -209,6 +208,7 @@ BO_ 571 WHEEL_BUTTONS: 3 XXX SG_ ACC_FOLLOW_INC : 8|1@0+ (1,0) [0|15] "" XXX SG_ ACC_CANCEL : 0|1@0+ (1,0) [0|15] "" XXX SG_ COUNTER : 15|4@0+ (1,0) [0|15] "" XXX + SG_ ACC_RESUME : 4|1@0+ (1,0) [0|15] "" XXX BO_ 669 NEW_MSG_29d: 3 XXX SG_ COUNTER : 15|4@0+ (1,0) [0|15] "" XXX @@ -261,7 +261,7 @@ BO_ 300 NEW_MSG_12C: 8 XXX BO_ 308 ACCEL_GAS_134: 8 XXX SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX - SG_ ACCEL_134 : 43|4@0+ (1,0) [0|15] "" XXX + SG_ ACCEL_134 : 46|7@0+ (1,0) [0|127] "" XXX BO_ 532 ENERGY_RELATED_214: 8 XXX SG_ NOISY_SLOWLY_DECREASING : 16|9@0+ (1,0) [0|255] "" XXX @@ -392,10 +392,8 @@ CM_ SG_ 678 LKAS_LANE_LINES "0x01 transparent lines, 0x02 left white, 0x03 right CM_ SG_ 678 LKAS_ALERTS "(0x01, 0x02) lane sense off, (0x03, 0x04, 0x06) place hands on steering wheel, 0x07 lane departure detected + place hands on steering wheel, (0x08, 0x09) lane sense unavailable + clean front windshield, 0x0b lane sense and auto high beam unavailable + clean front windshield, 0x0c lane sense unavailable + service required, (0x00, 0x05, 0x0a, 0x0d, 0x0e, 0x0f) null"; CM_ SG_ 705 AUTO_PARK_TOGGLE_1 "set briefly when turning on or off self-parking"; CM_ SG_ 705 INCREASING_UNKNOWN "sometimes decreasing"; -CM_ SG_ 671 AUTO_PARK_PARALLEL "parallel parking mode"; -CM_ SG_ 671 AUTO_PARK_PERPENDICULAR_1 "perpendicular parking mode"; -CM_ SG_ 671 AUTO_PARK_MAYBE_TURNING "something with autopark turning the steering wheel maybe."; -CM_ SG_ 671 AUTO_PARK_TURNING_STATUS "0 when not steering. when steering starts, 4 for two packets, and then 5 for the rest"; +CM_ SG_ 671 AUTO_PARK_CMD "Request Appears to be in NM"; +CM_ SG_ 671 AUTO_PARK_STATUS "1 = IDLE / NO REQUEST 9 = START REQUEST 10 = REQUEST MODE 11 = REQUEST MODE"; CM_ SG_ 784 INCREASING_UNKNOWN "perhaps distance traveled"; CM_ SG_ 826 AUTO_PARK_GEAR_1 "Reverse=0, Forward=f"; CM_ SG_ 826 AUTO_PARK_GEAR_2 "Reverse=0, Forward=f"; @@ -412,6 +410,7 @@ CM_ SG_ 825 BEEP_339 "sent every 0.5s. 0050 is no beep. To beep send 4355 or 415 CM_ SG_ 270 ELECTRIC_MOTOR "0x7fff indicates electric motor not in use"; CM_ SG_ 291 ENERGY_GAIN_LOSS "unsure what this actually is"; CM_ SG_ 291 ENERGY_SMOOTHER_CURVE "unusre what it is, but smoother"; +CM_ SG_ 308 ACCEL_134 "only set when human presses accel pedal"; CM_ SG_ 532 NOISY_SLOWLY_DECREASING "perhaps battery but do not know"; CM_ SG_ 816 TRACTION_OFF "set when traction off button is enabled"; CM_ SG_ 816 TOGGLE_PARKSENSE "sending 3000071ec0ff9000 enables or disables parksense"; diff --git a/opendbc/ford_cgea1_2_bodycan_2011.dbc b/opendbc/ford_cgea1_2_bodycan_2011.dbc index e13743a66a805b..49fcae19c2e4f8 100644 --- a/opendbc/ford_cgea1_2_bodycan_2011.dbc +++ b/opendbc/ford_cgea1_2_bodycan_2011.dbc @@ -31,6 +31,8 @@ NS_ : BU_BO_REL_ SG_MUL_VAL_ +BS_: + BU_: XXX diff --git a/opendbc/ford_cgea1_2_ptcan_2011.dbc b/opendbc/ford_cgea1_2_ptcan_2011.dbc index cc5635fa8ce4cc..128721cbbf7628 100644 --- a/opendbc/ford_cgea1_2_ptcan_2011.dbc +++ b/opendbc/ford_cgea1_2_ptcan_2011.dbc @@ -31,6 +31,8 @@ NS_ : BU_BO_REL_ SG_MUL_VAL_ +BS_: + BU_: XXX diff --git a/opendbc/ford_fusion_2018_adas.dbc b/opendbc/ford_fusion_2018_adas.dbc index 63a0b9909c3c3b..2e1647b3d8dee5 100644 --- a/opendbc/ford_fusion_2018_adas.dbc +++ b/opendbc/ford_fusion_2018_adas.dbc @@ -31,6 +31,8 @@ NS_ : BU_BO_REL_ SG_MUL_VAL_ +BS_: + BU_: XXX BO_ 1280 Object_00: 8 XXX diff --git a/opendbc/ford_fusion_2018_pt.dbc b/opendbc/ford_fusion_2018_pt.dbc index 1667a360b529d6..c4b706d0647039 100644 --- a/opendbc/ford_fusion_2018_pt.dbc +++ b/opendbc/ford_fusion_2018_pt.dbc @@ -31,6 +31,8 @@ NS_ : BU_BO_REL_ SG_MUL_VAL_ +BS_: + BU_: XXX BO_ 130 EPAS_INFO: 8 XXX @@ -128,9 +130,10 @@ BO_ 984 Lane_Keep_Assist_Ui: 8 XXX SG_ Hands_Warning : 49|1@0+ (1,0) [0|1] "" XXX SG_ Set_Me_X30 : 63|8@0+ (1,0) [0|255] "" XXX +CM_ SG_ 970 Lkas_Action "only vals 4, 5, 8, 9 seem to work. 4 and 5 are a bit smoother" ; + VAL_ 357 Cruise_State 4 "active" 3 "standby" 0 "off" ; VAL_ 970 Lkas_Action 15 "off" 9 "abrupt" 8 "abrupt2" 5 "smooth" 4 "smooth2" ; VAL_ 970 Lkas_Alert 15 "no_alert" 3 "high_intensity" 2 "mid_intensity" 1 "low_intensity" ; VAL_ 972 LaActAvail_D_Actl 3 "available" 2 "tbd" 1 "not_available" 0 "fault" ; VAL_ 984 Lines_Hud 15 "none" 11 "grey_yellow" 8 "green_red" 7 "yellow_grey" 6 "grey_grey" 4 "red_green" 3 "green_green" ; -CM_ SG_ 970 Lkas_Action "only vals 4, 5, 8, 9 seem to work. 4 and 5 are a bit smoother" ; diff --git a/opendbc/generator/generator.py b/opendbc/generator/generator.py index 85f3f009e27d02..ca7daac5ca6e38 100755 --- a/opendbc/generator/generator.py +++ b/opendbc/generator/generator.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 import os import re @@ -40,10 +40,10 @@ def create_dbc(dir_name, filename): if dir_name == cur_path: continue - print dir_name + print(dir_name) for filename in filenames: if filename.startswith('_'): continue - print filename + print(filename) create_dbc(dir_name, filename) diff --git a/opendbc/generator/honda/_bosch_2018.dbc b/opendbc/generator/honda/_bosch_2018.dbc index 0b8d8a17f02c9e..648f4b310c4367 100644 --- a/opendbc/generator/honda/_bosch_2018.dbc +++ b/opendbc/generator/honda/_bosch_2018.dbc @@ -33,6 +33,12 @@ NS_ : BU_: EBCM EON CAM RADAR PCM EPS VSA SCM BDY XXX EPB +BO_ 148 KINEMATICS: 8 XXX + SG_ LAT_ACCEL : 7|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON + SG_ LONG_ACCEL : 25|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + BO_ 228 STEERING_CONTROL: 5 EON SG_ STEER_TORQUE_REQUEST : 23|1@0+ (1,0) [0|1] "" EPS SG_ SET_ME_X00 : 22|7@0+ (1,0) [0|127] "" EPS @@ -114,15 +120,26 @@ BO_ 464 WHEEL_SPEEDS: 8 VSA SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON BO_ 479 ACC_CONTROL: 8 EON - SG_ SET_TO_1 : 20|5@0+ (1,0) [0|1] "" PCM + SG_ SET_TO_0 : 20|5@0+ (1,0) [0|1] "" XXX SG_ CONTROL_ON : 23|3@0+ (1,0) [0|5] "" XXX - SG_ RELATED_TO_GAS : 7|7@0+ (1,0) [0|69] "" XXX - SG_ GAS_COMMAND : 0|9@0+ (1,0) [0|1] "" PCM - SG_ GAS_BRAKE : 31|14@0- (1,0) [0|1] "" XXX - SG_ ZEROS_BOH : 33|18@0+ (1,0) [100|100] "" XXX + SG_ GAS_COMMAND : 7|16@0- (1,0) [0|0] "" XXX + SG_ ACCEL_COMMAND : 31|11@0- (0.01,0) [0|0] "m/s2" XXX + SG_ BRAKE_LIGHTS : 62|1@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_REQUEST : 34|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL : 35|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL_RELEASE : 36|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_STATUS : 33|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_BRAKING : 47|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_PREPARE : 43|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX +BO_ 490 VEHICLE_DYNAMICS: 8 VSA + SG_ LAT_ACCEL : 7|16@0- (0.0015,0) [-20|20] "m/s2" EON + SG_ LONG_ACCEL : 23|16@0- (0.0015,0) [-20|20] "m/s2" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + BO_ 495 ACC_CONTROL_ON: 8 XXX SG_ SET_TO_75 : 31|8@0+ (1,0) [0|255] "" XXX SG_ SET_TO_30 : 39|8@0+ (1,0) [0|255] "" XXX @@ -169,16 +186,16 @@ BO_ 773 SEATBELT_STATUS: 7 BDY SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON BO_ 777 CAR_SPEED: 8 PCM - SG_ ROUGH_CAR_SPEED : 23|8@0+ (1,0) [0|255] "" XXX - SG_ CAR_SPEED : 7|16@0+ (1,0) [0|65535] "" XXX - SG_ ROUGH_CAR_SPEED_3 : 39|16@0+ (1,0) [0|65535] "" XXX - SG_ ROUGH_CAR_SPEED_2 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ ROUGH_CAR_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX + SG_ CAR_SPEED : 7|16@0+ (0.01,0) [0|65535] "kph" XXX + SG_ ROUGH_CAR_SPEED_3 : 39|16@0+ (0.01,0) [0|65535] "kph" XXX + SG_ ROUGH_CAR_SPEED_2 : 31|8@0+ (1,0) [0|255] "mph" XXX SG_ LOCK_STATUS : 55|2@0+ (1,0) [0|255] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX BO_ 780 ACC_HUD: 8 ADAS - SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "" BDY + SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "kph" BDY SG_ DTC_MODE : 39|1@0+ (1,0) [0|1] "" BDY SG_ BOH : 38|1@0+ (1,0) [0|1] "" BDY SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY @@ -196,7 +213,8 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX - SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX + SG_ SET_TO_X1 : 55|1@0+ (1,0) [0|1] "" XXX + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX @@ -260,4 +278,8 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON -VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; \ No newline at end of file +CM_ SG_ 479 AEB_STATUS "set for the duration of AEB event"; +CM_ SG_ 479 AEB_BRAKING "set when braking is commanded during AEB event"; +CM_ SG_ 479 AEB_PREPARE "set 1s before AEB"; + +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; diff --git a/opendbc/generator/honda/_dual_can_nidec_2018.dbc b/opendbc/generator/honda/_dual_can_nidec_2018.dbc new file mode 100644 index 00000000000000..67c019c92f5ec4 --- /dev/null +++ b/opendbc/generator/honda/_dual_can_nidec_2018.dbc @@ -0,0 +1,215 @@ +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BU_: EBCM ADAS PCM EPS VSA SCM BDY XXX EPB EON + +BO_ 344 ENGINE_DATA: 8 PCM + SG_ XMISSION_SPEED : 7|16@0+ (0.01,0) [0|250] "kph" EON + SG_ ENGINE_RPM : 23|16@0+ (1,0) [0|15000] "rpm" EON + SG_ XMISSION_SPEED2 : 39|16@0+ (0.01,0) [0|250] "kph" EON + SG_ ODOMETER : 55|8@0+ (10,0) [0|2550] "m" XXX + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 380 POWERTRAIN_DATA: 8 PCM + SG_ PEDAL_GAS : 7|8@0+ (1,0) [0|255] "" EON + SG_ ENGINE_RPM : 23|16@0+ (1,0) [0|15000] "rpm" EON + SG_ GAS_PRESSED : 39|1@0+ (1,0) [0|1] "" EON + SG_ ACC_STATUS : 38|1@0+ (1,0) [0|1] "" EON + SG_ BOH_17C : 37|5@0+ (1,0) [0|1] "" EON + SG_ BRAKE_SWITCH : 32|1@0+ (1,0) [0|1] "" EON + SG_ BOH2_17C : 47|10@0+ (1,0) [0|1] "" EON + SG_ BRAKE_PRESSED : 53|1@0+ (1,0) [0|1] "" EON + SG_ BOH3_17C : 52|5@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 420 VSA_STATUS: 8 VSA + SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" EON + SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" EON + SG_ BRAKE_HOLD_RELATED : 52|1@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_HOLD_ACTIVE : 46|1@0+ (1,0) [0|1] "" EON + SG_ BRAKE_HOLD_ENABLED : 45|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 432 STANDSTILL: 7 VSA + SG_ CONTROLLED_STANDSTILL : 0|1@0+ (1,0) [0|1] "" EON + SG_ WHEELS_MOVING : 12|1@0+ (1,0) [0|1] "" EON + SG_ BRAKE_ERROR_1 : 11|1@0+ (1,0) [0|1] "" EON + SG_ BRAKE_ERROR_2 : 9|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON + +BO_ 464 WHEEL_SPEEDS: 8 VSA + SG_ WHEEL_SPEED_FL : 7|15@0+ (0.01,0) [0|250] "kph" EON + SG_ WHEEL_SPEED_FR : 8|15@0+ (0.01,0) [0|250] "kph" EON + SG_ WHEEL_SPEED_RL : 25|15@0+ (0.01,0) [0|250] "kph" EON + SG_ WHEEL_SPEED_RR : 42|15@0+ (0.01,0) [0|250] "kph" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 490 VEHICLE_DYNAMICS: 8 VSA + SG_ LONG_ACCEL : 23|16@0- (0.0015384,0) [-20|20] "m/s2" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 506 BRAKE_COMMAND: 8 ADAS + SG_ ZEROS_BOH : 7|12@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_PUMP_REQUEST : 11|1@0+ (1,0) [0|1] "" EBCM + SG_ ZEROS_BOH2 : 10|3@0+ (1,0) [0|7] "" XXX + SG_ CRUISE_BOH2 : 23|3@0+ (1,0) [0|1] "" EBCM + SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM + SG_ CRUISE_BOH3 : 19|1@0+ (1,0) [0|1] "" EBCM + SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM + SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM + SG_ COMPUTER_BRAKE_REQUEST : 16|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_0X80 : 31|8@0+ (1,0) [0|1] "" EBCM + SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM + SG_ CRUISE_STATES : 38|7@0+ (1,0) [0|1] "" EBCM + SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM + SG_ ZEROS_BOH6 : 44|1@0+ (1,0) [0|1] "" EBCM + SG_ FCW : 43|2@0+ (1,0) [0|3] "" EBCM + SG_ COMPUTER_BRAKE : 55|10@0+ (1,0) [0|1] "" EBCM + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EBCM + +BO_ 597 ROUGH_WHEEL_SPEED: 8 VSA + SG_ WHEEL_SPEED_FL : 7|8@0+ (1,0) [0|255] "mph" EON + SG_ WHEEL_SPEED_FR : 15|8@0+ (1,0) [0|255] "mph" EON + SG_ WHEEL_SPEED_RL : 23|8@0+ (1,0) [0|255] "mph" EON + SG_ WHEEL_SPEED_RR : 31|8@0+ (1,0) [0|255] "mph" EON + SG_ SET_TO_X55 : 39|8@0+ (1,0) [0|255] "" EON + SG_ SET_TO_X55_2 : 47|8@0+ (1,0) [0|255] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 773 SEATBELT_STATUS: 7 BDY + SG_ SEATBELT_DRIVER_LAMP : 7|1@0+ (1,0) [0|1] "" EON + SG_ SEATBELT_PASS_UNLATCHED : 10|1@0+ (1,0) [0|1] "" EON + SG_ SEATBELT_PASS_LATCHED : 11|1@0+ (1,0) [0|1] "" EON + SG_ SEATBELT_DRIVER_UNLATCHED : 12|1@0+ (1,0) [0|1] "" EON + SG_ SEATBELT_DRIVER_LATCHED : 13|1@0+ (1,0) [0|1] "" EON + SG_ PASS_AIRBAG_OFF : 14|1@0+ (1,0) [0|1] "" EON + SG_ PASS_AIRBAG_ON : 15|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON + +BO_ 777 LOCK_STATUS: 8 XXX + SG_ DOORS_UNLOCKED : 54|1@0+ (1,0) [0|1] "" EON + SG_ DOORS_LOCKED : 55|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 780 ACC_HUD: 8 ADAS + SG_ PCM_SPEED : 7|16@0+ (0.01,0) [0|250] "kph" BDY + SG_ PCM_GAS : 23|8@0+ (1,0) [0|127] "" BDY + SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "" BDY + SG_ DTC_MODE : 39|1@0+ (1,0) [0|1] "" BDY + SG_ BOH : 38|1@0+ (1,0) [0|1] "" BDY + SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY + SG_ FCM_OFF : 36|1@0+ (1,0) [0|1] "" BDY + SG_ BOH_2 : 35|1@0+ (1,0) [0|1] "" BDY + SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY + SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY + SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY + SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY + SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY + SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY + SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY + +BO_ 804 CRUISE: 8 PCM + SG_ HUD_SPEED_KPH : 7|8@0+ (1,0) [0|255] "kph" EON + SG_ HUD_SPEED_MPH : 15|8@0+ (1,0) [0|255] "mph" EON + SG_ TRIP_FUEL_CONSUMED : 23|16@0+ (1,0) [0|255] "" EON + SG_ CRUISE_SPEED_PCM : 39|8@0+ (1,0) [0|255] "" EON + SG_ BOH2 : 47|8@0- (1,0) [0|255] "" EON + SG_ BOH3 : 55|8@0+ (1,0) [0|255] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 829 LKAS_HUD: 5 ADAS + SG_ CAM_TEMP_HIGH : 7|1@0+ (1,0) [0|255] "" BDY + SG_ SET_ME_X41 : 6|7@0+ (1,0) [0|127] "" BDY + SG_ BOH : 6|7@0+ (1,0) [0|127] "" BDY + SG_ DASHED_LANES : 14|1@0+ (1,0) [0|1] "" BDY + SG_ DTC : 13|1@0+ (1,0) [0|1] "" BDY + SG_ LKAS_PROBLEM : 12|1@0+ (1,0) [0|1] "" BDY + SG_ LKAS_OFF : 11|1@0+ (1,0) [0|1] "" BDY + SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY + SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY + SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY + SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY + SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY + SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY + SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY + SG_ LDW_OFF : 27|1@0+ (1,0) [0|1] "" BDY + SG_ CLEAN_WINDSHIELD : 26|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X48 : 31|8@0+ (1,0) [0|255] "" BDY + SG_ COUNTER : 37|2@0+ (1,0) [0|3] "" BDY + SG_ CHECKSUM : 35|4@0+ (1,0) [0|15] "" BDY + +BO_ 892 CRUISE_PARAMS: 8 PCM + SG_ CRUISE_SPEED_OFFSET : 31|8@0- (0.1,0) [-128|127] "kph" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + +BO_ 1029 DOORS_STATUS: 8 BDY + SG_ DOOR_OPEN_FL : 37|1@0+ (1,0) [0|1] "" EON + SG_ DOOR_OPEN_FR : 38|1@0+ (1,0) [0|1] "" EON + SG_ DOOR_OPEN_RL : 39|1@0+ (1,0) [0|1] "" EON + SG_ DOOR_OPEN_RR : 40|1@0+ (1,0) [0|1] "" EON + SG_ TRUNK_OPEN : 41|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping"; +CM_ SG_ 773 PASS_AIRBAG_ON "Might just be indicator light"; +CM_ SG_ 773 PASS_AIRBAG_OFF "Might just be indicator light"; +CM_ SG_ 780 CRUISE_SPEED "255 = no speed"; +CM_ SG_ 804 CRUISE_SPEED_PCM "255 = no speed"; +CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc..."; + + +VAL_ 506 FCW 3 "fcw" 2 "fcw" 1 "fcw" 0 "no_fcw" ; +VAL_ 506 CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime" ; +VAL_ 780 CRUISE_SPEED 255 "no_speed" 252 "stopped" ; +VAL_ 780 HUD_LEAD 3 "acc_off" 2 "solid_car" 1 "dashed_car" 0 "no_car" ; +VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; diff --git a/opendbc/generator/honda/_honda_2017.dbc b/opendbc/generator/honda/_honda_2017.dbc index c79f2587beb008..d805d45e87a120 100644 --- a/opendbc/generator/honda/_honda_2017.dbc +++ b/opendbc/generator/honda/_honda_2017.dbc @@ -56,6 +56,7 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM BO_ 420 VSA_STATUS: 8 VSA SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" EON + SG_ COMPUTER_BRAKING : 23|1@0+ (1,0) [0|1] "" EON SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" EON SG_ BRAKE_HOLD_RELATED : 52|1@0+ (1,0) [0|1] "" XXX SG_ BRAKE_HOLD_ACTIVE : 46|1@0+ (1,0) [0|1] "" EON @@ -85,21 +86,24 @@ BO_ 490 VEHICLE_DYNAMICS: 8 VSA BO_ 506 BRAKE_COMMAND: 8 ADAS SG_ COMPUTER_BRAKE : 7|10@0+ (1,0) [0|1] "" EBCM - SG_ ZEROS_BOH : 13|5@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00 : 13|5@0+ (1,0) [0|1] "" EBCM SG_ BRAKE_PUMP_REQUEST : 8|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH2 : 23|3@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_2 : 23|3@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH3 : 19|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_3 : 19|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM SG_ COMPUTER_BRAKE_REQUEST : 16|1@0+ (1,0) [0|1] "" EBCM - SG_ SET_ME_0X80 : 31|8@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_1 : 31|1@0+ (1,0) [0|1] "" EBCM + SG_ AEB_REQ_1 : 29|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_REQ_2 : 26|3@0+ (1,0) [0|7] "" XXX SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_STATES : 38|7@0+ (1,0) [0|1] "" EBCM SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM - SG_ ZEROS_BOH6 : 44|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_4 : 44|1@0+ (1,0) [0|1] "" EBCM SG_ FCW : 43|2@0+ (1,0) [0|3] "" EBCM - SG_ ZEROS_BOH4 : 55|8@0+ (1,0) [0|0] "" EBCM + SG_ AEB_STATUS : 41|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X00_5 : 55|8@0+ (1,0) [0|0] "" EBCM SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EBCM @@ -142,14 +146,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY @@ -200,6 +205,7 @@ BO_ 1029 DOORS_STATUS: 8 BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping"; +CM_ SG_ 506 AEB_REQ_1 "set for duration of suspected AEB event"; CM_ SG_ 773 PASS_AIRBAG_ON "Might just be indicator light"; CM_ SG_ 773 PASS_AIRBAG_OFF "Might just be indicator light"; CM_ SG_ 780 CRUISE_SPEED "255 = no speed"; @@ -209,6 +215,7 @@ CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc..."; VAL_ 506 FCW 3 "fcw" 2 "fcw" 1 "fcw" 0 "no_fcw" ; VAL_ 506 CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime" ; +VAL_ 506 AEB_STATUS 3 "aeb_prepare" 2 "aeb_ready" 1 "aeb_braking" 0 "no_aeb" ; VAL_ 780 CRUISE_SPEED 255 "no_speed" 252 "stopped" ; VAL_ 780 HUD_LEAD 3 "acc_off" 2 "solid_car" 1 "dashed_car" 0 "no_car" ; VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; diff --git a/opendbc/generator/honda/honda_civic_touring_2016_can.dbc b/opendbc/generator/honda/honda_civic_touring_2016_can.dbc index 8af78ca052441d..1a7579d2a290bc 100644 --- a/opendbc/generator/honda/honda_civic_touring_2016_can.dbc +++ b/opendbc/generator/honda/honda_civic_touring_2016_can.dbc @@ -50,6 +50,9 @@ BO_ 450 EPB_STATUS: 8 EPB SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON +BO_ 493 HUD_SETTING: 5 XXX + SG_ IMPERIAL_UNIT : 5|1@0+ (1,0) [0|1] "" EON + BO_ 487 BRAKE_PRESSURE: 4 VSA SG_ BRAKE_PRESSURE1 : 7|10@0+ (0.015625,-103) [0|1000] "" EON SG_ BRAKE_PRESSURE2 : 9|10@0+ (0.015625,-103) [0|1000] "" EON diff --git a/opendbc/generator/honda/honda_fit_hybrid_2018_can.dbc b/opendbc/generator/honda/honda_fit_hybrid_2018_can.dbc new file mode 100644 index 00000000000000..6b0a896b71fe25 --- /dev/null +++ b/opendbc/generator/honda/honda_fit_hybrid_2018_can.dbc @@ -0,0 +1,111 @@ +CM_ "IMPORT _dual_can_nidec_2018.dbc" +CM_ "IMPORT _comma.dbc" + +BO_ 145 KINEMATICS: 8 XXX + SG_ LAT_ACCEL : 7|10@0+ (0.02,-512) [-20|20] "m/s2" EON + +BO_ 228 STEERING_CONTROL: 5 ADAS + SG_ STEER_TORQUE : 7|16@0- (1,0) [-3840|3840] "" EPS + SG_ STEER_TORQUE_REQUEST : 23|1@0+ (1,0) [0|1] "" EPS + SG_ SET_ME_X00 : 22|7@0+ (1,0) [0|127] "" EPS + SG_ SET_ME_X00_2 : 31|8@0+ (1,0) [0|0] "" EPS + SG_ COUNTER : 37|2@0+ (1,0) [0|3] "" EPS + SG_ CHECKSUM : 35|4@0+ (1,0) [0|15] "" EPS + +BO_ 304 GAS_PEDAL_2: 8 PCM + SG_ ENGINE_TORQUE_ESTIMATE : 7|16@0- (1,0) [-1000|1000] "Nm" EON + SG_ ENGINE_TORQUE_REQUEST : 23|16@0- (1,0) [-1000|1000] "Nm" EON + SG_ CAR_GAS : 39|8@0+ (1,0) [0|255] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 342 STEERING_SENSORS: 6 EPS + SG_ STEER_ANGLE : 7|16@0- (-0.1,0) [-500|500] "deg" EON + SG_ STEER_ANGLE_RATE : 23|16@0- (1,0) [-3000|3000] "deg/s" EON + SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON + +BO_ 399 STEER_STATUS: 7 EPS + SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON + SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON + +BO_ 419 GEARBOX: 8 PCM + SG_ GEAR : 7|8@0+ (1,0) [0|256] "" EON + SG_ GEAR_SHIFTER : 35|4@0+ (1,0) [0|15] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 422 SCM_BUTTONS: 8 SCM + SG_ CRUISE_BUTTONS : 7|3@0+ (1,0) [0|7] "" EON + SG_ LIGHTS_SETTING : 1|2@0+ (1,0) [0|3] "" EON + SG_ MAIN_ON : 47|1@0+ (1,0) [0|1] "" EON + SG_ CRUISE_SETTING : 43|2@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 487 BRAKE_PRESSURE: 4 VSA + SG_ BRAKE_PRESSURE1 : 7|10@0+ (0.015625,-103) [0|1000] "" EON + SG_ BRAKE_PRESSURE2 : 9|10@0+ (0.015625,-103) [0|1000] "" EON + SG_ CHECKSUM : 27|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 29|2@0+ (1,0) [0|3] "" EON + +BO_ 545 ECON_STATUS: 5 XXX + SG_ ECON_ON : 23|1@0+ (1,0) [0|1] "" EON + SG_ CHECKSUM : 35|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 37|2@0+ (1,0) [0|3] "" EON + +BO_ 660 SCM_FEEDBACK: 8 SCM + SG_ RIGHT_BLINKER : 6|1@0+ (1,0) [0|1] "" EON + SG_ LEFT_BLINKER : 5|1@0+ (1,0) [0|1] "" EON + SG_ WIPERS_SPEED : 4|2@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 862 HIGHBEAM_CONTROL: 8 ADAS + SG_ ZEROS_BOH : 7|50@0+ (1,0) [0|127] "" BDY + SG_ ZEROS_BOH_2 : 48|4@1+ (1,0) [0|15] "" XXX + SG_ HIGHBEAMS_ON : 52|1@0+ (1,0) [0|1] "" XXX + SG_ AUTO_HIGHBEAMS_ACTIVE : 53|1@0+ (1,0) [0|1] "" XXX + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX + +BO_ 884 STALK_STATUS: 8 XXX + SG_ AUTO_HEADLIGHTS : 46|1@0+ (1,0) [0|1] "" EON + SG_ HIGH_BEAM_HOLD : 47|1@0+ (1,0) [0|1] "" EON + SG_ HIGH_BEAM_FLASH : 45|1@0+ (1,0) [0|1] "" EON + SG_ HEADLIGHTS_ON : 54|1@0+ (1,0) [0|1] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + +BO_ 891 WIPERS: 8 XXX + SG_ WIPERS : 17|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + +BO_ 927 RADAR_HUD: 8 ADAS + SG_ ZEROS_BOH : 7|17@0+ (1,0) [0|127] "" BDY + SG_ APPLY_BRAKES_FOR_CANC : 23|1@0+ (1,0) [0|15] "" BDY + SG_ ZEROS_BOH2 : 31|8@0+ (1,0) [0|127] "" BDY + SG_ RESUME_INSTRUCTION : 21|1@0+ (1,0) [0|15] "" BDY + SG_ ACC_ALERTS : 20|5@0+ (1,0) [0|15] "" BDY + SG_ LEAD_SPEED : 39|9@0+ (1,0) [0|127] "" BDY + SG_ LEAD_STATE : 46|3@0+ (1,0) [0|127] "" BDY + SG_ LEAD_DISTANCE : 43|5@0+ (1,0) [0|31] "" BDY + SG_ ZEROS_BOH3 : 54|7@0+ (1,0) [0|127] "" BDY + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" BDY + +CM_ SG_ 419 GEAR "10 = reverse, 11 = transition"; +CM_ SG_ 420 BRAKE_HOLD_RELATED "On when Brake Hold engaged"; + +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 419 GEAR_SHIFTER 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; +VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; +VAL_ 422 LIGHTS_SETTING 3 "high_beam" 2 "low_beam" 1 "position" 0 "no_lights" ; +VAL_ 422 CRUISE_SETTING 3 "distance_adj" 2 "tbd" 1 "lkas_button" 0 "none" ; + +CM_ "CHFFR_METRIC 342 STEER_ANGLE STEER_ANGLE 0.36 180; CHFFR_METRIC 380 ENGINE_RPM ENGINE_RPM 1 0; CHFFR_METRIC 804 ENGINE_TEMPERATURE ENGINE_TEMPERATURE 1 0"; diff --git a/opendbc/generator/honda/honda_odyssey_extreme_edition_2018_china_can.dbc b/opendbc/generator/honda/honda_odyssey_extreme_edition_2018_china_can.dbc new file mode 100644 index 00000000000000..2d0d7e2b5d812b --- /dev/null +++ b/opendbc/generator/honda/honda_odyssey_extreme_edition_2018_china_can.dbc @@ -0,0 +1,76 @@ +CM_ "IMPORT _honda_2017.dbc" +CM_ "IMPORT _comma.dbc" + +BO_ 316 GAS_PEDAL: 8 PCM + SG_ CAR_GAS : 39|8@0+ (1,0) [0|255] "" EON + +BO_ 342 STEERING_SENSORS: 6 EPS + SG_ STEER_ANGLE_RATE : 23|16@0- (1,0) [-3000|3000] "deg/s" EON + SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 43|4@0+ (1,0) [0|15] "" EON + SG_ STEER_ANGLE : 7|16@0- (-0.1,0) [-500|500] "deg" EON + +BO_ 399 STEER_STATUS: 7 EPS + SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-2985|2985] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ CHECKSUM : 51|4@0+ (1,0) [0|15] "" EON + SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON + SG_ STEER_STATUS : 43|4@0+ (1,0) [0|15] "" EON + SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON + +BO_ 401 GEARBOX: 8 PCM + SG_ GEAR_SHIFTER : 5|6@0+ (1,0) [0|63] "" EON + SG_ GEAR : 35|4@0+ (1,0) [0|15] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 404 STEERING_CONTROL: 4 EON + SG_ SET_ME_X00 : 22|7@0+ (1,0) [0|127] "" EPS + SG_ STEER_TORQUE_REQUEST : 23|1@0+ (1,0) [0|1] "" EPS + SG_ COUNTER : 29|2@0+ (1,0) [0|15] "" EPS + SG_ CHECKSUM : 27|4@0+ (1,0) [0|3] "" EPS + SG_ STEER_TORQUE : 7|16@0- (-1,0) [-32767|32767] "" EPS + +BO_ 422 SCM_BUTTONS: 8 SCM + SG_ CRUISE_BUTTONS : 7|3@0+ (1,0) [0|7] "" EON + SG_ LIGHTS_SETTING : 1|2@0+ (1,0) [0|3] "" EON + SG_ MAIN_ON : 47|1@0+ (1,0) [0|1] "" EON + SG_ CRUISE_SETTING : 43|2@0+ (1,0) [0|3] "" EON + SG_ DRIVERS_DOOR_OPEN : 63|1@0+ (1,0) [0|1] "" XXX + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 450 EPB_STATUS: 8 XXX + SG_ EPB_BRAKE_AND_PULL : 6|1@0+ (1,0) [0|1] "" XXX + SG_ EPB_ACTIVE : 3|1@0+ (1,0) [0|1] "" XXX + SG_ EPB_STATE : 29|2@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX + +BO_ 660 SCM_FEEDBACK: 8 SCM + SG_ RIGHT_BLINKER : 6|1@0+ (1,0) [0|1] "" EON + SG_ LEFT_BLINKER : 5|1@0+ (1,0) [0|1] "" EON + SG_ WIPERS_SPEED : 4|2@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 862 HIGHBEAM_CONTROL: 8 ADAS + SG_ ZEROS_BOH : 7|50@0+ (1,0) [0|127] "" BDY + SG_ ZEROS_BOH_2 : 48|4@1+ (1,0) [0|15] "" XXX + SG_ HIGHBEAMS_ON : 52|1@0+ (1,0) [0|1] "" XXX + SG_ AUTO_HIGHBEAMS_ACTIVE : 53|1@0+ (1,0) [0|1] "" XXX + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX + +BO_ 1302 ODOMETER: 8 XXX + SG_ ODOMETER : 7|24@0+ (1,0) [0|16777215] "km" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +CM_ SG_ 401 GEAR "10 = reverse, 11 = transition"; +VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 401 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P" ; +VAL_ 401 GEAR 7 "L" 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; +VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; +VAL_ 422 LIGHTS_SETTING 3 "high_beam" 2 "low_beam" 1 "position" 0 "no_lights" ; +VAL_ 422 CRUISE_SETTING 3 "distance_adj" 2 "tbd" 1 "lkas_button" 0 "none" ; diff --git a/opendbc/generator/toyota/_toyota_2017.dbc b/opendbc/generator/toyota/_toyota_2017.dbc index c0e3a864850afc..3ad15b80556732 100644 --- a/opendbc/generator/toyota/_toyota_2017.dbc +++ b/opendbc/generator/toyota/_toyota_2017.dbc @@ -33,11 +33,11 @@ NS_ : BS_: -BU_: XXX DSU HCU EPS IPAS +BU_: XXX DSU HCU EPS IPAS CGW BO_ 36 KINEMATICS: 8 XXX - SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX - SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX BO_ 37 STEER_ANGLE_SENSOR: 8 XXX @@ -57,8 +57,8 @@ BO_ 170 WHEEL_SPEEDS: 8 XXX BO_ 180 SPEED: 8 XXX SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 353 DSU_SPEED: 8 XXX SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX @@ -69,6 +69,7 @@ BO_ 466 PCM_CRUISE: 8 XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 467 PCM_CRUISE_2: 8 XXX @@ -91,10 +92,19 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 643 PRE_COLLISION: 8 XXX +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX BO_ 740 STEERING_LKA: 5 XXX SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX @@ -120,6 +130,18 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + BO_ 921 PCM_CRUISE_SM: 8 XXX SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX @@ -128,6 +150,7 @@ BO_ 921 PCM_CRUISE_SM: 8 XXX BO_ 951 ESP_CONTROL: 8 ESP SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX BO_ 1041 ACC_HUD: 8 DSU @@ -152,7 +175,41 @@ BO_ 1042 LKAS_HUD: 8 XXX SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX -BO_ 1553 UI_SEETING: 8 XXX +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX BO_ 1556 STEERING_LEVERS: 8 XXX @@ -222,6 +279,9 @@ CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; @@ -245,6 +305,7 @@ VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; @@ -254,9 +315,9 @@ VAL_ 1553 UNITS 1 "km" 2 "miles"; VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; -VAL_ 1161 SPLSGN2 15 "conditional blank" 5 "rain" 0 "none"; -VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; -VAL_ 1162 SPLSGN3 15 "conditional blank" 5 "rain" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/opendbc/generator/toyota/lexus_ct200h_2018_pt.dbc b/opendbc/generator/toyota/lexus_ct200h_2018_pt.dbc new file mode 100644 index 00000000000000..c6ec5e11d120e5 --- /dev/null +++ b/opendbc/generator/toyota/lexus_ct200h_2018_pt.dbc @@ -0,0 +1,37 @@ +CM_ "IMPORT _toyota_2017.dbc" +CM_ "IMPORT _comma.dbc" + +BO_ 548 BRAKE_MODULE: 8 XXX + SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 581 GAS_PEDAL: 5 XXX + SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX + +BO_ 608 STEER_TORQUE_SENSOR: 8 XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (1,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX + SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 610 EPS_STATUS: 5 EPS + SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX + SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX + SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 956 GEAR_PACKET: 8 XXX + SG_ SPORT_ON : 2|1@0+ (1,0) [0|1] "" XXX + SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX + SG_ ECON_ON : 40|1@0+ (1,0) [0|1] "" XXX + +CM_ SG_ 548 BRAKE_PRESSURE "seems prop to pedal force"; +CM_ SG_ 548 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; +CM_ SG_ 581 GAS_PEDAL "it seems slightly filtered"; +CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; +VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; +VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; +VAL_ 956 GEAR 0 "D" 1 "S" 8 "N" 16 "R" 32 "P"; +VAL_ 956 SPORT_ON 0 "off" 1 "on"; +VAL_ 956 ECON_ON 0 "off" 1 "on"; diff --git a/opendbc/generator/toyota/lexus_gs300h_2017_pt.dbc b/opendbc/generator/toyota/lexus_gs300h_2017_pt.dbc new file mode 100644 index 00000000000000..070b4e6e728a53 --- /dev/null +++ b/opendbc/generator/toyota/lexus_gs300h_2017_pt.dbc @@ -0,0 +1,38 @@ +CM_ "IMPORT _toyota_2017.dbc" +CM_ "IMPORT _comma.dbc" + +BO_ 550 BRAKE_MODULE: 8 XXX + SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 581 GAS_PEDAL: 5 XXX + SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX + +BO_ 608 STEER_TORQUE_SENSOR: 8 XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX + SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 610 EPS_STATUS: 5 EPS + SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX + SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX + SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 956 GEAR_PACKET: 8 XXX + SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX + +BO_ 1009 PCM_CRUISE_3: 8 XXX + SG_ MAIN_ON : 13|1@0+ (1,0) [0|3] "" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX + SG_ CRUISE_STATE : 10|1@0+ (1,0) [0|15] "" XXX + +CM_ SG_ 550 BRAKE_PRESSURE "seems prop to pedal force"; +CM_ SG_ 550 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; +CM_ SG_ 581 GAS_PEDAL "it seems slightly filtered"; +CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; +VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; +VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; +VAL_ 956 GEAR 0 "D" 1 "S" 8 "N" 16 "R" 32 "P"; diff --git a/opendbc/generator/toyota/lexus_is_2018_pt.dbc b/opendbc/generator/toyota/lexus_is_2018_pt.dbc index 6548822fddca9c..e1a6922e89ce71 100644 --- a/opendbc/generator/toyota/lexus_is_2018_pt.dbc +++ b/opendbc/generator/toyota/lexus_is_2018_pt.dbc @@ -6,15 +6,19 @@ BO_ 550 BRAKE_MODULE: 8 XXX SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX +BO_ 581 GAS_PEDAL_ALT: 5 XXX + SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX + BO_ 705 GAS_PEDAL: 8 XXX SG_ GAS_RELEASED : 3|1@0+ (1,0) [0|1] "" XXX SG_ GAS_PEDAL : 55|8@0+ (0.005,0) [0|1] "" XXX BO_ 608 STEER_TORQUE_SENSOR: 8 XXX - SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (0.77,0) [-20000|20000] "" XXX SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + SG_ STEER_ANGLE : 31|16@0- (0.0573,0) [-500|500] "" XXX BO_ 610 EPS_STATUS: 5 EPS SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX @@ -25,11 +29,14 @@ BO_ 610 EPS_STATUS: 5 EPS BO_ 956 GEAR_PACKET: 8 XXX SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX -BO_ 1009 PCM_CRUISE_3: 8 XXX +BO_ 1009 PCM_CRUISE_ALT: 8 XXX SG_ MAIN_ON : 13|1@0+ (1,0) [0|3] "" XXX SG_ CRUISE_STATE : 10|1@0+ (1,0) [0|1] "" XXX SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX +BO_ 1599 LIGHT_STALK_ISH: 8 SCM + SG_ AUTO_HIGH_BEAM : 19|1@0+ (1,0) [0|1] "" XXX + CM_ SG_ 550 BRAKE_PRESSURE "seems prop to pedal force"; CM_ SG_ 550 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; diff --git a/opendbc/generator/toyota/lexus_is_hybrid_2017_pt.dbc b/opendbc/generator/toyota/lexus_is_hybrid_2017_pt.dbc deleted file mode 100644 index 7fb743770573c7..00000000000000 --- a/opendbc/generator/toyota/lexus_is_hybrid_2017_pt.dbc +++ /dev/null @@ -1,41 +0,0 @@ -CM_ "IMPORT _toyota_2017.dbc" -CM_ "IMPORT _comma.dbc" - -BO_ 581 GAS_PEDAL: 5 XXX - SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX - -BO_ 550 BRAKE_MODULE: 8 XXX - SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX - SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX - SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX - -BO_ 608 STEER_TORQUE_SENSOR: 8 XXX - SG_ STEER_TORQUE_EPS : 47|16@0- (0.66,0) [-20000|20000] "" XXX - SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX - SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 610 EPS_STATUS: 5 EPS - SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX - SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX - SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX - SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX - -BO_ 956 GEAR_PACKET: 8 XXX - SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX - -BO_ 1009 PCM_CRUISE_ISH: 8 XXX - SG_ MAIN_ON : 13|1@0+ (1,0) [0|3] "" XXX - SG_ CRUISE_STATE : 10|1@0+ (1,0) [0|1] "" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX - -BO_ 1599 LIGHT_STALK_ISH: 8 SCM - SG_ AUTO_HIGH_BEAM : 19|1@0+ (1,0) [0|1] "" XXX - -CM_ SG_ 550 BRAKE_PRESSURE "seems prop to pedal force"; -CM_ SG_ 550 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; -CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; -CM_ SG_ 1009 SET_SPEED "units seem to be whatever the car is set to"; -VAL_ 956 GEAR 0 "D" 1 "S" 8 "N" 16 "R" 32 "P"; -VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; -VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; diff --git a/opendbc/generator/toyota/lexus_rx_350_2016_pt.dbc b/opendbc/generator/toyota/lexus_rx_350_2016_pt.dbc new file mode 100644 index 00000000000000..4a6fe48fd91bf5 --- /dev/null +++ b/opendbc/generator/toyota/lexus_rx_350_2016_pt.dbc @@ -0,0 +1,37 @@ +CM_ "IMPORT _toyota_2017.dbc" +CM_ "IMPORT _comma.dbc" + +BO_ 550 BRAKE_MODULE: 8 XXX + SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 608 STEER_TORQUE_SENSOR: 8 XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX + SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 610 EPS_STATUS: 5 EPS + SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX + SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX + SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 956 GEAR_PACKET: 8 XXX + SG_ SPORT_ON : 2|1@0+ (1,0) [0|1] "" XXX + SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX + SG_ ECON_ON : 40|1@0+ (1,0) [0|1] "" XXX + +BO_ 705 GAS_PEDAL: 8 XXX + SG_ GAS_PEDAL : 55|8@0+ (1,0) [0|255] "" XXX + + +CM_ SG_ 550 BRAKE_PRESSURE "seems prop to pedal force"; +CM_ SG_ 550 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; +CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; +VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled" ; +VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby" ; +VAL_ 956 SPORT_ON 0 "off" 1 "on" ; +VAL_ 956 GEAR 0 "D" 1 "S" 8 "N" 16 "R" 32 "P" ; +VAL_ 956 ECON_ON 0 "off" 1 "on" ; diff --git a/opendbc/generator/toyota/toyota_camry_hybrid_2018_pt.dbc b/opendbc/generator/toyota/toyota_camry_hybrid_2018_pt.dbc index efde86ba9c81b5..8b2cda1eb78fbe 100644 --- a/opendbc/generator/toyota/toyota_camry_hybrid_2018_pt.dbc +++ b/opendbc/generator/toyota/toyota_camry_hybrid_2018_pt.dbc @@ -16,11 +16,11 @@ BO_ 581 GAS_PEDAL: 8 XXX SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX BO_ 608 STEER_TORQUE_SENSOR: 8 XXX - SG_ STEER_TORQUE_EPS : 47|16@0- (0.66,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - SG_ STEER_ANGLE : 31|16@0- (0.05527,0) [-500|500] "" XXX + SG_ STEER_ANGLE : 31|16@0- (0.0573,0) [-500|500] "" XXX BO_ 610 EPS_STATUS: 8 EPS SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX diff --git a/opendbc/generator/toyota/toyota_chr_2018_pt.dbc b/opendbc/generator/toyota/toyota_chr_2018_pt.dbc deleted file mode 100644 index 7306ed2c06e039..00000000000000 --- a/opendbc/generator/toyota/toyota_chr_2018_pt.dbc +++ /dev/null @@ -1,37 +0,0 @@ -CM_ "IMPORT _toyota_2017.dbc" -CM_ "IMPORT _comma.dbc" - -BO_ 550 BRAKE_MODULE: 8 XXX - SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX - SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX - SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX - -BO_ 705 GAS_PEDAL: 8 XXX - SG_ GAS_RELEASED : 3|1@0+ (1,0) [0|1] "" XXX - SG_ GAS_PEDAL : 55|8@0+ (0.005,0) [0|1] "" XXX - -BO_ 608 STEER_TORQUE_SENSOR: 8 XXX - SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX - SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX - SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 610 EPS_STATUS: 8 EPS - SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX - SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX - SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 956 GEAR_PACKET: 8 XXX - SG_ SPORT_ON : 2|1@0+ (1,0) [0|1] "" XXX - SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX - SG_ ECON_ON : 40|1@0+ (1,0) [0|1] "" XXX - -CM_ SG_ 548 BRAKE_PRESSURE "seems prop to pedal force"; -CM_ SG_ 548 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; -CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; -VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; -VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; -VAL_ 956 GEAR 0 "D" 1 "S" 8 "N" 16 "R" 32 "P"; -VAL_ 956 SPORT_ON 0 "off" 1 "on"; -VAL_ 956 ECON_ON 0 "off" 1 "on"; diff --git a/opendbc/generator/toyota/toyota_chr_hybrid_2018_pt.dbc b/opendbc/generator/toyota/toyota_chr_hybrid_2018_pt.dbc deleted file mode 100644 index c86fcaaf659c86..00000000000000 --- a/opendbc/generator/toyota/toyota_chr_hybrid_2018_pt.dbc +++ /dev/null @@ -1,36 +0,0 @@ -CM_ "IMPORT _toyota_2017.dbc" -CM_ "IMPORT _comma.dbc" - -BO_ 295 GEAR_PACKET: 8 XXX - SG_ CAR_MOVEMENT : 39|8@0- (1,0) [0|255] "" XXX - SG_ COUNTER : 55|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - SG_ GEAR : 47|4@0+ (1,0) [0|15] "" XXX - -BO_ 550 BRAKE_MODULE: 8 XXX - SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX - SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX - SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX - -BO_ 581 GAS_PEDAL: 8 XXX - SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX - -BO_ 608 STEER_TORQUE_SENSOR: 8 XXX - SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX - SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX - SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 610 EPS_STATUS: 8 EPS - SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX - SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX - SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -CM_ SG_ 548 BRAKE_PRESSURE "seems prop to pedal force"; -CM_ SG_ 548 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; -CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; -CM_ SG_ 581 GAS_PEDAL "it seems slightly filtered"; -VAL_ 295 GEAR 0 "P" 1 "R" 2 "N" 3 "D" 4 "B"; -VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; -VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; diff --git a/opendbc/generator/toyota/toyota_corolla_2017_pt.dbc b/opendbc/generator/toyota/toyota_corolla_2017_pt.dbc index caf7b6388d93cc..724b6e834bb0a4 100644 --- a/opendbc/generator/toyota/toyota_corolla_2017_pt.dbc +++ b/opendbc/generator/toyota/toyota_corolla_2017_pt.dbc @@ -23,6 +23,7 @@ BO_ 610 EPS_STATUS: 5 EPS BO_ 956 GEAR_PACKET: 8 XXX SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX + SG_ SPORT_ON : 3|1@0+ (1,0) [0|1] "" XXX CM_ SG_ 548 BRAKE_PRESSURE "seems prop to pedal force"; CM_ SG_ 548 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; diff --git a/opendbc/generator/toyota/toyota_nodsu_hybrid_pt.dbc b/opendbc/generator/toyota/toyota_nodsu_hybrid_pt.dbc new file mode 100644 index 00000000000000..ac91c726f3970d --- /dev/null +++ b/opendbc/generator/toyota/toyota_nodsu_hybrid_pt.dbc @@ -0,0 +1,37 @@ +CM_ "IMPORT _toyota_2017.dbc" +CM_ "IMPORT _comma.dbc" + +BO_ 295 GEAR_PACKET: 8 XXX + SG_ CAR_MOVEMENT : 39|8@0- (1,0) [0|255] "" XXX + SG_ COUNTER : 55|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + SG_ GEAR : 47|4@0+ (1,0) [0|15] "" XXX + +BO_ 550 BRAKE_MODULE: 8 XXX + SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 581 GAS_PEDAL: 8 XXX + SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX + +BO_ 608 STEER_TORQUE_SENSOR: 8 XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX + SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + SG_ STEER_ANGLE : 31|16@0- (0.0573,0) [-500|500] "" XXX + +BO_ 610 EPS_STATUS: 8 EPS + SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX + SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX + SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +CM_ SG_ 548 BRAKE_PRESSURE "seems prop to pedal force"; +CM_ SG_ 548 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; +CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; +CM_ SG_ 581 GAS_PEDAL "it seems slightly filtered"; +VAL_ 295 GEAR 0 "P" 1 "R" 2 "N" 3 "D" 4 "B"; +VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; +VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; diff --git a/opendbc/generator/toyota/toyota_nodsu_pt.dbc b/opendbc/generator/toyota/toyota_nodsu_pt.dbc new file mode 100644 index 00000000000000..9bc1b1e6739079 --- /dev/null +++ b/opendbc/generator/toyota/toyota_nodsu_pt.dbc @@ -0,0 +1,49 @@ +CM_ "IMPORT _toyota_2017.dbc" +CM_ "IMPORT _comma.dbc" + +BO_ 401 STEERING_LTA: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + SG_ SETME_X3 : 29|2@0+ (1,0) [0|3] "" XXX + SG_ PERCENTAGE : 39|8@0+ (1,0) [0|255] "" XXX + SG_ SETME_X64 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ ANGLE : 55|8@0- (0.5,0) [0|255] "" XXX + SG_ STEER_ANGLE_CMD : 15|16@0- (0.0573,0) [-540|540] "" XXX + SG_ STEER_REQUEST : 25|1@0+ (1,0) [0|1] "" XXX + SG_ BIT : 30|1@0+ (1,0) [0|1] "" XXX + +BO_ 550 BRAKE_MODULE: 8 XXX + SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 705 GAS_PEDAL: 8 XXX + SG_ GAS_RELEASED : 3|1@0+ (1,0) [0|1] "" XXX + SG_ GAS_PEDAL : 55|8@0+ (0.005,0) [0|1] "" XXX + +BO_ 608 STEER_TORQUE_SENSOR: 8 XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX + SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + SG_ STEER_ANGLE : 31|16@0- (0.0573,0) [-500|500] "" XXX + +BO_ 610 EPS_STATUS: 8 EPS + SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX + SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX + SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 956 GEAR_PACKET: 8 XXX + SG_ SPORT_ON : 2|1@0+ (1,0) [0|1] "" XXX + SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX + SG_ ECON_ON : 40|1@0+ (1,0) [0|1] "" XXX + +CM_ SG_ 548 BRAKE_PRESSURE "seems prop to pedal force"; +CM_ SG_ 548 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; +CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; +VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; +VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; +VAL_ 956 GEAR 0 "D" 1 "S" 8 "N" 16 "R" 32 "P"; +VAL_ 956 SPORT_ON 0 "off" 1 "on"; +VAL_ 956 ECON_ON 0 "off" 1 "on"; diff --git a/opendbc/generator/toyota/toyota_prius_2017_pt.dbc b/opendbc/generator/toyota/toyota_prius_2017_pt.dbc index d1a6d27db87ca1..cf04ee7c8e7f5b 100644 --- a/opendbc/generator/toyota/toyota_prius_2017_pt.dbc +++ b/opendbc/generator/toyota/toyota_prius_2017_pt.dbc @@ -20,6 +20,7 @@ BO_ 608 STEER_TORQUE_SENSOR: 8 XXX SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + SG_ STEER_ANGLE : 31|16@0- (0.0573,0) [-500|500] "" XXX BO_ 610 EPS_STATUS: 8 EPS SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX diff --git a/opendbc/gm_global_a_powertrain.dbc b/opendbc/gm_global_a_powertrain.dbc index 3caf60ce4a01ec..2e3bd7c85dd435 100644 --- a/opendbc/gm_global_a_powertrain.dbc +++ b/opendbc/gm_global_a_powertrain.dbc @@ -195,7 +195,7 @@ BO_ 1033 ASCMKeepAlive: 7 NEO BO_ 1034 ASCM_40A: 7 K124_ASCM BO_ 1217 ECMEngineCoolantTemp: 8 K20_ECM - SG_ EngineCoolantTemp : 23|8@0+ (1,-40) [0|0] "°C" NEO + SG_ EngineCoolantTemp : 23|8@0+ (1,-40) [0|0] "C" NEO BO_ 1249 VIN_Part2: 8 K20_ECM SG_ VINPart2 : 7|64@0+ (1,0) [0|0] "" NEO diff --git a/opendbc/honda_accord_lx15t_2018_can_generated.dbc b/opendbc/honda_accord_lx15t_2018_can_generated.dbc index 78896384986bdf..5b095ae79389f3 100644 --- a/opendbc/honda_accord_lx15t_2018_can_generated.dbc +++ b/opendbc/honda_accord_lx15t_2018_can_generated.dbc @@ -37,6 +37,12 @@ NS_ : BU_: EBCM EON CAM RADAR PCM EPS VSA SCM BDY XXX EPB +BO_ 148 KINEMATICS: 8 XXX + SG_ LAT_ACCEL : 7|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON + SG_ LONG_ACCEL : 25|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + BO_ 228 STEERING_CONTROL: 5 EON SG_ STEER_TORQUE_REQUEST : 23|1@0+ (1,0) [0|1] "" EPS SG_ SET_ME_X00 : 22|7@0+ (1,0) [0|127] "" EPS @@ -118,15 +124,26 @@ BO_ 464 WHEEL_SPEEDS: 8 VSA SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON BO_ 479 ACC_CONTROL: 8 EON - SG_ SET_TO_1 : 20|5@0+ (1,0) [0|1] "" PCM + SG_ SET_TO_0 : 20|5@0+ (1,0) [0|1] "" XXX SG_ CONTROL_ON : 23|3@0+ (1,0) [0|5] "" XXX - SG_ RELATED_TO_GAS : 7|7@0+ (1,0) [0|69] "" XXX - SG_ GAS_COMMAND : 0|9@0+ (1,0) [0|1] "" PCM - SG_ GAS_BRAKE : 31|14@0- (1,0) [0|1] "" XXX - SG_ ZEROS_BOH : 33|18@0+ (1,0) [100|100] "" XXX + SG_ GAS_COMMAND : 7|16@0- (1,0) [0|0] "" XXX + SG_ ACCEL_COMMAND : 31|11@0- (0.01,0) [0|0] "m/s2" XXX + SG_ BRAKE_LIGHTS : 62|1@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_REQUEST : 34|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL : 35|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL_RELEASE : 36|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_STATUS : 33|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_BRAKING : 47|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_PREPARE : 43|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX +BO_ 490 VEHICLE_DYNAMICS: 8 VSA + SG_ LAT_ACCEL : 7|16@0- (0.0015,0) [-20|20] "m/s2" EON + SG_ LONG_ACCEL : 23|16@0- (0.0015,0) [-20|20] "m/s2" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + BO_ 495 ACC_CONTROL_ON: 8 XXX SG_ SET_TO_75 : 31|8@0+ (1,0) [0|255] "" XXX SG_ SET_TO_30 : 39|8@0+ (1,0) [0|255] "" XXX @@ -173,16 +190,16 @@ BO_ 773 SEATBELT_STATUS: 7 BDY SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON BO_ 777 CAR_SPEED: 8 PCM - SG_ ROUGH_CAR_SPEED : 23|8@0+ (1,0) [0|255] "" XXX - SG_ CAR_SPEED : 7|16@0+ (1,0) [0|65535] "" XXX - SG_ ROUGH_CAR_SPEED_3 : 39|16@0+ (1,0) [0|65535] "" XXX - SG_ ROUGH_CAR_SPEED_2 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ ROUGH_CAR_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX + SG_ CAR_SPEED : 7|16@0+ (0.01,0) [0|65535] "kph" XXX + SG_ ROUGH_CAR_SPEED_3 : 39|16@0+ (0.01,0) [0|65535] "kph" XXX + SG_ ROUGH_CAR_SPEED_2 : 31|8@0+ (1,0) [0|255] "mph" XXX SG_ LOCK_STATUS : 55|2@0+ (1,0) [0|255] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX BO_ 780 ACC_HUD: 8 ADAS - SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "" BDY + SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "kph" BDY SG_ DTC_MODE : 39|1@0+ (1,0) [0|1] "" BDY SG_ BOH : 38|1@0+ (1,0) [0|1] "" BDY SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY @@ -200,7 +217,8 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX - SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX + SG_ SET_TO_X1 : 55|1@0+ (1,0) [0|1] "" XXX + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX @@ -264,7 +282,12 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON +CM_ SG_ 479 AEB_STATUS "set for the duration of AEB event"; +CM_ SG_ 479 AEB_BRAKING "set when braking is commanded during AEB event"; +CM_ SG_ 479 AEB_PREPARE "set 1s before AEB"; + VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; + CM_ "honda_accord_lx15t_2018_can.dbc starts here" diff --git a/opendbc/honda_accord_s2t_2018_can_generated.dbc b/opendbc/honda_accord_s2t_2018_can_generated.dbc index 43a46aff831d0c..12a2b889fd201d 100644 --- a/opendbc/honda_accord_s2t_2018_can_generated.dbc +++ b/opendbc/honda_accord_s2t_2018_can_generated.dbc @@ -37,6 +37,12 @@ NS_ : BU_: EBCM EON CAM RADAR PCM EPS VSA SCM BDY XXX EPB +BO_ 148 KINEMATICS: 8 XXX + SG_ LAT_ACCEL : 7|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON + SG_ LONG_ACCEL : 25|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + BO_ 228 STEERING_CONTROL: 5 EON SG_ STEER_TORQUE_REQUEST : 23|1@0+ (1,0) [0|1] "" EPS SG_ SET_ME_X00 : 22|7@0+ (1,0) [0|127] "" EPS @@ -118,15 +124,26 @@ BO_ 464 WHEEL_SPEEDS: 8 VSA SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON BO_ 479 ACC_CONTROL: 8 EON - SG_ SET_TO_1 : 20|5@0+ (1,0) [0|1] "" PCM + SG_ SET_TO_0 : 20|5@0+ (1,0) [0|1] "" XXX SG_ CONTROL_ON : 23|3@0+ (1,0) [0|5] "" XXX - SG_ RELATED_TO_GAS : 7|7@0+ (1,0) [0|69] "" XXX - SG_ GAS_COMMAND : 0|9@0+ (1,0) [0|1] "" PCM - SG_ GAS_BRAKE : 31|14@0- (1,0) [0|1] "" XXX - SG_ ZEROS_BOH : 33|18@0+ (1,0) [100|100] "" XXX + SG_ GAS_COMMAND : 7|16@0- (1,0) [0|0] "" XXX + SG_ ACCEL_COMMAND : 31|11@0- (0.01,0) [0|0] "m/s2" XXX + SG_ BRAKE_LIGHTS : 62|1@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_REQUEST : 34|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL : 35|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL_RELEASE : 36|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_STATUS : 33|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_BRAKING : 47|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_PREPARE : 43|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX +BO_ 490 VEHICLE_DYNAMICS: 8 VSA + SG_ LAT_ACCEL : 7|16@0- (0.0015,0) [-20|20] "m/s2" EON + SG_ LONG_ACCEL : 23|16@0- (0.0015,0) [-20|20] "m/s2" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + BO_ 495 ACC_CONTROL_ON: 8 XXX SG_ SET_TO_75 : 31|8@0+ (1,0) [0|255] "" XXX SG_ SET_TO_30 : 39|8@0+ (1,0) [0|255] "" XXX @@ -173,16 +190,16 @@ BO_ 773 SEATBELT_STATUS: 7 BDY SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON BO_ 777 CAR_SPEED: 8 PCM - SG_ ROUGH_CAR_SPEED : 23|8@0+ (1,0) [0|255] "" XXX - SG_ CAR_SPEED : 7|16@0+ (1,0) [0|65535] "" XXX - SG_ ROUGH_CAR_SPEED_3 : 39|16@0+ (1,0) [0|65535] "" XXX - SG_ ROUGH_CAR_SPEED_2 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ ROUGH_CAR_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX + SG_ CAR_SPEED : 7|16@0+ (0.01,0) [0|65535] "kph" XXX + SG_ ROUGH_CAR_SPEED_3 : 39|16@0+ (0.01,0) [0|65535] "kph" XXX + SG_ ROUGH_CAR_SPEED_2 : 31|8@0+ (1,0) [0|255] "mph" XXX SG_ LOCK_STATUS : 55|2@0+ (1,0) [0|255] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX BO_ 780 ACC_HUD: 8 ADAS - SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "" BDY + SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "kph" BDY SG_ DTC_MODE : 39|1@0+ (1,0) [0|1] "" BDY SG_ BOH : 38|1@0+ (1,0) [0|1] "" BDY SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY @@ -200,7 +217,8 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX - SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX + SG_ SET_TO_X1 : 55|1@0+ (1,0) [0|1] "" XXX + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX @@ -264,7 +282,12 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON +CM_ SG_ 479 AEB_STATUS "set for the duration of AEB event"; +CM_ SG_ 479 AEB_BRAKING "set when braking is commanded during AEB event"; +CM_ SG_ 479 AEB_PREPARE "set 1s before AEB"; + VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; + CM_ "honda_accord_s2t_2018_can.dbc starts here" diff --git a/opendbc/honda_accord_touring_2016_can.dbc b/opendbc/honda_accord_touring_2016_can.dbc index e8f388de08692c..744e55a9b5e3b5 100644 --- a/opendbc/honda_accord_touring_2016_can.dbc +++ b/opendbc/honda_accord_touring_2016_can.dbc @@ -177,14 +177,14 @@ BO_ 597 ROUGH_WHEEL_SPEED: 8 VSA SG_ SET_TO_X55_2 : 47|8@0+ (1,0) [0|255] "" NEO SG_ LONG_COUNTER : 55|8@0+ (1,0) [0|255] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX - SG_ CHECKSUM : 59|4@1+ (1,0) [0|15] "" XXX + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX BO_ 660 SCM_COMMANDS: 8 SCM SG_ RIGHT_BLINKER : 6|1@0+ (1,0) [0|1] "" NEO SG_ LEFT_BLINKER : 5|1@0+ (1,0) [0|1] "" NEO SG_ WIPERS_SPEED : 4|2@0+ (1,0) [0|3] "" NEO SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX - SG_ CHECKSUM : 59|4@1+ (1,0) [0|15] "" XXX + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX BO_ 661 XXX_10: 4 XXX SG_ COUNTER : 29|2@0+ (1,0) [0|3] "" XXX diff --git a/opendbc/honda_civic_hatchback_ex_2017_can_generated.dbc b/opendbc/honda_civic_hatchback_ex_2017_can_generated.dbc index bbf810dd7c4084..cfc8a6e48db410 100644 --- a/opendbc/honda_civic_hatchback_ex_2017_can_generated.dbc +++ b/opendbc/honda_civic_hatchback_ex_2017_can_generated.dbc @@ -37,6 +37,12 @@ NS_ : BU_: EBCM EON CAM RADAR PCM EPS VSA SCM BDY XXX EPB +BO_ 148 KINEMATICS: 8 XXX + SG_ LAT_ACCEL : 7|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON + SG_ LONG_ACCEL : 25|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + BO_ 228 STEERING_CONTROL: 5 EON SG_ STEER_TORQUE_REQUEST : 23|1@0+ (1,0) [0|1] "" EPS SG_ SET_ME_X00 : 22|7@0+ (1,0) [0|127] "" EPS @@ -118,15 +124,26 @@ BO_ 464 WHEEL_SPEEDS: 8 VSA SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON BO_ 479 ACC_CONTROL: 8 EON - SG_ SET_TO_1 : 20|5@0+ (1,0) [0|1] "" PCM + SG_ SET_TO_0 : 20|5@0+ (1,0) [0|1] "" XXX SG_ CONTROL_ON : 23|3@0+ (1,0) [0|5] "" XXX - SG_ RELATED_TO_GAS : 7|7@0+ (1,0) [0|69] "" XXX - SG_ GAS_COMMAND : 0|9@0+ (1,0) [0|1] "" PCM - SG_ GAS_BRAKE : 31|14@0- (1,0) [0|1] "" XXX - SG_ ZEROS_BOH : 33|18@0+ (1,0) [100|100] "" XXX + SG_ GAS_COMMAND : 7|16@0- (1,0) [0|0] "" XXX + SG_ ACCEL_COMMAND : 31|11@0- (0.01,0) [0|0] "m/s2" XXX + SG_ BRAKE_LIGHTS : 62|1@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_REQUEST : 34|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL : 35|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL_RELEASE : 36|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_STATUS : 33|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_BRAKING : 47|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_PREPARE : 43|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX +BO_ 490 VEHICLE_DYNAMICS: 8 VSA + SG_ LAT_ACCEL : 7|16@0- (0.0015,0) [-20|20] "m/s2" EON + SG_ LONG_ACCEL : 23|16@0- (0.0015,0) [-20|20] "m/s2" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + BO_ 495 ACC_CONTROL_ON: 8 XXX SG_ SET_TO_75 : 31|8@0+ (1,0) [0|255] "" XXX SG_ SET_TO_30 : 39|8@0+ (1,0) [0|255] "" XXX @@ -173,16 +190,16 @@ BO_ 773 SEATBELT_STATUS: 7 BDY SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON BO_ 777 CAR_SPEED: 8 PCM - SG_ ROUGH_CAR_SPEED : 23|8@0+ (1,0) [0|255] "" XXX - SG_ CAR_SPEED : 7|16@0+ (1,0) [0|65535] "" XXX - SG_ ROUGH_CAR_SPEED_3 : 39|16@0+ (1,0) [0|65535] "" XXX - SG_ ROUGH_CAR_SPEED_2 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ ROUGH_CAR_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX + SG_ CAR_SPEED : 7|16@0+ (0.01,0) [0|65535] "kph" XXX + SG_ ROUGH_CAR_SPEED_3 : 39|16@0+ (0.01,0) [0|65535] "kph" XXX + SG_ ROUGH_CAR_SPEED_2 : 31|8@0+ (1,0) [0|255] "mph" XXX SG_ LOCK_STATUS : 55|2@0+ (1,0) [0|255] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX BO_ 780 ACC_HUD: 8 ADAS - SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "" BDY + SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "kph" BDY SG_ DTC_MODE : 39|1@0+ (1,0) [0|1] "" BDY SG_ BOH : 38|1@0+ (1,0) [0|1] "" BDY SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY @@ -200,7 +217,8 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX - SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX + SG_ SET_TO_X1 : 55|1@0+ (1,0) [0|1] "" XXX + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX @@ -264,7 +282,12 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON +CM_ SG_ 479 AEB_STATUS "set for the duration of AEB event"; +CM_ SG_ 479 AEB_BRAKING "set when braking is commanded during AEB event"; +CM_ SG_ 479 AEB_PREPARE "set 1s before AEB"; + VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; + CM_ "honda_civic_hatchback_ex_2017_can.dbc starts here" diff --git a/opendbc/honda_civic_touring_2016_can_generated.dbc b/opendbc/honda_civic_touring_2016_can_generated.dbc index 7cee7c73dde8db..22f4a0b9fcad01 100644 --- a/opendbc/honda_civic_touring_2016_can_generated.dbc +++ b/opendbc/honda_civic_touring_2016_can_generated.dbc @@ -78,6 +78,7 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM BO_ 420 VSA_STATUS: 8 VSA SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" EON + SG_ COMPUTER_BRAKING : 23|1@0+ (1,0) [0|1] "" EON SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" EON SG_ BRAKE_HOLD_RELATED : 52|1@0+ (1,0) [0|1] "" XXX SG_ BRAKE_HOLD_ACTIVE : 46|1@0+ (1,0) [0|1] "" EON @@ -107,21 +108,24 @@ BO_ 490 VEHICLE_DYNAMICS: 8 VSA BO_ 506 BRAKE_COMMAND: 8 ADAS SG_ COMPUTER_BRAKE : 7|10@0+ (1,0) [0|1] "" EBCM - SG_ ZEROS_BOH : 13|5@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00 : 13|5@0+ (1,0) [0|1] "" EBCM SG_ BRAKE_PUMP_REQUEST : 8|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH2 : 23|3@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_2 : 23|3@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH3 : 19|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_3 : 19|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM SG_ COMPUTER_BRAKE_REQUEST : 16|1@0+ (1,0) [0|1] "" EBCM - SG_ SET_ME_0X80 : 31|8@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_1 : 31|1@0+ (1,0) [0|1] "" EBCM + SG_ AEB_REQ_1 : 29|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_REQ_2 : 26|3@0+ (1,0) [0|7] "" XXX SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_STATES : 38|7@0+ (1,0) [0|1] "" EBCM SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM - SG_ ZEROS_BOH6 : 44|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_4 : 44|1@0+ (1,0) [0|1] "" EBCM SG_ FCW : 43|2@0+ (1,0) [0|3] "" EBCM - SG_ ZEROS_BOH4 : 55|8@0+ (1,0) [0|0] "" EBCM + SG_ AEB_STATUS : 41|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X00_5 : 55|8@0+ (1,0) [0|0] "" EBCM SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EBCM @@ -164,14 +168,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY @@ -222,6 +227,7 @@ BO_ 1029 DOORS_STATUS: 8 BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping"; +CM_ SG_ 506 AEB_REQ_1 "set for duration of suspected AEB event"; CM_ SG_ 773 PASS_AIRBAG_ON "Might just be indicator light"; CM_ SG_ 773 PASS_AIRBAG_OFF "Might just be indicator light"; CM_ SG_ 780 CRUISE_SPEED "255 = no speed"; @@ -231,6 +237,7 @@ CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc..."; VAL_ 506 FCW 3 "fcw" 2 "fcw" 1 "fcw" 0 "no_fcw" ; VAL_ 506 CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime" ; +VAL_ 506 AEB_STATUS 3 "aeb_prepare" 2 "aeb_ready" 1 "aeb_braking" 0 "no_aeb" ; VAL_ 780 CRUISE_SPEED 255 "no_speed" 252 "stopped" ; VAL_ 780 HUD_LEAD 3 "acc_off" 2 "solid_car" 1 "dashed_car" 0 "no_car" ; VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; @@ -288,6 +295,9 @@ BO_ 450 EPB_STATUS: 8 EPB SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON +BO_ 493 HUD_SETTING: 5 XXX + SG_ IMPERIAL_UNIT : 5|1@0+ (1,0) [0|1] "" EON + BO_ 487 BRAKE_PRESSURE: 4 VSA SG_ BRAKE_PRESSURE1 : 7|10@0+ (0.015625,-103) [0|1000] "" EON SG_ BRAKE_PRESSURE2 : 9|10@0+ (0.015625,-103) [0|1000] "" EON diff --git a/opendbc/honda_clarity_hybrid_2018_can.dbc b/opendbc/honda_clarity_hybrid_2018_can.dbc index 86272de0bea3f2..3d46f52cd5433a 100644 --- a/opendbc/honda_clarity_hybrid_2018_can.dbc +++ b/opendbc/honda_clarity_hybrid_2018_can.dbc @@ -409,6 +409,7 @@ BO_TX_BU_ 862 : NEO,ADAS; BO_TX_BU_ 927 : NEO,ADAS; +CM_ "CHFFR_METRIC 330 STEER_ANGLE STEER_ANGLE 0.36 180; CHFFR_METRIC 380 ENGINE_RPM ENGINE_RPM 1 0; CHFFR_METRIC 804 ENGINE_TEMPERATURE ENGINE_TEMPERATURE 1 0"; CM_ SG_ 401 GEAR "10 = reverse, 11 = transition"; CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping"; CM_ SG_ 773 PASS_AIRBAG_ON "Might just be indicator light"; @@ -430,4 +431,3 @@ VAL_ 806 CMBS_BUTTON 3 "pressed" 0 "released" ; VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; VAL_ 891 WIPERS 4 "High" 2 "Low" 0 "Off" ; VAL_ 927 ACC_ALERTS 29 "esp_active_acc_canceled" 10 "b_pedal_applied" 9 "speed_too_low" 8 "speed_too_high" 7 "p_brake_applied" 6 "gear_no_d" 5 "seatbelt" 4 "too_steep_downhill" 3 "too_steep_uphill" 2 "too_close" 1 "no_vehicle_ahead" ; -CM_ "CHFFR_METRIC 330 STEER_ANGLE STEER_ANGLE 0.36 180; CHFFR_METRIC 380 ENGINE_RPM ENGINE_RPM 1 0; CHFFR_METRIC 804 ENGINE_TEMPERATURE ENGINE_TEMPERATURE 1 0"; diff --git a/opendbc/honda_crv_ex_2017_can_generated.dbc b/opendbc/honda_crv_ex_2017_can_generated.dbc index 56a6b4e1b1c872..f8b6846c53ad90 100644 --- a/opendbc/honda_crv_ex_2017_can_generated.dbc +++ b/opendbc/honda_crv_ex_2017_can_generated.dbc @@ -37,6 +37,12 @@ NS_ : BU_: EBCM EON CAM RADAR PCM EPS VSA SCM BDY XXX EPB +BO_ 148 KINEMATICS: 8 XXX + SG_ LAT_ACCEL : 7|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON + SG_ LONG_ACCEL : 25|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + BO_ 228 STEERING_CONTROL: 5 EON SG_ STEER_TORQUE_REQUEST : 23|1@0+ (1,0) [0|1] "" EPS SG_ SET_ME_X00 : 22|7@0+ (1,0) [0|127] "" EPS @@ -118,15 +124,26 @@ BO_ 464 WHEEL_SPEEDS: 8 VSA SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON BO_ 479 ACC_CONTROL: 8 EON - SG_ SET_TO_1 : 20|5@0+ (1,0) [0|1] "" PCM + SG_ SET_TO_0 : 20|5@0+ (1,0) [0|1] "" XXX SG_ CONTROL_ON : 23|3@0+ (1,0) [0|5] "" XXX - SG_ RELATED_TO_GAS : 7|7@0+ (1,0) [0|69] "" XXX - SG_ GAS_COMMAND : 0|9@0+ (1,0) [0|1] "" PCM - SG_ GAS_BRAKE : 31|14@0- (1,0) [0|1] "" XXX - SG_ ZEROS_BOH : 33|18@0+ (1,0) [100|100] "" XXX + SG_ GAS_COMMAND : 7|16@0- (1,0) [0|0] "" XXX + SG_ ACCEL_COMMAND : 31|11@0- (0.01,0) [0|0] "m/s2" XXX + SG_ BRAKE_LIGHTS : 62|1@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_REQUEST : 34|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL : 35|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL_RELEASE : 36|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_STATUS : 33|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_BRAKING : 47|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_PREPARE : 43|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX +BO_ 490 VEHICLE_DYNAMICS: 8 VSA + SG_ LAT_ACCEL : 7|16@0- (0.0015,0) [-20|20] "m/s2" EON + SG_ LONG_ACCEL : 23|16@0- (0.0015,0) [-20|20] "m/s2" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + BO_ 495 ACC_CONTROL_ON: 8 XXX SG_ SET_TO_75 : 31|8@0+ (1,0) [0|255] "" XXX SG_ SET_TO_30 : 39|8@0+ (1,0) [0|255] "" XXX @@ -173,16 +190,16 @@ BO_ 773 SEATBELT_STATUS: 7 BDY SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON BO_ 777 CAR_SPEED: 8 PCM - SG_ ROUGH_CAR_SPEED : 23|8@0+ (1,0) [0|255] "" XXX - SG_ CAR_SPEED : 7|16@0+ (1,0) [0|65535] "" XXX - SG_ ROUGH_CAR_SPEED_3 : 39|16@0+ (1,0) [0|65535] "" XXX - SG_ ROUGH_CAR_SPEED_2 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ ROUGH_CAR_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX + SG_ CAR_SPEED : 7|16@0+ (0.01,0) [0|65535] "kph" XXX + SG_ ROUGH_CAR_SPEED_3 : 39|16@0+ (0.01,0) [0|65535] "kph" XXX + SG_ ROUGH_CAR_SPEED_2 : 31|8@0+ (1,0) [0|255] "mph" XXX SG_ LOCK_STATUS : 55|2@0+ (1,0) [0|255] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX BO_ 780 ACC_HUD: 8 ADAS - SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "" BDY + SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "kph" BDY SG_ DTC_MODE : 39|1@0+ (1,0) [0|1] "" BDY SG_ BOH : 38|1@0+ (1,0) [0|1] "" BDY SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY @@ -200,7 +217,8 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX - SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX + SG_ SET_TO_X1 : 55|1@0+ (1,0) [0|1] "" XXX + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX @@ -264,7 +282,12 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON +CM_ SG_ 479 AEB_STATUS "set for the duration of AEB event"; +CM_ SG_ 479 AEB_BRAKING "set when braking is commanded during AEB event"; +CM_ SG_ 479 AEB_PREPARE "set 1s before AEB"; + VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; + CM_ "honda_crv_ex_2017_can.dbc starts here" diff --git a/opendbc/honda_crv_hybrid_2019_can_generated.dbc b/opendbc/honda_crv_hybrid_2019_can_generated.dbc index 73e5a431c18acf..eba7e72a2279d4 100644 --- a/opendbc/honda_crv_hybrid_2019_can_generated.dbc +++ b/opendbc/honda_crv_hybrid_2019_can_generated.dbc @@ -37,6 +37,12 @@ NS_ : BU_: EBCM EON CAM RADAR PCM EPS VSA SCM BDY XXX EPB +BO_ 148 KINEMATICS: 8 XXX + SG_ LAT_ACCEL : 7|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON + SG_ LONG_ACCEL : 25|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + BO_ 228 STEERING_CONTROL: 5 EON SG_ STEER_TORQUE_REQUEST : 23|1@0+ (1,0) [0|1] "" EPS SG_ SET_ME_X00 : 22|7@0+ (1,0) [0|127] "" EPS @@ -118,15 +124,26 @@ BO_ 464 WHEEL_SPEEDS: 8 VSA SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON BO_ 479 ACC_CONTROL: 8 EON - SG_ SET_TO_1 : 20|5@0+ (1,0) [0|1] "" PCM + SG_ SET_TO_0 : 20|5@0+ (1,0) [0|1] "" XXX SG_ CONTROL_ON : 23|3@0+ (1,0) [0|5] "" XXX - SG_ RELATED_TO_GAS : 7|7@0+ (1,0) [0|69] "" XXX - SG_ GAS_COMMAND : 0|9@0+ (1,0) [0|1] "" PCM - SG_ GAS_BRAKE : 31|14@0- (1,0) [0|1] "" XXX - SG_ ZEROS_BOH : 33|18@0+ (1,0) [100|100] "" XXX + SG_ GAS_COMMAND : 7|16@0- (1,0) [0|0] "" XXX + SG_ ACCEL_COMMAND : 31|11@0- (0.01,0) [0|0] "m/s2" XXX + SG_ BRAKE_LIGHTS : 62|1@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_REQUEST : 34|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL : 35|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL_RELEASE : 36|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_STATUS : 33|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_BRAKING : 47|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_PREPARE : 43|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX +BO_ 490 VEHICLE_DYNAMICS: 8 VSA + SG_ LAT_ACCEL : 7|16@0- (0.0015,0) [-20|20] "m/s2" EON + SG_ LONG_ACCEL : 23|16@0- (0.0015,0) [-20|20] "m/s2" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + BO_ 495 ACC_CONTROL_ON: 8 XXX SG_ SET_TO_75 : 31|8@0+ (1,0) [0|255] "" XXX SG_ SET_TO_30 : 39|8@0+ (1,0) [0|255] "" XXX @@ -173,16 +190,16 @@ BO_ 773 SEATBELT_STATUS: 7 BDY SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON BO_ 777 CAR_SPEED: 8 PCM - SG_ ROUGH_CAR_SPEED : 23|8@0+ (1,0) [0|255] "" XXX - SG_ CAR_SPEED : 7|16@0+ (1,0) [0|65535] "" XXX - SG_ ROUGH_CAR_SPEED_3 : 39|16@0+ (1,0) [0|65535] "" XXX - SG_ ROUGH_CAR_SPEED_2 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ ROUGH_CAR_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX + SG_ CAR_SPEED : 7|16@0+ (0.01,0) [0|65535] "kph" XXX + SG_ ROUGH_CAR_SPEED_3 : 39|16@0+ (0.01,0) [0|65535] "kph" XXX + SG_ ROUGH_CAR_SPEED_2 : 31|8@0+ (1,0) [0|255] "mph" XXX SG_ LOCK_STATUS : 55|2@0+ (1,0) [0|255] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX BO_ 780 ACC_HUD: 8 ADAS - SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "" BDY + SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "kph" BDY SG_ DTC_MODE : 39|1@0+ (1,0) [0|1] "" BDY SG_ BOH : 38|1@0+ (1,0) [0|1] "" BDY SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY @@ -200,7 +217,8 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX - SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX + SG_ SET_TO_X1 : 55|1@0+ (1,0) [0|1] "" XXX + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX @@ -264,7 +282,12 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON +CM_ SG_ 479 AEB_STATUS "set for the duration of AEB event"; +CM_ SG_ 479 AEB_BRAKING "set when braking is commanded during AEB event"; +CM_ SG_ 479 AEB_PREPARE "set 1s before AEB"; + VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; + CM_ "honda_crv_hybrid_2019_can.dbc starts here" diff --git a/opendbc/honda_crv_touring_2016_can_generated.dbc b/opendbc/honda_crv_touring_2016_can_generated.dbc index aaee239b909155..9b5075ba62dfd4 100644 --- a/opendbc/honda_crv_touring_2016_can_generated.dbc +++ b/opendbc/honda_crv_touring_2016_can_generated.dbc @@ -78,6 +78,7 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM BO_ 420 VSA_STATUS: 8 VSA SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" EON + SG_ COMPUTER_BRAKING : 23|1@0+ (1,0) [0|1] "" EON SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" EON SG_ BRAKE_HOLD_RELATED : 52|1@0+ (1,0) [0|1] "" XXX SG_ BRAKE_HOLD_ACTIVE : 46|1@0+ (1,0) [0|1] "" EON @@ -107,21 +108,24 @@ BO_ 490 VEHICLE_DYNAMICS: 8 VSA BO_ 506 BRAKE_COMMAND: 8 ADAS SG_ COMPUTER_BRAKE : 7|10@0+ (1,0) [0|1] "" EBCM - SG_ ZEROS_BOH : 13|5@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00 : 13|5@0+ (1,0) [0|1] "" EBCM SG_ BRAKE_PUMP_REQUEST : 8|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH2 : 23|3@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_2 : 23|3@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH3 : 19|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_3 : 19|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM SG_ COMPUTER_BRAKE_REQUEST : 16|1@0+ (1,0) [0|1] "" EBCM - SG_ SET_ME_0X80 : 31|8@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_1 : 31|1@0+ (1,0) [0|1] "" EBCM + SG_ AEB_REQ_1 : 29|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_REQ_2 : 26|3@0+ (1,0) [0|7] "" XXX SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_STATES : 38|7@0+ (1,0) [0|1] "" EBCM SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM - SG_ ZEROS_BOH6 : 44|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_4 : 44|1@0+ (1,0) [0|1] "" EBCM SG_ FCW : 43|2@0+ (1,0) [0|3] "" EBCM - SG_ ZEROS_BOH4 : 55|8@0+ (1,0) [0|0] "" EBCM + SG_ AEB_STATUS : 41|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X00_5 : 55|8@0+ (1,0) [0|0] "" EBCM SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EBCM @@ -164,14 +168,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY @@ -222,6 +227,7 @@ BO_ 1029 DOORS_STATUS: 8 BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping"; +CM_ SG_ 506 AEB_REQ_1 "set for duration of suspected AEB event"; CM_ SG_ 773 PASS_AIRBAG_ON "Might just be indicator light"; CM_ SG_ 773 PASS_AIRBAG_OFF "Might just be indicator light"; CM_ SG_ 780 CRUISE_SPEED "255 = no speed"; @@ -231,6 +237,7 @@ CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc..."; VAL_ 506 FCW 3 "fcw" 2 "fcw" 1 "fcw" 0 "no_fcw" ; VAL_ 506 CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime" ; +VAL_ 506 AEB_STATUS 3 "aeb_prepare" 2 "aeb_ready" 1 "aeb_braking" 0 "no_aeb" ; VAL_ 780 CRUISE_SPEED 255 "no_speed" 252 "stopped" ; VAL_ 780 HUD_LEAD 3 "acc_off" 2 "solid_car" 1 "dashed_car" 0 "no_car" ; VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; diff --git a/opendbc/honda_fit_ex_2018_can_generated.dbc b/opendbc/honda_fit_ex_2018_can_generated.dbc index 62be687b19953d..de9aca953f98b3 100644 --- a/opendbc/honda_fit_ex_2018_can_generated.dbc +++ b/opendbc/honda_fit_ex_2018_can_generated.dbc @@ -78,6 +78,7 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM BO_ 420 VSA_STATUS: 8 VSA SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" EON + SG_ COMPUTER_BRAKING : 23|1@0+ (1,0) [0|1] "" EON SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" EON SG_ BRAKE_HOLD_RELATED : 52|1@0+ (1,0) [0|1] "" XXX SG_ BRAKE_HOLD_ACTIVE : 46|1@0+ (1,0) [0|1] "" EON @@ -107,21 +108,24 @@ BO_ 490 VEHICLE_DYNAMICS: 8 VSA BO_ 506 BRAKE_COMMAND: 8 ADAS SG_ COMPUTER_BRAKE : 7|10@0+ (1,0) [0|1] "" EBCM - SG_ ZEROS_BOH : 13|5@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00 : 13|5@0+ (1,0) [0|1] "" EBCM SG_ BRAKE_PUMP_REQUEST : 8|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH2 : 23|3@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_2 : 23|3@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH3 : 19|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_3 : 19|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM SG_ COMPUTER_BRAKE_REQUEST : 16|1@0+ (1,0) [0|1] "" EBCM - SG_ SET_ME_0X80 : 31|8@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_1 : 31|1@0+ (1,0) [0|1] "" EBCM + SG_ AEB_REQ_1 : 29|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_REQ_2 : 26|3@0+ (1,0) [0|7] "" XXX SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_STATES : 38|7@0+ (1,0) [0|1] "" EBCM SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM - SG_ ZEROS_BOH6 : 44|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_4 : 44|1@0+ (1,0) [0|1] "" EBCM SG_ FCW : 43|2@0+ (1,0) [0|3] "" EBCM - SG_ ZEROS_BOH4 : 55|8@0+ (1,0) [0|0] "" EBCM + SG_ AEB_STATUS : 41|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X00_5 : 55|8@0+ (1,0) [0|0] "" EBCM SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EBCM @@ -164,14 +168,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY @@ -222,6 +227,7 @@ BO_ 1029 DOORS_STATUS: 8 BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping"; +CM_ SG_ 506 AEB_REQ_1 "set for duration of suspected AEB event"; CM_ SG_ 773 PASS_AIRBAG_ON "Might just be indicator light"; CM_ SG_ 773 PASS_AIRBAG_OFF "Might just be indicator light"; CM_ SG_ 780 CRUISE_SPEED "255 = no speed"; @@ -231,6 +237,7 @@ CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc..."; VAL_ 506 FCW 3 "fcw" 2 "fcw" 1 "fcw" 0 "no_fcw" ; VAL_ 506 CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime" ; +VAL_ 506 AEB_STATUS 3 "aeb_prepare" 2 "aeb_ready" 1 "aeb_braking" 0 "no_aeb" ; VAL_ 780 CRUISE_SPEED 255 "no_speed" 252 "stopped" ; VAL_ 780 HUD_LEAD 3 "acc_off" 2 "solid_car" 1 "dashed_car" 0 "no_car" ; VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; diff --git a/opendbc/honda_fit_hybrid_2018_can_generated.dbc b/opendbc/honda_fit_hybrid_2018_can_generated.dbc new file mode 100644 index 00000000000000..8d3db09ec461e0 --- /dev/null +++ b/opendbc/honda_fit_hybrid_2018_can_generated.dbc @@ -0,0 +1,350 @@ +CM_ "AUTOGENERATED FILE, DO NOT EDIT" + + +CM_ "Imported file _comma.dbc starts here" +BO_ 512 GAS_COMMAND: 6 EON + SG_ GAS_COMMAND : 7|16@0+ (0.253984064,-83.3) [0|1] "" INTERCEPTOR + SG_ GAS_COMMAND2 : 23|16@0+ (0.126992032,-83.3) [0|1] "" INTERCEPTOR + SG_ ENABLE : 39|1@0+ (1,0) [0|1] "" INTERCEPTOR + SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" INTERCEPTOR + SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" INTERCEPTOR + +BO_ 513 GAS_SENSOR: 6 INTERCEPTOR + SG_ INTERCEPTOR_GAS : 7|16@0+ (0.253984064,-83.3) [0|1] "" EON + SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.126992032,-83.3) [0|1] "" EON + SG_ STATE : 39|4@0+ (1,0) [0|15] "" EON + SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" EON + SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" EON + +VAL_ 513 STATE 5 "FAULT_TIMEOUT" 4 "FAULT_STARTUP" 3 "FAULT_SCE" 2 "FAULT_SEND" 1 "FAULT_BAD_CHECKSUM" 0 "NO_FAULT" ; + + +CM_ "Imported file _dual_can_nidec_2018.dbc starts here" +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BU_: EBCM ADAS PCM EPS VSA SCM BDY XXX EPB EON + +BO_ 344 ENGINE_DATA: 8 PCM + SG_ XMISSION_SPEED : 7|16@0+ (0.01,0) [0|250] "kph" EON + SG_ ENGINE_RPM : 23|16@0+ (1,0) [0|15000] "rpm" EON + SG_ XMISSION_SPEED2 : 39|16@0+ (0.01,0) [0|250] "kph" EON + SG_ ODOMETER : 55|8@0+ (10,0) [0|2550] "m" XXX + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 380 POWERTRAIN_DATA: 8 PCM + SG_ PEDAL_GAS : 7|8@0+ (1,0) [0|255] "" EON + SG_ ENGINE_RPM : 23|16@0+ (1,0) [0|15000] "rpm" EON + SG_ GAS_PRESSED : 39|1@0+ (1,0) [0|1] "" EON + SG_ ACC_STATUS : 38|1@0+ (1,0) [0|1] "" EON + SG_ BOH_17C : 37|5@0+ (1,0) [0|1] "" EON + SG_ BRAKE_SWITCH : 32|1@0+ (1,0) [0|1] "" EON + SG_ BOH2_17C : 47|10@0+ (1,0) [0|1] "" EON + SG_ BRAKE_PRESSED : 53|1@0+ (1,0) [0|1] "" EON + SG_ BOH3_17C : 52|5@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 420 VSA_STATUS: 8 VSA + SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" EON + SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" EON + SG_ BRAKE_HOLD_RELATED : 52|1@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_HOLD_ACTIVE : 46|1@0+ (1,0) [0|1] "" EON + SG_ BRAKE_HOLD_ENABLED : 45|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 432 STANDSTILL: 7 VSA + SG_ CONTROLLED_STANDSTILL : 0|1@0+ (1,0) [0|1] "" EON + SG_ WHEELS_MOVING : 12|1@0+ (1,0) [0|1] "" EON + SG_ BRAKE_ERROR_1 : 11|1@0+ (1,0) [0|1] "" EON + SG_ BRAKE_ERROR_2 : 9|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON + +BO_ 464 WHEEL_SPEEDS: 8 VSA + SG_ WHEEL_SPEED_FL : 7|15@0+ (0.01,0) [0|250] "kph" EON + SG_ WHEEL_SPEED_FR : 8|15@0+ (0.01,0) [0|250] "kph" EON + SG_ WHEEL_SPEED_RL : 25|15@0+ (0.01,0) [0|250] "kph" EON + SG_ WHEEL_SPEED_RR : 42|15@0+ (0.01,0) [0|250] "kph" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 490 VEHICLE_DYNAMICS: 8 VSA + SG_ LONG_ACCEL : 23|16@0- (0.0015384,0) [-20|20] "m/s2" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 506 BRAKE_COMMAND: 8 ADAS + SG_ ZEROS_BOH : 7|12@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_PUMP_REQUEST : 11|1@0+ (1,0) [0|1] "" EBCM + SG_ ZEROS_BOH2 : 10|3@0+ (1,0) [0|7] "" XXX + SG_ CRUISE_BOH2 : 23|3@0+ (1,0) [0|1] "" EBCM + SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM + SG_ CRUISE_BOH3 : 19|1@0+ (1,0) [0|1] "" EBCM + SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM + SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM + SG_ COMPUTER_BRAKE_REQUEST : 16|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_0X80 : 31|8@0+ (1,0) [0|1] "" EBCM + SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM + SG_ CRUISE_STATES : 38|7@0+ (1,0) [0|1] "" EBCM + SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM + SG_ ZEROS_BOH6 : 44|1@0+ (1,0) [0|1] "" EBCM + SG_ FCW : 43|2@0+ (1,0) [0|3] "" EBCM + SG_ COMPUTER_BRAKE : 55|10@0+ (1,0) [0|1] "" EBCM + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EBCM + +BO_ 597 ROUGH_WHEEL_SPEED: 8 VSA + SG_ WHEEL_SPEED_FL : 7|8@0+ (1,0) [0|255] "mph" EON + SG_ WHEEL_SPEED_FR : 15|8@0+ (1,0) [0|255] "mph" EON + SG_ WHEEL_SPEED_RL : 23|8@0+ (1,0) [0|255] "mph" EON + SG_ WHEEL_SPEED_RR : 31|8@0+ (1,0) [0|255] "mph" EON + SG_ SET_TO_X55 : 39|8@0+ (1,0) [0|255] "" EON + SG_ SET_TO_X55_2 : 47|8@0+ (1,0) [0|255] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 773 SEATBELT_STATUS: 7 BDY + SG_ SEATBELT_DRIVER_LAMP : 7|1@0+ (1,0) [0|1] "" EON + SG_ SEATBELT_PASS_UNLATCHED : 10|1@0+ (1,0) [0|1] "" EON + SG_ SEATBELT_PASS_LATCHED : 11|1@0+ (1,0) [0|1] "" EON + SG_ SEATBELT_DRIVER_UNLATCHED : 12|1@0+ (1,0) [0|1] "" EON + SG_ SEATBELT_DRIVER_LATCHED : 13|1@0+ (1,0) [0|1] "" EON + SG_ PASS_AIRBAG_OFF : 14|1@0+ (1,0) [0|1] "" EON + SG_ PASS_AIRBAG_ON : 15|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON + +BO_ 777 LOCK_STATUS: 8 XXX + SG_ DOORS_UNLOCKED : 54|1@0+ (1,0) [0|1] "" EON + SG_ DOORS_LOCKED : 55|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 780 ACC_HUD: 8 ADAS + SG_ PCM_SPEED : 7|16@0+ (0.01,0) [0|250] "kph" BDY + SG_ PCM_GAS : 23|8@0+ (1,0) [0|127] "" BDY + SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "" BDY + SG_ DTC_MODE : 39|1@0+ (1,0) [0|1] "" BDY + SG_ BOH : 38|1@0+ (1,0) [0|1] "" BDY + SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY + SG_ FCM_OFF : 36|1@0+ (1,0) [0|1] "" BDY + SG_ BOH_2 : 35|1@0+ (1,0) [0|1] "" BDY + SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY + SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY + SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY + SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY + SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY + SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY + SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY + +BO_ 804 CRUISE: 8 PCM + SG_ HUD_SPEED_KPH : 7|8@0+ (1,0) [0|255] "kph" EON + SG_ HUD_SPEED_MPH : 15|8@0+ (1,0) [0|255] "mph" EON + SG_ TRIP_FUEL_CONSUMED : 23|16@0+ (1,0) [0|255] "" EON + SG_ CRUISE_SPEED_PCM : 39|8@0+ (1,0) [0|255] "" EON + SG_ BOH2 : 47|8@0- (1,0) [0|255] "" EON + SG_ BOH3 : 55|8@0+ (1,0) [0|255] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 829 LKAS_HUD: 5 ADAS + SG_ CAM_TEMP_HIGH : 7|1@0+ (1,0) [0|255] "" BDY + SG_ SET_ME_X41 : 6|7@0+ (1,0) [0|127] "" BDY + SG_ BOH : 6|7@0+ (1,0) [0|127] "" BDY + SG_ DASHED_LANES : 14|1@0+ (1,0) [0|1] "" BDY + SG_ DTC : 13|1@0+ (1,0) [0|1] "" BDY + SG_ LKAS_PROBLEM : 12|1@0+ (1,0) [0|1] "" BDY + SG_ LKAS_OFF : 11|1@0+ (1,0) [0|1] "" BDY + SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY + SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY + SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY + SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY + SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY + SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY + SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY + SG_ LDW_OFF : 27|1@0+ (1,0) [0|1] "" BDY + SG_ CLEAN_WINDSHIELD : 26|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X48 : 31|8@0+ (1,0) [0|255] "" BDY + SG_ COUNTER : 37|2@0+ (1,0) [0|3] "" BDY + SG_ CHECKSUM : 35|4@0+ (1,0) [0|15] "" BDY + +BO_ 892 CRUISE_PARAMS: 8 PCM + SG_ CRUISE_SPEED_OFFSET : 31|8@0- (0.1,0) [-128|127] "kph" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + +BO_ 1029 DOORS_STATUS: 8 BDY + SG_ DOOR_OPEN_FL : 37|1@0+ (1,0) [0|1] "" EON + SG_ DOOR_OPEN_FR : 38|1@0+ (1,0) [0|1] "" EON + SG_ DOOR_OPEN_RL : 39|1@0+ (1,0) [0|1] "" EON + SG_ DOOR_OPEN_RR : 40|1@0+ (1,0) [0|1] "" EON + SG_ TRUNK_OPEN : 41|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping"; +CM_ SG_ 773 PASS_AIRBAG_ON "Might just be indicator light"; +CM_ SG_ 773 PASS_AIRBAG_OFF "Might just be indicator light"; +CM_ SG_ 780 CRUISE_SPEED "255 = no speed"; +CM_ SG_ 804 CRUISE_SPEED_PCM "255 = no speed"; +CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc..."; + + +VAL_ 506 FCW 3 "fcw" 2 "fcw" 1 "fcw" 0 "no_fcw" ; +VAL_ 506 CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime" ; +VAL_ 780 CRUISE_SPEED 255 "no_speed" 252 "stopped" ; +VAL_ 780 HUD_LEAD 3 "acc_off" 2 "solid_car" 1 "dashed_car" 0 "no_car" ; +VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; + +CM_ "honda_fit_hybrid_2018_can.dbc starts here" + + + +BO_ 145 KINEMATICS: 8 XXX + SG_ LAT_ACCEL : 7|10@0+ (0.02,-512) [-20|20] "m/s2" EON + +BO_ 228 STEERING_CONTROL: 5 ADAS + SG_ STEER_TORQUE : 7|16@0- (1,0) [-3840|3840] "" EPS + SG_ STEER_TORQUE_REQUEST : 23|1@0+ (1,0) [0|1] "" EPS + SG_ SET_ME_X00 : 22|7@0+ (1,0) [0|127] "" EPS + SG_ SET_ME_X00_2 : 31|8@0+ (1,0) [0|0] "" EPS + SG_ COUNTER : 37|2@0+ (1,0) [0|3] "" EPS + SG_ CHECKSUM : 35|4@0+ (1,0) [0|15] "" EPS + +BO_ 304 GAS_PEDAL_2: 8 PCM + SG_ ENGINE_TORQUE_ESTIMATE : 7|16@0- (1,0) [-1000|1000] "Nm" EON + SG_ ENGINE_TORQUE_REQUEST : 23|16@0- (1,0) [-1000|1000] "Nm" EON + SG_ CAR_GAS : 39|8@0+ (1,0) [0|255] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 342 STEERING_SENSORS: 6 EPS + SG_ STEER_ANGLE : 7|16@0- (-0.1,0) [-500|500] "deg" EON + SG_ STEER_ANGLE_RATE : 23|16@0- (1,0) [-3000|3000] "deg/s" EON + SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON + +BO_ 399 STEER_STATUS: 7 EPS + SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON + SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON + +BO_ 419 GEARBOX: 8 PCM + SG_ GEAR : 7|8@0+ (1,0) [0|256] "" EON + SG_ GEAR_SHIFTER : 35|4@0+ (1,0) [0|15] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 422 SCM_BUTTONS: 8 SCM + SG_ CRUISE_BUTTONS : 7|3@0+ (1,0) [0|7] "" EON + SG_ LIGHTS_SETTING : 1|2@0+ (1,0) [0|3] "" EON + SG_ MAIN_ON : 47|1@0+ (1,0) [0|1] "" EON + SG_ CRUISE_SETTING : 43|2@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 487 BRAKE_PRESSURE: 4 VSA + SG_ BRAKE_PRESSURE1 : 7|10@0+ (0.015625,-103) [0|1000] "" EON + SG_ BRAKE_PRESSURE2 : 9|10@0+ (0.015625,-103) [0|1000] "" EON + SG_ CHECKSUM : 27|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 29|2@0+ (1,0) [0|3] "" EON + +BO_ 545 ECON_STATUS: 5 XXX + SG_ ECON_ON : 23|1@0+ (1,0) [0|1] "" EON + SG_ CHECKSUM : 35|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 37|2@0+ (1,0) [0|3] "" EON + +BO_ 660 SCM_FEEDBACK: 8 SCM + SG_ RIGHT_BLINKER : 6|1@0+ (1,0) [0|1] "" EON + SG_ LEFT_BLINKER : 5|1@0+ (1,0) [0|1] "" EON + SG_ WIPERS_SPEED : 4|2@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 862 HIGHBEAM_CONTROL: 8 ADAS + SG_ ZEROS_BOH : 7|50@0+ (1,0) [0|127] "" BDY + SG_ ZEROS_BOH_2 : 48|4@1+ (1,0) [0|15] "" XXX + SG_ HIGHBEAMS_ON : 52|1@0+ (1,0) [0|1] "" XXX + SG_ AUTO_HIGHBEAMS_ACTIVE : 53|1@0+ (1,0) [0|1] "" XXX + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX + +BO_ 884 STALK_STATUS: 8 XXX + SG_ AUTO_HEADLIGHTS : 46|1@0+ (1,0) [0|1] "" EON + SG_ HIGH_BEAM_HOLD : 47|1@0+ (1,0) [0|1] "" EON + SG_ HIGH_BEAM_FLASH : 45|1@0+ (1,0) [0|1] "" EON + SG_ HEADLIGHTS_ON : 54|1@0+ (1,0) [0|1] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + +BO_ 891 WIPERS: 8 XXX + SG_ WIPERS : 17|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + +BO_ 927 RADAR_HUD: 8 ADAS + SG_ ZEROS_BOH : 7|17@0+ (1,0) [0|127] "" BDY + SG_ APPLY_BRAKES_FOR_CANC : 23|1@0+ (1,0) [0|15] "" BDY + SG_ ZEROS_BOH2 : 31|8@0+ (1,0) [0|127] "" BDY + SG_ RESUME_INSTRUCTION : 21|1@0+ (1,0) [0|15] "" BDY + SG_ ACC_ALERTS : 20|5@0+ (1,0) [0|15] "" BDY + SG_ LEAD_SPEED : 39|9@0+ (1,0) [0|127] "" BDY + SG_ LEAD_STATE : 46|3@0+ (1,0) [0|127] "" BDY + SG_ LEAD_DISTANCE : 43|5@0+ (1,0) [0|31] "" BDY + SG_ ZEROS_BOH3 : 54|7@0+ (1,0) [0|127] "" BDY + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" BDY + +CM_ SG_ 419 GEAR "10 = reverse, 11 = transition"; +CM_ SG_ 420 BRAKE_HOLD_RELATED "On when Brake Hold engaged"; + +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 419 GEAR_SHIFTER 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; +VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; +VAL_ 422 LIGHTS_SETTING 3 "high_beam" 2 "low_beam" 1 "position" 0 "no_lights" ; +VAL_ 422 CRUISE_SETTING 3 "distance_adj" 2 "tbd" 1 "lkas_button" 0 "none" ; + +CM_ "CHFFR_METRIC 342 STEER_ANGLE STEER_ANGLE 0.36 180; CHFFR_METRIC 380 ENGINE_RPM ENGINE_RPM 1 0; CHFFR_METRIC 804 ENGINE_TEMPERATURE ENGINE_TEMPERATURE 1 0"; diff --git a/opendbc/honda_insight_ex_2019_can_generated.dbc b/opendbc/honda_insight_ex_2019_can_generated.dbc index f2874fa45b86ce..92fc0b50ac2132 100644 --- a/opendbc/honda_insight_ex_2019_can_generated.dbc +++ b/opendbc/honda_insight_ex_2019_can_generated.dbc @@ -37,6 +37,12 @@ NS_ : BU_: EBCM EON CAM RADAR PCM EPS VSA SCM BDY XXX EPB +BO_ 148 KINEMATICS: 8 XXX + SG_ LAT_ACCEL : 7|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON + SG_ LONG_ACCEL : 25|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + BO_ 228 STEERING_CONTROL: 5 EON SG_ STEER_TORQUE_REQUEST : 23|1@0+ (1,0) [0|1] "" EPS SG_ SET_ME_X00 : 22|7@0+ (1,0) [0|127] "" EPS @@ -118,15 +124,26 @@ BO_ 464 WHEEL_SPEEDS: 8 VSA SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON BO_ 479 ACC_CONTROL: 8 EON - SG_ SET_TO_1 : 20|5@0+ (1,0) [0|1] "" PCM + SG_ SET_TO_0 : 20|5@0+ (1,0) [0|1] "" XXX SG_ CONTROL_ON : 23|3@0+ (1,0) [0|5] "" XXX - SG_ RELATED_TO_GAS : 7|7@0+ (1,0) [0|69] "" XXX - SG_ GAS_COMMAND : 0|9@0+ (1,0) [0|1] "" PCM - SG_ GAS_BRAKE : 31|14@0- (1,0) [0|1] "" XXX - SG_ ZEROS_BOH : 33|18@0+ (1,0) [100|100] "" XXX + SG_ GAS_COMMAND : 7|16@0- (1,0) [0|0] "" XXX + SG_ ACCEL_COMMAND : 31|11@0- (0.01,0) [0|0] "m/s2" XXX + SG_ BRAKE_LIGHTS : 62|1@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_REQUEST : 34|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL : 35|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL_RELEASE : 36|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_STATUS : 33|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_BRAKING : 47|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_PREPARE : 43|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX +BO_ 490 VEHICLE_DYNAMICS: 8 VSA + SG_ LAT_ACCEL : 7|16@0- (0.0015,0) [-20|20] "m/s2" EON + SG_ LONG_ACCEL : 23|16@0- (0.0015,0) [-20|20] "m/s2" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + BO_ 495 ACC_CONTROL_ON: 8 XXX SG_ SET_TO_75 : 31|8@0+ (1,0) [0|255] "" XXX SG_ SET_TO_30 : 39|8@0+ (1,0) [0|255] "" XXX @@ -173,16 +190,16 @@ BO_ 773 SEATBELT_STATUS: 7 BDY SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON BO_ 777 CAR_SPEED: 8 PCM - SG_ ROUGH_CAR_SPEED : 23|8@0+ (1,0) [0|255] "" XXX - SG_ CAR_SPEED : 7|16@0+ (1,0) [0|65535] "" XXX - SG_ ROUGH_CAR_SPEED_3 : 39|16@0+ (1,0) [0|65535] "" XXX - SG_ ROUGH_CAR_SPEED_2 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ ROUGH_CAR_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX + SG_ CAR_SPEED : 7|16@0+ (0.01,0) [0|65535] "kph" XXX + SG_ ROUGH_CAR_SPEED_3 : 39|16@0+ (0.01,0) [0|65535] "kph" XXX + SG_ ROUGH_CAR_SPEED_2 : 31|8@0+ (1,0) [0|255] "mph" XXX SG_ LOCK_STATUS : 55|2@0+ (1,0) [0|255] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX BO_ 780 ACC_HUD: 8 ADAS - SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "" BDY + SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "kph" BDY SG_ DTC_MODE : 39|1@0+ (1,0) [0|1] "" BDY SG_ BOH : 38|1@0+ (1,0) [0|1] "" BDY SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY @@ -200,7 +217,8 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX - SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX + SG_ SET_TO_X1 : 55|1@0+ (1,0) [0|1] "" XXX + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX @@ -264,7 +282,12 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON +CM_ SG_ 479 AEB_STATUS "set for the duration of AEB event"; +CM_ SG_ 479 AEB_BRAKING "set when braking is commanded during AEB event"; +CM_ SG_ 479 AEB_PREPARE "set 1s before AEB"; + VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; + CM_ "honda_insight_ex_2019_can.dbc starts here" diff --git a/opendbc/honda_odyssey_exl_2018_generated.dbc b/opendbc/honda_odyssey_exl_2018_generated.dbc index 6f00df2d45de6c..2899dba670a43c 100644 --- a/opendbc/honda_odyssey_exl_2018_generated.dbc +++ b/opendbc/honda_odyssey_exl_2018_generated.dbc @@ -78,6 +78,7 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM BO_ 420 VSA_STATUS: 8 VSA SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" EON + SG_ COMPUTER_BRAKING : 23|1@0+ (1,0) [0|1] "" EON SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" EON SG_ BRAKE_HOLD_RELATED : 52|1@0+ (1,0) [0|1] "" XXX SG_ BRAKE_HOLD_ACTIVE : 46|1@0+ (1,0) [0|1] "" EON @@ -107,21 +108,24 @@ BO_ 490 VEHICLE_DYNAMICS: 8 VSA BO_ 506 BRAKE_COMMAND: 8 ADAS SG_ COMPUTER_BRAKE : 7|10@0+ (1,0) [0|1] "" EBCM - SG_ ZEROS_BOH : 13|5@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00 : 13|5@0+ (1,0) [0|1] "" EBCM SG_ BRAKE_PUMP_REQUEST : 8|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH2 : 23|3@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_2 : 23|3@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH3 : 19|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_3 : 19|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM SG_ COMPUTER_BRAKE_REQUEST : 16|1@0+ (1,0) [0|1] "" EBCM - SG_ SET_ME_0X80 : 31|8@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_1 : 31|1@0+ (1,0) [0|1] "" EBCM + SG_ AEB_REQ_1 : 29|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_REQ_2 : 26|3@0+ (1,0) [0|7] "" XXX SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_STATES : 38|7@0+ (1,0) [0|1] "" EBCM SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM - SG_ ZEROS_BOH6 : 44|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_4 : 44|1@0+ (1,0) [0|1] "" EBCM SG_ FCW : 43|2@0+ (1,0) [0|3] "" EBCM - SG_ ZEROS_BOH4 : 55|8@0+ (1,0) [0|0] "" EBCM + SG_ AEB_STATUS : 41|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X00_5 : 55|8@0+ (1,0) [0|0] "" EBCM SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EBCM @@ -164,14 +168,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY @@ -222,6 +227,7 @@ BO_ 1029 DOORS_STATUS: 8 BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping"; +CM_ SG_ 506 AEB_REQ_1 "set for duration of suspected AEB event"; CM_ SG_ 773 PASS_AIRBAG_ON "Might just be indicator light"; CM_ SG_ 773 PASS_AIRBAG_OFF "Might just be indicator light"; CM_ SG_ 780 CRUISE_SPEED "255 = no speed"; @@ -231,6 +237,7 @@ CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc..."; VAL_ 506 FCW 3 "fcw" 2 "fcw" 1 "fcw" 0 "no_fcw" ; VAL_ 506 CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime" ; +VAL_ 506 AEB_STATUS 3 "aeb_prepare" 2 "aeb_ready" 1 "aeb_braking" 0 "no_aeb" ; VAL_ 780 CRUISE_SPEED 255 "no_speed" 252 "stopped" ; VAL_ 780 HUD_LEAD 3 "acc_off" 2 "solid_car" 1 "dashed_car" 0 "no_car" ; VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; diff --git a/opendbc/honda_odyssey_extreme_edition_2018_china_can.dbc b/opendbc/honda_odyssey_extreme_edition_2018_china_can.dbc deleted file mode 100644 index 91859aa2493749..00000000000000 --- a/opendbc/honda_odyssey_extreme_edition_2018_china_can.dbc +++ /dev/null @@ -1,298 +0,0 @@ -VERSION "" - - -NS_ : - NS_DESC_ - CM_ - BA_DEF_ - BA_ - VAL_ - CAT_DEF_ - CAT_ - FILTER - BA_DEF_DEF_ - EV_DATA_ - ENVVAR_DATA_ - SGTYPE_ - SGTYPE_VAL_ - BA_DEF_SGTYPE_ - BA_SGTYPE_ - SIG_TYPE_REF_ - VAL_TABLE_ - SIG_GROUP_ - SIG_VALTYPE_ - SIGTYPE_VALTYPE_ - BO_TX_BU_ - BA_DEF_REL_ - BA_REL_ - BA_DEF_DEF_REL_ - BU_SG_REL_ - BU_EV_REL_ - BU_BO_REL_ - SG_MUL_VAL_ - -BS_: - -BU_: EBCM ADAS PCM EPS VSA SCM BDY XXX EPB EON INTERCEPTOR - - -BO_ 344 ENGINE_DATA: 8 PCM - SG_ XMISSION_SPEED : 7|16@0+ (0.01,0) [0|250] "kph" EON - SG_ XMISSION_SPEED2 : 39|16@0+ (0.01,0) [0|250] "kph" EON - SG_ ODOMETER : 55|8@0+ (10,0) [0|2550] "m" XXX - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON - SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON - SG_ ZEROS : 23|16@0+ (1,0) [0|15000] "" EON - -BO_ 380 POWERTRAIN_DATA: 8 PCM - SG_ PEDAL_GAS : 7|8@0+ (1,0) [0|255] "" EON - SG_ ENGINE_RPM : 23|16@0+ (1,0) [0|15000] "rpm" EON - SG_ GAS_PRESSED : 39|1@0+ (1,0) [0|1] "" EON - SG_ ACC_STATUS : 38|1@0+ (1,0) [0|1] "rpm" EON - SG_ BOH_17C : 37|5@0+ (1,0) [0|1] "rpm" EON - SG_ BRAKE_SWITCH : 32|1@0+ (1,0) [0|1] "rpm" EON - SG_ BOH2_17C : 47|10@0+ (1,0) [0|1] "rpm" EON - SG_ BRAKE_PRESSED : 53|1@0+ (1,0) [0|1] "" EON - SG_ BOH3_17C : 52|5@0+ (1,0) [0|1] "rpm" EON - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON - SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON - -BO_ 432 STANDSTILL: 7 VSA - SG_ CONTROLLED_STANDSTILL : 0|1@0+ (1,0) [0|1] "" EON - SG_ WHEELS_MOVING : 12|1@0+ (1,0) [0|1] "" EON - SG_ BRAKE_ERROR_1 : 11|1@0+ (1,0) [0|1] "" EON - SG_ BRAKE_ERROR_2 : 9|1@0+ (1,0) [0|1] "" EON - SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON - SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON - -BO_ 464 WHEEL_SPEEDS: 8 VSA - SG_ WHEEL_SPEED_FL : 7|15@0+ (0.01,0) [0|250] "kph" EON - SG_ WHEEL_SPEED_FR : 8|15@0+ (0.01,0) [0|250] "kph" EON - SG_ WHEEL_SPEED_RL : 25|15@0+ (0.01,0) [0|250] "kph" EON - SG_ WHEEL_SPEED_RR : 42|15@0+ (0.01,0) [0|250] "kph" EON - SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON - -BO_ 490 VEHICLE_DYNAMICS: 8 VSA - SG_ LONG_ACCEL : 23|16@0- (0.0015384,0) [-20|20] "m/s2" EON - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON - SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON - -BO_ 506 BRAKE_COMMAND: 8 ADAS - SG_ COMPUTER_BRAKE : 7|10@0+ (1,0) [0|1] "" EBCM - SG_ ZEROS_BOH : 13|5@0+ (1,0) [0|1] "" EBCM - SG_ BRAKE_PUMP_REQUEST : 8|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH2 : 23|3@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH3 : 19|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM - SG_ COMPUTER_BRAKE_REQUEST : 16|1@0+ (1,0) [0|1] "" EBCM - SG_ SET_ME_0X80 : 31|8@0+ (1,0) [0|1] "" EBCM - SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_STATES : 38|7@0+ (1,0) [0|1] "" EBCM - SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM - SG_ ZEROS_BOH6 : 44|1@0+ (1,0) [0|1] "" EBCM - SG_ FCW : 43|2@0+ (1,0) [0|3] "" EBCM - SG_ ZEROS_BOH4 : 55|8@0+ (1,0) [0|0] "" EBCM - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM - SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EBCM - -BO_ 512 GAS_COMMAND: 6 EON - SG_ GAS_COMMAND : 7|16@0+ (0.253984064,-83.3) [0|1] "" INTERCEPTOR - SG_ GAS_COMMAND2 : 23|16@0+ (0.126992032,-83.3) [0|1] "" INTERCEPTOR - SG_ ENABLE : 39|1@0+ (1,0) [0|1] "" INTERCEPTOR - SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" INTERCEPTOR - SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" INTERCEPTOR - -BO_ 513 GAS_SENSOR: 6 INTERCEPTOR - SG_ INTERCEPTOR_GAS : 7|16@0+ (0.253984064,-83.3) [0|1] "" EON - SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.126992032,-83.3) [0|1] "" EON - SG_ STATE : 39|8@0+ (1,0) [0|255] "" EON - SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" EON - SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON - -BO_ 597 ROUGH_WHEEL_SPEED: 8 VSA - SG_ WHEEL_SPEED_FL : 7|8@0+ (1,0) [0|255] "mph" EON - SG_ WHEEL_SPEED_FR : 15|8@0+ (1,0) [0|255] "mph" EON - SG_ WHEEL_SPEED_RL : 23|8@0+ (1,0) [0|255] "mph" EON - SG_ WHEEL_SPEED_RR : 31|8@0+ (1,0) [0|255] "mph" EON - SG_ SET_TO_X55 : 39|8@0+ (1,0) [0|255] "" EON - SG_ SET_TO_X55_2 : 47|8@0+ (1,0) [0|255] "" EON - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON - SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON - -BO_ 773 SEATBELT_STATUS: 7 BDY - SG_ SEATBELT_DRIVER_LAMP : 7|1@0+ (1,0) [0|1] "" EON - SG_ SEATBELT_PASS_UNLATCHED : 10|1@0+ (1,0) [0|1] "" EON - SG_ SEATBELT_PASS_LATCHED : 11|1@0+ (1,0) [0|1] "" EON - SG_ SEATBELT_DRIVER_UNLATCHED : 12|1@0+ (1,0) [0|1] "" EON - SG_ SEATBELT_DRIVER_LATCHED : 13|1@0+ (1,0) [0|1] "" EON - SG_ PASS_AIRBAG_OFF : 14|1@0+ (1,0) [0|1] "" EON - SG_ PASS_AIRBAG_ON : 15|1@0+ (1,0) [0|1] "" EON - SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON - SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON - -BO_ 777 LOCK_STATUS: 8 XXX - SG_ DOORS_UNLOCKED : 54|1@0+ (1,0) [0|1] "" EON - SG_ DOORS_LOCKED : 55|1@0+ (1,0) [0|1] "" EON - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON - SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON - -BO_ 780 ACC_HUD: 8 ADAS - SG_ PCM_SPEED : 7|16@0+ (0.01,0) [0|250] "kph" BDY - SG_ PCM_GAS : 23|8@0+ (1,0) [0|127] "" BDY - SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "" BDY - SG_ DTC_MODE : 39|1@0+ (1,0) [0|1] "" BDY - SG_ BOH : 38|1@0+ (1,0) [0|1] "" BDY - SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY - SG_ FCM_OFF : 36|1@0+ (1,0) [0|1] "" BDY - SG_ BOH_2 : 35|1@0+ (1,0) [0|1] "" BDY - SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY - SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY - SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY - SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY - SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY - SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY - SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY - SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY - SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY - SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY - SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY - -BO_ 804 CRUISE: 8 PCM - SG_ HUD_SPEED_KPH : 7|8@0+ (1,0) [0|255] "kph" EON - SG_ HUD_SPEED_MPH : 15|8@0+ (1,0) [0|255] "mph" EON - SG_ TRIP_FUEL_CONSUMED : 23|16@0+ (1,0) [0|255] "" EON - SG_ CRUISE_SPEED_PCM : 39|8@0+ (1,0) [0|255] "" EON - SG_ BOH2 : 47|8@0- (1,0) [0|255] "" EON - SG_ BOH3 : 55|8@0+ (1,0) [0|255] "" EON - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON - SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON - -BO_ 829 LKAS_HUD: 5 ADAS - SG_ CAM_TEMP_HIGH : 7|1@0+ (1,0) [0|255] "" BDY - SG_ SET_ME_X41 : 6|7@0+ (1,0) [0|127] "" BDY - SG_ BOH : 6|7@0+ (1,0) [0|127] "" BDY - SG_ DASHED_LANES : 14|1@0+ (1,0) [0|1] "" BDY - SG_ DTC : 13|1@0+ (1,0) [0|1] "" BDY - SG_ LKAS_PROBLEM : 12|1@0+ (1,0) [0|1] "" BDY - SG_ LKAS_OFF : 11|1@0+ (1,0) [0|1] "" BDY - SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY - SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY - SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY - SG_ BOH2 : 23|2@0+ (1,0) [0|4] "" BDY - SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY - SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY - SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY - SG_ LDW_OFF : 27|1@0+ (1,0) [0|1] "" BDY - SG_ CLEAN_WINDSHIELD : 26|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X48 : 31|8@0+ (1,0) [0|255] "" BDY - SG_ COUNTER : 37|2@0+ (1,0) [0|3] "" BDY - SG_ CHECKSUM : 35|4@0+ (1,0) [0|15] "" BDY - -BO_ 892 CRUISE_PARAMS: 8 PCM - SG_ CRUISE_SPEED_OFFSET : 31|8@0- (0.1,0) [-128|127] "kph" EON - SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON - -BO_ 316 GAS_PEDAL: 8 PCM - SG_ CAR_GAS : 39|8@0+ (1,0) [0|255] "" EON - -BO_ 342 STEERING_SENSORS: 6 EPS - SG_ STEER_ANGLE_RATE : 23|16@0- (1,0) [-3000|3000] "deg/s" EON - SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" EON - SG_ CHECKSUM : 43|4@0+ (1,0) [0|15] "" EON - SG_ STEER_ANGLE : 7|16@0- (-0.1,0) [-500|500] "deg" EON - -BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-2985|2985] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ CHECKSUM : 51|4@0+ (1,0) [0|15] "" EON - SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON - SG_ STEER_STATUS : 43|4@0+ (1,0) [0|15] "" EON - SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON - -BO_ 401 GEARBOX: 8 PCM - SG_ GEAR_SHIFTER : 5|6@0+ (1,0) [0|63] "" EON - SG_ GEAR : 35|4@0+ (1,0) [0|15] "" EON - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON - SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON - -BO_ 404 STEERING_CONTROL: 4 EON - SG_ SET_ME_X00 : 22|7@0+ (1,0) [0|127] "" EPS - SG_ STEER_TORQUE_REQUEST : 23|1@0+ (1,0) [0|1] "" EPS - SG_ COUNTER : 29|2@0+ (1,0) [0|15] "" EPS - SG_ CHECKSUM : 27|4@0+ (1,0) [0|3] "" EPS - SG_ STEER_TORQUE : 7|16@0- (-1,0) [-32767|32767] "" EPS - -BO_ 420 VSA_STATUS: 8 VSA - SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" EON - SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" EON - SG_ BRAKE_HOLD_RELATED : 52|1@0+ (1,0) [0|1] "" XXX - SG_ BRAKE_HOLD_ACTIVE : 46|1@0+ (1,0) [0|1] "" EON - SG_ BRAKE_HOLD_ENABLED : 45|1@0+ (1,0) [0|1] "" EON - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON - SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON - -BO_ 422 SCM_BUTTONS: 8 SCM - SG_ CRUISE_BUTTONS : 7|3@0+ (1,0) [0|7] "" EON - SG_ LIGHTS_SETTING : 1|2@0+ (1,0) [0|3] "" EON - SG_ MAIN_ON : 47|1@0+ (1,0) [0|1] "" EON - SG_ CRUISE_SETTING : 43|2@0+ (1,0) [0|3] "" EON - SG_ DRIVERS_DOOR_OPEN : 63|1@0+ (1,0) [0|1] "" XXX - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON - SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON - -BO_ 450 EPB_STATUS: 8 XXX - SG_ EPB_BRAKE_AND_PULL : 6|1@0+ (1,0) [0|1] "" XXX - SG_ EPB_ACTIVE : 3|1@0+ (1,0) [0|1] "" XXX - SG_ EPB_STATE : 29|2@0+ (1,0) [0|1] "" XXX - SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX - -BO_ 660 SCM_FEEDBACK: 8 SCM - SG_ RIGHT_BLINKER : 6|1@0+ (1,0) [0|1] "" EON - SG_ LEFT_BLINKER : 5|1@0+ (1,0) [0|1] "" EON - SG_ WIPERS_SPEED : 4|2@0+ (1,0) [0|3] "" EON - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON - SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON - -BO_ 862 HIGHBEAM_CONTROL: 8 ADAS - SG_ ZEROS_BOH : 7|50@0+ (1,0) [0|127] "" BDY - SG_ ZEROS_BOH_2 : 48|4@1+ (1,0) [0|15] "" XXX - SG_ HIGHBEAMS_ON : 52|1@0+ (1,0) [0|1] "" XXX - SG_ AUTO_HIGHBEAMS_ACTIVE : 53|1@0+ (1,0) [0|1] "" XXX - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX - SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX - -BO_ 1302 ODOMETER: 8 XXX - SG_ ODOMETER : 7|24@0+ (1,0) [0|16777215] "km" EON - SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON - SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON - - - - -CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping"; -CM_ SG_ 773 PASS_AIRBAG_OFF "Might just be indicator light"; -CM_ SG_ 773 PASS_AIRBAG_ON "Might just be indicator light"; -CM_ SG_ 780 CRUISE_SPEED "255 = no speed"; -CM_ SG_ 804 CRUISE_SPEED_PCM "255 = no speed"; -CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc..."; -CM_ SG_ 401 GEAR "10 = reverse, 11 = transition"; -VAL_ 506 CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime" ; -VAL_ 506 FCW 3 "fcw" 2 "fcw" 1 "fcw" 0 "no_fcw" ; -VAL_ 513 STATE 5 "FAULT_TIMEOUT" 4 "FAULT_STARTUP" 3 "FAULT_SCE" 2 "FAULT_SEND" 1 "FAULT_BAD_CHECKSUM" 0 "NO_FAULT" ; -VAL_ 780 CRUISE_SPEED 255 "no_speed" 252 "stopped" ; -VAL_ 780 HUD_LEAD 3 "acc_off" 2 "solid_car" 1 "dashed_car" 0 "no_car" ; -VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; -VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; -VAL_ 401 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P" ; -VAL_ 401 GEAR 7 "L" 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; -VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; -VAL_ 422 LIGHTS_SETTING 3 "high_beam" 2 "low_beam" 1 "position" 0 "no_lights" ; -VAL_ 422 CRUISE_SETTING 3 "distance_adj" 2 "tbd" 1 "lkas_button" 0 "none" ; -CM_ "CHFFR_METRIC 342 STEER_ANGLE STEER_ANGLE 0.36 180; CHFFR_METRIC 380 ENGINE_RPM ENGINE_RPM 1 0; CHFFR_METRIC 804 ENGINE_TEMPERATURE ENGINE_TEMPERATURE 1 0"; diff --git a/opendbc/honda_odyssey_extreme_edition_2018_china_can_generated.dbc b/opendbc/honda_odyssey_extreme_edition_2018_china_can_generated.dbc new file mode 100644 index 00000000000000..f8565c03b03a32 --- /dev/null +++ b/opendbc/honda_odyssey_extreme_edition_2018_china_can_generated.dbc @@ -0,0 +1,321 @@ +CM_ "AUTOGENERATED FILE, DO NOT EDIT" + + +CM_ "Imported file _comma.dbc starts here" +BO_ 512 GAS_COMMAND: 6 EON + SG_ GAS_COMMAND : 7|16@0+ (0.253984064,-83.3) [0|1] "" INTERCEPTOR + SG_ GAS_COMMAND2 : 23|16@0+ (0.126992032,-83.3) [0|1] "" INTERCEPTOR + SG_ ENABLE : 39|1@0+ (1,0) [0|1] "" INTERCEPTOR + SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" INTERCEPTOR + SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" INTERCEPTOR + +BO_ 513 GAS_SENSOR: 6 INTERCEPTOR + SG_ INTERCEPTOR_GAS : 7|16@0+ (0.253984064,-83.3) [0|1] "" EON + SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.126992032,-83.3) [0|1] "" EON + SG_ STATE : 39|4@0+ (1,0) [0|15] "" EON + SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" EON + SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" EON + +VAL_ 513 STATE 5 "FAULT_TIMEOUT" 4 "FAULT_STARTUP" 3 "FAULT_SCE" 2 "FAULT_SEND" 1 "FAULT_BAD_CHECKSUM" 0 "NO_FAULT" ; + + +CM_ "Imported file _honda_2017.dbc starts here" +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BU_: EBCM ADAS PCM EPS VSA SCM BDY XXX EPB EON + +BO_ 344 ENGINE_DATA: 8 PCM + SG_ XMISSION_SPEED : 7|16@0+ (0.01,0) [0|250] "kph" EON + SG_ ENGINE_RPM : 23|16@0+ (1,0) [0|15000] "rpm" EON + SG_ XMISSION_SPEED2 : 39|16@0+ (0.01,0) [0|250] "kph" EON + SG_ ODOMETER : 55|8@0+ (10,0) [0|2550] "m" XXX + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 380 POWERTRAIN_DATA: 8 PCM + SG_ PEDAL_GAS : 7|8@0+ (1,0) [0|255] "" EON + SG_ ENGINE_RPM : 23|16@0+ (1,0) [0|15000] "rpm" EON + SG_ GAS_PRESSED : 39|1@0+ (1,0) [0|1] "" EON + SG_ ACC_STATUS : 38|1@0+ (1,0) [0|1] "rpm" EON + SG_ BOH_17C : 37|5@0+ (1,0) [0|1] "rpm" EON + SG_ BRAKE_SWITCH : 32|1@0+ (1,0) [0|1] "rpm" EON + SG_ BOH2_17C : 47|10@0+ (1,0) [0|1] "rpm" EON + SG_ BRAKE_PRESSED : 53|1@0+ (1,0) [0|1] "" EON + SG_ BOH3_17C : 52|5@0+ (1,0) [0|1] "rpm" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 420 VSA_STATUS: 8 VSA + SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" EON + SG_ COMPUTER_BRAKING : 23|1@0+ (1,0) [0|1] "" EON + SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" EON + SG_ BRAKE_HOLD_RELATED : 52|1@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_HOLD_ACTIVE : 46|1@0+ (1,0) [0|1] "" EON + SG_ BRAKE_HOLD_ENABLED : 45|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 432 STANDSTILL: 7 VSA + SG_ CONTROLLED_STANDSTILL : 0|1@0+ (1,0) [0|1] "" EON + SG_ WHEELS_MOVING : 12|1@0+ (1,0) [0|1] "" EON + SG_ BRAKE_ERROR_1 : 11|1@0+ (1,0) [0|1] "" EON + SG_ BRAKE_ERROR_2 : 9|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON + +BO_ 464 WHEEL_SPEEDS: 8 VSA + SG_ WHEEL_SPEED_FL : 7|15@0+ (0.01,0) [0|250] "kph" EON + SG_ WHEEL_SPEED_FR : 8|15@0+ (0.01,0) [0|250] "kph" EON + SG_ WHEEL_SPEED_RL : 25|15@0+ (0.01,0) [0|250] "kph" EON + SG_ WHEEL_SPEED_RR : 42|15@0+ (0.01,0) [0|250] "kph" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 490 VEHICLE_DYNAMICS: 8 VSA + SG_ LONG_ACCEL : 23|16@0- (0.0015384,0) [-20|20] "m/s2" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 506 BRAKE_COMMAND: 8 ADAS + SG_ COMPUTER_BRAKE : 7|10@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00 : 13|5@0+ (1,0) [0|1] "" EBCM + SG_ BRAKE_PUMP_REQUEST : 8|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_2 : 23|3@0+ (1,0) [0|1] "" EBCM + SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_3 : 19|1@0+ (1,0) [0|1] "" EBCM + SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM + SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM + SG_ COMPUTER_BRAKE_REQUEST : 16|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_1 : 31|1@0+ (1,0) [0|1] "" EBCM + SG_ AEB_REQ_1 : 29|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_REQ_2 : 26|3@0+ (1,0) [0|7] "" XXX + SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM + SG_ CRUISE_STATES : 38|7@0+ (1,0) [0|1] "" EBCM + SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM + SG_ SET_ME_X00_4 : 44|1@0+ (1,0) [0|1] "" EBCM + SG_ FCW : 43|2@0+ (1,0) [0|3] "" EBCM + SG_ AEB_STATUS : 41|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X00_5 : 55|8@0+ (1,0) [0|0] "" EBCM + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EBCM + +BO_ 597 ROUGH_WHEEL_SPEED: 8 VSA + SG_ WHEEL_SPEED_FL : 7|8@0+ (1,0) [0|255] "mph" EON + SG_ WHEEL_SPEED_FR : 15|8@0+ (1,0) [0|255] "mph" EON + SG_ WHEEL_SPEED_RL : 23|8@0+ (1,0) [0|255] "mph" EON + SG_ WHEEL_SPEED_RR : 31|8@0+ (1,0) [0|255] "mph" EON + SG_ SET_TO_X55 : 39|8@0+ (1,0) [0|255] "" EON + SG_ SET_TO_X55_2 : 47|8@0+ (1,0) [0|255] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 773 SEATBELT_STATUS: 7 BDY + SG_ SEATBELT_DRIVER_LAMP : 7|1@0+ (1,0) [0|1] "" EON + SG_ SEATBELT_PASS_UNLATCHED : 10|1@0+ (1,0) [0|1] "" EON + SG_ SEATBELT_PASS_LATCHED : 11|1@0+ (1,0) [0|1] "" EON + SG_ SEATBELT_DRIVER_UNLATCHED : 12|1@0+ (1,0) [0|1] "" EON + SG_ SEATBELT_DRIVER_LATCHED : 13|1@0+ (1,0) [0|1] "" EON + SG_ PASS_AIRBAG_OFF : 14|1@0+ (1,0) [0|1] "" EON + SG_ PASS_AIRBAG_ON : 15|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON + +BO_ 777 LOCK_STATUS: 8 XXX + SG_ DOORS_UNLOCKED : 54|1@0+ (1,0) [0|1] "" EON + SG_ DOORS_LOCKED : 55|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 780 ACC_HUD: 8 ADAS + SG_ PCM_SPEED : 7|16@0+ (0.01,0) [0|250] "kph" BDY + SG_ PCM_GAS : 23|8@0+ (1,0) [0|127] "" BDY + SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "" BDY + SG_ DTC_MODE : 39|1@0+ (1,0) [0|1] "" BDY + SG_ BOH : 38|1@0+ (1,0) [0|1] "" BDY + SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY + SG_ FCM_OFF : 36|1@0+ (1,0) [0|1] "" BDY + SG_ BOH_2 : 35|1@0+ (1,0) [0|1] "" BDY + SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY + SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY + SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY + SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY + SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY + SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY + SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY + +BO_ 804 CRUISE: 8 PCM + SG_ HUD_SPEED_KPH : 7|8@0+ (1,0) [0|255] "kph" EON + SG_ HUD_SPEED_MPH : 15|8@0+ (1,0) [0|255] "mph" EON + SG_ TRIP_FUEL_CONSUMED : 23|16@0+ (1,0) [0|255] "" EON + SG_ CRUISE_SPEED_PCM : 39|8@0+ (1,0) [0|255] "" EON + SG_ BOH2 : 47|8@0- (1,0) [0|255] "" EON + SG_ BOH3 : 55|8@0+ (1,0) [0|255] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +BO_ 829 LKAS_HUD: 5 ADAS + SG_ CAM_TEMP_HIGH : 7|1@0+ (1,0) [0|255] "" BDY + SG_ SET_ME_X41 : 6|7@0+ (1,0) [0|127] "" BDY + SG_ BOH : 6|7@0+ (1,0) [0|127] "" BDY + SG_ DASHED_LANES : 14|1@0+ (1,0) [0|1] "" BDY + SG_ DTC : 13|1@0+ (1,0) [0|1] "" BDY + SG_ LKAS_PROBLEM : 12|1@0+ (1,0) [0|1] "" BDY + SG_ LKAS_OFF : 11|1@0+ (1,0) [0|1] "" BDY + SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY + SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY + SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY + SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY + SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY + SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY + SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY + SG_ LDW_OFF : 27|1@0+ (1,0) [0|1] "" BDY + SG_ CLEAN_WINDSHIELD : 26|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X48 : 31|8@0+ (1,0) [0|255] "" BDY + SG_ COUNTER : 37|2@0+ (1,0) [0|3] "" BDY + SG_ CHECKSUM : 35|4@0+ (1,0) [0|15] "" BDY + +BO_ 892 CRUISE_PARAMS: 8 PCM + SG_ CRUISE_SPEED_OFFSET : 31|8@0- (0.1,0) [-128|127] "kph" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + +BO_ 1029 DOORS_STATUS: 8 BDY + SG_ DOOR_OPEN_FL : 37|1@0+ (1,0) [0|1] "" EON + SG_ DOOR_OPEN_FR : 38|1@0+ (1,0) [0|1] "" EON + SG_ DOOR_OPEN_RL : 39|1@0+ (1,0) [0|1] "" EON + SG_ DOOR_OPEN_RR : 40|1@0+ (1,0) [0|1] "" EON + SG_ TRUNK_OPEN : 41|1@0+ (1,0) [0|1] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping"; +CM_ SG_ 506 AEB_REQ_1 "set for duration of suspected AEB event"; +CM_ SG_ 773 PASS_AIRBAG_ON "Might just be indicator light"; +CM_ SG_ 773 PASS_AIRBAG_OFF "Might just be indicator light"; +CM_ SG_ 780 CRUISE_SPEED "255 = no speed"; +CM_ SG_ 804 CRUISE_SPEED_PCM "255 = no speed"; +CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc..."; + + +VAL_ 506 FCW 3 "fcw" 2 "fcw" 1 "fcw" 0 "no_fcw" ; +VAL_ 506 CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime" ; +VAL_ 506 AEB_STATUS 3 "aeb_prepare" 2 "aeb_ready" 1 "aeb_braking" 0 "no_aeb" ; +VAL_ 780 CRUISE_SPEED 255 "no_speed" 252 "stopped" ; +VAL_ 780 HUD_LEAD 3 "acc_off" 2 "solid_car" 1 "dashed_car" 0 "no_car" ; +VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; + +CM_ "honda_odyssey_extreme_edition_2018_china_can.dbc starts here" + + + +BO_ 316 GAS_PEDAL: 8 PCM + SG_ CAR_GAS : 39|8@0+ (1,0) [0|255] "" EON + +BO_ 342 STEERING_SENSORS: 6 EPS + SG_ STEER_ANGLE_RATE : 23|16@0- (1,0) [-3000|3000] "deg/s" EON + SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 43|4@0+ (1,0) [0|15] "" EON + SG_ STEER_ANGLE : 7|16@0- (-0.1,0) [-500|500] "deg" EON + +BO_ 399 STEER_STATUS: 7 EPS + SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-2985|2985] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ CHECKSUM : 51|4@0+ (1,0) [0|15] "" EON + SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON + SG_ STEER_STATUS : 43|4@0+ (1,0) [0|15] "" EON + SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON + +BO_ 401 GEARBOX: 8 PCM + SG_ GEAR_SHIFTER : 5|6@0+ (1,0) [0|63] "" EON + SG_ GEAR : 35|4@0+ (1,0) [0|15] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 404 STEERING_CONTROL: 4 EON + SG_ SET_ME_X00 : 22|7@0+ (1,0) [0|127] "" EPS + SG_ STEER_TORQUE_REQUEST : 23|1@0+ (1,0) [0|1] "" EPS + SG_ COUNTER : 29|2@0+ (1,0) [0|15] "" EPS + SG_ CHECKSUM : 27|4@0+ (1,0) [0|3] "" EPS + SG_ STEER_TORQUE : 7|16@0- (-1,0) [-32767|32767] "" EPS + +BO_ 422 SCM_BUTTONS: 8 SCM + SG_ CRUISE_BUTTONS : 7|3@0+ (1,0) [0|7] "" EON + SG_ LIGHTS_SETTING : 1|2@0+ (1,0) [0|3] "" EON + SG_ MAIN_ON : 47|1@0+ (1,0) [0|1] "" EON + SG_ CRUISE_SETTING : 43|2@0+ (1,0) [0|3] "" EON + SG_ DRIVERS_DOOR_OPEN : 63|1@0+ (1,0) [0|1] "" XXX + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 450 EPB_STATUS: 8 XXX + SG_ EPB_BRAKE_AND_PULL : 6|1@0+ (1,0) [0|1] "" XXX + SG_ EPB_ACTIVE : 3|1@0+ (1,0) [0|1] "" XXX + SG_ EPB_STATE : 29|2@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX + +BO_ 660 SCM_FEEDBACK: 8 SCM + SG_ RIGHT_BLINKER : 6|1@0+ (1,0) [0|1] "" EON + SG_ LEFT_BLINKER : 5|1@0+ (1,0) [0|1] "" EON + SG_ WIPERS_SPEED : 4|2@0+ (1,0) [0|3] "" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON + +BO_ 862 HIGHBEAM_CONTROL: 8 ADAS + SG_ ZEROS_BOH : 7|50@0+ (1,0) [0|127] "" BDY + SG_ ZEROS_BOH_2 : 48|4@1+ (1,0) [0|15] "" XXX + SG_ HIGHBEAMS_ON : 52|1@0+ (1,0) [0|1] "" XXX + SG_ AUTO_HIGHBEAMS_ACTIVE : 53|1@0+ (1,0) [0|1] "" XXX + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX + SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX + +BO_ 1302 ODOMETER: 8 XXX + SG_ ODOMETER : 7|24@0+ (1,0) [0|16777215] "km" EON + SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON + SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON + +CM_ SG_ 401 GEAR "10 = reverse, 11 = transition"; +VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ; +VAL_ 401 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P" ; +VAL_ 401 GEAR 7 "L" 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; +VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; +VAL_ 422 LIGHTS_SETTING 3 "high_beam" 2 "low_beam" 1 "position" 0 "no_lights" ; +VAL_ 422 CRUISE_SETTING 3 "distance_adj" 2 "tbd" 1 "lkas_button" 0 "none" ; diff --git a/opendbc/honda_pilot_touring_2017_can_generated.dbc b/opendbc/honda_pilot_touring_2017_can_generated.dbc index 310de029bee0a0..223aa1b27aa15b 100644 --- a/opendbc/honda_pilot_touring_2017_can_generated.dbc +++ b/opendbc/honda_pilot_touring_2017_can_generated.dbc @@ -78,6 +78,7 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM BO_ 420 VSA_STATUS: 8 VSA SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" EON + SG_ COMPUTER_BRAKING : 23|1@0+ (1,0) [0|1] "" EON SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" EON SG_ BRAKE_HOLD_RELATED : 52|1@0+ (1,0) [0|1] "" XXX SG_ BRAKE_HOLD_ACTIVE : 46|1@0+ (1,0) [0|1] "" EON @@ -107,21 +108,24 @@ BO_ 490 VEHICLE_DYNAMICS: 8 VSA BO_ 506 BRAKE_COMMAND: 8 ADAS SG_ COMPUTER_BRAKE : 7|10@0+ (1,0) [0|1] "" EBCM - SG_ ZEROS_BOH : 13|5@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00 : 13|5@0+ (1,0) [0|1] "" EBCM SG_ BRAKE_PUMP_REQUEST : 8|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH2 : 23|3@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_2 : 23|3@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH3 : 19|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_3 : 19|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM SG_ COMPUTER_BRAKE_REQUEST : 16|1@0+ (1,0) [0|1] "" EBCM - SG_ SET_ME_0X80 : 31|8@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_1 : 31|1@0+ (1,0) [0|1] "" EBCM + SG_ AEB_REQ_1 : 29|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_REQ_2 : 26|3@0+ (1,0) [0|7] "" XXX SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_STATES : 38|7@0+ (1,0) [0|1] "" EBCM SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM - SG_ ZEROS_BOH6 : 44|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_4 : 44|1@0+ (1,0) [0|1] "" EBCM SG_ FCW : 43|2@0+ (1,0) [0|3] "" EBCM - SG_ ZEROS_BOH4 : 55|8@0+ (1,0) [0|0] "" EBCM + SG_ AEB_STATUS : 41|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X00_5 : 55|8@0+ (1,0) [0|0] "" EBCM SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EBCM @@ -164,14 +168,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY @@ -222,6 +227,7 @@ BO_ 1029 DOORS_STATUS: 8 BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping"; +CM_ SG_ 506 AEB_REQ_1 "set for duration of suspected AEB event"; CM_ SG_ 773 PASS_AIRBAG_ON "Might just be indicator light"; CM_ SG_ 773 PASS_AIRBAG_OFF "Might just be indicator light"; CM_ SG_ 780 CRUISE_SPEED "255 = no speed"; @@ -231,6 +237,7 @@ CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc..."; VAL_ 506 FCW 3 "fcw" 2 "fcw" 1 "fcw" 0 "no_fcw" ; VAL_ 506 CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime" ; +VAL_ 506 AEB_STATUS 3 "aeb_prepare" 2 "aeb_ready" 1 "aeb_braking" 0 "no_aeb" ; VAL_ 780 CRUISE_SPEED 255 "no_speed" 252 "stopped" ; VAL_ 780 HUD_LEAD 3 "acc_off" 2 "solid_car" 1 "dashed_car" 0 "no_car" ; VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; diff --git a/opendbc/honda_ridgeline_black_edition_2017_can_generated.dbc b/opendbc/honda_ridgeline_black_edition_2017_can_generated.dbc index 04e1c78a262b46..8572b0b5edf78d 100644 --- a/opendbc/honda_ridgeline_black_edition_2017_can_generated.dbc +++ b/opendbc/honda_ridgeline_black_edition_2017_can_generated.dbc @@ -78,6 +78,7 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM BO_ 420 VSA_STATUS: 8 VSA SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" EON + SG_ COMPUTER_BRAKING : 23|1@0+ (1,0) [0|1] "" EON SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" EON SG_ BRAKE_HOLD_RELATED : 52|1@0+ (1,0) [0|1] "" XXX SG_ BRAKE_HOLD_ACTIVE : 46|1@0+ (1,0) [0|1] "" EON @@ -107,21 +108,24 @@ BO_ 490 VEHICLE_DYNAMICS: 8 VSA BO_ 506 BRAKE_COMMAND: 8 ADAS SG_ COMPUTER_BRAKE : 7|10@0+ (1,0) [0|1] "" EBCM - SG_ ZEROS_BOH : 13|5@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00 : 13|5@0+ (1,0) [0|1] "" EBCM SG_ BRAKE_PUMP_REQUEST : 8|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH2 : 23|3@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_2 : 23|3@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM - SG_ CRUISE_BOH3 : 19|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_3 : 19|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM SG_ COMPUTER_BRAKE_REQUEST : 16|1@0+ (1,0) [0|1] "" EBCM - SG_ SET_ME_0X80 : 31|8@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_1 : 31|1@0+ (1,0) [0|1] "" EBCM + SG_ AEB_REQ_1 : 29|1@0+ (1,0) [0|1] "" XXX + SG_ AEB_REQ_2 : 26|3@0+ (1,0) [0|7] "" XXX SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM SG_ CRUISE_STATES : 38|7@0+ (1,0) [0|1] "" EBCM SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM - SG_ ZEROS_BOH6 : 44|1@0+ (1,0) [0|1] "" EBCM + SG_ SET_ME_X00_4 : 44|1@0+ (1,0) [0|1] "" EBCM SG_ FCW : 43|2@0+ (1,0) [0|3] "" EBCM - SG_ ZEROS_BOH4 : 55|8@0+ (1,0) [0|0] "" EBCM + SG_ AEB_STATUS : 41|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X00_5 : 55|8@0+ (1,0) [0|0] "" EBCM SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EBCM @@ -164,14 +168,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" BDY + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY + SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY @@ -222,6 +227,7 @@ BO_ 1029 DOORS_STATUS: 8 BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping"; +CM_ SG_ 506 AEB_REQ_1 "set for duration of suspected AEB event"; CM_ SG_ 773 PASS_AIRBAG_ON "Might just be indicator light"; CM_ SG_ 773 PASS_AIRBAG_OFF "Might just be indicator light"; CM_ SG_ 780 CRUISE_SPEED "255 = no speed"; @@ -231,6 +237,7 @@ CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc..."; VAL_ 506 FCW 3 "fcw" 2 "fcw" 1 "fcw" 0 "no_fcw" ; VAL_ 506 CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime" ; +VAL_ 506 AEB_STATUS 3 "aeb_prepare" 2 "aeb_ready" 1 "aeb_braking" 0 "no_aeb" ; VAL_ 780 CRUISE_SPEED 255 "no_speed" 252 "stopped" ; VAL_ 780 HUD_LEAD 3 "acc_off" 2 "solid_car" 1 "dashed_car" 0 "no_car" ; VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ; diff --git a/opendbc/hyundai_2015_ccan.dbc b/opendbc/hyundai_2015_ccan.dbc index addc0cac31fa08..0c86beb9585aab 100644 --- a/opendbc/hyundai_2015_ccan.dbc +++ b/opendbc/hyundai_2015_ccan.dbc @@ -893,11 +893,11 @@ BO_ 67 DATC13: 8 DATC BO_ 66 DATC12: 8 DATC SG_ CR_Datc_DrTempDispC : 0|8@1+ (0.5,14.0) [15.0|32.0] "deg" CLU,IBOX - SG_ CR_Datc_DrTempDispF : 8|8@1+ (1.0,56.0) [58.0|90.0] "¢µ" CLU,IBOX + SG_ CR_Datc_DrTempDispF : 8|8@1+ (1.0,56.0) [58.0|90.0] "" CLU,IBOX SG_ CR_Datc_PsTempDispC : 16|8@1+ (0.5,14.0) [15.0|32.0] "deg" CLU,IBOX - SG_ CR_Datc_PsTempDispF : 24|8@1+ (1.0,56.0) [58.0|90.0] "¢µ" CLU,IBOX + SG_ CR_Datc_PsTempDispF : 24|8@1+ (1.0,56.0) [58.0|90.0] "" CLU,IBOX SG_ CR_Datc_RearDrTempDispC : 40|8@1+ (0.5,14.0) [15.0|32.0] "deg" CLU - SG_ CR_Datc_RearDrTempDispF : 48|8@1+ (1.0,58.0) [58.0|90.0] "¢µ" CLU + SG_ CR_Datc_RearDrTempDispF : 48|8@1+ (1.0,58.0) [58.0|90.0] "" CLU SG_ CF_Datc_CO2_Warning : 56|8@1+ (1.0,0.0) [0.0|3.0] "" CLU BO_ 1345 CGW1: 8 BCM diff --git a/opendbc/hyundai_kia_generic.dbc b/opendbc/hyundai_kia_generic.dbc index e3e6a1eb6118cb..2ade6a34b8b813 100644 --- a/opendbc/hyundai_kia_generic.dbc +++ b/opendbc/hyundai_kia_generic.dbc @@ -961,7 +961,7 @@ BO_ 64 DATC14: 8 DATC SG_ DATC_ADSDisp : 28|2@1+ (1.0,0.0) [0.0|3.0] "" CLU BO_ 832 LKAS11: 8 LDWS_LKAS - SG_ CF_Lkas_Icon : 0|2@1+ (1.0,0.0) [0.0|3.0] "" CLU,IBOX,PSB + SG_ CF_Lkas_Bca_R : 0|2@1+ (1.0,0.0) [0.0|3.0] "" CLU,IBOX,PSB SG_ CF_Lkas_LdwsSysState : 2|4@1+ (1.0,0.0) [0.0|15.0] "" CLU,IBOX,PSB SG_ CF_Lkas_SysWarning : 6|4@1+ (1.0,0.0) [0.0|15.0] "" BCM,CLU SG_ CF_Lkas_LdwsLHWarning : 10|2@1+ (1.0,0.0) [0.0|3.0] "" BCM,CLU,PSB @@ -1421,3 +1421,29 @@ BO_ 512 EMS20: 6 EMS SG_ FCO : 0|16@1+ (0.128,0.0) [0.0|8388.48] "ul" CLU,CUBIS,FPCM,IBOX SG_ CF_Ems_PumpTPres : 16|8@1+ (3.137254902,0.0) [0.0|800.0] "kPa" FPCM,IBOX SG_ Split_Stat : 32|1@1+ (1.0,0.0) [0.0|1.0] "" FPCM + +BO_ 909 FCA11: 8 FCA + SG_ CF_VSM_Prefill : 0|1@1+ (1,0) [0|1] "" ESC + SG_ CF_VSM_HBACmd : 1|2@1+ (1,0) [0|3] "" ESC + SG_ CF_VSM_Warn : 3|2@1+ (1,0) [0|3] "" ACU,CLU,ESC + SG_ CF_VSM_BeltCmd : 5|3@1+ (1,0) [0|7] "" ESC + SG_ CR_VSM_DecCmd : 8|8@1+ (0.01,0) [0|2.55] "g" ESC + SG_ FCA_Status : 18|2@1+ (1,0) [0|3] "" ACU,CLU,ESC + SG_ FCA_CmdAct : 20|1@1+ (1,0) [0|1] "" ESC + SG_ FCA_StopReq : 21|1@1+ (1,0) [0|1] "" CLU,ESC + SG_ FCA_DrvSetStatus : 22|3@1+ (1,0) [0|7] "" CLU,ESC + SG_ CF_VSM_DecCmdAct : 31|1@1+ (1,0) [0|1] "" ESC + SG_ FCA_Failinfo : 32|3@1+ (1,0) [0|7] "" ACU,CLU,ESC + SG_ CR_FCA_Alive : 56|4@1+ (1,0) [0|15] "" ESC + SG_ CR_FCA_ChkSum : 60|4@1+ (1,0) [0|15] "" ESC + +BO_ 905 SCC14: 8 SCC + SG_ ComfortBandUpper : 0|6@1+ (0.02,0) [0|1.26] "m/s^2" ESC + SG_ ComfortBandLower : 6|6@1+ (0.02,0) [0|1.26] "m/s^2" ESC + SG_ JerkUpperLimit : 12|7@1+ (0.1,0) [0|12.7] "m/s^3" ESC + SG_ JerkLowerLimit : 19|7@1+ (0.1,0) [0|12.7] "m/s^3" ESC + SG_ SCCMode : 32|3@1+ (1,0) [0|7] "" ESC + +BO_ 882 NEW11: 8 XXX + SG_ Gear_Signal : 16|3@1+ (1,0) [0|255] "" CLU + diff --git a/opendbc/lexus_ct200h_2018_pt_generated.dbc b/opendbc/lexus_ct200h_2018_pt_generated.dbc new file mode 100644 index 00000000000000..0f322dd16e49f1 --- /dev/null +++ b/opendbc/lexus_ct200h_2018_pt_generated.dbc @@ -0,0 +1,396 @@ +CM_ "AUTOGENERATED FILE, DO NOT EDIT" + + +CM_ "Imported file _comma.dbc starts here" +BO_ 359 STEERING_IPAS_COMMA: 8 IPAS + SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX + SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX + SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +CM BO_ STEERING_IPAS_COMMA "Copy of msg 614 so we can do angle control while the Park Assist ECU is connected (Panda spoofs 614 with 359 on connector J70). Note that addresses 0x266 and 0x167 are checksum-invariant"; + + BO_ 512 GAS_COMMAND: 6 EON + SG_ GAS_COMMAND : 7|16@0+ (0.159375,-75.555) [0|1] "" INTERCEPTOR + SG_ GAS_COMMAND2 : 23|16@0+ (0.159375,-151.111) [0|1] "" INTERCEPTOR + SG_ ENABLE : 39|1@0+ (1,0) [0|1] "" INTERCEPTOR + SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" INTERCEPTOR + SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" INTERCEPTOR + + BO_ 513 GAS_SENSOR: 6 INTERCEPTOR + SG_ INTERCEPTOR_GAS : 7|16@0+ (0.159375,-75.555) [0|1] "" EON + SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.159375,-151.111) [0|1] "" EON + SG_ STATE : 39|4@0+ (1,0) [0|15] "" EON + SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" EON + SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" EON + + VAL_ 513 STATE 5 "FAULT_TIMEOUT" 4 "FAULT_STARTUP" 3 "FAULT_SCE" 2 "FAULT_SEND" 1 "FAULT_BAD_CHECKSUM" 0 "NO_FAULT" ; + + +CM_ "Imported file _toyota_2017.dbc starts here" +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX DSU HCU EPS IPAS CGW + +BO_ 36 KINEMATICS: 8 XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX + SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX + +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + +BO_ 166 BRAKE: 8 XXX + SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX + SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX + +BO_ 170 WHEEL_SPEEDS: 8 XXX + SG_ WHEEL_SPEED_FR : 7|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_FL : 23|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_RR : 39|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_RL : 55|16@0+ (0.01,-67.67) [0|250] "kph" XXX + +BO_ 180 SPEED: 8 XXX + SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX + SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 353 DSU_SPEED: 8 XXX + SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX + +BO_ 466 PCM_CRUISE: 8 XXX + SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX + SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX + SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 552 ACCELEROMETER: 8 XXX + SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX + SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX + +BO_ 560 BRAKE_MODULE2: 7 XXX + SG_ BRAKE_PRESSED : 26|1@0+ (1,0) [0|1] "" XXX + +BO_ 614 STEERING_IPAS: 8 IPAS + SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX + SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX + SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX + +BO_ 740 STEERING_LKA: 5 XXX + SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX + SG_ STEER_REQUEST : 0|1@0+ (1,0) [0|1] "" XXX + SG_ COUNTER : 6|6@0+ (1,0) [0|63] "" XXX + SG_ SET_ME_1 : 7|1@0+ (1,0) [0|1] "" XXX + SG_ STEER_TORQUE_CMD : 15|16@0- (1,0) [0|65535] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 742 LEAD_INFO: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" HCU + SG_ LEAD_REL_SPEED : 23|12@0- (0.025,0) [-100|100] "m/s" HCU + SG_ LEAD_LONG_DIST : 7|13@0+ (0.05,0) [0|300] "m" HCU + +BO_ 835 ACC_CONTROL: 8 DSU + SG_ ACCEL_CMD : 7|16@0- (0.001,0) [-20|20] "m/s2" HCU + SG_ SET_ME_X01 : 23|2@0+ (1,0) [0|3] "" HCU + SG_ DISTANCE : 20|1@0+ (1,0) [0|1] "" XXX + SG_ MINI_CAR : 21|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X3 : 19|4@0+ (1,0) [0|15] "" XXX + SG_ SET_ME_1 : 30|1@0+ (1,0) [0|1] "" HCU + SG_ RELEASE_STANDSTILL : 31|1@0+ (1,0) [0|1] "" HCU + SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + +BO_ 921 PCM_CRUISE_SM: 8 XXX + SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX + SG_ DISTANCE_LINES : 14|2@0+ (1,0) [0|3] "" XXX + SG_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX + +BO_ 951 ESP_CONTROL: 8 ESP + SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX + +BO_ 1041 ACC_HUD: 8 DSU + SG_ FCW : 4|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X20 : 15|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X10 : 39|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X80 : 55|8@0+ (1,0) [0|1] "" XXX + +BO_ 1042 LKAS_HUD: 8 XXX + SG_ BARRIERS : 1|2@0+ (1,0) [0|3] "" XXX + SG_ RIGHT_LINE : 3|2@0+ (1,0) [0|3] "" XXX + SG_ LEFT_LINE : 5|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X01 : 7|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X01_2 : 11|2@0+ (1,0) [0|3] "" XXX + SG_ LDA_ALERT : 9|2@0+ (1,0) [0|3] "" XXX + SG_ TWO_BEEPS : 12|1@0+ (1,0) [0|1] "" XXX + SG_ ADJUSTING_CAMERA : 13|1@0+ (1,0) [0|1] "" XXX + SG_ LDA_MALFUNCTION : 15|1@0+ (1,0) [0|1] "" XXX + SG_ REPEATED_BEEPS : 32|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X0C : 23|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X2C : 47|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX + +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX + SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX + +BO_ 1568 SEATS_DOORS: 8 XXX + SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FL : 45|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RL : 42|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RR : 43|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FR : 44|1@0+ (1,0) [0|1] "" XXX + +BO_ 1570 LIGHT_STALK: 8 SCM + SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + +CM_ SG_ 36 ACCEL_Y "unit is tbd"; +CM_ SG_ 36 YAW_RATE "verify"; +CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +CM_ SG_ 37 STEER_RATE "factor is tbd"; +CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors"; +CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; +CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; +CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; +CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; +CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; +CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; +CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; +CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; +CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; +VAL_ 614 STATE 3 "enabled" 1 "disabled"; +VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; +VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; +VAL_ 1042 RIGHT_LINE 3 "orange" 2 "faded" 1 "solid" 0 "none"; +VAL_ 1042 LEFT_LINE 3 "orange" 2 "faded" 1 "solid" 0 "none"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; + + +CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; + +CM_ "lexus_ct200h_2018_pt.dbc starts here" + + + +BO_ 548 BRAKE_MODULE: 8 XXX + SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 581 GAS_PEDAL: 5 XXX + SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX + +BO_ 608 STEER_TORQUE_SENSOR: 8 XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (1,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX + SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 610 EPS_STATUS: 5 EPS + SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX + SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX + SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 956 GEAR_PACKET: 8 XXX + SG_ SPORT_ON : 2|1@0+ (1,0) [0|1] "" XXX + SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX + SG_ ECON_ON : 40|1@0+ (1,0) [0|1] "" XXX + +CM_ SG_ 548 BRAKE_PRESSURE "seems prop to pedal force"; +CM_ SG_ 548 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; +CM_ SG_ 581 GAS_PEDAL "it seems slightly filtered"; +CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; +VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; +VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; +VAL_ 956 GEAR 0 "D" 1 "S" 8 "N" 16 "R" 32 "P"; +VAL_ 956 SPORT_ON 0 "off" 1 "on"; +VAL_ 956 ECON_ON 0 "off" 1 "on"; diff --git a/opendbc/lexus_gs300h_2017_pt_generated.dbc b/opendbc/lexus_gs300h_2017_pt_generated.dbc new file mode 100644 index 00000000000000..5bd0bbf5d9d577 --- /dev/null +++ b/opendbc/lexus_gs300h_2017_pt_generated.dbc @@ -0,0 +1,397 @@ +CM_ "AUTOGENERATED FILE, DO NOT EDIT" + + +CM_ "Imported file _comma.dbc starts here" +BO_ 359 STEERING_IPAS_COMMA: 8 IPAS + SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX + SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX + SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +CM BO_ STEERING_IPAS_COMMA "Copy of msg 614 so we can do angle control while the Park Assist ECU is connected (Panda spoofs 614 with 359 on connector J70). Note that addresses 0x266 and 0x167 are checksum-invariant"; + + BO_ 512 GAS_COMMAND: 6 EON + SG_ GAS_COMMAND : 7|16@0+ (0.159375,-75.555) [0|1] "" INTERCEPTOR + SG_ GAS_COMMAND2 : 23|16@0+ (0.159375,-151.111) [0|1] "" INTERCEPTOR + SG_ ENABLE : 39|1@0+ (1,0) [0|1] "" INTERCEPTOR + SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" INTERCEPTOR + SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" INTERCEPTOR + + BO_ 513 GAS_SENSOR: 6 INTERCEPTOR + SG_ INTERCEPTOR_GAS : 7|16@0+ (0.159375,-75.555) [0|1] "" EON + SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.159375,-151.111) [0|1] "" EON + SG_ STATE : 39|4@0+ (1,0) [0|15] "" EON + SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" EON + SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" EON + + VAL_ 513 STATE 5 "FAULT_TIMEOUT" 4 "FAULT_STARTUP" 3 "FAULT_SCE" 2 "FAULT_SEND" 1 "FAULT_BAD_CHECKSUM" 0 "NO_FAULT" ; + + +CM_ "Imported file _toyota_2017.dbc starts here" +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX DSU HCU EPS IPAS CGW + +BO_ 36 KINEMATICS: 8 XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX + SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX + +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + +BO_ 166 BRAKE: 8 XXX + SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX + SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX + +BO_ 170 WHEEL_SPEEDS: 8 XXX + SG_ WHEEL_SPEED_FR : 7|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_FL : 23|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_RR : 39|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_RL : 55|16@0+ (0.01,-67.67) [0|250] "kph" XXX + +BO_ 180 SPEED: 8 XXX + SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX + SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 353 DSU_SPEED: 8 XXX + SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX + +BO_ 466 PCM_CRUISE: 8 XXX + SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX + SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX + SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 552 ACCELEROMETER: 8 XXX + SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX + SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX + +BO_ 560 BRAKE_MODULE2: 7 XXX + SG_ BRAKE_PRESSED : 26|1@0+ (1,0) [0|1] "" XXX + +BO_ 614 STEERING_IPAS: 8 IPAS + SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX + SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX + SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX + +BO_ 740 STEERING_LKA: 5 XXX + SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX + SG_ STEER_REQUEST : 0|1@0+ (1,0) [0|1] "" XXX + SG_ COUNTER : 6|6@0+ (1,0) [0|63] "" XXX + SG_ SET_ME_1 : 7|1@0+ (1,0) [0|1] "" XXX + SG_ STEER_TORQUE_CMD : 15|16@0- (1,0) [0|65535] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 742 LEAD_INFO: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" HCU + SG_ LEAD_REL_SPEED : 23|12@0- (0.025,0) [-100|100] "m/s" HCU + SG_ LEAD_LONG_DIST : 7|13@0+ (0.05,0) [0|300] "m" HCU + +BO_ 835 ACC_CONTROL: 8 DSU + SG_ ACCEL_CMD : 7|16@0- (0.001,0) [-20|20] "m/s2" HCU + SG_ SET_ME_X01 : 23|2@0+ (1,0) [0|3] "" HCU + SG_ DISTANCE : 20|1@0+ (1,0) [0|1] "" XXX + SG_ MINI_CAR : 21|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X3 : 19|4@0+ (1,0) [0|15] "" XXX + SG_ SET_ME_1 : 30|1@0+ (1,0) [0|1] "" HCU + SG_ RELEASE_STANDSTILL : 31|1@0+ (1,0) [0|1] "" HCU + SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + +BO_ 921 PCM_CRUISE_SM: 8 XXX + SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX + SG_ DISTANCE_LINES : 14|2@0+ (1,0) [0|3] "" XXX + SG_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX + +BO_ 951 ESP_CONTROL: 8 ESP + SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX + +BO_ 1041 ACC_HUD: 8 DSU + SG_ FCW : 4|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X20 : 15|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X10 : 39|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X80 : 55|8@0+ (1,0) [0|1] "" XXX + +BO_ 1042 LKAS_HUD: 8 XXX + SG_ BARRIERS : 1|2@0+ (1,0) [0|3] "" XXX + SG_ RIGHT_LINE : 3|2@0+ (1,0) [0|3] "" XXX + SG_ LEFT_LINE : 5|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X01 : 7|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X01_2 : 11|2@0+ (1,0) [0|3] "" XXX + SG_ LDA_ALERT : 9|2@0+ (1,0) [0|3] "" XXX + SG_ TWO_BEEPS : 12|1@0+ (1,0) [0|1] "" XXX + SG_ ADJUSTING_CAMERA : 13|1@0+ (1,0) [0|1] "" XXX + SG_ LDA_MALFUNCTION : 15|1@0+ (1,0) [0|1] "" XXX + SG_ REPEATED_BEEPS : 32|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X0C : 23|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X2C : 47|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX + +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX + SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX + +BO_ 1568 SEATS_DOORS: 8 XXX + SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FL : 45|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RL : 42|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RR : 43|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FR : 44|1@0+ (1,0) [0|1] "" XXX + +BO_ 1570 LIGHT_STALK: 8 SCM + SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + +CM_ SG_ 36 ACCEL_Y "unit is tbd"; +CM_ SG_ 36 YAW_RATE "verify"; +CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +CM_ SG_ 37 STEER_RATE "factor is tbd"; +CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors"; +CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; +CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; +CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; +CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; +CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; +CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; +CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; +CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; +CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; +VAL_ 614 STATE 3 "enabled" 1 "disabled"; +VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; +VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; +VAL_ 1042 RIGHT_LINE 3 "orange" 2 "faded" 1 "solid" 0 "none"; +VAL_ 1042 LEFT_LINE 3 "orange" 2 "faded" 1 "solid" 0 "none"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; + + +CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; + +CM_ "lexus_gs300h_2017_pt.dbc starts here" + + + +BO_ 550 BRAKE_MODULE: 8 XXX + SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 581 GAS_PEDAL: 5 XXX + SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX + +BO_ 608 STEER_TORQUE_SENSOR: 8 XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX + SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 610 EPS_STATUS: 5 EPS + SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX + SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX + SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 956 GEAR_PACKET: 8 XXX + SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX + +BO_ 1009 PCM_CRUISE_3: 8 XXX + SG_ MAIN_ON : 13|1@0+ (1,0) [0|3] "" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX + SG_ CRUISE_STATE : 10|1@0+ (1,0) [0|15] "" XXX + +CM_ SG_ 550 BRAKE_PRESSURE "seems prop to pedal force"; +CM_ SG_ 550 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; +CM_ SG_ 581 GAS_PEDAL "it seems slightly filtered"; +CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; +VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; +VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; +VAL_ 956 GEAR 0 "D" 1 "S" 8 "N" 16 "R" 32 "P"; diff --git a/opendbc/lexus_is_2018_pt_generated.dbc b/opendbc/lexus_is_2018_pt_generated.dbc index a207b26d64e7e0..0b1f5315e40e09 100644 --- a/opendbc/lexus_is_2018_pt_generated.dbc +++ b/opendbc/lexus_is_2018_pt_generated.dbc @@ -67,11 +67,11 @@ NS_ : BS_: -BU_: XXX DSU HCU EPS IPAS +BU_: XXX DSU HCU EPS IPAS CGW BO_ 36 KINEMATICS: 8 XXX - SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX - SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX BO_ 37 STEER_ANGLE_SENSOR: 8 XXX @@ -91,8 +91,8 @@ BO_ 170 WHEEL_SPEEDS: 8 XXX BO_ 180 SPEED: 8 XXX SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 353 DSU_SPEED: 8 XXX SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX @@ -103,6 +103,7 @@ BO_ 466 PCM_CRUISE: 8 XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 467 PCM_CRUISE_2: 8 XXX @@ -125,10 +126,19 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 643 PRE_COLLISION: 8 XXX +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX BO_ 740 STEERING_LKA: 5 XXX SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX @@ -154,6 +164,18 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + BO_ 921 PCM_CRUISE_SM: 8 XXX SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX @@ -162,6 +184,7 @@ BO_ 921 PCM_CRUISE_SM: 8 XXX BO_ 951 ESP_CONTROL: 8 ESP SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX BO_ 1041 ACC_HUD: 8 DSU @@ -186,7 +209,41 @@ BO_ 1042 LKAS_HUD: 8 XXX SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX -BO_ 1553 UI_SEETING: 8 XXX +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX BO_ 1556 STEERING_LEVERS: 8 XXX @@ -256,6 +313,9 @@ CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; @@ -279,6 +339,7 @@ VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; @@ -288,9 +349,9 @@ VAL_ 1553 UNITS 1 "km" 2 "miles"; VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; -VAL_ 1161 SPLSGN2 15 "conditional blank" 5 "rain" 0 "none"; -VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; -VAL_ 1162 SPLSGN3 15 "conditional blank" 5 "rain" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; @@ -304,15 +365,19 @@ BO_ 550 BRAKE_MODULE: 8 XXX SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX +BO_ 581 GAS_PEDAL_ALT: 5 XXX + SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX + BO_ 705 GAS_PEDAL: 8 XXX SG_ GAS_RELEASED : 3|1@0+ (1,0) [0|1] "" XXX SG_ GAS_PEDAL : 55|8@0+ (0.005,0) [0|1] "" XXX BO_ 608 STEER_TORQUE_SENSOR: 8 XXX - SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (0.77,0) [-20000|20000] "" XXX SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + SG_ STEER_ANGLE : 31|16@0- (0.0573,0) [-500|500] "" XXX BO_ 610 EPS_STATUS: 5 EPS SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX @@ -323,11 +388,14 @@ BO_ 610 EPS_STATUS: 5 EPS BO_ 956 GEAR_PACKET: 8 XXX SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX -BO_ 1009 PCM_CRUISE_3: 8 XXX +BO_ 1009 PCM_CRUISE_ALT: 8 XXX SG_ MAIN_ON : 13|1@0+ (1,0) [0|3] "" XXX SG_ CRUISE_STATE : 10|1@0+ (1,0) [0|1] "" XXX SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX +BO_ 1599 LIGHT_STALK_ISH: 8 SCM + SG_ AUTO_HIGH_BEAM : 19|1@0+ (1,0) [0|1] "" XXX + CM_ SG_ 550 BRAKE_PRESSURE "seems prop to pedal force"; CM_ SG_ 550 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; diff --git a/opendbc/lexus_is_hybrid_2017_pt_generated.dbc b/opendbc/lexus_is_hybrid_2017_pt_generated.dbc deleted file mode 100644 index e94824670de740..00000000000000 --- a/opendbc/lexus_is_hybrid_2017_pt_generated.dbc +++ /dev/null @@ -1,331 +0,0 @@ -CM_ "AUTOGENERATED FILE, DO NOT EDIT" - - -CM_ "Imported file _comma.dbc starts here" -BO_ 359 STEERING_IPAS_COMMA: 8 IPAS - SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX - SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX - SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX - SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -CM BO_ STEERING_IPAS_COMMA "Copy of msg 614 so we can do angle control while the Park Assist ECU is connected (Panda spoofs 614 with 359 on connector J70). Note that addresses 0x266 and 0x167 are checksum-invariant"; - - BO_ 512 GAS_COMMAND: 6 EON - SG_ GAS_COMMAND : 7|16@0+ (0.0244140625,0) [0|1] "" INTERCEPTOR - SG_ GAS_COMMAND2 : 23|16@0+ (0.0244140625,-11.962890625) [0|1] "" INTERCEPTOR - SG_ ENABLE : 39|1@0+ (1,0) [0|1] "" INTERCEPTOR - SG_ CHECKSUM : 47|8@0+ (1,0) [0|3] "" INTERCEPTOR - - BO_ 513 GAS_SENSOR: 6 INTERCEPTOR - SG_ INTERCEPTOR_GAS : 7|16@0+ (0.0244140625,0) [0|1] "" EON - SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.0244140625,-11.962890625) [0|1] "" EON - SG_ STATE : 39|8@0+ (1,0) [0|255] "" EON - SG_ CHECKSUM : 47|8@0+ (1,0) [0|3] "" EON - - VAL_ 513 STATE 5 "FAULT_TIMEOUT" 4 "FAULT_STARTUP" 3 "FAULT_SCE" 2 "FAULT_SEND" 1 "FAULT_BAD_CHECKSUM" 0 "NO_FAULT" ; - - -CM_ "Imported file _toyota_2017.dbc starts here" -VERSION "" - - -NS_ : - NS_DESC_ - CM_ - BA_DEF_ - BA_ - VAL_ - CAT_DEF_ - CAT_ - FILTER - BA_DEF_DEF_ - EV_DATA_ - ENVVAR_DATA_ - SGTYPE_ - SGTYPE_VAL_ - BA_DEF_SGTYPE_ - BA_SGTYPE_ - SIG_TYPE_REF_ - VAL_TABLE_ - SIG_GROUP_ - SIG_VALTYPE_ - SIGTYPE_VALTYPE_ - BO_TX_BU_ - BA_DEF_REL_ - BA_REL_ - BA_DEF_DEF_REL_ - BU_SG_REL_ - BU_EV_REL_ - BU_BO_REL_ - SG_MUL_VAL_ - -BS_: - -BU_: XXX DSU HCU EPS IPAS - -BO_ 36 KINEMATICS: 8 XXX - SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX - SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX - SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX - -BO_ 37 STEER_ANGLE_SENSOR: 8 XXX - SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX - SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX - SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX - -BO_ 166 BRAKE: 8 XXX - SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX - SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX - -BO_ 170 WHEEL_SPEEDS: 8 XXX - SG_ WHEEL_SPEED_FR : 7|16@0+ (0.01,-67.67) [0|250] "kph" XXX - SG_ WHEEL_SPEED_FL : 23|16@0+ (0.01,-67.67) [0|250] "kph" XXX - SG_ WHEEL_SPEED_RR : 39|16@0+ (0.01,-67.67) [0|250] "kph" XXX - SG_ WHEEL_SPEED_RL : 55|16@0+ (0.01,-67.67) [0|250] "kph" XXX - -BO_ 180 SPEED: 8 XXX - SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX - -BO_ 466 PCM_CRUISE: 8 XXX - SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX - SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX - SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX - SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX - SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 467 PCM_CRUISE_2: 8 XXX - SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX - SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 552 ACCELEROMETER: 8 XXX - SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX - SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX - -BO_ 560 BRAKE_MODULE2: 7 XXX - SG_ BRAKE_PRESSED : 26|1@0+ (1,0) [0|1] "" XXX - -BO_ 614 STEERING_IPAS: 8 IPAS - SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX - SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX - SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX - SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 643 PRE_COLLISION: 8 XXX - -BO_ 740 STEERING_LKA: 5 XXX - SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX - SG_ STEER_REQUEST : 0|1@0+ (1,0) [0|1] "" XXX - SG_ COUNTER : 6|6@0+ (1,0) [0|63] "" XXX - SG_ SET_ME_1 : 7|1@0+ (1,0) [0|1] "" XXX - SG_ STEER_TORQUE_CMD : 15|16@0- (1,0) [0|65535] "" XXX - SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX - -BO_ 742 LEAD_INFO: 8 DSU - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" HCU - SG_ LEAD_REL_SPEED : 23|12@0- (0.025,0) [-100|100] "m/s" HCU - SG_ LEAD_LONG_DIST : 7|13@0+ (0.05,0) [0|300] "m" HCU - -BO_ 835 ACC_CONTROL: 8 DSU - SG_ ACCEL_CMD : 7|16@0- (0.001,0) [-20|20] "m/s2" HCU - SG_ SET_ME_X63 : 23|8@0+ (1,0) [0|255] "" HCU - SG_ SET_ME_1 : 30|1@0+ (1,0) [0|1] "" HCU - SG_ RELEASE_STANDSTILL : 31|1@0+ (1,0) [0|1] "" HCU - SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 921 PCM_CRUISE_SM: 8 XXX - SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX - SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX - SG_ DISTANCE_LINES : 14|2@0+ (1,0) [0|3] "" XXX - SG_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX - -BO_ 951 ESP_CONTROL: 8 ESP - SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX - SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX - -BO_ 1041 ACC_HUD: 8 DSU - SG_ FCW : 4|1@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X20 : 15|8@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X10 : 39|8@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X80 : 55|8@0+ (1,0) [0|1] "" XXX - -BO_ 1042 LKAS_HUD: 8 XXX - SG_ BARRIERS : 1|2@0+ (1,0) [0|3] "" XXX - SG_ RIGHT_LINE : 3|2@0+ (1,0) [0|3] "" XXX - SG_ LEFT_LINE : 5|2@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_X01 : 7|2@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_X01_2 : 11|2@0+ (1,0) [0|3] "" XXX - SG_ LDA_ALERT : 9|2@0+ (1,0) [0|3] "" XXX - SG_ TWO_BEEPS : 12|1@0+ (1,0) [0|1] "" XXX - SG_ ADJUSTING_CAMERA : 13|1@0+ (1,0) [0|1] "" XXX - SG_ LDA_MALFUNCTION : 15|1@0+ (1,0) [0|1] "" XXX - SG_ REPEATED_BEEPS : 32|1@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X0C : 23|8@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X2C : 47|8@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX - -BO_ 1553 UI_SEETING: 8 XXX - SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX - -BO_ 1556 STEERING_LEVERS: 8 XXX - SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX - -BO_ 1568 SEATS_DOORS: 8 XXX - SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_FL : 45|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_RL : 42|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_RR : 43|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_FR : 44|1@0+ (1,0) [0|1] "" XXX - -BO_ 1570 LIGHT_STALK: 8 SCM - SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX - -BO_ 1161 RSA1: 8 FCM - SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX - SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX - SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX - SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX - SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX - SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX - SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX - SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX - SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX - SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX - SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX - SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX - SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX - -BO_ 1162 RSA2: 8 FCM - SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX - SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX - SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX - SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX - SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX - SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX - SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX - SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX - SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX - SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX - SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX - SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX - SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX - SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX - -BO_ 1163 RSA3: 8 FCM - SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX - SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX - SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX - SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX - SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX - SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX - SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX - SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX - SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX - -CM_ SG_ 36 ACCEL_Y "unit is tbd"; -CM_ SG_ 36 YAW_RATE "verify"; -CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; -CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; -CM_ SG_ 37 STEER_RATE "factor is tbd"; -CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors"; -CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; -CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; -CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; -CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; -CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; -CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; -CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; -CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; -CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; -CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; -CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; -CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; -CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" -CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; -CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; -CM_ SG_ 1163 TSREQPD "always 1"; -CM_ SG_ 1163 TSRMSW "always 1"; -CM_ SG_ 1163 OTSGNNTM "always 3"; -CM_ SG_ 1163 NTLVLSPD "always 3"; -CM_ SG_ 1163 OVSPNTM "always 3"; -CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; -CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; -CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; -CM_ SG_ 1163 TSRSPU "always 1"; - -VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; -VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; -VAL_ 614 STATE 3 "enabled" 1 "disabled"; -VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; -VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; -VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; -VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; -VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; -VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none"; -VAL_ 1553 UNITS 1 "km" 2 "miles"; -VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; -VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; -VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; -VAL_ 1161 SPLSGN2 15 "conditional blank" 5 "rain" 0 "none"; -VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; -VAL_ 1162 SPLSGN3 15 "conditional blank" 5 "rain" 0 "none"; - - -CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; - -CM_ "lexus_is_hybrid_2017_pt.dbc starts here" - - - -BO_ 581 GAS_PEDAL: 5 XXX - SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX - -BO_ 550 BRAKE_MODULE: 8 XXX - SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX - SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX - SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX - -BO_ 608 STEER_TORQUE_SENSOR: 8 XXX - SG_ STEER_TORQUE_EPS : 47|16@0- (0.66,0) [-20000|20000] "" XXX - SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX - SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 610 EPS_STATUS: 5 EPS - SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX - SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX - SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX - SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX - -BO_ 956 GEAR_PACKET: 8 XXX - SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX - -BO_ 1009 PCM_CRUISE_ISH: 8 XXX - SG_ MAIN_ON : 13|1@0+ (1,0) [0|3] "" XXX - SG_ CRUISE_STATE : 10|1@0+ (1,0) [0|1] "" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX - -BO_ 1599 LIGHT_STALK_ISH: 8 SCM - SG_ AUTO_HIGH_BEAM : 19|1@0+ (1,0) [0|1] "" XXX - -CM_ SG_ 550 BRAKE_PRESSURE "seems prop to pedal force"; -CM_ SG_ 550 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; -CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; -CM_ SG_ 1009 SET_SPEED "units seem to be whatever the car is set to"; -VAL_ 956 GEAR 0 "D" 1 "S" 8 "N" 16 "R" 32 "P"; -VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; -VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; diff --git a/opendbc/lexus_rx_350_2016_pt_generated.dbc b/opendbc/lexus_rx_350_2016_pt_generated.dbc new file mode 100644 index 00000000000000..2370835ae36b0c --- /dev/null +++ b/opendbc/lexus_rx_350_2016_pt_generated.dbc @@ -0,0 +1,396 @@ +CM_ "AUTOGENERATED FILE, DO NOT EDIT" + + +CM_ "Imported file _comma.dbc starts here" +BO_ 359 STEERING_IPAS_COMMA: 8 IPAS + SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX + SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX + SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +CM BO_ STEERING_IPAS_COMMA "Copy of msg 614 so we can do angle control while the Park Assist ECU is connected (Panda spoofs 614 with 359 on connector J70). Note that addresses 0x266 and 0x167 are checksum-invariant"; + + BO_ 512 GAS_COMMAND: 6 EON + SG_ GAS_COMMAND : 7|16@0+ (0.159375,-75.555) [0|1] "" INTERCEPTOR + SG_ GAS_COMMAND2 : 23|16@0+ (0.159375,-151.111) [0|1] "" INTERCEPTOR + SG_ ENABLE : 39|1@0+ (1,0) [0|1] "" INTERCEPTOR + SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" INTERCEPTOR + SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" INTERCEPTOR + + BO_ 513 GAS_SENSOR: 6 INTERCEPTOR + SG_ INTERCEPTOR_GAS : 7|16@0+ (0.159375,-75.555) [0|1] "" EON + SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.159375,-151.111) [0|1] "" EON + SG_ STATE : 39|4@0+ (1,0) [0|15] "" EON + SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" EON + SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" EON + + VAL_ 513 STATE 5 "FAULT_TIMEOUT" 4 "FAULT_STARTUP" 3 "FAULT_SCE" 2 "FAULT_SEND" 1 "FAULT_BAD_CHECKSUM" 0 "NO_FAULT" ; + + +CM_ "Imported file _toyota_2017.dbc starts here" +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX DSU HCU EPS IPAS CGW + +BO_ 36 KINEMATICS: 8 XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX + SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX + +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + +BO_ 166 BRAKE: 8 XXX + SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX + SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX + +BO_ 170 WHEEL_SPEEDS: 8 XXX + SG_ WHEEL_SPEED_FR : 7|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_FL : 23|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_RR : 39|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_RL : 55|16@0+ (0.01,-67.67) [0|250] "kph" XXX + +BO_ 180 SPEED: 8 XXX + SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX + SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 353 DSU_SPEED: 8 XXX + SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX + +BO_ 466 PCM_CRUISE: 8 XXX + SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX + SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX + SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 552 ACCELEROMETER: 8 XXX + SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX + SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX + +BO_ 560 BRAKE_MODULE2: 7 XXX + SG_ BRAKE_PRESSED : 26|1@0+ (1,0) [0|1] "" XXX + +BO_ 614 STEERING_IPAS: 8 IPAS + SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX + SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX + SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX + +BO_ 740 STEERING_LKA: 5 XXX + SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX + SG_ STEER_REQUEST : 0|1@0+ (1,0) [0|1] "" XXX + SG_ COUNTER : 6|6@0+ (1,0) [0|63] "" XXX + SG_ SET_ME_1 : 7|1@0+ (1,0) [0|1] "" XXX + SG_ STEER_TORQUE_CMD : 15|16@0- (1,0) [0|65535] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 742 LEAD_INFO: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" HCU + SG_ LEAD_REL_SPEED : 23|12@0- (0.025,0) [-100|100] "m/s" HCU + SG_ LEAD_LONG_DIST : 7|13@0+ (0.05,0) [0|300] "m" HCU + +BO_ 835 ACC_CONTROL: 8 DSU + SG_ ACCEL_CMD : 7|16@0- (0.001,0) [-20|20] "m/s2" HCU + SG_ SET_ME_X01 : 23|2@0+ (1,0) [0|3] "" HCU + SG_ DISTANCE : 20|1@0+ (1,0) [0|1] "" XXX + SG_ MINI_CAR : 21|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X3 : 19|4@0+ (1,0) [0|15] "" XXX + SG_ SET_ME_1 : 30|1@0+ (1,0) [0|1] "" HCU + SG_ RELEASE_STANDSTILL : 31|1@0+ (1,0) [0|1] "" HCU + SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + +BO_ 921 PCM_CRUISE_SM: 8 XXX + SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX + SG_ DISTANCE_LINES : 14|2@0+ (1,0) [0|3] "" XXX + SG_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX + +BO_ 951 ESP_CONTROL: 8 ESP + SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX + +BO_ 1041 ACC_HUD: 8 DSU + SG_ FCW : 4|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X20 : 15|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X10 : 39|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X80 : 55|8@0+ (1,0) [0|1] "" XXX + +BO_ 1042 LKAS_HUD: 8 XXX + SG_ BARRIERS : 1|2@0+ (1,0) [0|3] "" XXX + SG_ RIGHT_LINE : 3|2@0+ (1,0) [0|3] "" XXX + SG_ LEFT_LINE : 5|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X01 : 7|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X01_2 : 11|2@0+ (1,0) [0|3] "" XXX + SG_ LDA_ALERT : 9|2@0+ (1,0) [0|3] "" XXX + SG_ TWO_BEEPS : 12|1@0+ (1,0) [0|1] "" XXX + SG_ ADJUSTING_CAMERA : 13|1@0+ (1,0) [0|1] "" XXX + SG_ LDA_MALFUNCTION : 15|1@0+ (1,0) [0|1] "" XXX + SG_ REPEATED_BEEPS : 32|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X0C : 23|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X2C : 47|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX + +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX + SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX + +BO_ 1568 SEATS_DOORS: 8 XXX + SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FL : 45|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RL : 42|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RR : 43|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FR : 44|1@0+ (1,0) [0|1] "" XXX + +BO_ 1570 LIGHT_STALK: 8 SCM + SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + +CM_ SG_ 36 ACCEL_Y "unit is tbd"; +CM_ SG_ 36 YAW_RATE "verify"; +CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +CM_ SG_ 37 STEER_RATE "factor is tbd"; +CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors"; +CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; +CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; +CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; +CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; +CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; +CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; +CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; +CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; +CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; +VAL_ 614 STATE 3 "enabled" 1 "disabled"; +VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; +VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; +VAL_ 1042 RIGHT_LINE 3 "orange" 2 "faded" 1 "solid" 0 "none"; +VAL_ 1042 LEFT_LINE 3 "orange" 2 "faded" 1 "solid" 0 "none"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; + + +CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; + +CM_ "lexus_rx_350_2016_pt.dbc starts here" + + + +BO_ 550 BRAKE_MODULE: 8 XXX + SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 608 STEER_TORQUE_SENSOR: 8 XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX + SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 610 EPS_STATUS: 5 EPS + SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX + SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX + SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 956 GEAR_PACKET: 8 XXX + SG_ SPORT_ON : 2|1@0+ (1,0) [0|1] "" XXX + SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX + SG_ ECON_ON : 40|1@0+ (1,0) [0|1] "" XXX + +BO_ 705 GAS_PEDAL: 8 XXX + SG_ GAS_PEDAL : 55|8@0+ (1,0) [0|255] "" XXX + + +CM_ SG_ 550 BRAKE_PRESSURE "seems prop to pedal force"; +CM_ SG_ 550 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; +CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; +VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled" ; +VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby" ; +VAL_ 956 SPORT_ON 0 "off" 1 "on" ; +VAL_ 956 GEAR 0 "D" 1 "S" 8 "N" 16 "R" 32 "P" ; +VAL_ 956 ECON_ON 0 "off" 1 "on" ; diff --git a/opendbc/lexus_rx_hybrid_2017_pt_generated.dbc b/opendbc/lexus_rx_hybrid_2017_pt_generated.dbc index acbd9bb1994210..ef9052b28133ee 100644 --- a/opendbc/lexus_rx_hybrid_2017_pt_generated.dbc +++ b/opendbc/lexus_rx_hybrid_2017_pt_generated.dbc @@ -67,11 +67,11 @@ NS_ : BS_: -BU_: XXX DSU HCU EPS IPAS +BU_: XXX DSU HCU EPS IPAS CGW BO_ 36 KINEMATICS: 8 XXX - SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX - SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX BO_ 37 STEER_ANGLE_SENSOR: 8 XXX @@ -91,8 +91,8 @@ BO_ 170 WHEEL_SPEEDS: 8 XXX BO_ 180 SPEED: 8 XXX SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 353 DSU_SPEED: 8 XXX SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX @@ -103,6 +103,7 @@ BO_ 466 PCM_CRUISE: 8 XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 467 PCM_CRUISE_2: 8 XXX @@ -125,10 +126,19 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 643 PRE_COLLISION: 8 XXX +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX BO_ 740 STEERING_LKA: 5 XXX SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX @@ -154,6 +164,18 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + BO_ 921 PCM_CRUISE_SM: 8 XXX SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX @@ -162,6 +184,7 @@ BO_ 921 PCM_CRUISE_SM: 8 XXX BO_ 951 ESP_CONTROL: 8 ESP SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX BO_ 1041 ACC_HUD: 8 DSU @@ -186,7 +209,41 @@ BO_ 1042 LKAS_HUD: 8 XXX SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX -BO_ 1553 UI_SEETING: 8 XXX +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX BO_ 1556 STEERING_LEVERS: 8 XXX @@ -256,6 +313,9 @@ CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; @@ -279,6 +339,7 @@ VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; @@ -288,9 +349,9 @@ VAL_ 1553 UNITS 1 "km" 2 "miles"; VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; -VAL_ 1161 SPLSGN2 15 "conditional blank" 5 "rain" 0 "none"; -VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; -VAL_ 1162 SPLSGN3 15 "conditional blank" 5 "rain" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/opendbc/luxgen_s5_2015.dbc b/opendbc/luxgen_s5_2015.dbc new file mode 100644 index 00000000000000..855e67bfeba9e5 --- /dev/null +++ b/opendbc/luxgen_s5_2015.dbc @@ -0,0 +1,153 @@ +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX + + +BO_ 928 EPB_STATUS: 8 XXX + SG_ EPB_BRAKE : 16|1@1+ (1,0) [0|3] "" XXX + +BO_ 1104 SEATBELT_STATUS: 8 XXX + SG_ DRIVER_SEAT_BELT_ONOFF : 21|1@0+ (1,0) [0|3] "" XXX + +BO_ 1056 BODY_ECU_STATUS: 8 XXX + SG_ DOOR_RL_STATUS : 18|1@0+ (1,0) [0|255] "" XXX + SG_ DOOR_FL_STATUS : 13|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_FR_STATUS : 12|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_RR_STATUS : 19|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_BACK_DOOR_STATUS : 22|1@0+ (1,0) [0|1] "" XXX + SG_ LEFT_SIGNAL_STATUS : 10|1@0+ (1,0) [0|1] "" XXX + SG_ RIGHT_SIGNAL_STATUS : 9|1@0+ (1,0) [0|1] "" XXX + +BO_ 832 GEAR_RPM_SPEED_STATUS: 8 XXX + SG_ TRANS_MODE : 7|5@1+ (1,0) [0|0] "" XXX + SG_ TRANS_GEAR_POS : 2|3@0+ (1,0) [0|1] "" XXX + SG_ ENGINE_RPM1 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ ENGINE_TEMP : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 821 THROTTLE_STATUS: 8 XXX + SG_ CRUSE_ONOFF : 2|1@0+ (1,0) [0|1] "on/off" XXX + SG_ CRUSE_ENABLED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ THROTTLE_PEDAL_POS : 32|8@1+ (1,0) [0|255] "" XXX + SG_ THROTTLE_POS : 24|8@1+ (1,0) [0|255] "" XXX + SG_ RPM : 48|8@1- (1,0) [0|65535] "" XXX + +BO_ 922 STEERING_ANGLE_STATUS: 8 XXX + SG_ STEER_ANGLE_9000 : 7|16@0- (1,0) [0|65535] "" XXX + +BO_ 906 WHEEL_SPEEDS: 8 XXX + SG_ SPEED_FR : 24|8@1+ (1,0) [0|255] "" XXX + SG_ ABS_UNDEF1 : 32|8@1+ (1,0) [0|255] "" XXX + SG_ SPEED_FL : 0|8@1+ (1,0) [0|255] "" XXX + +BO_ 848 ABS_WHEELS_STATUS: 8 XXX + SG_ NEW_SIGNAL_1 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_3 : 7|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_4 : 15|8@0+ (1,0) [0|255] "" XXX + +BO_ 1402 DASH_STATUS: 8 XXX + SG_ CAR_SPEED : 32|8@1+ (1,0) [0|255] "" XXX + SG_ DASH_INFO2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ DASH_INFO0 : 0|8@1+ (1,0) [0|255] "" XXX + SG_ DASH_INFO_2 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ DASH_INFO_3 : 31|8@0+ (1,0) [0|255] "" XXX + +BO_ 1306 _SPEEDX: 8 XXX + SG_ DASH_CAR_SPEED : 7|9@0+ (1,0) [0|255] "" XXX + +BO_ 1296 undefined: 8 XXX + +BO_ 790 ENGINE_DATA: 8 XXX + SG_ _X2 : 6|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_1 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_3 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_4 : 39|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_5 : 47|8@0+ (1,0) [0|255] "" XXX + +BO_ 1313 undefined: 8 XXX + +BO_ 1312 __trigger_every_range: 8 XXX + SG_ __SIGNAL_every_interval : 4|1@0+ (1,0) [0|1] "" XXX + +BO_ 896 undefined: 8 XXX + SG_ NEW_SIGNAL_1 : 32|4@1+ (1,0) [0|15] "" XXX + +BO_ 809 undefined: 8 XXX + +BO_ 864 BREAK_TCS_STATUS: 8 XXX + SG_ SPEED3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ TCS_ON_FF : 45|1@0+ (1,0) [0|1] "" XXX + SG_ XXXX1 : 63|8@0+ (1,0) [0|255] "" XXX + SG_ BRAKE_PRSSED : 42|1@0+ (1,0) [0|1] "" XXX + +BO_ 842 undefined: 8 XXX + +BO_ 880 WHEEL_RPM_STATUS: 8 XXX + SG_ WHEEL_RL_SPEED : 23|16@0+ (1,0) [0|255] "" XXX + SG_ WHEEL_FR_SPEED : 39|16@0+ (1,0) [0|255] "" XXX + SG_ WHEEL_FL_SPEED : 55|16@0+ (1,0) [0|255] "" XXX + SG_ WHEEL_RR_SPEED : 7|16@0- (1,0) [0|255] "" XXX + +BO_ 1040 CONSOLE_STATUS: 8 XXX + SG_ LEFT_SIGNAL_SWITCH : 1|1@0+ (1,0) [0|1] "" XXX + SG_ RIGHT_SIGNAL_SWITCH : 2|1@0+ (1,0) [0|1] "" XXX + SG_ HEAD_LIGHT_HANDLE_SWITCH : 3|1@0+ (1,0) [0|1] "" XXX + SG_ HID_LIGHT_SWITCH : 4|1@0+ (1,0) [0|1] "" XXX + SG_ YELLOW_WARN_TEMP_TRIGGER : 5|1@0+ (1,0) [0|1] "" XXX + SG_ HID_LIGHT_HANDLE_SWITCH : 6|1@0+ (1,0) [0|1] "" XXX + SG_ MIX_MODE : 7|1@0+ (1,0) [0|1] "" XXX + SG_ slider_rain_bar : 13|1@0+ (1,0) [0|1] "" XXX + SG_ temp_slider_rain_bar : 15|1@0+ (1,0) [0|1] "" XXX + SG_ temp_water_push : 11|1@0+ (1,0) [0|1] "" XXX + +BO_ 1120 HAVC_STATUS: 8 XXX + SG_ HAVC_TEMP : 32|8@1+ (1,0) [0|255] "" XXX + + +CM_ SG_ 1104 DRIVER_SEAT_BELT_ONOFF "0 - on , 1 = off"; +CM_ SG_ 1056 DOOR_RL_STATUS "04 - RL - open"; +CM_ SG_ 1056 DOOR_FL_STATUS "28 - FL open , 38 - FR"; +CM_ SG_ 1056 RIGHT_SIGNAL_STATUS "R,L shows at same time means hazard"; +CM_ SG_ 832 TRANS_MODE "AT - 85 / MT - 8D"; +CM_ SG_ 832 TRANS_GEAR_POS "R-7 , 0 - N"; +CM_ SG_ 821 CRUSE_ONOFF "Cruse Switch"; +CM_ SG_ 821 CRUSE_ENABLED "Cruse enabled"; +CM_ SG_ 821 THROTTLE_PEDAL_POS "Real Pedal Pos"; +CM_ SG_ 821 THROTTLE_POS "Throttle Pos for Cruse Mode"; +CM_ SG_ 906 ABS_UNDEF1 "ABS force"; +CM_ SG_ 906 SPEED_FL "used for car speed in dash board"; +CM_ SG_ 864 TCS_ON_FF "ON = 1, OFF =0"; diff --git a/opendbc/mazda_cx5_gt_2017.dbc b/opendbc/mazda_cx5_gt_2017.dbc index d0b84c22a3a9b2..971b136118d2bf 100644 --- a/opendbc/mazda_cx5_gt_2017.dbc +++ b/opendbc/mazda_cx5_gt_2017.dbc @@ -40,21 +40,21 @@ BO_ 117 STEER_RELATED: 8 XXX SG_ CTR : 7|8@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_1 : 48|1@0+ (1,0) [0|1] "" XXX SG_ NEW_SIGNAL_2 : 49|1@0+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_3 : 55|1@0+ (1,0) [0|63] "" XXX - SG_ NEW_SIGNAL_4 : 54|4@0+ (1,0) [0|31] "" XXX SG_ NEW_SIGNAL_5 : 50|1@0+ (1,0) [0|1] "" XXX - SG_ STEER_TORQUE : 19|12@0+ (1,0) [0|255] "" XXX - SG_ STEER_ANGLE_2 : 39|16@0+ (1,0) [0|131071] "" XXX + SG_ NEW_SIGNAL_4 : 54|4@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_3 : 55|1@0+ (1,0) [0|63] "" XXX + SG_ STEER_ANGLE_2 : 39|16@0+ (0.1,-1800) [0|131071] "" XXX + SG_ STEER_TORQUE : 19|12@0+ (1,-2000) [0|255] "" XXX BO_ 118 RPM_RELATED: 8 XXX SG_ CTR : 7|8@0+ (1,0) [0|127] "" XXX SG_ NEW_SIGNAL_2 : 19|12@0+ (1,0) [0|4095] "" XXX BO_ 514 ENGINE_DATA: 8 XXX - SG_ RPM : 7|16@0+ (1,0) [0|65535] "" XXX - SG_ CHKSUM : 56|8@1+ (1,0) [0|127] "" XXX - SG_ SPEED : 23|16@0+ (0.01,0) [0|32767] "KPH" XXX - SG_ PEDAL_GAS : 39|12@0+ (1,0) [0|255] "" XXX + SG_ PEDAL_GAS : 39|12@0+ (0.002778,0) [0|255] "%" XXX + SG_ CHKSUM : 63|8@0+ (1,0) [0|127] "" XXX + SG_ RPM : 7|16@0+ (0.25,0) [0|8500] "rpm" XXX + SG_ SPEED : 23|16@0+ (0.01,0) [0|32767] "kph" XXX BO_ 357 PEDALS: 8 XXX SG_ NEW_SIGNAL_6 : 31|4@0+ (1,0) [0|1] "" XXX @@ -71,28 +71,30 @@ BO_ 357 PEDALS: 8 XXX SG_ NO_BRAKE_2 : 15|1@0+ (1,0) [0|7] "" XXX BO_ 533 WHEEL_SPEEDS: 8 XXX - SG_ FL : 7|16@0+ (0.01,-100) [0|16383] "" XXX - SG_ RL : 39|16@0+ (0.01,-100) [0|15] "" XXX - SG_ RR : 55|16@0+ (0.01,-100) [0|65535] "" XXX - SG_ FR : 23|16@0+ (0.01,-100) [0|65535] "" XXX + SG_ FL : 7|16@0+ (0.01,-100) [0|16383] "kph" XXX + SG_ FR : 23|16@0+ (0.01,-100) [0|65535] "kph" XXX + SG_ RL : 39|16@0+ (0.01,-100) [0|15] "kph" XXX + SG_ RR : 55|16@0+ (0.01,-100) [0|65535] "kph" XXX BO_ 134 STEER2: 8 XXX - SG_ NEW_SIGNAL_2 : 48|3@1+ (1,0) [0|7] "" XXX SG_ CTR : 22|4@0+ (1,0) [0|7] "" XXX SG_ NEW_SIGNAL_4 : 23|1@0+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_5 : 18|3@0+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_7 : 24|3@1+ (1,0) [0|7] "" XXX SG_ CTR_2 : 28|3@1+ (1,0) [0|7] "" XXX - SG_ NEW_SIGNAL_1 : 63|2@0+ (1,0) [0|255] "" XXX + SG_ STEER_ANGLE_ROUGH : 26|11@0+ (1,-1000) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 18|3@0+ (1,0) [0|1] "" XXX SG_ STEER_ANGLE : 7|16@0+ (0.1,-1600) [-500|500] "deg" XXX - SG_ STEER_ANGLE_ROUGH : 39|8@0- (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_1 : 63|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_3 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 47|8@0+ (1,0) [0|7] "" XXX BO_ 576 STEER_TORQUE: 8 XXX - SG_ NEW_SIGNAL_2 : 39|8@0+ (1,0) [0|127] "" XXX - SG_ NEW_SIGNAL_1 : 20|4@1+ (1,0) [0|255] "" XXX - SG_ STEER_TORQUE_SENSOR : 7|16@0+ (0.5,-15000) [0|255] "" XXX + SG_ NEW_SIGNAL_1 : 23|4@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_3 : 47|1@0+ (1,0) [0|1] "" XXX - SG_ STEER_TORQUE_MOTOR : 46|20@0- (0.01,0) [-3000|3000] "deg/s" XXX + SG_ SENSOR1 : 39|8@0+ (1,-128) [0|127] "" XXX + SG_ STEER_TORQUE_MOTOR : 46|15@0- (0.1,0) [-3000|3000] "tbd" XXX + SG_ NEW_SIGNAL_2 : 62|4@0+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_4 : 15|8@0+ (1,0) [0|127] "" XXX + SG_ STEER_TORQUE_SENSOR : 7|8@0+ (1,-127) [-85|85] "" XXX BO_ 577 STEER_RATE: 8 XXX SG_ STEER_ANGLE_RATE : 23|16@0+ (0.25,-8192) [0|1] "deg/s" XXX @@ -119,6 +121,7 @@ BO_ 605 CAM_PEDESTRIAN: 8 XXX SG_ PED_BRAKE : 3|3@0+ (1,0) [0|7] "" XXX SG_ RST_CTR : 23|6@0+ (1,0) [0|63] "" XXX SG_ S1 : 29|4@0+ (1,0) [0|31] "" XXX + SG_ BRAKE_WARNING : 25|1@0+ (1,0) [0|1] "" XXX BO_ 578 CAM_LANETRACK: 8 XXX SG_ CHKSUM : 63|8@0+ (1,0) [0|255] "" XXX @@ -132,14 +135,15 @@ BO_ 578 CAM_LANETRACK: 8 XXX SG_ LINE1 : 3|10@0+ (1,-686) [0|1] "" XXX BO_ 579 CAM_LKAS: 8 XXX - SG_ LKAS_REQUEST : 3|12@0+ (1,-2048) [0|2048] "" XXX SG_ CTR : 7|4@0+ (1,0) [0|15] "" XXX SG_ ERR_BIT_1 : 16|1@0+ (1,0) [0|1] "" XXX SG_ CHKSUM : 63|8@0+ (1,0) [0|15] "" XXX SG_ LINE_NOT_VISIBLE : 19|1@0+ (1,0) [0|1] "" XXX - SG_ BIT_1 : 29|1@0+ (1,0) [0|1] "" XXX SG_ BIT_2 : 33|1@0+ (1,0) [0|1] "" XXX SG_ ERR_BIT_2 : 30|1@0+ (1,0) [0|1] "" XXX + SG_ BIT_1 : 29|1@0+ (1,0) [0|1] "" XXX + SG_ LDW : 23|1@0+ (1,0) [0|1] "" XXX + SG_ LKAS_REQUEST : 3|12@0+ (1,-2048) [0|2048] "" XXX BO_ 580 CAM_DISTANCE: 8 XXX SG_ S1 : 0|8@1+ (1,0) [0|127] "" XXX @@ -170,7 +174,17 @@ BO_ 863 CAM_STATUS: 8 XXX SG_ NEW_SIGNAL_6 : 0|3@1+ (1,0) [0|7] "" XXX SG_ FORWARD_COLLISION : 40|8@1+ (1,0) [0|7] "" XXX -BO_ 1157 CAM_Empty2: 8 XXX +BO_ 1157 CAM_SETTINGS: 8 XXX + SG_ NEW_SIGNAL_2 : 14|1@0+ (1,0) [0|1] "" XXX + SG_ SBS_WARNING_DISTANCE : 25|2@0+ (1,0) [0|127] "" XXX + SG_ SBS_SCBC : 28|2@0+ (1,0) [0|7] "" XXX + SG_ LKAS_ASSIT_TIMING : 13|1@0+ (1,0) [0|1] "" XXX + SG_ LKAS_SENSETIVITY : 10|1@0+ (1,0) [0|1] "" XXX + SG_ ILKAS_NTERVENTION_ON2 : 17|1@0+ (1,0) [0|255] "" XXX + SG_ LANEE_DEPARTURE_ALERT : 16|2@0+ (1,0) [0|1] "" XXX + SG_ LKAS_INERVENTION_ON1 : 15|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_1 : 12|1@0+ (1,0) [0|7] "" XXX + SG_ WARNING : 11|1@0+ (1,0) [0|1] "" XXX BO_ 1160 CAM_Empty3: 8 XXX SG_ NEW_SIGNAL_1 : 47|24@0+ (1,0) [0|16777215] "" XXX @@ -189,6 +203,8 @@ BO_ 1088 CAM_LANEINFO: 8 XXX SG_ BIT1 : 6|1@0+ (1,0) [0|65535] "" XXX SG_ LINE_NOT_VISIBLE : 1|1@0+ (1,0) [0|1] "" XXX SG_ LINE_VISIBLE : 0|1@0+ (1,0) [0|3] "" XXX + SG_ LDW_WARN_RL : 58|1@0+ (1,0) [0|1] "" XXX + SG_ LDW_WARN_LL : 57|1@0+ (1,0) [0|1] "" XXX BO_ 1479 NEW_MSG_470: 8 XXX @@ -199,7 +215,6 @@ BO_ 1446 NEW_MSG_a600: 8 XXX BO_ 1416 MSG_18: 8 XXX BO_ 1086 DOORS: 8 XXX - SG_ DOOR_OPEN : 30|1@0+ (1,0) [0|255] "" XXX SG_ LEFTGATE : 32|1@0+ (1,0) [0|1] "" XXX SG_ NEW_SIGNAL_3 : 53|1@0+ (1,0) [0|255] "" XXX SG_ KEYFOB_HORN : 2|1@0+ (1,0) [0|1] "" XXX @@ -211,6 +226,7 @@ BO_ 1086 DOORS: 8 XXX SG_ BL : 35|1@0+ (1,0) [0|1] "" XXX SG_ FR : 36|1@0+ (1,0) [0|1] "" XXX SG_ FL : 37|1@0+ (1,0) [0|255] "" XXX + SG_ DOORS_UNLOCKED : 30|1@0+ (1,0) [0|255] "" XXX BO_ 977 TWO_STATES: 8 XXX SG_ NEW_SIGNAL_1 : 50|1@1+ (1,0) [0|7] "" XXX @@ -232,6 +248,7 @@ BO_ 1085 MSG_12: 8 XXX BO_ 159 MSG_11: 8 XXX SG_ NEW_SIGNAL_1 : 50|4@1+ (1,0) [0|15] "" XXX + SG_ INCREASEING : 39|8@0+ (1,0) [0|255] "" XXX BO_ 1278 NEW_MSG_3: 8 XXX SG_ NEW_SIGNAL_2 : 23|8@0+ (1,0) [0|255] "" XXX @@ -266,15 +283,18 @@ BO_ 1078 HVAC: 8 XXX SG_ NEW_SIGNAL_3 : 23|1@0+ (1,0) [0|65535] "" XXX SG_ NEW_SIGNAL_4 : 56|5@0+ (1,0) [0|255] "" XXX -BO_ 1056 NEW_MSG_13: 8 XXX - SG_ BIG_COUNTER_MAYBE : 55|16@0+ (1,0) [0|255] "" XXX +BO_ 1056 CHECK_AND_TEMP: 8 XXX SG_ NEW_SIGNAL_1 : 29|6@0+ (1,0) [0|255] "" XXX SG_ counter_or_GEAR : 15|8@0+ (1,0) [0|255] "" XXX - SG_ INCREASING : 7|8@0+ (1,0) [0|255] "" XXX SG_ CTR : 23|8@0+ (1,0) [0|255] "" XXX SG_ STANDSTILL : 32|1@0+ (1,0) [0|255] "" XXX + SG_ COOLANT_TEMP : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LOW_ENGINE_OIL_PRESSURE : 43|1@0+ (1,0) [0|1] "" XXX + SG_ CHECK_FUEL_CAP : 40|1@0+ (1,0) [0|1] "" XXX + SG_ CHARGING_SYSTEM_MALFUNCTION : 38|1@0+ (1,0) [0|1] "" XXX + SG_ OUTDOOR_TEMP : 63|8@0+ (0.25,-63) [0|255] "cel" XXX -BO_ 1045 MOVING: 8 XXX +BO_ 1045 TRACTION: 8 XXX SG_ NEW_SIGNAL_2 : 20|1@0+ (1,0) [0|3] "" XXX SG_ CTR2 : 19|4@0+ (1,0) [0|31] "" XXX SG_ CTR3 : 8|4@1+ (1,0) [0|15] "" XXX @@ -282,6 +302,12 @@ BO_ 1045 MOVING: 8 XXX SG_ CTR1 : 53|6@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_1 : 54|1@0+ (1,0) [0|1] "" XXX SG_ BRAKE : 55|1@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_WARNING : 2|1@0+ (1,0) [0|1] "" XXX + SG_ ABS_MALFUNCTION : 1|2@0+ (1,0) [0|3] "" XXX + SG_ DSC_OFF : 3|1@0+ (1,0) [0|1] "" XXX + SG_ TCS_DCS_MALFUNCTION : 6|2@0+ (1,0) [0|3] "" XXX + SG_ LOUD_BEEP : 28|1@0+ (1,0) [0|1] "" XXX + SG_ TPMS_WARNING_DOUBLE_BLINK : 31|1@0+ (1,0) [0|1] "" XXX BO_ 1034 MSG_07: 8 XXX SG_ NEW_SIGNAL_1 : 6|3@0+ (1,0) [0|3] "" XXX @@ -315,17 +341,17 @@ BO_ 867 NEW_MSG_17: 8 XXX BO_ 130 STEER: 8 XXX SG_ NEW_SIGNAL_5 : 55|8@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_6 : 63|8@0+ (1,0) [0|255] "" XXX - SG_ CTR : 47|8@0+ (1,0) [0|255] "" XXX - SG_ CTR_2 : 35|4@0+ (1,0) [0|255] "" XXX + SG_ CTR : 47|4@0+ (1,0) [0|255] "" XXX SG_ STEER_ANGLE : 23|16@0+ (0.05,-1600) [500|-500] "deg" XXX + SG_ CHKSUM_MAYBE : 39|8@0+ (1,0) [0|255] "" XXX -BO_ 120 NEW_MSG_18: 8 XXX +BO_ 120 BRAKE: 8 XXX SG_ NEW_SIGNAL_1 : 7|8@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_2 : 15|8@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_3 : 23|8@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_4 : 31|8@0+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_5 : 39|8@0+ (1,0) [0|255] "" XXX SG_ CTR : 55|8@0+ (1,0) [0|255] "" XXX + SG_ BRAKE_PRESSURE : 39|8@0+ (1,0) [0|255] "" XXX BO_ 304 GEAR_RELATED: 8 XXX SG_ NEW_SIGNAL_1 : 55|8@0+ (1,0) [0|255] "" XXX @@ -397,22 +423,24 @@ BO_ 154 BLINK_INFO: 8 XXX SG_ REAR_WIPER_ON : 0|1@0+ (1,0) [0|1] "" XXX SG_ WIPER_LO : 33|1@1+ (1,0) [0|31] "" XXX SG_ WIPER_HI : 34|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_BEAMS : 5|2@0+ (1,0) [0|3] "" XXX + SG_ HIGH_BEAMS : 7|2@0+ (1,0) [0|3] "" XXX + SG_ LBEAM1 : 17|1@0+ (1,0) [0|1] "" XXX + SG_ LBEAM2 : 50|1@0+ (1,0) [0|1] "" XXX + SG_ LBEAM3 : 60|1@0+ (1,0) [0|1] "" XXX BO_ 145 TURN_SWITCH: 8 XXX - SG_ NEW_SIGNAL_1 : 37|1@0+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_2 : 36|1@0+ (1,0) [0|3] "" XXX - SG_ TURN : 38|1@0+ (1,0) [0|3] "" XXX - SG_ TURN_LEFT_SWITCH : 13|1@0+ (1,0) [0|255] "" XXX - SG_ TURN_RIGHT_SWITCH : 12|1@1+ (1,0) [0|3] "" XXX SG_ HAZARD : 10|1@0+ (1,0) [0|1] "" XXX + SG_ TURN_RIGHT_SWITCH : 12|1@0+ (1,0) [0|3] "" XXX + SG_ TURN_LEFT_SWITCH : 13|1@0+ (1,0) [0|255] "" XXX SG_ CTR : 27|4@0+ (1,0) [0|255] "" XXX + SG_ CHKSUM : 39|8@0+ (1,0) [0|15] "" XXX BO_ 80 MSG_04: 8 XXX SG_ NEW_SIGNAL_1 : 25|1@0+ (1,0) [0|1] "" XXX SG_ SIGNAL : 24|1@0+ (1,0) [0|1] "" XXX BO_ 978 MSG_03: 8 XXX - SG_ NEW_SIGNAL_1 : 7|8@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_2 : 15|8@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_3 : 23|8@0+ (1,0) [0|1] "" XXX SG_ NEW_SIGNAL_4 : 31|8@0+ (1,0) [0|255] "" XXX @@ -420,6 +448,7 @@ BO_ 978 MSG_03: 8 XXX SG_ NEW_SIGNAL_6 : 47|8@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_7 : 55|8@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_8 : 63|8@0+ (1,0) [0|255] "" XXX + SG_ CTR : 1|2@0+ (1,0) [0|255] "" XXX BO_ 607 NEW_MSG_25: 8 XXX @@ -539,6 +568,8 @@ BO_ 540 CRZ_CTRL: 8 XXX SG_ ACC_GAS_MAYBE : 23|1@0+ (1,0) [0|31] "" XXX SG_ ACC_GAS_MAYBE2 : 29|1@0+ (1,0) [0|1] "" XXX SG_ CRZ_ACTIVE : 3|1@0+ (1,0) [0|1] "" XXX + SG_ HANDS_OFF_STEERING : 48|1@0+ (1,0) [0|1] "" XXX + SG_ HANDS_ON_STEER_WARN : 59|4@0+ (1,0) [0|255] "" XXX BO_ 539 CRZ_INFO: 8 XXX SG_ NEW_SIGNAL_1 : 17|1@0+ (1,0) [0|255] "" XXX @@ -546,10 +577,10 @@ BO_ 539 CRZ_INFO: 8 XXX SG_ NEW_SIGNAL_5 : 34|1@0+ (1,0) [0|1] "" XXX SG_ NEW_SIGNAL_7 : 47|1@0+ (1,0) [0|255] "" XXX SG_ CTR1 : 55|8@0+ (1,0) [0|255] "" XXX - SG_ CTR2 : 63|8@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_3 : 37|1@0+ (1,0) [0|255] "" XXX SG_ ACC_ACTIVE : 33|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_CMD : 31|10@0- (1,0) [0|1] "" XXX + SG_ CHKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 121 EPB: 8 XXX SG_ NEW_SIGNAL_1 : 4|4@0+ (1,0) [0|255] "" XXX @@ -585,10 +616,10 @@ BO_ 1435 2017_8: 8 XXX BO_ 253 NEW_MSG_7: 8 XXX SG_ NEW_SIGNAL_1 : 16|1@0+ (1,0) [0|65535] "" XXX - SG_ NEW_SIGNAL_2 : 41|1@0+ (1,0) [0|255] "" XXX SG_ CTR : 23|4@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 41|1@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_3 : 55|8@0+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_4 : 61|1@0+ (1,0) [0|255] "" XXX + SG_ CRZ_NOT_ACTIVE : 61|1@0+ (1,0) [0|255] "" XXX BO_ 359 NEW_MSG_11: 8 XXX SG_ NEW_SIGNAL_1 : 15|1@0+ (1,0) [0|255] "" XXX @@ -614,8 +645,10 @@ BO_ 512 NEW_MSG_30: 8 XXX SG_ NEW_SIGNAL_11 : 63|8@0+ (1,0) [0|255] "" XXX BO_ 515 MSG_01: 8 XXX - SG_ CTR : 39|8@0+ (1,0) [0|65535] "" XXX - SG_ CTR_2 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ CTR : 39|4@0+ (1,0) [0|65535] "" XXX + SG_ CHKSUM : 47|8@0+ (1,0) [0|255] "" XXX + SG_ START1 : 6|1@0+ (1,0) [0|1] "" XXX + SG_ START2 : 28|5@0+ (1,0) [0|255] "" XXX BO_ 529 NEW_MSG_36: 8 XXX SG_ NEW_SIGNAL_1 : 22|5@0+ (1,0) [0|65535] "" XXX @@ -684,11 +717,44 @@ BO_ 1272 MSG_17: 8 XXX BO_ 1425 MSG_19: 8 XXX +BO_ 70 MOB1: 8 XXX + SG_ NEW_SIGNAL_1 : 1|3@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 14|6@0+ (1,0) [0|127] "" XXX + SG_ NEW_SIGNAL_3 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_4 : 30|6@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_5 : 38|6@0+ (1,0) [0|7] "" XXX + +BO_ 64 MOB2: 8 XXX + SG_ NEW_SIGNAL_1 : 7|2@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 10|3@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_3 : 16|1@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_4 : 24|1@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_5 : 35|4@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_6 : 0|3@1+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_7 : 13|3@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_8 : 15|2@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_9 : 19|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_10 : 31|6@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_11 : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 1171 MOB3: 8 XXX + +BO_ 1248 MOB4: 8 XXX + CM_ SG_ 605 PED_BRAKE "3: no brake, 4: brake"; +CM_ SG_ 605 BRAKE_WARNING "Flashing brake warning and audible alert for potential forward collision"; +CM_ SG_ 1157 SBS_WARNING_DISTANCE "1 far, 2 mid, 3 near"; +CM_ SG_ 1157 SBS_SCBC "1 off, 2 on"; +CM_ SG_ 1157 LKAS_ASSIT_TIMING "1 at, 0 before"; +CM_ SG_ 1157 LKAS_SENSETIVITY "0 low, 1 high"; +CM_ SG_ 1157 LANEE_DEPARTURE_ALERT "1 off, 2 on"; +CM_ SG_ 1157 WARNING "1 Rare, 0 often"; CM_ SG_ 1088 LANE_LINES "0 LKAS disabled, 1 no lines, 2 two lines, 3 left line, 4 right line"; +CM_ SG_ 1045 ABS_MALFUNCTION "off: 0, solid: 1, slow blink: 2, fast blink: 3"; CM_ SG_ 157 CAN_OFF "Disengage Cruise if enabled, if already disabled TURN it OFF "; CM_ SG_ 552 GEAR "0 P/N, 12 R, 2 D M1, 4 M2, 14 Shift"; CM_ SG_ 552 MORE_GEAR ""; +CM_ SG_ 540 HANDS_ON_STEER_WARN "0 no warning, b warning"; diff --git a/opendbc/nissan_2017.dbc b/opendbc/nissan_2017.dbc new file mode 100644 index 00000000000000..1d03b7ab5f72d9 --- /dev/null +++ b/opendbc/nissan_2017.dbc @@ -0,0 +1,184 @@ +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX + + +BO_ 644 Speed_1: 8 XXX + SG_ Speed_FR : 7|16@0+ (0.0118,0) [0|65535] "" XXX + SG_ Speed_FL : 23|16@0+ (0.0118,0) [0|65535] "" XXX + SG_ Speed_Vehicle : 39|16@0+ (0.0245,0) [0|65535] "" XXX + +BO_ 645 WheelspeedRear: 8 XXX + SG_ RR : 7|16@0+ (0.00555,0) [0|65535] "KPH" XXX + SG_ RL : 23|16@0+ (0.00555,0) [0|65535] "KPH" XXX + +BO_ 768 STEER_TORQUE: 8 XXX + SG_ STEERING_TOURQUE : 0|7@1+ (1,0) [0|127] "" XXX + +BO_ 459 Maybe_RegenBraking: 8 XXX + +BO_ 372 Maybe_Gear_Selector: 8 XXX + SG_ Counter : 32|4@1+ (1,0) [0|15] "" XXX + +BO_ 374 Maybe_Motor_RPM_or_Speed: 8 XXX + SG_ Counter : 48|4@1+ (1,0) [0|15] "" XXX + +BO_ 460 Maybe_Brake_Related: 8 XXX + +BO_ 2 SteeringWheel: 8 XXX + SG_ Steering_RateChange : 23|8@0+ (1,0) [0|255] "" XXX + SG_ Always_07 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ Steering_Angle : 0|16@1- (-0.1,0) [0|65535] "" XXX + +BO_ 384 Maybe_PowerInfo: 8 XXX + SG_ Unknown_Timer_PowerInfo : 48|4@1+ (1,0) [0|15] "" XXX + SG_ EnginePower : 27|12@0- (1,0) [0|1] "" XXX + SG_ RequestedAccel : 23|12@0- (1,0) [0|4294967295] "" XXX + +BO_ 1107 Lights: 8 XXX + SG_ RIGHT_BLINKER : 12|1@0+ (1,0) [0|1] "" XXX + SG_ LEFT_BLINKER : 11|1@0+ (1,0) [0|1] "" XXX + SG_ _HEADLIGHTS : 5|1@0+ (1,0) [0|1] "" XXX + +BO_ 666 WheelspeedFront: 8 XXX + SG_ _FL_WHEELSPEED : 39|16@0+ (0.01014,0) [0|65535] "" XXX + SG_ FR : 7|16@0+ (0.00555,0) [0|65535] "KPH" XXX + SG_ FL : 23|16@0+ (0.00555,0) [0|65535] "KPH" XXX + +BO_ 398 NEW_MSG_2: 8 XXX + +BO_ 389 NEW_MSG_3: 8 XXX + SG_ NEW_SIGNAL_1 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 22|6@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_4 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_5 : 55|4@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_6 : 63|8@0+ (1,0) [0|127] "" XXX + SG_ COUNTER : 48|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 30|8@0- (1,0) [0|255] "" XXX + +BO_ 397 NEW_MSG_4: 8 XXX + SG_ NEW_SIGNAL_1 : 7|16@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_2 : 23|16@0+ (1,0) [0|32767] "" XXX + SG_ NEW_SIGNAL_3 : 39|16@0+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_4 : 55|16@0+ (1,0) [0|31] "" XXX + +BO_ 658 NEW_MSG_5: 8 XXX + SG_ NEW_SIGNAL_1 : 7|16@0+ (1,0) [0|255] "" XXX + +BO_ 855 NEW_MSG_6: 8 XXX + SG_ NEW_SIGNAL_1 : 7|8@0+ (1,0) [0|255] "" XXX + +BO_ 773 NEW_MSG_7: 8 XXX + SG_ NEW_SIGNAL_1 : 39|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 47|8@0+ (1,0) [0|255] "" XXX + +BO_ 851 SPEED_RELATED: 8 XXX + SG_ SPEED_RELATED : 7|16@0+ (0.01014,0) [0|65535] "" XXX + +BO_ 386 Accelerator: 8 XXX + SG_ Accelerator : 38|7@0+ (1,0) [0|127] "" XXX + +BO_ 347 ACCELSOMETHING: 8 XXX + SG_ PowerMaybe : 9|10@0+ (1,0) [0|1023] "" XXX + SG_ ACCELERATOR2 : 6|11@0+ (1,-800) [0|65535] "" XXX + +BO_ 346 ANOTHER_ACCEL: 8 XXX + SG_ ANOTHERACCEL : 23|10@0+ (1,0) [0|1023] "" XXX + SG_ Reverse_ACCEL : 25|10@0+ (1,0) [0|1023] "" XXX + +BO_ 348 FULLRANGEACCEL: 8 XXX + SG_ AccelFullRange : 47|10@0+ (1,0) [0|1023] "" XXX + SG_ Accel : 26|11@0+ (1,0) [0|2047] "" XXX + SG_ NEW_SIGNAL_1 : 7|8@0+ (1,0) [0|255] "" XXX + +BO_ 566 ANOTHERFULLRANGEACCEL: 8 XXX + SG_ ANOTHERFULLRANGEACCEL : 43|8@0+ (1,0) [0|1023] "" XXX + SG_ RPMORTORQUE : 31|8@0+ (1,0) [0|255] "" XXX + +BO_ 523 Yetyetanotheraccel: 8 XXX + SG_ ANOTHERREVERSEACCEL : 37|10@0+ (1,0) [0|1023] "" XXX + SG_ yetyetanotheraccel : 31|10@0+ (1,0) [0|255] "" XXX + +BO_ 779 ANOTHERRRFULLRANGEACCEL: 8 XXX + SG_ ANOTHERRRFULLRANGEACCEL : 47|8@0+ (1,0) [0|255] "" XXX + +BO_ 1108 Doors: 8 XXX + SG_ DOOR_CLOSED_RR : 40|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RR : 41|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_CLOSED_RL : 42|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RL : 43|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_CLOSED_FL : 44|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FL : 45|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_CLOSED_FR : 46|1@0+ (1,0) [0|3] "" XXX + SG_ DOOR_OPEN_FR : 47|1@0+ (1,0) [0|3] "" XXX + SG_ BOOT_OPEN : 55|1@0+ (1,0) [0|1] "" XXX + +BO_ 403 LKAS_OLD: 8 XXX + SG_ Checksum : 63|8@0+ (1,0) [0|255] "" XXX + SG_ Angle_2 : 32|13@0+ (1,-4000) [0|63] "" XXX + SG_ Counter : 48|4@1+ (1,0) [0|15] "" XXX + SG_ Angle_1 : 10|13@0+ (0.12,-480) [0|65535] "" XXX + SG_ Steering_Torque : 7|13@0+ (-1,4000) [0|65535] "" XXX + SG_ Torque_Command : 29|13@0+ (1,-4000) [0|255] "" XXX + +BO_ 412 NEW_MSG_9: 8 XXX + SG_ NEW_SIGNAL_1 : 7|16@0+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_3 : 23|16@0+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_2 : 39|8@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_4 : 47|8@0+ (1,0) [0|255] "" XXX + +BO_ 361 LKAS: 8 XXX + SG_ NEW_SIGNAL_4 : 39|8@0+ (1,0) [0|255] "" XXX + SG_ SET_X80 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ LKA_Active : 52|1@0+ (1,0) [0|15] "" XXX + SG_ CRC : 63|8@0+ (1,0) [0|255] "" XXX + SG_ SET_0x80_2 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ Counter : 51|4@0+ (1,0) [0|15] "" XXX + SG_ Des_Angle : 7|18@0+ (-0.01,1310) [0|255] "" XXX + +BO_ 438 ProPilot: 8 XXX + SG_ NEW_SIGNAL_2 : 11|4@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_4 : 27|4@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_8 : 63|8@0+ (1,0) [0|7] "" XXX + SG_ Counter : 55|4@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_6 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ SET_3 : 32|2@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_1 : 7|12@0- (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_3 : 23|12@0- (-1,0) [0|255] "" XXX + SG_ CRUISE_ON : 36|1@0+ (1,0) [0|255] "" XXX + SG_ CRUISE_ACTIVATED : 38|1@0+ (1,0) [0|3] "" XXX + SG_ STEER_STATUS : 51|1@1+ (1,0) [0|3] "" XXX + diff --git a/opendbc/subaru_crosstrek_2018.dbc b/opendbc/subaru_crosstrek_2018.dbc new file mode 100644 index 00000000000000..b766cdca87972d --- /dev/null +++ b/opendbc/subaru_crosstrek_2018.dbc @@ -0,0 +1,369 @@ +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX X + + +BO_ 2 Steering: 8 XXX + SG_ Counter : 25|3@1+ (1,0) [0|7] "" XXX + SG_ Checksum : 32|8@1+ (1,0) [0|255] "" XXX + SG_ Steering_Angle : 7|16@0- (0.1,0) [0|65535] "" XXX + +BO_ 64 Throttle: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Off_Accel : 60|4@1+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_3 : 56|4@1+ (1,0) [0|255] "" XXX + SG_ Throttle_Cruise : 40|8@1+ (1,0) [0|255] "" XXX + SG_ Throttle_Combo : 55|8@1+ (1,0) [0|255] "" XXX + SG_ Throttle_Pedal : 32|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 48|7@1+ (1,0) [0|1] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|255] "" XXX + SG_ Engine_RPM : 16|12@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_1 : 12|4@1+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_4 : 28|5@1+ (1,0) [0|1] "" XXX + +BO_ 65 NEW_MSG_1: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_4 : 32|12@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_3 : 16|12@1+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_5 : 31|1@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_6 : 48|8@1+ (1,0) [0|63] "" XXX + SG_ NEW_SIGNAL_7 : 59|2@0+ (1,0) [0|255] "" XXX + +BO_ 72 NEW_MSG_2: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 40|16@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_4 : 38|3@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_5 : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 316 NEW_MSG_3: 8 XXX + +BO_ 326 Cruise_Buttons: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ Signal1 : 12|30@1+ (1,0) [0|1073741823] "" XXX + SG_ Main : 42|1@1+ (1,0) [0|1] "" XXX + SG_ set : 43|1@1+ (1,0) [0|1] "" XXX + SG_ Resume : 44|1@1+ (1,0) [0|1] "" XXX + SG_ Signal2 : 45|19@1+ (1,0) [0|524287] "" XXX + +BO_ 315 G_Sensor: 8 XXX + SG_ longitudinal : 63|8@0- (1,0) [0|255] "" XXX + SG_ Latitudinal : 48|8@1- (1,0) [0|255] "" XXX + +BO_ 314 Wheel_Speeds: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ FR : 12|13@1+ (0.057,0) [0|255] "kph" XXX + SG_ RR : 25|13@1+ (0.057,0) [0|255] "kph" XXX + SG_ FL : 51|13@1+ (0.057,0) [0|255] "kph" XXX + SG_ RL : 38|13@1+ (0.057,0) [0|255] "kph" XXX + +BO_ 73 NEW_MSG_5: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_1 : 32|8@1+ (1,0) [0|4095] "" XXX + SG_ NEW_SIGNAL_2 : 24|8@1+ (1,0) [0|127] "" XXX + +BO_ 280 NEW_MSG_6: 8 XXX + SG_ NEW_SIGNAL_1 : 12|12@1- (1,0) [0|4095] "" XXX + SG_ NEW_SIGNAL_2 : 48|8@1- (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_3 : 61|1@1+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_4 : 40|4@1+ (1,0) [0|255] "" XXX + +BO_ 281 Steering_Torque: 8 XXX + SG_ checksum : 0|8@1+ (1,0) [0|3] "" XXX + SG_ counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ Steer_Torque_Sensor : 16|11@1- (-1,0) [0|3] "" XXX + SG_ Steering_Angle : 32|16@1- (-0.0217,0) [0|255] "" X + SG_ Steer_Torque_Output : 48|11@1- (-1,0) [0|31] "" XXX + +BO_ 312 Brake_Pressure_L_R: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|31] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|3] "" XXX + SG_ Brake_2 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ Brake_1 : 48|8@1+ (1,0) [0|255] "" XXX + +BO_ 313 Brake_Pedal: 8 XXX + SG_ Brake_Pedal_On : 34|1@1+ (1,0) [0|7] "" XXX + SG_ Brake_Pedal : 36|12@1+ (1,0) [0|65535] "" XXX + +BO_ 290 ES_LKAS: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ LKAS_Output : 16|13@1- (-1,0) [0|3] "" XXX + SG_ LKAS_Request : 29|1@0+ (1,0) [0|3] "" XXX + SG_ SET_1 : 12|1@0+ (1,0) [0|3] "" XXX + +BO_ 722 NEW_MSG_10: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_1 : 27|3@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_4 : 56|2@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_5 : 45|2@0+ (1,0) [0|3] "" XXX + +BO_ 544 ES_Brake: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ Brake_Pressure : 16|16@1+ (1,0) [0|255] "" XXX + SG_ __Status : 36|4@1+ (1,0) [0|63] "" XXX + +BO_ 545 ES_Distance: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ Signal1 : 12|20@1+ (1,0) [0|15] "" XXX + SG_ Signal2 : 32|24@1+ (1,0) [0|15] "" XXX + SG_ ACC_Cancel : 56|1@1+ (1,0) [0|1] "" XXX + SG_ ACC_Set : 57|1@1+ (1,0) [0|1] "" XXX + SG_ ACC_Resume : 58|1@1+ (1,0) [0|1] "" XXX + SG_ Signal3 : 59|5@1+ (1,0) [0|1] "" XXX + +BO_ 546 ES_Status: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ RPM : 16|12@1+ (1,0) [0|255] "" XXX + SG_ Cruise_Activated : 29|1@0+ (1,0) [0|3] "" XXX + SG_ Cruise_Brake : 30|1@1+ (1,0) [0|3] "" XXX + +BO_ 554 ES_Blank: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ SET_65535 : 39|16@1+ (1,0) [0|16777215] "" XXX + SG_ SET_1 : 13|1@1+ (1,0) [0|7] "" XXX + +BO_ 557 NEW_MSG_14: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + +BO_ 576 CruiseControl: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 42|1@1+ (1,0) [0|3] "" XXX + SG_ Cruise_On : 40|1@1+ (1,0) [0|3] "" XXX + SG_ Cruise_Activated : 41|1@1+ (1,0) [0|3] "" XXX + +BO_ 577 NEW_MSG_16: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_1 : 16|12@1+ (1,0) [0|255] "" XXX + +BO_ 552 NEW_MSG_17: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_1 : 48|1@1+ (1,0) [0|3] "" XXX + +BO_ 912 Dashlights: 8 XXX + SG_ NEW_SIGNAL_1 : 32|1@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_2 : 8|4@1+ (1,0) [0|15] "" XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ RIGHT_BLINKER : 51|1@1+ (1,0) [0|1] "" XXX + SG_ LEFT_BLINKER : 50|1@1+ (1,0) [0|3] "" XXX + SG_ SEATBELT_FL : 48|1@1+ (1,0) [0|1] "" XXX + +BO_ 940 BodyInfo: 8 XXX + SG_ DASH_BTN_LIGHTS : 56|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FL : 32|1@1+ (1,0) [0|255] "" XXX + SG_ DOOR_OPEN_FR : 33|1@1+ (1,0) [0|3] "" XXX + SG_ DOOR_OPEN_RL : 34|1@1+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RR : 35|1@1+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_TRUNK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ FOG_LIGHTS2 : 60|1@1+ (1,0) [0|1] "" XXX + SG_ Highbeam : 58|1@1+ (1,0) [0|1] "" XXX + SG_ Lowbeam : 57|1@1+ (1,0) [0|3] "" XXX + +BO_ 801 ES_DashStatus: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_10 : 49|2@1+ (1,0) [0|3] "" XXX + SG_ Brake_Pedal : 51|1@1+ (1,0) [0|3] "" XXX + SG_ Cruise_Set_Speed : 40|8@1+ (1,0) [0|255] "" XXX + SG_ Cruise_Activated : 36|1@1+ (1,0) [0|3] "" XXX + SG_ Cruise_Disengaged : 35|1@1+ (1,0) [0|3] "" XXX + SG_ Far_Distance : 56|4@1+ (1,0) [0|15] "" XXX + SG_ Car_Follow : 52|1@1+ (1,0) [0|3] "" XXX + SG_ ACC_Distance : 28|3@1+ (1,0) [0|3] "" XXX + SG_ ACC_Hold : 60|4@1+ (1,0) [0|15] "" XXX + +BO_ 802 ES_LKAS_State: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ Keep_Hands_On_Wheel : 12|1@1+ (1,0) [0|1] "" XXX + SG_ Empty_Box : 13|1@1+ (1,0) [0|1] "" XXX + SG_ Signal1 : 14|3@1+ (1,0) [0|7] "" XXX + SG_ LKAS_ACTIVE : 17|1@1+ (1,0) [0|3] "" XXX + SG_ Signal2 : 18|5@1+ (1,0) [0|7] "" XXX + SG_ Backward_Speed_Limit_Menu : 23|1@1+ (1,0) [0|1] "" XXX + SG_ LKAS_ENABLE_3 : 24|1@1+ (1,0) [0|1] "" XXX + SG_ Signal3 : 25|1@1+ (1,0) [0|1] "" XXX + SG_ LKAS_ENABLE_2 : 26|1@1+ (1,0) [0|1] "" XXX + SG_ Signal4 : 27|1@1+ (1,0) [0|1] "" XXX + SG_ LKAS_Left_Line_Visible : 28|1@1+ (1,0) [0|1] "" XXX + SG_ Signal6 : 29|1@1+ (1,0) [0|1] "" XXX + SG_ LKAS_Right_Line_Visible : 30|1@1+ (1,0) [0|1] "" XXX + SG_ Signal7 : 31|1@1+ (1,0) [0|1] "" XXX + SG_ FCW_Cont_Beep : 32|1@1+ (1,0) [0|1] "" XXX + SG_ FCW_Repeated_Beep : 33|1@1+ (1,0) [0|1] "" XXX + SG_ Throttle_Management_Activated : 34|1@1+ (1,0) [0|1] "" XXX + SG_ Right_Depart : 36|1@1+ (1,0) [0|3] "" XXX + SG_ Signal5 : 37|27@1+ (1,0) [0|1] "" XXX + SG_ Vehicle_In_Front_Has_Moved : 35|1@1+ (1,0) [0|1] "" XXX + +BO_ 805 ES_NEW_MSG_22: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 22|2@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_1 : 14|1@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_4 : 15|1@1+ (1,0) [0|3] "" XXX + +BO_ 808 NEW_MSG_23: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + +BO_ 837 NEW_MSG_24: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 40|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_4 : 32|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_5 : 24|8@1+ (1,0) [0|255] "" XXX + +BO_ 838 NEW_MSG_25: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_4 : 40|1@1+ (1,0) [0|3] "" XXX + +BO_ 842 NEW_MSG_26: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 32|8@1+ (1,0) [0|255] "" XXX + +BO_ 915 NEW_MSG_27: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_4 : 32|9@1+ (1,0) [0|255] "" XXX + +BO_ 1788 NEW_MSG_28: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 40|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_4 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_5 : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 816 NEW_MSG_29: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + +BO_ 826 NEW_MSG_30: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + +BO_ 839 NEW_MSG_31: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + +BO_ 2015 NEW_MSG_32: 8 XXX + SG_ NEW_SIGNAL_2 : 16|8@1+ (1,0) [0|255] "" XXX + +BO_ 2024 NEW_MSG_33: 8 XXX + SG_ NEW_SIGNAL_1 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 0|3@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_4 : 32|8@1+ (1,0) [0|255] "" XXX + +BO_ 1614 NEW_MSG_34: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + +BO_ 1617 NEW_MSG_35: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + +BO_ 1632 NEW_MSG_36: 8 XXX + SG_ NEW_SIGNAL_1 : 55|16@0+ (1,0) [0|255] "" XXX + +BO_ 1650 NEW_MSG_37: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + +BO_ 1657 NEW_MSG_38: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + +BO_ 1658 NEW_MSG_39: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 33|1@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_4 : 31|1@0+ (1,0) [0|3] "" XXX + +BO_ 1677 Dash_State: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 16|4@1+ (1,0) [0|15] "" XXX + SG_ Units : 29|3@1+ (1,0) [0|7] "" XXX + +BO_ 1743 NEW_MSG_41: 8 XXX + SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + +BO_ 1785 NEW_MSG_42: 8 XXX + SG_ NEW_SIGNAL_1 : 0|4@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 21|1@1+ (1,0) [0|31] "" XXX + SG_ NEW_SIGNAL_3 : 17|1@1+ (1,0) [0|7] "" XXX + +BO_ 1759 NEW_MSG_43: 8 XXX + SG_ NEW_SIGNAL_1 : 17|1@1+ (1,0) [0|3] "" XXX + +BO_ 1786 NEW_MSG_44: 8 XXX + SG_ NEW_SIGNAL_1 : 0|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 16|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_3 : 8|8@1+ (1,0) [0|15] "" XXX + +BO_ 1787 NEW_MSG_45: 8 XXX + SG_ NEW_SIGNAL_1 : 0|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 8|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_3 : 16|8@1+ (1,0) [0|255] "" XXX + + + + +CM_ SG_ 940 FOG_LIGHTS2 "yellow fog light in the dash"; +CM_ SG_ 940 Highbeam "01 = low beam, 11 = high beam"; +CM_ SG_ 801 ACC_Hold "0 = No Hold, 3 = Hold"; +CM_ SG_ 802 Vehicle_In_Front_Has_Moved "Crosstrek 2018 = car in front has moved"; +CM_ SG_ 805 NEW_SIGNAL_3 "always 3"; +CM_ SG_ 805 NEW_SIGNAL_4 "always 1"; +CM_ SG_ 1677 Units "1 = imperial, 6 = metric"; diff --git a/opendbc/subaru_global_2017.dbc b/opendbc/subaru_global_2017.dbc index 1c8b796ab2b7f6..39823f904968ca 100644 --- a/opendbc/subaru_global_2017.dbc +++ b/opendbc/subaru_global_2017.dbc @@ -43,14 +43,16 @@ BO_ 2 Steering: 8 XXX BO_ 64 Throttle: 8 XXX SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX - SG_ Counter : 8|4@1+ (1,0) [0|255] "" XXX SG_ Off_Accel : 60|4@1+ (1,0) [0|7] "" XXX SG_ NEW_SIGNAL_3 : 56|4@1+ (1,0) [0|255] "" XXX - SG_ Engine_RPM : 16|12@1+ (1,0) [0|255] "" XXX SG_ Throttle_Cruise : 40|8@1+ (1,0) [0|255] "" XXX - SG_ Throttle_Combo : 55|8@1+ (0.392157,0) [0|255] "" XXX + SG_ Throttle_Combo : 55|8@1+ (1,0) [0|255] "" XXX SG_ Throttle_Pedal : 32|8@1+ (1,0) [0|255] "" XXX - + SG_ NEW_SIGNAL_2 : 48|7@1+ (1,0) [0|1] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|255] "" XXX + SG_ Engine_RPM : 16|12@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_1 : 12|4@1+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_4 : 28|5@1+ (1,0) [0|1] "" XXX BO_ 65 NEW_MSG_1: 8 XXX SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX @@ -70,12 +72,14 @@ BO_ 72 NEW_MSG_2: 8 XXX BO_ 316 NEW_MSG_3: 8 XXX -BO_ 326 NEW_MSG_4: 8 XXX +BO_ 326 Cruise_Buttons: 8 XXX SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX - SG_ NEW_SIGNAL_1 : 16|12@1+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_2 : 32|8@1+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_3 : 40|2@1+ (1,0) [0|255] "" XXX + SG_ Signal1 : 12|30@1+ (1,0) [0|1073741823] "" XXX + SG_ Main : 42|1@1+ (1,0) [0|1] "" XXX + SG_ set : 43|1@1+ (1,0) [0|1] "" XXX + SG_ Resume : 44|1@1+ (1,0) [0|1] "" XXX + SG_ Signal2 : 45|19@1+ (1,0) [0|524287] "" XXX BO_ 315 G_Sensor: 8 XXX SG_ longitudinal : 63|8@0- (1,0) [0|255] "" XXX @@ -140,19 +144,10 @@ BO_ 544 ES_Brake: 8 XXX BO_ 545 ES_Distance: 8 XXX SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX - SG_ Close_Distance : 40|8@1+ (1,0) [0|255] "" XXX - SG_ Distance_Swap : 37|1@1+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_5 : 39|1@1+ (1,0) [0|31] "" XXX - SG_ NEW_SIGNAL_9 : 38|1@1+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_4 : 34|1@1+ (1,0) [0|3] "" XXX - SG_ Brake_Pedal : 33|1@1+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_10 : 35|1@1+ (1,0) [0|3] "" XXX - SG_ Throttle : 16|12@1+ (1,0) [0|65535] "" XXX - SG_ NEW_SIGNAL_1 : 31|4@0+ (1,0) [0|15] "" XXX - SG_ SET_1 : 12|1@0+ (1,0) [0|3] "" XXX - SG_ ACC_ENABLE_BTN : 56|1@0+ (1,0) [0|1] "" XXX - SG_ Car_Follow : 32|1@1+ (1,0) [0|3] "" XXX - SG_ Brake : 36|1@0+ (1,0) [0|3] "" XXX + SG_ Signal1 : 12|20@1+ (1,0) [0|15] "" XXX + SG_ Signal2 : 32|24@1+ (1,0) [0|15] "" XXX + SG_ Main : 56|1@1+ (1,0) [0|1] "" XXX + SG_ Signal3 : 57|7@1+ (1,0) [0|1] "" XXX BO_ 546 ES_Status: 8 XXX SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX @@ -225,19 +220,24 @@ BO_ 802 ES_LKAS_State: 8 XXX SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX SG_ Keep_Hands_On_Wheel : 12|1@1+ (1,0) [0|1] "" XXX SG_ Empty_Box : 13|1@1+ (1,0) [0|1] "" XXX + SG_ Signal1 : 14|3@1+ (1,0) [0|7] "" XXX SG_ LKAS_ACTIVE : 17|1@1+ (1,0) [0|3] "" XXX + SG_ Signal2 : 18|5@1+ (1,0) [0|7] "" XXX SG_ Backward_Speed_Limit_Menu : 23|1@1+ (1,0) [0|1] "" XXX SG_ LKAS_ENABLE_3 : 24|1@1+ (1,0) [0|1] "" XXX + SG_ Signal3 : 25|1@1+ (1,0) [0|1] "" XXX SG_ LKAS_ENABLE_2 : 26|1@1+ (1,0) [0|1] "" XXX - SG_ NEW_SIGNAL_7 : 28|1@1+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_2 : 30|1@1+ (1,0) [0|3] "" XXX + SG_ Signal4 : 27|1@1+ (1,0) [0|1] "" XXX + SG_ LKAS_Left_Line_Visible : 28|1@1+ (1,0) [0|1] "" XXX + SG_ Signal6 : 29|1@1+ (1,0) [0|1] "" XXX + SG_ LKAS_Right_Line_Visible : 30|1@1+ (1,0) [0|1] "" XXX + SG_ Signal7 : 31|1@1+ (1,0) [0|1] "" XXX SG_ FCW_Cont_Beep : 32|1@1+ (1,0) [0|1] "" XXX SG_ FCW_Repeated_Beep : 33|1@1+ (1,0) [0|1] "" XXX SG_ Throttle_Management_Activated : 34|1@1+ (1,0) [0|1] "" XXX SG_ Traffic_light_Ahead : 35|1@1+ (1,0) [0|1] "" XXX SG_ Right_Depart : 36|1@1+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_4 : 44|1@1+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_5 : 56|2@1+ (1,0) [0|3] "" XXX + SG_ Signal5 : 37|27@1+ (1,0) [0|1] "" XXX BO_ 805 ES_NEW_MSG_22: 8 XXX SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX @@ -327,10 +327,11 @@ BO_ 1658 NEW_MSG_39: 8 XXX SG_ NEW_SIGNAL_3 : 33|1@1+ (1,0) [0|3] "" XXX SG_ NEW_SIGNAL_4 : 31|1@0+ (1,0) [0|3] "" XXX -BO_ 1677 NEW_MSG_40: 8 XXX +BO_ 1677 Dash_State: 8 XXX SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX SG_ NEW_SIGNAL_3 : 16|4@1+ (1,0) [0|15] "" XXX + SG_ Units : 29|3@1+ (1,0) [0|7] "" XXX BO_ 1743 NEW_MSG_41: 8 XXX SG_ Checksum : 0|8@1+ (1,0) [0|255] "" XXX @@ -359,5 +360,7 @@ BO_ 1787 NEW_MSG_45: 8 XXX CM_ SG_ 940 FOG_LIGHTS2 "yellow fog light in the dash"; CM_ SG_ 940 Highbeam "01 = low beam, 11 = high beam"; +CM_ SG_ 802 Traffic_light_Ahead "Crosstrek 2018 = car in front has moved"; CM_ SG_ 805 NEW_SIGNAL_3 "always 3"; CM_ SG_ 805 NEW_SIGNAL_4 "always 1"; +CM_ SG_ 1677 Units "1 = imperial, 6 = metric"; diff --git a/opendbc/subaru_outback_2015_eyesight.dbc b/opendbc/subaru_outback_2015_eyesight.dbc index aad63e31058899..2f796558501817 100644 --- a/opendbc/subaru_outback_2015_eyesight.dbc +++ b/opendbc/subaru_outback_2015_eyesight.dbc @@ -33,16 +33,16 @@ NS_ : BS_: -BU_: XXX 0 +BU_: XXX BO_ 2 Steering: 8 XXX SG_ NEW_SIGNAL_1 : 31|4@0- (1,0) [0|65535] "" XXX - SG_ NEW_SIGNAL_6 : 24|1@1+ (1,0) [0|3] "" XXX SG_ Counter : 25|3@1+ (1,0) [0|15] "" XXX SG_ Checksum : 32|8@1+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_2 : 22|3@0+ (1,0) [0|7] "" XXX - SG_ Steering_Angle : 7|16@0- (-0.1,-9) [-497|500] "degree" XXX + SG_ NEW_SIGNAL_6 : 24|1@1+ (1,0) [0|3] "" XXX + SG_ Steering_Angle : 7|16@0- (0.1,0) [-500|500] "degree" XXX BO_ 208 G_Sensor: 8 XXX SG_ NEW_SIGNAL_3 : 32|8@1+ (1,0) [0|255] "" XXX @@ -52,10 +52,9 @@ BO_ 208 G_Sensor: 8 XXX SG_ _Longitudinal : 48|16@1- (0.000035,0) [0|255] "" XXX BO_ 209 Brake_Pedal: 8 XXX - SG_ NEW_SIGNAL_2 : 31|1@1+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_3 : 56|8@1+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_1 : 26|1@1+ (1,0) [0|3] "" XXX SG_ Brake_Pedal : 23|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 31|1@1+ (1,0) [0|255] "" XXX SG_ Speed : 0|16@1+ (0.05625,0) [0|255] "KPH" XXX BO_ 210 Brake_2: 8 XXX @@ -76,7 +75,7 @@ BO_ 211 Brake_Type: 8 XXX SG_ Brake_Cruise_On : 42|1@0+ (1,0) [0|3] "" XXX SG_ Brake_Pedal_On : 46|1@0+ (1,0) [0|3] "" XXX -BO_ 212 WHEEL_SPEEDS: 8 XXX +BO_ 212 Wheel_Speeds: 8 XXX SG_ FL : 0|16@1+ (0.0592,0) [2|255] "KPH" XXX SG_ FR : 16|16@1+ (0.0592,0) [0|255] "KPH" XXX SG_ RL : 32|16@1+ (0.0592,0) [0|255] "" XXX @@ -106,7 +105,7 @@ BO_ 321 undefined: 8 XXX SG_ Wheel_Torque : 16|12@1+ (1,0) [0|255] "" XXX SG_ Engine_Stop : 15|1@0+ (1,0) [0|3] "" XXX -BO_ 324 CruiseControl_2015: 8 XXX +BO_ 324 CruiseControl: 8 XXX SG_ Cruise_On : 48|1@0+ (1,0) [0|3] "" XXX SG_ OnOffButton : 2|1@1+ (1,0) [0|3] "" XXX SG_ SET_BUTTON : 3|1@0+ (1,0) [0|3] "" XXX @@ -117,8 +116,8 @@ BO_ 324 CruiseControl_2015: 8 XXX SG_ NEW_SIGNAL_2 : 8|1@0+ (1,0) [0|255] "" XXX SG_ Cruise_Activated : 49|1@0+ (1,0) [0|7] "" XXX SG_ Brake_Pedal_On : 51|1@0+ (1,0) [0|3] "" XXX - SG_ Button : 13|1@0+ (1,0) [0|3] "" XXX SG_ NEW_SIGNAL_1 : 23|8@0+ (1,-124) [0|255] "" XXX + SG_ Button : 13|1@0+ (1,0) [0|3] "" XXX BO_ 328 Transmission: 8 XXX SG_ Counter : 11|4@0+ (1,0) [0|255] "" XXX @@ -165,6 +164,7 @@ BO_ 352 ES_Brake: 8 XXX SG_ Brake_Light : 20|1@0+ (1,0) [0|2047] "" XXX SG_ Cruise_Activated : 23|1@0+ (1,0) [0|3] "" XXX SG_ Brake_Pressure : 0|16@1+ (1,0) [0|255] "" XXX + SG_ ES_Error : 21|1@0+ (1,0) [0|7] "" XXX BO_ 353 ES_CruiseThrottle: 8 XXX SG_ Throttle_Cruise : 0|12@1+ (1,0) [0|255] "" XXX @@ -182,6 +182,7 @@ BO_ 353 ES_CruiseThrottle: 8 XXX SG_ NEW_SIGNAL_6_Blank : 23|1@0+ (1,0) [0|7] "" XXX SG_ DistanceSwap : 21|1@0+ (1,0) [0|3] "" XXX SG_ Brake_On : 20|1@0+ (1,0) [0|7] "" XXX + SG_ ES_Error : 42|1@1+ (1,0) [0|3] "" XXX BO_ 354 ES_RPM: 8 XXX SG_ Counter : 48|3@1+ (1,0) [0|7] "" XXX @@ -192,17 +193,14 @@ BO_ 354 ES_RPM: 8 XXX BO_ 356 ES_LKAS: 8 XXX SG_ Checksum : 56|8@1+ (1,0) [0|255] "" XXX - SG_ Counter : 0|3@1+ (1,0) [0|8] "" XXX + SG_ Counter : 0|3@1+ (1,0) [0|7] "" XXX SG_ LKAS_Active : 24|1@1+ (1,0) [0|1] "" XXX - SG_ LKAS_Command : 8|13@1- (-1,0) [-4096|4095] "" XXX + SG_ LKAS_Command : 8|13@1- (-1,0) [-4096|4096] "" XXX -BO_ 358 ES_Status: 8 XXX +BO_ 358 ES_DashStatus: 8 XXX SG_ Counter : 39|3@0+ (1,0) [0|7] "" XXX - SG_ Cruise_On : 16|1@1+ (1,0) [0|7] "" XXX - SG_ Cruise_Activated : 17|1@1+ (1,0) [0|3] "" XXX SG_ Obstacle_Distance : 48|4@1+ (1,0) [0|15] "" XXX SG_ Cruise_Off : 22|1@0+ (1,0) [0|3] "" XXX - SG_ Saved_Speed : 24|8@1+ (1,0) [0|255] "" XXX SG_ Car_Follow : 46|1@1+ (1,0) [0|255] "" XXX SG_ Driver_Input : 20|1@0+ (1,0) [0|15] "" XXX SG_ WHEELS_MOVING_2015 : 19|1@1+ (1,0) [0|3] "" XXX @@ -211,24 +209,28 @@ BO_ 358 ES_Status: 8 XXX SG_ NEW_SIGNAL_5_Blank : 33|1@1+ (1,0) [0|3] "" XXX SG_ NEW_SIGNAL_4_Blank : 34|1@1+ (1,0) [0|7] "" XXX SG_ NEW_SIGNAL_1 : 35|1@0+ (1,0) [0|31] "" XXX - SG_ 3SecondDisengage : 13|2@0+ (1,0) [0|3] "" XXX - SG_ Not_Ready_Startup : 0|3@1+ (1,0) [0|7] "" XXX SG_ Steep_Hill_Disengage : 44|1@0+ (1,0) [0|3] "" XXX + SG_ ES_Error : 32|1@1+ (1,0) [0|3] "" XXX + SG_ Cruise_Activated : 17|1@1+ (1,0) [0|3] "" XXX + SG_ Cruise_On : 16|1@1+ (1,0) [0|7] "" XXX SG_ Disengage_Alert : 15|2@0+ (1,0) [0|3] "" XXX + SG_ 3SecondDisengage : 13|2@0+ (1,0) [0|3] "" XXX + SG_ Not_Ready_Startup : 0|3@1+ (1,0) [0|7] "" XXX + SG_ Cruise_Set_Speed : 24|8@1+ (1,0) [0|255] "" XXX BO_ 359 ES_LDW: 8 XXX - SG_ 2Right_Depart : 50|1@1+ (1,0) [0|7] "" XXX - SG_ 2All_Depart : 28|1@0+ (1,0) [0|3] "" XXX - SG_ 3All_Depart : 52|1@0+ (1,0) [0|3] "" XXX - SG_ Left_Depart_Front : 51|1@0+ (1,0) [0|3] "" XXX SG_ All_depart_2015 : 0|1@1+ (1,0) [0|255] "" XXX SG_ LKAS_Inactive_2017 : 36|1@1+ (1,0) [0|3] "" XXX SG_ LKAS_Steer_Active_2017 : 37|1@0+ (1,0) [0|3] "" XXX SG_ Right_Line_2017 : 24|1@1+ (1,0) [0|7] "" XXX SG_ Left_Line_2017 : 25|1@1+ (1,0) [0|3] "" XXX - SG_ 1All_Depart : 31|1@0+ (1,0) [0|15] "" XXX - SG_ 1Right_Depart_Front : 49|1@1+ (1,0) [0|3] "" XXX - SG_ 1Right_Depart : 48|1@1+ (1,0) [0|3] "" XXX + SG_ Sig2All_Depart : 28|1@0+ (1,0) [0|3] "" XXX + SG_ Sig1All_Depart : 31|1@0+ (1,0) [0|15] "" XXX + SG_ Sig1Right_Depart : 48|1@1+ (1,0) [0|3] "" XXX + SG_ Sig1Right_Depart_Front : 49|1@1+ (1,0) [0|3] "" XXX + SG_ Sig2Right_Depart : 50|1@1+ (1,0) [0|7] "" XXX + SG_ Left_Depart_Front : 51|1@0+ (1,0) [0|3] "" XXX + SG_ Sig3All_Depart : 52|1@0+ (1,0) [0|3] "" XXX BO_ 392 Counter_0: 8 XXX SG_ Counter : 16|4@1+ (1,0) [0|15] "" XXX @@ -255,6 +257,7 @@ BO_ 642 Dashlights: 8 XXX SG_ NEW_SIGNAL_3 : 34|2@1+ (1,0) [0|3] "" XXX SG_ LEFT_BLINKER : 44|1@0+ (1,0) [0|3] "" XXX SG_ RIGHT_BLINKER : 45|1@0+ (1,0) [0|3] "" XXX + SG_ SEATBELT_FL : 40|1@1+ (1,0) [0|3] "" XXX BO_ 644 NEW_MSG_8: 8 XXX SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX @@ -272,21 +275,23 @@ BO_ 880 Steer_Torque_2: 8 XXX SG_ Steer_Torque_Sensor : 32|8@1- (-1,0) [0|255] "" XXX BO_ 881 Steering_Torque: 8 XXX - SG_ Steering_Motor_Flat : 0|8@1+ (1,0) [0|255] "" XXX - SG_ Steer_Torque_Sensor : 39|8@0- (1,0) [0|255] "" XXX - SG_ Steering_Angle : 40|16@1- (-0.026,0) [0|255] "" XXX - SG_ Steering_Motor_LeftRight : 23|16@0- (-0.13,0) [0|255] "" XXX + SG_ Steering_Motor_Flat : 0|10@1+ (32,0) [0|16500] "" XXX + SG_ Steer_Torque_Output : 16|11@1- (-32,0) [-16500|16500] "" XXX + SG_ Steer_Torque_Sensor : 29|11@1- (8,0) [-8500|-8500] "" XXX + SG_ Steering_Angle : 40|16@1- (-0.026,0) [-600|600] "" XXX + SG_ LKA_Lockout : 27|1@1+ (1,0) [0|1] "" XXX BO_ 882 Counter: 8 XXX SG_ Counter : 15|4@0+ (1,0) [0|31] "" XXX SG_ Something : 16|2@1+ (1,0) [0|255] "" XXX -BO_ 884 DOORS_STATUS: 8 XXX +BO_ 884 BodyInfo: 8 XXX SG_ DOOR_OPEN_FR : 24|1@0+ (1,0) [0|1] "" XXX SG_ DOOR_OPEN_FL : 25|1@0+ (1,0) [0|1] "" XXX SG_ DOOR_OPEN_RL : 26|1@0+ (1,0) [0|1] "" XXX SG_ DOOR_OPEN_RR : 27|1@0+ (1,0) [0|1] "" XXX SG_ DOOR_OPEN_Hatch : 28|1@0+ (1,0) [0|1] "" XXX + SG_ _UNKNOWN : 2|3@0+ (1,0) [0|1] "" XXX BO_ 886 undefined: 8 XXX @@ -341,30 +346,27 @@ CM_ SG_ 320 Off_Throttle_2 "Less sensitive"; CM_ SG_ 320 Throttle_Body_ "Throttle related"; CM_ SG_ 328 Gear "15 = P, 14 = R, 0 = N, 1-6=gear"; CM_ SG_ 328 Gear_2 "15 = P, 14 = R, 0 = N, 1-6=gear"; -CM_ SG_ 338 Wiper "0 off, 1 on"; CM_ SG_ 353 NEW_SIGNAL_3_Blank "always 2"; CM_ SG_ 353 NEW_SIGNAL_2_Blank "0"; CM_ SG_ 353 NEW_SIGNAL_9 "flipped around quick engagement"; CM_ SG_ 353 NEW_SIGNAL_6_Blank "always 1"; CM_ SG_ 353 Brake_On "long activatedish"; CM_ SG_ 354 RPM "20hz version of Transmission_Engine under Transmission"; -CM_ SG_ 358 Cruise_Activated "is 1 when cruise is able to go"; CM_ SG_ 358 Car_Follow "front car detected"; -CM_ SG_ 358 3SecondDisengage "seatbelt disengage"; +CM_ SG_ 358 ES_Error "No engagement until restart"; +CM_ SG_ 358 Cruise_Activated "is 1 when cruise is able to go"; CM_ SG_ 358 Disengage_Alert "seatbelt and steep hill disengage"; -CM_ SG_ 359 2All_Depart "Left and right depart"; -CM_ SG_ 359 Left_Depart_Front "warning after acceleration into car in front and left depart"; +CM_ SG_ 358 3SecondDisengage "seatbelt disengage"; CM_ SG_ 359 All_depart_2015 "always 1 on 2017"; CM_ SG_ 359 LKAS_Inactive_2017 "1 when not steering, 0 when lkas steering"; -CM_ SG_ 359 1All_Depart "Left and right depart"; -CM_ SG_ 359 1Right_Depart_Front "object in front, right depart, hill steep and seatbelt disengage alert "; -CM_ SG_ 359 1Right_Depart "right depart, hill steep and seatbelt disengage"; +CM_ SG_ 359 Sig2All_Depart "Left and right depart"; +CM_ SG_ 359 Sig1All_Depart "Left and right depart"; +CM_ SG_ 359 Sig1Right_Depart "right depart, hill steep and seatbelt disengage"; +CM_ SG_ 359 Sig1Right_Depart_Front "object in front, right depart, hill steep and seatbelt disengage alert "; +CM_ SG_ 359 Left_Depart_Front "warning after acceleration into car in front and left depart"; CM_ SG_ 642 Counter "Affected by signals"; CM_ SG_ 642 RIGHT_BLINKER "0 off, 2 right, 1 left"; CM_ SG_ 880 Steering_Voltage_Flat "receives later than 371"; CM_ SG_ 880 NEW_SIGNAL_1 "0 in 2017"; -CM_ SG_ 880 NEW_SIGNAL_2 ""; CM_ SG_ 880 NEW_SIGNAL_4_2017 "1 in 2017"; CM_ SG_ 880 NEW_SIGNAL_5_2017 "1 in 2017"; -CM_ SG_ 881 Steering_Motor_Flat "Possibly motor voltage"; -CM_ SG_ 881 Steering_Angle "Missing extra larger bits"; diff --git a/opendbc/subaru_outback_2016_eyesight.dbc b/opendbc/subaru_outback_2016_eyesight.dbc deleted file mode 100644 index 871f7821843231..00000000000000 --- a/opendbc/subaru_outback_2016_eyesight.dbc +++ /dev/null @@ -1,73 +0,0 @@ -VERSION "" - - -NS_ : - NS_DESC_ - CM_ - BA_DEF_ - BA_ - VAL_ - CAT_DEF_ - CAT_ - FILTER - BA_DEF_DEF_ - EV_DATA_ - ENVVAR_DATA_ - SGTYPE_ - SGTYPE_VAL_ - BA_DEF_SGTYPE_ - BA_SGTYPE_ - SIG_TYPE_REF_ - VAL_TABLE_ - SIG_GROUP_ - SIG_VALTYPE_ - SIGTYPE_VALTYPE_ - BO_TX_BU_ - BA_DEF_REL_ - BA_REL_ - BA_DEF_DEF_REL_ - BU_SG_REL_ - BU_EV_REL_ - BU_BO_REL_ - SG_MUL_VAL_ - -BS_: - -BU_: XXX - - -BO_ 884 DoorStatus: 8 XXX - SG_ DoorOpenFD : 24|1@0+ (1,0) [0|1] "" XXX - SG_ DoorOpenFP : 25|1@0+ (1,0) [0|1] "" XXX - SG_ DoorOpenRP : 26|1@0+ (1,0) [0|1] "" XXX - SG_ DoorOpenRD : 27|1@0+ (1,0) [0|1] "" XXX - SG_ DoorOpenHatch : 28|1@0+ (1,0) [0|1] "" XXX - -BO_ 324 CruiseControl: 7 XXX - SG_ BrakeApplied : 8|1@0+ (1,0) [0|0] "" XXX - SG_ CruiseEnabled : 48|1@0+ (1,0) [0|0] "" XXX - SG_ BrakeStatus : 51|1@0+ (1,0) [0|0] "" XXX - SG_ CruiseButtons : 4|2@0+ (1,0) [0|3] "" XXX - -BO_ 320 Throttle: 8 XXX - SG_ ThrottlePosition : 7|8@0+ (1,0) [0|255] "" XXX - -BO_ 209 NEW_MSG_1: 8 XXX - SG_ BrakePosition : 23|8@0+ (1,0) [0|255] "" XXX - -BO_ 2 Steering: 8 XXX - SG_ SteeringAngle : 7|16@0- (0.1,0) [-500|500] "degree" XXX - -BO_ 642 NEW_MSG_2: 8 XXX - SG_ TurnSignal : 45|2@0+ (1,0) [0|3] "" XXX - - - -CM_ "CHFFR_METRIC 2 STEER_ANGLE STEER_ANGLE 0.36 180"; - -VAL_ 324 BrakeApplied 1 "On" 0 "Off" ; -VAL_ 324 CruiseEnabled 1 "On" 0 "Off" ; -VAL_ 324 BrakeStatus 1 "On" 0 "Off" ; -VAL_ 324 CruiseButtons 2 "Set" 1 "Resume" ; - -VAL_ 642 TurnSignal 2 "Left" 1 "Right" ; diff --git a/opendbc/tesla_can.dbc b/opendbc/tesla_can.dbc index 37d839e44671c3..c257fe2e032f77 100644 --- a/opendbc/tesla_can.dbc +++ b/opendbc/tesla_can.dbc @@ -307,6 +307,8 @@ BO_ 840 GTW_status: 8 GTW SG_ GTW_statusChecksum : 63|8@0+ (1,0) [0|255] "" NEO SG_ GTW_statusCounter : 51|4@0+ (1,0) [0|15] "" NEO +CM_ "CHFFR_METRIC 1160 DAS_steeringAngleRequest STEER_ANGLE 0.1098666 180; CHFFR_METRIC 264 DI_motorRPM ENGINE_RPM 1 0"; + VAL_ 3 StW_Angl 16383 "SNA" ; VAL_ 3 StW_AnglSens_Id 2 "MUST" 0 "PSBL" 1 "SELF" ; VAL_ 3 StW_AnglSens_Stat 2 "ERR" 3 "ERR_INI" 1 "INI" 0 "OK" ; @@ -417,5 +419,3 @@ VAL_ 904 MCU_clusterReadyForDrive 0 "NO_SNA" 1 "YES" ; VAL_ 1160 DAS_steeringAngleRequest 16384 "ZERO_ANGLE" ; VAL_ 1160 DAS_steeringControlType 1 "ANGLE_CONTROL" 3 "DISABLED" 0 "NONE" 2 "RESERVED" ; VAL_ 1160 DAS_steeringHapticRequest 1 "ACTIVE" 0 "IDLE" ; - -CM_ "CHFFR_METRIC 1160 DAS_steeringAngleRequest STEER_ANGLE 0.1098666 180; CHFFR_METRIC 264 DI_motorRPM ENGINE_RPM 1 0"; diff --git a/opendbc/tesla_radar.dbc b/opendbc/tesla_radar.dbc new file mode 100644 index 00000000000000..e7b9cbc055efd6 --- /dev/null +++ b/opendbc/tesla_radar.dbc @@ -0,0 +1,1371 @@ +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: FrontCamera Radar + + +BO_ 769 TeslaRadarSguInfo: 8 Radar + SG_ RADC_VerticalMisalignment : 0|8@1+ (1,0) [0|255] "" FrontCamera + SG_ RADC_SCUTemperature : 8|8@1+ (1,-128) [-128|127] "" FrontCamera + SG_ RADC_VMA_Plaus : 16|8@1+ (1,0) [0|255] "" FrontCamera + SG_ RADC_SGU_ITC : 24|8@1+ (1,0) [0|255] "" FrontCamera + SG_ RADC_HorizontMisalignment : 32|12@1+ (1,0) [0|4096] "" FrontCamera + SG_ RADC_SensorDirty : 44|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_HWFail : 45|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_SGUFail : 46|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_SGUInfoConsistBit : 47|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 770 TeslaRadarTguInfo: 8 Radar + SG_ RADC_ACCTargObj1_sguIndex : 0|6@1+ (1,0) [0|63] "" FrontCamera + SG_ RADC_ACCTargObj2_sguIndex : 6|6@1+ (1,0) [0|63] "" FrontCamera + SG_ RADC_ACCTargObj3_sguIndex : 12|6@1+ (1,0) [0|63] "" FrontCamera + SG_ RADC_ACCTargObj4_sguIndex : 18|6@1+ (1,0) [0|63] "" FrontCamera + SG_ RADC_ACCTargObj5_sguIndex : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ unused30 : 30|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_TGUInfoConsistBit : 31|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_ACCTargObj1_dBPower : 32|16@1+ (1,0) [0|65535] "" FrontCamera + SG_ RADC_ACCTargObj5_dBPower : 48|16@1+ (1,0) [0|65535] "" FrontCamera + +BO_ 1281 TeslaRadarAlertMatrix: 8 Radar + SG_ RADC_a001_ecuInternalPerf : 0|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a002_flashPerformance : 1|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a003_vBatHigh : 2|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a004_adjustmentNotDone : 3|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a005_adjustmentReq : 4|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a006_adjustmentNotOk : 5|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a007_sensorBlinded : 6|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a008_plantModeActive : 7|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a009_configMismatch : 8|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a010_canBusOff : 9|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a011_bdyMIA : 10|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a012_espMIA : 11|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a013_gtwMIA : 12|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a014_sccmMIA : 13|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a015_adasMIA : 14|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a016_bdyInvalidCount : 15|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a017_adasInvalidCount : 16|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a018_espInvalidCount : 17|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a019_sccmInvalidCount : 18|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a020_bdyInvalidChkSm : 19|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a021_espInvalidChkSm : 20|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a022_sccmInvalidChkSm : 21|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a023_sccmInvalidChkSm : 22|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a024_absValidity : 23|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a025_ambTValidity : 24|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a026_brakeValidity : 25|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a027_CntryCdValidity : 26|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a028_espValidity : 27|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a029_longAccOffValidity : 28|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a030_longAccValidity : 29|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a031_odoValidity : 30|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a032_gearValidity : 31|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a033_steerAngValidity : 32|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a034_steerAngSpdValidity : 33|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a035_indctrValidity : 34|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a036_vehStandStillValidity : 35|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a037_vinValidity : 36|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a038_whlRotValidity : 37|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a039_whlSpdValidity : 38|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a040_whlStandStillValidity : 39|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a041_wiperValidity : 40|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a042_xwdValidity : 41|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a043_yawOffValidity : 42|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a044_yawValidity : 43|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a045_bsdSanity : 44|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a046_rctaSanity : 45|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a047_lcwSanity : 46|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a048_steerAngOffSanity : 47|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a049_tireSizeSanity : 48|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a050_velocitySanity : 49|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a051_yawSanity : 50|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a052_radomeHtrInop : 51|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a053_espmodValidity : 52|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a054_gtwmodValidity : 53|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a055_stwmodValidity : 54|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a056_bcmodValidity : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a057_dimodValidity : 56|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a058_opmodValidity : 57|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a059_drmiInvalidChkSm : 58|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a060_drmiInvalidCount : 59|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a061_radPositionMismatch : 60|1@1+ (1,0) [0|1] "" FrontCamera + SG_ RADC_a062_strRackMismatch : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ unused62 : 62|2@1+ (1,0) [0|3] "" FrontCamera + +BO_ 784 M_310hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 785 M_310hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 787 M_313hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 788 M_313hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 790 M_316hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 791 M_316hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 793 M_319hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 794 M_319hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 796 M_31Chex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 797 M_31Chex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 799 M_31Fhex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 800 M_31Fhex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 802 M_322hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 803 M_322hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 805 M_325hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 806 M_325hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 808 M_328hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 809 M_328hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 811 M_32Bhex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 812 M_32Bhex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 814 M_32Ehex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 815 M_32Ehex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 817 M_331hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 818 M_331hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 820 M_334hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 821 M_334hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 823 M_337hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 824 M_337hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 826 M_33Ahex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 827 M_33Ahex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 829 M_33Dhex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 830 M_33Dhex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 832 M_340hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 833 M_340hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 835 M_343hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 836 M_343hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 838 M_346hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 839 M_346hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 841 M_349hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 842 M_349hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 844 M_34Chex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 845 M_34Chex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 847 M_34Fhex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 848 M_34Fhex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 850 M_352hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 851 M_352hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 853 M_355hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 854 M_355hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 856 M_358hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 857 M_358hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 859 M_35Bhex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 860 M_35Bhex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 862 M_35Ehex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 863 M_35Ehex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 865 M_361hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 866 M_361hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 868 M_364hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 869 M_364hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 871 M_367hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 872 M_367hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 874 M_36Ahex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 875 M_36Ahex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 877 M_36Dhex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 878 M_36Dhex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 881 L_1_371hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 882 L_1_371hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 884 L_2_374hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 885 L_2_375hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 887 L_3_377hex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 888 L_3_378hex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 890 L_4_37ahex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 891 L_4_37ahex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 893 L_5_37dhex: 8 Radar + SG_ LongDist : 0|12@1+ (0.0625,0) [0|255.9] "meters" FrontCamera + SG_ LongSpeed : 12|12@1+ (0.0625,-128) [-128|128] "meters/sec" FrontCamera + SG_ LatDist : 24|11@1+ (0.125,-128) [-128|128] "meters" FrontCamera + SG_ ProbExist : 35|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ LongAccel : 40|10@1+ (0.03125,-16) [-16|16] "meters/sec/sec" FrontCamera + SG_ ProbObstacle : 50|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Valid : 55|1@1+ (1,0) [0|1] "" FrontCamera + SG_ ProbNonObstacle : 56|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Meas : 61|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Tracked : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 894 L_5_37dhex2: 8 Radar + SG_ LatSpeed : 0|10@1+ (0.125,-64) [-64|64] "meters/sec" FrontCamera + SG_ Length : 10|6@1+ (0.125,0) [0|7.875] "m" FrontCamera + SG_ dZ : 16|6@1+ (0.25,-5) [-5|10.75] "m" FrontCamera + SG_ MovingState : 22|2@1+ (1,0) [0|3] "" FrontCamera + SG_ dxSigma : 24|6@1+ (1,0) [0|63] "" FrontCamera + SG_ vxSigma : 30|6@1+ (1,0) [0|63] "" FrontCamera + SG_ axSigma : 36|6@1+ (1,0) [0|63] "" FrontCamera + SG_ dySigma : 42|6@1+ (1,0) [0|63] "" FrontCamera + SG_ ProbClass : 48|5@1+ (3.125,0) [0|96.875] "%" FrontCamera + SG_ Class : 53|3@1+ (1,0) [0|7] "" FrontCamera + SG_ dxRearEndLoss : 56|6@1+ (1,0) [0|63] "" FrontCamera + SG_ NotUsed : 62|1@1+ (1,0) [0|1] "" FrontCamera + SG_ Index2 : 63|1@1+ (1,0) [0|1] "" FrontCamera + +BO_ 697 VIN_VIP_405HS: 8 FrontCamera + SG_ VIN_MuxID M : 0|8@1+ (1,0) [0|0] "" Radar + SG_ VIN_Part1 m16 : 47|24@0+ (1,0) [0|16777215] "" Radar + SG_ VIN_Part2 m17 : 15|56@0+ (1,0) [0|7.2057594038E+16] "" Radar + SG_ VIN_Part3 m18 : 15|56@0+ (1,0) [0|7.2057594038E+16] "" Radar + +BO_ 681 Msg2A9_GTW_carConfig: 8 FrontCamera + SG_ Msg2A9_Always0x02 : 48|8@1+ (1,0) [0|0] "" Radar + SG_ Msg2A9_Always0x10 : 56|8@1+ (1,0) [0|0] "" Radar + SG_ Msg2A9_Always0x16 : 8|8@1+ (1,0) [0|0] "" Radar + SG_ Msg2A9_Always0x41 : 24|8@1+ (1,0) [0|0] "" Radar + SG_ Msg2A9_Value1_0x02 : 0|3@1+ (1,0) [0|0] "" Radar + SG_ Msg2A9_FourWheelDrive : 3|2@1+ (1,0) [0|0] "" Radar + SG_ Msg2A9_Value2_0x02 : 5|3@1+ (1,0) [0|0] "" Radar + SG_ Msg2A9_Always0x43 : 16|8@1+ (1,0) [0|0] "" Radar + +BO_ 409 Msg199_STW_ANGLHP_STAT: 8 FrontCamera + SG_ Msg199Always0x04 : 32|8@1+ (1,0) [0|0] "" Radar + SG_ Msg199Always0x20 : 16|8@1+ (1,0) [0|0] "" Radar + SG_ Msg199Always0x2F : 0|8@1+ (1,0) [0|0] "" Radar + SG_ Msg199Always0x67 : 8|8@1+ (1,0) [0|0] "" Radar + SG_ Msg199Always0xFF : 40|8@1+ (1,0) [0|0] "" Radar + SG_ Msg199Checksum : 56|8@1+ (1,0) [0|0] "" Radar + SG_ Msg199Counter : 52|4@1+ (1,0) [0|0] "" Radar + +BO_ 361 Msg169_ESP_wheelSpeeds: 8 FrontCamera + SG_ ESP_wheelSpeedFrL_HS : 0|13@1+ (0.04,0) [0|327.64] "km/h" Radar + SG_ ESP_wheelSpeedFrR_HS : 13|13@1+ (0.04,0) [0|327.64] "km/h" Radar + SG_ ESP_wheelSpeedReL_HS : 26|13@1+ (0.04,0) [0|327.64] "km/h" Radar + SG_ ESP_wheelSpeedReR_HS : 39|13@1+ (0.04,0) [0|327.64] "km/h" Radar + SG_ Msg169Checksum : 56|8@1+ (1,0) [0|0] "" Radar + SG_ Msg169Counter : 52|4@1+ (1,0) [0|0] "" Radar + +BO_ 345 Msg159_ESP_C: 8 FrontCamera + SG_ Msg159Always0x3A : 16|8@1+ (1,0) [0|0] "" Radar + SG_ Msg159Always0xA5 : 0|8@1+ (1,0) [0|0] "" Radar + SG_ Msg159Always0xCF : 32|8@1+ (1,0) [0|0] "" Radar + SG_ Msg159Always0xF4 : 8|8@1+ (1,0) [0|0] "" Radar + SG_ Msg159Counter : 44|4@1+ (1,0) [0|0] "" Radar + SG_ Msg159Checksum : 24|8@1+ (1,0) [0|0] "" Radar + +BO_ 329 Msg149_ESP_145h: 8 FrontCamera + SG_ Msg149Always0x02 : 16|8@1+ (1,0) [0|0] "" Radar + SG_ Msg149Always0x04 : 40|8@1+ (1,0) [0|0] "" Radar + SG_ Msg149Always0x26 : 8|8@1+ (1,0) [0|0] "" Radar + SG_ Msg149Always0x6A : 24|8@1+ (1,0) [0|0] "" Radar + SG_ Msg149Always0xAA : 32|8@1+ (1,0) [0|0] "" Radar + SG_ Msg149Always0xF : 48|4@1+ (1,0) [0|0] "" Radar + SG_ Msg149Checksum : 56|8@1+ (1,0) [0|0] "" Radar + SG_ Msg149Counter : 52|4@1+ (1,0) [0|0] "" Radar + +BO_ 297 Msg129_ESP_115h: 6 FrontCamera + SG_ Msg129Always0x20 : 24|8@1+ (1,0) [0|0] "" Radar + SG_ Msg129Checksum : 40|8@1+ (1,0) [0|0] "" Radar + SG_ Msg129Counter : 36|4@1+ (1,0) [0|0] "" Radar + +BO_ 281 Msg119_DI_torque2: 6 FrontCamera + SG_ Msg119Always0x11 : 24|8@1+ (1,0) [0|0] "" Radar + SG_ Msg119Always0x1F : 8|8@1+ (1,0) [0|0] "" Radar + SG_ Msg119Always0x8 : 36|4@1+ (1,0) [0|0] "" Radar + SG_ Msg119Always0xF4 : 16|8@1+ (1,0) [0|0] "" Radar + SG_ Msg119Always0xFF : 0|8@1+ (1,0) [0|0] "" Radar + SG_ Msg119Checksum : 40|8@1+ (1,0) [0|0] "" Radar + SG_ Msg119Counter : 32|4@1+ (1,0) [0|0] "" Radar + +BO_ 265 Msg109_DI_torque1: 8 FrontCamera + SG_ Msg109Always0x80 : 24|8@1+ (1,0) [0|0] "" Radar + SG_ Msg109Checksum : 56|8@1+ (1,0) [0|0] "" Radar + SG_ Msg109Counter : 13|3@1+ (1,0) [0|0] "" Radar + +BO_ 521 Msg209_GTW_odo: 8 FrontCamera + SG_ Msg209Always0x61 : 8|8@1+ (1,0) [0|0] "" Radar + SG_ Msg209Always0x94 : 16|8@1+ (1,0) [0|0] "" Radar + SG_ Msg209Always0x52 : 24|8@1+ (1,0) [0|0] "" Radar + SG_ Msg209Always0x13 : 32|8@1+ (1,0) [0|0] "" Radar + SG_ Msg209Always0x03 : 40|8@1+ (1,0) [0|0] "" Radar + SG_ Msg209Always0x80 : 48|8@1+ (1,0) [0|0] "" Radar + +BO_ 537 Msg219_STW_ACTN_RQ: 8 FrontCamera + SG_ Msg219Counter : 52|4@1+ (1,0) [0|15] "" Radar + SG_ Msg219CRC : 56|8@1+ (1,0) [0|0] "" Radar + +BO_ 425 Msg1A9_DI_espControl: 5 FrontCamera + SG_ Msg1A9Always0x0C : 16|8@1+ (1,0) [0|0] "" Radar + SG_ Msg1A9Counter : 28|4@1+ (1,0) [0|0] "" Radar + SG_ Msg1A9Checksum : 32|8@1+ (1,0) [0|0] "" Radar + +BO_ 729 Msg2D9_BC_status : 8 FrontCamera + SG_ Msg2D9Always0x80 : 0|8@1+ (1,0) [0|0] "" Radar + SG_ Msg2D9Always0x40 : 8|8@1+ (1,0) [0|0] "" Radar + SG_ Msg2D9Always0x83 : 16|8@1+ (1,0) [0|0] "" Radar + +BO_ 1601 UDS_radarRequest: 8 FrontCamera + SG_ UDS_radarRequestData : 7|64@0+ (1,0) [0|0] "" Radar + +BO_ 1617 Radar_udsResponse: 8 Radar + SG_ Radar_udsResponseData : 7|64@0+ (1,0) [0|0] "" FrontCamera + +CM_ BO_ 697 "Start with MuxID 0x12, then 0x11 and finally 0x10 (VIN is then transmitted in the reverse order)"; +CM_ BO_ 681 "Message sent every 1000 ms. All fixed bytes, no checksum, the byte for RWD or AWD needs to match VIN config"; +CM_ BO_ 409 "Message sent every 10ms. Checksum : use all first 7 bytes with the SAE J1850 CRC algo"; +CM_ BO_ 361 "Message sent every 10ms. Checksum : Sum of all first 7 bytes + 0x76"; +CM_ BO_ 345 "Message sent every 20ms. Checksum : Sum of all first bytes + 0xc; place checksum in 4th octet"; +CM_ BO_ 329 "Message sent every 20ms. Checksum : Sum of all first 7 bytes + 0x46"; +CM_ BO_ 297 "Message sent every 20ms. Checksum : Sum of all first 5 bytes + 0x16"; +CM_ BO_ 281 "Message sent every 10ms. Checksum : Sum of all first 5 bytes + 0x17"; +CM_ BO_ 265 "Message sent every 10ms. Checksum : Sum of all first 7 bytes + 0x7"; +CM_ BO_ 521 "Message sent every 100ms. All fixed bytes, no checksum."; +CM_ BO_ 537 "Message sent every 100ms. Checksum : use all first 7 bytes with the SAE J1850 CRC algo"; +CM_ BO_ 425 "Message sent every 20ms. Checksum : Sum of all first 4 bytes + 0x38"; +CM_ BO_ 729 "Message sent every 1000ms. All fixed bytes, no checksum."; + +BA_DEF_ "BusType" STRING ; +BA_DEF_ BO_ "GenMsgCycleTime" INT 0 0; +BA_DEF_ SG_ "FieldType" STRING ; + +BA_DEF_DEF_ "BusType" "CAN"; +BA_DEF_DEF_ "FieldType" ""; +BA_DEF_DEF_ "GenMsgCycleTime" 0; + +BA_ "GenMsgCycleTime" BO_ 697 250; +BA_ "GenMsgCycleTime" BO_ 681 1000; +BA_ "GenMsgCycleTime" BO_ 409 10; +BA_ "GenMsgCycleTime" BO_ 361 10; +BA_ "GenMsgCycleTime" BO_ 345 20; +BA_ "GenMsgCycleTime" BO_ 329 20; +BA_ "GenMsgCycleTime" BO_ 297 20; +BA_ "GenMsgCycleTime" BO_ 281 10; +BA_ "GenMsgCycleTime" BO_ 265 10; +BA_ "GenMsgCycleTime" BO_ 521 100; +BA_ "GenMsgCycleTime" BO_ 537 100; +BA_ "GenMsgCycleTime" BO_ 425 20; +BA_ "GenMsgCycleTime" BO_ 729 1000; + +VAL_ 681 Msg2A9_FourWheelDrive 3 "SNA" 2 "UNUSED" 1 "4WD" 0 "2WD" ; +VAL_ 785 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 785 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 788 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 788 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 791 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 791 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 794 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 794 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 797 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 797 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 800 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 800 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 803 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 803 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 806 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 806 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 809 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 809 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 812 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 812 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 815 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 815 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 818 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 818 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 821 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 821 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 824 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 824 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 827 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 827 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 830 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 830 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 833 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 833 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 836 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 836 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 839 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 839 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 842 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 842 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 845 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 845 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 848 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 848 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 851 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 851 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 854 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 854 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 857 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 857 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 860 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 860 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 863 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 863 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 866 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 866 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 869 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 869 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 872 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 872 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 875 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 875 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 878 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 878 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 882 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 882 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 885 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 885 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 888 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 888 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 891 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 891 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; +VAL_ 894 MovingState 3 "RADAR_MOVESTATE_STANDING" 2 "RADAR_MOVESTATE_STOPPED" 1 "RADAR_MOVESTATE_MOVING" 0 "RADAR_MOVESTATE_INDETERMINATE" ; +VAL_ 894 Class 4 "RADAR_CLASS_CONSTRUCTION_ELEMENT" 3 "RADAR_CLASS_MOVING_PEDESTRIAN" 2 "RADAR_CLASS_MOVING_TWO_WHEEL_VEHICLE" 1 "RADAR_CLASS_MOVING_FOUR_WHEEL_VEHICLE" 0 "RADAR_CLASS_UNKNOWN" ; + diff --git a/opendbc/toyota_2017_ref_pt.dbc b/opendbc/toyota_2017_ref_pt.dbc new file mode 100644 index 00000000000000..17cd8f1b36900e --- /dev/null +++ b/opendbc/toyota_2017_ref_pt.dbc @@ -0,0 +1,1638 @@ +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: AFS BSR CGW CSR DS1 FCM FRD KSS MAV SCS Vector__XXX + + +BO_ 1196 ABG1D50: 8 CGW + SG_ DRABG01 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRABG02 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRABG03 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRABG04 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRABG05 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRABG06 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRABG07 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRABG08 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1212 ABG1D51: 8 CGW + SG_ DRABG09 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRABG10 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRABG11 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRABG12 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRABG13 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRABG14 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRABG15 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRABG16 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 945 ABG1S01: 8 CGW + SG_ CDT : 22|3@0+ (1,0) [0|0] "" DS1 + SG_ AB : 19|2@0+ (1,0) [0|0] "" DS1 + SG_ DBKLAB : 17|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ PODT : 27|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ PBKLAB : 25|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ EDRTRG : 44|2@0+ (1,0) [0|0] "" DS1 + +BO_ 836 ACC1F01: 8 DS1 + SG_ DSS1GDRV : 7|10@0- (0.1,0) [0|0] "m/s^2" Vector__XXX + SG_ DS1STAT2 : 13|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ DS1STBK2 : 10|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSWAR : 18|1@0+ (1,0) [0|0] "" FCM + SG_ PCSALM : 17|1@0+ (1,0) [0|0] "" FCM + SG_ PCSOPR : 16|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSABK : 31|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PBATRGR : 30|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ PPTRGR : 28|1@0+ (1,0) [0|0] "" FCM + SG_ IBTRGR : 27|1@0+ (1,0) [0|0] "" FCM + SG_ CLEXTRGR : 26|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ IRLT_REQ : 25|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ BRKHLD : 37|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ AVSTRGR : 36|1@0+ (1,0) [0|0] "" SCS + SG_ VGRSTRGR : 35|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ PREFILL : 33|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PBRTRGR : 32|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSDIS : 43|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PBPREPMP : 40|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ACCF01SM : 63|8@0+ (1,0) [0|0] "" FCM + +BO_ 1227 ACC1N01: 8 DS1 + SG_ ACCNID : 7|8@0+ (1,0) [0|0] "" CGW + SG_ ACCSNG : 15|1@0+ (1,0) [0|0] "" CGW + SG_ ACCSPF : 23|16@0+ (1,0) [0|0] "" CGW + SG_ ACCREV : 39|32@0+ (1,0) [0|0] "" CGW + +BO_ 835 ACC1S03: 8 DS1 + SG_ ATACC2 : 7|16@0- (0.001,0) [0|0] "m/s^2" Vector__XXX + SG_ ACCTYPE : 23|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ XTRGT2 : 21|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XLTMD2 : 20|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LCDT2 : 19|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LCNG : 18|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SMC : 17|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ STOKJD : 31|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PMTBRKG : 30|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LVSTP : 29|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LCCWOK : 25|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LCBW2 : 24|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CACC : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ AT_RAW : 47|8@0- (0.05,0) [0|0] "m/s^2" Vector__XXX + SG_ ACC03SUM : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 896 ACN1S01: 8 CGW + SG_ R_AC2 : 6|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ R_HTR : 5|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ECOSW : 2|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ R_EGON : 1|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ BLWON : 15|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SCAC : 13|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CGIH : 23|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ FAN_AC : 22|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ ACHI : 20|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ACMAX : 19|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ R_VSCUS : 31|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ R_SHTR : 30|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ R_PTC : 29|2@0+ (1,0) [0|0] "piece" Vector__XXX + SG_ GNRTIH : 27|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ R_COL_TM : 26|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ R_HET_TM : 24|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TAMOUT : 55|8@0- (0.625,0) [0|0] "" Vector__XXX + +BO_ 897 ACN1S04: 8 CGW + SG_ R_ACCALL : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ R_AC_WNG : 6|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ R_SW_CON : 5|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ R_BEEP : 4|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_RA_AUT : 3|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_RA_AC : 2|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_RA_LO : 1|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_RA_HI : 0|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_AUTO_D : 15|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_AUTO_P : 14|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_DEF : 13|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_RRDEF : 12|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_RFAUT : 11|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_REC : 10|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_FRS : 9|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_AC : 8|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_MHTR : 23|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_WIPD : 22|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_DUSY : 21|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_SWNG : 20|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_BLW_F : 19|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_OAUT_D : 31|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_OLET_D : 30|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_OAUT_P : 27|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_OLET_P : 26|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ ST_BMN_F : 39|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_AIRPR : 47|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_O2 : 46|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_PLSM : 45|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_KAFUN : 43|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_SAFS : 42|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_ACOFF : 41|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ R_ONSCRN : 40|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 944 ACN1S07: 6 CGW + SG_ RDEF : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ MHTR : 6|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TR_TEMP : 15|8@0+ (0.25,-6.5) [0|0] "" Vector__XXX + SG_ ACN_AMB : 31|8@0+ (1,0) [0|0] "" CSR,DS1,FCM + SG_ AC_AMB05 : 44|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ AC_MODE : 43|2@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1250 AFS1N01: 8 AFS + SG_ AFSNID : 7|8@0+ (1,0) [0|0] "" CGW + SG_ AFSSNG : 15|1@0+ (1,0) [0|0] "" CGW + SG_ AFSSPF : 23|16@0+ (1,0) [0|0] "" CGW + SG_ AFSREV : 39|32@0+ (1,0) [0|0] "" CGW + +BO_ 913 AFS1S01: 8 AFS + SG_ HLLI : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ AZB_ADV : 5|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ HEDH_AZB : 3|1@0+ (1,0) [0|0] "" FCM + SG_ AZB_IND : 13|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ AZB_HIND : 11|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ AZB_PRE : 10|1@0+ (1,0) [0|0] "" FCM + SG_ LED_HLI : 9|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ LPECU_PR : 24|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 845 AFS1S02: 5 AFS + SG_ AHRR : 17|10@0+ (0.0048828125,0) [0|0] "V" Vector__XXX + SG_ AHVLD : 39|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ AHFAIL : 38|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1044 AHB1S01: 8 FCM + SG_ AHB_DUTY : 47|8@0+ (0.5,0) [0|0] "%" Vector__XXX + SG_ F_AHB : 55|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ C_AHB : 51|4@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 900 AVN1S01: 6 CGW + SG_ RDC : 7|4@0+ (1,0) [0|0] "" SCS + SG_ CONFID01 : 3|2@0+ (1,0) [0|0] "" SCS + SG_ CONF : 1|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ LYT : 15|4@0+ (1,0) [0|0] "" SCS + SG_ DRVW : 9|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ MWMP : 8|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ GRAD : 23|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ HARSHID : 19|4@0+ (1,0) [0|0] "" SCS + SG_ BRANCH : 27|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ HARSH : 35|2@0+ (1,0) [0|0] "" SCS + SG_ TOLLGATE : 33|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TUNL : 32|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LEAVEOUT : 47|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ MRGLANE : 46|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LVLANE : 45|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 902 AVN1S03: 6 CGW + SG_ ANS : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CRS1 : 15|1@0+ (1,0) [0|0] "" SCS + SG_ RQAC : 14|7@0+ (0.02,0) [0|0] "G" Vector__XXX + SG_ GUID : 23|1@0+ (1,0) [0|0] "" SCS + SG_ GYRO : 22|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ NCRN : 21|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CRN6 : 20|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CRN5 : 19|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CRN3 : 18|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CRN2 : 17|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CRN1 : 16|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CONFID03 : 31|2@0+ (1,0) [0|0] "" SCS + SG_ CURV : 29|2@0+ (1,0) [0|0] "" SCS + SG_ CVST : 27|1@0+ (1,0) [0|0] "" SCS + SG_ NAVI_STR : 26|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ MIND : 25|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ONOFF : 24|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ HWPB : 39|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ RAD : 38|7@0+ (5,0) [0|0] "m" SCS + SG_ AFS_SW : 41|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ AVS_SW : 40|1@0+ (1,0) [0|0] "" SCS + +BO_ 911 AVN1S07: 8 CGW + SG_ TOFC_RST : 6|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SL_CSTM : 3|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SL_RMDG : 2|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ST_RTCOM : 1|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ AVN07VLD : 0|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ST_UCST : 15|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ RSCOM51 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ RSCOM52 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ RSCOM53 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ RSCOM54 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ RSCOM55 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ RSCOM56 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 905 AVN1S08: 8 CGW + SG_ VVSW : 7|3@0+ (1,0) [0|0] "" CSR + SG_ BZV : 4|3@0+ (1,0) [0|0] "" CSR + SG_ DFS : 1|2@0+ (1,0) [0|0] "" CSR + SG_ BZ_M_SW : 15|1@0+ (1,0) [0|0] "" CSR + SG_ VOL_SW : 14|1@0+ (1,0) [0|0] "" CSR + SG_ BM : 13|1@0+ (1,0) [0|0] "" CSR + SG_ DOFR : 12|1@0+ (1,0) [0|0] "" CSR + SG_ RDSW : 11|1@0+ (1,0) [0|0] "" CSR + SG_ FDSW : 10|1@0+ (1,0) [0|0] "" CSR + SG_ RBSW : 9|1@0+ (1,0) [0|0] "" CSR + SG_ FBSW : 8|1@0+ (1,0) [0|0] "" CSR + SG_ NVDP_OK : 23|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ DEVICE : 22|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ DISPSIZE : 31|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ HPTCSW_L : 30|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ HPTCSW_R : 29|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ HPTCSW_E : 28|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ D_MODE : 27|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ VARBGM : 26|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ WBGM : 24|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ X_LL : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ Y_LL : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ X_RH : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ Y_RH : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 998 AVN1S11: 5 CGW + SG_ SENSPFM : 7|3@0+ (1,0) [0|0] "" SCS + SG_ SENSFAIL : 4|3@0+ (1,0) [0|0] "" SCS + SG_ CONFID11 : 1|2@0+ (1,0) [0|0] "" SCS + SG_ CONFMMC : 15|8@0+ (1,0) [0|0] "" SCS + SG_ DISTERR : 23|8@0+ (1,0) [0|0] "" SCS + SG_ CONFLANE : 31|8@0+ (1,0) [0|0] "" SCS + SG_ CONFDIR : 39|8@0+ (1,0) [0|0] "" SCS + +BO_ 933 AVN1S13: 8 CGW + SG_ HUD_DISP : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRVSIDE : 6|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ DT_GP : 5|6@0+ (1,0) [0|0] "" Vector__XXX + SG_ DT_UNIT : 15|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ DIR_TURN : 12|5@0+ (11.25,0) [0|0] "degree" Vector__XXX + SG_ ROTARY : 23|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ROAD_TP1 : 22|15@0+ (1,0) [0|0] "" Vector__XXX + SG_ ROAD_TP2 : 39|16@0+ (1,0) [0|0] "" Vector__XXX + SG_ N_H_UP : 55|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ COMPASS : 54|6@0+ (11.25,0) [0|0] "degree" Vector__XXX + SG_ DIR : 63|6@0+ (11.25,0) [0|0] "degree" Vector__XXX + +BO_ 936 AVN1S16: 5 CGW + SG_ NDADVSRY : 7|5@0+ (1,0) [0|0] "" Vector__XXX + SG_ NDCAUTON : 15|5@0+ (1,0) [0|0] "" Vector__XXX + SG_ NDSSLCT : 23|5@0+ (1,0) [0|0] "" Vector__XXX + SG_ NDCNFDID : 18|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ NDINDST : 25|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ AVN16SUM : 39|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 999 AVN1S17: 7 CGW + SG_ AVN17VLD : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANEID17 : 6|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRVLANE : 3|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRV_SIDE : 12|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE_NS : 11|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE1FLG : 23|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE2FLG : 19|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE1DIR : 31|16@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE2DIR : 47|16@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1000 AVN1S18: 8 CGW + SG_ AVN18VLD : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANEID18 : 6|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE3FLG : 3|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE4FLG : 15|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE5FLG : 11|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE3DIR : 23|16@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE4DIR : 39|16@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE5DIR : 55|16@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1001 AVN1S19: 8 CGW + SG_ AVN19VLD : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANEID19 : 6|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE6FLG : 3|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE7FLG : 15|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE8FLG : 11|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE6DIR : 23|16@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE7DIR : 39|16@0+ (1,0) [0|0] "" Vector__XXX + SG_ LANE8DIR : 55|16@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1076 AVN1S20: 8 CGW + SG_ A_LNG_ST : 7|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_LANG : 5|6@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_LNGDB1 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_LNGDB2 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_LNGDB3 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_LNGDB4 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_LNGDB5 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_LNGDB6 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_LNGDB7 : 63|7@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_LNGCHG : 56|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1077 AVN1S21: 8 CGW + SG_ A_OPEN_S : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ OPENCHG : 6|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CAPSW_S : 5|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_CLR_S : 3|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ DISP_BRT : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DISP_CNT : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ MM_CLOCK : 31|11@0+ (1,0) [0|0] "" Vector__XXX + SG_ CLK_OFST : 36|4@0- (5,0) [0|0] "min" Vector__XXX + SG_ DST : 32|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CLK_TYP : 47|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_UNTTMP : 45|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_UNTSP : 43|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_UNTDST : 41|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_UNTCSP : 55|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_CLRCHG : 52|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_TMPCHG : 51|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_SPCHG : 50|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_DSTCHG : 49|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_CSPCHG : 48|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ A_SPLM : 63|6@0+ (5,0) [0|0] "" Vector__XXX + SG_ A_UTSPLM : 57|2@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1043 AVN1S31: 8 CGW + SG_ GPSTM_Y : 7|8@0+ (1,0) [0|0] "year" Vector__XXX + SG_ GPSTM_MO : 15|8@0+ (1,0) [0|0] "month" Vector__XXX + SG_ GPSTM_D : 23|8@0+ (1,0) [0|0] "day" Vector__XXX + SG_ GPSTM_H : 31|8@0+ (1,0) [0|0] "hour" Vector__XXX + SG_ GPSTM_MI : 39|8@0+ (1,0) [0|0] "minute" Vector__XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ GMTDIF_H : 54|4@0+ (1,0) [0|0] "hour" Vector__XXX + SG_ GMTDIF_M : 50|6@0+ (1,0) [0|0] "minute" Vector__XXX + SG_ SUMMERTM : 60|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1075054137 BDB1F01_14: 8 CGW + SG_ BDBF01ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ BDBF01IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ SALR : 23|6@0+ (1,0) [0|0] "" Vector__XXX + SG_ HDCY_BDB : 17|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ AARE_B : 31|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ I_SEN_B : 27|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ INTSET_B : 26|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ INCSET_B : 25|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ISSD_BDB : 39|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ SEID : 37|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ WS_ID : 44|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ WS_SWON : 41|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ WS_DATA : 55|16@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1075185211 BDB1F03_16: 8 CGW + SG_ BDBF03ID : 7|8@0+ (1,0) [0|0] "" DS1,FCM,MAV + SG_ BDBF03IF : 15|8@0+ (1,0) [0|0] "" DS1,FCM + SG_ TRIP_CNT : 23|16@0+ (1,0) [0|0] "trip" AFS,BSR,CSR,DS1,FCM,MAV + SG_ TIME_CNT : 39|32@0+ (100,0) [0|0] "ms" AFS,BSR,CSR,DS1,FCM,MAV + +BO_ 1074791968 BDB1S01_10: 8 CGW + SG_ BDB01_ID : 7|8@0+ (1,0) [0|0] "" FCM,MAV + SG_ BDB01_IF : 15|8@0+ (1,0) [0|0] "" FCM + SG_ LX : 23|16@0+ (0.2,0) [0|0] "ms" FCM + SG_ ADIM : 39|2@0+ (1,0) [0|0] "" AFS,BSR,CSR + SG_ IG_BDB : 37|1@0+ (1,0) [0|0] "" AFS,MAV + SG_ ACC_BDB : 36|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SKSW : 46|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ DCTY : 45|1@0+ (1,0) [0|0] "" FCM,MAV,SCS + SG_ PCTY : 44|1@0+ (1,0) [0|0] "" MAV,SCS + SG_ RRCY : 43|1@0+ (1,0) [0|0] "" MAV,SCS + SG_ RLCY : 42|1@0+ (1,0) [0|0] "" MAV,SCS + SG_ BCTY : 41|1@0+ (1,0) [0|0] "" MAV,SCS + SG_ PSW : 51|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ SRBZ : 49|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ DBKL : 63|2@0+ (1,0) [0|0] "" FCM + SG_ PKB_BDB : 60|1@0+ (1,0) [0|0] "" CSR + SG_ SREXIST : 59|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SRPOS : 58|3@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1074857505 BDB1S02_11: 8 CGW + SG_ BDB02_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ BDB02_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ LUD : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ TRNKOPN : 45|3@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1074923042 BDB1S03_12: 8 CGW + SG_ BDB03_ID : 7|8@0+ (1,0) [0|0] "" DS1,FCM + SG_ BDB03_IF : 15|8@0+ (1,0) [0|0] "" DS1,FCM + SG_ LTS : 23|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ PANL : 19|1@0+ (1,0) [0|0] "" BSR,CSR + SG_ UDRL : 31|1@0+ (1,0) [0|0] "" AFS + SG_ HEDH : 30|1@0+ (1,0) [0|0] "" AFS,DS1,FCM + SG_ HEDL : 29|1@0+ (1,0) [0|0] "" AFS,DS1 + SG_ TAIL : 28|1@0+ (1,0) [0|0] "" AFS,BSR,CSR,DS1 + SG_ FFOG : 27|1@0+ (1,0) [0|0] "" DS1 + SG_ RFOG : 26|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SB_IND : 39|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ SB_OK : 37|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ RTRRQ : 35|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SRWARN : 51|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PWWARN : 50|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ WEL_REQ : 48|1@0+ (1,0) [0|0] "" AFS + SG_ DRPBZ_R : 62|3@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1075381795 BDB1S04_19: 8 CGW + SG_ BDB04_ID : 7|8@0+ (1,0) [0|0] "" MAV + SG_ BDB04_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ MRMV_R : 23|2@0+ (1,0) [0|0] "" MAV + SG_ RSEL : 21|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LSEL : 20|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ MHR : 19|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ MHL : 18|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ MVU : 17|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ MVD : 16|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ GHSW : 31|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ GCTY : 30|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ GHOPN : 42|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ ABIF : 55|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ FLSHRQ : 63|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ SB_ADV : 60|2@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1074988600 BDB1S05_13: 8 CGW + SG_ BDB05_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ BDB05_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ PARK : 23|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ TSWB : 21|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LSWD : 20|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LSWP : 19|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LSWR : 18|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LSWL : 17|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LSWB : 16|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRVKS_R : 31|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ PWDRD : 39|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ PWDRP : 37|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ PWDRR : 35|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ PWDRL : 33|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ DKLS : 43|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ BKLS : 54|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ KIDSCN_R : 51|7@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1075250736 BDB1S06_17: 8 CGW + SG_ BDB06_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ BDB06_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ TBSW : 25|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ WBZF : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ WVOL : 42|3@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1075316273 BDB1S07_18: 8 CGW + SG_ BDB07_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ BDB07_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ WCD : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ W1D : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ W2D : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ W3D : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ BDB7SUM1 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ BDB7SUM2 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1075447332 BDB1S08_1A: 8 CGW + SG_ BDB08_ID : 7|8@0+ (1,0) [0|0] "" DS1,FCM,MAV + SG_ BDB08_IF : 15|8@0+ (1,0) [0|0] "" DS1,FCM + SG_ DEST_BDB : 23|8@0+ (1,0) [0|0] "" AFS,BSR,CSR,DS1,FCM,MAV + SG_ DS_PACK1 : 31|8@0+ (1,0) [0|0] "" AFS,BSR,DS1,FCM,MAV + SG_ DS_PACK2 : 39|8@0+ (1,0) [0|0] "" AFS,BSR,DS1,FCM,MAV + SG_ STRG_WHL : 47|2@0+ (1,0) [0|0] "" AFS,CSR,DS1,FCM,MAV + SG_ DEICER : 40|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ KEYPLATE : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DBLLCK : 62|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ U2OP_CST : 61|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ U2OP_DFT : 60|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1075643943 BDB1S11_1D: 8 CGW + SG_ BDB11_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ BDB11_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ BDBREQ11 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ BDBREQ12 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1083704892 BDB1S17_98: 8 CGW + SG_ BDB17_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ BDB17_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ CHABASE1 : 23|8@0+ (1,0) [0|0] "" AFS + SG_ CHABASE2 : 31|8@0+ (1,0) [0|0] "" AFS + SG_ CHABASE3 : 39|8@0+ (1,0) [0|0] "" AFS + SG_ CHA_NO1 : 47|4@0+ (1,0) [0|0] "" AFS + SG_ CHA_NO2 : 43|4@0+ (1,0) [0|0] "" AFS + SG_ CHA_NO3 : 55|4@0+ (1,0) [0|0] "" AFS + SG_ SP_BODY : 63|5@0+ (1,0) [0|0] "" AFS + +BO_ 1083770429 BDB1S18_99: 8 CGW + SG_ BDB18_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ BDB18_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ POP_NAME : 23|8@0+ (1,0) [0|0] "" AFS + SG_ BODY : 31|8@0+ (1,0) [0|0] "" AFS + SG_ GEAR : 39|8@0+ (1,0) [0|0] "" AFS + SG_ GRADE : 47|8@0+ (1,0) [0|0] "" AFS + SG_ ENGINE : 55|8@0+ (1,0) [0|0] "" AFS + +BO_ 1020 BDB1S19: 8 CGW + SG_ SOLAR_R : 23|9@0+ (100,0) [0|0] "" Vector__XXX + SG_ SOLAR_L : 39|9@0+ (100,0) [0|0] "" Vector__XXX + SG_ N_LX : 55|13@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1083835966 BDB1S20_9A: 8 CGW + SG_ BDB20_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ BDB20_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ RNBDYC : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ RNBDYD : 39|32@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1083901503 BDB1S21_9B: 8 CGW + SG_ BDB21_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ BDB21_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ RFOG_SW : 22|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ FFOG_SW : 21|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ HF_SW : 20|1@0+ (1,0) [0|0] "" AFS + SG_ HU_SW : 19|1@0+ (1,0) [0|0] "" AFS + SG_ AUTO_SW : 18|1@0+ (1,0) [0|0] "" AFS + SG_ HEAD_SW : 17|1@0+ (1,0) [0|0] "" AFS + SG_ TAIL_SW : 16|1@0+ (1,0) [0|0] "" AFS + SG_ DRL_OFF : 24|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1005 BGM1S01: 2 CGW + SG_ WCAA : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ R_DISP : 1|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ BGM_BEEP : 11|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ BGM_MODE : 9|2@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1237 BSR1N01: 8 BSR + SG_ BSRNID : 7|8@0+ (1,0) [0|0] "" CGW + SG_ BSRSNG : 15|1@0+ (1,0) [0|0] "" CGW + SG_ BSRSPF : 23|16@0+ (1,0) [0|0] "" CGW + SG_ BSRREV : 39|32@0+ (1,0) [0|0] "" CGW + +BO_ 1014 BSR1S01: 8 BSR + SG_ BSD_STAT : 7|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ BSD_SW : 15|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ BSD_BUZ : 23|1@0+ (1,0) [0|0] "" CSR + +BO_ 1114 CGW1N02: 8 CGW + SG_ CGW2REV : 7|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1228 CSR1N01: 8 CSR + SG_ CSRNID : 7|8@0+ (1,0) [0|0] "" CGW + SG_ CSRSNG : 15|1@0+ (1,0) [0|0] "" CGW + SG_ CSRSPF : 23|16@0+ (1,0) [0|0] "" CGW + SG_ CSRREV : 39|32@0+ (1,0) [0|0] "" CGW + +BO_ 918 CSR1S01: 7 CSR + SG_ CSV : 7|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ CSSR : 4|2@0+ (1,0) [0|0] "" MAV + SG_ CSD : 2|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CSME : 1|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CSIN : 0|1@0+ (1,0) [0|0] "" MAV + SG_ FL_INFO : 15|4@0+ (1,0) [0|0] "" MAV + SG_ FR_INFO : 11|4@0+ (1,0) [0|0] "" MAV + SG_ RB_INFO : 23|4@0+ (1,0) [0|0] "" MAV + SG_ FC_INFO : 19|4@0+ (1,0) [0|0] "" MAV + SG_ RL_INFO : 31|4@0+ (1,0) [0|0] "" MAV + SG_ RR_INFO : 27|4@0+ (1,0) [0|0] "" MAV + SG_ CZV : 39|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ VOT : 47|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ FCZD : 43|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ RCZD : 42|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ FCDD : 41|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ RCDD : 40|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ VOL : 55|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ CDG : 52|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ MUTE : 49|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ BZ_OFF : 48|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1087768273 DMS1S02_D6: 8 CGW + SG_ SS_MODE : 25|2@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 869 DS11D70: 7 DS1 + SG_ D_TRGJDG : 7|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ D_RESSW : 3|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ D_SETSW : 2|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ D_CANSW : 1|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ D_MAINSW : 0|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ D_VMCC : 15|8@0+ (1,0) [0|0] "km/h" Vector__XXX + SG_ D_VNCC : 23|8@0+ (1,0) [0|0] "km/h" Vector__XXX + SG_ D_CCREQ : 31|8@0+ (100,-12800) [0|0] "N" Vector__XXX + SG_ D_TGTDST : 39|8@0+ (1,0) [0|0] "m" Vector__XXX + SG_ D_VRCC : 47|8@0- (1,0) [0|0] "km/h" Vector__XXX + SG_ D_WSTL : 55|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ D_DSW : 54|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ D_FDJDG : 52|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ D_DSSJDG : 51|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 870 DS11D71: 7 DS1 + SG_ XREQALM : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XREQABK : 6|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TGT_DIST : 5|14@0+ (0.01,0) [0|0] "m" Vector__XXX + SG_ XREQPBA : 23|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XREQFPB : 22|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XREQPB : 21|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XREQEXT : 20|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XREQPSB : 19|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TGT_VGAP : 18|11@0+ (0.025,-51.175) [0|0] "m/s" Vector__XXX + SG_ PCSDISP : 39|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ XPCSRDY : 35|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TGT_NUMB : 34|3@0+ (1,1) [0|0] "" Vector__XXX + SG_ TGT_POSX : 47|8@0- (0.04,0) [0|0] "m" Vector__XXX + +BO_ 871 DS11D72: 2 FCM + SG_ LKADRTRG : 7|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ LKADRSHR : 5|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LKADRSLK : 4|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LKADRSLD : 3|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LKADRCC : 2|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ LKADRTUR : 15|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ LKADRINV : 13|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 643 DS11F01: 7 DS1 + SG_ DSCOUNT : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DSLCCW1 : 15|1@0+ (1,0) [0|0] "" FCM + SG_ DSSTPBZ : 14|1@0+ (1,0) [0|0] "" FCM + SG_ PBRTRGR2 : 12|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ DSSFTRQD : 11|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ DSS1FDRV : 23|16@0- (2,0) [0|0] "N" Vector__XXX + SG_ DSS1STBK : 39|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ DSS1STAT : 36|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ DSBHOK : 33|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PPTRGR2 : 32|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ DSRQBH : 47|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ IBTRGR2 : 45|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSABK2 : 44|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSNOCHG : 41|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ DS1F01SM : 55|8@0+ (1,0) [0|0] "" FCM + +BO_ 1041 DS12F02: 8 DS1 + SG_ PCSINDI : 7|2@0+ (1,0) [0|0] "" FCM + SG_ PCSWM : 5|2@0+ (1,0) [0|0] "" FCM + SG_ PCSFCT : 3|1@0+ (1,0) [0|0] "" FCM + SG_ PCSTUCT : 2|1@0+ (1,0) [0|0] "" FCM + SG_ DS1LCCK : 1|2@0+ (1,0) [0|0] "" FCM + SG_ PBTUCT : 14|1@0+ (1,0) [0|0] "" FCM + SG_ PCSEXIST : 13|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSWDUCT : 11|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSWD : 9|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSDW : 39|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSDSRF : 36|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSTEMP : 35|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSDUST : 34|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSLCCK : 33|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSPEDW : 47|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSPVSN : 44|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCTEMP2 : 42|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSDUST2 : 41|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSOFFS : 40|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSWDS : 55|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ FRDADJ : 53|3@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1042 DS12F03: 8 FCM + SG_ LKAINDI : 7|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ LKAWLSL : 5|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ LKAWLSR : 3|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ LKAFCT : 15|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LKATUCT : 14|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LKACAMT : 13|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LDWEXIST : 10|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LKASPCND : 23|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ LKAWTCS : 18|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ LKASAUT : 16|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LDWBZ : 32|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LDAFCVB : 47|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LDARDA : 46|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SWSSENSD : 45|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ SWSSWD : 43|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SWSRAD : 55|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ SWSFLD : 53|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ SWSBUZ : 50|2@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1207 ECO1D50: 8 CGW + SG_ DRECO01 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECO02 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECO03 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECO04 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECO05 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECO06 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECO07 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECO08 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 355 ECO1S01: 5 CGW + SG_ ECOSTAON : 19|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ECOMODE : 18|3@0+ (1,0) [0|0] "" KSS,SCS + SG_ FCREQ : 31|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SSVMREQ : 27|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ E2MRXMK : 26|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ BPHLDRQ : 36|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ BPHLDRQ2 : 35|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ ECOEGSTP : 33|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 922 ECO1S90: 8 CGW + SG_ ECOBZR : 23|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ ECOLMP : 21|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ TESTECO : 30|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ OPLMPMSK : 29|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ MSTART : 28|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ECOMODE3 : 27|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ INFSSCOP : 39|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ INFSSSTL : 36|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ ECLMP : 34|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ AUTOSTA : 47|1@0+ (1,0) [0|0] "" SCS + SG_ INFSSFAL : 46|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ INFSSINH : 45|6@0+ (1,0) [0|0] "" Vector__XXX + SG_ SSACMODE : 52|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ INFSSADV : 50|3@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1182 ECT1D50: 8 CGW + SG_ DRECT01 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT02 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT03 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT04 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT05 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT06 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT07 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT08 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1183 ECT1D51: 8 CGW + SG_ DRECT11 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT12 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT13 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT14 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT15 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT16 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT17 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT18 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1200 ECT1D52: 8 CGW + SG_ DRECT21 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT22 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT23 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT24 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT25 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT26 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT27 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT28 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1201 ECT1D53: 8 CGW + SG_ DRECT31 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT32 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT33 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT34 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT35 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT36 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT37 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT38 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1202 ECT1D54: 8 CGW + SG_ DRECT41 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT42 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT43 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT44 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT45 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT46 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT47 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT48 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1203 ECT1D55: 8 CGW + SG_ DRECT51 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT52 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT53 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT54 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT55 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT56 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT57 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRECT58 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 464 ECT1F03: 8 CGW + SG_ NT : 7|16@0- (0.390625,0) [0|0] "rpm" Vector__XXX + SG_ ACT : 23|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XDMET : 20|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XNTSW : 19|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XNMET : 18|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XRMET : 17|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XPMET : 16|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SFTOUT_S : 29|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ X3MET : 26|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ X2MET : 25|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XLOMET : 24|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ L4SW : 38|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SNOW : 36|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XFSFT : 35|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SFTOUT : 34|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ HSSLWN : 55|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ HSINH : 54|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CLTMODBK : 53|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ LUOUT : 51|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LUKG : 50|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ FBCOA : 48|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ECTF03SM : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 725 ECT1S10: 2 CGW + SG_ VTORATIO : 7|16@0+ (0.0009765625,0) [0|0] "" Vector__XXX + +BO_ 956 ECT1S92: 8 CGW + SG_ B_OILW : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_OILMD : 5|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_ISNW : 1|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_RJTB : 0|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_WNDL : 15|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_LMULRJ : 14|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_P : 13|1@0+ (1,0) [0|0] "" AFS,CSR,MAV + SG_ B_R : 12|1@0+ (1,0) [0|0] "" AFS,BSR,CSR,DS1,FCM,MAV + SG_ B_N : 11|1@0+ (1,0) [0|0] "" AFS,CSR,MAV + SG_ B_ISPTM : 10|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ BV_THOCL : 23|16@0+ (0.625,-50) [0|0] "" Vector__XXX + SG_ B_GEAR : 39|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_SMDE : 32|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_D : 47|1@0+ (1,0) [0|0] "" AFS,CSR,DS1,MAV + SG_ B_ECOMI : 40|1@0+ (1,0) [0|0] "" DS1 + SG_ B_SPTMI : 55|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_PWRM : 54|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_OILWM : 51|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_SPTMS : 49|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_DMODE : 61|3@0+ (1,0) [0|0] "" SCS + +BO_ 1176 ENG1D50: 8 CGW + SG_ DRENG01 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG02 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG03 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG04 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG05 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG06 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG07 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG08 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1177 ENG1D51: 8 CGW + SG_ DRENG11 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG12 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG13 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG14 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG15 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG16 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG17 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG18 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1178 ENG1D52: 8 CGW + SG_ DRENG21 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG22 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG23 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG24 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG25 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG26 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG27 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG28 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1179 ENG1D53: 8 CGW + SG_ DRENG31 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG32 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG33 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG34 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG35 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG36 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG37 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG38 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1180 ENG1D54: 8 CGW + SG_ DRENG41 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG42 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG43 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG44 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG45 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG46 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG47 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG48 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1181 ENG1D55: 8 CGW + SG_ DRENG51 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG52 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG53 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG54 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG55 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG56 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG57 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG58 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1192 ENG1D56: 8 CGW + SG_ DRENG61 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG62 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG63 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG64 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG65 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG66 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG67 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG68 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1191 ENG1D57: 8 CGW + SG_ DRENG71 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG72 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG73 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG74 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG75 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG76 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG77 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG78 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1197 ENG1D58: 8 CGW + SG_ DRENG81 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG82 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG83 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG84 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG85 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG86 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG87 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG88 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1198 ENG1D59: 8 CGW + SG_ DRENG91 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG92 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG93 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG94 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG95 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG96 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG97 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG98 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1199 ENG1D60: 8 CGW + SG_ DRENG101 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG102 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG103 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG104 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG105 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG106 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG107 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRENG108 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1017 ENG1F03: 8 CGW + SG_ VARENG1 : 7|4@0+ (1,0) [0|0] "" AFS,SCS + SG_ VARENG2 : 3|4@0+ (1,0) [0|0] "" AFS,SCS + SG_ VARENG3 : 15|4@0+ (1,0) [0|0] "" AFS,SCS + SG_ VARENG4 : 11|1@0+ (1,0) [0|0] "" AFS,SCS + SG_ HVFLAG : 10|1@0+ (1,0) [0|0] "" AFS,BSR,FCM,SCS + SG_ VARTRM1 : 23|4@0+ (1,0) [0|0] "" AFS,CSR,FCM,MAV,SCS + SG_ GEARINF : 19|4@0+ (1,0) [0|0] "" SCS + SG_ DVINF : 31|2@0+ (1,0) [0|0] "" AFS,DS1,FCM,SCS + SG_ OBDINF : 27|4@0+ (1,0) [0|0] "" BSR,DS1,FCM,SCS + SG_ ECOFLAG : 39|1@0+ (1,0) [0|0] "" FCM + SG_ CDYMD : 38|2@0+ (1,0) [0|0] "" DS1,FCM + SG_ ENGF03SM : 63|8@0+ (1,0) [0|0] "" DS1,FCM,MAV + +BO_ 452 ENG1F07: 8 CGW + SG_ NE1 : 7|16@0- (0.78125,0) [0|0] "rpm" SCS + SG_ THA1 : 23|8@0+ (2.5,-40) [0|0] "" Vector__XXX + SG_ THWX : 31|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ EGF : 30|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ T2ERXF : 29|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ T2ERXMK : 28|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ASTEFI : 27|1@0+ (1,0) [0|0] "" AFS + SG_ B2ERXMK : 26|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PDLF : 24|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ENTCAL2 : 39|8@0+ (12.5,0) [0|0] "rpm" Vector__XXX + SG_ EGFB : 46|1@0+ (1,0) [0|0] "" DS1,FCM + SG_ PTFB : 45|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ MILREQ : 43|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_ECOL : 55|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_IECOCR : 53|6@0+ (2,0) [0|0] "" Vector__XXX + SG_ ENGF07SM : 63|8@0+ (1,0) [0|0] "" AFS,DS1,FCM + +BO_ 114 ENG1F43: 5 CGW + SG_ FAVLMCHL : 7|16@0- (2,0) [0|0] "N" Vector__XXX + SG_ FAVLMONL : 23|16@0- (2,0) [0|0] "N" Vector__XXX + SG_ ENGF43SM : 39|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 705 ENG1S01: 8 CGW + SG_ ETCSFB : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ETCSF : 6|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ VSCTH : 5|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ THF : 4|1@0+ (1,0) [0|0] "" DS1 + SG_ IDL1 : 3|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XCCACT2 : 2|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ STPSWF : 1|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ WTC : 0|1@0+ (1,0) [0|0] "" KSS,SCS + SG_ ETQLVSC : 15|16@0- (0.03125,0) [0|0] "Nm" Vector__XXX + SG_ ETQREAL : 31|16@0- (0.03125,0) [0|0] "Nm" SCS + SG_ ETQISC : 47|8@0+ (1,-192) [0|0] "Nm" Vector__XXX + SG_ EACCP : 55|8@0+ (0.5,0) [0|0] "%" DS1,FCM + SG_ ENG01SUM : 63|8@0+ (1,0) [0|0] "" DS1,FCM + +BO_ 961 ENG1S23: 3 CGW + SG_ EKLSM : 7|8@0+ (0.625,0) [0|0] "%" Vector__XXX + SG_ GATHW : 15|16@0- (0.625,0) [0|0] "" Vector__XXX + +BO_ 979 ENG1S28: 2 CGW + SG_ B_FC : 7|16@0+ (0.0005,0) [0|0] "ml" Vector__XXX + +BO_ 1408 ENG1S51: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1409 ENG1S52: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1410 ENG1S54: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ VC : 52|5@0+ (1,0) [0|0] "" Vector__XXX + SG_ TES : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 955 ENG1S92: 8 CGW + SG_ B_ST : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_TC : 6|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_GLOW : 3|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_STPE : 0|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_OMWI : 15|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_SILUP : 13|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_SILDN : 12|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_WSTP : 11|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_LOUT : 10|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_OILPL : 9|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_TMP : 23|8@0+ (0.5,0) [0|0] "" Vector__XXX + SG_ OGENETCS : 30|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_DPFW : 28|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ BOSLAMP : 37|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ BOSMINF : 34|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ GOSLAMP : 45|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ GOSMINF : 42|3@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 921 ENG1S95: 8 CGW + SG_ B_LLSP2 : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TLSTBZ : 6|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_ASLBZ2 : 5|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_SPU2 : 4|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ACASID1 : 3|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ ACASID2 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_LSP2 : 31|8@0+ (1,0) [0|0] "km/h Emph" Vector__XXX + SG_ B_ASLSP2 : 39|8@0+ (1,0) [0|0] "km/h Emph" Vector__XXX + SG_ CACCTRN : 47|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CACCINF : 46|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CACCFR2 : 45|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CACCFR1 : 44|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CACCFLD : 43|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CACCCM3 : 42|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CACCCM2 : 41|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CACCCM1 : 40|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 238 ENG2F01: 4 CGW + SG_ STOFOK : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ GROWIND : 6|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_TMP3 : 15|8@0+ (0.5,0) [0|0] "" Vector__XXX + SG_ IMMINJST : 23|16@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 466 ENG2F04: 8 CGW + SG_ XLDR : 7|1@0+ (1,0) [0|0] "" DS1 + SG_ XACCACTV : 6|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XACCACT : 5|1@0+ (1,0) [0|0] "" DS1,FCM + SG_ XPAIDLV : 4|1@0+ (1,0) [0|0] "" DS1 + SG_ XPAIDL : 3|1@0+ (1,0) [0|0] "" DS1 + SG_ BHOK : 2|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ RQBH : 1|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ ACCSTAT : 15|3@0+ (1,0) [0|0] "" DS1 + SG_ ACCSTBK : 12|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ STPBZ : 9|1@0+ (1,0) [0|0] "" DS1,FCM + SG_ PLOCKF : 8|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ACCREQ : 23|16@0- (0.0009765625,0) [0|0] "m/s^2" DS1 + SG_ ACCAVL : 39|16@0- (2,0) [0|0] "N" Vector__XXX + SG_ SPDSTAT : 55|4@0+ (1,0) [0|0] "" DS1 + SG_ SSTOK : 51|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CANREQ : 49|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ FCACT : 48|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SM1D2 : 63|8@0+ (1,0) [0|0] "" DS1,FCM + +BO_ 467 ENG2F05: 8 CGW + SG_ LCCW2 : 4|1@0+ (1,0) [0|0] "" DS1,FCM + SG_ WSTL2 : 3|1@0+ (1,0) [0|0] "" DS1 + SG_ LCCHK : 2|3@0+ (1,0) [0|0] "" DS1 + SG_ XCCOK2 : 15|1@0+ (1,0) [0|0] "" DS1 + SG_ SLTACC : 14|2@0+ (1,0) [0|0] "" DS1 + SG_ LTME2 : 12|2@0+ (1,0) [0|0] "" DS1 + SG_ STPSWF2 : 10|1@0+ (1,0) [0|0] "" DS1 + SG_ CCSF : 9|1@0+ (1,0) [0|0] "" DS1 + SG_ CCSNG : 8|1@0+ (1,0) [0|0] "" DS1 + SG_ VM : 23|16@0+ (0.00390625,0) [0|0] "km/h" DS1 + SG_ INTG : 39|8@0- (0.04,0) [0|0] "m/s^2" DS1 + SG_ D2PRXMK : 47|1@0+ (1,0) [0|0] "" DS1 + SG_ SM1D3 : 63|8@0+ (1,0) [0|0] "" DS1,FCM + +BO_ 119 ENG2F41: 6 CGW + SG_ FDRV : 7|16@0- (2,0) [0|0] "N" Vector__XXX + SG_ FDRVREAL : 23|13@0- (10,0) [0|0] "N" Vector__XXX + SG_ XAECT : 39|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ XFDRVCOL : 38|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ FDRVSELP : 34|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ ENG2F41S : 47|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 120 ENG2F42: 4 CGW + SG_ FAVLMCHH : 7|16@0- (2,0) [0|0] "N" Vector__XXX + SG_ CCRNG : 23|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ FDRVTYPD : 22|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ GEARHD : 18|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ENG2F42S : 31|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 916 EPS1S90: 1 CGW + SG_ B_WPS0 : 1|2@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1235 FCM1N01: 8 FCM + SG_ FCMNID : 7|8@0+ (1,0) [0|0] "" CGW + SG_ FCMSNG : 15|1@0+ (1,0) [0|0] "" CGW + SG_ FCMSPF : 23|16@0+ (1,0) [0|0] "" CGW + SG_ FCMREV : 39|32@0+ (1,0) [0|0] "" CGW + +BO_ 1161 FCM1S10: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1162 FCM1S11: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1163 FCM1S12: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" Vector__XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" Vector__XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" Vector__XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1279 FRD1N01: 8 FRD + SG_ FRDNID : 7|8@0+ (1,0) [0|0] "" CGW + SG_ FRDSNG : 15|1@0+ (1,0) [0|0] "" CGW + SG_ FRDSPF : 23|16@0+ (1,0) [0|0] "" CGW + SG_ FRDREV : 39|32@0+ (1,0) [0|0] "" CGW + +BO_ 737 FWM1S01: 2 CGW + SG_ ACTHLF : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ MOT4WD : 6|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CCANCEL : 5|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ AI4WD : 4|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LOW4 : 3|1@0+ (1,0) [0|0] "" MAV,SCS + SG_ DLOCK : 2|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ RDLOCK : 1|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ HLN : 0|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ F_SP4WD : 15|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ RQ_SP4WD : 14|7@0+ (1,73) [0|0] "km/h" Vector__XXX + +BO_ 1082263092 IDT1S03_82: 8 CGW + SG_ IDT03_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ IDT03_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ CO_IDT : 23|16@0+ (1,0) [0|0] "" Vector__XXX + SG_ UACK : 39|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ WRT : 38|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ RSTP : 37|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1082328629 IDT1S04_83: 8 CGW + SG_ IDT04_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ IDT04_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ OSID : 47|16@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1257 KSS1N01: 8 KSS + SG_ KSSNID : 7|8@0+ (1,0) [0|0] "" CGW + SG_ KSSSNG : 15|1@0+ (1,0) [0|0] "" CGW + SG_ KSSSPF : 23|16@0+ (1,0) [0|0] "" CGW + SG_ KSSREV : 39|32@0+ (1,0) [0|0] "" CGW + +BO_ 927 KSS1S90: 1 KSS + SG_ LKSS0 : 1|2@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1263 MAV1N01: 8 MAV + SG_ MAVNID : 7|8@0+ (1,0) [0|0] "" CGW + SG_ MAVSNG : 15|1@0+ (1,0) [0|0] "" CGW + SG_ MAVSPF : 23|16@0+ (1,0) [0|0] "" CGW + +BO_ 1075840528 MET1S01_20: 8 CGW + SG_ MET01_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ MET01_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ MET_SPD : 23|8@0+ (1,0) [0|0] "km/h" CSR + SG_ RHEOSTAT : 30|7@0+ (1,0) [0|0] "%" Vector__XXX + SG_ TAIL_CN : 39|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ ILL_OF : 37|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ UNIT_TMP : 33|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ IN_FC : 47|16@0+ (0.1,0) [0|0] "Note" Vector__XXX + SG_ UNIT_0 : 63|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ SP_TL : 60|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ MET_TC : 56|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1075906065 MET1S02_21: 8 CGW + SG_ MET02_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ MET02_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ MET_DEST : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ ODO_UNIT : 29|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ OMRS : 27|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ UNIT_CH : 26|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ ODO : 39|32@0+ (1,0) [0|0] "km/mile" Vector__XXX + +BO_ 1076037145 MET1S04_23: 8 CGW + SG_ MET04_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ MET04_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ AF_FC : 23|16@0+ (0.1,0) [0|0] "Note" Vector__XXX + SG_ UNIT_3 : 39|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ RANGE : 47|16@0+ (1,0) [0|0] "Note" Vector__XXX + SG_ UNIT_4 : 63|2@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1076102682 MET1S05_24: 8 CGW + SG_ MET05_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ MET05_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ TO_SP : 23|16@0+ (0.1,0) [0|0] "km/h,MPH" Vector__XXX + SG_ UNIT_5 : 39|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ TO_FC : 47|16@0+ (0.1,0) [0|0] "MPG Ekm/l El/100km Ekm/gallon" Vector__XXX + SG_ UNIT_6 : 63|3@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1076299282 MET1S08_27: 8 CGW + SG_ MET08_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ MET08_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ TO_DT : 23|16@0+ (1,0) [0|0] "km,mile" Vector__XXX + SG_ UNIT_10 : 39|2@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1076364819 MET1S09_28: 8 CGW + SG_ MET09_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ MET09_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ WASH : 21|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ BLVW : 20|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ C_CW : 31|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ENGW : 29|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ABSW : 28|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ VSCW : 27|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ OPW : 37|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ OLW : 36|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LW : 35|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ FSRS : 33|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ HALW : 46|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ BRW : 43|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TIRW : 42|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ FWW : 40|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SUSW : 53|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LKAW : 61|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ MET_PCSW : 59|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ WTPW : 57|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1076430356 MET1S10_29: 8 CGW + SG_ MET10_ID : 7|8@0+ (1,0) [0|0] "" DS1,FCM + SG_ MET10_IF : 15|8@0+ (1,0) [0|0] "" DS1,FCM + SG_ OM_MLG : 23|7@0+ (100,0) [0|0] "miles" Vector__XXX + SG_ PR_OM_FL : 16|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TNS : 29|2@0+ (1,0) [0|0] "" AFS,BSR,DS1,FCM + SG_ HZS : 27|1@0+ (1,0) [0|0] "" AFS,FCM + +BO_ 1076495893 MET1S11_2A: 8 CGW + SG_ MET11_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ MET11_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ UNIT_CH2 : 23|2@0+ (1,0) [0|0] "" FCM + SG_ TOLER_A : 21|6@0+ (0.002,0.94) [0|0] "" FCM + SG_ CDISP_EX : 31|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TOLER_B : 29|6@0- (0.2,0) [0|0] "km/h" FCM + SG_ TRIP_B : 39|32@0+ (0.1,0) [0|0] "km/MILE" Vector__XXX + +BO_ 1076561430 MET1S12_2B: 8 CGW + SG_ MET12_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ MET12_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ ESLW : 19|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CSOW : 24|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LHLW : 37|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SMBW : 33|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ KDSW : 32|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ OMRW : 46|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ BSDW : 54|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ MTSW : 48|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ ATSW : 63|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 992 MET1S18: 8 CGW + SG_ M_LANG : 7|6@0+ (1,0) [0|0] "" Vector__XXX + SG_ M_LNG_ST : 1|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ M_LNGDB1 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ M_LNGDB2 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ M_LNGDB3 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ M_LNGDB4 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ M_LNGDB5 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ M_LNGDB6 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ M_LNGDB7 : 63|7@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1075840755 MET1S22_20: 8 CGW + SG_ ID6F320 : 7|8@0+ (1,0) [0|0] "" DS1,FCM + SG_ IF6F320 : 15|8@0+ (1,0) [0|0] "" DS1,FCM + SG_ TSR_OSM : 22|2@0+ (1,0) [0|0] "" FCM + SG_ TSR_OSL : 20|2@0+ (1,0) [0|0] "" FCM + SG_ TSR_SNM : 18|2@0+ (1,0) [0|0] "" FCM + SG_ TSR_MAIN : 16|1@0+ (1,0) [0|0] "" FCM + SG_ LDAMCUS : 31|2@0+ (1,0) [0|0] "" FCM + SG_ LDAMSW : 29|2@0+ (1,0) [0|0] "" FCM + SG_ FCMUSER : 27|1@0+ (1,0) [0|0] "" FCM + SG_ FCMMCUS : 26|2@0+ (1,0) [0|0] "" FCM + SG_ FCMMSW : 24|1@0+ (1,0) [0|0] "" FCM + SG_ BSMMSW : 37|1@0+ (1,0) [0|0] "" BSR + SG_ CSRMSW : 34|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSMCUS : 41|1@0+ (1,0) [0|0] "" DS1 + SG_ PCSMSW : 40|1@0+ (1,0) [0|0] "" DS1 + SG_ LKACTCSW : 51|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ LDA_SFB : 50|3@0+ (1,0) [0|0] "" FCM + +BO_ 1088685760 PMN1F03_E4: 8 CGW + SG_ PMNF03ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ PMNF03IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ PSSW_PMN : 17|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PSW_PMN : 31|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ KCC_PMN : 29|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PMOD_PMN : 27|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ MOD_EIG : 39|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ SWBZ_EIG : 36|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1193 SCS1D50: 8 SCS + SG_ DRSCS01 : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRSCS02 : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRSCS03 : 23|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRSCS04 : 31|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRSCS05 : 39|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRSCS06 : 47|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRSCS07 : 55|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ DRSCS08 : 63|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1226 SCS1N01: 8 SCS + SG_ SCSNID : 7|8@0+ (1,0) [0|0] "" CGW + SG_ SCSSNG : 15|1@0+ (1,0) [0|0] "" CGW + SG_ SCSSPF : 23|16@0+ (1,0) [0|0] "" CGW + SG_ SCSREV : 39|32@0+ (1,0) [0|0] "" CGW + +BO_ 744 SCS1S01: 8 SCS + SG_ SELECTOR : 3|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ AVS_MD : 63|3@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 815 SCS1S06: 5 SCS + SG_ RRVH : 23|8@0- (1,0) [0|0] "mm" AFS + SG_ RLVH : 31|8@0- (1,0) [0|0] "mm" AFS + SG_ SCECOINH : 35|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 917 SCS1S90: 4 SCS + SG_ B_LSUS6 : 7|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_LSUS4 : 5|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_LSUS2 : 3|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_LSUS8 : 9|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ DLR_HSID : 23|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ LAR_HS : 18|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ AVSNI : 16|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 37 STR1S01: 8 CGW + SG_ STS3 : 7|1@0+ (1,0) [0|0] "" AFS,BSR,DS1,FCM,MAV + SG_ STS2 : 6|1@0+ (1,0) [0|0] "" AFS,DS1,FCM,KSS,MAV,SCS + SG_ STS1 : 5|1@0+ (1,0) [0|0] "" AFS,BSR,DS1,FCM,KSS,MAV,SCS + SG_ STS0 : 4|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ SSA : 3|12@0- (1.5,0) [0|0] "deg" AFS,BSR,DS1,FCM,KSS,MAV,SCS + SG_ SAZS : 23|1@0+ (1,0) [0|0] "" AFS,BSR,DS1,FCM + SG_ SFRZ : 22|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ SSAZ : 19|12@0- (1.5,0) [0|0] "deg" AFS,BSR,DS1,FCM + SG_ SSAS : 39|4@0- (0.1,0) [0|0] "deg" FCM,KSS,SCS + SG_ SSAV : 35|12@0- (1,0) [0|0] "deg/s" FCM,KSS,SCS + SG_ STDID : 51|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ STR01SUM : 63|8@0+ (1,0) [0|0] "" AFS,DS1,FCM,MAV + +BO_ 1059 STR1S02: 1 CGW + SG_ SFR : 5|1@0+ (1,0) [0|0] "" MAV + SG_ STRWVG : 4|1@0+ (1,0) [0|0] "" AFS,BSR,DS1,FCM + +BO_ 170 VSC1F01: 8 CGW + SG_ VXFREF : 7|1@0+ (1,0) [0|0] "" AFS,FCM,MAV + SG_ VXFR : 6|15@0+ (0.01,-67.67) [0|0] "km/h" AFS,BSR,DS1,FCM,KSS,MAV,SCS + SG_ VXFLEF : 23|1@0+ (1,0) [0|0] "" AFS,FCM,MAV + SG_ VXFL : 22|15@0+ (0.01,-67.67) [0|0] "km/h" AFS,BSR,DS1,FCM,KSS,MAV,SCS + SG_ VXRREF : 39|1@0+ (1,0) [0|0] "" AFS,FCM,MAV + SG_ VXRR : 38|15@0+ (0.01,-67.67) [0|0] "km/h" AFS,BSR,DS1,FCM,KSS,MAV,SCS + SG_ VXRLEF : 55|1@0+ (1,0) [0|0] "" AFS,FCM,MAV + SG_ VXRL : 54|15@0+ (0.01,-67.67) [0|0] "km/h" AFS,BSR,DS1,FCM,KSS,MAV,SCS + +BO_ 426 VSC1F02: 6 CGW + SG_ VXFRF : 7|1@0+ (1,0) [0|0] "" AFS,BSR,FCM,MAV + SG_ VXFRIGS : 6|1@0+ (1,0) [0|0] "" BSR,DS1,FCM,MAV + SG_ VXFRHDS : 5|1@0+ (1,0) [0|0] "" FCM,KSS,MAV,SCS + SG_ VXFLF : 2|1@0+ (1,0) [0|0] "" AFS,BSR,FCM,MAV + SG_ VXFLIGS : 1|1@0+ (1,0) [0|0] "" BSR,DS1,FCM,MAV + SG_ VXFLHDS : 0|1@0+ (1,0) [0|0] "" FCM,KSS,MAV,SCS + SG_ VXRRF : 13|1@0+ (1,0) [0|0] "" AFS,BSR,FCM,MAV + SG_ VXRRIGS : 12|1@0+ (1,0) [0|0] "" BSR,DS1,FCM,MAV + SG_ VXRRHDS : 11|1@0+ (1,0) [0|0] "" FCM,KSS,MAV,SCS + SG_ VXRLF : 8|1@0+ (1,0) [0|0] "" AFS,BSR,FCM,MAV + SG_ VXRLIGS : 23|1@0+ (1,0) [0|0] "" BSR,DS1,FCM,MAV + SG_ VXRLHDS : 22|1@0+ (1,0) [0|0] "" FCM,KSS,MAV,SCS + SG_ VSCF02SM : 47|8@0+ (1,0) [0|0] "" AFS,DS1,FCM,MAV + +BO_ 550 VSC1F06: 8 CGW + SG_ VSCF01FG : 7|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ AHCURQ : 4|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PMCF : 3|1@0+ (1,0) [0|0] "" DS1 + SG_ PMCS : 2|1@0+ (1,0) [0|0] "" DS1 + SG_ PMC : 1|10@0+ (0.02,0) [0|0] "Mpa" DS1 + SG_ ECOEN : 23|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ CCS : 22|1@0+ (1,0) [0|0] "" DS1 + SG_ FBA : 21|1@0+ (1,0) [0|0] "" DS1 + SG_ TRBRKSYS : 20|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TS : 38|1@0+ (1,0) [0|0] "" KSS,SCS + SG_ WSTP : 37|1@0+ (1,0) [0|0] "" DS1,KSS,SCS + SG_ VSCACT : 36|1@0+ (1,0) [0|0] "" DS1,FCM + SG_ BAEX : 35|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TEM : 34|3@0+ (1,0) [0|0] "" SCS + SG_ FSTP : 60|1@0+ (1,0) [0|0] "" DS1 + SG_ ABSACT : 59|1@0+ (1,0) [0|0] "" DS1,FCM,MAV + +BO_ 180 VSC1S03: 8 CGW + SG_ SP1P : 39|6@0+ (1,0) [0|0] "" DS1,FCM + SG_ SP1S : 33|1@0+ (1,0) [0|0] "" BSR,DS1,FCM,MAV + SG_ SP1 : 47|16@0- (0.01,0) [0|0] "km/h" BSR,DS1,FCM,MAV + SG_ VSC03SUM : 63|8@0+ (1,0) [0|0] "" DS1,FCM,MAV + +BO_ 800 VSC1S07: 8 CGW + SG_ FBKRLY : 6|1@0+ (1,0) [0|0] "" DS1 + SG_ FVSCM : 4|1@0+ (1,0) [0|0] "" DS1 + SG_ FVSCSFT : 3|1@0+ (1,0) [0|0] "" DS1 + SG_ FABS : 2|1@0+ (1,0) [0|0] "" DS1,FCM + SG_ TSVSC : 1|1@0+ (1,0) [0|0] "" DS1 + SG_ FVSCL : 0|1@0+ (1,0) [0|0] "" DS1 + SG_ RQCSTBKB : 15|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PSBSTBY : 14|1@0+ (1,0) [0|0] "" DS1 + SG_ P2BRXMK : 13|1@0+ (1,0) [0|0] "" DS1 + SG_ MCC : 11|1@0+ (1,0) [0|0] "" DS1 + SG_ RQBKB : 10|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ BRSTOP : 9|1@0+ (1,0) [0|0] "" DS1,FCM + SG_ BRKON : 8|1@0+ (1,0) [0|0] "" DS1,FCM + SG_ ASLP : 23|8@0- (1,0) [0|0] "deg" DS1 + SG_ BRTYPACC : 31|2@0+ (1,0) [0|0] "" DS1 + SG_ BRKABT3 : 26|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ BRKABT2 : 25|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ BRKABT1 : 24|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ GVC : 39|8@0- (0.04,0) [0|0] "m/s^2" DS1 + SG_ XGVCINV : 43|1@0+ (1,0) [0|0] "" DS1 + SG_ S07CNT : 52|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ PCSBRSTA : 50|2@0+ (1,0) [0|0] "" DS1 + SG_ VSC07SUM : 63|8@0+ (1,0) [0|0] "" DS1,FCM + +BO_ 1056 VSC1S08: 8 CGW + SG_ YR1Z : 7|16@0- (1,0) [0|0] "rad/s" DS1,FCM,MAV + SG_ YR2Z : 23|16@0- (1,0) [0|0] "rad/s" DS1,FCM,MAV + SG_ GL1Z : 39|8@0- (0.0359,0) [0|0] "m/s^2" DS1,FCM,KSS,MAV,SCS + SG_ GL2Z : 47|8@0- (0.0359,0) [0|0] "m/s^2" DS1,FCM,KSS,MAV,SCS + SG_ YRGSDIR : 55|1@0+ (1,0) [0|0] "" DS1,FCM,KSS,SCS + SG_ GLZS : 51|1@0+ (1,0) [0|0] "" DS1,FCM,KSS,MAV,SCS + SG_ YRZF : 50|1@0+ (1,0) [0|0] "" DS1,FCM,MAV + SG_ YRZS : 49|1@0+ (1,0) [0|0] "" DS1,FCM,MAV + SG_ YRZKS : 48|1@0+ (1,0) [0|0] "" DS1,FCM,MAV + SG_ VSC08SUM : 63|8@0+ (1,0) [0|0] "" DS1,FCM,MAV + +BO_ 186 VSC1S12: 4 CGW + SG_ HAC2ESRQ : 21|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ FHACHOLD : 20|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ VSC12SUM : 31|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 562 VSC1S14: 6 CGW + SG_ VWPSUMFR : 7|8@0+ (1,0) [0|0] "" MAV + SG_ VWPSUMFL : 15|8@0+ (1,0) [0|0] "" MAV + SG_ VWPFRPM : 23|1@0+ (1,0) [0|0] "" MAV + SG_ VWPFLPM : 22|1@0+ (1,0) [0|0] "" MAV + SG_ S14CNT : 21|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ VWPFRPMS : 18|1@0+ (1,0) [0|0] "" MAV + SG_ VWPFLPMS : 17|1@0+ (1,0) [0|0] "" MAV + SG_ VWPSUMRR : 31|8@0+ (1,0) [0|0] "" MAV + SG_ VWPSUMRL : 39|8@0+ (1,0) [0|0] "" MAV + SG_ VSC14SUM : 47|8@0+ (1,0) [0|0] "" MAV + +BO_ 552 VSC1S29: 4 CGW + SG_ ICBACT : 7|1@0+ (1,0) [0|0] "" DS1 + SG_ DVS0PCS : 6|15@0- (0.001,0) [0|0] "m/s^2" DS1 + SG_ SM228 : 31|8@0+ (1,0) [0|0] "" DS1 + +BO_ 1168 VSC1S92: 1 CGW + SG_ C_DCMOD1 : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ C_DCMOD2 : 6|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ C_DCMOD3 : 3|4@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 951 VSC1S95: 8 CGW + SG_ B_BRKW : 7|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_ABS : 5|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_BRLV : 14|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TRCOFF : 13|1@0+ (1,0) [0|0] "" DS1,FCM + SG_ VSCOFF : 12|2@0+ (1,0) [0|0] "" DS1,FCM + SG_ SLP_WL : 10|3@0+ (1,0) [0|0] "" MAV + SG_ B_MCST : 19|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_BUZZER : 31|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_ALSD : 27|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_DACIND : 25|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ OGENVSC : 37|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_ATRC : 47|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_STRC : 46|3@0+ (1,0) [0|0] "" MAV + SG_ B_HZD : 43|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ VSCSWIH : 51|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ STRCDISP : 50|3@0+ (1,0) [0|0] "" Vector__XXX + SG_ STRCDSP2 : 60|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ VSCEXIST : 59|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1063 VSC1S96: 8 CGW + SG_ MTS_DISP : 5|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ B_MTS : 1|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ TRCCONRL : 11|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TRCCONRR : 10|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TRCCONFL : 9|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TRCCONFR : 8|1@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 545 VSC2F05: 5 CGW + SG_ TQER : 7|16@0- (0.03125,0) [0|0] "Nm" Vector__XXX + SG_ REQC : 23|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ REQ2 : 22|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ REQ1 : 21|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ AIDWI : 20|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ RTD : 19|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ LOMUSFT : 31|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ VSC2F05S : 39|8@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 544 VSC2F07: 4 CGW + SG_ FSROT : 7|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ BRK2 : 4|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ BRK1 : 3|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ FCNG : 1|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TSLP : 0|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ TRCACT : 15|1@0+ (1,0) [0|0] "" DS1,FCM + SG_ ABSSLP : 14|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ VDMACT : 13|1@0+ (1,0) [0|0] "" FCM + SG_ DAC_CND : 9|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ VSC2F07S : 31|8@0+ (1,0) [0|0] "" DS1,FCM + +BO_ 36 YGS1S03: 8 CGW + SG_ YRS11S : 7|1@0+ (1,0) [0|0] "" DS1,FCM,MAV + SG_ YRS14S : 6|1@0+ (1,0) [0|0] "" DS1,FCM,MAV + SG_ YRS21S : 5|1@0+ (1,0) [0|0] "" DS1,FCM,MAV + SG_ YRS24S : 4|1@0+ (1,0) [0|0] "" DS1,FCM,MAV + SG_ YGS1 : 3|1@0+ (1,0) [0|0] "" DS1,FCM,KSS,MAV,SCS + SG_ YGS0 : 2|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ YR : 1|10@0+ (0.244,-125) [0|0] "deg/sec" DS1,FCM,MAV + SG_ YR_CPUMN : 23|4@0+ (1,0) [0|0] "" Vector__XXX + SG_ GS4S : 19|1@0+ (1,0) [0|0] "" DS1,FCM,KSS,MAV,SCS + SG_ GS1S : 18|1@0+ (1,0) [0|0] "" DS1,FCM,KSS,MAV,SCS + SG_ GL1X : 17|10@0+ (0.03589,-18.375) [0|0] "m/s^2" DS1,FCM,KSS,MAV,SCS + SG_ YG_ID : 39|4@0+ (1,0) [0|0] "" DS1,FCM,KSS,SCS + SG_ GS5S : 35|1@0+ (1,0) [0|0] "" DS1,FCM,KSS,MAV,SCS + SG_ GS2S : 34|1@0+ (1,0) [0|0] "" DS1,FCM,KSS,MAV,SCS + SG_ GL2Y : 33|10@0+ (0.03589,-18.375) [0|0] "m/s^2" DS1,FCM,KSS,MAV,SCS + SG_ YR_DIF : 55|8@0+ (0.244,-31) [0|0] "deg/sec" DS1,FCM,MAV + SG_ YGS03SUM : 63|8@0+ (1,0) [0|0] "" DS1,FCM,MAV + +BO_ 1073743490 YGW1S01_0: 8 CGW + SG_ YGW01_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ YGW01_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ YR_STSW : 22|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ YR_EGST : 20|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ YR_DRLK : 18|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ YR_KLEG : 16|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ YR_HZRD : 26|3@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1073743491 YGW1S02_0: 8 CGW + SG_ YGW02_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ YGW02_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ YR_DEFOG : 19|2@0+ (1,0) [0|0] "" Vector__XXX + SG_ YR_ARCON : 17|2@0+ (1,0) [0|0] "" Vector__XXX + +BO_ 1073743494 YGW1S05_0: 8 CGW + SG_ YGW05_ID : 7|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ YGW05_IF : 15|8@0+ (1,0) [0|0] "" Vector__XXX + SG_ YI_IMO_E : 23|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ YI_UREQ : 16|1@0+ (1,0) [0|0] "" Vector__XXX + SG_ YI_RE : 47|16@0+ (1,0) [0|0] "" Vector__XXX diff --git a/opendbc/toyota_prius_2017_adas.dbc b/opendbc/toyota_adas.dbc similarity index 100% rename from opendbc/toyota_prius_2017_adas.dbc rename to opendbc/toyota_adas.dbc diff --git a/opendbc/toyota_avalon_2017_pt_generated.dbc b/opendbc/toyota_avalon_2017_pt_generated.dbc index 64c39ff82f5364..026191e9bacc77 100644 --- a/opendbc/toyota_avalon_2017_pt_generated.dbc +++ b/opendbc/toyota_avalon_2017_pt_generated.dbc @@ -67,11 +67,11 @@ NS_ : BS_: -BU_: XXX DSU HCU EPS IPAS +BU_: XXX DSU HCU EPS IPAS CGW BO_ 36 KINEMATICS: 8 XXX - SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX - SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX BO_ 37 STEER_ANGLE_SENSOR: 8 XXX @@ -91,8 +91,8 @@ BO_ 170 WHEEL_SPEEDS: 8 XXX BO_ 180 SPEED: 8 XXX SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 353 DSU_SPEED: 8 XXX SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX @@ -103,6 +103,7 @@ BO_ 466 PCM_CRUISE: 8 XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 467 PCM_CRUISE_2: 8 XXX @@ -125,10 +126,19 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 643 PRE_COLLISION: 8 XXX +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX BO_ 740 STEERING_LKA: 5 XXX SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX @@ -154,6 +164,18 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + BO_ 921 PCM_CRUISE_SM: 8 XXX SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX @@ -162,6 +184,7 @@ BO_ 921 PCM_CRUISE_SM: 8 XXX BO_ 951 ESP_CONTROL: 8 ESP SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX BO_ 1041 ACC_HUD: 8 DSU @@ -186,7 +209,41 @@ BO_ 1042 LKAS_HUD: 8 XXX SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX -BO_ 1553 UI_SEETING: 8 XXX +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX BO_ 1556 STEERING_LEVERS: 8 XXX @@ -256,6 +313,9 @@ CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; @@ -279,6 +339,7 @@ VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; @@ -288,9 +349,9 @@ VAL_ 1553 UNITS 1 "km" 2 "miles"; VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; -VAL_ 1161 SPLSGN2 15 "conditional blank" 5 "rain" 0 "none"; -VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; -VAL_ 1162 SPLSGN3 15 "conditional blank" 5 "rain" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/opendbc/toyota_camry_hybrid_2018_pt_generated.dbc b/opendbc/toyota_camry_hybrid_2018_pt_generated.dbc index 5d4fd39a6e32e2..f60681a17a184d 100644 --- a/opendbc/toyota_camry_hybrid_2018_pt_generated.dbc +++ b/opendbc/toyota_camry_hybrid_2018_pt_generated.dbc @@ -67,11 +67,11 @@ NS_ : BS_: -BU_: XXX DSU HCU EPS IPAS +BU_: XXX DSU HCU EPS IPAS CGW BO_ 36 KINEMATICS: 8 XXX - SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX - SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX BO_ 37 STEER_ANGLE_SENSOR: 8 XXX @@ -91,8 +91,8 @@ BO_ 170 WHEEL_SPEEDS: 8 XXX BO_ 180 SPEED: 8 XXX SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 353 DSU_SPEED: 8 XXX SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX @@ -103,6 +103,7 @@ BO_ 466 PCM_CRUISE: 8 XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 467 PCM_CRUISE_2: 8 XXX @@ -125,10 +126,19 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 643 PRE_COLLISION: 8 XXX +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX BO_ 740 STEERING_LKA: 5 XXX SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX @@ -154,6 +164,18 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + BO_ 921 PCM_CRUISE_SM: 8 XXX SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX @@ -162,6 +184,7 @@ BO_ 921 PCM_CRUISE_SM: 8 XXX BO_ 951 ESP_CONTROL: 8 ESP SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX BO_ 1041 ACC_HUD: 8 DSU @@ -186,7 +209,41 @@ BO_ 1042 LKAS_HUD: 8 XXX SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX -BO_ 1553 UI_SEETING: 8 XXX +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX BO_ 1556 STEERING_LEVERS: 8 XXX @@ -256,6 +313,9 @@ CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; @@ -279,6 +339,7 @@ VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; @@ -288,9 +349,9 @@ VAL_ 1553 UNITS 1 "km" 2 "miles"; VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; -VAL_ 1161 SPLSGN2 15 "conditional blank" 5 "rain" 0 "none"; -VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; -VAL_ 1162 SPLSGN3 15 "conditional blank" 5 "rain" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; @@ -314,11 +375,11 @@ BO_ 581 GAS_PEDAL: 8 XXX SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX BO_ 608 STEER_TORQUE_SENSOR: 8 XXX - SG_ STEER_TORQUE_EPS : 47|16@0- (0.66,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - SG_ STEER_ANGLE : 31|16@0- (0.05527,0) [-500|500] "" XXX + SG_ STEER_ANGLE : 31|16@0- (0.0573,0) [-500|500] "" XXX BO_ 610 EPS_STATUS: 8 EPS SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX diff --git a/opendbc/toyota_chr_2018_pt_generated.dbc b/opendbc/toyota_chr_2018_pt_generated.dbc deleted file mode 100644 index a2e169f94b5554..00000000000000 --- a/opendbc/toyota_chr_2018_pt_generated.dbc +++ /dev/null @@ -1,335 +0,0 @@ -CM_ "AUTOGENERATED FILE, DO NOT EDIT" - - -CM_ "Imported file _comma.dbc starts here" -BO_ 359 STEERING_IPAS_COMMA: 8 IPAS - SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX - SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX - SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX - SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -CM BO_ STEERING_IPAS_COMMA "Copy of msg 614 so we can do angle control while the Park Assist ECU is connected (Panda spoofs 614 with 359 on connector J70). Note that addresses 0x266 and 0x167 are checksum-invariant"; - - BO_ 512 GAS_COMMAND: 6 EON - SG_ GAS_COMMAND : 7|16@0+ (0.159375,-75.555) [0|1] "" INTERCEPTOR - SG_ GAS_COMMAND2 : 23|16@0+ (0.159375,-151.111) [0|1] "" INTERCEPTOR - SG_ ENABLE : 39|1@0+ (1,0) [0|1] "" INTERCEPTOR - SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" INTERCEPTOR - SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" INTERCEPTOR - - BO_ 513 GAS_SENSOR: 6 INTERCEPTOR - SG_ INTERCEPTOR_GAS : 7|16@0+ (0.159375,-75.555) [0|1] "" EON - SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.159375,-151.111) [0|1] "" EON - SG_ STATE : 39|4@0+ (1,0) [0|15] "" EON - SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" EON - SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" EON - - VAL_ 513 STATE 5 "FAULT_TIMEOUT" 4 "FAULT_STARTUP" 3 "FAULT_SCE" 2 "FAULT_SEND" 1 "FAULT_BAD_CHECKSUM" 0 "NO_FAULT" ; - - -CM_ "Imported file _toyota_2017.dbc starts here" -VERSION "" - - -NS_ : - NS_DESC_ - CM_ - BA_DEF_ - BA_ - VAL_ - CAT_DEF_ - CAT_ - FILTER - BA_DEF_DEF_ - EV_DATA_ - ENVVAR_DATA_ - SGTYPE_ - SGTYPE_VAL_ - BA_DEF_SGTYPE_ - BA_SGTYPE_ - SIG_TYPE_REF_ - VAL_TABLE_ - SIG_GROUP_ - SIG_VALTYPE_ - SIGTYPE_VALTYPE_ - BO_TX_BU_ - BA_DEF_REL_ - BA_REL_ - BA_DEF_DEF_REL_ - BU_SG_REL_ - BU_EV_REL_ - BU_BO_REL_ - SG_MUL_VAL_ - -BS_: - -BU_: XXX DSU HCU EPS IPAS - -BO_ 36 KINEMATICS: 8 XXX - SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX - SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX - SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX - -BO_ 37 STEER_ANGLE_SENSOR: 8 XXX - SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX - SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX - SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX - -BO_ 166 BRAKE: 8 XXX - SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX - SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX - -BO_ 170 WHEEL_SPEEDS: 8 XXX - SG_ WHEEL_SPEED_FR : 7|16@0+ (0.01,-67.67) [0|250] "kph" XXX - SG_ WHEEL_SPEED_FL : 23|16@0+ (0.01,-67.67) [0|250] "kph" XXX - SG_ WHEEL_SPEED_RR : 39|16@0+ (0.01,-67.67) [0|250] "kph" XXX - SG_ WHEEL_SPEED_RL : 55|16@0+ (0.01,-67.67) [0|250] "kph" XXX - -BO_ 180 SPEED: 8 XXX - SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX - -BO_ 353 DSU_SPEED: 8 XXX - SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX - -BO_ 466 PCM_CRUISE: 8 XXX - SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX - SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX - SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX - SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX - SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 467 PCM_CRUISE_2: 8 XXX - SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX - SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 552 ACCELEROMETER: 8 XXX - SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX - SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX - -BO_ 560 BRAKE_MODULE2: 7 XXX - SG_ BRAKE_PRESSED : 26|1@0+ (1,0) [0|1] "" XXX - -BO_ 614 STEERING_IPAS: 8 IPAS - SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX - SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX - SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX - SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 643 PRE_COLLISION: 8 XXX - -BO_ 740 STEERING_LKA: 5 XXX - SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX - SG_ STEER_REQUEST : 0|1@0+ (1,0) [0|1] "" XXX - SG_ COUNTER : 6|6@0+ (1,0) [0|63] "" XXX - SG_ SET_ME_1 : 7|1@0+ (1,0) [0|1] "" XXX - SG_ STEER_TORQUE_CMD : 15|16@0- (1,0) [0|65535] "" XXX - SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX - -BO_ 742 LEAD_INFO: 8 DSU - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" HCU - SG_ LEAD_REL_SPEED : 23|12@0- (0.025,0) [-100|100] "m/s" HCU - SG_ LEAD_LONG_DIST : 7|13@0+ (0.05,0) [0|300] "m" HCU - -BO_ 835 ACC_CONTROL: 8 DSU - SG_ ACCEL_CMD : 7|16@0- (0.001,0) [-20|20] "m/s2" HCU - SG_ SET_ME_X01 : 23|2@0+ (1,0) [0|3] "" HCU - SG_ DISTANCE : 20|1@0+ (1,0) [0|1] "" XXX - SG_ MINI_CAR : 21|1@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X3 : 19|4@0+ (1,0) [0|15] "" XXX - SG_ SET_ME_1 : 30|1@0+ (1,0) [0|1] "" HCU - SG_ RELEASE_STANDSTILL : 31|1@0+ (1,0) [0|1] "" HCU - SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 921 PCM_CRUISE_SM: 8 XXX - SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX - SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX - SG_ DISTANCE_LINES : 14|2@0+ (1,0) [0|3] "" XXX - SG_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX - -BO_ 951 ESP_CONTROL: 8 ESP - SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX - SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX - -BO_ 1041 ACC_HUD: 8 DSU - SG_ FCW : 4|1@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X20 : 15|8@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X10 : 39|8@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X80 : 55|8@0+ (1,0) [0|1] "" XXX - -BO_ 1042 LKAS_HUD: 8 XXX - SG_ BARRIERS : 1|2@0+ (1,0) [0|3] "" XXX - SG_ RIGHT_LINE : 3|2@0+ (1,0) [0|3] "" XXX - SG_ LEFT_LINE : 5|2@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_X01 : 7|2@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_X01_2 : 11|2@0+ (1,0) [0|3] "" XXX - SG_ LDA_ALERT : 9|2@0+ (1,0) [0|3] "" XXX - SG_ TWO_BEEPS : 12|1@0+ (1,0) [0|1] "" XXX - SG_ ADJUSTING_CAMERA : 13|1@0+ (1,0) [0|1] "" XXX - SG_ LDA_MALFUNCTION : 15|1@0+ (1,0) [0|1] "" XXX - SG_ REPEATED_BEEPS : 32|1@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X0C : 23|8@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X2C : 47|8@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX - -BO_ 1553 UI_SEETING: 8 XXX - SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX - -BO_ 1556 STEERING_LEVERS: 8 XXX - SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX - -BO_ 1568 SEATS_DOORS: 8 XXX - SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_FL : 45|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_RL : 42|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_RR : 43|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_FR : 44|1@0+ (1,0) [0|1] "" XXX - -BO_ 1570 LIGHT_STALK: 8 SCM - SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX - -BO_ 1161 RSA1: 8 FCM - SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX - SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX - SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX - SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX - SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX - SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX - SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX - SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX - SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX - SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX - SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX - SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX - SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX - -BO_ 1162 RSA2: 8 FCM - SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX - SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX - SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX - SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX - SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX - SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX - SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX - SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX - SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX - SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX - SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX - SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX - SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX - SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX - -BO_ 1163 RSA3: 8 FCM - SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX - SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX - SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX - SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX - SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX - SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX - SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX - SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX - SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX - -CM_ SG_ 36 ACCEL_Y "unit is tbd"; -CM_ SG_ 36 YAW_RATE "verify"; -CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; -CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; -CM_ SG_ 37 STEER_RATE "factor is tbd"; -CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors"; -CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; -CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; -CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; -CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; -CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; -CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; -CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; -CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; -CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; -CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; -CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; -CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; -CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" -CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; -CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; -CM_ SG_ 1163 TSREQPD "always 1"; -CM_ SG_ 1163 TSRMSW "always 1"; -CM_ SG_ 1163 OTSGNNTM "always 3"; -CM_ SG_ 1163 NTLVLSPD "always 3"; -CM_ SG_ 1163 OVSPNTM "always 3"; -CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; -CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; -CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; -CM_ SG_ 1163 TSRSPU "always 1"; - -VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; -VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; -VAL_ 614 STATE 3 "enabled" 1 "disabled"; -VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; -VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; -VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; -VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; -VAL_ 1042 RIGHT_LINE 3 "orange" 2 "faded" 1 "solid" 0 "none"; -VAL_ 1042 LEFT_LINE 3 "orange" 2 "faded" 1 "solid" 0 "none"; -VAL_ 1553 UNITS 1 "km" 2 "miles"; -VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; -VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; -VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; -VAL_ 1161 SPLSGN2 15 "conditional blank" 5 "rain" 0 "none"; -VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; -VAL_ 1162 SPLSGN3 15 "conditional blank" 5 "rain" 0 "none"; - - -CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; - -CM_ "toyota_chr_2018_pt.dbc starts here" - - - -BO_ 550 BRAKE_MODULE: 8 XXX - SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX - SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX - SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX - -BO_ 705 GAS_PEDAL: 8 XXX - SG_ GAS_RELEASED : 3|1@0+ (1,0) [0|1] "" XXX - SG_ GAS_PEDAL : 55|8@0+ (0.005,0) [0|1] "" XXX - -BO_ 608 STEER_TORQUE_SENSOR: 8 XXX - SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX - SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX - SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 610 EPS_STATUS: 8 EPS - SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX - SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX - SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 956 GEAR_PACKET: 8 XXX - SG_ SPORT_ON : 2|1@0+ (1,0) [0|1] "" XXX - SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX - SG_ ECON_ON : 40|1@0+ (1,0) [0|1] "" XXX - -CM_ SG_ 548 BRAKE_PRESSURE "seems prop to pedal force"; -CM_ SG_ 548 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; -CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; -VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; -VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; -VAL_ 956 GEAR 0 "D" 1 "S" 8 "N" 16 "R" 32 "P"; -VAL_ 956 SPORT_ON 0 "off" 1 "on"; -VAL_ 956 ECON_ON 0 "off" 1 "on"; diff --git a/opendbc/toyota_chr_hybrid_2018_pt_generated.dbc b/opendbc/toyota_chr_hybrid_2018_pt_generated.dbc deleted file mode 100644 index 574d3c2006bdb7..00000000000000 --- a/opendbc/toyota_chr_hybrid_2018_pt_generated.dbc +++ /dev/null @@ -1,334 +0,0 @@ -CM_ "AUTOGENERATED FILE, DO NOT EDIT" - - -CM_ "Imported file _comma.dbc starts here" -BO_ 359 STEERING_IPAS_COMMA: 8 IPAS - SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX - SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX - SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX - SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -CM BO_ STEERING_IPAS_COMMA "Copy of msg 614 so we can do angle control while the Park Assist ECU is connected (Panda spoofs 614 with 359 on connector J70). Note that addresses 0x266 and 0x167 are checksum-invariant"; - - BO_ 512 GAS_COMMAND: 6 EON - SG_ GAS_COMMAND : 7|16@0+ (0.159375,-75.555) [0|1] "" INTERCEPTOR - SG_ GAS_COMMAND2 : 23|16@0+ (0.159375,-151.111) [0|1] "" INTERCEPTOR - SG_ ENABLE : 39|1@0+ (1,0) [0|1] "" INTERCEPTOR - SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" INTERCEPTOR - SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" INTERCEPTOR - - BO_ 513 GAS_SENSOR: 6 INTERCEPTOR - SG_ INTERCEPTOR_GAS : 7|16@0+ (0.159375,-75.555) [0|1] "" EON - SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.159375,-151.111) [0|1] "" EON - SG_ STATE : 39|4@0+ (1,0) [0|15] "" EON - SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" EON - SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" EON - - VAL_ 513 STATE 5 "FAULT_TIMEOUT" 4 "FAULT_STARTUP" 3 "FAULT_SCE" 2 "FAULT_SEND" 1 "FAULT_BAD_CHECKSUM" 0 "NO_FAULT" ; - - -CM_ "Imported file _toyota_2017.dbc starts here" -VERSION "" - - -NS_ : - NS_DESC_ - CM_ - BA_DEF_ - BA_ - VAL_ - CAT_DEF_ - CAT_ - FILTER - BA_DEF_DEF_ - EV_DATA_ - ENVVAR_DATA_ - SGTYPE_ - SGTYPE_VAL_ - BA_DEF_SGTYPE_ - BA_SGTYPE_ - SIG_TYPE_REF_ - VAL_TABLE_ - SIG_GROUP_ - SIG_VALTYPE_ - SIGTYPE_VALTYPE_ - BO_TX_BU_ - BA_DEF_REL_ - BA_REL_ - BA_DEF_DEF_REL_ - BU_SG_REL_ - BU_EV_REL_ - BU_BO_REL_ - SG_MUL_VAL_ - -BS_: - -BU_: XXX DSU HCU EPS IPAS - -BO_ 36 KINEMATICS: 8 XXX - SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX - SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX - SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX - -BO_ 37 STEER_ANGLE_SENSOR: 8 XXX - SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX - SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX - SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX - -BO_ 166 BRAKE: 8 XXX - SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX - SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX - -BO_ 170 WHEEL_SPEEDS: 8 XXX - SG_ WHEEL_SPEED_FR : 7|16@0+ (0.01,-67.67) [0|250] "kph" XXX - SG_ WHEEL_SPEED_FL : 23|16@0+ (0.01,-67.67) [0|250] "kph" XXX - SG_ WHEEL_SPEED_RR : 39|16@0+ (0.01,-67.67) [0|250] "kph" XXX - SG_ WHEEL_SPEED_RL : 55|16@0+ (0.01,-67.67) [0|250] "kph" XXX - -BO_ 180 SPEED: 8 XXX - SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX - -BO_ 353 DSU_SPEED: 8 XXX - SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX - -BO_ 466 PCM_CRUISE: 8 XXX - SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX - SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX - SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX - SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX - SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 467 PCM_CRUISE_2: 8 XXX - SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX - SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX - SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 552 ACCELEROMETER: 8 XXX - SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX - SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX - -BO_ 560 BRAKE_MODULE2: 7 XXX - SG_ BRAKE_PRESSED : 26|1@0+ (1,0) [0|1] "" XXX - -BO_ 614 STEERING_IPAS: 8 IPAS - SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX - SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX - SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX - SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 643 PRE_COLLISION: 8 XXX - -BO_ 740 STEERING_LKA: 5 XXX - SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX - SG_ STEER_REQUEST : 0|1@0+ (1,0) [0|1] "" XXX - SG_ COUNTER : 6|6@0+ (1,0) [0|63] "" XXX - SG_ SET_ME_1 : 7|1@0+ (1,0) [0|1] "" XXX - SG_ STEER_TORQUE_CMD : 15|16@0- (1,0) [0|65535] "" XXX - SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX - -BO_ 742 LEAD_INFO: 8 DSU - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" HCU - SG_ LEAD_REL_SPEED : 23|12@0- (0.025,0) [-100|100] "m/s" HCU - SG_ LEAD_LONG_DIST : 7|13@0+ (0.05,0) [0|300] "m" HCU - -BO_ 835 ACC_CONTROL: 8 DSU - SG_ ACCEL_CMD : 7|16@0- (0.001,0) [-20|20] "m/s2" HCU - SG_ SET_ME_X01 : 23|2@0+ (1,0) [0|3] "" HCU - SG_ DISTANCE : 20|1@0+ (1,0) [0|1] "" XXX - SG_ MINI_CAR : 21|1@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X3 : 19|4@0+ (1,0) [0|15] "" XXX - SG_ SET_ME_1 : 30|1@0+ (1,0) [0|1] "" HCU - SG_ RELEASE_STANDSTILL : 31|1@0+ (1,0) [0|1] "" HCU - SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 921 PCM_CRUISE_SM: 8 XXX - SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX - SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX - SG_ DISTANCE_LINES : 14|2@0+ (1,0) [0|3] "" XXX - SG_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX - -BO_ 951 ESP_CONTROL: 8 ESP - SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX - SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX - -BO_ 1041 ACC_HUD: 8 DSU - SG_ FCW : 4|1@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X20 : 15|8@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X10 : 39|8@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X80 : 55|8@0+ (1,0) [0|1] "" XXX - -BO_ 1042 LKAS_HUD: 8 XXX - SG_ BARRIERS : 1|2@0+ (1,0) [0|3] "" XXX - SG_ RIGHT_LINE : 3|2@0+ (1,0) [0|3] "" XXX - SG_ LEFT_LINE : 5|2@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_X01 : 7|2@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_X01_2 : 11|2@0+ (1,0) [0|3] "" XXX - SG_ LDA_ALERT : 9|2@0+ (1,0) [0|3] "" XXX - SG_ TWO_BEEPS : 12|1@0+ (1,0) [0|1] "" XXX - SG_ ADJUSTING_CAMERA : 13|1@0+ (1,0) [0|1] "" XXX - SG_ LDA_MALFUNCTION : 15|1@0+ (1,0) [0|1] "" XXX - SG_ REPEATED_BEEPS : 32|1@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X0C : 23|8@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X2C : 47|8@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX - SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX - -BO_ 1553 UI_SEETING: 8 XXX - SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX - -BO_ 1556 STEERING_LEVERS: 8 XXX - SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX - -BO_ 1568 SEATS_DOORS: 8 XXX - SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_FL : 45|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_RL : 42|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_RR : 43|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_FR : 44|1@0+ (1,0) [0|1] "" XXX - -BO_ 1570 LIGHT_STALK: 8 SCM - SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX - -BO_ 1161 RSA1: 8 FCM - SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX - SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX - SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX - SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX - SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX - SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX - SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX - SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX - SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX - SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX - SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX - SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX - SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX - -BO_ 1162 RSA2: 8 FCM - SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX - SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX - SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX - SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX - SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX - SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX - SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX - SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX - SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX - SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX - SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX - SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX - SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX - SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX - -BO_ 1163 RSA3: 8 FCM - SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX - SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX - SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX - SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX - SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX - SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX - SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX - SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX - SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX - -CM_ SG_ 36 ACCEL_Y "unit is tbd"; -CM_ SG_ 36 YAW_RATE "verify"; -CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; -CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; -CM_ SG_ 37 STEER_RATE "factor is tbd"; -CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors"; -CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; -CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; -CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; -CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; -CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; -CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; -CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; -CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; -CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; -CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; -CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; -CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; -CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" -CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; -CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; -CM_ SG_ 1163 TSREQPD "always 1"; -CM_ SG_ 1163 TSRMSW "always 1"; -CM_ SG_ 1163 OTSGNNTM "always 3"; -CM_ SG_ 1163 NTLVLSPD "always 3"; -CM_ SG_ 1163 OVSPNTM "always 3"; -CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; -CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; -CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; -CM_ SG_ 1163 TSRSPU "always 1"; - -VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; -VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; -VAL_ 614 STATE 3 "enabled" 1 "disabled"; -VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; -VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; -VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; -VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; -VAL_ 1042 RIGHT_LINE 3 "orange" 2 "faded" 1 "solid" 0 "none"; -VAL_ 1042 LEFT_LINE 3 "orange" 2 "faded" 1 "solid" 0 "none"; -VAL_ 1553 UNITS 1 "km" 2 "miles"; -VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; -VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; -VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; -VAL_ 1161 SPLSGN2 15 "conditional blank" 5 "rain" 0 "none"; -VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; -VAL_ 1162 SPLSGN3 15 "conditional blank" 5 "rain" 0 "none"; - - -CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; - -CM_ "toyota_chr_hybrid_2018_pt.dbc starts here" - - - -BO_ 295 GEAR_PACKET: 8 XXX - SG_ CAR_MOVEMENT : 39|8@0- (1,0) [0|255] "" XXX - SG_ COUNTER : 55|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - SG_ GEAR : 47|4@0+ (1,0) [0|15] "" XXX - -BO_ 550 BRAKE_MODULE: 8 XXX - SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX - SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX - SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX - -BO_ 581 GAS_PEDAL: 8 XXX - SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX - -BO_ 608 STEER_TORQUE_SENSOR: 8 XXX - SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX - SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX - SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -BO_ 610 EPS_STATUS: 8 EPS - SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX - SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX - SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX - -CM_ SG_ 548 BRAKE_PRESSURE "seems prop to pedal force"; -CM_ SG_ 548 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; -CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; -CM_ SG_ 581 GAS_PEDAL "it seems slightly filtered"; -VAL_ 295 GEAR 0 "P" 1 "R" 2 "N" 3 "D" 4 "B"; -VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; -VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; diff --git a/opendbc/toyota_corolla_2017_pt_generated.dbc b/opendbc/toyota_corolla_2017_pt_generated.dbc index 14aff972e1d6de..f02e50195caf59 100644 --- a/opendbc/toyota_corolla_2017_pt_generated.dbc +++ b/opendbc/toyota_corolla_2017_pt_generated.dbc @@ -67,11 +67,11 @@ NS_ : BS_: -BU_: XXX DSU HCU EPS IPAS +BU_: XXX DSU HCU EPS IPAS CGW BO_ 36 KINEMATICS: 8 XXX - SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX - SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX BO_ 37 STEER_ANGLE_SENSOR: 8 XXX @@ -91,8 +91,8 @@ BO_ 170 WHEEL_SPEEDS: 8 XXX BO_ 180 SPEED: 8 XXX SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 353 DSU_SPEED: 8 XXX SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX @@ -103,6 +103,7 @@ BO_ 466 PCM_CRUISE: 8 XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 467 PCM_CRUISE_2: 8 XXX @@ -125,10 +126,19 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 643 PRE_COLLISION: 8 XXX +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX BO_ 740 STEERING_LKA: 5 XXX SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX @@ -154,6 +164,18 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + BO_ 921 PCM_CRUISE_SM: 8 XXX SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX @@ -162,6 +184,7 @@ BO_ 921 PCM_CRUISE_SM: 8 XXX BO_ 951 ESP_CONTROL: 8 ESP SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX BO_ 1041 ACC_HUD: 8 DSU @@ -186,7 +209,41 @@ BO_ 1042 LKAS_HUD: 8 XXX SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX -BO_ 1553 UI_SEETING: 8 XXX +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX BO_ 1556 STEERING_LEVERS: 8 XXX @@ -256,6 +313,9 @@ CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; @@ -279,6 +339,7 @@ VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; @@ -288,9 +349,9 @@ VAL_ 1553 UNITS 1 "km" 2 "miles"; VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; -VAL_ 1161 SPLSGN2 15 "conditional blank" 5 "rain" 0 "none"; -VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; -VAL_ 1162 SPLSGN3 15 "conditional blank" 5 "rain" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; @@ -321,6 +382,7 @@ BO_ 610 EPS_STATUS: 5 EPS BO_ 956 GEAR_PACKET: 8 XXX SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX + SG_ SPORT_ON : 3|1@0+ (1,0) [0|1] "" XXX CM_ SG_ 548 BRAKE_PRESSURE "seems prop to pedal force"; CM_ SG_ 548 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; diff --git a/opendbc/toyota_highlander_2017_pt_generated.dbc b/opendbc/toyota_highlander_2017_pt_generated.dbc index cd78b63de2e930..a5306ac8f64d05 100644 --- a/opendbc/toyota_highlander_2017_pt_generated.dbc +++ b/opendbc/toyota_highlander_2017_pt_generated.dbc @@ -67,11 +67,11 @@ NS_ : BS_: -BU_: XXX DSU HCU EPS IPAS +BU_: XXX DSU HCU EPS IPAS CGW BO_ 36 KINEMATICS: 8 XXX - SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX - SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX BO_ 37 STEER_ANGLE_SENSOR: 8 XXX @@ -91,8 +91,8 @@ BO_ 170 WHEEL_SPEEDS: 8 XXX BO_ 180 SPEED: 8 XXX SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 353 DSU_SPEED: 8 XXX SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX @@ -103,6 +103,7 @@ BO_ 466 PCM_CRUISE: 8 XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 467 PCM_CRUISE_2: 8 XXX @@ -125,10 +126,19 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 643 PRE_COLLISION: 8 XXX +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX BO_ 740 STEERING_LKA: 5 XXX SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX @@ -154,6 +164,18 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + BO_ 921 PCM_CRUISE_SM: 8 XXX SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX @@ -162,6 +184,7 @@ BO_ 921 PCM_CRUISE_SM: 8 XXX BO_ 951 ESP_CONTROL: 8 ESP SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX BO_ 1041 ACC_HUD: 8 DSU @@ -186,7 +209,41 @@ BO_ 1042 LKAS_HUD: 8 XXX SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX -BO_ 1553 UI_SEETING: 8 XXX +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX BO_ 1556 STEERING_LEVERS: 8 XXX @@ -256,6 +313,9 @@ CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; @@ -279,6 +339,7 @@ VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; @@ -288,9 +349,9 @@ VAL_ 1553 UNITS 1 "km" 2 "miles"; VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; -VAL_ 1161 SPLSGN2 15 "conditional blank" 5 "rain" 0 "none"; -VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; -VAL_ 1162 SPLSGN3 15 "conditional blank" 5 "rain" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/opendbc/toyota_highlander_hybrid_2018_pt_generated.dbc b/opendbc/toyota_highlander_hybrid_2018_pt_generated.dbc index 08831635d74c54..d19ac45fff0727 100644 --- a/opendbc/toyota_highlander_hybrid_2018_pt_generated.dbc +++ b/opendbc/toyota_highlander_hybrid_2018_pt_generated.dbc @@ -67,11 +67,11 @@ NS_ : BS_: -BU_: XXX DSU HCU EPS IPAS +BU_: XXX DSU HCU EPS IPAS CGW BO_ 36 KINEMATICS: 8 XXX - SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX - SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX BO_ 37 STEER_ANGLE_SENSOR: 8 XXX @@ -91,8 +91,8 @@ BO_ 170 WHEEL_SPEEDS: 8 XXX BO_ 180 SPEED: 8 XXX SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 353 DSU_SPEED: 8 XXX SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX @@ -103,6 +103,7 @@ BO_ 466 PCM_CRUISE: 8 XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 467 PCM_CRUISE_2: 8 XXX @@ -125,10 +126,19 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 643 PRE_COLLISION: 8 XXX +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX BO_ 740 STEERING_LKA: 5 XXX SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX @@ -154,6 +164,18 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + BO_ 921 PCM_CRUISE_SM: 8 XXX SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX @@ -162,6 +184,7 @@ BO_ 921 PCM_CRUISE_SM: 8 XXX BO_ 951 ESP_CONTROL: 8 ESP SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX BO_ 1041 ACC_HUD: 8 DSU @@ -186,7 +209,41 @@ BO_ 1042 LKAS_HUD: 8 XXX SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX -BO_ 1553 UI_SEETING: 8 XXX +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX BO_ 1556 STEERING_LEVERS: 8 XXX @@ -256,6 +313,9 @@ CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; @@ -279,6 +339,7 @@ VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; @@ -288,9 +349,9 @@ VAL_ 1553 UNITS 1 "km" 2 "miles"; VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; -VAL_ 1161 SPLSGN2 15 "conditional blank" 5 "rain" 0 "none"; -VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; -VAL_ 1162 SPLSGN3 15 "conditional blank" 5 "rain" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/opendbc/toyota_nodsu_hybrid_pt_generated.dbc b/opendbc/toyota_nodsu_hybrid_pt_generated.dbc new file mode 100644 index 00000000000000..28ad1d61aca454 --- /dev/null +++ b/opendbc/toyota_nodsu_hybrid_pt_generated.dbc @@ -0,0 +1,396 @@ +CM_ "AUTOGENERATED FILE, DO NOT EDIT" + + +CM_ "Imported file _comma.dbc starts here" +BO_ 359 STEERING_IPAS_COMMA: 8 IPAS + SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX + SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX + SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +CM BO_ STEERING_IPAS_COMMA "Copy of msg 614 so we can do angle control while the Park Assist ECU is connected (Panda spoofs 614 with 359 on connector J70). Note that addresses 0x266 and 0x167 are checksum-invariant"; + + BO_ 512 GAS_COMMAND: 6 EON + SG_ GAS_COMMAND : 7|16@0+ (0.159375,-75.555) [0|1] "" INTERCEPTOR + SG_ GAS_COMMAND2 : 23|16@0+ (0.159375,-151.111) [0|1] "" INTERCEPTOR + SG_ ENABLE : 39|1@0+ (1,0) [0|1] "" INTERCEPTOR + SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" INTERCEPTOR + SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" INTERCEPTOR + + BO_ 513 GAS_SENSOR: 6 INTERCEPTOR + SG_ INTERCEPTOR_GAS : 7|16@0+ (0.159375,-75.555) [0|1] "" EON + SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.159375,-151.111) [0|1] "" EON + SG_ STATE : 39|4@0+ (1,0) [0|15] "" EON + SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" EON + SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" EON + + VAL_ 513 STATE 5 "FAULT_TIMEOUT" 4 "FAULT_STARTUP" 3 "FAULT_SCE" 2 "FAULT_SEND" 1 "FAULT_BAD_CHECKSUM" 0 "NO_FAULT" ; + + +CM_ "Imported file _toyota_2017.dbc starts here" +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX DSU HCU EPS IPAS CGW + +BO_ 36 KINEMATICS: 8 XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX + SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX + +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + +BO_ 166 BRAKE: 8 XXX + SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX + SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX + +BO_ 170 WHEEL_SPEEDS: 8 XXX + SG_ WHEEL_SPEED_FR : 7|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_FL : 23|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_RR : 39|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_RL : 55|16@0+ (0.01,-67.67) [0|250] "kph" XXX + +BO_ 180 SPEED: 8 XXX + SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX + SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 353 DSU_SPEED: 8 XXX + SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX + +BO_ 466 PCM_CRUISE: 8 XXX + SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX + SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX + SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 552 ACCELEROMETER: 8 XXX + SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX + SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX + +BO_ 560 BRAKE_MODULE2: 7 XXX + SG_ BRAKE_PRESSED : 26|1@0+ (1,0) [0|1] "" XXX + +BO_ 614 STEERING_IPAS: 8 IPAS + SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX + SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX + SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX + +BO_ 740 STEERING_LKA: 5 XXX + SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX + SG_ STEER_REQUEST : 0|1@0+ (1,0) [0|1] "" XXX + SG_ COUNTER : 6|6@0+ (1,0) [0|63] "" XXX + SG_ SET_ME_1 : 7|1@0+ (1,0) [0|1] "" XXX + SG_ STEER_TORQUE_CMD : 15|16@0- (1,0) [0|65535] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 742 LEAD_INFO: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" HCU + SG_ LEAD_REL_SPEED : 23|12@0- (0.025,0) [-100|100] "m/s" HCU + SG_ LEAD_LONG_DIST : 7|13@0+ (0.05,0) [0|300] "m" HCU + +BO_ 835 ACC_CONTROL: 8 DSU + SG_ ACCEL_CMD : 7|16@0- (0.001,0) [-20|20] "m/s2" HCU + SG_ SET_ME_X01 : 23|2@0+ (1,0) [0|3] "" HCU + SG_ DISTANCE : 20|1@0+ (1,0) [0|1] "" XXX + SG_ MINI_CAR : 21|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X3 : 19|4@0+ (1,0) [0|15] "" XXX + SG_ SET_ME_1 : 30|1@0+ (1,0) [0|1] "" HCU + SG_ RELEASE_STANDSTILL : 31|1@0+ (1,0) [0|1] "" HCU + SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + +BO_ 921 PCM_CRUISE_SM: 8 XXX + SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX + SG_ DISTANCE_LINES : 14|2@0+ (1,0) [0|3] "" XXX + SG_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX + +BO_ 951 ESP_CONTROL: 8 ESP + SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX + +BO_ 1041 ACC_HUD: 8 DSU + SG_ FCW : 4|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X20 : 15|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X10 : 39|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X80 : 55|8@0+ (1,0) [0|1] "" XXX + +BO_ 1042 LKAS_HUD: 8 XXX + SG_ BARRIERS : 1|2@0+ (1,0) [0|3] "" XXX + SG_ RIGHT_LINE : 3|2@0+ (1,0) [0|3] "" XXX + SG_ LEFT_LINE : 5|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X01 : 7|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X01_2 : 11|2@0+ (1,0) [0|3] "" XXX + SG_ LDA_ALERT : 9|2@0+ (1,0) [0|3] "" XXX + SG_ TWO_BEEPS : 12|1@0+ (1,0) [0|1] "" XXX + SG_ ADJUSTING_CAMERA : 13|1@0+ (1,0) [0|1] "" XXX + SG_ LDA_MALFUNCTION : 15|1@0+ (1,0) [0|1] "" XXX + SG_ REPEATED_BEEPS : 32|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X0C : 23|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X2C : 47|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX + +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX + SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX + +BO_ 1568 SEATS_DOORS: 8 XXX + SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FL : 45|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RL : 42|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RR : 43|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FR : 44|1@0+ (1,0) [0|1] "" XXX + +BO_ 1570 LIGHT_STALK: 8 SCM + SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + +CM_ SG_ 36 ACCEL_Y "unit is tbd"; +CM_ SG_ 36 YAW_RATE "verify"; +CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +CM_ SG_ 37 STEER_RATE "factor is tbd"; +CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors"; +CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; +CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; +CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; +CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; +CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; +CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; +CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; +CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; +CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; +VAL_ 614 STATE 3 "enabled" 1 "disabled"; +VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; +VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; +VAL_ 1042 RIGHT_LINE 3 "orange" 2 "faded" 1 "solid" 0 "none"; +VAL_ 1042 LEFT_LINE 3 "orange" 2 "faded" 1 "solid" 0 "none"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; + + +CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; + +CM_ "toyota_nodsu_hybrid_pt.dbc starts here" + + + +BO_ 295 GEAR_PACKET: 8 XXX + SG_ CAR_MOVEMENT : 39|8@0- (1,0) [0|255] "" XXX + SG_ COUNTER : 55|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + SG_ GEAR : 47|4@0+ (1,0) [0|15] "" XXX + +BO_ 550 BRAKE_MODULE: 8 XXX + SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 581 GAS_PEDAL: 8 XXX + SG_ GAS_PEDAL : 23|8@0+ (0.005,0) [0|1] "" XXX + +BO_ 608 STEER_TORQUE_SENSOR: 8 XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX + SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + SG_ STEER_ANGLE : 31|16@0- (0.0573,0) [-500|500] "" XXX + +BO_ 610 EPS_STATUS: 8 EPS + SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX + SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX + SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +CM_ SG_ 548 BRAKE_PRESSURE "seems prop to pedal force"; +CM_ SG_ 548 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; +CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; +CM_ SG_ 581 GAS_PEDAL "it seems slightly filtered"; +VAL_ 295 GEAR 0 "P" 1 "R" 2 "N" 3 "D" 4 "B"; +VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; +VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; diff --git a/opendbc/toyota_nodsu_pt_generated.dbc b/opendbc/toyota_nodsu_pt_generated.dbc new file mode 100644 index 00000000000000..ab54939b50a4df --- /dev/null +++ b/opendbc/toyota_nodsu_pt_generated.dbc @@ -0,0 +1,408 @@ +CM_ "AUTOGENERATED FILE, DO NOT EDIT" + + +CM_ "Imported file _comma.dbc starts here" +BO_ 359 STEERING_IPAS_COMMA: 8 IPAS + SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX + SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX + SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +CM BO_ STEERING_IPAS_COMMA "Copy of msg 614 so we can do angle control while the Park Assist ECU is connected (Panda spoofs 614 with 359 on connector J70). Note that addresses 0x266 and 0x167 are checksum-invariant"; + + BO_ 512 GAS_COMMAND: 6 EON + SG_ GAS_COMMAND : 7|16@0+ (0.159375,-75.555) [0|1] "" INTERCEPTOR + SG_ GAS_COMMAND2 : 23|16@0+ (0.159375,-151.111) [0|1] "" INTERCEPTOR + SG_ ENABLE : 39|1@0+ (1,0) [0|1] "" INTERCEPTOR + SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" INTERCEPTOR + SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" INTERCEPTOR + + BO_ 513 GAS_SENSOR: 6 INTERCEPTOR + SG_ INTERCEPTOR_GAS : 7|16@0+ (0.159375,-75.555) [0|1] "" EON + SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.159375,-151.111) [0|1] "" EON + SG_ STATE : 39|4@0+ (1,0) [0|15] "" EON + SG_ COUNTER_PEDAL : 35|4@0+ (1,0) [0|15] "" EON + SG_ CHECKSUM_PEDAL : 47|8@0+ (1,0) [0|255] "" EON + + VAL_ 513 STATE 5 "FAULT_TIMEOUT" 4 "FAULT_STARTUP" 3 "FAULT_SCE" 2 "FAULT_SEND" 1 "FAULT_BAD_CHECKSUM" 0 "NO_FAULT" ; + + +CM_ "Imported file _toyota_2017.dbc starts here" +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX DSU HCU EPS IPAS CGW + +BO_ 36 KINEMATICS: 8 XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX + SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX + +BO_ 37 STEER_ANGLE_SENSOR: 8 XXX + SG_ STEER_ANGLE : 3|12@0- (1.5,0) [-500|500] "deg" XXX + SG_ STEER_FRACTION : 39|4@0- (0.1,0) [-0.7|0.7] "deg" XXX + SG_ STEER_RATE : 35|12@0- (1,0) [-2000|2000] "deg/s" XXX + +BO_ 166 BRAKE: 8 XXX + SG_ BRAKE_AMOUNT : 7|8@0+ (1,0) [0|255] "" XXX + SG_ BRAKE_PEDAL : 23|8@0+ (1,0) [0|255] "" XXX + +BO_ 170 WHEEL_SPEEDS: 8 XXX + SG_ WHEEL_SPEED_FR : 7|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_FL : 23|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_RR : 39|16@0+ (0.01,-67.67) [0|250] "kph" XXX + SG_ WHEEL_SPEED_RL : 55|16@0+ (0.01,-67.67) [0|250] "kph" XXX + +BO_ 180 SPEED: 8 XXX + SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX + SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 353 DSU_SPEED: 8 XXX + SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX + +BO_ 466 PCM_CRUISE: 8 XXX + SG_ GAS_RELEASED : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_ACTIVE : 5|1@0+ (1,0) [0|1] "" XXX + SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX + SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX + SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 467 PCM_CRUISE_2: 8 XXX + SG_ MAIN_ON : 15|1@0+ (1,0) [0|1] "" XXX + SG_ LOW_SPEED_LOCKOUT : 14|2@0+ (1,0) [0|3] "kph" XXX + SG_ SET_SPEED : 23|8@0+ (1,0) [0|255] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 552 ACCELEROMETER: 8 XXX + SG_ ACCEL_Z : 22|15@0- (1,0) [0|32767] "" XXX + SG_ ACCEL_X : 6|15@0- (0.001,0) [-20|20] "m/s2" XXX + +BO_ 560 BRAKE_MODULE2: 7 XXX + SG_ BRAKE_PRESSED : 26|1@0+ (1,0) [0|1] "" XXX + +BO_ 614 STEERING_IPAS: 8 IPAS + SG_ STATE : 7|4@0+ (1,0) [0|15] "" XXX + SG_ ANGLE : 3|12@0- (1.5,0) [-510|510] "deg" XXX + SG_ SET_ME_X10 : 23|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX + SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX + +BO_ 740 STEERING_LKA: 5 XXX + SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX + SG_ STEER_REQUEST : 0|1@0+ (1,0) [0|1] "" XXX + SG_ COUNTER : 6|6@0+ (1,0) [0|63] "" XXX + SG_ SET_ME_1 : 7|1@0+ (1,0) [0|1] "" XXX + SG_ STEER_TORQUE_CMD : 15|16@0- (1,0) [0|65535] "" XXX + SG_ CHECKSUM : 39|8@0+ (1,0) [0|255] "" XXX + +BO_ 742 LEAD_INFO: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" HCU + SG_ LEAD_REL_SPEED : 23|12@0- (0.025,0) [-100|100] "m/s" HCU + SG_ LEAD_LONG_DIST : 7|13@0+ (0.05,0) [0|300] "m" HCU + +BO_ 835 ACC_CONTROL: 8 DSU + SG_ ACCEL_CMD : 7|16@0- (0.001,0) [-20|20] "m/s2" HCU + SG_ SET_ME_X01 : 23|2@0+ (1,0) [0|3] "" HCU + SG_ DISTANCE : 20|1@0+ (1,0) [0|1] "" XXX + SG_ MINI_CAR : 21|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X3 : 19|4@0+ (1,0) [0|15] "" XXX + SG_ SET_ME_1 : 30|1@0+ (1,0) [0|1] "" HCU + SG_ RELEASE_STANDSTILL : 31|1@0+ (1,0) [0|1] "" HCU + SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + +BO_ 921 PCM_CRUISE_SM: 8 XXX + SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX + SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX + SG_ DISTANCE_LINES : 14|2@0+ (1,0) [0|3] "" XXX + SG_ UI_SET_SPEED : 31|8@0+ (1,0) [0|255] "" XXX + +BO_ 951 ESP_CONTROL: 8 ESP + SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX + SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX + +BO_ 1041 ACC_HUD: 8 DSU + SG_ FCW : 4|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X20 : 15|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X10 : 39|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X80 : 55|8@0+ (1,0) [0|1] "" XXX + +BO_ 1042 LKAS_HUD: 8 XXX + SG_ BARRIERS : 1|2@0+ (1,0) [0|3] "" XXX + SG_ RIGHT_LINE : 3|2@0+ (1,0) [0|3] "" XXX + SG_ LEFT_LINE : 5|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X01 : 7|2@0+ (1,0) [0|3] "" XXX + SG_ SET_ME_X01_2 : 11|2@0+ (1,0) [0|3] "" XXX + SG_ LDA_ALERT : 9|2@0+ (1,0) [0|3] "" XXX + SG_ TWO_BEEPS : 12|1@0+ (1,0) [0|1] "" XXX + SG_ ADJUSTING_CAMERA : 13|1@0+ (1,0) [0|1] "" XXX + SG_ LDA_MALFUNCTION : 15|1@0+ (1,0) [0|1] "" XXX + SG_ REPEATED_BEEPS : 32|1@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X0C : 23|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X2C : 47|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX + SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX + +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX + SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX + +BO_ 1556 STEERING_LEVERS: 8 XXX + SG_ TURN_SIGNALS : 29|2@0+ (1,0) [0|3] "" XXX + +BO_ 1568 SEATS_DOORS: 8 XXX + SG_ SEATBELT_DRIVER_UNLATCHED : 62|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FL : 45|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RL : 42|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RR : 43|1@0+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FR : 44|1@0+ (1,0) [0|1] "" XXX + +BO_ 1570 LIGHT_STALK: 8 SCM + SG_ AUTO_HIGH_BEAM : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 1161 RSA1: 8 FCM + SG_ TSGN1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY1 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT1 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL1 : 23|8@0+ (1,0) [0|0] "kph" XXX + SG_ SPLSGN1 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN2 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN2 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY2 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT2 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ SPDVAL2 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_P : 63|2@0+ (1,0) [0|0] "" XXX + SG_ BZRRQ_A : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID1 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1162 RSA2: 8 FCM + SG_ TSGN3 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY3 : 12|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT3 : 9|2@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN3 : 31|4@0+ (1,0) [0|0] "" XXX + SG_ SPLSGN4 : 27|4@0+ (1,0) [0|0] "" XXX + SG_ TSGN4 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ TSGNGRY4 : 44|3@0+ (1,0) [0|0] "" XXX + SG_ TSGNHLT4 : 41|2@0+ (1,0) [0|0] "" XXX + SG_ DPSGNREQ : 54|1@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMP : 53|3@0+ (1,0) [0|0] "" XXX + SG_ SGNNUMA : 50|3@0+ (1,0) [0|0] "" XXX + SG_ SPDUNT : 63|2@0+ (1,0) [0|0] "" XXX + SG_ TSRWMSG : 61|2@0+ (1,0) [0|0] "" XXX + SG_ SYNCID2 : 59|4@0+ (1,0) [0|0] "" XXX + +BO_ 1163 RSA3: 8 FCM + SG_ TSREQPD : 7|1@0+ (1,0) [0|0] "" XXX + SG_ TSRMSW : 6|1@0+ (1,0) [0|0] "" XXX + SG_ OTSGNNTM : 5|2@0+ (1,0) [0|0] "" XXX + SG_ NTLVLSPD : 3|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPNTM : 1|2@0+ (1,0) [0|0] "" XXX + SG_ OVSPVALL : 11|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALM : 19|4@0+ (1,-5) [0|0] "" XXX + SG_ OVSPVALH : 27|4@0+ (1,-5) [0|0] "" XXX + SG_ TSRSPU : 33|2@0+ (1,0) [0|0] "" XXX + +CM_ SG_ 36 ACCEL_Y "unit is tbd"; +CM_ SG_ 36 YAW_RATE "verify"; +CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; +CM_ SG_ 37 STEER_FRACTION "1/15th of the signal STEER_ANGLE, which is 1.5 deg; note that 0x8 is never set"; +CM_ SG_ 37 STEER_RATE "factor is tbd"; +CM_ SG_ 466 ACCEL_NET "net acceleration produced by the system, given ACCEL_CMD, road grade and other factors"; +CM_ SG_ 467 SET_SPEED "43 kph are shown as 28mph, so conversion isnt perfect"; +CM_ SG_ 467 LOW_SPEED_LOCKOUT "in low speed lockout, system would always disengage below 28mph"; +CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; +CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; +CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; +CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; +CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; +CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; +CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; +CM_ SG_ 1042 REPEATED_BEEPS "recommended for fcw and other important alerts"; +CM_ SG_ 1161 SPDVAL1 "Numbers 0-199 is displayed, 200-254 displays circle without number and 255 is for no limit."; +CM_ SG_ 1161 SYNCID1 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1161 SPDVAL2 "conditional speed value 70" +CM_ SG_ 1162 SGNNUMP "1 if SPDVAL1 is set, otherwise 0"; +CM_ SG_ 1162 SYNCID2 "counter from 1 to f at 1 Hz"; +CM_ SG_ 1163 TSREQPD "always 1"; +CM_ SG_ 1163 TSRMSW "always 1"; +CM_ SG_ 1163 OTSGNNTM "always 3"; +CM_ SG_ 1163 NTLVLSPD "always 3"; +CM_ SG_ 1163 OVSPNTM "always 3"; +CM_ SG_ 1163 OVSPVALL "-5 at start then 2 after 2 seconds"; +CM_ SG_ 1163 OVSPVALM "-5 at start then 5 after 2 seconds"; +CM_ SG_ 1163 OVSPVALH "-5 at start then 10 after 2 seconds"; +CM_ SG_ 1163 TSRSPU "always 1"; + +VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; +VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; +VAL_ 614 STATE 3 "enabled" 1 "disabled"; +VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; +VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; +VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; +VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; +VAL_ 1042 RIGHT_LINE 3 "orange" 2 "faded" 1 "solid" 0 "none"; +VAL_ 1042 LEFT_LINE 3 "orange" 2 "faded" 1 "solid" 0 "none"; +VAL_ 1553 UNITS 1 "km" 2 "miles"; +VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; +VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; +VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; + + +CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; + +CM_ "toyota_nodsu_pt.dbc starts here" + + + +BO_ 401 STEERING_LTA: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + SG_ SETME_X3 : 29|2@0+ (1,0) [0|3] "" XXX + SG_ PERCENTAGE : 39|8@0+ (1,0) [0|255] "" XXX + SG_ SETME_X64 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ ANGLE : 55|8@0- (0.5,0) [0|255] "" XXX + SG_ STEER_ANGLE_CMD : 15|16@0- (0.0573,0) [-540|540] "" XXX + SG_ STEER_REQUEST : 25|1@0+ (1,0) [0|1] "" XXX + SG_ BIT : 30|1@0+ (1,0) [0|1] "" XXX + +BO_ 550 BRAKE_MODULE: 8 XXX + SG_ BRAKE_PRESSURE : 0|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_POSITION : 16|9@0+ (1,0) [0|511] "" XXX + SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX + +BO_ 705 GAS_PEDAL: 8 XXX + SG_ GAS_RELEASED : 3|1@0+ (1,0) [0|1] "" XXX + SG_ GAS_PEDAL : 55|8@0+ (0.005,0) [0|1] "" XXX + +BO_ 608 STEER_TORQUE_SENSOR: 8 XXX + SG_ STEER_TORQUE_EPS : 47|16@0- (0.73,0) [-20000|20000] "" XXX + SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX + SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + SG_ STEER_ANGLE : 31|16@0- (0.0573,0) [-500|500] "" XXX + +BO_ 610 EPS_STATUS: 8 EPS + SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX + SG_ LKA_STATE : 31|7@0+ (1,0) [0|127] "" XXX + SG_ TYPE : 24|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 956 GEAR_PACKET: 8 XXX + SG_ SPORT_ON : 2|1@0+ (1,0) [0|1] "" XXX + SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX + SG_ ECON_ON : 40|1@0+ (1,0) [0|1] "" XXX + +CM_ SG_ 548 BRAKE_PRESSURE "seems prop to pedal force"; +CM_ SG_ 548 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8"; +CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others"; +VAL_ 610 IPAS_STATE 5 "override" 3 "enabled" 1 "disabled"; +VAL_ 610 LKA_STATE 25 "temporary_fault" 9 "temporary_fault2" 5 "active" 1 "standby"; +VAL_ 956 GEAR 0 "D" 1 "S" 8 "N" 16 "R" 32 "P"; +VAL_ 956 SPORT_ON 0 "off" 1 "on"; +VAL_ 956 ECON_ON 0 "off" 1 "on"; diff --git a/opendbc/toyota_prius_2010_pt.dbc b/opendbc/toyota_prius_2010_pt.dbc index 5dba519583c5bb..634b1dc0bf0b80 100644 --- a/opendbc/toyota_prius_2010_pt.dbc +++ b/opendbc/toyota_prius_2010_pt.dbc @@ -169,6 +169,7 @@ BO_ 452 POWERTRAIN: 8 XXX +CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; CM_ SG_ 36 ACCEL_Y "unit is tbd"; CM_ SG_ 36 STEERING_TORQUE "does not seem the steer torque, tbd"; CM_ SG_ 36 YAW_RATE "verify"; @@ -200,4 +201,3 @@ VAL_ 1042 RIGHT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none" ; VAL_ 1042 LEFT_LINE 3 "orange" 2 "double" 1 "solid" 0 "none" ; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none" ; VAL_ 1553 UNITS 1 "km" 2 "miles" ; -CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/opendbc/toyota_prius_2017_pt_generated.dbc b/opendbc/toyota_prius_2017_pt_generated.dbc index abc4f08171c367..2bd788e2d2105c 100644 --- a/opendbc/toyota_prius_2017_pt_generated.dbc +++ b/opendbc/toyota_prius_2017_pt_generated.dbc @@ -67,11 +67,11 @@ NS_ : BS_: -BU_: XXX DSU HCU EPS IPAS +BU_: XXX DSU HCU EPS IPAS CGW BO_ 36 KINEMATICS: 8 XXX - SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX - SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX BO_ 37 STEER_ANGLE_SENSOR: 8 XXX @@ -91,8 +91,8 @@ BO_ 170 WHEEL_SPEEDS: 8 XXX BO_ 180 SPEED: 8 XXX SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 353 DSU_SPEED: 8 XXX SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX @@ -103,6 +103,7 @@ BO_ 466 PCM_CRUISE: 8 XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 467 PCM_CRUISE_2: 8 XXX @@ -125,10 +126,19 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 643 PRE_COLLISION: 8 XXX +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX BO_ 740 STEERING_LKA: 5 XXX SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX @@ -154,6 +164,18 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + BO_ 921 PCM_CRUISE_SM: 8 XXX SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX @@ -162,6 +184,7 @@ BO_ 921 PCM_CRUISE_SM: 8 XXX BO_ 951 ESP_CONTROL: 8 ESP SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX BO_ 1041 ACC_HUD: 8 DSU @@ -186,7 +209,41 @@ BO_ 1042 LKAS_HUD: 8 XXX SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX -BO_ 1553 UI_SEETING: 8 XXX +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX BO_ 1556 STEERING_LEVERS: 8 XXX @@ -256,6 +313,9 @@ CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; @@ -279,6 +339,7 @@ VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; @@ -288,9 +349,9 @@ VAL_ 1553 UNITS 1 "km" 2 "miles"; VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; -VAL_ 1161 SPLSGN2 15 "conditional blank" 5 "rain" 0 "none"; -VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; -VAL_ 1162 SPLSGN3 15 "conditional blank" 5 "rain" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; @@ -318,6 +379,7 @@ BO_ 608 STEER_TORQUE_SENSOR: 8 XXX SG_ STEER_TORQUE_DRIVER : 15|16@0- (1,0) [-32768|32767] "" XXX SG_ STEER_OVERRIDE : 0|1@0+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + SG_ STEER_ANGLE : 31|16@0- (0.0573,0) [-500|500] "" XXX BO_ 610 EPS_STATUS: 8 EPS SG_ IPAS_STATE : 3|4@0+ (1,0) [0|15] "" XXX diff --git a/opendbc/toyota_rav4_2017_pt_generated.dbc b/opendbc/toyota_rav4_2017_pt_generated.dbc index 872715625d6892..a9e8a03e517da6 100644 --- a/opendbc/toyota_rav4_2017_pt_generated.dbc +++ b/opendbc/toyota_rav4_2017_pt_generated.dbc @@ -67,11 +67,11 @@ NS_ : BS_: -BU_: XXX DSU HCU EPS IPAS +BU_: XXX DSU HCU EPS IPAS CGW BO_ 36 KINEMATICS: 8 XXX - SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX - SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX BO_ 37 STEER_ANGLE_SENSOR: 8 XXX @@ -91,8 +91,8 @@ BO_ 170 WHEEL_SPEEDS: 8 XXX BO_ 180 SPEED: 8 XXX SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 353 DSU_SPEED: 8 XXX SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX @@ -103,6 +103,7 @@ BO_ 466 PCM_CRUISE: 8 XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 467 PCM_CRUISE_2: 8 XXX @@ -125,10 +126,19 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 643 PRE_COLLISION: 8 XXX +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX BO_ 740 STEERING_LKA: 5 XXX SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX @@ -154,6 +164,18 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + BO_ 921 PCM_CRUISE_SM: 8 XXX SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX @@ -162,6 +184,7 @@ BO_ 921 PCM_CRUISE_SM: 8 XXX BO_ 951 ESP_CONTROL: 8 ESP SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX BO_ 1041 ACC_HUD: 8 DSU @@ -186,7 +209,41 @@ BO_ 1042 LKAS_HUD: 8 XXX SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX -BO_ 1553 UI_SEETING: 8 XXX +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX BO_ 1556 STEERING_LEVERS: 8 XXX @@ -256,6 +313,9 @@ CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; @@ -279,6 +339,7 @@ VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; @@ -288,9 +349,9 @@ VAL_ 1553 UNITS 1 "km" 2 "miles"; VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; -VAL_ 1161 SPLSGN2 15 "conditional blank" 5 "rain" 0 "none"; -VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; -VAL_ 1162 SPLSGN3 15 "conditional blank" 5 "rain" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/opendbc/toyota_rav4_hybrid_2017_pt_generated.dbc b/opendbc/toyota_rav4_hybrid_2017_pt_generated.dbc index a75dcb3af916f6..27ced0f9cdb393 100644 --- a/opendbc/toyota_rav4_hybrid_2017_pt_generated.dbc +++ b/opendbc/toyota_rav4_hybrid_2017_pt_generated.dbc @@ -67,11 +67,11 @@ NS_ : BS_: -BU_: XXX DSU HCU EPS IPAS +BU_: XXX DSU HCU EPS IPAS CGW BO_ 36 KINEMATICS: 8 XXX - SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX - SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX BO_ 37 STEER_ANGLE_SENSOR: 8 XXX @@ -91,8 +91,8 @@ BO_ 170 WHEEL_SPEEDS: 8 XXX BO_ 180 SPEED: 8 XXX SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 353 DSU_SPEED: 8 XXX SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX @@ -103,6 +103,7 @@ BO_ 466 PCM_CRUISE: 8 XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 467 PCM_CRUISE_2: 8 XXX @@ -125,10 +126,19 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 643 PRE_COLLISION: 8 XXX +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX BO_ 740 STEERING_LKA: 5 XXX SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX @@ -154,6 +164,18 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + BO_ 921 PCM_CRUISE_SM: 8 XXX SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX @@ -162,6 +184,7 @@ BO_ 921 PCM_CRUISE_SM: 8 XXX BO_ 951 ESP_CONTROL: 8 ESP SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX BO_ 1041 ACC_HUD: 8 DSU @@ -186,7 +209,41 @@ BO_ 1042 LKAS_HUD: 8 XXX SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX -BO_ 1553 UI_SEETING: 8 XXX +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX BO_ 1556 STEERING_LEVERS: 8 XXX @@ -256,6 +313,9 @@ CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; @@ -279,6 +339,7 @@ VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; @@ -288,9 +349,9 @@ VAL_ 1553 UNITS 1 "km" 2 "miles"; VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; -VAL_ 1161 SPLSGN2 15 "conditional blank" 5 "rain" 0 "none"; -VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; -VAL_ 1162 SPLSGN3 15 "conditional blank" 5 "rain" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/opendbc/toyota_sienna_xle_2018_pt_generated.dbc b/opendbc/toyota_sienna_xle_2018_pt_generated.dbc index 32ef3f518a6047..2cbd918ce3e08a 100644 --- a/opendbc/toyota_sienna_xle_2018_pt_generated.dbc +++ b/opendbc/toyota_sienna_xle_2018_pt_generated.dbc @@ -67,11 +67,11 @@ NS_ : BS_: -BU_: XXX DSU HCU EPS IPAS +BU_: XXX DSU HCU EPS IPAS CGW BO_ 36 KINEMATICS: 8 XXX - SG_ ACCEL_Y : 33|10@0+ (1,-512) [0|65535] "" XXX - SG_ YAW_RATE : 1|10@0+ (1,-512) [0|65535] "" XXX + SG_ ACCEL_Y : 33|10@0+ (0.03589,-18.375) [0|65535] "m/s^2" XXX + SG_ YAW_RATE : 1|10@0+ (0.244,-125) [0|65535] "deg/sec" XXX SG_ STEERING_TORQUE : 17|10@0+ (1,-512) [0|65535] "" XXX BO_ 37 STEER_ANGLE_SENSOR: 8 XXX @@ -91,8 +91,8 @@ BO_ 170 WHEEL_SPEEDS: 8 XXX BO_ 180 SPEED: 8 XXX SG_ ENCODER : 39|8@0+ (1,0) [0|255] "" XXX - SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX SG_ SPEED : 47|16@0+ (0.01,0) [0|250] "kph" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 353 DSU_SPEED: 8 XXX SG_ FORWARD_SPEED : 15|16@0- (0.00390625,-30) [0|255] "kph" XXX @@ -103,6 +103,7 @@ BO_ 466 PCM_CRUISE: 8 XXX SG_ STANDSTILL_ON : 12|1@0+ (1,0) [0|1] "" XXX SG_ ACCEL_NET : 23|16@0- (0.001,0) [-20|20] "m/s2" XXX SG_ CRUISE_STATE : 55|4@0+ (1,0) [0|15] "" XXX + SG_ CANCEL_REQ : 49|1@1+ (1,0) [0|1] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 467 PCM_CRUISE_2: 8 XXX @@ -125,10 +126,19 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX -BO_ 643 PRE_COLLISION: 8 XXX +BO_ 643 PRE_COLLISION: 7 DSU + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00 : 15|8@0+ (1,0) [0|255] "" XXX + SG_ FORCE : 23|16@0- (2,0) [0|255] "N" XXX + SG_ SET_ME_X002 : 33|8@0+ (1,0) [0|3] "" XXX + SG_ BRAKE_STATUS : 39|3@0+ (1,0) [0|255] "" XXX + SG_ STATE : 36|3@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X003 : 40|1@0+ (1,0) [0|1] "" XXX + SG_ PRECOLLISION_ACTIVE : 41|1@0+ (1,0) [0|255] "" XXX + SG_ CHECKSUM : 55|8@0+ (1,0) [0|255] "" XXX BO_ 740 STEERING_LKA: 5 XXX SG_ LKA_STATE : 31|8@0+ (1,0) [0|255] "" XXX @@ -154,6 +164,18 @@ BO_ 835 ACC_CONTROL: 8 DSU SG_ CANCEL_REQ : 24|1@0+ (1,0) [0|1] "" HCU SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX +BO_ 836 PRE_COLLISION_2: 8 DSU + SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 869 DSU_CRUISE : 7 DSU + SG_ RES_BTN : 3|1@0+ (1,0) [0|0] "" XXX + SG_ SET_BTN : 2|1@0+ (1,0) [0|0] "" XXX + SG_ CANCEL_BTN : 1|1@0+ (1,0) [0|0] "" XXX + SG_ MAIN_ON : 0|1@0+ (1,0) [0|0] "" XXX + SG_ SET_SPEED : 15|8@0+ (1,0) [0|0] "km/h" XXX + SG_ CRUISE_REQUEST : 31|8@0+ (100,-12800) [0|0] "N" XXX + SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|0] "m" XXX + BO_ 921 PCM_CRUISE_SM: 8 XXX SG_ MAIN_ON : 4|1@0+ (1,0) [0|1] "" XXX SG_ CRUISE_CONTROL_STATE : 11|4@0+ (1,0) [0|15] "" XXX @@ -162,6 +184,7 @@ BO_ 921 PCM_CRUISE_SM: 8 XXX BO_ 951 ESP_CONTROL: 8 ESP SG_ TC_DISABLED : 13|1@0+ (1,0) [0|1] "" XXX + SG_ VSC_DISABLED : 12|2@0+ (1,0) [0|1] "" XXX SG_ BRAKE_LIGHTS_ACC : 18|1@0+ (1,0) [0|1] "" XXX BO_ 1041 ACC_HUD: 8 DSU @@ -186,7 +209,41 @@ BO_ 1042 LKAS_HUD: 8 XXX SG_ SET_ME_X38 : 55|8@0+ (1,0) [0|1] "" XXX SG_ SET_ME_X02 : 63|8@0+ (1,0) [0|1] "" XXX -BO_ 1553 UI_SEETING: 8 XXX +BO_ 1043 TIME : 8 CGW + SG_ YEAR : 7|8@0+ (1,0) [0|0] "year" XXX + SG_ MONTH : 15|8@0+ (1,0) [0|0] "month" XXX + SG_ DAY : 23|8@0+ (1,0) [0|0] "day" XXX + SG_ HOUR : 31|8@0+ (1,0) [0|0] "hour" XXX + SG_ MINUTE : 39|8@0+ (1,0) [0|0] "minute" XXX + SG_ GMT_DIFF : 55|1@0+ (1,0) [0|0] "" XXX + SG_ GMTDIFF_HOURS : 54|4@0+ (1,0) [0|0] "hours" XXX + SG_ GMTDIFF_MINUTES : 50|6@0+ (1,0) [0|0] "minutes" XXX + SG_ SUMMER : 60|1@0+ (1,0) [0|0] "" XXX + +BO_ 1408 VIN_PART_1: 8 CGW + SG_ VIN_1 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_2 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_3 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_4 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_5 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_6 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_7 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_8 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1409 VIN_PART_2: 8 CGW + SG_ VIN_9 : 7|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_10 : 15|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_11 : 23|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_12 : 31|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_13 : 39|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_14 : 47|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_15 : 55|8@0+ (1,0) [0|0] "" XXX + SG_ VIN_16 : 63|8@0+ (1,0) [0|0] "" XXX + +BO_ 1410 VIN_PART_3: 8 CGW + SG_ VIN_17 : 7|8@0+ (1,0) [0|0] "" XXX + +BO_ 1553 UI_SETTING: 8 XXX SG_ UNITS : 26|2@0+ (1,0) [0|3] "" XXX BO_ 1556 STEERING_LEVERS: 8 XXX @@ -256,6 +313,9 @@ CM_ SG_ 560 BRAKE_PRESSED "another brake pressed?"; CM_ SG_ 608 STEER_TORQUE_DRIVER "driver torque"; CM_ SG_ 608 STEER_OVERRIDE "set when driver torque exceeds a certain value"; CM_ SG_ 614 ANGLE "set to measured angle when ipas control isn't active"; +CM_ SG_ 643 COUNTER "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 BRAKE_STATUS "only used on cars that use this msg for cruise control"; +CM_ SG_ 643 PRECOLLISION_ACTIVE "set 0.5s before any braking"; CM_ SG_ 921 UI_SET_SPEED "set speed shown in UI with user set unit"; CM_ SG_ 951 BRAKE_LIGHTS_ACC "brake lights when ACC commands decel"; CM_ SG_ 1042 SET_ME_1 "unclear what this is, but it's always 1 in drive traces"; @@ -279,6 +339,7 @@ VAL_ 466 CRUISE_STATE 8 "active" 7 "standstill" 1 "off"; VAL_ 467 LOW_SPEED_LOCKOUT 2 "low speed locked" 1 "ok"; VAL_ 614 STATE 3 "enabled" 1 "disabled"; VAL_ 614 DIRECTION_CMD 3 "right" 2 "center" 1 "left"; +VAL_ 643 STATE 0 "normal" 1 "adaptive_cruise_control" 3 "emergency_braking"; VAL_ 921 CRUISE_CONTROL_STATE 2 "disabled" 11 "hold" 10 "hold_waiting_user_cmd" 6 "enabled" 5 "faulted"; VAL_ 1042 LDA_ALERT 3 "hold with continuous beep" 2 "LDA unavailable" 1 "hold" 0 "none"; VAL_ 1042 BARRIERS 3 "both" 2 "right" 1 "left" 0 "none"; @@ -288,9 +349,9 @@ VAL_ 1553 UNITS 1 "km" 2 "miles"; VAL_ 1556 TURN_SIGNALS 3 "none" 2 "right" 1 "left"; VAL_ 1161 TSGN1 1 "speed sign" 0 "none"; VAL_ 1161 TSGN2 1 "speed sign" 0 "none"; -VAL_ 1161 SPLSGN2 15 "conditional blank" 5 "rain" 0 "none"; -VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 65 "no overtake" 129 "no entry"; -VAL_ 1162 SPLSGN3 15 "conditional blank" 5 "rain" 0 "none"; +VAL_ 1161 SPLSGN2 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; +VAL_ 1162 TSGN3 0 "none" 1 "speed sign" 2 "0 unlimited" 7 "unlimited" 16 "highway" 17 "no highway" 18 "motorway" 19 "no motorway" 20 "in city" 21 "outside city" 22 "pedestrian area" 23 "no pedestrian area" 65 "no overtaking left" 66 "no overtaking right" 67 "overtaking allowed again" 129 "no entry"; +VAL_ 1162 SPLSGN3 15 "conditional blank" 4 "wet road" 5 "rain" 0 "none"; CM_ "CHFFR_METRIC 37 STEER_ANGLE STEER_ANGLE 0.36 180"; diff --git a/opendbc/toyota_tss2_adas.dbc b/opendbc/toyota_tss2_adas.dbc new file mode 100644 index 00000000000000..d472debd6156ac --- /dev/null +++ b/opendbc/toyota_tss2_adas.dbc @@ -0,0 +1,285 @@ +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX + + +BO_ 384 TRACK_A_0: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 385 TRACK_A_1: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 386 TRACK_A_2: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 387 TRACK_A_3: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 388 TRACK_A_4: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 389 TRACK_A_5: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 390 TRACK_A_6: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 391 TRACK_A_7: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 392 TRACK_A_8: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 393 TRACK_A_9: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 394 TRACK_A_10: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 395 TRACK_A_11: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 396 TRACK_A_12: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 397 TRACK_A_13: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 398 TRACK_A_14: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 399 TRACK_A_15: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ LAT_DIST : 31|11@0- (0.04,0) [-50|50] "m" XXX + SG_ LONG_DIST : 15|13@0+ (0.04,0) [0|300] "m" XXX + SG_ NEW_TRACK : 36|1@0+ (1,0) [0|1] "" XXX + SG_ REL_SPEED : 47|12@0- (0.025,0) [-100|100] "m/s" XXX + SG_ VALID : 48|1@0+ (1,0) [0|1] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 400 TRACK_B_0: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 401 TRACK_B_1: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 402 TRACK_B_2: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 403 TRACK_B_3: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 404 TRACK_B_4: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 405 TRACK_B_5: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 406 TRACK_B_6: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 407 TRACK_B_7: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 408 TRACK_B_8: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 409 TRACK_B_9: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 410 TRACK_B_10: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 411 TRACK_B_11: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 412 TRACK_B_12: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 413 TRACK_B_13: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 414 TRACK_B_14: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 415 TRACK_B_15: 8 XXX + SG_ COUNTER : 7|8@0+ (1,0) [0|255] "" XXX + SG_ REL_ACCEL : 15|7@0- (1,0) [-64|63] "" XXX + SG_ SCORE : 23|8@0+ (1,0) [0|100] "" XXX + SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX + +BO_ 576 NEW_MSG_1: 8 XXX + SG_ NEW_SIGNAL_1 : 15|7@0+ (1,0) [0|127] "" XXX + SG_ NEW_SIGNAL_2 : 23|8@0+ (1,0) [0|255] "" XXX + +BO_ 577 NEW_MSG_2: 8 XXX + SG_ NEW_SIGNAL_1 : 15|7@0+ (1,0) [0|127] "" XXX + SG_ NEW_SIGNAL_2 : 23|8@0+ (1,0) [0|255] "" XXX diff --git a/opendbc/vw_golf_mk4.dbc b/opendbc/vw_golf_mk4.dbc index 596f2d082ad041..bdfe6390f77740 100644 --- a/opendbc/vw_golf_mk4.dbc +++ b/opendbc/vw_golf_mk4.dbc @@ -1,7 +1,7 @@ VERSION "" -NS_ : +NS_ : NS_DESC_ CM_ BA_DEF_ @@ -187,10 +187,10 @@ BO_ 1298 PSG_2: 8 XXX SG_ RAM_Inhalt_1 : 0|16@1+ (1,0) [0|0] "" XXX BO_ 274 PSG_1: 8 XXX - SG_ Pumpentemperatur__2_1_ : 48|16@1+ (0.0625,0) [0|4096] "°K" XXX + SG_ Pumpentemperatur__2_1_ : 48|16@1+ (0.0625,0) [0|4096] "K" XXX SG_ Pumpentemperatur__3_2_2_ : 44|12@1+ (1,0) [0|0] "" XXX - SG_ Zylinderzaehler__3_2_2_ : 43|3@1+ (1,0) [1|8] "Zähler" XXX - SG_ Ansteuerdauer__3_2_2_ : 32|11@1+ (0.0469,0) [0|96] "°NW" XXX + SG_ Zylinderzaehler__3_2_2_ : 43|3@1+ (1,0) [1|8] "Zaehler" XXX + SG_ Ansteuerdauer__3_2_2_ : 32|11@1+ (0.0469,0) [0|96] "NW" XXX SG_ Nockenwellendrehzahl__3_2_2_ : 20|12@1+ (4,0) [0|16380] "upm" XXX SG_ Pumpen_Statuswort__3_2_2_ : 0|20@1+ (1,0) [0|0] "" XXX @@ -233,7 +233,7 @@ BO_ 1424 Niveau_1: 6 XXX SG_ ESP_Beeinflussung : 14|1@1+ (1,0) [0|0] "" XXX SG_ Warnlampe_Niveau_1 : 13|1@1+ (1,0) [0|0] "" XXX SG_ Frei_Niveau_1_1 : 12|1@1+ (1,0) [0|0] "" XXX - SG_ Zaehler_Niveau_1 : 8|4@1+ (1,0) [0|15] "Zähler" XXX + SG_ Zaehler_Niveau_1 : 8|4@1+ (1,0) [0|15] "Zaehler" XXX SG_ Checksumme_Niveau_1 : 0|8@1+ (1,0) [0|0] "" XXX BO_ 1328 Navigation_1: 7 XXX @@ -248,11 +248,11 @@ BO_ 1328 Navigation_1: 7 XXX SG_ Laenderkennung : 16|8@1+ (1,0) [0|0] "" XXX SG_ Vorzeichen_Gierrate______ : 15|1@1+ (1,0) [0|0] "" XXX SG_ Gierratenfehler : 14|1@1+ (1,0) [0|0] "" XXX - SG_ Gierrate : 0|14@1+ (0.01,0) [0|100] "°/sek" XXX + SG_ Gierrate : 0|14@1+ (0.01,0) [0|100] "deg/sek" XXX BO_ 1792 MSG_3: 3 XXX SG_ MSG_Konfiguration : 16|8@1+ (1,0) [0|0] "" XXX - SG_ Lage_des_OT_Impuls : 0|16@1+ (0.01172,-384) [-384|384] "°KW" XXX + SG_ Lage_des_OT_Impuls : 0|16@1+ (0.01172,-384) [-384|384] "KW" XXX BO_ 1280 MSG_2: 8 XXX SG_ RAM_Adresse_4 : 48|16@1+ (1,0) [0|0] "" XXX @@ -262,8 +262,8 @@ BO_ 1280 MSG_2: 8 XXX BO_ 256 MSG_1: 8 XXX SG_ Kurbelwellendrehzahl__3_2_2_ : 56|8@1+ (1,0) [0|0] "" XXX - SG_ Soll_Foerderbeginn_KW__3_2_2_ : 40|16@1+ (0.01172,-384) [-384|384] "°KW" XXX - SG_ Soll_Foerderbeginn_NW__3_2_2_ : 28|12@1+ (0.01172,0) [0|768] "°NW" XXX + SG_ Soll_Foerderbeginn_KW__3_2_2_ : 40|16@1+ (0.01172,-384) [-384|384] "KW" XXX + SG_ Soll_Foerderbeginn_NW__3_2_2_ : 28|12@1+ (0.01172,0) [0|768] "degNW" XXX SG_ Soll_Voreinspritzung : 16|12@1+ (1,0) [0|0] "" XXX SG_ Soll_Einspritzmenge : 0|16@1+ (0.03125,0) [0|2047] "mg/H" XXX @@ -273,7 +273,7 @@ BO_ 1796 Motor_NOX: 8 XXX SG_ Heizleistungsanforderung : 18|1@1+ (1,0) [0|0] "" XXX SG_ Offsetkorrektur_moeglich : 17|1@1+ (1,0) [0|0] "" XXX SG_ Betriebsbereich : 16|1@1+ (1,0) [0|0] "" XXX - SG_ Abgastemperatur_NOX : 8|8@1+ (5,-40) [-40|1230] "°C" XXX + SG_ Abgastemperatur_NOX : 8|8@1+ (5,-40) [-40|1230] "C" XXX SG_ Abgasdruck_NOX : 0|8@1+ (5,600) [600|1870] "mbar" XXX BO_ 900 Motor_Momente: 8 XXX @@ -361,7 +361,7 @@ BO_ 896 Motor_3: 8 XXX SG_ Vorzeichen_Rad_Wunschmoment : 36|1@1+ (1,0) [0|0] "" XXX SG_ Rad_Wunschmoment : 24|12@1+ (0.39,0) [0|1597] "MDI" XXX SG_ Fahrpedal_Rohsignal : 16|8@1+ (0.4,0) [0|101.6] "%" XXX - SG_ Ansauglufttemperatur : 8|8@1+ (0.75,-48) [-48|142.5] "°" XXX + SG_ Ansauglufttemperatur : 8|8@1+ (0.75,-48) [-48|142.5] "" XXX SG_ Fehlerstatus_Ansauglufttemperat : 7|1@1+ (1,0) [0|0] "" XXX SG_ Motorsteuerger_t_gesperrt : 6|1@1+ (1,0) [0|0] "" XXX SG_ Drosselklappenwinkel_ungenau : 5|1@1+ (1,0) [0|0] "" XXX @@ -384,7 +384,7 @@ BO_ 648 Motor_2: 8 XXX SG_ Fehlerstatus_Kuhlmitteltempera : 18|1@1+ (1,0) [0|0] "" XXX SG_ Bremstestschalter : 17|1@1+ (1,0) [0|0] "" XXX SG_ Bremslichtschalter : 16|1@1+ (1,0) [0|0] "" XXX - SG_ Kuehlmitteltemperatur__Motor_2_ : 8|8@1+ (0.75,-48) [-48|142.5] "°" XXX + SG_ Kuehlmitteltemperatur__Motor_2_ : 8|8@1+ (0.75,-48) [-48|142.5] "" XXX SG_ Multiplex_Code_Motor_2 M : 6|2@1+ (1,0) [0|0] "" XXX SG_ Multiplex_Info_Motorcode__4_x_ m1 : 0|6@1+ (1,0) [0|0] "" XXX SG_ Multiplex_Info_Getriebecode m2 : 0|6@1+ (1,0) [0|0] "" XXX @@ -409,7 +409,7 @@ BO_ 640 Motor_1: 8 XXX BO_ 262 Master_3: 8 XXX SG_ Frei_Master_3_1 : 56|8@1+ (1,0) [0|0] "" XXX - SG_ Motortemperatur_linearisiert : 48|8@1+ (0.75,-48) [-48|143.25] "°" XXX + SG_ Motortemperatur_linearisiert : 48|8@1+ (0.75,-48) [-48|143.25] "" XXX SG_ Indiziertes_Sollmoment_f_r_Vmax : 32|16@1+ (0.0015259,0) [0|100] "%" XXX SG_ Relative_Momentenanforderung_de : 16|16@1+ (0.003052,0) [0|200] "%" XXX SG_ Delta_Motormoment_aus_Verlustmo : 0|16@1+ (0.003052,-100) [-100|100] "%" XXX @@ -448,7 +448,7 @@ BO_ 1986 Lenkwinkel_Init: 4 XXX BO_ 192 Lenkwinkel_1__RB_: 2 XXX SG_ Vorzeichen__RB_ : 15|1@1+ (1,0) [0|0] "" XXX - SG_ Lenkwinkel__RB_ : 5|10@1+ (2.5,-720) [-720|720] "°" XXX + SG_ Lenkwinkel__RB_ : 5|10@1+ (2.5,-720) [-720|720] "" XXX SG_ LWS_OK__RB_ : 4|1@1+ (1,0) [0|0] "" XXX SG_ LWS_Abgleich__RB_ : 3|1@1+ (1,0) [0|0] "" XXX SG_ Frei_Lenkwinkel_1_1__RB_ : 2|1@1+ (1,0) [0|0] "" XXX @@ -457,7 +457,7 @@ BO_ 192 Lenkwinkel_1__RB_: 2 XXX BO_ 196 Lenkwinkel_1__ITT_: 2 XXX SG_ Vorzeichen__ITT_ : 15|1@1+ (1,0) [0|0] "" XXX - SG_ Lenkwinkel__ITT_ : 5|10@1+ (1.5,-768) [-768|766.5] "°" XXX + SG_ Lenkwinkel__ITT_ : 5|10@1+ (1.5,-768) [-768|766.5] "" XXX SG_ LWS_OK : 4|1@1+ (1,0) [0|0] "" XXX SG_ LWS_Abgleich__ITT_ : 3|1@1+ (1,0) [0|0] "" XXX SG_ LWS_Initialisierung__ITT_ : 2|1@1+ (1,0) [0|0] "" XXX @@ -558,10 +558,10 @@ BO_ 1056 Kombi_2: 8 XXX SG_ Klemme_58s__Kombi_2_ : 48|7@1+ (1,0) [0|100] "%" XXX SG_ Fehlerstatus_Kl__58_d : 47|1@1+ (1,0) [0|0] "" XXX SG_ Klemme_58d__Kombi_2_ : 40|7@1+ (1,0) [0|100] "%" XXX - SG_ Kuehlmitteltemp__4_1__Kombi_2_ : 32|8@1+ (0.75,-48) [-48|142.5] "°C" XXX - SG_ Oeltemperatur_4_1 : 24|8@1+ (1,-60) [-60|194] "°C" XXX - SG_ Aussentemp__ungefiltert_4_1__Ko : 16|8@1+ (0.5,-50) [-50|77] "°C" XXX - SG_ Aussentemperatur_gefiltert : 8|8@1+ (0.5,-50) [-50|77] "°C" XXX + SG_ Kuehlmitteltemp__4_1__Kombi_2_ : 32|8@1+ (0.75,-48) [-48|142.5] "C" XXX + SG_ Oeltemperatur_4_1 : 24|8@1+ (1,-60) [-60|194] "C" XXX + SG_ Aussentemp__ungefiltert_4_1__Ko : 16|8@1+ (0.5,-50) [-50|77] "C" XXX + SG_ Aussentemperatur_gefiltert : 8|8@1+ (0.5,-50) [-50|77] "C" XXX SG_ Fehlerspeichereintrag__Kombi_ : 7|1@1+ (1,0) [0|0] "" XXX SG_ Frei_Kombi_2_1 : 4|3@1+ (1,0) [0|0] "" XXX SG_ Anhaenger_erkannt : 3|1@1+ (1,0) [0|0] "" XXX @@ -596,7 +596,7 @@ BO_ 800 Kombi_1: 8 XXX SG_ Fahrertuer_4_1 : 0|1@1+ (1,0) [0|0] "" XXX BO_ 1504 Klima_1: 8 XXX - SG_ Aussentemp__ungef__Sto_f__4_1 : 56|8@1+ (0.5,-50) [-50|77] "°C" XXX + SG_ Aussentemp__ungef__Sto_f__4_1 : 56|8@1+ (0.5,-50) [-50|77] "C" XXX SG_ Fehlerspeichereintrag__Klima_ : 55|1@1+ (1,0) [0|0] "" XXX SG_ Frei_Klima_1_5 : 50|5@1+ (1,0) [0|0] "" XXX SG_ AC_Schalter : 49|1@1+ (1,0) [0|0] "" XXX @@ -605,7 +605,7 @@ BO_ 1504 Klima_1: 8 XXX SG_ Geblaeselast_4_1 : 32|8@1+ (0.4,0) [0|101.6] "%" XXX SG_ Kompressorlast : 24|8@1+ (0.25,0) [0|63.5] "Nm" XXX SG_ Klimadrucksignal__Klima_1_ : 16|8@1+ (0.2,0) [0|50.8] "bar" XXX - SG_ Aussentemp__ungef__4_1__Klima_1 : 8|8@1+ (0.5,-50) [-50|77] "°C" XXX + SG_ Aussentemp__ungef__4_1__Klima_1 : 8|8@1+ (0.5,-50) [-50|77] "C" XXX SG_ Kaeltemitteldruck_veraltet : 7|1@1+ (1,0) [0|0] "" XXX SG_ Kompressormoment_veraltet_4_1 : 6|1@1+ (1,0) [0|0] "" XXX SG_ Keine_Heizleistg_gewuenscht_4_1 : 5|1@1+ (1,0) [0|0] "" XXX @@ -836,9 +836,9 @@ BO_ 1192 Bremse_5: 8 XXX SG_ Checksumme_Bremse_5 : 56|8@1+ (1,0) [0|0] "" XXX SG_ Zaehler_Bremse_5 : 52|4@1+ (1,0) [0|15] "" XXX SG_ Bremslicht_ECD : 51|1@1+ (1,0) [0|0] "" XXX - SG_ Bremsentemperatur_vorn : 48|3@1+ (125,125) [125|1000] "°C" XXX + SG_ Bremsentemperatur_vorn : 48|3@1+ (125,125) [125|1000] "C" XXX SG_ Frei_Bremse_5_5 : 40|8@1+ (1,0) [0|0] "" XXX - SG_ Offset_Gierrate : 32|8@1+ (0.05,-6.375) [-6.375|6.375] "°/s" XXX + SG_ Offset_Gierrate : 32|8@1+ (0.05,-6.375) [-6.375|6.375] "deg/s" XXX SG_ Vorzeichen_Bremsdruck : 31|1@1+ (1,0) [0|0] "" XXX SG_ Status_Bremsdruck_durch_ESP_Sys : 30|1@1+ (1,0) [0|0] "" XXX SG_ Bremsdruck_ungueltig : 29|1@1+ (1,0) [0|0] "" XXX @@ -1039,3 +1039,12 @@ BO_ 1324 ADR_1: 8 XXX SG_ Fehler_ADR_1 : 12|1@1+ (1,0) [0|0] "" XXX SG_ Zaehler_ADR_1 : 8|4@1+ (1,0) [0|15] "" XXX SG_ Momentenanforderung_ADR : 0|8@1+ (0.39,0) [0|99] "MDI" XXX + +BO_ 210 PQ_HCA: 8 XXX + SG_ HCA_Torque : 16|15@1+ (1,0) [0|32767] "" XXX + SG_ UNK_Bit : 34|1@0+ (1,0) [0|1] "" XXX + SG_ HCA_Torque_VZ : 31|1@0+ (1,0) [0|1] "" XXX + SG_ PQ_HCA_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ PQ_HCA_Checksum : 0|4@1+ (1,0) [0|15] "" XXX + +BO_ 1490 VIN_1: 8 XXX diff --git a/opendbc/vw_mqb_2010.dbc b/opendbc/vw_mqb_2010.dbc index 9e7c7772a91c5f..063cd1b795b614 100644 --- a/opendbc/vw_mqb_2010.dbc +++ b/opendbc/vw_mqb_2010.dbc @@ -1,7 +1,7 @@ VERSION "" -NS_ : +NS_ : NS_DESC_ CM_ BA_DEF_ @@ -33,97 +33,97 @@ NS_ : BS_: -BU_: Airbag_MQB BAP_Tester_MQB BMS_MQB Datenlogger_MQB Gateway_MQB Getriebe_DQ_Hybrid_MQB Getriebe_DQ_MQB LEH_MQB Motor_Diesel_MQB Motor_Hybrid_MQB Motor_Otto_MQB SAK_MQB Waehlhebel_MQB +BU_: Airbag_MQB BAP_Tester_MQB BMS_MQB Datenlogger_MQB Gateway_MQB Getriebe_DQ_Hybrid_MQB Getriebe_DQ_MQB LEH_MQB Motor_Diesel_MQB Motor_Hybrid_MQB Motor_Otto_MQB SAK_MQB Waehlhebel_MQB Vector__XXX 9 l c i XXX BO_ 290 ACC_06: 8 Gateway_MQB - SG_ ACC_06_CRC : 0|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_06_BZ : 8|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_limitierte_Anfahrdyn : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_zul_Regelabw_unten : 16|6@1+ (0.024,0) [0|1.512] "Unit_MeterPerSeconSquar" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_StartStopp_Info : 22|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ ACC_Sollbeschleunigung_02 : 24|11@1+ (0.005,-7.22) [-7.22|3.005] "Unit_MeterPerSeconSquar" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_zul_Regelabw_oben : 35|5@1+ (0.0625,0) [0|1.9375] "Unit_MeterPerSeconSquar" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_neg_Sollbeschl_Grad_02 : 40|8@1+ (0.05,0) [0|12.75] "Unit_MeterPerCubicSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_pos_Sollbeschl_Grad_02 : 48|8@1+ (0.05,0) [0|12.75] "Unit_MeterPerCubicSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_Anfahren : 56|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_Anhalten : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_Typ : 58|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_Status_ACC : 60|3@1+ (1,0) [0|7] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_Minimale_Bremsung : 63|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_limitierte_Anfahrdyn : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_zul_Regelabw_unten : 16|6@1+ (0.024,0) [0|1.512] "Unit_MeterPerSeconSquar" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_StartStopp_Info : 22|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ ACC_Sollbeschleunigung_02 : 24|11@1+ (0.005,-7.22) [-7.22|3.005] "Unit_MeterPerSeconSquar" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_zul_Regelabw_oben : 35|5@1+ (0.0625,0) [0|1.9375] "Unit_MeterPerSeconSquar" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_neg_Sollbeschl_Grad_02 : 40|8@1+ (0.05,0) [0|12.75] "Unit_MeterPerCubicSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_pos_Sollbeschl_Grad_02 : 48|8@1+ (0.05,0) [0|12.75] "Unit_MeterPerCubicSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_Anfahren : 56|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_Anhalten : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_Typ : 58|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_Status_ACC : 60|3@1+ (1,0) [0|7] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_Minimale_Bremsung : 63|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 279 ACC_10: 8 Gateway_MQB - SG_ ACC_10_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ ACC_10_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB - SG_ AWV1_Anf_Prefill : 16|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" Airbag_MQB + SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" Airbag_MQB + SG_ AWV1_Anf_Prefill : 16|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ ANB_CM_Info : 17|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ AWV2_Freigabe : 18|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ AWV2_Freigabe : 18|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ AWV1_HBA_Param : 19|2@1+ (1,0) [0|3] "" Vector__XXX SG_ AWV2_Ruckprofil : 21|3@1+ (1,0) [0|7] "" Vector__XXX SG_ AWV2_Priowarnung : 24|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ANB_CM_Anforderung : 25|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ ANB_CM_Anforderung : 25|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ ANB_Info_Teilbremsung : 26|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ANB_Notfallblinken : 27|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ANB_Teilbremsung_Freigabe : 28|1@1+ (1,0) [0|1] "" Airbag_MQB - SG_ ANB_Zielbrems_Teilbrems_Verz_Anf : 29|10@1+ (0.024,-20.016) [-20.016|4.536] "Unit_MeterPerSeconSquar" Airbag_MQB - SG_ ANB_Zielbremsung_Freigabe : 39|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ ANB_Teilbremsung_Freigabe : 28|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ ANB_Zielbrems_Teilbrems_Verz_Anf : 29|10@1+ (0.024,-20.016) [-20.016|4.536] "Unit_MeterPerSeconSquar" Airbag_MQB + SG_ ANB_Zielbremsung_Freigabe : 39|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ AWV_Vorstufe : 40|1@1+ (1,0) [0|1] "" Vector__XXX SG_ AWV_Halten : 41|1@1+ (1,0) [0|1] "" Vector__XXX BO_ 64 Airbag_01: 8 Airbag_MQB - SG_ Airbag_01_CRC : 0|8@1+ (1,0) [0|255] "" BMS_MQB,Gateway_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Airbag_01_BZ : 8|4@1+ (1,0) [0|15] "" BMS_MQB,Gateway_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ AB_RGS_Anst : 12|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ AB_Front_Crash : 16|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Heck_Crash : 17|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_SF_Crash : 18|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_SB_Crash : 19|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Rollover_Crash : 20|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Crash_Int : 21|3@1+ (1,0) [0|7] "" BMS_MQB,Gateway_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ AB_Lampe : 24|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Deaktiviert : 25|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_VB_deaktiviert : 26|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Systemfehler : 27|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,LEH_MQB - SG_ AB_Diagnose : 28|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Stellgliedtest : 29|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ AB_Erh_Auf_VB : 30|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtwarn_VF : 32|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Gurtwarn_VB : 33|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Anzeige_Fussg : 34|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Texte_AKS : 36|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_PAO_Leuchte_Anf : 38|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_MKB_gueltig : 39|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_MKB_Anforderung : 40|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Versorgungsspannung : 41|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ Airbag_01_CRC : 0|8@1+ (1,0) [0|255] "" BMS_MQB,Gateway_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Airbag_01_BZ : 8|4@1+ (1,0) [0|15] "" BMS_MQB,Gateway_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AB_RGS_Anst : 12|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ AB_Front_Crash : 16|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Heck_Crash : 17|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_SF_Crash : 18|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_SB_Crash : 19|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Rollover_Crash : 20|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Crash_Int : 21|3@1+ (1,0) [0|7] "" BMS_MQB,Gateway_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AB_Lampe : 24|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Deaktiviert : 25|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_VB_deaktiviert : 26|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Systemfehler : 27|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,LEH_MQB + SG_ AB_Diagnose : 28|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Stellgliedtest : 29|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AB_Erh_Auf_VB : 30|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtwarn_VF : 32|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Gurtwarn_VB : 33|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Anzeige_Fussg : 34|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Texte_AKS : 36|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_PAO_Leuchte_Anf : 38|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_MKB_gueltig : 39|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_MKB_Anforderung : 40|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Versorgungsspannung : 41|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 1312 Airbag_02: 8 Airbag_MQB - SG_ AB_Belegung_VB : 26|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtschloss_FA : 40|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Otto_MQB - SG_ AB_Gurtschloss_BF : 42|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtschloss_Reihe2_FA : 44|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtschloss_Reihe2_MI : 46|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtschloss_Reihe2_BF : 48|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtschloss_Reihe3_FA : 50|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtschloss_Reihe3_MI : 52|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtschloss_Reihe3_BF : 54|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Sitzpos_Sens_FA : 56|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Sitzpos_Sens_BF : 58|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Belegung_VB : 26|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtschloss_FA : 40|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Otto_MQB + SG_ AB_Gurtschloss_BF : 42|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtschloss_Reihe2_FA : 44|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtschloss_Reihe2_MI : 46|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtschloss_Reihe2_BF : 48|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtschloss_Reihe3_FA : 50|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtschloss_Reihe3_MI : 52|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtschloss_Reihe3_BF : 54|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Sitzpos_Sens_FA : 56|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Sitzpos_Sens_BF : 58|2@1+ (1,0) [0|3] "" Gateway_MQB BO_ 65 Airbag_03: 8 Airbag_MQB - SG_ Airbag_03_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB - SG_ Airbag_03_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ AB_MKB_Safing : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ Airbag_03_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB + SG_ Airbag_03_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ AB_MKB_Safing : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 1633 Anhaenger_01: 8 Gateway_MQB - SG_ AAG_BZ : 0|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ AAG_Bremsl_durch_ECD : 5|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AAG_BZ : 0|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AAG_Bremsl_durch_ECD : 5|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ AAG_Anhaenger_abgesteckt : 6|1@1+ (1,0) [0|1] "" Vector__XXX SG_ AAG_NSL_aktiv : 7|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ AAG_Anhaenger_erkannt : 8|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AAG_Anhaenger_erkannt : 8|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ AAG_Blinker_H_aktiv : 9|1@1+ (1,0) [0|1] "" Vector__XXX SG_ AAG_Blinker_HL_def : 10|1@1+ (1,0) [0|1] "" Vector__XXX SG_ AAG_Blinker_HR_def : 11|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ AAG_Bremslicht_H_def : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AAG_Bremslicht_H_def : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ AAG_Schlusslicht_HL_def : 13|1@1+ (1,0) [0|1] "" Vector__XXX SG_ AAG_Schlusslicht_HR_def : 14|1@1+ (1,0) [0|1] "" Vector__XXX SG_ AAG_AVS_Fehler_02 : 18|1@1+ (1,0) [0|1] "" Vector__XXX @@ -134,99 +134,99 @@ BO_ 1626 BCM_01: 8 Gateway_MQB SG_ BCM_Bremsfluessigkeit_Sensor : 13|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BCM1_Licht_Warn : 14|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BCM_Waschwasser_Sensor : 15|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ BCM_Kuehlmittel_Sensor : 16|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ BCM_Kuehlmittel_Sensor : 16|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB SG_ BCM1_Kl_15_HW_erkannt : 17|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ BCM_Eis_Offroad_Taste : 18|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Otto_MQB + SG_ BCM_Eis_Offroad_Taste : 18|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Otto_MQB SG_ ZZH_Endlage_oben : 19|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ZZH_Endlage_unten : 20|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ZZH_Endlage_unplausibel : 21|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BCM2_EZS_gedrueckt : 22|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BCM2_SST_gedrueckt : 23|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ BCM_Hybrid_StartStopp_Taste : 24|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM_Hybrid_StartStopp_Taste : 24|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ BCM1_Warnblink_Taster : 25|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BCM1_Valet_Parking_Taster : 26|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ BCM_Remotestart_Betrieb : 27|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ BCM_Remotestart_Betrieb : 27|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB SG_ BCM1_HSK_Taster : 28|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BCM1_Heckrollo_Taster : 29|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ BCM1_Rueckfahrlicht_Schalter : 30|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BCM1_MH_Schalter : 31|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ BCM1_MH_WIV_Schalter : 32|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BCM_Eco_Charisma_Taste : 33|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ BCM_Thermomanagement : 34|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BCM_Thermomanagement_Fehler : 36|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BCM_Thermomanagement_gueltig : 37|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM1_Rueckfahrlicht_Schalter : 30|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM1_MH_Schalter : 31|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ BCM1_MH_WIV_Schalter : 32|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM_Eco_Charisma_Taste : 33|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ BCM_Thermomanagement : 34|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM_Thermomanagement_Fehler : 36|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM_Thermomanagement_gueltig : 37|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ BCM1_Lichtwarn_Texte : 38|2@1+ (1,0) [0|3] "" Vector__XXX BO_ 869 BEM_05: 8 Gateway_MQB - SG_ BEM_P_Generator : 16|8@1+ (50,0) [0|12700] "Unit_Watt" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_n_LLA : 24|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_01_Abschaltstufen : 26|3@1+ (1,0) [0|7] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_Anf_KL : 29|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_StartStopp_Info : 30|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ BEM_DFM : 32|5@1+ (3.225,0.025) [0.025|100] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_EMLIN_ungueltig : 37|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_Batt_Ab : 38|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_Segel_Info : 48|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_HYB_DC_uSollLV : 50|6@1+ (0.1,10.6) [10.6|16] "Unit_Volt" LEH_MQB - SG_ BEM_HYB_DC_uMinLV : 56|8@1+ (0.1,0) [0|25.3] "Unit_Volt" LEH_MQB + SG_ BEM_P_Generator : 16|8@1+ (50,0) [0|12700] "Unit_Watt" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_n_LLA : 24|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_01_Abschaltstufen : 26|3@1+ (1,0) [0|7] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_Anf_KL : 29|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_StartStopp_Info : 30|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ BEM_DFM : 32|5@1+ (3.225,0.025) [0.025|100] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_EMLIN_ungueltig : 37|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_Batt_Ab : 38|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_Segel_Info : 48|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_HYB_DC_uSollLV : 50|6@1+ (0.1,10.6) [10.6|16] "Unit_Volt" LEH_MQB + SG_ BEM_HYB_DC_uMinLV : 56|8@1+ (0.1,0) [0|25.3] "Unit_Volt" LEH_MQB BO_ 1628 BMS_Hybrid_01: 8 BMS_MQB - SG_ BMS_HYB_ASV_hinten_Status : 13|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ BMS_HYB_ASV_vorne_Status : 14|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ BMS_HYB_KD_Fehler : 15|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ BMS_HYB_BattFanSpd : 16|4@1+ (10,0) [0|100] "Unit_PerCent" Gateway_MQB - SG_ BMS_HYB_VentilationReq : 20|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ BMS_HYB_Spuelbetrieb_Status : 21|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ BMS_HYB_Kuehlung_Anf : 22|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ BMS_HYB_Temp_vor_Verd : 24|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB - SG_ BMS_HYB_Temp_nach_Verd : 32|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB - SG_ BMS_Temperatur : 40|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB - SG_ BMS_Temperatur_Ansaugluft : 48|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB - SG_ BMS_IstSpannung_HV : 56|8@1+ (1,100) [100|350] "Unit_Volt" Gateway_MQB + SG_ BMS_HYB_ASV_hinten_Status : 13|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ BMS_HYB_ASV_vorne_Status : 14|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ BMS_HYB_KD_Fehler : 15|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ BMS_HYB_BattFanSpd : 16|4@1+ (10,0) [0|100] "Unit_PerCent" Gateway_MQB + SG_ BMS_HYB_VentilationReq : 20|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ BMS_HYB_Spuelbetrieb_Status : 21|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ BMS_HYB_Kuehlung_Anf : 22|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ BMS_HYB_Temp_vor_Verd : 24|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB + SG_ BMS_HYB_Temp_nach_Verd : 32|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB + SG_ BMS_Temperatur : 40|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB + SG_ BMS_Temperatur_Ansaugluft : 48|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB + SG_ BMS_IstSpannung_HV : 56|8@1+ (1,100) [100|350] "Unit_Volt" Gateway_MQB BO_ 901 Charisma_01: 8 Gateway_MQB SG_ CHA_Ziel_FahrPr_ALR : 0|4@1+ (1,0) [0|15] "" Vector__XXX SG_ CHA_Ziel_FahrPr_ESP : 4|4@1+ (1,0) [0|15] "" Vector__XXX SG_ CHA_Ziel_FahrPr_FL : 8|4@1+ (1,0) [0|15] "" Vector__XXX - SG_ CHA_Fahrer_Umschaltung : 14|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ CHA_Ziel_FahrPr_MO : 16|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ CHA_Ziel_FahrPr_GE : 20|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ CHA_Fahrer_Umschaltung : 14|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ CHA_Ziel_FahrPr_MO : 16|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ CHA_Ziel_FahrPr_GE : 20|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ CHA_Ziel_FahrPr_ST : 24|4@1+ (1,0) [0|15] "" Vector__XXX SG_ CHA_Ziel_FahrPr_SCU : 28|4@1+ (1,0) [0|15] "" Vector__XXX SG_ CHA_Ziel_FahrPr_DR : 32|4@1+ (1,0) [0|15] "" Vector__XXX SG_ CHA_Ziel_FahrPr_QS : 36|4@1+ (1,0) [0|15] "" Vector__XXX SG_ CHA_Ziel_FahrPr_AFS : 40|4@1+ (1,0) [0|15] "" Vector__XXX - SG_ CHA_Ziel_FahrPr_RGS : 44|4@1+ (1,0) [0|15] "" Airbag_MQB + SG_ CHA_Ziel_FahrPr_RGS : 44|4@1+ (1,0) [0|15] "" Airbag_MQB SG_ CHA_Ziel_FahrPr_EPS : 48|4@1+ (1,0) [0|15] "" Vector__XXX SG_ CHA_Ziel_FahrPr_ACC : 52|4@1+ (1,0) [0|15] "" Vector__XXX - SG_ CHA_Ziel_FahrPr_SAK : 56|4@1+ (1,0) [0|15] "" SAK_MQB + SG_ CHA_Ziel_FahrPr_SAK : 56|4@1+ (1,0) [0|15] "" SAK_MQB SG_ CHA_Ziel_FahrPr_MStSt : 60|4@1+ (1,0) [0|15] "" Vector__XXX BO_ 945 DC_Hybrid_01: 8 LEH_MQB - SG_ DC_HYB_iAktLV : 12|10@1+ (1,-511) [-511|510] "Unit_Amper" Gateway_MQB - SG_ DC_HYB_iAktReserveLV : 22|10@1+ (1,-511) [-511|510] "Unit_Amper" Gateway_MQB - SG_ DC_HYB_uAktLV : 32|8@1+ (0.1,0) [0|25.3] "Unit_Volt" Gateway_MQB - SG_ DC_HYB_LangsRegelung : 40|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ DC_HYB_Abregelung_Temperatur : 41|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ DC_HYB_Fehler_RedLeistung : 42|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ DC_HYB_Fehler_intern : 43|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ DC_HYB_Fehler_Spannung : 44|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ DC_HYB_Auslastungsgrad : 56|8@1+ (0.4,0) [0|100] "Unit_PerCent" Gateway_MQB + SG_ DC_HYB_iAktLV : 12|10@1+ (1,-511) [-511|510] "Unit_Amper" Gateway_MQB + SG_ DC_HYB_iAktReserveLV : 22|10@1+ (1,-511) [-511|510] "Unit_Amper" Gateway_MQB + SG_ DC_HYB_uAktLV : 32|8@1+ (0.1,0) [0|25.3] "Unit_Volt" Gateway_MQB + SG_ DC_HYB_LangsRegelung : 40|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ DC_HYB_Abregelung_Temperatur : 41|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ DC_HYB_Fehler_RedLeistung : 42|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ DC_HYB_Fehler_intern : 43|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ DC_HYB_Fehler_Spannung : 44|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ DC_HYB_Auslastungsgrad : 56|8@1+ (0.4,0) [0|100] "Unit_PerCent" Gateway_MQB BO_ 1714 Diagnose_01: 8 Gateway_MQB - SG_ DGN_Verlernzaehler : 0|8@1+ (1,0) [0|254] "" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,SAK_MQB - SG_ KBI_Kilometerstand : 8|20@1+ (1,0) [0|1048573] "Unit_KiloMeter" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ UH_Jahr : 28|7@1+ (1,2000) [2000|2127] "Unit_Year" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ UH_Monat : 35|4@1+ (1,0) [1|12] "Unit_Month" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ UH_Tag : 39|5@1+ (1,0) [1|31] "Unit_Day" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ UH_Stunde : 44|5@1+ (1,0) [0|23] "Unit_Hours" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ UH_Minute : 49|6@1+ (1,0) [0|59] "Unit_Minut" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ UH_Sekunde : 55|6@1+ (1,0) [0|59] "Unit_Secon" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ Kombi_02_alt : 62|1@1+ (1,0) [0|1] "" Airbag_MQB,BMS_MQB,LEH_MQB - SG_ Uhrzeit_01_alt : 63|1@1+ (1,0) [0|1] "" Airbag_MQB,BMS_MQB,LEH_MQB + SG_ DGN_Verlernzaehler : 0|8@1+ (1,0) [0|254] "" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,SAK_MQB + SG_ KBI_Kilometerstand : 8|20@1+ (1,0) [0|1048573] "Unit_KiloMeter" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ UH_Jahr : 28|7@1+ (1,2000) [2000|2127] "Unit_Year" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ UH_Monat : 35|4@1+ (1,0) [1|12] "Unit_Month" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ UH_Tag : 39|5@1+ (1,0) [1|31] "Unit_Day" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ UH_Stunde : 44|5@1+ (1,0) [0|23] "Unit_Hours" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ UH_Minute : 49|6@1+ (1,0) [0|59] "Unit_Minut" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ UH_Sekunde : 55|6@1+ (1,0) [0|59] "Unit_Secon" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ Kombi_02_alt : 62|1@1+ (1,0) [0|1] "" Airbag_MQB,BMS_MQB,LEH_MQB + SG_ Uhrzeit_01_alt : 63|1@1+ (1,0) [0|1] "" Airbag_MQB,BMS_MQB,LEH_MQB BO_ 1520 Dimmung_01: 8 Gateway_MQB - SG_ DI_KL_58xd : 0|8@1+ (1,0) [0|253] "" Airbag_MQB + SG_ DI_KL_58xd : 0|8@1+ (1,0) [0|253] "" Airbag_MQB SG_ DI_KL_58xs : 8|7@1+ (1,0) [0|100] "Unit_PerCent" Vector__XXX SG_ DI_Display_Nachtdesign : 15|1@1+ (1,0) [0|1] "" Vector__XXX SG_ DI_KL_58xt : 16|7@1+ (1,0) [0|100] "Unit_PerCent" Vector__XXX @@ -235,7 +235,7 @@ BO_ 1520 Dimmung_01: 8 Gateway_MQB BO_ 1603 Einheiten_01: 8 Gateway_MQB SG_ KBI_Einheit_Datum : 0|2@1+ (1,0) [0|3] "" Vector__XXX SG_ KBI_Einheit_Druck : 2|2@1+ (1,0) [0|3] "" Vector__XXX - SG_ KBI_Einheit_Streckenanz : 4|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB + SG_ KBI_Einheit_Streckenanz : 4|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB SG_ KBI_MFA_v_Einheit_02 : 5|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_Einheit_Temp : 6|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_Einheit_Uhrzeit : 7|1@1+ (1,0) [0|1] "" Vector__XXX @@ -244,171 +244,171 @@ BO_ 1603 Einheiten_01: 8 Gateway_MQB SG_ KBI_Einheit_Sprache : 16|8@1+ (1,0) [0|255] "" Vector__XXX BO_ 260 EPB_01: 8 Gateway_MQB - SG_ EPB_01_CRC : 0|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ EPB_01_BZ : 8|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EPB_01_CRC : 0|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EPB_01_BZ : 8|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ EPB_QBit_Laengsbeschleunigung : 12|1@1+ (1,0) [0|1] "" Vector__XXX SG_ EPB_QBit_Pedalweg_Kuppl : 13|1@1+ (1,0) [0|1] "" Vector__XXX SG_ EPB_BCM2_Motor_Wakeup : 14|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ EPB_Freig_Verzoeg_Anf : 15|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EPB_Freig_Verzoeg_Anf : 15|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ EPB_Verzoeg_Anf : 16|8@1+ (0.048,-7.968) [-7.968|4.224] "Unit_MeterPerSeconSquar" Vector__XXX SG_ EPB_Laengsbeschleunigung : 24|8@1+ (1,-128) [-128|126] "Unit_PerCentOfForceOfGravi" Vector__XXX SG_ EPB_Pedalweg_Kuppl : 32|8@1+ (0.4,0) [8|92] "Unit_PerCent" Vector__XXX SG_ EPB_Anfahrwunsch_erkannt : 48|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ EPB_DAA_Randbed_erf : 49|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ EPB_DAA_Randbed_erf : 49|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ EPB_Fehlerstatus : 50|2@1+ (1,0) [0|3] "" Vector__XXX - SG_ EPB_Schalterposition : 52|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ EPB_QBit_Schalterpos : 54|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EPB_Schalterposition : 52|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EPB_QBit_Schalterpos : 54|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ EPB_Konsistenz_ACC : 55|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ EPB_Spannkraft : 56|5@1+ (1,0) [0|29] "Unit_KiloNewto" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ EPB_Status : 61|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EPB_Spannkraft : 56|5@1+ (1,0) [0|29] "Unit_KiloNewto" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ EPB_Status : 61|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 257 ESP_02: 8 Gateway_MQB - SG_ ESP_02_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_02_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Gierrate : 12|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ ESP_QBit_Laengsbeschl : 13|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Querb : 14|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_02_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_02_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Gierrate : 12|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_QBit_Laengsbeschl : 13|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Querb : 14|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Stillstandsflag : 15|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_Querbeschleunigung : 16|8@1+ (0.01,-1.27) [-1.27|1.27] "Unit_ForceOfGravi" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Laengsbeschl : 24|10@1+ (0.03125,-16) [-16|15.90625] "Unit_MeterPerSeconSquar" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Querbeschleunigung : 16|8@1+ (0.01,-1.27) [-1.27|1.27] "Unit_ForceOfGravi" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Laengsbeschl : 24|10@1+ (0.03125,-16) [-16|15.90625] "Unit_MeterPerSeconSquar" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Verteil_Wankmom : 34|5@1+ (0.1,-1) [-1|1] "" Vector__XXX SG_ ESP_QBit_Anf_Vert_Wank : 39|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_Gierrate : 40|14@1+ (0.01,0) [0|163.82] "Unit_DegreOfArcPerSecon" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ ESP_VZ_Gierrate : 54|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ ESP_Notbremsanzeige : 55|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ ESP_Gierrate : 40|14@1+ (0.01,0) [0|163.82] "Unit_DegreOfArcPerSecon" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_VZ_Gierrate : 54|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_Notbremsanzeige : 55|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ ESP_SpannungsAnf : 56|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_PLA_Abbruch : 57|3@1+ (1,0) [0|7] "" Vector__XXX - SG_ ESP_Status_ESP_PLA : 60|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_Status_ESP_PLA : 60|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 262 ESP_05: 8 Gateway_MQB - SG_ ESP_05_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_05_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Bremsdruck : 12|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Fahrer_bremst : 13|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Schwelle_Unterdruck : 14|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Bremsdruck : 16|10@1+ (0.3,-30) [-30|276.6] "Unit_Bar" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Fahrer_bremst : 26|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Verz_TSK_aktiv : 27|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Lenkeingriff_ADS : 28|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Konsistenz_TSK : 29|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Bremsruck_AWV2 : 30|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Bremsdruck : 12|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Fahrer_bremst : 13|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Schwelle_Unterdruck : 14|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Bremsdruck : 16|10@1+ (0.3,-30) [-30|276.6] "Unit_Bar" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Fahrer_bremst : 26|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Verz_TSK_aktiv : 27|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Lenkeingriff_ADS : 28|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Konsistenz_TSK : 29|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Bremsruck_AWV2 : 30|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Konsistenz_AWV2 : 31|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ECD_Fehler : 32|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ECD_nicht_verfuegbar : 33|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Status_Bremsentemp : 34|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ECD_Fehler : 32|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ECD_nicht_verfuegbar : 33|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Status_Bremsentemp : 34|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Autohold_Standby : 35|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_HDC_Standby : 36|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_HDC_Standby : 36|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ ESP_HBA_aktiv : 37|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_Prefill_ausgeloest : 38|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Prefill_ausgeloest : 38|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Rueckwaertsfahrt_erkannt : 39|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_Status_Anfahrhilfe : 40|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_HDC_aktiv : 41|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ ESP_StartStopp_Info : 42|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ ESP_Status_Anfahrhilfe : 40|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_HDC_aktiv : 41|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_StartStopp_Info : 42|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB SG_ ESP_Eingr_HL : 44|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_Eingr_HR : 45|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_Eingr_VL : 46|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_Eingr_VR : 47|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_BKV_Unterdruck : 48|8@1+ (4,0) [0|1012] "Unit_MilliBar" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Autohold_aktiv : 56|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_FStatus_Anfahrhilfe : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_BKV_Unterdruck : 48|8@1+ (4,0) [0|1012] "Unit_MilliBar" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Autohold_aktiv : 56|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_FStatus_Anfahrhilfe : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ ESP_Verz_EPB_aktiv : 58|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ECD_Bremslicht : 59|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ECD_Bremslicht : 59|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Verzoeg_EPB_verf : 60|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_Status_Bremsdruck : 61|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Status_Bremsdruck : 61|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Anforderung_EPB : 62|2@1+ (1,0) [0|3] "" Vector__XXX BO_ 914 ESP_07: 8 Gateway_MQB - SG_ ESP_07_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_07_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_07_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_07_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_ACC_LDE : 12|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_Quattro_Antrieb : 13|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_Codierung_ADS : 14|2@1+ (1,0) [0|3] "" Vector__XXX SG_ ESP_RTA_HL : 16|8@1+ (0.048828125,-6.20117) [-6.20117|6.152345625] "Unit_PerCent" Vector__XXX SG_ ESP_RTA_HR : 24|8@1+ (0.048828125,-6.20117) [-6.20117|6.152345625] "Unit_PerCent" Vector__XXX SG_ ESP_RTA_VR : 32|8@1+ (0.048828125,-6.20117) [-6.20117|6.152345625] "Unit_PerCent" Vector__XXX - SG_ OBD_Fehler_Radsensor_HL : 40|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_Fehler_Radsensor_HR : 44|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_Fehler_Radsensor_VL : 48|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_Fehler_Radsensor_VR : 52|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_Fehler_Radsensor_HL : 40|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_Fehler_Radsensor_HR : 44|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_Fehler_Radsensor_VL : 48|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_Fehler_Radsensor_VR : 52|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Qualifizierung_Antriebsart : 56|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_Offroad_Modus : 57|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_MKB_ausloesbar : 58|1@1+ (1,0) [0|1] "" Airbag_MQB - SG_ ESP_MKB_Status : 59|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ ESP_MKB_ausloesbar : 58|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ ESP_MKB_Status : 59|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ ESP_CM_Variante : 60|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_OBD_Status : 61|1@1+ (1,0) [0|1] "" Vector__XXX BO_ 278 ESP_10: 8 Gateway_MQB - SG_ ESP_10_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_10_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Wegimpuls_VL : 12|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Wegimpuls_VR : 13|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Wegimpuls_HL : 14|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Wegimpuls_HR : 15|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Wegimpuls_VL : 16|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Wegimpuls_VR : 26|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Wegimpuls_HL : 36|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Wegimpuls_HR : 46|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_VL_Fahrtrichtung : 56|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_VR_Fahrtrichtung : 58|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_HL_Fahrtrichtung : 60|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_HR_Fahrtrichtung : 62|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_10_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_10_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Wegimpuls_VL : 12|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Wegimpuls_VR : 13|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Wegimpuls_HL : 14|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Wegimpuls_HR : 15|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Wegimpuls_VL : 16|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Wegimpuls_VR : 26|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Wegimpuls_HL : 36|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Wegimpuls_HR : 46|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_VL_Fahrtrichtung : 56|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_VR_Fahrtrichtung : 58|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_HL_Fahrtrichtung : 60|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_HR_Fahrtrichtung : 62|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 178 ESP_19: 8 Gateway_MQB - SG_ ESP_HL_Radgeschw_02 : 0|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_HR_Radgeschw_02 : 16|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_VL_Radgeschw_02 : 32|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_VR_Radgeschw_02 : 48|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_HL_Radgeschw_02 : 0|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_HR_Radgeschw_02 : 16|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_VL_Radgeschw_02 : 32|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_VR_Radgeschw_02 : 48|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 1629 ESP_20: 8 Gateway_MQB - SG_ ESP_20_CRC : 0|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ ESP_20_BZ : 8|4@1+ (1,0) [0|15] "" Vector__XXX + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" Vector__XXX + SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" Vector__XXX SG_ BR_Systemart : 12|2@1+ (1,0) [0|3] "" Vector__XXX - SG_ ESP_Zaehnezahl : 16|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_Zaehnezahl : 16|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ ESP_Charisma_FahrPr : 24|4@1+ (1,0) [0|15] "" Vector__XXX SG_ ESP_Charisma_Status : 28|2@1+ (1,0) [0|3] "" Vector__XXX - SG_ BR_QBit_Reifenumfang : 51|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ BR_Reifenumfang : 52|12@1+ (1,0) [0|4095] "Unit_MilliMeter" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ BR_QBit_Reifenumfang : 51|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ BR_Reifenumfang : 52|12@1+ (1,0) [0|4095] "Unit_MilliMeter" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 253 ESP_21: 8 Gateway_MQB - SG_ ESP_21_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_21_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BR_Eingriffsmoment : 12|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_v_Signal : 32|16@1+ (0.01,0) [0|655.32] "Unit_KiloMeterPerHour" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ ASR_Tastung_passiv : 48|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Tastung_passiv : 49|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Systemstatus : 50|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ASR_Schalteingriff : 51|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ ESP_Haltebestaetigung : 53|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_v_Signal : 55|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ABS_Bremsung : 56|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ASR_Anf : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ MSR_Anf : 58|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ EBV_Eingriff : 59|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ EDS_Eingriff : 60|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Eingriff : 61|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_ASP : 62|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Anhaltevorgang_ACC_aktiv : 63|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BR_Eingriffsmoment : 12|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_v_Signal : 32|16@1+ (0.01,0) [0|655.32] "Unit_KiloMeterPerHour" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ ASR_Tastung_passiv : 48|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Tastung_passiv : 49|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Systemstatus : 50|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ASR_Schalteingriff : 51|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_Haltebestaetigung : 53|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_v_Signal : 55|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ABS_Bremsung : 56|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ASR_Anf : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ MSR_Anf : 58|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EBV_Eingriff : 59|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EDS_Eingriff : 60|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Eingriff : 61|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_ASP : 62|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Anhaltevorgang_ACC_aktiv : 63|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 987 Gateway_72: 8 Gateway_MQB - SG_ BCM_01_alt : 0|1@1+ (1,0) [0|1] "" Airbag_MQB - SG_ SMLS_01_alt : 1|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ ZV_02_alt : 2|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Wischer_01_alt : 3|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Anhaenger_01_alt : 4|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ Klima_Sensor_02_alt : 5|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ VSG_01_alt : 6|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ BCM_01_alt : 0|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ SMLS_01_alt : 1|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ ZV_02_alt : 2|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Wischer_01_alt : 3|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Anhaenger_01_alt : 4|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ Klima_Sensor_02_alt : 5|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ VSG_01_alt : 6|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ Klima_01_alt : 7|1@1+ (1,0) [0|1] "" Vector__XXX SG_ WFS_01_alt : 8|1@1+ (1,0) [0|1] "" Vector__XXX SG_ Licht_Anf_01_alt : 9|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ZV_HFS_offen : 20|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ZV_HBFS_offen : 21|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ VS_VD_offen_ver : 22|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ VS_VD_offen_ver : 22|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ VS_VD_zu_ver : 23|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ZV_BT_offen : 24|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ BCM1_Rueckfahrlicht_Schalter : 25|1@1+ (1,0) [0|1] "" Airbag_MQB - SG_ ZV_FT_offen : 26|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Wischer_vorne_aktiv : 27|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ AAG_Anhaenger_erkannt : 28|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ BCM1_Rueckfahrlicht_Schalter : 25|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ ZV_FT_offen : 26|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Wischer_vorne_aktiv : 27|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AAG_Anhaenger_erkannt : 28|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ BCM1_MH_Schalter : 29|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ZV_HD_offen : 30|1@1+ (1,0) [0|1] "" Vector__XXX SG_ Waschen_vorne_aktiv : 31|1@1+ (1,0) [0|1] "" Vector__XXX @@ -417,151 +417,152 @@ BO_ 987 Gateway_72: 8 Gateway_MQB SG_ BCM1_RFahrlicht_Fzg_Anf : 38|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BCM1_RFahrlicht_Ahg_Anf : 39|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BH_Fernlicht : 49|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ BH_Blinker_li : 50|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ BH_Blinker_re : 51|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ BCM1_OBD_FStatus_ATemp : 52|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BCM1_Aussen_Temp_ungef : 56|8@1+ (0.5,-50) [-50|76] "Unit_DegreCelsi" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BH_Blinker_li : 50|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ BH_Blinker_re : 51|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ BCM1_OBD_FStatus_ATemp : 52|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM1_Aussen_Temp_ungef : 56|8@1+ (0.5,-50) [-50|76] "Unit_DegreCelsi" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 989 Gateway_74: 8 Gateway_MQB - SG_ LH_EPS_01_alt : 0|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB - SG_ Kessy_04_alt : 1|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ LIN_2_alt : 2|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MFG_01_alt : 3|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ LH_EPS_01_alt : 0|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB + SG_ Kessy_04_alt : 1|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ LIN_2_alt : 2|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MFG_01_alt : 3|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB SG_ GW_74_va_14 : 4|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ Klima_02_alt : 5|1@1+ (1,0) [0|1] "" BMS_MQB - SG_ Parkhilfe_01_alt : 6|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ ELV_01_alt : 7|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KY_StartStopp_Info : 16|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ PH_StartStopp_Info : 18|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ EPS_Lenkerposition : 20|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB - SG_ ELV_Anf_Klemme_50 : 22|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ MF_StartStopp_Info : 25|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ KL_Geblaesespannung_Soll : 40|8@1+ (0.05,0.5) [2|13] "Unit_Volt" BMS_MQB + SG_ Klima_02_alt : 5|1@1+ (1,0) [0|1] "" BMS_MQB + SG_ Parkhilfe_01_alt : 6|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ ELV_01_alt : 7|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KY_StartStopp_Info : 16|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ PH_StartStopp_Info : 18|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ EPS_Lenkerposition : 20|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB + SG_ ELV_Anf_Klemme_50 : 22|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ MF_StartStopp_Info : 25|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ KL_Geblaesespannung_Soll : 40|8@1+ (0.05,0.5) [2|13] "Unit_Volt" BMS_MQB SG_ KL_Umluftklappe_Status : 48|4@1+ (1,0) [0|15] "" Vector__XXX - SG_ MFL_Tip_Down : 56|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MFL_Tip_Up : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ LS_Tiptronic_Fehler : 58|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MFL_Tip_Down : 56|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MFL_Tip_Up : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ LS_Tiptronic_Fehler : 58|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 296 Getriebe_06: 3 Getriebe_DQ_Hybrid_MQB - SG_ GE_WH_Sperre : 0|1@1+ (1,0) [0|1] "" Waehlhebel_MQB - SG_ GE_Ausleuchtungsmode : 1|1@1+ (1,0) [0|1] "" Waehlhebel_MQB - SG_ GE_Test_Freigabe : 2|1@1+ (1,0) [0|1] "" Waehlhebel_MQB - SG_ GE_Ist_Fahrstufe : 4|4@1+ (1,0) [0|15] "" Waehlhebel_MQB - SG_ GE_Testparameter_1 : 8|8@1+ (1,0) [0|255] "" Waehlhebel_MQB - SG_ GE_Testparameter_2 : 16|8@1+ (1,0) [0|255] "" Waehlhebel_MQB + SG_ GE_WH_Sperre : 0|1@1+ (1,0) [0|1] "" Waehlhebel_MQB + SG_ GE_Ausleuchtungsmode : 1|1@1+ (1,0) [0|1] "" Waehlhebel_MQB + SG_ GE_Test_Freigabe : 2|1@1+ (1,0) [0|1] "" Waehlhebel_MQB + SG_ GE_Ist_Fahrstufe : 4|4@1+ (1,0) [0|15] "" Waehlhebel_MQB + SG_ GE_Testparameter_1 : 8|8@1+ (1,0) [0|255] "" Waehlhebel_MQB + SG_ GE_Testparameter_2 : 16|8@1+ (1,0) [0|255] "" Waehlhebel_MQB BO_ 173 Getriebe_11: 8 Getriebe_DQ_Hybrid_MQB - SG_ Getriebe_11_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Getriebe_11_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_MMom_Soll_02 : 12|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_MMom_Vorhalt_02 : 22|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Uefkt : 32|10@1+ (0.1,0) [0|102.2] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Fahrstufe : 42|5@1+ (1,0) [0|31] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Schaltvorgang : 47|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Status_Kupplung : 54|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_MMom_Status : 56|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Freig_MMom_Vorhalt : 58|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Verbot_Ausblendung : 59|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Zielgang : 60|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ COUNTERXX : 8|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_MMom_Soll_02 : 12|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_MMom_Vorhalt_02 : 22|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Uefkt : 32|10@1+ (0.1,0) [0|102.2] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Fahrstufe : 42|5@1+ (1,0) [0|31] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Schaltvorgang : 47|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Status_Kupplung : 54|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_MMom_Status : 56|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Freig_MMom_Vorhalt : 58|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Verbot_Ausblendung : 59|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Zielgang : 60|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 174 Getriebe_12: 8 Getriebe_DQ_Hybrid_MQB - SG_ Getriebe_12_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Getriebe_12_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Drehzahlmesser_Daempfung : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Schubabschalt_Unt : 13|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Freigabe_Synchro : 14|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Synchro_Wunschdrehz : 15|9@1+ (25,0) [0|12750] "Unit_MinutInver" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Synchro_Zeit : 24|8@1+ (20,0) [0|5080] "Unit_MilliSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Mom_Begr_Gradient : 32|8@1+ (10,0) [0|2540] "Unit_NewtoMeterPerSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Anheb_Solldrehz_Leerlauf : 40|8@1+ (10,0) [0|2540] "Unit_MinutInver" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Aufnahmemoment : 48|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Getriebe_12_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Getriebe_12_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Drehzahlmesser_Daempfung : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Schubabschalt_Unt : 13|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Freigabe_Synchro : 14|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Synchro_Wunschdrehz : 15|9@1+ (25,0) [0|12750] "Unit_MinutInver" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Synchro_Zeit : 24|8@1+ (20,0) [0|5080] "Unit_MilliSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Mom_Begr_Gradient : 32|8@1+ (10,0) [0|2540] "Unit_NewtoMeterPerSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Anheb_Solldrehz_Leerlauf : 40|8@1+ (10,0) [0|2540] "Unit_MinutInver" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Aufnahmemoment : 48|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ GE_Anf_Zylabsch : 58|2@1+ (1,0) [0|3] "" Vector__XXX - SG_ GE_HYB_DZ_Eingriff : 62|2@1+ (1,0) [0|3] "" Motor_Hybrid_MQB + SG_ GE_HYB_DZ_Eingriff : 62|2@1+ (1,0) [0|3] "" Motor_Hybrid_MQB BO_ 301 Getriebe_13: 8 Getriebe_DQ_Hybrid_MQB - SG_ Getriebe_13_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Getriebe_13_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_StartStopp_Info : 12|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ GE_Langfr_Schutzmom_02 : 14|9@1+ (1,0) [0|509] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Eingangsdrehz : 48|14@1+ (1,0) [0|16381] "Unit_MinutInver" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Notlauf : 62|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Freig_Langfr_Schutzmom : 63|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Getriebe_13_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Getriebe_13_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_StartStopp_Info : 12|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ GE_Langfr_Schutzmom_02 : 14|9@1+ (1,0) [0|509] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Eingangsdrehz : 48|14@1+ (1,0) [0|16381] "Unit_MinutInver" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Notlauf : 62|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Freig_Langfr_Schutzmom : 63|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 968 Getriebe_14: 8 Getriebe_DQ_Hybrid_MQB - SG_ GE_OBD_AbsperrVent : 12|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_amax_moeglich : 16|9@1+ (0.024,-2.016) [-2.016|10.224] "Unit_MeterPerSeconSquar" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Charisma_FahrPr : 25|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ GE_Charisma_Status : 29|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ GE_Verlustmoment : 32|8@1+ (1,0) [0|254] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Freigabe_Verfallsinfo_WFS : 49|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ GE_Codierung_MSG : 50|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ GE_LaunchControl : 51|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ GE_Heizwunsch : 52|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_OBD_Status : 54|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_LFR_Adaption : 55|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Sumpftemperatur : 56|8@1+ (1,-58) [-58|196] "Unit_DegreCelsi" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_OBD_AbsperrVent : 12|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_amax_moeglich : 16|9@1+ (0.024,-2.016) [-2.016|10.224] "Unit_MeterPerSeconSquar" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Charisma_FahrPr : 25|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ GE_Charisma_Status : 29|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ GE_Verlustmoment : 32|8@1+ (1,0) [0|254] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Freigabe_Verfallsinfo_WFS : 49|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ GE_Codierung_MSG : 50|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ GE_LaunchControl : 51|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ GE_Heizwunsch : 52|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_OBD_Status : 54|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_LFR_Adaption : 55|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Sumpftemperatur : 56|8@1+ (1,-58) [-58|196] "Unit_DegreCelsi" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 158 Getriebe_Hybrid_01: 8 Getriebe_DQ_Hybrid_MQB - SG_ Getriebe_Hybrid_01_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Hybrid_MQB - SG_ Getriebe_Hybrid_01_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB - SG_ GE_HYB_Fehlerstatus : 12|2@1+ (1,0) [0|3] "" Motor_Hybrid_MQB - SG_ GE_HYB_Freigabe_K0 : 16|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB - SG_ GE_HYB_Freigabe_LL_Reg : 17|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB - SG_ GE_HYB_Freig_sSchl_K0 : 18|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB - SG_ GE_HYB_Freig_VM_EM_Stop : 19|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB - SG_ GE_HYB_Wiederstart : 20|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB - SG_ GE_HYB_Filt_MomAufbau : 21|3@1+ (1,0) [0|7] "" Motor_Hybrid_MQB + SG_ Getriebe_Hybrid_01_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Hybrid_MQB + SG_ Getriebe_Hybrid_01_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB + SG_ GE_HYB_Fehlerstatus : 12|2@1+ (1,0) [0|3] "" Motor_Hybrid_MQB + SG_ GE_HYB_Freigabe_K0 : 16|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_Freigabe_LL_Reg : 17|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_Freig_sSchl_K0 : 18|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_Freig_VM_EM_Stop : 19|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_Wiederstart : 20|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_Filt_MomAufbau : 21|3@1+ (1,0) [0|7] "" Motor_Hybrid_MQB SG_ GE_HYB_nK0 : 24|8@1+ (25,0) [0|6350] "Unit_MinutInver" Vector__XXX - SG_ GE_HYB_MomEingriff_EM : 32|6@1+ (0.5,0) [0|31.5] "Unit_NewtoMeter" LEH_MQB - SG_ GE_HYB_VZ_MomEingriff_EM : 38|1@1+ (1,0) [0|1] "" LEH_MQB - SG_ GE_HYB_Sportfaktor : 56|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB - SG_ GE_HYB_VM_akt_halten : 61|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB - SG_ GE_HYB_StartAnf : 62|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB - SG_ GE_HYB_VM_Startkontr : 63|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_MomEingriff_EM : 32|6@1+ (0.5,0) [0|31.5] "Unit_NewtoMeter" LEH_MQB + SG_ GE_HYB_VZ_MomEingriff_EM : 38|1@1+ (1,0) [0|1] "" LEH_MQB + SG_ GE_HYB_Sportfaktor : 56|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB + SG_ GE_HYB_VM_akt_halten : 61|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_StartAnf : 62|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_VM_Startkontr : 63|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB BO_ 299 GRA_ACC_01: 8 Gateway_MQB - SG_ GRA_ACC_01_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_ACC_01_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Hauptschalter : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Abbrechen : 13|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Typ_Hauptschalter : 14|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Limiter : 15|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Tip_Setzen : 16|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Tip_Hoch : 17|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Tip_Runter : 18|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Tip_Wiederaufnahme : 19|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Verstellung_Zeitluecke : 20|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Codierung : 22|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Fehler : 24|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Typ468 : 25|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Tip_Stufe_2 : 27|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Hauptschalter : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Abbrechen : 13|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Typ_Hauptschalter : 14|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Limiter : 15|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Tip_Setzen : 16|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Tip_Hoch : 17|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Tip_Runter : 18|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Tip_Wiederaufnahme : 19|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Verstellung_Zeitluecke : 20|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Codierung : 22|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Fehler : 24|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Typ468 : 25|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Tip_Stufe_2 : 27|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_ButtonTypeInfo : 28|2@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 960 Klemmen_Status_01: 4 Gateway_MQB - SG_ Klemmen_Status_01_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,BMS_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Klemmen_Status_01_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,BMS_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,BMS_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,BMS_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ZAS_Kl_S : 16|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ZAS_Kl_15 : 17|1@1+ (1,0) [0|1] "" Airbag_MQB,BMS_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ZAS_Kl_15 : 17|1@1+ (1,0) [0|1] "" Airbag_MQB,BMS_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ZAS_Kl_X : 18|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ZAS_Kl_50 : 19|1@1+ (1,0) [0|1] "" Vector__XXX BO_ 949 Klima_11: 8 Gateway_MQB - SG_ KL_Drehz_Anh : 0|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KL_Vorwarn_Komp_ein : 1|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KL_Drehz_Anh : 0|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KL_Vorwarn_Komp_ein : 1|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ KL_AC_Schalter : 2|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KL_Komp_Moment_alt : 3|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KL_Zonen : 4|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KL_Zonen : 4|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ KL_Vorwarn_Zuheizer_ein : 6|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KL_Zustand : 7|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KL_Zustand : 7|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ KL_Comp_rev_rq : 8|8@1+ (50,0) [0|8600] "Unit_MinutInver" Vector__XXX SG_ KL_Charisma_FahrPr : 16|4@1+ (1,0) [0|15] "" Vector__XXX SG_ KL_Charisma_Status : 20|2@1+ (1,0) [0|3] "" Vector__XXX SG_ KL_Comp_enable : 23|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KL_Last_Kompr : 24|8@1+ (0.25,0) [0|63.5] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KL_Last_Kompr : 24|8@1+ (0.25,0) [0|63.5] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ KL_Spannungs_Anf : 32|2@1+ (1,0) [0|3] "" Vector__XXX - SG_ KL_Thermomanagement : 34|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KL_StartStopp_Info : 36|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ KL_Anf_KL : 40|8@1+ (0.4,0) [0|101.6] "Unit_PerCent" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KL_el_Zuheizer_Stufe : 48|3@1+ (1,0) [0|7] "" Motor_Diesel_MQB + SG_ KL_Thermomanagement : 34|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KL_StartStopp_Info : 36|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ KL_Anf_KL : 40|8@1+ (0.4,0) [0|101.6] "Unit_PerCent" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KL_el_Zuheizer_Stufe : 48|3@1+ (1,0) [0|7] "" Motor_Diesel_MQB BO_ 1625 Klimakomp_01: 8 Gateway_MQB SG_ EKL_KD_Fehler : 15|1@1+ (1,0) [0|1] "" Vector__XXX @@ -572,80 +573,80 @@ BO_ 1625 Klimakomp_01: 8 Gateway_MQB SG_ EKL_Comp_Inv_stat : 24|2@1+ (1,0) [0|3] "" Vector__XXX SG_ EKL_Comp_photo_temp_stat : 30|2@1+ (1,0) [0|3] "" Vector__XXX SG_ EKL_Comp_photo_temp : 32|8@1+ (1,0) [0|254] "Unit_DegreCelsi" Vector__XXX - SG_ EKL_Comp_current : 40|8@1+ (0.1,0) [0|25.4] "Unit_Amper" Motor_Hybrid_MQB + SG_ EKL_Comp_current : 40|8@1+ (0.1,0) [0|25.4] "Unit_Amper" Motor_Hybrid_MQB SG_ EKL_Comp_rev_stat : 48|8@1+ (50,0) [0|8600] "Unit_MinutInver" Vector__XXX BO_ 2549088277 KN_Airbag_01: 8 Airbag_MQB SG_ Airbag_01_KompSchutz : 0|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ Airbag_01_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ AB_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ Airbag_01_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ AB_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 2549088380 KN_EMotor_01: 8 LEH_MQB SG_ EMotor_KompSchutz : 0|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ EMotor_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ EM_HYB_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ EMotor_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ EM_HYB_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 2549088375 KN_Getriebe_01: 8 Getriebe_DQ_Hybrid_MQB SG_ Getriebe_KompSchutz : 0|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ Getriebe_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ GE_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ Getriebe_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ GE_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 2549088379 KN_Hybrid_01: 8 BMS_MQB SG_ Hybrid_KompSchutz : 0|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ Hybrid_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ BMS_HYB_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ Hybrid_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ BMS_HYB_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 2549088374 KN_MO_01: 8 Motor_Diesel_MQB SG_ Motor_KompSchutz : 0|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ Motor_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ Motor_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 2549088284 KN_SAK: 8 SAK_MQB SG_ SAK_KompSchutz : 0|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ SAK_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ SAK_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ SAK_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ SAK_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 779 Kombi_01: 8 Gateway_MQB SG_ KBI_ABS_Lampe : 0|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_ESP_Lampe : 1|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_BKL_Lampe : 2|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KBI_Airbag_Lampe : 3|1@1+ (1,0) [0|1] "" Airbag_MQB - SG_ KBI_SILA_gueltig : 4|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ KBI_Airbag_Lampe : 3|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ KBI_SILA_gueltig : 4|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ KBI_Lenkung_Lampe : 5|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KBI_Vorglueh_System_Lampe : 6|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB + SG_ KBI_Vorglueh_System_Lampe : 6|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB SG_ KBI_NV_in_Anzeige : 7|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ Kombi_01_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Kombi_01_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ KBI_Anzeigestatus_ACC : 12|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KBI_Anzeigestatus_GRA : 13|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_Anzeigestatus_GRA : 13|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ KBI_Oeldruck_Schalter : 15|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KBI_Tankwarnung : 16|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_MFA_v_Einheit_01 : 17|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_im_Stellgliedtest : 18|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ KBI_Tankwarnung : 16|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_MFA_v_Einheit_01 : 17|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_im_Stellgliedtest : 18|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ KBI_Anzeigefehler_LDW : 19|2@1+ (1,0) [0|3] "" Vector__XXX SG_ KBI_Variante_USA : 21|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_Oeldruckwarnung : 22|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KBI_Handbremse : 23|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ KBI_Handbremse : 23|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ KBI_V_Digital : 24|9@1+ (1,0) [0|511] "" Vector__XXX SG_ KBI_PLA_in_Anzeige : 33|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_Anzeigefehler_NV : 34|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KBI_Anzeigestatus_LIM : 35|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_angez_Geschw : 48|10@1+ (0.32,0) [0|325.12] "Unit_KiloMeterPerHour" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_Einheit_Tacho : 58|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_Anzeigestatus_LIM : 35|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_angez_Geschw : 48|10@1+ (0.32,0) [0|325.12] "Unit_KiloMeterPerHour" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_Einheit_Tacho : 58|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ KBI_Konsistenz_ACC : 59|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_Fehler_Anzeige_ACC : 60|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_Anzeigefehler_SWA : 61|2@1+ (1,0) [0|3] "" Vector__XXX BO_ 1719 Kombi_02: 8 Gateway_MQB SG_ KBI_Kilometerstand : 0|20@1+ (1,0) [0|1048573] "Unit_KiloMeter" Vector__XXX - SG_ KBI_Standzeit_02 : 20|17@1+ (1,0) [0|131068] "Unit_Secon" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_Inhalt_Tank : 40|7@1+ (1,0) [0|125] "Unit_Liter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_FStatus_Tank : 47|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_QBit_Aussen_Temp_gef : 55|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_Aussen_Temp_gef : 56|8@1+ (0.5,-50) [-50|75] "Unit_DegreCelsi" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_Standzeit_02 : 20|17@1+ (1,0) [0|131068] "Unit_Secon" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_Inhalt_Tank : 40|7@1+ (1,0) [0|125] "Unit_Liter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_FStatus_Tank : 47|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_QBit_Aussen_Temp_gef : 55|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_Aussen_Temp_gef : 56|8@1+ (0.5,-50) [-50|75] "Unit_DegreCelsi" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 982 Licht_hinten_01: 8 Gateway_MQB - SG_ Licht_hinten_01_BZ : 0|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BCM2_Bremsl_durch_ECD : 5|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Licht_hinten_01_BZ : 0|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM2_Bremsl_durch_ECD : 5|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ LH_Aussenlicht_def : 7|1@1+ (1,0) [0|1] "" Vector__XXX SG_ LH_Standlicht_H_aktiv : 8|1@1+ (1,0) [0|1] "" Vector__XXX SG_ LH_Parklicht_HL_aktiv : 9|1@1+ (1,0) [0|1] "" Vector__XXX @@ -676,253 +677,240 @@ BO_ 982 Licht_hinten_01: 8 Gateway_MQB SG_ LH_SL_BRL_BLK_re_def : 42|1@1+ (1,0) [0|1] "" Vector__XXX SG_ LH_Brems_Blk_re_def : 43|1@1+ (1,0) [0|1] "" Vector__XXX SG_ LH_Kennzl_def : 48|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ LH_3_Bremsl_def : 49|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ LH_3_Bremsl_def : 49|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ LH_Nebel_mi_def : 50|1@1+ (1,0) [0|1] "" Vector__XXX SG_ LH_Rueckf_mi_def : 51|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ LH_Bremsl_li_ges_def : 54|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ LH_Bremsl_re_ges_def : 55|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ LH_Bremsl_li_ges_def : 54|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ LH_Bremsl_re_ges_def : 55|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 134 LWI_01: 8 Gateway_MQB - SG_ LWI_01_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ LWI_01_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ LWI_Sensorstatus : 12|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ LWI_Sensorstatus : 12|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ LWI_QBit_Sub_Daten : 13|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ LWI_QBit_Lenkradwinkel : 15|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ LWI_Lenkradwinkel : 16|13@1+ (0.1,0) [0|800] "Unit_DegreOfArc" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ LWI_VZ_Lenkradwinkel : 29|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ LWI_QBit_Lenkradwinkel : 15|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ LWI_Lenkradwinkel : 16|13@1+ (0.1,0) [0|800] "Unit_DegreOfArc" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ LWI_VZ_Lenkradwinkel : 29|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ LWI_VZ_Lenkradw_Geschw : 30|1@1+ (1,0) [0|1] "" Vector__XXX SG_ LWI_Lenkradw_Geschw : 31|9@1+ (5,0) [0|2500] "Unit_DegreOfArcPerSecon" Vector__XXX SG_ LWI_Sub_Daten : 40|16@1+ (1,0) [0|65535] "" Vector__XXX BO_ 263 Motor_04: 8 Motor_Diesel_MQB - SG_ MO_Istgang : 8|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_Sollgang : 12|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_Oeldruck : 16|8@1+ (0.04,0) [0|10] "Unit_Bar" Gateway_MQB - SG_ MO_Anzeigedrehz : 24|12@1+ (3,0) [0|12282] "Unit_MinutInver" Gateway_MQB - SG_ MO_Schaltempf_verfbar : 38|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Ladedruck : 39|9@1+ (0.01,0) [0|5.1] "Unit_Bar" Gateway_MQB - SG_ MO_KVS : 48|15@1+ (1,0) [0|32767] "Unit_MicroLiter" Gateway_MQB - SG_ MO_KVS_Ueberlauf : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Istgang : 8|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_Sollgang : 12|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_Oeldruck : 16|8@1+ (0.04,0) [0|10] "Unit_Bar" Gateway_MQB + SG_ MO_Anzeigedrehz : 24|12@1+ (3,0) [0|12282] "Unit_MinutInver" Gateway_MQB + SG_ MO_Schaltempf_verfbar : 38|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Ladedruck : 39|9@1+ (0.01,0) [0|5.1] "Unit_Bar" Gateway_MQB + SG_ MO_KVS : 48|15@1+ (1,0) [0|32767] "Unit_MicroLiter" Gateway_MQB + SG_ MO_KVS_Ueberlauf : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 1600 Motor_07: 8 Motor_Diesel_MQB - SG_ MO_QBit_Ansaugluft_Temp : 0|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_QBit_Oel_Temp : 1|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_QBit_Kuehlmittel_Temp : 2|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ MO_Stellgliedtest_Soundaktuator : 3|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_HYB_Fehler_HV_Netz : 4|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_aktives_Getriebeheizen : 5|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Absperrventil_oeffnen : 6|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Ansaugluft_Temp : 8|8@1+ (0.75,-48) [-48|141.75] "Unit_DegreCelsi" Gateway_MQB - SG_ MO_Oel_Temp : 16|8@1+ (1,-60) [-60|192] "Unit_DegreCelsi" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Kuehlmittel_Temp : 24|8@1+ (0.75,-48) [-48|141.75] "Unit_DegreCelsi" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ MO_Hoeheninfo : 32|8@1+ (0.00781,0) [0|1.98374] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Kennfeldk : 40|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Versionsinfo : 41|6@1+ (1,0) [0|63] "" Gateway_MQB - SG_ MO_Getriebe_kuehlen : 47|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Mom_Traegheit_02 : 48|5@1+ (0.01,0) [0|0.31] "Unit_KiloGramMeterSquar" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Heizungspumpenansteuerung : 53|4@1+ (10,0) [0|100] "Unit_PerCent" Gateway_MQB - SG_ MO_SpannungsAnf : 57|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Nachlaufzeit_Heizungspumpe : 58|6@1+ (15,0) [0|945] "Unit_Secon" Gateway_MQB + SG_ MO_QBit_Ansaugluft_Temp : 0|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_QBit_Oel_Temp : 1|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_QBit_Kuehlmittel_Temp : 2|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ MO_Stellgliedtest_Soundaktuator : 3|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Fehler_HV_Netz : 4|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_aktives_Getriebeheizen : 5|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Absperrventil_oeffnen : 6|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Ansaugluft_Temp : 8|8@1+ (0.75,-48) [-48|141.75] "Unit_DegreCelsi" Gateway_MQB + SG_ MO_Oel_Temp : 16|8@1+ (1,-60) [-60|192] "Unit_DegreCelsi" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Kuehlmittel_Temp : 24|8@1+ (0.75,-48) [-48|141.75] "Unit_DegreCelsi" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ MO_Hoeheninfo : 32|8@1+ (0.00781,0) [0|1.98374] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Kennfeldk : 40|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Versionsinfo : 41|6@1+ (1,0) [0|63] "" Gateway_MQB + SG_ MO_Getriebe_kuehlen : 47|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Mom_Traegheit_02 : 48|5@1+ (0.01,0) [0|0.31] "Unit_KiloGramMeterSquar" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Heizungspumpenansteuerung : 53|4@1+ (10,0) [0|100] "Unit_PerCent" Gateway_MQB + SG_ MO_SpannungsAnf : 57|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Nachlaufzeit_Heizungspumpe : 58|6@1+ (15,0) [0|945] "Unit_Secon" Gateway_MQB BO_ 1607 Motor_09: 8 Motor_Diesel_MQB - SG_ MO_ITM_Kuehlmittel_Temp : 0|8@1+ (0.75,-48) [-45.75|143.25] "Unit_DegreCelsi" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_E85_Sensor : 8|4@1+ (10,0) [0|100] "Unit_PerCent" Gateway_MQB - SG_ SCR_Anz_Motorstarts : 12|4@1+ (1,0) [0|8] "" Gateway_MQB - SG_ SCR_Reichweite : 16|15@1+ (1,0) [0|32766] "" Gateway_MQB - SG_ SCR_Warnstufe_1 : 32|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ SCR_Warnstufe_2 : 33|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ SCR_Text : 34|3@1+ (1,0) [0|7] "" Gateway_MQB - SG_ SCR_Akustik : 37|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Kraftstofffilter_Wasser : 40|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ SCR_Systemfehler : 41|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ SCR_Inducement_Strategie : 42|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_CO2_Faktor : 44|12@1+ (1,0) [1|4094] "Unit_GramPerLiter" Gateway_MQB - SG_ MO_MKB_MUX M : 56|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_MKB_01 m0 : 59|5@1+ (1,0) [0|31] "" Gateway_MQB - SG_ MO_MKB_02 m1 : 59|5@1+ (1,0) [0|31] "" Gateway_MQB - SG_ MO_MKB_03 m2 : 59|5@1+ (1,0) [0|31] "" Gateway_MQB - SG_ MO_MKB_04 m3 : 59|5@1+ (1,0) [0|31] "" Gateway_MQB + SG_ MO_ITM_Kuehlmittel_Temp : 0|8@1+ (0.75,-48) [-45.75|143.25] "Unit_DegreCelsi" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_E85_Sensor : 8|4@1+ (10,0) [0|100] "Unit_PerCent" Gateway_MQB + SG_ SCR_Anz_Motorstarts : 12|4@1+ (1,0) [0|8] "" Gateway_MQB + SG_ SCR_Reichweite : 16|15@1+ (1,0) [0|32766] "" Gateway_MQB + SG_ SCR_Warnstufe_1 : 32|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ SCR_Warnstufe_2 : 33|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ SCR_Text : 34|3@1+ (1,0) [0|7] "" Gateway_MQB + SG_ SCR_Akustik : 37|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Kraftstofffilter_Wasser : 40|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ SCR_Systemfehler : 41|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ SCR_Inducement_Strategie : 42|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_CO2_Faktor : 44|12@1+ (1,0) [1|4094] "Unit_GramPerLiter" Gateway_MQB BO_ 167 Motor_11: 8 Motor_Diesel_MQB - SG_ Motor_11_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ Motor_11_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Mom_Soll_Roh : 12|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Mom_Ist_Summe : 22|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,SAK_MQB - SG_ MO_Mom_Traegheit_Summe : 32|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Mom_Soll_gefiltert : 42|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Mom_Schub : 52|9@1+ (1,-509) [-509|0] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Status_Normalbetrieb_01 : 61|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_erste_Ungenauschwelle : 62|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_QBit_Motormomente : 63|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ Motor_11_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ Motor_11_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Mom_Soll_Roh : 12|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Mom_Ist_Summe : 22|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,SAK_MQB + SG_ MO_Mom_Traegheit_Summe : 32|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Mom_Soll_gefiltert : 42|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Mom_Schub : 52|9@1+ (1,-509) [-509|0] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Status_Normalbetrieb_01 : 61|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_erste_Ungenauschwelle : 62|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_QBit_Motormomente : 63|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 168 Motor_12: 8 Motor_Diesel_MQB - SG_ Motor_12_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ Motor_12_BZ : 8|4@1+ (1,0) [0|15] "" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ MO_Mom_neg_verfuegbar : 12|9@1+ (1,-509) [-509|0] "Unit_NewtoMeter" Gateway_MQB - SG_ MO_Mom_Begr_stat : 21|9@1+ (1,0) [0|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Mom_Begr_dyn : 30|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB - SG_ MO_Momentenintegral_02 : 40|7@1+ (1,0) [0|100] "Unit_PerCent" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_QBit_Drehzahl_01 : 47|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ MO_Drehzahl_01 : 48|16@1+ (0.25,0) [0|16383] "Unit_MinutInver" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,SAK_MQB + SG_ Motor_12_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ Motor_12_BZ : 8|4@1+ (1,0) [0|15] "" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ MO_Mom_neg_verfuegbar : 12|9@1+ (1,-509) [-509|0] "Unit_NewtoMeter" Gateway_MQB + SG_ MO_Mom_Begr_stat : 21|9@1+ (1,0) [0|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Mom_Begr_dyn : 30|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB + SG_ MO_Momentenintegral_02 : 40|7@1+ (1,0) [0|100] "Unit_PerCent" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_QBit_Drehzahl_01 : 47|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ MO_Drehzahl_01 : 48|16@1+ (0.25,0) [0|16383] "Unit_MinutInver" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,SAK_MQB BO_ 958 Motor_14: 8 Motor_Diesel_MQB - SG_ MO_StartStopp_Status : 12|2@1+ (1,0) [0|3] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_StartStopp_Wiederstart : 14|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_StartStopp_Motorstopp : 15|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Freig_Reku : 16|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Kl_75 : 18|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Kl_50 : 19|1@1+ (1,0) [0|1] "" Gateway_MQB,LEH_MQB - SG_ MO_Gangposition : 20|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_StartStopp_Fahrerwunsch : 24|2@1+ (1,0) [0|3] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_HYB_Fahrbereitschaft : 26|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB - SG_ MO_Ext_E_Fahrt_aktiv : 27|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Fahrer_bremst : 28|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_QBit_Fahrer_bremst : 29|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_BLS : 30|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Konsistenz_Bremsped : 31|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Timeout_ESP : 32|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Klima_Eingr : 33|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Aussp_Anlass : 35|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Freig_Anlass : 36|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Kuppl_schalter : 37|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Interlock : 38|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Motor_laeuft : 39|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Kickdown : 40|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Status_Zylabschalt_01 : 41|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_EKlKomLeiRed : 42|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Handshake_STH : 44|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_BKV_Unterdruckwarnung : 45|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Freigabe_Segeln : 46|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_PTC_Status : 47|3@1+ (1,0) [0|7] "" Gateway_MQB - SG_ MO_QBit_Gangposition : 50|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Signalquelle_Gangposition : 51|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Remotestart_Betrieb : 52|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_StartStopp_Status : 12|2@1+ (1,0) [0|3] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_StartStopp_Wiederstart : 14|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_StartStopp_Motorstopp : 15|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Freig_Reku : 16|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Kl_75 : 18|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Kl_50 : 19|1@1+ (1,0) [0|1] "" Gateway_MQB,LEH_MQB + SG_ MO_Gangposition : 20|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_StartStopp_Fahrerwunsch : 24|2@1+ (1,0) [0|3] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_HYB_Fahrbereitschaft : 26|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB + SG_ MO_Ext_E_Fahrt_aktiv : 27|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Fahrer_bremst : 28|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_QBit_Fahrer_bremst : 29|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_BLS : 30|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Konsistenz_Bremsped : 31|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Timeout_ESP : 32|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Klima_Eingr : 33|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Aussp_Anlass : 35|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Freig_Anlass : 36|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Kuppl_schalter : 37|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Interlock : 38|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Motor_laeuft : 39|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Kickdown : 40|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Status_Zylabschalt_01 : 41|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_EKlKomLeiRed : 42|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Handshake_STH : 44|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_BKV_Unterdruckwarnung : 45|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Freigabe_Segeln : 46|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_PTC_Status : 47|3@1+ (1,0) [0|7] "" Gateway_MQB + SG_ MO_QBit_Gangposition : 50|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Signalquelle_Gangposition : 51|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Remotestart_Betrieb : 52|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 1631 Motor_16: 8 Motor_Diesel_MQB - SG_ TSK_QBit_Steigung : 12|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_QBit_Fahrzeugmasse : 13|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_SpannungsAnf_02 : 14|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_DPF_reg : 16|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Heizstrom_EKAT : 17|7@1+ (1,0) [0|126] "Unit_Amper" Gateway_MQB - SG_ MO_Heizstrom_SCR : 24|6@1+ (1,0) [0|62] "Unit_Amper" Gateway_MQB - SG_ TSK_Fahrzeugmasse_02 : 48|8@1+ (32,0) [0|8128] "Unit_KiloGram" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_Steigung : 56|8@1+ (0.8,-101.6) [-101.6|101.6] "Unit_PerCent" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_QBit_Steigung : 12|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_QBit_Fahrzeugmasse : 13|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_SpannungsAnf_02 : 14|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_DPF_reg : 16|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Heizstrom_EKAT : 17|7@1+ (1,0) [0|126] "Unit_Amper" Gateway_MQB + SG_ MO_Heizstrom_SCR : 24|6@1+ (1,0) [0|62] "Unit_Amper" Gateway_MQB + SG_ TSK_Fahrzeugmasse_02 : 48|8@1+ (32,0) [0|8128] "Unit_KiloGram" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_Steigung : 56|8@1+ (0.8,-101.6) [-101.6|101.6] "Unit_PerCent" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 812 Motor_17: 8 Motor_Diesel_MQB - SG_ MO_Prio_MAX_Wunschdrehzahl : 12|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Prio_MIN_Wunschdrehzahl : 13|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Prio_MAX_Wunschdrehzahl : 12|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Prio_MIN_Wunschdrehzahl : 13|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ MO_Luftpfad_aktiv : 14|1@1+ (1,0) [0|1] "" Vector__XXX SG_ MO_v_Begrenz_Aktivierbar : 15|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ MO_Drehzahlbeeinflussung : 16|8@1+ (0.39,0) [0|99.45] "Unit_PerCent" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_MIN_Wunschdrehzahl : 24|8@1+ (25,0) [0|6350] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_MAX_Wunschdrehzahl : 32|9@1+ (25,0) [0|12750] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Charisma_FahrPr : 41|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_Charisma_Status : 45|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Drehzahlbeeinflussung : 16|8@1+ (0.39,0) [0|99.45] "Unit_PerCent" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_MIN_Wunschdrehzahl : 24|8@1+ (25,0) [0|6350] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_MAX_Wunschdrehzahl : 32|9@1+ (25,0) [0|12750] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Charisma_FahrPr : 41|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_Charisma_Status : 45|2@1+ (1,0) [0|3] "" Gateway_MQB BO_ 1648 Motor_18: 8 Motor_Diesel_MQB - SG_ MO_Hybrid_StartStopp_LED : 43|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Eis_Offroad_LED : 45|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Anzahl_Abgesch_Zyl : 47|3@1+ (1,0) [0|7] "" Gateway_MQB - SG_ MO_Zylabsch_Texte : 50|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_E85_BS_Texte : 52|3@1+ (1,0) [0|7] "" Gateway_MQB - SG_ MO_Drehzahl_Warnung : 55|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_obere_Drehzahlgrenze : 56|8@1+ (50,0) [50|12750] "Unit_MinutInver" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Hybrid_StartStopp_LED : 43|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Eis_Offroad_LED : 45|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Anzahl_Abgesch_Zyl : 47|3@1+ (1,0) [0|7] "" Gateway_MQB + SG_ MO_Zylabsch_Texte : 50|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_E85_BS_Texte : 52|3@1+ (1,0) [0|7] "" Gateway_MQB + SG_ MO_Drehzahl_Warnung : 55|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_obere_Drehzahlgrenze : 56|8@1+ (50,0) [50|12750] "Unit_MinutInver" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 289 Motor_20: 8 Motor_Diesel_MQB - SG_ MO_Fahrpedalrohwert_01 : 12|8@1+ (0.4,0) [0|101.6] "Unit_PerCent" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_QBit_Fahrpedalwerte_01 : 20|1@1+ (1,0) [0|1] "" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Fahrpedalgradient : 21|8@1+ (25,0) [0|6350] "Unit_PerCentPerSecon" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Sig_Fahrpedalgradient : 29|1@1+ (1,0) [0|1] "" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_rel_Saugrohrdruck : 30|6@1+ (18,0) [0|1116] "Unit_MilliBar" Gateway_MQB - SG_ MO_rel_Saugrohrdruck_gem_err : 36|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Moment_im_Leerlauf : 37|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Schubabschaltung : 38|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Solldrehz_Leerlauf : 40|8@1+ (10,0) [0|2540] "Unit_MinutInver" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Fahrpedalrohwert_01 : 12|8@1+ (0.4,0) [0|101.6] "Unit_PerCent" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_QBit_Fahrpedalwerte_01 : 20|1@1+ (1,0) [0|1] "" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Fahrpedalgradient : 21|8@1+ (25,0) [0|6350] "Unit_PerCentPerSecon" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Sig_Fahrpedalgradient : 29|1@1+ (1,0) [0|1] "" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_rel_Saugrohrdruck : 30|6@1+ (18,0) [0|1116] "Unit_MilliBar" Gateway_MQB + SG_ MO_rel_Saugrohrdruck_gem_err : 36|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Moment_im_Leerlauf : 37|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Schubabschaltung : 38|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Solldrehz_Leerlauf : 40|8@1+ (10,0) [0|2540] "Unit_MinutInver" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 967 Motor_26: 8 Motor_Diesel_MQB - SG_ MO_Kuehlerluefter_MUX M : 0|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Kuehlerluefter_1 m0 : 1|7@1+ (1,0) [0|100] "Unit_PerCent" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Kuehlerluefter_2 m1 : 1|7@1+ (1,0) [0|100] "Unit_PerCent" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_HYB_Status_HV_Ladung : 8|3@1+ (1,0) [0|7] "" Gateway_MQB - SG_ WIV_Anzeige_aktiv : 12|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Oelmin_Warn : 13|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Sensorfehler : 14|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Schieflage : 15|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Oelstand : 16|4@1+ (12.5,0) [0|100] "Unit_PerCent" Gateway_MQB - SG_ MO_Zustand_HWP : 20|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ WIV_Oelsystem_aktiv : 24|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_nicht_betriebswarm : 25|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Ueberfuell_Warn : 26|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_laufender_Motor : 27|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_HYB_Text_1 : 28|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_HYB_Text_2 : 29|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_HYB_Text_3 : 30|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_HYB_Text_4 : 31|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Text_Motorstart : 32|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_HYB_Text_5 : 36|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_HYB_Text_6 : 37|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_HYB_Text_7 : 38|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Text_Partikelfil_Reg : 41|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Oelmenge : 43|5@1+ (125,0) [0|3875] "Unit_MilliLiter" Gateway_MQB - SG_ MO_Systemlampe : 48|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_OBD2_Lampe : 49|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Heissleuchte : 50|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Partikel_Lampe : 51|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Winterfahrprog : 52|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WIV_Oelstand_nicht_vorhanden : 53|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_nachfuellanzeige_ein : 54|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Ueberfuell_deaktiv : 55|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Unterfuell_Warn : 56|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Tankdeckel_Lampe : 57|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Text_Tankdeckelwarn : 58|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Oeldr_Warn_Motor : 60|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Status_HV_Ladung : 8|3@1+ (1,0) [0|7] "" Gateway_MQB + SG_ WIV_Anzeige_aktiv : 12|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Oelmin_Warn : 13|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Sensorfehler : 14|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Schieflage : 15|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Oelstand : 16|4@1+ (12.5,0) [0|100] "Unit_PerCent" Gateway_MQB + SG_ MO_Zustand_HWP : 20|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ WIV_Oelsystem_aktiv : 24|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_nicht_betriebswarm : 25|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Ueberfuell_Warn : 26|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_laufender_Motor : 27|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Text_1 : 28|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Text_2 : 29|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Text_3 : 30|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Text_4 : 31|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Text_Motorstart : 32|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_HYB_Text_5 : 36|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Text_6 : 37|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Text_7 : 38|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Text_Partikelfil_Reg : 41|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Oelmenge : 43|5@1+ (125,0) [0|3875] "Unit_MilliLiter" Gateway_MQB + SG_ MO_Systemlampe : 48|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_OBD2_Lampe : 49|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Heissleuchte : 50|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Partikel_Lampe : 51|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Winterfahrprog : 52|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WIV_Oelstand_nicht_vorhanden : 53|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_nachfuellanzeige_ein : 54|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Ueberfuell_deaktiv : 55|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Unterfuell_Warn : 56|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Tankdeckel_Lampe : 57|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Text_Tankdeckelwarn : 58|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Oeldr_Warn_Motor : 60|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 1601 Motor_Code_01: 8 Motor_Diesel_MQB - SG_ Motor_Code_01_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB - SG_ Motor_Code_01_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_Faktor_Momente_02 : 12|2@1+ (1,0) [0|3] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Hybridfahrzeug : 14|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Code : 16|8@1+ (1,0) [0|255] "" Gateway_MQB,SAK_MQB - SG_ MO_Getriebe_Code : 24|6@1+ (1,0) [0|63] "" Gateway_MQB - SG_ MO_StartStopp_Codiert : 30|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Anzahl_Zyl : 32|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_Kraftstoffart : 36|4@1+ (1,0) [0|15] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Hubraum : 40|7@1+ (0.1,0) [0|12.7] "Unit_Liter" Gateway_MQB - SG_ MO_Ansaugsystem : 47|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Leistung : 48|9@1+ (1,0) [0|511] "Unit_KiloWatt" Gateway_MQB - SG_ MO_Abgastyp_EOBD : 57|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,LEH_MQB - SG_ MO_Abgastyp_OBD : 58|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,LEH_MQB - SG_ MO_DPF_verbaut : 59|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ TSK_Codierung : 60|3@1+ (1,0) [0|7] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Einspritzart : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ Motor_Code_01_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB + SG_ Motor_Code_01_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_Faktor_Momente_02 : 12|2@1+ (1,0) [0|3] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Hybridfahrzeug : 14|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Code : 16|8@1+ (1,0) [0|255] "" Gateway_MQB,SAK_MQB + SG_ MO_Getriebe_Code : 24|6@1+ (1,0) [0|63] "" Gateway_MQB + SG_ MO_StartStopp_Codiert : 30|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Anzahl_Zyl : 32|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_Kraftstoffart : 36|4@1+ (1,0) [0|15] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Hubraum : 40|7@1+ (0.1,0) [0|12.7] "Unit_Liter" Gateway_MQB + SG_ MO_Ansaugsystem : 47|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Leistung : 48|9@1+ (1,0) [0|511] "Unit_KiloWatt" Gateway_MQB + SG_ MO_Abgastyp_EOBD : 57|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,LEH_MQB + SG_ MO_Abgastyp_OBD : 58|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,LEH_MQB + SG_ MO_DPF_verbaut : 59|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ TSK_Codierung : 60|3@1+ (1,0) [0|7] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Einspritzart : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 157 Motor_Hybrid_01: 8 Motor_Hybrid_MQB - SG_ Motor_Hybrid_01_CRC : 0|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB - SG_ Motor_Hybrid_01_BZ : 8|4@1+ (1,0) [0|15] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_IstStatusK0 : 12|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_max_ind_VM_Mom : 16|10@1+ (1,0) [0|1021] "Unit_NewtoMeter" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_Zielzustand : 26|3@1+ (1,0) [0|7] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB + SG_ Motor_Hybrid_01_CRC : 0|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB + SG_ Motor_Hybrid_01_BZ : 8|4@1+ (1,0) [0|15] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_IstStatusK0 : 12|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_max_ind_VM_Mom : 16|10@1+ (1,0) [0|1021] "Unit_NewtoMeter" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_Zielzustand : 26|3@1+ (1,0) [0|7] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB SG_ MO_HYB_Startmodus : 29|3@1+ (1,0) [0|7] "" Vector__XXX - SG_ MO_HYB_Startmodus_PQ3x : 32|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_Stoppmodus : 33|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_VM_Mom_oE : 40|10@1+ (1,-100) [-100|922] "Unit_NewtoMeter" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_VM_aktiv : 50|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_Schaltverhinderung : 51|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_Selektor_Momverlauf_EM M : 53|3@1+ (1,0) [0|7] "" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_Momverlauf_Rek m1 : 56|8@1+ (2,0) [0|510] "Unit_NewtoMeter" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_KnickDZ_Rek m2 : 56|8@1+ (12.5,0) [0|3150] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_Momverlauf_EM m3 : 56|8@1+ (2,0) [0|510] "Unit_NewtoMeter" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_KnickDZ_EM m4 : 56|8@1+ (12.5,0) [0|3150] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_Startmodus_PQ3x : 32|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_Stoppmodus : 33|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_VM_Mom_oE : 40|10@1+ (1,-100) [-100|922] "Unit_NewtoMeter" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_VM_aktiv : 50|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_Schaltverhinderung : 51|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB BO_ 811 Motor_Hybrid_02: 8 Motor_Hybrid_MQB - SG_ MO_HYB_E_Faktor : 12|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_Drehzahl_VM : 16|16@1+ (0.25,0) [0|16256] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_LowSpeedModus : 32|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_E_Faktor : 12|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_Drehzahl_VM : 16|16@1+ (0.25,0) [0|16256] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_LowSpeedModus : 32|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB BO_ 2600468501 NMH_Airbag_01: 8 Airbag_MQB SG_ NM_Airbag_01_SNI : 0|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ NM_Airbag_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ NM_Airbag_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ NM_Airbag_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ NM_Airbag_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB SG_ NM_Airbag_01_Wakeup : 24|8@1+ (1,0) [0|255] "" Vector__XXX SG_ NM_Airbag_01_NM_aktiv_KL15 : 32|1@1+ (1,0) [0|1] "" Vector__XXX SG_ NM_Airbag_01_NM_aktiv_Diagnose : 33|1@1+ (1,0) [0|1] "" Vector__XXX @@ -931,8 +919,8 @@ BO_ 2600468501 NMH_Airbag_01: 8 Airbag_MQB BO_ 2600468604 NMH_EMotor_01: 8 LEH_MQB SG_ NM_EMotor_01_SNI : 0|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ NM_EMotor_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ NM_EMotor_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ NM_EMotor_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ NM_EMotor_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB SG_ NM_EMotor_01_Wakeup : 24|8@1+ (1,0) [0|255] "" Vector__XXX SG_ NM_EMotor_01_NM_aktiv_KL15 : 32|1@1+ (1,0) [0|1] "" Vector__XXX SG_ NM_EMotor_01_NM_aktiv_Diagnose : 33|1@1+ (1,0) [0|1] "" Vector__XXX @@ -942,7 +930,7 @@ BO_ 2600468604 NMH_EMotor_01: 8 LEH_MQB BO_ 2600468496 NMH_Gateway: 8 Gateway_MQB SG_ NM_Gateway_SNI : 0|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ NM_Gateway_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ NM_Gateway_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ NM_Gateway_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Vector__XXX SG_ NM_Gateway_Wakeup : 24|8@1+ (1,0) [0|255] "" Vector__XXX SG_ NM_Gateway_NM_aktiv_KL15 : 32|1@1+ (1,0) [0|1] "" Vector__XXX @@ -965,8 +953,8 @@ BO_ 2600468496 NMH_Gateway: 8 Gateway_MQB BO_ 2600468599 NMH_Getriebe_01: 8 Getriebe_DQ_Hybrid_MQB SG_ NM_Getriebe_01_SNI : 0|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ NM_Getriebe_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ NM_Getriebe_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ NM_Getriebe_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ NM_Getriebe_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB SG_ NM_Getriebe_01_Wakeup : 24|8@1+ (1,0) [0|255] "" Vector__XXX SG_ NM_Getriebe_01_NM_aktiv_KL15 : 32|1@1+ (1,0) [0|1] "" Vector__XXX SG_ NM_Getriebe_01_NM_aktiv_Diagnose : 33|1@1+ (1,0) [0|1] "" Vector__XXX @@ -979,8 +967,8 @@ BO_ 2600468599 NMH_Getriebe_01: 8 Getriebe_DQ_Hybrid_MQB BO_ 2600468603 NMH_Hybrid_01: 8 BMS_MQB SG_ NM_Hybrid_01_SNI : 0|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ NM_Hybrid_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ NM_Hybrid_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ NM_Hybrid_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ NM_Hybrid_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB SG_ NM_Hybrid_01_Wakeup : 24|8@1+ (1,0) [0|255] "" Vector__XXX SG_ NM_Hybrid_01_NM_aktiv_KL15 : 32|1@1+ (1,0) [0|1] "" Vector__XXX SG_ NM_Hybrid_01_NM_aktiv_Diagnose : 33|1@1+ (1,0) [0|1] "" Vector__XXX @@ -991,8 +979,8 @@ BO_ 2600468603 NMH_Hybrid_01: 8 BMS_MQB BO_ 2600468598 NMH_MO_01: 8 Motor_Diesel_MQB SG_ NM_MO_01_SNI : 0|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ NM_MO_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ NM_MO_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ NM_MO_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ NM_MO_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB SG_ NM_MO_01_Wakeup : 24|8@1+ (1,0) [0|255] "" Vector__XXX SG_ NM_MO_01_NM_aktiv_KL15 : 32|1@1+ (1,0) [0|1] "" Vector__XXX SG_ NM_MO_01_NM_aktiv_Diagnose : 33|1@1+ (1,0) [0|1] "" Vector__XXX @@ -1008,57 +996,57 @@ BO_ 2600468598 NMH_MO_01: 8 Motor_Diesel_MQB SG_ NM_MO_01_UDS_CC : 63|1@1+ (1,0) [0|1] "" Vector__XXX BO_ 913 OBD_01: 8 Motor_Diesel_MQB - SG_ OBD_Calc_Load_Val : 0|8@1+ (0.39215686275,0) [0|100] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Eng_Cool_Temp : 8|8@1+ (1,-40) [-40|215] "Unit_DegreCelsi" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Abs_Throttle_Pos : 16|8@1+ (0.39215686275,0) [0|100] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Abs_Load_Val : 24|16@1+ (0.39215686275,0) [0|25700] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Abs_Pedal_Pos : 40|8@1+ (0.39215686275,0) [0|100] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Kaltstart_Denominator : 59|1@1+ (1,0) [0|1] "" BMS_MQB,LEH_MQB - SG_ OBD_Minimum_Trip : 60|1@1+ (1,0) [0|1] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Driving_Cycle : 61|1@1+ (1,0) [0|1] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Warm_Up_Cycle : 62|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Normed_Trip : 63|1@1+ (1,0) [0|1] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Calc_Load_Val : 0|8@1+ (0.39215686275,0) [0|100] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Eng_Cool_Temp : 8|8@1+ (1,-40) [-40|215] "Unit_DegreCelsi" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Abs_Throttle_Pos : 16|8@1+ (0.39215686275,0) [0|100] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Abs_Load_Val : 24|16@1+ (0.39215686275,0) [0|25700] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Abs_Pedal_Pos : 40|8@1+ (0.39215686275,0) [0|100] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Kaltstart_Denominator : 59|1@1+ (1,0) [0|1] "" BMS_MQB,LEH_MQB + SG_ OBD_Minimum_Trip : 60|1@1+ (1,0) [0|1] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Driving_Cycle : 61|1@1+ (1,0) [0|1] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Warm_Up_Cycle : 62|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Normed_Trip : 63|1@1+ (1,0) [0|1] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB BO_ 1630 OBD_Tankgeber_01: 8 Gateway_MQB - SG_ OBD_TG_F_Status_1 : 0|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_TG_F_Status_2 : 4|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_TG_F_Status_3 : 8|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_TG_F_Status_4 : 12|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_TG_Sens_Rohwert_1 : 16|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_TG_Sens_Rohwert_2 : 28|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_TG_Sens_Rohwert_3 : 40|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_TG_Sens_Rohwert_4 : 52|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_F_Status_1 : 0|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_F_Status_2 : 4|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_F_Status_3 : 8|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_F_Status_4 : 12|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_Sens_Rohwert_1 : 16|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_Sens_Rohwert_2 : 28|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_Sens_Rohwert_3 : 40|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_Sens_Rohwert_4 : 52|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 1437 Remotestart_FFB: 8 Gateway_MQB - SG_ RSF_Tastencode_1 : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ RSF_Tastencode_2 : 8|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ RSF_Tastencode_Maske : 16|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ RSF_Tastencode_1 : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ RSF_Tastencode_2 : 8|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ RSF_Tastencode_Maske : 16|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Otto_MQB BO_ 984 RGS_VL_01: 8 Airbag_MQB - SG_ RGS_VL_Texte : 12|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ RGS_VL_Charisma_FahrPr : 14|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ RGS_VL_Charisma_Status : 18|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ RGS_VL_aktiv : 21|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ RGS_VL_PC_Aktuator_Sitz : 25|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ RGS_VL_PC_Aktuator_Schiebedach : 26|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ RGS_VL_PC_Aktuator_Fenster : 27|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ RGS_VL_PC_Aktuator_Warnblinken : 28|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ RGS_VL_Precrash_Basis : 32|8@1+ (1,0) [0|255] "" Gateway_MQB - SG_ RGS_VL_Precrash_Front : 40|8@1+ (1,0) [0|255] "" Gateway_MQB - SG_ RGS_VL_Precrash_Rear : 48|8@1+ (1,0) [0|255] "" Gateway_MQB + SG_ RGS_VL_Texte : 12|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ RGS_VL_Charisma_FahrPr : 14|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ RGS_VL_Charisma_Status : 18|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ RGS_VL_aktiv : 21|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ RGS_VL_PC_Aktuator_Sitz : 25|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ RGS_VL_PC_Aktuator_Schiebedach : 26|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ RGS_VL_PC_Aktuator_Fenster : 27|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ RGS_VL_PC_Aktuator_Warnblinken : 28|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ RGS_VL_Precrash_Basis : 32|8@1+ (1,0) [0|255] "" Gateway_MQB + SG_ RGS_VL_Precrash_Front : 40|8@1+ (1,0) [0|255] "" Gateway_MQB + SG_ RGS_VL_Precrash_Rear : 48|8@1+ (1,0) [0|255] "" Gateway_MQB BO_ 1528 SAK_01: 8 SAK_MQB - SG_ SAK_Charisma_FahrPr : 16|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ SAK_Charisma_Status : 20|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ SAK_Charisma_FahrPr : 16|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ SAK_Charisma_Status : 20|2@1+ (1,0) [0|3] "" Gateway_MQB BO_ 1313 STH_01: 8 Gateway_MQB SG_ STH_Funk_ein : 0|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STH_Funk_aus : 1|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STH_Zusatzheizung : 2|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ STH_LED : 3|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ STH_LED : 3|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ STH_Pumpe_ein : 4|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STH_Geblaese : 5|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ STH_EKP_Anst : 6|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ STH_EKP_Anst : 6|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ STH_Start_folgt : 7|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STH_Ventiloeffnungszeit : 8|6@1+ (1,0) [0|63] "Unit_Minut" Vector__XXX SG_ STH_Ventil_Status : 14|1@1+ (1,0) [0|1] "" Vector__XXX @@ -1067,15 +1055,15 @@ BO_ 1313 STH_01: 8 Gateway_MQB SG_ STH_Fehlerstatus : 37|3@1+ (1,0) [0|7] "" Vector__XXX SG_ STH_Heizleistung : 40|8@1+ (1,0) [0|255] "" Vector__XXX SG_ STH_Wassertemp : 48|8@1+ (0.75,-40) [-40|142.25] "Unit_DegreCelsi" Vector__XXX - SG_ STH_Motorvorwaermung : 59|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ STH_Motorvorwaermung : 59|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ STH_Servicemode : 60|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ STH_war_aktiv : 61|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ STH_war_aktiv : 61|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ STH_KVS_Ueberlauf : 62|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STH_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Vector__XXX BO_ 1172 STS_01: 8 Gateway_MQB - SG_ STS_01_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ STS_01_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ STS_01_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ STS_01_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ STS_Car_not_under_theft : 12|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STS_Car_under_theft : 13|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STS_Anlassersperre : 15|1@1+ (1,0) [0|1] "" Vector__XXX @@ -1090,15 +1078,15 @@ BO_ 1172 STS_01: 8 Gateway_MQB SG_ STS_Alarm_Blinker : 50|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STS_Notstart : 51|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STS_Signalhorn : 55|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ STS_Leerlaufschaltung : 56|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ STS_Leerlaufschaltung : 56|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 1413 Systeminfo_01: 8 Gateway_MQB SG_ SI_Sammel_SG_Fehler : 0|6@1+ (1,0) [0|60] "" Vector__XXX SG_ SI_Rollenmode : 6|2@1+ (1,0) [0|3] "" Vector__XXX - SG_ SI_QRS_Mode : 8|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ SI_QRS_Mode : 8|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ SI_T_Mode : 9|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ SI_NWDF : 10|1@1+ (1,0) [0|1] "" SAK_MQB - SG_ SI_NWDF_gueltig : 11|1@1+ (1,0) [0|1] "" SAK_MQB + SG_ SI_NWDF : 10|1@1+ (1,0) [0|1] "" SAK_MQB + SG_ SI_NWDF_gueltig : 11|1@1+ (1,0) [0|1] "" SAK_MQB SG_ SI_Sammelfehler : 12|1@1+ (1,0) [0|1] "" Vector__XXX SG_ GW_KD_Fehler : 13|1@1+ (1,0) [0|1] "" Vector__XXX SG_ SI_BUS_01 : 16|1@1+ (1,0) [0|1] "" Vector__XXX @@ -1118,25 +1106,25 @@ BO_ 1413 Systeminfo_01: 8 Gateway_MQB SG_ SI_BUS_15 : 30|1@1+ (1,0) [0|1] "" Vector__XXX BO_ 288 TSK_06: 8 Motor_Diesel_MQB - SG_ TSK_06_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_06_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_Radbremsmom : 12|12@1+ (8,0) [0|32760] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_Status : 24|3@1+ (1,0) [0|7] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_v_Begrenzung_aktiv : 27|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_Standby_Anf_ESP : 28|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ TSK_Freig_Verzoeg_Anf : 30|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_Limiter_ausgewaehlt : 31|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_ax_Getriebe_02 : 48|9@1+ (0.024,-2.016) [-2.016|10.224] "Unit_MeterPerSeconSquar" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_Zwangszusch_ESP : 57|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ TSK_zul_Regelabw : 58|6@1+ (0.024,0) [0|1.512] "Unit_MeterPerSeconSquar" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_06_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_06_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_Radbremsmom : 12|12@1+ (8,0) [0|32760] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_Status : 24|3@1+ (1,0) [0|7] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_v_Begrenzung_aktiv : 27|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_Standby_Anf_ESP : 28|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ TSK_Freig_Verzoeg_Anf : 30|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_Limiter_ausgewaehlt : 31|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_ax_Getriebe_02 : 48|9@1+ (0.024,-2.016) [-2.016|10.224] "Unit_MeterPerSeconSquar" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_Zwangszusch_ESP : 57|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ TSK_zul_Regelabw : 58|6@1+ (0.024,0) [0|1.512] "Unit_MeterPerSeconSquar" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 798 TSK_07: 8 Motor_Diesel_MQB - SG_ TSK_07_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB - SG_ TSK_07_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ TSK_Wunschgeschw : 12|10@1+ (0.32,0) [0|326.72] "Unit_KiloMeterPerHour" Gateway_MQB - SG_ TSK_Texte_Primaeranz : 48|5@1+ (1,0) [0|31] "" Gateway_MQB - SG_ TSK_Limiter_Anzeige : 55|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ TSK_Status_Anzeige : 61|3@1+ (1,0) [0|7] "" Gateway_MQB + SG_ TSK_07_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB + SG_ TSK_07_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ TSK_Wunschgeschw : 12|10@1+ (0.32,0) [0|326.72] "Unit_KiloMeterPerHour" Gateway_MQB + SG_ TSK_Texte_Primaeranz : 48|5@1+ (1,0) [0|31] "" Gateway_MQB + SG_ TSK_Limiter_Anzeige : 55|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ TSK_Status_Anzeige : 61|3@1+ (1,0) [0|7] "" Gateway_MQB BO_ 1716 VIN_01: 8 Gateway_MQB SG_ VIN_01_MUX M : 0|2@1+ (1,0) [0|3] "" Airbag_MQB @@ -1163,30 +1151,195 @@ BO_ 1716 VIN_01: 8 Gateway_MQB SG_ VIN_17 m2 : 56|8@1+ (1,0) [0|255] "" Airbag_MQB BO_ 175 Waehlhebel_03: 4 Waehlhebel_MQB - SG_ WH_Status_Sperre : 0|3@1+ (1,0) [0|7] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WH_Initialisierung : 3|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WH_SensorPos_roh : 4|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WH_03_BZ : 8|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WH_SensorPos_roh_inv : 12|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WH_Testergebnis : 16|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WH_Test_Aktiv : 24|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WH_Status : 25|7@1+ (1,0) [0|127] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_Status_Sperre : 0|3@1+ (1,0) [0|7] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_Initialisierung : 3|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_SensorPos_roh : 4|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_03_BZ : 8|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_SensorPos_roh_inv : 12|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_Testergebnis : 16|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_Test_Aktiv : 24|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_Status : 25|7@1+ (1,0) [0|127] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 916 WBA_03: 8 Getriebe_DQ_Hybrid_MQB - SG_ WBA_03_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB - SG_ WBA_03_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ WBA_Fahrstufe_02 : 12|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ WBA_ZielFahrstufe : 16|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ WBA_GE_Warnung_02 : 20|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ WBA_eing_Gang_02 : 24|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Otto_MQB - SG_ WBA_GE_Texte : 28|3@1+ (1,0) [0|7] "" Gateway_MQB - SG_ WBA_Segeln_aktiv : 31|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WBA_Schaltschema : 32|5@1+ (1,0) [0|31] "" Gateway_MQB + SG_ WBA_03_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB + SG_ WBA_03_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ WBA_Fahrstufe_02 : 12|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ WBA_ZielFahrstufe : 16|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ WBA_GE_Warnung_02 : 20|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ WBA_eing_Gang_02 : 24|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Otto_MQB + SG_ WBA_GE_Texte : 28|3@1+ (1,0) [0|7] "" Gateway_MQB + SG_ WBA_Segeln_aktiv : 31|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WBA_Schaltschema : 32|5@1+ (1,0) [0|31] "" Gateway_MQB BO_ 1602 WIV_01: 8 Motor_Diesel_MQB - SG_ WIV_Verschleissindex : 0|16@1+ (2E-008,0) [0|0.00131068] "" Gateway_MQB - SG_ WIV_Russindex : 16|16@1+ (2E-008,0) [0|0.00131068] "" Gateway_MQB - SG_ WIV_t_min : 32|6@1+ (1,0) [0|63] "Unit_Month" Gateway_MQB - SG_ WIV_t_max : 40|6@1+ (1,0) [0|63] "Unit_Month" Gateway_MQB - SG_ WIV_W_min : 48|7@1+ (1000,0) [0|127000] "Unit_KiloMeter" Gateway_MQB - SG_ WIV_W_max : 56|7@1+ (1000,0) [0|127000] "Unit_KiloMeter" Gateway_MQB + SG_ WIV_Verschleissindex : 0|16@1+ (2e-8,0) [0|0.00131068] "" Gateway_MQB + SG_ WIV_Russindex : 16|16@1+ (2e-8,0) [0|0.00131068] "" Gateway_MQB + SG_ WIV_t_min : 32|6@1+ (1,0) [0|63] "Unit_Month" Gateway_MQB + SG_ WIV_t_max : 40|6@1+ (1,0) [0|63] "Unit_Month" Gateway_MQB + SG_ WIV_W_min : 48|7@1+ (1000,0) [0|127000] "Unit_KiloMeter" Gateway_MQB + SG_ WIV_W_max : 56|7@1+ (1000,0) [0|127000] "Unit_KiloMeter" Gateway_MQB + +BO_ 294 HCA_01: 8 XXX + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX + SG_ COUNTER : 8|4@1+ (1,0) [0|255] "" XXX + SG_ SET_ME_0X3 : 12|4@1+ (1,0) [0|15] "" XXX + SG_ Assist_Torque : 16|14@1+ (1,0) [0|300] "Nm" XXX + SG_ Assist_Requested : 30|1@1+ (1,0) [0|1] "" XXX + SG_ Assist_VZ : 31|1@1+ (1,0) [0|1] "" XXX + SG_ HCA_Available : 32|1@1+ (1,0) [0|1] "" XXX + SG_ HCA_Standby : 33|1@1+ (1,0) [0|1] "" XXX + SG_ HCA_Active : 34|1@1+ (1,0) [0|1] "" XXX + SG_ SET_ME_0XFE : 40|8@1+ (1,0) [0|255] "" XXX + SG_ SET_ME_0X07 : 48|8@1+ (1,0) [0|255] "" XXX + +BO_ 159 EPS_01: 8 XXX + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX + SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX + SG_ Steering_Wheel_Angle : 16|13@1+ (0.15,0) [0|16383] "Unit_DegreOfArc" XXX + SG_ Steering_Wheel_Angle_VZ : 31|1@1+ (1,0) [0|1] "" XXX + SG_ HCA_Active : 34|1@1+ (1,0) [0|1] "" XXX + SG_ HCA_Standby : 33|1@1+ (1,0) [0|1] "" XXX + SG_ Unknown_Status2 : 63|1@1+ (1,0) [0|1] "" XXX + SG_ HCA_Ready : 32|1@1+ (1,0) [0|3] "" XXX + SG_ Driver_Strain : 40|13@1+ (1,0) [0|255] "Nm" XXX + SG_ Driver_Strain_VZ : 55|1@1+ (1,0) [0|1] "" XXX + SG_ Unknown_Status1 : 62|1@1+ (1,0) [0|1] "" XXX + +BO_ 286 VehicleSpeed: 8 XXX + SG_ VehicleSpeed_CRC : 0|8@1+ (1,0) [0|255] "" XXX + SG_ VehicleSpeed_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ Speed : 52|12@1+ (0.125,0) [0|1] "" XXX + +BO_ 919 LDW_02: 8 XXX + SG_ LDW_DLC : 40|8@1+ (0.01,0) [0|255] "m" XXX + SG_ LDW_TLC : 48|5@1+ (0.05,0) [0|255] "Seconds" XXX + SG_ LDW_Unknown : 14|2@1+ (1,0) [0|3] "" XXX + SG_ Alert_Message : 16|4@1+ (1,0) [0|15] "" XXX + SG_ LDW_Direction : 20|1@1+ (1,0) [0|1] "" XXX + SG_ Right_Lane_Status : 36|2@1+ (1,0) [0|3] "" XXX + SG_ Left_Lane_Status : 38|2@1+ (1,0) [0|3] "" XXX + SG_ Kombi_Lamp_Orange : 61|1@1+ (1,0) [0|1] "" XXX + SG_ Kombi_Lamp_Green : 62|1@1+ (1,0) [0|1] "" XXX + +BO_ 780 ACC_02: 8 XXX + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX + SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX + SG_ SetSpeed : 12|10@1+ (0.08865,0) [0|90.68] "Unit_MeterPerSecond" XXX + SG_ Kollision1 : 23|1@1+ (1,0) [0|1] "" XXX + SG_ Abstand : 24|10@1+ (0.1,0) [0|102.3] "m" XXX + SG_ ACC_MinusInv : 36|2@1+ (1,0) [0|3] "" XXX + SG_ ACC_Minus : 38|2@1+ (1,0) [0|3] "" XXX + SG_ Kollision2 : 40|1@1+ (1,0) [0|1] "" XXX + SG_ MotorbitB5_1 : 41|1@1+ (1,0) [0|1] "" XXX + SG_ 1_aktivieren : 42|1@1+ (1,0) [0|1] "" XXX + SG_ Tacho_LED : 43|1@1+ (1,0) [0|1] "" XXX + SG_ Hebelquit : 44|1@1+ (1,0) [0|1] "" XXX + SG_ 1_aktivieren_inv : 45|1@1+ (1,0) [0|1] "" XXX + SG_ Folgefahrt : 46|1@1+ (1,0) [0|1] "" XXX + SG_ MotorbitB5_7 : 47|1@1+ (1,0) [0|1] "" XXX + SG_ SetAbstand : 48|4@1+ (1,0) [0|15] "" XXX + SG_ Hebel : 56|4@1+ (1,0) [0|15] "" XXX + +BO_ 302 ACC_07: 8 XXX + SG_ ACC_07_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ ACC_07_CRC : 0|8@1+ (1,0) [0|255] "" XXX + +BO_ 264 Fahrwerk_01: 8 XXX + SG_ Fahrwerk_01_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ Fahrwerk_01_CRC : 0|8@1+ (1,0) [0|255] "" XXX + +BO_ 695 RCTA_01: 8 XXX + SG_ RCTA_01_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ RCTA_01_CRC : 0|8@1+ (1,0) [0|255] "" XXX + +BO_ 783 SWA_01: 8 XXX + SG_ SWA_01_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ SWA_01_CRC : 0|8@1+ (1,0) [0|255] "" XXX + +BO_ 804 ACC_04: 8 XXX + SG_ ACC_04_CRC : 0|8@1+ (1,0) [0|255] "" XXX + SG_ ACC_04_BZ : 8|4@1+ (1,0) [0|15] "" XXX + +BO_ 917 LWR_AFS_01: 8 XXX + +BO_ 991 Gateway_76: 8 XXX + +BO_ 997 TSG_FT_02: 8 XXX + SG_ TSG_FT_02_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ TSG_FT_02_CRC : 0|8@1+ (1,0) [0|255] "" XXX + +BO_ 1175 Parkhilfe_01: 8 XXX + +BO_ 427 ESP_33: 8 XXX + SG_ ESP_33_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ ESP_33_CRC : 0|8@1+ (1,0) [0|255] "" XXX + +BO_ 418 ESP_15: 8 XXX + SG_ ESP_15_CRC : 0|8@1+ (1,0) [0|255] "" XXX + SG_ ESP_15_BZ : 8|4@1+ (1,0) [0|15] "" XXX + +BO_ 1122 PSD_04: 8 XXX + SG_ PSD_Object_Index : 0|6@1+ (1,0) [0|63] "" XXX + +BO_ 1123 PSD_05: 8 XXX + SG_ PSD_Current_Route_Index : 0|6@1+ (1,0) [0|63] "" XXX + SG_ Route_Distance_Remaining : 8|5@1+ (1,0) [0|31] "" XXX + +BO_ 1124 PSD_06: 8 XXX + +BO_ 988 Gateway_73: 8 XXX + +BO_ 792 Kamera_Status: 8 XXX + +BO_ 981 Licht_Anf_01: 8 XXX + +BO_ 1440 RLS_01: 8 XXX + +BO_ 870 Blinkmodi_02: 8 XXX + +BO_ 1385 HVEM_04: 8 XXX + +BO_ 1605 FLA_01: 8 XXX + +BO_ 1624 Licht_vorne_01: 8 XXX + +BO_ 1646 Klima_03: 8 XXX + +BO_ 1720 Kombi_03: 8 XXX + +BO_ 391 EV_Gearshift: 8 XXX + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX + SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX + SG_ GearPosition : 16|4@1+ (1,0) [0|255] "" XXX + SG_ RegenBrakingMode : 12|2@1+ (1,0) [0|3] "" XXX + +CM_ SG_ 173 COUNTERXX "Message not renamed to COUNTER because J533 rate-limiting makes it look like messages are being lost"; +CM_ SG_ 134 LWI_Lenkradwinkel "Steering angle WITH variable ratio effect included"; +CM_ SG_ 294 3 "May be zero when sent by older cameras"; +CM_ SG_ 294 7 "May be zero when sent by older cameras"; +CM_ SG_ 294 254 "May be zero when sent by older cameras"; +CM_ SG_ 294 Assist_Torque "Heading control input, torque"; +CM_ SG_ 294 Assist_VZ "Heading control input, direction (sign)"; +CM_ SG_ 294 HCA_Available "Must be 1 for steering rack to accept HCA commands"; +CM_ SG_ 159 HCA_Ready "1 if HCA is okay, 0 if the rack doesn't have HCA configured or a timer/constraint has been violated, rack will not respond to HCA commands"; +CM_ SG_ 159 Driver_Strain "Steering input by driver, torque"; +CM_ SG_ 159 Driver_Strain_VZ "Steering input by driver, sign (direction)"; +CM_ SG_ 159 Steering_Wheel_Angle "Steering angle WITHOUT variable ratio effect included"; +CM_ SG_ 919 LDW_DLC "Probable DLC (distance to line crossing)"; +CM_ SG_ 919 LDW_TLC "Probable TLC (time to line crossing)"; +CM_ SG_ 919 LDW_Unknown "Might be a steering pressed / driver active flag"; +CM_ SG_ 919 Alert_Message "Static table of alert messages to be invoked in the instrument cluster, some with or without beeps, 0 = no current message"; +CM_ SG_ 919 LDW_Direction "Left/right indicator for DLC and TLC"; +CM_ SG_ 919 Right_Lane_Status "Display brightness range, 0 = no lane, 3 = full brightness"; +CM_ SG_ 919 Left_Lane_Status "Display brightness range, 0 = no lane, 3 = full brightness"; +CM_ SG_ 919 Kombi_Lamp_Orange "Enables orange LDW light in instrument cluster"; +CM_ SG_ 919 Kombi_Lamp_Green "Enables green LDW light in instrument cluster"; +CM_ SG_ 780 Folgefahrt "Following another vehicle"; +CM_ SG_ 780 SetAbstand "Set following distance"; +CM_ SG_ 780 Abstand "Following distance"; +CM_ SG_ 780 SetSpeed "ACC set speed"; +CM_ SG_ 391 GearPosition "Traditional PRND plus B-mode aggressive regen, B-mode mapped to Drive"; +CM_ SG_ 960 ZAS_Kl_15 "Indicates ignition on"; +VAL_ 173 GE_Fahrstufe 5 "P" 6 "R" 7 "N" 8 "D" 9 "S" 10 "E" 14 "T"; +VAL_ 391 GearPosition 2 "P" 3 "R" 4 "N" 5 "D" 6 "D"; +VAL_ 391 RegenBrakingMode 0 "default" 1 "B1" 2 "B2" 3 "B3"; diff --git a/panda/.circleci/config.yml b/panda/.circleci/config.yml index 6b98610c507527..58fc1d13bc9dbd 100644 --- a/panda/.circleci/config.yml +++ b/panda/.circleci/config.yml @@ -11,7 +11,28 @@ jobs: - run: name: Run safety test command: | - docker run panda_safety /bin/bash -c "cd /panda/tests/safety; ./test.sh" + docker run panda_safety /bin/bash -c "cd /panda/tests/safety; PYTHONPATH=/ ./test.sh" + + misra-c2012: + machine: + docker_layer_caching: true + steps: + - checkout + - run: + name: Build image + command: "docker build -t panda_misra -f tests/misra/Dockerfile ." + - run: + name: Run Misra C 2012 test + command: | + mkdir /tmp/misra + docker run -v /tmp/misra:/tmp/misra panda_misra /bin/bash -c "cd /panda/tests/misra; ./test_misra.sh" + - store_artifacts: + name: Store cppcheck test output + path: /tmp/misra/cppcheck_output.txt + - store_artifacts: + name: Store misra test output + path: /tmp/misra/misra_output.txt + build: machine: docker_layer_caching: true @@ -40,18 +61,58 @@ jobs: name: Build Pedal STM bootstub image command: | docker run panda_build /bin/bash -c "cd /panda/board/pedal; make obj/bootstub.bin" - - run: - name: Build NEO STM image - command: | - docker run panda_build /bin/bash -c "cd /panda/board; make clean; make -f Makefile.legacy obj/comma.bin" - run: name: Build ESP image command: | docker run panda_build /bin/bash -c "cd /panda/boardesp; make user1.bin" + safety_replay: + machine: + docker_layer_caching: true + steps: + - checkout + - run: + name: Build image + command: "docker build -t panda_safety_replay -f tests/safety_replay/Dockerfile ." + - run: + name: Replay drives + command: | + docker run panda_safety_replay /bin/bash -c "cd /openpilot/panda/tests/safety_replay; PYTHONPATH=/openpilot ./test_safety_replay.py" + + language_check: + machine: + docker_layer_caching: true + steps: + - checkout + - run: + name: Build image + command: "docker build -t language_check -f tests/language/Dockerfile ." + - run: + name: Check code for bad language + command: | + docker run language_check /bin/bash -c "cd /panda/tests/language; ./test_language.py" + + linter_python: + machine: + docker_layer_caching: true + steps: + - checkout + - run: + name: Build image + command: "docker build -t linter_python -f tests/linter_python/Dockerfile ." + - run: + name: Run linter python test + command: | + docker run linter_python /bin/bash -c "cd /panda/tests/linter_python; PYTHONPATH=/ ./flake8_panda.sh" + docker run linter_python /bin/bash -c "cd /panda/tests/linter_python; PYTHONPATH=/ ./pylint_panda.sh" + workflows: version: 2 main: jobs: - safety + - misra-c2012 - build + - safety_replay + - language_check + - linter_python diff --git a/panda/.dockerignore b/panda/.dockerignore new file mode 100644 index 00000000000000..f04ae5c0aa6892 --- /dev/null +++ b/panda/.dockerignore @@ -0,0 +1,3 @@ +.git +.DS_Store +boardesp/esp-open-sdk diff --git a/panda/.gitignore b/panda/.gitignore index 7b7762ef490663..397996a0bcca35 100644 --- a/panda/.gitignore +++ b/panda/.gitignore @@ -4,11 +4,14 @@ *.o *.so *.d +*.dump a.out *~ .#* dist/ pandacan.egg-info/ board/obj/ -examples/output.csv -.DS_Store +examples/output.csv +.DS_Store +.vscode +nosetests.xml diff --git a/panda/Dockerfile b/panda/Dockerfile new file mode 100644 index 00000000000000..a029a5ffa4af14 --- /dev/null +++ b/panda/Dockerfile @@ -0,0 +1,81 @@ +FROM ubuntu:16.04 +ENV PYTHONUNBUFFERED 1 + +RUN apt-get update && apt-get install -y \ + autoconf \ + automake \ + bash \ + bison \ + bzip2 \ + curl \ + dfu-util \ + flex \ + g++ \ + gawk \ + gcc \ + git \ + gperf \ + help2man \ + iputils-ping \ + libbz2-dev \ + libexpat-dev \ + libffi-dev \ + libssl-dev \ + libstdc++-arm-none-eabi-newlib \ + libtool \ + libtool-bin \ + libusb-1.0-0 \ + locales \ + make \ + ncurses-dev \ + network-manager \ + python-dev \ + python-serial \ + sed \ + texinfo \ + unrar-free \ + unzip \ + wget \ + build-essential \ + python-dev \ + python-pip \ + screen \ + vim \ + wget \ + wireless-tools \ + zlib1g-dev + +RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash + +ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}" +RUN pyenv install 3.7.3 +RUN pyenv install 2.7.12 +RUN pyenv global 3.7.3 +RUN pyenv rehash + +RUN pip install --upgrade pip==18.0 + +COPY requirements.txt /tmp/ +RUN pip install -r /tmp/requirements.txt + +RUN mkdir -p /home/batman +ENV HOME /home/batman + +ENV PYTHONPATH /tmp:$PYTHONPATH + +COPY ./boardesp/get_sdk_ci.sh /tmp/panda/boardesp/ +COPY ./boardesp/python2_make.py /tmp/panda/boardesp/ + +RUN useradd --system -s /sbin/nologin pandauser +RUN mkdir -p /tmp/panda/boardesp/esp-open-sdk +RUN chown pandauser /tmp/panda/boardesp/esp-open-sdk +USER pandauser +RUN cd /tmp/panda/boardesp && ./get_sdk_ci.sh +USER root + +ADD ./panda.tar.gz /tmp/panda diff --git a/panda/Jenkinsfile b/panda/Jenkinsfile new file mode 100644 index 00000000000000..204b5beb3d925a --- /dev/null +++ b/panda/Jenkinsfile @@ -0,0 +1,75 @@ +pipeline { + agent any + environment { + AUTHOR = """${sh( + returnStdout: true, + script: "git --no-pager show -s --format='%an' ${GIT_COMMIT}" + ).trim()}""" + + DOCKER_IMAGE_TAG = "panda:build-${env.GIT_COMMIT}" + DOCKER_NAME = "panda-test-${env.GIT_COMMIT}" + } + stages { + stage('Build Docker Image') { + steps { + timeout(time: 60, unit: 'MINUTES') { + script { + sh 'git archive -v -o panda.tar.gz --format=tar.gz HEAD' + dockerImage = docker.build("${env.DOCKER_IMAGE_TAG}") + } + } + } + } + stage('Test Dev Build (no WIFI)') { + steps { + lock(resource: "Pandas", inversePrecedence: true, quantity: 1){ + timeout(time: 60, unit: 'MINUTES') { + script { + sh "docker run --name ${env.DOCKER_NAME} --privileged --volume /dev/bus/usb:/dev/bus/usb --volume /var/run/dbus:/var/run/dbus --net host ${env.DOCKER_IMAGE_TAG} bash -c 'cd /tmp/panda; SKIPWIFI=1 ./run_automated_tests.sh'" + sh "docker cp ${env.DOCKER_NAME}:/tmp/panda/nosetests.xml test_results_dev_nowifi.xml" + sh "docker rm ${env.DOCKER_NAME}" + } + } + } + } + } + stage('Test EON Build') { + steps { + lock(resource: "Pandas", inversePrecedence: true, quantity: 1){ + timeout(time: 60, unit: 'MINUTES') { + script { + sh "docker run --name ${env.DOCKER_NAME} --privileged --volume /dev/bus/usb:/dev/bus/usb --volume /var/run/dbus:/var/run/dbus --net host ${env.DOCKER_IMAGE_TAG} bash -c 'touch /EON; cd /tmp/panda; ./run_automated_tests.sh'" + sh "docker cp ${env.DOCKER_NAME}:/tmp/panda/nosetests.xml test_results_eon.xml" + sh "docker rm ${env.DOCKER_NAME}" + } + } + } + } + } +/* + stage('Test Dev Build (WIFI)') { + steps { + lock(resource: "Pandas", inversePrecedence: true, quantity: 1){ + timeout(time: 60, unit: 'MINUTES') { + script { + sh "docker run --name ${env.DOCKER_NAME} --privileged --volume /dev/bus/usb:/dev/bus/usb --volume /var/run/dbus:/var/run/dbus --net host ${env.DOCKER_IMAGE_TAG} bash -c 'cd /tmp/panda; ./run_automated_tests.sh'" + sh "docker cp ${env.DOCKER_NAME}:/tmp/panda/nosetests.xml test_results_dev.xml" + sh "docker rm ${env.DOCKER_NAME}" + } + } + } + } + } +*/ + } + post { + failure { + script { + sh "docker rm ${env.DOCKER_NAME} || true" + } + } + always { + junit "test_results*.xml" + } + } +} diff --git a/panda/README.md b/panda/README.md index 42f432dfc32a38..634db4c120b157 100644 --- a/panda/README.md +++ b/panda/README.md @@ -37,6 +37,13 @@ And to send one on bus 0: ``` Find user made scripts on the [wiki](https://community.comma.ai/wiki/index.php/Panda_scripts) +Note that you may have to setup [udev rules](https://community.comma.ai/wiki/index.php/Panda#Linux_udev_rules) for Linux, such as +``` +sudo -i +echo 'SUBSYSTEMS=="usb", ATTR{idVendor}=="bbaa", ATTR{idProduct}=="ddcc", MODE:="0666"' > /etc/udev/rules.d/11-panda.rules +exit +``` + Usage (JavaScript) ------- @@ -80,9 +87,28 @@ To print out the serial console from the ESP8266, run PORT=1 tests/debug_console Safety Model ------ -When a panda powers up, by default it's in "SAFETY_NOOUTPUT" mode. While in no output mode, the buses are also forced to be silent. In order to send messages, you have to select a safety mode. Currently, setting safety modes is only supported over USB. +When a panda powers up, by default it's in `SAFETY_NOOUTPUT` mode. While in no output mode, the buses are also forced to be silent. In order to send messages, you have to select a safety mode. Currently, setting safety modes is only supported over USB. -Safety modes can also optionally support "controls_allowed", which allows or blocks a subset of messages based on a piece of state in the board. +Safety modes optionally supports `controls_allowed`, which allows or blocks a subset of messages based on a customizable state in the board. + +Code Rigor +------ +When compiled from an [EON Dev Kit](https://comma.ai/shop/products/eon-gold-dashcam-devkit), the panda FW is configured and optimized (at compile time) for its use in +conjuction with [openpilot](https://github.com/commaai/openpilot). The panda FW, through its safety model, provides and enforces the +[openpilot Safety](https://github.com/commaai/openpilot/blob/devel/SAFETY.md). Due to its critical function, it's important that the application code rigor within the `board` folder is held to high standards. + +These are the [CI regression tests](https://circleci.com/gh/commaai/panda) we have in place: +* A generic static code analysis is performed by [Cppcheck](https://github.com/danmar/cppcheck/). +* In addition, [Cppcheck](https://github.com/danmar/cppcheck/) has a specific addon to check for [MISRA C:2012](https://www.misra.org.uk/MISRAHome/MISRAC2012/tabid/196/Default.aspx) violations. See [current coverage](https://github.com/commaai/panda/blob/master/tests/misra/coverage_table). +* Compiler options are relatively strict: the flags `-Wall -Wextra -Wstrict-prototypes -Werror` are enforced on board and pedal makefiles. +* The [safety logic](https://github.com/commaai/panda/tree/master/board/safety) is tested and verified by [unit tests](https://github.com/commaai/panda/tree/master/tests/safety) for each supported car variant. +* A recorded drive for each supported car variant is [replayed through the safety logic](https://github.com/commaai/panda/tree/master/tests/safety_replay) +to ensure that the behavior remains unchanged. +* An internal Hardware-in-the-loop test, which currently only runs on pull requests opened by comma.ai's organization members, verifies the following functionalities: + * compiling the code in various configuration and flashing it both through USB and WiFi. + * Receiving, sending and forwarding CAN messages on all buses, over USB and WiFi. + +In addition, we run [Pylint](https://www.pylint.org/) and [Flake8](https://github.com/PyCQA/flake8) linters on all python files within the panda repo. Hardware ------ diff --git a/panda/UPDATING.md b/panda/UPDATING.md index 100acc6bab5fbc..ab60f88ac81694 100644 --- a/panda/UPDATING.md +++ b/panda/UPDATING.md @@ -1,9 +1,9 @@ # Updating your panda -Panda should update automatically via the [Chffr](http://chffr.comma.ai/) app ([apple](https://itunes.apple.com/us/app/chffr-dash-cam-that-remembers/id1146683979) and [android](https://play.google.com/store/apps/details?id=ai.comma.chffr)) +Panda should update automatically via the [openpilot](http://openpilot.comma.ai/). -If it doesn't however, you can use the following commands on linux or Mac OSX - `sudo pip install --upgrade pandacan` -` PYTHONPATH="" sudo python -c "import panda; panda.flash_release()"` - -(You'll need to have `pip` and `sudo` installed.) +On Linux or Mac OSX, you can manually update it using: +``` +sudo pip install --upgrade pandacan` +PYTHONPATH="" sudo python -c "import panda; panda.flash_release()"` +``` diff --git a/panda/VERSION b/panda/VERSION index 0408c30b42460f..4279ff22f4fa77 100644 --- a/panda/VERSION +++ b/panda/VERSION @@ -1 +1 @@ -v1.2.0 \ No newline at end of file +v1.5.9 \ No newline at end of file diff --git a/panda/__init__.py b/panda/__init__.py index b802cf5a59582a..5374d5a9ab550a 100644 --- a/panda/__init__.py +++ b/panda/__init__.py @@ -1 +1 @@ -from .python import Panda, PandaWifiStreaming, PandaDFU, ESPROM, CesantaFlasher, flash_release, BASEDIR, ensure_st_up_to_date, build_st, PandaSerial +from .python import Panda, PandaWifiStreaming, PandaDFU, ESPROM, CesantaFlasher, flash_release, BASEDIR, ensure_st_up_to_date, build_st, PandaSerial # noqa: F401 diff --git a/panda/board/Makefile b/panda/board/Makefile index ed6dcaa0309fc8..adeba0479a85e9 100644 --- a/panda/board/Makefile +++ b/panda/board/Makefile @@ -1,5 +1,5 @@ PROJ_NAME = panda -CFLAGS = -g -Wall +CFLAGS = -g -Wall -Wextra -Wstrict-prototypes -Werror CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4 CFLAGS += -mhard-float -DSTM32F4 -DSTM32F413xx -mfpu=fpv4-sp-d16 -fsingle-precision-constant diff --git a/panda/board/Makefile.legacy b/panda/board/Makefile.legacy deleted file mode 100644 index f6f9f9f32822fc..00000000000000 --- a/panda/board/Makefile.legacy +++ /dev/null @@ -1,9 +0,0 @@ -# :set noet -PROJ_NAME = comma -CFLAGS = -g -Wall - -CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m3 -CFLAGS += -msoft-float -DSTM32F2 -DSTM32F205xx -STARTUP_FILE = startup_stm32f205xx - -include build.mk diff --git a/panda/board/README.md b/panda/board/README.md index b3be654be31ebe..7151bfbf93e32a 100644 --- a/panda/board/README.md +++ b/panda/board/README.md @@ -4,6 +4,7 @@ Dependencies **Mac** ``` +xcode-select --install ./get_sdk_mac.sh ``` @@ -23,12 +24,6 @@ Programming make ``` -**NEO** - -``` -make -f Makefile.legacy -``` - Troubleshooting ---- diff --git a/panda/board/board.h b/panda/board/board.h new file mode 100644 index 00000000000000..5629a841d3f5fd --- /dev/null +++ b/panda/board/board.h @@ -0,0 +1,92 @@ +// ///////////////////////////////////////////////////////////// // +// Hardware abstraction layer for all different supported boards // +// ///////////////////////////////////////////////////////////// // +#include "board_declarations.h" +#include "boards/common.h" + +// ///// Board definition and detection ///// // +#include "drivers/harness.h" +#ifdef PANDA + #include "drivers/fan.h" + #include "drivers/rtc.h" + #include "boards/white.h" + #include "boards/grey.h" + #include "boards/black.h" + #include "boards/uno.h" +#else + #include "boards/pedal.h" +#endif + +void detect_board_type(void) { + #ifdef PANDA + // SPI lines floating: white (TODO: is this reliable?) + if((detect_with_pull(GPIOA, 4, PULL_DOWN)) || (detect_with_pull(GPIOA, 5, PULL_DOWN)) || (detect_with_pull(GPIOA, 6, PULL_DOWN)) || (detect_with_pull(GPIOA, 7, PULL_DOWN))){ + hw_type = HW_TYPE_WHITE_PANDA; + current_board = &board_white; + } else if(detect_with_pull(GPIOA, 13, PULL_DOWN)) { // Rev AB deprecated, so no pullup means black. In REV C, A13 is pulled up to 5V with a 10K + hw_type = HW_TYPE_GREY_PANDA; + current_board = &board_grey; + } else if(!detect_with_pull(GPIOB, 15, PULL_UP)) { + hw_type = HW_TYPE_UNO; + current_board = &board_uno; + } else { + hw_type = HW_TYPE_BLACK_PANDA; + current_board = &board_black; + } + #else + #ifdef PEDAL + hw_type = HW_TYPE_PEDAL; + current_board = &board_pedal; + #else + hw_type = HW_TYPE_UNKNOWN; + puts("Hardware type is UNKNOWN!\n"); + #endif + #endif +} + + +// ///// Configuration detection ///// // +bool has_external_debug_serial = 0; +bool is_entering_bootmode = 0; + +void detect_configuration(void) { + // detect if external serial debugging is present + has_external_debug_serial = detect_with_pull(GPIOA, 3, PULL_DOWN); + + #ifdef PANDA + if(hw_type == HW_TYPE_WHITE_PANDA) { + // check if the ESP is trying to put me in boot mode + is_entering_bootmode = !detect_with_pull(GPIOB, 0, PULL_UP); + } else { + is_entering_bootmode = 0; + } + #else + is_entering_bootmode = 0; + #endif +} + +// ///// Board functions ///// // +// TODO: Make these config options in the board struct +bool board_has_gps(void) { + return ((hw_type == HW_TYPE_GREY_PANDA) || (hw_type == HW_TYPE_BLACK_PANDA) || (hw_type == HW_TYPE_UNO)); +} + +bool board_has_gmlan(void) { + return ((hw_type == HW_TYPE_WHITE_PANDA) || (hw_type == HW_TYPE_GREY_PANDA)); +} + +bool board_has_obd(void) { + return ((hw_type == HW_TYPE_BLACK_PANDA) || (hw_type == HW_TYPE_UNO)); +} + +bool board_has_lin(void) { + return ((hw_type == HW_TYPE_WHITE_PANDA) || (hw_type == HW_TYPE_GREY_PANDA)); +} + +bool board_has_rtc(void) { + return (hw_type == HW_TYPE_UNO); +} + +bool board_has_relay(void) { + return ((hw_type == HW_TYPE_BLACK_PANDA) || (hw_type == HW_TYPE_UNO)); +} diff --git a/panda/board/board_declarations.h b/panda/board/board_declarations.h new file mode 100644 index 00000000000000..2fd3976a0dac68 --- /dev/null +++ b/panda/board/board_declarations.h @@ -0,0 +1,72 @@ +// ******************** Prototypes ******************** +typedef void (*board_init)(void); +typedef void (*board_enable_can_transciever)(uint8_t transciever, bool enabled); +typedef void (*board_enable_can_transcievers)(bool enabled); +typedef void (*board_set_led)(uint8_t color, bool enabled); +typedef void (*board_set_usb_power_mode)(uint8_t mode); +typedef void (*board_set_esp_gps_mode)(uint8_t mode); +typedef void (*board_set_can_mode)(uint8_t mode); +typedef void (*board_usb_power_mode_tick)(uint64_t tcnt); +typedef bool (*board_check_ignition)(void); +typedef uint32_t (*board_read_current)(void); +typedef void (*board_set_ir_power)(uint8_t percentage); +typedef void (*board_set_fan_power)(uint8_t percentage); + +struct board { + const char *board_type; + const harness_configuration *harness_config; + board_init init; + board_enable_can_transciever enable_can_transciever; + board_enable_can_transcievers enable_can_transcievers; + board_set_led set_led; + board_set_usb_power_mode set_usb_power_mode; + board_set_esp_gps_mode set_esp_gps_mode; + board_set_can_mode set_can_mode; + board_usb_power_mode_tick usb_power_mode_tick; + board_check_ignition check_ignition; + board_read_current read_current; + board_set_ir_power set_ir_power; + board_set_fan_power set_fan_power; +}; + +// ******************* Definitions ******************** +// These should match the enums in cereal/log.capnp and __init__.py +#define HW_TYPE_UNKNOWN 0U +#define HW_TYPE_WHITE_PANDA 1U +#define HW_TYPE_GREY_PANDA 2U +#define HW_TYPE_BLACK_PANDA 3U +#define HW_TYPE_PEDAL 4U +#define HW_TYPE_UNO 5U + +// LED colors +#define LED_RED 0U +#define LED_GREEN 1U +#define LED_BLUE 2U + +// USB power modes (from cereal.log.health) +#define USB_POWER_NONE 0U +#define USB_POWER_CLIENT 1U +#define USB_POWER_CDP 2U +#define USB_POWER_DCP 3U + +// ESP modes +#define ESP_GPS_DISABLED 0U +#define ESP_GPS_ENABLED 1U +#define ESP_GPS_BOOTMODE 2U + +// CAN modes +#define CAN_MODE_NORMAL 0U +#define CAN_MODE_GMLAN_CAN2 1U +#define CAN_MODE_GMLAN_CAN3 2U +#define CAN_MODE_OBD_CAN2 3U + +// ********************* Globals ********************** +uint8_t usb_power_mode = USB_POWER_NONE; + +// ************ Board function prototypes ************* +bool board_has_gps(void); +bool board_has_gmlan(void); +bool board_has_obd(void); +bool board_has_lin(void); +bool board_has_rtc(void); +bool board_has_relay(void); \ No newline at end of file diff --git a/panda/board/boards/black.h b/panda/board/boards/black.h new file mode 100644 index 00000000000000..f033e82b23ed34 --- /dev/null +++ b/panda/board/boards/black.h @@ -0,0 +1,231 @@ +// ///////////////////// // +// Black Panda + Harness // +// ///////////////////// // + +void black_enable_can_transciever(uint8_t transciever, bool enabled) { + switch (transciever){ + case 1U: + set_gpio_output(GPIOC, 1, !enabled); + break; + case 2U: + set_gpio_output(GPIOC, 13, !enabled); + break; + case 3U: + set_gpio_output(GPIOA, 0, !enabled); + break; + case 4U: + set_gpio_output(GPIOB, 10, !enabled); + break; + default: + puts("Invalid CAN transciever ("); puth(transciever); puts("): enabling failed\n"); + break; + } +} + +void black_enable_can_transcievers(bool enabled) { + uint8_t t1 = enabled ? 1U : 2U; // leave transciever 1 enabled to detect CAN ignition + for(uint8_t i=t1; i<=4U; i++) { + black_enable_can_transciever(i, enabled); + } +} + +void black_set_led(uint8_t color, bool enabled) { + switch (color){ + case LED_RED: + set_gpio_output(GPIOC, 9, !enabled); + break; + case LED_GREEN: + set_gpio_output(GPIOC, 7, !enabled); + break; + case LED_BLUE: + set_gpio_output(GPIOC, 6, !enabled); + break; + default: + break; + } +} + +void black_set_gps_load_switch(bool enabled) { + set_gpio_output(GPIOC, 12, enabled); +} + +void black_set_usb_load_switch(bool enabled) { + set_gpio_output(GPIOB, 1, !enabled); +} + +void black_set_usb_power_mode(uint8_t mode) { + bool valid = false; + switch (mode) { + case USB_POWER_CLIENT: + black_set_usb_load_switch(false); + valid = true; + break; + case USB_POWER_CDP: + black_set_usb_load_switch(true); + valid = true; + break; + default: + puts("Invalid USB power mode\n"); + break; + } + if (valid) { + usb_power_mode = mode; + } +} + +void black_set_esp_gps_mode(uint8_t mode) { + switch (mode) { + case ESP_GPS_DISABLED: + // GPS OFF + set_gpio_output(GPIOC, 14, 0); + set_gpio_output(GPIOC, 5, 0); + break; + case ESP_GPS_ENABLED: + // GPS ON + set_gpio_output(GPIOC, 14, 1); + set_gpio_output(GPIOC, 5, 1); + break; + case ESP_GPS_BOOTMODE: + set_gpio_output(GPIOC, 14, 1); + set_gpio_output(GPIOC, 5, 0); + break; + default: + puts("Invalid ESP/GPS mode\n"); + break; + } +} + +void black_set_can_mode(uint8_t mode){ + switch (mode) { + case CAN_MODE_NORMAL: + case CAN_MODE_OBD_CAN2: + if ((bool)(mode == CAN_MODE_NORMAL) != (bool)(car_harness_status == HARNESS_STATUS_NORMAL)) { + // B12,B13: disable OBD mode + set_gpio_mode(GPIOB, 12, MODE_INPUT); + set_gpio_mode(GPIOB, 13, MODE_INPUT); + + // B5,B6: normal CAN2 mode + set_gpio_alternate(GPIOB, 5, GPIO_AF9_CAN2); + set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2); + } else { + // B5,B6: disable normal CAN2 mode + set_gpio_mode(GPIOB, 5, MODE_INPUT); + set_gpio_mode(GPIOB, 6, MODE_INPUT); + + // B12,B13: OBD mode + set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2); + set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2); + } + break; + default: + puts("Tried to set unsupported CAN mode: "); puth(mode); puts("\n"); + break; + } +} + +void black_usb_power_mode_tick(uint64_t tcnt){ + UNUSED(tcnt); + // Not applicable +} + +bool black_check_ignition(void){ + // ignition is checked through harness + return harness_check_ignition(); +} + +uint32_t black_read_current(void){ + // No current sense on black panda + return 0U; +} + +void black_set_ir_power(uint8_t percentage){ + UNUSED(percentage); +} + +void black_set_fan_power(uint8_t percentage){ + UNUSED(percentage); +} + +void black_init(void) { + common_init_gpio(); + + // A8,A15: normal CAN3 mode + set_gpio_alternate(GPIOA, 8, GPIO_AF11_CAN3); + set_gpio_alternate(GPIOA, 15, GPIO_AF11_CAN3); + + // C0: OBD_SBU1 (orientation detection) + // C3: OBD_SBU2 (orientation detection) + set_gpio_mode(GPIOC, 0, MODE_ANALOG); + set_gpio_mode(GPIOC, 3, MODE_ANALOG); + + // C10: OBD_SBU1_RELAY (harness relay driving output) + // C11: OBD_SBU2_RELAY (harness relay driving output) + set_gpio_mode(GPIOC, 10, MODE_OUTPUT); + set_gpio_mode(GPIOC, 11, MODE_OUTPUT); + set_gpio_output_type(GPIOC, 10, OUTPUT_TYPE_OPEN_DRAIN); + set_gpio_output_type(GPIOC, 11, OUTPUT_TYPE_OPEN_DRAIN); + set_gpio_output(GPIOC, 10, 1); + set_gpio_output(GPIOC, 11, 1); + + // Turn on GPS load switch. + black_set_gps_load_switch(true); + + // Turn on USB load switch. + black_set_usb_load_switch(true); + + // Set right power mode + black_set_usb_power_mode(USB_POWER_CDP); + + // Initialize harness + harness_init(); + + // Enable CAN transcievers + black_enable_can_transcievers(true); + + // Disable LEDs + black_set_led(LED_RED, false); + black_set_led(LED_GREEN, false); + black_set_led(LED_BLUE, false); + + // Set normal CAN mode + black_set_can_mode(CAN_MODE_NORMAL); + + // flip CAN0 and CAN2 if we are flipped + if (car_harness_status == HARNESS_STATUS_NORMAL) { + can_flip_buses(0, 2); + } + + // init multiplexer + can_set_obd(car_harness_status, false); +} + +const harness_configuration black_harness_config = { + .has_harness = true, + .GPIO_SBU1 = GPIOC, + .GPIO_SBU2 = GPIOC, + .GPIO_relay_normal = GPIOC, + .GPIO_relay_flipped = GPIOC, + .pin_SBU1 = 0, + .pin_SBU2 = 3, + .pin_relay_normal = 10, + .pin_relay_flipped = 11, + .adc_channel_SBU1 = 10, + .adc_channel_SBU2 = 13 +}; + +const board board_black = { + .board_type = "Black", + .harness_config = &black_harness_config, + .init = black_init, + .enable_can_transciever = black_enable_can_transciever, + .enable_can_transcievers = black_enable_can_transcievers, + .set_led = black_set_led, + .set_usb_power_mode = black_set_usb_power_mode, + .set_esp_gps_mode = black_set_esp_gps_mode, + .set_can_mode = black_set_can_mode, + .usb_power_mode_tick = black_usb_power_mode_tick, + .check_ignition = black_check_ignition, + .read_current = black_read_current, + .set_fan_power = black_set_fan_power, + .set_ir_power = black_set_ir_power +}; diff --git a/panda/board/boards/common.h b/panda/board/boards/common.h new file mode 100644 index 00000000000000..e33b2a2f0426c4 --- /dev/null +++ b/panda/board/boards/common.h @@ -0,0 +1,84 @@ +#ifdef STM32F4 + #include "stm32f4xx_hal_gpio_ex.h" +#else + #include "stm32f2xx_hal_gpio_ex.h" +#endif + +// Common GPIO initialization +void common_init_gpio(void){ + // TODO: Is this block actually doing something??? + // pull low to hold ESP in reset?? + // enable OTG out tied to ground + GPIOA->ODR = 0; + GPIOB->ODR = 0; + GPIOA->PUPDR = 0; + GPIOB->AFR[0] = 0; + GPIOB->AFR[1] = 0; + + // C2: Voltage sense line + set_gpio_mode(GPIOC, 2, MODE_ANALOG); + + // A11,A12: USB + set_gpio_alternate(GPIOA, 11, GPIO_AF10_OTG_FS); + set_gpio_alternate(GPIOA, 12, GPIO_AF10_OTG_FS); + GPIOA->OSPEEDR = GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12; + + // A9,A10: USART 1 for talking to the ESP / GPS + set_gpio_alternate(GPIOA, 9, GPIO_AF7_USART1); + set_gpio_alternate(GPIOA, 10, GPIO_AF7_USART1); + + // B8,B9: CAN 1 + #ifdef STM32F4 + set_gpio_alternate(GPIOB, 8, GPIO_AF8_CAN1); + set_gpio_alternate(GPIOB, 9, GPIO_AF8_CAN1); + #else + set_gpio_alternate(GPIOB, 8, GPIO_AF9_CAN1); + set_gpio_alternate(GPIOB, 9, GPIO_AF9_CAN1); + #endif +} + +// Peripheral initialization +void peripherals_init(void){ + // enable GPIOB, UART2, CAN, USB clock + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; + RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; + + RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; + RCC->APB1ENR |= RCC_APB1ENR_USART2EN; + RCC->APB1ENR |= RCC_APB1ENR_USART3EN; + #ifdef PANDA + RCC->APB1ENR |= RCC_APB1ENR_UART5EN; + #endif + RCC->APB1ENR |= RCC_APB1ENR_CAN1EN; + RCC->APB1ENR |= RCC_APB1ENR_CAN2EN; + #ifdef CAN3 + RCC->APB1ENR |= RCC_APB1ENR_CAN3EN; + #endif + RCC->APB1ENR |= RCC_APB1ENR_DACEN; + RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // main counter + RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // pedal and fan PWM + RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; // gmlan_alt and IR PWM + //RCC->APB1ENR |= RCC_APB1ENR_TIM5EN; + //RCC->APB1ENR |= RCC_APB1ENR_TIM6EN; + RCC->APB1ENR |= RCC_APB1ENR_PWREN; // for RTC config + RCC->APB2ENR |= RCC_APB2ENR_USART1EN; + RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN; + //RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; + RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; + RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; + RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; + RCC->APB2ENR |= RCC_APB2ENR_TIM9EN; // slow loop +} + +// Detection with internal pullup +#define PULL_EFFECTIVE_DELAY 10 +bool detect_with_pull(GPIO_TypeDef *GPIO, int pin, int mode) { + set_gpio_mode(GPIO, pin, MODE_INPUT); + set_gpio_pullup(GPIO, pin, mode); + for (volatile int i=0; i= CLICKS) { + if (!is_enumerated) { + puts("USBP: didn't enumerate, switching to CDP mode\n"); + // switch to CDP + white_set_usb_power_mode(USB_POWER_CDP); + marker = tcnt; + } + } + // keep resetting the timer if it's enumerated + if (is_enumerated) { + marker = tcnt; + } + break; + case USB_POWER_CDP: + // been CLICKS clicks since we switched to CDP + if ((tcnt-marker) >= CLICKS) { + // measure current draw, if positive and no enumeration, switch to DCP + if (!is_enumerated && (current < CURRENT_THRESHOLD)) { + puts("USBP: no enumeration with current draw, switching to DCP mode\n"); + white_set_usb_power_mode(USB_POWER_DCP); + marker = tcnt; + } + } + // keep resetting the timer if there's no current draw in CDP + if (current >= CURRENT_THRESHOLD) { + marker = tcnt; + } + break; + case USB_POWER_DCP: + // been at least CLICKS clicks since we switched to DCP + if ((tcnt-marker) >= CLICKS) { + // if no current draw, switch back to CDP + if (current >= CURRENT_THRESHOLD) { + puts("USBP: no current draw, switching back to CDP mode\n"); + white_set_usb_power_mode(USB_POWER_CDP); + marker = tcnt; + } + } + // keep resetting the timer if there's current draw in DCP + if (current < CURRENT_THRESHOLD) { + marker = tcnt; + } + break; + default: + puts("USB power mode invalid\n"); // set_usb_power_mode prevents assigning invalid values + break; + } +#else + UNUSED(tcnt); +#endif +} + +void white_set_ir_power(uint8_t percentage){ + UNUSED(percentage); +} + +void white_set_fan_power(uint8_t percentage){ + UNUSED(percentage); +} + +bool white_check_ignition(void){ + // ignition is on PA1 + return !get_gpio_input(GPIOA, 1); +} + +void white_init(void) { + common_init_gpio(); + + // C3: current sense + set_gpio_mode(GPIOC, 3, MODE_ANALOG); + + // A1: started_alt + set_gpio_pullup(GPIOA, 1, PULL_UP); + + // A2, A3: USART 2 for debugging + set_gpio_alternate(GPIOA, 2, GPIO_AF7_USART2); + set_gpio_alternate(GPIOA, 3, GPIO_AF7_USART2); + + // A4, A5, A6, A7: SPI + set_gpio_alternate(GPIOA, 4, GPIO_AF5_SPI1); + set_gpio_alternate(GPIOA, 5, GPIO_AF5_SPI1); + set_gpio_alternate(GPIOA, 6, GPIO_AF5_SPI1); + set_gpio_alternate(GPIOA, 7, GPIO_AF5_SPI1); + + // B12: GMLAN, ignition sense, pull up + set_gpio_pullup(GPIOB, 12, PULL_UP); + + /* GMLAN mode pins: + M0(B15) M1(B14) mode + ======================= + 0 0 sleep + 1 0 100kbit + 0 1 high voltage wakeup + 1 1 33kbit (normal) + */ + set_gpio_output(GPIOB, 14, 1); + set_gpio_output(GPIOB, 15, 1); + + // B7: K-line enable + set_gpio_output(GPIOB, 7, 1); + + // C12, D2: Setup K-line (UART5) + set_gpio_alternate(GPIOC, 12, GPIO_AF8_UART5); + set_gpio_alternate(GPIOD, 2, GPIO_AF8_UART5); + set_gpio_pullup(GPIOD, 2, PULL_UP); + + // L-line enable + set_gpio_output(GPIOA, 14, 1); + + // C10, C11: L-Line setup (USART3) + set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3); + set_gpio_alternate(GPIOC, 11, GPIO_AF7_USART3); + set_gpio_pullup(GPIOC, 11, PULL_UP); + + // Enable CAN transcievers + white_enable_can_transcievers(true); + + // Disable LEDs + white_set_led(LED_RED, false); + white_set_led(LED_GREEN, false); + white_set_led(LED_BLUE, false); + + // Set normal CAN mode + white_set_can_mode(CAN_MODE_NORMAL); + + // Setup ignition interrupts + SYSCFG->EXTICR[1] = SYSCFG_EXTICR1_EXTI1_PA; + EXTI->IMR |= (1U << 1); + EXTI->RTSR |= (1U << 1); + EXTI->FTSR |= (1U << 1); + NVIC_EnableIRQ(EXTI1_IRQn); + + // Init usb power mode + uint32_t voltage = adc_get_voltage(); + // Init in CDP mode only if panda is powered by 12V. + // Otherwise a PC would not be able to flash a standalone panda with EON build + if (voltage > 8000U) { // 8V threshold + white_set_usb_power_mode(USB_POWER_CDP); + } else { + white_set_usb_power_mode(USB_POWER_CLIENT); + } +} + +const harness_configuration white_harness_config = { + .has_harness = false +}; + +const board board_white = { + .board_type = "White", + .harness_config = &white_harness_config, + .init = white_init, + .enable_can_transciever = white_enable_can_transciever, + .enable_can_transcievers = white_enable_can_transcievers, + .set_led = white_set_led, + .set_usb_power_mode = white_set_usb_power_mode, + .set_esp_gps_mode = white_set_esp_gps_mode, + .set_can_mode = white_set_can_mode, + .usb_power_mode_tick = white_usb_power_mode_tick, + .check_ignition = white_check_ignition, + .read_current = white_read_current, + .set_fan_power = white_set_fan_power, + .set_ir_power = white_set_ir_power +}; diff --git a/panda/board/bootstub.c b/panda/board/bootstub.c index e44986c29ec47c..8ada20c7383224 100644 --- a/panda/board/bootstub.c +++ b/panda/board/bootstub.c @@ -12,27 +12,37 @@ #include "stm32f2xx_hal_gpio_ex.h" #endif +// ******************** Prototypes ******************** +void puts(const char *a){ UNUSED(a); } +void puth(unsigned int i){ UNUSED(i); } +void puth2(unsigned int i){ UNUSED(i); } +typedef struct board board; +typedef struct harness_configuration harness_configuration; +// No CAN support on bootloader +void can_flip_buses(uint8_t bus1, uint8_t bus2){UNUSED(bus1); UNUSED(bus2);} +void can_set_obd(int harness_orientation, bool obd){UNUSED(harness_orientation); UNUSED(obd);} + +// ********************* Globals ********************** +int hw_type = 0; +const board *current_board; + +// ********************* Includes ********************* #include "libc.h" #include "provision.h" -#include "drivers/drivers.h" - +#include "drivers/clock.h" #include "drivers/llgpio.h" +#include "drivers/adc.h" +#include "drivers/pwm.h" + +#include "board.h" + #include "gpio.h" #include "drivers/spi.h" #include "drivers/usb.h" //#include "drivers/uart.h" -#ifdef PEDAL -#define CUSTOM_CAN_INTERRUPTS -#include "safety.h" -#include "drivers/can.h" -#endif - -int puts(const char *a) { return 0; } -void puth(unsigned int i) {} - #include "crypto/rsa.h" #include "crypto/sha.h" @@ -40,11 +50,11 @@ void puth(unsigned int i) {} #include "spi_flasher.h" -void __initialize_hardware_early() { +void __initialize_hardware_early(void) { early(); } -void fail() { +void fail(void) { soft_flasher_start(); } @@ -54,14 +64,11 @@ extern void *_app_start[]; // FIXME: sometimes your panda will fail flashing and will quickly blink a single Green LED // BOUNTY: $200 coupon on shop.comma.ai or $100 check. -int main() { - __disable_irq(); +int main(void) { + disable_interrupts(); clock_init(); - detect(); - - if (revision == PANDA_REV_C) { - set_usb_power_mode(USB_POWER_CLIENT); - } + detect_configuration(); + detect_board_type(); if (enter_bootloader_mode == ENTER_SOFTLOADER_MAGIC) { enter_bootloader_mode = 0; @@ -94,7 +101,7 @@ int main() { return 0; good: // jump to flash - ((void(*)()) _app_start[1])(); + ((void(*)(void)) _app_start[1])(); return 0; } diff --git a/panda/board/build.mk b/panda/board/build.mk index a84ed3fd9d9193..acac03095b334d 100644 --- a/panda/board/build.mk +++ b/panda/board/build.mk @@ -2,12 +2,15 @@ CFLAGS += -I inc -I ../ -nostdlib -fno-builtin -std=gnu11 -Os CFLAGS += -Tstm32_flash.ld +DFU_UTIL = "dfu-util" + # Compile fast charge (DCP) only not on EON ifeq (,$(wildcard /EON)) BUILDER = DEV else CFLAGS += "-DEON" BUILDER = EON + DFU_UTIL = "tools/dfu-util-aarch64" endif CC = arm-none-eabi-gcc @@ -22,7 +25,11 @@ else CFLAGS += "-DALLOW_DEBUG" endif -DFU_UTIL = "dfu-util" + +DEPDIR = generated_dependencies +$(shell mkdir -p -m 777 $(DEPDIR) >/dev/null) +DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td +POSTCOMPILE = @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $@ # this no longer pushes the bootstub flash: obj/$(PROJ_NAME).bin @@ -45,8 +52,9 @@ include ../common/version.mk obj/cert.h: ../crypto/getcertheader.py ../crypto/getcertheader.py ../certs/debug.pub ../certs/release.pub > $@ -obj/%.$(PROJ_NAME).o: %.c obj/cert.h obj/gitversion.h config.h drivers/*.h gpio.h libc.h provision.h safety.h safety/*.h spi_flasher.h - $(CC) $(CFLAGS) -o $@ -c $< +obj/%.$(PROJ_NAME).o: %.c obj/gitversion.h obj/cert.h $(DEPDIR)/%.d + $(CC) $(DEPFLAGS) $(CFLAGS) -o $@ -c $< + $(POSTCOMPILE) obj/%.$(PROJ_NAME).o: ../crypto/%.c $(CC) $(CFLAGS) -o $@ -c $< @@ -59,12 +67,18 @@ obj/$(PROJ_NAME).bin: obj/$(STARTUP_FILE).o obj/main.$(PROJ_NAME).o $(CC) -Wl,--section-start,.isr_vector=0x8004000 $(CFLAGS) -o obj/$(PROJ_NAME).elf $^ $(OBJCOPY) -v -O binary obj/$(PROJ_NAME).elf obj/code.bin SETLEN=1 ../crypto/sign.py obj/code.bin $@ $(CERT) - @BINSIZE=$$(du -b "obj/$(PROJ_NAME).bin" | cut -f 1) ; if [ $$BINSIZE -ge 32768 ]; then echo "ERROR obj/$(PROJ_NAME).bin is too big!"; exit 1; fi; - + @BINSIZE=$$(du -b "obj/$(PROJ_NAME).bin" | cut -f 1) ; \ + if [ $$BINSIZE -ge 49152 ]; then echo "ERROR obj/$(PROJ_NAME).bin is too big!"; exit 1; fi; obj/bootstub.$(PROJ_NAME).bin: obj/$(STARTUP_FILE).o obj/bootstub.$(PROJ_NAME).o obj/sha.$(PROJ_NAME).o obj/rsa.$(PROJ_NAME).o $(CC) $(CFLAGS) -o obj/bootstub.$(PROJ_NAME).elf $^ $(OBJCOPY) -v -O binary obj/bootstub.$(PROJ_NAME).elf $@ +$(DEPDIR)/%.d: ; +.PRECIOUS: $(DEPDIR)/%.d + +include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(wildcard *.c)))) + clean: - @rm -f obj/* + @$(RM) obj/* + @rm -rf $(DEPDIR) diff --git a/panda/board/config.h b/panda/board/config.h index e83429980d4163..c2eb412e960903 100644 --- a/panda/board/config.h +++ b/panda/board/config.h @@ -2,6 +2,7 @@ #define PANDA_CONFIG_H //#define DEBUG +//#define DEBUG_UART //#define DEBUG_USB //#define DEBUG_SPI @@ -12,29 +13,29 @@ #include "stm32f2xx.h" #endif -#define USB_VID 0xbbaa +#define USB_VID 0xbbaaU #ifdef BOOTSTUB -#define USB_PID 0xddee +#define USB_PID 0xddeeU #else -#define USB_PID 0xddcc +#define USB_PID 0xddccU #endif #include #define NULL ((void*)0) -#define COMPILE_TIME_ASSERT(pred) switch(0){case 0:case pred:;} +#define COMPILE_TIME_ASSERT(pred) ((void)sizeof(char[1 - (2 * ((int)(!(pred))))])) -#define min(a,b) \ +#define MIN(a,b) \ ({ __typeof__ (a) _a = (a); \ __typeof__ (b) _b = (b); \ - _a < _b ? _a : _b; }) + (_a < _b) ? _a : _b; }) -#define max(a,b) \ +#define MAX(a,b) \ ({ __typeof__ (a) _a = (a); \ __typeof__ (b) _b = (b); \ - _a > _b ? _a : _b; }) + (_a > _b) ? _a : _b; }) -#define MAX_RESP_LEN 0x40 +#define MAX_RESP_LEN 0x40U #endif diff --git a/panda/board/drivers/adc.h b/panda/board/drivers/adc.h index cb2aeede03958a..2a91fef8dcd64e 100644 --- a/panda/board/drivers/adc.h +++ b/panda/board/drivers/adc.h @@ -8,7 +8,7 @@ #define ADCCHAN_VOLTAGE 12 #define ADCCHAN_CURRENT 13 -void adc_init() { +void adc_init(void) { // global setup ADC->CCR = ADC_CCR_TSVREFE | ADC_CCR_VBATE; //ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_EOCS | ADC_CR2_DDS; @@ -19,7 +19,7 @@ void adc_init() { ADC1->SMPR1 = ADC_SMPR1_SMP12 | ADC_SMPR1_SMP13; } -uint32_t adc_get(int channel) { +uint32_t adc_get(unsigned int channel) { // includes length //ADC1->SQR1 = 0; @@ -36,3 +36,13 @@ uint32_t adc_get(int channel) { return ADC1->JDR1; } +uint32_t adc_get_voltage(void) { + // REVC has a 10, 1 (1/11) voltage divider + // Here is the calculation for the scale (s) + // ADCV = VIN_S * (1/11) * (4095/3.3) + // RETVAL = ADCV * s = VIN_S*1000 + // s = 1000/((4095/3.3)*(1/11)) = 8.8623046875 + + // Avoid needing floating point math, so output in mV + return (adc_get(ADCCHAN_VOLTAGE) * 8862U) / 1000U; +} diff --git a/panda/board/drivers/can.h b/panda/board/drivers/can.h index b837094c9a0d38..c9bf2d25436b35 100644 --- a/panda/board/drivers/can.h +++ b/panda/board/drivers/can.h @@ -1,6 +1,41 @@ -// IRQs: CAN1_TX, CAN1_RX0, CAN1_SCE, CAN2_TX, CAN2_RX0, CAN2_SCE, CAN3_TX, CAN3_RX0, CAN3_SCE +// IRQs: CAN1_TX, CAN1_RX0, CAN1_SCE +// CAN2_TX, CAN2_RX0, CAN2_SCE +// CAN3_TX, CAN3_RX0, CAN3_SCE + +typedef struct { + volatile uint32_t w_ptr; + volatile uint32_t r_ptr; + uint32_t fifo_size; + CAN_FIFOMailBox_TypeDef *elems; +} can_ring; + +#define CAN_BUS_RET_FLAG 0x80U +#define CAN_BUS_NUM_MASK 0x7FU + +#define BUS_MAX 4U + +uint32_t can_send_errs = 0; +uint32_t can_fwd_errs = 0; +uint32_t gmlan_send_errs = 0; +extern int can_live, pending_can_live; + +// must reinit after changing these +extern int can_loopback, can_silent; +extern uint32_t can_speed[4]; + +void can_set_forwarding(int from, int to); + +void can_init(uint8_t can_number); +void can_init_all(void); +void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number); +bool can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem); + +// Ignition detected from CAN meessages +bool ignition_can = false; + +// end API + #define ALL_CAN_SILENT 0xFF -#define ALL_CAN_BUT_MAIN_SILENT 0xFE #define ALL_CAN_LIVE 0 int can_live = 0, pending_can_live = 0, can_loopback = 0, can_silent = ALL_CAN_SILENT; @@ -14,54 +49,67 @@ int can_live = 0, pending_can_live = 0, can_loopback = 0, can_silent = ALL_CAN_S can_buffer(rx_q, 0x1000) can_buffer(tx1_q, 0x100) can_buffer(tx2_q, 0x100) +can_buffer(tx3_q, 0x100) +can_buffer(txgmlan_q, 0x100) +can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q, &can_tx3_q, &can_txgmlan_q}; -#ifdef PANDA - can_buffer(tx3_q, 0x100) - can_buffer(txgmlan_q, 0x100) - can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q, &can_tx3_q, &can_txgmlan_q}; -#else - can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q}; -#endif +// global CAN stats +int can_rx_cnt = 0; +int can_tx_cnt = 0; +int can_txd_cnt = 0; +int can_err_cnt = 0; +int can_overflow_cnt = 0; // ********************* interrupt safe queue ********************* -int can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) { - int ret = 0; +bool can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) { + bool ret = 0; - enter_critical_section(); + ENTER_CRITICAL(); if (q->w_ptr != q->r_ptr) { *elem = q->elems[q->r_ptr]; - if ((q->r_ptr + 1) == q->fifo_size) q->r_ptr = 0; - else q->r_ptr += 1; + if ((q->r_ptr + 1U) == q->fifo_size) { + q->r_ptr = 0; + } else { + q->r_ptr += 1U; + } ret = 1; } - exit_critical_section(); + EXIT_CRITICAL(); return ret; } -int can_push(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) { - int ret = 0; +bool can_push(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) { + bool ret = false; uint32_t next_w_ptr; - enter_critical_section(); - if ((q->w_ptr + 1) == q->fifo_size) next_w_ptr = 0; - else next_w_ptr = q->w_ptr + 1; + ENTER_CRITICAL(); + if ((q->w_ptr + 1U) == q->fifo_size) { + next_w_ptr = 0; + } else { + next_w_ptr = q->w_ptr + 1U; + } if (next_w_ptr != q->r_ptr) { q->elems[q->w_ptr] = *elem; q->w_ptr = next_w_ptr; - ret = 1; + ret = true; + } + EXIT_CRITICAL(); + if (!ret) { + can_overflow_cnt++; + #ifdef DEBUG + puts("can_push failed!\n"); + #endif } - exit_critical_section(); - if (ret == 0) puts("can_push failed!\n"); return ret; } void can_clear(can_ring *q) { - enter_critical_section(); + ENTER_CRITICAL(); q->w_ptr = 0; q->r_ptr = 0; - exit_critical_section(); + EXIT_CRITICAL(); } // assign CAN numbering @@ -73,227 +121,139 @@ void can_clear(can_ring *q) { // can_num_lookup: Translates from 'bus number' to 'can number'. // can_forwarding: Given a bus num, lookup bus num to forward to. -1 means no forward. -int can_rx_cnt = 0; -int can_tx_cnt = 0; -int can_txd_cnt = 0; -int can_err_cnt = 0; - -// NEO: Bus 1=CAN1 Bus 2=CAN2 // Panda: Bus 0=CAN1 Bus 1=CAN2 Bus 2=CAN3 -#ifdef PANDA - CAN_TypeDef *cans[] = {CAN1, CAN2, CAN3}; - uint8_t bus_lookup[] = {0,1,2}; - uint8_t can_num_lookup[] = {0,1,2,-1}; - int8_t can_forwarding[] = {-1,-1,-1,-1}; - uint32_t can_speed[] = {5000, 5000, 5000, 333}; - bool can_autobaud_enabled[] = {false, false, false, false}; - #define CAN_MAX 3 -#else - CAN_TypeDef *cans[] = {CAN1, CAN2}; - uint8_t bus_lookup[] = {1,0}; - uint8_t can_num_lookup[] = {1,0}; - int8_t can_forwarding[] = {-1,-1}; - uint32_t can_speed[] = {5000, 5000}; - bool can_autobaud_enabled[] = {false, false}; - #define CAN_MAX 2 -#endif - -uint32_t can_autobaud_speeds[] = {5000, 2500, 1250, 1000, 10000}; -#define AUTOBAUD_SPEEDS_LEN (sizeof(can_autobaud_speeds) / sizeof(can_autobaud_speeds[0])) +CAN_TypeDef *cans[] = {CAN1, CAN2, CAN3}; +uint8_t bus_lookup[] = {0,1,2}; +uint8_t can_num_lookup[] = {0,1,2,-1}; +int8_t can_forwarding[] = {-1,-1,-1,-1}; +uint32_t can_speed[] = {5000, 5000, 5000, 333}; +#define CAN_MAX 3U #define CANIF_FROM_CAN_NUM(num) (cans[num]) -#ifdef PANDA -#define CAN_NUM_FROM_CANIF(CAN) (CAN==CAN1 ? 0 : (CAN==CAN2 ? 1 : 2)) -#define CAN_NAME_FROM_CANIF(CAN) (CAN==CAN1 ? "CAN1" : (CAN==CAN2 ? "CAN2" : "CAN3")) -#else -#define CAN_NUM_FROM_CANIF(CAN) (CAN==CAN1 ? 0 : 1) -#define CAN_NAME_FROM_CANIF(CAN) (CAN==CAN1 ? "CAN1" : "CAN2") -#endif +#define CAN_NUM_FROM_CANIF(CAN) ((CAN)==CAN1 ? 0 : ((CAN) == CAN2 ? 1 : 2)) +#define CAN_NAME_FROM_CANIF(CAN) ((CAN)==CAN1 ? "CAN1" : ((CAN) == CAN2 ? "CAN2" : "CAN3")) #define BUS_NUM_FROM_CAN_NUM(num) (bus_lookup[num]) #define CAN_NUM_FROM_BUS_NUM(num) (can_num_lookup[num]) -// other option -/*#define CAN_QUANTA 16 -#define CAN_SEQ1 13 -#define CAN_SEQ2 2*/ - -// this is needed for 1 mbps support -#define CAN_QUANTA 8 -#define CAN_SEQ1 6 // roundf(quanta * 0.875f) - 1; -#define CAN_SEQ2 1 // roundf(quanta * 0.125f); - -#define CAN_PCLK 24000 -// 333 = 33.3 kbps -// 5000 = 500 kbps -#define can_speed_to_prescaler(x) (CAN_PCLK / CAN_QUANTA * 10 / (x)) - -void can_autobaud_speed_increment(uint8_t can_number) { - uint32_t autobaud_speed = can_autobaud_speeds[0]; - uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number); - for (int i = 0; i < AUTOBAUD_SPEEDS_LEN; i++) { - if (can_speed[bus_number] == can_autobaud_speeds[i]) { - if (i+1 < AUTOBAUD_SPEEDS_LEN) { - autobaud_speed = can_autobaud_speeds[i+1]; - } - break; - } - } - can_speed[bus_number] = autobaud_speed; -#ifdef DEBUG - CAN_TypeDef* CAN = CANIF_FROM_CAN_NUM(can_number); - puts(CAN_NAME_FROM_CANIF(CAN)); - puts(" auto-baud test "); - putui(can_speed[bus_number]); - puts(" cbps\n"); -#endif -} - void process_can(uint8_t can_number); void can_set_speed(uint8_t can_number) { CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number); uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number); - while (true) { - // initialization mode - CAN->MCR = CAN_MCR_TTCM | CAN_MCR_INRQ; - while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK); - - // set time quanta from defines - CAN->BTR = (CAN_BTR_TS1_0 * (CAN_SEQ1-1)) | - (CAN_BTR_TS2_0 * (CAN_SEQ2-1)) | - (can_speed_to_prescaler(can_speed[bus_number]) - 1); - - // silent loopback mode for debugging - if (can_loopback) { - CAN->BTR |= CAN_BTR_SILM | CAN_BTR_LBKM; - } - if (can_silent & (1 << can_number)) { - CAN->BTR |= CAN_BTR_SILM; - } - - // reset - CAN->MCR = CAN_MCR_TTCM | CAN_MCR_ABOM; - - #define CAN_TIMEOUT 1000000 - int tmp = 0; - while((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK && tmp < CAN_TIMEOUT) tmp++; - if (tmp < CAN_TIMEOUT) { - return; - } - - if (can_autobaud_enabled[bus_number]) { - can_autobaud_speed_increment(can_number); - } else { - puts("CAN init FAILED!!!!!\n"); - puth(can_number); puts(" "); - puth(BUS_NUM_FROM_CAN_NUM(can_number)); puts("\n"); - return; - } + if (!llcan_set_speed(CAN, can_speed[bus_number], can_loopback, (unsigned int)(can_silent) & (1U << can_number))) { + puts("CAN init FAILED!!!!!\n"); + puth(can_number); puts(" "); + puth(BUS_NUM_FROM_CAN_NUM(can_number)); puts("\n"); } } void can_init(uint8_t can_number) { - if (can_number == 0xff) return; + if (can_number != 0xffU) { + CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number); + can_set_speed(can_number); - CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number); - set_can_enable(CAN, 1); - can_set_speed(can_number); - - // accept all filter - CAN->FMR |= CAN_FMR_FINIT; - - // no mask - CAN->sFilterRegister[0].FR1 = 0; - CAN->sFilterRegister[0].FR2 = 0; - CAN->sFilterRegister[14].FR1 = 0; - CAN->sFilterRegister[14].FR2 = 0; - CAN->FA1R |= 1 | (1 << 14); - - CAN->FMR &= ~(CAN_FMR_FINIT); - - // enable certain CAN interrupts - CAN->IER |= CAN_IER_TMEIE | CAN_IER_FMPIE0; - - switch (can_number) { - case 0: - NVIC_EnableIRQ(CAN1_TX_IRQn); - NVIC_EnableIRQ(CAN1_RX0_IRQn); - NVIC_EnableIRQ(CAN1_SCE_IRQn); - break; - case 1: - NVIC_EnableIRQ(CAN2_TX_IRQn); - NVIC_EnableIRQ(CAN2_RX0_IRQn); - NVIC_EnableIRQ(CAN2_SCE_IRQn); - break; -#ifdef CAN3 - case 2: - NVIC_EnableIRQ(CAN3_TX_IRQn); - NVIC_EnableIRQ(CAN3_RX0_IRQn); - NVIC_EnableIRQ(CAN3_SCE_IRQn); - break; -#endif - } + llcan_init(CAN); - // in case there are queued up messages - process_can(can_number); + // in case there are queued up messages + process_can(can_number); + } } -void can_init_all() { - for (int i=0; i < CAN_MAX; i++) { +void can_init_all(void) { + for (uint8_t i=0U; i < CAN_MAX; i++) { can_init(i); } + current_board->enable_can_transcievers(true); } -void can_set_gmlan(int bus) { - #ifdef PANDA - if (bus == -1 || bus != can_num_lookup[3]) { - // GMLAN OFF - switch (can_num_lookup[3]) { +void can_flip_buses(uint8_t bus1, uint8_t bus2){ + bus_lookup[bus1] = bus2; + bus_lookup[bus2] = bus1; + can_num_lookup[bus1] = bus2; + can_num_lookup[bus2] = bus1; +} + +// TODO: Cleanup with new abstraction +void can_set_gmlan(uint8_t bus) { + if(board_has_gmlan()){ + // first, disable GMLAN on prev bus + uint8_t prev_bus = can_num_lookup[3]; + if (bus != prev_bus) { + switch (prev_bus) { + case 1: + case 2: + puts("Disable GMLAN on CAN"); + puth(prev_bus + 1U); + puts("\n"); + current_board->set_can_mode(CAN_MODE_NORMAL); + bus_lookup[prev_bus] = prev_bus; + can_num_lookup[prev_bus] = prev_bus; + can_num_lookup[3] = -1; + can_init(prev_bus); + break; + default: + // GMLAN was not set on either BUS 1 or 2 + break; + } + } + + // now enable GMLAN on the new bus + switch (bus) { case 1: - puts("disable GMLAN on CAN2\n"); - set_can_mode(1, 0); - bus_lookup[1] = 1; - can_num_lookup[1] = 1; - can_num_lookup[3] = -1; - can_init(1); - break; case 2: - puts("disable GMLAN on CAN3\n"); - set_can_mode(2, 0); - bus_lookup[2] = 2; - can_num_lookup[2] = 2; - can_num_lookup[3] = -1; - can_init(2); + puts("Enable GMLAN on CAN"); + puth(bus + 1U); + puts("\n"); + current_board->set_can_mode((bus == 1U) ? CAN_MODE_GMLAN_CAN2 : CAN_MODE_GMLAN_CAN3); + bus_lookup[bus] = 3; + can_num_lookup[bus] = -1; + can_num_lookup[3] = bus; + can_init(bus); + break; + case 0xFF: //-1 unsigned + break; + default: + puts("GMLAN can only be set on CAN2 or CAN3\n"); break; } + } else { + puts("GMLAN not available on black panda\n"); } +} - if (bus == 1) { - puts("GMLAN on CAN2\n"); - // GMLAN on CAN2 - set_can_mode(1, 1); - bus_lookup[1] = 3; - can_num_lookup[1] = -1; - can_num_lookup[3] = 1; - can_init(1); - } else if (bus == 2 && revision == PANDA_REV_C) { - puts("GMLAN on CAN3\n"); - // GMLAN on CAN3 - set_can_mode(2, 1); - bus_lookup[2] = 3; - can_num_lookup[2] = -1; - can_num_lookup[3] = 2; - can_init(2); +// TODO: remove +void can_set_obd(uint8_t harness_orientation, bool obd){ + if(obd){ + puts("setting CAN2 to be OBD\n"); + } else { + puts("setting CAN2 to be normal\n"); + } + if(board_has_obd()){ + if(obd != (bool)(harness_orientation == HARNESS_STATUS_NORMAL)){ + // B5,B6: disable normal mode + set_gpio_mode(GPIOB, 5, MODE_INPUT); + set_gpio_mode(GPIOB, 6, MODE_INPUT); + // B12,B13: CAN2 mode + set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2); + set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2); + } else { + // B5,B6: CAN2 mode + set_gpio_alternate(GPIOB, 5, GPIO_AF9_CAN2); + set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2); + // B12,B13: disable normal mode + set_gpio_mode(GPIOB, 12, MODE_INPUT); + set_gpio_mode(GPIOB, 13, MODE_INPUT); + } + } else { + puts("OBD CAN not available on this board\n"); } - #endif } // CAN error void can_sce(CAN_TypeDef *CAN) { - enter_critical_section(); + ENTER_CRITICAL(); - can_err_cnt += 1; #ifdef DEBUG if (CAN==CAN1) puts("CAN1: "); if (CAN==CAN2) puts("CAN2: "); @@ -313,78 +273,96 @@ void can_sce(CAN_TypeDef *CAN) { puts("\n"); #endif - uint8_t can_number = CAN_NUM_FROM_CANIF(CAN); - uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number); - if (can_autobaud_enabled[bus_number] && (CAN->ESR & CAN_ESR_LEC)) { - can_autobaud_speed_increment(can_number); - can_set_speed(can_number); - } - - // clear current send - CAN->TSR |= CAN_TSR_ABRQ0; - CAN->MSR &= ~(CAN_MSR_ERRI); - CAN->MSR = CAN->MSR; - - exit_critical_section(); + can_err_cnt += 1; + llcan_clear_send(CAN); + EXIT_CRITICAL(); } // ***************************** CAN ***************************** void process_can(uint8_t can_number) { - if (can_number == 0xff) return; - - enter_critical_section(); - - CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number); - uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number); - #ifdef DEBUG - puts("process CAN TX\n"); - #endif - - // check for empty mailbox - CAN_FIFOMailBox_TypeDef to_send; - if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) { - // add successfully transmitted message to my fifo - if ((CAN->TSR & CAN_TSR_RQCP0) == CAN_TSR_RQCP0) { - can_txd_cnt += 1; - - if ((CAN->TSR & CAN_TSR_TXOK0) == CAN_TSR_TXOK0) { - CAN_FIFOMailBox_TypeDef to_push; - to_push.RIR = CAN->sTxMailBox[0].TIR; - to_push.RDTR = (CAN->sTxMailBox[0].TDTR & 0xFFFF000F) | ((CAN_BUS_RET_FLAG | bus_number) << 4); - to_push.RDLR = CAN->sTxMailBox[0].TDLR; - to_push.RDHR = CAN->sTxMailBox[0].TDHR; - can_push(&can_rx_q, &to_push); + if (can_number != 0xffU) { + + ENTER_CRITICAL(); + + CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number); + uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number); + + // check for empty mailbox + CAN_FIFOMailBox_TypeDef to_send; + if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) { + // add successfully transmitted message to my fifo + if ((CAN->TSR & CAN_TSR_RQCP0) == CAN_TSR_RQCP0) { + can_txd_cnt += 1; + + if ((CAN->TSR & CAN_TSR_TXOK0) == CAN_TSR_TXOK0) { + CAN_FIFOMailBox_TypeDef to_push; + to_push.RIR = CAN->sTxMailBox[0].TIR; + to_push.RDTR = (CAN->sTxMailBox[0].TDTR & 0xFFFF000FU) | ((CAN_BUS_RET_FLAG | bus_number) << 4); + to_push.RDLR = CAN->sTxMailBox[0].TDLR; + to_push.RDHR = CAN->sTxMailBox[0].TDHR; + can_send_errs += can_push(&can_rx_q, &to_push) ? 0U : 1U; + } + + if ((CAN->TSR & CAN_TSR_TERR0) == CAN_TSR_TERR0) { + #ifdef DEBUG + puts("CAN TX ERROR!\n"); + #endif + } + + if ((CAN->TSR & CAN_TSR_ALST0) == CAN_TSR_ALST0) { + #ifdef DEBUG + puts("CAN TX ARBITRATION LOST!\n"); + #endif + } + + // clear interrupt + // careful, this can also be cleared by requesting a transmission + CAN->TSR |= CAN_TSR_RQCP0; } - if ((CAN->TSR & CAN_TSR_TERR0) == CAN_TSR_TERR0) { - #ifdef DEBUG - puts("CAN TX ERROR!\n"); - #endif + if (can_pop(can_queues[bus_number], &to_send)) { + can_tx_cnt += 1; + // only send if we have received a packet + CAN->sTxMailBox[0].TDLR = to_send.RDLR; + CAN->sTxMailBox[0].TDHR = to_send.RDHR; + CAN->sTxMailBox[0].TDTR = to_send.RDTR; + CAN->sTxMailBox[0].TIR = to_send.RIR; } + } - if ((CAN->TSR & CAN_TSR_ALST0) == CAN_TSR_ALST0) { - #ifdef DEBUG - puts("CAN TX ARBITRATION LOST!\n"); - #endif - } + EXIT_CRITICAL(); + } +} - // clear interrupt - // careful, this can also be cleared by requesting a transmission - CAN->TSR |= CAN_TSR_RQCP0; - } +void ignition_can_hook(CAN_FIFOMailBox_TypeDef *to_push) { + + int bus = GET_BUS(to_push); + int addr = GET_ADDR(to_push); + int len = GET_LEN(to_push); - if (can_pop(can_queues[bus_number], &to_send)) { - can_tx_cnt += 1; - // only send if we have received a packet - CAN->sTxMailBox[0].TDLR = to_send.RDLR; - CAN->sTxMailBox[0].TDHR = to_send.RDHR; - CAN->sTxMailBox[0].TDTR = to_send.RDTR; - CAN->sTxMailBox[0].TIR = to_send.RIR; + if (bus == 0) { + // GM exception + if ((addr == 0x1F1) && (len == 8)) { + //Bit 5 is ignition "on" + ignition_can = (GET_BYTE(to_push, 0) & 0x20) != 0; + } + // Tesla exception + if ((addr == 0x348) && (len == 8)) { + // GTW_status + ignition_can = (GET_BYTE(to_push, 0) & 0x1) != 0; + } + // Cadillac exception + if ((addr == 0x160) && (len == 5)) { + // this message isn't all zeros when ignition is on + ignition_can = GET_BYTES_04(to_push) != 0; + } + // VW exception + if ((addr == 0x3C0) && (len == 4)) { + // VW Terminal 15 (ignition-on) state + ignition_can = (GET_BYTE(to_push, 2) & 0x2) != 0; } } - - exit_critical_section(); } // CAN receive handlers @@ -392,17 +370,7 @@ void process_can(uint8_t can_number) { void can_rx(uint8_t can_number) { CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number); uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number); - while (CAN->RF0R & CAN_RF0R_FMP0) { - if (can_autobaud_enabled[bus_number]) { - can_autobaud_enabled[bus_number] = false; - puts(CAN_NAME_FROM_CANIF(CAN)); - #ifdef DEBUG - puts(" auto-baud "); - putui(can_speed[bus_number]); - puts(" cbps\n"); - #endif - } - + while ((CAN->RF0R & CAN_RF0R_FMP0) != 0) { can_rx_cnt += 1; // can is live @@ -419,61 +387,49 @@ void can_rx(uint8_t can_number) { to_push.RDTR = (to_push.RDTR & 0xFFFF000F) | (bus_number << 4); // forwarding (panda only) - #ifdef PANDA - int bus_fwd_num = can_forwarding[bus_number] != -1 ? can_forwarding[bus_number] : safety_fwd_hook(bus_number, &to_push); - if (bus_fwd_num != -1) { - CAN_FIFOMailBox_TypeDef to_send; - to_send.RIR = to_push.RIR | 1; // TXRQ - to_send.RDTR = to_push.RDTR; - to_send.RDLR = to_push.RDLR; - to_send.RDHR = to_push.RDHR; - can_send(&to_send, bus_fwd_num); - } - #endif + int bus_fwd_num = (can_forwarding[bus_number] != -1) ? can_forwarding[bus_number] : safety_fwd_hook(bus_number, &to_push); + if (bus_fwd_num != -1) { + CAN_FIFOMailBox_TypeDef to_send; + to_send.RIR = to_push.RIR | 1; // TXRQ + to_send.RDTR = to_push.RDTR; + to_send.RDLR = to_push.RDLR; + to_send.RDHR = to_push.RDHR; + can_send(&to_send, bus_fwd_num); + } safety_rx_hook(&to_push); + ignition_can_hook(&to_push); - #ifdef PANDA - set_led(LED_BLUE, 1); - #endif - can_push(&can_rx_q, &to_push); + current_board->set_led(LED_BLUE, true); + can_send_errs += can_push(&can_rx_q, &to_push) ? 0U : 1U; // next CAN->RF0R |= CAN_RF0R_RFOM0; } } -#ifndef CUSTOM_CAN_INTERRUPTS +void CAN1_TX_IRQHandler(void) { process_can(0); } +void CAN1_RX0_IRQHandler(void) { can_rx(0); } +void CAN1_SCE_IRQHandler(void) { can_sce(CAN1); } -void CAN1_TX_IRQHandler() { process_can(0); } -void CAN1_RX0_IRQHandler() { can_rx(0); } -void CAN1_SCE_IRQHandler() { can_sce(CAN1); } +void CAN2_TX_IRQHandler(void) { process_can(1); } +void CAN2_RX0_IRQHandler(void) { can_rx(1); } +void CAN2_SCE_IRQHandler(void) { can_sce(CAN2); } -void CAN2_TX_IRQHandler() { process_can(1); } -void CAN2_RX0_IRQHandler() { can_rx(1); } -void CAN2_SCE_IRQHandler() { can_sce(CAN2); } - -#ifdef CAN3 -void CAN3_TX_IRQHandler() { process_can(2); } -void CAN3_RX0_IRQHandler() { can_rx(2); } -void CAN3_SCE_IRQHandler() { can_sce(CAN3); } -#endif - -#endif +void CAN3_TX_IRQHandler(void) { process_can(2); } +void CAN3_RX0_IRQHandler(void) { can_rx(2); } +void CAN3_SCE_IRQHandler(void) { can_sce(CAN3); } void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number) { - if (safety_tx_hook(to_push) && !can_autobaud_enabled[bus_number]) { + if (safety_tx_hook(to_push) != 0) { if (bus_number < BUS_MAX) { // add CAN packet to send queue // bus number isn't passed through to_push->RDTR &= 0xF; - if (bus_number == 3 && can_num_lookup[3] == 0xFF) { - #ifdef PANDA - // TODO: why uint8 bro? only int8? - bitbang_gmlan(to_push); - #endif + if ((bus_number == 3U) && (can_num_lookup[3] == 0xFFU)) { + gmlan_send_errs += bitbang_gmlan(to_push) ? 0U : 1U; } else { - can_push(can_queues[bus_number], to_push); + can_fwd_errs += can_push(can_queues[bus_number], to_push) ? 0U : 1U; process_can(CAN_NUM_FROM_BUS_NUM(bus_number)); } } @@ -483,3 +439,4 @@ void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number) { void can_set_forwarding(int from, int to) { can_forwarding[from] = to; } + diff --git a/panda/board/drivers/clock.h b/panda/board/drivers/clock.h new file mode 100644 index 00000000000000..d564c7f01db28d --- /dev/null +++ b/panda/board/drivers/clock.h @@ -0,0 +1,40 @@ +void clock_init(void) { + // enable external oscillator + RCC->CR |= RCC_CR_HSEON; + while ((RCC->CR & RCC_CR_HSERDY) == 0); + + // divide things + RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV4; + + // 16mhz crystal + RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 | + RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE; + + // start PLL + RCC->CR |= RCC_CR_PLLON; + while ((RCC->CR & RCC_CR_PLLRDY) == 0); + + // Configure Flash prefetch, Instruction cache, Data cache and wait state + // *** without this, it breaks *** + FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS; + + // switch to PLL + RCC->CFGR |= RCC_CFGR_SW_PLL; + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); + + // *** running on PLL *** +} + +void watchdog_init(void) { + // setup watchdog + IWDG->KR = 0x5555; + IWDG->PR = 0; // divider /4 + // 0 = 0.125 ms, let's have a 50ms watchdog + IWDG->RLR = 400 - 1; + IWDG->KR = 0xCCCC; +} + +void watchdog_feed(void) { + IWDG->KR = 0xAAAA; +} + diff --git a/panda/board/drivers/dac.h b/panda/board/drivers/dac.h index b8833dc4a62cfe..ac565eb221cd05 100644 --- a/panda/board/drivers/dac.h +++ b/panda/board/drivers/dac.h @@ -1,4 +1,7 @@ -void dac_init() { +void puth(unsigned int i); +void puts(const char *a); + +void dac_init(void) { // no buffers required since we have an opamp //DAC->CR = DAC_CR_EN1 | DAC_CR_BOFF1 | DAC_CR_EN2 | DAC_CR_BOFF2; DAC->DHR12R1 = 0; @@ -11,6 +14,10 @@ void dac_set(int channel, uint32_t value) { DAC->DHR12R1 = value; } else if (channel == 1) { DAC->DHR12R2 = value; + } else { + puts("Failed to set DAC: invalid channel value: "); + puth(value); + puts("\n"); } } diff --git a/panda/board/drivers/drivers.h b/panda/board/drivers/drivers.h deleted file mode 100644 index d3409d60994eed..00000000000000 --- a/panda/board/drivers/drivers.h +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef PANDA_DRIVERS_H -#define PANDA_DRIVERS_H - -// ********************* LLGPIO ********************* - -#define MODE_INPUT 0 -#define MODE_OUTPUT 1 -#define MODE_ALTERNATE 2 -#define MODE_ANALOG 3 - -#define PULL_NONE 0 -#define PULL_UP 1 -#define PULL_DOWN 2 - -void set_gpio_mode(GPIO_TypeDef *GPIO, int pin, int mode); -void set_gpio_output(GPIO_TypeDef *GPIO, int pin, int val); -void set_gpio_alternate(GPIO_TypeDef *GPIO, int pin, int mode); -void set_gpio_pullup(GPIO_TypeDef *GPIO, int pin, int mode); - -int get_gpio_input(GPIO_TypeDef *GPIO, int pin); - - -// ********************* USB ********************* -// IRQs: OTG_FS - -typedef union { - uint16_t w; - struct BW { - uint8_t msb; - uint8_t lsb; - } - bw; -} -uint16_t_uint8_t; - -typedef union _USB_Setup { - uint32_t d8[2]; - struct _SetupPkt_Struc - { - uint8_t bmRequestType; - uint8_t bRequest; - uint16_t_uint8_t wValue; - uint16_t_uint8_t wIndex; - uint16_t_uint8_t wLength; - } b; -} -USB_Setup_TypeDef; - -void usb_init(); -int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired); -int usb_cb_ep1_in(uint8_t *usbdata, int len, int hardwired); -void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired); -void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired); -void usb_cb_enumeration_complete(); - - -// ********************* UART ********************* -// IRQs: USART1, USART2, USART3, UART5 - -#define FIFO_SIZE 0x400 -typedef struct uart_ring { - uint16_t w_ptr_tx; - uint16_t r_ptr_tx; - uint8_t elems_tx[FIFO_SIZE]; - uint16_t w_ptr_rx; - uint16_t r_ptr_rx; - uint8_t elems_rx[FIFO_SIZE]; - USART_TypeDef *uart; - void (*callback)(struct uart_ring*); -} uart_ring; - -void uart_init(USART_TypeDef *u, int baud); - -int getc(uart_ring *q, char *elem); -int putc(uart_ring *q, char elem); - -int puts(const char *a); -void puth(unsigned int i); -void hexdump(const void *a, int l); - - -// ********************* ADC ********************* - -void adc_init(); -uint32_t adc_get(int channel); - - -// ********************* DAC ********************* - -void dac_init(); -void dac_set(int channel, uint32_t value); - - -// ********************* TIMER ********************* - -void timer_init(TIM_TypeDef *TIM, int psc); - - -// ********************* SPI ********************* -// IRQs: DMA2_Stream2, DMA2_Stream3, EXTI4 - -void spi_init(); -int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out); - - -// ********************* CAN ********************* -// IRQs: CAN1_TX, CAN1_RX0, CAN1_SCE -// CAN2_TX, CAN2_RX0, CAN2_SCE -// CAN3_TX, CAN3_RX0, CAN3_SCE - -typedef struct { - uint32_t w_ptr; - uint32_t r_ptr; - uint32_t fifo_size; - CAN_FIFOMailBox_TypeDef *elems; -} can_ring; - -#define CAN_BUS_RET_FLAG 0x80 -#define CAN_BUS_NUM_MASK 0x7F - -#ifdef PANDA - #define BUS_MAX 4 -#else - #define BUS_MAX 2 -#endif - -extern int can_live, pending_can_live; - -// must reinit after changing these -extern int can_loopback, can_silent; -extern uint32_t can_speed[]; - -void can_set_forwarding(int from, int to); - -void can_init(uint8_t can_number); -void can_init_all(); -void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number); -int can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem); - -#endif - diff --git a/panda/board/drivers/fan.h b/panda/board/drivers/fan.h new file mode 100644 index 00000000000000..d7326ec0b33d59 --- /dev/null +++ b/panda/board/drivers/fan.h @@ -0,0 +1,36 @@ +void fan_init(void){ + // Init PWM speed control + pwm_init(TIM3, 3); + + // Init TACH interrupt + SYSCFG->EXTICR[0] = SYSCFG_EXTICR1_EXTI2_PD; + EXTI->IMR |= (1U << 2); + EXTI->RTSR |= (1U << 2); + EXTI->FTSR |= (1U << 2); + NVIC_EnableIRQ(EXTI2_IRQn); +} + +void fan_set_power(uint8_t percentage){ + pwm_set(TIM3, 3, percentage); +} + +uint16_t fan_tach_counter = 0U; +uint16_t fan_rpm = 0U; + +// Can be way more acurate than this, but this is probably good enough for our purposes. + +// Call this every second +void fan_tick(void){ + // 4 interrupts per rotation + fan_rpm = fan_tach_counter * 15U; + fan_tach_counter = 0U; +} + +// TACH interrupt handler +void EXTI2_IRQHandler(void) { + volatile unsigned int pr = EXTI->PR & (1U << 2); + if ((pr & (1U << 2)) != 0U) { + fan_tach_counter++; + } + EXTI->PR = (1U << 2); +} \ No newline at end of file diff --git a/panda/board/drivers/gmlan_alt.h b/panda/board/drivers/gmlan_alt.h index 8521100a88083a..c697a21b41ef9c 100644 --- a/panda/board/drivers/gmlan_alt.h +++ b/panda/board/drivers/gmlan_alt.h @@ -9,7 +9,7 @@ #define MAX_BITS_CAN_PACKET (200) -int gmlan_alt_mode = DISABLED; +int gmlan_alt_mode = DISABLED; // returns out_len int do_bitstuff(char *out, char *in, int in_len) { @@ -18,7 +18,8 @@ int do_bitstuff(char *out, char *in, int in_len) { int j = 0; for (int i = 0; i < in_len; i++) { char bit = in[i]; - out[j++] = bit; + out[j] = bit; + j++; // do the stuffing if (bit == last_bit) { @@ -26,7 +27,8 @@ int do_bitstuff(char *out, char *in, int in_len) { if (bit_cnt == 5) { // 5 in a row the same, do stuff last_bit = !bit; - out[j++] = last_bit; + out[j] = last_bit; + j++; bit_cnt = 1; } } else { @@ -39,32 +41,38 @@ int do_bitstuff(char *out, char *in, int in_len) { } int append_crc(char *in, int in_len) { - int crc = 0; + unsigned int crc = 0; for (int i = 0; i < in_len; i++) { crc <<= 1; - if (in[i] ^ ((crc>>15)&1)) { - crc = crc ^ 0x4599; + if (((unsigned int)(in[i]) ^ ((crc >> 15) & 1U)) != 0U) { + crc = crc ^ 0x4599U; } - crc &= 0x7fff; + crc &= 0x7fffU; } + int in_len_copy = in_len; for (int i = 14; i >= 0; i--) { - in[in_len++] = (crc>>i)&1; + in[in_len_copy] = (crc >> (unsigned int)(i)) & 1U; + in_len_copy++; } - return in_len; + return in_len_copy; } int append_bits(char *in, int in_len, char *app, int app_len) { + int in_len_copy = in_len; for (int i = 0; i < app_len; i++) { - in[in_len++] = app[i]; + in[in_len_copy] = app[i]; + in_len_copy++; } - return in_len; + return in_len_copy; } int append_int(char *in, int in_len, int val, int val_len) { - for (int i = val_len-1; i >= 0; i--) { - in[in_len++] = (val&(1<= 0; i--) { + in[in_len_copy] = ((unsigned int)(val) & (1U << (unsigned int)(i))) != 0U; + in_len_copy++; } - return in_len; + return in_len_copy; } int get_bit_message(char *out, CAN_FIFOMailBox_TypeDef *to_bang) { @@ -82,12 +90,12 @@ int get_bit_message(char *out, CAN_FIFOMailBox_TypeDef *to_bang) { // test packet int dlc_len = to_bang->RDTR & 0xF; len = append_int(pkt, len, 0, 1); // Start-of-frame - - if (to_bang->RIR & 4) { + + if ((to_bang->RIR & 4) != 0) { // extended identifier len = append_int(pkt, len, to_bang->RIR >> 21, 11); // Identifier len = append_int(pkt, len, 3, 2); // SRR+IDE - len = append_int(pkt, len, (to_bang->RIR >> 3) & ((1<<18)-1), 18); // Identifier + len = append_int(pkt, len, (to_bang->RIR >> 3) & ((1U << 18) - 1U), 18); // Identifier len = append_int(pkt, len, 0, 3); // RTR+r1+r0 } else { // standard identifier @@ -114,9 +122,7 @@ int get_bit_message(char *out, CAN_FIFOMailBox_TypeDef *to_bang) { return len; } -#ifdef PANDA - -void setup_timer4() { +void setup_timer4(void) { // setup TIM4->PSC = 48-1; // tick on 1 us TIM4->CR1 = TIM_CR1_CEN; // enable @@ -133,7 +139,7 @@ void setup_timer4() { int gmlan_timeout_counter = GMLAN_TICKS_PER_TIMEOUT_TICKLE; //GMLAN transceiver times out every 17ms held high; tickle every 15ms int can_timeout_counter = GMLAN_TICKS_PER_SECOND; //1 second -int inverted_bit_to_send = GMLAN_HIGH; +int inverted_bit_to_send = GMLAN_HIGH; int gmlan_switch_below_timeout = -1; int gmlan_switch_timeout_enable = 0; @@ -142,9 +148,9 @@ void gmlan_switch_init(int timeout_enable) { gmlan_alt_mode = GPIO_SWITCH; gmlan_switch_below_timeout = 1; set_gpio_mode(GPIOB, 13, MODE_OUTPUT); - + setup_timer4(); - + inverted_bit_to_send = GMLAN_LOW; //We got initialized, set the output low } @@ -164,16 +170,17 @@ void reset_gmlan_switch_timeout(void) { } void set_bitbanged_gmlan(int val) { - if (val) { - GPIOB->ODR |= (1 << 13); + if (val != 0) { + GPIOB->ODR |= (1U << 13); } else { - GPIOB->ODR &= ~(1 << 13); + GPIOB->ODR &= ~(1U << 13); } } char pkt_stuffed[MAX_BITS_CAN_PACKET]; int gmlan_sending = -1; int gmlan_sendmax = -1; +bool gmlan_send_ok = true; int gmlan_silent_count = 0; int gmlan_fail_count = 0; @@ -182,7 +189,7 @@ int gmlan_fail_count = 0; void TIM4_IRQHandler(void) { if (gmlan_alt_mode == BITBANG) { - if (TIM4->SR & TIM_SR_UIF && gmlan_sendmax != -1) { + if ((TIM4->SR & TIM_SR_UIF) && (gmlan_sendmax != -1)) { int read = get_gpio_input(GPIOB, 12); if (gmlan_silent_count < REQUIRED_SILENT_TIME) { if (read == 0) { @@ -190,19 +197,21 @@ void TIM4_IRQHandler(void) { } else { gmlan_silent_count++; } - } else if (gmlan_silent_count == REQUIRED_SILENT_TIME) { - int retry = 0; + } else { + bool retry = 0; // in send loop - if (gmlan_sending > 0 && // not first bit - (read == 0 && pkt_stuffed[gmlan_sending-1] == 1) && // bus wrongly dominant - gmlan_sending != (gmlan_sendmax-11)) { //not ack bit + if ((gmlan_sending > 0) && // not first bit + ((read == 0) && (pkt_stuffed[gmlan_sending-1] == 1)) && // bus wrongly dominant + (gmlan_sending != (gmlan_sendmax - 11))) { //not ack bit puts("GMLAN ERR: bus driven at "); puth(gmlan_sending); puts("\n"); retry = 1; - } else if (read == 1 && gmlan_sending == (gmlan_sendmax-11)) { // recessive during ACK + } else if ((read == 1) && (gmlan_sending == (gmlan_sendmax - 11))) { // recessive during ACK puts("GMLAN ERR: didn't recv ACK\n"); retry = 1; + } else { + // do not retry } if (retry) { // reset sender (retry after 7 silent) @@ -212,13 +221,14 @@ void TIM4_IRQHandler(void) { gmlan_fail_count++; if (gmlan_fail_count == MAX_FAIL_COUNT) { puts("GMLAN ERR: giving up send\n"); + gmlan_send_ok = false; } } else { set_bitbanged_gmlan(pkt_stuffed[gmlan_sending]); gmlan_sending++; } } - if (gmlan_sending == gmlan_sendmax || gmlan_fail_count == MAX_FAIL_COUNT) { + if ((gmlan_sending == gmlan_sendmax) || (gmlan_fail_count == MAX_FAIL_COUNT)) { set_bitbanged_gmlan(1); // recessive set_gpio_mode(GPIOB, 13, MODE_INPUT); TIM4->DIER = 0; // no update interrupt @@ -227,11 +237,9 @@ void TIM4_IRQHandler(void) { } } TIM4->SR = 0; - } //bit bang mode - - else if (gmlan_alt_mode == GPIO_SWITCH) { - if (TIM4->SR & TIM_SR_UIF && gmlan_switch_below_timeout != -1) { - if (can_timeout_counter == 0 && gmlan_switch_timeout_enable) { + } else if (gmlan_alt_mode == GPIO_SWITCH) { + if ((TIM4->SR & TIM_SR_UIF) && (gmlan_switch_below_timeout != -1)) { + if ((can_timeout_counter == 0) && gmlan_switch_timeout_enable) { //it has been more than 1 second since timeout was reset; disable timer and restore the GMLAN output set_gpio_output(GPIOB, 13, GMLAN_LOW); gmlan_switch_below_timeout = -1; @@ -252,25 +260,27 @@ void TIM4_IRQHandler(void) { } } TIM4->SR = 0; - } //gmlan switch mode + } else { + puts("invalid gmlan_alt_mode\n"); + } } -void bitbang_gmlan(CAN_FIFOMailBox_TypeDef *to_bang) { +bool bitbang_gmlan(CAN_FIFOMailBox_TypeDef *to_bang) { + gmlan_send_ok = true; gmlan_alt_mode = BITBANG; - // TODO: make failure less silent - if (gmlan_sendmax != -1) return; - - int len = get_bit_message(pkt_stuffed, to_bang); - gmlan_fail_count = 0; - gmlan_silent_count = 0; - gmlan_sending = 0; - gmlan_sendmax = len; - - // setup for bitbang loop - set_bitbanged_gmlan(1); // recessive - set_gpio_mode(GPIOB, 13, MODE_OUTPUT); - setup_timer4(); + if (gmlan_sendmax == -1) { + int len = get_bit_message(pkt_stuffed, to_bang); + gmlan_fail_count = 0; + gmlan_silent_count = 0; + gmlan_sending = 0; + gmlan_sendmax = len; + // setup for bitbang loop + set_bitbanged_gmlan(1); // recessive + set_gpio_mode(GPIOB, 13, MODE_OUTPUT); + + setup_timer4(); + } + return gmlan_send_ok; } -#endif diff --git a/panda/board/drivers/harness.h b/panda/board/drivers/harness.h new file mode 100644 index 00000000000000..17520a4bab8055 --- /dev/null +++ b/panda/board/drivers/harness.h @@ -0,0 +1,130 @@ +uint8_t car_harness_status = 0U; +#define HARNESS_STATUS_NC 0U +#define HARNESS_STATUS_NORMAL 1U +#define HARNESS_STATUS_FLIPPED 2U + +// Threshold voltage (mV) for either of the SBUs to be below before deciding harness is connected +#define HARNESS_CONNECTED_THRESHOLD 2500U + +struct harness_configuration { + const bool has_harness; + GPIO_TypeDef *GPIO_SBU1; + GPIO_TypeDef *GPIO_SBU2; + GPIO_TypeDef *GPIO_relay_normal; + GPIO_TypeDef *GPIO_relay_flipped; + uint8_t pin_SBU1; + uint8_t pin_SBU2; + uint8_t pin_relay_normal; + uint8_t pin_relay_flipped; + uint8_t adc_channel_SBU1; + uint8_t adc_channel_SBU2; +}; + +// this function will be the API for tici +void set_intercept_relay(bool intercept) { + if (car_harness_status != HARNESS_STATUS_NC) { + if (intercept) { + puts("switching harness to intercept (relay on)\n"); + } else { + puts("switching harness to passthrough (relay off)\n"); + } + + if(car_harness_status == HARNESS_STATUS_NORMAL){ + set_gpio_output(current_board->harness_config->GPIO_relay_normal, current_board->harness_config->pin_relay_normal, !intercept); + } else { + set_gpio_output(current_board->harness_config->GPIO_relay_flipped, current_board->harness_config->pin_relay_flipped, !intercept); + } + } +} + +bool harness_check_ignition(void) { + bool ret = false; + switch(car_harness_status){ + case HARNESS_STATUS_NORMAL: + ret = !get_gpio_input(current_board->harness_config->GPIO_SBU2, current_board->harness_config->pin_SBU2); + break; + case HARNESS_STATUS_FLIPPED: + ret = !get_gpio_input(current_board->harness_config->GPIO_SBU1, current_board->harness_config->pin_SBU1); + break; + default: + break; + } + return ret; +} + +// TODO: refactor to use harness config +void harness_setup_ignition_interrupts(void){ + if(car_harness_status == HARNESS_STATUS_NORMAL){ + SYSCFG->EXTICR[0] = SYSCFG_EXTICR1_EXTI3_PC; + EXTI->IMR |= (1U << 3); + EXTI->RTSR |= (1U << 3); + EXTI->FTSR |= (1U << 3); + puts("setup interrupts: normal\n"); + } else if(car_harness_status == HARNESS_STATUS_FLIPPED) { + SYSCFG->EXTICR[0] = SYSCFG_EXTICR1_EXTI0_PC; + EXTI->IMR |= (1U << 0); + EXTI->RTSR |= (1U << 0); + EXTI->FTSR |= (1U << 0); + NVIC_EnableIRQ(EXTI1_IRQn); + puts("setup interrupts: flipped\n"); + } else { + puts("tried to setup ignition interrupts without harness connected\n"); + } + NVIC_EnableIRQ(EXTI0_IRQn); + NVIC_EnableIRQ(EXTI3_IRQn); +} + +uint8_t harness_detect_orientation(void) { + uint8_t ret = HARNESS_STATUS_NC; + + #ifndef BOOTSTUB + uint32_t sbu1_voltage = adc_get(current_board->harness_config->adc_channel_SBU1); + uint32_t sbu2_voltage = adc_get(current_board->harness_config->adc_channel_SBU2); + + // Detect connection and orientation + if((sbu1_voltage < HARNESS_CONNECTED_THRESHOLD) || (sbu2_voltage < HARNESS_CONNECTED_THRESHOLD)){ + if (sbu1_voltage < sbu2_voltage) { + // orientation normal + ret = HARNESS_STATUS_NORMAL; + } else { + // orientation flipped + ret = HARNESS_STATUS_FLIPPED; + } + } + #endif + + return ret; +} + +void harness_init(void) { + // delay such that the connection is fully made before trying orientation detection + current_board->set_led(LED_BLUE, true); + delay(10000000); + current_board->set_led(LED_BLUE, false); + + // try to detect orientation + uint8_t ret = harness_detect_orientation(); + if (ret != HARNESS_STATUS_NC) { + puts("detected car harness with orientation "); puth2(ret); puts("\n"); + car_harness_status = ret; + + // set the SBU lines to be inputs before using the relay. The lines are not 5V tolerant in ADC mode! + set_gpio_mode(current_board->harness_config->GPIO_SBU1, current_board->harness_config->pin_SBU1, MODE_INPUT); + set_gpio_mode(current_board->harness_config->GPIO_SBU2, current_board->harness_config->pin_SBU2, MODE_INPUT); + + // now we have orientation, set pin ignition detection + if(car_harness_status == HARNESS_STATUS_NORMAL){ + set_gpio_mode(current_board->harness_config->GPIO_SBU2, current_board->harness_config->pin_SBU2, MODE_INPUT); + } else { + set_gpio_mode(current_board->harness_config->GPIO_SBU1, current_board->harness_config->pin_SBU1, MODE_INPUT); + } + + // keep busses connected by default + set_intercept_relay(false); + + // setup ignition interrupts + harness_setup_ignition_interrupts(); + } else { + puts("failed to detect car harness!\n"); + } +} \ No newline at end of file diff --git a/panda/board/drivers/llcan.h b/panda/board/drivers/llcan.h new file mode 100644 index 00000000000000..0a698d4e8d9b93 --- /dev/null +++ b/panda/board/drivers/llcan.h @@ -0,0 +1,94 @@ +// this is needed for 1 mbps support +#define CAN_QUANTA 8U +#define CAN_SEQ1 6 // roundf(quanta * 0.875f) - 1; +#define CAN_SEQ2 1 // roundf(quanta * 0.125f); + +#define CAN_PCLK 24000U +// 333 = 33.3 kbps +// 5000 = 500 kbps +#define can_speed_to_prescaler(x) (CAN_PCLK / CAN_QUANTA * 10U / (x)) + +#define GET_BUS(msg) (((msg)->RDTR >> 4) & 0xFF) +#define GET_LEN(msg) ((msg)->RDTR & 0xF) +#define GET_ADDR(msg) ((((msg)->RIR & 4) != 0) ? ((msg)->RIR >> 3) : ((msg)->RIR >> 21)) +#define GET_BYTE(msg, b) (((int)(b) > 3) ? (((msg)->RDHR >> (8U * ((unsigned int)(b) % 4U))) & 0XFFU) : (((msg)->RDLR >> (8U * (unsigned int)(b))) & 0xFFU)) +#define GET_BYTES_04(msg) ((msg)->RDLR) +#define GET_BYTES_48(msg) ((msg)->RDHR) + +void puts(const char *a); + +bool llcan_set_speed(CAN_TypeDef *CAN_obj, uint32_t speed, bool loopback, bool silent) { + // initialization mode + CAN_obj->MCR = CAN_MCR_TTCM | CAN_MCR_INRQ; + while((CAN_obj->MSR & CAN_MSR_INAK) != CAN_MSR_INAK); + + // set time quanta from defines + CAN_obj->BTR = (CAN_BTR_TS1_0 * (CAN_SEQ1-1)) | + (CAN_BTR_TS2_0 * (CAN_SEQ2-1)) | + (can_speed_to_prescaler(speed) - 1U); + + // silent loopback mode for debugging + if (loopback) { + CAN_obj->BTR |= CAN_BTR_SILM | CAN_BTR_LBKM; + } + if (silent) { + CAN_obj->BTR |= CAN_BTR_SILM; + } + + // reset + // cppcheck-suppress redundantAssignment ; it's a register + CAN_obj->MCR = CAN_MCR_TTCM | CAN_MCR_ABOM; + + #define CAN_TIMEOUT 1000000 + int tmp = 0; + bool ret = false; + while(((CAN_obj->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) && (tmp < CAN_TIMEOUT)) tmp++; + if (tmp < CAN_TIMEOUT) { + ret = true; + } + + return ret; +} + +void llcan_init(CAN_TypeDef *CAN_obj) { + // accept all filter + CAN_obj->FMR |= CAN_FMR_FINIT; + + // no mask + CAN_obj->sFilterRegister[0].FR1 = 0; + CAN_obj->sFilterRegister[0].FR2 = 0; + CAN_obj->sFilterRegister[14].FR1 = 0; + CAN_obj->sFilterRegister[14].FR2 = 0; + CAN_obj->FA1R |= 1U | (1U << 14); + + CAN_obj->FMR &= ~(CAN_FMR_FINIT); + + // enable certain CAN interrupts + CAN_obj->IER |= CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_WKUIE; + + if (CAN_obj == CAN1) { + NVIC_EnableIRQ(CAN1_TX_IRQn); + NVIC_EnableIRQ(CAN1_RX0_IRQn); + NVIC_EnableIRQ(CAN1_SCE_IRQn); + } else if (CAN_obj == CAN2) { + NVIC_EnableIRQ(CAN2_TX_IRQn); + NVIC_EnableIRQ(CAN2_RX0_IRQn); + NVIC_EnableIRQ(CAN2_SCE_IRQn); +#ifdef CAN3 + } else if (CAN_obj == CAN3) { + NVIC_EnableIRQ(CAN3_TX_IRQn); + NVIC_EnableIRQ(CAN3_RX0_IRQn); + NVIC_EnableIRQ(CAN3_SCE_IRQn); +#endif + } else { + puts("Invalid CAN: initialization failed\n"); + } +} + +void llcan_clear_send(CAN_TypeDef *CAN_obj) { + CAN_obj->TSR |= CAN_TSR_ABRQ0; + CAN_obj->MSR &= ~(CAN_MSR_ERRI); + // cppcheck-suppress selfAssignment ; needed to clear the register + CAN_obj->MSR = CAN_obj->MSR; +} + diff --git a/panda/board/drivers/llgpio.h b/panda/board/drivers/llgpio.h index e1835ec0f40c91..9304cbe0105e22 100644 --- a/panda/board/drivers/llgpio.h +++ b/panda/board/drivers/llgpio.h @@ -1,35 +1,65 @@ -void set_gpio_mode(GPIO_TypeDef *GPIO, int pin, int mode) { +#define MODE_INPUT 0 +#define MODE_OUTPUT 1 +#define MODE_ALTERNATE 2 +#define MODE_ANALOG 3 + +#define PULL_NONE 0 +#define PULL_UP 1 +#define PULL_DOWN 2 + +#define OUTPUT_TYPE_PUSH_PULL 0U +#define OUTPUT_TYPE_OPEN_DRAIN 1U + +void set_gpio_mode(GPIO_TypeDef *GPIO, unsigned int pin, unsigned int mode) { + ENTER_CRITICAL(); uint32_t tmp = GPIO->MODER; - tmp &= ~(3 << (pin*2)); - tmp |= (mode << (pin*2)); + tmp &= ~(3U << (pin * 2U)); + tmp |= (mode << (pin * 2U)); GPIO->MODER = tmp; + EXIT_CRITICAL(); } -void set_gpio_output(GPIO_TypeDef *GPIO, int pin, int val) { - if (val) { - GPIO->ODR |= (1 << pin); +void set_gpio_output(GPIO_TypeDef *GPIO, unsigned int pin, bool enabled) { + ENTER_CRITICAL(); + if (enabled) { + GPIO->ODR |= (1U << pin); } else { - GPIO->ODR &= ~(1 << pin); + GPIO->ODR &= ~(1U << pin); } set_gpio_mode(GPIO, pin, MODE_OUTPUT); + EXIT_CRITICAL(); +} + +void set_gpio_output_type(GPIO_TypeDef *GPIO, unsigned int pin, unsigned int output_type){ + ENTER_CRITICAL(); + if(output_type == OUTPUT_TYPE_OPEN_DRAIN) { + GPIO->OTYPER |= (1U << pin); + } else { + GPIO->OTYPER &= ~(1U << pin); + } + EXIT_CRITICAL(); } -void set_gpio_alternate(GPIO_TypeDef *GPIO, int pin, int mode) { - uint32_t tmp = GPIO->AFR[pin>>3]; - tmp &= ~(0xF << ((pin&7)*4)); - tmp |= mode << ((pin&7)*4); - GPIO->AFR[pin>>3] = tmp; +void set_gpio_alternate(GPIO_TypeDef *GPIO, unsigned int pin, unsigned int mode) { + ENTER_CRITICAL(); + uint32_t tmp = GPIO->AFR[pin >> 3U]; + tmp &= ~(0xFU << ((pin & 7U) * 4U)); + tmp |= mode << ((pin & 7U) * 4U); + GPIO->AFR[pin >> 3] = tmp; set_gpio_mode(GPIO, pin, MODE_ALTERNATE); + EXIT_CRITICAL(); } -void set_gpio_pullup(GPIO_TypeDef *GPIO, int pin, int mode) { +void set_gpio_pullup(GPIO_TypeDef *GPIO, unsigned int pin, unsigned int mode) { + ENTER_CRITICAL(); uint32_t tmp = GPIO->PUPDR; - tmp &= ~(3 << (pin*2)); - tmp |= (mode << (pin*2)); + tmp &= ~(3U << (pin * 2U)); + tmp |= (mode << (pin * 2U)); GPIO->PUPDR = tmp; + EXIT_CRITICAL(); } -int get_gpio_input(GPIO_TypeDef *GPIO, int pin) { - return (GPIO->IDR & (1 << pin)) == (1 << pin); +int get_gpio_input(GPIO_TypeDef *GPIO, unsigned int pin) { + return (GPIO->IDR & (1U << pin)) == (1U << pin); } diff --git a/panda/board/drivers/pwm.h b/panda/board/drivers/pwm.h new file mode 100644 index 00000000000000..d2e1652c1ce4ff --- /dev/null +++ b/panda/board/drivers/pwm.h @@ -0,0 +1,55 @@ +#define PWM_COUNTER_OVERFLOW 2000U // To get ~50kHz + +void pwm_init(TIM_TypeDef *TIM, uint8_t channel){ + // Enable timer and auto-reload + TIM->CR1 = TIM_CR1_CEN | TIM_CR1_ARPE; + + // Set channel as PWM mode 1 and enable output + switch(channel){ + case 1U: + TIM->CCMR1 |= (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE); + TIM->CCER |= TIM_CCER_CC1E; + break; + case 2U: + TIM->CCMR1 |= (TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE); + TIM->CCER |= TIM_CCER_CC2E; + break; + case 3U: + TIM->CCMR2 |= (TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3PE); + TIM->CCER |= TIM_CCER_CC3E; + break; + case 4U: + TIM->CCMR2 |= (TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4PE); + TIM->CCER |= TIM_CCER_CC4E; + break; + default: + break; + } + + // Set max counter value + TIM->ARR = PWM_COUNTER_OVERFLOW; + + // Update registers and clear counter + TIM->EGR |= TIM_EGR_UG; +} + +// TODO: Implement for 32-bit timers +void pwm_set(TIM_TypeDef *TIM, uint8_t channel, uint8_t percentage){ + uint16_t comp_value = (((uint16_t) percentage * PWM_COUNTER_OVERFLOW) / 100U); + switch(channel){ + case 1U: + TIM->CCR1 = comp_value; + break; + case 2U: + TIM->CCR2 = comp_value; + break; + case 3U: + TIM->CCR3 = comp_value; + break; + case 4U: + TIM->CCR4 = comp_value; + break; + default: + break; + } +} \ No newline at end of file diff --git a/panda/board/drivers/rtc.h b/panda/board/drivers/rtc.h new file mode 100644 index 00000000000000..9cf113a02e82fb --- /dev/null +++ b/panda/board/drivers/rtc.h @@ -0,0 +1,108 @@ +#define RCC_BDCR_OPTIONS (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_0 | RCC_BDCR_LSEON) +#define RCC_BDCR_MASK (RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL | RCC_BDCR_LSEMOD | RCC_BDCR_LSEBYP | RCC_BDCR_LSEON) + +#define YEAR_OFFSET 2000U + +typedef struct __attribute__((packed)) timestamp_t { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t weekday; + uint8_t hour; + uint8_t minute; + uint8_t second; +} timestamp_t; + +uint8_t to_bcd(uint16_t value){ + return (((value / 10U) & 0x0FU) << 4U) | ((value % 10U) & 0x0FU); +} + +uint16_t from_bcd(uint8_t value){ + return (((value & 0xF0U) >> 4U) * 10U) + (value & 0x0FU); +} + +void rtc_init(void){ + if(board_has_rtc()){ + // Initialize RTC module and clock if not done already. + if((RCC->BDCR & RCC_BDCR_MASK) != RCC_BDCR_OPTIONS){ + puts("Initializing RTC\n"); + // Reset backup domain + RCC->BDCR |= RCC_BDCR_BDRST; + + // Disable write protection + PWR->CR |= PWR_CR_DBP; + + // Clear backup domain reset + RCC->BDCR &= ~(RCC_BDCR_BDRST); + + // Set RTC options + RCC->BDCR = RCC_BDCR_OPTIONS | (RCC->BDCR & (~RCC_BDCR_MASK)); + + // Enable write protection + PWR->CR &= ~(PWR_CR_DBP); + } + } +} + +void rtc_set_time(timestamp_t time){ + if(board_has_rtc()){ + puts("Setting RTC time\n"); + + // Disable write protection + PWR->CR |= PWR_CR_DBP; + RTC->WPR = 0xCA; + RTC->WPR = 0x53; + + // Enable initialization mode + RTC->ISR |= RTC_ISR_INIT; + while((RTC->ISR & RTC_ISR_INITF) == 0){} + + // Set time + RTC->TR = (to_bcd(time.hour) << RTC_TR_HU_Pos) | (to_bcd(time.minute) << RTC_TR_MNU_Pos) | (to_bcd(time.second) << RTC_TR_SU_Pos); + RTC->DR = (to_bcd(time.year - YEAR_OFFSET) << RTC_DR_YU_Pos) | (time.weekday << RTC_DR_WDU_Pos) | (to_bcd(time.month) << RTC_DR_MU_Pos) | (to_bcd(time.day) << RTC_DR_DU_Pos); + + // Set options + RTC->CR = 0U; + + // Disable initalization mode + RTC->ISR &= ~(RTC_ISR_INIT); + + // Wait for synchronization + while((RTC->ISR & RTC_ISR_RSF) == 0){} + + // Re-enable write protection + RTC->WPR = 0x00; + PWR->CR &= ~(PWR_CR_DBP); + } +} + +timestamp_t rtc_get_time(void){ + timestamp_t result; + // Init with zero values in case there is no RTC running + result.year = 0U; + result.month = 0U; + result.day = 0U; + result.weekday = 0U; + result.hour = 0U; + result.minute = 0U; + result.second = 0U; + + if(board_has_rtc()){ + // Wait until the register sync flag is set + while((RTC->ISR & RTC_ISR_RSF) == 0){} + + // Read time and date registers. Since our HSE > 7*LSE, this should be fine. + uint32_t time = RTC->TR; + uint32_t date = RTC->DR; + + // Parse values + result.year = from_bcd((date & (RTC_DR_YT | RTC_DR_YU)) >> RTC_DR_YU_Pos) + YEAR_OFFSET; + result.month = from_bcd((date & (RTC_DR_MT | RTC_DR_MU)) >> RTC_DR_MU_Pos); + result.day = from_bcd((date & (RTC_DR_DT | RTC_DR_DU)) >> RTC_DR_DU_Pos); + result.weekday = ((date & RTC_DR_WDU) >> RTC_DR_WDU_Pos); + result.hour = from_bcd((time & (RTC_TR_HT | RTC_TR_HU)) >> RTC_TR_HU_Pos); + result.minute = from_bcd((time & (RTC_TR_MNT | RTC_TR_MNU)) >> RTC_TR_MNU_Pos); + result.second = from_bcd((time & (RTC_TR_ST | RTC_TR_SU)) >> RTC_TR_SU_Pos); + } + return result; +} \ No newline at end of file diff --git a/panda/board/drivers/spi.h b/panda/board/drivers/spi.h index 7a5945d37257cb..26690984de7bb8 100644 --- a/panda/board/drivers/spi.h +++ b/panda/board/drivers/spi.h @@ -1,11 +1,16 @@ // IRQs: DMA2_Stream2, DMA2_Stream3, EXTI4 +void spi_init(void); +int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out); + +// end API + #define SPI_BUF_SIZE 256 uint8_t spi_buf[SPI_BUF_SIZE]; int spi_buf_count = 0; int spi_total_count = 0; -void spi_init() { +void spi_init(void) { //puts("SPI init\n"); SPI1->CR1 = SPI_CR1_SPE; @@ -23,8 +28,8 @@ void spi_init() { // setup interrupt on falling edge of SPI enable (on PA4) SYSCFG->EXTICR[2] = SYSCFG_EXTICR2_EXTI4_PA; - EXTI->IMR = (1 << 4); - EXTI->FTSR = (1 << 4); + EXTI->IMR |= (1U << 4); + EXTI->FTSR |= (1U << 4); NVIC_EnableIRQ(EXTI4_IRQn); } @@ -80,7 +85,7 @@ uint8_t spi_tx_buf[0x44]; // SPI RX void DMA2_Stream2_IRQHandler(void) { int *resp_len = (int*)spi_tx_buf; - memset(spi_tx_buf, 0xaa, 0x44); + (void)memset(spi_tx_buf, 0xaa, 0x44); *resp_len = spi_cb_rx(spi_buf, 0x14, spi_tx_buf+4); #ifdef DEBUG_SPI puts("SPI write: "); @@ -108,12 +113,12 @@ void DMA2_Stream3_IRQHandler(void) { } void EXTI4_IRQHandler(void) { - volatile int pr = EXTI->PR; + volatile unsigned int pr = EXTI->PR & (1U << 4); #ifdef DEBUG_SPI puts("exti4\n"); #endif // SPI CS falling - if (pr & (1 << 4)) { + if ((pr & (1U << 4)) != 0U) { spi_total_count = 0; spi_rx_dma(spi_buf, 0x14); } diff --git a/panda/board/drivers/uart.h b/panda/board/drivers/uart.h index 5ca82888d4fe7a..3a095f67261d8e 100644 --- a/panda/board/drivers/uart.h +++ b/panda/board/drivers/uart.h @@ -1,304 +1,433 @@ // IRQs: USART1, USART2, USART3, UART5 -// ***************************** serial port queues ***************************** +// ***************************** Definitions ***************************** +#define FIFO_SIZE_INT 0x400U +#define FIFO_SIZE_DMA 0x1000U + +typedef struct uart_ring { + volatile uint16_t w_ptr_tx; + volatile uint16_t r_ptr_tx; + uint8_t *elems_tx; + uint32_t tx_fifo_size; + volatile uint16_t w_ptr_rx; + volatile uint16_t r_ptr_rx; + uint8_t *elems_rx; + uint32_t rx_fifo_size; + USART_TypeDef *uart; + void (*callback)(struct uart_ring*); + bool dma_rx; +} uart_ring; + +#define UART_BUFFER(x, size_rx, size_tx, uart_ptr, callback_ptr, rx_dma) \ + uint8_t elems_rx_##x[size_rx]; \ + uint8_t elems_tx_##x[size_tx]; \ + uart_ring uart_ring_##x = { \ + .w_ptr_tx = 0, \ + .r_ptr_tx = 0, \ + .elems_tx = ((uint8_t *)&elems_tx_##x), \ + .tx_fifo_size = size_tx, \ + .w_ptr_rx = 0, \ + .r_ptr_rx = 0, \ + .elems_rx = ((uint8_t *)&elems_rx_##x), \ + .rx_fifo_size = size_rx, \ + .uart = uart_ptr, \ + .callback = callback_ptr, \ + .dma_rx = rx_dma \ + }; + + +// ***************************** Function prototypes ***************************** +void uart_init(uart_ring *q, int baud); + +bool getc(uart_ring *q, char *elem); +bool putc(uart_ring *q, char elem); + +void puts(const char *a); +void puth(unsigned int i); +void hexdump(const void *a, int l); -// esp = USART1 -uart_ring esp_ring = { .w_ptr_tx = 0, .r_ptr_tx = 0, - .w_ptr_rx = 0, .r_ptr_rx = 0, - .uart = USART1, - .callback = NULL}; +void debug_ring_callback(uart_ring *ring); + +// ******************************** UART buffers ******************************** + +// esp_gps = USART1 +UART_BUFFER(esp_gps, FIFO_SIZE_DMA, FIFO_SIZE_INT, USART1, NULL, true) // lin1, K-LINE = UART5 // lin2, L-LINE = USART3 -uart_ring lin1_ring = { .w_ptr_tx = 0, .r_ptr_tx = 0, - .w_ptr_rx = 0, .r_ptr_rx = 0, - .uart = UART5, - .callback = NULL}; -uart_ring lin2_ring = { .w_ptr_tx = 0, .r_ptr_tx = 0, - .w_ptr_rx = 0, .r_ptr_rx = 0, - .uart = USART3, - .callback = NULL}; +UART_BUFFER(lin1, FIFO_SIZE_INT, FIFO_SIZE_INT, UART5, NULL, false) +UART_BUFFER(lin2, FIFO_SIZE_INT, FIFO_SIZE_INT, USART3, NULL, false) // debug = USART2 -void debug_ring_callback(uart_ring *ring); -uart_ring debug_ring = { .w_ptr_tx = 0, .r_ptr_tx = 0, - .w_ptr_rx = 0, .r_ptr_rx = 0, - .uart = USART2, - .callback = debug_ring_callback}; - +UART_BUFFER(debug, FIFO_SIZE_INT, FIFO_SIZE_INT, USART2, debug_ring_callback, false) uart_ring *get_ring_by_number(int a) { + uart_ring *ring = NULL; switch(a) { case 0: - return &debug_ring; + ring = &uart_ring_debug; + break; case 1: - return &esp_ring; + ring = &uart_ring_esp_gps; + break; case 2: - return &lin1_ring; + ring = &uart_ring_lin1; + break; case 3: - return &lin2_ring; + ring = &uart_ring_lin2; + break; default: - return NULL; + ring = NULL; + break; } + return ring; } -// ***************************** serial port ***************************** - -void uart_ring_process(uart_ring *q) { - enter_critical_section(); - // TODO: check if external serial is connected - int sr = q->uart->SR; +// ***************************** Interrupt handlers ***************************** +void uart_tx_ring(uart_ring *q){ + ENTER_CRITICAL(); + // Send out next byte of TX buffer if (q->w_ptr_tx != q->r_ptr_tx) { - if (sr & USART_SR_TXE) { - q->uart->DR = q->elems_tx[q->r_ptr_tx]; - q->r_ptr_tx = (q->r_ptr_tx + 1) % FIFO_SIZE; - } else { - // push on interrupt later + // Only send if transmit register is empty (aka last byte has been sent) + if ((q->uart->SR & USART_SR_TXE) != 0) { + q->uart->DR = q->elems_tx[q->r_ptr_tx]; // This clears TXE + q->r_ptr_tx = (q->r_ptr_tx + 1U) % q->tx_fifo_size; + } + + // Enable TXE interrupt if there is still data to be sent + if(q->r_ptr_tx != q->w_ptr_tx){ q->uart->CR1 |= USART_CR1_TXEIE; + } else { + q->uart->CR1 &= ~USART_CR1_TXEIE; } - } else { - // nothing to send - q->uart->CR1 &= ~USART_CR1_TXEIE; } + EXIT_CRITICAL(); +} - if (sr & USART_SR_RXNE || sr & USART_SR_ORE) { - uint8_t c = q->uart->DR; // TODO: can drop packets - if (q != &esp_ring) { - uint16_t next_w_ptr = (q->w_ptr_rx + 1) % FIFO_SIZE; - if (next_w_ptr != q->r_ptr_rx) { - q->elems_rx[q->w_ptr_rx] = c; - q->w_ptr_rx = next_w_ptr; - if (q->callback) q->callback(q); +void uart_rx_ring(uart_ring *q){ + // Do not read out directly if DMA enabled + if (q->dma_rx == false) { + ENTER_CRITICAL(); + + // Read out RX buffer + uint8_t c = q->uart->DR; // This read after reading SR clears a bunch of interrupts + + uint16_t next_w_ptr = (q->w_ptr_rx + 1U) % q->rx_fifo_size; + // Do not overwrite buffer data + if (next_w_ptr != q->r_ptr_rx) { + q->elems_rx[q->w_ptr_rx] = c; + q->w_ptr_rx = next_w_ptr; + if (q->callback != NULL) { + q->callback(q); } } + + EXIT_CRITICAL(); } +} + +// This function should be called on: +// * Half-transfer DMA interrupt +// * Full-transfer DMA interrupt +// * UART IDLE detection +uint32_t prev_w_index = 0; +void dma_pointer_handler(uart_ring *q, uint32_t dma_ndtr) { + ENTER_CRITICAL(); + uint32_t w_index = (q->rx_fifo_size - dma_ndtr); + + // Check for new data + if (w_index != prev_w_index){ + // Check for overflow + if ( + ((prev_w_index < q->r_ptr_rx) && (q->r_ptr_rx <= w_index)) || // No rollover + ((w_index < prev_w_index) && ((q->r_ptr_rx <= w_index) || (prev_w_index < q->r_ptr_rx))) // Rollover + ){ + // We lost data. Set the new read pointer to the oldest byte still available + q->r_ptr_rx = (w_index + 1U) % q->rx_fifo_size; + } - if (sr & USART_SR_ORE) { - // set dropped packet flag? + // Set write pointer + q->w_ptr_rx = w_index; } - exit_critical_section(); + prev_w_index = w_index; + EXIT_CRITICAL(); } -// interrupt boilerplate +// This read after reading SR clears all error interrupts. We don't want compiler warnings, nor optimizations +#define UART_READ_DR(uart) volatile uint8_t t = (uart)->DR; UNUSED(t); -void USART1_IRQHandler(void) { uart_ring_process(&esp_ring); } -void USART2_IRQHandler(void) { uart_ring_process(&debug_ring); } -void USART3_IRQHandler(void) { uart_ring_process(&lin2_ring); } -void UART5_IRQHandler(void) { uart_ring_process(&lin1_ring); } +void uart_interrupt_handler(uart_ring *q) { + ENTER_CRITICAL(); -int getc(uart_ring *q, char *elem) { - int ret = 0; + // Read UART status. This is also the first step necessary in clearing most interrupts + uint32_t status = q->uart->SR; - enter_critical_section(); - if (q->w_ptr_rx != q->r_ptr_rx) { - *elem = q->elems_rx[q->r_ptr_rx]; - q->r_ptr_rx = (q->r_ptr_rx + 1) % FIFO_SIZE; - ret = 1; + // If RXNE is set, perform a read. This clears RXNE, ORE, IDLE, NF and FE + if((status & USART_SR_RXNE) != 0U){ + uart_rx_ring(q); } - exit_critical_section(); - return ret; -} + // Detect errors and clear them + uint32_t err = (status & USART_SR_ORE) | (status & USART_SR_NE) | (status & USART_SR_FE) | (status & USART_SR_PE); + if(err != 0U){ + #ifdef DEBUG_UART + puts("Encountered UART error: "); puth(err); puts("\n"); + #endif + UART_READ_DR(q->uart) + } + // Send if necessary + uart_tx_ring(q); -int injectc(uart_ring *q, char elem) { - int ret = 0; - uint16_t next_w_ptr; + // Run DMA pointer handler if the line is idle + if(q->dma_rx && (status & USART_SR_IDLE)){ + // Reset IDLE flag + UART_READ_DR(q->uart) - enter_critical_section(); - next_w_ptr = (q->w_ptr_rx + 1) % FIFO_SIZE; - if (next_w_ptr != q->r_ptr_rx) { - q->elems_rx[q->w_ptr_rx] = elem; - q->w_ptr_rx = next_w_ptr; - ret = 1; + if(q == &uart_ring_esp_gps){ + dma_pointer_handler(&uart_ring_esp_gps, DMA2_Stream5->NDTR); + } else { + #ifdef DEBUG_UART + puts("No IDLE dma_pointer_handler implemented for this UART."); + #endif + } } - exit_critical_section(); - return ret; + EXIT_CRITICAL(); } -int putc(uart_ring *q, char elem) { - int ret = 0; - uint16_t next_w_ptr; +void USART1_IRQHandler(void) { uart_interrupt_handler(&uart_ring_esp_gps); } +void USART2_IRQHandler(void) { uart_interrupt_handler(&uart_ring_debug); } +void USART3_IRQHandler(void) { uart_interrupt_handler(&uart_ring_lin2); } +void UART5_IRQHandler(void) { uart_interrupt_handler(&uart_ring_lin1); } - enter_critical_section(); - next_w_ptr = (q->w_ptr_tx + 1) % FIFO_SIZE; - if (next_w_ptr != q->r_ptr_tx) { - q->elems_tx[q->w_ptr_tx] = elem; - q->w_ptr_tx = next_w_ptr; - ret = 1; +void DMA2_Stream5_IRQHandler(void) { + ENTER_CRITICAL(); + + // Handle errors + if((DMA2->HISR & DMA_HISR_TEIF5) || (DMA2->HISR & DMA_HISR_DMEIF5) || (DMA2->HISR & DMA_HISR_FEIF5)){ + #ifdef DEBUG_UART + puts("Encountered UART DMA error. Clearing and restarting DMA...\n"); + #endif + + // Clear flags + DMA2->HIFCR = DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5; + + // Re-enable the DMA if necessary + DMA2_Stream5->CR |= DMA_SxCR_EN; } - exit_critical_section(); - uart_ring_process(q); + // Re-calculate write pointer and reset flags + dma_pointer_handler(&uart_ring_esp_gps, DMA2_Stream5->NDTR); + DMA2->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5; - return ret; + EXIT_CRITICAL(); } -void clear_uart_buff(uart_ring *q) { - enter_critical_section(); - q->w_ptr_tx = 0; - q->r_ptr_tx = 0; - q->w_ptr_rx = 0; - q->r_ptr_rx = 0; - exit_critical_section(); -} +// ***************************** Hardware setup ***************************** -// ***************************** start UART code ***************************** +void dma_rx_init(uart_ring *q) { + // Initialization is UART-dependent + if(q == &uart_ring_esp_gps){ + // DMA2, stream 5, channel 4 -#define __DIV(_PCLK_, _BAUD_) (((_PCLK_)*25)/(4*(_BAUD_))) -#define __DIVMANT(_PCLK_, _BAUD_) (__DIV((_PCLK_), (_BAUD_))/100) -#define __DIVFRAQ(_PCLK_, _BAUD_) (((__DIV((_PCLK_), (_BAUD_)) - (__DIVMANT((_PCLK_), (_BAUD_)) * 100)) * 16 + 50) / 100) -#define __USART_BRR(_PCLK_, _BAUD_) ((__DIVMANT((_PCLK_), (_BAUD_)) << 4)|(__DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0F)) + // Disable FIFO mode (enable direct) + DMA2_Stream5->FCR &= ~DMA_SxFCR_DMDIS; -void uart_set_baud(USART_TypeDef *u, int baud) { - if (u == USART1) { - // USART1 is on APB2 - u->BRR = __USART_BRR(48000000, baud); + // Setup addresses + DMA2_Stream5->PAR = (uint32_t)&(USART1->DR); // Source + DMA2_Stream5->M0AR = (uint32_t)q->elems_rx; // Destination + DMA2_Stream5->NDTR = q->rx_fifo_size; // Number of bytes to copy + + // Circular, Increment memory, byte size, periph -> memory, enable + // Transfer complete, half transfer, transfer error and direct mode error interrupt enable + DMA2_Stream5->CR = DMA_SxCR_CHSEL_2 | DMA_SxCR_MINC | DMA_SxCR_CIRC | DMA_SxCR_HTIE | DMA_SxCR_TCIE | DMA_SxCR_TEIE | DMA_SxCR_DMEIE | DMA_SxCR_EN; + + // Enable DMA receiver in UART + q->uart->CR3 |= USART_CR3_DMAR; + + // Enable UART IDLE interrupt + q->uart->CR1 |= USART_CR1_IDLEIE; + + // Enable interrupt + NVIC_EnableIRQ(DMA2_Stream5_IRQn); } else { - u->BRR = __USART_BRR(24000000, baud); + puts("Tried to initialize RX DMA for an unsupported UART\n"); } } -#define USART1_DMA_LEN 0x20 -char usart1_dma[USART1_DMA_LEN]; +#define __DIV(_PCLK_, _BAUD_) (((_PCLK_) * 25U) / (4U * (_BAUD_))) +#define __DIVMANT(_PCLK_, _BAUD_) (__DIV((_PCLK_), (_BAUD_)) / 100U) +#define __DIVFRAQ(_PCLK_, _BAUD_) ((((__DIV((_PCLK_), (_BAUD_)) - (__DIVMANT((_PCLK_), (_BAUD_)) * 100U)) * 16U) + 50U) / 100U) +#define __USART_BRR(_PCLK_, _BAUD_) ((__DIVMANT((_PCLK_), (_BAUD_)) << 4) | (__DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0FU)) -void uart_dma_drain() { - uart_ring *q = &esp_ring; +void uart_set_baud(USART_TypeDef *u, unsigned int baud) { + if (u == USART1) { + // USART1 is on APB2 + u->BRR = __USART_BRR(48000000U, baud); + } else { + u->BRR = __USART_BRR(24000000U, baud); + } +} - enter_critical_section(); +void uart_init(uart_ring *q, int baud) { + // Set baud and enable peripheral with TX and RX mode + uart_set_baud(q->uart, baud); + q->uart->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE; - if (DMA2->HISR & DMA_HISR_TCIF5 || DMA2->HISR & DMA_HISR_HTIF5 || DMA2_Stream5->NDTR != USART1_DMA_LEN) { - // disable DMA - q->uart->CR3 &= ~USART_CR3_DMAR; - DMA2_Stream5->CR &= ~DMA_SxCR_EN; - while (DMA2_Stream5->CR & DMA_SxCR_EN); + // Enable UART interrupts + if(q->uart == USART1){ + NVIC_EnableIRQ(USART1_IRQn); + } else if (q->uart == USART2){ + NVIC_EnableIRQ(USART2_IRQn); + } else if (q->uart == USART3){ + NVIC_EnableIRQ(USART3_IRQn); + } else if (q->uart == UART5){ + NVIC_EnableIRQ(UART5_IRQn); + } else { + // UART not used. Skip enabling interrupts + } - int i; - for (i = 0; i < USART1_DMA_LEN - DMA2_Stream5->NDTR; i++) { - char c = usart1_dma[i]; - uint16_t next_w_ptr = (q->w_ptr_rx + 1) % FIFO_SIZE; - if (next_w_ptr != q->r_ptr_rx) { - q->elems_rx[q->w_ptr_rx] = c; - q->w_ptr_rx = next_w_ptr; - } - } + // Initialise RX DMA if used + if(q->dma_rx){ + dma_rx_init(q); + } +} - // reset DMA len - DMA2_Stream5->NDTR = USART1_DMA_LEN; +// ************************* Low-level buffer functions ************************* - // clear interrupts - DMA2->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5; - //DMA2->HIFCR = DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5; +bool getc(uart_ring *q, char *elem) { + bool ret = false; - // enable DMA - DMA2_Stream5->CR |= DMA_SxCR_EN; - q->uart->CR3 |= USART_CR3_DMAR; + ENTER_CRITICAL(); + if (q->w_ptr_rx != q->r_ptr_rx) { + if (elem != NULL) *elem = q->elems_rx[q->r_ptr_rx]; + q->r_ptr_rx = (q->r_ptr_rx + 1U) % q->rx_fifo_size; + ret = true; } + EXIT_CRITICAL(); - exit_critical_section(); + return ret; } -void DMA2_Stream5_IRQHandler(void) { - //set_led(LED_BLUE, 1); - uart_dma_drain(); - //set_led(LED_BLUE, 0); -} +bool injectc(uart_ring *q, char elem) { + int ret = false; + uint16_t next_w_ptr; -void uart_init(USART_TypeDef *u, int baud) { - // enable uart and tx+rx mode - u->CR1 = USART_CR1_UE; - uart_set_baud(u, baud); + ENTER_CRITICAL(); + next_w_ptr = (q->w_ptr_rx + 1U) % q->tx_fifo_size; + if (next_w_ptr != q->r_ptr_rx) { + q->elems_rx[q->w_ptr_rx] = elem; + q->w_ptr_rx = next_w_ptr; + ret = true; + } + EXIT_CRITICAL(); + + return ret; +} - u->CR1 |= USART_CR1_TE | USART_CR1_RE; - //u->CR2 = USART_CR2_STOP_0 | USART_CR2_STOP_1; - //u->CR2 = USART_CR2_STOP_0; - // ** UART is ready to work ** +bool putc(uart_ring *q, char elem) { + bool ret = false; + uint16_t next_w_ptr; - // enable interrupts - if (u != USART1) { - u->CR1 |= USART_CR1_RXNEIE; + ENTER_CRITICAL(); + next_w_ptr = (q->w_ptr_tx + 1U) % q->tx_fifo_size; + if (next_w_ptr != q->r_ptr_tx) { + q->elems_tx[q->w_ptr_tx] = elem; + q->w_ptr_tx = next_w_ptr; + ret = true; } + EXIT_CRITICAL(); - if (u == USART1) { - // DMA2, stream 2, channel 3 - DMA2_Stream5->M0AR = (uint32_t)usart1_dma; - DMA2_Stream5->NDTR = USART1_DMA_LEN; - DMA2_Stream5->PAR = (uint32_t)&(USART1->DR); + uart_tx_ring(q); - // channel4, increment memory, periph -> memory, enable - DMA2_Stream5->CR = DMA_SxCR_CHSEL_2 | DMA_SxCR_MINC | DMA_SxCR_HTIE | DMA_SxCR_TCIE | DMA_SxCR_EN; + return ret; +} - // this one uses DMA receiver - u->CR3 = USART_CR3_DMAR; +// Seems dangerous to use (might lock CPU if called with interrupts disabled f.e.) +// TODO: Remove? Not used anyways +void uart_flush(uart_ring *q) { + while (q->w_ptr_tx != q->r_ptr_tx) { + __WFI(); + } +} - NVIC_EnableIRQ(DMA2_Stream5_IRQn); - NVIC_EnableIRQ(USART1_IRQn); - } else if (u == USART2) { - NVIC_EnableIRQ(USART2_IRQn); - } else if (u == USART3) { - NVIC_EnableIRQ(USART3_IRQn); - } else if (u == UART5) { - NVIC_EnableIRQ(UART5_IRQn); +void uart_flush_sync(uart_ring *q) { + // empty the TX buffer + while (q->w_ptr_tx != q->r_ptr_tx) { + uart_tx_ring(q); } } +void uart_send_break(uart_ring *u) { + while ((u->uart->CR1 & USART_CR1_SBK) != 0); + u->uart->CR1 |= USART_CR1_SBK; +} + +void clear_uart_buff(uart_ring *q) { + ENTER_CRITICAL(); + q->w_ptr_tx = 0; + q->r_ptr_tx = 0; + q->w_ptr_rx = 0; + q->r_ptr_rx = 0; + EXIT_CRITICAL(); +} + +// ************************ High-level debug functions ********************** void putch(const char a) { if (has_external_debug_serial) { - /*while ((debug_ring.uart->SR & USART_SR_TXE) == 0); - debug_ring.uart->DR = a;*/ - // assuming debugging is important if there's external serial connected - while (!putc(&debug_ring, a)); + while (!putc(&uart_ring_debug, a)); - //putc(&debug_ring, a); } else { - injectc(&debug_ring, a); + // misra-c2012-17.7: serial debug function, ok to ignore output + (void)injectc(&uart_ring_debug, a); } } -int puts(const char *a) { - for (;*a;a++) { - if (*a == '\n') putch('\r'); - putch(*a); +void puts(const char *a) { + for (const char *in = a; *in; in++) { + if (*in == '\n') putch('\r'); + putch(*in); } - return 0; } void putui(uint32_t i) { + uint32_t i_copy = i; char str[11]; uint8_t idx = 10; - str[idx--] = '\0'; + str[idx] = '\0'; + idx--; do { - str[idx--] = (i % 10) + 0x30; - i /= 10; - } while (i); - puts(str + idx + 1); + str[idx] = (i_copy % 10U) + 0x30U; + idx--; + i_copy /= 10; + } while (i_copy != 0U); + puts(&str[idx + 1U]); } void puth(unsigned int i) { - int pos; char c[] = "0123456789abcdef"; - for (pos = 28; pos != -4; pos -= 4) { - putch(c[(i >> pos) & 0xF]); + for (int pos = 28; pos != -4; pos -= 4) { + putch(c[(i >> (unsigned int)(pos)) & 0xFU]); } } void puth2(unsigned int i) { - int pos; char c[] = "0123456789abcdef"; - for (pos = 4; pos != -4; pos -= 4) { - putch(c[(i >> pos) & 0xF]); + for (int pos = 4; pos != -4; pos -= 4) { + putch(c[(i >> (unsigned int)(pos)) & 0xFU]); } } void hexdump(const void *a, int l) { - int i; - for (i=0;i>8)&0xFF) + ((num) & 0xFFU), (((num) >> 8) & 0xFFU) // take in string length and return the first 2 bytes of a string descriptor #define STRING_DESCRIPTOR_HEADER(size)\ - (((size * 2 + 2)&0xFF) | 0x0300) + (((((size) * 2) + 2) & 0xFF) | 0x0300) uint8_t device_desc[] = { DSCR_DEVICE_LEN, USB_DESC_TYPE_DEVICE, //Length, Type @@ -128,7 +158,7 @@ uint8_t device_qualifier[] = { uint8_t configuration_desc[] = { DSCR_CONFIG_LEN, USB_DESC_TYPE_CONFIGURATION, // Length, Type, - TOUSBORDER(0x0045), // Total Len (uint16) + TOUSBORDER(0x0045U), // Total Len (uint16) 0x01, 0x01, STRING_OFFSET_ICONFIGURATION, // Num Interface, Config Value, Configuration 0xc0, 0x32, // Attributes, Max Power // interface 0 ALT 0 @@ -139,17 +169,17 @@ uint8_t configuration_desc[] = { // endpoint 1, read CAN DSCR_ENDPOINT_LEN, USB_DESC_TYPE_ENDPOINT, // Length, Type ENDPOINT_RCV | 1, ENDPOINT_TYPE_BULK, // Endpoint Num/Direction, Type - TOUSBORDER(0x0040), // Max Packet (0x0040) + TOUSBORDER(0x0040U), // Max Packet (0x0040) 0x00, // Polling Interval (NA) // endpoint 2, send serial DSCR_ENDPOINT_LEN, USB_DESC_TYPE_ENDPOINT, // Length, Type ENDPOINT_SND | 2, ENDPOINT_TYPE_BULK, // Endpoint Num/Direction, Type - TOUSBORDER(0x0040), // Max Packet (0x0040) + TOUSBORDER(0x0040U), // Max Packet (0x0040) 0x00, // Polling Interval // endpoint 3, send CAN DSCR_ENDPOINT_LEN, USB_DESC_TYPE_ENDPOINT, // Length, Type ENDPOINT_SND | 3, ENDPOINT_TYPE_BULK, // Endpoint Num/Direction, Type - TOUSBORDER(0x0040), // Max Packet (0x0040) + TOUSBORDER(0x0040U), // Max Packet (0x0040) 0x00, // Polling Interval // interface 0 ALT 1 DSCR_INTERFACE_LEN, USB_DESC_TYPE_INTERFACE, // Length, Type @@ -159,17 +189,17 @@ uint8_t configuration_desc[] = { // endpoint 1, read CAN DSCR_ENDPOINT_LEN, USB_DESC_TYPE_ENDPOINT, // Length, Type ENDPOINT_RCV | 1, ENDPOINT_TYPE_INT, // Endpoint Num/Direction, Type - TOUSBORDER(0x0040), // Max Packet (0x0040) + TOUSBORDER(0x0040U), // Max Packet (0x0040) 0x05, // Polling Interval (5 frames) // endpoint 2, send serial DSCR_ENDPOINT_LEN, USB_DESC_TYPE_ENDPOINT, // Length, Type ENDPOINT_SND | 2, ENDPOINT_TYPE_BULK, // Endpoint Num/Direction, Type - TOUSBORDER(0x0040), // Max Packet (0x0040) + TOUSBORDER(0x0040U), // Max Packet (0x0040) 0x00, // Polling Interval // endpoint 3, send CAN DSCR_ENDPOINT_LEN, USB_DESC_TYPE_ENDPOINT, // Length, Type ENDPOINT_SND | 3, ENDPOINT_TYPE_BULK, // Endpoint Num/Direction, Type - TOUSBORDER(0x0040), // Max Packet (0x0040) + TOUSBORDER(0x0040U), // Max Packet (0x0040) 0x00, // Polling Interval }; @@ -186,17 +216,10 @@ uint16_t string_manufacturer_desc[] = { 'c', 'o', 'm', 'm', 'a', '.', 'a', 'i' }; -#ifdef PANDA uint16_t string_product_desc[] = { STRING_DESCRIPTOR_HEADER(5), 'p', 'a', 'n', 'd', 'a' }; -#else -uint16_t string_product_desc[] = { - STRING_DESCRIPTOR_HEADER(5), - 'N', 'E', 'O', 'v', '1' -}; -#endif // default serial number when we're not a panda uint16_t string_serial_desc[] = { @@ -210,7 +233,6 @@ uint16_t string_configuration_desc[] = { '0', '1' // "01" }; -#ifdef PANDA // WCID (auto install WinUSB driver) // https://github.com/pbatard/libwdi/wiki/WCID-Devices // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/winusb-installation#automatic-installation-of--winusb-without-an-inf-file @@ -360,8 +382,6 @@ uint8_t winusb_20_desc[WINUSB_PLATFORM_DESCRIPTOR_LENGTH] = { '1', 0x00, 'a', 0x00, 'd', 0x00, 'e', 0x00, '9', 0x00, '}', 0x00, 0x00, 0x00 // 78 bytes }; -#endif - // current packet USB_Setup_TypeDef setup; uint8_t usbdata[0x100]; @@ -374,34 +394,36 @@ int current_int0_alt_setting = 0; // packet read and write void *USB_ReadPacket(void *dest, uint16_t len) { - uint32_t i=0; - uint32_t count32b = (len + 3) / 4; + uint32_t *dest_copy = (uint32_t *)dest; + uint32_t count32b = (len + 3U) / 4U; - for ( i = 0; i < count32b; i++, dest += 4 ) { - // packed? - *(__attribute__((__packed__)) uint32_t *)dest = USBx_DFIFO(0); + for (uint32_t i = 0; i < count32b; i++) { + *dest_copy = USBx_DFIFO(0); + dest_copy++; } - return ((void *)dest); + return ((void *)dest_copy); } -void USB_WritePacket(const uint8_t *src, uint16_t len, uint32_t ep) { +void USB_WritePacket(const void *src, uint16_t len, uint32_t ep) { #ifdef DEBUG_USB puts("writing "); hexdump(src, len); #endif - uint8_t numpacket = (len+(MAX_RESP_LEN-1))/MAX_RESP_LEN; - uint32_t count32b = 0, i = 0; - count32b = (len + 3) / 4; + uint8_t numpacket = (len + (MAX_RESP_LEN - 1U)) / MAX_RESP_LEN; + uint32_t count32b = 0; + count32b = (len + 3U) / 4U; - // bullshit + // TODO: revisit this USBx_INEP(ep)->DIEPTSIZ = ((numpacket << 19) & USB_OTG_DIEPTSIZ_PKTCNT) | (len & USB_OTG_DIEPTSIZ_XFRSIZ); USBx_INEP(ep)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA); // load the FIFO - for (i = 0; i < count32b; i++, src += 4) { - USBx_DFIFO(ep) = *((__attribute__((__packed__)) uint32_t *)src); + const uint32_t *src_copy = (const uint32_t *)src; + for (uint32_t i = 0; i < count32b; i++) { + USBx_DFIFO(ep) = *src_copy; + src_copy++; } } @@ -413,11 +435,11 @@ void USB_WritePacket_EP0(uint8_t *src, uint16_t len) { hexdump(src, len); #endif - uint16_t wplen = min(len, 0x40); + uint16_t wplen = MIN(len, 0x40); USB_WritePacket(src, wplen, 0); if (wplen < len) { - ep0_txdata = src + wplen; + ep0_txdata = &src[wplen]; ep0_txlen = len - wplen; USBx_DEVICE->DIEPEMPMSK |= 1; } else { @@ -425,7 +447,7 @@ void USB_WritePacket_EP0(uint8_t *src, uint16_t len) { } } -void usb_reset() { +void usb_reset(void) { // unmask endpoint interrupts, so many sets USBx_DEVICE->DAINT = 0xFFFFFFFF; USBx_DEVICE->DAINTMSK = 0xFFFFFFFF; @@ -449,10 +471,10 @@ void usb_reset() { USBx->GRXFSIZ = 0x40; // 0x100 to offset past GRXFSIZ - USBx->DIEPTXF0_HNPTXFSIZ = (0x40 << 16) | 0x40; + USBx->DIEPTXF0_HNPTXFSIZ = (0x40U << 16) | 0x40U; // EP1, massive - USBx->DIEPTXF[0] = (0x40 << 16) | 0x80; + USBx->DIEPTXF[0] = (0x40U << 16) | 0x80U; // flush TX fifo USBx->GRSTCTL = USB_OTG_GRSTCTL_TXFFLSH | USB_OTG_GRSTCTL_TXFNUM_4; @@ -465,34 +487,36 @@ void usb_reset() { USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK; // ready to receive setup packets - USBx_OUTEP(0)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) | (3 * 8); + USBx_OUTEP(0)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19)) | (3U << 3); } char to_hex_char(int a) { + char ret; if (a < 10) { - return '0' + a; + ret = '0' + a; } else { - return 'a' + (a-10); + ret = 'a' + (a - 10); } + return ret; } -void usb_setup() { +void usb_setup(void) { int resp_len; // setup packet is ready switch (setup.b.bRequest) { case USB_REQ_SET_CONFIGURATION: // enable other endpoints, has to be here? - USBx_INEP(1)->DIEPCTL = (0x40 & USB_OTG_DIEPCTL_MPSIZ) | (2 << 18) | (1 << 22) | + USBx_INEP(1)->DIEPCTL = (0x40U & USB_OTG_DIEPCTL_MPSIZ) | (2U << 18) | (1U << 22) | USB_OTG_DIEPCTL_SD0PID_SEVNFRM | USB_OTG_DIEPCTL_USBAEP; USBx_INEP(1)->DIEPINT = 0xFF; - USBx_OUTEP(2)->DOEPTSIZ = (1 << 19) | 0x40; - USBx_OUTEP(2)->DOEPCTL = (0x40 & USB_OTG_DOEPCTL_MPSIZ) | (2 << 18) | + USBx_OUTEP(2)->DOEPTSIZ = (1U << 19) | 0x40U; + USBx_OUTEP(2)->DOEPCTL = (0x40U & USB_OTG_DOEPCTL_MPSIZ) | (2U << 18) | USB_OTG_DOEPCTL_SD0PID_SEVNFRM | USB_OTG_DOEPCTL_USBAEP; USBx_OUTEP(2)->DOEPINT = 0xFF; - USBx_OUTEP(3)->DOEPTSIZ = (1 << 19) | 0x40; - USBx_OUTEP(3)->DOEPCTL = (0x40 & USB_OTG_DOEPCTL_MPSIZ) | (2 << 18) | + USBx_OUTEP(3)->DOEPTSIZ = (1U << 19) | 0x40U; + USBx_OUTEP(3)->DOEPCTL = (0x40U & USB_OTG_DOEPCTL_MPSIZ) | (2U << 18) | USB_OTG_DOEPCTL_SD0PID_SEVNFRM | USB_OTG_DOEPCTL_USBAEP; USBx_OUTEP(3)->DOEPINT = 0xFF; @@ -505,7 +529,7 @@ void usb_setup() { break; case USB_REQ_SET_ADDRESS: // set now? - USBx_DEVICE->DCFG |= ((setup.b.wValue.w & 0x7f) << 4); + USBx_DEVICE->DCFG |= ((setup.b.wValue.w & 0x7fU) << 4); #ifdef DEBUG_USB puts(" set address\n"); @@ -525,57 +549,55 @@ void usb_setup() { //puts(" writing device descriptor\n"); // setup transfer - USB_WritePacket(device_desc, min(sizeof(device_desc), setup.b.wLength.w), 0); + USB_WritePacket(device_desc, MIN(sizeof(device_desc), setup.b.wLength.w), 0); USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; //puts("D"); break; case USB_DESC_TYPE_CONFIGURATION: - USB_WritePacket(configuration_desc, min(sizeof(configuration_desc), setup.b.wLength.w), 0); + USB_WritePacket(configuration_desc, MIN(sizeof(configuration_desc), setup.b.wLength.w), 0); USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; case USB_DESC_TYPE_DEVICE_QUALIFIER: - USB_WritePacket(device_qualifier, min(sizeof(device_qualifier), setup.b.wLength.w), 0); + USB_WritePacket(device_qualifier, MIN(sizeof(device_qualifier), setup.b.wLength.w), 0); USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; case USB_DESC_TYPE_STRING: switch (setup.b.wValue.bw.msb) { case STRING_OFFSET_LANGID: - USB_WritePacket((uint8_t*)string_language_desc, min(sizeof(string_language_desc), setup.b.wLength.w), 0); + USB_WritePacket((uint8_t*)string_language_desc, MIN(sizeof(string_language_desc), setup.b.wLength.w), 0); break; case STRING_OFFSET_IMANUFACTURER: - USB_WritePacket((uint8_t*)string_manufacturer_desc, min(sizeof(string_manufacturer_desc), setup.b.wLength.w), 0); + USB_WritePacket((uint8_t*)string_manufacturer_desc, MIN(sizeof(string_manufacturer_desc), setup.b.wLength.w), 0); break; case STRING_OFFSET_IPRODUCT: - USB_WritePacket((uint8_t*)string_product_desc, min(sizeof(string_product_desc), setup.b.wLength.w), 0); + USB_WritePacket((uint8_t*)string_product_desc, MIN(sizeof(string_product_desc), setup.b.wLength.w), 0); break; case STRING_OFFSET_ISERIAL: - #ifdef PANDA - resp[0] = 0x02 + 12*4; + #ifdef UID_BASE + resp[0] = 0x02 + (12 * 4); resp[1] = 0x03; // 96 bits = 12 bytes for (int i = 0; i < 12; i++){ uint8_t cc = ((uint8_t *)UID_BASE)[i]; - resp[2 + i*4 + 0] = to_hex_char((cc>>4)&0xF); - resp[2 + i*4 + 1] = '\0'; - resp[2 + i*4 + 2] = to_hex_char((cc>>0)&0xF); - resp[2 + i*4 + 3] = '\0'; + resp[2 + (i * 4) + 0] = to_hex_char((cc >> 4) & 0xFU); + resp[2 + (i * 4) + 1] = '\0'; + resp[2 + (i * 4) + 2] = to_hex_char((cc >> 0) & 0xFU); + resp[2 + (i * 4) + 3] = '\0'; } - USB_WritePacket(resp, min(resp[0], setup.b.wLength.w), 0); + USB_WritePacket(resp, MIN(resp[0], setup.b.wLength.w), 0); #else - USB_WritePacket((const uint8_t *)string_serial_desc, min(sizeof(string_serial_desc), setup.b.wLength.w), 0); + USB_WritePacket((const uint8_t *)string_serial_desc, MIN(sizeof(string_serial_desc), setup.b.wLength.w), 0); #endif break; - #ifdef PANDA case STRING_OFFSET_ICONFIGURATION: - USB_WritePacket((uint8_t*)string_configuration_desc, min(sizeof(string_configuration_desc), setup.b.wLength.w), 0); + USB_WritePacket((uint8_t*)string_configuration_desc, MIN(sizeof(string_configuration_desc), setup.b.wLength.w), 0); break; case 238: - USB_WritePacket((uint8_t*)string_238_desc, min(sizeof(string_238_desc), setup.b.wLength.w), 0); + USB_WritePacket((uint8_t*)string_238_desc, MIN(sizeof(string_238_desc), setup.b.wLength.w), 0); break; - #endif default: // nothing USB_WritePacket(0, 0, 0); @@ -583,12 +605,10 @@ void usb_setup() { } USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; - #ifdef PANDA case USB_DESC_TYPE_BINARY_OBJECT_STORE: - USB_WritePacket(binary_object_store_desc, min(sizeof(binary_object_store_desc), setup.b.wLength.w), 0); + USB_WritePacket(binary_object_store_desc, MIN(sizeof(binary_object_store_desc), setup.b.wLength.w), 0); USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; - #endif default: // nothing here? USB_WritePacket(0, 0, 0); @@ -609,11 +629,10 @@ void usb_setup() { USB_WritePacket(0, 0, 0); USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; - #ifdef PANDA case WEBUSB_VENDOR_CODE: switch (setup.b.wIndex.w) { case WEBUSB_REQ_GET_URL: - USB_WritePacket(webusb_url_descriptor, min(sizeof(webusb_url_descriptor), setup.b.wLength.w), 0); + USB_WritePacket(webusb_url_descriptor, MIN(sizeof(webusb_url_descriptor), setup.b.wLength.w), 0); USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; default: @@ -627,29 +646,28 @@ void usb_setup() { switch (setup.b.wIndex.w) { // winusb 2.0 descriptor from BOS case WINUSB_REQ_GET_DESCRIPTOR: - USB_WritePacket_EP0((uint8_t*)winusb_20_desc, min(sizeof(winusb_20_desc), setup.b.wLength.w)); + USB_WritePacket_EP0((uint8_t*)winusb_20_desc, MIN(sizeof(winusb_20_desc), setup.b.wLength.w)); break; // Extended Compat ID OS Descriptor case WINUSB_REQ_GET_COMPATID_DESCRIPTOR: - USB_WritePacket_EP0((uint8_t*)winusb_ext_compatid_os_desc, min(sizeof(winusb_ext_compatid_os_desc), setup.b.wLength.w)); + USB_WritePacket_EP0((uint8_t*)winusb_ext_compatid_os_desc, MIN(sizeof(winusb_ext_compatid_os_desc), setup.b.wLength.w)); break; // Extended Properties OS Descriptor case WINUSB_REQ_GET_EXT_PROPS_OS: - USB_WritePacket_EP0((uint8_t*)winusb_ext_prop_os_desc, min(sizeof(winusb_ext_prop_os_desc), setup.b.wLength.w)); + USB_WritePacket_EP0((uint8_t*)winusb_ext_prop_os_desc, MIN(sizeof(winusb_ext_prop_os_desc), setup.b.wLength.w)); break; default: USB_WritePacket_EP0(0, 0); } break; - #endif default: resp_len = usb_cb_control_msg(&setup, resp, 1); - USB_WritePacket(resp, min(resp_len, setup.b.wLength.w), 0); + USB_WritePacket(resp, MIN(resp_len, setup.b.wLength.w), 0); USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; } } -void usb_init() { +void usb_init(void) { // full speed PHY, do reset and remove power down /*puth(USBx->GRSTCTL); puts(" resetting PHY\n");*/ @@ -665,7 +683,7 @@ void usb_init() { USBx->GUSBCFG = USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_FDMOD; // slowest timings - USBx->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT); + USBx->GUSBCFG |= ((USBD_FS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT); // power up the PHY #ifdef STM32F4 @@ -714,7 +732,6 @@ void usb_init() { USBx->GAHBCFG = USB_OTG_GAHBCFG_GINT; // DCTL startup value is 2 on new chip, 0 on old chip - // THIS IS FUCKING BULLSHIT USBx_DEVICE->DCTL = 0; // enable the IRQ @@ -742,27 +759,27 @@ void usb_irqhandler(void) { puts(" USB interrupt!\n"); #endif - if (gintsts & USB_OTG_GINTSTS_CIDSCHG) { + if ((gintsts & USB_OTG_GINTSTS_CIDSCHG) != 0) { puts("connector ID status change\n"); } - if (gintsts & USB_OTG_GINTSTS_ESUSP) { + if ((gintsts & USB_OTG_GINTSTS_ESUSP) != 0) { puts("ESUSP detected\n"); } - if (gintsts & USB_OTG_GINTSTS_USBRST) { + if ((gintsts & USB_OTG_GINTSTS_USBRST) != 0) { puts("USB reset\n"); usb_reset(); } - if (gintsts & USB_OTG_GINTSTS_ENUMDNE) { + if ((gintsts & USB_OTG_GINTSTS_ENUMDNE) != 0) { puts("enumeration done"); // Full speed, ENUMSPD //puth(USBx_DEVICE->DSTS); puts("\n"); } - if (gintsts & USB_OTG_GINTSTS_OTGINT) { + if ((gintsts & USB_OTG_GINTSTS_OTGINT) != 0) { puts("OTG int:"); puth(USBx->GOTGINT); puts("\n"); @@ -772,24 +789,25 @@ void usb_irqhandler(void) { } // RX FIFO first - if (gintsts & USB_OTG_GINTSTS_RXFLVL) { + if ((gintsts & USB_OTG_GINTSTS_RXFLVL) != 0) { // 1. Read the Receive status pop register volatile unsigned int rxst = USBx->GRXSTSP; + int status = (rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17; #ifdef DEBUG_USB puts(" RX FIFO:"); puth(rxst); puts(" status: "); - puth((rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17); + puth(status); puts(" len: "); puth((rxst & USB_OTG_GRXSTSP_BCNT) >> 4); puts("\n"); #endif - if (((rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT) { + if (status == STS_DATA_UPDT) { int endpoint = (rxst & USB_OTG_GRXSTSP_EPNUM); int len = (rxst & USB_OTG_GRXSTSP_BCNT) >> 4; - USB_ReadPacket(&usbdata, len); + (void)USB_ReadPacket(&usbdata, len); #ifdef DEBUG_USB puts(" data "); puth(len); @@ -804,13 +822,15 @@ void usb_irqhandler(void) { if (endpoint == 3) { usb_cb_ep3_out(usbdata, len, 1); } - } else if (((rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT) { - USB_ReadPacket(&setup, 8); + } else if (status == STS_SETUP_UPDT) { + (void)USB_ReadPacket(&setup, 8); #ifdef DEBUG_USB puts(" setup "); hexdump(&setup, 8); puts("\n"); #endif + } else { + // status is neither STS_DATA_UPDT or STS_SETUP_UPDT, skip } } @@ -834,7 +854,7 @@ void usb_irqhandler(void) { USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK | USB_OTG_DCTL_CGINAK; } - if (gintsts & USB_OTG_GINTSTS_SRQINT) { + if ((gintsts & USB_OTG_GINTSTS_SRQINT) != 0) { // we want to do "A-device host negotiation protocol" since we are the A-device /*puts("start request\n"); puth(USBx->GOTGCTL); @@ -845,7 +865,7 @@ void usb_irqhandler(void) { } // out endpoint hit - if (gintsts & USB_OTG_GINTSTS_OEPINT) { + if ((gintsts & USB_OTG_GINTSTS_OEPINT) != 0) { #ifdef DEBUG_USB puts(" 0:"); puth(USBx_OUTEP(0)->DOEPINT); @@ -860,40 +880,42 @@ void usb_irqhandler(void) { puts(" OUT ENDPOINT\n"); #endif - if (USBx_OUTEP(2)->DOEPINT & USB_OTG_DOEPINT_XFRC) { + if ((USBx_OUTEP(2)->DOEPINT & USB_OTG_DOEPINT_XFRC) != 0) { #ifdef DEBUG_USB puts(" OUT2 PACKET XFRC\n"); #endif - USBx_OUTEP(2)->DOEPTSIZ = (1 << 19) | 0x40; + USBx_OUTEP(2)->DOEPTSIZ = (1U << 19) | 0x40U; USBx_OUTEP(2)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; } - if (USBx_OUTEP(3)->DOEPINT & USB_OTG_DOEPINT_XFRC) { + if ((USBx_OUTEP(3)->DOEPINT & USB_OTG_DOEPINT_XFRC) != 0) { #ifdef DEBUG_USB puts(" OUT3 PACKET XFRC\n"); #endif - USBx_OUTEP(3)->DOEPTSIZ = (1 << 19) | 0x40; + USBx_OUTEP(3)->DOEPTSIZ = (1U << 19) | 0x40U; USBx_OUTEP(3)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; - } else if (USBx_OUTEP(3)->DOEPINT & 0x2000) { + } else if ((USBx_OUTEP(3)->DOEPINT & 0x2000) != 0) { #ifdef DEBUG_USB puts(" OUT3 PACKET WTF\n"); #endif // if NAK was set trigger this, unknown interrupt - USBx_OUTEP(3)->DOEPTSIZ = (1 << 19) | 0x40; + USBx_OUTEP(3)->DOEPTSIZ = (1U << 19) | 0x40U; USBx_OUTEP(3)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; - } else if (USBx_OUTEP(3)->DOEPINT) { + } else if ((USBx_OUTEP(3)->DOEPINT) != 0) { puts("OUTEP3 error "); puth(USBx_OUTEP(3)->DOEPINT); puts("\n"); + } else { + // USBx_OUTEP(3)->DOEPINT is 0, ok to skip } - if (USBx_OUTEP(0)->DOEPINT & USB_OTG_DIEPINT_XFRC) { + if ((USBx_OUTEP(0)->DOEPINT & USB_OTG_DIEPINT_XFRC) != 0) { // ready for next packet - USBx_OUTEP(0)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) | (1 * 8); + USBx_OUTEP(0)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19)) | (1U << 3); } // respond to setup packets - if (USBx_OUTEP(0)->DOEPINT & USB_OTG_DOEPINT_STUP) { + if ((USBx_OUTEP(0)->DOEPINT & USB_OTG_DOEPINT_STUP) != 0) { usb_setup(); } @@ -903,7 +925,7 @@ void usb_irqhandler(void) { } // interrupt endpoint hit (Page 1221) - if (gintsts & USB_OTG_GINTSTS_IEPINT) { + if ((gintsts & USB_OTG_GINTSTS_IEPINT) != 0) { #ifdef DEBUG_USB puts(" "); puth(USBx_INEP(0)->DIEPINT); @@ -918,8 +940,8 @@ void usb_irqhandler(void) { // No need to set NAK in OTG_DIEPCTL0 when nothing to send, // Appears USB core automatically sets NAK. WritePacket clears it. - // Handle the two interface alternate settings. Setting 0 is has - // EP1 as bulk. Setting 1 has EP1 as interrupt. The code to handle + // Handle the two interface alternate settings. Setting 0 has EP1 + // as bulk. Setting 1 has EP1 as interrupt. The code to handle // these two EP variations are very similar and can be // restructured for smaller code footprint. Keeping split out for // now for clarity. @@ -928,7 +950,7 @@ void usb_irqhandler(void) { switch (current_int0_alt_setting) { case 0: ////// Bulk config // *** IN token received when TxFIFO is empty - if (USBx_INEP(1)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) { + if ((USBx_INEP(1)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) != 0) { #ifdef DEBUG_USB puts(" IN PACKET QUEUE\n"); #endif @@ -939,7 +961,7 @@ void usb_irqhandler(void) { case 1: ////// Interrupt config // *** IN token received when TxFIFO is empty - if (USBx_INEP(1)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) { + if ((USBx_INEP(1)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) != 0) { #ifdef DEBUG_USB puts(" IN PACKET QUEUE\n"); #endif @@ -950,19 +972,22 @@ void usb_irqhandler(void) { } } break; + default: + puts("current_int0_alt_setting value invalid\n"); + break; } - if (USBx_INEP(0)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) { + if ((USBx_INEP(0)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) != 0) { #ifdef DEBUG_USB puts(" IN PACKET QUEUE\n"); #endif - if (ep0_txlen != 0 && (USBx_INEP(0)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= 0x40) { - uint16_t len = min(ep0_txlen, 0x40); + if ((ep0_txlen != 0U) && ((USBx_INEP(0)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= 0x40U)) { + uint16_t len = MIN(ep0_txlen, 0x40); USB_WritePacket(ep0_txdata, len, 0); - ep0_txdata += len; + ep0_txdata = &ep0_txdata[len]; ep0_txlen -= len; - if (ep0_txlen == 0) { + if (ep0_txlen == 0U) { ep0_txdata = NULL; USBx_DEVICE->DIEPEMPMSK &= ~1; USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; diff --git a/panda/board/get_sdk.sh b/panda/board/get_sdk.sh index 7b8d1f9154c0ac..3a009a5a13173f 100755 --- a/panda/board/get_sdk.sh +++ b/panda/board/get_sdk.sh @@ -1,3 +1,3 @@ #!/bin/bash sudo apt-get install gcc-arm-none-eabi python-pip -sudo pip2 install libusb1 pycrypto requests +sudo pip install libusb1 pycrypto requests diff --git a/panda/board/get_sdk_mac.sh b/panda/board/get_sdk_mac.sh index a6f641dce12116..a0a919f7d85e04 100755 --- a/panda/board/get_sdk_mac.sh +++ b/panda/board/get_sdk_mac.sh @@ -2,4 +2,4 @@ # Need formula for gcc brew tap ArmMbed/homebrew-formulae brew install python dfu-util arm-none-eabi-gcc -pip2 install libusb1 pycrypto requests +pip install --user libusb1 pycrypto requests diff --git a/panda/board/gpio.h b/panda/board/gpio.h index 7bd24ecbb7c32d..f33196e8fa37da 100644 --- a/panda/board/gpio.h +++ b/panda/board/gpio.h @@ -1,407 +1,4 @@ -#ifdef STM32F4 - #include "stm32f4xx_hal_gpio_ex.h" -#else - #include "stm32f2xx_hal_gpio_ex.h" -#endif - -// ********************* dynamic configuration detection ********************* - -#define PANDA_REV_AB 0 -#define PANDA_REV_C 1 - -#define PULL_EFFECTIVE_DELAY 10 - -int has_external_debug_serial = 0; -int is_giant_panda = 0; -int is_entering_bootmode = 0; -int revision = PANDA_REV_AB; -int is_grey_panda = 0; - -int detect_with_pull(GPIO_TypeDef *GPIO, int pin, int mode) { - set_gpio_mode(GPIO, pin, MODE_INPUT); - set_gpio_pullup(GPIO, pin, mode); - for (volatile int i=0; iCR |= RCC_CR_HSEON; - while ((RCC->CR & RCC_CR_HSERDY) == 0); - - // divide shit - RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV4; - #ifdef PANDA - RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 | - RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE; - #else - #ifdef PEDAL - // comma pedal has a 16mhz crystal - RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 | - RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE; - #else - // NEO board has a 8mhz crystal - RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 | - RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLSRC_HSE; - #endif - #endif - - // start PLL - RCC->CR |= RCC_CR_PLLON; - while ((RCC->CR & RCC_CR_PLLRDY) == 0); - - // Configure Flash prefetch, Instruction cache, Data cache and wait state - // *** without this, it breaks *** - FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS; - - // switch to PLL - RCC->CFGR |= RCC_CFGR_SW_PLL; - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); - - // *** running on PLL *** -} - -void periph_init() { - // enable GPIOB, UART2, CAN, USB clock - RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; - RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; - RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; - RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; - - RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; - RCC->APB1ENR |= RCC_APB1ENR_USART2EN; - RCC->APB1ENR |= RCC_APB1ENR_USART3EN; - #ifdef PANDA - RCC->APB1ENR |= RCC_APB1ENR_UART5EN; - #endif - RCC->APB1ENR |= RCC_APB1ENR_CAN1EN; - RCC->APB1ENR |= RCC_APB1ENR_CAN2EN; - #ifdef CAN3 - RCC->APB1ENR |= RCC_APB1ENR_CAN3EN; - #endif - RCC->APB1ENR |= RCC_APB1ENR_DACEN; - RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; - RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; - RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; - RCC->APB2ENR |= RCC_APB2ENR_USART1EN; - RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN; - RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; - RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; - RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; - - // needed? - RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; -} - -// ********************* setters ********************* - -void set_can_enable(CAN_TypeDef *CAN, int enabled) { - // enable CAN busses - if (CAN == CAN1) { - #ifdef PANDA - // CAN1_EN - set_gpio_output(GPIOC, 1, !enabled); - #else - #ifdef PEDAL - // CAN1_EN (not flipped) - set_gpio_output(GPIOB, 3, !enabled); - #else - // CAN1_EN - set_gpio_output(GPIOB, 3, enabled); - #endif - #endif - } else if (CAN == CAN2) { - #ifdef PANDA - // CAN2_EN - set_gpio_output(GPIOC, 13, !enabled); - #else - // CAN2_EN - set_gpio_output(GPIOB, 4, enabled); - #endif - #ifdef CAN3 - } else if (CAN == CAN3) { - // CAN3_EN - set_gpio_output(GPIOA, 0, !enabled); - #endif - } -} - -#ifdef PANDA - #define LED_RED 9 - #define LED_GREEN 7 - #define LED_BLUE 6 -#else - #define LED_RED 10 - #define LED_GREEN 11 - #define LED_BLUE -1 -#endif - -void set_led(int led_num, int on) { - if (led_num == -1) return; - - #ifdef PANDA - set_gpio_output(GPIOC, led_num, !on); - #else - set_gpio_output(GPIOB, led_num, !on); - #endif -} - -void set_can_mode(int can, int use_gmlan) { - // connects to CAN2 xcvr or GMLAN xcvr - if (use_gmlan) { - if (can == 1) { - // B5,B6: disable normal mode - set_gpio_mode(GPIOB, 5, MODE_INPUT); - set_gpio_mode(GPIOB, 6, MODE_INPUT); - - // B12,B13: gmlan mode - set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2); - set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2); -#ifdef CAN3 - } else if (revision == PANDA_REV_C && can == 2) { - // A8,A15: disable normal mode - set_gpio_mode(GPIOA, 8, MODE_INPUT); - set_gpio_mode(GPIOA, 15, MODE_INPUT); - - // B3,B4: enable gmlan mode - set_gpio_alternate(GPIOB, 3, GPIO_AF11_CAN3); - set_gpio_alternate(GPIOB, 4, GPIO_AF11_CAN3); -#endif - } - } else { - if (can == 1) { - // B12,B13: disable gmlan mode - set_gpio_mode(GPIOB, 12, MODE_INPUT); - set_gpio_mode(GPIOB, 13, MODE_INPUT); - - // B5,B6: normal mode - set_gpio_alternate(GPIOB, 5, GPIO_AF9_CAN2); - set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2); -#ifdef CAN3 - } else if (can == 2) { - if(revision == PANDA_REV_C){ - // B3,B4: disable gmlan mode - set_gpio_mode(GPIOB, 3, MODE_INPUT); - set_gpio_mode(GPIOB, 4, MODE_INPUT); - } - // A8,A15: normal mode - set_gpio_alternate(GPIOA, 8, GPIO_AF11_CAN3); - set_gpio_alternate(GPIOA, 15, GPIO_AF11_CAN3); -#endif - } - } -} - -#define USB_POWER_NONE 0 -#define USB_POWER_CLIENT 1 -#define USB_POWER_CDP 2 -#define USB_POWER_DCP 3 - -int usb_power_mode = USB_POWER_NONE; - -void set_usb_power_mode(int mode) { - switch (mode) { - case USB_POWER_CLIENT: - // B2,A13: set client mode - set_gpio_output(GPIOB, 2, 0); - set_gpio_output(GPIOA, 13, 1); - break; - case USB_POWER_CDP: - // B2,A13: set CDP mode - set_gpio_output(GPIOB, 2, 1); - set_gpio_output(GPIOA, 13, 1); - break; - case USB_POWER_DCP: - // B2,A13: set DCP mode on the charger (breaks USB!) - set_gpio_output(GPIOB, 2, 0); - set_gpio_output(GPIOA, 13, 0); - break; - } - usb_power_mode = mode; -} - -#define ESP_DISABLED 0 -#define ESP_ENABLED 1 -#define ESP_BOOTMODE 2 - -void set_esp_mode(int mode) { - switch (mode) { - case ESP_DISABLED: - // ESP OFF - set_gpio_output(GPIOC, 14, 0); - set_gpio_output(GPIOC, 5, 0); - break; - case ESP_ENABLED: - // ESP ON - set_gpio_output(GPIOC, 14, 1); - set_gpio_output(GPIOC, 5, 1); - break; - case ESP_BOOTMODE: - set_gpio_output(GPIOC, 14, 1); - set_gpio_output(GPIOC, 5, 0); - break; - } -} - -// ********************* big init function ********************* - -// board specific -void gpio_init() { - // pull low to hold ESP in reset?? - // enable OTG out tied to ground - GPIOA->ODR = 0; - GPIOB->ODR = 0; - GPIOA->PUPDR = 0; - //GPIOC->ODR = 0; - GPIOB->AFR[0] = 0; - GPIOB->AFR[1] = 0; - - // C2,C3: analog mode, voltage and current sense - set_gpio_mode(GPIOC, 2, MODE_ANALOG); - set_gpio_mode(GPIOC, 3, MODE_ANALOG); - -#ifdef PEDAL - // comma pedal has inputs on C0 and C1 - set_gpio_mode(GPIOC, 0, MODE_ANALOG); - set_gpio_mode(GPIOC, 1, MODE_ANALOG); - // DAC outputs on A4 and A5 - // apparently they don't need GPIO setup -#endif - - // C8: FAN aka TIM3_CH4 - set_gpio_alternate(GPIOC, 8, GPIO_AF2_TIM3); - - // turn off LEDs and set mode - set_led(LED_RED, 0); - set_led(LED_GREEN, 0); - set_led(LED_BLUE, 0); - - // A11,A12: USB - set_gpio_alternate(GPIOA, 11, GPIO_AF10_OTG_FS); - set_gpio_alternate(GPIOA, 12, GPIO_AF10_OTG_FS); - GPIOA->OSPEEDR = GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12; - -#ifdef PANDA - // enable started_alt on the panda - set_gpio_pullup(GPIOA, 1, PULL_UP); - - // A2,A3: USART 2 for debugging - set_gpio_alternate(GPIOA, 2, GPIO_AF7_USART2); - set_gpio_alternate(GPIOA, 3, GPIO_AF7_USART2); - - // A9,A10: USART 1 for talking to the ESP - set_gpio_alternate(GPIOA, 9, GPIO_AF7_USART1); - set_gpio_alternate(GPIOA, 10, GPIO_AF7_USART1); - - // B12: GMLAN, ignition sense, pull up - set_gpio_pullup(GPIOB, 12, PULL_UP); - - // A4,A5,A6,A7: setup SPI - set_gpio_alternate(GPIOA, 4, GPIO_AF5_SPI1); - set_gpio_alternate(GPIOA, 5, GPIO_AF5_SPI1); - set_gpio_alternate(GPIOA, 6, GPIO_AF5_SPI1); - set_gpio_alternate(GPIOA, 7, GPIO_AF5_SPI1); -#endif - - // B8,B9: CAN 1 -#ifdef STM32F4 - set_gpio_alternate(GPIOB, 8, GPIO_AF8_CAN1); - set_gpio_alternate(GPIOB, 9, GPIO_AF8_CAN1); -#else - set_gpio_alternate(GPIOB, 8, GPIO_AF9_CAN1); - set_gpio_alternate(GPIOB, 9, GPIO_AF9_CAN1); -#endif - set_can_enable(CAN1, 1); - - // B5,B6: CAN 2 - set_can_mode(1, 0); - set_can_enable(CAN2, 1); - - // A8,A15: CAN 3 - #ifdef CAN3 - set_can_mode(2, 0); - set_can_enable(CAN3, 1); - #endif - - /* GMLAN mode pins: - M0(B15) M1(B14) mode - ======================= - 0 0 sleep - 1 0 100kbit - 0 1 high voltage wakeup - 1 1 33kbit (normal) - */ - - // put gmlan transceiver in normal mode - set_gpio_output(GPIOB, 14, 1); - set_gpio_output(GPIOB, 15, 1); - - #ifdef PANDA - // K-line enable moved from B4->B7 to make room for GMLAN on CAN3 - if (revision == PANDA_REV_C) { - set_gpio_output(GPIOB, 7, 1); // REV C - } else { - set_gpio_output(GPIOB, 4, 1); // REV AB - } - - // C12,D2: K-Line setup on UART 5 - set_gpio_alternate(GPIOC, 12, GPIO_AF8_UART5); - set_gpio_alternate(GPIOD, 2, GPIO_AF8_UART5); - set_gpio_pullup(GPIOD, 2, PULL_UP); - - // L-line enable - set_gpio_output(GPIOA, 14, 1); - - // C10,C11: L-Line setup on USART 3 - set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3); - set_gpio_alternate(GPIOC, 11, GPIO_AF7_USART3); - set_gpio_pullup(GPIOC, 11, PULL_UP); - #endif - - if (revision == PANDA_REV_C) { - set_usb_power_mode(USB_POWER_CLIENT); - } -} - -// ********************* early bringup ********************* - +// Early bringup #define ENTER_BOOTLOADER_MAGIC 0xdeadbeef #define ENTER_SOFTLOADER_MAGIC 0xdeadc0de #define BOOT_NORMAL 0xdeadb111 @@ -409,7 +6,7 @@ void gpio_init() { extern void *g_pfnVectors; extern uint32_t enter_bootloader_mode; -void jump_to_bootloader() { +void jump_to_bootloader(void) { // do enter bootloader enter_bootloader_mode = 0; void (*bootloader)(void) = (void (*)(void)) (*((uint32_t *)0x1fff0004)); @@ -422,11 +19,17 @@ void jump_to_bootloader() { NVIC_SystemReset(); } -void early() { +void early(void) { + // Reset global critical depth + global_critical_depth = 0; + + // neccesary for DFU flashing on a non-power cycled white panda + enable_interrupts(); + // after it's been in the bootloader, things are initted differently, so we reset - if (enter_bootloader_mode != BOOT_NORMAL && - enter_bootloader_mode != ENTER_BOOTLOADER_MAGIC && - enter_bootloader_mode != ENTER_SOFTLOADER_MAGIC) { + if ((enter_bootloader_mode != BOOT_NORMAL) && + (enter_bootloader_mode != ENTER_BOOTLOADER_MAGIC) && + (enter_bootloader_mode != ENTER_SOFTLOADER_MAGIC)) { enter_bootloader_mode = BOOT_NORMAL; NVIC_SystemReset(); } @@ -434,9 +37,13 @@ void early() { // if wrong chip, reboot volatile unsigned int id = DBGMCU->IDCODE; #ifdef STM32F4 - if ((id&0xFFF) != 0x463) enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC; + if ((id & 0xFFFU) != 0x463U) { + enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC; + } #else - if ((id&0xFFF) != 0x411) enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC; + if ((id & 0xFFFU) != 0x411U) { + enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC; + } #endif // setup interrupt table @@ -449,30 +56,25 @@ void early() { GPIOA->ODR = 0; GPIOB->ODR = 0; GPIOC->ODR = 0; GPIOA->PUPDR = 0; GPIOB->PUPDR = 0; GPIOC->PUPDR = 0; - detect(); + detect_configuration(); + detect_board_type(); #ifdef PANDA // enable the ESP, disable ESP boot mode - // unless we are on a giant panda, then there's no ESP // dont disable on grey panda - if (is_giant_panda) { - set_esp_mode(ESP_DISABLED); - } else { - set_esp_mode(ESP_ENABLED); - } + current_board->set_esp_gps_mode(ESP_GPS_ENABLED); #endif if (enter_bootloader_mode == ENTER_BOOTLOADER_MAGIC) { #ifdef PANDA - set_esp_mode(ESP_DISABLED); + current_board->set_esp_gps_mode(ESP_GPS_DISABLED); #endif - set_led(LED_GREEN, 1); + current_board->set_led(LED_GREEN, 1); jump_to_bootloader(); } if (is_entering_bootmode) { enter_bootloader_mode = ENTER_SOFTLOADER_MAGIC; } -} - +} \ No newline at end of file diff --git a/panda/board/inc/cmsis_compiler.h b/panda/board/inc/cmsis_compiler.h new file mode 100644 index 00000000000000..d0f39eef67ed91 --- /dev/null +++ b/panda/board/inc/cmsis_compiler.h @@ -0,0 +1,284 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.1.0 + * @date 09. October 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6.6 LTM (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) + #include "cmsis_armclang_ltm.h" + + /* + * Arm Compiler above 6.10.1 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #define __RESTRICT __restrict + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + + diff --git a/panda/board/inc/cmsis_gcc.h b/panda/board/inc/cmsis_gcc.h index bb89fbba9e4000..3589d18b243b7d 100644 --- a/panda/board/inc/cmsis_gcc.h +++ b/panda/board/inc/cmsis_gcc.h @@ -1,48 +1,186 @@ /**************************************************************************//** * @file cmsis_gcc.h - * @brief CMSIS Cortex-M Core Function/Instruction Header File - * @version V4.30 - * @date 20. October 2015 + * @brief CMSIS compiler GCC header file + * @version V5.2.0 + * @date 08. May 2019 ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - 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 ARM 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 COPYRIGHT HOLDERS AND 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. - ---------------------------------------------------------------------------*/ - +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef __CMSIS_GCC_H #define __CMSIS_GCC_H /* ignore some GCC warnings */ -#if defined ( __GNUC__ ) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsign-conversion" #pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") #endif +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START + +/** + \brief Initializes data and bss sections + \details This default implementations initialized all data and additional bss + sections relying on .copy.table and .zero.table specified properly + in the used linker script. + + */ +__STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void) +{ + extern void _start(void) __NO_RETURN; + + typedef struct { + uint32_t const* src; + uint32_t* dest; + uint32_t wlen; + } __copy_table_t; + + typedef struct { + uint32_t* dest; + uint32_t wlen; + } __zero_table_t; + + extern const __copy_table_t __copy_table_start__; + extern const __copy_table_t __copy_table_end__; + extern const __zero_table_t __zero_table_start__; + extern const __zero_table_t __zero_table_end__; + + for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = pTable->src[i]; + } + } + + for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = 0u; + } + } + + _start(); +} + +#define __PROGRAM_START __cmsis_start +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP __StackTop +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT __StackLimit +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute((used, section(".vectors"))) +#endif /* ########################### Core Function Access ########################### */ /** \ingroup CMSIS_Core_FunctionInterface @@ -55,7 +193,7 @@ \details Enables IRQ interrupts by clearing the I-bit in the CPSR. Can only be executed in Privileged modes. */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) +__STATIC_FORCEINLINE void __enable_irq(void) { __ASM volatile ("cpsie i" : : : "memory"); } @@ -64,9 +202,9 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) /** \brief Disable IRQ Interrupts \details Disables IRQ interrupts by setting the I-bit in the CPSR. - Can only be executed in Privileged modes. + Can only be executed in Privileged modes. */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) +__STATIC_FORCEINLINE void __disable_irq(void) { __ASM volatile ("cpsid i" : : : "memory"); } @@ -77,7 +215,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) \details Returns the content of the Control Register. \return Control Register value */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) { uint32_t result; @@ -86,23 +224,52 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) } +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + /** \brief Set Control Register \details Writes the given value to the Control Register. \param [in] control Control Register value to set */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) { __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); } +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + /** \brief Get IPSR Register \details Returns the content of the IPSR Register. \return IPSR Register value */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) { uint32_t result; @@ -116,7 +283,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) \details Returns the content of the APSR Register. \return APSR Register value */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) +__STATIC_FORCEINLINE uint32_t __get_APSR(void) { uint32_t result; @@ -128,10 +295,9 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) /** \brief Get xPSR Register \details Returns the content of the xPSR Register. - - \return xPSR Register value + \return xPSR Register value */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) { uint32_t result; @@ -145,13 +311,29 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) \details Returns the current value of the Process Stack Pointer (PSP). \return PSP Register value */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) { - register uint32_t result; + uint32_t result; - __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); return(result); } +#endif /** @@ -159,36 +341,104 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) \details Assigns the given value to the Process Stack Pointer (PSP). \param [in] topOfProcStack Process Stack Pointer value to set */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) { - __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp"); + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); } +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + /** \brief Get Main Stack Pointer \details Returns the current value of the Main Stack Pointer (MSP). \return MSP Register value */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) +__STATIC_FORCEINLINE uint32_t __get_MSP(void) { - register uint32_t result; + uint32_t result; - __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); + __ASM volatile ("MRS %0, msp" : "=r" (result) ); return(result); } +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + /** \brief Set Main Stack Pointer \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} - \param [in] topOfMainStack Main Stack Pointer value to set + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) { - __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp"); + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); } +#endif /** @@ -196,13 +446,29 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOf \details Returns the current state of the priority mask bit from the Priority Mask Register. \return Priority Mask value */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) :: "memory"); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) { uint32_t result; - __ASM volatile ("MRS %0, primask" : "=r" (result) ); + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) :: "memory"); return(result); } +#endif /** @@ -210,20 +476,34 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) \details Assigns the given value to the Priority Mask Register. \param [in] priMask Priority Mask */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) { __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); } -#if (__CORTEX_M >= 0x03U) +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) /** \brief Enable FIQ \details Enables FIQ interrupts by clearing the F-bit in the CPSR. Can only be executed in Privileged modes. */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) +__STATIC_FORCEINLINE void __enable_fault_irq(void) { __ASM volatile ("cpsie f" : : : "memory"); } @@ -234,7 +514,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) \details Disables FIQ interrupts by setting the F-bit in the CPSR. Can only be executed in Privileged modes. */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) +__STATIC_FORCEINLINE void __disable_fault_irq(void) { __ASM volatile ("cpsid f" : : : "memory"); } @@ -245,7 +525,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void \details Returns the current value of the Base Priority register. \return Base Priority register value */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) { uint32_t result; @@ -254,15 +534,44 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) } +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + /** \brief Set Base Priority \details Assigns the given value to the Base Priority register. \param [in] basePri Base Priority value to set */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) { - __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); } +#endif /** @@ -271,9 +580,9 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t v or the new value increases the BASEPRI priority level. \param [in] basePri Base Priority value to set */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value) +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) { - __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory"); + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); } @@ -282,7 +591,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32 \details Returns the current value of the Fault Mask register. \return Fault Mask register value */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) { uint32_t result; @@ -291,38 +600,253 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void } +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + /** \brief Set Fault Mask \details Assigns the given value to the Fault Mask register. \param [in] faultMask Fault Mask value to set */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) { __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); } -#endif /* (__CORTEX_M >= 0x03U) */ +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ -#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) /** \brief Get FPSCR \details Returns the current value of the Floating Point Status/Control register. \return Floating Point Status/Control register value */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) -{ -#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else uint32_t result; - /* Empty asm statement works as a scheduling barrier */ - __ASM volatile (""); __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); - __ASM volatile (""); return(result); +#endif #else - return(0); + return(0U); #endif } @@ -332,19 +856,23 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) \details Assigns the given value to the Floating Point Status/Control register. \param [in] fpscr Floating Point Status/Control value to set */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) -{ -#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) - /* Empty asm statement works as a scheduling barrier */ - __ASM volatile (""); - __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); - __ASM volatile (""); +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; #endif } -#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */ - - /*@} end of CMSIS_Core_RegAccFunctions */ @@ -360,9 +888,11 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fps * Otherwise, use general registers, specified by constraint "r" */ #if defined (__thumb__) && !defined (__thumb2__) #define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) #define __CMSIS_GCC_USE_REG(r) "l" (r) #else #define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) #define __CMSIS_GCC_USE_REG(r) "r" (r) #endif @@ -370,41 +900,28 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fps \brief No Operation \details No Operation does nothing. This instruction can be used for code alignment purposes. */ -__attribute__((always_inline)) __STATIC_INLINE void __NOP(void) -{ - __ASM volatile ("nop"); -} - +#define __NOP() __ASM volatile ("nop") /** \brief Wait For Interrupt \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. */ -__attribute__((always_inline)) __STATIC_INLINE void __WFI(void) -{ - __ASM volatile ("wfi"); -} +#define __WFI() __ASM volatile ("wfi") /** \brief Wait For Event \details Wait For Event is a hint instruction that permits the processor to enter - a low-power state until one of a number of events occurs. + a low-power state until one of a number of events occurs. */ -__attribute__((always_inline)) __STATIC_INLINE void __WFE(void) -{ - __ASM volatile ("wfe"); -} +#define __WFE() __ASM volatile ("wfe") /** \brief Send Event \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. */ -__attribute__((always_inline)) __STATIC_INLINE void __SEV(void) -{ - __ASM volatile ("sev"); -} +#define __SEV() __ASM volatile ("sev") /** @@ -413,7 +930,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __SEV(void) so that all instructions following the ISB are fetched from cache or memory, after the instruction has been completed. */ -__attribute__((always_inline)) __STATIC_INLINE void __ISB(void) +__STATIC_FORCEINLINE void __ISB(void) { __ASM volatile ("isb 0xF":::"memory"); } @@ -424,7 +941,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __ISB(void) \details Acts as a special kind of Data Memory Barrier. It completes when all explicit memory accesses before this instruction complete. */ -__attribute__((always_inline)) __STATIC_INLINE void __DSB(void) +__STATIC_FORCEINLINE void __DSB(void) { __ASM volatile ("dsb 0xF":::"memory"); } @@ -435,7 +952,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __DSB(void) \details Ensures the apparent order of the explicit memory operations before and after the instruction, without ensuring their completion. */ -__attribute__((always_inline)) __STATIC_INLINE void __DMB(void) +__STATIC_FORCEINLINE void __DMB(void) { __ASM volatile ("dmb 0xF":::"memory"); } @@ -443,11 +960,11 @@ __attribute__((always_inline)) __STATIC_INLINE void __DMB(void) /** \brief Reverse byte order (32 bit) - \details Reverses the byte order in integer value. + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. \param [in] value Value to reverse \return Reversed value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value) +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) { #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) return __builtin_bswap32(value); @@ -455,41 +972,41 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value) uint32_t result; __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); + return result; #endif } /** \brief Reverse byte order (16 bit) - \details Reverses the byte order in two unsigned short values. + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. \param [in] value Value to reverse \return Reversed value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) { uint32_t result; __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); + return result; } /** - \brief Reverse byte order in signed short value - \details Reverses the byte order in a signed short value with sign extension to integer. + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. \param [in] value Value to reverse \return Reversed value */ -__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) { #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - return (short)__builtin_bswap16(value); + return (int16_t)__builtin_bswap16(value); #else - int32_t result; + int16_t result; __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); + return result; #endif } @@ -497,12 +1014,17 @@ __attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) /** \brief Rotate Right in unsigned value (32 bit) \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. - \param [in] value Value to rotate - \param [in] value Number of Bits to rotate + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate \return Rotated value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) { + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } return (op1 >> op2) | (op1 << (32U - op2)); } @@ -523,17 +1045,19 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint \param [in] value Value to reverse \return Reversed value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) { uint32_t result; -#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); #else - int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */ + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ result = value; /* r will be reversed bits of v; first get LSB of v */ - for (value >>= 1U; value; value >>= 1U) + for (value >>= 1U; value != 0U; value >>= 1U) { result <<= 1U; result |= value & 1U; @@ -541,7 +1065,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) } result <<= s; /* shift when v's highest bits are zero */ #endif - return(result); + return result; } @@ -551,18 +1075,36 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) \param [in] value Value to count the leading zeros \return number of leading zeros in value */ -#define __CLZ __builtin_clz - +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} -#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) /** \brief LDR Exclusive (8 bit) \details Executes a exclusive LDR instruction for 8 bit value. \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) { uint32_t result; @@ -584,7 +1126,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) { uint32_t result; @@ -606,7 +1148,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16 \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) { uint32_t result; @@ -623,7 +1165,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32 \return 0 Function succeeded \return 1 Function failed */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) { uint32_t result; @@ -640,7 +1182,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, \return 0 Function succeeded \return 1 Function failed */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) { uint32_t result; @@ -657,7 +1199,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, \return 0 Function succeeded \return 1 Function failed */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) { uint32_t result; @@ -670,22 +1212,31 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, \brief Remove the exclusive lock \details Removes the exclusive lock which is created by LDREX. */ -__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void) +__STATIC_FORCEINLINE void __CLREX(void) { __ASM volatile ("clrex" ::: "memory"); } +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) /** \brief Signed Saturate \details Saturates a signed value. - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (1..32) + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) \return Saturated value */ #define __SSAT(ARG1,ARG2) \ +__extension__ \ ({ \ - uint32_t __RES, __ARG1 = (ARG1); \ + int32_t __RES, __ARG1 = (ARG1); \ __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ __RES; \ }) @@ -694,11 +1245,12 @@ __attribute__((always_inline)) __STATIC_INLINE void __CLREX(void) /** \brief Unsigned Saturate \details Saturates an unsigned value. - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (0..31) + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) \return Saturated value */ #define __USAT(ARG1,ARG2) \ + __extension__ \ ({ \ uint32_t __RES, __ARG1 = (ARG1); \ __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ @@ -713,7 +1265,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __CLREX(void) \param [in] value Value to rotate \return Rotated value */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) { uint32_t result; @@ -728,17 +1280,17 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) \param [in] ptr Pointer to data \return value of type uint8_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr) +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) { uint32_t result; #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) ); + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); #else /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not accepted by assembler. So has to use following less efficient pattern. */ - __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); #endif return ((uint8_t) result); /* Add explicit type cast here */ } @@ -750,17 +1302,17 @@ __attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t \param [in] ptr Pointer to data \return value of type uint16_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr) +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) { uint32_t result; #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) ); + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); #else /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not accepted by assembler. So has to use following less efficient pattern. */ - __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); #endif return ((uint16_t) result); /* Add explicit type cast here */ } @@ -772,11 +1324,11 @@ __attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_ \param [in] ptr Pointer to data \return value of type uint32_t at (*ptr) */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr) +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) { uint32_t result; - __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) ); + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); return(result); } @@ -787,9 +1339,9 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t \param [in] value Value to store \param [in] ptr Pointer to location */ -__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) { - __ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } @@ -799,9 +1351,9 @@ __attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volat \param [in] value Value to store \param [in] ptr Pointer to location */ -__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) { - __ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); } @@ -811,12 +1363,249 @@ __attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, vola \param [in] value Value to store \param [in] ptr Pointer to location */ -__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr) +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) { - __ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) ); + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); } -#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */ +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ /*@}*/ /* end of group CMSIS_Core_InstructionInterface */ @@ -827,9 +1616,9 @@ __attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volat @{ */ -#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */ +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -837,7 +1626,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1 return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -845,7 +1634,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1 return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -853,7 +1642,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -861,7 +1650,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1 return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -869,7 +1658,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -878,7 +1667,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -886,7 +1675,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1 return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -894,7 +1683,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1 return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -902,7 +1691,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -910,7 +1699,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1 return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -918,7 +1707,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -927,7 +1716,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -935,7 +1724,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -943,7 +1732,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -951,7 +1740,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t o return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -959,7 +1748,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -967,7 +1756,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t o return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -975,7 +1764,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t o return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -983,7 +1772,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -991,7 +1780,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -999,7 +1788,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t o return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1007,7 +1796,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1015,7 +1804,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t o return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1023,7 +1812,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t o return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1031,7 +1820,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1039,7 +1828,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1047,7 +1836,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1 return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1055,7 +1844,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1063,7 +1852,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1 return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1071,7 +1860,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1 return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1079,7 +1868,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1087,7 +1876,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1095,7 +1884,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1 return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1103,7 +1892,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1111,7 +1900,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1 return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1119,7 +1908,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1 return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1127,7 +1916,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1 return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; @@ -1149,7 +1938,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op __RES; \ }) -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) { uint32_t result; @@ -1157,7 +1946,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1165,7 +1954,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t o return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) { uint32_t result; @@ -1173,7 +1962,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) { uint32_t result; @@ -1181,7 +1970,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t o return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) { uint32_t result; @@ -1189,7 +1978,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t o return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) { uint32_t result; @@ -1197,7 +1986,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t o return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; @@ -1205,7 +1994,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; @@ -1213,7 +2002,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t o return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; @@ -1230,7 +2019,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t o return(llr.w64); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; @@ -1247,7 +2036,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t return(llr.w64); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) { uint32_t result; @@ -1255,7 +2044,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t o return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) { uint32_t result; @@ -1263,7 +2052,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t o return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; @@ -1271,7 +2060,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; @@ -1279,7 +2068,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t o return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; @@ -1296,7 +2085,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t o return(llr.w64); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) { union llreg_u{ uint32_t w32[2]; @@ -1313,7 +2102,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t return(llr.w64); } -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) { uint32_t result; @@ -1321,7 +2110,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1 return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __QADD( int32_t op1, int32_t op2) +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) { int32_t result; @@ -1329,7 +2118,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __QADD( int32_t op1, return(result); } -__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __QSUB( int32_t op1, int32_t op2) +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) { int32_t result; @@ -1337,6 +2126,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __QSUB( int32_t op1, return(result); } +#if 0 #define __PKHBT(ARG1,ARG2,ARG3) \ ({ \ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ @@ -1353,8 +2143,15 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __QSUB( int32_t op1, __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ __RES; \ }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) { int32_t result; @@ -1362,12 +2159,11 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1 return(result); } -#endif /* (__CORTEX_M >= 0x04) */ +#endif /* (__ARM_FEATURE_DSP == 1) */ /*@} end of group CMSIS_SIMD_intrinsics */ -#if defined ( __GNUC__ ) #pragma GCC diagnostic pop -#endif #endif /* __CMSIS_GCC_H */ + diff --git a/panda/board/inc/cmsis_version.h b/panda/board/inc/cmsis_version.h new file mode 100644 index 00000000000000..bf57cf3e805348 --- /dev/null +++ b/panda/board/inc/cmsis_version.h @@ -0,0 +1,40 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.3 + * @date 24. June 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 3U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif + diff --git a/panda/board/inc/core_cm3.h b/panda/board/inc/core_cm3.h index b4ac4c7b05a799..0918c5eb4c827b 100644 --- a/panda/board/inc/core_cm3.h +++ b/panda/board/inc/core_cm3.h @@ -1,40 +1,30 @@ /**************************************************************************//** * @file core_cm3.h * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File - * @version V4.30 - * @date 20. October 2015 + * @version V5.1.0 + * @date 13. March 2019 ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - 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 ARM 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 COPYRIGHT HOLDERS AND 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. - ---------------------------------------------------------------------------*/ - +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif @@ -70,53 +60,15 @@ @{ */ +#include "cmsis_version.h" + /* CMSIS CM3 definitions */ -#define __CM3_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ -#define __CM3_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ #define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ - __CM3_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x03U) /*!< Cortex-M Core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - #define __STATIC_INLINE static inline - -#elif defined ( __TMS470__ ) - #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __CSMC__ ) - #define __packed - #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ - #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ - #define __STATIC_INLINE static inline + __CM3_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ -#else - #error Unknown compiler -#endif +#define __CORTEX_M (3U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all @@ -128,8 +80,8 @@ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #if defined __ARM_PCS_VFP +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif @@ -143,7 +95,7 @@ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif -#elif defined ( __TMS470__ ) +#elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" #endif @@ -160,8 +112,8 @@ #endif -#include "core_cmInstr.h" /* Core Instruction Access */ -#include "core_cmFunc.h" /* Core Function Access */ +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + #ifdef __cplusplus } @@ -191,7 +143,7 @@ #endif #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 4U + #define __NVIC_PRIO_BITS 3U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif @@ -308,9 +260,11 @@ typedef union struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ @@ -336,12 +290,15 @@ typedef union #define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ #define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ -#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ -#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ @@ -385,7 +342,7 @@ typedef struct __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[24U]; __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[24U]; + uint32_t RESERVED1[24U]; __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[24U]; __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ @@ -487,7 +444,7 @@ typedef struct #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ /* SCB Vector Table Offset Register Definitions */ -#if (__CM3_REV < 0x0201U) /* core r2p1 */ +#if defined (__CM3_REV) && (__CM3_REV < 0x0201U) /* core r2p1 */ #define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ #define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ @@ -602,6 +559,60 @@ typedef struct #define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ #define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + /* SCB Hard Fault Status Register Definitions */ #define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ #define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ @@ -645,7 +656,7 @@ typedef struct { uint32_t RESERVED0[1U]; __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ -#if ((defined __CM3_REV) && (__CM3_REV >= 0x200U)) +#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ #else uint32_t RESERVED1[1U]; @@ -657,6 +668,12 @@ typedef struct #define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ /* Auxiliary Control Register Definitions */ +#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ #define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ #define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ @@ -666,6 +683,7 @@ typedef struct #define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ #define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ +#endif /*@} end of group CMSIS_SCnotSCB */ @@ -746,10 +764,7 @@ typedef struct __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ uint32_t RESERVED2[15U]; __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ - uint32_t RESERVED3[29U]; - __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ - __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ - __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED3[32U]; uint32_t RESERVED4[43U]; __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ @@ -770,7 +785,7 @@ typedef struct /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ @@ -800,18 +815,6 @@ typedef struct #define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ #define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ -/* ITM Integration Write Register Definitions */ -#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ -#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ - -/* ITM Integration Read Register Definitions */ -#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ -#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ - -/* ITM Integration Mode Control Register Definitions */ -#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ -#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ - /* ITM Lock Status Register Definitions */ #define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ #define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ @@ -984,7 +987,7 @@ typedef struct */ typedef struct { - __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ @@ -995,7 +998,7 @@ typedef struct __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ uint32_t RESERVED3[759U]; - __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ uint32_t RESERVED4[1U]; @@ -1044,13 +1047,13 @@ typedef struct /* TPI Integration ETM Data Register Definitions (FIFO0) */ #define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ #define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ #define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ #define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ #define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ #define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ @@ -1065,18 +1068,21 @@ typedef struct #define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ /* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ /* TPI Integration ITM Data Register Definitions (FIFO1) */ #define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ #define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ #define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ #define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ #define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ #define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ @@ -1091,12 +1097,15 @@ typedef struct #define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ /* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ @@ -1118,16 +1127,16 @@ typedef struct #define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + /*@}*/ /* end of group CMSIS_TPI */ -#if (__MPU_PRESENT == 1U) +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_MPU Memory Protection Unit (MPU) @@ -1153,6 +1162,8 @@ typedef struct __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ } MPU_Type; +#define MPU_TYPE_RALIASES 4U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -1337,18 +1348,18 @@ typedef struct /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. - \param[in] value Value of the bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ -#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. - \param[in] value Value of register. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ -#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ @@ -1360,7 +1371,7 @@ typedef struct @{ */ -/* Memory mapping of Cortex-M3 Hardware */ +/* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ @@ -1379,7 +1390,7 @@ typedef struct #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ -#if (__MPU_PRESENT == 1U) +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ #endif @@ -1410,6 +1421,45 @@ typedef struct @{ */ +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + /** \brief Set Priority Grouping \details Sets the priority grouping field using the required unlock sequence. @@ -1419,7 +1469,7 @@ typedef struct priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ -__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ @@ -1428,7 +1478,7 @@ __STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB->AIRCR = reg_value; } @@ -1438,121 +1488,180 @@ __STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) \details Reads the priority grouping field from the NVIC Interrupt Controller. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ -__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) { return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** - \brief Enable External Interrupt - \details Enables a device-specific interrupt in the NVIC interrupt controller. - \param [in] IRQn External interrupt number. Value cannot be negative. + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. */ -__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } } /** - \brief Disable External Interrupt - \details Disables a device-specific interrupt in the NVIC interrupt controller. - \param [in] IRQn External interrupt number. Value cannot be negative. + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. */ -__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } } /** \brief Get Pending Interrupt - \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. - \param [in] IRQn Interrupt number. + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. + \note IRQn must not be negative. */ -__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } } /** \brief Set Pending Interrupt - \details Sets the pending bit of an external interrupt. - \param [in] IRQn Interrupt number. Value cannot be negative. + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. */ -__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } } /** \brief Clear Pending Interrupt - \details Clears the pending bit of an external interrupt. - \param [in] IRQn External interrupt number. Value cannot be negative. + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. */ -__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } } /** \brief Get Active Interrupt - \details Reads the active register in NVIC and returns the active bit. - \param [in] IRQn Interrupt number. + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. + \note IRQn must not be negative. */ -__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } } /** \brief Set Interrupt Priority - \details Sets the priority of an interrupt. - \note The priority cannot be set for every core interrupt. + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. */ -__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { - if ((int32_t)(IRQn) < 0) + if ((int32_t)(IRQn) >= 0) { - SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { - NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority - \details Reads the priority of an interrupt. - The interrupt number can be positive to specify an external (device specific) interrupt, - or negative to specify an internal (core) interrupt. + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ -__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { - if ((int32_t)(IRQn) < 0) + if ((int32_t)(IRQn) >= 0) { - return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { - return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } @@ -1609,11 +1718,43 @@ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGr } +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t vectors = (uint32_t )SCB->VTOR; + (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; + /* ARM Application Note 321 states that the M3 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t vectors = (uint32_t )SCB->VTOR; + return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); +} + + /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ -__STATIC_INLINE void NVIC_SystemReset(void) +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ @@ -1630,6 +1771,39 @@ __STATIC_INLINE void NVIC_SystemReset(void) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + /* ################################## SysTick function ############################################ */ @@ -1640,7 +1814,7 @@ __STATIC_INLINE void NVIC_SystemReset(void) @{ */ -#if (__Vendor_SysTickConfig == 0U) +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration @@ -1683,8 +1857,8 @@ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) @{ */ -extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ -#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ /** @@ -1761,3 +1935,4 @@ __STATIC_INLINE int32_t ITM_CheckChar (void) #endif /* __CORE_CM3_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ + diff --git a/panda/board/inc/core_cm4.h b/panda/board/inc/core_cm4.h index dc840ebf222138..0d40081a385dc1 100644 --- a/panda/board/inc/core_cm4.h +++ b/panda/board/inc/core_cm4.h @@ -1,40 +1,30 @@ /**************************************************************************//** * @file core_cm4.h * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File - * @version V4.30 - * @date 20. October 2015 + * @version V5.1.0 + * @date 13. March 2019 ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - 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 ARM 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 COPYRIGHT HOLDERS AND 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. - ---------------------------------------------------------------------------*/ - +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) #pragma clang system_header /* treat file as system include file */ #endif @@ -70,60 +60,22 @@ @{ */ -/* CMSIS CM4 definitions */ -#define __CM4_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ -#define __CM4_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ -#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ - __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x04U) /*!< Cortex-M Core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - #define __STATIC_INLINE static inline +#include "cmsis_version.h" -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - #define __STATIC_INLINE static inline - -#elif defined ( __TMS470__ ) - #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - #define __STATIC_INLINE static inline +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ -#elif defined ( __CSMC__ ) - #define __packed - #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ - #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ - #define __STATIC_INLINE static inline - -#else - #error Unknown compiler -#endif +#define __CORTEX_M (4U) /*!< Cortex-M Core */ /** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. */ #if defined ( __CC_ARM ) #if defined __TARGET_FPU_VFP - #if (__FPU_PRESENT == 1U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" @@ -133,9 +85,9 @@ #define __FPU_USED 0U #endif -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #if defined __ARM_PCS_VFP - #if (__FPU_PRESENT == 1) +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" @@ -147,7 +99,7 @@ #elif defined ( __GNUC__ ) #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #if (__FPU_PRESENT == 1U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" @@ -159,7 +111,7 @@ #elif defined ( __ICCARM__ ) #if defined __ARMVFP__ - #if (__FPU_PRESENT == 1U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" @@ -169,9 +121,9 @@ #define __FPU_USED 0U #endif -#elif defined ( __TMS470__ ) +#elif defined ( __TI_ARM__ ) #if defined __TI_VFP_SUPPORT__ - #if (__FPU_PRESENT == 1U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" @@ -183,7 +135,7 @@ #elif defined ( __TASKING__ ) #if defined __FPU_VFP__ - #if (__FPU_PRESENT == 1U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" @@ -195,7 +147,7 @@ #elif defined ( __CSMC__ ) #if ( __CSMC__ & 0x400U) - #if (__FPU_PRESENT == 1U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) #define __FPU_USED 1U #else #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" @@ -207,9 +159,8 @@ #endif -#include "core_cmInstr.h" /* Core Instruction Access */ -#include "core_cmFunc.h" /* Core Function Access */ -#include "core_cmSimd.h" /* Compiler specific SIMD Intrinsics */ +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + #ifdef __cplusplus } @@ -244,7 +195,7 @@ #endif #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 4U + #define __NVIC_PRIO_BITS 3U #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" #endif @@ -367,11 +318,12 @@ typedef union struct { uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ uint32_t C:1; /*!< bit: 29 Carry condition code flag */ @@ -397,8 +349,8 @@ typedef union #define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ #define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ -#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ -#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ #define xPSR_T_Pos 24U /*!< xPSR: T Position */ #define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ @@ -406,6 +358,9 @@ typedef union #define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ #define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + #define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ #define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ @@ -453,7 +408,7 @@ typedef struct __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ uint32_t RESERVED0[24U]; __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[24U]; + uint32_t RESERVED1[24U]; __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ uint32_t RESERVED2[24U]; __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ @@ -662,6 +617,66 @@ typedef struct #define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ #define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + /* SCB Hard Fault Status Register Definitions */ #define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ #define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ @@ -807,10 +822,7 @@ typedef struct __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ uint32_t RESERVED2[15U]; __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ - uint32_t RESERVED3[29U]; - __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ - __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ - __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED3[32U]; uint32_t RESERVED4[43U]; __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ @@ -831,7 +843,7 @@ typedef struct /* ITM Trace Privilege Register Definitions */ #define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ /* ITM Trace Control Register Definitions */ #define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ @@ -861,18 +873,6 @@ typedef struct #define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ #define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ -/* ITM Integration Write Register Definitions */ -#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ -#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ - -/* ITM Integration Read Register Definitions */ -#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ -#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ - -/* ITM Integration Mode Control Register Definitions */ -#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ -#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ - /* ITM Lock Status Register Definitions */ #define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ #define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ @@ -1045,7 +1045,7 @@ typedef struct */ typedef struct { - __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ uint32_t RESERVED0[2U]; __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ @@ -1056,7 +1056,7 @@ typedef struct __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ uint32_t RESERVED3[759U]; - __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ uint32_t RESERVED4[1U]; @@ -1105,13 +1105,13 @@ typedef struct /* TPI Integration ETM Data Register Definitions (FIFO0) */ #define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ #define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ #define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ #define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ #define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ #define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ @@ -1126,18 +1126,21 @@ typedef struct #define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ /* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ /* TPI Integration ITM Data Register Definitions (FIFO1) */ #define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ #define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ #define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ #define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ #define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ #define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ @@ -1152,12 +1155,15 @@ typedef struct #define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ /* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ /* TPI Integration Mode Control Register Definitions */ #define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ /* TPI DEVID Register Definitions */ #define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ @@ -1179,16 +1185,16 @@ typedef struct #define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ /* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ #define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + /*@}*/ /* end of group CMSIS_TPI */ -#if (__MPU_PRESENT == 1U) +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_MPU Memory Protection Unit (MPU) @@ -1214,6 +1220,8 @@ typedef struct __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ } MPU_Type; +#define MPU_TYPE_RALIASES 4U + /* MPU Type Register Definitions */ #define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ #define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ @@ -1280,10 +1288,9 @@ typedef struct #define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ /*@} end of group CMSIS_MPU */ -#endif +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ -#if (__FPU_PRESENT == 1U) /** \ingroup CMSIS_core_register \defgroup CMSIS_FPU Floating Point Unit (FPU) @@ -1302,6 +1309,7 @@ typedef struct __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ } FPU_Type; /* Floating-Point Context Control Register Definitions */ @@ -1387,8 +1395,12 @@ typedef struct #define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ #define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ +/* Media and FP Feature Register 2 Definitions */ + +#define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ +#define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ + /*@} end of group CMSIS_FPU */ -#endif /** @@ -1506,18 +1518,18 @@ typedef struct /** \brief Mask and shift a bit field value for use in a register bit range. \param[in] field Name of the register bit field. - \param[in] value Value of the bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. \return Masked and shifted value. */ -#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) /** \brief Mask and shift a register value to extract a bit filed value. \param[in] field Name of the register bit field. - \param[in] value Value of register. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. \return Masked and shifted bit field value. */ -#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) /*@} end of group CMSIS_core_bitfield */ @@ -1529,7 +1541,7 @@ typedef struct @{ */ -/* Memory mapping of Cortex-M4 Hardware */ +/* Memory mapping of Core Hardware */ #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ @@ -1548,15 +1560,13 @@ typedef struct #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ -#if (__MPU_PRESENT == 1U) +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ #endif -#if (__FPU_PRESENT == 1U) - #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ - #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ -#endif +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ /*@} */ @@ -1584,6 +1594,48 @@ typedef struct @{ */ +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + /** \brief Set Priority Grouping \details Sets the priority grouping field using the required unlock sequence. @@ -1593,7 +1645,7 @@ typedef struct priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. \param [in] PriorityGroup Priority grouping field. */ -__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { uint32_t reg_value; uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ @@ -1602,7 +1654,7 @@ __STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value = (reg_value | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ SCB->AIRCR = reg_value; } @@ -1612,121 +1664,180 @@ __STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) \details Reads the priority grouping field from the NVIC Interrupt Controller. \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). */ -__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) { return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); } /** - \brief Enable External Interrupt - \details Enables a device-specific interrupt in the NVIC interrupt controller. - \param [in] IRQn External interrupt number. Value cannot be negative. + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. */ -__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) { - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } } /** - \brief Disable External Interrupt - \details Disables a device-specific interrupt in the NVIC interrupt controller. - \param [in] IRQn External interrupt number. Value cannot be negative. + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. */ -__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) { - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } } /** \brief Get Pending Interrupt - \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. - \param [in] IRQn Interrupt number. + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not pending. \return 1 Interrupt status is pending. + \note IRQn must not be negative. */ -__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) { - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } } /** \brief Set Pending Interrupt - \details Sets the pending bit of an external interrupt. - \param [in] IRQn Interrupt number. Value cannot be negative. + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. */ -__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) { - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } } /** \brief Clear Pending Interrupt - \details Clears the pending bit of an external interrupt. - \param [in] IRQn External interrupt number. Value cannot be negative. + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. */ -__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) { - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } } /** \brief Get Active Interrupt - \details Reads the active register in NVIC and returns the active bit. - \param [in] IRQn Interrupt number. + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. \return 0 Interrupt status is not active. \return 1 Interrupt status is active. + \note IRQn must not be negative. */ -__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) { - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } } /** \brief Set Interrupt Priority - \details Sets the priority of an interrupt. - \note The priority cannot be set for every core interrupt. + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. \param [in] IRQn Interrupt number. \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. */ -__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { - if ((int32_t)(IRQn) < 0) + if ((int32_t)(IRQn) >= 0) { - SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } else { - NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); } } /** \brief Get Interrupt Priority - \details Reads the priority of an interrupt. - The interrupt number can be positive to specify an external (device specific) interrupt, - or negative to specify an internal (core) interrupt. + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. \param [in] IRQn Interrupt number. \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. */ -__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) { - if ((int32_t)(IRQn) < 0) + if ((int32_t)(IRQn) >= 0) { - return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); } else { - return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); } } @@ -1783,11 +1894,43 @@ __STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGr } +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t vectors = (uint32_t )SCB->VTOR; + (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector; + /* ARM Application Note 321 states that the M4 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t vectors = (uint32_t )SCB->VTOR; + return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)); +} + + /** \brief System Reset \details Initiates a system reset request to reset the MCU. */ -__STATIC_INLINE void NVIC_SystemReset(void) +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { __DSB(); /* Ensure all outstanding memory accesses included buffered write are completed before reset */ @@ -1805,6 +1948,50 @@ __STATIC_INLINE void NVIC_SystemReset(void) /*@} end of CMSIS_Core_NVICFunctions */ +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + /* ################################## SysTick function ############################################ */ /** @@ -1814,7 +2001,7 @@ __STATIC_INLINE void NVIC_SystemReset(void) @{ */ -#if (__Vendor_SysTickConfig == 0U) +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) /** \brief System Tick Configuration @@ -1857,8 +2044,8 @@ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) @{ */ -extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ -#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ /** @@ -1935,3 +2122,4 @@ __STATIC_INLINE int32_t ITM_CheckChar (void) #endif /* __CORE_CM4_H_DEPENDANT */ #endif /* __CMSIS_GENERIC */ + diff --git a/panda/board/inc/core_cmFunc.h b/panda/board/inc/core_cmFunc.h deleted file mode 100644 index 652a48af07a93d..00000000000000 --- a/panda/board/inc/core_cmFunc.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************//** - * @file core_cmFunc.h - * @brief CMSIS Cortex-M Core Function Access Header File - * @version V4.30 - * @date 20. October 2015 - ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - 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 ARM 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 COPYRIGHT HOLDERS AND 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. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #pragma clang system_header /* treat file as system include file */ -#endif - -#ifndef __CORE_CMFUNC_H -#define __CORE_CMFUNC_H - - -/* ########################### Core Function Access ########################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions - @{ -*/ - -/*------------------ RealView Compiler -----------------*/ -#if defined ( __CC_ARM ) - #include "cmsis_armcc.h" - -/*------------------ ARM Compiler V6 -------------------*/ -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #include "cmsis_armcc_V6.h" - -/*------------------ GNU Compiler ----------------------*/ -#elif defined ( __GNUC__ ) - #include "cmsis_gcc.h" - -/*------------------ ICC Compiler ----------------------*/ -#elif defined ( __ICCARM__ ) - #include - -/*------------------ TI CCS Compiler -------------------*/ -#elif defined ( __TMS470__ ) - #include - -/*------------------ TASKING Compiler ------------------*/ -#elif defined ( __TASKING__ ) - /* - * The CMSIS functions have been implemented as intrinsics in the compiler. - * Please use "carm -?i" to get an up to date list of all intrinsics, - * Including the CMSIS ones. - */ - -/*------------------ COSMIC Compiler -------------------*/ -#elif defined ( __CSMC__ ) - #include - -#endif - -/*@} end of CMSIS_Core_RegAccFunctions */ - -#endif /* __CORE_CMFUNC_H */ diff --git a/panda/board/inc/core_cmInstr.h b/panda/board/inc/core_cmInstr.h deleted file mode 100644 index f474b0e6f362c7..00000000000000 --- a/panda/board/inc/core_cmInstr.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************//** - * @file core_cmInstr.h - * @brief CMSIS Cortex-M Core Instruction Access Header File - * @version V4.30 - * @date 20. October 2015 - ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - 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 ARM 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 COPYRIGHT HOLDERS AND 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. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #pragma clang system_header /* treat file as system include file */ -#endif - -#ifndef __CORE_CMINSTR_H -#define __CORE_CMINSTR_H - - -/* ########################## Core Instruction Access ######################### */ -/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface - Access to dedicated instructions - @{ -*/ - -/*------------------ RealView Compiler -----------------*/ -#if defined ( __CC_ARM ) - #include "cmsis_armcc.h" - -/*------------------ ARM Compiler V6 -------------------*/ -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #include "cmsis_armcc_V6.h" - -/*------------------ GNU Compiler ----------------------*/ -#elif defined ( __GNUC__ ) - #include "cmsis_gcc.h" - -/*------------------ ICC Compiler ----------------------*/ -#elif defined ( __ICCARM__ ) - #include - -/*------------------ TI CCS Compiler -------------------*/ -#elif defined ( __TMS470__ ) - #include - -/*------------------ TASKING Compiler ------------------*/ -#elif defined ( __TASKING__ ) - /* - * The CMSIS functions have been implemented as intrinsics in the compiler. - * Please use "carm -?i" to get an up to date list of all intrinsics, - * Including the CMSIS ones. - */ - -/*------------------ COSMIC Compiler -------------------*/ -#elif defined ( __CSMC__ ) - #include - -#endif - -/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ - -#endif /* __CORE_CMINSTR_H */ diff --git a/panda/board/inc/core_cmSimd.h b/panda/board/inc/core_cmSimd.h deleted file mode 100644 index 66bf5c2a725b6d..00000000000000 --- a/panda/board/inc/core_cmSimd.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************//** - * @file core_cmSimd.h - * @brief CMSIS Cortex-M SIMD Header File - * @version V4.30 - * @date 20. October 2015 - ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - 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 ARM 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 COPYRIGHT HOLDERS AND 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. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #pragma clang system_header /* treat file as system include file */ -#endif - -#ifndef __CORE_CMSIMD_H -#define __CORE_CMSIMD_H - -#ifdef __cplusplus - extern "C" { -#endif - - -/* ################### Compiler specific Intrinsics ########################### */ -/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics - Access to dedicated SIMD instructions - @{ -*/ - -/*------------------ RealView Compiler -----------------*/ -#if defined ( __CC_ARM ) - #include "cmsis_armcc.h" - -/*------------------ ARM Compiler V6 -------------------*/ -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #include "cmsis_armcc_V6.h" - -/*------------------ GNU Compiler ----------------------*/ -#elif defined ( __GNUC__ ) - #include "cmsis_gcc.h" - -/*------------------ ICC Compiler ----------------------*/ -#elif defined ( __ICCARM__ ) - #include - -/*------------------ TI CCS Compiler -------------------*/ -#elif defined ( __TMS470__ ) - #include - -/*------------------ TASKING Compiler ------------------*/ -#elif defined ( __TASKING__ ) - /* - * The CMSIS functions have been implemented as intrinsics in the compiler. - * Please use "carm -?i" to get an up to date list of all intrinsics, - * Including the CMSIS ones. - */ - -/*------------------ COSMIC Compiler -------------------*/ -#elif defined ( __CSMC__ ) - #include - -#endif - -/*@} end of group CMSIS_SIMD_intrinsics */ - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CMSIMD_H */ diff --git a/panda/board/inc/mpu_armv7.h b/panda/board/inc/mpu_armv7.h new file mode 100644 index 00000000000000..ef8e6810ca42ff --- /dev/null +++ b/panda/board/inc/mpu_armv7.h @@ -0,0 +1,273 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.1.0 + * @date 08. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2017-2019 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \ + (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ + (((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ + (((MPU_RASR_ENABLE_Msk)))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if shareable) or 010b (if non-shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) & 2U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif + diff --git a/panda/board/inc/stm32f205xx.h b/panda/board/inc/stm32f205xx.h index ba825d1970327c..622faead62b0ea 100644 --- a/panda/board/inc/stm32f205xx.h +++ b/panda/board/inc/stm32f205xx.h @@ -4,8 +4,8 @@ * @author MCD Application Team * @version V2.1.2 * @date 29-June-2016 - * @brief CMSIS STM32F205xx Device Peripheral Access Layer Header File. - * This file contains : + * @brief CMSIS STM32F205xx Device Peripheral Access Layer Header File. + * This file contains : * - Data structures and the address mapping for all peripherals * - Peripherals registers declarations and bits definition * - Macros to access peripheral’s registers hardware @@ -47,21 +47,21 @@ /** @addtogroup stm32f205xx * @{ */ - + #ifndef __STM32F205xx_H #define __STM32F205xx_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - + /** @addtogroup Configuration_section_for_CMSIS * @{ */ /** - * @brief Configuration of the Cortex-M3 Processor and Core Peripherals + * @brief Configuration of the Cortex-M3 Processor and Core Peripherals */ #define __CM3_REV 0x0200U /*!< Core revision r0p1 */ #define __MPU_PRESENT 1U /*!< STM32F2XX provides an MPU */ @@ -71,14 +71,14 @@ /** * @} */ - + /** @addtogroup Peripheral_interrupt_number_definition * @{ */ /** - * @brief STM32F2XX Interrupt Number Definition, according to the selected device - * in @ref Library_configuration_section + * @brief STM32F2XX Interrupt Number Definition, according to the selected device + * in @ref Library_configuration_section */ typedef enum { @@ -126,7 +126,7 @@ typedef enum I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ - I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ USART1_IRQn = 37, /*!< USART1 global Interrupt */ @@ -134,7 +134,7 @@ typedef enum USART3_IRQn = 39, /*!< USART3 global Interrupt */ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ RTC_Alarm_IRQn = 41, /*!< RTC Alarm (A and B) through EXTI Line Interrupt */ - OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS Wakeup through EXTI line interrupt */ + OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS Wakeup through EXTI line interrupt */ TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global interrupt */ TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global interrupt */ TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */ @@ -181,16 +181,16 @@ typedef enum /** @addtogroup Peripheral_registers_structures * @{ - */ + */ -/** - * @brief Analog to Digital Converter +/** + * @brief Analog to Digital Converter */ typedef struct { __IO uint32_t SR; /*!< ADC status register, Address offset: 0x00 */ - __IO uint32_t CR1; /*!< ADC control register 1, Address offset: 0x04 */ + __IO uint32_t CR1; /*!< ADC control register 1, Address offset: 0x04 */ __IO uint32_t CR2; /*!< ADC control register 2, Address offset: 0x08 */ __IO uint32_t SMPR1; /*!< ADC sample time register 1, Address offset: 0x0C */ __IO uint32_t SMPR2; /*!< ADC sample time register 2, Address offset: 0x10 */ @@ -220,8 +220,8 @@ typedef struct } ADC_Common_TypeDef; -/** - * @brief Controller Area Network TxMailBox +/** + * @brief Controller Area Network TxMailBox */ typedef struct @@ -232,10 +232,10 @@ typedef struct __IO uint32_t TDHR; /*!< CAN mailbox data high register */ } CAN_TxMailBox_TypeDef; -/** - * @brief Controller Area Network FIFOMailBox +/** + * @brief Controller Area Network FIFOMailBox */ - + typedef struct { __IO uint32_t RIR; /*!< CAN receive FIFO mailbox identifier register */ @@ -244,20 +244,20 @@ typedef struct __IO uint32_t RDHR; /*!< CAN receive FIFO mailbox data high register */ } CAN_FIFOMailBox_TypeDef; -/** - * @brief Controller Area Network FilterRegister +/** + * @brief Controller Area Network FilterRegister */ - + typedef struct { __IO uint32_t FR1; /*!< CAN Filter bank register 1 */ __IO uint32_t FR2; /*!< CAN Filter bank register 1 */ } CAN_FilterRegister_TypeDef; -/** - * @brief Controller Area Network +/** + * @brief Controller Area Network */ - + typedef struct { __IO uint32_t MCR; /*!< CAN master control register, Address offset: 0x00 */ @@ -280,12 +280,12 @@ typedef struct __IO uint32_t FFA1R; /*!< CAN filter FIFO assignment register, Address offset: 0x214 */ uint32_t RESERVED4; /*!< Reserved, 0x218 */ __IO uint32_t FA1R; /*!< CAN filter activation register, Address offset: 0x21C */ - uint32_t RESERVED5[8]; /*!< Reserved, 0x220-0x23F */ + uint32_t RESERVED5[8]; /*!< Reserved, 0x220-0x23F */ CAN_FilterRegister_TypeDef sFilterRegister[28]; /*!< CAN Filter Register, Address offset: 0x240-0x31C */ } CAN_TypeDef; -/** - * @brief CRC calculation unit +/** + * @brief CRC calculation unit */ typedef struct @@ -297,7 +297,7 @@ typedef struct __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ } CRC_TypeDef; -/** +/** * @brief Digital to Analog Converter */ @@ -319,7 +319,7 @@ typedef struct __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ } DAC_TypeDef; -/** +/** * @brief Debug MCU */ @@ -332,7 +332,7 @@ typedef struct }DBGMCU_TypeDef; -/** +/** * @brief DMA Controller */ @@ -355,7 +355,7 @@ typedef struct } DMA_TypeDef; -/** +/** * @brief External Interrupt/Event Controller */ @@ -369,7 +369,7 @@ typedef struct __IO uint32_t PR; /*!< EXTI Pending register, Address offset: 0x14 */ } EXTI_TypeDef; -/** +/** * @brief FLASH Registers */ @@ -384,28 +384,28 @@ typedef struct } FLASH_TypeDef; -/** +/** * @brief Flexible Static Memory Controller */ typedef struct { - __IO uint32_t BTCR[8]; /*!< NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR), Address offset: 0x00-1C */ -} FSMC_Bank1_TypeDef; + __IO uint32_t BTCR[8]; /*!< NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR), Address offset: 0x00-1C */ +} FSMC_Bank1_TypeDef; -/** +/** * @brief Flexible Static Memory Controller Bank1E */ - + typedef struct { __IO uint32_t BWTR[7]; /*!< NOR/PSRAM write timing registers, Address offset: 0x104-0x11C */ } FSMC_Bank1E_TypeDef; -/** +/** * @brief Flexible Static Memory Controller Bank2 */ - + typedef struct { __IO uint32_t PCR2; /*!< NAND Flash control register 2, Address offset: 0x60 */ @@ -424,10 +424,10 @@ typedef struct __IO uint32_t ECCR3; /*!< NAND Flash ECC result registers 3, Address offset: 0x94 */ } FSMC_Bank2_3_TypeDef; -/** +/** * @brief Flexible Static Memory Controller Bank4 */ - + typedef struct { __IO uint32_t PCR4; /*!< PC Card control register 4, Address offset: 0xA0 */ @@ -435,10 +435,10 @@ typedef struct __IO uint32_t PMEM4; /*!< PC Card Common memory space timing register 4, Address offset: 0xA8 */ __IO uint32_t PATT4; /*!< PC Card Attribute memory space timing register 4, Address offset: 0xAC */ __IO uint32_t PIO4; /*!< PC Card I/O space timing register 4, Address offset: 0xB0 */ -} FSMC_Bank4_TypeDef; +} FSMC_Bank4_TypeDef; -/** +/** * @brief General Purpose I/O */ @@ -455,20 +455,20 @@ typedef struct __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ } GPIO_TypeDef; -/** +/** * @brief System configuration controller */ - + typedef struct { __IO uint32_t MEMRMP; /*!< SYSCFG memory remap register, Address offset: 0x00 */ __IO uint32_t PMC; /*!< SYSCFG peripheral mode configuration register, Address offset: 0x04 */ __IO uint32_t EXTICR[4]; /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 */ - uint32_t RESERVED[2]; /*!< Reserved, 0x18-0x1C */ + uint32_t RESERVED[2]; /*!< Reserved, 0x18-0x1C */ __IO uint32_t CMPCR; /*!< SYSCFG Compensation cell control register, Address offset: 0x20 */ } SYSCFG_TypeDef; -/** +/** * @brief Inter-integrated Circuit Interface */ @@ -485,7 +485,7 @@ typedef struct __IO uint32_t TRISE; /*!< I2C TRISE register, Address offset: 0x20 */ } I2C_TypeDef; -/** +/** * @brief Independent WATCHDOG */ @@ -497,7 +497,7 @@ typedef struct __IO uint32_t SR; /*!< IWDG Status register, Address offset: 0x0C */ } IWDG_TypeDef; -/** +/** * @brief Power Control */ @@ -507,7 +507,7 @@ typedef struct __IO uint32_t CSR; /*!< PWR power control/status register, Address offset: 0x04 */ } PWR_TypeDef; -/** +/** * @brief Reset and Clock Control */ @@ -546,7 +546,7 @@ typedef struct } RCC_TypeDef; -/** +/** * @brief Real-Time Clock */ @@ -595,7 +595,7 @@ typedef struct } RTC_TypeDef; -/** +/** * @brief SD host Interface */ @@ -623,7 +623,7 @@ typedef struct __IO uint32_t FIFO; /*!< SDIO data FIFO register, Address offset: 0x80 */ } SDIO_TypeDef; -/** +/** * @brief Serial Peripheral Interface */ @@ -640,7 +640,7 @@ typedef struct __IO uint32_t I2SPR; /*!< SPI_I2S prescaler register, Address offset: 0x20 */ } SPI_TypeDef; -/** +/** * @brief TIM */ @@ -669,10 +669,10 @@ typedef struct __IO uint32_t OR; /*!< TIM option register, Address offset: 0x50 */ } TIM_TypeDef; -/** +/** * @brief Universal Synchronous Asynchronous Receiver Transmitter */ - + typedef struct { __IO uint32_t SR; /*!< USART Status register, Address offset: 0x00 */ @@ -684,7 +684,7 @@ typedef struct __IO uint32_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */ } USART_TypeDef; -/** +/** * @brief Window WATCHDOG */ @@ -696,11 +696,11 @@ typedef struct } WWDG_TypeDef; -/** +/** * @brief RNG */ - -typedef struct + +typedef struct { __IO uint32_t CR; /*!< RNG control register, Address offset: 0x00 */ __IO uint32_t SR; /*!< RNG status register, Address offset: 0x04 */ @@ -708,8 +708,8 @@ typedef struct } RNG_TypeDef; - -/** + +/** * @brief __USB_OTG_Core_register */ typedef struct @@ -737,10 +737,10 @@ USB_OTG_GlobalTypeDef; -/** +/** * @brief __device_Registers */ -typedef struct +typedef struct { __IO uint32_t DCFG; /*!< dev Configuration Register Address offset : 0x800 */ __IO uint32_t DCTL; /*!< dev Control Register Address offset : 0x804 */ @@ -757,19 +757,19 @@ typedef struct __IO uint32_t DTHRCTL; /*!< dev thr Address offset : 0x830 */ __IO uint32_t DIEPEMPMSK; /*!< dev empty msk Address offset : 0x834 */ __IO uint32_t DEACHINT; /*!< dedicated EP interrupt Address offset : 0x838 */ - __IO uint32_t DEACHMSK; /*!< dedicated EP msk Address offset : 0x83C */ + __IO uint32_t DEACHMSK; /*!< dedicated EP msk Address offset : 0x83C */ uint32_t Reserved40; /*!< dedicated EP mask Address offset : 0x840 */ __IO uint32_t DINEP1MSK; /*!< dedicated EP mask Address offset : 0x844 */ uint32_t Reserved44[15]; /*!< Reserved Address offset : 0x844-0x87C */ - __IO uint32_t DOUTEP1MSK; /*!< dedicated EP msk Address offset : 0x884 */ + __IO uint32_t DOUTEP1MSK; /*!< dedicated EP msk Address offset : 0x884 */ } USB_OTG_DeviceTypeDef; -/** +/** * @brief __IN_Endpoint-Specific_Register */ -typedef struct +typedef struct { __IO uint32_t DIEPCTL; /* dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h */ uint32_t Reserved04; /* Reserved 900h + (ep_num * 20h) + 04h */ @@ -783,10 +783,10 @@ typedef struct USB_OTG_INEndpointTypeDef; -/** +/** * @brief __OUT_Endpoint-Specific_Registers */ -typedef struct +typedef struct { __IO uint32_t DOEPCTL; /* dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h*/ uint32_t Reserved04; /* Reserved B00h + (ep_num * 20h) + 04h*/ @@ -799,10 +799,10 @@ typedef struct USB_OTG_OUTEndpointTypeDef; -/** +/** * @brief __Host_Mode_Register_Structures */ -typedef struct +typedef struct { __IO uint32_t HCFG; /* Host Configuration Register 400h*/ __IO uint32_t HFIR; /* Host Frame Interval Register 404h*/ @@ -815,7 +815,7 @@ typedef struct USB_OTG_HostTypeDef; -/** +/** * @brief __Host_Channel_Specific_Registers */ typedef struct @@ -830,8 +830,8 @@ typedef struct } USB_OTG_HostChannelTypeDef; - -/** + +/** * @brief Peripheral_memory_map */ #define FLASH_BASE 0x08000000U /*!< FLASH(up to 1 MB) base address in the alias region */ @@ -965,10 +965,10 @@ USB_OTG_HostChannelTypeDef; /** * @} */ - + /** @addtogroup Peripheral_declaration * @{ - */ + */ #define TIM2 ((TIM_TypeDef *) TIM2_BASE) #define TIM3 ((TIM_TypeDef *) TIM3_BASE) #define TIM4 ((TIM_TypeDef *) TIM4_BASE) @@ -1003,7 +1003,7 @@ USB_OTG_HostChannelTypeDef; #define ADC2 ((ADC_TypeDef *) ADC2_BASE) #define ADC3 ((ADC_TypeDef *) ADC3_BASE) #define SDIO ((SDIO_TypeDef *) SDIO_BASE) -#define SPI1 ((SPI_TypeDef *) SPI1_BASE) +#define SPI1 ((SPI_TypeDef *) SPI1_BASE) #define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE) #define EXTI ((EXTI_TypeDef *) EXTI_BASE) #define TIM9 ((TIM_TypeDef *) TIM9_BASE) @@ -1038,7 +1038,7 @@ USB_OTG_HostChannelTypeDef; #define DMA2_Stream4 ((DMA_Stream_TypeDef *) DMA2_Stream4_BASE) #define DMA2_Stream5 ((DMA_Stream_TypeDef *) DMA2_Stream5_BASE) #define DMA2_Stream6 ((DMA_Stream_TypeDef *) DMA2_Stream6_BASE) -#define DMA2_Stream7 ((DMA_Stream_TypeDef *) DMA2_Stream7_BASE) +#define DMA2_Stream7 ((DMA_Stream_TypeDef *) DMA2_Stream7_BASE) #define RNG ((RNG_TypeDef *) RNG_BASE) #define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE) #define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE) @@ -1057,11 +1057,11 @@ USB_OTG_HostChannelTypeDef; /** @addtogroup Exported_constants * @{ */ - + /** @addtogroup Peripheral_Registers_Bits_Definition * @{ */ - + /******************************************************************************/ /* Peripheral Registers_Bits_Definition */ /******************************************************************************/ @@ -1104,7 +1104,7 @@ USB_OTG_HostChannelTypeDef; #define ADC_CR1_RES_0 0x01000000U /*!
© COPYRIGHT(c) 2016 STMicroelectronics
@@ -32,8 +32,8 @@ * 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. * - ****************************************************************************** - */ + ****************************************************************************** + */ /** @addtogroup CMSIS * @{ @@ -41,8 +41,8 @@ /** @addtogroup stm32f4xx_system * @{ - */ - + */ + /** * @brief Define to prevent recursive inclusion */ @@ -51,7 +51,7 @@ #ifdef __cplusplus extern "C" { -#endif +#endif /** @addtogroup STM32F4xx_System_Includes * @{ @@ -68,7 +68,7 @@ /* This variable is updated in three ways: 1) by calling CMSIS function SystemCoreClockUpdate() 2) by calling HAL API function HAL_RCC_GetSysClockFreq() - 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency Note: If you use this function to configure the system clock; then there is no need to call the 2 first functions listed above, since SystemCoreClock variable is updated automatically. @@ -101,7 +101,7 @@ extern const uint8_t APBPrescTable[8]; /*!< APB prescalers table values */ /** @addtogroup STM32F4xx_System_Exported_Functions * @{ */ - + extern void SystemInit(void); extern void SystemCoreClockUpdate(void); /** @@ -117,8 +117,8 @@ extern void SystemCoreClockUpdate(void); /** * @} */ - + /** * @} - */ + */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/panda/board/libc.h b/panda/board/libc.h index 8d80a3aad855a9..f8d9dbce2acdda 100644 --- a/panda/board/libc.h +++ b/panda/board/libc.h @@ -1,51 +1,67 @@ -// **** shitty libc **** +// **** libc **** void delay(int a) { volatile int i; - for (i=0;iCCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1; - TIM3->CCER = TIM_CCER_CC3E; - timer_init(TIM3, 10); -} +#include "power_saving.h" +#include "safety.h" -void fan_set_speed(int fan_speed) { - TIM3->CCR3 = fan_speed; -} +#include "drivers/can.h" -// ********************* serial debugging ********************* +// ********************* Serial debugging ********************* + +bool check_started(void) { + return current_board->check_ignition() || ignition_can; +} void debug_ring_callback(uart_ring *ring) { char rcv; while (getc(ring, &rcv)) { - putc(ring, rcv); + (void)putc(ring, rcv); // misra-c2012-17.7: cast to void is ok: debug function // jump to DFU flash if (rcv == 'z') { @@ -55,126 +59,260 @@ void debug_ring_callback(uart_ring *ring) { // enable CDP mode if (rcv == 'C') { puts("switching USB to CDP mode\n"); - set_usb_power_mode(USB_POWER_CDP); + current_board->set_usb_power_mode(USB_POWER_CDP); } if (rcv == 'c') { puts("switching USB to client mode\n"); - set_usb_power_mode(USB_POWER_CLIENT); + current_board->set_usb_power_mode(USB_POWER_CLIENT); } if (rcv == 'D') { puts("switching USB to DCP mode\n"); - set_usb_power_mode(USB_POWER_DCP); + current_board->set_usb_power_mode(USB_POWER_DCP); } } } -// ***************************** USB port ***************************** +// ***************************** started logic ***************************** +void started_interrupt_handler(uint8_t interrupt_line) { + volatile unsigned int pr = EXTI->PR & (1U << interrupt_line); + if ((pr & (1U << interrupt_line)) != 0U) { + #ifdef DEBUG + puts("got started interrupt\n"); + #endif -int get_health_pkt(void *dat) { - struct __attribute__((packed)) { - uint32_t voltage; - uint32_t current; - uint8_t started; - uint8_t controls_allowed; - uint8_t gas_interceptor_detected; - uint8_t started_signal_detected; - uint8_t started_alt; - } *health = dat; + // jenky debounce + delay(100000); - //Voltage will be measured in mv. 5000 = 5V - uint32_t voltage = adc_get(ADCCHAN_VOLTAGE); - if (revision == PANDA_REV_AB) { - //REVB has a 100, 27 (27/127) voltage divider - //Here is the calculation for the scale - //ADCV = VIN_S * (27/127) * (4095/3.3) - //RETVAL = ADCV * s = VIN_S*1000 - //s = 1000/((4095/3.3)*(27/127)) = 3.79053046 - - //Avoid needing floating point math - health->voltage = (voltage * 3791) / 1000; - } else { - //REVC has a 10, 1 (1/11) voltage divider - //Here is the calculation for the scale (s) - //ADCV = VIN_S * (1/11) * (4095/3.3) - //RETVAL = ADCV * s = VIN_S*1000 - //s = 1000/((4095/3.3)*(1/11)) = 8.8623046875 - - //Avoid needing floating point math - health->voltage = (voltage * 8862) / 1000; + #ifdef EON + // set power savings mode here if on EON build + int power_save_state = check_started() ? POWER_SAVE_STATUS_DISABLED : POWER_SAVE_STATUS_ENABLED; + set_power_save_state(power_save_state); + // set CDP usb power mode everytime that the car starts to make sure EON is charging + if (check_started()) { + current_board->set_usb_power_mode(USB_POWER_CDP); + } + #endif } + EXTI->PR = (1U << interrupt_line); +} + +// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck +void EXTI0_IRQHandler(void) { + started_interrupt_handler(0); +} + +// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck +void EXTI1_IRQHandler(void) { + started_interrupt_handler(1); +} -#ifdef PANDA - health->current = adc_get(ADCCHAN_CURRENT); - int safety_ignition = safety_ignition_hook(); - if (safety_ignition < 0) { - //Use the GPIO pin to determine ignition - health->started = (GPIOA->IDR & (1 << 1)) == 0; +// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck +void EXTI3_IRQHandler(void) { + started_interrupt_handler(3); +} + +// ****************************** safety mode ****************************** + +// this is the only way to leave silent mode +void set_safety_mode(uint16_t mode, int16_t param) { + int err = safety_set_mode(mode, param); + if (err == -1) { + puts("Error: safety set mode failed\n"); } else { - //Current safety hooks want to determine ignition (ex: GM) - health->started = safety_ignition; + switch (mode) { + case SAFETY_NOOUTPUT: + set_intercept_relay(false); + if(board_has_obd()){ + current_board->set_can_mode(CAN_MODE_NORMAL); + } + can_silent = ALL_CAN_LIVE; + break; + case SAFETY_ELM327: + set_intercept_relay(false); + heartbeat_counter = 0U; + if(board_has_obd()){ + current_board->set_can_mode(CAN_MODE_OBD_CAN2); + } + can_silent = ALL_CAN_LIVE; + break; + default: + set_intercept_relay(true); + heartbeat_counter = 0U; + if(board_has_obd()){ + current_board->set_can_mode(CAN_MODE_NORMAL); + } + can_silent = ALL_CAN_LIVE; + break; + } + can_init_all(); } -#else - health->current = 0; - health->started = (GPIOC->IDR & (1 << 13)) != 0; -#endif +} + +// ***************************** USB port ***************************** + +int get_health_pkt(void *dat) { + struct __attribute__((packed)) { + uint32_t voltage_pkt; + uint32_t current_pkt; + uint32_t can_send_errs_pkt; + uint32_t can_fwd_errs_pkt; + uint32_t gmlan_send_errs_pkt; + uint8_t ignition_line_pkt; + uint8_t ignition_can_pkt; + uint8_t controls_allowed_pkt; + uint8_t gas_interceptor_detected_pkt; + uint8_t car_harness_status_pkt; + uint8_t usb_power_mode_pkt; + uint8_t safety_mode_pkt; + } *health = dat; + + health->voltage_pkt = adc_get_voltage(); + health->current_pkt = current_board->read_current(); - health->controls_allowed = controls_allowed; - health->gas_interceptor_detected = gas_interceptor_detected; + //Use the GPIO pin to determine ignition or use a CAN based logic + health->ignition_line_pkt = (uint8_t)(current_board->check_ignition()); + health->ignition_can_pkt = (uint8_t)(ignition_can); - // DEPRECATED - health->started_alt = 0; - health->started_signal_detected = 0; + health->controls_allowed_pkt = controls_allowed; + health->gas_interceptor_detected_pkt = gas_interceptor_detected; + health->can_send_errs_pkt = can_send_errs; + health->can_fwd_errs_pkt = can_fwd_errs; + health->gmlan_send_errs_pkt = gmlan_send_errs; + health->car_harness_status_pkt = car_harness_status; + health->usb_power_mode_pkt = usb_power_mode; + health->safety_mode_pkt = (uint8_t)(current_safety_mode); return sizeof(*health); } -int usb_cb_ep1_in(uint8_t *usbdata, int len, int hardwired) { +int get_rtc_pkt(void *dat) { + timestamp_t t = rtc_get_time(); + (void)memcpy(dat, &t, sizeof(t)); + return sizeof(t); +} + +int usb_cb_ep1_in(void *usbdata, int len, bool hardwired) { + UNUSED(hardwired); CAN_FIFOMailBox_TypeDef *reply = (CAN_FIFOMailBox_TypeDef *)usbdata; int ilen = 0; - while (ilen < min(len/0x10, 4) && can_pop(&can_rx_q, &reply[ilen])) ilen++; + while (ilen < MIN(len/0x10, 4) && can_pop(&can_rx_q, &reply[ilen])) { + ilen++; + } return ilen*0x10; } // send on serial, first byte to select the ring -void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired) { - if (len == 0) return; - uart_ring *ur = get_ring_by_number(usbdata[0]); - if (!ur) return; - if ((usbdata[0] < 2) || safety_tx_lin_hook(usbdata[0]-2, usbdata+1, len-1)) { - for (int i = 1; i < len; i++) while (!putc(ur, usbdata[i])); +void usb_cb_ep2_out(void *usbdata, int len, bool hardwired) { + UNUSED(hardwired); + uint8_t *usbdata8 = (uint8_t *)usbdata; + uart_ring *ur = get_ring_by_number(usbdata8[0]); + if ((len != 0) && (ur != NULL)) { + if ((usbdata8[0] < 2U) || safety_tx_lin_hook(usbdata8[0] - 2U, &usbdata8[1], len - 1)) { + for (int i = 1; i < len; i++) { + while (!putc(ur, usbdata8[i])) { + // wait + } + } + } } } // send on CAN -void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired) { +void usb_cb_ep3_out(void *usbdata, int len, bool hardwired) { + UNUSED(hardwired); int dpkt = 0; - for (dpkt = 0; dpkt < len; dpkt += 0x10) { - uint32_t *tf = (uint32_t*)(&usbdata[dpkt]); - - // make a copy + uint32_t *d32 = (uint32_t *)usbdata; + for (dpkt = 0; dpkt < (len / 4); dpkt += 4) { CAN_FIFOMailBox_TypeDef to_push; - to_push.RDHR = tf[3]; - to_push.RDLR = tf[2]; - to_push.RDTR = tf[1]; - to_push.RIR = tf[0]; + to_push.RDHR = d32[dpkt + 3]; + to_push.RDLR = d32[dpkt + 2]; + to_push.RDTR = d32[dpkt + 1]; + to_push.RIR = d32[dpkt]; uint8_t bus_number = (to_push.RDTR >> 4) & CAN_BUS_NUM_MASK; can_send(&to_push, bus_number); } } -int is_enumerated = 0; - void usb_cb_enumeration_complete() { puts("USB enumeration complete\n"); is_enumerated = 1; } -int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { - int resp_len = 0; +int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired) { + unsigned int resp_len = 0; uart_ring *ur = NULL; int i; + timestamp_t t; switch (setup->b.bRequest) { + // **** 0xa0: get rtc time + case 0xa0: + resp_len = get_rtc_pkt(resp); + break; + // **** 0xa1: set rtc year + case 0xa1: + t = rtc_get_time(); + t.year = setup->b.wValue.w; + rtc_set_time(t); + break; + // **** 0xa2: set rtc month + case 0xa2: + t = rtc_get_time(); + t.month = setup->b.wValue.w; + rtc_set_time(t); + break; + // **** 0xa3: set rtc day + case 0xa3: + t = rtc_get_time(); + t.day = setup->b.wValue.w; + rtc_set_time(t); + break; + // **** 0xa4: set rtc weekday + case 0xa4: + t = rtc_get_time(); + t.weekday = setup->b.wValue.w; + rtc_set_time(t); + break; + // **** 0xa5: set rtc hour + case 0xa5: + t = rtc_get_time(); + t.hour = setup->b.wValue.w; + rtc_set_time(t); + break; + // **** 0xa6: set rtc minute + case 0xa6: + t = rtc_get_time(); + t.minute = setup->b.wValue.w; + rtc_set_time(t); + break; + // **** 0xa7: set rtc second + case 0xa7: + t = rtc_get_time(); + t.second = setup->b.wValue.w; + rtc_set_time(t); + break; + // **** 0xb0: set IR power + case 0xb0: + if(power_save_status == POWER_SAVE_STATUS_DISABLED){ + current_board->set_ir_power(setup->b.wValue.w); + } else { + puts("Setting IR power not allowed in power saving mode\n"); + } + break; + // **** 0xb1: set fan power + case 0xb1: + if(power_save_status == POWER_SAVE_STATUS_DISABLED){ + current_board->set_fan_power(setup->b.wValue.w); + } else { + puts("Setting fan power not allowed in power saving mode\n"); + } + break; + // **** 0xb2: get fan rpm + case 0xb2: + resp[0] = (fan_rpm & 0x00FFU); + resp[1] = ((fan_rpm & 0xFF00U) >> 8U); + resp_len = 2; + break; // **** 0xc0: get CAN debug info case 0xc0: puts("can tx: "); puth(can_tx_cnt); @@ -183,23 +321,21 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { puts(" err: "); puth(can_err_cnt); puts("\n"); break; - // **** 0xc1: is grey panda + // **** 0xc1: get hardware type case 0xc1: - resp[0] = is_grey_panda; + resp[0] = hw_type; resp_len = 1; break; // **** 0xd0: fetch serial number case 0xd0: - #ifdef PANDA - // addresses are OTP - if (setup->b.wValue.w == 1) { - memcpy(resp, (void *)0x1fff79c0, 0x10); - resp_len = 0x10; - } else { - get_provision_chunk(resp); - resp_len = PROVISION_CHUNK_LEN; - } - #endif + // addresses are OTP + if (setup->b.wValue.w == 1U) { + (void)memcpy(resp, (uint8_t *)0x1fff79c0, 0x10); + resp_len = 0x10; + } else { + get_provision_chunk(resp); + resp_len = PROVISION_CHUNK_LEN; + } break; // **** 0xd1: enter bootloader mode case 0xd1: @@ -207,32 +343,34 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { // so it's blocked over wifi switch (setup->b.wValue.w) { case 0: - if (hardwired) { - puts("-> entering bootloader\n"); - enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC; - NVIC_SystemReset(); - } + // only allow bootloader entry on debug builds + #ifdef ALLOW_DEBUG + if (hardwired) { + puts("-> entering bootloader\n"); + enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC; + NVIC_SystemReset(); + } + #endif break; case 1: puts("-> entering softloader\n"); enter_bootloader_mode = ENTER_SOFTLOADER_MAGIC; NVIC_SystemReset(); break; + default: + puts("Bootloader mode invalid\n"); + break; } break; // **** 0xd2: get health packet case 0xd2: resp_len = get_health_pkt(resp); break; - // **** 0xd3: set fan speed - case 0xd3: - fan_set_speed(setup->b.wValue.w); - break; // **** 0xd6: get version case 0xd6: - COMPILE_TIME_ASSERT(sizeof(gitversion) <= MAX_RESP_LEN) - memcpy(resp, gitversion, sizeof(gitversion)); - resp_len = sizeof(gitversion)-1; + COMPILE_TIME_ASSERT(sizeof(gitversion) <= MAX_RESP_LEN); + (void)memcpy(resp, gitversion, sizeof(gitversion)); + resp_len = sizeof(gitversion) - 1U; break; // **** 0xd8: reset ST case 0xd8: @@ -240,95 +378,100 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { break; // **** 0xd9: set ESP power case 0xd9: - if (setup->b.wValue.w == 1) { - set_esp_mode(ESP_ENABLED); - } else if (setup->b.wValue.w == 2) { - set_esp_mode(ESP_BOOTMODE); + if (setup->b.wValue.w == 1U) { + current_board->set_esp_gps_mode(ESP_GPS_ENABLED); + } else if (setup->b.wValue.w == 2U) { + current_board->set_esp_gps_mode(ESP_GPS_BOOTMODE); } else { - set_esp_mode(ESP_DISABLED); + current_board->set_esp_gps_mode(ESP_GPS_DISABLED); } break; // **** 0xda: reset ESP, with optional boot mode case 0xda: - set_esp_mode(ESP_DISABLED); + current_board->set_esp_gps_mode(ESP_GPS_DISABLED); delay(1000000); - if (setup->b.wValue.w == 1) { - set_esp_mode(ESP_BOOTMODE); + if (setup->b.wValue.w == 1U) { + current_board->set_esp_gps_mode(ESP_GPS_BOOTMODE); } else { - set_esp_mode(ESP_ENABLED); + current_board->set_esp_gps_mode(ESP_GPS_ENABLED); } delay(1000000); - set_esp_mode(ESP_ENABLED); + current_board->set_esp_gps_mode(ESP_GPS_ENABLED); break; - // **** 0xdb: set GMLAN multiplexing mode + // **** 0xdb: set GMLAN (white/grey) or OBD CAN (black) multiplexing mode case 0xdb: - #ifdef PANDA - if (setup->b.wValue.w == 1) { + if(board_has_obd()){ + if (setup->b.wValue.w == 1U) { + // Enable OBD CAN + current_board->set_can_mode(CAN_MODE_OBD_CAN2); + } else { + // Disable OBD CAN + current_board->set_can_mode(CAN_MODE_NORMAL); + } + } else { + if (setup->b.wValue.w == 1U) { // GMLAN ON - if (setup->b.wIndex.w == 1) { + if (setup->b.wIndex.w == 1U) { can_set_gmlan(1); - } else if (setup->b.wIndex.w == 2) { - // might be ignored on rev b panda + } else if (setup->b.wIndex.w == 2U) { can_set_gmlan(2); + } else { + puts("Invalid bus num for GMLAN CAN set\n"); } } else { can_set_gmlan(-1); } - #endif + } break; + // **** 0xdc: set safety mode case 0xdc: - // this is the only way to leave silent mode - // and it's blocked over WiFi - // Allow ELM security mode to be set over wifi. - if (hardwired || setup->b.wValue.w == SAFETY_NOOUTPUT || setup->b.wValue.w == SAFETY_ELM327) { - safety_set_mode(setup->b.wValue.w, (int16_t)setup->b.wIndex.w); - switch (setup->b.wValue.w) { - case SAFETY_NOOUTPUT: - can_silent = ALL_CAN_SILENT; - break; - case SAFETY_ELM327: - can_silent = ALL_CAN_BUT_MAIN_SILENT; - can_autobaud_enabled[0] = false; - break; - default: - can_silent = ALL_CAN_LIVE; - can_autobaud_enabled[0] = false; - can_autobaud_enabled[1] = false; - #ifdef PANDA - can_autobaud_enabled[2] = false; - #endif - break; - } - can_init_all(); + // Blocked over WiFi. + // Allow NOOUTPUT and ELM security mode to be set over wifi. + if (hardwired || (setup->b.wValue.w == SAFETY_NOOUTPUT) || (setup->b.wValue.w == SAFETY_ELM327)) { + set_safety_mode(setup->b.wValue.w, (uint16_t) setup->b.wIndex.w); } break; // **** 0xdd: enable can forwarding case 0xdd: // wValue = Can Bus Num to forward from // wIndex = Can Bus Num to forward to - if (setup->b.wValue.w < BUS_MAX && setup->b.wIndex.w < BUS_MAX && - setup->b.wValue.w != setup->b.wIndex.w) { // set forwarding + if ((setup->b.wValue.w < BUS_MAX) && (setup->b.wIndex.w < BUS_MAX) && + (setup->b.wValue.w != setup->b.wIndex.w)) { // set forwarding can_set_forwarding(setup->b.wValue.w, setup->b.wIndex.w & CAN_BUS_NUM_MASK); - } else if(setup->b.wValue.w < BUS_MAX && setup->b.wIndex.w == 0xFF){ //Clear Forwarding + } else if((setup->b.wValue.w < BUS_MAX) && (setup->b.wIndex.w == 0xFFU)){ //Clear Forwarding can_set_forwarding(setup->b.wValue.w, -1); + } else { + puts("Invalid CAN bus forwarding\n"); } break; // **** 0xde: set can bitrate case 0xde: if (setup->b.wValue.w < BUS_MAX) { - can_autobaud_enabled[setup->b.wValue.w] = false; can_speed[setup->b.wValue.w] = setup->b.wIndex.w; can_init(CAN_NUM_FROM_BUS_NUM(setup->b.wValue.w)); } break; + // **** 0xdf: set long controls allowed + case 0xdf: + if (hardwired) { + long_controls_allowed = setup->b.wValue.w & 1U; + } + break; // **** 0xe0: uart read case 0xe0: ur = get_ring_by_number(setup->b.wValue.w); - if (!ur) break; - if (ur == &esp_ring) uart_dma_drain(); + if (!ur) { + break; + } + + // TODO: Remove this again and fix boardd code to hande the message bursts instead of single chars + if (ur == &uart_ring_esp_gps) { + dma_pointer_handler(ur, DMA2_Stream5->NDTR); + } + // read - while ((resp_len < min(setup->b.wLength.w, MAX_RESP_LEN)) && + while ((resp_len < MIN(setup->b.wLength.w, MAX_RESP_LEN)) && getc(ur, (char*)&resp[resp_len])) { ++resp_len; } @@ -336,13 +479,17 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { // **** 0xe1: uart set baud rate case 0xe1: ur = get_ring_by_number(setup->b.wValue.w); - if (!ur) break; + if (!ur) { + break; + } uart_set_baud(ur->uart, setup->b.wIndex.w); break; // **** 0xe2: uart set parity case 0xe2: ur = get_ring_by_number(setup->b.wValue.w); - if (!ur) break; + if (!ur) { + break; + } switch (setup->b.wIndex.w) { case 0: // disable parity, 8-bit @@ -365,53 +512,44 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { // **** 0xe4: uart set baud rate extended case 0xe4: ur = get_ring_by_number(setup->b.wValue.w); - if (!ur) break; + if (!ur) { + break; + } uart_set_baud(ur->uart, (int)setup->b.wIndex.w*300); break; // **** 0xe5: set CAN loopback (for testing) case 0xe5: - can_loopback = (setup->b.wValue.w > 0); + can_loopback = (setup->b.wValue.w > 0U); can_init_all(); break; // **** 0xe6: set USB power case 0xe6: - if (revision == PANDA_REV_C) { - if (setup->b.wValue.w == 1) { - puts("user setting CDP mode\n"); - set_usb_power_mode(USB_POWER_CDP); - } else if (setup->b.wValue.w == 2) { - puts("user setting DCP mode\n"); - set_usb_power_mode(USB_POWER_DCP); - } else { - puts("user setting CLIENT mode\n"); - set_usb_power_mode(USB_POWER_CLIENT); - } - } + current_board->set_usb_power_mode(setup->b.wValue.w); break; // **** 0xf0: do k-line wValue pulse on uart2 for Acura case 0xf0: - if (setup->b.wValue.w == 1) { - GPIOC->ODR &= ~(1 << 10); + if (setup->b.wValue.w == 1U) { + GPIOC->ODR &= ~(1U << 10); GPIOC->MODER &= ~GPIO_MODER_MODER10_1; GPIOC->MODER |= GPIO_MODER_MODER10_0; } else { - GPIOC->ODR &= ~(1 << 12); + GPIOC->ODR &= ~(1U << 12); GPIOC->MODER &= ~GPIO_MODER_MODER12_1; GPIOC->MODER |= GPIO_MODER_MODER12_0; } for (i = 0; i < 80; i++) { delay(8000); - if (setup->b.wValue.w == 1) { - GPIOC->ODR |= (1 << 10); - GPIOC->ODR &= ~(1 << 10); + if (setup->b.wValue.w == 1U) { + GPIOC->ODR |= (1U << 10); + GPIOC->ODR &= ~(1U << 10); } else { - GPIOC->ODR |= (1 << 12); - GPIOC->ODR &= ~(1 << 12); + GPIOC->ODR |= (1U << 12); + GPIOC->ODR &= ~(1U << 12); } } - if (setup->b.wValue.w == 1) { + if (setup->b.wValue.w == 1U) { GPIOC->MODER &= ~GPIO_MODER_MODER10_0; GPIOC->MODER |= GPIO_MODER_MODER10_1; } else { @@ -423,24 +561,32 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { break; // **** 0xf1: Clear CAN ring buffer. case 0xf1: - if (setup->b.wValue.w == 0xFFFF) { + if (setup->b.wValue.w == 0xFFFFU) { puts("Clearing CAN Rx queue\n"); can_clear(&can_rx_q); } else if (setup->b.wValue.w < BUS_MAX) { puts("Clearing CAN Tx queue\n"); can_clear(can_queues[setup->b.wValue.w]); + } else { + puts("Clearing CAN CAN ring buffer failed: wrong bus number\n"); } break; // **** 0xf2: Clear UART ring buffer. case 0xf2: { uart_ring * rb = get_ring_by_number(setup->b.wValue.w); - if (rb) { + if (rb != NULL) { puts("Clearing UART queue.\n"); clear_uart_buff(rb); } break; } + // **** 0xf3: Heartbeat. Resets heartbeat counter. + case 0xf3: + { + heartbeat_counter = 0U; + break; + } default: puts("NO HANDLER "); puth(setup->b.bRequest); @@ -450,12 +596,12 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { return resp_len; } -#ifdef PANDA +#ifndef EON int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) { // data[0] = endpoint // data[2] = length // data[4:] = data - + UNUSED(len); int resp_len = 0; switch (data[0]) { case 0: @@ -474,81 +620,137 @@ int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) { // ep 3, send CAN usb_cb_ep3_out(data+4, data[2], 0); break; + default: + puts("SPI data invalid"); + break; } return resp_len; } - -#else - -int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) { return 0; }; - #endif - // ***************************** main code ***************************** -void __initialize_hardware_early() { +// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck +void __initialize_hardware_early(void) { early(); } -void __attribute__ ((noinline)) enable_fpu() { +void __attribute__ ((noinline)) enable_fpu(void) { // enable the FPU - SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2)); + SCB->CPACR |= ((3UL << (10U * 2U)) | (3UL << (11U * 2U))); } -int main() { +uint64_t tcnt = 0; + +// go into NOOUTPUT when the EON does not send a heartbeat for this amount of seconds. +#define EON_HEARTBEAT_IGNITION_CNT_ON 5U +#define EON_HEARTBEAT_IGNITION_CNT_OFF 2U + +// called once per second +// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck +void TIM1_BRK_TIM9_IRQHandler(void) { + if (TIM9->SR != 0) { + can_live = pending_can_live; + + current_board->usb_power_mode_tick(tcnt); + + //puth(usart1_dma); puts(" "); puth(DMA2_Stream5->M0AR); puts(" "); puth(DMA2_Stream5->NDTR); puts("\n"); + + // reset this every 16th pass + if ((tcnt & 0xFU) == 0U) { + pending_can_live = 0; + } + #ifdef DEBUG + puts("** blink "); + puth(can_rx_q.r_ptr); puts(" "); puth(can_rx_q.w_ptr); puts(" "); + puth(can_tx1_q.r_ptr); puts(" "); puth(can_tx1_q.w_ptr); puts(" "); + puth(can_tx2_q.r_ptr); puts(" "); puth(can_tx2_q.w_ptr); puts("\n"); + #endif + + // Tick fan driver + fan_tick(); + //puts("Fan speed: "); puth((unsigned int) fan_rpm); puts("rpm\n"); + + // set green LED to be controls allowed + current_board->set_led(LED_GREEN, controls_allowed); + + // turn off the blue LED, turned on by CAN + // unless we are in power saving mode + current_board->set_led(LED_BLUE, (tcnt & 1U) && (power_save_status == POWER_SAVE_STATUS_ENABLED)); + + // increase heartbeat counter and cap it at the uint32 limit + if (heartbeat_counter < __UINT32_MAX__) { + heartbeat_counter += 1U; + } + + // check heartbeat counter if we are running EON code. If the heartbeat has been gone for a while, go to NOOUTPUT safety mode. + #ifdef EON + if (heartbeat_counter >= (check_started() ? EON_HEARTBEAT_IGNITION_CNT_ON : EON_HEARTBEAT_IGNITION_CNT_OFF)) { + puts("EON hasn't sent a heartbeat for 0x"); puth(heartbeat_counter); puts(" seconds. Safety is set to NOOUTPUT mode.\n"); + if(current_safety_mode != SAFETY_NOOUTPUT){ + set_safety_mode(SAFETY_NOOUTPUT, 0U); + } + } + #endif + + // on to the next one + tcnt += 1U; + } + TIM9->SR = 0; +} + +int main(void) { // shouldn't have interrupts here, but just in case - __disable_irq(); + disable_interrupts(); // init early devices clock_init(); - periph_init(); - detect(); + peripherals_init(); + detect_configuration(); + detect_board_type(); + adc_init(); // print hello puts("\n\n\n************************ MAIN START ************************\n"); - // detect the revision and init the GPIOs - puts("config:\n"); - #ifdef PANDA - puts(revision == PANDA_REV_C ? " panda rev c\n" : " panda rev a or b\n"); - #else - puts(" legacy\n"); - #endif - puts(has_external_debug_serial ? " real serial\n" : " USB serial\n"); - puts(is_giant_panda ? " GIANTpanda detected\n" : " not GIANTpanda\n"); - puts(is_grey_panda ? " gray panda detected!\n" : " white panda\n"); - puts(is_entering_bootmode ? " ESP wants bootmode\n" : " no bootmode\n"); - gpio_init(); - -#ifdef PANDA + // check for non-supported board types + if(hw_type == HW_TYPE_UNKNOWN){ + puts("Unsupported board type\n"); + while (1) { /* hang */ } + } + + puts("Config:\n"); + puts(" Board type: "); puts(current_board->board_type); puts("\n"); + puts(has_external_debug_serial ? " Real serial\n" : " USB serial\n"); + puts(is_entering_bootmode ? " ESP wants bootmode\n" : " No bootmode\n"); + + // init board + current_board->init(); + // panda has an FPU, let's use it! enable_fpu(); -#endif // enable main uart if it's connected if (has_external_debug_serial) { // WEIRDNESS: without this gate around the UART, it would "crash", but only if the ESP is enabled // assuming it's because the lines were left floating and spurious noise was on them - uart_init(USART2, 115200); + uart_init(&uart_ring_debug, 115200); } -#ifdef PANDA - if (is_grey_panda) { - uart_init(USART1, 9600); + if (board_has_gps()) { + uart_init(&uart_ring_esp_gps, 9600); } else { // enable ESP uart - uart_init(USART1, 115200); - #ifdef EON - set_esp_mode(ESP_DISABLED); - #endif + uart_init(&uart_ring_esp_gps, 115200); + } + + if(board_has_lin()){ + // enable LIN + uart_init(&uart_ring_lin1, 10400); + UART5->CR2 |= USART_CR2_LINEN; + uart_init(&uart_ring_lin2, 10400); + USART3->CR2 |= USART_CR2_LINEN; } - // enable LIN - uart_init(UART5, 10400); - UART5->CR2 |= USART_CR2_LINEN; - uart_init(USART3, 10400); - USART3->CR2 |= USART_CR2_LINEN; -#endif // init microsecond system timer // increments 1000000 times per second @@ -558,136 +760,66 @@ int main() { TIM2->EGR = TIM_EGR_UG; // use TIM2->CNT to read - // enable USB - usb_init(); - // default to silent mode to prevent issues with Ford // hardcode a specific safety mode if you want to force the panda to be in a specific mode - safety_set_mode(SAFETY_NOOUTPUT, 0); - can_silent = ALL_CAN_SILENT; + int err = safety_set_mode(SAFETY_NOOUTPUT, 0); + if (err == -1) { + puts("Failed to set safety mode\n"); + while (true) { + // if SAFETY_NOOUTPUT isn't succesfully set, we can't continue + } + } + can_silent = ALL_CAN_LIVE; can_init_all(); - adc_init(); - -#ifdef PANDA +#ifndef EON spi_init(); #endif - // set PWM - fan_init(); - fan_set_speed(0); - - puts("**** INTERRUPTS ON ****\n"); +#ifdef EON + // have to save power + if (hw_type == HW_TYPE_WHITE_PANDA) { + current_board->set_esp_gps_mode(ESP_GPS_DISABLED); + } + // only enter power save after the first cycle + /*if (check_started()) { + set_power_save_state(POWER_SAVE_STATUS_ENABLED); + }*/ +#endif + // 1hz + timer_init(TIM9, 1464); + NVIC_EnableIRQ(TIM1_BRK_TIM9_IRQn); - __enable_irq(); +#ifdef DEBUG + puts("DEBUG ENABLED\n"); +#endif + // enable USB (right before interrupts or enum can fail!) + usb_init(); - // if the error interrupt is enabled to quickly when the CAN bus is active - // something bad happens and you can't connect to the device over USB - delay(10000000); - CAN1->IER |= CAN_IER_ERRIE | CAN_IER_LECIE; + puts("**** INTERRUPTS ON ****\n"); + enable_interrupts(); // LED should keep on blinking all the time uint64_t cnt = 0; - #ifdef PANDA - uint64_t marker = 0; - #define CURRENT_THRESHOLD 0xF00 - #define CLICKS 8 - #endif - for (cnt=0;;cnt++) { - can_live = pending_can_live; - - //puth(usart1_dma); puts(" "); puth(DMA2_Stream5->M0AR); puts(" "); puth(DMA2_Stream5->NDTR); puts("\n"); - - #ifdef PANDA - int current = adc_get(ADCCHAN_CURRENT); - - switch (usb_power_mode) { - case USB_POWER_CLIENT: - if ((cnt-marker) >= CLICKS) { - if (!is_enumerated) { - puts("USBP: didn't enumerate, switching to CDP mode\n"); - // switch to CDP - set_usb_power_mode(USB_POWER_CDP); - marker = cnt; - } + if (power_save_status == POWER_SAVE_STATUS_DISABLED) { + int div_mode = ((usb_power_mode == USB_POWER_DCP) ? 4 : 1); + + // useful for debugging, fade breaks = panda is overloaded + for (int div_mode_loop = 0; div_mode_loop < div_mode; div_mode_loop++) { + for (int fade = 0; fade < 1024; fade += 8) { + for (int i = 0; i < (128/div_mode); i++) { + current_board->set_led(LED_RED, 1); + if (fade < 512) { delay(fade); } else { delay(1024-fade); } + current_board->set_led(LED_RED, 0); + if (fade < 512) { delay(512-fade); } else { delay(fade-512); } } - // keep resetting the timer if it's enumerated - if (is_enumerated) { - marker = cnt; - } - break; - case USB_POWER_CDP: -#ifndef EON - // been CLICKS clicks since we switched to CDP - if ((cnt-marker) >= CLICKS) { - // measure current draw, if positive and no enumeration, switch to DCP - if (!is_enumerated && current < CURRENT_THRESHOLD) { - puts("USBP: no enumeration with current draw, switching to DCP mode\n"); - set_usb_power_mode(USB_POWER_DCP); - marker = cnt; - } - } - // keep resetting the timer if there's no current draw in CDP - if (current >= CURRENT_THRESHOLD) { - marker = cnt; - } -#endif - break; - case USB_POWER_DCP: - // been at least CLICKS clicks since we switched to DCP - if ((cnt-marker) >= CLICKS) { - // if no current draw, switch back to CDP - if (current >= CURRENT_THRESHOLD) { - puts("USBP: no current draw, switching back to CDP mode\n"); - set_usb_power_mode(USB_POWER_CDP); - marker = cnt; - } - } - // keep resetting the timer if there's current draw in DCP - if (current < CURRENT_THRESHOLD) { - marker = cnt; - } - break; - } - - // ~0x9a = 500 ma - /*puth(current); - puts("\n");*/ - #endif - - // reset this every 16th pass - if ((cnt&0xF) == 0) pending_can_live = 0; - - #ifdef DEBUG - puts("** blink "); - puth(can_rx_q.r_ptr); puts(" "); puth(can_rx_q.w_ptr); puts(" "); - puth(can_tx1_q.r_ptr); puts(" "); puth(can_tx1_q.w_ptr); puts(" "); - puth(can_tx2_q.r_ptr); puts(" "); puth(can_tx2_q.w_ptr); puts("\n"); - #endif - - // set green LED to be controls allowed - set_led(LED_GREEN, controls_allowed); - - // blink the red LED - int div_mode = ((usb_power_mode == USB_POWER_DCP) ? 4 : 1); - - for (int div_mode_loop = 0; div_mode_loop < div_mode; div_mode_loop++) { - for (int fade = 0; fade < 1024; fade += 8) { - for (int i = 0; i < 128/div_mode; i++) { - set_led(LED_RED, 0); - if (fade < 512) { delay(512-fade); } else { delay(fade-512); } - set_led(LED_RED, 1); - if (fade < 512) { delay(fade); } else { delay(1024-fade); } } } + } else { + __WFI(); } - - // turn off the blue LED, turned on by CAN - #ifdef PANDA - set_led(LED_BLUE, 0); - #endif } return 0; diff --git a/panda/board/main_declarations.h b/panda/board/main_declarations.h new file mode 100644 index 00000000000000..8929e9ac0e0cd9 --- /dev/null +++ b/panda/board/main_declarations.h @@ -0,0 +1,14 @@ +// ******************** Prototypes ******************** +void puts(const char *a); +void puth(unsigned int i); +void puth2(unsigned int i); +typedef struct board board; +typedef struct harness_configuration harness_configuration; +void can_flip_buses(uint8_t bus1, uint8_t bus2); +void can_set_obd(uint8_t harness_orientation, bool obd); + +// ********************* Globals ********************** +uint8_t hw_type = 0; +const board *current_board; +bool is_enumerated = 0; +uint32_t heartbeat_counter = 0; \ No newline at end of file diff --git a/panda/board/obj/panda.bin.signed b/panda/board/obj/panda.bin.signed new file mode 100644 index 00000000000000..7fa3f83e559081 Binary files /dev/null and b/panda/board/obj/panda.bin.signed differ diff --git a/panda/board/pedal/Makefile b/panda/board/pedal/Makefile index 37b95f90fb1880..7ce6dd07684da5 100644 --- a/panda/board/pedal/Makefile +++ b/panda/board/pedal/Makefile @@ -1,10 +1,10 @@ # :set noet PROJ_NAME = comma -CFLAGS = -O2 -Wall -std=gnu11 -DPEDAL +CFLAGS = -O2 -Wall -Wextra -Wstrict-prototypes -Werror -std=gnu11 -DPEDAL CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m3 CFLAGS += -msoft-float -DSTM32F2 -DSTM32F205xx -CFLAGS += -I ../inc -I ../ -I ../../ -nostdlib +CFLAGS += -I ../inc -I ../ -I ../../ -nostdlib -fno-builtin CFLAGS += -T../stm32_flash.ld STARTUP_FILE = startup_stm32f205xx diff --git a/panda/board/pedal/main.c b/panda/board/pedal/main.c index 13a221a871fafc..e7642f0c005635 100644 --- a/panda/board/pedal/main.c +++ b/panda/board/pedal/main.c @@ -1,69 +1,100 @@ -//#define DEBUG -//#define CAN_LOOPBACK_MODE -//#define USE_INTERNAL_OSC - +// ********************* Includes ********************* #include "../config.h" +#include "libc.h" -#include "drivers/drivers.h" +#include "main_declarations.h" + +#include "drivers/llcan.h" #include "drivers/llgpio.h" -#include "gpio.h" +#include "drivers/adc.h" -#define CUSTOM_CAN_INTERRUPTS +#include "board.h" -#include "libc.h" -#include "safety.h" -#include "drivers/adc.h" -#include "drivers/uart.h" +#include "drivers/clock.h" #include "drivers/dac.h" -#include "drivers/can.h" #include "drivers/timer.h" +#include "gpio.h" + #define CAN CAN1 //#define PEDAL_USB #ifdef PEDAL_USB + #include "drivers/uart.h" #include "drivers/usb.h" +#else + // no serial either + void puts(const char *a) { + UNUSED(a); + } + void puth(unsigned int i) { + UNUSED(i); + } + void puth2(unsigned int i) { + UNUSED(i); + } #endif #define ENTER_BOOTLOADER_MAGIC 0xdeadbeef uint32_t enter_bootloader_mode; -void __initialize_hardware_early() { +// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck +void __initialize_hardware_early(void) { early(); } // ********************* serial debugging ********************* +#ifdef PEDAL_USB + void debug_ring_callback(uart_ring *ring) { char rcv; - while (getc(ring, &rcv)) { - putc(ring, rcv); + while (getc(ring, &rcv) != 0) { + (void)putc(ring, rcv); } } -#ifdef PEDAL_USB - -int usb_cb_ep1_in(uint8_t *usbdata, int len, int hardwired) { return 0; } -void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired) {} -void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired) {} -void usb_cb_enumeration_complete() {} +int usb_cb_ep1_in(void *usbdata, int len, bool hardwired) { + UNUSED(usbdata); + UNUSED(len); + UNUSED(hardwired); + return 0; +} +void usb_cb_ep2_out(void *usbdata, int len, bool hardwired) { + UNUSED(usbdata); + UNUSED(len); + UNUSED(hardwired); +} +void usb_cb_ep3_out(void *usbdata, int len, bool hardwired) { + UNUSED(usbdata); + UNUSED(len); + UNUSED(hardwired); +} +void usb_cb_enumeration_complete(void) {} -int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { - int resp_len = 0; +int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired) { + UNUSED(hardwired); + unsigned int resp_len = 0; uart_ring *ur = NULL; switch (setup->b.bRequest) { // **** 0xe0: uart read case 0xe0: ur = get_ring_by_number(setup->b.wValue.w); - if (!ur) break; - if (ur == &esp_ring) uart_dma_drain(); + if (!ur) { + break; + } // read - while ((resp_len < min(setup->b.wLength.w, MAX_RESP_LEN)) && + while ((resp_len < MIN(setup->b.wLength.w, MAX_RESP_LEN)) && getc(ur, (char*)&resp[resp_len])) { ++resp_len; } break; + default: + puts("NO HANDLER "); + puth(setup->b.bRequest); + puts("\n"); + break; } return resp_len; } @@ -79,7 +110,7 @@ uint8_t pedal_checksum(uint8_t *dat, int len) { for (i = len - 1; i >= 0; i--) { crc ^= dat[i]; for (j = 0; j < 8; j++) { - if ((crc & 0x80) != 0) { + if ((crc & 0x80U) != 0U) { crc = (uint8_t)((crc << 1) ^ poly); } else { @@ -94,11 +125,12 @@ uint8_t pedal_checksum(uint8_t *dat, int len) { // addresses to be used on CAN #define CAN_GAS_INPUT 0x200 -#define CAN_GAS_OUTPUT 0x201 +#define CAN_GAS_OUTPUT 0x201U #define CAN_GAS_SIZE 6 -#define COUNTER_CYCLE 0xF +#define COUNTER_CYCLE 0xFU -void CAN1_TX_IRQHandler() { +// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck +void CAN1_TX_IRQHandler(void) { // clear interrupt CAN->TSR |= CAN_TSR_RQCP0; } @@ -107,54 +139,54 @@ void CAN1_TX_IRQHandler() { uint16_t gas_set_0 = 0; uint16_t gas_set_1 = 0; -#define MAX_TIMEOUT 10 +#define MAX_TIMEOUT 10U uint32_t timeout = 0; uint32_t current_index = 0; -#define NO_FAULT 0 -#define FAULT_BAD_CHECKSUM 1 -#define FAULT_SEND 2 -#define FAULT_SCE 3 -#define FAULT_STARTUP 4 -#define FAULT_TIMEOUT 5 -#define FAULT_INVALID 6 +#define NO_FAULT 0U +#define FAULT_BAD_CHECKSUM 1U +#define FAULT_SEND 2U +#define FAULT_SCE 3U +#define FAULT_STARTUP 4U +#define FAULT_TIMEOUT 5U +#define FAULT_INVALID 6U uint8_t state = FAULT_STARTUP; -void CAN1_RX0_IRQHandler() { - while (CAN->RF0R & CAN_RF0R_FMP0) { +// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck +void CAN1_RX0_IRQHandler(void) { + while ((CAN->RF0R & CAN_RF0R_FMP0) != 0) { #ifdef DEBUG puts("CAN RX\n"); #endif - uint32_t address = CAN->sFIFOMailBox[0].RIR>>21; + int address = CAN->sFIFOMailBox[0].RIR >> 21; if (address == CAN_GAS_INPUT) { // softloader entry - if (CAN->sFIFOMailBox[0].RDLR == 0xdeadface) { - if (CAN->sFIFOMailBox[0].RDHR == 0x0ab00b1e) { + if (GET_BYTES_04(&CAN->sFIFOMailBox[0]) == 0xdeadface) { + if (GET_BYTES_48(&CAN->sFIFOMailBox[0]) == 0x0ab00b1e) { enter_bootloader_mode = ENTER_SOFTLOADER_MAGIC; NVIC_SystemReset(); - } else if (CAN->sFIFOMailBox[0].RDHR == 0x02b00b1e) { + } else if (GET_BYTES_48(&CAN->sFIFOMailBox[0]) == 0x02b00b1e) { enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC; NVIC_SystemReset(); + } else { + puts("Failed entering Softloader or Bootloader\n"); } } // normal packet uint8_t dat[8]; - uint8_t *rdlr = (uint8_t *)&CAN->sFIFOMailBox[0].RDLR; - uint8_t *rdhr = (uint8_t *)&CAN->sFIFOMailBox[0].RDHR; - for (int i=0; i<4; i++) { - dat[i] = rdlr[i]; - dat[i+4] = rdhr[i]; + for (int i=0; i<8; i++) { + dat[i] = GET_BYTE(&CAN->sFIFOMailBox[0], i); } uint16_t value_0 = (dat[0] << 8) | dat[1]; uint16_t value_1 = (dat[2] << 8) | dat[3]; - uint8_t enable = (dat[4] >> 7) & 1; + bool enable = ((dat[4] >> 7) & 1U) != 0U; uint8_t index = dat[4] & COUNTER_CYCLE; if (pedal_checksum(dat, CAN_GAS_SIZE - 1) == dat[5]) { - if (((current_index + 1) & COUNTER_CYCLE) == index) { + if (((current_index + 1U) & COUNTER_CYCLE) == index) { #ifdef DEBUG puts("setting gas "); - puth(value); + puth(value_0); puts("\n"); #endif if (enable) { @@ -162,12 +194,13 @@ void CAN1_RX0_IRQHandler() { gas_set_1 = value_1; } else { // clear the fault state if values are 0 - if (value_0 == 0 && value_1 == 0) { + if ((value_0 == 0U) && (value_1 == 0U)) { state = NO_FAULT; } else { state = FAULT_INVALID; } - gas_set_0 = gas_set_1 = 0; + gas_set_0 = 0; + gas_set_1 = 0; } // clear the timeout timeout = 0; @@ -183,17 +216,20 @@ void CAN1_RX0_IRQHandler() { } } -void CAN1_SCE_IRQHandler() { +// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck +void CAN1_SCE_IRQHandler(void) { state = FAULT_SCE; - can_sce(CAN); + llcan_clear_send(CAN); } -int pdl0 = 0, pdl1 = 0; -int pkt_idx = 0; +uint32_t pdl0 = 0; +uint32_t pdl1 = 0; +unsigned int pkt_idx = 0; int led_value = 0; -void TIM3_IRQHandler() { +// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck +void TIM3_IRQHandler(void) { #ifdef DEBUG puth(TIM3->CNT); puts(" "); @@ -206,16 +242,16 @@ void TIM3_IRQHandler() { // check timer for sending the user pedal and clearing the CAN if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) { uint8_t dat[8]; - dat[0] = (pdl0>>8) & 0xFF; - dat[1] = (pdl0>>0) & 0xFF; - dat[2] = (pdl1>>8) & 0xFF; - dat[3] = (pdl1>>0) & 0xFF; - dat[4] = (state & 0xF) << 4 | pkt_idx; + dat[0] = (pdl0 >> 8) & 0xFFU; + dat[1] = (pdl0 >> 0) & 0xFFU; + dat[2] = (pdl1 >> 8) & 0xFFU; + dat[3] = (pdl1 >> 0) & 0xFFU; + dat[4] = ((state & 0xFU) << 4) | pkt_idx; dat[5] = pedal_checksum(dat, CAN_GAS_SIZE - 1); - CAN->sTxMailBox[0].TDLR = dat[0] | (dat[1]<<8) | (dat[2]<<16) | (dat[3]<<24); - CAN->sTxMailBox[0].TDHR = dat[4] | (dat[5]<<8); + CAN->sTxMailBox[0].TDLR = dat[0] | (dat[1] << 8) | (dat[2] << 16) | (dat[3] << 24); + CAN->sTxMailBox[0].TDHR = dat[4] | (dat[5] << 8); CAN->sTxMailBox[0].TDTR = 6; // len of packet is 5 - CAN->sTxMailBox[0].TIR = (CAN_GAS_OUTPUT << 21) | 1; + CAN->sTxMailBox[0].TIR = (CAN_GAS_OUTPUT << 21) | 1U; ++pkt_idx; pkt_idx &= COUNTER_CYCLE; } else { @@ -227,7 +263,7 @@ void TIM3_IRQHandler() { } // blink the LED - set_led(LED_GREEN, led_value); + current_board->set_led(LED_GREEN, led_value); led_value = !led_value; TIM3->SR = 0; @@ -236,37 +272,40 @@ void TIM3_IRQHandler() { if (timeout == MAX_TIMEOUT) { state = FAULT_TIMEOUT; } else { - timeout += 1; + timeout += 1U; } } // ***************************** main code ***************************** -void pedal() { +void pedal(void) { // read/write pdl0 = adc_get(ADCCHAN_ACCEL0); pdl1 = adc_get(ADCCHAN_ACCEL1); // write the pedal to the DAC if (state == NO_FAULT) { - dac_set(0, max(gas_set_0, pdl0)); - dac_set(1, max(gas_set_1, pdl1)); + dac_set(0, MAX(gas_set_0, pdl0)); + dac_set(1, MAX(gas_set_1, pdl1)); } else { dac_set(0, pdl0); dac_set(1, pdl1); } - // feed the watchdog - IWDG->KR = 0xAAAA; + watchdog_feed(); } -int main() { - __disable_irq(); +int main(void) { + disable_interrupts(); // init devices clock_init(); - periph_init(); - gpio_init(); + peripherals_init(); + detect_configuration(); + detect_board_type(); + + // init board + current_board->init(); #ifdef PEDAL_USB // enable USB @@ -278,22 +317,21 @@ int main() { adc_init(); // init can - can_silent = ALL_CAN_LIVE; - can_init(0); + bool llcan_speed_set = llcan_set_speed(CAN1, 5000, false, false); + if (!llcan_speed_set) { + puts("Failed to set llcan speed"); + } + + llcan_init(CAN1); // 48mhz / 65536 ~= 732 timer_init(TIM3, 15); NVIC_EnableIRQ(TIM3_IRQn); - // setup watchdog - IWDG->KR = 0x5555; - IWDG->PR = 0; // divider /4 - // 0 = 0.125 ms, let's have a 50ms watchdog - IWDG->RLR = 400 - 1; - IWDG->KR = 0xCCCC; + watchdog_init(); puts("**** INTERRUPTS ON ****\n"); - __enable_irq(); + enable_interrupts(); // main pedal loop while (1) { @@ -302,4 +340,3 @@ int main() { return 0; } - diff --git a/panda/board/pedal/main_declarations.h b/panda/board/pedal/main_declarations.h new file mode 100644 index 00000000000000..9a40f8ae3af447 --- /dev/null +++ b/panda/board/pedal/main_declarations.h @@ -0,0 +1,11 @@ +// ******************** Prototypes ******************** +void puts(const char *a); +void puth(unsigned int i); +void puth2(unsigned int i); +typedef struct board board; +typedef struct harness_configuration harness_configuration; + +// ********************* Globals ********************** +uint8_t hw_type = 0; +const board *current_board; +bool is_enumerated = 0; \ No newline at end of file diff --git a/panda/board/power_saving.h b/panda/board/power_saving.h new file mode 100644 index 00000000000000..d397884f6e6a8f --- /dev/null +++ b/panda/board/power_saving.h @@ -0,0 +1,57 @@ +#define POWER_SAVE_STATUS_DISABLED 0 +#define POWER_SAVE_STATUS_ENABLED 1 + +int power_save_status = POWER_SAVE_STATUS_DISABLED; + +void set_power_save_state(int state) { + + bool is_valid_state = (state == POWER_SAVE_STATUS_ENABLED) || (state == POWER_SAVE_STATUS_DISABLED); + if (is_valid_state && (state != power_save_status)) { + bool enable = false; + if (state == POWER_SAVE_STATUS_ENABLED) { + puts("enable power savings\n"); + if (board_has_gps()) { + char UBLOX_SLEEP_MSG[] = "\xb5\x62\x06\x04\x04\x00\x01\x00\x08\x00\x17\x78"; + uart_ring *ur = get_ring_by_number(1); + for (unsigned int i = 0; i < sizeof(UBLOX_SLEEP_MSG) - 1U; i++) while (!putc(ur, UBLOX_SLEEP_MSG[i])); + } + } else { + puts("disable power savings\n"); + if (board_has_gps()) { + char UBLOX_WAKE_MSG[] = "\xb5\x62\x06\x04\x04\x00\x01\x00\x09\x00\x18\x7a"; + uart_ring *ur = get_ring_by_number(1); + for (unsigned int i = 0; i < sizeof(UBLOX_WAKE_MSG) - 1U; i++) while (!putc(ur, UBLOX_WAKE_MSG[i])); + } + enable = true; + } + + current_board->enable_can_transcievers(enable); + + // Switch EPS/GPS + if (enable) { + current_board->set_esp_gps_mode(ESP_GPS_ENABLED); + } else { + current_board->set_esp_gps_mode(ESP_GPS_DISABLED); + } + + if(board_has_gmlan()){ + // turn on GMLAN + set_gpio_output(GPIOB, 14, enable); + set_gpio_output(GPIOB, 15, enable); + } + + if(board_has_lin()){ + // turn on LIN + set_gpio_output(GPIOB, 7, enable); + set_gpio_output(GPIOA, 14, enable); + } + + // Switch off IR and fan when in power saving + if(!enable){ + current_board->set_ir_power(0U); + current_board->set_fan_power(0U); + } + + power_save_status = state; + } +} diff --git a/panda/board/provision.h b/panda/board/provision.h index 2fad513508132d..9091322f1a1091 100644 --- a/panda/board/provision.h +++ b/panda/board/provision.h @@ -5,9 +5,9 @@ // SHA1 checksum = 0x1C - 0x20 void get_provision_chunk(uint8_t *resp) { - memcpy(resp, (void *)0x1fff79e0, PROVISION_CHUNK_LEN); + (void)memcpy(resp, (uint8_t *)0x1fff79e0, PROVISION_CHUNK_LEN); if (memcmp(resp, "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", 0x20) == 0) { - memcpy(resp, "unprovisioned\x00\x00\x00testing123\x00\x00\xa3\xa6\x99\xec", 0x20); + (void)memcpy(resp, "unprovisioned\x00\x00\x00testing123\x00\x00\xa3\xa6\x99\xec", 0x20); } } diff --git a/panda/board/safety.h b/panda/board/safety.h index 6e5dc8e36f62b2..c68eda2c4a4864 100644 --- a/panda/board/safety.h +++ b/panda/board/safety.h @@ -1,72 +1,42 @@ -// sample struct that keeps 3 samples in memory -struct sample_t { - int values[6]; - int min; - int max; -} sample_t_default = {{0}, 0, 0}; - -// no float support in STM32F2 micros (cortex-m3) -#ifdef PANDA -struct lookup_t { - float x[3]; - float y[3]; -}; -#endif - -void safety_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); -int safety_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); -int safety_tx_lin_hook(int lin_num, uint8_t *data, int len); -int safety_ignition_hook(); -uint32_t get_ts_elapsed(uint32_t ts, uint32_t ts_last); -int to_signed(int d, int bits); -void update_sample(struct sample_t *sample, int sample_new); -int max_limit_check(int val, const int MAX, const int MIN); -int dist_to_meas_check(int val, int val_last, struct sample_t *val_meas, - const int MAX_RATE_UP, const int MAX_RATE_DOWN, const int MAX_ERROR); -int driver_limit_check(int val, int val_last, struct sample_t *val_driver, - const int MAX, const int MAX_RATE_UP, const int MAX_RATE_DOWN, - const int MAX_ALLOWANCE, const int DRIVER_FACTOR); -int rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA); -#ifdef PANDA -float interpolate(struct lookup_t xy, float x); -#endif - -typedef void (*safety_hook_init)(int16_t param); -typedef void (*rx_hook)(CAN_FIFOMailBox_TypeDef *to_push); -typedef int (*tx_hook)(CAN_FIFOMailBox_TypeDef *to_send); -typedef int (*tx_lin_hook)(int lin_num, uint8_t *data, int len); -typedef int (*ign_hook)(); -typedef int (*fwd_hook)(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd); - -typedef struct { - safety_hook_init init; - ign_hook ignition; - rx_hook rx; - tx_hook tx; - tx_lin_hook tx_lin; - fwd_hook fwd; -} safety_hooks; - -// This can be set by the safety hooks. -int controls_allowed = 0; - +// include first, needed by safety policies +#include "safety_declarations.h" // Include the actual safety policies. #include "safety/safety_defaults.h" #include "safety/safety_honda.h" #include "safety/safety_toyota.h" -#ifdef PANDA #include "safety/safety_toyota_ipas.h" #include "safety/safety_tesla.h" #include "safety/safety_gm_ascm.h" -#endif #include "safety/safety_gm.h" #include "safety/safety_ford.h" #include "safety/safety_cadillac.h" #include "safety/safety_hyundai.h" #include "safety/safety_chrysler.h" #include "safety/safety_subaru.h" +#include "safety/safety_mazda.h" +#include "safety/safety_volkswagen.h" #include "safety/safety_elm327.h" +// from cereal.car.CarParams.SafetyModel +#define SAFETY_NOOUTPUT 0U +#define SAFETY_HONDA 1U +#define SAFETY_TOYOTA 2U +#define SAFETY_ELM327 3U +#define SAFETY_GM 4U +#define SAFETY_HONDA_BOSCH 5U +#define SAFETY_FORD 6U +#define SAFETY_CADILLAC 7U +#define SAFETY_HYUNDAI 8U +#define SAFETY_CHRYSLER 9U +#define SAFETY_TESLA 10U +#define SAFETY_SUBARU 11U +#define SAFETY_MAZDA 13U +#define SAFETY_VOLKSWAGEN 15U +#define SAFETY_TOYOTA_IPAS 16U +#define SAFETY_ALLOUTPUT 17U +#define SAFETY_GM_ASCM 18U + +uint16_t current_safety_mode = SAFETY_NOOUTPUT; const safety_hooks *current_hooks = &nooutput_hooks; void safety_rx_hook(CAN_FIFOMailBox_TypeDef *to_push){ @@ -81,12 +51,6 @@ int safety_tx_lin_hook(int lin_num, uint8_t *data, int len){ return current_hooks->tx_lin(lin_num, data, len); } -// -1 = Disabled (Use GPIO to determine ignition) -// 0 = Off (not started) -// 1 = On (started) -int safety_ignition_hook() { - return current_hooks->ignition(); -} int safety_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { return current_hooks->fwd(bus_num, to_fwd); } @@ -96,121 +60,115 @@ typedef struct { const safety_hooks *hooks; } safety_hook_config; -#define SAFETY_NOOUTPUT 0 -#define SAFETY_HONDA 1 -#define SAFETY_TOYOTA 2 -#define SAFETY_GM 3 -#define SAFETY_HONDA_BOSCH 4 -#define SAFETY_FORD 5 -#define SAFETY_CADILLAC 6 -#define SAFETY_HYUNDAI 7 -#define SAFETY_TESLA 8 -#define SAFETY_CHRYSLER 9 -#define SAFETY_SUBARU 10 -#define SAFETY_GM_ASCM 0x1334 -#define SAFETY_TOYOTA_IPAS 0x1335 -#define SAFETY_TOYOTA_NOLIMITS 0x1336 -#define SAFETY_ALLOUTPUT 0x1337 -#define SAFETY_ELM327 0xE327 - const safety_hook_config safety_hook_registry[] = { {SAFETY_NOOUTPUT, &nooutput_hooks}, {SAFETY_HONDA, &honda_hooks}, - {SAFETY_HONDA_BOSCH, &honda_bosch_hooks}, {SAFETY_TOYOTA, &toyota_hooks}, + {SAFETY_ELM327, &elm327_hooks}, {SAFETY_GM, &gm_hooks}, + {SAFETY_HONDA_BOSCH, &honda_bosch_hooks}, {SAFETY_FORD, &ford_hooks}, {SAFETY_CADILLAC, &cadillac_hooks}, {SAFETY_HYUNDAI, &hyundai_hooks}, {SAFETY_CHRYSLER, &chrysler_hooks}, + {SAFETY_TESLA, &tesla_hooks}, {SAFETY_SUBARU, &subaru_hooks}, - {SAFETY_TOYOTA_NOLIMITS, &toyota_nolimits_hooks}, -#ifdef PANDA + {SAFETY_MAZDA, &mazda_hooks}, + {SAFETY_VOLKSWAGEN, &volkswagen_hooks}, {SAFETY_TOYOTA_IPAS, &toyota_ipas_hooks}, - {SAFETY_GM_ASCM, &gm_ascm_hooks}, - {SAFETY_TESLA, &tesla_hooks}, -#endif {SAFETY_ALLOUTPUT, &alloutput_hooks}, - {SAFETY_ELM327, &elm327_hooks}, + {SAFETY_GM_ASCM, &gm_ascm_hooks}, }; -#define HOOK_CONFIG_COUNT (sizeof(safety_hook_registry)/sizeof(safety_hook_config)) - int safety_set_mode(uint16_t mode, int16_t param) { - for (int i = 0; i < HOOK_CONFIG_COUNT; i++) { + int set_status = -1; // not set + int hook_config_count = sizeof(safety_hook_registry) / sizeof(safety_hook_config); + for (int i = 0; i < hook_config_count; i++) { if (safety_hook_registry[i].id == mode) { current_hooks = safety_hook_registry[i].hooks; - if (current_hooks->init) current_hooks->init(param); - return 0; + current_safety_mode = safety_hook_registry[i].id; + set_status = 0; // set + break; } } - return -1; + if ((set_status == 0) && (current_hooks->init != NULL)) { + current_hooks->init(param); + } + return set_status; } // compute the time elapsed (in microseconds) from 2 counter samples +// case where ts < ts_last is ok: overflow is properly re-casted into uint32_t uint32_t get_ts_elapsed(uint32_t ts, uint32_t ts_last) { - return ts > ts_last ? ts - ts_last : (0xFFFFFFFF - ts_last) + 1 + ts; + return ts - ts_last; } // convert a trimmed integer to signed 32 bit int int to_signed(int d, int bits) { - if (d >= (1 << (bits - 1))) { - d -= (1 << bits); + int d_signed = d; + if (d >= (1 << MAX((bits - 1), 0))) { + d_signed = d - (1 << MAX(bits, 0)); } - return d; + return d_signed; } // given a new sample, update the smaple_t struct void update_sample(struct sample_t *sample, int sample_new) { - for (int i = sizeof(sample->values)/sizeof(sample->values[0]) - 1; i > 0; i--) { + int sample_size = sizeof(sample->values) / sizeof(sample->values[0]); + for (int i = sample_size - 1; i > 0; i--) { sample->values[i] = sample->values[i-1]; } sample->values[0] = sample_new; // get the minimum and maximum measured samples - sample->min = sample->max = sample->values[0]; - for (int i = 1; i < sizeof(sample->values)/sizeof(sample->values[0]); i++) { - if (sample->values[i] < sample->min) sample->min = sample->values[i]; - if (sample->values[i] > sample->max) sample->max = sample->values[i]; + sample->min = sample->values[0]; + sample->max = sample->values[0]; + for (int i = 1; i < sample_size; i++) { + if (sample->values[i] < sample->min) { + sample->min = sample->values[i]; + } + if (sample->values[i] > sample->max) { + sample->max = sample->values[i]; + } } } -int max_limit_check(int val, const int MAX, const int MIN) { - return (val > MAX) || (val < MIN); +bool max_limit_check(int val, const int MAX_VAL, const int MIN_VAL) { + return (val > MAX_VAL) || (val < MIN_VAL); } // check that commanded value isn't too far from measured -int dist_to_meas_check(int val, int val_last, struct sample_t *val_meas, +bool dist_to_meas_check(int val, int val_last, struct sample_t *val_meas, const int MAX_RATE_UP, const int MAX_RATE_DOWN, const int MAX_ERROR) { // *** val rate limit check *** - int highest_allowed_val = max(val_last, 0) + MAX_RATE_UP; - int lowest_allowed_val = min(val_last, 0) - MAX_RATE_UP; + int highest_allowed_rl = MAX(val_last, 0) + MAX_RATE_UP; + int lowest_allowed_rl = MIN(val_last, 0) - MAX_RATE_UP; // if we've exceeded the meas val, we must start moving toward 0 - highest_allowed_val = min(highest_allowed_val, max(val_last - MAX_RATE_DOWN, max(val_meas->max, 0) + MAX_ERROR)); - lowest_allowed_val = max(lowest_allowed_val, min(val_last + MAX_RATE_DOWN, min(val_meas->min, 0) - MAX_ERROR)); + int highest_allowed = MIN(highest_allowed_rl, MAX(val_last - MAX_RATE_DOWN, MAX(val_meas->max, 0) + MAX_ERROR)); + int lowest_allowed = MAX(lowest_allowed_rl, MIN(val_last + MAX_RATE_DOWN, MIN(val_meas->min, 0) - MAX_ERROR)); // check for violation - return (val < lowest_allowed_val) || (val > highest_allowed_val); + return (val < lowest_allowed) || (val > highest_allowed); } // check that commanded value isn't fighting against driver -int driver_limit_check(int val, int val_last, struct sample_t *val_driver, - const int MAX, const int MAX_RATE_UP, const int MAX_RATE_DOWN, +bool driver_limit_check(int val, int val_last, struct sample_t *val_driver, + const int MAX_VAL, const int MAX_RATE_UP, const int MAX_RATE_DOWN, const int MAX_ALLOWANCE, const int DRIVER_FACTOR) { - int highest_allowed = max(val_last, 0) + MAX_RATE_UP; - int lowest_allowed = min(val_last, 0) - MAX_RATE_UP; + int highest_allowed_rl = MAX(val_last, 0) + MAX_RATE_UP; + int lowest_allowed_rl = MIN(val_last, 0) - MAX_RATE_UP; - int driver_max_limit = MAX + (MAX_ALLOWANCE + val_driver->max) * DRIVER_FACTOR; - int driver_min_limit = -MAX + (-MAX_ALLOWANCE + val_driver->min) * DRIVER_FACTOR; + int driver_max_limit = MAX_VAL + (MAX_ALLOWANCE + val_driver->max) * DRIVER_FACTOR; + int driver_min_limit = -MAX_VAL + (-MAX_ALLOWANCE + val_driver->min) * DRIVER_FACTOR; // if we've exceeded the applied torque, we must start moving toward 0 - highest_allowed = min(highest_allowed, max(val_last - MAX_RATE_DOWN, - max(driver_max_limit, 0))); - lowest_allowed = max(lowest_allowed, min(val_last + MAX_RATE_DOWN, - min(driver_min_limit, 0))); + int highest_allowed = MIN(highest_allowed_rl, MAX(val_last - MAX_RATE_DOWN, + MAX(driver_max_limit, 0))); + int lowest_allowed = MAX(lowest_allowed_rl, MIN(val_last + MAX_RATE_DOWN, + MIN(driver_min_limit, 0))); // check for violation return (val < lowest_allowed) || (val > highest_allowed); @@ -218,40 +176,43 @@ int driver_limit_check(int val, int val_last, struct sample_t *val_driver, // real time check, mainly used for steer torque rate limiter -int rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA) { +bool rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA) { // *** torque real time rate limit check *** - int highest_val = max(val_last, 0) + MAX_RT_DELTA; - int lowest_val = min(val_last, 0) - MAX_RT_DELTA; + int highest_val = MAX(val_last, 0) + MAX_RT_DELTA; + int lowest_val = MIN(val_last, 0) - MAX_RT_DELTA; // check for violation return (val < lowest_val) || (val > highest_val); } -#ifdef PANDA // interp function that holds extreme values float interpolate(struct lookup_t xy, float x) { + int size = sizeof(xy.x) / sizeof(xy.x[0]); + float ret = xy.y[size - 1]; // default output is last point + // x is lower than the first point in the x array. Return the first point if (x <= xy.x[0]) { - return xy.y[0]; + ret = xy.y[0]; } else { // find the index such that (xy.x[i] <= x < xy.x[i+1]) and linearly interp - for (int i=0; i < size-1; i++) { + for (int i=0; i < (size - 1); i++) { if (x < xy.x[i+1]) { float x0 = xy.x[i]; float y0 = xy.y[i]; float dx = xy.x[i+1] - x0; float dy = xy.y[i+1] - y0; // dx should not be zero as xy.x is supposed ot be monotonic - if (dx <= 0.) dx = 0.0001; - return dy * (x - x0) / dx + y0; + if (dx <= 0.) { + dx = 0.0001; + } + ret = (dy * (x - x0) / dx) + y0; + break; } } - // if no such point is found, then x > xy.x[size-1]. Return last point - return xy.y[size - 1]; } + return ret; } -#endif diff --git a/panda/board/safety/safety_cadillac.h b/panda/board/safety/safety_cadillac.h index 2a2d8b9857ff91..4ae2045505d8a7 100644 --- a/panda/board/safety/safety_cadillac.h +++ b/panda/board/safety/safety_cadillac.h @@ -1,50 +1,46 @@ +#define CADILLAC_TORQUE_MSG_N 4 // 4 torque messages: 0x151, 0x152, 0x153, 0x154 + const int CADILLAC_MAX_STEER = 150; // 1s // real time torque limit to prevent controls spamming // the real time limit is 1500/sec const int CADILLAC_MAX_RT_DELTA = 75; // max delta torque allowed for real time checks -const int32_t CADILLAC_RT_INTERVAL = 250000; // 250ms between real time checks +const uint32_t CADILLAC_RT_INTERVAL = 250000; // 250ms between real time checks const int CADILLAC_MAX_RATE_UP = 2; const int CADILLAC_MAX_RATE_DOWN = 5; const int CADILLAC_DRIVER_TORQUE_ALLOWANCE = 50; const int CADILLAC_DRIVER_TORQUE_FACTOR = 4; -int cadillac_ign = 0; int cadillac_cruise_engaged_last = 0; int cadillac_rt_torque_last = 0; -int cadillac_desired_torque_last[4] = {0}; // 4 torque messages +const int cadillac_torque_msgs_n = 4; +int cadillac_desired_torque_last[CADILLAC_TORQUE_MSG_N] = {0}; uint32_t cadillac_ts_last = 0; -int cadillac_supercruise_on = 0; +bool cadillac_supercruise_on = 0; struct sample_t cadillac_torque_driver; // last few driver torques measured -int cadillac_get_torque_idx(uint32_t addr) { - if (addr==0x151) return 0; - else if (addr==0x152) return 1; - else if (addr==0x153) return 2; - else return 3; +int cadillac_get_torque_idx(int addr, int array_size) { + return MIN(MAX(addr - 0x151, 0), array_size); // 0x151 is id 0, 0x152 is id 1 and so on... } static void cadillac_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { - int bus_number = (to_push->RDTR >> 4) & 0xFF; - uint32_t addr = to_push->RIR >> 21; + int bus = GET_BUS(to_push); + int addr = GET_ADDR(to_push); if (addr == 356) { - int torque_driver_new = ((to_push->RDLR & 0x7) << 8) | ((to_push->RDLR >> 8) & 0xFF); + int torque_driver_new = ((GET_BYTE(to_push, 0) & 0x7U) << 8) | (GET_BYTE(to_push, 1)); + torque_driver_new = to_signed(torque_driver_new, 11); // update array of samples update_sample(&cadillac_torque_driver, torque_driver_new); } - // this message isn't all zeros when ignition is on - if (addr == 0x160 && bus_number == 0) { - cadillac_ign = to_push->RDLR > 0; - } - // enter controls on rising edge of ACC, exit controls on ACC off - if ((addr == 0x370) && (bus_number == 0)) { - int cruise_engaged = to_push->RDLR & 0x800000; // bit 23 + if ((addr == 0x370) && (bus == 0)) { + int cruise_engaged = GET_BYTE(to_push, 2) & 0x80; // bit 23 if (cruise_engaged && !cadillac_cruise_engaged_last) { controls_allowed = 1; - } else if (!cruise_engaged) { + } + if (!cruise_engaged) { controls_allowed = 0; } cadillac_cruise_engaged_last = cruise_engaged; @@ -52,19 +48,20 @@ static void cadillac_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // know supercruise mode and block openpilot msgs if on if ((addr == 0x152) || (addr == 0x154)) { - cadillac_supercruise_on = (to_push->RDHR>>4) & 0x1; + cadillac_supercruise_on = (GET_BYTE(to_push, 4) & 0x10) != 0; } } static int cadillac_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { - uint32_t addr = to_send->RIR >> 21; + int tx = 1; + int addr = GET_ADDR(to_send); // steer cmd checks - if (addr == 0x151 || addr == 0x152 || addr == 0x153 || addr == 0x154) { - int desired_torque = ((to_send->RDLR & 0x3f) << 8) + ((to_send->RDLR & 0xff00) >> 8); + if ((addr == 0x151) || (addr == 0x152) || (addr == 0x153) || (addr == 0x154)) { + int desired_torque = ((GET_BYTE(to_send, 0) & 0x3f) << 8) | GET_BYTE(to_send, 1); int violation = 0; uint32_t ts = TIM2->CNT; - int idx = cadillac_get_torque_idx(addr); + int idx = cadillac_get_torque_idx(addr, CADILLAC_TORQUE_MSG_N); desired_torque = to_signed(desired_torque, 14); if (controls_allowed) { @@ -105,20 +102,16 @@ static int cadillac_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { } if (violation || cadillac_supercruise_on) { - return false; + tx = 0; } } - return true; + return tx; } static void cadillac_init(int16_t param) { + UNUSED(param); controls_allowed = 0; - cadillac_ign = 0; -} - -static int cadillac_ign_hook() { - return cadillac_ign; } const safety_hooks cadillac_hooks = { @@ -126,6 +119,5 @@ const safety_hooks cadillac_hooks = { .rx = cadillac_rx_hook, .tx = cadillac_tx_hook, .tx_lin = nooutput_tx_lin_hook, - .ignition = cadillac_ign_hook, - .fwd = alloutput_fwd_hook, + .fwd = default_fwd_hook, }; diff --git a/panda/board/safety/safety_chrysler.h b/panda/board/safety/safety_chrysler.h index b1c6a743f10258..9b8fc361546f59 100644 --- a/panda/board/safety/safety_chrysler.h +++ b/panda/board/safety/safety_chrysler.h @@ -1,11 +1,11 @@ const int CHRYSLER_MAX_STEER = 261; const int CHRYSLER_MAX_RT_DELTA = 112; // max delta torque allowed for real time checks -const int32_t CHRYSLER_RT_INTERVAL = 250000; // 250ms between real time checks +const uint32_t CHRYSLER_RT_INTERVAL = 250000; // 250ms between real time checks const int CHRYSLER_MAX_RATE_UP = 3; const int CHRYSLER_MAX_RATE_DOWN = 3; const int CHRYSLER_MAX_TORQUE_ERROR = 80; // max torque cmd in excess of torque motor -int chrysler_camera_detected = 0; +bool chrysler_camera_detected = 0; // is giraffe switch 2 high? int chrysler_rt_torque_last = 0; int chrysler_desired_torque_last = 0; int chrysler_cruise_engaged_last = 0; @@ -13,40 +13,31 @@ uint32_t chrysler_ts_last = 0; struct sample_t chrysler_torque_meas; // last few torques measured static void chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { - int bus = (to_push->RDTR >> 4) & 0xFF; - uint32_t addr; - if (to_push->RIR & 4) { - // Extended - // Not looked at, but have to be separated - // to avoid address collision - addr = to_push->RIR >> 3; - } else { - // Normal - addr = to_push->RIR >> 21; - } + int bus = GET_BUS(to_push); + int addr = GET_ADDR(to_push); // Measured eps torque if (addr == 544) { - int rdhr = to_push->RDHR; - int torque_meas_new = ((rdhr & 0x7) << 8) + ((rdhr & 0xFF00) >> 8) - 1024; + int torque_meas_new = ((GET_BYTE(to_push, 4) & 0x7U) << 8) + GET_BYTE(to_push, 5) - 1024U; // update array of samples update_sample(&chrysler_torque_meas, torque_meas_new); } // enter controls on rising edge of ACC, exit controls on ACC off - if (addr == 0x1f4) { - int cruise_engaged = ((to_push->RDLR & 0x380000) >> 19) == 7; + if (addr == 0x1F4) { + int cruise_engaged = ((GET_BYTE(to_push, 2) & 0x38) >> 3) == 7; if (cruise_engaged && !chrysler_cruise_engaged_last) { controls_allowed = 1; - } else if (!cruise_engaged) { + } + if (!cruise_engaged) { controls_allowed = 0; } chrysler_cruise_engaged_last = cruise_engaged; } // check if stock camera ECU is still online - if (bus == 0 && addr == 0x292) { + if ((bus == 0) && (addr == 0x292)) { chrysler_camera_detected = 1; controls_allowed = 0; } @@ -54,27 +45,20 @@ static void chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { - // There can be only one! (camera) - if (chrysler_camera_detected) { - return 0; - } + int tx = 1; - uint32_t addr; - if (to_send->RIR & 4) { - // Extended - addr = to_send->RIR >> 3; - } else { - // Normal - addr = to_send->RIR >> 21; + // If camera is on bus 0, then nothing can be sent + if (chrysler_camera_detected) { + tx = 0; } + int addr = GET_ADDR(to_send); // LKA STEER if (addr == 0x292) { - int rdlr = to_send->RDLR; - int desired_torque = ((rdlr & 0x7) << 8) + ((rdlr & 0xFF00) >> 8) - 1024; + int desired_torque = ((GET_BYTE(to_send, 0) & 0x7U) << 8) + GET_BYTE(to_send, 1) - 1024U; uint32_t ts = TIM2->CNT; - int violation = 0; + bool violation = 0; if (controls_allowed) { @@ -112,7 +96,7 @@ static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { } if (violation) { - return false; + tx = 0; } } @@ -122,15 +106,35 @@ static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { // TODO: fix bug preventing the button msg to be fwd'd on bus 2 // 1 allows the message through - return true; + return tx; +} + +static void chrysler_init(int16_t param) { + UNUSED(param); + controls_allowed = 0; + chrysler_camera_detected = 0; +} + +static int chrysler_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { + + int bus_fwd = -1; + int addr = GET_ADDR(to_fwd); + // forward CAN 0 -> 2 so stock LKAS camera sees messages + if ((bus_num == 0) && !chrysler_camera_detected) { + bus_fwd = 2; + } + // forward all messages from camera except LKAS_COMMAND and LKAS_HUD + if ((bus_num == 2) && !chrysler_camera_detected && (addr != 658) && (addr != 678)) { + bus_fwd = 0; + } + return bus_fwd; } const safety_hooks chrysler_hooks = { - .init = nooutput_init, + .init = chrysler_init, .rx = chrysler_rx_hook, .tx = chrysler_tx_hook, .tx_lin = nooutput_tx_lin_hook, - .ignition = default_ign_hook, - .fwd = nooutput_fwd_hook, + .fwd = chrysler_fwd_hook, }; diff --git a/panda/board/safety/safety_defaults.h b/panda/board/safety/safety_defaults.h index 196df65d2f8eb6..5fd4ea94a8cab9 100644 --- a/panda/board/safety/safety_defaults.h +++ b/panda/board/safety/safety_defaults.h @@ -1,25 +1,134 @@ -void default_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {} +bool HKG_forwarding_enabled = 1; +int HKG_MDPS12_checksum = -1; +int HKG_MDPS12_cnt = 0; +int HKG_last_StrColT = 0; -int default_ign_hook() { - return -1; // use GPIO to determine ignition +void default_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { + int addr = GET_ADDR(to_push); + + if (addr == 593) { + if (HKG_MDPS12_checksum == -1) { + int New_Chksum2 = 0; + uint8_t dat[8]; + for (int i=0; i<8; i++) { + dat[i] = GET_BYTE(to_push, i); + } + int Chksum2 = dat[3]; + dat[3] = 0; + for (int i=0; i<8; i++) { + New_Chksum2 += dat[i]; + } + New_Chksum2 %= 256; + if (Chksum2 == New_Chksum2) { + HKG_MDPS12_checksum = 0; + } + else { + HKG_MDPS12_checksum = 1; + } + } + } } // *** no output safety mode *** static void nooutput_init(int16_t param) { + UNUSED(param); controls_allowed = 0; } static int nooutput_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { - return false; + UNUSED(to_send); + return 1; } static int nooutput_tx_lin_hook(int lin_num, uint8_t *data, int len) { + UNUSED(lin_num); + UNUSED(data); + UNUSED(len); return false; } -static int nooutput_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { - return -1; + static int default_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { + int addr = GET_ADDR(to_fwd); + int bus_fwd = -1; + + if ((bus_num == 0) && (addr == 832)) { + HKG_forwarding_enabled = 0; + } + + if (HKG_forwarding_enabled) { + if (bus_num == 0) { + if (addr == 593) { + uint8_t dat[8]; + int New_Chksum2 = 0; + for (int i=0; i<8; i++) { + dat[i] = GET_BYTE(to_fwd, i); + } + if (HKG_MDPS12_cnt > 330) { + int StrColTq = dat[0] | (dat[1] & 0x7) << 8; + int OutTq = dat[6] >> 4 | dat[7] << 4; + if (HKG_MDPS12_cnt == 331) { + StrColTq -= 164; + } + else { + StrColTq = HKG_last_StrColT + 34; + } + OutTq = 2058; + + dat[0] = StrColTq & 0xFF; + dat[1] &= 0xF8; + dat[1] |= StrColTq >> 8; + dat[6] &= 0xF; + dat[6] |= (OutTq & 0xF) << 4; + dat[7] = OutTq >> 4; + + + to_fwd->RDLR &= 0xFFF800; + to_fwd->RDLR |= StrColTq; + to_fwd->RDHR &= 0xFFFFF; + to_fwd->RDHR |= OutTq << 20; + HKG_last_StrColT = StrColTq; + + dat[3] = 0; + if (HKG_MDPS12_checksum == 0) { + for (int i=0; i<8; i++) { + New_Chksum2 += dat[i]; + } + New_Chksum2 %= 256; + } + else if (HKG_MDPS12_checksum == 1) { //we need CRC8 checksum + uint8_t crc = 0xFF; + uint8_t poly = 0x1D; + int i, j; + for (i=0; i<8; i++){ + if (i!=3){ //don't include CRC byte + crc ^= dat[i]; + for (j=0; j<8; j++) { + if ((crc & 0x80) != 0U) { + crc = (crc << 1) ^ poly; + } else + { + crc <<= 1; + } + } + } + } + crc ^= 0xFF; + crc %= 256; + New_Chksum2 = crc; + } + to_fwd->RDLR |= New_Chksum2 << 24; + } + HKG_MDPS12_cnt += 1; + HKG_MDPS12_cnt %= 345; + } + bus_fwd = 2; + } + if (bus_num == 2) { + bus_fwd = 0; + } + } + return bus_fwd; } const safety_hooks nooutput_hooks = { @@ -27,33 +136,32 @@ const safety_hooks nooutput_hooks = { .rx = default_rx_hook, .tx = nooutput_tx_hook, .tx_lin = nooutput_tx_lin_hook, - .ignition = default_ign_hook, - .fwd = nooutput_fwd_hook, + .fwd = default_fwd_hook, }; // *** all output safety mode *** static void alloutput_init(int16_t param) { + UNUSED(param); controls_allowed = 1; } static int alloutput_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { + UNUSED(to_send); return true; } static int alloutput_tx_lin_hook(int lin_num, uint8_t *data, int len) { + UNUSED(lin_num); + UNUSED(data); + UNUSED(len); return true; } -static int alloutput_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { - return -1; -} - const safety_hooks alloutput_hooks = { .init = alloutput_init, .rx = default_rx_hook, .tx = alloutput_tx_hook, .tx_lin = alloutput_tx_lin_hook, - .ignition = default_ign_hook, - .fwd = alloutput_fwd_hook, + .fwd = default_fwd_hook, }; diff --git a/panda/board/safety/safety_elm327.h b/panda/board/safety/safety_elm327.h index 98dce6532ac8ba..171dbfe5c38a37 100644 --- a/panda/board/safety/safety_elm327.h +++ b/panda/board/safety/safety_elm327.h @@ -1,45 +1,44 @@ -static void elm327_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {} - static int elm327_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { - //All ELM traffic must appear on CAN0 - if(((to_send->RDTR >> 4) & 0xf) != 0) return 0; - //All ISO 15765-4 messages must be 8 bytes long - if((to_send->RDTR & 0xf) != 8) return 0; - if(to_send->RIR & 4){ - uint32_t addr = to_send->RIR >> 3; - //Check valid 29 bit send addresses for ISO 15765-4 - if(!(addr == 0x18DB33F1 || (addr & 0x1FFF00FF) == 0x18DA00F1)) return 0; - } else { - uint32_t addr = to_send->RIR >> 21; - //Check valid 11 bit send addresses for ISO 15765-4 - if(!(addr == 0x7DF || (addr & 0x7F8) == 0x7E0)) return 0; + int tx = 1; + int addr = GET_ADDR(to_send); + int len = GET_LEN(to_send); + + //All ISO 15765-4 messages must be 8 bytes long + if (len != 8) { + tx = 0; } - return true; + //Check valid 29 bit send addresses for ISO 15765-4 + //Check valid 11 bit send addresses for ISO 15765-4 + if ((addr != 0x18DB33F1) && ((addr & 0x1FFF00FF) != 0x18DA00F1) && + ((addr != 0x7DF) && ((addr & 0x7F8) != 0x7E0))) { + tx = 0; + } + // needed for forwarding + tx = 1; + return tx; } static int elm327_tx_lin_hook(int lin_num, uint8_t *data, int len) { - if(lin_num != 0) return false; //Only operate on LIN 0, aka serial 2 - if(len < 5 || len > 11) return false; //Valid KWP size - if(!((data[0] & 0xF8) == 0xC0 && (data[0] & 0x07) > 0 && - data[1] == 0x33 && data[2] == 0xF1)) return false; //Bad msg - return true; -} - -static void elm327_init(int16_t param) { - controls_allowed = 1; -} - -static int elm327_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { - return -1; + int tx = 1; + if (lin_num != 0) { + tx = 0; //Only operate on LIN 0, aka serial 2 + } + if ((len < 5) || (len > 11)) { + tx = 0; //Valid KWP size + } + if (!(((data[0] & 0xF8U) == 0xC0U) && ((data[0] & 0x07U) != 0U) && + (data[1] == 0x33U) && (data[2] == 0xF1U))) { + tx = 0; //Bad msg + } + return tx; } const safety_hooks elm327_hooks = { - .init = elm327_init, - .rx = elm327_rx_hook, + .init = nooutput_init, + .rx = default_rx_hook, .tx = elm327_tx_hook, .tx_lin = elm327_tx_lin_hook, - .ignition = default_ign_hook, - .fwd = elm327_fwd_hook, + .fwd = default_fwd_hook, }; diff --git a/panda/board/safety/safety_ford.h b/panda/board/safety/safety_ford.h index 075029fb623e0f..22fc604ff1dd9d 100644 --- a/panda/board/safety/safety_ford.h +++ b/panda/board/safety/safety_ford.h @@ -9,40 +9,45 @@ int ford_brake_prev = 0; int ford_gas_prev = 0; -int ford_is_moving = 0; +bool ford_moving = false; static void ford_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { - if ((to_push->RIR>>21) == 0x217) { + int addr = GET_ADDR(to_push); + + if (addr == 0x217) { // wheel speeds are 14 bits every 16 - ford_is_moving = 0xFCFF & (to_push->RDLR | (to_push->RDLR >> 16) | - to_push->RDHR | (to_push->RDHR >> 16)); + ford_moving = false; + for (int i = 0; i < 8; i += 2) { + ford_moving |= GET_BYTE(to_push, i) | (GET_BYTE(to_push, (int)(i + 1)) & 0xFCU); + } } // state machine to enter and exit controls - if ((to_push->RIR>>21) == 0x83) { - int cancel = ((to_push->RDLR >> 8) & 0x1); - int set_or_resume = (to_push->RDLR >> 28) & 0x3; + if (addr == 0x83) { + bool cancel = GET_BYTE(to_push, 1) & 0x1; + bool set_or_resume = GET_BYTE(to_push, 3) & 0x30; if (cancel) { controls_allowed = 0; - } else if (set_or_resume) { + } + if (set_or_resume) { controls_allowed = 1; } } // exit controls on rising edge of brake press or on brake press when // speed > 0 - if ((to_push->RIR>>21) == 0x165) { - int brake = to_push->RDLR & 0x20; - if (brake && (!(ford_brake_prev) || ford_is_moving)) { + if (addr == 0x165) { + int brake = GET_BYTE(to_push, 0) & 0x20; + if (brake && (!(ford_brake_prev) || ford_moving)) { controls_allowed = 0; } ford_brake_prev = brake; } // exit controls on rising edge of gas press - if ((to_push->RIR>>21) == 0x204) { - int gas = to_push->RDLR & 0xFF03; + if (addr == 0x204) { + int gas = (GET_BYTE(to_push, 0) & 0x03) | GET_BYTE(to_push, 1); if (gas && !(ford_gas_prev)) { controls_allowed = 0; } @@ -58,29 +63,33 @@ static void ford_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { static int ford_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { + int tx = 1; // disallow actuator commands if gas or brake (with vehicle moving) are pressed // and the the latching controls_allowed flag is True - int pedal_pressed = ford_gas_prev || (ford_brake_prev && ford_is_moving); - int current_controls_allowed = controls_allowed && !(pedal_pressed); + int pedal_pressed = ford_gas_prev || (ford_brake_prev && ford_moving); + bool current_controls_allowed = controls_allowed && !(pedal_pressed); + int addr = GET_ADDR(to_send); // STEER: safety check - if ((to_send->RIR>>21) == 0x3CA) { - if (current_controls_allowed) { - // all messages are fine here - } else { + if (addr == 0x3CA) { + if (!current_controls_allowed) { // bits 7-4 need to be 0xF to disallow lkas commands - if (((to_send->RDLR >> 4) & 0xF) != 0xF) return 0; + if ((GET_BYTE(to_send, 0) & 0xF0) != 0xF0) { + tx = 0; + } } } // FORCE CANCEL: safety check only relevant when spamming the cancel button // ensuring that set and resume aren't sent - if ((to_send->RIR>>21) == 0x83) { - if ((to_send->RDLR >> 28) & 0x3) return 0; + if (addr == 0x83) { + if ((GET_BYTE(to_send, 3) & 0x30) != 0) { + tx = 0; + } } // 1 allows the message through - return true; + return tx; } const safety_hooks ford_hooks = { @@ -88,6 +97,5 @@ const safety_hooks ford_hooks = { .rx = ford_rx_hook, .tx = ford_tx_hook, .tx_lin = nooutput_tx_lin_hook, - .ignition = default_ign_hook, - .fwd = nooutput_fwd_hook, + .fwd = default_fwd_hook, }; diff --git a/panda/board/safety/safety_gm.h b/panda/board/safety/safety_gm.h index f35b26b4ef84d3..452f70953df640 100644 --- a/panda/board/safety/safety_gm.h +++ b/panda/board/safety/safety_gm.h @@ -10,7 +10,7 @@ const int GM_MAX_STEER = 300; const int GM_MAX_RT_DELTA = 128; // max delta torque allowed for real time checks -const int32_t GM_RT_INTERVAL = 250000; // 250ms between real time checks +const uint32_t GM_RT_INTERVAL = 250000; // 250ms between real time checks const int GM_MAX_RATE_UP = 7; const int GM_MAX_RATE_DOWN = 17; const int GM_DRIVER_TORQUE_ALLOWANCE = 50; @@ -21,78 +21,66 @@ const int GM_MAX_BRAKE = 350; int gm_brake_prev = 0; int gm_gas_prev = 0; -int gm_speed = 0; +bool gm_moving = false; // silence everything if stock car control ECUs are still online -int gm_ascm_detected = 0; -int gm_ignition_started = 0; +bool gm_ascm_detected = 0; int gm_rt_torque_last = 0; int gm_desired_torque_last = 0; uint32_t gm_ts_last = 0; struct sample_t gm_torque_driver; // last few driver torques measured static void gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { - int bus_number = (to_push->RDTR >> 4) & 0xFF; - uint32_t addr; - if (to_push->RIR & 4) { - // Extended - // Not looked at, but have to be separated - // to avoid address collision - addr = to_push->RIR >> 3; - } else { - // Normal - addr = to_push->RIR >> 21; - } + int bus_number = GET_BUS(to_push); + int addr = GET_ADDR(to_push); if (addr == 388) { - int torque_driver_new = (((to_push->RDHR >> 16) & 0x7) << 8) | ((to_push->RDHR >> 24) & 0xFF); + int torque_driver_new = ((GET_BYTE(to_push, 6) & 0x7) << 8) | GET_BYTE(to_push, 7); torque_driver_new = to_signed(torque_driver_new, 11); // update array of samples update_sample(&gm_torque_driver, torque_driver_new); } - if (addr == 0x1f1 && bus_number == 0) { - //Bit 5 should be ignition "on" - //Backup plan is Bit 2 (accessory power) - uint32_t ign = (to_push->RDLR) & 0x20; - gm_ignition_started = ign > 0; - } - // sample speed, really only care if car is moving or not // rear left wheel speed if (addr == 842) { - gm_speed = to_push->RDLR & 0xFFFF; + gm_moving = GET_BYTE(to_push, 0) | GET_BYTE(to_push, 1); } // Check if ASCM or LKA camera are online // on powertrain bus. // 384 = ASCMLKASteeringCmd // 715 = ASCMGasRegenCmd - if (bus_number == 0 && (addr == 384 || addr == 715)) { + if ((bus_number == 0) && ((addr == 384) || (addr == 715))) { gm_ascm_detected = 1; controls_allowed = 0; } // ACC steering wheel buttons if (addr == 481) { - int buttons = (to_push->RDHR >> 12) & 0x7; - // res/set - enable, cancel button - disable - if (buttons == 2 || buttons == 3) { - controls_allowed = 1; - } else if (buttons == 6) { - controls_allowed = 0; + int button = (GET_BYTE(to_push, 5) & 0x70) >> 4; + switch (button) { + case 2: // resume + case 3: // set + controls_allowed = 1; + break; + case 6: // cancel + controls_allowed = 0; + break; + default: + break; // any other button is irrelevant } } // exit controls on rising edge of brake press or on brake press when // speed > 0 if (addr == 241) { - int brake = (to_push->RDLR & 0xFF00) >> 8; + int brake = GET_BYTE(to_push, 1); // Brake pedal's potentiometer returns near-zero reading // even when pedal is not pressed if (brake < 10) { brake = 0; } - if (brake && (!gm_brake_prev || gm_speed)) { + if (brake && (!gm_brake_prev || gm_moving)) { controls_allowed = 0; } gm_brake_prev = brake; @@ -100,8 +88,8 @@ static void gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // exit controls on rising edge of gas press if (addr == 417) { - int gas = to_push->RDHR & 0xFF0000; - if (gas && !gm_gas_prev) { + int gas = GET_BYTE(to_push, 6); + if (gas && !gm_gas_prev && long_controls_allowed) { controls_allowed = 0; } gm_gas_prev = gas; @@ -109,7 +97,7 @@ static void gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // exit controls on regen paddle if (addr == 189) { - int regen = to_push->RDLR & 0x20; + bool regen = GET_BYTE(to_push, 0) & 0x20; if (regen) { controls_allowed = 0; } @@ -124,43 +112,39 @@ static void gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { + int tx = 1; + // There can be only one! (ASCM) if (gm_ascm_detected) { - return 0; + tx = 0; } // disallow actuator commands if gas or brake (with vehicle moving) are pressed // and the the latching controls_allowed flag is True - int pedal_pressed = gm_gas_prev || (gm_brake_prev && gm_speed); - int current_controls_allowed = controls_allowed && !pedal_pressed; - - uint32_t addr; - if (to_send->RIR & 4) { - // Extended - addr = to_send->RIR >> 3; - } else { - // Normal - addr = to_send->RIR >> 21; - } + int pedal_pressed = gm_gas_prev || (gm_brake_prev && gm_moving); + bool current_controls_allowed = controls_allowed && !pedal_pressed; + + int addr = GET_ADDR(to_send); // BRAKE: safety check if (addr == 789) { - int rdlr = to_send->RDLR; - int brake = ((rdlr & 0xF) << 8) + ((rdlr & 0xFF00) >> 8); + int brake = ((GET_BYTE(to_send, 0) & 0xFU) << 8) + GET_BYTE(to_send, 1); brake = (0x1000 - brake) & 0xFFF; - if (current_controls_allowed) { - if (brake > GM_MAX_BRAKE) return 0; - } else { - if (brake != 0) return 0; + if (!current_controls_allowed || !long_controls_allowed) { + if (brake != 0) { + tx = 0; + } + } + if (brake > GM_MAX_BRAKE) { + tx = 0; } } // LKA STEER: safety check if (addr == 384) { - int rdlr = to_send->RDLR; - int desired_torque = ((rdlr & 0x7) << 8) + ((rdlr & 0xFF00) >> 8); + int desired_torque = ((GET_BYTE(to_send, 0) & 0x7U) << 8) + GET_BYTE(to_send, 1); uint32_t ts = TIM2->CNT; - int violation = 0; + bool violation = 0; desired_torque = to_signed(desired_torque, 11); if (current_controls_allowed) { @@ -200,46 +184,45 @@ static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { } if (violation) { - return false; + tx = 0; } } // PARK ASSIST STEER: unlimited torque, no thanks - if (addr == 823) return 0; + if (addr == 823) { + tx = 0; + } // GAS/REGEN: safety check if (addr == 715) { - int rdlr = to_send->RDLR; - int gas_regen = ((rdlr & 0x7F0000) >> 11) + ((rdlr & 0xF8000000) >> 27); - int apply = rdlr & 1; - if (current_controls_allowed) { - if (gas_regen > GM_MAX_GAS) return 0; - } else { - // Disabled message is !engaed with gas - // value that corresponds to max regen. - if (apply || gas_regen != GM_MAX_REGEN) return 0; + int gas_regen = ((GET_BYTE(to_send, 2) & 0x7FU) << 5) + ((GET_BYTE(to_send, 3) & 0xF8U) >> 3); + // Disabled message is !engaged with gas + // value that corresponds to max regen. + if (!current_controls_allowed || !long_controls_allowed) { + bool apply = GET_BYTE(to_send, 0) & 1U; + if (apply || (gas_regen != GM_MAX_REGEN)) { + tx = 0; + } + } + if (gas_regen > GM_MAX_GAS) { + tx = 0; } } // 1 allows the message through - return true; + return tx; } static void gm_init(int16_t param) { + UNUSED(param); controls_allowed = 0; - gm_ignition_started = 0; } -static int gm_ign_hook() { - return gm_ignition_started; -} const safety_hooks gm_hooks = { .init = gm_init, .rx = gm_rx_hook, .tx = gm_tx_hook, .tx_lin = nooutput_tx_lin_hook, - .ignition = gm_ign_hook, - .fwd = nooutput_fwd_hook, + .fwd = default_fwd_hook, }; - diff --git a/panda/board/safety/safety_gm_ascm.h b/panda/board/safety/safety_gm_ascm.h index 70a042ec514a69..36fd1d8f2adfa9 100644 --- a/panda/board/safety/safety_gm_ascm.h +++ b/panda/board/safety/safety_gm_ascm.h @@ -3,42 +3,35 @@ static int gm_ascm_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { - uint32_t addr = to_fwd->RIR>>21; + int bus_fwd = -1; if (bus_num == 0) { - - // do not propagate lkas messages from ascm to actuators + int addr = GET_ADDR(to_fwd); + bus_fwd = 2; + // do not propagate lkas messages from ascm to actuators, unless supercruise is on // block 0x152 and 0x154, which are the lkas command from ASCM1 and ASCM2 // block 0x315 and 0x2cb, which are the brake and accel commands from ASCM1 //if ((addr == 0x152) || (addr == 0x154) || (addr == 0x315) || (addr == 0x2cb)) { if ((addr == 0x152) || (addr == 0x154)) { - int supercruise_on = (to_fwd->RDHR>>4) & 0x1; // bit 36 - if (!supercruise_on) return -1; - } - - // on the chassis bus, the OBDII port is on the module side, so we need to read - // the lkas messages sent by openpilot (put on unused 0x151 ane 0x153 addrs) and send it to - // the actuator as 0x152 and 0x154 - if (addr == 0x151) { - to_fwd->RIR = (0x152 << 21) | (to_fwd->RIR & 0x1fffff); + bool supercruise_on = (GET_BYTE(to_fwd, 4) & 0x10) != 0; // bit 36 + if (!supercruise_on) { + bus_fwd = -1; + } } - if (addr == 0x153) { - to_fwd->RIR = (0x154 << 21) | (to_fwd->RIR & 0x1fffff); + if ((addr == 0x151) || (addr == 0x153) || (addr == 0x314)) { + // on the chassis bus, the OBDII port is on the module side, so we need to read + // the lkas messages sent by openpilot (put on unused 0x151 ane 0x153 addrs) and send it to + // the actuator as 0x152 and 0x154 + uint32_t fwd_addr = addr + 1; + to_fwd->RIR = (fwd_addr << 21) | (to_fwd->RIR & 0x1fffff); } - - // brake - if (addr == 0x314) { - to_fwd->RIR = (0x315 << 21) | (to_fwd->RIR & 0x1fffff); - } - - return 2; } if (bus_num == 2) { - return 0; + bus_fwd = 0; } - return -1; + return bus_fwd; } const safety_hooks gm_ascm_hooks = { @@ -46,7 +39,6 @@ const safety_hooks gm_ascm_hooks = { .rx = default_rx_hook, .tx = alloutput_tx_hook, .tx_lin = nooutput_tx_lin_hook, - .ignition = default_ign_hook, .fwd = gm_ascm_fwd_hook, }; diff --git a/panda/board/safety/safety_honda.h b/panda/board/safety/safety_honda.h index fbee6cfe861f53..f59e288812a7cf 100644 --- a/panda/board/safety/safety_honda.h +++ b/panda/board/safety/safety_honda.h @@ -7,33 +7,41 @@ // brake rising edge // brake > 0mph -// these are set in the Honda safety hooks...this is the wrong place -const int gas_interceptor_threshold = 328; -int gas_interceptor_detected = 0; -int brake_prev = 0; -int gas_prev = 0; -int gas_interceptor_prev = 0; -int ego_speed = 0; -// TODO: auto-detect bosch hardware based on CAN messages? -bool bosch_hardware = false; +const int HONDA_GAS_INTERCEPTOR_THRESHOLD = 328; // ratio between offset and gain from dbc file +int honda_brake = 0; +int honda_gas_prev = 0; +bool honda_brake_pressed_prev = false; +bool honda_moving = false; +bool honda_bosch_hardware = false; bool honda_alt_brake_msg = false; +bool honda_fwd_brake = false; static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { + int addr = GET_ADDR(to_push); + int len = GET_LEN(to_push); + int bus = GET_BUS(to_push); + // sample speed - if ((to_push->RIR>>21) == 0x158) { + if (addr == 0x158) { // first 2 bytes - ego_speed = to_push->RDLR & 0xFFFF; + honda_moving = GET_BYTE(to_push, 0) | GET_BYTE(to_push, 1); } // state machine to enter and exit controls // 0x1A6 for the ILX, 0x296 for the Civic Touring - if ((to_push->RIR>>21) == 0x1A6 || (to_push->RIR>>21) == 0x296) { - int buttons = (to_push->RDLR & 0xE0) >> 5; - if (buttons == 4 || buttons == 3) { - controls_allowed = 1; - } else if (buttons == 2) { - controls_allowed = 0; + if ((addr == 0x1A6) || (addr == 0x296)) { + int button = (GET_BYTE(to_push, 0) & 0xE0) >> 5; + switch (button) { + case 2: // cancel + controls_allowed = 0; + break; + case 3: // set + case 4: // resume + controls_allowed = 1; + break; + default: + break; // any other button is irrelevant } } @@ -43,25 +51,24 @@ static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // in these cases, this is used instead. // most hondas: 0x17C bit 53 // accord, crv: 0x1BE bit 4 - #define IS_USER_BRAKE_MSG(to_push) (!honda_alt_brake_msg ? to_push->RIR>>21 == 0x17C : to_push->RIR>>21 == 0x1BE) - #define USER_BRAKE_VALUE(to_push) (!honda_alt_brake_msg ? to_push->RDHR & 0x200000 : to_push->RDLR & 0x10) - // exit controls on rising edge of brake press or on brake press when - // speed > 0 - if (IS_USER_BRAKE_MSG(to_push)) { - int brake = USER_BRAKE_VALUE(to_push); - if (brake && (!(brake_prev) || ego_speed)) { + // exit controls on rising edge of brake press or on brake press when speed > 0 + bool is_user_brake_msg = honda_alt_brake_msg ? ((addr) == 0x1BE) : ((addr) == 0x17C); + if (is_user_brake_msg) { + bool brake_pressed = honda_alt_brake_msg ? (GET_BYTE((to_push), 0) & 0x10) : (GET_BYTE((to_push), 6) & 0x20); + if (brake_pressed && (!(honda_brake_pressed_prev) || honda_moving)) { controls_allowed = 0; } - brake_prev = brake; + honda_brake_pressed_prev = brake_pressed; } // exit controls on rising edge of gas press if interceptor (0x201 w/ len = 6) // length check because bosch hardware also uses this id (0x201 w/ len = 8) - if ((to_push->RIR>>21) == 0x201 && (to_push->RDTR & 0xf) == 6) { + if ((addr == 0x201) && (len == 6)) { gas_interceptor_detected = 1; - int gas_interceptor = ((to_push->RDLR & 0xFF) << 8) | ((to_push->RDLR & 0xFF00) >> 8); - if ((gas_interceptor > gas_interceptor_threshold) && - (gas_interceptor_prev <= gas_interceptor_threshold)) { + int gas_interceptor = GET_INTERCEPTOR(to_push); + if ((gas_interceptor > HONDA_GAS_INTERCEPTOR_THRESHOLD) && + (gas_interceptor_prev <= HONDA_GAS_INTERCEPTOR_THRESHOLD) && + long_controls_allowed) { controls_allowed = 0; } gas_interceptor_prev = gas_interceptor; @@ -69,12 +76,26 @@ static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // exit controls on rising edge of gas press if no interceptor if (!gas_interceptor_detected) { - if ((to_push->RIR>>21) == 0x17C) { - int gas = to_push->RDLR & 0xFF; - if (gas && !(gas_prev)) { + if (addr == 0x17C) { + int gas = GET_BYTE(to_push, 0); + if (gas && !(honda_gas_prev) && long_controls_allowed) { controls_allowed = 0; } - gas_prev = gas; + honda_gas_prev = gas; + } + } + if ((bus == 2) && (addr == 0x1FA)) { + bool honda_stock_aeb = GET_BYTE(to_push, 3) & 0x20; + int honda_stock_brake = (GET_BYTE(to_push, 0) << 2) + ((GET_BYTE(to_push, 1) >> 6) & 0x3); + + // Forward AEB when stock braking is higher than openpilot braking + // only stop forwarding when AEB event is over + if (!honda_stock_aeb) { + honda_fwd_brake = false; + } else if (honda_stock_brake >= honda_brake) { + honda_fwd_brake = true; + } else { + // Leave honda forward brake as is } } } @@ -87,62 +108,78 @@ static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { + int tx = 1; + int addr = GET_ADDR(to_send); + int bus = GET_BUS(to_send); + // disallow actuator commands if gas or brake (with vehicle moving) are pressed // and the the latching controls_allowed flag is True - int pedal_pressed = gas_prev || (gas_interceptor_prev > gas_interceptor_threshold) || - (brake_prev && ego_speed); - int current_controls_allowed = controls_allowed && !(pedal_pressed); + int pedal_pressed = honda_gas_prev || (gas_interceptor_prev > HONDA_GAS_INTERCEPTOR_THRESHOLD) || + (honda_brake_pressed_prev && honda_moving); + bool current_controls_allowed = controls_allowed && !(pedal_pressed); // BRAKE: safety check - if ((to_send->RIR>>21) == 0x1FA) { - if (current_controls_allowed) { - if ((to_send->RDLR & 0xFFFFFF3F) != to_send->RDLR) return 0; - } else { - if ((to_send->RDLR & 0xFFFF0000) != to_send->RDLR) return 0; + if ((addr == 0x1FA) && (bus == 0)) { + honda_brake = (GET_BYTE(to_send, 0) << 2) + ((GET_BYTE(to_send, 1) >> 6) & 0x3); + if (!current_controls_allowed || !long_controls_allowed) { + if (honda_brake != 0) { + tx = 0; + } + } + if (honda_brake > 255) { + tx = 0; + } + if (honda_fwd_brake) { + tx = 0; } } // STEER: safety check - if ((to_send->RIR>>21) == 0xE4 || (to_send->RIR>>21) == 0x194) { - if (current_controls_allowed) { - // all messages are fine here - } else { - if ((to_send->RDLR & 0xFFFF0000) != to_send->RDLR) return 0; + if ((addr == 0xE4) || (addr == 0x194)) { + if (!current_controls_allowed) { + bool steer_applied = GET_BYTE(to_send, 0) | GET_BYTE(to_send, 1); + if (steer_applied) { + tx = 0; + } } } // GAS: safety check - if ((to_send->RIR>>21) == 0x200) { - if (current_controls_allowed) { - // all messages are fine here - } else { - if ((to_send->RDLR & 0xFFFF0000) != to_send->RDLR) return 0; + if (addr == 0x200) { + if (!current_controls_allowed || !long_controls_allowed) { + if (GET_BYTE(to_send, 0) || GET_BYTE(to_send, 1)) { + tx = 0; + } } } // FORCE CANCEL: safety check only relevant when spamming the cancel button in Bosch HW // ensuring that only the cancel button press is sent (VAL 2) when controls are off. // This avoids unintended engagements while still allowing resume spam - if (((to_send->RIR>>21) == 0x296) && bosch_hardware && - !current_controls_allowed && ((to_send->RDTR >> 4) & 0xFF) == 0) { - if (((to_send->RDLR >> 5) & 0x7) != 2) return 0; + int bus_pt = ((board_has_relay()) && honda_bosch_hardware)? 1 : 0; + if ((addr == 0x296) && honda_bosch_hardware && + !current_controls_allowed && (bus == bus_pt)) { + if (((GET_BYTE(to_send, 0) >> 5) & 0x7) != 2) { + tx = 0; + } } // 1 allows the message through - return true; + return tx; } static void honda_init(int16_t param) { + UNUSED(param); controls_allowed = 0; - bosch_hardware = false; + honda_bosch_hardware = false; honda_alt_brake_msg = false; } static void honda_bosch_init(int16_t param) { controls_allowed = 0; - bosch_hardware = true; + honda_bosch_hardware = true; // Checking for alternate brake override from safety parameter - honda_alt_brake_msg = param == 1 ? true : false; + honda_alt_brake_msg = (param == 1) ? true : false; } static int honda_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { @@ -150,23 +187,43 @@ static int honda_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { // 0xE4 is steering on all cars except CRV and RDX, 0x194 for CRV and RDX, // 0x1FA is brake control, 0x30C is acc hud, 0x33D is lkas hud, // 0x39f is radar hud - int addr = to_fwd->RIR>>21; + int bus_fwd = -1; + if (bus_num == 0) { - return 2; - } else if (bus_num == 2 && addr != 0xE4 && addr != 0x194 && addr != 0x1FA && - addr != 0x30C && addr != 0x33D && addr != 0x39F) { - return 0; + bus_fwd = 2; } - - return -1; + if (bus_num == 2) { + // block stock lkas messages and stock acc messages (if OP is doing ACC) + int addr = GET_ADDR(to_fwd); + bool is_lkas_msg = (addr == 0xE4) || (addr == 0x194) || (addr == 0x33D); + bool is_acc_hud_msg = (addr == 0x30C) || (addr == 0x39F); + bool is_brake_msg = addr == 0x1FA; + bool block_fwd = is_lkas_msg || + (is_acc_hud_msg && long_controls_allowed) || + (is_brake_msg && long_controls_allowed && !honda_fwd_brake); + if (!block_fwd) { + bus_fwd = 0; + } + } + return bus_fwd; } static int honda_bosch_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { - if (bus_num == 1 || bus_num == 2) { - int addr = to_fwd->RIR>>21; - return addr != 0xE4 && addr != 0x33D ? (uint8_t)(~bus_num & 0x3) : -1; + int bus_fwd = -1; + int bus_rdr_cam = (board_has_relay()) ? 2 : 1; // radar bus, camera side + int bus_rdr_car = (board_has_relay()) ? 0 : 2; // radar bus, car side + + if (bus_num == bus_rdr_car) { + bus_fwd = bus_rdr_cam; + } + if (bus_num == bus_rdr_cam) { + int addr = GET_ADDR(to_fwd); + int is_lkas_msg = (addr == 0xE4) || (addr == 0x33D); + if (!is_lkas_msg) { + bus_fwd = bus_rdr_car; + } } - return -1; + return bus_fwd; } const safety_hooks honda_hooks = { @@ -174,7 +231,6 @@ const safety_hooks honda_hooks = { .rx = honda_rx_hook, .tx = honda_tx_hook, .tx_lin = nooutput_tx_lin_hook, - .ignition = default_ign_hook, .fwd = honda_fwd_hook, }; @@ -183,6 +239,5 @@ const safety_hooks honda_bosch_hooks = { .rx = honda_rx_hook, .tx = honda_tx_hook, .tx_lin = nooutput_tx_lin_hook, - .ignition = default_ign_hook, .fwd = honda_bosch_fwd_hook, }; diff --git a/panda/board/safety/safety_hyundai.h b/panda/board/safety/safety_hyundai.h index b67632141d8365..cb503d7bd2cd13 100644 --- a/panda/board/safety/safety_hyundai.h +++ b/panda/board/safety/safety_hyundai.h @@ -1,41 +1,35 @@ const int HYUNDAI_MAX_STEER = 255; // like stock const int HYUNDAI_MAX_RT_DELTA = 112; // max delta torque allowed for real time checks -const int32_t HYUNDAI_RT_INTERVAL = 250000; // 250ms between real time checks +const uint32_t HYUNDAI_RT_INTERVAL = 250000; // 250ms between real time checks const int HYUNDAI_MAX_RATE_UP = 3; const int HYUNDAI_MAX_RATE_DOWN = 7; const int HYUNDAI_DRIVER_TORQUE_ALLOWANCE = 50; const int HYUNDAI_DRIVER_TORQUE_FACTOR = 2; -int hyundai_camera_detected = 0; +bool hyundai_camera_detected = 0; +bool hyundai_giraffe_switch_2 = 0; // is giraffe switch 2 high? int hyundai_camera_bus = 0; -int hyundai_giraffe_switch_2 = 0; // is giraffe switch 2 high? int hyundai_rt_torque_last = 0; int hyundai_desired_torque_last = 0; int hyundai_cruise_engaged_last = 0; uint32_t hyundai_ts_last = 0; struct sample_t hyundai_torque_driver; // last few driver torques measured +int OP_LKAS_live = 0; +bool hyundai_LKAS_forwarded = 0; +bool hyundai_has_scc = 0; static void hyundai_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { - int bus = (to_push->RDTR >> 4) & 0xFF; - uint32_t addr; - if (to_push->RIR & 4) { - // Extended - // Not looked at, but have to be separated - // to avoid address collision - addr = to_push->RIR >> 3; - } else { - // Normal - addr = to_push->RIR >> 21; - } + int bus = GET_BUS(to_push); + int addr = GET_ADDR(to_push); if (addr == 897) { - int torque_driver_new = ((to_push->RDLR >> 11) & 0xfff) - 2048; + int torque_driver_new = ((GET_BYTES_04(to_push) >> 11) & 0xfff) - 2048; // update array of samples update_sample(&hyundai_torque_driver, torque_driver_new); } // check if stock camera ECU is still online - if (bus == 0 && addr == 832) { + if ((bus == 0) && (addr == 832)) { hyundai_camera_detected = 1; controls_allowed = 0; } @@ -46,45 +40,60 @@ static void hyundai_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { } // enter controls on rising edge of ACC, exit controls on ACC off - if ((to_push->RIR>>21) == 1057) { + if (addr == 1057) { + hyundai_has_scc = 1; // 2 bits: 13-14 - int cruise_engaged = (to_push->RDLR >> 13) & 0x3; + int cruise_engaged = (GET_BYTES_04(to_push) >> 13) & 0x3; if (cruise_engaged && !hyundai_cruise_engaged_last) { controls_allowed = 1; - } else if (!cruise_engaged) { + } + if (!cruise_engaged) { + controls_allowed = 0; + } + hyundai_cruise_engaged_last = cruise_engaged; + } + // cruise control for car without SCC + if ((addr == 871) && (!hyundai_has_scc)) { + // first byte + int cruise_engaged = (GET_BYTES_04(to_push) & 0xFF); + if (cruise_engaged && !hyundai_cruise_engaged_last) { + controls_allowed = 1; + } + if (!cruise_engaged) { controls_allowed = 0; } hyundai_cruise_engaged_last = cruise_engaged; } // 832 is lkas cmd. If it is on camera bus, then giraffe switch 2 is high - if ((to_push->RIR>>21) == 832 && (bus == hyundai_camera_bus) && (hyundai_camera_bus != 0)) { + if ((addr == 832) && (bus == hyundai_camera_bus) && (hyundai_camera_bus != 0)) { hyundai_giraffe_switch_2 = 1; } } static int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { + int tx = 1; + int addr = GET_ADDR(to_send); + // There can be only one! (camera) if (hyundai_camera_detected) { - return 0; - } - - uint32_t addr; - if (to_send->RIR & 4) { - // Extended - addr = to_send->RIR >> 3; - } else { - // Normal - addr = to_send->RIR >> 21; + tx = 0; } // LKA STEER: safety check if (addr == 832) { - int desired_torque = ((to_send->RDLR >> 16) & 0x7ff) - 1024; + int desired_torque = ((GET_BYTES_04(to_send) >> 16) & 0x7ff) - 1024; uint32_t ts = TIM2->CNT; - int violation = 0; + bool violation = 0; + if (!hyundai_LKAS_forwarded) { + OP_LKAS_live = 20; + } + if ((hyundai_LKAS_forwarded) && (!OP_LKAS_live)) { + hyundai_LKAS_forwarded = 0; + return 1; + } if (controls_allowed) { // *** global torque limit check *** @@ -122,7 +131,7 @@ static int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { } if (violation) { - return false; + tx = 0; } } @@ -130,26 +139,43 @@ static int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { // ensuring that only the cancel button press is sent (VAL 4) when controls are off. // This avoids unintended engagements while still allowing resume spam // TODO: fix bug preventing the button msg to be fwd'd on bus 2 - //if (((to_send->RIR>>21) == 1265) && !controls_allowed && ((to_send->RDTR >> 4) & 0xFF) == 0) { - // if ((to_send->RDLR & 0x7) != 4) return 0; + //if ((addr == 1265) && !controls_allowed && (bus == 0) { + // if ((GET_BYTES_04(to_send) & 0x7) != 4) { + // tx = 0; + // } //} // 1 allows the message through - return true; + return tx; } static int hyundai_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { - // forward cam to ccan and viceversa, except lkas cmd - if ((bus_num == 0 || bus_num == hyundai_camera_bus) && hyundai_giraffe_switch_2) { - if ((to_fwd->RIR>>21) == 832 && bus_num == hyundai_camera_bus) return -1; - if (bus_num == 0) return hyundai_camera_bus; - if (bus_num == hyundai_camera_bus) return 0; + int bus_fwd = -1; + // forward cam to ccan and viceversa, except lkas cmd + if (!hyundai_camera_detected) { + if (bus_num == 0) { + bus_fwd = hyundai_camera_bus; + } + if (bus_num == hyundai_camera_bus) { + int addr = GET_ADDR(to_fwd); + if (addr != 832) { + bus_fwd = 0; + } + else if (!OP_LKAS_live) { + hyundai_LKAS_forwarded = 1; + bus_fwd = 0; + } + else { + OP_LKAS_live -= 1; + } + } } - return -1; + return bus_fwd; } static void hyundai_init(int16_t param) { + UNUSED(param); controls_allowed = 0; hyundai_giraffe_switch_2 = 0; } @@ -159,6 +185,5 @@ const safety_hooks hyundai_hooks = { .rx = hyundai_rx_hook, .tx = hyundai_tx_hook, .tx_lin = nooutput_tx_lin_hook, - .ignition = default_ign_hook, .fwd = hyundai_fwd_hook, }; diff --git a/panda/board/safety/safety_mazda.h b/panda/board/safety/safety_mazda.h new file mode 100644 index 00000000000000..60d8b2bda9b16a --- /dev/null +++ b/panda/board/safety/safety_mazda.h @@ -0,0 +1,168 @@ + +// CAN msgs we care about +#define MAZDA_LKAS 0x243 +#define MAZDA_LANEINFO 0x440 +#define MAZDA_CRZ_CTRL 0x21c +#define MAZDA_WHEEL_SPEED 0x215 +#define MAZDA_STEER_TORQUE 0x240 + +// CAN bus numbers +#define MAZDA_MAIN 0 +#define MAZDA_AUX 1 +#define MAZDA_CAM 2 + +#define MAZDA_MAX_STEER 2048 + +// max delta torque allowed for real time checks +#define MAZDA_MAX_RT_DELTA 940 +// 250ms between real time checks +#define MAZDA_RT_INTERVAL 250000 +#define MAZDA_MAX_RATE_UP 10 +#define MAZDA_MAX_RATE_DOWN 25 +#define MAZDA_DRIVER_TORQUE_ALLOWANCE 15 +#define MAZDA_DRIVER_TORQUE_FACTOR 1 + + +int mazda_cruise_engaged_last = 0; +int mazda_rt_torque_last = 0; +int mazda_desired_torque_last = 0; +uint32_t mazda_ts_last = 0; +struct sample_t mazda_torque_driver; // last few driver torques measured + +// track msgs coming from OP so that we know what CAM msgs to drop and what to forward +int mazda_op_lkas_detected = 0; +int mazda_op_laneinfo_detected = 0; + +int mazda_forward_cam = 0; +int mazda_giraffe_switch_2_on = 0; + +void mazda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { + int bus = GET_BUS(to_push); + int addr = GET_ADDR(to_push); + + if ((addr == MAZDA_STEER_TORQUE) && (bus == MAZDA_MAIN)) { + int torque_driver_new = GET_BYTE(to_push, 0) - 127; + // update array of samples + update_sample(&mazda_torque_driver, torque_driver_new); + } + + // enter controls on rising edge of ACC, exit controls on ACC off + if ((addr == MAZDA_CRZ_CTRL) && (bus == MAZDA_MAIN)) { + int cruise_engaged = GET_BYTE(to_push, 0) & 8; + if (cruise_engaged != 0) { + if (!mazda_cruise_engaged_last) { + controls_allowed = 1; + } + } + else { + controls_allowed = 0; + } + mazda_cruise_engaged_last = cruise_engaged; + } + + // we have msgs on bus MAZDA_CAM + if (bus == MAZDA_CAM) { + // the stock CAM is connected + if (addr == MAZDA_LKAS) { + mazda_forward_cam = 1; + } + // if we see wheel speed msgs on MAZDA_CAM bus then giraffe switch 2 is high + // (hardware passthru) + if (addr == MAZDA_WHEEL_SPEED) { + mazda_giraffe_switch_2_on = 1; + } + } +} + +static int mazda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { + int tx = 1; + int addr = GET_ADDR(to_send); + int bus = GET_BUS(to_send); + + // Check if msg is sent on the main BUS + if (bus == MAZDA_MAIN) { + if ((addr == MAZDA_LKAS) && !mazda_op_lkas_detected){ + mazda_op_lkas_detected = 1; + } + if ((addr == MAZDA_LANEINFO) && !mazda_op_laneinfo_detected){ + mazda_op_laneinfo_detected = 1; + } + + // steer cmd checks + if (addr == MAZDA_LKAS) { + int desired_torque = (((GET_BYTE(to_send, 0) & 0x0f) << 8) | GET_BYTE(to_send, 1)) - MAZDA_MAX_STEER; + bool violation = 0; + uint32_t ts = TIM2->CNT; + + if (controls_allowed) { + + // *** global torque limit check *** + violation |= max_limit_check(desired_torque, MAZDA_MAX_STEER, -MAZDA_MAX_STEER); + + // *** torque rate limit check *** + int desired_torque_last = mazda_desired_torque_last; + violation |= driver_limit_check(desired_torque, desired_torque_last, &mazda_torque_driver, + MAZDA_MAX_STEER, MAZDA_MAX_RATE_UP, MAZDA_MAX_RATE_DOWN, + MAZDA_DRIVER_TORQUE_ALLOWANCE, MAZDA_DRIVER_TORQUE_FACTOR); + // used next time + mazda_desired_torque_last = desired_torque; + + // *** torque real time rate limit check *** + violation |= rt_rate_limit_check(desired_torque, mazda_rt_torque_last, MAZDA_MAX_RT_DELTA); + + // every RT_INTERVAL set the new limits + uint32_t ts_elapsed = get_ts_elapsed(ts, mazda_ts_last); + if (ts_elapsed > ((uint32_t) MAZDA_RT_INTERVAL)) { + mazda_rt_torque_last = desired_torque; + mazda_ts_last = ts; + } + } + + // no torque if controls is not allowed + if (!controls_allowed && (desired_torque != 0)) { + violation = 1; + } + + // reset to 0 if either controls is not allowed or there's a violation + if (violation || !controls_allowed) { + mazda_desired_torque_last = 0; + mazda_rt_torque_last = 0; + mazda_ts_last = ts; + } + + if (violation) { + tx = 0; + } + } + } + return tx; +} + +static int mazda_fwd_hook(int bus, CAN_FIFOMailBox_TypeDef *to_fwd) { + int bus_fwd = -1; + if (mazda_forward_cam && !mazda_giraffe_switch_2_on) { + int addr = GET_ADDR(to_fwd); + if (bus == MAZDA_MAIN) { + bus_fwd = MAZDA_CAM; + } + else if (bus == MAZDA_CAM) { + // drop stock CAM_LKAS and CAM_LANEINFI if OP is sending them + if (!((addr == MAZDA_LKAS) && mazda_op_lkas_detected) && + !((addr == MAZDA_LANEINFO) && mazda_op_laneinfo_detected)) { + bus_fwd = MAZDA_MAIN; + } + } + else { + bus_fwd = -1; + } + } + return bus_fwd; +} + +const safety_hooks mazda_hooks = { + .init = nooutput_init, + .rx = mazda_rx_hook, + .tx = mazda_tx_hook, + .tx_lin = nooutput_tx_lin_hook, + .fwd = mazda_fwd_hook, +}; diff --git a/panda/board/safety/safety_subaru.h b/panda/board/safety/safety_subaru.h index 00fe1abf91d2f7..c09b9d6225ed19 100644 --- a/panda/board/safety/safety_subaru.h +++ b/panda/board/safety/safety_subaru.h @@ -2,7 +2,7 @@ const int SUBARU_MAX_STEER = 2047; // 1s // real time torque limit to prevent controls spamming // the real time limit is 1500/sec const int SUBARU_MAX_RT_DELTA = 940; // max delta torque allowed for real time checks -const int32_t SUBARU_RT_INTERVAL = 250000; // 250ms between real time checks +const uint32_t SUBARU_RT_INTERVAL = 250000; // 250ms between real time checks const int SUBARU_MAX_RATE_UP = 50; const int SUBARU_MAX_RATE_DOWN = 70; const int SUBARU_DRIVER_TORQUE_ALLOWANCE = 60; @@ -14,24 +14,26 @@ int subaru_desired_torque_last = 0; uint32_t subaru_ts_last = 0; struct sample_t subaru_torque_driver; // last few driver torques measured - static void subaru_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { - int bus_number = (to_push->RDTR >> 4) & 0xFF; - uint32_t addr = to_push->RIR >> 21; + int bus = GET_BUS(to_push); + int addr = GET_ADDR(to_push); - if ((addr == 0x119) && (bus_number == 0)){ - int torque_driver_new = ((to_push->RDLR >> 16) & 0x7FF); + if (((addr == 0x119) || (addr == 0x371)) && (bus == 0)){ + int bit_shift = (addr == 0x119) ? 16 : 29; + int torque_driver_new = ((GET_BYTES_04(to_push) >> bit_shift) & 0x7FF); torque_driver_new = to_signed(torque_driver_new, 11); // update array of samples update_sample(&subaru_torque_driver, torque_driver_new); } // enter controls on rising edge of ACC, exit controls on ACC off - if ((addr == 0x240) && (bus_number == 0)) { - int cruise_engaged = (to_push->RDHR >> 9) & 1; + if (((addr == 0x240) || (addr == 0x144)) && (bus == 0)) { + int bit_shift = (addr == 0x240) ? 9 : 17; + int cruise_engaged = ((GET_BYTES_48(to_push) >> bit_shift) & 1); if (cruise_engaged && !subaru_cruise_engaged_last) { controls_allowed = 1; - } else if (!cruise_engaged) { + } + if (!cruise_engaged) { controls_allowed = 0; } subaru_cruise_engaged_last = cruise_engaged; @@ -39,12 +41,14 @@ static void subaru_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { } static int subaru_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { - uint32_t addr = to_send->RIR >> 21; + int tx = 1; + int addr = GET_ADDR(to_send); // steer cmd checks - if (addr == 0x122) { - int desired_torque = ((to_send->RDLR >> 16) & 0x1FFF); - int violation = 0; + if ((addr == 0x122) || (addr == 0x164)) { + int bit_shift = (addr == 0x122) ? 16 : 8; + int desired_torque = ((GET_BYTES_04(to_send) >> bit_shift) & 0x1FFF); + bool violation = 0; uint32_t ts = TIM2->CNT; desired_torque = to_signed(desired_torque, 13); @@ -86,39 +90,33 @@ static int subaru_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { } if (violation) { - return false; + tx = 0; } } - return true; + return tx; } static int subaru_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { - // shifts bits 29 > 11 - int32_t addr = to_fwd->RIR >> 21; - - // forward CAN 0 > 1 + int bus_fwd = -1; if (bus_num == 0) { - return 2; // ES CAN + bus_fwd = 2; // Camera CAN } - // forward CAN 1 > 0, except ES_LKAS - else if (bus_num == 2) { - - // outback 2015 - if (addr == 0x164) { - return -1; - } - // global platform - if (addr == 0x122) { - return -1; + if (bus_num == 2) { + // 290 is LKAS for Global Platform + // 356 is LKAS for outback 2015 + // 545 is ES_Distance + // 802 is ES_LKAS + int addr = GET_ADDR(to_fwd); + int block_msg = (addr == 290) || (addr == 356) || (addr == 545) || (addr == 802); + if (!block_msg) { + bus_fwd = 0; // Main CAN } - - return 0; // Main CAN } // fallback to do not forward - return -1; + return bus_fwd; } const safety_hooks subaru_hooks = { @@ -126,6 +124,5 @@ const safety_hooks subaru_hooks = { .rx = subaru_rx_hook, .tx = subaru_tx_hook, .tx_lin = nooutput_tx_lin_hook, - .ignition = default_ign_hook, .fwd = subaru_fwd_hook, }; diff --git a/panda/board/safety/safety_tesla.h b/panda/board/safety/safety_tesla.h index 78c450e85e31c6..2e5d20c622826e 100644 --- a/panda/board/safety/safety_tesla.h +++ b/panda/board/safety/safety_tesla.h @@ -8,8 +8,8 @@ // brake rising edge // brake > 0mph // -int fmax_limit_check(float val, const float MAX, const float MIN) { - return (val > MAX) || (val < MIN); +bool fmax_limit_check(float val, const float MAX_VAL, const float MIN_VAL) { + return (val > MAX_VAL) || (val < MIN_VAL); } // 2m/s are added to be less restrictive @@ -25,7 +25,7 @@ const struct lookup_t TESLA_LOOKUP_MAX_ANGLE = { {2., 29., 38.}, {410., 92., 36.}}; -const int TESLA_RT_INTERVAL = 250000; // 250ms between real time checks +const uint32_t TESLA_RT_INTERVAL = 250000; // 250ms between real time checks // state of angle limits float tesla_desired_angle_last = 0; // last desired steer angle @@ -39,121 +39,82 @@ int tesla_gas_prev = 0; int tesla_speed = 0; int eac_status = 0; -int tesla_ignition_started = 0; - - void set_gmlan_digital_output(int to_set); void reset_gmlan_switch_timeout(void); void gmlan_switch_init(int timeout_enable); -static void tesla_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) -{ +static void tesla_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { set_gmlan_digital_output(0); // #define GMLAN_HIGH 0 reset_gmlan_switch_timeout(); //we're still in tesla safety mode, reset the timeout counter and make sure our output is enabled - //int bus_number = (to_push->RDTR >> 4) & 0xFF; - uint32_t addr; - if (to_push->RIR & 4) - { - // Extended - // Not looked at, but have to be separated - // to avoid address collision - addr = to_push->RIR >> 3; - } - else - { - // Normal - addr = to_push->RIR >> 21; - } + int addr = GET_ADDR(to_push); - if (addr == 0x45) - { + if (addr == 0x45) { // 6 bits starting at position 0 - int lever_position = (to_push->RDLR & 0x3F); - if (lever_position == 2) - { // pull forward + int lever_position = GET_BYTE(to_push, 0) & 0x3F; + if (lever_position == 2) { // pull forward // activate openpilot controls_allowed = 1; - //} } - else if (lever_position == 1) - { // push towards the back + if (lever_position == 1) { // push towards the back // deactivate openpilot controls_allowed = 0; } } - // Detect drive rail on (ignition) (start recording) - if (addr == 0x348) - { - // GTW_status - int drive_rail_on = (to_push->RDLR & 0x0001); - tesla_ignition_started = drive_rail_on == 1; - } - // exit controls on brake press // DI_torque2::DI_brakePedal 0x118 - if (addr == 0x118) - { + if (addr == 0x118) { // 1 bit at position 16 - if (((to_push->RDLR & 0x8000)) >> 15 == 1) - { - //disable break cancel by commenting line below + if ((GET_BYTE(to_push, 1) & 0x80) != 0) { + // disable break cancel by commenting line below controls_allowed = 0; } //get vehicle speed in m/s. Tesla gives MPH - tesla_speed = ((((((to_push->RDLR >> 24) & 0x0F) << 8) + ((to_push->RDLR >> 16) & 0xFF)) * 0.05 - 25) * 1.609 / 3.6); - if (tesla_speed < 0) - { + tesla_speed = (((((GET_BYTE(to_push, 3) & 0xF) << 8) + GET_BYTE(to_push, 2)) * 0.05) - 25) * 1.609 / 3.6; + if (tesla_speed < 0) { tesla_speed = 0; } } // exit controls on EPAS error // EPAS_sysStatus::EPAS_eacStatus 0x370 - if (addr == 0x370) - { + if (addr == 0x370) { // if EPAS_eacStatus is not 1 or 2, disable control - eac_status = ((to_push->RDHR >> 21)) & 0x7; + eac_status = (GET_BYTE(to_push, 6) >> 5) & 0x7; // For human steering override we must not disable controls when eac_status == 0 // Additional safety: we could only allow eac_status == 0 when we have human steering allowed - if ((controls_allowed == 1) && (eac_status != 0) && (eac_status != 1) && (eac_status != 2)) - { + if (controls_allowed && (eac_status != 0) && (eac_status != 1) && (eac_status != 2)) { controls_allowed = 0; //puts("EPAS error! \n"); } } //get latest steering wheel angle - if (addr == 0x00E) - { - float angle_meas_now = (int)((((to_push->RDLR & 0x3F) << 8) + ((to_push->RDLR >> 8) & 0xFF)) * 0.1 - 819.2); + if (addr == 0x00E) { + float angle_meas_now = (int)(((((GET_BYTE(to_push, 0) & 0x3F) << 8) + GET_BYTE(to_push, 1)) * 0.1) - 819.2); uint32_t ts = TIM2->CNT; uint32_t ts_elapsed = get_ts_elapsed(ts, tesla_ts_angle_last); // *** angle real time check // add 1 to not false trigger the violation and multiply by 25 since the check is done every 250 ms and steer angle is updated at 100Hz - float rt_delta_angle_up = interpolate(TESLA_LOOKUP_ANGLE_RATE_UP, tesla_speed) * 25. + 1.; - float rt_delta_angle_down = interpolate(TESLA_LOOKUP_ANGLE_RATE_DOWN, tesla_speed) * 25. + 1.; - float highest_rt_angle = tesla_rt_angle_last + (tesla_rt_angle_last > 0 ? rt_delta_angle_up : rt_delta_angle_down); - float lowest_rt_angle = tesla_rt_angle_last - (tesla_rt_angle_last > 0 ? rt_delta_angle_down : rt_delta_angle_up); + float rt_delta_angle_up = (interpolate(TESLA_LOOKUP_ANGLE_RATE_UP, tesla_speed) * 25.) + 1.; + float rt_delta_angle_down = (interpolate(TESLA_LOOKUP_ANGLE_RATE_DOWN, tesla_speed) * 25.) + 1.; + float highest_rt_angle = tesla_rt_angle_last + ((tesla_rt_angle_last > 0.) ? rt_delta_angle_up : rt_delta_angle_down); + float lowest_rt_angle = tesla_rt_angle_last - ((tesla_rt_angle_last > 0.) ? rt_delta_angle_down : rt_delta_angle_up); - if ((ts_elapsed > TESLA_RT_INTERVAL) || (controls_allowed && !tesla_controls_allowed_last)) - { + if ((ts_elapsed > TESLA_RT_INTERVAL) || (controls_allowed && !tesla_controls_allowed_last)) { tesla_rt_angle_last = angle_meas_now; tesla_ts_angle_last = ts; } // check for violation; - if (fmax_limit_check(angle_meas_now, highest_rt_angle, lowest_rt_angle)) - { + if (fmax_limit_check(angle_meas_now, highest_rt_angle, lowest_rt_angle)) { // We should not be able to STEER under these conditions // Other sending is fine (to allow human override) controls_allowed = 0; //puts("WARN: RT Angle - No steer allowed! \n"); - } - else - { + } else { controls_allowed = 1; } @@ -167,37 +128,28 @@ static void tesla_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) // else // block all commands that produce actuation -static int tesla_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) -{ - - uint32_t addr; - float angle_raw; - float desired_angle; +static int tesla_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { - addr = to_send->RIR >> 21; + int tx = 1; + int addr = GET_ADDR(to_send); // do not transmit CAN message if steering angle too high // DAS_steeringControl::DAS_steeringAngleRequest - if (addr == 0x488) - { - angle_raw = ((to_send->RDLR & 0x7F) << 8) + ((to_send->RDLR & 0xFF00) >> 8); - desired_angle = angle_raw * 0.1 - 1638.35; - int16_t violation = 0; - int st_enabled = (to_send->RDLR & 0x400000) >> 22; + if (addr == 0x488) { + float angle_raw = ((GET_BYTE(to_send, 0) & 0x7F) << 8) + GET_BYTE(to_send, 1); + float desired_angle = (angle_raw * 0.1) - 1638.35; + bool violation = 0; + int st_enabled = GET_BYTE(to_send, 2) & 0x40; if (st_enabled == 0) { //steering is not enabled, do not check angles and do send tesla_desired_angle_last = desired_angle; - return true; - } - - if (controls_allowed) - { + } else if (controls_allowed) { // add 1 to not false trigger the violation float delta_angle_up = interpolate(TESLA_LOOKUP_ANGLE_RATE_UP, tesla_speed) + 1.; float delta_angle_down = interpolate(TESLA_LOOKUP_ANGLE_RATE_DOWN, tesla_speed) + 1.; - float highest_desired_angle = tesla_desired_angle_last + (tesla_desired_angle_last > 0 ? delta_angle_up : delta_angle_down); - float lowest_desired_angle = tesla_desired_angle_last - (tesla_desired_angle_last > 0 ? delta_angle_down : delta_angle_up); + float highest_desired_angle = tesla_desired_angle_last + ((tesla_desired_angle_last > 0.) ? delta_angle_up : delta_angle_down); + float lowest_desired_angle = tesla_desired_angle_last - ((tesla_desired_angle_last > 0.) ? delta_angle_down : delta_angle_up); float TESLA_MAX_ANGLE = interpolate(TESLA_LOOKUP_MAX_ANGLE, tesla_speed) + 1.; //check for max angles @@ -206,82 +158,56 @@ static int tesla_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) //check for angle delta changes violation |= fmax_limit_check(desired_angle, highest_desired_angle, lowest_desired_angle); - if (violation) - { + if (violation) { controls_allowed = 0; - return false; + tx = 0; } tesla_desired_angle_last = desired_angle; - return true; + } else { + tx = 0; } - return false; } - return true; + return tx; } -static int tesla_tx_lin_hook(int lin_num, uint8_t *data, int len) -{ - // LIN is not used on the Tesla - return false; -} - -static void tesla_init(int16_t param) -{ +static void tesla_init(int16_t param) { + UNUSED(param); controls_allowed = 0; - tesla_ignition_started = 0; gmlan_switch_init(1); //init the gmlan switch with 1s timeout enabled } -static int tesla_ign_hook() -{ - return tesla_ignition_started; -} - -static int tesla_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) -{ - - int32_t addr = to_fwd->RIR >> 21; +static int tesla_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { - if (bus_num == 0) - { + int bus_fwd = -1; + int addr = GET_ADDR(to_fwd); + if (bus_num == 0) { // change inhibit of GTW_epasControl - if (addr == 0x101) - { - to_fwd->RDLR = to_fwd->RDLR | 0x4000; // 0x4000: WITH_ANGLE, 0xC000: WITH_BOTH (angle and torque) - int checksum = (((to_fwd->RDLR & 0xFF00) >> 8) + (to_fwd->RDLR & 0xFF) + 2) & 0xFF; - to_fwd->RDLR = to_fwd->RDLR & 0xFFFF; - to_fwd->RDLR = to_fwd->RDLR + (checksum << 16); - return 2; - } - // remove EPB_epasControl - if (addr == 0x214) - { - return -1; + if (addr != 0x214) { + // remove EPB_epasControl + bus_fwd = 2; // Custom EPAS bus + } + if (addr == 0x101) { + to_fwd->RDLR = GET_BYTES_04(to_fwd) | 0x4000; // 0x4000: WITH_ANGLE, 0xC000: WITH_BOTH (angle and torque) + uint32_t checksum = (GET_BYTE(to_fwd, 1) + GET_BYTE(to_fwd, 0) + 2) & 0xFF; + to_fwd->RDLR = GET_BYTES_04(to_fwd) & 0xFFFF; + to_fwd->RDLR = GET_BYTES_04(to_fwd) + (checksum << 16); } - - return 2; // Custom EPAS bus } - if (bus_num == 2) - { - + if (bus_num == 2) { // remove GTW_epasControl in forwards - if (addr == 0x101) - { - return -1; + if (addr != 0x101) { + bus_fwd = 0; // Chassis CAN } - - return 0; // Chassis CAN } - return -1; + return bus_fwd; } const safety_hooks tesla_hooks = { - .init = tesla_init, - .rx = tesla_rx_hook, - .tx = tesla_tx_hook, - .tx_lin = tesla_tx_lin_hook, - .ignition = tesla_ign_hook, - .fwd = tesla_fwd_hook, + .init = tesla_init, + .rx = tesla_rx_hook, + .tx = tesla_tx_hook, + .tx_lin = nooutput_tx_lin_hook, + .fwd = tesla_fwd_hook, }; diff --git a/panda/board/safety/safety_toyota.h b/panda/board/safety/safety_toyota.h index 50d457ab69c6c7..134cc845c97283 100644 --- a/panda/board/safety/safety_toyota.h +++ b/panda/board/safety/safety_toyota.h @@ -1,6 +1,3 @@ -int toyota_giraffe_switch_1 = 0; // is giraffe switch 1 high? -int toyota_camera_forwarded = 0; // should we forward the camera bus? - // global torque limit const int TOYOTA_MAX_TORQUE = 1500; // max torque cmd allowed ever @@ -13,103 +10,141 @@ const int TOYOTA_MAX_TORQUE_ERROR = 350; // max torque cmd in excess of torque // real time torque limit to prevent controls spamming // the real time limit is 1500/sec const int TOYOTA_MAX_RT_DELTA = 375; // max delta torque allowed for real time checks -const int TOYOTA_RT_INTERVAL = 250000; // 250ms between real time checks +const uint32_t TOYOTA_RT_INTERVAL = 250000; // 250ms between real time checks // longitudinal limits const int TOYOTA_MAX_ACCEL = 1500; // 1.5 m/s2 const int TOYOTA_MIN_ACCEL = -3000; // 3.0 m/s2 -// global actuation limit state -int toyota_actuation_limits = 1; // by default steer limits are imposed +const int TOYOTA_GAS_INTERCEPTOR_THRESHOLD = 475; // ratio between offset and gain from dbc file + +// global actuation limit states int toyota_dbc_eps_torque_factor = 100; // conversion factor for STEER_TORQUE_EPS in %: see dbc file -// state of torque limits +// states +int toyota_giraffe_switch_1 = 0; // is giraffe switch 1 high? +int toyota_camera_forwarded = 0; // should we forward the camera bus? int toyota_desired_torque_last = 0; // last desired steer torque int toyota_rt_torque_last = 0; // last desired torque for real time check uint32_t toyota_ts_last = 0; int toyota_cruise_engaged_last = 0; // cruise state +int toyota_gas_prev = 0; struct sample_t toyota_torque_meas; // last 3 motor torques produced by the eps static void toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { + + int bus = GET_BUS(to_push); + int addr = GET_ADDR(to_push); + // get eps motor torque (0.66 factor in dbc) - if ((to_push->RIR>>21) == 0x260) { - int torque_meas_new = (((to_push->RDHR) & 0xFF00) | ((to_push->RDHR >> 16) & 0xFF)); + if (addr == 0x260) { + int torque_meas_new = (GET_BYTE(to_push, 5) << 8) | GET_BYTE(to_push, 6); torque_meas_new = to_signed(torque_meas_new, 16); // scale by dbc_factor torque_meas_new = (torque_meas_new * toyota_dbc_eps_torque_factor) / 100; - // increase torque_meas by 1 to be conservative on rounding - torque_meas_new += (torque_meas_new > 0 ? 1 : -1); - // update array of sample update_sample(&toyota_torque_meas, torque_meas_new); + + // increase torque_meas by 1 to be conservative on rounding + toyota_torque_meas.min--; + toyota_torque_meas.max++; } // enter controls on rising edge of ACC, exit controls on ACC off - if ((to_push->RIR>>21) == 0x1D2) { + if (addr == 0x1D2) { // 5th bit is CRUISE_ACTIVE - int cruise_engaged = to_push->RDLR & 0x20; + int cruise_engaged = GET_BYTE(to_push, 0) & 0x20; + if (!cruise_engaged) { + controls_allowed = 0; + } if (cruise_engaged && !toyota_cruise_engaged_last) { controls_allowed = 1; - } else if (!cruise_engaged) { - controls_allowed = 0; } toyota_cruise_engaged_last = cruise_engaged; } - int bus = (to_push->RDTR >> 4) & 0xF; + // exit controls on rising edge of interceptor gas press + if (addr == 0x201) { + gas_interceptor_detected = 1; + int gas_interceptor = GET_INTERCEPTOR(to_push); + if ((gas_interceptor > TOYOTA_GAS_INTERCEPTOR_THRESHOLD) && + (gas_interceptor_prev <= TOYOTA_GAS_INTERCEPTOR_THRESHOLD) && + long_controls_allowed) { + controls_allowed = 0; + } + gas_interceptor_prev = gas_interceptor; + } + + // exit controls on rising edge of gas press + if (addr == 0x2C1) { + int gas = GET_BYTE(to_push, 6) & 0xFF; + if ((gas > 0) && (toyota_gas_prev == 0) && !gas_interceptor_detected && long_controls_allowed) { + controls_allowed = 0; + } + toyota_gas_prev = gas; + } + // msgs are only on bus 2 if panda is connected to frc if (bus == 2) { toyota_camera_forwarded = 1; } // 0x2E4 is lkas cmd. If it is on bus 0, then giraffe switch 1 is high - if ((to_push->RIR>>21) == 0x2E4 && (bus == 0)) { + if ((addr == 0x2E4) && (bus == 0)) { toyota_giraffe_switch_1 = 1; } } static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { + int tx = 1; + int addr = GET_ADDR(to_send); + int bus = GET_BUS(to_send); + // Check if msg is sent on BUS 0 - if (((to_send->RDTR >> 4) & 0xF) == 0) { + if (bus == 0) { // no IPAS in non IPAS mode - if (((to_send->RIR>>21) == 0x266) || ((to_send->RIR>>21) == 0x167)) return false; + if ((addr == 0x266) || (addr == 0x167)) { + tx = 0; + } // GAS PEDAL: safety check - if ((to_send->RIR>>21) == 0x200) { - if (controls_allowed && toyota_actuation_limits) { - // all messages are fine here - } else { - if ((to_send->RDLR & 0xFFFF0000) != to_send->RDLR) return 0; + if (addr == 0x200) { + if (!controls_allowed || !long_controls_allowed) { + if (GET_BYTE(to_send, 0) || GET_BYTE(to_send, 1)) { + tx = 0; + } } } // ACCEL: safety check on byte 1-2 - if ((to_send->RIR>>21) == 0x343) { - int desired_accel = ((to_send->RDLR & 0xFF) << 8) | ((to_send->RDLR >> 8) & 0xFF); + if (addr == 0x343) { + int desired_accel = (GET_BYTE(to_send, 0) << 8) | GET_BYTE(to_send, 1); desired_accel = to_signed(desired_accel, 16); - if (controls_allowed && toyota_actuation_limits) { - int violation = max_limit_check(desired_accel, TOYOTA_MAX_ACCEL, TOYOTA_MIN_ACCEL); - if (violation) return 0; - } else if (!controls_allowed && (desired_accel != 0)) { - return 0; + if (!controls_allowed || !long_controls_allowed) { + if (desired_accel != 0) { + tx = 0; + } + } + bool violation = max_limit_check(desired_accel, TOYOTA_MAX_ACCEL, TOYOTA_MIN_ACCEL); + if (violation) { + tx = 0; } } // STEER: safety check on bytes 2-3 - if ((to_send->RIR>>21) == 0x2E4) { - int desired_torque = (to_send->RDLR & 0xFF00) | ((to_send->RDLR >> 16) & 0xFF); + if (addr == 0x2E4) { + int desired_torque = (GET_BYTE(to_send, 1) << 8) | GET_BYTE(to_send, 2); desired_torque = to_signed(desired_torque, 16); - int violation = 0; + bool violation = 0; uint32_t ts = TIM2->CNT; - // only check if controls are allowed and actuation_limits are imposed - if (controls_allowed && toyota_actuation_limits) { + if (controls_allowed) { // *** global torque limit check *** violation |= max_limit_check(desired_torque, TOYOTA_MAX_TORQUE, -TOYOTA_MAX_TORQUE); @@ -145,18 +180,17 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { } if (violation) { - return false; + tx = 0; } } } // 1 allows the message through - return true; + return tx; } static void toyota_init(int16_t param) { controls_allowed = 0; - toyota_actuation_limits = 1; toyota_giraffe_switch_1 = 0; toyota_camera_forwarded = 0; toyota_dbc_eps_torque_factor = param; @@ -164,14 +198,25 @@ static void toyota_init(int16_t param) { static int toyota_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { - // forward cam to radar and viceversa if car, except lkas cmd and hud - // don't forward when switch 1 is high - if ((bus_num == 0 || bus_num == 2) && toyota_camera_forwarded && !toyota_giraffe_switch_1) { - int addr = to_fwd->RIR>>21; - bool is_lkas_msg = (addr == 0x2E4 || addr == 0x412) && bus_num == 2; - return is_lkas_msg? -1 : (uint8_t)(~bus_num & 0x2); + int bus_fwd = -1; + if (toyota_camera_forwarded && !toyota_giraffe_switch_1) { + if (bus_num == 0) { + bus_fwd = 2; + } + if (bus_num == 2) { + int addr = GET_ADDR(to_fwd); + // block stock lkas messages and stock acc messages (if OP is doing ACC) + // in TSS2, 0.191 is LTA which we need to block to avoid controls collision + int is_lkas_msg = ((addr == 0x2E4) || (addr == 0x412) || (addr == 0x191)); + // in TSS2 the camera does ACC as well, so filter 0x343 + int is_acc_msg = (addr == 0x343); + int block_msg = is_lkas_msg || (is_acc_msg && long_controls_allowed); + if (!block_msg) { + bus_fwd = 0; + } + } } - return -1; + return bus_fwd; } const safety_hooks toyota_hooks = { @@ -179,23 +224,5 @@ const safety_hooks toyota_hooks = { .rx = toyota_rx_hook, .tx = toyota_tx_hook, .tx_lin = nooutput_tx_lin_hook, - .ignition = default_ign_hook, - .fwd = toyota_fwd_hook, -}; - -static void toyota_nolimits_init(int16_t param) { - controls_allowed = 0; - toyota_actuation_limits = 0; - toyota_giraffe_switch_1 = 0; - toyota_camera_forwarded = 0; - toyota_dbc_eps_torque_factor = param; -} - -const safety_hooks toyota_nolimits_hooks = { - .init = toyota_nolimits_init, - .rx = toyota_rx_hook, - .tx = toyota_tx_hook, - .tx_lin = nooutput_tx_lin_hook, - .ignition = default_ign_hook, .fwd = toyota_fwd_hook, }; diff --git a/panda/board/safety/safety_toyota_ipas.h b/panda/board/safety/safety_toyota_ipas.h index ff4158e3c77c3b..d5833e45db5544 100644 --- a/panda/board/safety/safety_toyota_ipas.h +++ b/panda/board/safety/safety_toyota_ipas.h @@ -35,17 +35,19 @@ static void toyota_ipas_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // check standard toyota stuff as well toyota_rx_hook(to_push); - if ((to_push->RIR>>21) == 0x260) { + int addr = GET_ADDR(to_push); + + if (addr == 0x260) { // get driver steering torque - int16_t torque_driver_new = (((to_push->RDLR) & 0xFF00) | ((to_push->RDLR >> 16) & 0xFF)); + int16_t torque_driver_new = (GET_BYTE(to_push, 1) << 8) | GET_BYTE(to_push, 2); // update array of samples update_sample(&torque_driver, torque_driver_new); } // get steer angle - if ((to_push->RIR>>21) == 0x25) { - int angle_meas_new = ((to_push->RDLR & 0xf) << 8) + ((to_push->RDLR & 0xff00) >> 8); + if (addr == 0x25) { + int angle_meas_new = ((GET_BYTE(to_push, 0) & 0xF) << 8) | GET_BYTE(to_push, 1); uint32_t ts = TIM2->CNT; angle_meas_new = to_signed(angle_meas_new, 12); @@ -55,10 +57,10 @@ static void toyota_ipas_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // *** angle real time check // add 1 to not false trigger the violation and multiply by 20 since the check is done every 250ms and steer angle is updated at 80Hz - int rt_delta_angle_up = ((int)(RT_ANGLE_FUDGE * (interpolate(LOOKUP_ANGLE_RATE_UP, speed) * 20. * CAN_TO_DEG + 1.))); - int rt_delta_angle_down = ((int)(RT_ANGLE_FUDGE * (interpolate(LOOKUP_ANGLE_RATE_DOWN, speed) * 20. * CAN_TO_DEG + 1.))); - int highest_rt_angle = rt_angle_last + (rt_angle_last > 0? rt_delta_angle_up:rt_delta_angle_down); - int lowest_rt_angle = rt_angle_last - (rt_angle_last > 0? rt_delta_angle_down:rt_delta_angle_up); + int rt_delta_angle_up = ((int)(RT_ANGLE_FUDGE * ((interpolate(LOOKUP_ANGLE_RATE_UP, speed) * 20. * CAN_TO_DEG) + 1.))); + int rt_delta_angle_down = ((int)(RT_ANGLE_FUDGE * ((interpolate(LOOKUP_ANGLE_RATE_DOWN, speed) * 20. * CAN_TO_DEG) + 1.))); + int highest_rt_angle = rt_angle_last + ((rt_angle_last > 0) ? rt_delta_angle_up : rt_delta_angle_down); + int lowest_rt_angle = rt_angle_last - ((rt_angle_last > 0) ? rt_delta_angle_down : rt_delta_angle_up); // every RT_INTERVAL or when controls are turned on, set the new limits uint32_t ts_elapsed = get_ts_elapsed(ts, ts_angle_last); @@ -78,13 +80,13 @@ static void toyota_ipas_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { } // get speed - if ((to_push->RIR>>21) == 0xb4) { - speed = ((float) (((to_push->RDHR) & 0xFF00) | ((to_push->RDHR >> 16) & 0xFF))) * 0.01 / 3.6; + if (addr == 0xb4) { + speed = ((float)((GET_BYTE(to_push, 5) << 8) | GET_BYTE(to_push, 6))) * 0.01 / 3.6; } // get ipas state - if ((to_push->RIR>>21) == 0x262) { - ipas_state = (to_push->RDLR & 0xf); + if (addr == 0x262) { + ipas_state = GET_BYTE(to_push, 0) & 0xf; } // exit controls on high steering override @@ -97,25 +99,34 @@ static void toyota_ipas_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { static int toyota_ipas_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { + int tx = 1; + int bypass_standard_tx_hook = 0; + int bus = GET_BUS(to_send); + int addr = GET_ADDR(to_send); + // Check if msg is sent on BUS 0 - if (((to_send->RDTR >> 4) & 0xF) == 0) { + if (bus == 0) { // STEER ANGLE - if (((to_send->RIR>>21) == 0x266) || ((to_send->RIR>>21) == 0x167)) { + if ((addr == 0x266) || (addr == 0x167)) { angle_control = 1; // we are in angle control mode - int desired_angle = ((to_send->RDLR & 0xf) << 8) + ((to_send->RDLR & 0xff00) >> 8); - int ipas_state_cmd = ((to_send->RDLR & 0xff) >> 4); - int16_t violation = 0; + int desired_angle = ((GET_BYTE(to_send, 0) & 0xF) << 8) | GET_BYTE(to_send, 1); + int ipas_state_cmd = GET_BYTE(to_send, 0) >> 4; + bool violation = 0; desired_angle = to_signed(desired_angle, 12); if (controls_allowed) { // add 1 to not false trigger the violation - int delta_angle_up = (int) (interpolate(LOOKUP_ANGLE_RATE_UP, speed) * CAN_TO_DEG + 1.); - int delta_angle_down = (int) (interpolate(LOOKUP_ANGLE_RATE_DOWN, speed) * CAN_TO_DEG + 1.); - int highest_desired_angle = desired_angle_last + (desired_angle_last > 0? delta_angle_up:delta_angle_down); - int lowest_desired_angle = desired_angle_last - (desired_angle_last > 0? delta_angle_down:delta_angle_up); + float delta_angle_float; + delta_angle_float = (interpolate(LOOKUP_ANGLE_RATE_UP, speed) * CAN_TO_DEG) + 1.; + int delta_angle_up = (int) (delta_angle_float); + delta_angle_float = (interpolate(LOOKUP_ANGLE_RATE_DOWN, speed) * CAN_TO_DEG) + 1.; + int delta_angle_down = (int) (delta_angle_float); + + int highest_desired_angle = desired_angle_last + ((desired_angle_last > 0) ? delta_angle_up : delta_angle_down); + int lowest_desired_angle = desired_angle_last - ((desired_angle_last > 0) ? delta_angle_down : delta_angle_up); if ((desired_angle > highest_desired_angle) || (desired_angle < lowest_desired_angle)){ violation = 1; @@ -134,15 +145,18 @@ static int toyota_ipas_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { desired_angle_last = desired_angle; if (violation) { - return false; + tx = 0; } - - return true; + bypass_standard_tx_hook = 1; } } - // check standard toyota stuff as well - return toyota_tx_hook(to_send); + // check standard toyota stuff as well if addr isn't IPAS related + if (!bypass_standard_tx_hook) { + tx &= toyota_tx_hook(to_send); + } + + return tx; } const safety_hooks toyota_ipas_hooks = { @@ -150,7 +164,5 @@ const safety_hooks toyota_ipas_hooks = { .rx = toyota_ipas_rx_hook, .tx = toyota_ipas_tx_hook, .tx_lin = nooutput_tx_lin_hook, - .ignition = default_ign_hook, .fwd = toyota_fwd_hook, }; - diff --git a/panda/board/safety/safety_volkswagen.h b/panda/board/safety/safety_volkswagen.h new file mode 100644 index 00000000000000..bb184cd91f5418 --- /dev/null +++ b/panda/board/safety/safety_volkswagen.h @@ -0,0 +1,167 @@ +const int VOLKSWAGEN_MAX_STEER = 250; // 2.5 Nm (EPS side max of 3.0Nm with fault if violated) +const int VOLKSWAGEN_MAX_RT_DELTA = 75; // 4 max rate up * 50Hz send rate * 250000 RT interval / 1000000 = 50 ; 50 * 1.5 for safety pad = 75 +const uint32_t VOLKSWAGEN_RT_INTERVAL = 250000; // 250ms between real time checks +const int VOLKSWAGEN_MAX_RATE_UP = 4; // 2.0 Nm/s available rate of change from the steering rack (EPS side delta-limit of 5.0 Nm/s) +const int VOLKSWAGEN_MAX_RATE_DOWN = 10; // 5.0 Nm/s available rate of change from the steering rack (EPS side delta-limit of 5.0 Nm/s) +const int VOLKSWAGEN_DRIVER_TORQUE_ALLOWANCE = 80; +const int VOLKSWAGEN_DRIVER_TORQUE_FACTOR = 3; + +struct sample_t volkswagen_torque_driver; // last few driver torques measured +int volkswagen_rt_torque_last = 0; +int volkswagen_desired_torque_last = 0; +uint32_t volkswagen_ts_last = 0; +int volkswagen_gas_prev = 0; + +// Safety-relevant CAN messages for the Volkswagen MQB platform. +#define MSG_EPS_01 0x09F +#define MSG_MOTOR_20 0x121 +#define MSG_ACC_06 0x122 +#define MSG_HCA_01 0x126 +#define MSG_GRA_ACC_01 0x12B +#define MSG_LDW_02 0x397 +#define MSG_KLEMMEN_STATUS_01 0x3C0 + +static void volkswagen_init(int16_t param) { + UNUSED(param); // May use param in the future to indicate MQB vs PQ35/PQ46/NMS vs MLB, or wiring configuration. + controls_allowed = 0; +} + +static void volkswagen_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { + int bus = GET_BUS(to_push); + int addr = GET_ADDR(to_push); + + // Update driver input torque samples from EPS_01.Driver_Strain for absolute torque, and EPS_01.Driver_Strain_VZ + // for the direction. + if ((bus == 0) && (addr == MSG_EPS_01)) { + int torque_driver_new = GET_BYTE(to_push, 5) | ((GET_BYTE(to_push, 6) & 0x1F) << 8); + int sign = (GET_BYTE(to_push, 6) & 0x80) >> 7; + if (sign == 1) { + torque_driver_new *= -1; + } + + update_sample(&volkswagen_torque_driver, torque_driver_new); + } + + // Monitor ACC_06.ACC_Status_ACC for stock ACC status. Because the current MQB port is lateral-only, OP's control + // allowed state is directly driven by stock ACC engagement. Permit the ACC message to come from either bus, in + // order to accommodate future camera-side integrations if needed. + if (addr == MSG_ACC_06) { + int acc_status = (GET_BYTE(to_push, 7) & 0x70) >> 4; + controls_allowed = ((acc_status == 3) || (acc_status == 4) || (acc_status == 5)) ? 1 : 0; + } + + // exit controls on rising edge of gas press. Bits [12-20) + if (addr == MSG_MOTOR_20) { + int gas = (GET_BYTES_04(to_push) >> 12) & 0xFF; + if ((gas > 0) && (volkswagen_gas_prev == 0) && long_controls_allowed) { + controls_allowed = 0; + } + volkswagen_gas_prev = gas; + } +} + +static int volkswagen_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { + int addr = GET_ADDR(to_send); + int bus = GET_BUS(to_send); + int tx = 1; + + // Safety check for HCA_01 Heading Control Assist torque. + if (addr == MSG_HCA_01) { + bool violation = false; + + int desired_torque = GET_BYTE(to_send, 2) | ((GET_BYTE(to_send, 3) & 0x3F) << 8); + int sign = (GET_BYTE(to_send, 3) & 0x80) >> 7; + if (sign == 1) { + desired_torque *= -1; + } + + uint32_t ts = TIM2->CNT; + + if (controls_allowed) { + + // *** global torque limit check *** + violation |= max_limit_check(desired_torque, VOLKSWAGEN_MAX_STEER, -VOLKSWAGEN_MAX_STEER); + + // *** torque rate limit check *** + violation |= driver_limit_check(desired_torque, volkswagen_desired_torque_last, &volkswagen_torque_driver, + VOLKSWAGEN_MAX_STEER, VOLKSWAGEN_MAX_RATE_UP, VOLKSWAGEN_MAX_RATE_DOWN, + VOLKSWAGEN_DRIVER_TORQUE_ALLOWANCE, VOLKSWAGEN_DRIVER_TORQUE_FACTOR); + volkswagen_desired_torque_last = desired_torque; + + // *** torque real time rate limit check *** + violation |= rt_rate_limit_check(desired_torque, volkswagen_rt_torque_last, VOLKSWAGEN_MAX_RT_DELTA); + + // every RT_INTERVAL set the new limits + uint32_t ts_elapsed = get_ts_elapsed(ts, volkswagen_ts_last); + if (ts_elapsed > VOLKSWAGEN_RT_INTERVAL) { + volkswagen_rt_torque_last = desired_torque; + volkswagen_ts_last = ts; + } + } + + // no torque if controls is not allowed + if (!controls_allowed && (desired_torque != 0)) { + violation = true; + } + + // reset to 0 if either controls is not allowed or there's a violation + if (violation || !controls_allowed) { + volkswagen_desired_torque_last = 0; + volkswagen_rt_torque_last = 0; + volkswagen_ts_last = ts; + } + + if (violation) { + tx = 0; + } + } + + // FORCE CANCEL: ensuring that only the cancel button press is sent when controls are off. + // This avoids unintended engagements while still allowing resume spam + if ((bus == 2) && (addr == MSG_GRA_ACC_01) && !controls_allowed) { + // disallow resume and set: bits 16 and 19 + if ((GET_BYTE(to_send, 2) & 0x9) != 0) { + tx = 0; + } + } + + // 1 allows the message through + return tx; +} + +static int volkswagen_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { + int addr = GET_ADDR(to_fwd); + int bus_fwd = -1; + + // NOTE: Will need refactoring for other bus layouts, such as no-forwarding at camera or J533 running-gear CAN + + switch (bus_num) { + case 0: + // Forward all traffic from J533 gateway to Extended CAN devices. + bus_fwd = 2; + break; + case 2: + if ((addr == MSG_HCA_01) || (addr == MSG_LDW_02)) { + // OP takes control of the Heading Control Assist and Lane Departure Warning messages from the camera. + bus_fwd = -1; + } else { + // Forward all remaining traffic from Extended CAN devices to J533 gateway. + bus_fwd = 0; + } + break; + default: + // No other buses should be in use; fallback to do-not-forward. + bus_fwd = -1; + break; + } + + return bus_fwd; +} + +const safety_hooks volkswagen_hooks = { + .init = volkswagen_init, + .rx = volkswagen_rx_hook, + .tx = volkswagen_tx_hook, + .tx_lin = nooutput_tx_lin_hook, + .fwd = volkswagen_fwd_hook, +}; diff --git a/panda/board/safety_declarations.h b/panda/board/safety_declarations.h new file mode 100644 index 00000000000000..efa6a4e2b8744c --- /dev/null +++ b/panda/board/safety_declarations.h @@ -0,0 +1,52 @@ +// sample struct that keeps 3 samples in memory +struct sample_t { + int values[6]; + int min; + int max; +} sample_t_default = {{0}, 0, 0}; + +// safety code requires floats +struct lookup_t { + float x[3]; + float y[3]; +}; + +void safety_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); +int safety_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); +int safety_tx_lin_hook(int lin_num, uint8_t *data, int len); +uint32_t get_ts_elapsed(uint32_t ts, uint32_t ts_last); +int to_signed(int d, int bits); +void update_sample(struct sample_t *sample, int sample_new); +bool max_limit_check(int val, const int MAX, const int MIN); +bool dist_to_meas_check(int val, int val_last, struct sample_t *val_meas, + const int MAX_RATE_UP, const int MAX_RATE_DOWN, const int MAX_ERROR); +bool driver_limit_check(int val, int val_last, struct sample_t *val_driver, + const int MAX, const int MAX_RATE_UP, const int MAX_RATE_DOWN, + const int MAX_ALLOWANCE, const int DRIVER_FACTOR); +bool rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA); +float interpolate(struct lookup_t xy, float x); + +typedef void (*safety_hook_init)(int16_t param); +typedef void (*rx_hook)(CAN_FIFOMailBox_TypeDef *to_push); +typedef int (*tx_hook)(CAN_FIFOMailBox_TypeDef *to_send); +typedef int (*tx_lin_hook)(int lin_num, uint8_t *data, int len); +typedef int (*fwd_hook)(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd); + +typedef struct { + safety_hook_init init; + rx_hook rx; + tx_hook tx; + tx_lin_hook tx_lin; + fwd_hook fwd; +} safety_hooks; + +// This can be set by the safety hooks. +bool controls_allowed = 0; +bool gas_interceptor_detected = 0; +int gas_interceptor_prev = 0; + +// This is set by USB command 0xdf +bool long_controls_allowed = 1; + +// avg between 2 tracks +#define GET_INTERCEPTOR(msg) (((GET_BYTE((msg), 0) << 8) + GET_BYTE((msg), 1) + ((GET_BYTE((msg), 2) << 8) + GET_BYTE((msg), 3)) / 2 ) / 2) diff --git a/panda/board/spi_flasher.h b/panda/board/spi_flasher.h index 179a095b970ef9..b1bba71d4623c4 100644 --- a/panda/board/spi_flasher.h +++ b/panda/board/spi_flasher.h @@ -2,9 +2,11 @@ uint32_t *prog_ptr = NULL; int unlocked = 0; +#ifdef uart_ring void debug_ring_callback(uart_ring *ring) {} +#endif -int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { +int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired) { int resp_len = 0; // flasher machine @@ -29,7 +31,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { FLASH->KEYR = 0xCDEF89AB; resp[1] = 0xff; } - set_led(LED_GREEN, 1); + current_board->set_led(LED_GREEN, 1); unlocked = 1; prog_ptr = (uint32_t *)0x8004000; break; @@ -46,7 +48,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { break; // **** 0xd0: fetch serial number case 0xd0: - #ifdef PANDA + #ifdef STM32F4 // addresses are OTP if (setup->b.wValue.w == 1) { memcpy(resp, (void *)0x1fff79c0, 0x10); @@ -78,7 +80,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { break; // **** 0xd6: get version case 0xd6: - COMPILE_TIME_ASSERT(sizeof(gitversion) <= MAX_RESP_LEN) + COMPILE_TIME_ASSERT(sizeof(gitversion) <= MAX_RESP_LEN); memcpy(resp, gitversion, sizeof(gitversion)); resp_len = sizeof(gitversion); break; @@ -90,17 +92,27 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { return resp_len; } -int usb_cb_ep1_in(uint8_t *usbdata, int len, int hardwired) { return 0; } -void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired) { } +int usb_cb_ep1_in(void *usbdata, int len, bool hardwired) { + UNUSED(usbdata); + UNUSED(len); + UNUSED(hardwired); + return 0; +} +void usb_cb_ep3_out(void *usbdata, int len, bool hardwired) { + UNUSED(usbdata); + UNUSED(len); + UNUSED(hardwired); +} int is_enumerated = 0; -void usb_cb_enumeration_complete() { +void usb_cb_enumeration_complete(void) { puts("USB enumeration complete\n"); is_enumerated = 1; } -void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired) { - set_led(LED_RED, 0); +void usb_cb_ep2_out(void *usbdata, int len, bool hardwired) { + UNUSED(hardwired); + current_board->set_led(LED_RED, 0); for (int i = 0; i < len/4; i++) { // program byte 1 FLASH->CR = FLASH_CR_PSIZE_1 | FLASH_CR_PG; @@ -111,11 +123,12 @@ void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired) { //*(uint64_t*)(&spi_tx_buf[0x30+(i*4)]) = *prog_ptr; prog_ptr++; } - set_led(LED_RED, 1); + current_board->set_led(LED_RED, 1); } int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) { + UNUSED(len); int resp_len = 0; switch (data[0]) { case 0: @@ -132,12 +145,13 @@ int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) { #ifdef PEDAL +#include "drivers/llcan.h" #define CAN CAN1 #define CAN_BL_INPUT 0x1 #define CAN_BL_OUTPUT 0x2 -void CAN1_TX_IRQHandler() { +void CAN1_TX_IRQHandler(void) { // clear interrupt CAN->TSR |= CAN_TSR_RQCP0; } @@ -164,12 +178,13 @@ void bl_can_send(uint8_t *odat) { CAN->sTxMailBox[0].TIR = (CAN_BL_OUTPUT << 21) | 1; } -void CAN1_RX0_IRQHandler() { +void CAN1_RX0_IRQHandler(void) { while (CAN->RF0R & CAN_RF0R_FMP0) { if ((CAN->sFIFOMailBox[0].RIR>>21) == CAN_BL_INPUT) { uint8_t dat[8]; - ((uint32_t*)dat)[0] = CAN->sFIFOMailBox[0].RDLR; - ((uint32_t*)dat)[1] = CAN->sFIFOMailBox[0].RDHR; + for (int i = 0; i < 8; i++) { + dat[i] = GET_BYTE(&CAN->sFIFOMailBox[0], i); + } uint8_t odat[8]; uint8_t type = dat[0] & 0xF0; if (type == 0x30) { @@ -238,13 +253,13 @@ void CAN1_RX0_IRQHandler() { } } -void CAN1_SCE_IRQHandler() { - can_sce(CAN); +void CAN1_SCE_IRQHandler(void) { + llcan_clear_send(CAN); } #endif -void soft_flasher_start() { +void soft_flasher_start(void) { puts("\n\n\n************************ FLASHER START ************************\n"); enter_bootloader_mode = 0; @@ -261,11 +276,11 @@ void soft_flasher_start() { // B8,B9: CAN 1 set_gpio_alternate(GPIOB, 8, GPIO_AF9_CAN1); set_gpio_alternate(GPIOB, 9, GPIO_AF9_CAN1); - set_can_enable(CAN1, 1); + current_board->enable_can_transciever(1, true); // init can - can_silent = ALL_CAN_LIVE; - can_init(0); + llcan_set_speed(CAN1, 5000, false, false); + llcan_init(CAN1); #endif // A4,A5,A6,A7: setup SPI @@ -290,9 +305,9 @@ void soft_flasher_start() { usb_init(); // green LED on for flashing - set_led(LED_GREEN, 1); + current_board->set_led(LED_GREEN, 1); - __enable_irq(); + enable_interrupts(); uint64_t cnt = 0; @@ -301,13 +316,13 @@ void soft_flasher_start() { // if you are connected through a hub to the phone // you need power to be able to see the device puts("USBP: didn't enumerate, switching to CDP mode\n"); - set_usb_power_mode(USB_POWER_CDP); - set_led(LED_BLUE, 1); + current_board->set_usb_power_mode(USB_POWER_CDP); + current_board->set_led(LED_BLUE, 1); } // blink the green LED fast - set_led(LED_GREEN, 0); + current_board->set_led(LED_GREEN, 0); delay(500000); - set_led(LED_GREEN, 1); + current_board->set_led(LED_GREEN, 1); delay(500000); } } diff --git a/panda/board/startup_stm32f205xx.s b/panda/board/startup_stm32f205xx.s index f4b6c6cb741272..7554efc4c180da 100644 --- a/panda/board/startup_stm32f205xx.s +++ b/panda/board/startup_stm32f205xx.s @@ -4,7 +4,7 @@ * @author MCD Application Team * @version V2.1.2 * @date 29-June-2016 - * @brief STM32F205xx Devices vector table for Atollic TrueSTUDIO toolchain. + * @brief STM32F205xx Devices vector table for Atollic TrueSTUDIO toolchain. * This module performs: * - Set the initial SP * - Set the initial PC == Reset_Handler, @@ -42,7 +42,7 @@ * ****************************************************************************** */ - + .syntax unified .cpu cortex-m3 .thumb @@ -50,10 +50,10 @@ .global g_pfnVectors .global Default_Handler -/* start address for the initialization values of the .data section. +/* start address for the initialization values of the .data section. defined in linker script */ .word _sidata -/* start address for the .data section. defined in linker script */ +/* start address for the .data section. defined in linker script */ .word _sdata /* end address for the .data section. defined in linker script */ .word _edata @@ -67,7 +67,7 @@ defined in linker script */ * @brief This is the code that gets called when the processor first * starts execution following a reset event. Only the absolutely * necessary set is performed, after which the application - * supplied main() routine is called. + * supplied main() routine is called. * @param None * @retval : None */ @@ -75,7 +75,7 @@ defined in linker script */ .section .text.Reset_Handler .weak Reset_Handler .type Reset_Handler, %function -Reset_Handler: +Reset_Handler: ldr sp, =_estack /* set stack pointer */ bl __initialize_hardware_early @@ -88,7 +88,7 @@ CopyDataInit: ldr r3, [r3, r1] str r3, [r0, r1] adds r1, r1, #4 - + LoopCopyDataInit: ldr r0, =_sdata ldr r3, =_edata @@ -101,7 +101,7 @@ LoopCopyDataInit: FillZerobss: movs r3, #0 str r3, [r2], #4 - + LoopFillZerobss: ldr r3, = _ebss cmp r2, r3 @@ -113,15 +113,15 @@ LoopFillZerobss: /*bl __libc_init_array*/ /* Call the application's entry point.*/ bl main - bx lr + bx lr .size Reset_Handler, .-Reset_Handler /** - * @brief This is the code that gets called when the processor receives an + * @brief This is the code that gets called when the processor receives an * unexpected interrupt. This simply enters an infinite loop, preserving * the system state for examination by a debugger. - * @param None - * @retval None + * @param None + * @retval None */ .section .text.Default_Handler,"ax",%progbits Default_Handler: @@ -133,14 +133,14 @@ Infinite_Loop: * The minimal vector table for a Cortex M3. Note that the proper constructs * must be placed on this to ensure that it ends up at physical address * 0x0000.0000. -* +* *******************************************************************************/ .section .isr_vector,"a",%progbits .type g_pfnVectors, %object .size g_pfnVectors, .-g_pfnVectors - - + + g_pfnVectors: .word _estack .word Reset_Handler @@ -159,7 +159,7 @@ g_pfnVectors: .word 0 .word PendSV_Handler .word SysTick_Handler - + /* External Interrupts */ .word WWDG_IRQHandler /* Window WatchDog */ .word PVD_IRQHandler /* PVD through EXTI Line detection */ @@ -248,7 +248,7 @@ g_pfnVectors: * Provide weak aliases for each Exception handler to the Default_Handler. * As they are weak aliases, any function with the same name will override * this definition. -* +* *******************************************************************************/ .weak NMI_Handler .thumb_set NMI_Handler,Default_Handler @@ -302,7 +302,7 @@ g_pfnVectors: .thumb_set EXTI1_IRQHandler,Default_Handler .weak EXTI2_IRQHandler - .thumb_set EXTI2_IRQHandler,Default_Handler + .thumb_set EXTI2_IRQHandler,Default_Handler .weak EXTI3_IRQHandler .thumb_set EXTI3_IRQHandler,Default_Handler @@ -320,7 +320,7 @@ g_pfnVectors: .thumb_set DMA1_Stream2_IRQHandler,Default_Handler .weak DMA1_Stream3_IRQHandler - .thumb_set DMA1_Stream3_IRQHandler,Default_Handler + .thumb_set DMA1_Stream3_IRQHandler,Default_Handler .weak DMA1_Stream4_IRQHandler .thumb_set DMA1_Stream4_IRQHandler,Default_Handler @@ -432,7 +432,7 @@ g_pfnVectors: .weak SPI3_IRQHandler .thumb_set SPI3_IRQHandler,Default_Handler - + .weak UART4_IRQHandler .thumb_set UART4_IRQHandler,Default_Handler diff --git a/panda/board/startup_stm32f413xx.s b/panda/board/startup_stm32f413xx.s index 00b645d11b098b..6e6fb5ffa58bc5 100644 --- a/panda/board/startup_stm32f413xx.s +++ b/panda/board/startup_stm32f413xx.s @@ -4,7 +4,7 @@ * @author MCD Application Team * @version V2.6.0 * @date 04-November-2016 - * @brief STM32F413xx Devices vector table for GCC based toolchains. + * @brief STM32F413xx Devices vector table for GCC based toolchains. * This module performs: * - Set the initial SP * - Set the initial PC == Reset_Handler, @@ -42,7 +42,7 @@ * ****************************************************************************** */ - + .syntax unified .cpu cortex-m4 .fpu softvfp @@ -51,7 +51,7 @@ .global g_pfnVectors .global Default_Handler -/* start address for the initialization values of the .data section. +/* start address for the initialization values of the .data section. defined in linker script */ .word _sidata /* start address for the .data section. defined in linker script */ @@ -68,7 +68,7 @@ defined in linker script */ * @brief This is the code that gets called when the processor first * starts execution following a reset event. Only the absolutely * necessary set is performed, after which the application - * supplied main() routine is called. + * supplied main() routine is called. * @param None * @retval : None */ @@ -76,7 +76,7 @@ defined in linker script */ .section .text.Reset_Handler .weak Reset_Handler .type Reset_Handler, %function -Reset_Handler: +Reset_Handler: ldr sp, =_estack /* set stack pointer */ bl __initialize_hardware_early @@ -89,7 +89,7 @@ CopyDataInit: ldr r3, [r3, r1] str r3, [r0, r1] adds r1, r1, #4 - + LoopCopyDataInit: ldr r0, =_sdata ldr r3, =_edata @@ -102,7 +102,7 @@ LoopCopyDataInit: FillZerobss: movs r3, #0 str r3, [r2], #4 - + LoopFillZerobss: ldr r3, = _ebss cmp r2, r3 @@ -114,15 +114,15 @@ LoopFillZerobss: /* bl __libc_init_array */ /* Call the application's entry point.*/ bl main - bx lr + bx lr .size Reset_Handler, .-Reset_Handler /** - * @brief This is the code that gets called when the processor receives an + * @brief This is the code that gets called when the processor receives an * unexpected interrupt. This simply enters an infinite loop, preserving * the system state for examination by a debugger. - * @param None - * @retval None + * @param None + * @retval None */ .section .text.Default_Handler,"ax",%progbits Default_Handler: @@ -134,12 +134,12 @@ Infinite_Loop: * The minimal vector table for a Cortex M3. Note that the proper constructs * must be placed on this to ensure that it ends up at physical address * 0x0000.0000. -* +* *******************************************************************************/ .section .isr_vector,"a",%progbits .type g_pfnVectors, %object .size g_pfnVectors, .-g_pfnVectors - + g_pfnVectors: .word _estack .word Reset_Handler @@ -261,11 +261,11 @@ g_pfnVectors: .word DFSDM2_FLT1_IRQHandler /* DFSDM2 Filter1 */ .word DFSDM2_FLT2_IRQHandler /* DFSDM2 Filter2 */ .word DFSDM2_FLT3_IRQHandler /* DFSDM2 Filter3 */ - + /******************************************************************************* * -* Provide weak aliases for each Exception handler to the Default_Handler. -* As they are weak aliases, any function with the same name will override +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override * this definition. * *******************************************************************************/ @@ -277,7 +277,7 @@ g_pfnVectors: .weak MemManage_Handler .thumb_set MemManage_Handler,Default_Handler - + .weak BusFault_Handler .thumb_set BusFault_Handler,Default_Handler @@ -321,7 +321,7 @@ g_pfnVectors: .thumb_set EXTI1_IRQHandler,Default_Handler .weak EXTI2_IRQHandler - .thumb_set EXTI2_IRQHandler,Default_Handler + .thumb_set EXTI2_IRQHandler,Default_Handler .weak EXTI3_IRQHandler .thumb_set EXTI3_IRQHandler,Default_Handler @@ -439,9 +439,9 @@ g_pfnVectors: .weak DMA1_Stream7_IRQHandler .thumb_set DMA1_Stream7_IRQHandler,Default_Handler - + .weak FSMC_IRQHandler - .thumb_set FSMC_IRQHandler,Default_Handler + .thumb_set FSMC_IRQHandler,Default_Handler .weak SDIO_IRQHandler .thumb_set SDIO_IRQHandler,Default_Handler @@ -451,12 +451,12 @@ g_pfnVectors: .weak SPI3_IRQHandler .thumb_set SPI3_IRQHandler,Default_Handler - + .weak UART4_IRQHandler .thumb_set UART4_IRQHandler,Default_Handler .weak UART5_IRQHandler - .thumb_set UART5_IRQHandler,Default_Handler + .thumb_set UART5_IRQHandler,Default_Handler .weak TIM6_DAC_IRQHandler .thumb_set TIM6_DAC_IRQHandler,Default_Handler @@ -517,7 +517,7 @@ g_pfnVectors: .weak I2C3_ER_IRQHandler .thumb_set I2C3_ER_IRQHandler,Default_Handler - + .weak CAN3_TX_IRQHandler .thumb_set CAN3_TX_IRQHandler,Default_Handler @@ -528,26 +528,26 @@ g_pfnVectors: .thumb_set CAN3_RX1_IRQHandler,Default_Handler .weak CAN3_SCE_IRQHandler - .thumb_set CAN3_SCE_IRQHandler,Default_Handler + .thumb_set CAN3_SCE_IRQHandler,Default_Handler .weak RNG_IRQHandler .thumb_set RNG_IRQHandler,Default_Handler .weak FPU_IRQHandler .thumb_set FPU_IRQHandler,Default_Handler - + .weak UART7_IRQHandler .thumb_set UART7_IRQHandler,Default_Handler .weak UART8_IRQHandler - .thumb_set UART8_IRQHandler,Default_Handler + .thumb_set UART8_IRQHandler,Default_Handler .weak SPI4_IRQHandler .thumb_set SPI4_IRQHandler,Default_Handler .weak SPI5_IRQHandler .thumb_set SPI5_IRQHandler,Default_Handler - + .weak SAI1_IRQHandler .thumb_set SAI1_IRQHandler,Default_Handler @@ -555,7 +555,7 @@ g_pfnVectors: .thumb_set UART9_IRQHandler,Default_Handler .weak UART10_IRQHandler - .thumb_set UART10_IRQHandler,Default_Handler + .thumb_set UART10_IRQHandler,Default_Handler .weak QUADSPI_IRQHandler .thumb_set QUADSPI_IRQHandler,Default_Handler @@ -565,7 +565,7 @@ g_pfnVectors: .weak FMPI2C1_ER_IRQHandler .thumb_set FMPI2C1_ER_IRQHandler,Default_Handler - + .weak LPTIM1_IRQHandler .thumb_set LPTIM1_IRQHandler,Default_Handler diff --git a/panda/board/tools/enter_download_mode.py b/panda/board/tools/enter_download_mode.py index ff3cf84ca97aa3..17d30dda1131e8 100755 --- a/panda/board/tools/enter_download_mode.py +++ b/panda/board/tools/enter_download_mode.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python -from __future__ import print_function +#!/usr/bin/env python3 + import sys import time @@ -11,7 +11,7 @@ def enter_download_mode(device): try: handle.controlWrite(usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE, 0xd1, 0, 0, b'') - except (usb1.USBErrorIO, usb1.USBErrorPipe) as e: + except (usb1.USBErrorIO, usb1.USBErrorPipe): print("Device download mode enabled.") time.sleep(1) else: diff --git a/panda/boardesp/Makefile b/panda/boardesp/Makefile index 0b8fe32b693ff5..c713a0061c9a61 100644 --- a/panda/boardesp/Makefile +++ b/panda/boardesp/Makefile @@ -50,7 +50,7 @@ user1.bin: obj/proxy.o obj/elm327.o obj/webserver.o obj/sha.o obj/rsa.o $(OBJCP) --only-section .data -O binary a.out eagle.app.v6.data.bin $(OBJCP) --only-section .rodata -O binary a.out eagle.app.v6.rodata.bin $(OBJCP) --only-section .irom0.text -O binary a.out eagle.app.v6.irom0text.bin - COMPILE=gcc python ./esp-open-sdk/ESP8266_NONOS_SDK_V1.5.4_16_05_20/tools/gen_appbin.py a.out 2 0 32 4 0 + COMPILE=gcc python2 ./esp-open-sdk/ESP8266_NONOS_SDK_V1.5.4_16_05_20/tools/gen_appbin.py a.out 2 0 32 4 0 rm -f eagle.app.v6.*.bin mv eagle.app.flash.bin $@ ../crypto/sign.py $@ $@ $(CERT) @@ -61,7 +61,7 @@ user2.bin: obj/proxy.o obj/elm327.o obj/webserver.o obj/sha.o obj/rsa.o $(OBJCP) --only-section .data -O binary a.out eagle.app.v6.data.bin $(OBJCP) --only-section .rodata -O binary a.out eagle.app.v6.rodata.bin $(OBJCP) --only-section .irom0.text -O binary a.out eagle.app.v6.irom0text.bin - COMPILE=gcc python ./esp-open-sdk/ESP8266_NONOS_SDK_V1.5.4_16_05_20/tools/gen_appbin.py a.out 2 0 32 4 0 + COMPILE=gcc python2 ./esp-open-sdk/ESP8266_NONOS_SDK_V1.5.4_16_05_20/tools/gen_appbin.py a.out 2 0 32 4 0 rm -f eagle.app.v6.*.bin mv eagle.app.flash.bin $@ ../crypto/sign.py $@ $@ $(CERT) diff --git a/panda/boardesp/elm327.c b/panda/boardesp/elm327.c index 6c18c4463b484d..cec9fd836d8554 100644 --- a/panda/boardesp/elm327.c +++ b/panda/boardesp/elm327.c @@ -10,8 +10,8 @@ //#define ELM_DEBUG -#define min(a,b) ((a) < (b) ? (a) : (b)) -#define max(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) int ICACHE_FLASH_ATTR spi_comm(char *dat, int len, uint32_t *recvData, int recvDataLen); #define ELM_PORT 35000 @@ -52,6 +52,8 @@ typedef struct __attribute__((packed)) { #define PANDA_USB_CAN_WRITE_BUS_NUM 3 #define PANDA_USB_LIN_WRITE_BUS_NUM 2 +#define SAFETY_ELM327 3U + typedef struct _elm_tcp_conn { struct espconn *conn; struct _elm_tcp_conn *next; @@ -855,7 +857,7 @@ static void ICACHE_FLASH_ATTR elm_process_obd_cmd_LINFast(const elm_protocol_t* panda_kline_wakeup_pulse(); } else { - bytelen = min(bytelen, 7); + bytelen = MIN(bytelen, 7); for(int i = 0; i < bytelen; i++){ msg.dat[i] = elm_decode_hex_byte(&cmd[i*2]); msg.dat[bytelen] += msg.dat[i]; @@ -1059,7 +1061,7 @@ static void ICACHE_FLASH_ATTR elm_process_obd_cmd_ISO15765(const elm_protocol_t* return; } - msg.len = min(msg.len, 7); + msg.len = MIN(msg.len, 7); for(int i = 0; i < msg.len; i++) msg.dat[i] = elm_decode_hex_byte(&cmd[i*2]); @@ -1398,7 +1400,7 @@ static void ICACHE_FLASH_ATTR elm_process_at_cmd(char *cmd, uint16_t len) { } tmp = elm_decode_hex_byte(&cmd[2]); - elm_mode_keepalive_period = tmp ? max(tmp, 0x20) * 20 : 0; + elm_mode_keepalive_period = tmp ? MAX(tmp, 0x20) * 20 : 0; if(lin_bus_initialized){ os_timer_disarm(&elm_proto_aux_timeout); @@ -1420,7 +1422,7 @@ static void ICACHE_FLASH_ATTR elm_process_at_cmd(char *cmd, uint16_t len) { elm_append_rsp_const("\r\r"); elm_append_rsp_const(IDENT_MSG); - panda_set_safety_mode(0xE327); + panda_set_safety_mode(SAFETY_ELM327); elm_proto_reinit(elm_current_proto()); return; diff --git a/panda/boardesp/get_sdk.sh b/panda/boardesp/get_sdk.sh index adccf678f9c6a9..b1e8bf2be85eda 100755 --- a/panda/boardesp/get_sdk.sh +++ b/panda/boardesp/get_sdk.sh @@ -8,5 +8,5 @@ sudo apt-get install libtool-bin git clone --recursive https://github.com/pfalcon/esp-open-sdk.git cd esp-open-sdk git checkout 03f5e898a059451ec5f3de30e7feff30455f7cec -LD_LIBRARY_PATH="" make STANDALONE=y - +cp ../python2_make.py . +python2 python2_make.py 'LD_LIBRARY_PATH="" make STANDALONE=y' diff --git a/panda/boardesp/get_sdk_ci.sh b/panda/boardesp/get_sdk_ci.sh new file mode 100755 index 00000000000000..e95b7bd2624c6d --- /dev/null +++ b/panda/boardesp/get_sdk_ci.sh @@ -0,0 +1,6 @@ +#!/bin/bash +git clone --recursive https://github.com/pfalcon/esp-open-sdk.git +cd esp-open-sdk +git checkout 03f5e898a059451ec5f3de30e7feff30455f7cec +cp ../python2_make.py . +python2 python2_make.py 'LD_LIBRARY_PATH="" make STANDALONE=y' diff --git a/panda/boardesp/get_sdk_mac.sh b/panda/boardesp/get_sdk_mac.sh index a8c2d709d45811..c2cfcd53b4d904 100755 --- a/panda/boardesp/get_sdk_mac.sh +++ b/panda/boardesp/get_sdk_mac.sh @@ -28,5 +28,5 @@ git checkout 03f5e898a059451ec5f3de30e7feff30455f7cec git submodule init git submodule update --recursive -make STANDALONE=y - +cp ../python2_make.py . +python2 python2_make.py 'make STANDALONE=y' diff --git a/panda/boardesp/proxy.c b/panda/boardesp/proxy.c index bb89743c198ec9..65586d6096c2bb 100644 --- a/panda/boardesp/proxy.c +++ b/panda/boardesp/proxy.c @@ -9,12 +9,12 @@ #include "driver/uart.h" #include "crypto/sha.h" -#define min(a,b) \ +#define MIN(a,b) \ ({ __typeof__ (a) _a = (a); \ __typeof__ (b) _b = (b); \ _a < _b ? _a : _b; }) -#define max(a,b) \ +#define MAX(a,b) \ ({ __typeof__ (a) _a = (a); \ __typeof__ (b) _b = (b); \ _a > _b ? _a : _b; }) diff --git a/panda/boardesp/python2_make.py b/panda/boardesp/python2_make.py new file mode 100644 index 00000000000000..85bee3457719bf --- /dev/null +++ b/panda/boardesp/python2_make.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python2 +import os +import sys +os.system(sys.argv[1]) diff --git a/panda/boardesp/webserver.c b/panda/boardesp/webserver.c index 9266b08f70f605..b1a514626f6a6e 100644 --- a/panda/boardesp/webserver.c +++ b/panda/boardesp/webserver.c @@ -14,8 +14,8 @@ #include "obj/gitversion.h" #include "obj/cert.h" -#define max(a,b) ((a) > (b) ? (a) : (b)) -#define min(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) #define espconn_send_string(conn, x) espconn_send(conn, x, strlen(x)) #define MAX_RESP 0x800 @@ -28,8 +28,7 @@ char pageheader[] = "HTTP/1.0 200 OK\nContent-Type: text/html\n\n" "\n" "\n" "
This is your comma.ai panda\n\n"
-"It's open source. Find the code here\n"
-"Designed to work with our dashcam, chffr\n";
+"It's open source. Find the code here\n";
 
 char pagefooter[] = "
\n" "\n" @@ -84,7 +83,7 @@ int ICACHE_FLASH_ATTR usb_cmd(int ep, int len, int request, return recv[0]; } - + void ICACHE_FLASH_ATTR st_flash() { if (st_firmware != NULL) { @@ -116,7 +115,7 @@ void ICACHE_FLASH_ATTR st_flash() { // real content length will always be 0x10 aligned os_printf("st_flash: flashing\n"); for (int i = 0; i < real_content_length; i += 0x10) { - int rl = min(0x10, real_content_length-i); + int rl = MIN(0x10, real_content_length-i); usb_cmd(2, rl, 0, 0, 0, &st_firmware[i]); system_soft_wdt_feed(); } @@ -212,14 +211,14 @@ static void ICACHE_FLASH_ATTR web_rx_cb(void *arg, char *data, uint16_t len) { } else { ets_strcat(resp, "\nin INSECURE mode...secure it"); } - + ets_strcat(resp,"\nSet USB Mode:" "" "" "\n"); ets_strcat(resp, pagefooter); - + espconn_send_string(&web_conn, resp); espconn_disconnect(conn); } else if (memcmp(data, "GET /secure", 11) == 0 && !wifi_secure_mode) { @@ -235,7 +234,7 @@ static void ICACHE_FLASH_ATTR web_rx_cb(void *arg, char *data, uint16_t len) { os_sprintf(resp, "%sUSB Mode set to %02x\n\n", OK_header, mode_value); espconn_send_string(&web_conn, resp); espconn_disconnect(conn); - } + } } else if (memcmp(data, "PUT /stupdate ", 14) == 0 && wifi_secure_mode) { os_printf("init st firmware\n"); char *cl = strstr(data, "Content-Length: "); @@ -251,7 +250,7 @@ static void ICACHE_FLASH_ATTR web_rx_cb(void *arg, char *data, uint16_t len) { memset(st_firmware, 0, real_content_length); state = RECEIVING_ST_FIRMWARE; } - + } else if (((memcmp(data, "PUT /espupdate1 ", 16) == 0) || (memcmp(data, "PUT /espupdate2 ", 16) == 0)) && wifi_secure_mode) { // 0x1000 = user1.bin @@ -288,7 +287,7 @@ static void ICACHE_FLASH_ATTR web_rx_cb(void *arg, char *data, uint16_t len) { } } else if (state == RECEIVING_ST_FIRMWARE) { os_printf("receiving st firmware: %d/%d\n", len, content_length); - memcpy(st_firmware_ptr, data, min(content_length, len)); + memcpy(st_firmware_ptr, data, MIN(content_length, len)); st_firmware_ptr += len; content_length -= len; @@ -333,7 +332,7 @@ static void ICACHE_FLASH_ATTR web_rx_cb(void *arg, char *data, uint16_t len) { SHA_init(&ctx); for (ll = start_address; ll < esp_address-RSANUMBYTES; ll += 0x80) { spi_flash_read(ll, dat, 0x80); - SHA_update(&ctx, dat, min((esp_address-RSANUMBYTES)-ll, 0x80)); + SHA_update(&ctx, dat, MIN((esp_address-RSANUMBYTES)-ll, 0x80)); } memcpy(digest, SHA_final(&ctx), SHA_DIGEST_SIZE); diff --git a/panda/buy.png b/panda/buy.png index 72c70574225173..a4a9e0fd40a426 100644 Binary files a/panda/buy.png and b/panda/buy.png differ diff --git a/panda/crypto/getcertheader.py b/panda/crypto/getcertheader.py index 75d04e977ad8c1..bbbe475ef8b000 100755 --- a/panda/crypto/getcertheader.py +++ b/panda/crypto/getcertheader.py @@ -1,6 +1,5 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import sys -import struct from Crypto.PublicKey import RSA def egcd(a, b): @@ -26,7 +25,7 @@ def to_c_uint32(x): nums = [] for i in range(0x20): nums.append(x%(2**32)) - x /= (2**32) + x //= (2**32) return "{"+'U,'.join(map(str, nums))+"U}" for fn in sys.argv[1:]: @@ -36,11 +35,11 @@ def to_c_uint32(x): cname = fn.split("/")[-1].split(".")[0] + "_rsa_key" - print 'RSAPublicKey '+cname+' = {.len = 0x20,' - print ' .n0inv = %dU,' % n0inv - print ' .n = %s,' % to_c_uint32(rsa.n) - print ' .rr = %s,' % to_c_uint32(rr) - print ' .exponent = %d,' % rsa.e - print '};' + print('RSAPublicKey '+cname+' = {.len = 0x20,') + print(' .n0inv = %dU,' % n0inv) + print(' .n = %s,' % to_c_uint32(rsa.n)) + print(' .rr = %s,' % to_c_uint32(rr)) + print(' .exponent = %d,' % rsa.e) + print('};') diff --git a/panda/crypto/sha.c b/panda/crypto/sha.c index 8e1715525c68a2..a13162c5fac0d3 100644 --- a/panda/crypto/sha.c +++ b/panda/crypto/sha.c @@ -130,7 +130,7 @@ const uint8_t* SHA_final(SHA_CTX* ctx) { /* Hack - right shift operator with non const argument requires * libgcc.a which is missing in EON - * thus expanding for loop from + * thus expanding for loop from for (i = 0; i < 8; ++i) { uint8_t tmp = (uint8_t) (cnt >> ((7 - i) * 8)); diff --git a/panda/crypto/sign.py b/panda/crypto/sign.py index 159299271e91e0..0f1ce030815b6d 100755 --- a/panda/crypto/sign.py +++ b/panda/crypto/sign.py @@ -1,16 +1,17 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import os import sys import struct import hashlib from Crypto.PublicKey import RSA +import binascii rsa = RSA.importKey(open(sys.argv[3]).read()) -with open(sys.argv[1]) as f: +with open(sys.argv[1], "rb") as f: dat = f.read() -print "signing", len(dat), "bytes" +print("signing", len(dat), "bytes") with open(sys.argv[2], "wb") as f: if os.getenv("SETLEN") is not None: @@ -20,10 +21,11 @@ else: x = dat dd = hashlib.sha1(dat).digest() - print "hash:",dd.encode("hex") - dd = "\x00\x01" + "\xff"*0x69 + "\x00" + dd - rsa_out = pow(int(dd.encode("hex"), 16), rsa.d, rsa.n) - sig = (hex(rsa_out)[2:-1].rjust(0x100, '0')).decode("hex") - x += sig + + print("hash:", str(binascii.hexlify(dd), "utf-8")) + dd = b"\x00\x01" + b"\xff"*0x69 + b"\x00" + dd + rsa_out = pow(int.from_bytes(dd, byteorder='big', signed=False), rsa.d, rsa.n) + sig = (hex(rsa_out)[2:].rjust(0x100, '0')) + x += binascii.unhexlify(sig) f.write(x) diff --git a/panda/drivers/linux/panda.c b/panda/drivers/linux/panda.c index 4c5980a9d2ff3c..3d4f957f9c5083 100644 --- a/panda/drivers/linux/panda.c +++ b/panda/drivers/linux/panda.c @@ -38,6 +38,9 @@ #define PANDA_DLC_MASK 0x0F +#define SAFETY_ALLOUTPUT 17 +#define SAFETY_NOOUTPUT 0 + struct panda_usb_ctx { struct panda_inf_priv *priv; u32 ndx; @@ -156,7 +159,7 @@ static int panda_set_output_enable(struct panda_inf_priv* priv, bool enable){ return usb_control_msg(priv->priv_dev->udev, usb_sndctrlpipe(priv->priv_dev->udev, 0), 0xDC, USB_TYPE_VENDOR | USB_RECIP_DEVICE, - enable ? 0x1337 : 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); + enable ? SAFETY_ALLOUTPUT : SAFETY_NOOUTPUT, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); } static void panda_usb_write_bulk_callback(struct urb *urb) diff --git a/panda/drivers/windows/pandaJ2534DLL/MessageRx.h b/panda/drivers/windows/pandaJ2534DLL/MessageRx.h index e22278d4d0a934..2af24364ff3a36 100644 --- a/panda/drivers/windows/pandaJ2534DLL/MessageRx.h +++ b/panda/drivers/windows/pandaJ2534DLL/MessageRx.h @@ -21,7 +21,7 @@ class MessageRx } this->next_part = (this->next_part + 1) % 0x10; - unsigned int payload_len = min(expected_size - msg.size(), max_packet_size); + unsigned int payload_len = MIN(expected_size - msg.size(), max_packet_size); if (piece.size() < payload_len) { //A frame was received that could have held more data. //No examples of this protocol show that happening, so diff --git a/panda/drivers/windows/pandaJ2534DLL/PandaJ2534Device.cpp b/panda/drivers/windows/pandaJ2534DLL/PandaJ2534Device.cpp index 1b961579e079ab..19ae43b0d70d08 100644 --- a/panda/drivers/windows/pandaJ2534DLL/PandaJ2534Device.cpp +++ b/panda/drivers/windows/pandaJ2534DLL/PandaJ2534Device.cpp @@ -93,7 +93,7 @@ DWORD PandaJ2534Device::can_process_thread() { if (count == 0) { continue; } - + for (int i = 0; i < count; i++) { auto msg_in = msg_recv[i]; J2534Frame msg_out(msg_in); @@ -170,7 +170,7 @@ DWORD PandaJ2534Device::msg_tx_thread() { } else { //Ran out of things that need to be sent now. Sleep! auto time_diff = std::chrono::duration_cast (this->task_queue.front()->expire - std::chrono::steady_clock::now()); - sleepDuration = max(1, time_diff.count()); + sleepDuration = MAX(1, time_diff.count()); goto break_flow_ctrl_loop; } } diff --git a/panda/drivers/windows/pandaJ2534DLL/resource.h b/panda/drivers/windows/pandaJ2534DLL/resource.h index 771e7b80bc1e81..af0e13cc04d638 100644 --- a/panda/drivers/windows/pandaJ2534DLL/resource.h +++ b/panda/drivers/windows/pandaJ2534DLL/resource.h @@ -3,7 +3,7 @@ // Used by pandaJ2534DLL.rc // Next default values for new objects -// +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 diff --git a/panda/drivers/windows/panda_shared/panda.h b/panda/drivers/windows/panda_shared/panda.h index ade8fa36a8601e..8d98b08b71a405 100644 --- a/panda/drivers/windows/panda_shared/panda.h +++ b/panda/drivers/windows/panda_shared/panda.h @@ -40,7 +40,7 @@ namespace panda { typedef enum _PANDA_SAFETY_MODE : uint16_t { SAFETY_NOOUTPUT = 0, SAFETY_HONDA = 1, - SAFETY_ALLOUTPUT = 0x1337, + SAFETY_ALLOUTPUT = 17, } PANDA_SAFETY_MODE; typedef enum _PANDA_SERIAL_PORT : uint8_t { diff --git a/panda/examples/can_bit_transition.py b/panda/examples/can_bit_transition.py index 5c15e4bbc26eed..aa4aa9df95f010 100755 --- a/panda/examples/can_bit_transition.py +++ b/panda/examples/can_bit_transition.py @@ -1,6 +1,4 @@ -#!/usr/bin/env python - -import binascii +#!/usr/bin/env python3 import csv import sys @@ -13,13 +11,13 @@ def __init__(self, message_id): def printBitDiff(self, other): """Prints bits that transition from always zero to always 1 and vice versa.""" - for i in xrange(len(self.ones)): + for i in range(len(self.ones)): zero_to_one = other.zeros[i] & self.ones[i] if zero_to_one: - print 'id %s 0 -> 1 at byte %d bitmask %d' % (self.message_id, i, zero_to_one) + print('id %s 0 -> 1 at byte %d bitmask %d' % (self.message_id, i, zero_to_one)) one_to_zero = other.ones[i] & self.zeros[i] if one_to_zero: - print 'id %s 1 -> 0 at byte %d bitmask %d' % (self.message_id, i, one_to_zero) + print('id %s 1 -> 0 at byte %d bitmask %d' % (self.message_id, i, one_to_zero)) class Info(): @@ -56,7 +54,7 @@ def load(self, filename, start, end): new_message = True message = self.messages[message_id] bytes = bytearray.fromhex(data) - for i in xrange(len(bytes)): + for i in range(len(bytes)): ones = int(bytes[i]) message.ones[i] = ones if new_message else message.ones[i] & ones # Inverts the data and masks it to a byte to get the zeros as ones. @@ -65,11 +63,11 @@ def load(self, filename, start, end): def PrintUnique(log_file, low_range, high_range): # find messages with bits that are always low - start, end = map(float, low_range.split('-')) + start, end = list(map(float, low_range.split('-'))) low = Info() low.load(log_file, start, end) # find messages with bits that are always high - start, end = map(float, high_range.split('-')) + start, end = list(map(float, high_range.split('-'))) high = Info() high.load(log_file, start, end) # print messages that go from low to high @@ -78,10 +76,10 @@ def PrintUnique(log_file, low_range, high_range): if message_id in low.messages: high.messages[message_id].printBitDiff(low.messages[message_id]) found = True - if not found: print 'No messages that transition from always low to always high found!' + if not found: print('No messages that transition from always low to always high found!') if __name__ == "__main__": if len(sys.argv) < 4: - print 'Usage:\n%s log.csv - -' % sys.argv[0] + print('Usage:\n%s log.csv - -' % sys.argv[0]) sys.exit(0) PrintUnique(sys.argv[1], sys.argv[2], sys.argv[3]) diff --git a/panda/examples/can_logger.py b/panda/examples/can_logger.py index 05c28a26df1228..203023dc92c106 100755 --- a/panda/examples/can_logger.py +++ b/panda/examples/can_logger.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python -from __future__ import print_function +#!/usr/bin/env python3 + import binascii import csv import sys diff --git a/panda/examples/can_unique.md b/panda/examples/can_unique.md index bf316940d3adb9..4d8ac460e4d6c3 100644 --- a/panda/examples/can_unique.md +++ b/panda/examples/can_unique.md @@ -10,8 +10,8 @@ First record a few minutes of background CAN messages with all the doors closed ./can_logger.py mv output.csv background.csv ``` -Then run can_logger.py for a few seconds while performing the action you're interested, such as opening and then closing the -front-left door and save it as door-fl-1.csv +Then run can_logger.py for a few seconds while performing the action you're interested, such as opening and then closing the +front-left door and save it as door-fl-1.csv Repeat the process and save it as door-f1-2.csv to have an easy way to confirm any suspicions. Now we'll use can_unique.py to look for unique bits: diff --git a/panda/examples/can_unique.py b/panda/examples/can_unique.py index ad6de296ee4174..fdd586c3d3517d 100755 --- a/panda/examples/can_unique.py +++ b/panda/examples/can_unique.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Given an interesting CSV file of CAN messages and a list of background CAN # messages, print which bits in the interesting file have never appeared @@ -13,10 +13,8 @@ # 0,344,c000c00000000000 -import binascii import csv import sys -from panda import Panda class Message(): """Details about a specific message ID.""" @@ -28,15 +26,15 @@ def __init__(self, message_id): def printBitDiff(self, other): """Prints bits that are set or cleared compared to other background.""" - for i in xrange(len(self.ones)): + for i in range(len(self.ones)): new_ones = ((~other.ones[i]) & 0xff) & self.ones[i] if new_ones: - print 'id %s new one at byte %d bitmask %d' % ( - self.message_id, i, new_ones) + print('id %s new one at byte %d bitmask %d' % ( + self.message_id, i, new_ones)) new_zeros = ((~other.zeros[i]) & 0xff) & self.zeros[i] if new_zeros: - print 'id %s new zero at byte %d bitmask %d' % ( - self.message_id, i, new_zeros) + print('id %s new zero at byte %d bitmask %d' % ( + self.message_id, i, new_zeros)) class Info(): @@ -67,7 +65,7 @@ def load(self, filename): if data not in self.messages[message_id].data: message.data[data] = True bytes = bytearray.fromhex(data) - for i in xrange(len(bytes)): + for i in range(len(bytes)): message.ones[i] = message.ones[i] | int(bytes[i]) # Inverts the data and masks it to a byte to get the zeros as ones. message.zeros[i] = message.zeros[i] | ( (~int(bytes[i])) & 0xff) @@ -80,7 +78,7 @@ def PrintUnique(interesting_file, background_files): interesting.load(interesting_file) for message_id in sorted(interesting.messages): if message_id not in background.messages: - print 'New message_id: %s' % message_id + print('New message_id: %s' % message_id) else: interesting.messages[message_id].printBitDiff( background.messages[message_id]) @@ -88,6 +86,6 @@ def PrintUnique(interesting_file, background_files): if __name__ == "__main__": if len(sys.argv) < 3: - print 'Usage:\n%s interesting.csv background*.csv' % sys.argv[0] + print('Usage:\n%s interesting.csv background*.csv' % sys.argv[0]) sys.exit(0) PrintUnique(sys.argv[1], sys.argv[2:]) diff --git a/panda/examples/eps_read_software_ids.py b/panda/examples/eps_read_software_ids.py new file mode 100755 index 00000000000000..a3292207c7e90c --- /dev/null +++ b/panda/examples/eps_read_software_ids.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +from panda import Panda +from panda.python.uds import UdsClient, NegativeResponseError, DATA_IDENTIFIER_TYPE + +if __name__ == "__main__": + address = 0x18da30f1 # Honda EPS + panda = Panda() + uds_client = UdsClient(panda, address, debug=False) + + print("tester present ...") + uds_client.tester_present() + + try: + print("") + print("read data by id: boot software id ...") + data = uds_client.read_data_by_identifier(DATA_IDENTIFIER_TYPE.BOOT_SOFTWARE_IDENTIFICATION) + print(data.decode('utf-8')) + except NegativeResponseError as e: + print(e) + + try: + print("") + print("read data by id: application software id ...") + data = uds_client.read_data_by_identifier(DATA_IDENTIFIER_TYPE.APPLICATION_SOFTWARE_IDENTIFICATION) + print(data.decode('utf-8')) + except NegativeResponseError as e: + print(e) + + try: + print("") + print("read data by id: application data id ...") + data = uds_client.read_data_by_identifier(DATA_IDENTIFIER_TYPE.APPLICATION_DATA_IDENTIFICATION) + print(data.decode('utf-8')) + except NegativeResponseError as e: + print(e) + + try: + print("") + print("read data by id: boot software fingerprint ...") + data = uds_client.read_data_by_identifier(DATA_IDENTIFIER_TYPE.BOOT_SOFTWARE_FINGERPRINT) + print(data.decode('utf-8')) + except NegativeResponseError as e: + print(e) + + try: + print("") + print("read data by id: application software fingerprint ...") + data = uds_client.read_data_by_identifier(DATA_IDENTIFIER_TYPE.APPLICATION_SOFTWARE_FINGERPRINT) + print(data.decode('utf-8')) + except NegativeResponseError as e: + print(e) + + try: + print("") + print("read data by id: application data fingerprint ...") + data = uds_client.read_data_by_identifier(DATA_IDENTIFIER_TYPE.APPLICATION_DATA_FINGERPRINT) + print(data.decode('utf-8')) + except NegativeResponseError as e: + print(e) diff --git a/panda/examples/get_panda_password.py b/panda/examples/get_panda_password.py index 11071d035346be..54cbe57ec363a6 100644 --- a/panda/examples/get_panda_password.py +++ b/panda/examples/get_panda_password.py @@ -1,12 +1,13 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 +import sys from panda import Panda def get_panda_password(): - + try: print("Trying to connect to Panda over USB...") p = Panda() - + except AssertionError: print("USB connection failed") sys.exit(0) @@ -15,6 +16,6 @@ def get_panda_password(): #print('[%s]' % ', '.join(map(str, wifi))) print("SSID: " + wifi[0]) print("Password: " + wifi[1]) - + if __name__ == "__main__": - get_panda_password() \ No newline at end of file + get_panda_password() diff --git a/panda/examples/query_vin_and_stats.py b/panda/examples/query_vin_and_stats.py index cd2185b4a6f11f..f8b5d9b2eb880a 100755 --- a/panda/examples/query_vin_and_stats.py +++ b/panda/examples/query_vin_and_stats.py @@ -1,16 +1,17 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import time import struct from panda import Panda from hexdump import hexdump -from isotp import isotp_send, isotp_recv +from panda.python.isotp import isotp_send, isotp_recv # 0x7e0 = Toyota # 0x18DB33F1 for Honda? + def get_current_data_for_pid(pid): # 01 xx = Show current data - isotp_send(panda, "\x01"+chr(pid), 0x7e0) + isotp_send(panda, b"\x01"+ bytes([pid]), 0x7e0) return isotp_recv(panda, 0x7e8) def get_supported_pids(): @@ -33,18 +34,18 @@ def get_supported_pids(): panda.can_clear(0) # 09 02 = Get VIN - isotp_send(panda, "\x09\x02", 0x7e0) + isotp_send(panda, b"\x09\x02", 0x7df) ret = isotp_recv(panda, 0x7e8) hexdump(ret) - print "VIN: %s" % ret[2:] + print("VIN: %s" % "".join(map(chr, ret[:2]))) # 03 = get DTCS - isotp_send(panda, "\x03", 0x7e0) + isotp_send(panda, b"\x03", 0x7e0) dtcs = isotp_recv(panda, 0x7e8) - print "DTCs:", dtcs[2:].encode("hex") + print("DTCs:", "".join(map(chr, dtcs[:2]))) supported_pids = get_supported_pids() - print "Supported PIDs:",supported_pids + print("Supported PIDs:",supported_pids) while 1: speed = struct.unpack(">B", get_current_data_for_pid(13)[2:])[0] # kph @@ -52,7 +53,7 @@ def get_supported_pids(): throttle = struct.unpack(">B", get_current_data_for_pid(17)[2:])[0]/255.0 * 100 # percent temp = struct.unpack(">B", get_current_data_for_pid(5)[2:])[0] - 40 # degrees C load = struct.unpack(">B", get_current_data_for_pid(4)[2:])[0]/255.0 * 100 # percent - print "%d KPH, %d RPM, %.1f%% Throttle, %d deg C, %.1f%% load" % (speed, rpm, throttle, temp, load) + print("%d KPH, %d RPM, %.1f%% Throttle, %d deg C, %.1f%% load" % (speed, rpm, throttle, temp, load)) time.sleep(0.2) diff --git a/panda/examples/tesla_tester.py b/panda/examples/tesla_tester.py index 99d8d92854423b..9a77eb4edf502a 100644 --- a/panda/examples/tesla_tester.py +++ b/panda/examples/tesla_tester.py @@ -1,17 +1,17 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import sys import binascii from panda import Panda def tesla_tester(): - + try: print("Trying to connect to Panda over USB...") p = Panda() - + except AssertionError: print("USB connection failed. Trying WiFi...") - + try: p = Panda("WIFI") except: @@ -21,26 +21,26 @@ def tesla_tester(): body_bus_speed = 125 # Tesla Body busses (B, BF) are 125kbps, rest are 500kbps body_bus_num = 1 # My TDC to OBD adapter has PT on bus0 BDY on bus1 and CH on bus2 p.set_can_speed_kbps(body_bus_num, body_bus_speed) - + # Now set the panda from its default of SAFETY_NOOUTPUT (read only) to SAFETY_ALLOUTPUT # Careful, as this will let us send any CAN messages we want (which could be very bad!) print("Setting Panda to output mode...") p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) - + # BDY 0x248 is the MCU_commands message, which includes folding mirrors, opening the trunk, frunk, setting the cars lock state and more. For our test, we will edit the 3rd byte, which is MCU_lockRequest. 0x01 will lock, 0x02 will unlock: print("Unlocking Tesla...") - p.can_send(0x248, "\x00\x00\x02\x00\x00\x00\x00\x00", body_bus_num) + p.can_send(0x248, b"\x00\x00\x02\x00\x00\x00\x00\x00", body_bus_num) #Or, we can set the first byte, MCU_frontHoodCommand + MCU_liftgateSwitch, to 0x01 to pop the frunk, or 0x04 to open/close the trunk (0x05 should open both) print("Opening Frunk...") - p.can_send(0x248, "\x01\x00\x00\x00\x00\x00\x00\x00", body_bus_num) - + p.can_send(0x248, b"\x01\x00\x00\x00\x00\x00\x00\x00", body_bus_num) + #Back to safety... print("Disabling output on Panda...") p.set_safety_mode(Panda.SAFETY_NOOUTPUT) - + print("Reading VIN from 0x568. This is painfully slow and can take up to 3 minutes (1 minute per message; 3 messages needed for full VIN)...") - + vin = {} while True: #Read the VIN diff --git a/panda/python/__init__.py b/panda/python/__init__.py index b3610e6c3f9970..326128d3ec306a 100644 --- a/panda/python/__init__.py +++ b/panda/python/__init__.py @@ -1,5 +1,5 @@ # python library to interface with panda -from __future__ import print_function +import datetime import binascii import struct import hashlib @@ -9,29 +9,28 @@ import time import traceback import subprocess -from dfu import PandaDFU -from esptool import ESPROM, CesantaFlasher -from flash_release import flash_release -from update import ensure_st_up_to_date -from serial import PandaSerial -from isotp import isotp_send, isotp_recv +from .dfu import PandaDFU +from .esptool import ESPROM, CesantaFlasher # noqa: F401 +from .flash_release import flash_release # noqa: F401 +from .update import ensure_st_up_to_date # noqa: F401 +from .serial import PandaSerial # noqa: F401 +from .isotp import isotp_send, isotp_recv -__version__ = '0.0.8' +__version__ = '0.0.9' BASEDIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../") DEBUG = os.getenv("PANDADEBUG") is not None # *** wifi mode *** - def build_st(target, mkfile="Makefile"): from panda import BASEDIR cmd = 'cd %s && make -f %s clean && make -f %s %s >/dev/null' % (os.path.join(BASEDIR, "board"), mkfile, mkfile, target) try: - output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True) - except subprocess.CalledProcessError as exception: - output = exception.output - returncode = exception.returncode + _ = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True) + except subprocess.CalledProcessError: + #output = exception.output + #returncode = exception.returncode raise def parse_can_buffer(dat): @@ -46,7 +45,7 @@ def parse_can_buffer(dat): address = f1 >> 21 dddat = ddat[8:8+(f2&0xF)] if DEBUG: - print(" R %x: %s" % (address, str(dddat).encode("hex"))) + print(" R %x: %s" % (address, binascii.hexlify(dddat))) ret.append((address, f2>>16, dddat, (f2>>4)&0xFF)) return ret @@ -109,20 +108,25 @@ def close(self): # *** normal mode *** class Panda(object): + + # matches cereal.car.CarParams.SafetyModel SAFETY_NOOUTPUT = 0 SAFETY_HONDA = 1 SAFETY_TOYOTA = 2 - SAFETY_GM = 3 - SAFETY_HONDA_BOSCH = 4 - SAFETY_FORD = 5 - SAFETY_CADILLAC = 6 - SAFETY_HYUNDAI = 7 - SAFETY_TESLA = 8 + SAFETY_ELM327 = 3 + SAFETY_GM = 4 + SAFETY_HONDA_BOSCH = 5 + SAFETY_FORD = 6 + SAFETY_CADILLAC = 7 + SAFETY_HYUNDAI = 8 SAFETY_CHRYSLER = 9 - SAFETY_TOYOTA_IPAS = 0x1335 - SAFETY_TOYOTA_NOLIMITS = 0x1336 - SAFETY_ALLOUTPUT = 0x1337 - SAFETY_ELM327 = 0xE327 + SAFETY_TESLA = 10 + SAFETY_SUBARU = 11 + SAFETY_MAZDA = 13 + SAFETY_VOLKSWAGEN = 15 + SAFETY_TOYOTA_IPAS = 16 + SAFETY_ALLOUTPUT = 17 + SAFETY_GM_ASCM = 18 SERIAL_DEBUG = 0 SERIAL_ESP = 1 @@ -135,6 +139,13 @@ class Panda(object): REQUEST_IN = usb1.ENDPOINT_IN | usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE REQUEST_OUT = usb1.ENDPOINT_OUT | usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE + HW_TYPE_UNKNOWN = b'\x00' + HW_TYPE_WHITE_PANDA = b'\x01' + HW_TYPE_GREY_PANDA = b'\x02' + HW_TYPE_BLACK_PANDA = b'\x03' + HW_TYPE_PEDAL = b'\x04' + HW_TYPE_UNO = b'\x05' + def __init__(self, serial=None, claim=True): self._serial = serial self._handle = None @@ -182,6 +193,7 @@ def connect(self, claim=True, wait=False): traceback.print_exc() if wait == False or self._handle != None: break + context = usb1.USBContext() #New context needed so new devices show up assert(self._handle != None) print("connected") @@ -225,16 +237,16 @@ def reconnect(self): def flash_static(handle, code): # confirm flasher is present fr = handle.controlRead(Panda.REQUEST_IN, 0xb0, 0, 0, 0xc) - assert fr[4:8] == "\xde\xad\xd0\x0d" + assert fr[4:8] == b"\xde\xad\xd0\x0d" # unlock flash print("flash: unlocking") handle.controlWrite(Panda.REQUEST_IN, 0xb1, 0, 0, b'') - # erase sectors 1 and 2 + # erase sectors 1 through 3 print("flash: erasing") - handle.controlWrite(Panda.REQUEST_IN, 0xb2, 1, 0, b'') - handle.controlWrite(Panda.REQUEST_IN, 0xb2, 2, 0, b'') + for i in range(1, 4): + handle.controlWrite(Panda.REQUEST_IN, 0xb2, i, 0, b'') # flash over EP2 STEP = 0x10 @@ -267,7 +279,7 @@ def flash(self, fn=None, code=None, reconnect=True): fn = os.path.join(BASEDIR, "board", fn) if code is None: - with open(fn) as f: + with open(fn, "rb") as f: code = f.read() # get version @@ -280,11 +292,14 @@ def flash(self, fn=None, code=None, reconnect=True): if reconnect: self.reconnect() - def recover(self): + def recover(self, timeout=None): self.reset(enter_bootloader=True) + t_start = time.time() while len(PandaDFU.list()) == 0: print("waiting for DFU...") time.sleep(0.1) + if timeout is not None and (time.time() - t_start) > timeout: + return False dfu = PandaDFU(PandaDFU.st_serial_to_dfu_serial(self._serial)) dfu.recover() @@ -292,6 +307,7 @@ def recover(self): # reflash after recover self.connect(True, True) self.flash() + return True @staticmethod def flash_ota_st(): @@ -300,8 +316,9 @@ def flash_ota_st(): return ret==0 @staticmethod - def flash_ota_wifi(): - ret = os.system("cd %s && make clean && make ota" % (os.path.join(BASEDIR, "boardesp"))) + def flash_ota_wifi(release=False): + release_str = "RELEASE=1" if release else "" + ret = os.system("cd {} && make clean && {} make ota".format(os.path.join(BASEDIR, "boardesp"),release_str)) time.sleep(1) return ret==0 @@ -328,13 +345,19 @@ def call_control_api(self, msg): # ******************* health ******************* def health(self): - dat = self._handle.controlRead(Panda.REQUEST_IN, 0xd2, 0, 0, 13) - a = struct.unpack("IIBBBBB", dat) - return {"voltage": a[0], "current": a[1], - "started": a[2], "controls_allowed": a[3], - "gas_interceptor_detected": a[4], - "started_signal_detected": a[5], - "started_alt": a[6]} + dat = self._handle.controlRead(Panda.REQUEST_IN, 0xd2, 0, 0, 24) + a = struct.unpack("IIIIIBBBB", dat) + return { + "voltage": a[0], + "current": a[1], + "can_send_errs": a[2], + "can_fwd_errs": a[3], + "gmlan_send_errs": a[4], + "started": a[5], + "controls_allowed": a[6], + "gas_interceptor_detected": a[7], + "car_harness_status": a[8] + } # ******************* control ******************* @@ -346,17 +369,28 @@ def enter_bootloader(self): pass def get_version(self): - return self._handle.controlRead(Panda.REQUEST_IN, 0xd6, 0, 0, 0x40) + return self._handle.controlRead(Panda.REQUEST_IN, 0xd6, 0, 0, 0x40).decode('utf8') + + def get_type(self): + return self._handle.controlRead(Panda.REQUEST_IN, 0xc1, 0, 0, 0x40) + + def is_white(self): + return self.get_type() == Panda.HW_TYPE_WHITE_PANDA def is_grey(self): - ret = self._handle.controlRead(Panda.REQUEST_IN, 0xc1, 0, 0, 0x40) - return ret == "\x01" + return self.get_type() == Panda.HW_TYPE_GREY_PANDA + + def is_black(self): + return self.get_type() == Panda.HW_TYPE_BLACK_PANDA + + def is_uno(self): + return self.get_type() == Panda.HW_TYPE_UNO def get_serial(self): dat = self._handle.controlRead(Panda.REQUEST_IN, 0xd0, 0, 0, 0x20) hashsig, calc_hash = dat[0x1c:], hashlib.sha1(dat[0:0x1c]).digest()[0:4] assert(hashsig == calc_hash) - return [dat[0:0x10], dat[0x10:0x10+10]] + return [dat[0:0x10].decode("utf8"), dat[0x10:0x10+10].decode("utf8")] def get_secret(self): return self._handle.controlRead(Panda.REQUEST_IN, 0xd0, 1, 0, 0x10) @@ -381,20 +415,29 @@ def set_can_forwarding(self, from_bus, to_bus): self._handle.controlWrite(Panda.REQUEST_OUT, 0xdd, from_bus, to_bus, b'') def set_gmlan(self, bus=2): + # TODO: check panda type if bus is None: self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, 0, 0, b'') elif bus in [Panda.GMLAN_CAN2, Panda.GMLAN_CAN3]: self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, 1, bus, b'') + def set_obd(self, obd): + # TODO: check panda type + self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, int(obd), 0, b'') + def set_can_loopback(self, enable): # set can loopback mode for all buses self._handle.controlWrite(Panda.REQUEST_OUT, 0xe5, int(enable), 0, b'') + def set_can_enable(self, bus_num, enable): + # sets the can transciever enable pin + self._handle.controlWrite(Panda.REQUEST_OUT, 0xf4, int(bus_num), int(enable), b'') + def set_can_speed_kbps(self, bus, speed): self._handle.controlWrite(Panda.REQUEST_OUT, 0xde, bus, int(speed*10), b'') def set_uart_baud(self, uart, rate): - self._handle.controlWrite(Panda.REQUEST_OUT, 0xe4, uart, rate/300, b'') + self._handle.controlWrite(Panda.REQUEST_OUT, 0xe4, uart, int(rate/300), b'') def set_uart_parity(self, uart, parity): # parity, 0=off, 1=even, 2=odd @@ -412,7 +455,7 @@ def can_send_many(self, arr): for addr, _, dat, bus in arr: assert len(dat) <= 8 if DEBUG: - print(" W %x: %s" % (addr, dat.encode("hex"))) + print(" W %x: %s" % (addr, binascii.hexlify(dat))) if addr >= 0x800: rir = (addr << 3) | transmit | extended else: @@ -444,6 +487,7 @@ def can_recv(self): break except (usb1.USBErrorIO, usb1.USBErrorOverflow): print("CAN: BAD RECV, RETRYING") + time.sleep(0.1) return parse_can_buffer(dat) def can_clear(self, bus): @@ -510,16 +554,16 @@ def kline_drain(self, bus=2): if len(ret) == 0: break elif DEBUG: - print("kline drain: "+str(ret).encode("hex")) + print("kline drain: " + binascii.hexlify(ret)) bret += ret return bytes(bret) def kline_ll_recv(self, cnt, bus=2): echo = bytearray() while len(echo) != cnt: - ret = str(self._handle.controlRead(Panda.REQUEST_OUT, 0xe0, bus, 0, cnt-len(echo))) + ret = self._handle.controlRead(Panda.REQUEST_OUT, 0xe0, bus, 0, cnt-len(echo)) if DEBUG and len(ret) > 0: - print("kline recv: "+ret.encode("hex")) + print("kline recv: " + binascii.hexlify(ret)) echo += ret return str(echo) @@ -536,8 +580,8 @@ def get_checksum(dat): for i in range(0, len(x), 0xf): ts = x[i:i+0xf] if DEBUG: - print("kline send: "+ts.encode("hex")) - self._handle.bulkWrite(2, chr(bus).encode()+ts) + print("kline send: " + binascii.hexlify(ts)) + self._handle.bulkWrite(2, bytes([bus]) + ts) echo = self.kline_ll_recv(len(ts), bus=bus) if echo != ts: print("**** ECHO ERROR %d ****" % i) @@ -549,3 +593,34 @@ def kline_recv(self, bus=2): msg = self.kline_ll_recv(2, bus=bus) msg += self.kline_ll_recv(ord(msg[1])-2, bus=bus) return msg + + def send_heartbeat(self): + self._handle.controlWrite(Panda.REQUEST_OUT, 0xf3, 0, 0, b'') + + # ******************* RTC ******************* + def set_datetime(self, dt): + self._handle.controlWrite(Panda.REQUEST_OUT, 0xa1, int(dt.year), 0, b'') + self._handle.controlWrite(Panda.REQUEST_OUT, 0xa2, int(dt.month), 0, b'') + self._handle.controlWrite(Panda.REQUEST_OUT, 0xa3, int(dt.day), 0, b'') + self._handle.controlWrite(Panda.REQUEST_OUT, 0xa4, int(dt.isoweekday()), 0, b'') + self._handle.controlWrite(Panda.REQUEST_OUT, 0xa5, int(dt.hour), 0, b'') + self._handle.controlWrite(Panda.REQUEST_OUT, 0xa6, int(dt.minute), 0, b'') + self._handle.controlWrite(Panda.REQUEST_OUT, 0xa7, int(dt.second), 0, b'') + + def get_datetime(self): + dat = self._handle.controlRead(Panda.REQUEST_IN, 0xa0, 0, 0, 8) + a = struct.unpack("HBBBBBB", dat) + return datetime.datetime(a[0], a[1], a[2], a[4], a[5], a[6]) + + # ******************* IR ******************* + def set_ir_power(self, percentage): + self._handle.controlWrite(Panda.REQUEST_OUT, 0xb0, int(percentage), 0, b'') + + # ******************* Fan ****************** + def set_fan_power(self, percentage): + self._handle.controlWrite(Panda.REQUEST_OUT, 0xb1, int(percentage), 0, b'') + + def get_fan_rpm(self): + dat = self._handle.controlRead(Panda.REQUEST_IN, 0xb2, 0, 0, 2) + a = struct.unpack("H", dat) + return a[0] \ No newline at end of file diff --git a/panda/python/dfu.py b/panda/python/dfu.py index 782b4dca429906..d9d619a822de80 100644 --- a/panda/python/dfu.py +++ b/panda/python/dfu.py @@ -1,8 +1,7 @@ -from __future__ import print_function import os import usb1 import struct -import time +import binascii # *** DFU mode *** @@ -18,7 +17,7 @@ def __init__(self, dfu_serial): for device in context.getDeviceList(skip_on_error=True): if device.getVendorID() == 0x0483 and device.getProductID() == 0xdf11: try: - this_dfu_serial = device._getASCIIStringDescriptor(3) + this_dfu_serial = device.open().getASCIIStringDescriptor(3) except Exception: continue if this_dfu_serial == dfu_serial or dfu_serial is None: @@ -35,7 +34,7 @@ def list(): for device in context.getDeviceList(skip_on_error=True): if device.getVendorID() == 0x0483 and device.getProductID() == 0xdf11: try: - dfu_serials.append(device._getASCIIStringDescriptor(3)) + dfu_serials.append(device.open().getASCIIStringDescriptor(3)) except Exception: pass except Exception: @@ -46,41 +45,40 @@ def list(): def st_serial_to_dfu_serial(st): if st == None or st == "none": return None - uid_base = struct.unpack("H"*6, st.decode("hex")) - return struct.pack("!HHH", uid_base[1] + uid_base[5], uid_base[0] + uid_base[4] + 0xA, uid_base[3]).encode("hex").upper() - + uid_base = struct.unpack("H"*6, bytes.fromhex(st)) + return binascii.hexlify(struct.pack("!HHH", uid_base[1] + uid_base[5], uid_base[0] + uid_base[4] + 0xA, uid_base[3])).upper().decode("utf-8") def status(self): while 1: - dat = str(self._handle.controlRead(0x21, DFU_GETSTATUS, 0, 0, 6)) - if dat[1] == "\x00": + dat = self._handle.controlRead(0x21, DFU_GETSTATUS, 0, 0, 6) + if dat[1] == 0: break def clear_status(self): # Clear status - stat = str(self._handle.controlRead(0x21, DFU_GETSTATUS, 0, 0, 6)) - if stat[4] == "\x0a": + stat = self._handle.controlRead(0x21, DFU_GETSTATUS, 0, 0, 6) + if stat[4] == 0xa: self._handle.controlRead(0x21, DFU_CLRSTATUS, 0, 0, 0) - elif stat[4] == "\x09": - self._handle.controlWrite(0x21, DFU_ABORT, 0, 0, "") + elif stat[4] == 0x9: + self._handle.controlWrite(0x21, DFU_ABORT, 0, 0, b"") self.status() stat = str(self._handle.controlRead(0x21, DFU_GETSTATUS, 0, 0, 6)) def erase(self, address): - self._handle.controlWrite(0x21, DFU_DNLOAD, 0, 0, "\x41" + struct.pack("I", address)) + self._handle.controlWrite(0x21, DFU_DNLOAD, 0, 0, b"\x41" + struct.pack("I", address)) self.status() def program(self, address, dat, block_size=None): if block_size == None: block_size = len(dat) - + # Set Address Pointer - self._handle.controlWrite(0x21, DFU_DNLOAD, 0, 0, "\x21" + struct.pack("I", address)) + self._handle.controlWrite(0x21, DFU_DNLOAD, 0, 0, b"\x21" + struct.pack("I", address)) self.status() # Program - dat += "\xFF"*((block_size-len(dat)) % block_size) - for i in range(0, len(dat)/block_size): + dat += b"\xFF"*((block_size-len(dat)) % block_size) + for i in range(0, len(dat)//block_size): ldat = dat[i*block_size:(i+1)*block_size] print("programming %d with length %d" % (i, len(ldat))) self._handle.controlWrite(0x21, DFU_DNLOAD, 2+i, 0, ldat) @@ -105,18 +103,17 @@ def recover(self): build_st(fn) fn = os.path.join(BASEDIR, "board", fn) - with open(fn) as f: + with open(fn, "rb") as f: code = f.read() self.program_bootstub(code) def reset(self): # **** Reset **** - self._handle.controlWrite(0x21, DFU_DNLOAD, 0, 0, "\x21" + struct.pack("I", 0x8000000)) + self._handle.controlWrite(0x21, DFU_DNLOAD, 0, 0, b"\x21" + struct.pack("I", 0x8000000)) self.status() try: - self._handle.controlWrite(0x21, DFU_DNLOAD, 2, 0, "") - stat = str(self._handle.controlRead(0x21, DFU_GETSTATUS, 0, 0, 6)) + self._handle.controlWrite(0x21, DFU_DNLOAD, 2, 0, b"") + _ = str(self._handle.controlRead(0x21, DFU_GETSTATUS, 0, 0, 6)) except Exception: pass - diff --git a/panda/python/esptool.py b/panda/python/esptool.py index 970aa3d4d83fd5..74e383eb08600c 100755 --- a/panda/python/esptool.py +++ b/panda/python/esptool.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -# NB: Before sending a PR to change the above line to '#!/usr/bin/env python2', please read https://github.com/themadinventor/esptool/issues/21 +# NB: Before sending a PR to change the above line to '#!/usr/bin/env python3', please read https://github.com/themadinventor/esptool/issues/21 # # ESP8266 ROM Bootloader Utility # https://github.com/themadinventor/esptool @@ -29,7 +29,7 @@ import sys import tempfile import time -import traceback +#import traceback import usb1 __version__ = "1.2" @@ -44,11 +44,11 @@ def __init__(self, serial=None): @property def baudrate(self): - return self._baudrate + return self.baudrate @baudrate.setter def baudrate(self, x): - print "set baud to", x + print("set baud to", x) self.panda.set_uart_baud(1, x) def write(self, buf): @@ -114,7 +114,7 @@ def __init__(self, port=None, baud=ESP_ROM_BAUD): """ Read a SLIP packet from the serial port """ def read(self): - return self._slip_reader.next() + return next(self._slip_reader) """ Write bytes to the serial port while performing SLIP escaping """ def write(self, packet): @@ -140,7 +140,7 @@ def command(self, op=None, data=None, chk=0): # same operation as the request or a retries limit has # exceeded. This is needed for some esp8266s that # reply with more sync responses than expected. - for retry in xrange(100): + for retry in range(100): p = self.read() if len(p) < 8: continue @@ -156,14 +156,14 @@ def command(self, op=None, data=None, chk=0): """ Perform a connection test """ def sync(self): self.command(ESPROM.ESP_SYNC, '\x07\x07\x12\x20' + 32 * '\x55') - for i in xrange(7): + for i in range(7): self.command() """ Try connecting repeatedly until successful, or giving up """ def connect(self): - print 'Connecting...' + print('Connecting...') - for _ in xrange(4): + for _ in range(4): # issue reset-to-bootloader: # RTS = either CH_PD or nRESET (both active low = chip in reset) # DTR = GPIO0 (active low = boot to flasher) @@ -180,7 +180,7 @@ def connect(self): # worst-case latency timer should be 255ms (probably <20ms) self._port.timeout = 0.3 - for _ in xrange(4): + for _ in range(4): try: self._port.flushInput() self._slip_reader = slip_reader(self._port) @@ -250,7 +250,7 @@ def flash_begin(self, size, offset): result = self.command(ESPROM.ESP_FLASH_BEGIN, struct.pack(' 16: raise FatalError('Invalid firmware image magic=%d segments=%d' % (magic, segments)) - for i in xrange(segments): + for i in range(segments): self.load_segment(load_file) self.checksum = self.read_checksum(load_file) @@ -480,7 +480,7 @@ def __init__(self, load_file=None): raise FatalError('Invalid V2 image magic=%d' % (magic)) if segments != 4: # segment count is not really segment count here, but we expect to see '4' - print 'Warning: V2 header has unexpected "segment" count %d (usually 4)' % segments + print('Warning: V2 header has unexpected "segment" count %d (usually 4)' % segments) # irom segment comes before the second header self.load_segment(load_file, True) @@ -501,7 +501,7 @@ def __init__(self, load_file=None): raise FatalError('Invalid V2 second header magic=%d segments=%d' % (magic, segments)) # load all the usual segments - for _ in xrange(segments): + for _ in range(segments): self.load_segment(load_file) self.checksum = self.read_checksum(load_file) @@ -543,13 +543,13 @@ def _fetch_symbols(self): tool_nm = "xt-nm" proc = subprocess.Popen([tool_nm, self.name], stdout=subprocess.PIPE) except OSError: - print "Error calling %s, do you have Xtensa toolchain in PATH?" % tool_nm + print("Error calling %s, do you have Xtensa toolchain in PATH?" % tool_nm) sys.exit(1) for l in proc.stdout: fields = l.strip().split() try: if fields[0] == "U": - print "Warning: ELF binary has undefined symbol %s" % fields[1] + print("Warning: ELF binary has undefined symbol %s" % fields[1]) continue if fields[0] == "w": continue # can skip weak symbols @@ -568,7 +568,7 @@ def get_entry_point(self): try: proc = subprocess.Popen([tool_readelf, "-h", self.name], stdout=subprocess.PIPE) except OSError: - print "Error calling %s, do you have Xtensa toolchain in PATH?" % tool_readelf + print("Error calling %s, do you have Xtensa toolchain in PATH?" % tool_readelf) sys.exit(1) for l in proc.stdout: fields = l.strip().split() @@ -599,7 +599,7 @@ class CesantaFlasher(object): CMD_BOOT_FW = 6 def __init__(self, esp, baud_rate=0): - print 'Running Cesanta flasher stub...' + print('Running Cesanta flasher stub...') if baud_rate <= ESPROM.ESP_ROM_BAUD: # don't change baud rates if we already synced at that rate baud_rate = 0 self._esp = esp @@ -640,7 +640,7 @@ def flash_write(self, addr, data, show_progress=False): raise FatalError('Expected digest, got: %s' % hexify(p)) digest = hexify(p).upper() expected_digest = hashlib.md5(data).hexdigest().upper() - print + print() if digest != expected_digest: raise FatalError('Digest mismatch: expected %s, got %s' % (expected_digest, digest)) p = self._esp.read() @@ -679,7 +679,7 @@ def flash_read(self, addr, length, show_progress=False): raise FatalError('Expected digest, got: %s' % hexify(p)) expected_digest = hexify(p).upper() digest = hashlib.md5(data).hexdigest().upper() - print + print() if digest != expected_digest: raise FatalError('Digest mismatch: expected %s, got %s' % (expected_digest, digest)) p = self._esp.read() @@ -791,7 +791,7 @@ def binutils_safe_path(p): try: return subprocess.check_output(["cygpath", "-w", p]).rstrip('\n') except subprocess.CalledProcessError: - print "WARNING: Failed to call cygpath to sanitise Cygwin path." + print("WARNING: Failed to call cygpath to sanitise Cygwin path.") return p @@ -837,9 +837,9 @@ def WithResult(message, result): def load_ram(esp, args): image = LoadFirmwareImage(args.filename) - print 'RAM boot...' + print('RAM boot...') for (offset, size, data) in image.segments: - print 'Downloading %d bytes at %08x...' % (size, offset), + print('Downloading %d bytes at %08x...' % (size, offset), end=' ') sys.stdout.flush() esp.mem_begin(size, div_roundup(size, esp.ESP_RAM_BLOCK), esp.ESP_RAM_BLOCK, offset) @@ -848,31 +848,31 @@ def load_ram(esp, args): esp.mem_block(data[0:esp.ESP_RAM_BLOCK], seq) data = data[esp.ESP_RAM_BLOCK:] seq += 1 - print 'done!' + print('done!') - print 'All segments done, executing at %08x' % image.entrypoint + print('All segments done, executing at %08x' % image.entrypoint) esp.mem_finish(image.entrypoint) def read_mem(esp, args): - print '0x%08x = 0x%08x' % (args.address, esp.read_reg(args.address)) + print('0x%08x = 0x%08x' % (args.address, esp.read_reg(args.address))) def write_mem(esp, args): esp.write_reg(args.address, args.value, args.mask, 0) - print 'Wrote %08x, mask %08x to %08x' % (args.value, args.mask, args.address) + print('Wrote %08x, mask %08x to %08x' % (args.value, args.mask, args.address)) def dump_mem(esp, args): - f = file(args.filename, 'wb') - for i in xrange(args.size / 4): + f = open(args.filename, 'wb') + for i in range(args.size / 4): d = esp.read_reg(args.address + (i * 4)) f.write(struct.pack('> 16 args.flash_size = {18: '2m', 19: '4m', 20: '8m', 21: '16m', 22: '32m'}.get(size_id) if args.flash_size is None: - print 'Warning: Could not auto-detect Flash size (FlashID=0x%x, SizeID=0x%x), defaulting to 4m' % (flash_id, size_id) + print('Warning: Could not auto-detect Flash size (FlashID=0x%x, SizeID=0x%x), defaulting to 4m' % (flash_id, size_id)) args.flash_size = '4m' else: - print 'Auto-detected Flash size:', args.flash_size + print('Auto-detected Flash size:', args.flash_size) def write_flash(esp, args): @@ -900,10 +900,10 @@ def write_flash(esp, args): image = argfile.read() argfile.seek(0) # rewind in case we need it again if address + len(image) > int(args.flash_size.split('m')[0]) * (1 << 17): - print 'WARNING: Unlikely to work as data goes beyond end of flash. Hint: Use --flash_size' + print('WARNING: Unlikely to work as data goes beyond end of flash. Hint: Use --flash_size') # Fix sflash config data. if address == 0 and image[0] == '\xe9': - print 'Flash params set to 0x%02x%02x' % (flash_mode, flash_size_freq) + print('Flash params set to 0x%02x%02x' % (flash_mode, flash_size_freq)) image = image[0:2] + flash_params + image[4:] # Pad to sector size, which is the minimum unit of writing (erasing really). if len(image) % esp.ESP_FLASH_SECTOR != 0: @@ -911,11 +911,11 @@ def write_flash(esp, args): t = time.time() flasher.flash_write(address, image, not args.no_progress) t = time.time() - t - print ('\rWrote %d bytes at 0x%x in %.1f seconds (%.1f kbit/s)...' + print('\rWrote %d bytes at 0x%x in %.1f seconds (%.1f kbit/s)...' % (len(image), address, t, len(image) / t * 8 / 1000)) - print 'Leaving...' + print('Leaving...') if args.verify: - print 'Verifying just-written flash...' + print('Verifying just-written flash...') _verify_flash(flasher, args, flash_params) flasher.boot_fw() @@ -923,18 +923,18 @@ def write_flash(esp, args): def image_info(args): image = LoadFirmwareImage(args.filename) print('Image version: %d' % image.version) - print('Entry point: %08x' % image.entrypoint) if image.entrypoint != 0 else 'Entry point not set' - print '%d segments' % len(image.segments) - print + print(('Entry point: %08x' % image.entrypoint) if image.entrypoint != 0 else 'Entry point not set') + print('%d segments' % len(image.segments)) + print() checksum = ESPROM.ESP_CHECKSUM_MAGIC for (idx, (offset, size, data)) in enumerate(image.segments): if image.version == 2 and idx == 0: - print 'Segment 1: %d bytes IROM0 (no load address)' % size + print('Segment 1: %d bytes IROM0 (no load address)' % size) else: - print 'Segment %d: %5d bytes at %08x' % (idx + 1, size, offset) + print('Segment %d: %5d bytes at %08x' % (idx + 1, size, offset)) checksum = ESPROM.checksum(data, checksum) - print - print 'Checksum: %02x (%s)' % (image.checksum, 'valid' if image.checksum == checksum else 'invalid!') + print() + print('Checksum: %02x (%s)' % (image.checksum, 'valid' if image.checksum == checksum else 'invalid!')) def make_image(args): @@ -944,7 +944,7 @@ def make_image(args): if len(args.segfile) != len(args.segaddr): raise FatalError('Number of specified files does not match number of specified addresses') for (seg, addr) in zip(args.segfile, args.segaddr): - data = file(seg, 'rb').read() + data = open(seg, 'rb').read() image.add_segment(addr, data) image.entrypoint = args.entrypoint image.save(args.output) @@ -979,7 +979,7 @@ def elf2image(args): if irom_offs < 0: raise FatalError('Address of symbol _irom0_text_start in ELF is located before flash mapping address. Bad linker script?') if (irom_offs & 0xFFF) != 0: # irom0 isn't flash sector aligned - print "WARNING: irom0 section offset is 0x%08x. ELF is probably linked for 'elf2image --version=2'" % irom_offs + print("WARNING: irom0 section offset is 0x%08x. ELF is probably linked for 'elf2image --version=2'" % irom_offs) with open(args.output + "0x%05x.bin" % irom_offs, "wb") as f: f.write(data) f.close() @@ -991,21 +991,21 @@ def elf2image(args): def read_mac(esp, args): mac = esp.read_mac() - print 'MAC: %s' % ':'.join(map(lambda x: '%02x' % x, mac)) + print('MAC: %s' % ':'.join(['%02x' % x for x in mac])) def chip_id(esp, args): chipid = esp.chip_id() - print 'Chip ID: 0x%08x' % chipid + print('Chip ID: 0x%08x' % chipid) def erase_flash(esp, args): flasher = CesantaFlasher(esp, args.baud) - print 'Erasing flash (this may take a while)...' + print('Erasing flash (this may take a while)...') t = time.time() flasher.flash_erase_chip() t = time.time() - t - print 'Erase took %.1f seconds' % t + print('Erase took %.1f seconds' % t) def run(esp, args): @@ -1015,8 +1015,8 @@ def run(esp, args): def flash_id(esp, args): flash_id = esp.flash_id() esp.flash_finish(False) - print 'Manufacturer: %02x' % (flash_id & 0xff) - print 'Device: %02x%02x' % ((flash_id >> 8) & 0xff, (flash_id >> 16) & 0xff) + print('Manufacturer: %02x' % (flash_id & 0xff)) + print('Device: %02x%02x' % ((flash_id >> 8) & 0xff, (flash_id >> 16) & 0xff)) def read_flash(esp, args): @@ -1024,9 +1024,9 @@ def read_flash(esp, args): t = time.time() data = flasher.flash_read(args.address, args.size, not args.no_progress) t = time.time() - t - print ('\rRead %d bytes at 0x%x in %.1f seconds (%.1f kbit/s)...' + print('\rRead %d bytes at 0x%x in %.1f seconds (%.1f kbit/s)...' % (len(data), args.address, t, len(data) / t * 8 / 1000)) - file(args.filename, 'wb').write(data) + open(args.filename, 'wb').write(data) def _verify_flash(flasher, args, flash_params=None): @@ -1037,26 +1037,26 @@ def _verify_flash(flasher, args, flash_params=None): if address == 0 and image[0] == '\xe9' and flash_params is not None: image = image[0:2] + flash_params + image[4:] image_size = len(image) - print 'Verifying 0x%x (%d) bytes @ 0x%08x in flash against %s...' % (image_size, image_size, address, argfile.name) + print('Verifying 0x%x (%d) bytes @ 0x%08x in flash against %s...' % (image_size, image_size, address, argfile.name)) # Try digest first, only read if there are differences. digest, _ = flasher.flash_digest(address, image_size) digest = hexify(digest).upper() expected_digest = hashlib.md5(image).hexdigest().upper() if digest == expected_digest: - print '-- verify OK (digest matched)' + print('-- verify OK (digest matched)') continue else: differences = True if getattr(args, 'diff', 'no') != 'yes': - print '-- verify FAILED (digest mismatch)' + print('-- verify FAILED (digest mismatch)') continue flash = flasher.flash_read(address, image_size) assert flash != image - diff = [i for i in xrange(image_size) if flash[i] != image[i]] - print '-- verify FAILED: %d differences, first @ 0x%08x' % (len(diff), address + diff[0]) + diff = [i for i in range(image_size) if flash[i] != image[i]] + print('-- verify FAILED: %d differences, first @ 0x%08x' % (len(diff), address + diff[0])) for d in diff: - print ' %08x %02x %02x' % (address + d, ord(flash[d]), ord(image[d])) + print(' %08x %02x %02x' % (address + d, ord(flash[d]), ord(image[d]))) if differences: raise FatalError("Verify failed.") @@ -1067,7 +1067,7 @@ def verify_flash(esp, args, flash_params=None): def version(args): - print __version__ + print(__version__) # # End of operations functions @@ -1203,12 +1203,12 @@ def add_spi_flash_subparsers(parent, auto_detect=False): 'version', help='Print esptool version') # internal sanity check - every operation matches a module function of the same name - for operation in subparsers.choices.keys(): + for operation in list(subparsers.choices.keys()): assert operation in globals(), "%s should be a module function" % operation args = parser.parse_args() - print 'esptool.py v%s' % __version__ + print('esptool.py v%s' % __version__) # operation function can take 1 arg (args), 2 args (esp, arg) # or be a member function of the ESPROM class. @@ -1235,7 +1235,7 @@ def __call__(self, parser, namespace, values, option_string=None): for i in range(0,len(values),2): try: address = int(values[i],0) - except ValueError as e: + except ValueError: raise argparse.ArgumentError(self,'Address "%s" must be a number' % values[i]) try: argfile = open(values[i + 1], 'rb') @@ -1310,5 +1310,5 @@ def __call__(self, parser, namespace, values, option_string=None): try: main() except FatalError as e: - print '\nA fatal error occurred: %s' % e + print('\nA fatal error occurred: %s' % e) sys.exit(2) diff --git a/panda/python/flash_release.py b/panda/python/flash_release.py index 51f6a72e7a6c07..b50c9b36b3af78 100755 --- a/panda/python/flash_release.py +++ b/panda/python/flash_release.py @@ -1,10 +1,10 @@ -#!/usr/bin/env python -from __future__ import print_function +#!/usr/bin/env python3 + import sys import time import requests import json -import StringIO +import io def flash_release(path=None, st_serial=None): from panda import Panda, PandaDFU, ESPROM, CesantaFlasher @@ -29,7 +29,7 @@ def status(x): url = json.loads(r.text)['url'] r = requests.get(url) print("Fetching firmware from %s" % url) - path = StringIO.StringIO(r.content) + path = io.StringIO(r.content) zf = ZipFile(path) zf.printdir() @@ -89,7 +89,7 @@ def status(x): # done! status("6. Success!") - + if __name__ == "__main__": flash_release(*sys.argv[1:]) diff --git a/panda/python/isotp.py b/panda/python/isotp.py index d68aa4d70e0bbe..69cddc4ec220c1 100644 --- a/panda/python/isotp.py +++ b/panda/python/isotp.py @@ -1,13 +1,15 @@ +import binascii + DEBUG = False def msg(x): if DEBUG: - print "S:",x.encode("hex") + print("S:", binascii.hexlify(x)) if len(x) <= 7: - ret = chr(len(x)) + x + ret = bytes([len(x)]) + x else: assert False - return ret.ljust(8, "\x00") + return ret.ljust(8, b"\x00") kmsgs = [] def recv(panda, cnt, addr, nbus): @@ -24,35 +26,35 @@ def recv(panda, cnt, addr, nbus): # leave around nmsgs.append((ids, ts, dat, bus)) kmsgs = nmsgs[-256:] - return map(str, ret) + return ret def isotp_recv_subaddr(panda, addr, bus, sendaddr, subaddr): msg = recv(panda, 1, addr, bus)[0] - # TODO: handle other subaddr also communicating - assert ord(msg[0]) == subaddr + # TODO: handle other subaddr also communicating + assert msg[0] == subaddr - if ord(msg[1])&0xf0 == 0x10: + if msg[1]&0xf0 == 0x10: # first - tlen = ((ord(msg[1]) & 0xf) << 8) | ord(msg[2]) + tlen = ((msg[1] & 0xf) << 8) | msg[2] dat = msg[3:] # 0 block size? - CONTINUE = chr(subaddr) + "\x30" + "\x00"*6 + CONTINUE = bytes([subaddr]) + b"\x30" + b"\x00"*6 panda.can_send(sendaddr, CONTINUE, bus) idx = 1 - for mm in recv(panda, (tlen-len(dat) + 5)/6, addr, bus): - assert ord(mm[0]) == subaddr - assert ord(mm[1]) == (0x20 | (idx&0xF)) + for mm in recv(panda, (tlen-len(dat) + 5)//6, addr, bus): + assert mm[0] == subaddr + assert mm[1] == (0x20 | (idx&0xF)) dat += mm[2:] idx += 1 - elif ord(msg[1])&0xf0 == 0x00: + elif msg[1]&0xf0 == 0x00: # single - tlen = ord(msg[1]) & 0xf + tlen = msg[1] & 0xf dat = msg[2:] else: - print msg.encode("hex") + print(binascii.hexlify(msg)) assert False return dat[0:tlen] @@ -66,29 +68,29 @@ def isotp_send(panda, x, addr, bus=0, recvaddr=None, subaddr=None): if len(x) <= 7 and subaddr is None: panda.can_send(addr, msg(x), bus) elif len(x) <= 6 and subaddr is not None: - panda.can_send(addr, chr(subaddr)+msg(x)[0:7], bus) + panda.can_send(addr, bytes([subaddr]) + msg(x)[0:7], bus) else: if subaddr: - ss = chr(subaddr) + chr(0x10 + (len(x)>>8)) + chr(len(x)&0xFF) + x[0:5] + ss = bytes([subaddr, 0x10 + (len(x) >> 8), len(x) & 0xFF]) + x[0:5] x = x[5:] else: - ss = chr(0x10 + (len(x)>>8)) + chr(len(x)&0xFF) + x[0:6] + ss = bytes([0x10 + (len(x) >> 8), len(x) & 0xFF]) + x[0:6] x = x[6:] idx = 1 sends = [] while len(x) > 0: if subaddr: - sends.append(((chr(subaddr) + chr(0x20 + (idx&0xF)) + x[0:6]).ljust(8, "\x00"))) + sends.append(((bytes([subaddr, 0x20 + (idx & 0xF)]) + x[0:6]).ljust(8, b"\x00"))) x = x[6:] else: - sends.append(((chr(0x20 + (idx&0xF)) + x[0:7]).ljust(8, "\x00"))) + sends.append(((bytes([0x20 + (idx & 0xF)]) + x[0:7]).ljust(8, b"\x00"))) x = x[7:] idx += 1 # actually send panda.can_send(addr, ss, bus) rr = recv(panda, 1, recvaddr, bus)[0] - if rr.find("\x30\x01") != -1: + if rr.find(b"\x30\x01") != -1: for s in sends[:-1]: panda.can_send(addr, s, 0) rr = recv(panda, 1, recvaddr, bus)[0] @@ -105,31 +107,31 @@ def isotp_recv(panda, addr, bus=0, sendaddr=None, subaddr=None): else: msg = recv(panda, 1, addr, bus)[0] - if ord(msg[0])&0xf0 == 0x10: + if msg[0] & 0xf0 == 0x10: # first - tlen = ((ord(msg[0]) & 0xf) << 8) | ord(msg[1]) + tlen = ((msg[0] & 0xf) << 8) | msg[1] dat = msg[2:] # 0 block size? - CONTINUE = "\x30" + "\x00"*7 + CONTINUE = b"\x30" + b"\x00"*7 panda.can_send(sendaddr, CONTINUE, bus) idx = 1 - for mm in recv(panda, (tlen-len(dat) + 6)/7, addr, bus): - assert ord(mm[0]) == (0x20 | (idx&0xF)) + for mm in recv(panda, (tlen-len(dat) + 6)//7, addr, bus): + assert mm[0] == (0x20 | (idx&0xF)) dat += mm[1:] idx += 1 - elif ord(msg[0])&0xf0 == 0x00: + elif msg[0] & 0xf0 == 0x00: # single - tlen = ord(msg[0]) & 0xf + tlen = msg[0] & 0xf dat = msg[1:] else: assert False dat = dat[0:tlen] if DEBUG: - print "R:",dat.encode("hex") + print("R:", binascii.hexlify(dat)) return dat diff --git a/panda/python/serial.py b/panda/python/serial.py index 1bcfebb32eabd0..4d900cf29f6610 100644 --- a/panda/python/serial.py +++ b/panda/python/serial.py @@ -5,7 +5,7 @@ def __init__(self, panda, port, baud): self.port = port self.panda.set_uart_parity(self.port, 0) self.panda.set_uart_baud(self.port, baud) - self.buf = "" + self.buf = b"" def read(self, l=1): tt = self.panda.serial_read(self.port) diff --git a/panda/python/uds.py b/panda/python/uds.py new file mode 100644 index 00000000000000..5f5ae53bfbac01 --- /dev/null +++ b/panda/python/uds.py @@ -0,0 +1,770 @@ +#!/usr/bin/env python3 +import time +import struct +from typing import NamedTuple, List +from enum import IntEnum +from queue import Queue, Empty +from threading import Thread +from binascii import hexlify + +class SERVICE_TYPE(IntEnum): + DIAGNOSTIC_SESSION_CONTROL = 0x10 + ECU_RESET = 0x11 + SECURITY_ACCESS = 0x27 + COMMUNICATION_CONTROL = 0x28 + TESTER_PRESENT = 0x3E + ACCESS_TIMING_PARAMETER = 0x83 + SECURED_DATA_TRANSMISSION = 0x84 + CONTROL_DTC_SETTING = 0x85 + RESPONSE_ON_EVENT = 0x86 + LINK_CONTROL = 0x87 + READ_DATA_BY_IDENTIFIER = 0x22 + READ_MEMORY_BY_ADDRESS = 0x23 + READ_SCALING_DATA_BY_IDENTIFIER = 0x24 + READ_DATA_BY_PERIODIC_IDENTIFIER = 0x2A + DYNAMICALLY_DEFINE_DATA_IDENTIFIER = 0x2C + WRITE_DATA_BY_IDENTIFIER = 0x2E + WRITE_MEMORY_BY_ADDRESS = 0x3D + CLEAR_DIAGNOSTIC_INFORMATION = 0x14 + READ_DTC_INFORMATION = 0x19 + INPUT_OUTPUT_CONTROL_BY_IDENTIFIER = 0x2F + ROUTINE_CONTROL = 0x31 + REQUEST_DOWNLOAD = 0x34 + REQUEST_UPLOAD = 0x35 + TRANSFER_DATA = 0x36 + REQUEST_TRANSFER_EXIT = 0x37 + +class SESSION_TYPE(IntEnum): + DEFAULT = 1 + PROGRAMMING = 2 + EXTENDED_DIAGNOSTIC = 3 + SAFETY_SYSTEM_DIAGNOSTIC = 4 + +class RESET_TYPE(IntEnum): + HARD = 1 + KEY_OFF_ON = 2 + SOFT = 3 + ENABLE_RAPID_POWER_SHUTDOWN = 4 + DISABLE_RAPID_POWER_SHUTDOWN = 5 + +class ACCESS_TYPE(IntEnum): + REQUEST_SEED = 1 + SEND_KEY = 2 + +class CONTROL_TYPE(IntEnum): + ENABLE_RX_ENABLE_TX = 0 + ENABLE_RX_DISABLE_TX = 1 + DISABLE_RX_ENABLE_TX = 2 + DISABLE_RX_DISABLE_TX = 3 + +class MESSAGE_TYPE(IntEnum): + NORMAL = 1 + NETWORK_MANAGEMENT = 2 + NORMAL_AND_NETWORK_MANAGEMENT = 3 + +class TIMING_PARAMETER_TYPE(IntEnum): + READ_EXTENDED_SET = 1 + SET_TO_DEFAULT_VALUES = 2 + READ_CURRENTLY_ACTIVE = 3 + SET_TO_GIVEN_VALUES = 4 + +class DTC_SETTING_TYPE(IntEnum): + ON = 1 + OFF = 2 + +class RESPONSE_EVENT_TYPE(IntEnum): + STOP_RESPONSE_ON_EVENT = 0 + ON_DTC_STATUS_CHANGE = 1 + ON_TIMER_INTERRUPT = 2 + ON_CHANGE_OF_DATA_IDENTIFIER = 3 + REPORT_ACTIVATED_EVENTS = 4 + START_RESPONSE_ON_EVENT = 5 + CLEAR_RESPONSE_ON_EVENT = 6 + ON_COMPARISON_OF_VALUES = 7 + +class LINK_CONTROL_TYPE(IntEnum): + VERIFY_BAUDRATE_TRANSITION_WITH_FIXED_BAUDRATE = 1 + VERIFY_BAUDRATE_TRANSITION_WITH_SPECIFIC_BAUDRATE = 2 + TRANSITION_BAUDRATE = 3 + +class BAUD_RATE_TYPE(IntEnum): + PC9600 = 1 + PC19200 = 2 + PC38400 = 3 + PC57600 = 4 + PC115200 = 5 + CAN125000 = 16 + CAN250000 = 17 + CAN500000 = 18 + CAN1000000 = 19 + +class DATA_IDENTIFIER_TYPE(IntEnum): + BOOT_SOFTWARE_IDENTIFICATION = 0xF180 + APPLICATION_SOFTWARE_IDENTIFICATION = 0xF181 + APPLICATION_DATA_IDENTIFICATION = 0xF182 + BOOT_SOFTWARE_FINGERPRINT = 0xF183 + APPLICATION_SOFTWARE_FINGERPRINT = 0xF184 + APPLICATION_DATA_FINGERPRINT = 0xF185 + ACTIVE_DIAGNOSTIC_SESSION = 0xF186 + VEHICLE_MANUFACTURER_SPARE_PART_NUMBER = 0xF187 + VEHICLE_MANUFACTURER_ECU_SOFTWARE_NUMBER = 0xF188 + VEHICLE_MANUFACTURER_ECU_SOFTWARE_VERSION_NUMBER = 0xF189 + SYSTEM_SUPPLIER_IDENTIFIER = 0xF18A + ECU_MANUFACTURING_DATE = 0xF18B + ECU_SERIAL_NUMBER = 0xF18C + SUPPORTED_FUNCTIONAL_UNITS = 0xF18D + VEHICLE_MANUFACTURER_KIT_ASSEMBLY_PART_NUMBER = 0xF18E + VIN = 0xF190 + VEHICLE_MANUFACTURER_ECU_HARDWARE_NUMBER = 0xF191 + SYSTEM_SUPPLIER_ECU_HARDWARE_NUMBER = 0xF192 + SYSTEM_SUPPLIER_ECU_HARDWARE_VERSION_NUMBER = 0xF193 + SYSTEM_SUPPLIER_ECU_SOFTWARE_NUMBER = 0xF194 + SYSTEM_SUPPLIER_ECU_SOFTWARE_VERSION_NUMBER = 0xF195 + EXHAUST_REGULATION_OR_TYPE_APPROVAL_NUMBER = 0xF196 + SYSTEM_NAME_OR_ENGINE_TYPE = 0xF197 + REPAIR_SHOP_CODE_OR_TESTER_SERIAL_NUMBER = 0xF198 + PROGRAMMING_DATE = 0xF199 + CALIBRATION_REPAIR_SHOP_CODE_OR_CALIBRATION_EQUIPMENT_SERIAL_NUMBER = 0xF19A + CALIBRATION_DATE = 0xF19B + CALIBRATION_EQUIPMENT_SOFTWARE_NUMBER = 0xF19C + ECU_INSTALLATION_DATE = 0xF19D + ODX_FILE = 0xF19E + ENTITY = 0xF19F + +class TRANSMISSION_MODE_TYPE(IntEnum): + SEND_AT_SLOW_RATE = 1 + SEND_AT_MEDIUM_RATE = 2 + SEND_AT_FAST_RATE = 3 + STOP_SENDING = 4 + +class DYNAMIC_DEFINITION_TYPE(IntEnum): + DEFINE_BY_IDENTIFIER = 1 + DEFINE_BY_MEMORY_ADDRESS = 2 + CLEAR_DYNAMICALLY_DEFINED_DATA_IDENTIFIER = 3 + +class DynamicSourceDefinition(NamedTuple): + data_identifier: int + position: int + memory_size: int + memory_address: int + +class DTC_GROUP_TYPE(IntEnum): + EMISSIONS = 0x000000 + ALL = 0xFFFFFF + +class DTC_REPORT_TYPE(IntEnum): + NUMBER_OF_DTC_BY_STATUS_MASK = 0x01 + DTC_BY_STATUS_MASK = 0x02 + DTC_SNAPSHOT_IDENTIFICATION = 0x03 + DTC_SNAPSHOT_RECORD_BY_DTC_NUMBER = 0x04 + DTC_SNAPSHOT_RECORD_BY_RECORD_NUMBER = 0x05 + DTC_EXTENDED_DATA_RECORD_BY_DTC_NUMBER = 0x06 + NUMBER_OF_DTC_BY_SEVERITY_MASK_RECORD = 0x07 + DTC_BY_SEVERITY_MASK_RECORD = 0x08 + SEVERITY_INFORMATION_OF_DTC = 0x09 + SUPPORTED_DTC = 0x0A + FIRST_TEST_FAILED_DTC = 0x0B + FIRST_CONFIRMED_DTC = 0x0C + MOST_RECENT_TEST_FAILED_DTC = 0x0D + MOST_RECENT_CONFIRMED_DTC = 0x0E + MIRROR_MEMORY_DTC_BY_STATUS_MASK = 0x0F + MIRROR_MEMORY_DTC_EXTENDED_DATA_RECORD_BY_DTC_NUMBER = 0x10 + NUMBER_OF_MIRROR_MEMORY_DTC_BY_STATUS_MASK = 0x11 + NUMBER_OF_EMISSIONS_RELATED_OBD_DTC_BY_STATUS_MASK = 0x12 + EMISSIONS_RELATED_OBD_DTC_BY_STATUS_MASK = 0x13 + DTC_FAULT_DETECTION_COUNTER = 0x14 + DTC_WITH_PERMANENT_STATUS = 0x15 + +class DTC_STATUS_MASK_TYPE(IntEnum): + TEST_FAILED = 0x01 + TEST_FAILED_THIS_OPERATION_CYCLE = 0x02 + PENDING_DTC = 0x04 + CONFIRMED_DTC = 0x08 + TEST_NOT_COMPLETED_SINCE_LAST_CLEAR = 0x10 + TEST_FAILED_SINCE_LAST_CLEAR = 0x20 + TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE = 0x40 + WARNING_INDICATOR_REQUESTED = 0x80 + ALL = 0xFF + +class DTC_SEVERITY_MASK_TYPE(IntEnum): + MAINTENANCE_ONLY = 0x20 + CHECK_AT_NEXT_HALT = 0x40 + CHECK_IMMEDIATELY = 0x80 + ALL = 0xE0 + +class CONTROL_PARAMETER_TYPE(IntEnum): + RETURN_CONTROL_TO_ECU = 0 + RESET_TO_DEFAULT = 1 + FREEZE_CURRENT_STATE = 2 + SHORT_TERM_ADJUSTMENT = 3 + +class ROUTINE_CONTROL_TYPE(IntEnum): + START = 1 + STOP = 2 + REQUEST_RESULTS = 3 + +class ROUTINE_IDENTIFIER_TYPE(IntEnum): + ERASE_MEMORY = 0xFF00 + CHECK_PROGRAMMING_DEPENDENCIES = 0xFF01 + ERASE_MIRROR_MEMORY_DTCS = 0xFF02 + +class MessageTimeoutError(Exception): + pass + +class NegativeResponseError(Exception): + def __init__(self, message, service_id, error_code): + self.message = message + self.service_id = service_id + self.error_code = error_code + + def __str__(self): + return self.message + +class InvalidServiceIdError(Exception): + pass + +class InvalidSubFunctioneError(Exception): + pass + +_negative_response_codes = { + 0x00: 'positive response', + 0x10: 'general reject', + 0x11: 'service not supported', + 0x12: 'sub-function not supported', + 0x13: 'incorrect message length or invalid format', + 0x14: 'response too long', + 0x21: 'busy repeat request', + 0x22: 'conditions not correct', + 0x24: 'request sequence error', + 0x25: 'no response from subnet component', + 0x26: 'failure prevents execution of requested action', + 0x31: 'request out of range', + 0x33: 'security access denied', + 0x35: 'invalid key', + 0x36: 'exceed numebr of attempts', + 0x37: 'required time delay not expired', + 0x70: 'upload download not accepted', + 0x71: 'transfer data suspended', + 0x72: 'general programming failure', + 0x73: 'wrong block sequence counter', + 0x78: 'request correctly received - response pending', + 0x7e: 'sub-function not supported in active session', + 0x7f: 'service not supported in active session', + 0x81: 'rpm too high', + 0x82: 'rpm too low', + 0x83: 'engine is running', + 0x84: 'engine is not running', + 0x85: 'engine run time too low', + 0x86: 'temperature too high', + 0x87: 'temperature too low', + 0x88: 'vehicle speed too high', + 0x89: 'vehicle speed too low', + 0x8a: 'throttle/pedal too high', + 0x8b: 'throttle/pedal too low', + 0x8c: 'transmission not in neutral', + 0x8d: 'transmission not in gear', + 0x8f: 'brake switch(es) not closed', + 0x90: 'shifter lever not in park', + 0x91: 'torque converter clutch locked', + 0x92: 'voltage too high', + 0x93: 'voltage too low', +} + +class IsoTpMessage(): + def __init__(self, can_tx_queue: Queue, can_rx_queue: Queue, timeout: float, debug: bool=False): + self.can_tx_queue = can_tx_queue + self.can_rx_queue = can_rx_queue + self.timeout = timeout + self.debug = debug + + def send(self, dat: bytes) -> None: + self.tx_dat = dat + self.tx_len = len(dat) + self.tx_idx = 0 + self.tx_done = False + + if self.debug: print(f"ISO-TP: REQUEST - {hexlify(self.tx_dat)}") + self._tx_first_frame() + + def _tx_first_frame(self) -> None: + if self.tx_len < 8: + # single frame (send all bytes) + if self.debug: print("ISO-TP: TX - single frame") + msg = (bytes([self.tx_len]) + self.tx_dat).ljust(8, b"\x00") + self.tx_done = True + else: + # first frame (send first 6 bytes) + if self.debug: print("ISO-TP: TX - first frame") + msg = (struct.pack("!H", 0x1000 | self.tx_len) + self.tx_dat[:6]).ljust(8, b"\x00") + self.can_tx_queue.put(msg) + + def recv(self) -> bytes: + self.rx_dat = b"" + self.rx_len = 0 + self.rx_idx = 0 + self.rx_done = False + + try: + while True: + self._isotp_rx_next() + if self.tx_done and self.rx_done: + return self.rx_dat + except Empty: + raise MessageTimeoutError("timeout waiting for response") + finally: + if self.debug: print(f"ISO-TP: RESPONSE - {hexlify(self.rx_dat)}") + + def _isotp_rx_next(self) -> None: + rx_data = self.can_rx_queue.get(block=True, timeout=self.timeout) + + # single rx_frame + if rx_data[0] >> 4 == 0x0: + self.rx_len = rx_data[0] & 0xFF + self.rx_dat = rx_data[1:1+self.rx_len] + self.rx_idx = 0 + self.rx_done = True + if self.debug: print(f"ISO-TP: RX - single frame - idx={self.rx_idx} done={self.rx_done}") + return + + # first rx_frame + if rx_data[0] >> 4 == 0x1: + self.rx_len = ((rx_data[0] & 0x0F) << 8) + rx_data[1] + self.rx_dat = rx_data[2:] + self.rx_idx = 0 + self.rx_done = False + if self.debug: print(f"ISO-TP: RX - first frame - idx={self.rx_idx} done={self.rx_done}") + if self.debug: print(f"ISO-TP: TX - flow control continue") + # send flow control message (send all bytes) + msg = b"\x30\x00\x00".ljust(8, b"\x00") + self.can_tx_queue.put(msg) + return + + # consecutive rx frame + if rx_data[0] >> 4 == 0x2: + assert self.rx_done == False, "isotp - rx: consecutive frame with no active frame" + self.rx_idx += 1 + assert self.rx_idx & 0xF == rx_data[0] & 0xF, "isotp - rx: invalid consecutive frame index" + rx_size = self.rx_len - len(self.rx_dat) + self.rx_dat += rx_data[1:1+min(rx_size, 7)] + if self.rx_len == len(self.rx_dat): + self.rx_done = True + if self.debug: print(f"ISO-TP: RX - consecutive frame - idx={self.rx_idx} done={self.rx_done}") + return + + # flow control + if rx_data[0] >> 4 == 0x3: + assert self.tx_done == False, "isotp - rx: flow control with no active frame" + assert rx_data[0] != 0x32, "isotp - rx: flow-control overflow/abort" + assert rx_data[0] == 0x30 or rx_data[0] == 0x31, "isotp - rx: flow-control transfer state indicator invalid" + if rx_data[0] == 0x30: + if self.debug: print("ISO-TP: RX - flow control continue") + delay_ts = rx_data[2] & 0x7F + # scale is 1 milliseconds if first bit == 0, 100 micro seconds if first bit == 1 + delay_div = 1000. if rx_data[2] & 0x80 == 0 else 10000. + # first frame = 6 bytes, each consecutive frame = 7 bytes + start = 6 + self.tx_idx * 7 + count = rx_data[1] + end = start + count * 7 if count > 0 else self.tx_len + for i in range(start, end, 7): + if delay_ts > 0 and i > start: + delay_s = delay_ts / delay_div + if self.debug: print(f"ISO-TP: TX - delay - seconds={delay_s}") + time.sleep(delay_s) + self.tx_idx += 1 + # consecutive tx frames + msg = (bytes([0x20 | (self.tx_idx & 0xF)]) + self.tx_dat[i:i+7]).ljust(8, b"\x00") + self.can_tx_queue.put(msg) + if end >= self.tx_len: + self.tx_done = True + if self.debug: print(f"ISO-TP: TX - consecutive frame - idx={self.tx_idx} done={self.tx_done}") + elif rx_data[0] == 0x31: + # wait (do nothing until next flow control message) + if self.debug: print("ISO-TP: TX - flow control wait") + +class UdsClient(): + def __init__(self, panda, tx_addr: int, rx_addr: int=None, bus: int=0, timeout: float=10, debug: bool=False): + self.panda = panda + self.bus = bus + self.tx_addr = tx_addr + if rx_addr == None: + if tx_addr < 0xFFF8: + # standard 11 bit response addr (add 8) + self.rx_addr = tx_addr+8 + elif tx_addr > 0x10000000 and tx_addr < 0xFFFFFFFF: + # standard 29 bit response addr (flip last two bytes) + self.rx_addr = (tx_addr & 0xFFFF0000) + (tx_addr<<8 & 0xFF00) + (tx_addr>>8 & 0xFF) + else: + raise ValueError("invalid tx_addr: {}".format(tx_addr)) + + self.can_tx_queue = Queue() + self.can_rx_queue = Queue() + self.timeout = timeout + self.debug = debug + + self.can_thread = Thread(target=self._can_thread, args=(self.debug,)) + self.can_thread.daemon = True + self.can_thread.start() + + def _can_thread(self, debug: bool=False): + try: + # allow all output + self.panda.set_safety_mode(0x1337) + # clear tx buffer + self.panda.can_clear(self.bus) + # clear rx buffer + self.panda.can_clear(0xFFFF) + + while True: + # send + while not self.can_tx_queue.empty(): + msg = self.can_tx_queue.get(block=False) + if debug: print("CAN-TX: {} - {}".format(hex(self.tx_addr), hexlify(msg))) + self.panda.can_send(self.tx_addr, msg, self.bus) + + # receive + msgs = self.panda.can_recv() + for rx_addr, rx_ts, rx_data, rx_bus in msgs: + if rx_bus != self.bus or rx_addr != self.rx_addr or len(rx_data) == 0: + continue + if debug: print("CAN-RX: {} - {}".format(hex(self.rx_addr), hexlify(rx_data))) + self.can_rx_queue.put(rx_data) + else: + time.sleep(0.01) + finally: + self.panda.close() + + # generic uds request + def _uds_request(self, service_type: SERVICE_TYPE, subfunction: int=None, data: bytes=None) -> bytes: + req = bytes([service_type]) + if subfunction is not None: + req += bytes([subfunction]) + if data is not None: + req += data + + # send request, wait for response + isotp_msg = IsoTpMessage(self.can_tx_queue, self.can_rx_queue, self.timeout, self.debug) + isotp_msg.send(req) + while True: + resp = isotp_msg.recv() + resp_sid = resp[0] if len(resp) > 0 else None + + # negative response + if resp_sid == 0x7F: + service_id = resp[1] if len(resp) > 1 else -1 + try: + service_desc = SERVICE_TYPE(service_id).name + except Exception: + service_desc = 'NON_STANDARD_SERVICE' + error_code = resp[2] if len(resp) > 2 else -1 + try: + error_desc = _negative_response_codes[error_code] + except Exception: + error_desc = resp[3:] + # wait for another message if response pending + if error_code == 0x78: + if self.debug: print("UDS-RX: response pending") + continue + raise NegativeResponseError('{} - {}'.format(service_desc, error_desc), service_id, error_code) + + # positive response + if service_type+0x40 != resp_sid: + resp_sid_hex = hex(resp_sid) if resp_sid is not None else None + raise InvalidServiceIdError('invalid response service id: {}'.format(resp_sid_hex)) + + if subfunction is not None: + resp_sfn = resp[1] if len(resp) > 1 else None + if subfunction != resp_sfn: + resp_sfn_hex = hex(resp_sfn) if resp_sfn is not None else None + raise InvalidSubFunctioneError('invalid response subfunction: {}'.format(hex(resp_sfn_hex))) + + # return data (exclude service id and sub-function id) + return resp[(1 if subfunction is None else 2):] + + # services + def diagnostic_session_control(self, session_type: SESSION_TYPE): + self._uds_request(SERVICE_TYPE.DIAGNOSTIC_SESSION_CONTROL, subfunction=session_type) + + def ecu_reset(self, reset_type: RESET_TYPE): + resp = self._uds_request(SERVICE_TYPE.ECU_RESET, subfunction=reset_type) + power_down_time = None + if reset_type == RESET_TYPE.ENABLE_RAPID_POWER_SHUTDOWN: + power_down_time = resp[0] + return power_down_time + + def security_access(self, access_type: ACCESS_TYPE, security_key: bytes=None): + request_seed = access_type % 2 != 0 + if request_seed and security_key is not None: + raise ValueError('security_key not allowed') + if not request_seed and security_key is None: + raise ValueError('security_key is missing') + resp = self._uds_request(SERVICE_TYPE.SECURITY_ACCESS, subfunction=access_type, data=security_key) + if request_seed: + security_seed = resp + return security_seed + + def communication_control(self, control_type: CONTROL_TYPE, message_type: MESSAGE_TYPE): + data = bytes([message_type]) + self._uds_request(SERVICE_TYPE.COMMUNICATION_CONTROL, subfunction=control_type, data=data) + + def tester_present(self, ): + self._uds_request(SERVICE_TYPE.TESTER_PRESENT, subfunction=0x00) + + def access_timing_parameter(self, timing_parameter_type: TIMING_PARAMETER_TYPE, parameter_values: bytes=None): + write_custom_values = timing_parameter_type == TIMING_PARAMETER_TYPE.SET_TO_GIVEN_VALUES + read_values = ( + timing_parameter_type == TIMING_PARAMETER_TYPE.READ_CURRENTLY_ACTIVE or + timing_parameter_type == TIMING_PARAMETER_TYPE.READ_EXTENDED_SET + ) + if not write_custom_values and parameter_values is not None: + raise ValueError('parameter_values not allowed') + if write_custom_values and parameter_values is None: + raise ValueError('parameter_values is missing') + resp = self._uds_request(SERVICE_TYPE.ACCESS_TIMING_PARAMETER, subfunction=timing_parameter_type, data=parameter_values) + if read_values: + # TODO: parse response into values? + parameter_values = resp + return parameter_values + + def secured_data_transmission(self, data: bytes): + # TODO: split data into multiple input parameters? + resp = self._uds_request(SERVICE_TYPE.SECURED_DATA_TRANSMISSION, subfunction=None, data=data) + # TODO: parse response into multiple output values? + return resp + + def control_dtc_setting(self, dtc_setting_type: DTC_SETTING_TYPE): + self._uds_request(SERVICE_TYPE.CONTROL_DTC_SETTING, subfunction=dtc_setting_type) + + def response_on_event(self, response_event_type: RESPONSE_EVENT_TYPE, store_event: bool, window_time: int, event_type_record: int, service_response_record: int): + if store_event: + response_event_type |= 0x20 + # TODO: split record parameters into arrays + data = bytes([window_time, event_type_record, service_response_record]) + resp = self._uds_request(SERVICE_TYPE.RESPONSE_ON_EVENT, subfunction=response_event_type, data=data) + + if response_event_type == RESPONSE_EVENT_TYPE.REPORT_ACTIVATED_EVENTS: + return { + "num_of_activated_events": resp[0], + "data": resp[1:], # TODO: parse the reset of response + } + + return { + "num_of_identified_events": resp[0], + "event_window_time": resp[1], + "data": resp[2:], # TODO: parse the reset of response + } + + def link_control(self, link_control_type: LINK_CONTROL_TYPE, baud_rate_type: BAUD_RATE_TYPE=None): + if link_control_type == LINK_CONTROL_TYPE.VERIFY_BAUDRATE_TRANSITION_WITH_FIXED_BAUDRATE: + # baud_rate_type = BAUD_RATE_TYPE + data = bytes([baud_rate_type]) + elif link_control_type == LINK_CONTROL_TYPE.VERIFY_BAUDRATE_TRANSITION_WITH_SPECIFIC_BAUDRATE: + # baud_rate_type = custom value (3 bytes big-endian) + data = struct.pack('!I', baud_rate_type)[1:] + else: + data = None + self._uds_request(SERVICE_TYPE.LINK_CONTROL, subfunction=link_control_type, data=data) + + def read_data_by_identifier(self, data_identifier_type: DATA_IDENTIFIER_TYPE): + # TODO: support list of identifiers + data = struct.pack('!H', data_identifier_type) + resp = self._uds_request(SERVICE_TYPE.READ_DATA_BY_IDENTIFIER, subfunction=None, data=data) + resp_id = struct.unpack('!H', resp[0:2])[0] if len(resp) >= 2 else None + if resp_id != data_identifier_type: + raise ValueError('invalid response data identifier: {}'.format(hex(resp_id))) + return resp[2:] + + def read_memory_by_address(self, memory_address: int, memory_size: int, memory_address_bytes: int=4, memory_size_bytes: int=1): + if memory_address_bytes < 1 or memory_address_bytes > 4: + raise ValueError('invalid memory_address_bytes: {}'.format(memory_address_bytes)) + if memory_size_bytes < 1 or memory_size_bytes > 4: + raise ValueError('invalid memory_size_bytes: {}'.format(memory_size_bytes)) + data = bytes([memory_size_bytes<<4 | memory_address_bytes]) + + if memory_address >= 1<<(memory_address_bytes*8): + raise ValueError('invalid memory_address: {}'.format(memory_address)) + data += struct.pack('!I', memory_address)[4-memory_address_bytes:] + if memory_size >= 1<<(memory_size_bytes*8): + raise ValueError('invalid memory_size: {}'.format(memory_size)) + data += struct.pack('!I', memory_size)[4-memory_size_bytes:] + + resp = self._uds_request(SERVICE_TYPE.READ_MEMORY_BY_ADDRESS, subfunction=None, data=data) + return resp + + def read_scaling_data_by_identifier(self, data_identifier_type: DATA_IDENTIFIER_TYPE): + data = struct.pack('!H', data_identifier_type) + resp = self._uds_request(SERVICE_TYPE.READ_SCALING_DATA_BY_IDENTIFIER, subfunction=None, data=data) + resp_id = struct.unpack('!H', resp[0:2])[0] if len(resp) >= 2 else None + if resp_id != data_identifier_type: + raise ValueError('invalid response data identifier: {}'.format(hex(resp_id))) + return resp[2:] # TODO: parse the response + + def read_data_by_periodic_identifier(self, transmission_mode_type: TRANSMISSION_MODE_TYPE, periodic_data_identifier: int): + # TODO: support list of identifiers + data = bytes([transmission_mode_type, periodic_data_identifier]) + self._uds_request(SERVICE_TYPE.READ_DATA_BY_PERIODIC_IDENTIFIER, subfunction=None, data=data) + + def dynamically_define_data_identifier(self, dynamic_definition_type: DYNAMIC_DEFINITION_TYPE, dynamic_data_identifier: int, source_definitions: List[DynamicSourceDefinition], memory_address_bytes: int=4, memory_size_bytes: int=1): + if memory_address_bytes < 1 or memory_address_bytes > 4: + raise ValueError('invalid memory_address_bytes: {}'.format(memory_address_bytes)) + if memory_size_bytes < 1 or memory_size_bytes > 4: + raise ValueError('invalid memory_size_bytes: {}'.format(memory_size_bytes)) + + data = struct.pack('!H', dynamic_data_identifier) + if dynamic_definition_type == DYNAMIC_DEFINITION_TYPE.DEFINE_BY_IDENTIFIER: + for s in source_definitions: + data += struct.pack('!H', s["data_identifier"]) + bytes([s["position"], s["memory_size"]]) + elif dynamic_definition_type == DYNAMIC_DEFINITION_TYPE.DEFINE_BY_MEMORY_ADDRESS: + data += bytes([memory_size_bytes<<4 | memory_address_bytes]) + for s in source_definitions: + if s["memory_address"] >= 1<<(memory_address_bytes*8): + raise ValueError('invalid memory_address: {}'.format(s["memory_address"])) + data += struct.pack('!I', s["memory_address"])[4-memory_address_bytes:] + if s["memory_size"] >= 1<<(memory_size_bytes*8): + raise ValueError('invalid memory_size: {}'.format(s["memory_size"])) + data += struct.pack('!I', s["memory_size"])[4-memory_size_bytes:] + elif dynamic_definition_type == DYNAMIC_DEFINITION_TYPE.CLEAR_DYNAMICALLY_DEFINED_DATA_IDENTIFIER: + pass + else: + raise ValueError('invalid dynamic identifier type: {}'.format(hex(dynamic_definition_type))) + self._uds_request(SERVICE_TYPE.DYNAMICALLY_DEFINE_DATA_IDENTIFIER, subfunction=dynamic_definition_type, data=data) + + def write_data_by_identifier(self, data_identifier_type: DATA_IDENTIFIER_TYPE, data_record: bytes): + data = struct.pack('!H', data_identifier_type) + data_record + resp = self._uds_request(SERVICE_TYPE.WRITE_DATA_BY_IDENTIFIER, subfunction=None, data=data) + resp_id = struct.unpack('!H', resp[0:2])[0] if len(resp) >= 2 else None + if resp_id != data_identifier_type: + raise ValueError('invalid response data identifier: {}'.format(hex(resp_id))) + + def write_memory_by_address(self, memory_address: int, memory_size: int, data_record: bytes, memory_address_bytes: int=4, memory_size_bytes: int=1): + if memory_address_bytes < 1 or memory_address_bytes > 4: + raise ValueError('invalid memory_address_bytes: {}'.format(memory_address_bytes)) + if memory_size_bytes < 1 or memory_size_bytes > 4: + raise ValueError('invalid memory_size_bytes: {}'.format(memory_size_bytes)) + data = bytes([memory_size_bytes<<4 | memory_address_bytes]) + + if memory_address >= 1<<(memory_address_bytes*8): + raise ValueError('invalid memory_address: {}'.format(memory_address)) + data += struct.pack('!I', memory_address)[4-memory_address_bytes:] + if memory_size >= 1<<(memory_size_bytes*8): + raise ValueError('invalid memory_size: {}'.format(memory_size)) + data += struct.pack('!I', memory_size)[4-memory_size_bytes:] + + data += data_record + self._uds_request(SERVICE_TYPE.WRITE_MEMORY_BY_ADDRESS, subfunction=0x00, data=data) + + def clear_diagnostic_information(self, dtc_group_type: DTC_GROUP_TYPE): + data = struct.pack('!I', dtc_group_type)[1:] # 3 bytes + self._uds_request(SERVICE_TYPE.CLEAR_DIAGNOSTIC_INFORMATION, subfunction=None, data=data) + + def read_dtc_information(self, dtc_report_type: DTC_REPORT_TYPE, dtc_status_mask_type: DTC_STATUS_MASK_TYPE=DTC_STATUS_MASK_TYPE.ALL, dtc_severity_mask_type: DTC_SEVERITY_MASK_TYPE=DTC_SEVERITY_MASK_TYPE.ALL, dtc_mask_record: int=0xFFFFFF, dtc_snapshot_record_num: int=0xFF, dtc_extended_record_num: int=0xFF): + data = b'' + # dtc_status_mask_type + if dtc_report_type == DTC_REPORT_TYPE.NUMBER_OF_DTC_BY_STATUS_MASK or \ + dtc_report_type == DTC_REPORT_TYPE.DTC_BY_STATUS_MASK or \ + dtc_report_type == DTC_REPORT_TYPE.MIRROR_MEMORY_DTC_BY_STATUS_MASK or \ + dtc_report_type == DTC_REPORT_TYPE.NUMBER_OF_MIRROR_MEMORY_DTC_BY_STATUS_MASK or \ + dtc_report_type == DTC_REPORT_TYPE.NUMBER_OF_EMISSIONS_RELATED_OBD_DTC_BY_STATUS_MASK or \ + dtc_report_type == DTC_REPORT_TYPE.EMISSIONS_RELATED_OBD_DTC_BY_STATUS_MASK: + data += bytes([dtc_status_mask_type]) + # dtc_mask_record + if dtc_report_type == DTC_REPORT_TYPE.DTC_SNAPSHOT_IDENTIFICATION or \ + dtc_report_type == DTC_REPORT_TYPE.DTC_SNAPSHOT_RECORD_BY_DTC_NUMBER or \ + dtc_report_type == DTC_REPORT_TYPE.DTC_EXTENDED_DATA_RECORD_BY_DTC_NUMBER or \ + dtc_report_type == DTC_REPORT_TYPE.MIRROR_MEMORY_DTC_EXTENDED_DATA_RECORD_BY_DTC_NUMBER or \ + dtc_report_type == DTC_REPORT_TYPE.SEVERITY_INFORMATION_OF_DTC: + data += struct.pack('!I', dtc_mask_record)[1:] # 3 bytes + # dtc_snapshot_record_num + if dtc_report_type == DTC_REPORT_TYPE.DTC_SNAPSHOT_IDENTIFICATION or \ + dtc_report_type == DTC_REPORT_TYPE.DTC_SNAPSHOT_RECORD_BY_DTC_NUMBER or \ + dtc_report_type == DTC_REPORT_TYPE.DTC_SNAPSHOT_RECORD_BY_RECORD_NUMBER: + data += ord(dtc_snapshot_record_num) + # dtc_extended_record_num + if dtc_report_type == DTC_REPORT_TYPE.DTC_EXTENDED_DATA_RECORD_BY_DTC_NUMBER or \ + dtc_report_type == DTC_REPORT_TYPE.MIRROR_MEMORY_DTC_EXTENDED_DATA_RECORD_BY_DTC_NUMBER: + data += bytes([dtc_extended_record_num]) + # dtc_severity_mask_type + if dtc_report_type == DTC_REPORT_TYPE.NUMBER_OF_DTC_BY_SEVERITY_MASK_RECORD or \ + dtc_report_type == DTC_REPORT_TYPE.DTC_BY_SEVERITY_MASK_RECORD: + data += bytes([dtc_severity_mask_type, dtc_status_mask_type]) + + resp = self._uds_request(SERVICE_TYPE.READ_DTC_INFORMATION, subfunction=dtc_report_type, data=data) + + # TODO: parse response + return resp + + def input_output_control_by_identifier(self, data_identifier_type: DATA_IDENTIFIER_TYPE, control_parameter_type: CONTROL_PARAMETER_TYPE, control_option_record: bytes, control_enable_mask_record: bytes=b''): + data = struct.pack('!H', data_identifier_type) + bytes([control_parameter_type]) + control_option_record + control_enable_mask_record + resp = self._uds_request(SERVICE_TYPE.INPUT_OUTPUT_CONTROL_BY_IDENTIFIER, subfunction=None, data=data) + resp_id = struct.unpack('!H', resp[0:2])[0] if len(resp) >= 2 else None + if resp_id != data_identifier_type: + raise ValueError('invalid response data identifier: {}'.format(hex(resp_id))) + return resp[2:] + + def routine_control(self, routine_control_type: ROUTINE_CONTROL_TYPE, routine_identifier_type: ROUTINE_IDENTIFIER_TYPE, routine_option_record: bytes=b''): + data = struct.pack('!H', routine_identifier_type) + routine_option_record + resp = self._uds_request(SERVICE_TYPE.ROUTINE_CONTROL, subfunction=routine_control_type, data=data) + resp_id = struct.unpack('!H', resp[0:2])[0] if len(resp) >= 2 else None + if resp_id != routine_identifier_type: + raise ValueError('invalid response routine identifier: {}'.format(hex(resp_id))) + return resp[2:] + + def request_download(self, memory_address: int, memory_size: int, memory_address_bytes: int=4, memory_size_bytes: int=4, data_format: int=0x00): + data = bytes([data_format]) + + if memory_address_bytes < 1 or memory_address_bytes > 4: + raise ValueError('invalid memory_address_bytes: {}'.format(memory_address_bytes)) + if memory_size_bytes < 1 or memory_size_bytes > 4: + raise ValueError('invalid memory_size_bytes: {}'.format(memory_size_bytes)) + data += bytes([memory_size_bytes<<4 | memory_address_bytes]) + + if memory_address >= 1<<(memory_address_bytes*8): + raise ValueError('invalid memory_address: {}'.format(memory_address)) + data += struct.pack('!I', memory_address)[4-memory_address_bytes:] + if memory_size >= 1<<(memory_size_bytes*8): + raise ValueError('invalid memory_size: {}'.format(memory_size)) + data += struct.pack('!I', memory_size)[4-memory_size_bytes:] + + resp = self._uds_request(SERVICE_TYPE.REQUEST_DOWNLOAD, subfunction=None, data=data) + max_num_bytes_len = resp[0] >> 4 if len(resp) > 0 else None + if max_num_bytes_len >= 1 and max_num_bytes_len <= 4: + max_num_bytes = struct.unpack('!I', (b"\x00"*(4-max_num_bytes_len))+resp[1:max_num_bytes_len+1])[0] + else: + raise ValueError('invalid max_num_bytes_len: {}'.format(max_num_bytes_len)) + + return max_num_bytes # max number of bytes per transfer data request + + def request_upload(self, memory_address: int, memory_size: int, memory_address_bytes: int=4, memory_size_bytes: int=4, data_format: int=0x00): + data = bytes([data_format]) + + if memory_address_bytes < 1 or memory_address_bytes > 4: + raise ValueError('invalid memory_address_bytes: {}'.format(memory_address_bytes)) + if memory_size_bytes < 1 or memory_size_bytes > 4: + raise ValueError('invalid memory_size_bytes: {}'.format(memory_size_bytes)) + data += bytes([memory_size_bytes<<4 | memory_address_bytes]) + + if memory_address >= 1<<(memory_address_bytes*8): + raise ValueError('invalid memory_address: {}'.format(memory_address)) + data += struct.pack('!I', memory_address)[4-memory_address_bytes:] + if memory_size >= 1<<(memory_size_bytes*8): + raise ValueError('invalid memory_size: {}'.format(memory_size)) + data += struct.pack('!I', memory_size)[4-memory_size_bytes:] + + resp = self._uds_request(SERVICE_TYPE.REQUEST_UPLOAD, subfunction=None, data=data) + max_num_bytes_len = resp[0] >> 4 if len(resp) > 0 else None + if max_num_bytes_len >= 1 and max_num_bytes_len <= 4: + max_num_bytes = struct.unpack('!I', (b"\x00"*(4-max_num_bytes_len))+resp[1:max_num_bytes_len+1])[0] + else: + raise ValueError('invalid max_num_bytes_len: {}'.format(max_num_bytes_len)) + + return max_num_bytes # max number of bytes per transfer data request + + def transfer_data(self, block_sequence_count: int, data: bytes=b''): + data = bytes([block_sequence_count]) + data + resp = self._uds_request(SERVICE_TYPE.TRANSFER_DATA, subfunction=None, data=data) + resp_id = resp[0] if len(resp) > 0 else None + if resp_id != block_sequence_count: + raise ValueError('invalid block_sequence_count: {}'.format(resp_id)) + return resp[1:] + + def request_transfer_exit(self): + self._uds_request(SERVICE_TYPE.REQUEST_TRANSFER_EXIT, subfunction=None) diff --git a/panda/python/update.py b/panda/python/update.py index ce730e4919119e..7d8d2c04023b8e 100755 --- a/panda/python/update.py +++ b/panda/python/update.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import os import time @@ -12,7 +12,6 @@ def ensure_st_up_to_date(): panda = None panda_dfu = None - should_flash_recover = False while 1: # break on normal mode Panda @@ -27,7 +26,7 @@ def ensure_st_up_to_date(): panda_dfu = PandaDFU(panda_dfu[0]) panda_dfu.recover() - print "waiting for board..." + print("waiting for board...") time.sleep(1) if panda.bootstub or not panda.get_version().startswith(repo_version): diff --git a/panda/release/make_release.sh b/panda/release/make_release.sh index 7be994c82c8813..5aec1a79495fe1 100755 --- a/panda/release/make_release.sh +++ b/panda/release/make_release.sh @@ -7,6 +7,7 @@ if [ ! -d "../../pandaextra" ]; then fi export RELEASE=1 +export BUILDER=DEV # make ST + bootstub pushd . diff --git a/panda/requirements.txt b/panda/requirements.txt index e968bfb6bad43e..e7cf9931d550e7 100644 --- a/panda/requirements.txt +++ b/panda/requirements.txt @@ -1,4 +1,11 @@ -libusb1 -hexdump -pycrypto -tqdm +libusb1 == 1.6.6 +numpy==1.17.2 +hexdump>=3.3 +pycrypto==2.6.1 +tqdm>=4.14.0 +nose +parameterized +requests +flake8==3.7.8 +pylint==2.4.2 +cffi==1.11.4 diff --git a/panda/run_automated_tests.sh b/panda/run_automated_tests.sh index d7b7541902d9eb..e876c670a74c0e 100755 --- a/panda/run_automated_tests.sh +++ b/panda/run_automated_tests.sh @@ -1,3 +1,21 @@ -#!/bin/bash -PYTHONPATH="." nosetests -x -s tests/automated/$1*.py +#!/bin/bash -e +TEST_FILENAME=${TEST_FILENAME:-nosetests.xml} +if [ -f "/EON" ]; then + TESTSUITE_NAME="Panda_Test-EON" +else + TESTSUITE_NAME="Panda_Test-DEV" +fi +if [ ! -z "${SKIPWIFI}" ] || [ -f "/EON" ]; then + TEST_SCRIPTS=$(ls tests/automated/$1*.py | grep -v wifi) +else + TEST_SCRIPTS=$(ls tests/automated/$1*.py) +fi + +IFS=$'\n' +for NAME in $(nmcli --fields NAME con show | grep panda | awk '{$1=$1};1') +do + nmcli connection delete "$NAME" +done + +PYTHONPATH="." $(which nosetests) -v --with-xunit --xunit-file=./$TEST_FILENAME --xunit-testsuite-name=$TESTSUITE_NAME -s $TEST_SCRIPTS diff --git a/panda/setup.py b/panda/setup.py index 312fdca42a0848..f34905d7a2ee17 100644 --- a/panda/setup.py +++ b/panda/setup.py @@ -13,7 +13,7 @@ import codecs import os import re -from setuptools import setup, Extension +from setuptools import setup here = os.path.abspath(os.path.dirname(__file__)) @@ -46,7 +46,7 @@ def find_version(*file_paths): platforms='any', license='MIT', install_requires=[ - 'libusb1 >= 1.6.4', + 'libusb1 == 1.6.6', 'hexdump >= 3.3', 'pycrypto >= 2.6.1', 'tqdm >= 4.14.0', diff --git a/panda/tests/all_wifi_test.py b/panda/tests/all_wifi_test.py index 4e9d3a5318a16c..85dc173b07625c 100755 --- a/panda/tests/all_wifi_test.py +++ b/panda/tests/all_wifi_test.py @@ -1,7 +1,7 @@ -#!/usr/bin/python +#!/usr/bin/env python3 import requests import json -from automated.helpers import _connect_wifi +from .automated.helpers import _connect_wifi from panda import Panda from nose.tools import assert_equal @@ -12,12 +12,12 @@ for p in Panda.list(): dongle_id, pw = Panda(p).get_serial() - print dongle_id, pw + print(dongle_id, pw) assert(dongle_id.isalnum()) _connect_wifi(dongle_id, pw) r = requests.get("http://192.168.0.10/") - print r.text + print(r.text) wifi_dongle_id = r.text.split("ssid: panda-")[1].split("
")[0] st_version = r.text.split("st version:")[1].strip().split("
")[0] esp_version = r.text.split("esp version:")[1].strip().split("
")[0] diff --git a/panda/tests/automated/0_builds.py b/panda/tests/automated/0_builds.py index d5e434a2c22876..fa3a1125d48244 100644 --- a/panda/tests/automated/0_builds.py +++ b/panda/tests/automated/0_builds.py @@ -1,12 +1,5 @@ -import os from panda import build_st -def test_build_legacy(): - build_st("obj/comma.bin", "Makefile.legacy") - -def test_build_bootstub_legacy(): - build_st("obj/bootstub.comma.bin", "Makefile.legacy") - def test_build_panda(): build_st("obj/panda.bin") diff --git a/panda/tests/automated/1_program.py b/panda/tests/automated/1_program.py index 7da801bcd54e7b..538f18c0c7f63a 100644 --- a/panda/tests/automated/1_program.py +++ b/panda/tests/automated/1_program.py @@ -1,11 +1,11 @@ -import os -from panda import Panda +from .helpers import test_all_pandas, panda_connect_and_init -def test_recover(): - p = Panda() - p.recover() +@test_all_pandas +@panda_connect_and_init +def test_recover(p): + assert p.recover(timeout=30) -def test_flash(): - p = Panda() +@test_all_pandas +@panda_connect_and_init +def test_flash(p): p.flash() - diff --git a/panda/tests/automated/2_usb_to_can.py b/panda/tests/automated/2_usb_to_can.py index 481564240752a2..32ef558cfc409a 100644 --- a/panda/tests/automated/2_usb_to_can.py +++ b/panda/tests/automated/2_usb_to_can.py @@ -1,17 +1,12 @@ -from __future__ import print_function -import os import sys import time from panda import Panda -from nose.tools import timed, assert_equal, assert_less, assert_greater -from helpers import time_many_sends, connect_wo_esp - -SPEED_NORMAL = 500 -SPEED_GMLAN = 33.3 - -def test_can_loopback(): - p = connect_wo_esp() +from nose.tools import assert_equal, assert_less, assert_greater +from .helpers import SPEED_NORMAL, SPEED_GMLAN, time_many_sends, test_white_and_grey, panda_type_to_serial, test_all_pandas, panda_connect_and_init +@test_all_pandas +@panda_connect_and_init +def test_can_loopback(p): # enable output mode p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) @@ -28,23 +23,23 @@ def test_can_loopback(): p.set_can_speed_kbps(bus, 250) # send a message on bus 0 - p.can_send(0x1aa, "message", bus) + p.can_send(0x1aa, b"message", bus) # confirm receive both on loopback and send receipt time.sleep(0.05) r = p.can_recv() - sr = filter(lambda x: x[3] == 0x80 | bus, r) - lb = filter(lambda x: x[3] == bus, r) + sr = [x for x in r if x[3] == 0x80 | bus] + lb = [x for x in r if x[3] == bus] assert len(sr) == 1 assert len(lb) == 1 # confirm data is correct assert 0x1aa == sr[0][0] == lb[0][0] - assert "message" == sr[0][2] == lb[0][2] - -def test_safety_nooutput(): - p = connect_wo_esp() + assert b"message" == sr[0][2] == lb[0][2] +@test_all_pandas +@panda_connect_and_init +def test_safety_nooutput(p): # enable output mode p.set_safety_mode(Panda.SAFETY_NOOUTPUT) @@ -52,16 +47,16 @@ def test_safety_nooutput(): p.set_can_loopback(True) # send a message on bus 0 - p.can_send(0x1aa, "message", 0) + p.can_send(0x1aa, b"message", 0) # confirm receive nothing time.sleep(0.05) r = p.can_recv() assert len(r) == 0 -def test_reliability(): - p = connect_wo_esp() - +@test_all_pandas +@panda_connect_and_init +def test_reliability(p): LOOP_COUNT = 100 MSG_COUNT = 100 @@ -70,8 +65,8 @@ def test_reliability(): p.set_can_loopback(True) p.set_can_speed_kbps(0, 1000) - addrs = range(100, 100+MSG_COUNT) - ts = [(j, 0, "\xaa"*8, 0) for j in addrs] + addrs = list(range(100, 100+MSG_COUNT)) + ts = [(j, 0, b"\xaa"*8, 0) for j in addrs] # 100 loops for i in range(LOOP_COUNT): @@ -83,11 +78,11 @@ def test_reliability(): while len(r) < 200 and (time.time() - st) < 0.5: r.extend(p.can_recv()) - sent_echo = filter(lambda x: x[3] == 0x80, r) - loopback_resp = filter(lambda x: x[3] == 0, r) + sent_echo = [x for x in r if x[3] == 0x80] + loopback_resp = [x for x in r if x[3] == 0] - assert_equal(sorted(map(lambda x: x[0], loopback_resp)), addrs) - assert_equal(sorted(map(lambda x: x[0], sent_echo)), addrs) + assert_equal(sorted([x[0] for x in loopback_resp]), addrs) + assert_equal(sorted([x[0] for x in sent_echo]), addrs) assert_equal(len(r), 200) # take sub 20ms @@ -97,9 +92,9 @@ def test_reliability(): sys.stdout.write("P") sys.stdout.flush() -def test_throughput(): - p = connect_wo_esp() - +@test_all_pandas +@panda_connect_and_init +def test_throughput(p): # enable output mode p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) @@ -120,9 +115,10 @@ def test_throughput(): print("loopback 100 messages at speed %d, comp speed is %.2f, percent %.2f" % (speed, comp_kbps, saturation_pct)) -def test_gmlan(): - p = connect_wo_esp() - +@test_white_and_grey +@panda_type_to_serial +@panda_connect_and_init +def test_gmlan(p): if p.legacy: return @@ -135,7 +131,7 @@ def test_gmlan(): p.set_can_speed_kbps(1, SPEED_NORMAL) p.set_can_speed_kbps(2, SPEED_NORMAL) p.set_can_speed_kbps(3, SPEED_GMLAN) - + # set gmlan on CAN2 for bus in [Panda.GMLAN_CAN2, Panda.GMLAN_CAN3, Panda.GMLAN_CAN2, Panda.GMLAN_CAN3]: p.set_gmlan(bus) @@ -150,9 +146,10 @@ def test_gmlan(): print("%d: %.2f kbps vs %.2f kbps" % (bus, comp_kbps_gmlan, comp_kbps_normal)) -def test_gmlan_bad_toggle(): - p = connect_wo_esp() - +@test_white_and_grey +@panda_type_to_serial +@panda_connect_and_init +def test_gmlan_bad_toggle(p): if p.legacy: return @@ -178,9 +175,9 @@ def test_gmlan_bad_toggle(): # this will fail if you have hardware serial connected -def test_serial_debug(): - p = connect_wo_esp() - junk = p.serial_read(Panda.SERIAL_DEBUG) +@test_all_pandas +@panda_connect_and_init +def test_serial_debug(p): + _ = p.serial_read(Panda.SERIAL_DEBUG) # junk p.call_control_api(0xc0) - assert(p.serial_read(Panda.SERIAL_DEBUG).startswith("can ")) - + assert(p.serial_read(Panda.SERIAL_DEBUG).startswith(b"can ")) diff --git a/panda/tests/automated/3_wifi.py b/panda/tests/automated/3_wifi.py index c6f4154ba8eaec..df66d6c0f37d2f 100644 --- a/panda/tests/automated/3_wifi.py +++ b/panda/tests/automated/3_wifi.py @@ -1,33 +1,56 @@ -from __future__ import print_function -import os +import time from panda import Panda -from helpers import connect_wifi +from .helpers import connect_wifi, test_white, test_all_pandas, panda_type_to_serial, panda_connect_and_init import requests -def test_get_serial(): - p = Panda() +@test_all_pandas +@panda_connect_and_init +def test_get_serial(p): print(p.get_serial()) -def test_get_serial_in_flash_mode(): - p = Panda() +@test_all_pandas +@panda_connect_and_init +def test_get_serial_in_flash_mode(p): p.reset(enter_bootstub=True) assert(p.bootstub) print(p.get_serial()) p.reset() -def test_connect_wifi(): - connect_wifi() - -def test_flash_wifi(): - Panda.flash_ota_wifi() - connect_wifi() - -def test_wifi_flash_st(): - Panda.flash_ota_st() - -def test_webpage_fetch(): +@test_white +@panda_type_to_serial +def test_connect_wifi(serials=None): + connect_wifi(serials[0]) + +@test_white +@panda_type_to_serial +def test_flash_wifi(serials=None): + connect_wifi(serials[0]) + assert Panda.flash_ota_wifi(release=False), "OTA Wifi Flash Failed" + connect_wifi(serials[0]) + +@test_white +@panda_type_to_serial +def test_wifi_flash_st(serials=None): + connect_wifi(serials[0]) + assert Panda.flash_ota_st(), "OTA ST Flash Failed" + connected = False + st = time.time() + while not connected and (time.time() - st) < 20: + try: + p = Panda(serial=serials[0]) + p.get_serial() + connected = True + except: + time.sleep(1) + + if not connected: + assert False, "Panda failed to connect on USB after flashing" + +@test_white +@panda_type_to_serial +def test_webpage_fetch(serials=None): + connect_wifi(serials[0]) r = requests.get("http://192.168.0.10/") print(r.text) assert "This is your comma.ai panda" in r.text - diff --git a/panda/tests/automated/4_wifi_functionality.py b/panda/tests/automated/4_wifi_functionality.py index 68686008e3373f..ee349ddcbf69b8 100644 --- a/panda/tests/automated/4_wifi_functionality.py +++ b/panda/tests/automated/4_wifi_functionality.py @@ -1,17 +1,20 @@ -from __future__ import print_function import time from panda import Panda -from helpers import time_many_sends, connect_wifi -from nose.tools import timed, assert_equal, assert_less, assert_greater +from .helpers import time_many_sends, connect_wifi, test_white, panda_type_to_serial -def test_get_serial_wifi(): - connect_wifi() +@test_white +@panda_type_to_serial +def test_get_serial_wifi(serials=None): + connect_wifi(serials[0]) p = Panda("WIFI") print(p.get_serial()) -def test_throughput(): - p = Panda() +@test_white +@panda_type_to_serial +def test_throughput(serials=None): + connect_wifi(serials[0]) + p = Panda(serials[0]) # enable output mode p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) @@ -24,7 +27,7 @@ def test_throughput(): for speed in [100,250,500,750,1000]: # set bus 0 speed to speed p.set_can_speed_kbps(0, speed) - time.sleep(0.05) + time.sleep(0.1) comp_kbps = time_many_sends(p, 0) @@ -35,9 +38,13 @@ def test_throughput(): print("WIFI loopback 100 messages at speed %d, comp speed is %.2f, percent %.2f" % (speed, comp_kbps, saturation_pct)) -def test_recv_only(): - p = Panda() +@test_white +@panda_type_to_serial +def test_recv_only(serials=None): + connect_wifi(serials[0]) + p = Panda(serials[0]) p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + p.set_can_loopback(True) pwifi = Panda("WIFI") @@ -49,4 +56,3 @@ def test_recv_only(): saturation_pct = (comp_kbps/speed) * 100.0 print("HT WIFI loopback %d messages at speed %d, comp speed is %.2f, percent %.2f" % (msg_count, speed, comp_kbps, saturation_pct)) - diff --git a/panda/tests/automated/5_wifi_udp.py b/panda/tests/automated/5_wifi_udp.py index 7d6ccba660b645..fd905aa895e4b3 100644 --- a/panda/tests/automated/5_wifi_udp.py +++ b/panda/tests/automated/5_wifi_udp.py @@ -1,14 +1,16 @@ -from __future__ import print_function + import sys import time -from helpers import time_many_sends, connect_wifi +from .helpers import time_many_sends, connect_wifi, test_white, panda_type_to_serial from panda import Panda, PandaWifiStreaming -from nose.tools import timed, assert_equal, assert_less, assert_greater +from nose.tools import assert_less, assert_greater -def test_udp_doesnt_drop(): - connect_wifi() +@test_white +@panda_type_to_serial +def test_udp_doesnt_drop(serials=None): + connect_wifi(serials[0]) - p = Panda() + p = Panda(serials[0]) p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) p.set_can_loopback(True) @@ -18,6 +20,7 @@ def test_udp_doesnt_drop(): break for msg_count in [1, 100]: + saturation_pcts = [] for i in range({1: 0x80, 100: 0x20}[msg_count]): pwifi.kick() @@ -31,9 +34,33 @@ def test_udp_doesnt_drop(): sys.stdout.flush() else: print("UDP WIFI loopback %d messages at speed %d, comp speed is %.2f, percent %.2f" % (msg_count, speed, comp_kbps, saturation_pct)) - assert_greater(saturation_pct, 40) + assert_greater(saturation_pct, 20) #sometimes the wifi can be slow... assert_less(saturation_pct, 100) - print("") - - + saturation_pcts.append(saturation_pct) + if len(saturation_pcts) > 0: + assert_greater(sum(saturation_pcts)/len(saturation_pcts), 60) + time.sleep(5) + usb_ok_cnt = 0 + REQ_USB_OK_CNT = 500 + st = time.time() + msg_id = 0x1bb + bus = 0 + last_missing_msg = 0 + while usb_ok_cnt < REQ_USB_OK_CNT and (time.time() - st) < 40: + p.can_send(msg_id, "message", bus) + time.sleep(0.01) + r = [1] + missing = True + while len(r) > 0: + r = p.can_recv() + r = [x for x in r if x[3] == bus and x[0] == msg_id] + if len(r) > 0: + missing = False + usb_ok_cnt += len(r) + if missing: + last_missing_msg = time.time() + et = time.time() - st + last_missing_msg = last_missing_msg - st + print("waited {} for panda to recv can on usb, {} msgs, last missing at {}".format(et, usb_ok_cnt, last_missing_msg)) + assert usb_ok_cnt >= REQ_USB_OK_CNT, "Unable to recv can on USB after UDP" diff --git a/panda/tests/automated/6_two_panda.py b/panda/tests/automated/6_two_panda.py new file mode 100644 index 00000000000000..f91403545f367a --- /dev/null +++ b/panda/tests/automated/6_two_panda.py @@ -0,0 +1,195 @@ + +import os +import time +import random +from panda import Panda +from nose.tools import assert_equal, assert_less, assert_greater +from .helpers import time_many_sends, test_two_panda, test_two_black_panda, panda_type_to_serial, clear_can_buffers, panda_connect_and_init + +@test_two_panda +@panda_type_to_serial +@panda_connect_and_init +def test_send_recv(p_send, p_recv): + p_send.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + p_recv.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + p_send.set_can_loopback(False) + p_recv.set_can_loopback(False) + + assert not p_send.legacy + assert not p_recv.legacy + + p_send.can_send_many([(0x1ba, 0, b"message", 0)]*2) + time.sleep(0.05) + p_recv.can_recv() + p_send.can_recv() + + busses = [0,1,2] + + for bus in busses: + for speed in [100, 250, 500, 750, 1000]: + p_send.set_can_speed_kbps(bus, speed) + p_recv.set_can_speed_kbps(bus, speed) + time.sleep(0.05) + + comp_kbps = time_many_sends(p_send, bus, p_recv, two_pandas=True) + + saturation_pct = (comp_kbps/speed) * 100.0 + assert_greater(saturation_pct, 80) + assert_less(saturation_pct, 100) + + print("two pandas bus {}, 100 messages at speed {:4d}, comp speed is {:7.2f}, percent {:6.2f}".format(bus, speed, comp_kbps, saturation_pct)) + +@test_two_panda +@panda_type_to_serial +@panda_connect_and_init +def test_latency(p_send, p_recv): + p_send.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + p_recv.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + p_send.set_can_loopback(False) + p_recv.set_can_loopback(False) + + assert not p_send.legacy + assert not p_recv.legacy + + p_send.set_can_speed_kbps(0, 100) + p_recv.set_can_speed_kbps(0, 100) + time.sleep(0.05) + + p_send.can_send_many([(0x1ba, 0, b"testmsg", 0)]*10) + time.sleep(0.05) + p_recv.can_recv() + p_send.can_recv() + + busses = [0,1,2] + + for bus in busses: + for speed in [100, 250, 500, 750, 1000]: + p_send.set_can_speed_kbps(bus, speed) + p_recv.set_can_speed_kbps(bus, speed) + time.sleep(0.1) + + #clear can buffers + clear_can_buffers(p_send) + clear_can_buffers(p_recv) + + latencies = [] + comp_kbps_list = [] + saturation_pcts = [] + + num_messages = 100 + + for i in range(num_messages): + st = time.time() + p_send.can_send(0x1ab, b"message", bus) + r = [] + while len(r) < 1 and (time.time() - st) < 5: + r = p_recv.can_recv() + et = time.time() + r_echo = [] + while len(r_echo) < 1 and (time.time() - st) < 10: + r_echo = p_send.can_recv() + + if len(r) == 0 or len(r_echo) == 0: + print("r: {}, r_echo: {}".format(r, r_echo)) + + assert_equal(len(r),1) + assert_equal(len(r_echo),1) + + et = (et - st)*1000.0 + comp_kbps = (1+11+1+1+1+4+8*8+15+1+1+1+7) / et + latency = et - ((1+11+1+1+1+4+8*8+15+1+1+1+7) / speed) + + assert_less(latency, 5.0) + + saturation_pct = (comp_kbps/speed) * 100.0 + latencies.append(latency) + comp_kbps_list.append(comp_kbps) + saturation_pcts.append(saturation_pct) + + average_latency = sum(latencies)/num_messages + assert_less(average_latency, 1.0) + average_comp_kbps = sum(comp_kbps_list)/num_messages + average_saturation_pct = sum(saturation_pcts)/num_messages + + print("two pandas bus {}, {} message average at speed {:4d}, latency is {:5.3f}ms, comp speed is {:7.2f}, percent {:6.2f}"\ + .format(bus, num_messages, speed, average_latency, average_comp_kbps, average_saturation_pct)) + +@test_two_black_panda +@panda_type_to_serial +@panda_connect_and_init +def test_black_loopback(panda0, panda1): + # disable safety modes + panda0.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + panda1.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + + # disable loopback + panda0.set_can_loopback(False) + panda1.set_can_loopback(False) + + # clear stuff + panda0.can_send_many([(0x1ba, 0, b"testmsg", 0)]*10) + time.sleep(0.05) + panda0.can_recv() + panda1.can_recv() + + # test array (send bus, sender obd, reciever obd, expected busses) + test_array = [ + (0, False, False, [0]), + (1, False, False, [1]), + (2, False, False, [2]), + (0, False, True, [0, 1]), + (1, False, True, []), + (2, False, True, [2]), + (0, True, False, [0]), + (1, True, False, [0]), + (2, True, False, [2]), + (0, True, True, [0, 1]), + (1, True, True, [0, 1]), + (2, True, True, [2]) + ] + + # test functions + def get_test_string(): + return b"test"+os.urandom(10) + + def _test_buses(send_panda, recv_panda, _test_array): + for send_bus, send_obd, recv_obd, recv_buses in _test_array: + print("\nSend bus:", send_bus, " Send OBD:", send_obd, " Recv OBD:", recv_obd) + + # set OBD on pandas + send_panda.set_gmlan(True if send_obd else None) + recv_panda.set_gmlan(True if recv_obd else None) + + # clear buffers + clear_can_buffers(send_panda) + clear_can_buffers(recv_panda) + + # send the characters + at = random.randint(1, 2000) + st = get_test_string()[0:8] + send_panda.can_send(at, st, send_bus) + time.sleep(0.1) + + # check for receive + _ = send_panda.can_recv() # cans echo + cans_loop = recv_panda.can_recv() + + loop_buses = [] + for loop in cans_loop: + print(" Loop on bus", str(loop[3])) + loop_buses.append(loop[3]) + if len(cans_loop) == 0: + print(" No loop") + + # test loop buses + recv_buses.sort() + loop_buses.sort() + assert recv_buses == loop_buses + print(" TEST PASSED") + print("\n") + + # test both orientations + print("***************** TESTING (0 --> 1) *****************") + _test_buses(panda0, panda1, test_array) + print("***************** TESTING (1 --> 0) *****************") + _test_buses(panda1, panda0, test_array) diff --git a/panda/tests/automated/helpers.py b/panda/tests/automated/helpers.py index 1ddced117980ee..2642e9156ad316 100644 --- a/panda/tests/automated/helpers.py +++ b/panda/tests/automated/helpers.py @@ -4,30 +4,63 @@ import random import subprocess import requests +import _thread +from functools import wraps from panda import Panda -from nose.tools import timed, assert_equal, assert_less, assert_greater +from nose.tools import assert_equal +from parameterized import parameterized, param -def connect_wo_esp(): - # connect to the panda - p = Panda() +SPEED_NORMAL = 500 +SPEED_GMLAN = 33.3 - # power down the ESP - p.set_esp_power(False) +test_all_types = parameterized([ + param(panda_type=Panda.HW_TYPE_WHITE_PANDA), + param(panda_type=Panda.HW_TYPE_GREY_PANDA), + param(panda_type=Panda.HW_TYPE_BLACK_PANDA) + ]) +test_all_pandas = parameterized( + Panda.list() + ) +test_white_and_grey = parameterized([ + param(panda_type=Panda.HW_TYPE_WHITE_PANDA), + param(panda_type=Panda.HW_TYPE_GREY_PANDA) + ]) +test_white = parameterized([ + param(panda_type=Panda.HW_TYPE_WHITE_PANDA) + ]) +test_grey = parameterized([ + param(panda_type=Panda.HW_TYPE_GREY_PANDA) + ]) +test_two_panda = parameterized([ + param(panda_type=[Panda.HW_TYPE_GREY_PANDA, Panda.HW_TYPE_WHITE_PANDA]), + param(panda_type=[Panda.HW_TYPE_WHITE_PANDA, Panda.HW_TYPE_GREY_PANDA]), + param(panda_type=[Panda.HW_TYPE_BLACK_PANDA, Panda.HW_TYPE_BLACK_PANDA]) + ]) +test_two_black_panda = parameterized([ + param(panda_type=[Panda.HW_TYPE_BLACK_PANDA, Panda.HW_TYPE_BLACK_PANDA]) + ]) - # clear old junk - while len(p.can_recv()) > 0: - pass - - return p - -def connect_wifi(): - p = Panda() +def connect_wifi(serial=None): + p = Panda(serial=serial) + p.set_esp_power(True) dongle_id, pw = p.get_serial() assert(dongle_id.isalnum()) _connect_wifi(dongle_id, pw) +FNULL = open(os.devnull, 'w') def _connect_wifi(dongle_id, pw, insecure_okay=False): - ssid = str("panda-" + dongle_id) + ssid = "panda-" + dongle_id + + r = subprocess.call(["ping", "-W", "4", "-c", "1", "192.168.0.10"], stdout=FNULL, stderr=subprocess.STDOUT) + if not r: + #Can already ping, try connecting on wifi + try: + p = Panda("WIFI") + p.get_serial() + print("Already connected") + return + except: + pass print("WIFI: connecting to %s" % ssid) @@ -35,14 +68,15 @@ def _connect_wifi(dongle_id, pw, insecure_okay=False): if sys.platform == "darwin": os.system("networksetup -setairportnetwork en0 %s %s" % (ssid, pw)) else: - wlan_interface = subprocess.check_output(["sh", "-c", "iw dev | awk '/Interface/ {print $2}'"]).strip() + wlan_interface = subprocess.check_output(["sh", "-c", "iw dev | awk '/Interface/ {print $2}'"]).strip().decode('utf8') cnt = 0 MAX_TRIES = 10 while cnt < MAX_TRIES: - print "WIFI: scanning %d" % cnt - os.system("sudo iwlist %s scanning > /dev/null" % wlan_interface) + print("WIFI: scanning %d" % cnt) + os.system("iwlist %s scanning > /dev/null" % wlan_interface) os.system("nmcli device wifi rescan") - wifi_scan = filter(lambda x: ssid in x, subprocess.check_output(["nmcli","dev", "wifi", "list"]).split("\n")) + wifi_networks = [x.decode("utf8") for x in subprocess.check_output(["nmcli","dev", "wifi", "list"]).split(b"\n")] + wifi_scan = [x for x in wifi_networks if ssid in x] if len(wifi_scan) != 0: break time.sleep(0.1) @@ -51,45 +85,177 @@ def _connect_wifi(dongle_id, pw, insecure_okay=False): assert cnt < MAX_TRIES if "-pair" in wifi_scan[0]: os.system("nmcli d wifi connect %s-pair" % (ssid)) + connect_cnt = 0 + MAX_TRIES = 100 + while connect_cnt < MAX_TRIES: + connect_cnt += 1 + r = subprocess.call(["ping", "-W", "4", "-c", "1", "192.168.0.10"], stdout=FNULL, stderr=subprocess.STDOUT) + if r: + print("Waiting for panda to ping...") + time.sleep(0.5) + else: + break if insecure_okay: break # fetch webpage - print "connecting to insecure network to secure" - r = requests.get("http://192.168.0.10/") + print("connecting to insecure network to secure") + try: + r = requests.get("http://192.168.0.10/") + except requests.ConnectionError: + r = requests.get("http://192.168.0.10/") assert r.status_code==200 - print "securing" + print("securing") try: r = requests.get("http://192.168.0.10/secure", timeout=0.01) except requests.exceptions.Timeout: + print("timeout http request to secure") pass else: - os.system("nmcli d wifi connect %s password %s" % (ssid, pw)) - break - + ret = os.system("nmcli d wifi connect %s password %s" % (ssid, pw)) + if os.WEXITSTATUS(ret) == 0: + #check ping too + ping_ok = False + connect_cnt = 0 + MAX_TRIES = 10 + while connect_cnt < MAX_TRIES: + connect_cnt += 1 + r = subprocess.call(["ping", "-W", "4", "-c", "1", "192.168.0.10"], stdout=FNULL, stderr=subprocess.STDOUT) + if r: + print("Waiting for panda to ping...") + time.sleep(0.1) + else: + ping_ok = True + break + if ping_ok: + break + # TODO: confirm that it's connected to the right panda -def time_many_sends(p, bus, precv=None, msg_count=100, msg_id=None): +def time_many_sends(p, bus, precv=None, msg_count=100, msg_id=None, two_pandas=False): if precv == None: precv = p if msg_id == None: msg_id = random.randint(0x100, 0x200) + if p == precv and two_pandas: + raise ValueError("Cannot have two pandas that are the same panda") st = time.time() - p.can_send_many([(msg_id, 0, "\xaa"*8, bus)]*msg_count) + p.can_send_many([(msg_id, 0, b"\xaa"*8, bus)]*msg_count) r = [] + r_echo = [] + r_len_expected = msg_count if two_pandas else msg_count*2 + r_echo_len_exected = msg_count if two_pandas else 0 - while len(r) < (msg_count*2) and (time.time() - st) < 3: + while len(r) < r_len_expected and (time.time() - st) < 5: r.extend(precv.can_recv()) + et = time.time() + if two_pandas: + while len(r_echo) < r_echo_len_exected and (time.time() - st) < 10: + r_echo.extend(p.can_recv()) - sent_echo = filter(lambda x: x[3] == 0x80 | bus and x[0] == msg_id, r) - loopback_resp = filter(lambda x: x[3] == bus and x[0] == msg_id, r) + sent_echo = [x for x in r if x[3] == 0x80 | bus and x[0] == msg_id] + sent_echo.extend([x for x in r_echo if x[3] == 0x80 | bus and x[0] == msg_id]) + resp = [x for x in r if x[3] == bus and x[0] == msg_id] + leftovers = [x for x in r if (x[3] != 0x80 | bus and x[3] != bus) or x[0] != msg_id] + assert_equal(len(leftovers), 0) + + assert_equal(len(resp), msg_count) assert_equal(len(sent_echo), msg_count) - assert_equal(len(loopback_resp), msg_count) - et = (time.time()-st)*1000.0 + et = (et-st)*1000.0 comp_kbps = (1+11+1+1+1+4+8*8+15+1+1+1+7)*msg_count / et return comp_kbps +_panda_serials = None +def panda_type_to_serial(fn): + @wraps(fn) + def wrapper(panda_type=None, **kwargs): + # Change panda_types to a list + if panda_type is not None: + if not isinstance(panda_type, list): + panda_type = [panda_type] + + # If not done already, get panda serials and their type + global _panda_serials + if _panda_serials == None: + _panda_serials = [] + for serial in Panda.list(): + p = Panda(serial=serial) + _panda_serials.append((serial, p.get_type())) + p.close() + + # Find a panda with the correct types and add the corresponding serial + serials = [] + for p_type in panda_type: + found = False + for serial, pt in _panda_serials: + # Never take the same panda twice + if (pt == p_type) and (serial not in serials): + serials.append(serial) + found = True + break + if not found: + raise IOError("No unused panda found for type: {}".format(p_type)) + return fn(serials, **kwargs) + return wrapper + +def heartbeat_thread(p): + while True: + try: + p.send_heartbeat() + time.sleep(1) + except: + break + +def panda_connect_and_init(fn): + @wraps(fn) + def wrapper(panda_serials=None, **kwargs): + # Change panda_serials to a list + if panda_serials is not None: + if not isinstance(panda_serials, list): + panda_serials = [panda_serials] + + # Connect to pandas + pandas = [] + for panda_serial in panda_serials: + pandas.append(Panda(serial=panda_serial)) + + # Initialize pandas + for panda in pandas: + panda.set_can_loopback(False) + panda.set_gmlan(None) + panda.set_esp_power(False) + for bus, speed in [(0, SPEED_NORMAL), (1, SPEED_NORMAL), (2, SPEED_NORMAL), (3, SPEED_GMLAN)]: + panda.set_can_speed_kbps(bus, speed) + clear_can_buffers(panda) + _thread.start_new_thread(heartbeat_thread, (panda,)) + + # Run test function + ret = fn(*pandas, **kwargs) + + # Close all connections + for panda in pandas: + panda.close() + + # Return test function result + return ret + return wrapper + +def clear_can_buffers(panda): + # clear tx buffers + for i in range(4): + panda.can_clear(i) + + # clear rx buffers + panda.can_clear(0xFFFF) + r = [1] + st = time.time() + while len(r) > 0: + r = panda.can_recv() + time.sleep(0.05) + if (time.time() - st) > 10: + print("Unable to clear can buffers for panda ", panda.get_serial()) + assert False diff --git a/panda/tests/black_loopback_test.py b/panda/tests/black_loopback_test.py new file mode 100755 index 00000000000000..5fe0c48077e238 --- /dev/null +++ b/panda/tests/black_loopback_test.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 + +# Loopback test between two black pandas (+ harness and power) +# Tests all buses, including OBD CAN, which is on the same bus as CAN0 in this test. +# To be sure, the test should be run with both harness orientations + + +import os +import sys +import time +import random +import argparse + +sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..")) +from panda import Panda + +def get_test_string(): + return b"test"+os.urandom(10) + +def run_test(sleep_duration): + pandas = Panda.list() + print(pandas) + + # make sure two pandas are connected + if len(pandas) != 2: + print("Connect white/grey and black panda to run this test!") + assert False + + # connect + pandas[0] = Panda(pandas[0]) + pandas[1] = Panda(pandas[1]) + + # find out the hardware types + if not pandas[0].is_black() or not pandas[1].is_black(): + print("Connect two black pandas to run this test!") + assert False + + for panda in pandas: + # disable safety modes + panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + + # test health packet + print("panda health", panda.health()) + + # setup test array (send bus, sender obd, reciever obd, expected busses) + test_array = [ + (0, False, False, [0]), + (1, False, False, [1]), + (2, False, False, [2]), + (0, False, True, [0, 1]), + (1, False, True, []), + (2, False, True, [2]), + (0, True, False, [0]), + (1, True, False, [0]), + (2, True, False, [2]), + (0, True, True, [0, 1]), + (1, True, True, [0, 1]), + (2, True, True, [2]) + ] + + # test both orientations + print("***************** TESTING (0 --> 1) *****************") + test_buses(pandas[0], pandas[1], test_array, sleep_duration) + print("***************** TESTING (1 --> 0) *****************") + test_buses(pandas[1], pandas[0], test_array, sleep_duration) + + +def test_buses(send_panda, recv_panda, test_array, sleep_duration): + for send_bus, send_obd, recv_obd, recv_buses in test_array: + send_panda.send_heartbeat() + recv_panda.send_heartbeat() + print("\nSend bus:", send_bus, " Send OBD:", send_obd, " Recv OBD:", recv_obd) + + # set OBD on pandas + send_panda.set_gmlan(True if send_obd else None) + recv_panda.set_gmlan(True if recv_obd else None) + + # clear and flush + send_panda.can_clear(send_bus) + for recv_bus in recv_buses: + recv_panda.can_clear(recv_bus) + send_panda.can_recv() + recv_panda.can_recv() + + # send the characters + at = random.randint(1, 2000) + st = get_test_string()[0:8] + send_panda.can_send(at, st, send_bus) + time.sleep(0.1) + + # check for receive + _ = send_panda.can_recv() # cans echo + cans_loop = recv_panda.can_recv() + + loop_buses = [] + for loop in cans_loop: + print(" Loop on bus", str(loop[3])) + loop_buses.append(loop[3]) + if len(cans_loop) == 0: + print(" No loop") + + # test loop buses + recv_buses.sort() + loop_buses.sort() + assert recv_buses == loop_buses + print(" TEST PASSED") + + time.sleep(sleep_duration) + print("\n") + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("-n", type=int, help="Number of test iterations to run") + parser.add_argument("-sleep", type=int, help="Sleep time between tests", default=0) + args = parser.parse_args() + + if args.n is None: + while True: + run_test(sleep_duration=args.sleep) + else: + for i in range(args.n): + run_test(sleep_duration=args.sleep) diff --git a/panda/tests/black_white_loopback_test.py b/panda/tests/black_white_loopback_test.py new file mode 100755 index 00000000000000..66c5e80f452ad6 --- /dev/null +++ b/panda/tests/black_white_loopback_test.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 + +# Loopback test between black panda (+ harness and power) and white/grey panda +# Tests all buses, including OBD CAN, which is on the same bus as CAN0 in this test. +# To be sure, the test should be run with both harness orientations + + +import os +import sys +import time +import random +import argparse + +sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..")) +from panda import Panda + +def get_test_string(): + return b"test"+os.urandom(10) + +counter = 0 +nonzero_bus_errors = 0 +zero_bus_errors = 0 +content_errors = 0 + +def run_test(sleep_duration): + global counter, nonzero_bus_errors, zero_bus_errors, content_errors + + pandas = Panda.list() + print(pandas) + + # make sure two pandas are connected + if len(pandas) != 2: + print("Connect white/grey and black panda to run this test!") + assert False + + # connect + pandas[0] = Panda(pandas[0]) + pandas[1] = Panda(pandas[1]) + + black_panda = None + other_panda = None + + # find out which one is black + if pandas[0].is_black() and not pandas[1].is_black(): + black_panda = pandas[0] + other_panda = pandas[1] + elif not pandas[0].is_black() and pandas[1].is_black(): + black_panda = pandas[1] + other_panda = pandas[0] + else: + print("Connect white/grey and black panda to run this test!") + assert False + + # disable safety modes + black_panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + other_panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + + # test health packet + print("black panda health", black_panda.health()) + print("other panda health", other_panda.health()) + + # test black -> other + while True: + test_buses(black_panda, other_panda, True, [(0, False, [0]), (1, False, [1]), (2, False, [2]), (1, True, [0])], sleep_duration) + test_buses(black_panda, other_panda, False, [(0, False, [0]), (1, False, [1]), (2, False, [2]), (0, True, [0, 1])], sleep_duration) + counter += 1 + print("Number of cycles:", counter, "Non-zero bus errors:", nonzero_bus_errors, "Zero bus errors:", zero_bus_errors, "Content errors:", content_errors) + + # Toggle relay + black_panda.set_safety_mode(Panda.SAFETY_NOOUTPUT) + time.sleep(1) + black_panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + time.sleep(1) + + +def test_buses(black_panda, other_panda, direction, test_array, sleep_duration): + global nonzero_bus_errors, zero_bus_errors, content_errors + + if direction: + print("***************** TESTING (BLACK --> OTHER) *****************") + else: + print("***************** TESTING (OTHER --> BLACK) *****************") + + for send_bus, obd, recv_buses in test_array: + black_panda.send_heartbeat() + other_panda.send_heartbeat() + print("\ntest can: ", send_bus, " OBD: ", obd) + + # set OBD on black panda + black_panda.set_gmlan(True if obd else None) + + # clear and flush + if direction: + black_panda.can_clear(send_bus) + else: + other_panda.can_clear(send_bus) + + for recv_bus in recv_buses: + if direction: + other_panda.can_clear(recv_bus) + else: + black_panda.can_clear(recv_bus) + + black_panda.can_recv() + other_panda.can_recv() + + # send the characters + at = random.randint(1, 2000) + st = get_test_string()[0:8] + if direction: + black_panda.can_send(at, st, send_bus) + else: + other_panda.can_send(at, st, send_bus) + time.sleep(0.1) + + # check for receive + if direction: + _ = black_panda.can_recv() # can echo + cans_loop = other_panda.can_recv() + else: + _ = other_panda.can_recv() # can echo + cans_loop = black_panda.can_recv() + + loop_buses = [] + for loop in cans_loop: + if (loop[0] != at) or (loop[2] != st): + content_errors += 1 + + print(" Loop on bus", str(loop[3])) + loop_buses.append(loop[3]) + if len(cans_loop) == 0: + print(" No loop") + if not os.getenv("NOASSERT"): + assert False + + # test loop buses + recv_buses.sort() + loop_buses.sort() + if(recv_buses != loop_buses): + if len(loop_buses) == 0: + zero_bus_errors += 1 + else: + nonzero_bus_errors += 1 + if not os.getenv("NOASSERT"): + assert False + else: + print(" TEST PASSED") + + time.sleep(sleep_duration) + print("\n") + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("-n", type=int, help="Number of test iterations to run") + parser.add_argument("-sleep", type=int, help="Sleep time between tests", default=0) + args = parser.parse_args() + + if args.n is None: + while True: + run_test(sleep_duration=args.sleep) + else: + for i in range(args.n): + run_test(sleep_duration=args.sleep) diff --git a/panda/tests/black_white_relay_endurance.py b/panda/tests/black_white_relay_endurance.py new file mode 100755 index 00000000000000..6970966526c7bc --- /dev/null +++ b/panda/tests/black_white_relay_endurance.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 + +# Loopback test between black panda (+ harness and power) and white/grey panda +# Tests all buses, including OBD CAN, which is on the same bus as CAN0 in this test. +# To be sure, the test should be run with both harness orientations + + +import os +import sys +import time +import random +import argparse + +sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..")) +from panda import Panda + +def get_test_string(): + return b"test"+os.urandom(10) + +counter = 0 +nonzero_bus_errors = 0 +zero_bus_errors = 0 +content_errors = 0 + +def run_test(sleep_duration): + global counter, nonzero_bus_errors, zero_bus_errors, content_errors + + pandas = Panda.list() + print(pandas) + + # make sure two pandas are connected + if len(pandas) != 2: + print("Connect white/grey and black panda to run this test!") + assert False + + # connect + pandas[0] = Panda(pandas[0]) + pandas[1] = Panda(pandas[1]) + + black_panda = None + other_panda = None + + # find out which one is black + if pandas[0].is_black() and not pandas[1].is_black(): + black_panda = pandas[0] + other_panda = pandas[1] + elif not pandas[0].is_black() and pandas[1].is_black(): + black_panda = pandas[1] + other_panda = pandas[0] + else: + print("Connect white/grey and black panda to run this test!") + assert False + + # disable safety modes + black_panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + other_panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + + # test health packet + print("black panda health", black_panda.health()) + print("other panda health", other_panda.health()) + + # test black -> other + start_time = time.time() + temp_start_time = start_time + while True: + test_buses(black_panda, other_panda, True, [(0, False, [0]), (1, False, [1]), (2, False, [2]), (1, True, [0])], sleep_duration) + test_buses(black_panda, other_panda, False, [(0, False, [0]), (1, False, [1]), (2, False, [2]), (0, True, [0, 1])], sleep_duration) + counter += 1 + + runtime = time.time() - start_time + print("Number of cycles:", counter, "Non-zero bus errors:", nonzero_bus_errors, "Zero bus errors:", zero_bus_errors, "Content errors:", content_errors, "Runtime: ", runtime) + + if (time.time() - temp_start_time) > 3600*6: + # Toggle relay + black_panda.set_safety_mode(Panda.SAFETY_NOOUTPUT) + time.sleep(1) + black_panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + time.sleep(1) + temp_start_time = time.time() + + +def test_buses(black_panda, other_panda, direction, test_array, sleep_duration): + global nonzero_bus_errors, zero_bus_errors, content_errors + + if direction: + print("***************** TESTING (BLACK --> OTHER) *****************") + else: + print("***************** TESTING (OTHER --> BLACK) *****************") + + for send_bus, obd, recv_buses in test_array: + black_panda.send_heartbeat() + other_panda.send_heartbeat() + print("\ntest can: ", send_bus, " OBD: ", obd) + + # set OBD on black panda + black_panda.set_gmlan(True if obd else None) + + # clear and flush + if direction: + black_panda.can_clear(send_bus) + else: + other_panda.can_clear(send_bus) + + for recv_bus in recv_buses: + if direction: + other_panda.can_clear(recv_bus) + else: + black_panda.can_clear(recv_bus) + + black_panda.can_recv() + other_panda.can_recv() + + # send the characters + at = random.randint(1, 2000) + st = get_test_string()[0:8] + if direction: + black_panda.can_send(at, st, send_bus) + else: + other_panda.can_send(at, st, send_bus) + time.sleep(0.1) + + # check for receive + if direction: + _ = black_panda.can_recv() # cans echo + cans_loop = other_panda.can_recv() + else: + _ = other_panda.can_recv() # cans echo + cans_loop = black_panda.can_recv() + + loop_buses = [] + for loop in cans_loop: + if (loop[0] != at) or (loop[2] != st): + content_errors += 1 + + print(" Loop on bus", str(loop[3])) + loop_buses.append(loop[3]) + if len(cans_loop) == 0: + print(" No loop") + if not os.getenv("NOASSERT"): + assert False + + # test loop buses + recv_buses.sort() + loop_buses.sort() + if(recv_buses != loop_buses): + if len(loop_buses) == 0: + zero_bus_errors += 1 + else: + nonzero_bus_errors += 1 + if not os.getenv("NOASSERT"): + assert False + else: + print(" TEST PASSED") + + time.sleep(sleep_duration) + print("\n") + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("-n", type=int, help="Number of test iterations to run") + parser.add_argument("-sleep", type=int, help="Sleep time between tests", default=0) + args = parser.parse_args() + + if args.n is None: + while True: + run_test(sleep_duration=args.sleep) + else: + for i in range(args.n): + run_test(sleep_duration=args.sleep) diff --git a/panda/tests/black_white_relay_test.py b/panda/tests/black_white_relay_test.py new file mode 100755 index 00000000000000..d80490f7d465da --- /dev/null +++ b/panda/tests/black_white_relay_test.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 + +# Relay test with loopback between black panda (+ harness and power) and white/grey panda +# Tests the relay switching multiple times / second by looking at the buses on which loop occurs. + + +import os +import sys +import time +import random +import argparse + +sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..")) +from panda import Panda + +def get_test_string(): + return b"test"+os.urandom(10) + +counter = 0 +open_errors = 0 +closed_errors = 0 +content_errors = 0 + +def run_test(sleep_duration): + global counter, open_errors, closed_errors, content_errors + + pandas = Panda.list() + #pandas = ["540046000c51363338383037", "07801b800f51363038363036"] + print(pandas) + + # make sure two pandas are connected + if len(pandas) != 2: + print("Connect white/grey and black panda to run this test!") + assert False + + # connect + pandas[0] = Panda(pandas[0]) + pandas[1] = Panda(pandas[1]) + + # find out which one is black + type0 = pandas[0].get_type() + type1 = pandas[1].get_type() + + black_panda = None + other_panda = None + + if type0 == "\x03" and type1 != "\x03": + black_panda = pandas[0] + other_panda = pandas[1] + elif type0 != "\x03" and type1 == "\x03": + black_panda = pandas[1] + other_panda = pandas[0] + else: + print("Connect white/grey and black panda to run this test!") + assert False + + # disable safety modes + black_panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + other_panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + + # test health packet + print("black panda health", black_panda.health()) + print("other panda health", other_panda.health()) + + # test black -> other + while True: + # Switch on relay + black_panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + time.sleep(0.05) + + if not test_buses(black_panda, other_panda, (0, False, [0])): + open_errors += 1 + print("Open error") + assert False + + # Switch off relay + black_panda.set_safety_mode(Panda.SAFETY_NOOUTPUT) + time.sleep(0.05) + + if not test_buses(black_panda, other_panda, (0, False, [0, 2])): + closed_errors += 1 + print("Close error") + assert False + + counter += 1 + print("Number of cycles:", counter, "Open errors:", open_errors, "Closed errors:", closed_errors, "Content errors:", content_errors) + +def test_buses(black_panda, other_panda, test_obj): + global content_errors + send_bus, obd, recv_buses = test_obj + + black_panda.send_heartbeat() + other_panda.send_heartbeat() + + # Set OBD on send panda + other_panda.set_gmlan(True if obd else None) + + # clear and flush + other_panda.can_clear(send_bus) + + for recv_bus in recv_buses: + black_panda.can_clear(recv_bus) + + black_panda.can_recv() + other_panda.can_recv() + + # send the characters + at = random.randint(1, 2000) + st = get_test_string()[0:8] + other_panda.can_send(at, st, send_bus) + time.sleep(0.05) + + # check for receive + _ = other_panda.can_recv() # can echo + cans_loop = black_panda.can_recv() + + loop_buses = [] + for loop in cans_loop: + if (loop[0] != at) or (loop[2] != st): + content_errors += 1 + loop_buses.append(loop[3]) + + # test loop buses + recv_buses.sort() + loop_buses.sort() + if(recv_buses != loop_buses): + return False + else: + return True + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("-n", type=int, help="Number of test iterations to run") + parser.add_argument("-sleep", type=int, help="Sleep time between tests", default=0) + args = parser.parse_args() + + if args.n is None: + while True: + run_test(sleep_duration=args.sleep) + else: + for i in range(args.n): + run_test(sleep_duration=args.sleep) diff --git a/panda/tests/build/Dockerfile b/panda/tests/build/Dockerfile index 276a25ed0b9495..0f982160beb8de 100644 --- a/panda/tests/build/Dockerfile +++ b/panda/tests/build/Dockerfile @@ -1,6 +1,19 @@ FROM ubuntu:16.04 -RUN apt-get update && apt-get install -y gcc-arm-none-eabi libnewlib-arm-none-eabi python python-pip gcc g++ git autoconf gperf bison flex automake texinfo wget help2man gawk libtool libtool-bin ncurses-dev unzip unrar-free libexpat-dev sed bzip2 +RUN apt-get update && apt-get install -y gcc-arm-none-eabi libnewlib-arm-none-eabi python python-pip gcc g++ git autoconf gperf bison flex automake texinfo wget help2man gawk libtool libtool-bin ncurses-dev unzip unrar-free libexpat-dev sed bzip2 locales curl zlib1g-dev libffi-dev libssl-dev + +RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash + +ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}" +RUN pyenv install 2.7.12 +RUN pyenv install 3.7.3 +RUN pyenv global 3.7.3 +RUN pyenv rehash RUN pip install pycrypto==2.6.1 @@ -10,7 +23,8 @@ WORKDIR /panda/boardesp RUN git clone --recursive https://github.com/pfalcon/esp-open-sdk.git WORKDIR /panda/boardesp/esp-open-sdk RUN git checkout 03f5e898a059451ec5f3de30e7feff30455f7ce -RUN CT_ALLOW_BUILD_AS_ROOT_SURE=1 make STANDALONE=y +COPY ./boardesp/python2_make.py /panda/boardesp/esp-open-sdk +RUN python2 python2_make.py "CT_ALLOW_BUILD_AS_ROOT_SURE=1 make STANDALONE=y" COPY . /panda diff --git a/panda/tests/can_printer.py b/panda/tests/can_printer.py index e863889c16424b..c8bbc3f18442b7 100755 --- a/panda/tests/can_printer.py +++ b/panda/tests/can_printer.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python -from __future__ import print_function +#!/usr/bin/env python3 + import os import sys import time @@ -15,7 +15,7 @@ def sec_since_boot(): def can_printer(): p = Panda() - p.set_safety_mode(0x1337) + p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) start = sec_since_boot() lp = sec_since_boot() @@ -30,7 +30,7 @@ def can_printer(): if sec_since_boot() - lp > 0.1: dd = chr(27) + "[2J" dd += "%5.2f\n" % (sec_since_boot() - start) - for k,v in sorted(zip(msgs.keys(), map(lambda x: binascii.hexlify(x[-1]), msgs.values()))): + for k,v in sorted(zip(list(msgs.keys()), [binascii.hexlify(x[-1]) for x in list(msgs.values())])): dd += "%s(%6d) %s\n" % ("%04X(%4d)" % (k,k),len(msgs[k]), v) print(dd) lp = sec_since_boot() diff --git a/panda/tests/debug_console.py b/panda/tests/debug_console.py index f4db77f091e0da..8e66946dd4d8db 100755 --- a/panda/tests/debug_console.py +++ b/panda/tests/debug_console.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python -from __future__ import print_function +#!/usr/bin/env python3 + import os import sys import time @@ -12,30 +12,38 @@ unsetcolor = "\033[00m" if __name__ == "__main__": - port_number = int(os.getenv("PORT", 0)) - claim = os.getenv("CLAIM") is not None + while True: + try: + port_number = int(os.getenv("PORT", 0)) + claim = os.getenv("CLAIM") is not None - serials = Panda.list() - if os.getenv("SERIAL"): - serials = filter(lambda x: x==os.getenv("SERIAL"), serials) + serials = Panda.list() + if os.getenv("SERIAL"): + serials = [x for x in serials if x==os.getenv("SERIAL")] - pandas = list(map(lambda x: Panda(x, claim=claim), serials)) + pandas = list([Panda(x, claim=claim) for x in serials]) - if os.getenv("BAUD") is not None: - for panda in pandas: - panda.set_uart_baud(port_number, int(os.getenv("BAUD"))) + if not len(pandas): + sys.exit("no pandas found") + + if os.getenv("BAUD") is not None: + for panda in pandas: + panda.set_uart_baud(port_number, int(os.getenv("BAUD"))) - while True: - for i, panda in enumerate(pandas): while True: - ret = panda.serial_read(port_number) - if len(ret) > 0: - sys.stdout.write(setcolor[i] + str(ret) + unsetcolor) - sys.stdout.flush() - else: - break - if select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], []): - ln = sys.stdin.readline() - if claim: - panda.serial_write(port_number, ln) - time.sleep(0.01) + for i, panda in enumerate(pandas): + while True: + ret = panda.serial_read(port_number) + if len(ret) > 0: + sys.stdout.write(setcolor[i] + ret.decode('ascii') + unsetcolor) + sys.stdout.flush() + else: + break + if select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], []): + ln = sys.stdin.readline() + if claim: + panda.serial_write(port_number, ln) + time.sleep(0.01) + except: + print("panda disconnected!") + time.sleep(0.5); diff --git a/panda/tests/disable_esp.py b/panda/tests/disable_esp.py index abebd9c17b8a5d..ce1dd6db2eec36 100755 --- a/panda/tests/disable_esp.py +++ b/panda/tests/disable_esp.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from panda import Panda Panda().set_esp_power(False) diff --git a/panda/tests/elm_car_simulator.py b/panda/tests/elm_car_simulator.py index f931e66ff40999..01b79c88404e48 100755 --- a/panda/tests/elm_car_simulator.py +++ b/panda/tests/elm_car_simulator.py @@ -1,6 +1,6 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """Used to Reverse/Test ELM protocol auto detect and OBD message response without a car.""" -from __future__ import print_function + import sys import os import struct @@ -109,9 +109,9 @@ def _lin_send(self, to_addr, msg): print(" LIN Reply (%x)" % to_addr, binascii.hexlify(msg)) PHYS_ADDR = 0x80 - FUNC_ADDR = 0xC0 + #FUNC_ADDR = 0xC0 RECV = 0xF1 - SEND = 0x33 # Car OBD Functional Address + #SEND = 0x33 # Car OBD Functional Address headers = struct.pack("BBB", PHYS_ADDR | len(msg), RECV, to_addr) if not self.__silent: print(" Sending LIN", binascii.hexlify(headers+msg), @@ -172,7 +172,7 @@ def __can_monitor(self): while not self.__stop: for address, ts, data, src in self.panda.can_recv(): - if self.__on and src is 0 and len(data) == 8 and data[0] >= 2: + if self.__on and src == 0 and len(data) == 8 and data[0] >= 2: if not self.__silent: print("Processing CAN message", src, hex(address), binascii.hexlify(data)) self.__can_process_msg(data[1], data[2], address, ts, data, src) diff --git a/panda/tests/elm_throughput.py b/panda/tests/elm_throughput.py index 39625728899a74..2895b0926119d9 100755 --- a/panda/tests/elm_throughput.py +++ b/panda/tests/elm_throughput.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python -from __future__ import print_function +#!/usr/bin/env python3 + import socket import threading import select diff --git a/panda/tests/elm_wifi.py b/panda/tests/elm_wifi.py index f5a8849833df60..b0645ea8898d22 100644 --- a/panda/tests/elm_wifi.py +++ b/panda/tests/elm_wifi.py @@ -1,16 +1,14 @@ -from __future__ import print_function import os import sys import time import socket import select -import pytest import struct sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..")) -import elm_car_simulator sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "..")) from panda import Panda +from panda.tests import elm_car_simulator def elm_connect(): s = socket.create_connection(("192.168.0.10", 35000)) @@ -234,35 +232,35 @@ def test_elm_send_lin_multiline_msg(): send_compare(s, b'0902\r', # headers OFF, Spaces ON b"BUS INIT: OK\r" - "49 02 01 00 00 00 31 \r" - "49 02 02 44 34 47 50 \r" - "49 02 03 30 30 52 35 \r" - "49 02 04 35 42 31 32 \r" - "49 02 05 33 34 35 36 \r\r>") + b"49 02 01 00 00 00 31 \r" + b"49 02 02 44 34 47 50 \r" + b"49 02 03 30 30 52 35 \r" + b"49 02 04 35 42 31 32 \r" + b"49 02 05 33 34 35 36 \r\r>") send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces OFF send_compare(s, b'0902\r', # Headers OFF, Spaces OFF b"49020100000031\r" - "49020244344750\r" - "49020330305235\r" - "49020435423132\r" - "49020533343536\r\r>") + b"49020244344750\r" + b"49020330305235\r" + b"49020435423132\r" + b"49020533343536\r\r>") send_compare(s, b'ATH1\r', b'OK\r\r>') # Headers ON send_compare(s, b'0902\r', # Headers ON, Spaces OFF b"87F1104902010000003105\r" - "87F11049020244344750E4\r" - "87F11049020330305235BD\r" - "87F11049020435423132B1\r" - "87F11049020533343536AA\r\r>") + b"87F11049020244344750E4\r" + b"87F11049020330305235BD\r" + b"87F11049020435423132B1\r" + b"87F11049020533343536AA\r\r>") send_compare(s, b'ATS1\r', b'OK\r\r>') # Spaces ON send_compare(s, b'0902\r', # Headers ON, Spaces ON b"87 F1 10 49 02 01 00 00 00 31 05 \r" - "87 F1 10 49 02 02 44 34 47 50 E4 \r" - "87 F1 10 49 02 03 30 30 52 35 BD \r" - "87 F1 10 49 02 04 35 42 31 32 B1 \r" - "87 F1 10 49 02 05 33 34 35 36 AA \r\r>") + b"87 F1 10 49 02 02 44 34 47 50 E4 \r" + b"87 F1 10 49 02 03 30 30 52 35 BD \r" + b"87 F1 10 49 02 04 35 42 31 32 B1 \r" + b"87 F1 10 49 02 05 33 34 35 36 AA \r\r>") finally: sim.stop() sim.join() @@ -301,7 +299,7 @@ def test_elm_panda_safety_mode_KWPFast(): p_car.kline_drain() p_elm = Panda("WIFI") - p_elm.set_safety_mode(0xE327); + p_elm.set_safety_mode(Panda.SAFETY_ELM327); def get_checksum(dat): result = 0 @@ -322,7 +320,7 @@ def timed_recv_check(p, bus, goodmsg): def kline_send(p, x, bus=2): p.kline_drain(bus=bus) - p._handle.bulkWrite(2, chr(bus).encode()+x) + p._handle.bulkWrite(2, bytes([bus]) + x) return timed_recv_check(p, bus, x) def did_send(priority, toaddr, fromaddr, dat, bus=2, checkbyte=None): @@ -461,7 +459,7 @@ def test_elm_send_can_multimsg(): sim.can_add_extra_noise(b'\x03\x41\x0D\xFA', addr=0x7E9)# Inject message into the stream send_compare(s, b'010D\r', b"7E8 03 41 0D 53 \r" - "7E9 03 41 0D FA \r\r>") # Check it was ignored. + b"7E9 03 41 0D FA \r\r>") # Check it was ignored. finally: sim.stop() sim.join() @@ -503,28 +501,28 @@ def test_elm_send_can_multiline_msg(): send_compare(s, b'0902\r', # headers OFF, Spaces ON b"014 \r" - "0: 49 02 01 31 44 34 \r" - "1: 47 50 30 30 52 35 35 \r" - "2: 42 31 32 33 34 35 36 \r\r>") + b"0: 49 02 01 31 44 34 \r" + b"1: 47 50 30 30 52 35 35 \r" + b"2: 42 31 32 33 34 35 36 \r\r>") send_compare(s, b'ATS0\r', b'OK\r\r>') # Spaces OFF send_compare(s, b'0902\r', # Headers OFF, Spaces OFF b"014\r" - "0:490201314434\r" - "1:47503030523535\r" - "2:42313233343536\r\r>") + b"0:490201314434\r" + b"1:47503030523535\r" + b"2:42313233343536\r\r>") send_compare(s, b'ATH1\r', b'OK\r\r>') # Headers ON send_compare(s, b'0902\r', # Headers ON, Spaces OFF b"7E81014490201314434\r" - "7E82147503030523535\r" - "7E82242313233343536\r\r>") + b"7E82147503030523535\r" + b"7E82242313233343536\r\r>") send_compare(s, b'ATS1\r', b'OK\r\r>') # Spaces ON send_compare(s, b'0902\r', # Headers ON, Spaces ON b"7E8 10 14 49 02 01 31 44 34 \r" - "7E8 21 47 50 30 30 52 35 35 \r" - "7E8 22 42 31 32 33 34 35 36 \r\r>") + b"7E8 21 47 50 30 30 52 35 35 \r" + b"7E8 22 42 31 32 33 34 35 36 \r\r>") finally: sim.stop() sim.join() @@ -625,7 +623,7 @@ def test_elm_panda_safety_mode_ISO15765(): p_car.set_safety_mode(Panda.SAFETY_ALLOUTPUT) p_elm = Panda("WIFI") - p_elm.set_safety_mode(0xE327); + p_elm.set_safety_mode(Panda.SAFETY_ELM327); #sim = elm_car_simulator.ELMCarSimulator(serial, lin=False) #sim.start() diff --git a/panda/tests/fan_test.py b/panda/tests/fan_test.py new file mode 100755 index 00000000000000..73856988281b19 --- /dev/null +++ b/panda/tests/fan_test.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +import os +import sys +import time + +sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..")) +from panda import Panda + +power = 0 +if __name__ == "__main__": + p = Panda() + while True: + p.set_fan_power(power) + time.sleep(5) + print("Power: ", power, "RPM: ", str(p.get_fan_rpm())) + power += 10 + power %=100 diff --git a/panda/tests/get_version.py b/panda/tests/get_version.py index 0cd7795fdcc71d..73e51e1f0df2ab 100755 --- a/panda/tests/get_version.py +++ b/panda/tests/get_version.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from panda import Panda if __name__ == "__main__": diff --git a/panda/tests/gmbitbang/recv.py b/panda/tests/gmbitbang/recv.py index 6eb70aa4ad3abb..3949c424d9ef36 100755 --- a/panda/tests/gmbitbang/recv.py +++ b/panda/tests/gmbitbang/recv.py @@ -1,17 +1,16 @@ -#!/usr/bin/env python -import time +#!/usr/bin/env python3 from panda import Panda p = Panda() p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) p.set_gmlan(bus=2) -#p.can_send(0xaaa, "\x00\x00", bus=3) +#p.can_send(0xaaa, b"\x00\x00", bus=3) last_add = None while 1: ret = p.can_recv() if len(ret) > 0: add = ret[0][0] - if last_add is not None and add != last_add+1: - print "MISS %d %d" % (last_add, add) + if last_add is not None and add != last_add + 1: + print("MISS: ", last_add, add) last_add = add - print ret + print(ret) diff --git a/panda/tests/gmbitbang/rigol.py b/panda/tests/gmbitbang/rigol.py index 3d690fdd84c725..5fcdf243ecd4d7 100755 --- a/panda/tests/gmbitbang/rigol.py +++ b/panda/tests/gmbitbang/rigol.py @@ -1,10 +1,11 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 +# pylint: skip-file import numpy as np import visa import matplotlib.pyplot as plt resources = visa.ResourceManager() -print resources.list_resources() +print(resources.list_resources()) scope = resources.open_resource('USB0::0x1AB1::0x04CE::DS1ZA184652242::INSTR', timeout=2000, chunk_size=1024000) print(scope.query('*IDN?').strip()) @@ -17,7 +18,7 @@ scope.write(":WAV:DATA? CHAN1")[10:] rawdata = scope.read_raw() data = np.frombuffer(rawdata, 'B') -print data.shape +print(data.shape) s1 = data[0:650] s2 = data[650:] @@ -31,5 +32,5 @@ plt.show() #data = (data - 130.0 - voltoffset/voltscale*25) / 25 * voltscale -print data +print(data) diff --git a/panda/tests/gmbitbang/test.py b/panda/tests/gmbitbang/test.py index 652ac1ddd8ad24..0934c6442028cd 100755 --- a/panda/tests/gmbitbang/test.py +++ b/panda/tests/gmbitbang/test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import time from panda import Panda @@ -28,6 +28,6 @@ #p1.set_gmlan(bus=2) #p1.can_send(iden, dat, bus=3) time.sleep(0.01) - print p2.can_recv() + print(p2.can_recv()) #exit(0) diff --git a/panda/tests/gmbitbang/test_one.py b/panda/tests/gmbitbang/test_one.py index a398e2780385b1..635cd2c91f4a45 100755 --- a/panda/tests/gmbitbang/test_one.py +++ b/panda/tests/gmbitbang/test_one.py @@ -1,17 +1,17 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import time from panda import Panda p = Panda() p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) -# ack any crap on bus +# hack anything on bus p.set_gmlan(bus=2) time.sleep(0.1) while len(p.can_recv()) > 0: - print "clearing" + print("clearing") time.sleep(0.1) -print "cleared" +print("cleared") p.set_gmlan(bus=None) iden = 18000 diff --git a/panda/tests/gps_stability_test.py b/panda/tests/gps_stability_test.py new file mode 100755 index 00000000000000..529970e0f4e1fa --- /dev/null +++ b/panda/tests/gps_stability_test.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 + +import os +import sys +import time +import random +import threading + +sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..")) +from panda import Panda, PandaSerial + +INIT_GPS_BAUD = 9600 +GPS_BAUD = 460800 + +def connect(): + pandas = Panda.list() + print(pandas) + + # make sure two pandas are connected + if len(pandas) != 2: + print("Connect white and grey/black panda to run this test!") + assert False + + # connect + pandas[0] = Panda(pandas[0]) + pandas[1] = Panda(pandas[1]) + + white_panda = None + gps_panda = None + + # find out which one is white (for spamming the CAN buses) + if pandas[0].is_white() and not pandas[1].is_white(): + white_panda = pandas[0] + gps_panda = pandas[1] + elif not pandas[0].is_white() and pandas[1].is_white(): + white_panda = pandas[1] + gps_panda = pandas[0] + else: + print("Connect white and grey/black panda to run this test!") + assert False + return white_panda, gps_panda + +def spam_buses_thread(panda): + try: + panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + while True: + at = random.randint(1, 2000) + st = (b"test"+os.urandom(10))[0:8] + bus = random.randint(0, 2) + panda.can_send(at, st, bus) + except Exception as e: + print(e) + +def read_can_thread(panda): + try: + while True: + panda.can_recv() + except Exception as e: + print(e) + +def init_gps(panda): + def add_nmea_checksum(msg): + d = msg[1:] + cs = 0 + for i in d: + cs ^= ord(i) + return msg + "*%02X" % cs + + ser = PandaSerial(panda, 1, INIT_GPS_BAUD) + + # Power cycle the gps by toggling reset + print("Resetting GPS") + panda.set_esp_power(0) + time.sleep(0.5) + panda.set_esp_power(1) + time.sleep(0.5) + + # Upping baud rate + print("Upping GPS baud rate") + msg = str.encode(add_nmea_checksum("$PUBX,41,1,0007,0003,%d,0" % GPS_BAUD)+"\r\n") + ser.write(msg) + time.sleep(1) # needs a wait for it to actually send + + # Reconnecting with the correct baud + ser = PandaSerial(panda, 1, GPS_BAUD) + + # Sending all config messages boardd sends + print("Sending config") + ser.write(b"\xB5\x62\x06\x00\x14\x00\x03\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x1E\x7F") + ser.write(b"\xB5\x62\x06\x3E\x00\x00\x44\xD2") + ser.write(b"\xB5\x62\x06\x00\x14\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x35") + ser.write(b"\xB5\x62\x06\x00\x14\x00\x01\x00\x00\x00\xC0\x08\x00\x00\x00\x08\x07\x00\x01\x00\x01\x00\x00\x00\x00\x00\xF4\x80") + ser.write(b"\xB5\x62\x06\x00\x14\x00\x04\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1D\x85") + ser.write(b"\xB5\x62\x06\x00\x00\x00\x06\x18") + ser.write(b"\xB5\x62\x06\x00\x01\x00\x01\x08\x22") + ser.write(b"\xB5\x62\x06\x00\x01\x00\x02\x09\x23") + ser.write(b"\xB5\x62\x06\x00\x01\x00\x03\x0A\x24") + ser.write(b"\xB5\x62\x06\x08\x06\x00\x64\x00\x01\x00\x00\x00\x79\x10") + ser.write(b"\xB5\x62\x06\x24\x24\x00\x05\x00\x04\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5A\x63") + ser.write(b"\xB5\x62\x06\x1E\x14\x00\x00\x00\x00\x00\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3C\x37") + ser.write(b"\xB5\x62\x06\x24\x00\x00\x2A\x84") + ser.write(b"\xB5\x62\x06\x23\x00\x00\x29\x81") + ser.write(b"\xB5\x62\x06\x1E\x00\x00\x24\x72") + ser.write(b"\xB5\x62\x06\x01\x03\x00\x01\x07\x01\x13\x51") + ser.write(b"\xB5\x62\x06\x01\x03\x00\x02\x15\x01\x22\x70") + ser.write(b"\xB5\x62\x06\x01\x03\x00\x02\x13\x01\x20\x6C") + + print("Initialized GPS") + +received_messages = 0 +received_bytes = 0 +send_something = False +def gps_read_thread(panda): + global received_messages, received_bytes, send_something + ser = PandaSerial(panda, 1, GPS_BAUD) + while True: + ret = ser.read(1024) + time.sleep(0.001) + l = len(ret) + if l > 0: + received_messages+=1 + received_bytes+=l + if send_something: + ser.write("test") + send_something = False + + +CHECK_PERIOD = 5 +MIN_BYTES = 10000 +MAX_BYTES = 50000 + +min_failures = 0 +max_failures = 0 + +if __name__ == "__main__": + white_panda, gps_panda = connect() + + # Start spamming the CAN buses with the white panda. Also read the messages to add load on the GPS panda + threading.Thread(target=spam_buses_thread, args=(white_panda,)).start() + threading.Thread(target=read_can_thread, args=(gps_panda,)).start() + + # Start GPS checking + init_gps(gps_panda) + + read_thread = threading.Thread(target=gps_read_thread, args=(gps_panda,)) + read_thread.start() + while True: + time.sleep(CHECK_PERIOD) + if(received_bytes < MIN_BYTES): + print("Panda is not sending out enough data! Got " + str(received_messages) + " (" + str(received_bytes) + "B) in the last " + str(CHECK_PERIOD) + " seconds") + send_something = True + min_failures+=1 + elif(received_bytes > MAX_BYTES): + print("Panda is not sending out too much data! Got " + str(received_messages) + " (" + str(received_bytes) + "B) in the last " + str(CHECK_PERIOD) + " seconds") + print("Probably not on the right baud rate, got reset somehow? Resetting...") + max_failures+=1 + init_gps(gps_panda) + else: + print("Got " + str(received_messages) + " (" + str(received_bytes) + "B) messages in the last " + str(CHECK_PERIOD) + " seconds.") + if(min_failures > 0): + print("Total min failures: ", min_failures) + if(max_failures > 0): + print("Total max failures: ", max_failures) + received_messages = 0 + received_bytes = 0 diff --git a/panda/tests/health_test.py b/panda/tests/health_test.py new file mode 100755 index 00000000000000..69234c7d6462f2 --- /dev/null +++ b/panda/tests/health_test.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +import time +from panda import Panda + +if __name__ == "__main__": + panda_serials = Panda.list() + pandas = [] + for ps in panda_serials: + pandas.append(Panda(serial=ps)) + if len(pandas) == 0: + print("No pandas connected") + assert False + + while True: + for panda in pandas: + print(panda.health()) + print("\n") + time.sleep(0.5) + diff --git a/panda/tests/ir_test.py b/panda/tests/ir_test.py new file mode 100755 index 00000000000000..caef9e4909d3d9 --- /dev/null +++ b/panda/tests/ir_test.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +import os +import sys +import time + +sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..")) +from panda import Panda + +power = 0 +if __name__ == "__main__": + p = Panda() + while True: + p.set_ir_power(power) + print("Power: ", str(power)) + time.sleep(1) + power += 10 + power %=100 diff --git a/panda/tests/language/Dockerfile b/panda/tests/language/Dockerfile new file mode 100644 index 00000000000000..6a1d8bb7c77ff9 --- /dev/null +++ b/panda/tests/language/Dockerfile @@ -0,0 +1,17 @@ +FROM ubuntu:16.04 + +RUN apt-get update && apt-get install -y make python python-pip locales curl git zlib1g-dev libffi-dev bzip2 libssl-dev + +RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash + +ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}" +RUN pyenv install 3.7.3 +RUN pyenv global 3.7.3 +RUN pyenv rehash + +COPY . /panda diff --git a/panda/tests/language/LICENSE b/panda/tests/language/LICENSE new file mode 100644 index 00000000000000..8dada3edaf50db --- /dev/null +++ b/panda/tests/language/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/panda/tests/language/list.txt b/panda/tests/language/list.txt new file mode 100644 index 00000000000000..cfd25897d8dc55 --- /dev/null +++ b/panda/tests/language/list.txt @@ -0,0 +1,451 @@ +4r5e +5h1t +5hit +a55 +anal +anus +ar5e +arrse +arse +ass +ass-fucker +asses +assfucker +assfukka +asshole +assholes +asswhole +a_s_s +b!tch +b00bs +b17ch +b1tch +ballbag +balls +ballsack +bastard +beastial +beastiality +bellend +bestial +bestiality +bi+ch +biatch +bitch +bitcher +bitchers +bitches +bitchin +bitching +bloody +blow job +blowjob +blowjobs +boiolas +bollock +bollok +boner +boob +boobs +booobs +boooobs +booooobs +booooooobs +breasts +buceta +bugger +bum +bunny fucker +bullshit +butt +butthole +buttmuch +buttplug +c0ck +c0cksucker +carpet muncher +cawk +chink +cipa +cl1t +clit +clitoris +clits +cnut +cock +cock-sucker +cockface +cockhead +cockmunch +cockmuncher +cocks +cocksuck +cocksucked +cocksucker +cocksucking +cocksucks +cocksuka +cocksukka +cok +cokmuncher +coksucka +coon +cox +crap +cum +cummer +cumming +cums +cumshot +cunilingus +cunillingus +cunnilingus +cunt +cuntlick +cuntlicker +cuntlicking +cunts +cyalis +cyberfuc +cyberfuck +cyberfucked +cyberfucker +cyberfuckers +cyberfucking +d1ck +damn +dick +dickhead +dildo +dildos +dink +dinks +dirsa +dlck +dog-fucker +doggin +dogging +donkeyribber +doosh +duche +dyke +ejaculate +ejaculated +ejaculates +ejaculating +ejaculatings +ejaculation +ejakulate +f u c k +f u c k e r +f4nny +fag +fagging +faggitt +faggot +faggs +fagot +fagots +fags +fanny +fannyflaps +fannyfucker +fanyy +fatass +fcuk +fcuker +fcuking +feck +fecker +felching +fellate +fellatio +fingerfuck +fingerfucked +fingerfucker +fingerfuckers +fingerfucking +fingerfucks +fistfuck +fistfucked +fistfucker +fistfuckers +fistfucking +fistfuckings +fistfucks +flange +fook +fooker +fuck +fucka +fucked +fucker +fuckers +fuckhead +fuckheads +fuckin +fucking +fuckings +fuckingshitmotherfucker +fuckme +fucks +fuckwhit +fuckwit +fudge packer +fudgepacker +fuk +fuker +fukker +fukkin +fuks +fukwhit +fukwit +fux +fux0r +f_u_c_k +gangbang +gangbanged +gangbangs +gaylord +gaysex +goatse +God +god-dam +god-damned +goddamn +goddamned +hardcoresex +hell +heshe +hoar +hoare +hoer +homo +hore +horniest +horny +hotsex +jack-off +jackoff +jap +jerk-off +jism +jiz +jizm +jizz +kawk +knob +knobead +knobed +knobend +knobhead +knobjocky +knobjokey +kock +kondum +kondums +kum +kummer +kumming +kums +kunilingus +l3i+ch +l3itch +labia +lmfao +lust +lusting +m0f0 +m0fo +m45terbate +ma5terb8 +ma5terbate +masochist +master-bate +masterb8 +masterbat* +masterbat3 +masterbate +masterbation +masterbations +masturbate +mo-fo +mof0 +mofo +mothafuck +mothafucka +mothafuckas +mothafuckaz +mothafucked +mothafucker +mothafuckers +mothafuckin +mothafucking +mothafuckings +mothafucks +mother fucker +motherfuck +motherfucked +motherfucker +motherfuckers +motherfuckin +motherfucking +motherfuckings +motherfuckka +motherfucks +muff +mutha +muthafecker +muthafuckker +muther +mutherfucker +n1gga +n1gger +nazi +nigg3r +nigg4h +nigga +niggah +niggas +niggaz +nigger +niggers +nob +nob jokey +nobhead +nobjocky +nobjokey +numbnuts +nutsack +orgasim +orgasims +orgasm +orgasms +p0rn +pawn +pecker +penis +penisfucker +phonesex +phuck +phuk +phuked +phuking +phukked +phukking +phuks +phuq +pigfucker +pimpis +piss +pissed +pisser +pissers +pisses +pissflaps +pissin +pissing +pissoff +poop +porn +porno +pornography +pornos +prick +pricks +pron +pube +pusse +pussi +pussies +pussy +pussys +rectum +retard +rimjaw +rimming +s hit +s.o.b. +sadist +schlong +screwing +scroat +scrote +scrotum +semen +sex +sh!+ +sh!t +sh1t +shag +shagger +shaggin +shagging +shemale +shi+ +shit +shitdick +shite +shited +shitey +shitfuck +shitfull +shithead +shiting +shitings +shits +shitted +shitter +shitters +shitting +shittings +shitty +skank +slut +sluts +smegma +smut +snatch +son-of-a-bitch +spac +spunk +s_h_i_t +t1tt1e5 +t1tties +teets +teez +testical +testicle +tit +titfuck +tits +titt +tittie5 +tittiefucker +titties +tittyfuck +tittywank +titwank +tosser +turd +tw4t +twat +twathead +twatty +twunt +twunter +v14gra +v1gra +vagina +viagra +vulva +w00se +wang +wank +wanker +wanky +whoar +whore +willies +willy +xrated diff --git a/panda/tests/language/test_language.py b/panda/tests/language/test_language.py new file mode 100755 index 00000000000000..98b029042551e9 --- /dev/null +++ b/panda/tests/language/test_language.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 + +import subprocess +import sys + +checked_ext = ["h", "c", "py", "pyx", "cpp", "hpp", "md", "mk"] + +if __name__ == "__main__": + with open("list.txt", 'r') as handle: + + suffix_cmd = " " + for i in checked_ext: + suffix_cmd += "--include \*." + i + " " + + found_bad_language = False + for line in handle: + line = line.rstrip('\n').rstrip(" ") + try: + cmd = "cd ../../; grep -R -i -w " + suffix_cmd + " '" + line + "'" + res = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT) + print(res) + found_bad_language = True + except subprocess.CalledProcessError: + pass + if found_bad_language: + sys.exit("Failed: found bad language") + else: + print("Success") diff --git a/panda/tests/linter_python/.pylintrc b/panda/tests/linter_python/.pylintrc new file mode 100644 index 00000000000000..64a55daf8fabb3 --- /dev/null +++ b/panda/tests/linter_python/.pylintrc @@ -0,0 +1,585 @@ +[MASTER] + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code +extension-pkg-whitelist=scipy + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS + +# Add files or directories matching the regex patterns to the blacklist. The +# regex matches against base names, not paths. +ignore-patterns= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Use multiple processes to speed up Pylint. +jobs=4 + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + +# Pickle collected data for later comparisons. +persistent=yes + +# Specify a configuration file. +#rcfile= + +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages +suggestion-mode=yes + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED +confidence= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once).You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use"--disable=all --enable=classes +# --disable=W" +disable=print-statement, + parameter-unpacking, + unpacking-in-except, + old-raise-syntax, + backtick, + long-suffix, + old-ne-operator, + old-octal-literal, + import-star-module-level, + non-ascii-bytes-literal, + raw-checker-failed, + bad-inline-option, + locally-disabled, + locally-enabled, + file-ignored, + suppressed-message, + useless-suppression, + deprecated-pragma, + apply-builtin, + basestring-builtin, + buffer-builtin, + cmp-builtin, + coerce-builtin, + execfile-builtin, + file-builtin, + long-builtin, + raw_input-builtin, + reduce-builtin, + standarderror-builtin, + unicode-builtin, + xrange-builtin, + coerce-method, + delslice-method, + getslice-method, + setslice-method, + no-absolute-import, + old-division, + dict-iter-method, + dict-view-method, + next-method-called, + metaclass-assignment, + indexing-exception, + raising-string, + reload-builtin, + oct-method, + hex-method, + nonzero-method, + cmp-method, + input-builtin, + round-builtin, + intern-builtin, + unichr-builtin, + map-builtin-not-iterating, + zip-builtin-not-iterating, + range-builtin-not-iterating, + filter-builtin-not-iterating, + using-cmp-argument, + eq-without-hash, + div-method, + idiv-method, + rdiv-method, + exception-message-attribute, + invalid-str-codec, + sys-max-int, + bad-python3-import, + deprecated-string-function, + deprecated-str-translate-call, + deprecated-itertools-function, + deprecated-types-field, + next-method-defined, + dict-items-not-iterating, + dict-keys-not-iterating, + dict-values-not-iterating, + bad-indentation, + line-too-long, + missing-docstring, + multiple-statements, + bad-continuation, + invalid-name, + too-many-arguments, + too-many-locals, + superfluous-parens, + bad-whitespace, + too-many-instance-attributes, + wrong-import-position, + ungrouped-imports, + wrong-import-order, + protected-access, + trailing-whitespace, + too-many-branches, + too-few-public-methods, + too-many-statements, + trailing-newlines, + attribute-defined-outside-init, + too-many-return-statements, + too-many-public-methods, + unused-argument, + old-style-class, + no-init, + len-as-condition, + unneeded-not, + no-self-use, + multiple-imports, + no-else-return, + logging-not-lazy, + fixme, + redefined-outer-name, + unused-variable, + unsubscriptable-object, + expression-not-assigned, + too-many-boolean-expressions, + consider-using-ternary, + invalid-unary-operand-type, + relative-import, + deprecated-lambda + + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable=c-extension-no-member + + +[REPORTS] + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details +#msg-template= + +# Set the output format. Available formats are text, parseable, colorized, json +# and msvs (visual studio).You can also give a reporter class, eg +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Tells whether to display a full report or only the messages +reports=no + +# Activate the evaluation score. +score=yes + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=optparse.Values,sys.exit + + +[LOGGING] + +# Logging modules to check that the string format arguments are in logging +# function parameter format +logging-modules=logging + + +[SPELLING] + +# Limits count of emitted suggestions for spelling mistakes +max-spelling-suggestions=4 + +# Spelling dictionary name. Available dictionaries: none. To make it working +# install python-enchant package. +spelling-dict= + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to indicated private dictionary in +# --spelling-private-dict-file option instead of raising a message. +spelling-store-unknown-words=no + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME, + XXX, + TODO + + +[SIMILARITIES] + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + +# Minimum lines number of a similarity. +min-similarity-lines=4 + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members=capnp.* cereal.* pygame.* zmq.* setproctitle.* smbus2.* usb1.* serial.* cv2.* + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis. It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules=flask setproctitle usb1 flask.ext.socketio smbus2 usb1.* + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + + +[VARIABLES] + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb + +# A regular expression matching the name of dummy variables (i.e. expectedly +# not used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore +ignored-argument-names=_.*|^ignored_|^unused_ + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins + + +[FORMAT] + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Maximum number of characters on a single line. +max-line-length=100 + +# Maximum number of lines in a module +max-module-lines=1000 + +# List of optional constructs for which whitespace checking is disabled. `dict- +# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. +# `trailing-comma` allows a space between comma and closing bracket: (a, ). +# `empty-line` allows space-only lines. +no-space-check=trailing-comma, + dict-separator + +# Allow the body of a class to be on the same line as the declaration if body +# contains single statement. +single-line-class-stmt=no + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + + +[BASIC] + +# Naming style matching correct argument names +argument-naming-style=snake_case + +# Regular expression matching correct argument names. Overrides argument- +# naming-style +#argument-rgx= + +# Naming style matching correct attribute names +attr-naming-style=snake_case + +# Regular expression matching correct attribute names. Overrides attr-naming- +# style +#attr-rgx= + +# Bad variable names which should always be refused, separated by a comma +bad-names=foo, + bar, + baz, + toto, + tutu, + tata + +# Naming style matching correct class attribute names +class-attribute-naming-style=any + +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style +#class-attribute-rgx= + +# Naming style matching correct class names +class-naming-style=PascalCase + +# Regular expression matching correct class names. Overrides class-naming-style +#class-rgx= + +# Naming style matching correct constant names +const-naming-style=UPPER_CASE + +# Regular expression matching correct constant names. Overrides const-naming- +# style +#const-rgx= + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + +# Naming style matching correct function names +function-naming-style=snake_case + +# Regular expression matching correct function names. Overrides function- +# naming-style +#function-rgx= + +# Good variable names which should always be accepted, separated by a comma +good-names=i, + j, + k, + ex, + Run, + _ + +# Include a hint for the correct naming format with invalid-name +include-naming-hint=no + +# Naming style matching correct inline iteration names +inlinevar-naming-style=any + +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style +#inlinevar-rgx= + +# Naming style matching correct method names +method-naming-style=snake_case + +# Regular expression matching correct method names. Overrides method-naming- +# style +#method-rgx= + +# Naming style matching correct module names +module-naming-style=snake_case + +# Regular expression matching correct module names. Overrides module-naming- +# style +#module-rgx= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +property-classes=abc.abstractproperty + +# Naming style matching correct variable names +variable-naming-style=snake_case + +# Regular expression matching correct variable names. Overrides variable- +# naming-style +#variable-rgx= + + +[DESIGN] + +# Maximum number of arguments for function / method +max-args=5 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in a if statement +max-bool-expr=5 + +# Maximum number of branch for function / method body +max-branches=12 + +# Maximum number of locals for function / method body +max-locals=15 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of return / yield for function / method body +max-returns=6 + +# Maximum number of statements in function / method body +max-statements=50 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[CLASSES] + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=mcs + + +[IMPORTS] + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub, + TERMIOS, + Bastion, + rexec + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled) +import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled) +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception" +overgeneral-exceptions=Exception diff --git a/panda/tests/linter_python/Dockerfile b/panda/tests/linter_python/Dockerfile new file mode 100644 index 00000000000000..819d692109e1c3 --- /dev/null +++ b/panda/tests/linter_python/Dockerfile @@ -0,0 +1,19 @@ +FROM ubuntu:16.04 + +RUN apt-get update && apt-get install -y make python python-pip locales curl git zlib1g-dev libffi-dev bzip2 libssl-dev + +RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash + +ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}" +RUN pyenv install 3.7.3 +RUN pyenv global 3.7.3 +RUN pyenv rehash + +COPY requirements.txt /tmp/ +RUN pip install -r /tmp/requirements.txt +COPY . /panda diff --git a/panda/tests/linter_python/flake8_panda.sh b/panda/tests/linter_python/flake8_panda.sh new file mode 100755 index 00000000000000..a1d02ea548eabe --- /dev/null +++ b/panda/tests/linter_python/flake8_panda.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +RESULT=$(python3 -m flake8 --select=F $(find ../../ -type f | grep -v "/boardesp/" | grep -v "/cppcheck/" | grep "\.py$")) +if [[ $RESULT ]]; then + echo "Pyflakes found errors in the code. Please fix and try again" + echo "$RESULT" + exit 1 +fi diff --git a/panda/tests/linter_python/pylint_panda.sh b/panda/tests/linter_python/pylint_panda.sh new file mode 100755 index 00000000000000..1486bd839cceff --- /dev/null +++ b/panda/tests/linter_python/pylint_panda.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +python3 -m pylint --disable=R,C,W $(find ../../ -type f | grep -v "/boardesp/" | grep -v "/cppcheck/" | grep "\.py$") + +exit_status=$? +(( res = exit_status & 3 )) + +if [[ $res != 0 ]]; then + echo "Pylint found errors in the code. Please fix and try again" + exit 1 +fi diff --git a/panda/tests/location_listener.py b/panda/tests/location_listener.py index cbbb00d794f5e3..1a784babc98806 100755 --- a/panda/tests/location_listener.py +++ b/panda/tests/location_listener.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import os import time import sys @@ -18,20 +18,20 @@ def add_nmea_checksum(msg): ser = PandaSerial(panda, 1, 9600) # power cycle by toggling reset - print "resetting" + print("resetting") panda.set_esp_power(0) time.sleep(0.5) panda.set_esp_power(1) time.sleep(0.5) - print "done" - print ser.read(1024) + print("done") + print(ser.read(1024)) # upping baud rate baudrate = 460800 - print "upping baud rate" - msg = add_nmea_checksum("$PUBX,41,1,0007,0003,%d,0" % baudrate)+"\r\n" - print msg + print("upping baud rate") + msg = str.encode(add_nmea_checksum("$PUBX,41,1,0007,0003,%d,0" % baudrate)+"\r\n") + print(msg) ser.write(msg) time.sleep(0.1) # needs a wait for it to actually send @@ -41,7 +41,7 @@ def add_nmea_checksum(msg): while True: ret = ser.read(1024) if len(ret) > 0: - sys.stdout.write(ret) + sys.stdout.write(ret.decode('ascii', 'ignore')) sys.stdout.flush() #print str(ret).encode("hex") diff --git a/panda/tests/loopback_test.py b/panda/tests/loopback_test.py index a871295ad6fd83..60009fae51fd00 100755 --- a/panda/tests/loopback_test.py +++ b/panda/tests/loopback_test.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python -from __future__ import print_function +#!/usr/bin/env python3 + import os import sys import time @@ -29,14 +29,14 @@ def run_test(sleep_duration): run_test_w_pandas(pandas, sleep_duration) def run_test_w_pandas(pandas, sleep_duration): - h = list(map(lambda x: Panda(x), pandas)) + h = list([Panda(x) for x in pandas]) print("H", h) for hh in h: hh.set_safety_mode(Panda.SAFETY_ALLOUTPUT) # test both directions - for ho in permutations(range(len(h)), r=2): + for ho in permutations(list(range(len(h))), r=2): print("***************** TESTING", ho) panda0, panda1 = h[ho[0]], h[ho[1]] @@ -55,7 +55,7 @@ def run_test_w_pandas(pandas, sleep_duration): # send the characters st = get_test_string() - st = b"\xaa"+chr(len(st)+3).encode()+st + st = bytes([0xaa, len(st) + 3]) + st h[ho[0]].kline_send(st, bus=bus, checksum=False) # check for receive diff --git a/panda/tests/misra/Dockerfile b/panda/tests/misra/Dockerfile new file mode 100644 index 00000000000000..06882834fcdfbe --- /dev/null +++ b/panda/tests/misra/Dockerfile @@ -0,0 +1,19 @@ +FROM ubuntu:16.04 + +RUN apt-get update && apt-get install -y clang make python python-pip git curl locales zlib1g-dev libffi-dev bzip2 libssl-dev libbz2-dev libusb-1.0-0 + +RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash + +ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}" +RUN pyenv install 3.7.3 +RUN pyenv global 3.7.3 +RUN pyenv rehash + +COPY requirements.txt /tmp/ +RUN pip install -r /tmp/requirements.txt +COPY . /panda diff --git a/panda/tests/misra/coverage_table b/panda/tests/misra/coverage_table new file mode 100644 index 00000000000000..dcb5992bc74743 --- /dev/null +++ b/panda/tests/misra/coverage_table @@ -0,0 +1,143 @@ +1.1 +1.2 +1.3 X (Cppcheck) +2.1 X (Cppcheck) +2.2 X (Cppcheck) +2.3 +2.4 X (Cppcheck) +2.5 +2.6 X (Cppcheck) +2.7 +3.1 X (Addon) +3.2 X (Addon) +4.1 X (Addon) +4.2 X (Addon) +5.1 X (Addon) +5.2 X (Addon) +5.3 X (Addon) +5.4 X (Addon) +5.5 X (Addon) +5.6 +5.7 +5.8 +5.9 +6.1 +6.2 +7.1 X (Addon) +7.2 +7.3 X (Addon) +7.4 +8.1 +8.2 +8.3 X (Cppcheck) +8.4 +8.5 +8.6 +8.7 +8.8 +8.9 +8.10 +8.11 X (Addon) +8.12 X (Addon) +8.13 +8.14 X (Addon) +9.1 +9.2 +9.3 +9.4 +9.5 X (Addon) +10.1 X (Addon) +10.2 +10.3 +10.4 X (Addon) +10.5 +10.6 X (Addon) +10.7 +10.8 X (Addon) +11.1 +11.2 +11.3 X (Addon) +11.4 X (Addon) +11.5 X (Addon) +11.6 X (Addon) +11.7 X (Addon) +11.8 X (Addon) +11.9 X (Addon) +12.1 X (Addon) +12.2 X (Addon) +12.3 X (Addon) +12.4 X (Addon) +13.1 X (Addon) +13.2 X (Cppcheck) +13.3 X (Addon) +13.4 X (Addon) +13.5 X (Addon) +13.6 X (Addon) +14.1 X (Addon) +14.2 X (Addon) +14.3 X (Cppcheck) +14.4 X (Addon) +15.1 X (Addon) +15.2 X (Addon) +15.3 X (Addon) +15.4 +15.5 X (Addon) +15.6 X (Addon) +15.7 X (Addon) +16.1 +16.2 X (Addon) +16.3 X (Addon) +16.4 X (Addon) +16.5 X (Addon) +16.6 X (Addon) +16.7 X (Addon) +17.1 X (Addon) +17.2 X (Addon) +17.3 +17.4 +17.5 X (Cppcheck) +17.6 X (Addon) +17.7 X (Addon) +17.8 X (Addon) +18.1 X (Cppcheck) +18.2 X (Cppcheck) +18.3 X (Cppcheck) +18.4 X (Addon) +18.5 X (Addon) +18.6 X (Cppcheck) +18.7 X (Addon) +18.8 X (Addon) +19.1 +19.2 X (Addon) +20.1 X (Addon) +20.2 X (Addon) +20.3 X (Addon) +20.4 X (Addon) +20.5 X (Addon) +20.6 X (Cppcheck) +20.7 X (Addon) +20.8 +20.9 +20.10 X (Addon) +20.11 +20.12 +20.13 X (Addon) +20.14 X (Addon) +21.1 X (Addon) +21.2 +21.3 X (Addon) +21.4 X (Addon) +21.5 X (Addon) +21.6 X (Addon) +21.7 X (Addon) +21.8 X (Addon) +21.9 X (Addon) +21.10 X (Addon) +21.11 X (Addon) +21.12 X (Addon) +22.1 X (Cppcheck) +22.2 X (Cppcheck) +22.3 +22.4 X (Cppcheck) +22.5 +22.6 X (Cppcheck) diff --git a/panda/tests/misra/suppressions.txt b/panda/tests/misra/suppressions.txt new file mode 100644 index 00000000000000..e0a270831a3526 --- /dev/null +++ b/panda/tests/misra/suppressions.txt @@ -0,0 +1,8 @@ +# Advisory: union types can be used +misra.19.2 +# Advisory: casting from void pointer to type pointer is ok. Done by STM libraries as well +misra.11.4 +# Advisory: casting from void pointer to type pointer is ok. Done by STM libraries as well +misra.11.5 +# Required: it's ok re-defining potentially reserved Macro names. Not likely to cause confusion +misra.21.1 diff --git a/panda/tests/misra/test_misra.sh b/panda/tests/misra/test_misra.sh new file mode 100755 index 00000000000000..2542290744d963 --- /dev/null +++ b/panda/tests/misra/test_misra.sh @@ -0,0 +1,55 @@ +#!/bin/bash -e + +mkdir /tmp/misra || true +git clone https://github.com/danmar/cppcheck.git || true +cd cppcheck +git fetch +git checkout bdd41151ed550e3d240a6dd6847859216b7ad736 +make -j4 +cd ../../../ + +# generate coverage matrix +python tests/misra/cppcheck/addons/misra.py -generate-table > tests/misra/coverage_table + +printf "\nPANDA CODE\n" +tests/misra/cppcheck/cppcheck -DPANDA -UPEDAL -DCAN3 -DUID_BASE -DEON \ + --suppressions-list=tests/misra/suppressions.txt \ + --dump --enable=all --inline-suppr --force \ + board/main.c 2>/tmp/misra/cppcheck_output.txt + +python tests/misra/cppcheck/addons/misra.py board/main.c.dump 2> /tmp/misra/misra_output.txt || true + +# strip (information) lines +cppcheck_output=$( cat /tmp/misra/cppcheck_output.txt | grep -v ": information: " ) || true +misra_output=$( cat /tmp/misra/misra_output.txt | grep -v ": information: " ) || true + + +printf "\nPEDAL CODE\n" +tests/misra/cppcheck/cppcheck -UPANDA -DPEDAL -UCAN3 \ + --suppressions-list=tests/misra/suppressions.txt \ + -I board/ --dump --enable=all --inline-suppr --force \ + board/pedal/main.c 2>/tmp/misra/cppcheck_pedal_output.txt + +python tests/misra/cppcheck/addons/misra.py board/pedal/main.c.dump 2> /tmp/misra/misra_pedal_output.txt || true + +# strip (information) lines +cppcheck_pedal_output=$( cat /tmp/misra/cppcheck_pedal_output.txt | grep -v ": information: " ) || true +misra_pedal_output=$( cat /tmp/misra/misra_pedal_output.txt | grep -v ": information: " ) || true + +if [[ -n "$misra_output" ]] || [[ -n "$cppcheck_output" ]] +then + echo "Failed! found Misra violations in panda code:" + echo "$misra_output" + echo "$cppcheck_output" + exit 1 +fi + +if [[ -n "$misra_pedal_output" ]] || [[ -n "$cppcheck_pedal_output" ]] +then + echo "Failed! found Misra violations in pedal code:" + echo "$misra_pedal_output" + echo "$cppcheck_pedal_output" + exit 1 +fi + +echo "Success" diff --git a/panda/tests/pedal/enter_canloader.py b/panda/tests/pedal/enter_canloader.py index c6f06ca35499a0..4488c3205626cf 100755 --- a/panda/tests/pedal/enter_canloader.py +++ b/panda/tests/pedal/enter_canloader.py @@ -1,5 +1,4 @@ -#!/usr/bin/env python -import sys +#!/usr/bin/env python3 import time import struct import argparse @@ -53,24 +52,24 @@ def bulkRead(self, endpoint, length, timeout=0): args = parser.parse_args() p = Panda() - p.set_safety_mode(0x1337) + p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) while 1: if len(p.can_recv()) == 0: break if args.recover: - p.can_send(0x200, "\xce\xfa\xad\xde\x1e\x0b\xb0\x02", 0) + p.can_send(0x200, b"\xce\xfa\xad\xde\x1e\x0b\xb0\x02", 0) exit(0) else: - p.can_send(0x200, "\xce\xfa\xad\xde\x1e\x0b\xb0\x0a", 0) + p.can_send(0x200, b"\xce\xfa\xad\xde\x1e\x0b\xb0\x0a", 0) if args.fn: time.sleep(0.1) - print "flashing", args.fn - code = open(args.fn).read() + print("flashing", args.fn) + code = open(args.fn, "rb").read() Panda.flash_static(CanHandle(p), code) - print "can flash done" + print("can flash done") diff --git a/panda/tests/read_winusb_descriptors.py b/panda/tests/read_winusb_descriptors.py index e38df8d1caa9c3..ea5e93f32dfce8 100644 --- a/panda/tests/read_winusb_descriptors.py +++ b/panda/tests/read_winusb_descriptors.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from panda import Panda from hexdump import hexdump @@ -8,22 +8,22 @@ p = Panda() len = p._handle.controlRead(Panda.REQUEST_IN, 0x06, 3 << 8 | 238, 0, 1) - print 'Microsoft OS String Descriptor' + print('Microsoft OS String Descriptor') dat = p._handle.controlRead(Panda.REQUEST_IN, 0x06, 3 << 8 | 238, 0, len[0]) - if DEBUG: print 'LEN: {}'.format(hex(len[0])) + if DEBUG: print('LEN: {}'.format(hex(len[0]))) hexdump("".join(map(chr, dat))) ms_vendor_code = dat[16] - if DEBUG: print 'MS_VENDOR_CODE: {}'.format(hex(len[0])) + if DEBUG: print('MS_VENDOR_CODE: {}'.format(hex(len[0]))) - print '\nMicrosoft Compatible ID Feature Descriptor' + print('\nMicrosoft Compatible ID Feature Descriptor') len = p._handle.controlRead(Panda.REQUEST_IN, ms_vendor_code, 0, 4, 1) - if DEBUG: print 'LEN: {}'.format(hex(len[0])) + if DEBUG: print('LEN: {}'.format(hex(len[0]))) dat = p._handle.controlRead(Panda.REQUEST_IN, ms_vendor_code, 0, 4, len[0]) hexdump("".join(map(chr, dat))) - print '\nMicrosoft Extended Properties Feature Descriptor' + print('\nMicrosoft Extended Properties Feature Descriptor') len = p._handle.controlRead(Panda.REQUEST_IN, ms_vendor_code, 0, 5, 1) - if DEBUG: print 'LEN: {}'.format(hex(len[0])) + if DEBUG: print('LEN: {}'.format(hex(len[0]))) dat = p._handle.controlRead(Panda.REQUEST_IN, ms_vendor_code, 0, 5, len[0]) hexdump("".join(map(chr, dat))) diff --git a/panda/tests/rtc_test.py b/panda/tests/rtc_test.py new file mode 100755 index 00000000000000..3732cb765f81e9 --- /dev/null +++ b/panda/tests/rtc_test.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python +import os +import sys +import datetime + +sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..")) +from panda import Panda + +if __name__ == "__main__": + p = Panda() + + p.set_datetime(datetime.datetime.now()) + print(p.get_datetime()) diff --git a/panda/tests/safety/Dockerfile b/panda/tests/safety/Dockerfile index 9381fdc4085759..3c70d253411b26 100644 --- a/panda/tests/safety/Dockerfile +++ b/panda/tests/safety/Dockerfile @@ -1,6 +1,20 @@ FROM ubuntu:16.04 -RUN apt-get update && apt-get install -y clang make python python-pip -COPY tests/safety/requirements.txt /panda/tests/safety/requirements.txt -RUN pip install -r /panda/tests/safety/requirements.txt +RUN apt-get update && apt-get install -y clang make python python-pip git curl locales zlib1g-dev libffi-dev bzip2 libssl-dev libbz2-dev libusb-1.0-0 + +RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash + +ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}" +RUN pyenv install 3.7.3 +RUN pyenv global 3.7.3 +RUN pyenv rehash + +COPY requirements.txt /tmp/ +RUN pip install -r /tmp/requirements.txt + COPY . /panda diff --git a/pyextra/jsonrpc/backend/__init__.py b/panda/tests/safety/__init__.py similarity index 100% rename from pyextra/jsonrpc/backend/__init__.py rename to panda/tests/safety/__init__.py diff --git a/panda/tests/safety/libpandasafety_py.py b/panda/tests/safety/libpandasafety_py.py index d8cb27cf8c8092..819fcada37e3d2 100644 --- a/panda/tests/safety/libpandasafety_py.py +++ b/panda/tests/safety/libpandasafety_py.py @@ -30,74 +30,77 @@ uint32_t CNT; } TIM_TypeDef; -void set_controls_allowed(int c); -int get_controls_allowed(void); -void set_timer(int t); +bool board_has_relay(void); + +void set_controls_allowed(bool c); +bool get_controls_allowed(void); +void set_long_controls_allowed(bool c); +bool get_long_controls_allowed(void); +void set_gas_interceptor_detected(bool c); +bool get_gas_interceptor_detetcted(void); +int get_gas_interceptor_prev(void); +int get_hw_type(void); +void set_timer(uint32_t t); void reset_angle_control(void); +void safety_rx_hook(CAN_FIFOMailBox_TypeDef *to_send); +int safety_tx_hook(CAN_FIFOMailBox_TypeDef *to_push); +int safety_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd); +int safety_set_mode(uint16_t mode, int16_t param); + void init_tests_toyota(void); -void toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); -int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); -void toyota_init(int16_t param); int get_toyota_torque_meas_min(void); int get_toyota_torque_meas_max(void); +int get_toyota_gas_prev(void); void set_toyota_torque_meas(int min, int max); void set_toyota_desired_torque_last(int t); +void set_toyota_camera_forwarded(int t); void set_toyota_rt_torque_last(int t); void init_tests_honda(void); -int get_ego_speed(void); -void honda_init(int16_t param); -void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); -int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); -int get_brake_prev(void); -int get_gas_prev(void); +bool get_honda_moving(void); +bool get_honda_brake_pressed_prev(void); +int get_honda_gas_prev(void); +void set_honda_fwd_brake(bool); void set_honda_alt_brake_msg(bool); -void set_bosch_hardware(bool); +void set_honda_bosch_hardware(bool); +int get_honda_bosch_hardware(void); void init_tests_cadillac(void); -void cadillac_init(int16_t param); -void cadillac_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); -int cadillac_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); void set_cadillac_desired_torque_last(int t); void set_cadillac_rt_torque_last(int t); void set_cadillac_torque_driver(int min, int max); void init_tests_gm(void); -void gm_init(int16_t param); -void gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); -int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); void set_gm_desired_torque_last(int t); void set_gm_rt_torque_last(int t); void set_gm_torque_driver(int min, int max); void init_tests_hyundai(void); -void nooutput_init(int16_t param); -void hyundai_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); -int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); void set_hyundai_desired_torque_last(int t); void set_hyundai_rt_torque_last(int t); void set_hyundai_torque_driver(int min, int max); - -void toyota_ipas_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); -int toyota_ipas_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); +void set_hyundai_giraffe_switch_2(int t); +void set_hyundai_camera_bus(int t); void init_tests_chrysler(void); -void chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); -int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); void set_chrysler_desired_torque_last(int t); void set_chrysler_rt_torque_last(int t); +void set_chrysler_camera_detected(int t); int get_chrysler_torque_meas_min(void); int get_chrysler_torque_meas_max(void); void set_chrysler_torque_meas(int min, int max); void init_tests_subaru(void); -void subaru_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); -int subaru_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); void set_subaru_desired_torque_last(int t); void set_subaru_rt_torque_last(int t); void set_subaru_torque_driver(int min, int max); +void init_tests_volkswagen(void); +void set_volkswagen_desired_torque_last(int t); +void set_volkswagen_rt_torque_last(int t); +void set_volkswagen_torque_driver(int min, int max); +int get_volkswagen_gas_prev(void); """) diff --git a/panda/tests/safety/requirements.txt b/panda/tests/safety/requirements.txt deleted file mode 100644 index 8bbfb1d7df38a2..00000000000000 --- a/panda/tests/safety/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -cffi==1.11.4 -numpy==1.14.1 diff --git a/panda/tests/safety/test.c b/panda/tests/safety/test.c index 9b4c807d72d3f7..c61f64077c63b1 100644 --- a/panda/tests/safety/test.c +++ b/panda/tests/safety/test.c @@ -1,5 +1,6 @@ #include #include +#include typedef struct { @@ -28,41 +29,97 @@ struct sample_t gm_torque_driver; struct sample_t hyundai_torque_driver; struct sample_t chrysler_torque_meas; struct sample_t subaru_torque_driver; +struct sample_t volkswagen_torque_driver; TIM_TypeDef timer; TIM_TypeDef *TIM2 = &timer; -#define min(a,b) \ +// from board_declarations.h +#define HW_TYPE_UNKNOWN 0U +#define HW_TYPE_WHITE_PANDA 1U +#define HW_TYPE_GREY_PANDA 2U +#define HW_TYPE_BLACK_PANDA 3U +#define HW_TYPE_PEDAL 4U +#define HW_TYPE_UNO 5U + +// from main_declarations.h +uint8_t hw_type = HW_TYPE_UNKNOWN; + +// from board.h +bool board_has_relay(void) { + return hw_type == HW_TYPE_BLACK_PANDA || hw_type == HW_TYPE_UNO; +} + +// from config.h +#define MIN(a,b) \ ({ __typeof__ (a) _a = (a); \ __typeof__ (b) _b = (b); \ _a < _b ? _a : _b; }) -#define max(a,b) \ +#define MAX(a,b) \ ({ __typeof__ (a) _a = (a); \ __typeof__ (b) _b = (b); \ _a > _b ? _a : _b; }) +// from llcan.h +#define GET_BUS(msg) (((msg)->RDTR >> 4) & 0xFF) +#define GET_LEN(msg) ((msg)->RDTR & 0xf) +#define GET_ADDR(msg) ((((msg)->RIR & 4) != 0) ? ((msg)->RIR >> 3) : ((msg)->RIR >> 21)) +#define GET_BYTE(msg, b) (((int)(b) > 3) ? (((msg)->RDHR >> (8U * ((unsigned int)(b) % 4U))) & 0XFFU) : (((msg)->RDLR >> (8U * (unsigned int)(b))) & 0xFFU)) +#define GET_BYTES_04(msg) ((msg)->RDLR) +#define GET_BYTES_48(msg) ((msg)->RDHR) + +#define UNUSED(x) (void)(x) #define PANDA +#define NULL ((void*)0) #define static #include "safety.h" -void set_controls_allowed(int c){ +void set_controls_allowed(bool c){ controls_allowed = c; } +void set_long_controls_allowed(bool c){ + long_controls_allowed = c; +} + +void set_gas_interceptor_detected(bool c){ + gas_interceptor_detected = c; +} + void reset_angle_control(void){ angle_control = 0; } -int get_controls_allowed(void){ +bool get_controls_allowed(void){ return controls_allowed; } -void set_timer(int t){ +bool get_long_controls_allowed(void){ + return long_controls_allowed; +} + +bool get_gas_interceptor_detected(void){ + return gas_interceptor_detected; +} + +int get_gas_interceptor_prev(void){ + return gas_interceptor_prev; +} + +int get_hw_type(void){ + return hw_type; +} + +void set_timer(uint32_t t){ timer.CNT = t; } +void set_toyota_camera_forwarded(int t){ + toyota_camera_forwarded = t; +} + void set_toyota_torque_meas(int min, int max){ toyota_torque_meas.min = min; toyota_torque_meas.max = max; @@ -83,6 +140,18 @@ void set_hyundai_torque_driver(int min, int max){ hyundai_torque_driver.max = max; } +void set_hyundai_camera_bus(int t){ + hyundai_camera_bus = t; +} + +void set_hyundai_giraffe_switch_2(int t){ + hyundai_giraffe_switch_2 = t; +} + +void set_chrysler_camera_detected(int t){ + chrysler_camera_detected = t; +} + void set_chrysler_torque_meas(int min, int max){ chrysler_torque_meas.min = min; chrysler_torque_meas.max = max; @@ -93,6 +162,11 @@ void set_subaru_torque_driver(int min, int max){ subaru_torque_driver.max = max; } +void set_volkswagen_torque_driver(int min, int max){ + volkswagen_torque_driver.min = min; + volkswagen_torque_driver.max = max; +} + int get_chrysler_torque_meas_min(void){ return chrysler_torque_meas.min; } @@ -101,6 +175,10 @@ int get_chrysler_torque_meas_max(void){ return chrysler_torque_meas.max; } +int get_toyota_gas_prev(void){ + return toyota_gas_prev; +} + int get_toyota_torque_meas_min(void){ return toyota_torque_meas.min; } @@ -133,6 +211,10 @@ void set_subaru_rt_torque_last(int t){ subaru_rt_torque_last = t; } +void set_volkswagen_rt_torque_last(int t){ + volkswagen_rt_torque_last = t; +} + void set_toyota_desired_torque_last(int t){ toyota_desired_torque_last = t; } @@ -157,27 +239,49 @@ void set_subaru_desired_torque_last(int t){ subaru_desired_torque_last = t; } -int get_ego_speed(void){ - return ego_speed; +void set_volkswagen_desired_torque_last(int t){ + volkswagen_desired_torque_last = t; +} + +int get_volkswagen_gas_prev(void){ + return volkswagen_gas_prev; +} + +bool get_honda_moving(void){ + return honda_moving; } -int get_brake_prev(void){ - return brake_prev; +bool get_honda_brake_pressed_prev(void){ + return honda_brake_pressed_prev; } -int get_gas_prev(void){ - return gas_prev; +int get_honda_gas_prev(void){ + return honda_gas_prev; } void set_honda_alt_brake_msg(bool c){ honda_alt_brake_msg = c; } -void set_bosch_hardware(bool c){ - bosch_hardware = c; +void set_honda_bosch_hardware(bool c){ + honda_bosch_hardware = c; +} + +int get_honda_bosch_hardware(void) { + return honda_bosch_hardware; +} + +void set_honda_fwd_brake(bool c){ + honda_fwd_brake = c; +} + +void init_tests(void){ + // get HW_TYPE from env variable set in test.sh + hw_type = atoi(getenv("HW_TYPE")); } void init_tests_toyota(void){ + init_tests(); toyota_torque_meas.min = 0; toyota_torque_meas.max = 0; toyota_desired_torque_last = 0; @@ -187,6 +291,7 @@ void init_tests_toyota(void){ } void init_tests_cadillac(void){ + init_tests(); cadillac_torque_driver.min = 0; cadillac_torque_driver.max = 0; for (int i = 0; i < 4; i++) cadillac_desired_torque_last[i] = 0; @@ -196,6 +301,7 @@ void init_tests_cadillac(void){ } void init_tests_gm(void){ + init_tests(); gm_torque_driver.min = 0; gm_torque_driver.max = 0; gm_desired_torque_last = 0; @@ -205,6 +311,7 @@ void init_tests_gm(void){ } void init_tests_hyundai(void){ + init_tests(); hyundai_torque_driver.min = 0; hyundai_torque_driver.max = 0; hyundai_desired_torque_last = 0; @@ -214,6 +321,7 @@ void init_tests_hyundai(void){ } void init_tests_chrysler(void){ + init_tests(); chrysler_torque_meas.min = 0; chrysler_torque_meas.max = 0; chrysler_desired_torque_last = 0; @@ -223,6 +331,7 @@ void init_tests_chrysler(void){ } void init_tests_subaru(void){ + init_tests(); subaru_torque_driver.min = 0; subaru_torque_driver.max = 0; subaru_desired_torque_last = 0; @@ -231,11 +340,22 @@ void init_tests_subaru(void){ set_timer(0); } +void init_tests_volkswagen(void){ + init_tests(); + volkswagen_torque_driver.min = 0; + volkswagen_torque_driver.max = 0; + volkswagen_desired_torque_last = 0; + volkswagen_rt_torque_last = 0; + volkswagen_ts_last = 0; + set_timer(0); +} + void init_tests_honda(void){ - ego_speed = 0; - gas_interceptor_detected = 0; - brake_prev = 0; - gas_prev = 0; + init_tests(); + honda_moving = false; + honda_brake_pressed_prev = false; + honda_gas_prev = 0; + honda_fwd_brake = false; } void set_gmlan_digital_output(int to_set){ @@ -246,3 +366,4 @@ void reset_gmlan_switch_timeout(void){ void gmlan_switch_init(int timeout_enable){ } + diff --git a/panda/tests/safety/test.sh b/panda/tests/safety/test.sh index 83d8f5b31fa420..39d70ff615bee8 100755 --- a/panda/tests/safety/test.sh +++ b/panda/tests/safety/test.sh @@ -1,2 +1,18 @@ #!/usr/bin/env sh -python -m unittest discover . + +# Loop over all hardware types: +# HW_TYPE_UNKNOWN 0U +# HW_TYPE_WHITE_PANDA 1U +# HW_TYPE_GREY_PANDA 2U +# HW_TYPE_BLACK_PANDA 3U +# HW_TYPE_PEDAL 4U +# HW_TYPE_UNO 5U + +# Make sure test fails if one HW_TYPE fails +set -e + +for hw_type in 0 1 2 3 4 5 +do + echo "Testing HW_TYPE: $hw_type" + HW_TYPE=$hw_type python -m unittest discover . +done diff --git a/panda/tests/safety/test_cadillac.py b/panda/tests/safety/test_cadillac.py index 53c943e966d6fc..f211908b7bd11d 100644 --- a/panda/tests/safety/test_cadillac.py +++ b/panda/tests/safety/test_cadillac.py @@ -1,7 +1,8 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 import unittest import numpy as np -import libpandasafety_py +import libpandasafety_py # pylint: disable=import-error +from panda import Panda MAX_RATE_UP = 2 MAX_RATE_DOWN = 5 @@ -31,9 +32,16 @@ class TestCadillacSafety(unittest.TestCase): @classmethod def setUp(cls): cls.safety = libpandasafety_py.libpandasafety - cls.safety.cadillac_init(0) + cls.safety.safety_set_mode(Panda.SAFETY_CADILLAC, 0) cls.safety.init_tests_cadillac() + def _send_msg(self, bus, addr, length): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = addr << 21 + to_send[0].RDTR = length + to_send[0].RDTR = bus << 4 + return to_send + def _set_prev_torque(self, t): self.safety.set_cadillac_desired_torque_last(t) self.safety.set_cadillac_rt_torque_last(t) @@ -46,10 +54,6 @@ def _torque_driver_msg(self, torque): to_send[0].RDLR = ((t >> 8) & 0x7) | ((t & 0xFF) << 8) return to_send - def _torque_driver_msg_array(self, torque): - for i in range(3): - self.safety.cadillac_ipas_rx_hook(self._torque_driver_msg(torque)) - def _torque_msg(self, torque): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') to_send[0].RIR = 0x151 << 21 @@ -72,7 +76,7 @@ def test_enable_control_allowed_from_cruise(self): to_push[0].RDLR = 0x800000 to_push[0].RDTR = 0 - self.safety.cadillac_rx_hook(to_push) + self.safety.safety_rx_hook(to_push) self.assertTrue(self.safety.get_controls_allowed()) def test_disable_control_allowed_from_cruise(self): @@ -82,7 +86,7 @@ def test_disable_control_allowed_from_cruise(self): to_push[0].RDTR = 0 self.safety.set_controls_allowed(1) - self.safety.cadillac_rx_hook(to_push) + self.safety.safety_rx_hook(to_push) self.assertFalse(self.safety.get_controls_allowed()) def test_torque_absolute_limits(self): @@ -98,22 +102,22 @@ def test_torque_absolute_limits(self): else: send = torque == 0 - self.assertEqual(send, self.safety.cadillac_tx_hook(self._torque_msg(torque))) + self.assertEqual(send, self.safety.safety_tx_hook(self._torque_msg(torque))) def test_non_realtime_limit_up(self): self.safety.set_cadillac_torque_driver(0, 0) self.safety.set_controls_allowed(True) self._set_prev_torque(0) - self.assertTrue(self.safety.cadillac_tx_hook(self._torque_msg(MAX_RATE_UP))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP))) self._set_prev_torque(0) - self.assertTrue(self.safety.cadillac_tx_hook(self._torque_msg(-MAX_RATE_UP))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP))) self._set_prev_torque(0) - self.assertFalse(self.safety.cadillac_tx_hook(self._torque_msg(MAX_RATE_UP + 1))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP + 1))) self.safety.set_controls_allowed(True) self._set_prev_torque(0) - self.assertFalse(self.safety.cadillac_tx_hook(self._torque_msg(-MAX_RATE_UP - 1))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP - 1))) def test_non_realtime_limit_down(self): self.safety.set_cadillac_torque_driver(0, 0) @@ -127,10 +131,10 @@ def test_exceed_torque_sensor(self): t *= -sign self.safety.set_cadillac_torque_driver(t, t) self._set_prev_torque(MAX_TORQUE * sign) - self.assertTrue(self.safety.cadillac_tx_hook(self._torque_msg(MAX_TORQUE * sign))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(MAX_TORQUE * sign))) self.safety.set_cadillac_torque_driver(DRIVER_TORQUE_ALLOWANCE + 1, DRIVER_TORQUE_ALLOWANCE + 1) - self.assertFalse(self.safety.cadillac_tx_hook(self._torque_msg(-MAX_TORQUE))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(-MAX_TORQUE))) # spot check some individual cases for sign in [-1, 1]: @@ -139,20 +143,20 @@ def test_exceed_torque_sensor(self): delta = 1 * sign self._set_prev_torque(torque_desired) self.safety.set_cadillac_torque_driver(-driver_torque, -driver_torque) - self.assertTrue(self.safety.cadillac_tx_hook(self._torque_msg(torque_desired))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(torque_desired))) self._set_prev_torque(torque_desired + delta) self.safety.set_cadillac_torque_driver(-driver_torque, -driver_torque) - self.assertFalse(self.safety.cadillac_tx_hook(self._torque_msg(torque_desired + delta))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(torque_desired + delta))) self._set_prev_torque(MAX_TORQUE * sign) self.safety.set_cadillac_torque_driver(-MAX_TORQUE * sign, -MAX_TORQUE * sign) - self.assertTrue(self.safety.cadillac_tx_hook(self._torque_msg((MAX_TORQUE - MAX_RATE_DOWN) * sign))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg((MAX_TORQUE - MAX_RATE_DOWN) * sign))) self._set_prev_torque(MAX_TORQUE * sign) self.safety.set_cadillac_torque_driver(-MAX_TORQUE * sign, -MAX_TORQUE * sign) - self.assertTrue(self.safety.cadillac_tx_hook(self._torque_msg(0))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(0))) self._set_prev_torque(MAX_TORQUE * sign) self.safety.set_cadillac_torque_driver(-MAX_TORQUE * sign, -MAX_TORQUE * sign) - self.assertFalse(self.safety.cadillac_tx_hook(self._torque_msg((MAX_TORQUE - MAX_RATE_DOWN + 1) * sign))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg((MAX_TORQUE - MAX_RATE_DOWN + 1) * sign))) def test_realtime_limits(self): @@ -164,18 +168,29 @@ def test_realtime_limits(self): self.safety.set_cadillac_torque_driver(0, 0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign - self.assertTrue(self.safety.cadillac_tx_hook(self._torque_msg(t))) - self.assertFalse(self.safety.cadillac_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) self._set_prev_torque(0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign - self.assertTrue(self.safety.cadillac_tx_hook(self._torque_msg(t))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) # Increase timer to update rt_torque_last self.safety.set_timer(RT_INTERVAL + 1) - self.assertTrue(self.safety.cadillac_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA - 1)))) - self.assertTrue(self.safety.cadillac_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA - 1)))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) + + + def test_fwd_hook(self): + # nothing allowed + buss = list(range(0x0, 0x3)) + msgs = list(range(0x1, 0x800)) + + for b in buss: + for m in msgs: + # assume len 8 + self.assertEqual(-1, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) if __name__ == "__main__": diff --git a/panda/tests/safety/test_chrysler.py b/panda/tests/safety/test_chrysler.py index 0fcfc3bcfbf07d..37bffe0eaf392b 100755 --- a/panda/tests/safety/test_chrysler.py +++ b/panda/tests/safety/test_chrysler.py @@ -1,9 +1,8 @@ -#!/usr/bin/env python2 -import csv -import glob +#!/usr/bin/env python3 import unittest import numpy as np -import libpandasafety_py +import libpandasafety_py # pylint: disable=import-error +from panda import Panda MAX_RATE_UP = 3 MAX_RATE_DOWN = 3 @@ -35,9 +34,16 @@ class TestChryslerSafety(unittest.TestCase): @classmethod def setUp(cls): cls.safety = libpandasafety_py.libpandasafety - cls.safety.nooutput_init(0) + cls.safety.safety_set_mode(Panda.SAFETY_CHRYSLER, 0) cls.safety.init_tests_chrysler() + def _send_msg(self, bus, addr, length): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = addr << 21 + to_send[0].RDTR = length + to_send[0].RDTR = bus << 4 + return to_send + def _button_msg(self, buttons): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') to_send[0].RIR = 1265 << 21 @@ -70,9 +76,9 @@ def test_steer_safety_check(self): self.safety.set_controls_allowed(enabled) self._set_prev_torque(t) if abs(t) > MAX_STEER or (not enabled and abs(t) > 0): - self.assertFalse(self.safety.chrysler_tx_hook(self._torque_msg(t))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(t))) else: - self.assertTrue(self.safety.chrysler_tx_hook(self._torque_msg(t))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) def test_manually_enable_controls_allowed(self): self.safety.set_controls_allowed(1) @@ -85,7 +91,7 @@ def test_enable_control_allowed_from_cruise(self): to_push[0].RIR = 0x1f4 << 21 to_push[0].RDLR = 0x380000 - self.safety.chrysler_rx_hook(to_push) + self.safety.safety_rx_hook(to_push) self.assertTrue(self.safety.get_controls_allowed()) def test_disable_control_allowed_from_cruise(self): @@ -94,17 +100,17 @@ def test_disable_control_allowed_from_cruise(self): to_push[0].RDLR = 0 self.safety.set_controls_allowed(1) - self.safety.chrysler_rx_hook(to_push) + self.safety.safety_rx_hook(to_push) self.assertFalse(self.safety.get_controls_allowed()) def test_non_realtime_limit_up(self): self.safety.set_controls_allowed(True) self._set_prev_torque(0) - self.assertTrue(self.safety.chrysler_tx_hook(self._torque_msg(MAX_RATE_UP))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP))) self._set_prev_torque(0) - self.assertFalse(self.safety.chrysler_tx_hook(self._torque_msg(MAX_RATE_UP + 1))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP + 1))) def test_non_realtime_limit_down(self): self.safety.set_controls_allowed(True) @@ -113,12 +119,12 @@ def test_non_realtime_limit_down(self): torque_meas = MAX_STEER - MAX_TORQUE_ERROR - 20 self.safety.set_chrysler_torque_meas(torque_meas, torque_meas) self.safety.set_chrysler_desired_torque_last(MAX_STEER) - self.assertTrue(self.safety.chrysler_tx_hook(self._torque_msg(MAX_STEER - MAX_RATE_DOWN))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(MAX_STEER - MAX_RATE_DOWN))) self.safety.set_chrysler_rt_torque_last(MAX_STEER) self.safety.set_chrysler_torque_meas(torque_meas, torque_meas) self.safety.set_chrysler_desired_torque_last(MAX_STEER) - self.assertFalse(self.safety.chrysler_tx_hook(self._torque_msg(MAX_STEER - MAX_RATE_DOWN + 1))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(MAX_STEER - MAX_RATE_DOWN + 1))) def test_exceed_torque_sensor(self): self.safety.set_controls_allowed(True) @@ -127,9 +133,9 @@ def test_exceed_torque_sensor(self): self._set_prev_torque(0) for t in np.arange(0, MAX_TORQUE_ERROR + 2, 2): # step needs to be smaller than MAX_TORQUE_ERROR t *= sign - self.assertTrue(self.safety.chrysler_tx_hook(self._torque_msg(t))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) - self.assertFalse(self.safety.chrysler_tx_hook(self._torque_msg(sign * (MAX_TORQUE_ERROR + 2)))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_TORQUE_ERROR + 2)))) def test_realtime_limit_up(self): self.safety.set_controls_allowed(True) @@ -140,65 +146,61 @@ def test_realtime_limit_up(self): for t in np.arange(0, MAX_RT_DELTA+1, 1): t *= sign self.safety.set_chrysler_torque_meas(t, t) - self.assertTrue(self.safety.chrysler_tx_hook(self._torque_msg(t))) - self.assertFalse(self.safety.chrysler_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) self._set_prev_torque(0) for t in np.arange(0, MAX_RT_DELTA+1, 1): t *= sign self.safety.set_chrysler_torque_meas(t, t) - self.assertTrue(self.safety.chrysler_tx_hook(self._torque_msg(t))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) # Increase timer to update rt_torque_last self.safety.set_timer(RT_INTERVAL + 1) - self.assertTrue(self.safety.chrysler_tx_hook(self._torque_msg(sign * MAX_RT_DELTA))) - self.assertTrue(self.safety.chrysler_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * MAX_RT_DELTA))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) def test_torque_measurements(self): - self.safety.chrysler_rx_hook(self._torque_meas_msg(50)) - self.safety.chrysler_rx_hook(self._torque_meas_msg(-50)) - self.safety.chrysler_rx_hook(self._torque_meas_msg(0)) - self.safety.chrysler_rx_hook(self._torque_meas_msg(0)) - self.safety.chrysler_rx_hook(self._torque_meas_msg(0)) - self.safety.chrysler_rx_hook(self._torque_meas_msg(0)) + self.safety.safety_rx_hook(self._torque_meas_msg(50)) + self.safety.safety_rx_hook(self._torque_meas_msg(-50)) + self.safety.safety_rx_hook(self._torque_meas_msg(0)) + self.safety.safety_rx_hook(self._torque_meas_msg(0)) + self.safety.safety_rx_hook(self._torque_meas_msg(0)) + self.safety.safety_rx_hook(self._torque_meas_msg(0)) self.assertEqual(-50, self.safety.get_chrysler_torque_meas_min()) self.assertEqual(50, self.safety.get_chrysler_torque_meas_max()) - self.safety.chrysler_rx_hook(self._torque_meas_msg(0)) + self.safety.safety_rx_hook(self._torque_meas_msg(0)) self.assertEqual(0, self.safety.get_chrysler_torque_meas_max()) self.assertEqual(-50, self.safety.get_chrysler_torque_meas_min()) - self.safety.chrysler_rx_hook(self._torque_meas_msg(0)) + self.safety.safety_rx_hook(self._torque_meas_msg(0)) self.assertEqual(0, self.safety.get_chrysler_torque_meas_max()) self.assertEqual(0, self.safety.get_chrysler_torque_meas_min()) - def _replay_drive(self, csv_reader): - for row in csv_reader: - if len(row) != 4: # sometimes truncated at end of the file - continue - if row[0] == 'time': # skip CSV header - continue - addr = int(row[1]) - bus = int(row[2]) - data_str = row[3] # Example '081407ff0806e06f' - to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') - to_send[0].RIR = addr << 21 - to_send[0].RDHR = swap_bytes(data_str[8:]) - to_send[0].RDLR = swap_bytes(data_str[:8]) - if (bus == 128): - self.assertTrue(self.safety.chrysler_tx_hook(to_send), msg=row) - else: - self.safety.chrysler_rx_hook(to_send) - - def test_replay_drive(self): - # In Cabana, click "Save Log" and then put the downloaded CSV in this directory. - test_files = glob.glob('chrysler_*.csv') - for filename in test_files: - print 'testing %s' % filename - with open(filename) as csvfile: - reader = csv.reader(csvfile) - self._replay_drive(reader) + def test_fwd_hook(self): + buss = list(range(0x0, 0x3)) + msgs = list(range(0x1, 0x800)) + chrysler_camera_detected = [0, 1] + + for ccd in chrysler_camera_detected: + self.safety.set_chrysler_camera_detected(ccd) + blocked_msgs = [658, 678] + for b in buss: + for m in msgs: + if not ccd: + if b == 0: + fwd_bus = 2 + elif b == 1: + fwd_bus = -1 + elif b == 2: + fwd_bus = -1 if m in blocked_msgs else 0 + else: + fwd_bus = -1 + + # assume len 8 + self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) if __name__ == "__main__": diff --git a/panda/tests/safety/test_gm.py b/panda/tests/safety/test_gm.py index 299de5a7e9ff51..304dbbe939bf48 100644 --- a/panda/tests/safety/test_gm.py +++ b/panda/tests/safety/test_gm.py @@ -1,7 +1,8 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 import unittest import numpy as np -import libpandasafety_py +import libpandasafety_py # pylint: disable=import-error +from panda import Panda MAX_RATE_UP = 7 MAX_RATE_DOWN = 17 @@ -32,9 +33,16 @@ class TestGmSafety(unittest.TestCase): @classmethod def setUp(cls): cls.safety = libpandasafety_py.libpandasafety - cls.safety.gm_init(0) + cls.safety.safety_set_mode(Panda.SAFETY_GM, 0) cls.safety.init_tests_gm() + def _send_msg(self, bus, addr, length): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = addr << 21 + to_send[0].RDTR = length + to_send[0].RDTR = bus << 4 + return to_send + def _speed_msg(self, speed): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') to_send[0].RIR = 842 << 21 @@ -98,75 +106,86 @@ def test_default_controls_not_allowed(self): def test_resume_button(self): RESUME_BTN = 2 self.safety.set_controls_allowed(0) - self.safety.gm_rx_hook(self._button_msg(RESUME_BTN)) + self.safety.safety_rx_hook(self._button_msg(RESUME_BTN)) self.assertTrue(self.safety.get_controls_allowed()) def test_set_button(self): SET_BTN = 3 self.safety.set_controls_allowed(0) - self.safety.gm_rx_hook(self._button_msg(SET_BTN)) + self.safety.safety_rx_hook(self._button_msg(SET_BTN)) self.assertTrue(self.safety.get_controls_allowed()) def test_cancel_button(self): CANCEL_BTN = 6 self.safety.set_controls_allowed(1) - self.safety.gm_rx_hook(self._button_msg(CANCEL_BTN)) + self.safety.safety_rx_hook(self._button_msg(CANCEL_BTN)) self.assertFalse(self.safety.get_controls_allowed()) def test_disengage_on_brake(self): self.safety.set_controls_allowed(1) - self.safety.gm_rx_hook(self._brake_msg(True)) + self.safety.safety_rx_hook(self._brake_msg(True)) self.assertFalse(self.safety.get_controls_allowed()) def test_allow_brake_at_zero_speed(self): # Brake was already pressed - self.safety.gm_rx_hook(self._brake_msg(True)) + self.safety.safety_rx_hook(self._brake_msg(True)) self.safety.set_controls_allowed(1) - self.safety.gm_rx_hook(self._brake_msg(True)) + self.safety.safety_rx_hook(self._brake_msg(True)) self.assertTrue(self.safety.get_controls_allowed()) - self.safety.gm_rx_hook(self._brake_msg(False)) + self.safety.safety_rx_hook(self._brake_msg(False)) def test_not_allow_brake_when_moving(self): # Brake was already pressed - self.safety.gm_rx_hook(self._brake_msg(True)) - self.safety.gm_rx_hook(self._speed_msg(100)) + self.safety.safety_rx_hook(self._brake_msg(True)) + self.safety.safety_rx_hook(self._speed_msg(100)) self.safety.set_controls_allowed(1) - self.safety.gm_rx_hook(self._brake_msg(True)) + self.safety.safety_rx_hook(self._brake_msg(True)) self.assertFalse(self.safety.get_controls_allowed()) - self.safety.gm_rx_hook(self._brake_msg(False)) + self.safety.safety_rx_hook(self._brake_msg(False)) def test_disengage_on_gas(self): - self.safety.set_controls_allowed(1) - self.safety.gm_rx_hook(self._gas_msg(True)) - self.assertFalse(self.safety.get_controls_allowed()) - self.safety.gm_rx_hook(self._gas_msg(False)) + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + self.safety.set_controls_allowed(1) + self.safety.safety_rx_hook(self._gas_msg(True)) + if long_controls_allowed: + self.assertFalse(self.safety.get_controls_allowed()) + else: + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.safety_rx_hook(self._gas_msg(False)) def test_allow_engage_with_gas_pressed(self): - self.safety.gm_rx_hook(self._gas_msg(True)) + self.safety.safety_rx_hook(self._gas_msg(True)) self.safety.set_controls_allowed(1) - self.safety.gm_rx_hook(self._gas_msg(True)) + self.safety.safety_rx_hook(self._gas_msg(True)) self.assertTrue(self.safety.get_controls_allowed()) - self.safety.gm_rx_hook(self._gas_msg(False)) + self.safety.safety_rx_hook(self._gas_msg(False)) def test_brake_safety_check(self): - for enabled in [0, 1]: - for b in range(0, 500): - self.safety.set_controls_allowed(enabled) - if abs(b) > MAX_BRAKE or (not enabled and b != 0): - self.assertFalse(self.safety.gm_tx_hook(self._send_brake_msg(b))) - else: - self.assertTrue(self.safety.gm_tx_hook(self._send_brake_msg(b))) + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + for enabled in [0, 1]: + for b in range(0, 500): + self.safety.set_controls_allowed(enabled) + if abs(b) > MAX_BRAKE or ((not enabled or not long_controls_allowed) and b != 0): + self.assertFalse(self.safety.safety_tx_hook(self._send_brake_msg(b))) + else: + self.assertTrue(self.safety.safety_tx_hook(self._send_brake_msg(b))) + self.safety.set_long_controls_allowed(True) def test_gas_safety_check(self): - for enabled in [0, 1]: - for g in range(0, 2**12-1): - self.safety.set_controls_allowed(enabled) - if abs(g) > MAX_GAS or (not enabled and g != MAX_REGEN): - self.assertFalse(self.safety.gm_tx_hook(self._send_gas_msg(g))) - else: - self.assertTrue(self.safety.gm_tx_hook(self._send_gas_msg(g))) + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + for enabled in [0, 1]: + for g in range(0, 2**12-1): + self.safety.set_controls_allowed(enabled) + if abs(g) > MAX_GAS or ((not enabled or not long_controls_allowed) and g != MAX_REGEN): + self.assertFalse(self.safety.safety_tx_hook(self._send_gas_msg(g))) + else: + self.assertTrue(self.safety.safety_tx_hook(self._send_gas_msg(g))) + self.safety.set_long_controls_allowed(True) def test_steer_safety_check(self): for enabled in [0, 1]: @@ -174,9 +193,9 @@ def test_steer_safety_check(self): self.safety.set_controls_allowed(enabled) self._set_prev_torque(t) if abs(t) > MAX_STEER or (not enabled and abs(t) > 0): - self.assertFalse(self.safety.gm_tx_hook(self._torque_msg(t))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(t))) else: - self.assertTrue(self.safety.gm_tx_hook(self._torque_msg(t))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) def test_manually_enable_controls_allowed(self): self.safety.set_controls_allowed(1) @@ -189,15 +208,15 @@ def test_non_realtime_limit_up(self): self.safety.set_controls_allowed(True) self._set_prev_torque(0) - self.assertTrue(self.safety.gm_tx_hook(self._torque_msg(MAX_RATE_UP))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP))) self._set_prev_torque(0) - self.assertTrue(self.safety.gm_tx_hook(self._torque_msg(-MAX_RATE_UP))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP))) self._set_prev_torque(0) - self.assertFalse(self.safety.gm_tx_hook(self._torque_msg(MAX_RATE_UP + 1))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP + 1))) self.safety.set_controls_allowed(True) self._set_prev_torque(0) - self.assertFalse(self.safety.gm_tx_hook(self._torque_msg(-MAX_RATE_UP - 1))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP - 1))) def test_non_realtime_limit_down(self): self.safety.set_gm_torque_driver(0, 0) @@ -211,10 +230,10 @@ def test_against_torque_driver(self): t *= -sign self.safety.set_gm_torque_driver(t, t) self._set_prev_torque(MAX_STEER * sign) - self.assertTrue(self.safety.gm_tx_hook(self._torque_msg(MAX_STEER * sign))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(MAX_STEER * sign))) self.safety.set_gm_torque_driver(DRIVER_TORQUE_ALLOWANCE + 1, DRIVER_TORQUE_ALLOWANCE + 1) - self.assertFalse(self.safety.gm_tx_hook(self._torque_msg(-MAX_STEER))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(-MAX_STEER))) # spot check some individual cases for sign in [-1, 1]: @@ -223,20 +242,20 @@ def test_against_torque_driver(self): delta = 1 * sign self._set_prev_torque(torque_desired) self.safety.set_gm_torque_driver(-driver_torque, -driver_torque) - self.assertTrue(self.safety.gm_tx_hook(self._torque_msg(torque_desired))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(torque_desired))) self._set_prev_torque(torque_desired + delta) self.safety.set_gm_torque_driver(-driver_torque, -driver_torque) - self.assertFalse(self.safety.gm_tx_hook(self._torque_msg(torque_desired + delta))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(torque_desired + delta))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_gm_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) - self.assertTrue(self.safety.gm_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN) * sign))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN) * sign))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_gm_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) - self.assertTrue(self.safety.gm_tx_hook(self._torque_msg(0))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(0))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_gm_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) - self.assertFalse(self.safety.gm_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign))) def test_realtime_limits(self): @@ -248,18 +267,29 @@ def test_realtime_limits(self): self.safety.set_gm_torque_driver(0, 0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign - self.assertTrue(self.safety.gm_tx_hook(self._torque_msg(t))) - self.assertFalse(self.safety.gm_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) self._set_prev_torque(0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign - self.assertTrue(self.safety.gm_tx_hook(self._torque_msg(t))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) # Increase timer to update rt_torque_last self.safety.set_timer(RT_INTERVAL + 1) - self.assertTrue(self.safety.gm_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA - 1)))) - self.assertTrue(self.safety.gm_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA - 1)))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) + + + def test_fwd_hook(self): + # nothing allowed + buss = list(range(0x0, 0x3)) + msgs = list(range(0x1, 0x800)) + + for b in buss: + for m in msgs: + # assume len 8 + self.assertEqual(-1, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) if __name__ == "__main__": diff --git a/panda/tests/safety/test_honda.py b/panda/tests/safety/test_honda.py index 48b678eaaec43e..55a376a2e58a37 100755 --- a/panda/tests/safety/test_honda.py +++ b/panda/tests/safety/test_honda.py @@ -1,16 +1,28 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 import unittest import numpy as np -import libpandasafety_py +import libpandasafety_py # pylint: disable=import-error +from panda import Panda +MAX_BRAKE = 255 + +INTERCEPTOR_THRESHOLD = 328 class TestHondaSafety(unittest.TestCase): @classmethod def setUp(cls): cls.safety = libpandasafety_py.libpandasafety - cls.safety.honda_init(0) + cls.safety.safety_set_mode(Panda.SAFETY_HONDA, 0) cls.safety.init_tests_honda() + def _send_msg(self, bus, addr, length): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = addr << 21 + to_send[0].RDTR = length + to_send[0].RDTR = bus << 4 + + return to_send + def _speed_msg(self, speed): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') to_send[0].RIR = 0x158 << 21 @@ -22,6 +34,10 @@ def _button_msg(self, buttons, msg): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') to_send[0].RIR = msg << 21 to_send[0].RDLR = buttons << 5 + has_relay = self.safety.board_has_relay() + honda_bosch_hardware = self.safety.get_honda_bosch_hardware() + bus = 1 if has_relay and honda_bosch_hardware else 0 + to_send[0].RDTR = bus << 4 return to_send @@ -49,14 +65,17 @@ def _gas_msg(self, gas): def _send_brake_msg(self, brake): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') to_send[0].RIR = 0x1FA << 21 - to_send[0].RDLR = brake + to_send[0].RDLR = ((brake & 0x3) << 14) | ((brake & 0x3FF) >> 2) return to_send - def _send_gas_msg(self, gas): + def _send_interceptor_msg(self, gas, addr): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') - to_send[0].RIR = 0x200 << 21 - to_send[0].RDLR = gas + to_send[0].RIR = addr << 21 + to_send[0].RDTR = 6 + gas2 = gas * 2 + to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8) | \ + ((gas2 & 0xff) << 24) | ((gas2 & 0xff00) << 8) return to_send @@ -73,112 +92,200 @@ def test_default_controls_not_allowed(self): def test_resume_button(self): RESUME_BTN = 4 self.safety.set_controls_allowed(0) - self.safety.honda_rx_hook(self._button_msg(RESUME_BTN, 0x1A6)) + self.safety.safety_rx_hook(self._button_msg(RESUME_BTN, 0x1A6)) self.assertTrue(self.safety.get_controls_allowed()) def test_set_button(self): SET_BTN = 3 self.safety.set_controls_allowed(0) - self.safety.honda_rx_hook(self._button_msg(SET_BTN, 0x1A6)) + self.safety.safety_rx_hook(self._button_msg(SET_BTN, 0x1A6)) self.assertTrue(self.safety.get_controls_allowed()) def test_cancel_button(self): CANCEL_BTN = 2 self.safety.set_controls_allowed(1) - self.safety.honda_rx_hook(self._button_msg(CANCEL_BTN, 0x1A6)) + self.safety.safety_rx_hook(self._button_msg(CANCEL_BTN, 0x1A6)) self.assertFalse(self.safety.get_controls_allowed()) def test_sample_speed(self): - self.assertEqual(0, self.safety.get_ego_speed()) - self.safety.honda_rx_hook(self._speed_msg(100)) - self.assertEqual(100, self.safety.get_ego_speed()) + self.assertEqual(0, self.safety.get_honda_moving()) + self.safety.safety_rx_hook(self._speed_msg(100)) + self.assertEqual(1, self.safety.get_honda_moving()) def test_prev_brake(self): - self.assertFalse(self.safety.get_brake_prev()) - self.safety.honda_rx_hook(self._brake_msg(True)) - self.assertTrue(self.safety.get_brake_prev()) + self.assertFalse(self.safety.get_honda_brake_pressed_prev()) + self.safety.safety_rx_hook(self._brake_msg(True)) + self.assertTrue(self.safety.get_honda_brake_pressed_prev()) def test_disengage_on_brake(self): self.safety.set_controls_allowed(1) - self.safety.honda_rx_hook(self._brake_msg(1)) + self.safety.safety_rx_hook(self._brake_msg(1)) self.assertFalse(self.safety.get_controls_allowed()) def test_alt_disengage_on_brake(self): self.safety.set_honda_alt_brake_msg(1) self.safety.set_controls_allowed(1) - self.safety.honda_rx_hook(self._alt_brake_msg(1)) + self.safety.safety_rx_hook(self._alt_brake_msg(1)) self.assertFalse(self.safety.get_controls_allowed()) self.safety.set_honda_alt_brake_msg(0) self.safety.set_controls_allowed(1) - self.safety.honda_rx_hook(self._alt_brake_msg(1)) + self.safety.safety_rx_hook(self._alt_brake_msg(1)) self.assertTrue(self.safety.get_controls_allowed()) def test_allow_brake_at_zero_speed(self): # Brake was already pressed - self.safety.honda_rx_hook(self._brake_msg(True)) + self.safety.safety_rx_hook(self._brake_msg(True)) self.safety.set_controls_allowed(1) - self.safety.honda_rx_hook(self._brake_msg(True)) + self.safety.safety_rx_hook(self._brake_msg(True)) self.assertTrue(self.safety.get_controls_allowed()) - self.safety.honda_rx_hook(self._brake_msg(False)) # reset no brakes + self.safety.safety_rx_hook(self._brake_msg(False)) # reset no brakes def test_not_allow_brake_when_moving(self): # Brake was already pressed - self.safety.honda_rx_hook(self._brake_msg(True)) - self.safety.honda_rx_hook(self._speed_msg(100)) + self.safety.safety_rx_hook(self._brake_msg(True)) + self.safety.safety_rx_hook(self._speed_msg(100)) self.safety.set_controls_allowed(1) - self.safety.honda_rx_hook(self._brake_msg(True)) + self.safety.safety_rx_hook(self._brake_msg(True)) self.assertFalse(self.safety.get_controls_allowed()) def test_prev_gas(self): - self.assertFalse(self.safety.get_gas_prev()) - self.safety.honda_rx_hook(self._gas_msg(True)) - self.assertTrue(self.safety.get_gas_prev()) + self.safety.safety_rx_hook(self._gas_msg(False)) + self.assertFalse(self.safety.get_honda_gas_prev()) + self.safety.safety_rx_hook(self._gas_msg(True)) + self.assertTrue(self.safety.get_honda_gas_prev()) + + def test_prev_gas_interceptor(self): + self.safety.safety_rx_hook(self._send_interceptor_msg(0x0, 0x201)) + self.assertFalse(self.safety.get_gas_interceptor_prev()) + self.safety.safety_rx_hook(self._send_interceptor_msg(0x1000, 0x201)) + self.assertTrue(self.safety.get_gas_interceptor_prev()) + self.safety.safety_rx_hook(self._send_interceptor_msg(0x0, 0x201)) + self.safety.set_gas_interceptor_detected(False) def test_disengage_on_gas(self): - self.safety.set_controls_allowed(1) - self.safety.honda_rx_hook(self._gas_msg(1)) - self.assertFalse(self.safety.get_controls_allowed()) + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + self.safety.safety_rx_hook(self._gas_msg(0)) + self.safety.set_controls_allowed(1) + self.safety.safety_rx_hook(self._gas_msg(1)) + if long_controls_allowed: + self.assertFalse(self.safety.get_controls_allowed()) + else: + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.set_long_controls_allowed(True) def test_allow_engage_with_gas_pressed(self): - self.safety.honda_rx_hook(self._gas_msg(1)) + self.safety.safety_rx_hook(self._gas_msg(1)) self.safety.set_controls_allowed(1) - self.safety.honda_rx_hook(self._gas_msg(1)) + self.safety.safety_rx_hook(self._gas_msg(1)) self.assertTrue(self.safety.get_controls_allowed()) - def test_brake_safety_check(self): - self.assertTrue(self.safety.honda_tx_hook(self._send_brake_msg(0x0000))) - self.assertFalse(self.safety.honda_tx_hook(self._send_brake_msg(0x1000))) - + def test_disengage_on_gas_interceptor(self): + for long_controls_allowed in [0, 1]: + for g in range(0, 0x1000): + self.safety.set_long_controls_allowed(long_controls_allowed) + self.safety.safety_rx_hook(self._send_interceptor_msg(0, 0x201)) + self.safety.set_controls_allowed(True) + self.safety.safety_rx_hook(self._send_interceptor_msg(g, 0x201)) + remain_enabled = (not long_controls_allowed or g <= INTERCEPTOR_THRESHOLD) + self.assertEqual(remain_enabled, self.safety.get_controls_allowed()) + self.safety.safety_rx_hook(self._send_interceptor_msg(0, 0x201)) + self.safety.set_gas_interceptor_detected(False) + self.safety.set_long_controls_allowed(True) + + def test_allow_engage_with_gas_interceptor_pressed(self): + self.safety.safety_rx_hook(self._send_interceptor_msg(0x1000, 0x201)) self.safety.set_controls_allowed(1) - self.assertTrue(self.safety.honda_tx_hook(self._send_brake_msg(0x1000))) - self.assertFalse(self.safety.honda_tx_hook(self._send_brake_msg(0x00F0))) + self.safety.safety_rx_hook(self._send_interceptor_msg(0x1000, 0x201)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.safety_rx_hook(self._send_interceptor_msg(0, 0x201)) + self.safety.set_gas_interceptor_detected(False) - def test_gas_safety_check(self): - self.safety.set_controls_allowed(0) - self.assertTrue(self.safety.honda_tx_hook(self._send_gas_msg(0x0000))) - self.assertFalse(self.safety.honda_tx_hook(self._send_gas_msg(0x1000))) + def test_brake_safety_check(self): + for fwd_brake in [False, True]: + self.safety.set_honda_fwd_brake(fwd_brake) + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + for brake in np.arange(0, MAX_BRAKE + 10, 1): + for controls_allowed in [True, False]: + self.safety.set_controls_allowed(controls_allowed) + if fwd_brake: + send = False # block openpilot brake msg when fwd'ing stock msg + elif controls_allowed and long_controls_allowed: + send = MAX_BRAKE >= brake >= 0 + else: + send = brake == 0 + self.assertEqual(send, self.safety.safety_tx_hook(self._send_brake_msg(brake))) + self.safety.set_long_controls_allowed(True) + self.safety.set_honda_fwd_brake(False) + + def test_gas_interceptor_safety_check(self): + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + for gas in np.arange(0, 4000, 100): + for controls_allowed in [True, False]: + self.safety.set_controls_allowed(controls_allowed) + if controls_allowed and long_controls_allowed: + send = True + else: + send = gas == 0 + self.assertEqual(send, self.safety.safety_tx_hook(self._send_interceptor_msg(gas, 0x200))) + self.safety.set_long_controls_allowed(True) def test_steer_safety_check(self): self.safety.set_controls_allowed(0) - self.assertTrue(self.safety.honda_tx_hook(self._send_steer_msg(0x0000))) - self.assertFalse(self.safety.honda_tx_hook(self._send_steer_msg(0x1000))) + self.assertTrue(self.safety.safety_tx_hook(self._send_steer_msg(0x0000))) + self.assertFalse(self.safety.safety_tx_hook(self._send_steer_msg(0x1000))) def test_spam_cancel_safety_check(self): RESUME_BTN = 4 SET_BTN = 3 CANCEL_BTN = 2 BUTTON_MSG = 0x296 - self.safety.set_bosch_hardware(1) + self.safety.set_honda_bosch_hardware(1) self.safety.set_controls_allowed(0) - self.assertTrue(self.safety.honda_tx_hook(self._button_msg(CANCEL_BTN, BUTTON_MSG))) - self.assertFalse(self.safety.honda_tx_hook(self._button_msg(RESUME_BTN, BUTTON_MSG))) - self.assertFalse(self.safety.honda_tx_hook(self._button_msg(SET_BTN, BUTTON_MSG))) + self.assertTrue(self.safety.safety_tx_hook(self._button_msg(CANCEL_BTN, BUTTON_MSG))) + self.assertFalse(self.safety.safety_tx_hook(self._button_msg(RESUME_BTN, BUTTON_MSG))) + self.assertFalse(self.safety.safety_tx_hook(self._button_msg(SET_BTN, BUTTON_MSG))) # do not block resume if we are engaged already self.safety.set_controls_allowed(1) - self.assertTrue(self.safety.honda_tx_hook(self._button_msg(RESUME_BTN, BUTTON_MSG))) + self.assertTrue(self.safety.safety_tx_hook(self._button_msg(RESUME_BTN, BUTTON_MSG))) + + def test_fwd_hook(self): + buss = list(range(0x0, 0x3)) + msgs = list(range(0x1, 0x800)) + long_controls_allowed = [0, 1] + fwd_brake = [False, True] + + self.safety.set_honda_bosch_hardware(0) + + for f in fwd_brake: + self.safety.set_honda_fwd_brake(f) + for l in long_controls_allowed: + self.safety.set_long_controls_allowed(l) + blocked_msgs = [0xE4, 0x194, 0x33D] + if l: + blocked_msgs += [0x30C, 0x39F] + if not f: + blocked_msgs += [0x1FA] + for b in buss: + for m in msgs: + if b == 0: + fwd_bus = 2 + elif b == 1: + fwd_bus = -1 + elif b == 2: + fwd_bus = -1 if m in blocked_msgs else 0 + + # assume len 8 + self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) + + self.safety.set_long_controls_allowed(True) + self.safety.set_honda_fwd_brake(False) + if __name__ == "__main__": diff --git a/panda/tests/safety/test_honda_bosch.py b/panda/tests/safety/test_honda_bosch.py new file mode 100755 index 00000000000000..7571e1eddc4576 --- /dev/null +++ b/panda/tests/safety/test_honda_bosch.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +import unittest +import libpandasafety_py # pylint: disable=import-error +from panda import Panda + +MAX_BRAKE = 255 + +class TestHondaSafety(unittest.TestCase): + @classmethod + def setUp(cls): + cls.safety = libpandasafety_py.libpandasafety + cls.safety.safety_set_mode(Panda.SAFETY_HONDA_BOSCH, 0) + cls.safety.init_tests_honda() + + def _send_msg(self, bus, addr, length): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = addr << 21 + to_send[0].RDTR = length + to_send[0].RDTR = bus << 4 + + return to_send + + def test_fwd_hook(self): + buss = range(0x0, 0x3) + msgs = range(0x1, 0x800) + #has_relay = self.safety.get_hw_type() == 3 # black panda + has_relay = self.safety.board_has_relay() + bus_rdr_cam = 2 if has_relay else 1 + bus_rdr_car = 0 if has_relay else 2 + bus_pt = 1 if has_relay else 0 + + blocked_msgs = [0xE4, 0x33D] + for b in buss: + for m in msgs: + if b == bus_pt: + fwd_bus = -1 + elif b == bus_rdr_cam: + fwd_bus = -1 if m in blocked_msgs else bus_rdr_car + elif b == bus_rdr_car: + fwd_bus = bus_rdr_cam + + # assume len 8 + self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) + + +if __name__ == "__main__": + unittest.main() diff --git a/panda/tests/safety/test_hyundai.py b/panda/tests/safety/test_hyundai.py index bcf9b761189d55..d8fa02691b6d41 100644 --- a/panda/tests/safety/test_hyundai.py +++ b/panda/tests/safety/test_hyundai.py @@ -1,7 +1,8 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 import unittest import numpy as np -import libpandasafety_py +import libpandasafety_py # pylint: disable=import-error +from panda import Panda MAX_RATE_UP = 3 MAX_RATE_DOWN = 7 @@ -29,9 +30,16 @@ class TestHyundaiSafety(unittest.TestCase): @classmethod def setUp(cls): cls.safety = libpandasafety_py.libpandasafety - cls.safety.nooutput_init(0) + cls.safety.safety_set_mode(Panda.SAFETY_HYUNDAI, 0) cls.safety.init_tests_hyundai() + def _send_msg(self, bus, addr, length): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = addr << 21 + to_send[0].RDTR = length + to_send[0].RDTR = bus << 4 + return to_send + def _button_msg(self, buttons): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') to_send[0].RIR = 1265 << 21 @@ -63,9 +71,9 @@ def test_steer_safety_check(self): self.safety.set_controls_allowed(enabled) self._set_prev_torque(t) if abs(t) > MAX_STEER or (not enabled and abs(t) > 0): - self.assertFalse(self.safety.hyundai_tx_hook(self._torque_msg(t))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(t))) else: - self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(t))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) def test_manually_enable_controls_allowed(self): self.safety.set_controls_allowed(1) @@ -78,7 +86,7 @@ def test_enable_control_allowed_from_cruise(self): to_push[0].RIR = 1057 << 21 to_push[0].RDLR = 1 << 13 - self.safety.hyundai_rx_hook(to_push) + self.safety.safety_rx_hook(to_push) self.assertTrue(self.safety.get_controls_allowed()) def test_disable_control_allowed_from_cruise(self): @@ -87,7 +95,7 @@ def test_disable_control_allowed_from_cruise(self): to_push[0].RDLR = 0 self.safety.set_controls_allowed(1) - self.safety.hyundai_rx_hook(to_push) + self.safety.safety_rx_hook(to_push) self.assertFalse(self.safety.get_controls_allowed()) def test_non_realtime_limit_up(self): @@ -95,15 +103,15 @@ def test_non_realtime_limit_up(self): self.safety.set_controls_allowed(True) self._set_prev_torque(0) - self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(MAX_RATE_UP))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP))) self._set_prev_torque(0) - self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(-MAX_RATE_UP))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP))) self._set_prev_torque(0) - self.assertFalse(self.safety.hyundai_tx_hook(self._torque_msg(MAX_RATE_UP + 1))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP + 1))) self.safety.set_controls_allowed(True) self._set_prev_torque(0) - self.assertFalse(self.safety.hyundai_tx_hook(self._torque_msg(-MAX_RATE_UP - 1))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP - 1))) def test_non_realtime_limit_down(self): self.safety.set_hyundai_torque_driver(0, 0) @@ -117,10 +125,10 @@ def test_against_torque_driver(self): t *= -sign self.safety.set_hyundai_torque_driver(t, t) self._set_prev_torque(MAX_STEER * sign) - self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(MAX_STEER * sign))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(MAX_STEER * sign))) self.safety.set_hyundai_torque_driver(DRIVER_TORQUE_ALLOWANCE + 1, DRIVER_TORQUE_ALLOWANCE + 1) - self.assertFalse(self.safety.hyundai_tx_hook(self._torque_msg(-MAX_STEER))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(-MAX_STEER))) # spot check some individual cases for sign in [-1, 1]: @@ -129,20 +137,20 @@ def test_against_torque_driver(self): delta = 1 * sign self._set_prev_torque(torque_desired) self.safety.set_hyundai_torque_driver(-driver_torque, -driver_torque) - self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(torque_desired))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(torque_desired))) self._set_prev_torque(torque_desired + delta) self.safety.set_hyundai_torque_driver(-driver_torque, -driver_torque) - self.assertFalse(self.safety.hyundai_tx_hook(self._torque_msg(torque_desired + delta))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(torque_desired + delta))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_hyundai_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) - self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN) * sign))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN) * sign))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_hyundai_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) - self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(0))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(0))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_hyundai_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) - self.assertFalse(self.safety.hyundai_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign))) def test_realtime_limits(self): @@ -154,18 +162,18 @@ def test_realtime_limits(self): self.safety.set_hyundai_torque_driver(0, 0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign - self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(t))) - self.assertFalse(self.safety.hyundai_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) self._set_prev_torque(0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign - self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(t))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) # Increase timer to update rt_torque_last self.safety.set_timer(RT_INTERVAL + 1) - self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA - 1)))) - self.assertTrue(self.safety.hyundai_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA - 1)))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) #def test_spam_cancel_safety_check(self): @@ -174,12 +182,37 @@ def test_realtime_limits(self): # CANCEL_BTN = 4 # BUTTON_MSG = 1265 # self.safety.set_controls_allowed(0) - # self.assertTrue(self.safety.hyundai_tx_hook(self._button_msg(CANCEL_BTN))) - # self.assertFalse(self.safety.hyundai_tx_hook(self._button_msg(RESUME_BTN))) - # self.assertFalse(self.safety.hyundai_tx_hook(self._button_msg(SET_BTN))) + # self.assertTrue(self.safety.safety_tx_hook(self._button_msg(CANCEL_BTN))) + # self.assertFalse(self.safety.safety_tx_hook(self._button_msg(RESUME_BTN))) + # self.assertFalse(self.safety.safety_tx_hook(self._button_msg(SET_BTN))) # # do not block resume if we are engaged already # self.safety.set_controls_allowed(1) - # self.assertTrue(self.safety.hyundai_tx_hook(self._button_msg(RESUME_BTN))) + # self.assertTrue(self.safety.safety_tx_hook(self._button_msg(RESUME_BTN))) + + def test_fwd_hook(self): + + buss = list(range(0x0, 0x3)) + msgs = list(range(0x1, 0x800)) + hyundai_giraffe_switch_2 = [0, 1] + + self.safety.set_hyundai_camera_bus(2) + for hgs in hyundai_giraffe_switch_2: + self.safety.set_hyundai_giraffe_switch_2(hgs) + blocked_msgs = [832] + for b in buss: + for m in msgs: + if hgs: + if b == 0: + fwd_bus = 2 + elif b == 1: + fwd_bus = -1 + elif b == 2: + fwd_bus = -1 if m in blocked_msgs else 0 + else: + fwd_bus = -1 + + # assume len 8 + self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) if __name__ == "__main__": diff --git a/panda/tests/safety/test_subaru.py b/panda/tests/safety/test_subaru.py index a1e03fea15cc85..49933e6636dd3c 100644 --- a/panda/tests/safety/test_subaru.py +++ b/panda/tests/safety/test_subaru.py @@ -1,7 +1,8 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 import unittest import numpy as np -import libpandasafety_py +import libpandasafety_py # pylint: disable=import-error +from panda import Panda MAX_RATE_UP = 50 MAX_RATE_DOWN = 70 @@ -29,9 +30,16 @@ class TestSubaruSafety(unittest.TestCase): @classmethod def setUp(cls): cls.safety = libpandasafety_py.libpandasafety - cls.safety.nooutput_init(0) + cls.safety.safety_set_mode(Panda.SAFETY_SUBARU, 0) cls.safety.init_tests_subaru() + def _send_msg(self, bus, addr, length): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = addr << 21 + to_send[0].RDTR = length + to_send[0].RDTR = bus << 4 + return to_send + def _set_prev_torque(self, t): self.safety.set_subaru_desired_torque_last(t) self.safety.set_subaru_rt_torque_last(t) @@ -60,7 +68,7 @@ def test_enable_control_allowed_from_cruise(self): to_push[0].RIR = 0x240 << 21 to_push[0].RDHR = 1 << 9 - self.safety.subaru_rx_hook(to_push) + self.safety.safety_rx_hook(to_push) self.assertTrue(self.safety.get_controls_allowed()) def test_disable_control_allowed_from_cruise(self): @@ -69,7 +77,7 @@ def test_disable_control_allowed_from_cruise(self): to_push[0].RDHR = 0 self.safety.set_controls_allowed(1) - self.safety.subaru_rx_hook(to_push) + self.safety.safety_rx_hook(to_push) self.assertFalse(self.safety.get_controls_allowed()) def test_steer_safety_check(self): @@ -78,9 +86,9 @@ def test_steer_safety_check(self): self.safety.set_controls_allowed(enabled) self._set_prev_torque(t) if abs(t) > MAX_STEER or (not enabled and abs(t) > 0): - self.assertFalse(self.safety.subaru_tx_hook(self._torque_msg(t))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(t))) else: - self.assertTrue(self.safety.subaru_tx_hook(self._torque_msg(t))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) def test_manually_enable_controls_allowed(self): self.safety.set_controls_allowed(1) @@ -93,15 +101,15 @@ def test_non_realtime_limit_up(self): self.safety.set_controls_allowed(True) self._set_prev_torque(0) - self.assertTrue(self.safety.subaru_tx_hook(self._torque_msg(MAX_RATE_UP))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP))) self._set_prev_torque(0) - self.assertTrue(self.safety.subaru_tx_hook(self._torque_msg(-MAX_RATE_UP))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP))) self._set_prev_torque(0) - self.assertFalse(self.safety.subaru_tx_hook(self._torque_msg(MAX_RATE_UP + 1))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP + 1))) self.safety.set_controls_allowed(True) self._set_prev_torque(0) - self.assertFalse(self.safety.subaru_tx_hook(self._torque_msg(-MAX_RATE_UP - 1))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP - 1))) def test_non_realtime_limit_down(self): self.safety.set_subaru_torque_driver(0, 0) @@ -115,10 +123,10 @@ def test_against_torque_driver(self): t *= -sign self.safety.set_subaru_torque_driver(t, t) self._set_prev_torque(MAX_STEER * sign) - self.assertTrue(self.safety.subaru_tx_hook(self._torque_msg(MAX_STEER * sign))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(MAX_STEER * sign))) self.safety.set_subaru_torque_driver(DRIVER_TORQUE_ALLOWANCE + 1, DRIVER_TORQUE_ALLOWANCE + 1) - self.assertFalse(self.safety.subaru_tx_hook(self._torque_msg(-MAX_STEER))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(-MAX_STEER))) # spot check some individual cases for sign in [-1, 1]: @@ -127,20 +135,20 @@ def test_against_torque_driver(self): delta = 1 * sign self._set_prev_torque(torque_desired) self.safety.set_subaru_torque_driver(-driver_torque, -driver_torque) - self.assertTrue(self.safety.subaru_tx_hook(self._torque_msg(torque_desired))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(torque_desired))) self._set_prev_torque(torque_desired + delta) self.safety.set_subaru_torque_driver(-driver_torque, -driver_torque) - self.assertFalse(self.safety.subaru_tx_hook(self._torque_msg(torque_desired + delta))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(torque_desired + delta))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_subaru_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) - self.assertTrue(self.safety.subaru_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN) * sign))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN) * sign))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_subaru_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) - self.assertTrue(self.safety.subaru_tx_hook(self._torque_msg(0))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(0))) self._set_prev_torque(MAX_STEER * sign) self.safety.set_subaru_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) - self.assertFalse(self.safety.subaru_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign))) def test_realtime_limits(self): @@ -152,18 +160,35 @@ def test_realtime_limits(self): self.safety.set_subaru_torque_driver(0, 0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign - self.assertTrue(self.safety.subaru_tx_hook(self._torque_msg(t))) - self.assertFalse(self.safety.subaru_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) self._set_prev_torque(0) for t in np.arange(0, MAX_RT_DELTA, 1): t *= sign - self.assertTrue(self.safety.subaru_tx_hook(self._torque_msg(t))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) # Increase timer to update rt_torque_last self.safety.set_timer(RT_INTERVAL + 1) - self.assertTrue(self.safety.subaru_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA - 1)))) - self.assertTrue(self.safety.subaru_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA - 1)))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) + + + def test_fwd_hook(self): + buss = list(range(0x0, 0x3)) + msgs = list(range(0x1, 0x800)) + blocked_msgs = [290, 356, 545, 802] + for b in buss: + for m in msgs: + if b == 0: + fwd_bus = 2 + elif b == 1: + fwd_bus = -1 + elif b == 2: + fwd_bus = -1 if m in blocked_msgs else 0 + + # assume len 8 + self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) if __name__ == "__main__": diff --git a/panda/tests/safety/test_toyota.py b/panda/tests/safety/test_toyota.py index 52c7015af3e5bc..15d3b20cc5f8bc 100644 --- a/panda/tests/safety/test_toyota.py +++ b/panda/tests/safety/test_toyota.py @@ -1,7 +1,8 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 import unittest import numpy as np -import libpandasafety_py +import libpandasafety_py # pylint: disable=import-error +from panda import Panda MAX_RATE_UP = 10 MAX_RATE_DOWN = 25 @@ -15,11 +16,7 @@ MAX_TORQUE_ERROR = 350 -IPAS_OVERRIDE_THRESHOLD = 200 - -ANGLE_DELTA_BP = [0., 5., 15.] -ANGLE_DELTA_V = [5., .8, .15] # windup limit -ANGLE_DELTA_VU = [5., 3.5, 0.4] # unwind limit +INTERCEPTOR_THRESHOLD = 475 def twos_comp(val, bits): if val >= 0: @@ -37,9 +34,16 @@ class TestToyotaSafety(unittest.TestCase): @classmethod def setUp(cls): cls.safety = libpandasafety_py.libpandasafety - cls.safety.toyota_init(100) + cls.safety.safety_set_mode(Panda.SAFETY_TOYOTA, 100) cls.safety.init_tests_toyota() + def _send_msg(self, bus, addr, length): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = addr << 21 + to_send[0].RDTR = length + to_send[0].RDTR = bus << 4 + return to_send + def _set_prev_torque(self, t): self.safety.set_toyota_desired_torque_last(t) self.safety.set_toyota_rt_torque_last(t) @@ -53,30 +57,6 @@ def _torque_meas_msg(self, torque): to_send[0].RDHR = t | ((t & 0xFF) << 16) return to_send - def _torque_driver_msg(self, torque): - to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') - to_send[0].RIR = 0x260 << 21 - - t = twos_comp(torque, 16) - to_send[0].RDLR = t | ((t & 0xFF) << 16) - return to_send - - def _torque_driver_msg_array(self, torque): - for i in range(6): - self.safety.toyota_ipas_rx_hook(self._torque_driver_msg(torque)) - - def _angle_meas_msg(self, angle): - to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') - to_send[0].RIR = 0x25 << 21 - - t = twos_comp(angle, 12) - to_send[0].RDLR = ((t & 0xF00) >> 8) | ((t & 0xFF) << 8) - return to_send - - def _angle_meas_msg_array(self, angle): - for i in range(6): - self.safety.toyota_ipas_rx_hook(self._angle_meas_msg(angle)) - def _torque_msg(self, torque): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') to_send[0].RIR = 0x2E4 << 21 @@ -85,44 +65,35 @@ def _torque_msg(self, torque): to_send[0].RDLR = t | ((t & 0xFF) << 16) return to_send - def _ipas_state_msg(self, state): + def _accel_msg(self, accel): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') - to_send[0].RIR = 0x262 << 21 + to_send[0].RIR = 0x343 << 21 - to_send[0].RDLR = state & 0xF + a = twos_comp(accel, 16) + to_send[0].RDLR = (a & 0xFF) << 8 | (a >> 8) return to_send - def _ipas_control_msg(self, angle, state): - # note: we command 2/3 of the angle due to CAN conversion + def _send_gas_msg(self, gas): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') - to_send[0].RIR = 0x266 << 21 - - t = twos_comp(angle, 12) - to_send[0].RDLR = ((t & 0xF00) >> 8) | ((t & 0xFF) << 8) - to_send[0].RDLR |= ((state & 0xf) << 4) + to_send[0].RIR = 0x2C1 << 21 + to_send[0].RDHR = (gas & 0xFF) << 16 return to_send - def _speed_msg(self, speed): + def _send_interceptor_msg(self, gas, addr): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') - to_send[0].RIR = 0xb4 << 21 - speed = int(speed * 100 * 3.6) + to_send[0].RIR = addr << 21 + to_send[0].RDTR = 6 + gas2 = gas * 2 + to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8) | \ + ((gas2 & 0xff) << 24) | ((gas2 & 0xff00) << 8) - to_send[0].RDHR = ((speed & 0xFF) << 16) | (speed & 0xFF00) return to_send - def _accel_msg(self, accel): + def _pcm_cruise_msg(self, cruise_on): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') - to_send[0].RIR = 0x343 << 21 - - a = twos_comp(accel, 16) - to_send[0].RDLR = (a & 0xFF) << 8 | (a >> 8) - return to_send - - def _gas_msg(self, gas): - to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') - to_send[0].RIR = 0x200 << 21 - to_send[0].RDLR = gas + to_send[0].RIR = 0x1D2 << 21 + to_send[0].RDLR = cruise_on << 5 return to_send @@ -134,32 +105,82 @@ def test_manually_enable_controls_allowed(self): self.assertTrue(self.safety.get_controls_allowed()) def test_enable_control_allowed_from_cruise(self): - to_push = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') - to_push[0].RIR = 0x1D2 << 21 - to_push[0].RDLR = 0x20 - - self.safety.toyota_rx_hook(to_push) + self.safety.safety_rx_hook(self._pcm_cruise_msg(False)) + self.assertFalse(self.safety.get_controls_allowed()) + self.safety.safety_rx_hook(self._pcm_cruise_msg(True)) self.assertTrue(self.safety.get_controls_allowed()) def test_disable_control_allowed_from_cruise(self): - to_push = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') - to_push[0].RIR = 0x1D2 << 21 - to_push[0].RDLR = 0 - self.safety.set_controls_allowed(1) - self.safety.toyota_rx_hook(to_push) + self.safety.safety_rx_hook(self._pcm_cruise_msg(False)) self.assertFalse(self.safety.get_controls_allowed()) - def test_accel_actuation_limits(self): - for accel in np.arange(MIN_ACCEL - 1000, MAX_ACCEL + 1000, 100): - for controls_allowed in [True, False]: - self.safety.set_controls_allowed(controls_allowed) + def test_prev_gas(self): + for g in range(0, 256): + self.safety.safety_rx_hook(self._send_gas_msg(g)) + self.assertEqual(g, self.safety.get_toyota_gas_prev()) + + def test_prev_gas_interceptor(self): + self.safety.safety_rx_hook(self._send_interceptor_msg(0x0, 0x201)) + self.assertFalse(self.safety.get_gas_interceptor_prev()) + self.safety.safety_rx_hook(self._send_interceptor_msg(0x1000, 0x201)) + self.assertTrue(self.safety.get_gas_interceptor_prev()) + self.safety.safety_rx_hook(self._send_interceptor_msg(0x0, 0x201)) + self.safety.set_gas_interceptor_detected(False) + + def test_disengage_on_gas(self): + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + self.safety.safety_rx_hook(self._send_gas_msg(0)) + self.safety.set_controls_allowed(True) + self.safety.safety_rx_hook(self._send_gas_msg(1)) + if long_controls_allowed: + self.assertFalse(self.safety.get_controls_allowed()) + else: + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.set_long_controls_allowed(True) - if controls_allowed: - send = MIN_ACCEL <= accel <= MAX_ACCEL - else: - send = accel == 0 - self.assertEqual(send, self.safety.toyota_tx_hook(self._accel_msg(accel))) + def test_allow_engage_with_gas_pressed(self): + self.safety.safety_rx_hook(self._send_gas_msg(1)) + self.safety.set_controls_allowed(True) + self.safety.safety_rx_hook(self._send_gas_msg(1)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.safety_rx_hook(self._send_gas_msg(1)) + self.assertTrue(self.safety.get_controls_allowed()) + + def test_disengage_on_gas_interceptor(self): + for long_controls_allowed in [0, 1]: + for g in range(0, 0x1000): + self.safety.set_long_controls_allowed(long_controls_allowed) + self.safety.safety_rx_hook(self._send_interceptor_msg(0, 0x201)) + self.safety.set_controls_allowed(True) + self.safety.safety_rx_hook(self._send_interceptor_msg(g, 0x201)) + remain_enabled = (not long_controls_allowed or g <= INTERCEPTOR_THRESHOLD) + self.assertEqual(remain_enabled, self.safety.get_controls_allowed()) + self.safety.safety_rx_hook(self._send_interceptor_msg(0, 0x201)) + self.safety.set_gas_interceptor_detected(False) + self.safety.set_long_controls_allowed(True) + + def test_allow_engage_with_gas_interceptor_pressed(self): + self.safety.safety_rx_hook(self._send_interceptor_msg(0x1000, 0x201)) + self.safety.set_controls_allowed(1) + self.safety.safety_rx_hook(self._send_interceptor_msg(0x1000, 0x201)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.safety_rx_hook(self._send_interceptor_msg(0, 0x201)) + self.safety.set_gas_interceptor_detected(False) + + def test_accel_actuation_limits(self): + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + for accel in np.arange(MIN_ACCEL - 1000, MAX_ACCEL + 1000, 100): + for controls_allowed in [True, False]: + self.safety.set_controls_allowed(controls_allowed) + if controls_allowed and long_controls_allowed: + send = MIN_ACCEL <= accel <= MAX_ACCEL + else: + send = accel == 0 + self.assertEqual(send, self.safety.safety_tx_hook(self._accel_msg(accel))) + self.safety.set_long_controls_allowed(True) def test_torque_absolute_limits(self): for controls_allowed in [True, False]: @@ -174,16 +195,16 @@ def test_torque_absolute_limits(self): else: send = torque == 0 - self.assertEqual(send, self.safety.toyota_tx_hook(self._torque_msg(torque))) + self.assertEqual(send, self.safety.safety_tx_hook(self._torque_msg(torque))) def test_non_realtime_limit_up(self): self.safety.set_controls_allowed(True) self._set_prev_torque(0) - self.assertTrue(self.safety.toyota_tx_hook(self._torque_msg(MAX_RATE_UP))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP))) self._set_prev_torque(0) - self.assertFalse(self.safety.toyota_tx_hook(self._torque_msg(MAX_RATE_UP + 1))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP + 1))) def test_non_realtime_limit_down(self): self.safety.set_controls_allowed(True) @@ -191,12 +212,12 @@ def test_non_realtime_limit_down(self): self.safety.set_toyota_rt_torque_last(1000) self.safety.set_toyota_torque_meas(500, 500) self.safety.set_toyota_desired_torque_last(1000) - self.assertTrue(self.safety.toyota_tx_hook(self._torque_msg(1000 - MAX_RATE_DOWN))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(1000 - MAX_RATE_DOWN))) self.safety.set_toyota_rt_torque_last(1000) self.safety.set_toyota_torque_meas(500, 500) self.safety.set_toyota_desired_torque_last(1000) - self.assertFalse(self.safety.toyota_tx_hook(self._torque_msg(1000 - MAX_RATE_DOWN + 1))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(1000 - MAX_RATE_DOWN + 1))) def test_exceed_torque_sensor(self): self.safety.set_controls_allowed(True) @@ -205,9 +226,9 @@ def test_exceed_torque_sensor(self): self._set_prev_torque(0) for t in np.arange(0, MAX_TORQUE_ERROR + 10, 10): t *= sign - self.assertTrue(self.safety.toyota_tx_hook(self._torque_msg(t))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) - self.assertFalse(self.safety.toyota_tx_hook(self._torque_msg(sign * (MAX_TORQUE_ERROR + 10)))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_TORQUE_ERROR + 10)))) def test_realtime_limit_up(self): self.safety.set_controls_allowed(True) @@ -218,210 +239,77 @@ def test_realtime_limit_up(self): for t in np.arange(0, 380, 10): t *= sign self.safety.set_toyota_torque_meas(t, t) - self.assertTrue(self.safety.toyota_tx_hook(self._torque_msg(t))) - self.assertFalse(self.safety.toyota_tx_hook(self._torque_msg(sign * 380))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(sign * 380))) self._set_prev_torque(0) for t in np.arange(0, 370, 10): t *= sign self.safety.set_toyota_torque_meas(t, t) - self.assertTrue(self.safety.toyota_tx_hook(self._torque_msg(t))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) # Increase timer to update rt_torque_last self.safety.set_timer(RT_INTERVAL + 1) - self.assertTrue(self.safety.toyota_tx_hook(self._torque_msg(sign * 370))) - self.assertTrue(self.safety.toyota_tx_hook(self._torque_msg(sign * 380))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * 370))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * 380))) def test_torque_measurements(self): - self.safety.toyota_rx_hook(self._torque_meas_msg(50)) - self.safety.toyota_rx_hook(self._torque_meas_msg(-50)) - self.safety.toyota_rx_hook(self._torque_meas_msg(0)) - self.safety.toyota_rx_hook(self._torque_meas_msg(0)) - self.safety.toyota_rx_hook(self._torque_meas_msg(0)) - self.safety.toyota_rx_hook(self._torque_meas_msg(0)) + self.safety.safety_rx_hook(self._torque_meas_msg(50)) + self.safety.safety_rx_hook(self._torque_meas_msg(-50)) + self.safety.safety_rx_hook(self._torque_meas_msg(0)) + self.safety.safety_rx_hook(self._torque_meas_msg(0)) + self.safety.safety_rx_hook(self._torque_meas_msg(0)) + self.safety.safety_rx_hook(self._torque_meas_msg(0)) self.assertEqual(-51, self.safety.get_toyota_torque_meas_min()) self.assertEqual(51, self.safety.get_toyota_torque_meas_max()) - self.safety.toyota_rx_hook(self._torque_meas_msg(0)) - self.assertEqual(-1, self.safety.get_toyota_torque_meas_max()) + self.safety.safety_rx_hook(self._torque_meas_msg(0)) + self.assertEqual(1, self.safety.get_toyota_torque_meas_max()) self.assertEqual(-51, self.safety.get_toyota_torque_meas_min()) - self.safety.toyota_rx_hook(self._torque_meas_msg(0)) - self.assertEqual(-1, self.safety.get_toyota_torque_meas_max()) + self.safety.safety_rx_hook(self._torque_meas_msg(0)) + self.assertEqual(1, self.safety.get_toyota_torque_meas_max()) self.assertEqual(-1, self.safety.get_toyota_torque_meas_min()) - def test_ipas_override(self): - - ## angle control is not active - self.safety.set_controls_allowed(1) - - # 3 consecutive msgs where driver exceeds threshold but angle_control isn't active - self.safety.set_controls_allowed(1) - self._torque_driver_msg_array(IPAS_OVERRIDE_THRESHOLD + 1) - self.assertTrue(self.safety.get_controls_allowed()) - - self._torque_driver_msg_array(-IPAS_OVERRIDE_THRESHOLD - 1) - self.assertTrue(self.safety.get_controls_allowed()) - - # ipas state is override - self.safety.toyota_ipas_rx_hook(self._ipas_state_msg(5)) - self.assertTrue(self.safety.get_controls_allowed()) - - ## now angle control is active - self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(0, 0)) - self.safety.toyota_ipas_rx_hook(self._ipas_state_msg(0)) - - # 3 consecutive msgs where driver does exceed threshold - self.safety.set_controls_allowed(1) - self._torque_driver_msg_array(IPAS_OVERRIDE_THRESHOLD + 1) - self.assertFalse(self.safety.get_controls_allowed()) - - self.safety.set_controls_allowed(1) - self._torque_driver_msg_array(-IPAS_OVERRIDE_THRESHOLD - 1) - self.assertFalse(self.safety.get_controls_allowed()) - - # ipas state is override and torque isn't overriding any more - self.safety.set_controls_allowed(1) - self._torque_driver_msg_array(0) - self.safety.toyota_ipas_rx_hook(self._ipas_state_msg(5)) - self.assertFalse(self.safety.get_controls_allowed()) - - # 3 consecutive msgs where driver does not exceed threshold and - # ipas state is not override - self.safety.set_controls_allowed(1) - self.safety.toyota_ipas_rx_hook(self._ipas_state_msg(0)) - self.assertTrue(self.safety.get_controls_allowed()) - - self._torque_driver_msg_array(IPAS_OVERRIDE_THRESHOLD) - self.assertTrue(self.safety.get_controls_allowed()) - - self._torque_driver_msg_array(-IPAS_OVERRIDE_THRESHOLD) - self.assertTrue(self.safety.get_controls_allowed()) - - # reset no angle control at the end of the test - self.safety.reset_angle_control() - - def test_angle_cmd_when_disabled(self): - - self.safety.set_controls_allowed(0) - - # test angle cmd too far from actual - angle_refs = [-10, 10] - deltas = range(-2, 3) - expected_results = [False, True, True, True, False] - - for a in angle_refs: - self._angle_meas_msg_array(a) - for i, d in enumerate(deltas): - self.assertEqual(expected_results[i], self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(a + d, 1))) - - # test ipas state cmd enabled - self._angle_meas_msg_array(0) - self.assertEqual(0, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(0, 3))) - - # reset no angle control at the end of the test - self.safety.reset_angle_control() - - def test_angle_cmd_when_enabled(self): - - # ipas angle cmd should pass through when controls are enabled - - self.safety.set_controls_allowed(1) - self._angle_meas_msg_array(0) - self.safety.toyota_ipas_rx_hook(self._speed_msg(0.1)) - - self.assertEqual(1, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(0, 1))) - self.assertEqual(1, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(4, 1))) - self.assertEqual(1, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(0, 3))) - self.assertEqual(1, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(-4, 3))) - self.assertEqual(1, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(-8, 3))) - - # reset no angle control at the end of the test - self.safety.reset_angle_control() - - - def test_angle_cmd_rate_when_disabled(self): - - # as long as the command is close to the measured, no rate limit is enforced when - # controls are disabled - self.safety.set_controls_allowed(0) - self.safety.toyota_ipas_rx_hook(self._angle_meas_msg(0)) - self.assertEqual(1, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(0, 1))) - self.safety.toyota_ipas_rx_hook(self._angle_meas_msg(100)) - self.assertEqual(1, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(100, 1))) - self.safety.toyota_ipas_rx_hook(self._angle_meas_msg(-100)) - self.assertEqual(1, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(-100, 1))) - - # reset no angle control at the end of the test - self.safety.reset_angle_control() - - def test_angle_cmd_rate_when_enabled(self): - - # when controls are allowed, angle cmd rate limit is enforced - # test 1: no limitations if we stay within limits - speeds = [0., 1., 5., 10., 15., 100.] - angles = [-300, -100, -10, 0, 10, 100, 300] - for a in angles: - for s in speeds: - - # first test against false positives - self._angle_meas_msg_array(a) - self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(a, 1)) - self.safety.set_controls_allowed(1) - self.safety.toyota_ipas_rx_hook(self._speed_msg(s)) - max_delta_up = int(np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_V) * 2 / 3. + 1.) - max_delta_down = int(np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_VU) * 2 / 3. + 1.) - self.assertEqual(True, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(a + sign(a) * max_delta_up, 1))) - self.assertTrue(self.safety.get_controls_allowed()) - self.assertEqual(True, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(a, 1))) - self.assertTrue(self.safety.get_controls_allowed()) - self.assertEqual(True, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(a - sign(a) * max_delta_down, 1))) - self.assertTrue(self.safety.get_controls_allowed()) - - # now inject too high rates - self.assertEqual(False, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(a + sign(a) * - (max_delta_up + 1), 1))) - self.assertFalse(self.safety.get_controls_allowed()) - self.safety.set_controls_allowed(1) - self.assertEqual(True, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(a + sign(a) * max_delta_up, 1))) - self.assertTrue(self.safety.get_controls_allowed()) - self.assertEqual(True, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(a, 1))) - self.assertTrue(self.safety.get_controls_allowed()) - self.assertEqual(False, self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(a - sign(a) * - (max_delta_down + 1), 1))) - self.assertFalse(self.safety.get_controls_allowed()) - - # reset no angle control at the end of the test - self.safety.reset_angle_control() - - def test_angle_measured_rate(self): - - speeds = [0., 1., 5., 10., 15., 100.] - angles = [-300, -100, -10, 0, 10, 100, 300] - angles = [10] - for a in angles: - for s in speeds: - self._angle_meas_msg_array(a) - self.safety.toyota_ipas_tx_hook(self._ipas_control_msg(a, 1)) - self.safety.set_controls_allowed(1) - self.safety.toyota_ipas_rx_hook(self._speed_msg(s)) - max_delta_up = int(np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_V) * 2 / 3. + 1.) - max_delta_down = int(np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_VU) * 2 / 3. + 1.) - self.safety.toyota_ipas_rx_hook(self._angle_meas_msg(a)) - self.assertTrue(self.safety.get_controls_allowed()) - self.safety.toyota_ipas_rx_hook(self._angle_meas_msg(a + 150)) - self.assertFalse(self.safety.get_controls_allowed()) - - # reset no angle control at the end of the test - self.safety.reset_angle_control() + def test_gas_interceptor_safety_check(self): - def test_gas_safety_check(self): self.safety.set_controls_allowed(0) - self.assertTrue(self.safety.honda_tx_hook(self._gas_msg(0x0000))) - self.assertFalse(self.safety.honda_tx_hook(self._gas_msg(0x1000))) + self.assertTrue(self.safety.safety_tx_hook(self._send_interceptor_msg(0, 0x200))) + self.assertFalse(self.safety.safety_tx_hook(self._send_interceptor_msg(0x1000, 0x200))) self.safety.set_controls_allowed(1) - self.assertTrue(self.safety.honda_tx_hook(self._gas_msg(0x1000))) + self.assertTrue(self.safety.safety_tx_hook(self._send_interceptor_msg(0x1000, 0x200))) + + def test_fwd_hook(self): + + buss = list(range(0x0, 0x3)) + msgs = list(range(0x1, 0x800)) + long_controls_allowed = [0, 1] + toyota_camera_forwarded = [0, 1] + + for tcf in toyota_camera_forwarded: + self.safety.set_toyota_camera_forwarded(tcf) + for lca in long_controls_allowed: + self.safety.set_long_controls_allowed(lca) + blocked_msgs = [0x2E4, 0x412, 0x191] + if lca: + blocked_msgs += [0x343] + for b in buss: + for m in msgs: + if tcf: + if b == 0: + fwd_bus = 2 + elif b == 1: + fwd_bus = -1 + elif b == 2: + fwd_bus = -1 if m in blocked_msgs else 0 + else: + fwd_bus = -1 + + # assume len 8 + self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) + + self.safety.set_long_controls_allowed(True) if __name__ == "__main__": diff --git a/panda/tests/safety/test_toyota_ipas.py b/panda/tests/safety/test_toyota_ipas.py new file mode 100644 index 00000000000000..df0f36ffd76e47 --- /dev/null +++ b/panda/tests/safety/test_toyota_ipas.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python3 +import unittest +import numpy as np +import libpandasafety_py # pylint: disable=import-error +from panda import Panda + +IPAS_OVERRIDE_THRESHOLD = 200 + +ANGLE_DELTA_BP = [0., 5., 15.] +ANGLE_DELTA_V = [5., .8, .15] # windup limit +ANGLE_DELTA_VU = [5., 3.5, 0.4] # unwind limit + +def twos_comp(val, bits): + if val >= 0: + return val + else: + return (2**bits) + val + +def sign(a): + if a > 0: + return 1 + else: + return -1 + +class TestToyotaSafety(unittest.TestCase): + @classmethod + def setUp(cls): + cls.safety = libpandasafety_py.libpandasafety + cls.safety.safety_set_mode(Panda.SAFETY_TOYOTA_IPAS, 66) + cls.safety.init_tests_toyota() + + def _torque_driver_msg(self, torque): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = 0x260 << 21 + + t = twos_comp(torque, 16) + to_send[0].RDLR = t | ((t & 0xFF) << 16) + return to_send + + def _torque_driver_msg_array(self, torque): + for i in range(6): + self.safety.safety_rx_hook(self._torque_driver_msg(torque)) + + def _angle_meas_msg(self, angle): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = 0x25 << 21 + + t = twos_comp(angle, 12) + to_send[0].RDLR = ((t & 0xF00) >> 8) | ((t & 0xFF) << 8) + return to_send + + def _angle_meas_msg_array(self, angle): + for i in range(6): + self.safety.safety_rx_hook(self._angle_meas_msg(angle)) + + def _ipas_state_msg(self, state): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = 0x262 << 21 + + to_send[0].RDLR = state & 0xF + return to_send + + def _ipas_control_msg(self, angle, state): + # note: we command 2/3 of the angle due to CAN conversion + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = 0x266 << 21 + + t = twos_comp(angle, 12) + to_send[0].RDLR = ((t & 0xF00) >> 8) | ((t & 0xFF) << 8) + to_send[0].RDLR |= ((state & 0xf) << 4) + + return to_send + + def _speed_msg(self, speed): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = 0xb4 << 21 + speed = int(speed * 100 * 3.6) + + to_send[0].RDHR = ((speed & 0xFF) << 16) | (speed & 0xFF00) + return to_send + + def test_ipas_override(self): + + ## angle control is not active + self.safety.set_controls_allowed(1) + + # 3 consecutive msgs where driver exceeds threshold but angle_control isn't active + self.safety.set_controls_allowed(1) + self._torque_driver_msg_array(IPAS_OVERRIDE_THRESHOLD + 1) + self.assertTrue(self.safety.get_controls_allowed()) + + self._torque_driver_msg_array(-IPAS_OVERRIDE_THRESHOLD - 1) + self.assertTrue(self.safety.get_controls_allowed()) + + # ipas state is override + self.safety.safety_rx_hook(self._ipas_state_msg(5)) + self.assertTrue(self.safety.get_controls_allowed()) + + ## now angle control is active + self.safety.safety_tx_hook(self._ipas_control_msg(0, 0)) + self.safety.safety_rx_hook(self._ipas_state_msg(0)) + + # 3 consecutive msgs where driver does exceed threshold + self.safety.set_controls_allowed(1) + self._torque_driver_msg_array(IPAS_OVERRIDE_THRESHOLD + 1) + self.assertFalse(self.safety.get_controls_allowed()) + + self.safety.set_controls_allowed(1) + self._torque_driver_msg_array(-IPAS_OVERRIDE_THRESHOLD - 1) + self.assertFalse(self.safety.get_controls_allowed()) + + # ipas state is override and torque isn't overriding any more + self.safety.set_controls_allowed(1) + self._torque_driver_msg_array(0) + self.safety.safety_rx_hook(self._ipas_state_msg(5)) + self.assertFalse(self.safety.get_controls_allowed()) + + # 3 consecutive msgs where driver does not exceed threshold and + # ipas state is not override + self.safety.set_controls_allowed(1) + self.safety.safety_rx_hook(self._ipas_state_msg(0)) + self.assertTrue(self.safety.get_controls_allowed()) + + self._torque_driver_msg_array(IPAS_OVERRIDE_THRESHOLD) + self.assertTrue(self.safety.get_controls_allowed()) + + self._torque_driver_msg_array(-IPAS_OVERRIDE_THRESHOLD) + self.assertTrue(self.safety.get_controls_allowed()) + + # reset no angle control at the end of the test + self.safety.reset_angle_control() + + def test_angle_cmd_when_disabled(self): + + self.safety.set_controls_allowed(0) + + # test angle cmd too far from actual + angle_refs = [-10, 10] + deltas = list(range(-2, 3)) + expected_results = [False, True, True, True, False] + + for a in angle_refs: + self._angle_meas_msg_array(a) + for i, d in enumerate(deltas): + self.assertEqual(expected_results[i], self.safety.safety_tx_hook(self._ipas_control_msg(a + d, 1))) + + # test ipas state cmd enabled + self._angle_meas_msg_array(0) + self.assertEqual(0, self.safety.safety_tx_hook(self._ipas_control_msg(0, 3))) + + # reset no angle control at the end of the test + self.safety.reset_angle_control() + + def test_angle_cmd_when_enabled(self): + + # ipas angle cmd should pass through when controls are enabled + + self.safety.set_controls_allowed(1) + self._angle_meas_msg_array(0) + self.safety.safety_rx_hook(self._speed_msg(0.1)) + + self.assertEqual(1, self.safety.safety_tx_hook(self._ipas_control_msg(0, 1))) + self.assertEqual(1, self.safety.safety_tx_hook(self._ipas_control_msg(4, 1))) + self.assertEqual(1, self.safety.safety_tx_hook(self._ipas_control_msg(0, 3))) + self.assertEqual(1, self.safety.safety_tx_hook(self._ipas_control_msg(-4, 3))) + self.assertEqual(1, self.safety.safety_tx_hook(self._ipas_control_msg(-8, 3))) + + # reset no angle control at the end of the test + self.safety.reset_angle_control() + + def test_angle_cmd_rate_when_disabled(self): + + # as long as the command is close to the measured, no rate limit is enforced when + # controls are disabled + self.safety.set_controls_allowed(0) + self.safety.safety_rx_hook(self._angle_meas_msg(0)) + self.assertEqual(1, self.safety.safety_tx_hook(self._ipas_control_msg(0, 1))) + self.safety.safety_rx_hook(self._angle_meas_msg(100)) + self.assertEqual(1, self.safety.safety_tx_hook(self._ipas_control_msg(100, 1))) + self.safety.safety_rx_hook(self._angle_meas_msg(-100)) + self.assertEqual(1, self.safety.safety_tx_hook(self._ipas_control_msg(-100, 1))) + + # reset no angle control at the end of the test + self.safety.reset_angle_control() + + def test_angle_cmd_rate_when_enabled(self): + + # when controls are allowed, angle cmd rate limit is enforced + # test 1: no limitations if we stay within limits + speeds = [0., 1., 5., 10., 15., 100.] + angles = [-300, -100, -10, 0, 10, 100, 300] + for a in angles: + for s in speeds: + + # first test against false positives + self._angle_meas_msg_array(a) + self.safety.safety_tx_hook(self._ipas_control_msg(a, 1)) + self.safety.set_controls_allowed(1) + self.safety.safety_rx_hook(self._speed_msg(s)) + max_delta_up = int(np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_V) * 2 / 3. + 1.) + max_delta_down = int(np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_VU) * 2 / 3. + 1.) + self.assertEqual(True, self.safety.safety_tx_hook(self._ipas_control_msg(a + sign(a) * max_delta_up, 1))) + self.assertTrue(self.safety.get_controls_allowed()) + self.assertEqual(True, self.safety.safety_tx_hook(self._ipas_control_msg(a, 1))) + self.assertTrue(self.safety.get_controls_allowed()) + self.assertEqual(True, self.safety.safety_tx_hook(self._ipas_control_msg(a - sign(a) * max_delta_down, 1))) + self.assertTrue(self.safety.get_controls_allowed()) + + # now inject too high rates + self.assertEqual(False, self.safety.safety_tx_hook(self._ipas_control_msg(a + sign(a) * + (max_delta_up + 1), 1))) + self.assertFalse(self.safety.get_controls_allowed()) + self.safety.set_controls_allowed(1) + self.assertEqual(True, self.safety.safety_tx_hook(self._ipas_control_msg(a + sign(a) * max_delta_up, 1))) + self.assertTrue(self.safety.get_controls_allowed()) + self.assertEqual(True, self.safety.safety_tx_hook(self._ipas_control_msg(a, 1))) + self.assertTrue(self.safety.get_controls_allowed()) + self.assertEqual(False, self.safety.safety_tx_hook(self._ipas_control_msg(a - sign(a) * + (max_delta_down + 1), 1))) + self.assertFalse(self.safety.get_controls_allowed()) + + # reset no angle control at the end of the test + self.safety.reset_angle_control() + + def test_angle_measured_rate(self): + + speeds = [0., 1., 5., 10., 15., 100.] + angles = [-300, -100, -10, 0, 10, 100, 300] + angles = [10] + for a in angles: + for s in speeds: + self._angle_meas_msg_array(a) + self.safety.safety_tx_hook(self._ipas_control_msg(a, 1)) + self.safety.set_controls_allowed(1) + self.safety.safety_rx_hook(self._speed_msg(s)) + #max_delta_up = int(np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_V) * 2 / 3. + 1.) + #max_delta_down = int(np.interp(s, ANGLE_DELTA_BP, ANGLE_DELTA_VU) * 2 / 3. + 1.) + self.safety.safety_rx_hook(self._angle_meas_msg(a)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.safety_rx_hook(self._angle_meas_msg(a + 150)) + self.assertFalse(self.safety.get_controls_allowed()) + + # reset no angle control at the end of the test + self.safety.reset_angle_control() + + +if __name__ == "__main__": + unittest.main() diff --git a/panda/tests/safety/test_volkswagen.py b/panda/tests/safety/test_volkswagen.py new file mode 100644 index 00000000000000..aa535cdac9cbf1 --- /dev/null +++ b/panda/tests/safety/test_volkswagen.py @@ -0,0 +1,247 @@ +#!/usr/bin/env python3 +import unittest +import numpy as np +import libpandasafety_py # pylint: disable=import-error +from panda import Panda + +MAX_RATE_UP = 4 +MAX_RATE_DOWN = 10 +MAX_STEER = 250 + +MAX_RT_DELTA = 75 +RT_INTERVAL = 250000 + +DRIVER_TORQUE_ALLOWANCE = 80 +DRIVER_TORQUE_FACTOR = 3 + +def sign(a): + if a > 0: + return 1 + else: + return -1 + +class TestVolkswagenSafety(unittest.TestCase): + @classmethod + def setUp(cls): + cls.safety = libpandasafety_py.libpandasafety + cls.safety.safety_set_mode(Panda.SAFETY_VOLKSWAGEN, 0) + cls.safety.init_tests_volkswagen() + + def _send_msg(self, bus, addr, length): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = addr << 21 + to_send[0].RDTR = length + to_send[0].RDTR = bus << 4 + return to_send + + def _set_prev_torque(self, t): + self.safety.set_volkswagen_desired_torque_last(t) + self.safety.set_volkswagen_rt_torque_last(t) + + def _torque_driver_msg(self, torque): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = 0x9F << 21 + + t = abs(torque) + to_send[0].RDHR = ((t & 0x1FFF) << 8) + if torque < 0: + to_send[0].RDHR |= 0x1 << 23 + return to_send + + def _torque_msg(self, torque): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = 0x126 << 21 + + t = abs(torque) + to_send[0].RDLR = (t & 0xFFF) << 16 + if torque < 0: + to_send[0].RDLR |= 0x1 << 31 + return to_send + + def _gas_msg(self, gas): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = 0x121 << 21 + to_send[0].RDLR = (gas & 0xFF) << 12 + + return to_send + + def _button_msg(self, bit): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = 0x12B << 21 + to_send[0].RDLR = 1 << bit + to_send[0].RDTR = 2 << 4 + + return to_send + + def test_prev_gas(self): + for g in range(0, 256): + self.safety.safety_rx_hook(self._gas_msg(g)) + self.assertEqual(g, self.safety.get_volkswagen_gas_prev()) + + def test_default_controls_not_allowed(self): + self.assertFalse(self.safety.get_controls_allowed()) + + def test_enable_control_allowed_from_cruise(self): + to_push = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_push[0].RIR = 0x122 << 21 + to_push[0].RDHR = 0x30000000 + + self.safety.safety_rx_hook(to_push) + self.assertTrue(self.safety.get_controls_allowed()) + + def test_disable_control_allowed_from_cruise(self): + to_push = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_push[0].RIR = 0x122 << 21 + to_push[0].RDHR = 0 + + self.safety.set_controls_allowed(1) + self.safety.safety_rx_hook(to_push) + self.assertFalse(self.safety.get_controls_allowed()) + + def test_disengage_on_gas(self): + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + self.safety.safety_rx_hook(self._gas_msg(0)) + self.safety.set_controls_allowed(True) + self.safety.safety_rx_hook(self._gas_msg(1)) + if long_controls_allowed: + self.assertFalse(self.safety.get_controls_allowed()) + else: + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.set_long_controls_allowed(True) + + def test_allow_engage_with_gas_pressed(self): + self.safety.safety_rx_hook(self._gas_msg(1)) + self.safety.set_controls_allowed(True) + self.safety.safety_rx_hook(self._gas_msg(1)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.safety_rx_hook(self._gas_msg(1)) + self.assertTrue(self.safety.get_controls_allowed()) + + + def test_steer_safety_check(self): + for enabled in [0, 1]: + for t in range(-500, 500): + self.safety.set_controls_allowed(enabled) + self._set_prev_torque(t) + if abs(t) > MAX_STEER or (not enabled and abs(t) > 0): + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(t))) + else: + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) + + def test_manually_enable_controls_allowed(self): + self.safety.set_controls_allowed(1) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.set_controls_allowed(0) + self.assertFalse(self.safety.get_controls_allowed()) + + def test_spam_cancel_safety_check(self): + BIT_CANCEL = 13 + BIT_RESUME = 19 + BIT_SET = 16 + self.safety.set_controls_allowed(0) + self.assertTrue(self.safety.safety_tx_hook(self._button_msg(BIT_CANCEL))) + self.assertFalse(self.safety.safety_tx_hook(self._button_msg(BIT_RESUME))) + self.assertFalse(self.safety.safety_tx_hook(self._button_msg(BIT_SET))) + # do not block resume if we are engaged already + self.safety.set_controls_allowed(1) + self.assertTrue(self.safety.safety_tx_hook(self._button_msg(BIT_RESUME))) + + def test_non_realtime_limit_up(self): + self.safety.set_volkswagen_torque_driver(0, 0) + self.safety.set_controls_allowed(True) + + self._set_prev_torque(0) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP))) + self._set_prev_torque(0) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP))) + + self._set_prev_torque(0) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(MAX_RATE_UP + 1))) + self.safety.set_controls_allowed(True) + self._set_prev_torque(0) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(-MAX_RATE_UP - 1))) + + def test_non_realtime_limit_down(self): + self.safety.set_volkswagen_torque_driver(0, 0) + self.safety.set_controls_allowed(True) + + def test_against_torque_driver(self): + self.safety.set_controls_allowed(True) + + for sign in [-1, 1]: + for t in np.arange(0, DRIVER_TORQUE_ALLOWANCE + 1, 1): + t *= -sign + self.safety.set_volkswagen_torque_driver(t, t) + self._set_prev_torque(MAX_STEER * sign) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(MAX_STEER * sign))) + + self.safety.set_volkswagen_torque_driver(DRIVER_TORQUE_ALLOWANCE + 1, DRIVER_TORQUE_ALLOWANCE + 1) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(-MAX_STEER))) + + # spot check some individual cases + for sign in [-1, 1]: + driver_torque = (DRIVER_TORQUE_ALLOWANCE + 10) * sign + torque_desired = (MAX_STEER - 10 * DRIVER_TORQUE_FACTOR) * sign + delta = 1 * sign + self._set_prev_torque(torque_desired) + self.safety.set_volkswagen_torque_driver(-driver_torque, -driver_torque) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(torque_desired))) + self._set_prev_torque(torque_desired + delta) + self.safety.set_volkswagen_torque_driver(-driver_torque, -driver_torque) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(torque_desired + delta))) + + self._set_prev_torque(MAX_STEER * sign) + self.safety.set_volkswagen_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN) * sign))) + self._set_prev_torque(MAX_STEER * sign) + self.safety.set_volkswagen_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(0))) + self._set_prev_torque(MAX_STEER * sign) + self.safety.set_volkswagen_torque_driver(-MAX_STEER * sign, -MAX_STEER * sign) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg((MAX_STEER - MAX_RATE_DOWN + 1) * sign))) + + + def test_realtime_limits(self): + self.safety.set_controls_allowed(True) + + for sign in [-1, 1]: + self.safety.init_tests_volkswagen() + self._set_prev_torque(0) + self.safety.set_volkswagen_torque_driver(0, 0) + for t in np.arange(0, MAX_RT_DELTA, 1): + t *= sign + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) + self.assertFalse(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) + + self._set_prev_torque(0) + for t in np.arange(0, MAX_RT_DELTA, 1): + t *= sign + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(t))) + + # Increase timer to update rt_torque_last + self.safety.set_timer(RT_INTERVAL + 1) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA - 1)))) + self.assertTrue(self.safety.safety_tx_hook(self._torque_msg(sign * (MAX_RT_DELTA + 1)))) + + + def test_fwd_hook(self): + buss = list(range(0x0, 0x2)) + msgs = list(range(0x1, 0x800)) + blocked_msgs_0to2 = [] + blocked_msgs_2to0 = [0x122, 0x397] + for b in buss: + for m in msgs: + if b == 0: + fwd_bus = -1 if m in blocked_msgs_0to2 else 2 + elif b == 1: + fwd_bus = -1 + elif b == 2: + fwd_bus = -1 if m in blocked_msgs_2to0 else 0 + + # assume len 8 + self.assertEqual(fwd_bus, self.safety.safety_fwd_hook(b, self._send_msg(b, m, 8))) + + +if __name__ == "__main__": + unittest.main() diff --git a/panda/tests/safety/trim_csv.py b/panda/tests/safety/trim_csv.py deleted file mode 100755 index 511bd385f4e49a..00000000000000 --- a/panda/tests/safety/trim_csv.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python2 - -# This trims CAN message CSV files to just the messages relevant for Panda testing. -# Usage: -# cat input.csv | ./trim_csv.py > output.csv -import fileinput - -addr_to_keep = [544, 0x1f4, 0x292] # For Chrysler, update to the addresses that matter for you. - -for line in fileinput.input(): - line = line.strip() - cols = line.split(',') - if len(cols) != 4: - continue # malformed, such as at the end or every 60s. - (_, addr, bus, _) = cols - if (addr == 'addr'): - continue - if (int(bus) == 128): # Keep all messages sent by OpenPilot. - print line - elif (int(addr) in addr_to_keep): - print line diff --git a/panda/tests/safety_replay/Dockerfile b/panda/tests/safety_replay/Dockerfile new file mode 100644 index 00000000000000..f5175c74582005 --- /dev/null +++ b/panda/tests/safety_replay/Dockerfile @@ -0,0 +1,34 @@ +FROM ubuntu:16.04 + +RUN apt-get update && apt-get install -y make clang python python-pip git libarchive-dev libusb-1.0-0 locales curl zlib1g-dev libffi-dev bzip2 libssl-dev libbz2-dev + +RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash + +ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}" +RUN pyenv install 3.7.3 +RUN pyenv global 3.7.3 +RUN pyenv rehash + +COPY requirements.txt /tmp/ +RUN pip install -r /tmp/requirements.txt +COPY tests/safety_replay/requirements_extra.txt requirements_extra.txt +RUN pip install -r requirements_extra.txt +COPY tests/safety_replay/install_capnp.sh install_capnp.sh +RUN ./install_capnp.sh + +RUN mkdir /openpilot +WORKDIR /openpilot +RUN git clone https://github.com/commaai/cereal.git || true +WORKDIR /openpilot/cereal +RUN git checkout f7043fde062cbfd49ec90af669901a9caba52de9 +COPY . /openpilot/panda + +WORKDIR /openpilot/panda/tests/safety_replay +RUN git clone https://github.com/commaai/openpilot-tools.git tools || true +WORKDIR tools +RUN git checkout d69c6bc85f221766305ec53956e9a1d3bf283160 diff --git a/pyextra/jsonrpc/tests/__init__.py b/panda/tests/safety_replay/__init__.py similarity index 100% rename from pyextra/jsonrpc/tests/__init__.py rename to panda/tests/safety_replay/__init__.py diff --git a/panda/tests/safety_replay/helpers.py b/panda/tests/safety_replay/helpers.py new file mode 100644 index 00000000000000..6f4e63c3256304 --- /dev/null +++ b/panda/tests/safety_replay/helpers.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 +import struct +import panda.tests.safety.libpandasafety_py as libpandasafety_py +from panda import Panda + +def to_signed(d, bits): + ret = d + if d >= (1 << (bits - 1)): + ret = d - (1 << bits) + return ret + +def is_steering_msg(mode, addr): + ret = False + if mode == Panda.SAFETY_HONDA or mode == Panda.SAFETY_HONDA_BOSCH: + ret = (addr == 0xE4) or (addr == 0x194) or (addr == 0x33D) + elif mode == Panda.SAFETY_TOYOTA: + ret = addr == 0x2E4 + elif mode == Panda.SAFETY_GM: + ret = addr == 384 + elif mode == Panda.SAFETY_HYUNDAI: + ret = addr == 832 + elif mode == Panda.SAFETY_CHRYSLER: + ret = addr == 0x292 + elif mode == Panda.SAFETY_SUBARU: + ret = addr == 0x122 + return ret + +def get_steer_torque(mode, to_send): + ret = 0 + if mode == Panda.SAFETY_HONDA or mode == Panda.SAFETY_HONDA_BOSCH: + ret = to_send.RDLR & 0xFFFF0000 + elif mode == Panda.SAFETY_TOYOTA: + ret = (to_send.RDLR & 0xFF00) | ((to_send.RDLR >> 16) & 0xFF) + ret = to_signed(ret, 16) + elif mode == Panda.SAFETY_GM: + ret = ((to_send.RDLR & 0x7) << 8) + ((to_send.RDLR & 0xFF00) >> 8) + ret = to_signed(ret, 11) + elif mode == Panda.SAFETY_HYUNDAI: + ret = ((to_send.RDLR >> 16) & 0x7ff) - 1024 + elif mode == Panda.SAFETY_CHRYSLER: + ret = ((to_send.RDLR & 0x7) << 8) + ((to_send.RDLR & 0xFF00) >> 8) - 1024 + elif mode == Panda.SAFETY_SUBARU: + ret = ((to_send.RDLR >> 16) & 0x1FFF) + ret = to_signed(ret, 13) + return ret + +def set_desired_torque_last(safety, mode, torque): + if mode == Panda.SAFETY_HONDA or mode == Panda.SAFETY_HONDA_BOSCH: + pass # honda safety mode doesn't enforce a rate on steering msgs + elif mode == Panda.SAFETY_TOYOTA: + safety.set_toyota_desired_torque_last(torque) + elif mode == Panda.SAFETY_GM: + safety.set_gm_desired_torque_last(torque) + elif mode == Panda.SAFETY_HYUNDAI: + safety.set_hyundai_desired_torque_last(torque) + elif mode == Panda.SAFETY_CHRYSLER: + safety.set_chrysler_desired_torque_last(torque) + elif mode == Panda.SAFETY_SUBARU: + safety.set_subaru_desired_torque_last(torque) + +def package_can_msg(msg): + addr_shift = 3 if msg.address >= 0x800 else 21 + rdlr, rdhr = struct.unpack('II', msg.dat.ljust(8, b'\x00')) + + ret = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + ret[0].RIR = msg.address << addr_shift + ret[0].RDTR = len(msg.dat) | ((msg.src & 0xF) << 4) + ret[0].RDHR = rdhr + ret[0].RDLR = rdlr + + return ret + +def init_segment(safety, lr, mode): + sendcan = (msg for msg in lr if msg.which() == 'sendcan') + steering_msgs = (can for msg in sendcan for can in msg.sendcan if is_steering_msg(mode, can.address)) + + msg = next(steering_msgs, None) + if msg is None: + # no steering msgs + return + + to_send = package_can_msg(msg) + torque = get_steer_torque(mode, to_send) + if torque != 0: + safety.set_controls_allowed(1) + set_desired_torque_last(safety, mode, torque) + assert safety.safety_tx_hook(to_send), "failed to initialize panda safety for segment" + diff --git a/panda/tests/safety_replay/install_capnp.sh b/panda/tests/safety_replay/install_capnp.sh new file mode 100755 index 00000000000000..51559d3991b0a9 --- /dev/null +++ b/panda/tests/safety_replay/install_capnp.sh @@ -0,0 +1,10 @@ +#!/bin/bash -e + +apt-get install -y autoconf curl libtool +curl -O https://capnproto.org/capnproto-c++-0.6.1.tar.gz +tar xvf capnproto-c++-0.6.1.tar.gz +cd capnproto-c++-0.6.1 +./configure --prefix=/usr/local CPPFLAGS=-DPIC CFLAGS=-fPIC CXXFLAGS=-fPIC LDFLAGS=-fPIC --disable-shared --enable-static +make -j4 +make install + diff --git a/panda/tests/safety_replay/replay_drive.py b/panda/tests/safety_replay/replay_drive.py new file mode 100755 index 00000000000000..3db57dfd168fae --- /dev/null +++ b/panda/tests/safety_replay/replay_drive.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 + +import os +import sys +import panda.tests.safety.libpandasafety_py as libpandasafety_py +from panda.tests.safety_replay.helpers import package_can_msg, init_segment +from tools.lib.logreader import LogReader # pylint: disable=import-error + +# replay a drive to check for safety violations +def replay_drive(lr, safety_mode, param): + safety = libpandasafety_py.libpandasafety + + err = safety.safety_set_mode(safety_mode, param) + assert err == 0, "invalid safety mode: %d" % safety_mode + + if "SEGMENT" in os.environ: + init_segment(safety, lr, mode) + + tx_tot, tx_blocked, tx_controls, tx_controls_blocked = 0, 0, 0, 0 + blocked_addrs = set() + start_t = None + + for msg in lr: + if start_t is None: + start_t = msg.logMonoTime + safety.set_timer(((msg.logMonoTime // 1000)) % 0xFFFFFFFF) + + if msg.which() == 'sendcan': + for canmsg in msg.sendcan: + to_send = package_can_msg(canmsg) + sent = safety.safety_tx_hook(to_send) + if not sent: + tx_blocked += 1 + tx_controls_blocked += safety.get_controls_allowed() + blocked_addrs.add(canmsg.address) + + if "DEBUG" in os.environ: + print("blocked %d at %f" % (canmsg.address, (msg.logMonoTime - start_t)/(1e9))) + tx_controls += safety.get_controls_allowed() + tx_tot += 1 + elif msg.which() == 'can': + for canmsg in msg.can: + # ignore msgs we sent + if canmsg.src >= 128: + continue + to_push = package_can_msg(canmsg) + safety.safety_rx_hook(to_push) + + print("total openpilot msgs:", tx_tot) + print("total msgs with controls allowed:", tx_controls) + print("blocked msgs:", tx_blocked) + print("blocked with controls allowed:", tx_controls_blocked) + print("blocked addrs:", blocked_addrs) + + return tx_controls_blocked == 0 + +if __name__ == "__main__": + mode = int(sys.argv[2]) + param = 0 if len(sys.argv) < 4 else int(sys.argv[3]) + lr = LogReader(sys.argv[1]) + + print("replaying drive %s with safety mode %d and param %d" % (sys.argv[1], mode, param)) + + replay_drive(lr, mode, param) + diff --git a/panda/tests/safety_replay/requirements_extra.txt b/panda/tests/safety_replay/requirements_extra.txt new file mode 100644 index 00000000000000..b04b7674d76efa --- /dev/null +++ b/panda/tests/safety_replay/requirements_extra.txt @@ -0,0 +1,4 @@ +aenum +subprocess32 +libarchive +pycapnp diff --git a/panda/tests/safety_replay/test_safety_replay.py b/panda/tests/safety_replay/test_safety_replay.py new file mode 100755 index 00000000000000..cb38a94edff66a --- /dev/null +++ b/panda/tests/safety_replay/test_safety_replay.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 + +import os +import requests + +from panda import Panda +from replay_drive import replay_drive +from tools.lib.logreader import LogReader # pylint: disable=import-error + +BASE_URL = "https://commadataci.blob.core.windows.net/openpilotci/" + +# (route, safety mode, param) +logs = [ + ("b0c9d2329ad1606b|2019-05-30--20-23-57.bz2", Panda.SAFETY_HONDA, 0), # HONDA.CIVIC + ("38bfd238edecbcd7|2019-06-07--10-15-25.bz2", Panda.SAFETY_TOYOTA, 66), # TOYOTA.PRIUS + ("f89c604cf653e2bf|2018-09-29--13-46-50.bz2", Panda.SAFETY_GM, 0), # GM.VOLT + ("0375fdf7b1ce594d|2019-05-21--20-10-33.bz2", Panda.SAFETY_HONDA_BOSCH, 1), # HONDA.ACCORD + ("02ec6bea180a4d36|2019-04-17--11-21-35.bz2", Panda.SAFETY_HYUNDAI, 0), # HYUNDAI.SANTA_FE + ("03efb1fda29e30fe|2019-02-21--18-03-45.bz2", Panda.SAFETY_CHRYSLER, 0), # CHRYSLER.PACIFICA_2018_HYBRID + ("791340bc01ed993d|2019-04-08--10-26-00.bz2", Panda.SAFETY_SUBARU, 0), # SUBARU.IMPREZA +] + +if __name__ == "__main__": + for route, _, _ in logs: + if not os.path.isfile(route): + with open(route, "wb") as f: + f.write(requests.get(BASE_URL + route).content) + + failed = [] + for route, mode, param in logs: + lr = LogReader(route) + + print("\nreplaying %s with safety mode %d and param %s" % (route, mode, param)) + if not replay_drive(lr, mode, int(param)): + failed.append(route) + + for f in failed: + print("\n**** failed on %s ****" % f) + assert len(failed) == 0, "\nfailed on %d logs" % len(failed) + diff --git a/panda/tests/spam_can.py b/panda/tests/spam_can.py new file mode 100755 index 00000000000000..1daffdbd91009d --- /dev/null +++ b/panda/tests/spam_can.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 + +import os +import sys +import random + +sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "..")) +from panda import Panda + +def get_test_string(): + return b"test"+os.urandom(10) + +if __name__ == "__main__": + p = Panda() + p.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + + print("Spamming all buses...") + while True: + at = random.randint(1, 2000) + st = get_test_string()[0:8] + bus = random.randint(0, 2) + p.can_send(at, st, bus) + #print("Sent message on bus: ", bus) diff --git a/panda/tests/standalone_test.py b/panda/tests/standalone_test.py index ca6ea49f1056de..9e181d8fc95fca 100755 --- a/panda/tests/standalone_test.py +++ b/panda/tests/standalone_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import os import sys import struct diff --git a/panda/tests/throughput_test.py b/panda/tests/throughput_test.py index 5812ce42c2aa1c..9f6021240173e9 100755 --- a/panda/tests/throughput_test.py +++ b/panda/tests/throughput_test.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python -from __future__ import print_function +#!/usr/bin/env python3 + import os import sys import struct @@ -25,7 +25,7 @@ # p_in.can_recv() #sys.exit(0) - p_out.set_controls_allowed(True) + p_out.set_safety_mode(Panda.SAFETY_ALLOUTPUT) set_out, set_in = set(), set() @@ -34,7 +34,7 @@ p_in.can_recv() BATCH_SIZE = 16 - for a in tqdm(range(0, 10000, BATCH_SIZE)): + for a in tqdm(list(range(0, 10000, BATCH_SIZE))): for b in range(0, BATCH_SIZE): msg = b"\xaa"*4 + struct.pack("I", a+b) if a%1 == 0: @@ -61,4 +61,4 @@ if len(set_out - set_in): print("MISSING %d" % len(set_out - set_in)) if len(set_out - set_in) < 256: - print(map(hex, sorted(list(set_out - set_in)))) + print(list(map(hex, sorted(list(set_out - set_in))))) diff --git a/panda/tests/tucan_loopback.py b/panda/tests/tucan_loopback.py index a3f3e6e2d7cbad..cb5d1cbfea12e8 100755 --- a/panda/tests/tucan_loopback.py +++ b/panda/tests/tucan_loopback.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python -from __future__ import print_function +#!/usr/bin/env python3 + import os import sys import time @@ -29,14 +29,14 @@ def run_test(sleep_duration): run_test_w_pandas(pandas, sleep_duration) def run_test_w_pandas(pandas, sleep_duration): - h = list(map(lambda x: Panda(x), pandas)) + h = list([Panda(x) for x in pandas]) print("H", h) for hh in h: - hh.set_controls_allowed(True) + hh.set_safety_mode(Panda.SAFETY_ALLOUTPUT) # test both directions - for ho in permutations(range(len(h)), r=2): + for ho in permutations(list(range(len(h))), r=2): print("***************** TESTING", ho) panda0, panda1 = h[ho[0]], h[ho[1]] @@ -55,7 +55,7 @@ def run_test_w_pandas(pandas, sleep_duration): # send the characters st = get_test_string() - st = b"\xaa"+chr(len(st)+3).encode()+st + st = bytes([0xaa, len(st) + 3]) + st h[ho[0]].kline_send(st, bus=bus, checksum=False) # check for receive @@ -70,8 +70,8 @@ def run_test_w_pandas(pandas, sleep_duration): time.sleep(sleep_duration) # **** test can line loopback **** -# for bus, gmlan in [(0, None), (1, False), (2, False), (1, True), (2, True)]: -for bus, gmlan in [(0, None), (1, None)]: + # for bus, gmlan in [(0, None), (1, False), (2, False), (1, True), (2, True)]: + for bus, gmlan in [(0, None), (1, None)]: print("\ntest can", bus) # flush cans_echo = panda0.can_recv() diff --git a/phonelibs/android_frameworks_native/get.txt b/phonelibs/android_frameworks_native/get.txt new file mode 100644 index 00000000000000..31f42ebe0e3f36 --- /dev/null +++ b/phonelibs/android_frameworks_native/get.txt @@ -0,0 +1,3 @@ +git clone https://github.com/CyanogenMod/android_frameworks_native.git && cd android_frameworks_native +git reset --hard b22bca465e55618a949d9cbdea665a1a3a831241 +cp -r include ~/one/phonelibs/android_frameworks_native/ diff --git a/phonelibs/android_frameworks_native/include/android/asset_manager.h b/phonelibs/android_frameworks_native/include/android/asset_manager.h new file mode 100644 index 00000000000000..d65483968e4673 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/asset_manager.h @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup Asset + * @{ + */ + +/** + * @file asset_manager.h + */ + +#ifndef ANDROID_ASSET_MANAGER_H +#define ANDROID_ASSET_MANAGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct AAssetManager; +/** + * {@link AAssetManager} provides access to an application's raw assets by + * creating {@link AAsset} objects. + * + * AAssetManager is a wrapper to the low-level native implementation + * of the java {@link AAssetManager}, a pointer can be obtained using + * AAssetManager_fromJava(). + * + * The asset hierarchy may be examined like a filesystem, using + * {@link AAssetDir} objects to peruse a single directory. + * + * A native {@link AAssetManager} pointer may be shared across multiple threads. + */ +typedef struct AAssetManager AAssetManager; + +struct AAssetDir; +/** + * {@link AAssetDir} provides access to a chunk of the asset hierarchy as if + * it were a single directory. The contents are populated by the + * {@link AAssetManager}. + * + * The list of files will be sorted in ascending order by ASCII value. + */ +typedef struct AAssetDir AAssetDir; + +struct AAsset; +/** + * {@link AAsset} provides access to a read-only asset. + * + * {@link AAsset} objects are NOT thread-safe, and should not be shared across + * threads. + */ +typedef struct AAsset AAsset; + +/** Available access modes for opening assets with {@link AAssetManager_open} */ +enum { + /** No specific information about how data will be accessed. **/ + AASSET_MODE_UNKNOWN = 0, + /** Read chunks, and seek forward and backward. */ + AASSET_MODE_RANDOM = 1, + /** Read sequentially, with an occasional forward seek. */ + AASSET_MODE_STREAMING = 2, + /** Caller plans to ask for a read-only buffer with all data. */ + AASSET_MODE_BUFFER = 3 +}; + + +/** + * Open the named directory within the asset hierarchy. The directory can then + * be inspected with the AAssetDir functions. To open the top-level directory, + * pass in "" as the dirName. + * + * The object returned here should be freed by calling AAssetDir_close(). + */ +AAssetDir* AAssetManager_openDir(AAssetManager* mgr, const char* dirName); + +/** + * Open an asset. + * + * The object returned here should be freed by calling AAsset_close(). + */ +AAsset* AAssetManager_open(AAssetManager* mgr, const char* filename, int mode); + +/** + * Iterate over the files in an asset directory. A NULL string is returned + * when all the file names have been returned. + * + * The returned file name is suitable for passing to AAssetManager_open(). + * + * The string returned here is owned by the AssetDir implementation and is not + * guaranteed to remain valid if any other calls are made on this AAssetDir + * instance. + */ +const char* AAssetDir_getNextFileName(AAssetDir* assetDir); + +/** + * Reset the iteration state of AAssetDir_getNextFileName() to the beginning. + */ +void AAssetDir_rewind(AAssetDir* assetDir); + +/** + * Close an opened AAssetDir, freeing any related resources. + */ +void AAssetDir_close(AAssetDir* assetDir); + +/** + * Attempt to read 'count' bytes of data from the current offset. + * + * Returns the number of bytes read, zero on EOF, or < 0 on error. + */ +int AAsset_read(AAsset* asset, void* buf, size_t count); + +/** + * Seek to the specified offset within the asset data. 'whence' uses the + * same constants as lseek()/fseek(). + * + * Returns the new position on success, or (off_t) -1 on error. + */ +off_t AAsset_seek(AAsset* asset, off_t offset, int whence); + +/** + * Seek to the specified offset within the asset data. 'whence' uses the + * same constants as lseek()/fseek(). + * + * Uses 64-bit data type for large files as opposed to the 32-bit type used + * by AAsset_seek. + * + * Returns the new position on success, or (off64_t) -1 on error. + */ +off64_t AAsset_seek64(AAsset* asset, off64_t offset, int whence); + +/** + * Close the asset, freeing all associated resources. + */ +void AAsset_close(AAsset* asset); + +/** + * Get a pointer to a buffer holding the entire contents of the assset. + * + * Returns NULL on failure. + */ +const void* AAsset_getBuffer(AAsset* asset); + +/** + * Report the total size of the asset data. + */ +off_t AAsset_getLength(AAsset* asset); + +/** + * Report the total size of the asset data. Reports the size using a 64-bit + * number insted of 32-bit as AAsset_getLength. + */ +off64_t AAsset_getLength64(AAsset* asset); + +/** + * Report the total amount of asset data that can be read from the current position. + */ +off_t AAsset_getRemainingLength(AAsset* asset); + +/** + * Report the total amount of asset data that can be read from the current position. + * + * Uses a 64-bit number instead of a 32-bit number as AAsset_getRemainingLength does. + */ +off64_t AAsset_getRemainingLength64(AAsset* asset); + +/** + * Open a new file descriptor that can be used to read the asset data. If the + * start or length cannot be represented by a 32-bit number, it will be + * truncated. If the file is large, use AAsset_openFileDescriptor64 instead. + * + * Returns < 0 if direct fd access is not possible (for example, if the asset is + * compressed). + */ +int AAsset_openFileDescriptor(AAsset* asset, off_t* outStart, off_t* outLength); + +/** + * Open a new file descriptor that can be used to read the asset data. + * + * Uses a 64-bit number for the offset and length instead of 32-bit instead of + * as AAsset_openFileDescriptor does. + * + * Returns < 0 if direct fd access is not possible (for example, if the asset is + * compressed). + */ +int AAsset_openFileDescriptor64(AAsset* asset, off64_t* outStart, off64_t* outLength); + +/** + * Returns whether this asset's internal buffer is allocated in ordinary RAM (i.e. not + * mmapped). + */ +int AAsset_isAllocated(AAsset* asset); + + + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_ASSET_MANAGER_H + +/** @} */ diff --git a/phonelibs/android_frameworks_native/include/android/asset_manager_jni.h b/phonelibs/android_frameworks_native/include/android/asset_manager_jni.h new file mode 100644 index 00000000000000..dcee17e10f143b --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/asset_manager_jni.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup Asset + * @{ + */ + +/** + * @file asset_manager_jni.h + */ + +#ifndef ANDROID_ASSET_MANAGER_JNI_H +#define ANDROID_ASSET_MANAGER_JNI_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Given a Dalvik AssetManager object, obtain the corresponding native AAssetManager + * object. Note that the caller is responsible for obtaining and holding a VM reference + * to the jobject to prevent its being garbage collected while the native object is + * in use. + */ +AAssetManager* AAssetManager_fromJava(JNIEnv* env, jobject assetManager); + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_ASSET_MANAGER_JNI_H + +/** @} */ diff --git a/phonelibs/android_frameworks_native/include/android/bitmap.h b/phonelibs/android_frameworks_native/include/android/bitmap.h new file mode 100644 index 00000000000000..261e64fac9b825 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/bitmap.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup Bitmap + * @{ + */ + +/** + * @file bitmap.h + */ + +#ifndef ANDROID_BITMAP_H +#define ANDROID_BITMAP_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** AndroidBitmap functions result code. */ +enum { + /** Operation was successful. */ + ANDROID_BITMAP_RESULT_SUCCESS = 0, + /** Bad parameter. */ + ANDROID_BITMAP_RESULT_BAD_PARAMETER = -1, + /** JNI exception occured. */ + ANDROID_BITMAP_RESULT_JNI_EXCEPTION = -2, + /** Allocation failed. */ + ANDROID_BITMAP_RESULT_ALLOCATION_FAILED = -3, +}; + +/** Backward compatibility: this macro used to be misspelled. */ +#define ANDROID_BITMAP_RESUT_SUCCESS ANDROID_BITMAP_RESULT_SUCCESS + +/** Bitmap pixel format. */ +enum AndroidBitmapFormat { + /** No format. */ + ANDROID_BITMAP_FORMAT_NONE = 0, + /** Red: 8 bits, Green: 8 bits, Blue: 8 bits, Alpha: 8 bits. **/ + ANDROID_BITMAP_FORMAT_RGBA_8888 = 1, + /** Red: 5 bits, Green: 6 bits, Blue: 5 bits. **/ + ANDROID_BITMAP_FORMAT_RGB_565 = 4, + /** Red: 4 bits, Green: 4 bits, Blue: 4 bits, Alpha: 4 bits. **/ + ANDROID_BITMAP_FORMAT_RGBA_4444 = 7, + /** Deprecated. */ + ANDROID_BITMAP_FORMAT_A_8 = 8, +}; + +/** Bitmap info, see AndroidBitmap_getInfo(). */ +typedef struct { + /** The bitmap width in pixels. */ + uint32_t width; + /** The bitmap height in pixels. */ + uint32_t height; + /** The number of byte per row. */ + uint32_t stride; + /** The bitmap pixel format. See {@link AndroidBitmapFormat} */ + int32_t format; + /** Unused. */ + uint32_t flags; // 0 for now +} AndroidBitmapInfo; + +/** + * Given a java bitmap object, fill out the AndroidBitmapInfo struct for it. + * If the call fails, the info parameter will be ignored. + */ +int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap, + AndroidBitmapInfo* info); + +/** + * Given a java bitmap object, attempt to lock the pixel address. + * Locking will ensure that the memory for the pixels will not move + * until the unlockPixels call, and ensure that, if the pixels had been + * previously purged, they will have been restored. + * + * If this call succeeds, it must be balanced by a call to + * AndroidBitmap_unlockPixels, after which time the address of the pixels should + * no longer be used. + * + * If this succeeds, *addrPtr will be set to the pixel address. If the call + * fails, addrPtr will be ignored. + */ +int AndroidBitmap_lockPixels(JNIEnv* env, jobject jbitmap, void** addrPtr); + +/** + * Call this to balance a successful call to AndroidBitmap_lockPixels. + */ +int AndroidBitmap_unlockPixels(JNIEnv* env, jobject jbitmap); + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ diff --git a/phonelibs/android_frameworks_native/include/android/configuration.h b/phonelibs/android_frameworks_native/include/android/configuration.h new file mode 100644 index 00000000000000..81f71a92cb05e2 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/configuration.h @@ -0,0 +1,708 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup Configuration + * @{ + */ + +/** + * @file configuration.h + */ + +#ifndef ANDROID_CONFIGURATION_H +#define ANDROID_CONFIGURATION_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct AConfiguration; +/** + * {@link AConfiguration} is an opaque type used to get and set + * various subsystem configurations. + * + * A {@link AConfiguration} pointer can be obtained using: + * - AConfiguration_new() + * - AConfiguration_fromAssetManager() + */ +typedef struct AConfiguration AConfiguration; + + +/** + * Define flags and constants for various subsystem configurations. + */ +enum { + /** Orientation: not specified. */ + ACONFIGURATION_ORIENTATION_ANY = 0x0000, + /** + * Orientation: value corresponding to the + * port + * resource qualifier. + */ + ACONFIGURATION_ORIENTATION_PORT = 0x0001, + /** + * Orientation: value corresponding to the + * land + * resource qualifier. + */ + ACONFIGURATION_ORIENTATION_LAND = 0x0002, + /** @deprecated Not currently supported or used. */ + ACONFIGURATION_ORIENTATION_SQUARE = 0x0003, + + /** Touchscreen: not specified. */ + ACONFIGURATION_TOUCHSCREEN_ANY = 0x0000, + /** + * Touchscreen: value corresponding to the + * notouch + * resource qualifier. + */ + ACONFIGURATION_TOUCHSCREEN_NOTOUCH = 0x0001, + /** @deprecated Not currently supported or used. */ + ACONFIGURATION_TOUCHSCREEN_STYLUS = 0x0002, + /** + * Touchscreen: value corresponding to the + * finger + * resource qualifier. + */ + ACONFIGURATION_TOUCHSCREEN_FINGER = 0x0003, + + /** Density: default density. */ + ACONFIGURATION_DENSITY_DEFAULT = 0, + /** + * Density: value corresponding to the + * ldpi + * resource qualifier. + */ + ACONFIGURATION_DENSITY_LOW = 120, + /** + * Density: value corresponding to the + * mdpi + * resource qualifier. + */ + ACONFIGURATION_DENSITY_MEDIUM = 160, + /** + * Density: value corresponding to the + * tvdpi + * resource qualifier. + */ + ACONFIGURATION_DENSITY_TV = 213, + /** + * Density: value corresponding to the + * hdpi + * resource qualifier. + */ + ACONFIGURATION_DENSITY_HIGH = 240, + /** + * Density: value corresponding to the + * xhdpi + * resource qualifier. + */ + ACONFIGURATION_DENSITY_XHIGH = 320, + /** + * Density: value corresponding to the + * xxhdpi + * resource qualifier. + */ + ACONFIGURATION_DENSITY_XXHIGH = 480, + /** + * Density: value corresponding to the + * xxxhdpi + * resource qualifier. + */ + ACONFIGURATION_DENSITY_XXXHIGH = 640, + /** Density: any density. */ + ACONFIGURATION_DENSITY_ANY = 0xfffe, + /** Density: no density specified. */ + ACONFIGURATION_DENSITY_NONE = 0xffff, + + /** Keyboard: not specified. */ + ACONFIGURATION_KEYBOARD_ANY = 0x0000, + /** + * Keyboard: value corresponding to the + * nokeys + * resource qualifier. + */ + ACONFIGURATION_KEYBOARD_NOKEYS = 0x0001, + /** + * Keyboard: value corresponding to the + * qwerty + * resource qualifier. + */ + ACONFIGURATION_KEYBOARD_QWERTY = 0x0002, + /** + * Keyboard: value corresponding to the + * 12key + * resource qualifier. + */ + ACONFIGURATION_KEYBOARD_12KEY = 0x0003, + + /** Navigation: not specified. */ + ACONFIGURATION_NAVIGATION_ANY = 0x0000, + /** + * Navigation: value corresponding to the + * nonav + * resource qualifier. + */ + ACONFIGURATION_NAVIGATION_NONAV = 0x0001, + /** + * Navigation: value corresponding to the + * dpad + * resource qualifier. + */ + ACONFIGURATION_NAVIGATION_DPAD = 0x0002, + /** + * Navigation: value corresponding to the + * trackball + * resource qualifier. + */ + ACONFIGURATION_NAVIGATION_TRACKBALL = 0x0003, + /** + * Navigation: value corresponding to the + * wheel + * resource qualifier. + */ + ACONFIGURATION_NAVIGATION_WHEEL = 0x0004, + + /** Keyboard availability: not specified. */ + ACONFIGURATION_KEYSHIDDEN_ANY = 0x0000, + /** + * Keyboard availability: value corresponding to the + * keysexposed + * resource qualifier. + */ + ACONFIGURATION_KEYSHIDDEN_NO = 0x0001, + /** + * Keyboard availability: value corresponding to the + * keyshidden + * resource qualifier. + */ + ACONFIGURATION_KEYSHIDDEN_YES = 0x0002, + /** + * Keyboard availability: value corresponding to the + * keyssoft + * resource qualifier. + */ + ACONFIGURATION_KEYSHIDDEN_SOFT = 0x0003, + + /** Navigation availability: not specified. */ + ACONFIGURATION_NAVHIDDEN_ANY = 0x0000, + /** + * Navigation availability: value corresponding to the + * navexposed + * resource qualifier. + */ + ACONFIGURATION_NAVHIDDEN_NO = 0x0001, + /** + * Navigation availability: value corresponding to the + * navhidden + * resource qualifier. + */ + ACONFIGURATION_NAVHIDDEN_YES = 0x0002, + + /** Screen size: not specified. */ + ACONFIGURATION_SCREENSIZE_ANY = 0x00, + /** + * Screen size: value indicating the screen is at least + * approximately 320x426 dp units, corresponding to the + * small + * resource qualifier. + */ + ACONFIGURATION_SCREENSIZE_SMALL = 0x01, + /** + * Screen size: value indicating the screen is at least + * approximately 320x470 dp units, corresponding to the + * normal + * resource qualifier. + */ + ACONFIGURATION_SCREENSIZE_NORMAL = 0x02, + /** + * Screen size: value indicating the screen is at least + * approximately 480x640 dp units, corresponding to the + * large + * resource qualifier. + */ + ACONFIGURATION_SCREENSIZE_LARGE = 0x03, + /** + * Screen size: value indicating the screen is at least + * approximately 720x960 dp units, corresponding to the + * xlarge + * resource qualifier. + */ + ACONFIGURATION_SCREENSIZE_XLARGE = 0x04, + + /** Screen layout: not specified. */ + ACONFIGURATION_SCREENLONG_ANY = 0x00, + /** + * Screen layout: value that corresponds to the + * notlong + * resource qualifier. + */ + ACONFIGURATION_SCREENLONG_NO = 0x1, + /** + * Screen layout: value that corresponds to the + * long + * resource qualifier. + */ + ACONFIGURATION_SCREENLONG_YES = 0x2, + + ACONFIGURATION_SCREENROUND_ANY = 0x00, + ACONFIGURATION_SCREENROUND_NO = 0x1, + ACONFIGURATION_SCREENROUND_YES = 0x2, + + /** UI mode: not specified. */ + ACONFIGURATION_UI_MODE_TYPE_ANY = 0x00, + /** + * UI mode: value that corresponds to + * no + * UI mode type resource qualifier specified. + */ + ACONFIGURATION_UI_MODE_TYPE_NORMAL = 0x01, + /** + * UI mode: value that corresponds to + * desk resource qualifier specified. + */ + ACONFIGURATION_UI_MODE_TYPE_DESK = 0x02, + /** + * UI mode: value that corresponds to + * car resource qualifier specified. + */ + ACONFIGURATION_UI_MODE_TYPE_CAR = 0x03, + /** + * UI mode: value that corresponds to + * television resource qualifier specified. + */ + ACONFIGURATION_UI_MODE_TYPE_TELEVISION = 0x04, + /** + * UI mode: value that corresponds to + * appliance resource qualifier specified. + */ + ACONFIGURATION_UI_MODE_TYPE_APPLIANCE = 0x05, + /** + * UI mode: value that corresponds to + * watch resource qualifier specified. + */ + ACONFIGURATION_UI_MODE_TYPE_WATCH = 0x06, + + /** UI night mode: not specified.*/ + ACONFIGURATION_UI_MODE_NIGHT_ANY = 0x00, + /** + * UI night mode: value that corresponds to + * notnight resource qualifier specified. + */ + ACONFIGURATION_UI_MODE_NIGHT_NO = 0x1, + /** + * UI night mode: value that corresponds to + * night resource qualifier specified. + */ + ACONFIGURATION_UI_MODE_NIGHT_YES = 0x2, + + /** Screen width DPI: not specified. */ + ACONFIGURATION_SCREEN_WIDTH_DP_ANY = 0x0000, + + /** Screen height DPI: not specified. */ + ACONFIGURATION_SCREEN_HEIGHT_DP_ANY = 0x0000, + + /** Smallest screen width DPI: not specified.*/ + ACONFIGURATION_SMALLEST_SCREEN_WIDTH_DP_ANY = 0x0000, + + /** Layout direction: not specified. */ + ACONFIGURATION_LAYOUTDIR_ANY = 0x00, + /** + * Layout direction: value that corresponds to + * ldltr resource qualifier specified. + */ + ACONFIGURATION_LAYOUTDIR_LTR = 0x01, + /** + * Layout direction: value that corresponds to + * ldrtl resource qualifier specified. + */ + ACONFIGURATION_LAYOUTDIR_RTL = 0x02, + + /** + * Bit mask for + * mcc + * configuration. + */ + ACONFIGURATION_MCC = 0x0001, + /** + * Bit mask for + * mnc + * configuration. + */ + ACONFIGURATION_MNC = 0x0002, + /** + * Bit mask for + * locale + * configuration. + */ + ACONFIGURATION_LOCALE = 0x0004, + /** + * Bit mask for + * touchscreen + * configuration. + */ + ACONFIGURATION_TOUCHSCREEN = 0x0008, + /** + * Bit mask for + * keyboard + * configuration. + */ + ACONFIGURATION_KEYBOARD = 0x0010, + /** + * Bit mask for + * keyboardHidden + * configuration. + */ + ACONFIGURATION_KEYBOARD_HIDDEN = 0x0020, + /** + * Bit mask for + * navigation + * configuration. + */ + ACONFIGURATION_NAVIGATION = 0x0040, + /** + * Bit mask for + * orientation + * configuration. + */ + ACONFIGURATION_ORIENTATION = 0x0080, + /** + * Bit mask for + * density + * configuration. + */ + ACONFIGURATION_DENSITY = 0x0100, + /** + * Bit mask for + * screen size + * configuration. + */ + ACONFIGURATION_SCREEN_SIZE = 0x0200, + /** + * Bit mask for + * platform version + * configuration. + */ + ACONFIGURATION_VERSION = 0x0400, + /** + * Bit mask for screen layout configuration. + */ + ACONFIGURATION_SCREEN_LAYOUT = 0x0800, + /** + * Bit mask for + * ui mode + * configuration. + */ + ACONFIGURATION_UI_MODE = 0x1000, + /** + * Bit mask for + * smallest screen width + * configuration. + */ + ACONFIGURATION_SMALLEST_SCREEN_SIZE = 0x2000, + /** + * Bit mask for + * layout direction + * configuration. + */ + ACONFIGURATION_LAYOUTDIR = 0x4000, + ACONFIGURATION_SCREEN_ROUND = 0x8000, + /** + * Constant used to to represent MNC (Mobile Network Code) zero. + * 0 cannot be used, since it is used to represent an undefined MNC. + */ + ACONFIGURATION_MNC_ZERO = 0xffff, +}; + +/** + * Create a new AConfiguration, initialized with no values set. + */ +AConfiguration* AConfiguration_new(); + +/** + * Free an AConfiguration that was previously created with + * AConfiguration_new(). + */ +void AConfiguration_delete(AConfiguration* config); + +/** + * Create and return a new AConfiguration based on the current configuration in + * use in the given {@link AAssetManager}. + */ +void AConfiguration_fromAssetManager(AConfiguration* out, AAssetManager* am); + +/** + * Copy the contents of 'src' to 'dest'. + */ +void AConfiguration_copy(AConfiguration* dest, AConfiguration* src); + +/** + * Return the current MCC set in the configuration. 0 if not set. + */ +int32_t AConfiguration_getMcc(AConfiguration* config); + +/** + * Set the current MCC in the configuration. 0 to clear. + */ +void AConfiguration_setMcc(AConfiguration* config, int32_t mcc); + +/** + * Return the current MNC set in the configuration. 0 if not set. + */ +int32_t AConfiguration_getMnc(AConfiguration* config); + +/** + * Set the current MNC in the configuration. 0 to clear. + */ +void AConfiguration_setMnc(AConfiguration* config, int32_t mnc); + +/** + * Return the current language code set in the configuration. The output will + * be filled with an array of two characters. They are not 0-terminated. If + * a language is not set, they will be 0. + */ +void AConfiguration_getLanguage(AConfiguration* config, char* outLanguage); + +/** + * Set the current language code in the configuration, from the first two + * characters in the string. + */ +void AConfiguration_setLanguage(AConfiguration* config, const char* language); + +/** + * Return the current country code set in the configuration. The output will + * be filled with an array of two characters. They are not 0-terminated. If + * a country is not set, they will be 0. + */ +void AConfiguration_getCountry(AConfiguration* config, char* outCountry); + +/** + * Set the current country code in the configuration, from the first two + * characters in the string. + */ +void AConfiguration_setCountry(AConfiguration* config, const char* country); + +/** + * Return the current ACONFIGURATION_ORIENTATION_* set in the configuration. + */ +int32_t AConfiguration_getOrientation(AConfiguration* config); + +/** + * Set the current orientation in the configuration. + */ +void AConfiguration_setOrientation(AConfiguration* config, int32_t orientation); + +/** + * Return the current ACONFIGURATION_TOUCHSCREEN_* set in the configuration. + */ +int32_t AConfiguration_getTouchscreen(AConfiguration* config); + +/** + * Set the current touchscreen in the configuration. + */ +void AConfiguration_setTouchscreen(AConfiguration* config, int32_t touchscreen); + +/** + * Return the current ACONFIGURATION_DENSITY_* set in the configuration. + */ +int32_t AConfiguration_getDensity(AConfiguration* config); + +/** + * Set the current density in the configuration. + */ +void AConfiguration_setDensity(AConfiguration* config, int32_t density); + +/** + * Return the current ACONFIGURATION_KEYBOARD_* set in the configuration. + */ +int32_t AConfiguration_getKeyboard(AConfiguration* config); + +/** + * Set the current keyboard in the configuration. + */ +void AConfiguration_setKeyboard(AConfiguration* config, int32_t keyboard); + +/** + * Return the current ACONFIGURATION_NAVIGATION_* set in the configuration. + */ +int32_t AConfiguration_getNavigation(AConfiguration* config); + +/** + * Set the current navigation in the configuration. + */ +void AConfiguration_setNavigation(AConfiguration* config, int32_t navigation); + +/** + * Return the current ACONFIGURATION_KEYSHIDDEN_* set in the configuration. + */ +int32_t AConfiguration_getKeysHidden(AConfiguration* config); + +/** + * Set the current keys hidden in the configuration. + */ +void AConfiguration_setKeysHidden(AConfiguration* config, int32_t keysHidden); + +/** + * Return the current ACONFIGURATION_NAVHIDDEN_* set in the configuration. + */ +int32_t AConfiguration_getNavHidden(AConfiguration* config); + +/** + * Set the current nav hidden in the configuration. + */ +void AConfiguration_setNavHidden(AConfiguration* config, int32_t navHidden); + +/** + * Return the current SDK (API) version set in the configuration. + */ +int32_t AConfiguration_getSdkVersion(AConfiguration* config); + +/** + * Set the current SDK version in the configuration. + */ +void AConfiguration_setSdkVersion(AConfiguration* config, int32_t sdkVersion); + +/** + * Return the current ACONFIGURATION_SCREENSIZE_* set in the configuration. + */ +int32_t AConfiguration_getScreenSize(AConfiguration* config); + +/** + * Set the current screen size in the configuration. + */ +void AConfiguration_setScreenSize(AConfiguration* config, int32_t screenSize); + +/** + * Return the current ACONFIGURATION_SCREENLONG_* set in the configuration. + */ +int32_t AConfiguration_getScreenLong(AConfiguration* config); + +/** + * Set the current screen long in the configuration. + */ +void AConfiguration_setScreenLong(AConfiguration* config, int32_t screenLong); + +/** + * Return the current ACONFIGURATION_SCREENROUND_* set in the configuration. + */ +int32_t AConfiguration_getScreenRound(AConfiguration* config); + +/** + * Set the current screen round in the configuration. + */ +void AConfiguration_setScreenRound(AConfiguration* config, int32_t screenRound); + +/** + * Return the current ACONFIGURATION_UI_MODE_TYPE_* set in the configuration. + */ +int32_t AConfiguration_getUiModeType(AConfiguration* config); + +/** + * Set the current UI mode type in the configuration. + */ +void AConfiguration_setUiModeType(AConfiguration* config, int32_t uiModeType); + +/** + * Return the current ACONFIGURATION_UI_MODE_NIGHT_* set in the configuration. + */ +int32_t AConfiguration_getUiModeNight(AConfiguration* config); + +/** + * Set the current UI mode night in the configuration. + */ +void AConfiguration_setUiModeNight(AConfiguration* config, int32_t uiModeNight); + +/** + * Return the current configuration screen width in dp units, or + * ACONFIGURATION_SCREEN_WIDTH_DP_ANY if not set. + */ +int32_t AConfiguration_getScreenWidthDp(AConfiguration* config); + +/** + * Set the configuration's current screen width in dp units. + */ +void AConfiguration_setScreenWidthDp(AConfiguration* config, int32_t value); + +/** + * Return the current configuration screen height in dp units, or + * ACONFIGURATION_SCREEN_HEIGHT_DP_ANY if not set. + */ +int32_t AConfiguration_getScreenHeightDp(AConfiguration* config); + +/** + * Set the configuration's current screen width in dp units. + */ +void AConfiguration_setScreenHeightDp(AConfiguration* config, int32_t value); + +/** + * Return the configuration's smallest screen width in dp units, or + * ACONFIGURATION_SMALLEST_SCREEN_WIDTH_DP_ANY if not set. + */ +int32_t AConfiguration_getSmallestScreenWidthDp(AConfiguration* config); + +/** + * Set the configuration's smallest screen width in dp units. + */ +void AConfiguration_setSmallestScreenWidthDp(AConfiguration* config, int32_t value); + +/** + * Return the configuration's layout direction, or + * ACONFIGURATION_LAYOUTDIR_ANY if not set. + */ +int32_t AConfiguration_getLayoutDirection(AConfiguration* config); + +/** + * Set the configuration's layout direction. + */ +void AConfiguration_setLayoutDirection(AConfiguration* config, int32_t value); + +/** + * Perform a diff between two configurations. Returns a bit mask of + * ACONFIGURATION_* constants, each bit set meaning that configuration element + * is different between them. + */ +int32_t AConfiguration_diff(AConfiguration* config1, AConfiguration* config2); + +/** + * Determine whether 'base' is a valid configuration for use within the + * environment 'requested'. Returns 0 if there are any values in 'base' + * that conflict with 'requested'. Returns 1 if it does not conflict. + */ +int32_t AConfiguration_match(AConfiguration* base, AConfiguration* requested); + +/** + * Determine whether the configuration in 'test' is better than the existing + * configuration in 'base'. If 'requested' is non-NULL, this decision is based + * on the overall configuration given there. If it is NULL, this decision is + * simply based on which configuration is more specific. Returns non-0 if + * 'test' is better than 'base'. + * + * This assumes you have already filtered the configurations with + * AConfiguration_match(). + */ +int32_t AConfiguration_isBetterThan(AConfiguration* base, AConfiguration* test, + AConfiguration* requested); + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_CONFIGURATION_H + +/** @} */ diff --git a/phonelibs/android_frameworks_native/include/android/input.h b/phonelibs/android_frameworks_native/include/android/input.h new file mode 100644 index 00000000000000..46cf89c7e1714b --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/input.h @@ -0,0 +1,1317 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup Input + * @{ + */ + +/** + * @file input.h + */ + +#ifndef _ANDROID_INPUT_H +#define _ANDROID_INPUT_H + +/****************************************************************** + * + * IMPORTANT NOTICE: + * + * This file is part of Android's set of stable system headers + * exposed by the Android NDK (Native Development Kit). + * + * Third-party source AND binary code relies on the definitions + * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES. + * + * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES) + * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS + * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY + * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES + */ + +/* + * Structures and functions to receive and process input events in + * native code. + * + * NOTE: These functions MUST be implemented by /system/lib/libui.so + */ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Key states (may be returned by queries about the current state of a + * particular key code, scan code or switch). + */ +enum { + /** The key state is unknown or the requested key itself is not supported. */ + AKEY_STATE_UNKNOWN = -1, + + /** The key is up. */ + AKEY_STATE_UP = 0, + + /** The key is down. */ + AKEY_STATE_DOWN = 1, + + /** The key is down but is a virtual key press that is being emulated by the system. */ + AKEY_STATE_VIRTUAL = 2 +}; + +/** + * Meta key / modifer state. + */ +enum { + /** No meta keys are pressed. */ + AMETA_NONE = 0, + + /** This mask is used to check whether one of the ALT meta keys is pressed. */ + AMETA_ALT_ON = 0x02, + + /** This mask is used to check whether the left ALT meta key is pressed. */ + AMETA_ALT_LEFT_ON = 0x10, + + /** This mask is used to check whether the right ALT meta key is pressed. */ + AMETA_ALT_RIGHT_ON = 0x20, + + /** This mask is used to check whether one of the SHIFT meta keys is pressed. */ + AMETA_SHIFT_ON = 0x01, + + /** This mask is used to check whether the left SHIFT meta key is pressed. */ + AMETA_SHIFT_LEFT_ON = 0x40, + + /** This mask is used to check whether the right SHIFT meta key is pressed. */ + AMETA_SHIFT_RIGHT_ON = 0x80, + + /** This mask is used to check whether the SYM meta key is pressed. */ + AMETA_SYM_ON = 0x04, + + /** This mask is used to check whether the FUNCTION meta key is pressed. */ + AMETA_FUNCTION_ON = 0x08, + + /** This mask is used to check whether one of the CTRL meta keys is pressed. */ + AMETA_CTRL_ON = 0x1000, + + /** This mask is used to check whether the left CTRL meta key is pressed. */ + AMETA_CTRL_LEFT_ON = 0x2000, + + /** This mask is used to check whether the right CTRL meta key is pressed. */ + AMETA_CTRL_RIGHT_ON = 0x4000, + + /** This mask is used to check whether one of the META meta keys is pressed. */ + AMETA_META_ON = 0x10000, + + /** This mask is used to check whether the left META meta key is pressed. */ + AMETA_META_LEFT_ON = 0x20000, + + /** This mask is used to check whether the right META meta key is pressed. */ + AMETA_META_RIGHT_ON = 0x40000, + + /** This mask is used to check whether the CAPS LOCK meta key is on. */ + AMETA_CAPS_LOCK_ON = 0x100000, + + /** This mask is used to check whether the NUM LOCK meta key is on. */ + AMETA_NUM_LOCK_ON = 0x200000, + + /** This mask is used to check whether the SCROLL LOCK meta key is on. */ + AMETA_SCROLL_LOCK_ON = 0x400000, +}; + +struct AInputEvent; +/** + * Input events. + * + * Input events are opaque structures. Use the provided accessors functions to + * read their properties. + */ +typedef struct AInputEvent AInputEvent; + +/** + * Input event types. + */ +enum { + /** Indicates that the input event is a key event. */ + AINPUT_EVENT_TYPE_KEY = 1, + + /** Indicates that the input event is a motion event. */ + AINPUT_EVENT_TYPE_MOTION = 2 +}; + +/** + * Key event actions. + */ +enum { + /** The key has been pressed down. */ + AKEY_EVENT_ACTION_DOWN = 0, + + /** The key has been released. */ + AKEY_EVENT_ACTION_UP = 1, + + /** + * Multiple duplicate key events have occurred in a row, or a + * complex string is being delivered. The repeat_count property + * of the key event contains the number of times the given key + * code should be executed. + */ + AKEY_EVENT_ACTION_MULTIPLE = 2 +}; + +/** + * Key event flags. + */ +enum { + /** This mask is set if the device woke because of this key event. */ + AKEY_EVENT_FLAG_WOKE_HERE = 0x1, + + /** This mask is set if the key event was generated by a software keyboard. */ + AKEY_EVENT_FLAG_SOFT_KEYBOARD = 0x2, + + /** This mask is set if we don't want the key event to cause us to leave touch mode. */ + AKEY_EVENT_FLAG_KEEP_TOUCH_MODE = 0x4, + + /** + * This mask is set if an event was known to come from a trusted + * part of the system. That is, the event is known to come from + * the user, and could not have been spoofed by a third party + * component. + */ + AKEY_EVENT_FLAG_FROM_SYSTEM = 0x8, + + /** + * This mask is used for compatibility, to identify enter keys that are + * coming from an IME whose enter key has been auto-labelled "next" or + * "done". This allows TextView to dispatch these as normal enter keys + * for old applications, but still do the appropriate action when + * receiving them. + */ + AKEY_EVENT_FLAG_EDITOR_ACTION = 0x10, + + /** + * When associated with up key events, this indicates that the key press + * has been canceled. Typically this is used with virtual touch screen + * keys, where the user can slide from the virtual key area on to the + * display: in that case, the application will receive a canceled up + * event and should not perform the action normally associated with the + * key. Note that for this to work, the application can not perform an + * action for a key until it receives an up or the long press timeout has + * expired. + */ + AKEY_EVENT_FLAG_CANCELED = 0x20, + + /** + * This key event was generated by a virtual (on-screen) hard key area. + * Typically this is an area of the touchscreen, outside of the regular + * display, dedicated to "hardware" buttons. + */ + AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY = 0x40, + + /** + * This flag is set for the first key repeat that occurs after the + * long press timeout. + */ + AKEY_EVENT_FLAG_LONG_PRESS = 0x80, + + /** + * Set when a key event has AKEY_EVENT_FLAG_CANCELED set because a long + * press action was executed while it was down. + */ + AKEY_EVENT_FLAG_CANCELED_LONG_PRESS = 0x100, + + /** + * Set for AKEY_EVENT_ACTION_UP when this event's key code is still being + * tracked from its initial down. That is, somebody requested that tracking + * started on the key down and a long press has not caused + * the tracking to be canceled. + */ + AKEY_EVENT_FLAG_TRACKING = 0x200, + + /** + * Set when a key event has been synthesized to implement default behavior + * for an event that the application did not handle. + * Fallback key events are generated by unhandled trackball motions + * (to emulate a directional keypad) and by certain unhandled key presses + * that are declared in the key map (such as special function numeric keypad + * keys when numlock is off). + */ + AKEY_EVENT_FLAG_FALLBACK = 0x400, +}; + +/** + * Bit shift for the action bits holding the pointer index as + * defined by AMOTION_EVENT_ACTION_POINTER_INDEX_MASK. + */ +#define AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT 8 + +/** Motion event actions */ +enum { + /** Bit mask of the parts of the action code that are the action itself. */ + AMOTION_EVENT_ACTION_MASK = 0xff, + + /** + * Bits in the action code that represent a pointer index, used with + * AMOTION_EVENT_ACTION_POINTER_DOWN and AMOTION_EVENT_ACTION_POINTER_UP. Shifting + * down by AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT provides the actual pointer + * index where the data for the pointer going up or down can be found. + */ + AMOTION_EVENT_ACTION_POINTER_INDEX_MASK = 0xff00, + + /** A pressed gesture has started, the motion contains the initial starting location. */ + AMOTION_EVENT_ACTION_DOWN = 0, + + /** + * A pressed gesture has finished, the motion contains the final release location + * as well as any intermediate points since the last down or move event. + */ + AMOTION_EVENT_ACTION_UP = 1, + + /** + * A change has happened during a press gesture (between AMOTION_EVENT_ACTION_DOWN and + * AMOTION_EVENT_ACTION_UP). The motion contains the most recent point, as well as + * any intermediate points since the last down or move event. + */ + AMOTION_EVENT_ACTION_MOVE = 2, + + /** + * The current gesture has been aborted. + * You will not receive any more points in it. You should treat this as + * an up event, but not perform any action that you normally would. + */ + AMOTION_EVENT_ACTION_CANCEL = 3, + + /** + * A movement has happened outside of the normal bounds of the UI element. + * This does not provide a full gesture, but only the initial location of the movement/touch. + */ + AMOTION_EVENT_ACTION_OUTSIDE = 4, + + /** + * A non-primary pointer has gone down. + * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed. + */ + AMOTION_EVENT_ACTION_POINTER_DOWN = 5, + + /** + * A non-primary pointer has gone up. + * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed. + */ + AMOTION_EVENT_ACTION_POINTER_UP = 6, + + /** + * A change happened but the pointer is not down (unlike AMOTION_EVENT_ACTION_MOVE). + * The motion contains the most recent point, as well as any intermediate points since + * the last hover move event. + */ + AMOTION_EVENT_ACTION_HOVER_MOVE = 7, + + /** + * The motion event contains relative vertical and/or horizontal scroll offsets. + * Use getAxisValue to retrieve the information from AMOTION_EVENT_AXIS_VSCROLL + * and AMOTION_EVENT_AXIS_HSCROLL. + * The pointer may or may not be down when this event is dispatched. + * This action is always delivered to the winder under the pointer, which + * may not be the window currently touched. + */ + AMOTION_EVENT_ACTION_SCROLL = 8, + + /** The pointer is not down but has entered the boundaries of a window or view. */ + AMOTION_EVENT_ACTION_HOVER_ENTER = 9, + + /** The pointer is not down but has exited the boundaries of a window or view. */ + AMOTION_EVENT_ACTION_HOVER_EXIT = 10, + + /* One or more buttons have been pressed. */ + AMOTION_EVENT_ACTION_BUTTON_PRESS = 11, + + /* One or more buttons have been released. */ + AMOTION_EVENT_ACTION_BUTTON_RELEASE = 12, +}; + +/** + * Motion event flags. + */ +enum { + /** + * This flag indicates that the window that received this motion event is partly + * or wholly obscured by another visible window above it. This flag is set to true + * even if the event did not directly pass through the obscured area. + * A security sensitive application can check this flag to identify situations in which + * a malicious application may have covered up part of its content for the purpose + * of misleading the user or hijacking touches. An appropriate response might be + * to drop the suspect touches or to take additional precautions to confirm the user's + * actual intent. + */ + AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED = 0x1, +}; + +/** + * Motion event edge touch flags. + */ +enum { + /** No edges intersected. */ + AMOTION_EVENT_EDGE_FLAG_NONE = 0, + + /** Flag indicating the motion event intersected the top edge of the screen. */ + AMOTION_EVENT_EDGE_FLAG_TOP = 0x01, + + /** Flag indicating the motion event intersected the bottom edge of the screen. */ + AMOTION_EVENT_EDGE_FLAG_BOTTOM = 0x02, + + /** Flag indicating the motion event intersected the left edge of the screen. */ + AMOTION_EVENT_EDGE_FLAG_LEFT = 0x04, + + /** Flag indicating the motion event intersected the right edge of the screen. */ + AMOTION_EVENT_EDGE_FLAG_RIGHT = 0x08 +}; + +/** + * Constants that identify each individual axis of a motion event. + * @anchor AMOTION_EVENT_AXIS + */ +enum { + /** + * Axis constant: X axis of a motion event. + * + * - For a touch screen, reports the absolute X screen position of the center of + * the touch contact area. The units are display pixels. + * - For a touch pad, reports the absolute X surface position of the center of the touch + * contact area. The units are device-dependent. + * - For a mouse, reports the absolute X screen position of the mouse pointer. + * The units are display pixels. + * - For a trackball, reports the relative horizontal displacement of the trackball. + * The value is normalized to a range from -1.0 (left) to 1.0 (right). + * - For a joystick, reports the absolute X position of the joystick. + * The value is normalized to a range from -1.0 (left) to 1.0 (right). + */ + AMOTION_EVENT_AXIS_X = 0, + /** + * Axis constant: Y axis of a motion event. + * + * - For a touch screen, reports the absolute Y screen position of the center of + * the touch contact area. The units are display pixels. + * - For a touch pad, reports the absolute Y surface position of the center of the touch + * contact area. The units are device-dependent. + * - For a mouse, reports the absolute Y screen position of the mouse pointer. + * The units are display pixels. + * - For a trackball, reports the relative vertical displacement of the trackball. + * The value is normalized to a range from -1.0 (up) to 1.0 (down). + * - For a joystick, reports the absolute Y position of the joystick. + * The value is normalized to a range from -1.0 (up or far) to 1.0 (down or near). + */ + AMOTION_EVENT_AXIS_Y = 1, + /** + * Axis constant: Pressure axis of a motion event. + * + * - For a touch screen or touch pad, reports the approximate pressure applied to the surface + * by a finger or other tool. The value is normalized to a range from + * 0 (no pressure at all) to 1 (normal pressure), although values higher than 1 + * may be generated depending on the calibration of the input device. + * - For a trackball, the value is set to 1 if the trackball button is pressed + * or 0 otherwise. + * - For a mouse, the value is set to 1 if the primary mouse button is pressed + * or 0 otherwise. + */ + AMOTION_EVENT_AXIS_PRESSURE = 2, + /** + * Axis constant: Size axis of a motion event. + * + * - For a touch screen or touch pad, reports the approximate size of the contact area in + * relation to the maximum detectable size for the device. The value is normalized + * to a range from 0 (smallest detectable size) to 1 (largest detectable size), + * although it is not a linear scale. This value is of limited use. + * To obtain calibrated size information, see + * {@link AMOTION_EVENT_AXIS_TOUCH_MAJOR} or {@link AMOTION_EVENT_AXIS_TOOL_MAJOR}. + */ + AMOTION_EVENT_AXIS_SIZE = 3, + /** + * Axis constant: TouchMajor axis of a motion event. + * + * - For a touch screen, reports the length of the major axis of an ellipse that + * represents the touch area at the point of contact. + * The units are display pixels. + * - For a touch pad, reports the length of the major axis of an ellipse that + * represents the touch area at the point of contact. + * The units are device-dependent. + */ + AMOTION_EVENT_AXIS_TOUCH_MAJOR = 4, + /** + * Axis constant: TouchMinor axis of a motion event. + * + * - For a touch screen, reports the length of the minor axis of an ellipse that + * represents the touch area at the point of contact. + * The units are display pixels. + * - For a touch pad, reports the length of the minor axis of an ellipse that + * represents the touch area at the point of contact. + * The units are device-dependent. + * + * When the touch is circular, the major and minor axis lengths will be equal to one another. + */ + AMOTION_EVENT_AXIS_TOUCH_MINOR = 5, + /** + * Axis constant: ToolMajor axis of a motion event. + * + * - For a touch screen, reports the length of the major axis of an ellipse that + * represents the size of the approaching finger or tool used to make contact. + * - For a touch pad, reports the length of the major axis of an ellipse that + * represents the size of the approaching finger or tool used to make contact. + * The units are device-dependent. + * + * When the touch is circular, the major and minor axis lengths will be equal to one another. + * + * The tool size may be larger than the touch size since the tool may not be fully + * in contact with the touch sensor. + */ + AMOTION_EVENT_AXIS_TOOL_MAJOR = 6, + /** + * Axis constant: ToolMinor axis of a motion event. + * + * - For a touch screen, reports the length of the minor axis of an ellipse that + * represents the size of the approaching finger or tool used to make contact. + * - For a touch pad, reports the length of the minor axis of an ellipse that + * represents the size of the approaching finger or tool used to make contact. + * The units are device-dependent. + * + * When the touch is circular, the major and minor axis lengths will be equal to one another. + * + * The tool size may be larger than the touch size since the tool may not be fully + * in contact with the touch sensor. + */ + AMOTION_EVENT_AXIS_TOOL_MINOR = 7, + /** + * Axis constant: Orientation axis of a motion event. + * + * - For a touch screen or touch pad, reports the orientation of the finger + * or tool in radians relative to the vertical plane of the device. + * An angle of 0 radians indicates that the major axis of contact is oriented + * upwards, is perfectly circular or is of unknown orientation. A positive angle + * indicates that the major axis of contact is oriented to the right. A negative angle + * indicates that the major axis of contact is oriented to the left. + * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians + * (finger pointing fully right). + * - For a stylus, the orientation indicates the direction in which the stylus + * is pointing in relation to the vertical axis of the current orientation of the screen. + * The range is from -PI radians to PI radians, where 0 is pointing up, + * -PI/2 radians is pointing left, -PI or PI radians is pointing down, and PI/2 radians + * is pointing right. See also {@link AMOTION_EVENT_AXIS_TILT}. + */ + AMOTION_EVENT_AXIS_ORIENTATION = 8, + /** + * Axis constant: Vertical Scroll axis of a motion event. + * + * - For a mouse, reports the relative movement of the vertical scroll wheel. + * The value is normalized to a range from -1.0 (down) to 1.0 (up). + * + * This axis should be used to scroll views vertically. + */ + AMOTION_EVENT_AXIS_VSCROLL = 9, + /** + * Axis constant: Horizontal Scroll axis of a motion event. + * + * - For a mouse, reports the relative movement of the horizontal scroll wheel. + * The value is normalized to a range from -1.0 (left) to 1.0 (right). + * + * This axis should be used to scroll views horizontally. + */ + AMOTION_EVENT_AXIS_HSCROLL = 10, + /** + * Axis constant: Z axis of a motion event. + * + * - For a joystick, reports the absolute Z position of the joystick. + * The value is normalized to a range from -1.0 (high) to 1.0 (low). + * On game pads with two analog joysticks, this axis is often reinterpreted + * to report the absolute X position of the second joystick instead. + */ + AMOTION_EVENT_AXIS_Z = 11, + /** + * Axis constant: X Rotation axis of a motion event. + * + * - For a joystick, reports the absolute rotation angle about the X axis. + * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise). + */ + AMOTION_EVENT_AXIS_RX = 12, + /** + * Axis constant: Y Rotation axis of a motion event. + * + * - For a joystick, reports the absolute rotation angle about the Y axis. + * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise). + */ + AMOTION_EVENT_AXIS_RY = 13, + /** + * Axis constant: Z Rotation axis of a motion event. + * + * - For a joystick, reports the absolute rotation angle about the Z axis. + * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise). + * On game pads with two analog joysticks, this axis is often reinterpreted + * to report the absolute Y position of the second joystick instead. + */ + AMOTION_EVENT_AXIS_RZ = 14, + /** + * Axis constant: Hat X axis of a motion event. + * + * - For a joystick, reports the absolute X position of the directional hat control. + * The value is normalized to a range from -1.0 (left) to 1.0 (right). + */ + AMOTION_EVENT_AXIS_HAT_X = 15, + /** + * Axis constant: Hat Y axis of a motion event. + * + * - For a joystick, reports the absolute Y position of the directional hat control. + * The value is normalized to a range from -1.0 (up) to 1.0 (down). + */ + AMOTION_EVENT_AXIS_HAT_Y = 16, + /** + * Axis constant: Left Trigger axis of a motion event. + * + * - For a joystick, reports the absolute position of the left trigger control. + * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed). + */ + AMOTION_EVENT_AXIS_LTRIGGER = 17, + /** + * Axis constant: Right Trigger axis of a motion event. + * + * - For a joystick, reports the absolute position of the right trigger control. + * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed). + */ + AMOTION_EVENT_AXIS_RTRIGGER = 18, + /** + * Axis constant: Throttle axis of a motion event. + * + * - For a joystick, reports the absolute position of the throttle control. + * The value is normalized to a range from 0.0 (fully open) to 1.0 (fully closed). + */ + AMOTION_EVENT_AXIS_THROTTLE = 19, + /** + * Axis constant: Rudder axis of a motion event. + * + * - For a joystick, reports the absolute position of the rudder control. + * The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right). + */ + AMOTION_EVENT_AXIS_RUDDER = 20, + /** + * Axis constant: Wheel axis of a motion event. + * + * - For a joystick, reports the absolute position of the steering wheel control. + * The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right). + */ + AMOTION_EVENT_AXIS_WHEEL = 21, + /** + * Axis constant: Gas axis of a motion event. + * + * - For a joystick, reports the absolute position of the gas (accelerator) control. + * The value is normalized to a range from 0.0 (no acceleration) + * to 1.0 (maximum acceleration). + */ + AMOTION_EVENT_AXIS_GAS = 22, + /** + * Axis constant: Brake axis of a motion event. + * + * - For a joystick, reports the absolute position of the brake control. + * The value is normalized to a range from 0.0 (no braking) to 1.0 (maximum braking). + */ + AMOTION_EVENT_AXIS_BRAKE = 23, + /** + * Axis constant: Distance axis of a motion event. + * + * - For a stylus, reports the distance of the stylus from the screen. + * A value of 0.0 indicates direct contact and larger values indicate increasing + * distance from the surface. + */ + AMOTION_EVENT_AXIS_DISTANCE = 24, + /** + * Axis constant: Tilt axis of a motion event. + * + * - For a stylus, reports the tilt angle of the stylus in radians where + * 0 radians indicates that the stylus is being held perpendicular to the + * surface, and PI/2 radians indicates that the stylus is being held flat + * against the surface. + */ + AMOTION_EVENT_AXIS_TILT = 25, + /** + * Axis constant: Generic 1 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_1 = 32, + /** + * Axis constant: Generic 2 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_2 = 33, + /** + * Axis constant: Generic 3 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_3 = 34, + /** + * Axis constant: Generic 4 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_4 = 35, + /** + * Axis constant: Generic 5 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_5 = 36, + /** + * Axis constant: Generic 6 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_6 = 37, + /** + * Axis constant: Generic 7 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_7 = 38, + /** + * Axis constant: Generic 8 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_8 = 39, + /** + * Axis constant: Generic 9 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_9 = 40, + /** + * Axis constant: Generic 10 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_10 = 41, + /** + * Axis constant: Generic 11 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_11 = 42, + /** + * Axis constant: Generic 12 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_12 = 43, + /** + * Axis constant: Generic 13 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_13 = 44, + /** + * Axis constant: Generic 14 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_14 = 45, + /** + * Axis constant: Generic 15 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_15 = 46, + /** + * Axis constant: Generic 16 axis of a motion event. + * The interpretation of a generic axis is device-specific. + */ + AMOTION_EVENT_AXIS_GENERIC_16 = 47, + + // NOTE: If you add a new axis here you must also add it to several other files. + // Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list. +}; + +/** + * Constants that identify buttons that are associated with motion events. + * Refer to the documentation on the MotionEvent class for descriptions of each button. + */ +enum { + /** primary */ + AMOTION_EVENT_BUTTON_PRIMARY = 1 << 0, + /** secondary */ + AMOTION_EVENT_BUTTON_SECONDARY = 1 << 1, + /** tertiary */ + AMOTION_EVENT_BUTTON_TERTIARY = 1 << 2, + /** back */ + AMOTION_EVENT_BUTTON_BACK = 1 << 3, + /** forward */ + AMOTION_EVENT_BUTTON_FORWARD = 1 << 4, + AMOTION_EVENT_BUTTON_STYLUS_PRIMARY = 1 << 5, + AMOTION_EVENT_BUTTON_STYLUS_SECONDARY = 1 << 6, +}; + +/** + * Constants that identify tool types. + * Refer to the documentation on the MotionEvent class for descriptions of each tool type. + */ +enum { + /** unknown */ + AMOTION_EVENT_TOOL_TYPE_UNKNOWN = 0, + /** finger */ + AMOTION_EVENT_TOOL_TYPE_FINGER = 1, + /** stylus */ + AMOTION_EVENT_TOOL_TYPE_STYLUS = 2, + /** mouse */ + AMOTION_EVENT_TOOL_TYPE_MOUSE = 3, + /** eraser */ + AMOTION_EVENT_TOOL_TYPE_ERASER = 4, +}; + +/** + * Input source masks. + * + * Refer to the documentation on android.view.InputDevice for more details about input sources + * and their correct interpretation. + */ +enum { + /** mask */ + AINPUT_SOURCE_CLASS_MASK = 0x000000ff, + + /** none */ + AINPUT_SOURCE_CLASS_NONE = 0x00000000, + /** button */ + AINPUT_SOURCE_CLASS_BUTTON = 0x00000001, + /** pointer */ + AINPUT_SOURCE_CLASS_POINTER = 0x00000002, + /** navigation */ + AINPUT_SOURCE_CLASS_NAVIGATION = 0x00000004, + /** position */ + AINPUT_SOURCE_CLASS_POSITION = 0x00000008, + /** joystick */ + AINPUT_SOURCE_CLASS_JOYSTICK = 0x00000010, +}; + +/** + * Input sources. + */ +enum { + /** unknown */ + AINPUT_SOURCE_UNKNOWN = 0x00000000, + + /** keyboard */ + AINPUT_SOURCE_KEYBOARD = 0x00000100 | AINPUT_SOURCE_CLASS_BUTTON, + /** dpad */ + AINPUT_SOURCE_DPAD = 0x00000200 | AINPUT_SOURCE_CLASS_BUTTON, + /** gamepad */ + AINPUT_SOURCE_GAMEPAD = 0x00000400 | AINPUT_SOURCE_CLASS_BUTTON, + /** touchscreen */ + AINPUT_SOURCE_TOUCHSCREEN = 0x00001000 | AINPUT_SOURCE_CLASS_POINTER, + /** mouse */ + AINPUT_SOURCE_MOUSE = 0x00002000 | AINPUT_SOURCE_CLASS_POINTER, + /** stylus */ + AINPUT_SOURCE_STYLUS = 0x00004000 | AINPUT_SOURCE_CLASS_POINTER, + /** bluetooth stylus */ + AINPUT_SOURCE_BLUETOOTH_STYLUS = 0x00008000 | AINPUT_SOURCE_STYLUS, + /** trackball */ + AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION, + /** touchpad */ + AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION, + /** navigation */ + AINPUT_SOURCE_TOUCH_NAVIGATION = 0x00200000 | AINPUT_SOURCE_CLASS_NONE, + /** gesture sensor (?) */ + AINPUT_SOURCE_GESTURE_SENSOR = 0x00400000 | AINPUT_SOURCE_CLASS_NONE, + /** joystick */ + AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK, + + /** any */ + AINPUT_SOURCE_ANY = 0xffffff00, +}; + +/** + * Keyboard types. + * + * Refer to the documentation on android.view.InputDevice for more details. + */ +enum { + /** none */ + AINPUT_KEYBOARD_TYPE_NONE = 0, + /** non alphabetic */ + AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC = 1, + /** alphabetic */ + AINPUT_KEYBOARD_TYPE_ALPHABETIC = 2, +}; + +/** + * Constants used to retrieve information about the range of motion for a particular + * coordinate of a motion event. + * + * Refer to the documentation on android.view.InputDevice for more details about input sources + * and their correct interpretation. + * + * @deprecated These constants are deprecated. Use {@link AMOTION_EVENT_AXIS AMOTION_EVENT_AXIS_*} constants instead. + */ +enum { + /** x */ + AINPUT_MOTION_RANGE_X = AMOTION_EVENT_AXIS_X, + /** y */ + AINPUT_MOTION_RANGE_Y = AMOTION_EVENT_AXIS_Y, + /** pressure */ + AINPUT_MOTION_RANGE_PRESSURE = AMOTION_EVENT_AXIS_PRESSURE, + /** size */ + AINPUT_MOTION_RANGE_SIZE = AMOTION_EVENT_AXIS_SIZE, + /** touch major */ + AINPUT_MOTION_RANGE_TOUCH_MAJOR = AMOTION_EVENT_AXIS_TOUCH_MAJOR, + /** touch minor */ + AINPUT_MOTION_RANGE_TOUCH_MINOR = AMOTION_EVENT_AXIS_TOUCH_MINOR, + /** tool major */ + AINPUT_MOTION_RANGE_TOOL_MAJOR = AMOTION_EVENT_AXIS_TOOL_MAJOR, + /** tool minor */ + AINPUT_MOTION_RANGE_TOOL_MINOR = AMOTION_EVENT_AXIS_TOOL_MINOR, + /** orientation */ + AINPUT_MOTION_RANGE_ORIENTATION = AMOTION_EVENT_AXIS_ORIENTATION, +}; + + +/** + * Input event accessors. + * + * Note that most functions can only be used on input events that are of a given type. + * Calling these functions on input events of other types will yield undefined behavior. + */ + +/*** Accessors for all input events. ***/ + +/** Get the input event type. */ +int32_t AInputEvent_getType(const AInputEvent* event); + +/** Get the id for the device that an input event came from. + * + * Input events can be generated by multiple different input devices. + * Use the input device id to obtain information about the input + * device that was responsible for generating a particular event. + * + * An input device id of 0 indicates that the event didn't come from a physical device; + * other numbers are arbitrary and you shouldn't depend on the values. + * Use the provided input device query API to obtain information about input devices. + */ +int32_t AInputEvent_getDeviceId(const AInputEvent* event); + +/** Get the input event source. */ +int32_t AInputEvent_getSource(const AInputEvent* event); + +/*** Accessors for key events only. ***/ + +/** Get the key event action. */ +int32_t AKeyEvent_getAction(const AInputEvent* key_event); + +/** Get the key event flags. */ +int32_t AKeyEvent_getFlags(const AInputEvent* key_event); + +/** + * Get the key code of the key event. + * This is the physical key that was pressed, not the Unicode character. + */ +int32_t AKeyEvent_getKeyCode(const AInputEvent* key_event); + +/** + * Get the hardware key id of this key event. + * These values are not reliable and vary from device to device. + */ +int32_t AKeyEvent_getScanCode(const AInputEvent* key_event); + +/** Get the meta key state. */ +int32_t AKeyEvent_getMetaState(const AInputEvent* key_event); + +/** + * Get the repeat count of the event. + * For both key up an key down events, this is the number of times the key has + * repeated with the first down starting at 0 and counting up from there. For + * multiple key events, this is the number of down/up pairs that have occurred. + */ +int32_t AKeyEvent_getRepeatCount(const AInputEvent* key_event); + +/** + * Get the time of the most recent key down event, in the + * java.lang.System.nanoTime() time base. If this is a down event, + * this will be the same as eventTime. + * Note that when chording keys, this value is the down time of the most recently + * pressed key, which may not be the same physical key of this event. + */ +int64_t AKeyEvent_getDownTime(const AInputEvent* key_event); + +/** + * Get the time this event occurred, in the + * java.lang.System.nanoTime() time base. + */ +int64_t AKeyEvent_getEventTime(const AInputEvent* key_event); + +/*** Accessors for motion events only. ***/ + +/** Get the combined motion event action code and pointer index. */ +int32_t AMotionEvent_getAction(const AInputEvent* motion_event); + +/** Get the motion event flags. */ +int32_t AMotionEvent_getFlags(const AInputEvent* motion_event); + +/** + * Get the state of any meta / modifier keys that were in effect when the + * event was generated. + */ +int32_t AMotionEvent_getMetaState(const AInputEvent* motion_event); + +/** Get the button state of all buttons that are pressed. */ +int32_t AMotionEvent_getButtonState(const AInputEvent* motion_event); + +/** + * Get a bitfield indicating which edges, if any, were touched by this motion event. + * For touch events, clients can use this to determine if the user's finger was + * touching the edge of the display. + */ +int32_t AMotionEvent_getEdgeFlags(const AInputEvent* motion_event); + +/** + * Get the time when the user originally pressed down to start a stream of + * position events, in the java.lang.System.nanoTime() time base. + */ +int64_t AMotionEvent_getDownTime(const AInputEvent* motion_event); + +/** + * Get the time when this specific event was generated, + * in the java.lang.System.nanoTime() time base. + */ +int64_t AMotionEvent_getEventTime(const AInputEvent* motion_event); + +/** + * Get the X coordinate offset. + * For touch events on the screen, this is the delta that was added to the raw + * screen coordinates to adjust for the absolute position of the containing windows + * and views. + */ +float AMotionEvent_getXOffset(const AInputEvent* motion_event); + +/** + * Get the Y coordinate offset. + * For touch events on the screen, this is the delta that was added to the raw + * screen coordinates to adjust for the absolute position of the containing windows + * and views. + */ +float AMotionEvent_getYOffset(const AInputEvent* motion_event); + +/** + * Get the precision of the X coordinates being reported. + * You can multiply this number with an X coordinate sample to find the + * actual hardware value of the X coordinate. + */ +float AMotionEvent_getXPrecision(const AInputEvent* motion_event); + +/** + * Get the precision of the Y coordinates being reported. + * You can multiply this number with a Y coordinate sample to find the + * actual hardware value of the Y coordinate. + */ +float AMotionEvent_getYPrecision(const AInputEvent* motion_event); + +/** + * Get the number of pointers of data contained in this event. + * Always >= 1. + */ +size_t AMotionEvent_getPointerCount(const AInputEvent* motion_event); + +/** + * Get the pointer identifier associated with a particular pointer + * data index in this event. The identifier tells you the actual pointer + * number associated with the data, accounting for individual pointers + * going up and down since the start of the current gesture. + */ +int32_t AMotionEvent_getPointerId(const AInputEvent* motion_event, size_t pointer_index); + +/** + * Get the tool type of a pointer for the given pointer index. + * The tool type indicates the type of tool used to make contact such as a + * finger or stylus, if known. + */ +int32_t AMotionEvent_getToolType(const AInputEvent* motion_event, size_t pointer_index); + +/** + * Get the original raw X coordinate of this event. + * For touch events on the screen, this is the original location of the event + * on the screen, before it had been adjusted for the containing window + * and views. + */ +float AMotionEvent_getRawX(const AInputEvent* motion_event, size_t pointer_index); + +/** + * Get the original raw X coordinate of this event. + * For touch events on the screen, this is the original location of the event + * on the screen, before it had been adjusted for the containing window + * and views. + */ +float AMotionEvent_getRawY(const AInputEvent* motion_event, size_t pointer_index); + +/** + * Get the current X coordinate of this event for the given pointer index. + * Whole numbers are pixels; the value may have a fraction for input devices + * that are sub-pixel precise. + */ +float AMotionEvent_getX(const AInputEvent* motion_event, size_t pointer_index); + +/** + * Get the current Y coordinate of this event for the given pointer index. + * Whole numbers are pixels; the value may have a fraction for input devices + * that are sub-pixel precise. + */ +float AMotionEvent_getY(const AInputEvent* motion_event, size_t pointer_index); + +/** + * Get the current pressure of this event for the given pointer index. + * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure), + * although values higher than 1 may be generated depending on the calibration of + * the input device. + */ +float AMotionEvent_getPressure(const AInputEvent* motion_event, size_t pointer_index); + +/** + * Get the current scaled value of the approximate size for the given pointer index. + * This represents some approximation of the area of the screen being + * pressed; the actual value in pixels corresponding to the + * touch is normalized with the device specific range of values + * and scaled to a value between 0 and 1. The value of size can be used to + * determine fat touch events. + */ +float AMotionEvent_getSize(const AInputEvent* motion_event, size_t pointer_index); + +/** + * Get the current length of the major axis of an ellipse that describes the touch area + * at the point of contact for the given pointer index. + */ +float AMotionEvent_getTouchMajor(const AInputEvent* motion_event, size_t pointer_index); + +/** + * Get the current length of the minor axis of an ellipse that describes the touch area + * at the point of contact for the given pointer index. + */ +float AMotionEvent_getTouchMinor(const AInputEvent* motion_event, size_t pointer_index); + +/** + * Get the current length of the major axis of an ellipse that describes the size + * of the approaching tool for the given pointer index. + * The tool area represents the estimated size of the finger or pen that is + * touching the device independent of its actual touch area at the point of contact. + */ +float AMotionEvent_getToolMajor(const AInputEvent* motion_event, size_t pointer_index); + +/** + * Get the current length of the minor axis of an ellipse that describes the size + * of the approaching tool for the given pointer index. + * The tool area represents the estimated size of the finger or pen that is + * touching the device independent of its actual touch area at the point of contact. + */ +float AMotionEvent_getToolMinor(const AInputEvent* motion_event, size_t pointer_index); + +/** + * Get the current orientation of the touch area and tool area in radians clockwise from + * vertical for the given pointer index. + * An angle of 0 degrees indicates that the major axis of contact is oriented + * upwards, is perfectly circular or is of unknown orientation. A positive angle + * indicates that the major axis of contact is oriented to the right. A negative angle + * indicates that the major axis of contact is oriented to the left. + * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians + * (finger pointing fully right). + */ +float AMotionEvent_getOrientation(const AInputEvent* motion_event, size_t pointer_index); + +/** Get the value of the request axis for the given pointer index. */ +float AMotionEvent_getAxisValue(const AInputEvent* motion_event, + int32_t axis, size_t pointer_index); + +/** + * Get the number of historical points in this event. These are movements that + * have occurred between this event and the previous event. This only applies + * to AMOTION_EVENT_ACTION_MOVE events -- all other actions will have a size of 0. + * Historical samples are indexed from oldest to newest. + */ +size_t AMotionEvent_getHistorySize(const AInputEvent* motion_event); + +/** + * Get the time that a historical movement occurred between this event and + * the previous event, in the java.lang.System.nanoTime() time base. + */ +int64_t AMotionEvent_getHistoricalEventTime(const AInputEvent* motion_event, + size_t history_index); + +/** + * Get the historical raw X coordinate of this event for the given pointer index that + * occurred between this event and the previous motion event. + * For touch events on the screen, this is the original location of the event + * on the screen, before it had been adjusted for the containing window + * and views. + * Whole numbers are pixels; the value may have a fraction for input devices + * that are sub-pixel precise. + */ +float AMotionEvent_getHistoricalRawX(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + +/** + * Get the historical raw Y coordinate of this event for the given pointer index that + * occurred between this event and the previous motion event. + * For touch events on the screen, this is the original location of the event + * on the screen, before it had been adjusted for the containing window + * and views. + * Whole numbers are pixels; the value may have a fraction for input devices + * that are sub-pixel precise. + */ +float AMotionEvent_getHistoricalRawY(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + +/** + * Get the historical X coordinate of this event for the given pointer index that + * occurred between this event and the previous motion event. + * Whole numbers are pixels; the value may have a fraction for input devices + * that are sub-pixel precise. + */ +float AMotionEvent_getHistoricalX(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + +/** + * Get the historical Y coordinate of this event for the given pointer index that + * occurred between this event and the previous motion event. + * Whole numbers are pixels; the value may have a fraction for input devices + * that are sub-pixel precise. + */ +float AMotionEvent_getHistoricalY(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + +/** + * Get the historical pressure of this event for the given pointer index that + * occurred between this event and the previous motion event. + * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure), + * although values higher than 1 may be generated depending on the calibration of + * the input device. + */ +float AMotionEvent_getHistoricalPressure(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + +/** + * Get the current scaled value of the approximate size for the given pointer index that + * occurred between this event and the previous motion event. + * This represents some approximation of the area of the screen being + * pressed; the actual value in pixels corresponding to the + * touch is normalized with the device specific range of values + * and scaled to a value between 0 and 1. The value of size can be used to + * determine fat touch events. + */ +float AMotionEvent_getHistoricalSize(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + +/** + * Get the historical length of the major axis of an ellipse that describes the touch area + * at the point of contact for the given pointer index that + * occurred between this event and the previous motion event. + */ +float AMotionEvent_getHistoricalTouchMajor(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + +/** + * Get the historical length of the minor axis of an ellipse that describes the touch area + * at the point of contact for the given pointer index that + * occurred between this event and the previous motion event. + */ +float AMotionEvent_getHistoricalTouchMinor(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + +/** + * Get the historical length of the major axis of an ellipse that describes the size + * of the approaching tool for the given pointer index that + * occurred between this event and the previous motion event. + * The tool area represents the estimated size of the finger or pen that is + * touching the device independent of its actual touch area at the point of contact. + */ +float AMotionEvent_getHistoricalToolMajor(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + +/** + * Get the historical length of the minor axis of an ellipse that describes the size + * of the approaching tool for the given pointer index that + * occurred between this event and the previous motion event. + * The tool area represents the estimated size of the finger or pen that is + * touching the device independent of its actual touch area at the point of contact. + */ +float AMotionEvent_getHistoricalToolMinor(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + +/** + * Get the historical orientation of the touch area and tool area in radians clockwise from + * vertical for the given pointer index that + * occurred between this event and the previous motion event. + * An angle of 0 degrees indicates that the major axis of contact is oriented + * upwards, is perfectly circular or is of unknown orientation. A positive angle + * indicates that the major axis of contact is oriented to the right. A negative angle + * indicates that the major axis of contact is oriented to the left. + * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians + * (finger pointing fully right). + */ +float AMotionEvent_getHistoricalOrientation(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + +/** + * Get the historical value of the request axis for the given pointer index + * that occurred between this event and the previous motion event. + */ +float AMotionEvent_getHistoricalAxisValue(const AInputEvent* motion_event, + int32_t axis, size_t pointer_index, size_t history_index); + + +struct AInputQueue; +/** + * Input queue + * + * An input queue is the facility through which you retrieve input + * events. + */ +typedef struct AInputQueue AInputQueue; + +/** + * Add this input queue to a looper for processing. See + * ALooper_addFd() for information on the ident, callback, and data params. + */ +void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper, + int ident, ALooper_callbackFunc callback, void* data); + +/** + * Remove the input queue from the looper it is currently attached to. + */ +void AInputQueue_detachLooper(AInputQueue* queue); + +/** + * Returns true if there are one or more events available in the + * input queue. Returns 1 if the queue has events; 0 if + * it does not have events; and a negative value if there is an error. + */ +int32_t AInputQueue_hasEvents(AInputQueue* queue); + +/** + * Returns the next available event from the queue. Returns a negative + * value if no events are available or an error has occurred. + */ +int32_t AInputQueue_getEvent(AInputQueue* queue, AInputEvent** outEvent); + +/** + * Sends the key for standard pre-dispatching -- that is, possibly deliver + * it to the current IME to be consumed before the app. Returns 0 if it + * was not pre-dispatched, meaning you can process it right now. If non-zero + * is returned, you must abandon the current event processing and allow the + * event to appear again in the event queue (if it does not get consumed during + * pre-dispatching). + */ +int32_t AInputQueue_preDispatchEvent(AInputQueue* queue, AInputEvent* event); + +/** + * Report that dispatching has finished with the given event. + * This must be called after receiving an event with AInputQueue_get_event(). + */ +void AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled); + +#ifdef __cplusplus +} +#endif + +#endif // _ANDROID_INPUT_H + +/** @} */ diff --git a/phonelibs/android_frameworks_native/include/android/keycodes.h b/phonelibs/android_frameworks_native/include/android/keycodes.h new file mode 100644 index 00000000000000..421abe54777d9d --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/keycodes.h @@ -0,0 +1,752 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup Input + * @{ + */ + +/** + * @file keycodes.h + */ + +#ifndef _ANDROID_KEYCODES_H +#define _ANDROID_KEYCODES_H + +/****************************************************************** + * + * IMPORTANT NOTICE: + * + * This file is part of Android's set of stable system headers + * exposed by the Android NDK (Native Development Kit). + * + * Third-party source AND binary code relies on the definitions + * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES. + * + * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES) + * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS + * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY + * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Key codes. + */ +enum { + /** Unknown key code. */ + AKEYCODE_UNKNOWN = 0, + /** Soft Left key. + * Usually situated below the display on phones and used as a multi-function + * feature key for selecting a software defined function shown on the bottom left + * of the display. */ + AKEYCODE_SOFT_LEFT = 1, + /** Soft Right key. + * Usually situated below the display on phones and used as a multi-function + * feature key for selecting a software defined function shown on the bottom right + * of the display. */ + AKEYCODE_SOFT_RIGHT = 2, + /** Home key. + * This key is handled by the framework and is never delivered to applications. */ + AKEYCODE_HOME = 3, + /** Back key. */ + AKEYCODE_BACK = 4, + /** Call key. */ + AKEYCODE_CALL = 5, + /** End Call key. */ + AKEYCODE_ENDCALL = 6, + /** '0' key. */ + AKEYCODE_0 = 7, + /** '1' key. */ + AKEYCODE_1 = 8, + /** '2' key. */ + AKEYCODE_2 = 9, + /** '3' key. */ + AKEYCODE_3 = 10, + /** '4' key. */ + AKEYCODE_4 = 11, + /** '5' key. */ + AKEYCODE_5 = 12, + /** '6' key. */ + AKEYCODE_6 = 13, + /** '7' key. */ + AKEYCODE_7 = 14, + /** '8' key. */ + AKEYCODE_8 = 15, + /** '9' key. */ + AKEYCODE_9 = 16, + /** '*' key. */ + AKEYCODE_STAR = 17, + /** '#' key. */ + AKEYCODE_POUND = 18, + /** Directional Pad Up key. + * May also be synthesized from trackball motions. */ + AKEYCODE_DPAD_UP = 19, + /** Directional Pad Down key. + * May also be synthesized from trackball motions. */ + AKEYCODE_DPAD_DOWN = 20, + /** Directional Pad Left key. + * May also be synthesized from trackball motions. */ + AKEYCODE_DPAD_LEFT = 21, + /** Directional Pad Right key. + * May also be synthesized from trackball motions. */ + AKEYCODE_DPAD_RIGHT = 22, + /** Directional Pad Center key. + * May also be synthesized from trackball motions. */ + AKEYCODE_DPAD_CENTER = 23, + /** Volume Up key. + * Adjusts the speaker volume up. */ + AKEYCODE_VOLUME_UP = 24, + /** Volume Down key. + * Adjusts the speaker volume down. */ + AKEYCODE_VOLUME_DOWN = 25, + /** Power key. */ + AKEYCODE_POWER = 26, + /** Camera key. + * Used to launch a camera application or take pictures. */ + AKEYCODE_CAMERA = 27, + /** Clear key. */ + AKEYCODE_CLEAR = 28, + /** 'A' key. */ + AKEYCODE_A = 29, + /** 'B' key. */ + AKEYCODE_B = 30, + /** 'C' key. */ + AKEYCODE_C = 31, + /** 'D' key. */ + AKEYCODE_D = 32, + /** 'E' key. */ + AKEYCODE_E = 33, + /** 'F' key. */ + AKEYCODE_F = 34, + /** 'G' key. */ + AKEYCODE_G = 35, + /** 'H' key. */ + AKEYCODE_H = 36, + /** 'I' key. */ + AKEYCODE_I = 37, + /** 'J' key. */ + AKEYCODE_J = 38, + /** 'K' key. */ + AKEYCODE_K = 39, + /** 'L' key. */ + AKEYCODE_L = 40, + /** 'M' key. */ + AKEYCODE_M = 41, + /** 'N' key. */ + AKEYCODE_N = 42, + /** 'O' key. */ + AKEYCODE_O = 43, + /** 'P' key. */ + AKEYCODE_P = 44, + /** 'Q' key. */ + AKEYCODE_Q = 45, + /** 'R' key. */ + AKEYCODE_R = 46, + /** 'S' key. */ + AKEYCODE_S = 47, + /** 'T' key. */ + AKEYCODE_T = 48, + /** 'U' key. */ + AKEYCODE_U = 49, + /** 'V' key. */ + AKEYCODE_V = 50, + /** 'W' key. */ + AKEYCODE_W = 51, + /** 'X' key. */ + AKEYCODE_X = 52, + /** 'Y' key. */ + AKEYCODE_Y = 53, + /** 'Z' key. */ + AKEYCODE_Z = 54, + /** ',' key. */ + AKEYCODE_COMMA = 55, + /** '.' key. */ + AKEYCODE_PERIOD = 56, + /** Left Alt modifier key. */ + AKEYCODE_ALT_LEFT = 57, + /** Right Alt modifier key. */ + AKEYCODE_ALT_RIGHT = 58, + /** Left Shift modifier key. */ + AKEYCODE_SHIFT_LEFT = 59, + /** Right Shift modifier key. */ + AKEYCODE_SHIFT_RIGHT = 60, + /** Tab key. */ + AKEYCODE_TAB = 61, + /** Space key. */ + AKEYCODE_SPACE = 62, + /** Symbol modifier key. + * Used to enter alternate symbols. */ + AKEYCODE_SYM = 63, + /** Explorer special function key. + * Used to launch a browser application. */ + AKEYCODE_EXPLORER = 64, + /** Envelope special function key. + * Used to launch a mail application. */ + AKEYCODE_ENVELOPE = 65, + /** Enter key. */ + AKEYCODE_ENTER = 66, + /** Backspace key. + * Deletes characters before the insertion point, unlike {@link AKEYCODE_FORWARD_DEL}. */ + AKEYCODE_DEL = 67, + /** '`' (backtick) key. */ + AKEYCODE_GRAVE = 68, + /** '-'. */ + AKEYCODE_MINUS = 69, + /** '=' key. */ + AKEYCODE_EQUALS = 70, + /** '[' key. */ + AKEYCODE_LEFT_BRACKET = 71, + /** ']' key. */ + AKEYCODE_RIGHT_BRACKET = 72, + /** '\' key. */ + AKEYCODE_BACKSLASH = 73, + /** ';' key. */ + AKEYCODE_SEMICOLON = 74, + /** ''' (apostrophe) key. */ + AKEYCODE_APOSTROPHE = 75, + /** '/' key. */ + AKEYCODE_SLASH = 76, + /** '@' key. */ + AKEYCODE_AT = 77, + /** Number modifier key. + * Used to enter numeric symbols. + * This key is not {@link AKEYCODE_NUM_LOCK}; it is more like {@link AKEYCODE_ALT_LEFT}. */ + AKEYCODE_NUM = 78, + /** Headset Hook key. + * Used to hang up calls and stop media. */ + AKEYCODE_HEADSETHOOK = 79, + /** Camera Focus key. + * Used to focus the camera. */ + AKEYCODE_FOCUS = 80, + /** '+' key. */ + AKEYCODE_PLUS = 81, + /** Menu key. */ + AKEYCODE_MENU = 82, + /** Notification key. */ + AKEYCODE_NOTIFICATION = 83, + /** Search key. */ + AKEYCODE_SEARCH = 84, + /** Play/Pause media key. */ + AKEYCODE_MEDIA_PLAY_PAUSE= 85, + /** Stop media key. */ + AKEYCODE_MEDIA_STOP = 86, + /** Play Next media key. */ + AKEYCODE_MEDIA_NEXT = 87, + /** Play Previous media key. */ + AKEYCODE_MEDIA_PREVIOUS = 88, + /** Rewind media key. */ + AKEYCODE_MEDIA_REWIND = 89, + /** Fast Forward media key. */ + AKEYCODE_MEDIA_FAST_FORWARD = 90, + /** Mute key. + * Mutes the microphone, unlike {@link AKEYCODE_VOLUME_MUTE}. */ + AKEYCODE_MUTE = 91, + /** Page Up key. */ + AKEYCODE_PAGE_UP = 92, + /** Page Down key. */ + AKEYCODE_PAGE_DOWN = 93, + /** Picture Symbols modifier key. + * Used to switch symbol sets (Emoji, Kao-moji). */ + AKEYCODE_PICTSYMBOLS = 94, + /** Switch Charset modifier key. + * Used to switch character sets (Kanji, Katakana). */ + AKEYCODE_SWITCH_CHARSET = 95, + /** A Button key. + * On a game controller, the A button should be either the button labeled A + * or the first button on the bottom row of controller buttons. */ + AKEYCODE_BUTTON_A = 96, + /** B Button key. + * On a game controller, the B button should be either the button labeled B + * or the second button on the bottom row of controller buttons. */ + AKEYCODE_BUTTON_B = 97, + /** C Button key. + * On a game controller, the C button should be either the button labeled C + * or the third button on the bottom row of controller buttons. */ + AKEYCODE_BUTTON_C = 98, + /** X Button key. + * On a game controller, the X button should be either the button labeled X + * or the first button on the upper row of controller buttons. */ + AKEYCODE_BUTTON_X = 99, + /** Y Button key. + * On a game controller, the Y button should be either the button labeled Y + * or the second button on the upper row of controller buttons. */ + AKEYCODE_BUTTON_Y = 100, + /** Z Button key. + * On a game controller, the Z button should be either the button labeled Z + * or the third button on the upper row of controller buttons. */ + AKEYCODE_BUTTON_Z = 101, + /** L1 Button key. + * On a game controller, the L1 button should be either the button labeled L1 (or L) + * or the top left trigger button. */ + AKEYCODE_BUTTON_L1 = 102, + /** R1 Button key. + * On a game controller, the R1 button should be either the button labeled R1 (or R) + * or the top right trigger button. */ + AKEYCODE_BUTTON_R1 = 103, + /** L2 Button key. + * On a game controller, the L2 button should be either the button labeled L2 + * or the bottom left trigger button. */ + AKEYCODE_BUTTON_L2 = 104, + /** R2 Button key. + * On a game controller, the R2 button should be either the button labeled R2 + * or the bottom right trigger button. */ + AKEYCODE_BUTTON_R2 = 105, + /** Left Thumb Button key. + * On a game controller, the left thumb button indicates that the left (or only) + * joystick is pressed. */ + AKEYCODE_BUTTON_THUMBL = 106, + /** Right Thumb Button key. + * On a game controller, the right thumb button indicates that the right + * joystick is pressed. */ + AKEYCODE_BUTTON_THUMBR = 107, + /** Start Button key. + * On a game controller, the button labeled Start. */ + AKEYCODE_BUTTON_START = 108, + /** Select Button key. + * On a game controller, the button labeled Select. */ + AKEYCODE_BUTTON_SELECT = 109, + /** Mode Button key. + * On a game controller, the button labeled Mode. */ + AKEYCODE_BUTTON_MODE = 110, + /** Escape key. */ + AKEYCODE_ESCAPE = 111, + /** Forward Delete key. + * Deletes characters ahead of the insertion point, unlike {@link AKEYCODE_DEL}. */ + AKEYCODE_FORWARD_DEL = 112, + /** Left Control modifier key. */ + AKEYCODE_CTRL_LEFT = 113, + /** Right Control modifier key. */ + AKEYCODE_CTRL_RIGHT = 114, + /** Caps Lock key. */ + AKEYCODE_CAPS_LOCK = 115, + /** Scroll Lock key. */ + AKEYCODE_SCROLL_LOCK = 116, + /** Left Meta modifier key. */ + AKEYCODE_META_LEFT = 117, + /** Right Meta modifier key. */ + AKEYCODE_META_RIGHT = 118, + /** Function modifier key. */ + AKEYCODE_FUNCTION = 119, + /** System Request / Print Screen key. */ + AKEYCODE_SYSRQ = 120, + /** Break / Pause key. */ + AKEYCODE_BREAK = 121, + /** Home Movement key. + * Used for scrolling or moving the cursor around to the start of a line + * or to the top of a list. */ + AKEYCODE_MOVE_HOME = 122, + /** End Movement key. + * Used for scrolling or moving the cursor around to the end of a line + * or to the bottom of a list. */ + AKEYCODE_MOVE_END = 123, + /** Insert key. + * Toggles insert / overwrite edit mode. */ + AKEYCODE_INSERT = 124, + /** Forward key. + * Navigates forward in the history stack. Complement of {@link AKEYCODE_BACK}. */ + AKEYCODE_FORWARD = 125, + /** Play media key. */ + AKEYCODE_MEDIA_PLAY = 126, + /** Pause media key. */ + AKEYCODE_MEDIA_PAUSE = 127, + /** Close media key. + * May be used to close a CD tray, for example. */ + AKEYCODE_MEDIA_CLOSE = 128, + /** Eject media key. + * May be used to eject a CD tray, for example. */ + AKEYCODE_MEDIA_EJECT = 129, + /** Record media key. */ + AKEYCODE_MEDIA_RECORD = 130, + /** F1 key. */ + AKEYCODE_F1 = 131, + /** F2 key. */ + AKEYCODE_F2 = 132, + /** F3 key. */ + AKEYCODE_F3 = 133, + /** F4 key. */ + AKEYCODE_F4 = 134, + /** F5 key. */ + AKEYCODE_F5 = 135, + /** F6 key. */ + AKEYCODE_F6 = 136, + /** F7 key. */ + AKEYCODE_F7 = 137, + /** F8 key. */ + AKEYCODE_F8 = 138, + /** F9 key. */ + AKEYCODE_F9 = 139, + /** F10 key. */ + AKEYCODE_F10 = 140, + /** F11 key. */ + AKEYCODE_F11 = 141, + /** F12 key. */ + AKEYCODE_F12 = 142, + /** Num Lock key. + * This is the Num Lock key; it is different from {@link AKEYCODE_NUM}. + * This key alters the behavior of other keys on the numeric keypad. */ + AKEYCODE_NUM_LOCK = 143, + /** Numeric keypad '0' key. */ + AKEYCODE_NUMPAD_0 = 144, + /** Numeric keypad '1' key. */ + AKEYCODE_NUMPAD_1 = 145, + /** Numeric keypad '2' key. */ + AKEYCODE_NUMPAD_2 = 146, + /** Numeric keypad '3' key. */ + AKEYCODE_NUMPAD_3 = 147, + /** Numeric keypad '4' key. */ + AKEYCODE_NUMPAD_4 = 148, + /** Numeric keypad '5' key. */ + AKEYCODE_NUMPAD_5 = 149, + /** Numeric keypad '6' key. */ + AKEYCODE_NUMPAD_6 = 150, + /** Numeric keypad '7' key. */ + AKEYCODE_NUMPAD_7 = 151, + /** Numeric keypad '8' key. */ + AKEYCODE_NUMPAD_8 = 152, + /** Numeric keypad '9' key. */ + AKEYCODE_NUMPAD_9 = 153, + /** Numeric keypad '/' key (for division). */ + AKEYCODE_NUMPAD_DIVIDE = 154, + /** Numeric keypad '*' key (for multiplication). */ + AKEYCODE_NUMPAD_MULTIPLY = 155, + /** Numeric keypad '-' key (for subtraction). */ + AKEYCODE_NUMPAD_SUBTRACT = 156, + /** Numeric keypad '+' key (for addition). */ + AKEYCODE_NUMPAD_ADD = 157, + /** Numeric keypad '.' key (for decimals or digit grouping). */ + AKEYCODE_NUMPAD_DOT = 158, + /** Numeric keypad ',' key (for decimals or digit grouping). */ + AKEYCODE_NUMPAD_COMMA = 159, + /** Numeric keypad Enter key. */ + AKEYCODE_NUMPAD_ENTER = 160, + /** Numeric keypad '=' key. */ + AKEYCODE_NUMPAD_EQUALS = 161, + /** Numeric keypad '(' key. */ + AKEYCODE_NUMPAD_LEFT_PAREN = 162, + /** Numeric keypad ')' key. */ + AKEYCODE_NUMPAD_RIGHT_PAREN = 163, + /** Volume Mute key. + * Mutes the speaker, unlike {@link AKEYCODE_MUTE}. + * This key should normally be implemented as a toggle such that the first press + * mutes the speaker and the second press restores the original volume. */ + AKEYCODE_VOLUME_MUTE = 164, + /** Info key. + * Common on TV remotes to show additional information related to what is + * currently being viewed. */ + AKEYCODE_INFO = 165, + /** Channel up key. + * On TV remotes, increments the television channel. */ + AKEYCODE_CHANNEL_UP = 166, + /** Channel down key. + * On TV remotes, decrements the television channel. */ + AKEYCODE_CHANNEL_DOWN = 167, + /** Zoom in key. */ + AKEYCODE_ZOOM_IN = 168, + /** Zoom out key. */ + AKEYCODE_ZOOM_OUT = 169, + /** TV key. + * On TV remotes, switches to viewing live TV. */ + AKEYCODE_TV = 170, + /** Window key. + * On TV remotes, toggles picture-in-picture mode or other windowing functions. */ + AKEYCODE_WINDOW = 171, + /** Guide key. + * On TV remotes, shows a programming guide. */ + AKEYCODE_GUIDE = 172, + /** DVR key. + * On some TV remotes, switches to a DVR mode for recorded shows. */ + AKEYCODE_DVR = 173, + /** Bookmark key. + * On some TV remotes, bookmarks content or web pages. */ + AKEYCODE_BOOKMARK = 174, + /** Toggle captions key. + * Switches the mode for closed-captioning text, for example during television shows. */ + AKEYCODE_CAPTIONS = 175, + /** Settings key. + * Starts the system settings activity. */ + AKEYCODE_SETTINGS = 176, + /** TV power key. + * On TV remotes, toggles the power on a television screen. */ + AKEYCODE_TV_POWER = 177, + /** TV input key. + * On TV remotes, switches the input on a television screen. */ + AKEYCODE_TV_INPUT = 178, + /** Set-top-box power key. + * On TV remotes, toggles the power on an external Set-top-box. */ + AKEYCODE_STB_POWER = 179, + /** Set-top-box input key. + * On TV remotes, switches the input mode on an external Set-top-box. */ + AKEYCODE_STB_INPUT = 180, + /** A/V Receiver power key. + * On TV remotes, toggles the power on an external A/V Receiver. */ + AKEYCODE_AVR_POWER = 181, + /** A/V Receiver input key. + * On TV remotes, switches the input mode on an external A/V Receiver. */ + AKEYCODE_AVR_INPUT = 182, + /** Red "programmable" key. + * On TV remotes, acts as a contextual/programmable key. */ + AKEYCODE_PROG_RED = 183, + /** Green "programmable" key. + * On TV remotes, actsas a contextual/programmable key. */ + AKEYCODE_PROG_GREEN = 184, + /** Yellow "programmable" key. + * On TV remotes, acts as a contextual/programmable key. */ + AKEYCODE_PROG_YELLOW = 185, + /** Blue "programmable" key. + * On TV remotes, acts as a contextual/programmable key. */ + AKEYCODE_PROG_BLUE = 186, + /** App switch key. + * Should bring up the application switcher dialog. */ + AKEYCODE_APP_SWITCH = 187, + /** Generic Game Pad Button #1.*/ + AKEYCODE_BUTTON_1 = 188, + /** Generic Game Pad Button #2.*/ + AKEYCODE_BUTTON_2 = 189, + /** Generic Game Pad Button #3.*/ + AKEYCODE_BUTTON_3 = 190, + /** Generic Game Pad Button #4.*/ + AKEYCODE_BUTTON_4 = 191, + /** Generic Game Pad Button #5.*/ + AKEYCODE_BUTTON_5 = 192, + /** Generic Game Pad Button #6.*/ + AKEYCODE_BUTTON_6 = 193, + /** Generic Game Pad Button #7.*/ + AKEYCODE_BUTTON_7 = 194, + /** Generic Game Pad Button #8.*/ + AKEYCODE_BUTTON_8 = 195, + /** Generic Game Pad Button #9.*/ + AKEYCODE_BUTTON_9 = 196, + /** Generic Game Pad Button #10.*/ + AKEYCODE_BUTTON_10 = 197, + /** Generic Game Pad Button #11.*/ + AKEYCODE_BUTTON_11 = 198, + /** Generic Game Pad Button #12.*/ + AKEYCODE_BUTTON_12 = 199, + /** Generic Game Pad Button #13.*/ + AKEYCODE_BUTTON_13 = 200, + /** Generic Game Pad Button #14.*/ + AKEYCODE_BUTTON_14 = 201, + /** Generic Game Pad Button #15.*/ + AKEYCODE_BUTTON_15 = 202, + /** Generic Game Pad Button #16.*/ + AKEYCODE_BUTTON_16 = 203, + /** Language Switch key. + * Toggles the current input language such as switching between English and Japanese on + * a QWERTY keyboard. On some devices, the same function may be performed by + * pressing Shift+Spacebar. */ + AKEYCODE_LANGUAGE_SWITCH = 204, + /** Manner Mode key. + * Toggles silent or vibrate mode on and off to make the device behave more politely + * in certain settings such as on a crowded train. On some devices, the key may only + * operate when long-pressed. */ + AKEYCODE_MANNER_MODE = 205, + /** 3D Mode key. + * Toggles the display between 2D and 3D mode. */ + AKEYCODE_3D_MODE = 206, + /** Contacts special function key. + * Used to launch an address book application. */ + AKEYCODE_CONTACTS = 207, + /** Calendar special function key. + * Used to launch a calendar application. */ + AKEYCODE_CALENDAR = 208, + /** Music special function key. + * Used to launch a music player application. */ + AKEYCODE_MUSIC = 209, + /** Calculator special function key. + * Used to launch a calculator application. */ + AKEYCODE_CALCULATOR = 210, + /** Japanese full-width / half-width key. */ + AKEYCODE_ZENKAKU_HANKAKU = 211, + /** Japanese alphanumeric key. */ + AKEYCODE_EISU = 212, + /** Japanese non-conversion key. */ + AKEYCODE_MUHENKAN = 213, + /** Japanese conversion key. */ + AKEYCODE_HENKAN = 214, + /** Japanese katakana / hiragana key. */ + AKEYCODE_KATAKANA_HIRAGANA = 215, + /** Japanese Yen key. */ + AKEYCODE_YEN = 216, + /** Japanese Ro key. */ + AKEYCODE_RO = 217, + /** Japanese kana key. */ + AKEYCODE_KANA = 218, + /** Assist key. + * Launches the global assist activity. Not delivered to applications. */ + AKEYCODE_ASSIST = 219, + /** Brightness Down key. + * Adjusts the screen brightness down. */ + AKEYCODE_BRIGHTNESS_DOWN = 220, + /** Brightness Up key. + * Adjusts the screen brightness up. */ + AKEYCODE_BRIGHTNESS_UP = 221, + /** Audio Track key. + * Switches the audio tracks. */ + AKEYCODE_MEDIA_AUDIO_TRACK = 222, + /** Sleep key. + * Puts the device to sleep. Behaves somewhat like {@link AKEYCODE_POWER} but it + * has no effect if the device is already asleep. */ + AKEYCODE_SLEEP = 223, + /** Wakeup key. + * Wakes up the device. Behaves somewhat like {@link AKEYCODE_POWER} but it + * has no effect if the device is already awake. */ + AKEYCODE_WAKEUP = 224, + /** Pairing key. + * Initiates peripheral pairing mode. Useful for pairing remote control + * devices or game controllers, especially if no other input mode is + * available. */ + AKEYCODE_PAIRING = 225, + /** Media Top Menu key. + * Goes to the top of media menu. */ + AKEYCODE_MEDIA_TOP_MENU = 226, + /** '11' key. */ + AKEYCODE_11 = 227, + /** '12' key. */ + AKEYCODE_12 = 228, + /** Last Channel key. + * Goes to the last viewed channel. */ + AKEYCODE_LAST_CHANNEL = 229, + /** TV data service key. + * Displays data services like weather, sports. */ + AKEYCODE_TV_DATA_SERVICE = 230, + /** Voice Assist key. + * Launches the global voice assist activity. Not delivered to applications. */ + AKEYCODE_VOICE_ASSIST = 231, + /** Radio key. + * Toggles TV service / Radio service. */ + AKEYCODE_TV_RADIO_SERVICE = 232, + /** Teletext key. + * Displays Teletext service. */ + AKEYCODE_TV_TELETEXT = 233, + /** Number entry key. + * Initiates to enter multi-digit channel nubmber when each digit key is assigned + * for selecting separate channel. Corresponds to Number Entry Mode (0x1D) of CEC + * User Control Code. */ + AKEYCODE_TV_NUMBER_ENTRY = 234, + /** Analog Terrestrial key. + * Switches to analog terrestrial broadcast service. */ + AKEYCODE_TV_TERRESTRIAL_ANALOG = 235, + /** Digital Terrestrial key. + * Switches to digital terrestrial broadcast service. */ + AKEYCODE_TV_TERRESTRIAL_DIGITAL = 236, + /** Satellite key. + * Switches to digital satellite broadcast service. */ + AKEYCODE_TV_SATELLITE = 237, + /** BS key. + * Switches to BS digital satellite broadcasting service available in Japan. */ + AKEYCODE_TV_SATELLITE_BS = 238, + /** CS key. + * Switches to CS digital satellite broadcasting service available in Japan. */ + AKEYCODE_TV_SATELLITE_CS = 239, + /** BS/CS key. + * Toggles between BS and CS digital satellite services. */ + AKEYCODE_TV_SATELLITE_SERVICE = 240, + /** Toggle Network key. + * Toggles selecting broacast services. */ + AKEYCODE_TV_NETWORK = 241, + /** Antenna/Cable key. + * Toggles broadcast input source between antenna and cable. */ + AKEYCODE_TV_ANTENNA_CABLE = 242, + /** HDMI #1 key. + * Switches to HDMI input #1. */ + AKEYCODE_TV_INPUT_HDMI_1 = 243, + /** HDMI #2 key. + * Switches to HDMI input #2. */ + AKEYCODE_TV_INPUT_HDMI_2 = 244, + /** HDMI #3 key. + * Switches to HDMI input #3. */ + AKEYCODE_TV_INPUT_HDMI_3 = 245, + /** HDMI #4 key. + * Switches to HDMI input #4. */ + AKEYCODE_TV_INPUT_HDMI_4 = 246, + /** Composite #1 key. + * Switches to composite video input #1. */ + AKEYCODE_TV_INPUT_COMPOSITE_1 = 247, + /** Composite #2 key. + * Switches to composite video input #2. */ + AKEYCODE_TV_INPUT_COMPOSITE_2 = 248, + /** Component #1 key. + * Switches to component video input #1. */ + AKEYCODE_TV_INPUT_COMPONENT_1 = 249, + /** Component #2 key. + * Switches to component video input #2. */ + AKEYCODE_TV_INPUT_COMPONENT_2 = 250, + /** VGA #1 key. + * Switches to VGA (analog RGB) input #1. */ + AKEYCODE_TV_INPUT_VGA_1 = 251, + /** Audio description key. + * Toggles audio description off / on. */ + AKEYCODE_TV_AUDIO_DESCRIPTION = 252, + /** Audio description mixing volume up key. + * Louden audio description volume as compared with normal audio volume. */ + AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP = 253, + /** Audio description mixing volume down key. + * Lessen audio description volume as compared with normal audio volume. */ + AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN = 254, + /** Zoom mode key. + * Changes Zoom mode (Normal, Full, Zoom, Wide-zoom, etc.) */ + AKEYCODE_TV_ZOOM_MODE = 255, + /** Contents menu key. + * Goes to the title list. Corresponds to Contents Menu (0x0B) of CEC User Control + * Code */ + AKEYCODE_TV_CONTENTS_MENU = 256, + /** Media context menu key. + * Goes to the context menu of media contents. Corresponds to Media Context-sensitive + * Menu (0x11) of CEC User Control Code. */ + AKEYCODE_TV_MEDIA_CONTEXT_MENU = 257, + /** Timer programming key. + * Goes to the timer recording menu. Corresponds to Timer Programming (0x54) of + * CEC User Control Code. */ + AKEYCODE_TV_TIMER_PROGRAMMING = 258, + /** Help key. */ + AKEYCODE_HELP = 259, + AKEYCODE_NAVIGATE_PREVIOUS = 260, + AKEYCODE_NAVIGATE_NEXT = 261, + AKEYCODE_NAVIGATE_IN = 262, + AKEYCODE_NAVIGATE_OUT = 263, + /** Primary stem key for Wear + * Main power/reset button on watch. */ + AKEYCODE_STEM_PRIMARY = 264, + /** Generic stem key 1 for Wear */ + AKEYCODE_STEM_1 = 265, + /** Generic stem key 2 for Wear */ + AKEYCODE_STEM_2 = 266, + /** Generic stem key 3 for Wear */ + AKEYCODE_STEM_3 = 267, + AKEYCODE_MEDIA_SKIP_FORWARD = 272, + AKEYCODE_MEDIA_SKIP_BACKWARD = 273, + AKEYCODE_MEDIA_STEP_FORWARD = 274, + AKEYCODE_MEDIA_STEP_BACKWARD = 275, + /** Put device to sleep unless a wakelock is held. */ + AKEYCODE_SOFT_SLEEP = 276 + + // NOTE: If you add a new keycode here you must also add it to several other files. + // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list. +}; + +#ifdef __cplusplus +} +#endif + +#endif // _ANDROID_KEYCODES_H + +/** @} */ diff --git a/phonelibs/android_frameworks_native/include/android/looper.h b/phonelibs/android_frameworks_native/include/android/looper.h new file mode 100644 index 00000000000000..718f703048dcbd --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/looper.h @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup Looper + * @{ + */ + +/** + * @file looper.h + */ + +#ifndef ANDROID_LOOPER_H +#define ANDROID_LOOPER_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct ALooper; +/** + * ALooper + * + * A looper is the state tracking an event loop for a thread. + * Loopers do not define event structures or other such things; rather + * they are a lower-level facility to attach one or more discrete objects + * listening for an event. An "event" here is simply data available on + * a file descriptor: each attached object has an associated file descriptor, + * and waiting for "events" means (internally) polling on all of these file + * descriptors until one or more of them have data available. + * + * A thread can have only one ALooper associated with it. + */ +typedef struct ALooper ALooper; + +/** + * Returns the looper associated with the calling thread, or NULL if + * there is not one. + */ +ALooper* ALooper_forThread(); + +/** Option for for ALooper_prepare(). */ +enum { + /** + * This looper will accept calls to ALooper_addFd() that do not + * have a callback (that is provide NULL for the callback). In + * this case the caller of ALooper_pollOnce() or ALooper_pollAll() + * MUST check the return from these functions to discover when + * data is available on such fds and process it. + */ + ALOOPER_PREPARE_ALLOW_NON_CALLBACKS = 1<<0 +}; + +/** + * Prepares a looper associated with the calling thread, and returns it. + * If the thread already has a looper, it is returned. Otherwise, a new + * one is created, associated with the thread, and returned. + * + * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0. + */ +ALooper* ALooper_prepare(int opts); + +/** Result from ALooper_pollOnce() and ALooper_pollAll(). */ +enum { + /** + * The poll was awoken using wake() before the timeout expired + * and no callbacks were executed and no other file descriptors were ready. + */ + ALOOPER_POLL_WAKE = -1, + + /** + * Result from ALooper_pollOnce() and ALooper_pollAll(): + * One or more callbacks were executed. + */ + ALOOPER_POLL_CALLBACK = -2, + + /** + * Result from ALooper_pollOnce() and ALooper_pollAll(): + * The timeout expired. + */ + ALOOPER_POLL_TIMEOUT = -3, + + /** + * Result from ALooper_pollOnce() and ALooper_pollAll(): + * An error occurred. + */ + ALOOPER_POLL_ERROR = -4, +}; + +/** + * Acquire a reference on the given ALooper object. This prevents the object + * from being deleted until the reference is removed. This is only needed + * to safely hand an ALooper from one thread to another. + */ +void ALooper_acquire(ALooper* looper); + +/** + * Remove a reference that was previously acquired with ALooper_acquire(). + */ +void ALooper_release(ALooper* looper); + +/** + * Flags for file descriptor events that a looper can monitor. + * + * These flag bits can be combined to monitor multiple events at once. + */ +enum { + /** + * The file descriptor is available for read operations. + */ + ALOOPER_EVENT_INPUT = 1 << 0, + + /** + * The file descriptor is available for write operations. + */ + ALOOPER_EVENT_OUTPUT = 1 << 1, + + /** + * The file descriptor has encountered an error condition. + * + * The looper always sends notifications about errors; it is not necessary + * to specify this event flag in the requested event set. + */ + ALOOPER_EVENT_ERROR = 1 << 2, + + /** + * The file descriptor was hung up. + * For example, indicates that the remote end of a pipe or socket was closed. + * + * The looper always sends notifications about hangups; it is not necessary + * to specify this event flag in the requested event set. + */ + ALOOPER_EVENT_HANGUP = 1 << 3, + + /** + * The file descriptor is invalid. + * For example, the file descriptor was closed prematurely. + * + * The looper always sends notifications about invalid file descriptors; it is not necessary + * to specify this event flag in the requested event set. + */ + ALOOPER_EVENT_INVALID = 1 << 4, +}; + +/** + * For callback-based event loops, this is the prototype of the function + * that is called when a file descriptor event occurs. + * It is given the file descriptor it is associated with, + * a bitmask of the poll events that were triggered (typically ALOOPER_EVENT_INPUT), + * and the data pointer that was originally supplied. + * + * Implementations should return 1 to continue receiving callbacks, or 0 + * to have this file descriptor and callback unregistered from the looper. + */ +typedef int (*ALooper_callbackFunc)(int fd, int events, void* data); + +/** + * Waits for events to be available, with optional timeout in milliseconds. + * Invokes callbacks for all file descriptors on which an event occurred. + * + * If the timeout is zero, returns immediately without blocking. + * If the timeout is negative, waits indefinitely until an event appears. + * + * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before + * the timeout expired and no callbacks were invoked and no other file + * descriptors were ready. + * + * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked. + * + * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given + * timeout expired. + * + * Returns ALOOPER_POLL_ERROR if an error occurred. + * + * Returns a value >= 0 containing an identifier (the same identifier + * `ident` passed to ALooper_addFd()) if its file descriptor has data + * and it has no callback function (requiring the caller here to + * handle it). In this (and only this) case outFd, outEvents and + * outData will contain the poll events and data associated with the + * fd, otherwise they will be set to NULL. + * + * This method does not return until it has finished invoking the appropriate callbacks + * for all file descriptors that were signalled. + */ +int ALooper_pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData); + +/** + * Like ALooper_pollOnce(), but performs all pending callbacks until all + * data has been consumed or a file descriptor is available with no callback. + * This function will never return ALOOPER_POLL_CALLBACK. + */ +int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData); + +/** + * Wakes the poll asynchronously. + * + * This method can be called on any thread. + * This method returns immediately. + */ +void ALooper_wake(ALooper* looper); + +/** + * Adds a new file descriptor to be polled by the looper. + * If the same file descriptor was previously added, it is replaced. + * + * "fd" is the file descriptor to be added. + * "ident" is an identifier for this event, which is returned from ALooper_pollOnce(). + * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback. + * "events" are the poll events to wake up on. Typically this is ALOOPER_EVENT_INPUT. + * "callback" is the function to call when there is an event on the file descriptor. + * "data" is a private data pointer to supply to the callback. + * + * There are two main uses of this function: + * + * (1) If "callback" is non-NULL, then this function will be called when there is + * data on the file descriptor. It should execute any events it has pending, + * appropriately reading from the file descriptor. The 'ident' is ignored in this case. + * + * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce + * when its file descriptor has data available, requiring the caller to take + * care of processing it. + * + * Returns 1 if the file descriptor was added or -1 if an error occurred. + * + * This method can be called on any thread. + * This method may block briefly if it needs to wake the poll. + */ +int ALooper_addFd(ALooper* looper, int fd, int ident, int events, + ALooper_callbackFunc callback, void* data); + +/** + * Removes a previously added file descriptor from the looper. + * + * When this method returns, it is safe to close the file descriptor since the looper + * will no longer have a reference to it. However, it is possible for the callback to + * already be running or for it to run one last time if the file descriptor was already + * signalled. Calling code is responsible for ensuring that this case is safely handled. + * For example, if the callback takes care of removing itself during its own execution either + * by returning 0 or by calling this method, then it can be guaranteed to not be invoked + * again at any later time unless registered anew. + * + * Returns 1 if the file descriptor was removed, 0 if none was previously registered + * or -1 if an error occurred. + * + * This method can be called on any thread. + * This method may block briefly if it needs to wake the poll. + */ +int ALooper_removeFd(ALooper* looper, int fd); + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_LOOPER_H + +/** @} */ diff --git a/phonelibs/android_frameworks_native/include/android/multinetwork.h b/phonelibs/android_frameworks_native/include/android/multinetwork.h new file mode 100644 index 00000000000000..6c718c9037da6b --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/multinetwork.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_MULTINETWORK_H +#define ANDROID_MULTINETWORK_H + +#include +#include +#include + +__BEGIN_DECLS + +/** + * The corresponding C type for android.net.Network#getNetworkHandle() return + * values. The Java signed long value can be safely cast to a net_handle_t: + * + * [C] ((net_handle_t) java_long_network_handle) + * [C++] static_cast(java_long_network_handle) + * + * as appropriate. + */ +typedef uint64_t net_handle_t; + +/** + * The value NETWORK_UNSPECIFIED indicates no specific network. + * + * For some functions (documented below), a previous binding may be cleared + * by an invocation with NETWORK_UNSPECIFIED. + * + * Depending on the context it may indicate an error. It is expressly + * not used to indicate some notion of the "current default network". + */ +#define NETWORK_UNSPECIFIED ((net_handle_t)0) + + +/** + * All functions below that return an int return 0 on success or -1 + * on failure with an appropriate errno value set. + */ + + +/** + * Set the network to be used by the given socket file descriptor. + * + * To clear a previous socket binding invoke with NETWORK_UNSPECIFIED. + * + * This is the equivalent of: + * + * [ android.net.Network#bindSocket() ] + * https://developer.android.com/reference/android/net/Network.html#bindSocket(java.net.Socket) + */ +int android_setsocknetwork(net_handle_t network, int fd); + + +/** + * Binds the current process to |network|. All sockets created in the future + * (and not explicitly bound via android_setsocknetwork()) will be bound to + * |network|. All host name resolutions will be limited to |network| as well. + * Note that if the network identified by |network| ever disconnects, all + * sockets created in this way will cease to work and all host name + * resolutions will fail. This is by design so an application doesn't + * accidentally use sockets it thinks are still bound to a particular network. + * + * To clear a previous process binding invoke with NETWORK_UNSPECIFIED. + * + * This is the equivalent of: + * + * [ android.net.ConnectivityManager#setProcessDefaultNetwork() ] + * https://developer.android.com/reference/android/net/ConnectivityManager.html#setProcessDefaultNetwork(android.net.Network) + */ +int android_setprocnetwork(net_handle_t network); + + +/** + * Perform hostname resolution via the DNS servers associated with |network|. + * + * All arguments (apart from |network|) are used identically as those passed + * to getaddrinfo(3). Return and error values are identical to those of + * getaddrinfo(3), and in particular gai_strerror(3) can be used as expected. + * Similar to getaddrinfo(3): + * - |hints| may be NULL (in which case man page documented defaults apply) + * - either |node| or |service| may be NULL, but not both + * - |res| must not be NULL + * + * This is the equivalent of: + * + * [ android.net.Network#getAllByName() ] + * https://developer.android.com/reference/android/net/Network.html#getAllByName(java.lang.String) + */ +int android_getaddrinfofornetwork(net_handle_t network, + const char *node, const char *service, + const struct addrinfo *hints, struct addrinfo **res); + +__END_DECLS + +#endif // ANDROID_MULTINETWORK_H diff --git a/phonelibs/android_frameworks_native/include/android/native_activity.h b/phonelibs/android_frameworks_native/include/android/native_activity.h new file mode 100644 index 00000000000000..d3d99cf7a9b95e --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/native_activity.h @@ -0,0 +1,340 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup NativeActivity Native Activity + * @{ + */ + +/** + * @file native_activity.h + */ + +#ifndef ANDROID_NATIVE_ACTIVITY_H +#define ANDROID_NATIVE_ACTIVITY_H + +#include +#include + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * {@link ANativeActivityCallbacks} + */ +struct ANativeActivityCallbacks; + +/** + * This structure defines the native side of an android.app.NativeActivity. + * It is created by the framework, and handed to the application's native + * code as it is being launched. + */ +typedef struct ANativeActivity { + /** + * Pointer to the callback function table of the native application. + * You can set the functions here to your own callbacks. The callbacks + * pointer itself here should not be changed; it is allocated and managed + * for you by the framework. + */ + struct ANativeActivityCallbacks* callbacks; + + /** + * The global handle on the process's Java VM. + */ + JavaVM* vm; + + /** + * JNI context for the main thread of the app. Note that this field + * can ONLY be used from the main thread of the process; that is, the + * thread that calls into the ANativeActivityCallbacks. + */ + JNIEnv* env; + + /** + * The NativeActivity object handle. + * + * IMPORTANT NOTE: This member is mis-named. It should really be named + * 'activity' instead of 'clazz', since it's a reference to the + * NativeActivity instance created by the system for you. + * + * We unfortunately cannot change this without breaking NDK + * source-compatibility. + */ + jobject clazz; + + /** + * Path to this application's internal data directory. + */ + const char* internalDataPath; + + /** + * Path to this application's external (removable/mountable) data directory. + */ + const char* externalDataPath; + + /** + * The platform's SDK version code. + */ + int32_t sdkVersion; + + /** + * This is the native instance of the application. It is not used by + * the framework, but can be set by the application to its own instance + * state. + */ + void* instance; + + /** + * Pointer to the Asset Manager instance for the application. The application + * uses this to access binary assets bundled inside its own .apk file. + */ + AAssetManager* assetManager; + + /** + * Available starting with Honeycomb: path to the directory containing + * the application's OBB files (if any). If the app doesn't have any + * OBB files, this directory may not exist. + */ + const char* obbPath; +} ANativeActivity; + +/** + * These are the callbacks the framework makes into a native application. + * All of these callbacks happen on the main thread of the application. + * By default, all callbacks are NULL; set to a pointer to your own function + * to have it called. + */ +typedef struct ANativeActivityCallbacks { + /** + * NativeActivity has started. See Java documentation for Activity.onStart() + * for more information. + */ + void (*onStart)(ANativeActivity* activity); + + /** + * NativeActivity has resumed. See Java documentation for Activity.onResume() + * for more information. + */ + void (*onResume)(ANativeActivity* activity); + + /** + * Framework is asking NativeActivity to save its current instance state. + * See Java documentation for Activity.onSaveInstanceState() for more + * information. The returned pointer needs to be created with malloc(); + * the framework will call free() on it for you. You also must fill in + * outSize with the number of bytes in the allocation. Note that the + * saved state will be persisted, so it can not contain any active + * entities (pointers to memory, file descriptors, etc). + */ + void* (*onSaveInstanceState)(ANativeActivity* activity, size_t* outSize); + + /** + * NativeActivity has paused. See Java documentation for Activity.onPause() + * for more information. + */ + void (*onPause)(ANativeActivity* activity); + + /** + * NativeActivity has stopped. See Java documentation for Activity.onStop() + * for more information. + */ + void (*onStop)(ANativeActivity* activity); + + /** + * NativeActivity is being destroyed. See Java documentation for Activity.onDestroy() + * for more information. + */ + void (*onDestroy)(ANativeActivity* activity); + + /** + * Focus has changed in this NativeActivity's window. This is often used, + * for example, to pause a game when it loses input focus. + */ + void (*onWindowFocusChanged)(ANativeActivity* activity, int hasFocus); + + /** + * The drawing window for this native activity has been created. You + * can use the given native window object to start drawing. + */ + void (*onNativeWindowCreated)(ANativeActivity* activity, ANativeWindow* window); + + /** + * The drawing window for this native activity has been resized. You should + * retrieve the new size from the window and ensure that your rendering in + * it now matches. + */ + void (*onNativeWindowResized)(ANativeActivity* activity, ANativeWindow* window); + + /** + * The drawing window for this native activity needs to be redrawn. To avoid + * transient artifacts during screen changes (such resizing after rotation), + * applications should not return from this function until they have finished + * drawing their window in its current state. + */ + void (*onNativeWindowRedrawNeeded)(ANativeActivity* activity, ANativeWindow* window); + + /** + * The drawing window for this native activity is going to be destroyed. + * You MUST ensure that you do not touch the window object after returning + * from this function: in the common case of drawing to the window from + * another thread, that means the implementation of this callback must + * properly synchronize with the other thread to stop its drawing before + * returning from here. + */ + void (*onNativeWindowDestroyed)(ANativeActivity* activity, ANativeWindow* window); + + /** + * The input queue for this native activity's window has been created. + * You can use the given input queue to start retrieving input events. + */ + void (*onInputQueueCreated)(ANativeActivity* activity, AInputQueue* queue); + + /** + * The input queue for this native activity's window is being destroyed. + * You should no longer try to reference this object upon returning from this + * function. + */ + void (*onInputQueueDestroyed)(ANativeActivity* activity, AInputQueue* queue); + + /** + * The rectangle in the window in which content should be placed has changed. + */ + void (*onContentRectChanged)(ANativeActivity* activity, const ARect* rect); + + /** + * The current device AConfiguration has changed. The new configuration can + * be retrieved from assetManager. + */ + void (*onConfigurationChanged)(ANativeActivity* activity); + + /** + * The system is running low on memory. Use this callback to release + * resources you do not need, to help the system avoid killing more + * important processes. + */ + void (*onLowMemory)(ANativeActivity* activity); +} ANativeActivityCallbacks; + +/** + * This is the function that must be in the native code to instantiate the + * application's native activity. It is called with the activity instance (see + * above); if the code is being instantiated from a previously saved instance, + * the savedState will be non-NULL and point to the saved data. You must make + * any copy of this data you need -- it will be released after you return from + * this function. + */ +typedef void ANativeActivity_createFunc(ANativeActivity* activity, + void* savedState, size_t savedStateSize); + +/** + * The name of the function that NativeInstance looks for when launching its + * native code. This is the default function that is used, you can specify + * "android.app.func_name" string meta-data in your manifest to use a different + * function. + */ +extern ANativeActivity_createFunc ANativeActivity_onCreate; + +/** + * Finish the given activity. Its finish() method will be called, causing it + * to be stopped and destroyed. Note that this method can be called from + * *any* thread; it will send a message to the main thread of the process + * where the Java finish call will take place. + */ +void ANativeActivity_finish(ANativeActivity* activity); + +/** + * Change the window format of the given activity. Calls getWindow().setFormat() + * of the given activity. Note that this method can be called from + * *any* thread; it will send a message to the main thread of the process + * where the Java finish call will take place. + */ +void ANativeActivity_setWindowFormat(ANativeActivity* activity, int32_t format); + +/** + * Change the window flags of the given activity. Calls getWindow().setFlags() + * of the given activity. Note that this method can be called from + * *any* thread; it will send a message to the main thread of the process + * where the Java finish call will take place. See window.h for flag constants. + */ +void ANativeActivity_setWindowFlags(ANativeActivity* activity, + uint32_t addFlags, uint32_t removeFlags); + +/** + * Flags for ANativeActivity_showSoftInput; see the Java InputMethodManager + * API for documentation. + */ +enum { + /** + * Implicit request to show the input window, not as the result + * of a direct request by the user. + */ + ANATIVEACTIVITY_SHOW_SOFT_INPUT_IMPLICIT = 0x0001, + + /** + * The user has forced the input method open (such as by + * long-pressing menu) so it should not be closed until they + * explicitly do so. + */ + ANATIVEACTIVITY_SHOW_SOFT_INPUT_FORCED = 0x0002, +}; + +/** + * Show the IME while in the given activity. Calls InputMethodManager.showSoftInput() + * for the given activity. Note that this method can be called from + * *any* thread; it will send a message to the main thread of the process + * where the Java finish call will take place. + */ +void ANativeActivity_showSoftInput(ANativeActivity* activity, uint32_t flags); + +/** + * Flags for ANativeActivity_hideSoftInput; see the Java InputMethodManager + * API for documentation. + */ +enum { + /** + * The soft input window should only be hidden if it was not + * explicitly shown by the user. + */ + ANATIVEACTIVITY_HIDE_SOFT_INPUT_IMPLICIT_ONLY = 0x0001, + /** + * The soft input window should normally be hidden, unless it was + * originally shown with {@link ANATIVEACTIVITY_SHOW_SOFT_INPUT_FORCED}. + */ + ANATIVEACTIVITY_HIDE_SOFT_INPUT_NOT_ALWAYS = 0x0002, +}; + +/** + * Hide the IME while in the given activity. Calls InputMethodManager.hideSoftInput() + * for the given activity. Note that this method can be called from + * *any* thread; it will send a message to the main thread of the process + * where the Java finish call will take place. + */ +void ANativeActivity_hideSoftInput(ANativeActivity* activity, uint32_t flags); + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_NATIVE_ACTIVITY_H + +/** @} */ diff --git a/phonelibs/android_frameworks_native/include/android/native_window.h b/phonelibs/android_frameworks_native/include/android/native_window.h new file mode 100644 index 00000000000000..cf07f1afad9856 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/native_window.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup NativeActivity Native Activity + * @{ + */ + +/** + * @file native_window.h + */ + +#ifndef ANDROID_NATIVE_WINDOW_H +#define ANDROID_NATIVE_WINDOW_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Pixel formats that a window can use. + */ +enum { + /** Red: 8 bits, Green: 8 bits, Blue: 8 bits, Alpha: 8 bits. **/ + WINDOW_FORMAT_RGBA_8888 = 1, + /** Red: 8 bits, Green: 8 bits, Blue: 8 bits, Unused: 8 bits. **/ + WINDOW_FORMAT_RGBX_8888 = 2, + /** Red: 5 bits, Green: 6 bits, Blue: 5 bits. **/ + WINDOW_FORMAT_RGB_565 = 4, +}; + +struct ANativeWindow; +/** + * {@link ANativeWindow} is opaque type that provides access to a native window. + * + * A pointer can be obtained using ANativeWindow_fromSurface(). + */ +typedef struct ANativeWindow ANativeWindow; + +/** + * {@link ANativeWindow} is a struct that represents a windows buffer. + * + * A pointer can be obtained using ANativeWindow_lock(). + */ +typedef struct ANativeWindow_Buffer { + // The number of pixels that are show horizontally. + int32_t width; + + // The number of pixels that are shown vertically. + int32_t height; + + // The number of *pixels* that a line in the buffer takes in + // memory. This may be >= width. + int32_t stride; + + // The format of the buffer. One of WINDOW_FORMAT_* + int32_t format; + + // The actual bits. + void* bits; + + // Do not touch. + uint32_t reserved[6]; +} ANativeWindow_Buffer; + +/** + * Acquire a reference on the given ANativeWindow object. This prevents the object + * from being deleted until the reference is removed. + */ +void ANativeWindow_acquire(ANativeWindow* window); + +/** + * Remove a reference that was previously acquired with ANativeWindow_acquire(). + */ +void ANativeWindow_release(ANativeWindow* window); + +/** + * Return the current width in pixels of the window surface. Returns a + * negative value on error. + */ +int32_t ANativeWindow_getWidth(ANativeWindow* window); + +/** + * Return the current height in pixels of the window surface. Returns a + * negative value on error. + */ +int32_t ANativeWindow_getHeight(ANativeWindow* window); + +/** + * Return the current pixel format of the window surface. Returns a + * negative value on error. + */ +int32_t ANativeWindow_getFormat(ANativeWindow* window); + +/** + * Change the format and size of the window buffers. + * + * The width and height control the number of pixels in the buffers, not the + * dimensions of the window on screen. If these are different than the + * window's physical size, then it buffer will be scaled to match that size + * when compositing it to the screen. + * + * For all of these parameters, if 0 is supplied then the window's base + * value will come back in force. + * + * width and height must be either both zero or both non-zero. + * + */ +int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, + int32_t width, int32_t height, int32_t format); + +/** + * Lock the window's next drawing surface for writing. + * inOutDirtyBounds is used as an in/out parameter, upon entering the + * function, it contains the dirty region, that is, the region the caller + * intends to redraw. When the function returns, inOutDirtyBounds is updated + * with the actual area the caller needs to redraw -- this region is often + * extended by ANativeWindow_lock. + */ +int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer, + ARect* inOutDirtyBounds); + +/** + * Unlock the window's drawing surface after previously locking it, + * posting the new buffer to the display. + */ +int32_t ANativeWindow_unlockAndPost(ANativeWindow* window); + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_NATIVE_WINDOW_H + +/** @} */ diff --git a/phonelibs/android_frameworks_native/include/android/native_window_jni.h b/phonelibs/android_frameworks_native/include/android/native_window_jni.h new file mode 100644 index 00000000000000..60a36c3f271076 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/native_window_jni.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup NativeActivity Native Activity + * @{ + */ + +/** + * @file native_window_jni.h + */ + +#ifndef ANDROID_NATIVE_WINDOW_JNI_H +#define ANDROID_NATIVE_WINDOW_JNI_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Return the ANativeWindow associated with a Java Surface object, + * for interacting with it through native code. This acquires a reference + * on the ANativeWindow that is returned; be sure to use ANativeWindow_release() + * when done with it so that it doesn't leak. + */ +ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface); + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_NATIVE_WINDOW_H + +/** @} */ diff --git a/phonelibs/android_frameworks_native/include/android/obb.h b/phonelibs/android_frameworks_native/include/android/obb.h new file mode 100644 index 00000000000000..4c6d9d7badd5b6 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/obb.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup Storage + * @{ + */ + +/** + * @file obb.h + */ + +#ifndef ANDROID_OBB_H +#define ANDROID_OBB_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct AObbInfo; +/** {@link AObbInfo} is an opaque type representing information for obb storage. */ +typedef struct AObbInfo AObbInfo; + +/** Flag for an obb file, returned by AObbInfo_getFlags(). */ +enum { + /** overlay */ + AOBBINFO_OVERLAY = 0x0001, +}; + +/** + * Scan an OBB and get information about it. + */ +AObbInfo* AObbScanner_getObbInfo(const char* filename); + +/** + * Destroy the AObbInfo object. You must call this when finished with the object. + */ +void AObbInfo_delete(AObbInfo* obbInfo); + +/** + * Get the package name for the OBB. + */ +const char* AObbInfo_getPackageName(AObbInfo* obbInfo); + +/** + * Get the version of an OBB file. + */ +int32_t AObbInfo_getVersion(AObbInfo* obbInfo); + +/** + * Get the flags of an OBB file. + */ +int32_t AObbInfo_getFlags(AObbInfo* obbInfo); + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_OBB_H + +/** @} */ diff --git a/phonelibs/android_frameworks_native/include/android/rect.h b/phonelibs/android_frameworks_native/include/android/rect.h new file mode 100644 index 00000000000000..80741c04420e21 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/rect.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup NativeActivity Native Activity + * @{ + */ + +/** + * @file rect.h + */ + +#ifndef ANDROID_RECT_H +#define ANDROID_RECT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * {@link ARect} is a struct that represents a rectangular window area. + * + * It is used with {@link + * ANativeActivityCallbacks::onContentRectChanged} event callback and + * ANativeWindow_lock() function. + */ +typedef struct ARect { +#ifdef __cplusplus + typedef int32_t value_type; +#endif + /** left position */ + int32_t left; + /** top position */ + int32_t top; + /** left position */ + int32_t right; + /** bottom position */ + int32_t bottom; +} ARect; + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_RECT_H + +/** @} */ diff --git a/phonelibs/android_frameworks_native/include/android/sensor.h b/phonelibs/android_frameworks_native/include/android/sensor.h new file mode 100644 index 00000000000000..73928ea76f9925 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/sensor.h @@ -0,0 +1,475 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup Sensor + * @{ + */ + +/** + * @file sensor.h + */ + +#ifndef ANDROID_SENSOR_H +#define ANDROID_SENSOR_H + +/****************************************************************** + * + * IMPORTANT NOTICE: + * + * This file is part of Android's set of stable system headers + * exposed by the Android NDK (Native Development Kit). + * + * Third-party source AND binary code relies on the definitions + * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES. + * + * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES) + * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS + * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY + * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES + */ + +/** + * Structures and functions to receive and process sensor events in + * native code. + * + */ + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Sensor types. + * (keep in sync with hardware/sensor.h) + */ +enum { + /** + * {@link ASENSOR_TYPE_ACCELEROMETER} + * reporting-mode: continuous + * + * All values are in SI units (m/s^2) and measure the acceleration of the + * device minus the force of gravity. + */ + ASENSOR_TYPE_ACCELEROMETER = 1, + /** + * {@link ASENSOR_TYPE_MAGNETIC_FIELD} + * reporting-mode: continuous + * + * All values are in micro-Tesla (uT) and measure the geomagnetic + * field in the X, Y and Z axis. + */ + ASENSOR_TYPE_MAGNETIC_FIELD = 2, + /** + * {@link ASENSOR_TYPE_GYROSCOPE} + * reporting-mode: continuous + * + * All values are in radians/second and measure the rate of rotation + * around the X, Y and Z axis. + */ + ASENSOR_TYPE_GYROSCOPE = 4, + /** + * {@link ASENSOR_TYPE_LIGHT} + * reporting-mode: on-change + * + * The light sensor value is returned in SI lux units. + */ + ASENSOR_TYPE_LIGHT = 5, + /** + * {@link ASENSOR_TYPE_PROXIMITY} + * reporting-mode: on-change + * + * The proximity sensor which turns the screen off and back on during calls is the + * wake-up proximity sensor. Implement wake-up proximity sensor before implementing + * a non wake-up proximity sensor. For the wake-up proximity sensor set the flag + * SENSOR_FLAG_WAKE_UP. + * The value corresponds to the distance to the nearest object in centimeters. + */ + ASENSOR_TYPE_PROXIMITY = 8 +}; + +/** + * Sensor accuracy measure. + */ +enum { + /** no contact */ + ASENSOR_STATUS_NO_CONTACT = -1, + /** unreliable */ + ASENSOR_STATUS_UNRELIABLE = 0, + /** low accuracy */ + ASENSOR_STATUS_ACCURACY_LOW = 1, + /** medium accuracy */ + ASENSOR_STATUS_ACCURACY_MEDIUM = 2, + /** high accuracy */ + ASENSOR_STATUS_ACCURACY_HIGH = 3 +}; + +/** + * Sensor Reporting Modes. + */ +enum { + /** continuous reporting */ + AREPORTING_MODE_CONTINUOUS = 0, + /** reporting on change */ + AREPORTING_MODE_ON_CHANGE = 1, + /** on shot reporting */ + AREPORTING_MODE_ONE_SHOT = 2, + /** special trigger reporting */ + AREPORTING_MODE_SPECIAL_TRIGGER = 3 +}; + +/* + * A few useful constants + */ + +/** Earth's gravity in m/s^2 */ +#define ASENSOR_STANDARD_GRAVITY (9.80665f) +/** Maximum magnetic field on Earth's surface in uT */ +#define ASENSOR_MAGNETIC_FIELD_EARTH_MAX (60.0f) +/** Minimum magnetic field on Earth's surface in uT*/ +#define ASENSOR_MAGNETIC_FIELD_EARTH_MIN (30.0f) + +/** + * A sensor event. + */ + +/* NOTE: Must match hardware/sensors.h */ +typedef struct ASensorVector { + union { + float v[3]; + struct { + float x; + float y; + float z; + }; + struct { + float azimuth; + float pitch; + float roll; + }; + }; + int8_t status; + uint8_t reserved[3]; +} ASensorVector; + +typedef struct AMetaDataEvent { + int32_t what; + int32_t sensor; +} AMetaDataEvent; + +typedef struct AUncalibratedEvent { + union { + float uncalib[3]; + struct { + float x_uncalib; + float y_uncalib; + float z_uncalib; + }; + }; + union { + float bias[3]; + struct { + float x_bias; + float y_bias; + float z_bias; + }; + }; +} AUncalibratedEvent; + +typedef struct AHeartRateEvent { + float bpm; + int8_t status; +} AHeartRateEvent; + +/* NOTE: Must match hardware/sensors.h */ +typedef struct ASensorEvent { + int32_t version; /* sizeof(struct ASensorEvent) */ + int32_t sensor; + int32_t type; + int32_t reserved0; + int64_t timestamp; + union { + union { + float data[16]; + ASensorVector vector; + ASensorVector acceleration; + ASensorVector magnetic; + float temperature; + float distance; + float light; + float pressure; + float relative_humidity; + AUncalibratedEvent uncalibrated_gyro; + AUncalibratedEvent uncalibrated_magnetic; + AMetaDataEvent meta_data; + AHeartRateEvent heart_rate; + }; + union { + uint64_t data[8]; + uint64_t step_counter; + } u64; + }; + + uint32_t flags; + int32_t reserved1[3]; +} ASensorEvent; + +struct ASensorManager; +/** + * {@link ASensorManager} is an opaque type to manage sensors and + * events queues. + * + * {@link ASensorManager} is a singleton that can be obtained using + * ASensorManager_getInstance(). + * + * This file provides a set of functions that uses {@link + * ASensorManager} to access and list hardware sensors, and + * create and destroy event queues: + * - ASensorManager_getSensorList() + * - ASensorManager_getDefaultSensor() + * - ASensorManager_getDefaultSensorEx() + * - ASensorManager_createEventQueue() + * - ASensorManager_destroyEventQueue() + */ +typedef struct ASensorManager ASensorManager; + + +struct ASensorEventQueue; +/** + * {@link ASensorEventQueue} is an opaque type that provides access to + * {@link ASensorEvent} from hardware sensors. + * + * A new {@link ASensorEventQueue} can be obtained using ASensorManager_createEventQueue(). + * + * This file provides a set of functions to enable and disable + * sensors, check and get events, and set event rates on a {@link + * ASensorEventQueue}. + * - ASensorEventQueue_enableSensor() + * - ASensorEventQueue_disableSensor() + * - ASensorEventQueue_hasEvents() + * - ASensorEventQueue_getEvents() + * - ASensorEventQueue_setEventRate() + */ +typedef struct ASensorEventQueue ASensorEventQueue; + +struct ASensor; +/** + * {@link ASensor} is an opaque type that provides information about + * an hardware sensors. + * + * A {@link ASensor} pointer can be obtained using + * ASensorManager_getDefaultSensor(), + * ASensorManager_getDefaultSensorEx() or from a {@link ASensorList}. + * + * This file provides a set of functions to access properties of a + * {@link ASensor}: + * - ASensor_getName() + * - ASensor_getVendor() + * - ASensor_getType() + * - ASensor_getResolution() + * - ASensor_getMinDelay() + * - ASensor_getFifoMaxEventCount() + * - ASensor_getFifoReservedEventCount() + * - ASensor_getStringType() + * - ASensor_getReportingMode() + * - ASensor_isWakeUpSensor() + */ +typedef struct ASensor ASensor; +/** + * {@link ASensorRef} is a type for constant pointers to {@link ASensor}. + * + * This is used to define entry in {@link ASensorList} arrays. + */ +typedef ASensor const* ASensorRef; +/** + * {@link ASensorList} is an array of reference to {@link ASensor}. + * + * A {@link ASensorList} can be initialized using ASensorManager_getSensorList(). + */ +typedef ASensorRef const* ASensorList; + +/*****************************************************************************/ + +/** + * Get a reference to the sensor manager. ASensorManager is a singleton + * per package as different packages may have access to different sensors. + * + * Deprecated: Use ASensorManager_getInstanceForPackage(const char*) instead. + * + * Example: + * + * ASensorManager* sensorManager = ASensorManager_getInstance(); + * + */ +__attribute__ ((deprecated)) ASensorManager* ASensorManager_getInstance(); + +/* + * Get a reference to the sensor manager. ASensorManager is a singleton + * per package as different packages may have access to different sensors. + * + * Example: + * + * ASensorManager* sensorManager = ASensorManager_getInstanceForPackage("foo.bar.baz"); + * + */ +ASensorManager* ASensorManager_getInstanceForPackage(const char* packageName); + +/** + * Returns the list of available sensors. + */ +int ASensorManager_getSensorList(ASensorManager* manager, ASensorList* list); + +/** + * Returns the default sensor for the given type, or NULL if no sensor + * of that type exists. + */ +ASensor const* ASensorManager_getDefaultSensor(ASensorManager* manager, int type); + +/** + * Returns the default sensor with the given type and wakeUp properties or NULL if no sensor + * of this type and wakeUp properties exists. + */ +ASensor const* ASensorManager_getDefaultSensorEx(ASensorManager* manager, int type, + bool wakeUp); + +/** + * Creates a new sensor event queue and associate it with a looper. + * + * "ident" is a identifier for the events that will be returned when + * calling ALooper_pollOnce(). The identifier must be >= 0, or + * ALOOPER_POLL_CALLBACK if providing a non-NULL callback. + */ +ASensorEventQueue* ASensorManager_createEventQueue(ASensorManager* manager, + ALooper* looper, int ident, ALooper_callbackFunc callback, void* data); + +/** + * Destroys the event queue and free all resources associated to it. + */ +int ASensorManager_destroyEventQueue(ASensorManager* manager, ASensorEventQueue* queue); + + +/*****************************************************************************/ + +/** + * Enable the selected sensor. Returns a negative error code on failure. + */ +int ASensorEventQueue_enableSensor(ASensorEventQueue* queue, ASensor const* sensor); + +/** + * Disable the selected sensor. Returns a negative error code on failure. + */ +int ASensorEventQueue_disableSensor(ASensorEventQueue* queue, ASensor const* sensor); + +/** + * Sets the delivery rate of events in microseconds for the given sensor. + * Note that this is a hint only, generally event will arrive at a higher + * rate. It is an error to set a rate inferior to the value returned by + * ASensor_getMinDelay(). + * Returns a negative error code on failure. + */ +int ASensorEventQueue_setEventRate(ASensorEventQueue* queue, ASensor const* sensor, int32_t usec); + +/** + * Returns true if there are one or more events available in the + * sensor queue. Returns 1 if the queue has events; 0 if + * it does not have events; and a negative value if there is an error. + */ +int ASensorEventQueue_hasEvents(ASensorEventQueue* queue); + +/** + * Returns the next available events from the queue. Returns a negative + * value if no events are available or an error has occurred, otherwise + * the number of events returned. + * + * Examples: + * ASensorEvent event; + * ssize_t numEvent = ASensorEventQueue_getEvents(queue, &event, 1); + * + * ASensorEvent eventBuffer[8]; + * ssize_t numEvent = ASensorEventQueue_getEvents(queue, eventBuffer, 8); + * + */ +ssize_t ASensorEventQueue_getEvents(ASensorEventQueue* queue, + ASensorEvent* events, size_t count); + + +/*****************************************************************************/ + +/** + * Returns this sensor's name (non localized) + */ +const char* ASensor_getName(ASensor const* sensor); + +/** + * Returns this sensor's vendor's name (non localized) + */ +const char* ASensor_getVendor(ASensor const* sensor); + +/** + * Return this sensor's type + */ +int ASensor_getType(ASensor const* sensor); + +/** + * Returns this sensors's resolution + */ +float ASensor_getResolution(ASensor const* sensor); + +/** + * Returns the minimum delay allowed between events in microseconds. + * A value of zero means that this sensor doesn't report events at a + * constant rate, but rather only when a new data is available. + */ +int ASensor_getMinDelay(ASensor const* sensor); + +/** + * Returns the maximum size of batches for this sensor. Batches will often be + * smaller, as the hardware fifo might be used for other sensors. + */ +int ASensor_getFifoMaxEventCount(ASensor const* sensor); + +/** + * Returns the hardware batch fifo size reserved to this sensor. + */ +int ASensor_getFifoReservedEventCount(ASensor const* sensor); + +/** + * Returns this sensor's string type. + */ +const char* ASensor_getStringType(ASensor const* sensor); + +/** + * Returns the reporting mode for this sensor. One of AREPORTING_MODE_* constants. + */ +int ASensor_getReportingMode(ASensor const* sensor); + +/** + * Returns true if this is a wake up sensor, false otherwise. + */ +bool ASensor_isWakeUpSensor(ASensor const* sensor); + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_SENSOR_H + +/** @} */ diff --git a/phonelibs/android_frameworks_native/include/android/storage_manager.h b/phonelibs/android_frameworks_native/include/android/storage_manager.h new file mode 100644 index 00000000000000..7f2ee08d62c347 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/storage_manager.h @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup Storage + * @{ + */ + +/** + * @file storage_manager.h + */ + +#ifndef ANDROID_STORAGE_MANAGER_H +#define ANDROID_STORAGE_MANAGER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct AStorageManager; +/** + * {@link AStorageManager} manages application OBB storage, a pointer + * can be obtained with AStorageManager_new(). + */ +typedef struct AStorageManager AStorageManager; + +/** + * The different states of a OBB storage passed to AStorageManager_obbCallbackFunc(). + */ +enum { + /** + * The OBB container is now mounted and ready for use. Can be returned + * as the status for callbacks made during asynchronous OBB actions. + */ + AOBB_STATE_MOUNTED = 1, + + /** + * The OBB container is now unmounted and not usable. Can be returned + * as the status for callbacks made during asynchronous OBB actions. + */ + AOBB_STATE_UNMOUNTED = 2, + + /** + * There was an internal system error encountered while trying to + * mount the OBB. Can be returned as the status for callbacks made + * during asynchronous OBB actions. + */ + AOBB_STATE_ERROR_INTERNAL = 20, + + /** + * The OBB could not be mounted by the system. Can be returned as the + * status for callbacks made during asynchronous OBB actions. + */ + AOBB_STATE_ERROR_COULD_NOT_MOUNT = 21, + + /** + * The OBB could not be unmounted. This most likely indicates that a + * file is in use on the OBB. Can be returned as the status for + * callbacks made during asynchronous OBB actions. + */ + AOBB_STATE_ERROR_COULD_NOT_UNMOUNT = 22, + + /** + * A call was made to unmount the OBB when it was not mounted. Can be + * returned as the status for callbacks made during asynchronous OBB + * actions. + */ + AOBB_STATE_ERROR_NOT_MOUNTED = 23, + + /** + * The OBB has already been mounted. Can be returned as the status for + * callbacks made during asynchronous OBB actions. + */ + AOBB_STATE_ERROR_ALREADY_MOUNTED = 24, + + /** + * The current application does not have permission to use this OBB. + * This could be because the OBB indicates it's owned by a different + * package. Can be returned as the status for callbacks made during + * asynchronous OBB actions. + */ + AOBB_STATE_ERROR_PERMISSION_DENIED = 25, +}; + +/** + * Obtains a new instance of AStorageManager. + */ +AStorageManager* AStorageManager_new(); + +/** + * Release AStorageManager instance. + */ +void AStorageManager_delete(AStorageManager* mgr); + +/** + * Callback function for asynchronous calls made on OBB files. + * + * "state" is one of the following constants: + * - {@link AOBB_STATE_MOUNTED} + * - {@link AOBB_STATE_UNMOUNTED} + * - {@link AOBB_STATE_ERROR_INTERNAL} + * - {@link AOBB_STATE_ERROR_COULD_NOT_MOUNT} + * - {@link AOBB_STATE_ERROR_COULD_NOT_UNMOUNT} + * - {@link AOBB_STATE_ERROR_NOT_MOUNTED} + * - {@link AOBB_STATE_ERROR_ALREADY_MOUNTED} + * - {@link AOBB_STATE_ERROR_PERMISSION_DENIED} + */ +typedef void (*AStorageManager_obbCallbackFunc)(const char* filename, const int32_t state, void* data); + +/** + * Attempts to mount an OBB file. This is an asynchronous operation. + */ +void AStorageManager_mountObb(AStorageManager* mgr, const char* filename, const char* key, + AStorageManager_obbCallbackFunc cb, void* data); + +/** + * Attempts to unmount an OBB file. This is an asynchronous operation. + */ +void AStorageManager_unmountObb(AStorageManager* mgr, const char* filename, const int force, + AStorageManager_obbCallbackFunc cb, void* data); + +/** + * Check whether an OBB is mounted. + */ +int AStorageManager_isObbMounted(AStorageManager* mgr, const char* filename); + +/** + * Get the mounted path for an OBB. + */ +const char* AStorageManager_getMountedObbPath(AStorageManager* mgr, const char* filename); + + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_STORAGE_MANAGER_H + +/** @} */ diff --git a/phonelibs/android_frameworks_native/include/android/trace.h b/phonelibs/android_frameworks_native/include/android/trace.h new file mode 100644 index 00000000000000..e42e3341024dc4 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/trace.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_NATIVE_TRACE_H +#define ANDROID_NATIVE_TRACE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Returns true if tracing is enabled. Use this signal to avoid expensive computation only necessary + * when tracing is enabled. + */ +bool ATrace_isEnabled(); + +/** + * Writes a tracing message to indicate that the given section of code has begun. This call must be + * followed by a corresponding call to endSection() on the same thread. + * + * Note: At this time the vertical bar character '|' and newline character '\n' are used internally + * by the tracing mechanism. If sectionName contains these characters they will be replaced with a + * space character in the trace. + */ +void ATrace_beginSection(const char* sectionName); + +/** + * Writes a tracing message to indicate that a given section of code has ended. This call must be + * preceeded by a corresponding call to beginSection(char*) on the same thread. Calling this method + * will mark the end of the most recently begun section of code, so care must be taken to ensure + * that beginSection / endSection pairs are properly nested and called from the same thread. + */ +void ATrace_endSection(); + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_NATIVE_TRACE_H diff --git a/phonelibs/android_frameworks_native/include/android/window.h b/phonelibs/android_frameworks_native/include/android/window.h new file mode 100644 index 00000000000000..436bf3a8307ce0 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/android/window.h @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup NativeActivity Native Activity + * @{ + */ + +/** + * @file window.h + */ + +#ifndef ANDROID_WINDOW_H +#define ANDROID_WINDOW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Window flags, as per the Java API at android.view.WindowManager.LayoutParams. + */ +enum { + /** + * As long as this window is visible to the user, allow the lock + * screen to activate while the screen is on. This can be used + * independently, or in combination with {@link + * AWINDOW_FLAG_KEEP_SCREEN_ON} and/or {@link + * AWINDOW_FLAG_SHOW_WHEN_LOCKED} + */ + AWINDOW_FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001, + /** Everything behind this window will be dimmed. */ + AWINDOW_FLAG_DIM_BEHIND = 0x00000002, + /** + * Blur everything behind this window. + * @deprecated Blurring is no longer supported. + */ + AWINDOW_FLAG_BLUR_BEHIND = 0x00000004, + /** + * This window won't ever get key input focus, so the + * user can not send key or other button events to it. Those will + * instead go to whatever focusable window is behind it. This flag + * will also enable {@link AWINDOW_FLAG_NOT_TOUCH_MODAL} whether or not that + * is explicitly set. + * + * Setting this flag also implies that the window will not need to + * interact with + * a soft input method, so it will be Z-ordered and positioned + * independently of any active input method (typically this means it + * gets Z-ordered on top of the input method, so it can use the full + * screen for its content and cover the input method if needed. You + * can use {@link AWINDOW_FLAG_ALT_FOCUSABLE_IM} to modify this behavior. + */ + AWINDOW_FLAG_NOT_FOCUSABLE = 0x00000008, + /** this window can never receive touch events. */ + AWINDOW_FLAG_NOT_TOUCHABLE = 0x00000010, + /** + * Even when this window is focusable (its + * {@link AWINDOW_FLAG_NOT_FOCUSABLE} is not set), allow any pointer events + * outside of the window to be sent to the windows behind it. Otherwise + * it will consume all pointer events itself, regardless of whether they + * are inside of the window. + */ + AWINDOW_FLAG_NOT_TOUCH_MODAL = 0x00000020, + /** + * When set, if the device is asleep when the touch + * screen is pressed, you will receive this first touch event. Usually + * the first touch event is consumed by the system since the user can + * not see what they are pressing on. + * + * @deprecated This flag has no effect. + */ + AWINDOW_FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040, + /** + * As long as this window is visible to the user, keep + * the device's screen turned on and bright. + */ + AWINDOW_FLAG_KEEP_SCREEN_ON = 0x00000080, + /** + * Place the window within the entire screen, ignoring + * decorations around the border (such as the status bar). The + * window must correctly position its contents to take the screen + * decoration into account. + */ + AWINDOW_FLAG_LAYOUT_IN_SCREEN = 0x00000100, + /** allow window to extend outside of the screen. */ + AWINDOW_FLAG_LAYOUT_NO_LIMITS = 0x00000200, + /** + * Hide all screen decorations (such as the status + * bar) while this window is displayed. This allows the window to + * use the entire display space for itself -- the status bar will + * be hidden when an app window with this flag set is on the top + * layer. A fullscreen window will ignore a value of {@link + * AWINDOW_SOFT_INPUT_ADJUST_RESIZE}; the window will stay + * fullscreen and will not resize. + */ + AWINDOW_FLAG_FULLSCREEN = 0x00000400, + /** + * Override {@link AWINDOW_FLAG_FULLSCREEN} and force the + * screen decorations (such as the status bar) to be shown. + */ + AWINDOW_FLAG_FORCE_NOT_FULLSCREEN = 0x00000800, + /** + * Turn on dithering when compositing this window to + * the screen. + * @deprecated This flag is no longer used. + */ + AWINDOW_FLAG_DITHER = 0x00001000, + /** + * Treat the content of the window as secure, preventing + * it from appearing in screenshots or from being viewed on non-secure + * displays. + */ + AWINDOW_FLAG_SECURE = 0x00002000, + /** + * A special mode where the layout parameters are used + * to perform scaling of the surface when it is composited to the + * screen. + */ + AWINDOW_FLAG_SCALED = 0x00004000, + /** + * Intended for windows that will often be used when the user is + * holding the screen against their face, it will aggressively + * filter the event stream to prevent unintended presses in this + * situation that may not be desired for a particular window, when + * such an event stream is detected, the application will receive + * a {@link AMOTION_EVENT_ACTION_CANCEL} to indicate this so + * applications can handle this accordingly by taking no action on + * the event until the finger is released. + */ + AWINDOW_FLAG_IGNORE_CHEEK_PRESSES = 0x00008000, + /** + * A special option only for use in combination with + * {@link AWINDOW_FLAG_LAYOUT_IN_SCREEN}. When requesting layout in the + * screen your window may appear on top of or behind screen decorations + * such as the status bar. By also including this flag, the window + * manager will report the inset rectangle needed to ensure your + * content is not covered by screen decorations. + */ + AWINDOW_FLAG_LAYOUT_INSET_DECOR = 0x00010000, + /** + * Invert the state of {@link AWINDOW_FLAG_NOT_FOCUSABLE} with + * respect to how this window interacts with the current method. + * That is, if FLAG_NOT_FOCUSABLE is set and this flag is set, + * then the window will behave as if it needs to interact with the + * input method and thus be placed behind/away from it; if {@link + * AWINDOW_FLAG_NOT_FOCUSABLE} is not set and this flag is set, + * then the window will behave as if it doesn't need to interact + * with the input method and can be placed to use more space and + * cover the input method. + */ + AWINDOW_FLAG_ALT_FOCUSABLE_IM = 0x00020000, + /** + * If you have set {@link AWINDOW_FLAG_NOT_TOUCH_MODAL}, you + * can set this flag to receive a single special MotionEvent with + * the action + * {@link AMOTION_EVENT_ACTION_OUTSIDE} for + * touches that occur outside of your window. Note that you will not + * receive the full down/move/up gesture, only the location of the + * first down as an {@link AMOTION_EVENT_ACTION_OUTSIDE}. + */ + AWINDOW_FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000, + /** + * Special flag to let windows be shown when the screen + * is locked. This will let application windows take precedence over + * key guard or any other lock screens. Can be used with + * {@link AWINDOW_FLAG_KEEP_SCREEN_ON} to turn screen on and display windows + * directly before showing the key guard window. Can be used with + * {@link AWINDOW_FLAG_DISMISS_KEYGUARD} to automatically fully dismisss + * non-secure keyguards. This flag only applies to the top-most + * full-screen window. + */ + AWINDOW_FLAG_SHOW_WHEN_LOCKED = 0x00080000, + /** + * Ask that the system wallpaper be shown behind + * your window. The window surface must be translucent to be able + * to actually see the wallpaper behind it; this flag just ensures + * that the wallpaper surface will be there if this window actually + * has translucent regions. + */ + AWINDOW_FLAG_SHOW_WALLPAPER = 0x00100000, + /** + * When set as a window is being added or made + * visible, once the window has been shown then the system will + * poke the power manager's user activity (as if the user had woken + * up the device) to turn the screen on. + */ + AWINDOW_FLAG_TURN_SCREEN_ON = 0x00200000, + /** + * When set the window will cause the keyguard to + * be dismissed, only if it is not a secure lock keyguard. Because such + * a keyguard is not needed for security, it will never re-appear if + * the user navigates to another window (in contrast to + * {@link AWINDOW_FLAG_SHOW_WHEN_LOCKED}, which will only temporarily + * hide both secure and non-secure keyguards but ensure they reappear + * when the user moves to another UI that doesn't hide them). + * If the keyguard is currently active and is secure (requires an + * unlock pattern) than the user will still need to confirm it before + * seeing this window, unless {@link AWINDOW_FLAG_SHOW_WHEN_LOCKED} has + * also been set. + */ + AWINDOW_FLAG_DISMISS_KEYGUARD = 0x00400000, +}; + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_WINDOW_H + +/** @} */ diff --git a/phonelibs/android_frameworks_native/include/batteryservice/BatteryService.h b/phonelibs/android_frameworks_native/include/batteryservice/BatteryService.h new file mode 100644 index 00000000000000..3e6bfb8204f611 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/batteryservice/BatteryService.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2015 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_BATTERYSERVICE_H +#define ANDROID_BATTERYSERVICE_H + +#include +#include +#include +#include + +namespace android { + +// must be kept in sync with definitions in BatteryManager.java +enum { + BATTERY_STATUS_UNKNOWN = 1, // equals BatteryManager.BATTERY_STATUS_UNKNOWN constant + BATTERY_STATUS_CHARGING = 2, // equals BatteryManager.BATTERY_STATUS_CHARGING constant + BATTERY_STATUS_DISCHARGING = 3, // equals BatteryManager.BATTERY_STATUS_DISCHARGING constant + BATTERY_STATUS_NOT_CHARGING = 4, // equals BatteryManager.BATTERY_STATUS_NOT_CHARGING constant + BATTERY_STATUS_FULL = 5, // equals BatteryManager.BATTERY_STATUS_FULL constant +}; + +// must be kept in sync with definitions in BatteryManager.java +enum { + BATTERY_HEALTH_UNKNOWN = 1, // equals BatteryManager.BATTERY_HEALTH_UNKNOWN constant + BATTERY_HEALTH_GOOD = 2, // equals BatteryManager.BATTERY_HEALTH_GOOD constant + BATTERY_HEALTH_OVERHEAT = 3, // equals BatteryManager.BATTERY_HEALTH_OVERHEAT constant + BATTERY_HEALTH_DEAD = 4, // equals BatteryManager.BATTERY_HEALTH_DEAD constant + BATTERY_HEALTH_OVER_VOLTAGE = 5, // equals BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE constant + BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6, // equals BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE constant + BATTERY_HEALTH_COLD = 7, // equals BatteryManager.BATTERY_HEALTH_COLD constant +}; + +// must be kept in sync with definitions in BatteryProperty.java +enum { + BATTERY_PROP_CHARGE_COUNTER = 1, // equals BatteryProperty.CHARGE_COUNTER constant + BATTERY_PROP_CURRENT_NOW = 2, // equals BatteryProperty.CURRENT_NOW constant + BATTERY_PROP_CURRENT_AVG = 3, // equals BatteryProperty.CURRENT_AVG constant + BATTERY_PROP_CAPACITY = 4, // equals BatteryProperty.CAPACITY constant + BATTERY_PROP_ENERGY_COUNTER = 5, // equals BatteryProperty.ENERGY_COUNTER constant +}; + +struct BatteryProperties { + bool chargerAcOnline; + bool chargerUsbOnline; + bool chargerWirelessOnline; + int maxChargingCurrent; + int batteryStatus; + int batteryHealth; + bool batteryPresent; + int batteryLevel; + int batteryVoltage; + int batteryTemperature; + String8 batteryTechnology; + + bool dockBatterySupported; + bool chargerDockAcOnline; + int dockBatteryStatus; + int dockBatteryHealth; + bool dockBatteryPresent; + int dockBatteryLevel; + int dockBatteryVoltage; + int dockBatteryTemperature; + String8 dockBatteryTechnology; + + status_t writeToParcel(Parcel* parcel) const; + status_t readFromParcel(Parcel* parcel); +}; + +struct BatteryProperty { + int64_t valueInt64; + + status_t writeToParcel(Parcel* parcel) const; + status_t readFromParcel(Parcel* parcel); +}; + +}; // namespace android + +#endif // ANDROID_BATTERYSERVICE_H diff --git a/phonelibs/android_frameworks_native/include/batteryservice/IBatteryPropertiesListener.h b/phonelibs/android_frameworks_native/include/batteryservice/IBatteryPropertiesListener.h new file mode 100644 index 00000000000000..b02d8e907335eb --- /dev/null +++ b/phonelibs/android_frameworks_native/include/batteryservice/IBatteryPropertiesListener.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IBATTERYPROPERTIESLISTENER_H +#define ANDROID_IBATTERYPROPERTIESLISTENER_H + +#include +#include + +#include + +namespace android { + +// must be kept in sync with interface defined in IBatteryPropertiesListener.aidl +enum { + TRANSACT_BATTERYPROPERTIESCHANGED = IBinder::FIRST_CALL_TRANSACTION, +}; + +// ---------------------------------------------------------------------------- + +class IBatteryPropertiesListener : public IInterface { +public: + DECLARE_META_INTERFACE(BatteryPropertiesListener); + + virtual void batteryPropertiesChanged(struct BatteryProperties props) = 0; +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IBATTERYPROPERTIESLISTENER_H diff --git a/phonelibs/android_frameworks_native/include/batteryservice/IBatteryPropertiesRegistrar.h b/phonelibs/android_frameworks_native/include/batteryservice/IBatteryPropertiesRegistrar.h new file mode 100644 index 00000000000000..f6a7981d54b95a --- /dev/null +++ b/phonelibs/android_frameworks_native/include/batteryservice/IBatteryPropertiesRegistrar.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2015 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IBATTERYPROPERTIESREGISTRAR_H +#define ANDROID_IBATTERYPROPERTIESREGISTRAR_H + +#include +#include + +namespace android { + +// must be kept in sync with interface defined in IBatteryPropertiesRegistrar.aidl +enum { + REGISTER_LISTENER = IBinder::FIRST_CALL_TRANSACTION, + UNREGISTER_LISTENER, + GET_PROPERTY, + GET_DOCK_PROPERTY, +}; + +class IBatteryPropertiesRegistrar : public IInterface { +public: + DECLARE_META_INTERFACE(BatteryPropertiesRegistrar); + + virtual void registerListener(const sp& listener) = 0; + virtual void unregisterListener(const sp& listener) = 0; + virtual status_t getProperty(int id, struct BatteryProperty *val) = 0; + virtual status_t getDockProperty(int id, struct BatteryProperty *val) = 0; +}; + +class BnBatteryPropertiesRegistrar : public BnInterface { +public: + virtual status_t onTransact(uint32_t code, const Parcel& data, + Parcel* reply, uint32_t flags = 0); +}; + +}; // namespace android + +#endif // ANDROID_IBATTERYPROPERTIESREGISTRAR_H diff --git a/phonelibs/android_frameworks_native/include/binder/AppOpsManager.h b/phonelibs/android_frameworks_native/include/binder/AppOpsManager.h new file mode 100644 index 00000000000000..1d0e968c4a43fb --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/AppOpsManager.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_APP_OPS_MANAGER_H +#define ANDROID_APP_OPS_MANAGER_H + +#include + +#include + +// --------------------------------------------------------------------------- +namespace android { + +class AppOpsManager +{ +public: + enum { + MODE_ALLOWED = IAppOpsService::MODE_ALLOWED, + MODE_IGNORED = IAppOpsService::MODE_IGNORED, + MODE_ERRORED = IAppOpsService::MODE_ERRORED + }; + + enum { + OP_NONE = -1, + OP_COARSE_LOCATION = 0, + OP_FINE_LOCATION = 1, + OP_GPS = 2, + OP_VIBRATE = 3, + OP_READ_CONTACTS = 4, + OP_WRITE_CONTACTS = 5, + OP_READ_CALL_LOG = 6, + OP_WRITE_CALL_LOG = 7, + OP_READ_CALENDAR = 8, + OP_WRITE_CALENDAR = 9, + OP_WIFI_SCAN = 10, + OP_POST_NOTIFICATION = 11, + OP_NEIGHBORING_CELLS = 12, + OP_CALL_PHONE = 13, + OP_READ_SMS = 14, + OP_WRITE_SMS = 15, + OP_RECEIVE_SMS = 16, + OP_RECEIVE_EMERGECY_SMS = 17, + OP_RECEIVE_MMS = 18, + OP_RECEIVE_WAP_PUSH = 19, + OP_SEND_SMS = 20, + OP_READ_ICC_SMS = 21, + OP_WRITE_ICC_SMS = 22, + OP_WRITE_SETTINGS = 23, + OP_SYSTEM_ALERT_WINDOW = 24, + OP_ACCESS_NOTIFICATIONS = 25, + OP_CAMERA = 26, + OP_RECORD_AUDIO = 27, + OP_PLAY_AUDIO = 28, + OP_READ_CLIPBOARD = 29, + OP_WRITE_CLIPBOARD = 30, + OP_TAKE_MEDIA_BUTTONS = 31, + OP_TAKE_AUDIO_FOCUS = 32, + OP_AUDIO_MASTER_VOLUME = 33, + OP_AUDIO_VOICE_VOLUME = 34, + OP_AUDIO_RING_VOLUME = 35, + OP_AUDIO_MEDIA_VOLUME = 36, + OP_AUDIO_ALARM_VOLUME = 37, + OP_AUDIO_NOTIFICATION_VOLUME = 38, + OP_AUDIO_BLUETOOTH_VOLUME = 39, + OP_WAKE_LOCK = 40, + OP_MONITOR_LOCATION = 41, + OP_MONITOR_HIGH_POWER_LOCATION = 42, + OP_GET_USAGE_STATS = 43, + OP_MUTE_MICROPHONE = 44, + OP_TOAST_WINDOW = 45, + OP_PROJECT_MEDIA = 46, + OP_ACTIVATE_VPN = 47, + OP_WRITE_WALLPAPER = 48, + OP_ASSIST_STRUCTURE = 49, + OP_ASSIST_SCREENSHOT = 50, + OP_READ_PHONE_STATE = 51, + OP_ADD_VOICEMAIL = 52, + OP_USE_SIP = 53, + OP_PROCESS_OUTGOING_CALLS = 54, + OP_USE_FINGERPRINT = 55, + OP_BODY_SENSORS = 56, + OP_READ_CELL_BROADCASTS = 57, + OP_MOCK_LOCATION = 58, + OP_READ_EXTERNAL_STORAGE = 59, + OP_WRITE_EXTERNAL_STORAGE = 60, + OP_TURN_SCREEN_ON = 61, + OP_GET_ACCOUNTS = 62, + OP_WIFI_CHANGE = 63, + OP_BLUETOOTH_CHANGE = 64, + OP_BOOT_COMPLETED = 65, + OP_NFC_CHANGE = 66, + OP_DATA_CONNECT_CHANGE = 67, + OP_SU = 68 + }; + + AppOpsManager(); + + int32_t checkOp(int32_t op, int32_t uid, const String16& callingPackage); + int32_t noteOp(int32_t op, int32_t uid, const String16& callingPackage); + int32_t startOp(int32_t op, int32_t uid, const String16& callingPackage); + void finishOp(int32_t op, int32_t uid, const String16& callingPackage); + void startWatchingMode(int32_t op, const String16& packageName, + const sp& callback); + void stopWatchingMode(const sp& callback); + int32_t permissionToOpCode(const String16& permission); + +private: + Mutex mLock; + sp mService; + + sp getService(); +}; + + +}; // namespace android +// --------------------------------------------------------------------------- +#endif // ANDROID_APP_OPS_MANAGER_H diff --git a/phonelibs/android_frameworks_native/include/binder/Binder.h b/phonelibs/android_frameworks_native/include/binder/Binder.h new file mode 100644 index 00000000000000..86628a03d351e6 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/Binder.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_BINDER_H +#define ANDROID_BINDER_H + +#include +#include +#include + +// --------------------------------------------------------------------------- +namespace android { + +class BBinder : public IBinder +{ +public: + BBinder(); + + virtual const String16& getInterfaceDescriptor() const; + virtual bool isBinderAlive() const; + virtual status_t pingBinder(); + virtual status_t dump(int fd, const Vector& args); + + virtual status_t transact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); + + virtual status_t linkToDeath(const sp& recipient, + void* cookie = NULL, + uint32_t flags = 0); + + virtual status_t unlinkToDeath( const wp& recipient, + void* cookie = NULL, + uint32_t flags = 0, + wp* outRecipient = NULL); + + virtual void attachObject( const void* objectID, + void* object, + void* cleanupCookie, + object_cleanup_func func); + virtual void* findObject(const void* objectID) const; + virtual void detachObject(const void* objectID); + + virtual BBinder* localBinder(); + +protected: + virtual ~BBinder(); + + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); + +private: + BBinder(const BBinder& o); + BBinder& operator=(const BBinder& o); + + class Extras; + + atomic_uintptr_t mExtras; // should be atomic + void* mReserved0; +}; + +// --------------------------------------------------------------------------- + +class BpRefBase : public virtual RefBase +{ +protected: + BpRefBase(const sp& o); + virtual ~BpRefBase(); + virtual void onFirstRef(); + virtual void onLastStrongRef(const void* id); + virtual bool onIncStrongAttempted(uint32_t flags, const void* id); + + inline IBinder* remote() { return mRemote; } + inline IBinder* remote() const { return mRemote; } + +private: + BpRefBase(const BpRefBase& o); + BpRefBase& operator=(const BpRefBase& o); + + IBinder* const mRemote; + RefBase::weakref_type* mRefs; + volatile int32_t mState; +}; + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_BINDER_H diff --git a/phonelibs/android_frameworks_native/include/binder/BinderService.h b/phonelibs/android_frameworks_native/include/binder/BinderService.h new file mode 100644 index 00000000000000..ef703bda904b9e --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/BinderService.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_BINDER_SERVICE_H +#define ANDROID_BINDER_SERVICE_H + +#include + +#include +#include + +#include +#include +#include +#include + +// --------------------------------------------------------------------------- +namespace android { + +template +class BinderService +{ +public: + static status_t publish(bool allowIsolated = false) { + sp sm(defaultServiceManager()); + return sm->addService( + String16(SERVICE::getServiceName()), + new SERVICE(), allowIsolated); + } + + static void publishAndJoinThreadPool(bool allowIsolated = false) { + publish(allowIsolated); + joinThreadPool(); + } + + static void instantiate() { publish(); } + + static status_t shutdown() { return NO_ERROR; } + +private: + static void joinThreadPool() { + sp ps(ProcessState::self()); + ps->startThreadPool(); + ps->giveThreadPoolName(); + IPCThreadState::self()->joinThreadPool(); + } +}; + + +}; // namespace android +// --------------------------------------------------------------------------- +#endif // ANDROID_BINDER_SERVICE_H diff --git a/phonelibs/android_frameworks_native/include/binder/BpBinder.h b/phonelibs/android_frameworks_native/include/binder/BpBinder.h new file mode 100644 index 00000000000000..7ef93aa390414f --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/BpBinder.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_BPBINDER_H +#define ANDROID_BPBINDER_H + +#include +#include +#include + +// --------------------------------------------------------------------------- +namespace android { + +class BpBinder : public IBinder +{ +public: + BpBinder(int32_t handle); + + inline int32_t handle() const { return mHandle; } + + virtual const String16& getInterfaceDescriptor() const; + virtual bool isBinderAlive() const; + virtual status_t pingBinder(); + virtual status_t dump(int fd, const Vector& args); + + virtual status_t transact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); + + virtual status_t linkToDeath(const sp& recipient, + void* cookie = NULL, + uint32_t flags = 0); + virtual status_t unlinkToDeath( const wp& recipient, + void* cookie = NULL, + uint32_t flags = 0, + wp* outRecipient = NULL); + + virtual void attachObject( const void* objectID, + void* object, + void* cleanupCookie, + object_cleanup_func func); + virtual void* findObject(const void* objectID) const; + virtual void detachObject(const void* objectID); + + virtual BpBinder* remoteBinder(); + + status_t setConstantData(const void* data, size_t size); + void sendObituary(); + + class ObjectManager + { + public: + ObjectManager(); + ~ObjectManager(); + + void attach( const void* objectID, + void* object, + void* cleanupCookie, + IBinder::object_cleanup_func func); + void* find(const void* objectID) const; + void detach(const void* objectID); + + void kill(); + + private: + ObjectManager(const ObjectManager&); + ObjectManager& operator=(const ObjectManager&); + + struct entry_t + { + void* object; + void* cleanupCookie; + IBinder::object_cleanup_func func; + }; + + KeyedVector mObjects; + }; + +protected: + virtual ~BpBinder(); + virtual void onFirstRef(); + virtual void onLastStrongRef(const void* id); + virtual bool onIncStrongAttempted(uint32_t flags, const void* id); + +private: + const int32_t mHandle; + + struct Obituary { + wp recipient; + void* cookie; + uint32_t flags; + }; + + void reportOneDeath(const Obituary& obit); + bool isDescriptorCached() const; + + mutable Mutex mLock; + volatile int32_t mAlive; + volatile int32_t mObitsSent; + Vector* mObituaries; + ObjectManager mObjects; + Parcel* mConstantData; + mutable String16 mDescriptorCache; +}; + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_BPBINDER_H diff --git a/phonelibs/android_frameworks_native/include/binder/BufferedTextOutput.h b/phonelibs/android_frameworks_native/include/binder/BufferedTextOutput.h new file mode 100644 index 00000000000000..9a7c43bb13996d --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/BufferedTextOutput.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_BUFFEREDTEXTOUTPUT_H +#define ANDROID_BUFFEREDTEXTOUTPUT_H + +#include +#include +#include + +// --------------------------------------------------------------------------- +namespace android { + +class BufferedTextOutput : public TextOutput +{ +public: + //** Flags for constructor */ + enum { + MULTITHREADED = 0x0001 + }; + + BufferedTextOutput(uint32_t flags = 0); + virtual ~BufferedTextOutput(); + + virtual status_t print(const char* txt, size_t len); + virtual void moveIndent(int delta); + + virtual void pushBundle(); + virtual void popBundle(); + +protected: + virtual status_t writeLines(const struct iovec& vec, size_t N) = 0; + +private: + struct BufferState; + struct ThreadState; + + static ThreadState*getThreadState(); + static void threadDestructor(void *st); + + BufferState*getBuffer() const; + + uint32_t mFlags; + const int32_t mSeq; + const int32_t mIndex; + + Mutex mLock; + BufferState* mGlobalState; +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_BUFFEREDTEXTOUTPUT_H diff --git a/phonelibs/android_frameworks_native/include/binder/Debug.h b/phonelibs/android_frameworks_native/include/binder/Debug.h new file mode 100644 index 00000000000000..f6a335502fe2cc --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/Debug.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_BINDER_DEBUG_H +#define ANDROID_BINDER_DEBUG_H + +#include +#include + +namespace android { +// --------------------------------------------------------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +const char* stringForIndent(int32_t indentLevel); + +typedef void (*debugPrintFunc)(void* cookie, const char* txt); + +void printTypeCode(uint32_t typeCode, + debugPrintFunc func = 0, void* cookie = 0); + +void printHexData(int32_t indent, const void *buf, size_t length, + size_t bytesPerLine=16, int32_t singleLineBytesCutoff=16, + size_t alignment=0, bool cArrayStyle=false, + debugPrintFunc func = 0, void* cookie = 0); + +#ifdef __cplusplus +} +#endif + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_BINDER_DEBUG_H diff --git a/phonelibs/android_frameworks_native/include/binder/IAppOpsCallback.h b/phonelibs/android_frameworks_native/include/binder/IAppOpsCallback.h new file mode 100644 index 00000000000000..7f8eb0168b7224 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/IAppOpsCallback.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +#ifndef ANDROID_IAPP_OPS_CALLBACK_H +#define ANDROID_IAPP_OPS_CALLBACK_H + +#include + +namespace android { + +// ---------------------------------------------------------------------- + +class IAppOpsCallback : public IInterface +{ +public: + DECLARE_META_INTERFACE(AppOpsCallback); + + virtual void opChanged(int32_t op, const String16& packageName) = 0; + + enum { + OP_CHANGED_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + }; +}; + +// ---------------------------------------------------------------------- + +class BnAppOpsCallback : public BnInterface +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IAPP_OPS_CALLBACK_H + diff --git a/phonelibs/android_frameworks_native/include/binder/IAppOpsService.h b/phonelibs/android_frameworks_native/include/binder/IAppOpsService.h new file mode 100644 index 00000000000000..cd81efa363fe45 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/IAppOpsService.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +#ifndef ANDROID_IAPP_OPS_SERVICE_H +#define ANDROID_IAPP_OPS_SERVICE_H + +#include +#include + +namespace android { + +// ---------------------------------------------------------------------- + +class IAppOpsService : public IInterface +{ +public: + DECLARE_META_INTERFACE(AppOpsService); + + virtual int32_t checkOperation(int32_t code, int32_t uid, const String16& packageName) = 0; + virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName) = 0; + virtual int32_t startOperation(const sp& token, int32_t code, int32_t uid, + const String16& packageName) = 0; + virtual void finishOperation(const sp& token, int32_t code, int32_t uid, + const String16& packageName) = 0; + virtual void startWatchingMode(int32_t op, const String16& packageName, + const sp& callback) = 0; + virtual void stopWatchingMode(const sp& callback) = 0; + virtual sp getToken(const sp& clientToken) = 0; + virtual int32_t permissionToOpCode(const String16& permission) = 0; + + enum { + CHECK_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, + NOTE_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+1, + START_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+2, + FINISH_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+3, + START_WATCHING_MODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+4, + STOP_WATCHING_MODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+5, + GET_TOKEN_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+6, + PERMISSION_TO_OP_CODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+7, + }; + + enum { + MODE_ALLOWED = 0, + MODE_IGNORED = 1, + MODE_ERRORED = 2 + }; +}; + +// ---------------------------------------------------------------------- + +class BnAppOpsService : public BnInterface +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IAPP_OPS_SERVICE_H diff --git a/phonelibs/android_frameworks_native/include/binder/IBatteryStats.h b/phonelibs/android_frameworks_native/include/binder/IBatteryStats.h new file mode 100644 index 00000000000000..5f3818652be2dc --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/IBatteryStats.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IBATTERYSTATS_H +#define ANDROID_IBATTERYSTATS_H + +#include + +namespace android { + +// ---------------------------------------------------------------------- + +class IBatteryStats : public IInterface +{ +public: + DECLARE_META_INTERFACE(BatteryStats); + + virtual void noteStartSensor(int uid, int sensor) = 0; + virtual void noteStopSensor(int uid, int sensor) = 0; + virtual void noteStartVideo(int uid) = 0; + virtual void noteStopVideo(int uid) = 0; + virtual void noteStartAudio(int uid) = 0; + virtual void noteStopAudio(int uid) = 0; + virtual void noteResetVideo() = 0; + virtual void noteResetAudio() = 0; + virtual void noteFlashlightOn(int uid) = 0; + virtual void noteFlashlightOff(int uid) = 0; + virtual void noteStartCamera(int uid) = 0; + virtual void noteStopCamera(int uid) = 0; + virtual void noteResetCamera() = 0; + virtual void noteResetFlashlight() = 0; + + enum { + NOTE_START_SENSOR_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, + NOTE_STOP_SENSOR_TRANSACTION, + NOTE_START_VIDEO_TRANSACTION, + NOTE_STOP_VIDEO_TRANSACTION, + NOTE_START_AUDIO_TRANSACTION, + NOTE_STOP_AUDIO_TRANSACTION, + NOTE_RESET_VIDEO_TRANSACTION, + NOTE_RESET_AUDIO_TRANSACTION, + NOTE_FLASHLIGHT_ON_TRANSACTION, + NOTE_FLASHLIGHT_OFF_TRANSACTION, + NOTE_START_CAMERA_TRANSACTION, + NOTE_STOP_CAMERA_TRANSACTION, + NOTE_RESET_CAMERA_TRANSACTION, + NOTE_RESET_FLASHLIGHT_TRANSACTION + }; +}; + +// ---------------------------------------------------------------------- + +class BnBatteryStats : public BnInterface +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IBATTERYSTATS_H diff --git a/phonelibs/android_frameworks_native/include/binder/IBinder.h b/phonelibs/android_frameworks_native/include/binder/IBinder.h new file mode 100644 index 00000000000000..43b654334b027b --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/IBinder.h @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IBINDER_H +#define ANDROID_IBINDER_H + +#include +#include +#include +#include + + +#define B_PACK_CHARS(c1, c2, c3, c4) \ + ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4)) + +// --------------------------------------------------------------------------- +namespace android { + +class BBinder; +class BpBinder; +class IInterface; +class Parcel; + +/** + * Base class and low-level protocol for a remotable object. + * You can derive from this class to create an object for which other + * processes can hold references to it. Communication between processes + * (method calls, property get and set) is down through a low-level + * protocol implemented on top of the transact() API. + */ +class IBinder : public virtual RefBase +{ +public: + enum { + FIRST_CALL_TRANSACTION = 0x00000001, + LAST_CALL_TRANSACTION = 0x00ffffff, + + PING_TRANSACTION = B_PACK_CHARS('_','P','N','G'), + DUMP_TRANSACTION = B_PACK_CHARS('_','D','M','P'), + INTERFACE_TRANSACTION = B_PACK_CHARS('_', 'N', 'T', 'F'), + SYSPROPS_TRANSACTION = B_PACK_CHARS('_', 'S', 'P', 'R'), + + // Corresponds to TF_ONE_WAY -- an asynchronous call. + FLAG_ONEWAY = 0x00000001 + }; + + IBinder(); + + /** + * Check if this IBinder implements the interface named by + * @a descriptor. If it does, the base pointer to it is returned, + * which you can safely static_cast<> to the concrete C++ interface. + */ + virtual sp queryLocalInterface(const String16& descriptor); + + /** + * Return the canonical name of the interface provided by this IBinder + * object. + */ + virtual const String16& getInterfaceDescriptor() const = 0; + + virtual bool isBinderAlive() const = 0; + virtual status_t pingBinder() = 0; + virtual status_t dump(int fd, const Vector& args) = 0; + + virtual status_t transact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0) = 0; + + class DeathRecipient : public virtual RefBase + { + public: + virtual void binderDied(const wp& who) = 0; + }; + + /** + * Register the @a recipient for a notification if this binder + * goes away. If this binder object unexpectedly goes away + * (typically because its hosting process has been killed), + * then DeathRecipient::binderDied() will be called with a reference + * to this. + * + * The @a cookie is optional -- if non-NULL, it should be a + * memory address that you own (that is, you know it is unique). + * + * @note You will only receive death notifications for remote binders, + * as local binders by definition can't die without you dying as well. + * Trying to use this function on a local binder will result in an + * INVALID_OPERATION code being returned and nothing happening. + * + * @note This link always holds a weak reference to its recipient. + * + * @note You will only receive a weak reference to the dead + * binder. You should not try to promote this to a strong reference. + * (Nor should you need to, as there is nothing useful you can + * directly do with it now that it has passed on.) + */ + virtual status_t linkToDeath(const sp& recipient, + void* cookie = NULL, + uint32_t flags = 0) = 0; + + /** + * Remove a previously registered death notification. + * The @a recipient will no longer be called if this object + * dies. The @a cookie is optional. If non-NULL, you can + * supply a NULL @a recipient, and the recipient previously + * added with that cookie will be unlinked. + */ + virtual status_t unlinkToDeath( const wp& recipient, + void* cookie = NULL, + uint32_t flags = 0, + wp* outRecipient = NULL) = 0; + + virtual bool checkSubclass(const void* subclassID) const; + + typedef void (*object_cleanup_func)(const void* id, void* obj, void* cleanupCookie); + + virtual void attachObject( const void* objectID, + void* object, + void* cleanupCookie, + object_cleanup_func func) = 0; + virtual void* findObject(const void* objectID) const = 0; + virtual void detachObject(const void* objectID) = 0; + + virtual BBinder* localBinder(); + virtual BpBinder* remoteBinder(); + +protected: + virtual ~IBinder(); + +private: +}; + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_IBINDER_H diff --git a/phonelibs/android_frameworks_native/include/binder/IInterface.h b/phonelibs/android_frameworks_native/include/binder/IInterface.h new file mode 100644 index 00000000000000..4ce361380db7a2 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/IInterface.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +#ifndef ANDROID_IINTERFACE_H +#define ANDROID_IINTERFACE_H + +#include + +namespace android { + +// ---------------------------------------------------------------------- + +class IInterface : public virtual RefBase +{ +public: + IInterface(); + static sp asBinder(const IInterface*); + static sp asBinder(const sp&); + +protected: + virtual ~IInterface(); + virtual IBinder* onAsBinder() = 0; +}; + +// ---------------------------------------------------------------------- + +template +inline sp interface_cast(const sp& obj) +{ + return INTERFACE::asInterface(obj); +} + +// ---------------------------------------------------------------------- + +template +class BnInterface : public INTERFACE, public BBinder +{ +public: + virtual sp queryLocalInterface(const String16& _descriptor); + virtual const String16& getInterfaceDescriptor() const; + +protected: + virtual IBinder* onAsBinder(); +}; + +// ---------------------------------------------------------------------- + +template +class BpInterface : public INTERFACE, public BpRefBase +{ +public: + BpInterface(const sp& remote); + +protected: + virtual IBinder* onAsBinder(); +}; + +// ---------------------------------------------------------------------- + +#define DECLARE_META_INTERFACE(INTERFACE) \ + static const android::String16 descriptor; \ + static android::sp asInterface( \ + const android::sp& obj); \ + virtual const android::String16& getInterfaceDescriptor() const; \ + I##INTERFACE(); \ + virtual ~I##INTERFACE(); \ + + +#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ + const android::String16 I##INTERFACE::descriptor(NAME); \ + const android::String16& \ + I##INTERFACE::getInterfaceDescriptor() const { \ + return I##INTERFACE::descriptor; \ + } \ + android::sp I##INTERFACE::asInterface( \ + const android::sp& obj) \ + { \ + android::sp intr; \ + if (obj != NULL) { \ + intr = static_cast( \ + obj->queryLocalInterface( \ + I##INTERFACE::descriptor).get()); \ + if (intr == NULL) { \ + intr = new Bp##INTERFACE(obj); \ + } \ + } \ + return intr; \ + } \ + I##INTERFACE::I##INTERFACE() { } \ + I##INTERFACE::~I##INTERFACE() { } \ + + +#define CHECK_INTERFACE(interface, data, reply) \ + if (!data.checkInterface(this)) { return PERMISSION_DENIED; } \ + + +// ---------------------------------------------------------------------- +// No user-serviceable parts after this... + +template +inline sp BnInterface::queryLocalInterface( + const String16& _descriptor) +{ + if (_descriptor == INTERFACE::descriptor) return this; + return NULL; +} + +template +inline const String16& BnInterface::getInterfaceDescriptor() const +{ + return INTERFACE::getInterfaceDescriptor(); +} + +template +IBinder* BnInterface::onAsBinder() +{ + return this; +} + +template +inline BpInterface::BpInterface(const sp& remote) + : BpRefBase(remote) +{ +} + +template +inline IBinder* BpInterface::onAsBinder() +{ + return remote(); +} + +// ---------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IINTERFACE_H diff --git a/phonelibs/android_frameworks_native/include/binder/IMemory.h b/phonelibs/android_frameworks_native/include/binder/IMemory.h new file mode 100644 index 00000000000000..178ef85937301d --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/IMemory.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IMEMORY_H +#define ANDROID_IMEMORY_H + +#include +#include +#include + +#include +#include +#include + +namespace android { + +// ---------------------------------------------------------------------------- + +class IMemoryHeap : public IInterface +{ +public: + DECLARE_META_INTERFACE(MemoryHeap); + + // flags returned by getFlags() + enum { + READ_ONLY = 0x00000001, +#ifdef USE_MEMORY_HEAP_ION + USE_ION_FD = 0x00008000 +#else + USE_ION_FD = 0x00000008 +#endif + }; + + virtual int getHeapID() const = 0; + virtual void* getBase() const = 0; + virtual size_t getSize() const = 0; + virtual uint32_t getFlags() const = 0; + virtual uint32_t getOffset() const = 0; + + // these are there just for backward source compatibility + int32_t heapID() const { return getHeapID(); } + void* base() const { return getBase(); } + size_t virtualSize() const { return getSize(); } +}; + +class BnMemoryHeap : public BnInterface +{ +public: + virtual status_t onTransact( + uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); + + BnMemoryHeap(); +protected: + virtual ~BnMemoryHeap(); +}; + +// ---------------------------------------------------------------------------- + +class IMemory : public IInterface +{ +public: + DECLARE_META_INTERFACE(Memory); + + virtual sp getMemory(ssize_t* offset=0, size_t* size=0) const = 0; + + // helpers + void* fastPointer(const sp& heap, ssize_t offset) const; + void* pointer() const; + size_t size() const; + ssize_t offset() const; +}; + +class BnMemory : public BnInterface +{ +public: + virtual status_t onTransact( + uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); + + BnMemory(); +protected: + virtual ~BnMemory(); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IMEMORY_H diff --git a/phonelibs/android_frameworks_native/include/binder/IPCThreadState.h b/phonelibs/android_frameworks_native/include/binder/IPCThreadState.h new file mode 100644 index 00000000000000..1853cff235cec7 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/IPCThreadState.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IPC_THREAD_STATE_H +#define ANDROID_IPC_THREAD_STATE_H + +#include +#include +#include +#include + +#if defined(_WIN32) +typedef int uid_t; +#endif + +// --------------------------------------------------------------------------- +namespace android { + +class IPCThreadState +{ +public: + static IPCThreadState* self(); + static IPCThreadState* selfOrNull(); // self(), but won't instantiate + + sp process(); + + status_t clearLastError(); + + pid_t getCallingPid() const; + uid_t getCallingUid() const; + + void setStrictModePolicy(int32_t policy); + int32_t getStrictModePolicy() const; + + void setLastTransactionBinderFlags(int32_t flags); + int32_t getLastTransactionBinderFlags() const; + + int64_t clearCallingIdentity(); + void restoreCallingIdentity(int64_t token); + + int setupPolling(int* fd); + status_t handlePolledCommands(); + void flushCommands(); + + void joinThreadPool(bool isMain = true); + + // Stop the local process. + void stopProcess(bool immediate = true); + + status_t transact(int32_t handle, + uint32_t code, const Parcel& data, + Parcel* reply, uint32_t flags); + + void incStrongHandle(int32_t handle); + void decStrongHandle(int32_t handle); + void incWeakHandle(int32_t handle); + void decWeakHandle(int32_t handle); + status_t attemptIncStrongHandle(int32_t handle); + static void expungeHandle(int32_t handle, IBinder* binder); + status_t requestDeathNotification( int32_t handle, + BpBinder* proxy); + status_t clearDeathNotification( int32_t handle, + BpBinder* proxy); + + static void shutdown(); + + // Call this to disable switching threads to background scheduling when + // receiving incoming IPC calls. This is specifically here for the + // Android system process, since it expects to have background apps calling + // in to it but doesn't want to acquire locks in its services while in + // the background. + static void disableBackgroundScheduling(bool disable); + + // Call blocks until the number of executing binder threads is less than + // the maximum number of binder threads threads allowed for this process. + void blockUntilThreadAvailable(); + +private: + IPCThreadState(); + ~IPCThreadState(); + + status_t sendReply(const Parcel& reply, uint32_t flags); + status_t waitForResponse(Parcel *reply, + status_t *acquireResult=NULL); + status_t talkWithDriver(bool doReceive=true); + status_t writeTransactionData(int32_t cmd, + uint32_t binderFlags, + int32_t handle, + uint32_t code, + const Parcel& data, + status_t* statusBuffer); + status_t getAndExecuteCommand(); + status_t executeCommand(int32_t command); + void processPendingDerefs(); + + void clearCaller(); + + static void threadDestructor(void *st); + static void freeBuffer(Parcel* parcel, + const uint8_t* data, size_t dataSize, + const binder_size_t* objects, size_t objectsSize, + void* cookie); + + const sp mProcess; + const pid_t mMyThreadId; + Vector mPendingStrongDerefs; + Vector mPendingWeakDerefs; + + Parcel mIn; + Parcel mOut; + status_t mLastError; + pid_t mCallingPid; + uid_t mCallingUid; + int32_t mStrictModePolicy; + int32_t mLastTransactionBinderFlags; +}; + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_IPC_THREAD_STATE_H diff --git a/phonelibs/android_frameworks_native/include/binder/IPermissionController.h b/phonelibs/android_frameworks_native/include/binder/IPermissionController.h new file mode 100644 index 00000000000000..4e5fb34838c453 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/IPermissionController.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +#ifndef ANDROID_IPERMISSION_CONTROLLER_H +#define ANDROID_IPERMISSION_CONTROLLER_H + +#include +#include + +namespace android { + +// ---------------------------------------------------------------------- + +class IPermissionController : public IInterface +{ +public: + DECLARE_META_INTERFACE(PermissionController); + + virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid) = 0; + + virtual void getPackagesForUid(const uid_t uid, Vector &packages) = 0; + + virtual bool isRuntimePermission(const String16& permission) = 0; + + enum { + CHECK_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, + GET_PACKAGES_FOR_UID_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 1, + IS_RUNTIME_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 2 + }; +}; + +// ---------------------------------------------------------------------- + +class BnPermissionController : public BnInterface +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IPERMISSION_CONTROLLER_H + diff --git a/phonelibs/android_frameworks_native/include/binder/IProcessInfoService.h b/phonelibs/android_frameworks_native/include/binder/IProcessInfoService.h new file mode 100644 index 00000000000000..dc62f457c72ccf --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/IProcessInfoService.h @@ -0,0 +1,53 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_I_PROCESS_INFO_SERVICE_H +#define ANDROID_I_PROCESS_INFO_SERVICE_H + +#include + +namespace android { + +// ---------------------------------------------------------------------- + +class IProcessInfoService : public IInterface { +public: + DECLARE_META_INTERFACE(ProcessInfoService); + + virtual status_t getProcessStatesFromPids( size_t length, + /*in*/ int32_t* pids, + /*out*/ int32_t* states) = 0; + + enum { + GET_PROCESS_STATES_FROM_PIDS = IBinder::FIRST_CALL_TRANSACTION, + }; +}; + +// ---------------------------------------------------------------------- + +class BnProcessInfoService : public BnInterface { +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_I_PROCESS_INFO_SERVICE_H diff --git a/phonelibs/android_frameworks_native/include/binder/IServiceManager.h b/phonelibs/android_frameworks_native/include/binder/IServiceManager.h new file mode 100644 index 00000000000000..2c297d64fb510e --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/IServiceManager.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +#ifndef ANDROID_ISERVICE_MANAGER_H +#define ANDROID_ISERVICE_MANAGER_H + +#include +#include +#include +#include + +namespace android { + +// ---------------------------------------------------------------------- + +class IServiceManager : public IInterface +{ +public: + DECLARE_META_INTERFACE(ServiceManager); + + /** + * Retrieve an existing service, blocking for a few seconds + * if it doesn't yet exist. + */ + virtual sp getService( const String16& name) const = 0; + + /** + * Retrieve an existing service, non-blocking. + */ + virtual sp checkService( const String16& name) const = 0; + + /** + * Register a service. + */ + virtual status_t addService( const String16& name, + const sp& service, + bool allowIsolated = false) = 0; + + /** + * Return list of all existing services. + */ + virtual Vector listServices() = 0; + + enum { + GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, + CHECK_SERVICE_TRANSACTION, + ADD_SERVICE_TRANSACTION, + LIST_SERVICES_TRANSACTION, + }; +}; + +sp defaultServiceManager(); + +template +status_t getService(const String16& name, sp* outService) +{ + const sp sm = defaultServiceManager(); + if (sm != NULL) { + *outService = interface_cast(sm->getService(name)); + if ((*outService) != NULL) return NO_ERROR; + } + return NAME_NOT_FOUND; +} + +bool checkCallingPermission(const String16& permission); +bool checkCallingPermission(const String16& permission, + int32_t* outPid, int32_t* outUid); +bool checkPermission(const String16& permission, pid_t pid, uid_t uid); + + +// ---------------------------------------------------------------------- + +class BnServiceManager : public BnInterface +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_ISERVICE_MANAGER_H + diff --git a/phonelibs/android_frameworks_native/include/binder/MemoryBase.h b/phonelibs/android_frameworks_native/include/binder/MemoryBase.h new file mode 100644 index 00000000000000..463e26d9772fa4 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/MemoryBase.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_MEMORY_BASE_H +#define ANDROID_MEMORY_BASE_H + +#include +#include + +#include + + +namespace android { + +// --------------------------------------------------------------------------- + +class MemoryBase : public BnMemory +{ +public: + MemoryBase(const sp& heap, ssize_t offset, size_t size); + virtual ~MemoryBase(); + virtual sp getMemory(ssize_t* offset, size_t* size) const; + +protected: + size_t getSize() const { return mSize; } + ssize_t getOffset() const { return mOffset; } + const sp& getHeap() const { return mHeap; } + +private: + size_t mSize; + ssize_t mOffset; + sp mHeap; +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_MEMORY_BASE_H diff --git a/phonelibs/android_frameworks_native/include/binder/MemoryDealer.h b/phonelibs/android_frameworks_native/include/binder/MemoryDealer.h new file mode 100644 index 00000000000000..aa415d5ac84117 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/MemoryDealer.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_MEMORY_DEALER_H +#define ANDROID_MEMORY_DEALER_H + + +#include +#include + +#include +#include + +namespace android { +// ---------------------------------------------------------------------------- + +class SimpleBestFitAllocator; + +// ---------------------------------------------------------------------------- + +class MemoryDealer : public RefBase +{ +public: + MemoryDealer(size_t size, const char* name = 0, + uint32_t flags = 0 /* or bits such as MemoryHeapBase::READ_ONLY */ ); + + virtual sp allocate(size_t size); + virtual void deallocate(size_t offset); + virtual void dump(const char* what) const; + + sp getMemoryHeap() const { return heap(); } + +protected: + virtual ~MemoryDealer(); + +private: + const sp& heap() const; + SimpleBestFitAllocator* allocator() const; + + sp mHeap; + SimpleBestFitAllocator* mAllocator; +}; + + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_MEMORY_DEALER_H diff --git a/phonelibs/android_frameworks_native/include/binder/MemoryHeapBase.h b/phonelibs/android_frameworks_native/include/binder/MemoryHeapBase.h new file mode 100644 index 00000000000000..ea9b66c4976349 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/MemoryHeapBase.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_MEMORY_HEAP_BASE_H +#define ANDROID_MEMORY_HEAP_BASE_H + +#include +#include + +#include + + +namespace android { + +// --------------------------------------------------------------------------- + +class MemoryHeapBase : public virtual BnMemoryHeap +{ +public: + enum { + READ_ONLY = IMemoryHeap::READ_ONLY, + // memory won't be mapped locally, but will be mapped in the remote + // process. + DONT_MAP_LOCALLY = 0x00000100, + NO_CACHING = 0x00000200 + }; + + /* + * maps the memory referenced by fd. but DOESN'T take ownership + * of the filedescriptor (it makes a copy with dup() + */ + MemoryHeapBase(int fd, size_t size, uint32_t flags = 0, uint32_t offset = 0); + + /* + * maps memory from the given device + */ + MemoryHeapBase(const char* device, size_t size = 0, uint32_t flags = 0); + + /* + * maps memory from ashmem, with the given name for debugging + */ + MemoryHeapBase(size_t size, uint32_t flags = 0, char const* name = NULL); + + virtual ~MemoryHeapBase(); + + /* implement IMemoryHeap interface */ + virtual int getHeapID() const; + + /* virtual address of the heap. returns MAP_FAILED in case of error */ + virtual void* getBase() const; + + virtual size_t getSize() const; + virtual uint32_t getFlags() const; + virtual uint32_t getOffset() const; + + const char* getDevice() const; + + /* this closes this heap -- use carefully */ + void dispose(); + + /* this is only needed as a workaround, use only if you know + * what you are doing */ + status_t setDevice(const char* device) { + if (mDevice == 0) + mDevice = device; + return mDevice ? NO_ERROR : ALREADY_EXISTS; + } + +protected: + MemoryHeapBase(); + // init() takes ownership of fd + status_t init(int fd, void *base, int size, + int flags = 0, const char* device = NULL); + +private: + status_t mapfd(int fd, size_t size, uint32_t offset = 0); + + int mFD; + size_t mSize; + void* mBase; + uint32_t mFlags; + const char* mDevice; + bool mNeedUnmap; + uint32_t mOffset; +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_MEMORY_HEAP_BASE_H diff --git a/phonelibs/android_frameworks_native/include/binder/MemoryHeapIon.h b/phonelibs/android_frameworks_native/include/binder/MemoryHeapIon.h new file mode 100644 index 00000000000000..7e059f4eac2627 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/MemoryHeapIon.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * Copyright 2011, Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * \file MemoryHeapIon.h + * \brief header file for MemoryHeapIon + * \author MinGu, Jeon(mingu85.jeon) + * \date 2011/11/20 + * + * Revision History: + * - 2011/11/21 : MinGu, Jeon(mingu85.jeon)) \n + * Initial version + * - 2012/11/29 : MinGu, Jeon(mingu85.jeon)) \n + * Change name + */ + +#ifndef ANDROID_MEMORY_HEAP_ION_H +#define ANDROID_MEMORY_HEAP_ION_H + +#include +#include +#include + +#define MHB_ION_HEAP_SYSTEM_CONTIG_MASK (1 << 1) +#define MHB_ION_HEAP_EXYNOS_CONTIG_MASK (1 << 4) +#define MHB_ION_HEAP_EXYNOS_MASK (1 << 5) +#define MHB_ION_HEAP_SYSTEM_MASK (1 << 6) + +#define MHB_ION_FLAG_CACHED (1 << 16) +#define MHB_ION_FLAG_CACHED_NEEDS_SYNC (1 << 17) +#define MHB_ION_FLAG_PRESERVE_KMAP (1 << 18) + +#define MHB_ION_EXYNOS_VIDEO_MASK (1 << 21) +#define MHB_ION_EXYNOS_MFC_INPUT_MASK (1 << 25) +#define MHB_ION_EXYNOS_MFC_OUTPUT_MASK (1 << 26) +#define MHB_ION_EXYNOS_GSC_MASK (1 << 27) +#define MHB_ION_EXYNOS_FIMD_VIDEO_MASK (1 << 28) + +namespace android { + +class MemoryHeapIon : public MemoryHeapBase +{ +public: + enum { + USE_ION_FD = IMemoryHeap::USE_ION_FD + }; + MemoryHeapIon(size_t size, uint32_t flags = 0, char const* name = NULL); + MemoryHeapIon(int fd, size_t size, uint32_t flags = 0, uint32_t offset = 0); + ~MemoryHeapIon(); +private: + int mIonClient; +}; + +}; +#endif diff --git a/phonelibs/android_frameworks_native/include/binder/Parcel.h b/phonelibs/android_frameworks_native/include/binder/Parcel.h new file mode 100644 index 00000000000000..91ffae0ba3520b --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/Parcel.h @@ -0,0 +1,436 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_PARCEL_H +#define ANDROID_PARCEL_H + +#include +#include +#include +#include +#include +#include +#include + +// --------------------------------------------------------------------------- +namespace android { + +template class Flattenable; +template class LightFlattenable; +class IBinder; +class IPCThreadState; +class ProcessState; +class String8; +class TextOutput; + +class Parcel { + friend class IPCThreadState; +public: + class ReadableBlob; + class WritableBlob; + + Parcel(); + ~Parcel(); + + const uint8_t* data() const; + size_t dataSize() const; + size_t dataAvail() const; + size_t dataPosition() const; + size_t dataCapacity() const; + + status_t setDataSize(size_t size); + void setDataPosition(size_t pos) const; + status_t setDataCapacity(size_t size); + + status_t setData(const uint8_t* buffer, size_t len); + + status_t appendFrom(const Parcel *parcel, + size_t start, size_t len); + + bool allowFds() const; + bool pushAllowFds(bool allowFds); + void restoreAllowFds(bool lastValue); + + bool hasFileDescriptors() const; + + // Writes the RPC header. + status_t writeInterfaceToken(const String16& interface); + + // Parses the RPC header, returning true if the interface name + // in the header matches the expected interface from the caller. + // + // Additionally, enforceInterface does part of the work of + // propagating the StrictMode policy mask, populating the current + // IPCThreadState, which as an optimization may optionally be + // passed in. + bool enforceInterface(const String16& interface, + IPCThreadState* threadState = NULL) const; + bool checkInterface(IBinder*) const; + + void freeData(); + +private: + const binder_size_t* objects() const; + +public: + size_t objectsCount() const; + + status_t errorCheck() const; + void setError(status_t err); + + status_t write(const void* data, size_t len); + void* writeInplace(size_t len); + status_t writeUnpadded(const void* data, size_t len); + status_t writeInt32(int32_t val); + status_t writeUint32(uint32_t val); + status_t writeInt64(int64_t val); + status_t writeUint64(uint64_t val); + status_t writeFloat(float val); + status_t writeDouble(double val); + status_t writeCString(const char* str); + status_t writeString8(const String8& str); + status_t writeString16(const String16& str); + status_t writeString16(const char16_t* str, size_t len); + status_t writeStrongBinder(const sp& val); + status_t writeWeakBinder(const wp& val); + status_t writeInt32Array(size_t len, const int32_t *val); + status_t writeByteArray(size_t len, const uint8_t *val); + + template + status_t write(const Flattenable& val); + + template + status_t write(const LightFlattenable& val); + + + // Place a native_handle into the parcel (the native_handle's file- + // descriptors are dup'ed, so it is safe to delete the native_handle + // when this function returns). + // Doesn't take ownership of the native_handle. + status_t writeNativeHandle(const native_handle* handle); + + // Place a file descriptor into the parcel. The given fd must remain + // valid for the lifetime of the parcel. + // The Parcel does not take ownership of the given fd unless you ask it to. + status_t writeFileDescriptor(int fd, bool takeOwnership = false); + + // Place a file descriptor into the parcel. A dup of the fd is made, which + // will be closed once the parcel is destroyed. + status_t writeDupFileDescriptor(int fd); + + // Writes a blob to the parcel. + // If the blob is small, then it is stored in-place, otherwise it is + // transferred by way of an anonymous shared memory region. Prefer sending + // immutable blobs if possible since they may be subsequently transferred between + // processes without further copying whereas mutable blobs always need to be copied. + // The caller should call release() on the blob after writing its contents. + status_t writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob); + + // Write an existing immutable blob file descriptor to the parcel. + // This allows the client to send the same blob to multiple processes + // as long as it keeps a dup of the blob file descriptor handy for later. + status_t writeDupImmutableBlobFileDescriptor(int fd); + + status_t writeObject(const flat_binder_object& val, bool nullMetaData); + + // Like Parcel.java's writeNoException(). Just writes a zero int32. + // Currently the native implementation doesn't do any of the StrictMode + // stack gathering and serialization that the Java implementation does. + status_t writeNoException(); + + void remove(size_t start, size_t amt); + + status_t read(void* outData, size_t len) const; + const void* readInplace(size_t len) const; + int32_t readInt32() const; + status_t readInt32(int32_t *pArg) const; + uint32_t readUint32() const; + status_t readUint32(uint32_t *pArg) const; + int64_t readInt64() const; + status_t readInt64(int64_t *pArg) const; + uint64_t readUint64() const; + status_t readUint64(uint64_t *pArg) const; + float readFloat() const; + status_t readFloat(float *pArg) const; + double readDouble() const; + status_t readDouble(double *pArg) const; + intptr_t readIntPtr() const; + status_t readIntPtr(intptr_t *pArg) const; + + const char* readCString() const; + String8 readString8() const; + String16 readString16() const; + const char16_t* readString16Inplace(size_t* outLen) const; + sp readStrongBinder() const; + wp readWeakBinder() const; + + template + status_t read(Flattenable& val) const; + + template + status_t read(LightFlattenable& val) const; + + // Like Parcel.java's readExceptionCode(). Reads the first int32 + // off of a Parcel's header, returning 0 or the negative error + // code on exceptions, but also deals with skipping over rich + // response headers. Callers should use this to read & parse the + // response headers rather than doing it by hand. + int32_t readExceptionCode() const; + + // Retrieve native_handle from the parcel. This returns a copy of the + // parcel's native_handle (the caller takes ownership). The caller + // must free the native_handle with native_handle_close() and + // native_handle_delete(). + native_handle* readNativeHandle() const; + + + // Retrieve a file descriptor from the parcel. This returns the raw fd + // in the parcel, which you do not own -- use dup() to get your own copy. + int readFileDescriptor() const; + + // Reads a blob from the parcel. + // The caller should call release() on the blob after reading its contents. + status_t readBlob(size_t len, ReadableBlob* outBlob) const; + + const flat_binder_object* readObject(bool nullMetaData) const; + + // Explicitly close all file descriptors in the parcel. + void closeFileDescriptors(); + + // Debugging: get metrics on current allocations. + static size_t getGlobalAllocSize(); + static size_t getGlobalAllocCount(); + +private: + typedef void (*release_func)(Parcel* parcel, + const uint8_t* data, size_t dataSize, + const binder_size_t* objects, size_t objectsSize, + void* cookie); + + uintptr_t ipcData() const; + size_t ipcDataSize() const; + uintptr_t ipcObjects() const; + size_t ipcObjectsCount() const; + void ipcSetDataReference(const uint8_t* data, size_t dataSize, + const binder_size_t* objects, size_t objectsCount, + release_func relFunc, void* relCookie); + +public: + void print(TextOutput& to, uint32_t flags = 0) const; + +private: + Parcel(const Parcel& o); + Parcel& operator=(const Parcel& o); + + status_t finishWrite(size_t len); + void releaseObjects(); + void acquireObjects(); + status_t growData(size_t len); + status_t restartWrite(size_t desired); + status_t continueWrite(size_t desired); + status_t writePointer(uintptr_t val); + status_t readPointer(uintptr_t *pArg) const; + uintptr_t readPointer() const; + void freeDataNoInit(); + void initState(); + void scanForFds() const; + + template + status_t readAligned(T *pArg) const; + + template T readAligned() const; + + template + status_t writeAligned(T val); + + status_t mError; + uint8_t* mData; + size_t mDataSize; + size_t mDataCapacity; + mutable size_t mDataPos; + binder_size_t* mObjects; + size_t mObjectsSize; + size_t mObjectsCapacity; + mutable size_t mNextObjectHint; + + mutable bool mFdsKnown; + mutable bool mHasFds; + bool mAllowFds; + + release_func mOwner; + void* mOwnerCookie; + + class Blob { + public: + Blob(); + ~Blob(); + + void clear(); + void release(); + inline size_t size() const { return mSize; } + inline int fd() const { return mFd; }; + inline bool isMutable() const { return mMutable; } + + protected: + void init(int fd, void* data, size_t size, bool isMutable); + + int mFd; // owned by parcel so not closed when released + void* mData; + size_t mSize; + bool mMutable; + }; + + class FlattenableHelperInterface { + protected: + ~FlattenableHelperInterface() { } + public: + virtual size_t getFlattenedSize() const = 0; + virtual size_t getFdCount() const = 0; + virtual status_t flatten(void* buffer, size_t size, int* fds, size_t count) const = 0; + virtual status_t unflatten(void const* buffer, size_t size, int const* fds, size_t count) = 0; + }; + + template + class FlattenableHelper : public FlattenableHelperInterface { + friend class Parcel; + const Flattenable& val; + explicit FlattenableHelper(const Flattenable& val) : val(val) { } + + public: + virtual size_t getFlattenedSize() const { + return val.getFlattenedSize(); + } + virtual size_t getFdCount() const { + return val.getFdCount(); + } + virtual status_t flatten(void* buffer, size_t size, int* fds, size_t count) const { + return val.flatten(buffer, size, fds, count); + } + virtual status_t unflatten(void const* buffer, size_t size, int const* fds, size_t count) { + return const_cast&>(val).unflatten(buffer, size, fds, count); + } + }; + status_t write(const FlattenableHelperInterface& val); + status_t read(FlattenableHelperInterface& val) const; + +public: + class ReadableBlob : public Blob { + friend class Parcel; + public: + inline const void* data() const { return mData; } + inline void* mutableData() { return isMutable() ? mData : NULL; } + }; + + class WritableBlob : public Blob { + friend class Parcel; + public: + inline void* data() { return mData; } + }; + +#ifndef DISABLE_ASHMEM_TRACKING +private: + size_t mOpenAshmemSize; +#endif + +public: + // TODO: Remove once ABI can be changed. + size_t getBlobAshmemSize() const; + size_t getOpenAshmemSize() const; +}; + +// --------------------------------------------------------------------------- + +template +status_t Parcel::write(const Flattenable& val) { + const FlattenableHelper helper(val); + return write(helper); +} + +template +status_t Parcel::write(const LightFlattenable& val) { + size_t size(val.getFlattenedSize()); + if (!val.isFixedSize()) { + status_t err = writeInt32(size); + if (err != NO_ERROR) { + return err; + } + } + if (size) { + void* buffer = writeInplace(size); + if (buffer == NULL) + return NO_MEMORY; + return val.flatten(buffer, size); + } + return NO_ERROR; +} + +template +status_t Parcel::read(Flattenable& val) const { + FlattenableHelper helper(val); + return read(helper); +} + +template +status_t Parcel::read(LightFlattenable& val) const { + size_t size; + if (val.isFixedSize()) { + size = val.getFlattenedSize(); + } else { + int32_t s; + status_t err = readInt32(&s); + if (err != NO_ERROR) { + return err; + } + size = s; + } + if (size) { + void const* buffer = readInplace(size); + return buffer == NULL ? NO_MEMORY : + val.unflatten(buffer, size); + } + return NO_ERROR; +} + +// --------------------------------------------------------------------------- + +inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel) +{ + parcel.print(to); + return to; +} + +// --------------------------------------------------------------------------- + +// Generic acquire and release of objects. +void acquire_object(const sp& proc, + const flat_binder_object& obj, const void* who); +void release_object(const sp& proc, + const flat_binder_object& obj, const void* who); + +void flatten_binder(const sp& proc, + const sp& binder, flat_binder_object* out); +void flatten_binder(const sp& proc, + const wp& binder, flat_binder_object* out); +status_t unflatten_binder(const sp& proc, + const flat_binder_object& flat, sp* out); +status_t unflatten_binder(const sp& proc, + const flat_binder_object& flat, wp* out); + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_PARCEL_H diff --git a/phonelibs/android_frameworks_native/include/binder/PermissionCache.h b/phonelibs/android_frameworks_native/include/binder/PermissionCache.h new file mode 100644 index 00000000000000..bcdf0c291434ed --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/PermissionCache.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BINDER_PERMISSION_H +#define BINDER_PERMISSION_H + +#include +#include + +#include +#include +#include + +namespace android { +// --------------------------------------------------------------------------- + +/* + * PermissionCache caches permission checks for a given uid. + * + * Currently the cache is not updated when there is a permission change, + * for instance when an application is uninstalled. + * + * IMPORTANT: for the reason stated above, only system permissions are safe + * to cache. This restriction may be lifted at a later time. + * + */ + +class PermissionCache : Singleton { + struct Entry { + String16 name; + uid_t uid; + bool granted; + inline bool operator < (const Entry& e) const { + return (uid == e.uid) ? (name < e.name) : (uid < e.uid); + } + }; + mutable Mutex mLock; + // we pool all the permission names we see, as many permissions checks + // will have identical names + SortedVector< String16 > mPermissionNamesPool; + // this is our cache per say. it stores pooled names. + SortedVector< Entry > mCache; + + // free the whole cache, but keep the permission name pool + void purge(); + + status_t check(bool* granted, + const String16& permission, uid_t uid) const; + + void cache(const String16& permission, uid_t uid, bool granted); + +public: + PermissionCache(); + + static bool checkCallingPermission(const String16& permission); + + static bool checkCallingPermission(const String16& permission, + int32_t* outPid, int32_t* outUid); + + static bool checkPermission(const String16& permission, + pid_t pid, uid_t uid); +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif /* BINDER_PERMISSION_H */ diff --git a/phonelibs/android_frameworks_native/include/binder/ProcessInfoService.h b/phonelibs/android_frameworks_native/include/binder/ProcessInfoService.h new file mode 100644 index 00000000000000..c5ead2067657a0 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/ProcessInfoService.h @@ -0,0 +1,65 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_PROCESS_INFO_SERVICE_H +#define ANDROID_PROCESS_INFO_SERVICE_H + +#include +#include +#include +#include + +namespace android { + +// ---------------------------------------------------------------------- + +class ProcessInfoService : public Singleton { + + friend class Singleton; + sp mProcessInfoService; + Mutex mProcessInfoLock; + + ProcessInfoService(); + + status_t getProcessStatesImpl(size_t length, /*in*/ int32_t* pids, /*out*/ int32_t* states); + void updateBinderLocked(); + + static const int BINDER_ATTEMPT_LIMIT = 5; + +public: + + /** + * For each PID in the given "pids" input array, write the current process state + * for that process into the "states" output array, or + * ActivityManager.PROCESS_STATE_NONEXISTENT * to indicate that no process with the given PID + * exists. + * + * Returns NO_ERROR if this operation was successful, or a negative error code otherwise. + */ + static status_t getProcessStatesFromPids(size_t length, /*in*/ int32_t* pids, + /*out*/ int32_t* states) { + return ProcessInfoService::getInstance().getProcessStatesImpl(length, /*in*/ pids, + /*out*/ states); + } + +}; + +// ---------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_PROCESS_INFO_SERVICE_H + diff --git a/phonelibs/android_frameworks_native/include/binder/ProcessState.h b/phonelibs/android_frameworks_native/include/binder/ProcessState.h new file mode 100644 index 00000000000000..f9edc2a691fc02 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/ProcessState.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_PROCESS_STATE_H +#define ANDROID_PROCESS_STATE_H + +#include +#include +#include +#include + +#include + +#include + +// --------------------------------------------------------------------------- +namespace android { + +class IPCThreadState; + +class ProcessState : public virtual RefBase +{ +public: + static sp self(); + + void setContextObject(const sp& object); + sp getContextObject(const sp& caller); + + void setContextObject(const sp& object, + const String16& name); + sp getContextObject(const String16& name, + const sp& caller); + + void startThreadPool(); + + typedef bool (*context_check_func)(const String16& name, + const sp& caller, + void* userData); + + bool isContextManager(void) const; + bool becomeContextManager( + context_check_func checkFunc, + void* userData); + + sp getStrongProxyForHandle(int32_t handle); + wp getWeakProxyForHandle(int32_t handle); + void expungeHandle(int32_t handle, IBinder* binder); + + void spawnPooledThread(bool isMain); + + status_t setThreadPoolMaxThreadCount(size_t maxThreads); + void giveThreadPoolName(); + +private: + friend class IPCThreadState; + + ProcessState(); + ~ProcessState(); + + ProcessState(const ProcessState& o); + ProcessState& operator=(const ProcessState& o); + String8 makeBinderThreadName(); + + struct handle_entry { + IBinder* binder; + RefBase::weakref_type* refs; + }; + + handle_entry* lookupHandleLocked(int32_t handle); + + int mDriverFD; + void* mVMStart; + + // Protects thread count variable below. + pthread_mutex_t mThreadCountLock; + pthread_cond_t mThreadCountDecrement; + // Number of binder threads current executing a command. + size_t mExecutingThreadsCount; + // Maximum number for binder threads allowed for this process. + size_t mMaxThreads; + + mutable Mutex mLock; // protects everything below. + + VectormHandleToObject; + + bool mManagesContexts; + context_check_func mBinderContextCheckFunc; + void* mBinderContextUserData; + + KeyedVector > + mContexts; + + + String8 mRootDir; + bool mThreadPoolStarted; + volatile int32_t mThreadPoolSeq; +}; + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_PROCESS_STATE_H diff --git a/phonelibs/android_frameworks_native/include/binder/TextOutput.h b/phonelibs/android_frameworks_native/include/binder/TextOutput.h new file mode 100644 index 00000000000000..974a194d8c4631 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/binder/TextOutput.h @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_TEXTOUTPUT_H +#define ANDROID_TEXTOUTPUT_H + +#include + +#include +#include + +// --------------------------------------------------------------------------- +namespace android { + +class String8; +class String16; + +class TextOutput +{ +public: + TextOutput(); + virtual ~TextOutput(); + + virtual status_t print(const char* txt, size_t len) = 0; + virtual void moveIndent(int delta) = 0; + + class Bundle { + public: + inline Bundle(TextOutput& to) : mTO(to) { to.pushBundle(); } + inline ~Bundle() { mTO.popBundle(); } + private: + TextOutput& mTO; + }; + + virtual void pushBundle() = 0; + virtual void popBundle() = 0; +}; + +// --------------------------------------------------------------------------- + +// Text output stream for printing to the log (via utils/Log.h). +extern TextOutput& alog; + +// Text output stream for printing to stdout. +extern TextOutput& aout; + +// Text output stream for printing to stderr. +extern TextOutput& aerr; + +typedef TextOutput& (*TextOutputManipFunc)(TextOutput&); + +TextOutput& endl(TextOutput& to); +TextOutput& indent(TextOutput& to); +TextOutput& dedent(TextOutput& to); + +TextOutput& operator<<(TextOutput& to, const char* str); +TextOutput& operator<<(TextOutput& to, char); // writes raw character +TextOutput& operator<<(TextOutput& to, bool); +TextOutput& operator<<(TextOutput& to, int); +TextOutput& operator<<(TextOutput& to, long); +TextOutput& operator<<(TextOutput& to, unsigned int); +TextOutput& operator<<(TextOutput& to, unsigned long); +TextOutput& operator<<(TextOutput& to, long long); +TextOutput& operator<<(TextOutput& to, unsigned long long); +TextOutput& operator<<(TextOutput& to, float); +TextOutput& operator<<(TextOutput& to, double); +TextOutput& operator<<(TextOutput& to, TextOutputManipFunc func); +TextOutput& operator<<(TextOutput& to, const void*); +TextOutput& operator<<(TextOutput& to, const String8& val); +TextOutput& operator<<(TextOutput& to, const String16& val); + +class TypeCode +{ +public: + inline TypeCode(uint32_t code); + inline ~TypeCode(); + + inline uint32_t typeCode() const; + +private: + uint32_t mCode; +}; + +TextOutput& operator<<(TextOutput& to, const TypeCode& val); + +class HexDump +{ +public: + HexDump(const void *buf, size_t size, size_t bytesPerLine=16); + inline ~HexDump(); + + inline HexDump& setBytesPerLine(size_t bytesPerLine); + inline HexDump& setSingleLineCutoff(int32_t bytes); + inline HexDump& setAlignment(size_t alignment); + inline HexDump& setCArrayStyle(bool enabled); + + inline const void* buffer() const; + inline size_t size() const; + inline size_t bytesPerLine() const; + inline int32_t singleLineCutoff() const; + inline size_t alignment() const; + inline bool carrayStyle() const; + +private: + const void* mBuffer; + size_t mSize; + size_t mBytesPerLine; + int32_t mSingleLineCutoff; + size_t mAlignment; + bool mCArrayStyle; +}; + +TextOutput& operator<<(TextOutput& to, const HexDump& val); + +// --------------------------------------------------------------------------- +// No user servicable parts below. + +inline TextOutput& endl(TextOutput& to) +{ + to.print("\n", 1); + return to; +} + +inline TextOutput& indent(TextOutput& to) +{ + to.moveIndent(1); + return to; +} + +inline TextOutput& dedent(TextOutput& to) +{ + to.moveIndent(-1); + return to; +} + +inline TextOutput& operator<<(TextOutput& to, const char* str) +{ + to.print(str, strlen(str)); + return to; +} + +inline TextOutput& operator<<(TextOutput& to, char c) +{ + to.print(&c, 1); + return to; +} + +inline TextOutput& operator<<(TextOutput& to, TextOutputManipFunc func) +{ + return (*func)(to); +} + +inline TypeCode::TypeCode(uint32_t code) : mCode(code) { } +inline TypeCode::~TypeCode() { } +inline uint32_t TypeCode::typeCode() const { return mCode; } + +inline HexDump::~HexDump() { } + +inline HexDump& HexDump::setBytesPerLine(size_t bytesPerLine) { + mBytesPerLine = bytesPerLine; return *this; +} +inline HexDump& HexDump::setSingleLineCutoff(int32_t bytes) { + mSingleLineCutoff = bytes; return *this; +} +inline HexDump& HexDump::setAlignment(size_t alignment) { + mAlignment = alignment; return *this; +} +inline HexDump& HexDump::setCArrayStyle(bool enabled) { + mCArrayStyle = enabled; return *this; +} + +inline const void* HexDump::buffer() const { return mBuffer; } +inline size_t HexDump::size() const { return mSize; } +inline size_t HexDump::bytesPerLine() const { return mBytesPerLine; } +inline int32_t HexDump::singleLineCutoff() const { return mSingleLineCutoff; } +inline size_t HexDump::alignment() const { return mAlignment; } +inline bool HexDump::carrayStyle() const { return mCArrayStyle; } + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_TEXTOUTPUT_H diff --git a/phonelibs/android_frameworks_native/include/diskusage/dirsize.h b/phonelibs/android_frameworks_native/include/diskusage/dirsize.h new file mode 100644 index 00000000000000..34236c0e6f7006 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/diskusage/dirsize.h @@ -0,0 +1,30 @@ +/* + * + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LIBDISKUSAGE_DIRSIZE_H +#define __LIBDISKUSAGE_DIRSIZE_H + +#include + +__BEGIN_DECLS + +int64_t stat_size(struct stat *s); +int64_t calculate_dir_size(int dfd); + +__END_DECLS + +#endif /* __LIBDISKUSAGE_DIRSIZE_H */ diff --git a/phonelibs/android_frameworks_native/include/gui/BitTube.h b/phonelibs/android_frameworks_native/include/gui/BitTube.h new file mode 100644 index 00000000000000..3ecac52ad766f7 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/BitTube.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_SENSOR_CHANNEL_H +#define ANDROID_GUI_SENSOR_CHANNEL_H + +#include +#include + +#include +#include +#include + + +namespace android { +// ---------------------------------------------------------------------------- +class Parcel; + +class BitTube : public RefBase +{ +public: + + // creates a BitTube with a default (4KB) send buffer + BitTube(); + + // creates a BitTube with a a specified send and receive buffer size + explicit BitTube(size_t bufsize); + + explicit BitTube(const Parcel& data); + virtual ~BitTube(); + + // check state after construction + status_t initCheck() const; + + // get receive file-descriptor + int getFd() const; + + // get the send file-descriptor. + int getSendFd() const; + + // send objects (sized blobs). All objects are guaranteed to be written or the call fails. + template + static ssize_t sendObjects(const sp& tube, + T const* events, size_t count) { + return sendObjects(tube, events, count, sizeof(T)); + } + + // receive objects (sized blobs). If the receiving buffer isn't large enough, + // excess messages are silently discarded. + template + static ssize_t recvObjects(const sp& tube, + T* events, size_t count) { + return recvObjects(tube, events, count, sizeof(T)); + } + + // parcels this BitTube + status_t writeToParcel(Parcel* reply) const; + +private: + void init(size_t rcvbuf, size_t sndbuf); + + // send a message. The write is guaranteed to send the whole message or fail. + ssize_t write(void const* vaddr, size_t size); + + // receive a message. the passed buffer must be at least as large as the + // write call used to send the message, excess data is silently discarded. + ssize_t read(void* vaddr, size_t size); + + int mSendFd; + mutable int mReceiveFd; + + static ssize_t sendObjects(const sp& tube, + void const* events, size_t count, size_t objSize); + + static ssize_t recvObjects(const sp& tube, + void* events, size_t count, size_t objSize); +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_SENSOR_CHANNEL_H diff --git a/phonelibs/android_frameworks_native/include/gui/BufferItem.h b/phonelibs/android_frameworks_native/include/gui/BufferItem.h new file mode 100644 index 00000000000000..145efe6f602b84 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/BufferItem.h @@ -0,0 +1,130 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERITEM_H +#define ANDROID_GUI_BUFFERITEM_H + +#include +#include + +#include +#include + +#include + +#include +#include + +namespace android { + +class Fence; +class GraphicBuffer; + +class BufferItem : public Flattenable { + friend class Flattenable; + size_t getPodSize() const; + size_t getFlattenedSize() const; + size_t getFdCount() const; + status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const; + status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count); + + public: + // The default value of mBuf, used to indicate this doesn't correspond to a slot. + enum { INVALID_BUFFER_SLOT = -1 }; + BufferItem(); + ~BufferItem(); + + static const char* scalingModeName(uint32_t scalingMode); + + // mGraphicBuffer points to the buffer allocated for this slot, or is NULL + // if the buffer in this slot has been acquired in the past (see + // BufferSlot.mAcquireCalled). + sp mGraphicBuffer; + + // mFence is a fence that will signal when the buffer is idle. + sp mFence; + + // mCrop is the current crop rectangle for this buffer slot. + Rect mCrop; + + // mTransform is the current transform flags for this buffer slot. + // refer to NATIVE_WINDOW_TRANSFORM_* in + uint32_t mTransform; + + // mScalingMode is the current scaling mode for this buffer slot. + // refer to NATIVE_WINDOW_SCALING_* in + uint32_t mScalingMode; + + // mTimestamp is the current timestamp for this buffer slot. This gets + // to set by queueBuffer each time this slot is queued. This value + // is guaranteed to be monotonically increasing for each newly + // acquired buffer. + union { + int64_t mTimestamp; + struct { + uint32_t mTimestampLo; + uint32_t mTimestampHi; + }; + }; + + // mIsAutoTimestamp indicates whether mTimestamp was generated + // automatically when the buffer was queued. + bool mIsAutoTimestamp; + + // mDataSpace is the current dataSpace value for this buffer slot. This gets + // set by queueBuffer each time this slot is queued. The meaning of the + // dataSpace is format-dependent. + android_dataspace mDataSpace; + + // mFrameNumber is the number of the queued frame for this slot. + union { + uint64_t mFrameNumber; + struct { + uint32_t mFrameNumberLo; + uint32_t mFrameNumberHi; + }; + }; + + union { + // mSlot is the slot index of this buffer (default INVALID_BUFFER_SLOT). + int mSlot; + + // mBuf is the former name for mSlot + int mBuf; + }; + + // mIsDroppable whether this buffer was queued with the + // property that it can be replaced by a new buffer for the purpose of + // making sure dequeueBuffer() won't block. + // i.e.: was the BufferQueue in "mDequeueBufferCannotBlock" when this buffer + // was queued. + bool mIsDroppable; + + // Indicates whether this buffer has been seen by a consumer yet + bool mAcquireCalled; + + // Indicates this buffer must be transformed by the inverse transform of the screen + // it is displayed onto. This is applied after mTransform. + bool mTransformToDisplayInverse; + + // Describes the portion of the surface that has been modified since the + // previous frame + Region mSurfaceDamage; +}; + +} // namespace android + +#endif diff --git a/phonelibs/android_frameworks_native/include/gui/BufferItemConsumer.h b/phonelibs/android_frameworks_native/include/gui/BufferItemConsumer.h new file mode 100644 index 00000000000000..56c7a3f46382f2 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/BufferItemConsumer.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERITEMCONSUMER_H +#define ANDROID_GUI_BUFFERITEMCONSUMER_H + +#include + +#include + +#include +#include +#include + +#define ANDROID_GRAPHICS_BUFFERITEMCONSUMER_JNI_ID "mBufferItemConsumer" + +namespace android { + +class BufferQueue; + +/** + * BufferItemConsumer is a BufferQueue consumer endpoint that allows clients + * access to the whole BufferItem entry from BufferQueue. Multiple buffers may + * be acquired at once, to be used concurrently by the client. This consumer can + * operate either in synchronous or asynchronous mode. + */ +class BufferItemConsumer: public ConsumerBase +{ + public: + typedef ConsumerBase::FrameAvailableListener FrameAvailableListener; + + enum { DEFAULT_MAX_BUFFERS = -1 }; + enum { INVALID_BUFFER_SLOT = BufferQueue::INVALID_BUFFER_SLOT }; + enum { NO_BUFFER_AVAILABLE = BufferQueue::NO_BUFFER_AVAILABLE }; + + // Create a new buffer item consumer. The consumerUsage parameter determines + // the consumer usage flags passed to the graphics allocator. The + // bufferCount parameter specifies how many buffers can be locked for user + // access at the same time. + // controlledByApp tells whether this consumer is controlled by the + // application. + BufferItemConsumer(const sp& consumer, + uint32_t consumerUsage, int bufferCount = DEFAULT_MAX_BUFFERS, + bool controlledByApp = false); + + virtual ~BufferItemConsumer(); + + // set the name of the BufferItemConsumer that will be used to identify it in + // log messages. + void setName(const String8& name); + + // Gets the next graphics buffer from the producer, filling out the + // passed-in BufferItem structure. Returns NO_BUFFER_AVAILABLE if the queue + // of buffers is empty, and INVALID_OPERATION if the maximum number of + // buffers is already acquired. + // + // Only a fixed number of buffers can be acquired at a time, determined by + // the construction-time bufferCount parameter. If INVALID_OPERATION is + // returned by acquireBuffer, then old buffers must be returned to the + // queue by calling releaseBuffer before more buffers can be acquired. + // + // If waitForFence is true, and the acquired BufferItem has a valid fence object, + // acquireBuffer will wait on the fence with no timeout before returning. + status_t acquireBuffer(BufferItem* item, nsecs_t presentWhen, + bool waitForFence = true); + + // Returns an acquired buffer to the queue, allowing it to be reused. Since + // only a fixed number of buffers may be acquired at a time, old buffers + // must be released by calling releaseBuffer to ensure new buffers can be + // acquired by acquireBuffer. Once a BufferItem is released, the caller must + // not access any members of the BufferItem, and should immediately remove + // all of its references to the BufferItem itself. + status_t releaseBuffer(const BufferItem &item, + const sp& releaseFence = Fence::NO_FENCE); + +}; + +} // namespace android + +#endif // ANDROID_GUI_CPUCONSUMER_H diff --git a/phonelibs/android_frameworks_native/include/gui/BufferQueue.h b/phonelibs/android_frameworks_native/include/gui/BufferQueue.h new file mode 100644 index 00000000000000..09300a20c96fd0 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/BufferQueue.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERQUEUE_H +#define ANDROID_GUI_BUFFERQUEUE_H + +#include +#include +#include +#include +#include + +// These are only required to keep other parts of the framework with incomplete +// dependencies building successfully +#include + +namespace android { + +class BufferQueue { +public: + // BufferQueue will keep track of at most this value of buffers. + // Attempts at runtime to increase the number of buffers past this will fail. + enum { NUM_BUFFER_SLOTS = BufferQueueDefs::NUM_BUFFER_SLOTS }; + // Used as a placeholder slot# when the value isn't pointing to an existing buffer. + enum { INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT }; + // Alias to -- please scope from there in future code! + enum { + NO_BUFFER_AVAILABLE = IGraphicBufferConsumer::NO_BUFFER_AVAILABLE, + PRESENT_LATER = IGraphicBufferConsumer::PRESENT_LATER, + }; + + // When in async mode we reserve two slots in order to guarantee that the + // producer and consumer can run asynchronously. + enum { MAX_MAX_ACQUIRED_BUFFERS = NUM_BUFFER_SLOTS - 2 }; + + // for backward source compatibility + typedef ::android::ConsumerListener ConsumerListener; + + // ProxyConsumerListener is a ConsumerListener implementation that keeps a weak + // reference to the actual consumer object. It forwards all calls to that + // consumer object so long as it exists. + // + // This class exists to avoid having a circular reference between the + // BufferQueue object and the consumer object. The reason this can't be a weak + // reference in the BufferQueue class is because we're planning to expose the + // consumer side of a BufferQueue as a binder interface, which doesn't support + // weak references. + class ProxyConsumerListener : public BnConsumerListener { + public: + ProxyConsumerListener(const wp& consumerListener); + virtual ~ProxyConsumerListener(); + virtual void onFrameAvailable(const BufferItem& item) override; + virtual void onFrameReplaced(const BufferItem& item) override; + virtual void onBuffersReleased() override; + virtual void onSidebandStreamChanged() override; + private: + // mConsumerListener is a weak reference to the IConsumerListener. This is + // the raison d'etre of ProxyConsumerListener. + wp mConsumerListener; + }; + + // BufferQueue manages a pool of gralloc memory slots to be used by + // producers and consumers. allocator is used to allocate all the + // needed gralloc buffers. + static void createBufferQueue(sp* outProducer, + sp* outConsumer, + const sp& allocator = NULL); + +private: + BufferQueue(); // Create through createBufferQueue +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_BUFFERQUEUE_H diff --git a/phonelibs/android_frameworks_native/include/gui/BufferQueueConsumer.h b/phonelibs/android_frameworks_native/include/gui/BufferQueueConsumer.h new file mode 100644 index 00000000000000..cde302f8a61f67 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/BufferQueueConsumer.h @@ -0,0 +1,187 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERQUEUECONSUMER_H +#define ANDROID_GUI_BUFFERQUEUECONSUMER_H + +#include +#include + +#include +#include + +namespace android { + +class BufferQueueCore; + +class BufferQueueConsumer : public BnGraphicBufferConsumer { + +public: + BufferQueueConsumer(const sp& core); + virtual ~BufferQueueConsumer(); + + // acquireBuffer attempts to acquire ownership of the next pending buffer in + // the BufferQueue. If no buffer is pending then it returns + // NO_BUFFER_AVAILABLE. If a buffer is successfully acquired, the + // information about the buffer is returned in BufferItem. If the buffer + // returned had previously been acquired then the BufferItem::mGraphicBuffer + // field of buffer is set to NULL and it is assumed that the consumer still + // holds a reference to the buffer. + // + // If expectedPresent is nonzero, it indicates the time when the buffer + // will be displayed on screen. If the buffer's timestamp is farther in the + // future, the buffer won't be acquired, and PRESENT_LATER will be + // returned. The presentation time is in nanoseconds, and the time base + // is CLOCK_MONOTONIC. + virtual status_t acquireBuffer(BufferItem* outBuffer, + nsecs_t expectedPresent, uint64_t maxFrameNumber = 0) override; + + // See IGraphicBufferConsumer::detachBuffer + virtual status_t detachBuffer(int slot); + + // See IGraphicBufferConsumer::attachBuffer + virtual status_t attachBuffer(int* slot, const sp& buffer); + + // releaseBuffer releases a buffer slot from the consumer back to the + // BufferQueue. This may be done while the buffer's contents are still + // being accessed. The fence will signal when the buffer is no longer + // in use. frameNumber is used to indentify the exact buffer returned. + // + // If releaseBuffer returns STALE_BUFFER_SLOT, then the consumer must free + // any references to the just-released buffer that it might have, as if it + // had received a onBuffersReleased() call with a mask set for the released + // buffer. + // + // Note that the dependencies on EGL will be removed once we switch to using + // the Android HW Sync HAL. + virtual status_t releaseBuffer(int slot, uint64_t frameNumber, + const sp& releaseFence, EGLDisplay display, + EGLSyncKHR fence); + + // connect connects a consumer to the BufferQueue. Only one + // consumer may be connected, and when that consumer disconnects the + // BufferQueue is placed into the "abandoned" state, causing most + // interactions with the BufferQueue by the producer to fail. + // controlledByApp indicates whether the consumer is controlled by + // the application. + // + // consumerListener may not be NULL. + virtual status_t connect(const sp& consumerListener, + bool controlledByApp); + + // disconnect disconnects a consumer from the BufferQueue. All + // buffers will be freed and the BufferQueue is placed in the "abandoned" + // state, causing most interactions with the BufferQueue by the producer to + // fail. + virtual status_t disconnect(); + + // getReleasedBuffers sets the value pointed to by outSlotMask to a bit mask + // indicating which buffer slots have been released by the BufferQueue + // but have not yet been released by the consumer. + // + // This should be called from the onBuffersReleased() callback. + virtual status_t getReleasedBuffers(uint64_t* outSlotMask); + + // setDefaultBufferSize is used to set the size of buffers returned by + // dequeueBuffer when a width and height of zero is requested. Default + // is 1x1. + virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height); + + // setDefaultMaxBufferCount sets the default value for the maximum buffer + // count (the initial default is 2). If the producer has requested a + // buffer count using setBufferCount, the default buffer count will only + // take effect if the producer sets the count back to zero. + // + // The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. + virtual status_t setDefaultMaxBufferCount(int bufferCount); + + // disableAsyncBuffer disables the extra buffer used in async mode + // (when both producer and consumer have set their "isControlledByApp" + // flag) and has dequeueBuffer() return WOULD_BLOCK instead. + // + // This can only be called before connect(). + virtual status_t disableAsyncBuffer(); + + // setMaxAcquiredBufferCount sets the maximum number of buffers that can + // be acquired by the consumer at one time (default 1). This call will + // fail if a producer is connected to the BufferQueue. + virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers); + + // setConsumerName sets the name used in logging + virtual void setConsumerName(const String8& name); + + // setDefaultBufferFormat allows the BufferQueue to create + // GraphicBuffers of a defaultFormat if no format is specified + // in dequeueBuffer. The initial default is HAL_PIXEL_FORMAT_RGBA_8888. + virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat); + + // setDefaultBufferDataSpace allows the BufferQueue to create + // GraphicBuffers of a defaultDataSpace if no data space is specified + // in queueBuffer. + // The initial default is HAL_DATASPACE_UNKNOWN + virtual status_t setDefaultBufferDataSpace( + android_dataspace defaultDataSpace); + + // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer. + // These are merged with the bits passed to dequeueBuffer. The values are + // enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER; the default is 0. + virtual status_t setConsumerUsageBits(uint32_t usage); + + // setTransformHint bakes in rotation to buffers so overlays can be used. + // The values are enumerated in window.h, e.g. + // NATIVE_WINDOW_TRANSFORM_ROT_90. The default is 0 (no transform). + virtual status_t setTransformHint(uint32_t hint); + + // Retrieve the sideband buffer stream, if any. + virtual sp getSidebandStream() const; + + // dump our state in a String + virtual void dump(String8& result, const char* prefix) const; + + // Functions required for backwards compatibility. + // These will be modified/renamed in IGraphicBufferConsumer and will be + // removed from this class at that time. See b/13306289. + + virtual status_t releaseBuffer(int buf, uint64_t frameNumber, + EGLDisplay display, EGLSyncKHR fence, + const sp& releaseFence) { + return releaseBuffer(buf, frameNumber, releaseFence, display, fence); + } + + virtual status_t consumerConnect(const sp& consumer, + bool controlledByApp) { + return connect(consumer, controlledByApp); + } + + virtual status_t consumerDisconnect() { return disconnect(); } + + // End functions required for backwards compatibility + +private: + sp mCore; + + // This references mCore->mSlots. Lock mCore->mMutex while accessing. + BufferQueueDefs::SlotsType& mSlots; + + // This is a cached copy of the name stored in the BufferQueueCore. + // It's updated during setConsumerName. + String8 mConsumerName; + +}; // class BufferQueueConsumer + +} // namespace android + +#endif diff --git a/phonelibs/android_frameworks_native/include/gui/BufferQueueCore.h b/phonelibs/android_frameworks_native/include/gui/BufferQueueCore.h new file mode 100644 index 00000000000000..99134ea5018a45 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/BufferQueueCore.h @@ -0,0 +1,287 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERQUEUECORE_H +#define ANDROID_GUI_BUFFERQUEUECORE_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define BQ_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) +#define BQ_LOGD(x, ...) ALOGD("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) +#define BQ_LOGI(x, ...) ALOGI("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) +#define BQ_LOGW(x, ...) ALOGW("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) +#define BQ_LOGE(x, ...) ALOGE("[%s] " x, mConsumerName.string(), ##__VA_ARGS__) + +#define ATRACE_BUFFER_INDEX(index) \ + if (ATRACE_ENABLED()) { \ + char ___traceBuf[1024]; \ + snprintf(___traceBuf, 1024, "%s: %d", \ + mCore->mConsumerName.string(), (index)); \ + android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf); \ + } + +namespace android { + +class IConsumerListener; +class IGraphicBufferAlloc; +class IProducerListener; + +class BufferQueueCore : public virtual RefBase { + + friend class BufferQueueProducer; + friend class BufferQueueConsumer; + +public: + // Used as a placeholder slot number when the value isn't pointing to an + // existing buffer. + enum { INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT }; + + // We reserve two slots in order to guarantee that the producer and + // consumer can run asynchronously. + enum { MAX_MAX_ACQUIRED_BUFFERS = BufferQueueDefs::NUM_BUFFER_SLOTS - 2 }; + + // The default API number used to indicate that no producer is connected + enum { NO_CONNECTED_API = 0 }; + + typedef Vector Fifo; + + // BufferQueueCore manages a pool of gralloc memory slots to be used by + // producers and consumers. allocator is used to allocate all the needed + // gralloc buffers. + BufferQueueCore(const sp& allocator = NULL); + virtual ~BufferQueueCore(); + +private: + // Dump our state in a string + void dump(String8& result, const char* prefix) const; + + // getMinUndequeuedBufferCountLocked returns the minimum number of buffers + // that must remain in a state other than DEQUEUED. The async parameter + // tells whether we're in asynchronous mode. + int getMinUndequeuedBufferCountLocked(bool async) const; + + // getMinMaxBufferCountLocked returns the minimum number of buffers allowed + // given the current BufferQueue state. The async parameter tells whether + // we're in asynchonous mode. + int getMinMaxBufferCountLocked(bool async) const; + + // getMaxBufferCountLocked returns the maximum number of buffers that can be + // allocated at once. This value depends on the following member variables: + // + // mDequeueBufferCannotBlock + // mMaxAcquiredBufferCount + // mDefaultMaxBufferCount + // mOverrideMaxBufferCount + // async parameter + // + // Any time one of these member variables is changed while a producer is + // connected, mDequeueCondition must be broadcast. + int getMaxBufferCountLocked(bool async) const; + + // setDefaultMaxBufferCountLocked sets the maximum number of buffer slots + // that will be used if the producer does not override the buffer slot + // count. The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. The + // initial default is 2. + status_t setDefaultMaxBufferCountLocked(int count); + + // freeBufferLocked frees the GraphicBuffer and sync resources for the + // given slot. + void freeBufferLocked(int slot); + + // freeAllBuffersLocked frees the GraphicBuffer and sync resources for + // all slots. + void freeAllBuffersLocked(); + + // stillTracking returns true iff the buffer item is still being tracked + // in one of the slots. + bool stillTracking(const BufferItem* item) const; + + // waitWhileAllocatingLocked blocks until mIsAllocating is false. + void waitWhileAllocatingLocked() const; + + // validateConsistencyLocked ensures that the free lists are in sync with + // the information stored in mSlots + void validateConsistencyLocked() const; + + // mAllocator is the connection to SurfaceFlinger that is used to allocate + // new GraphicBuffer objects. + sp mAllocator; + + // mMutex is the mutex used to prevent concurrent access to the member + // variables of BufferQueueCore objects. It must be locked whenever any + // member variable is accessed. + mutable Mutex mMutex; + + // mIsAbandoned indicates that the BufferQueue will no longer be used to + // consume image buffers pushed to it using the IGraphicBufferProducer + // interface. It is initialized to false, and set to true in the + // consumerDisconnect method. A BufferQueue that is abandoned will return + // the NO_INIT error from all IGraphicBufferProducer methods capable of + // returning an error. + bool mIsAbandoned; + + // mConsumerControlledByApp indicates whether the connected consumer is + // controlled by the application. + bool mConsumerControlledByApp; + + // mConsumerName is a string used to identify the BufferQueue in log + // messages. It is set by the IGraphicBufferConsumer::setConsumerName + // method. + String8 mConsumerName; + + // mConsumerListener is used to notify the connected consumer of + // asynchronous events that it may wish to react to. It is initially + // set to NULL and is written by consumerConnect and consumerDisconnect. + sp mConsumerListener; + + // mConsumerUsageBits contains flags that the consumer wants for + // GraphicBuffers. + uint32_t mConsumerUsageBits; + + // mConnectedApi indicates the producer API that is currently connected + // to this BufferQueue. It defaults to NO_CONNECTED_API, and gets updated + // by the connect and disconnect methods. + int mConnectedApi; + + // mConnectedProducerToken is used to set a binder death notification on + // the producer. + sp mConnectedProducerListener; + + // mSlots is an array of buffer slots that must be mirrored on the producer + // side. This allows buffer ownership to be transferred between the producer + // and consumer without sending a GraphicBuffer over Binder. The entire + // array is initialized to NULL at construction time, and buffers are + // allocated for a slot when requestBuffer is called with that slot's index. + BufferQueueDefs::SlotsType mSlots; + + // mQueue is a FIFO of queued buffers used in synchronous mode. + Fifo mQueue; + + // mFreeSlots contains all of the slots which are FREE and do not currently + // have a buffer attached + std::set mFreeSlots; + + // mFreeBuffers contains all of the slots which are FREE and currently have + // a buffer attached + std::list mFreeBuffers; + + // mOverrideMaxBufferCount is the limit on the number of buffers that will + // be allocated at one time. This value is set by the producer by calling + // setBufferCount. The default is 0, which means that the producer doesn't + // care about the number of buffers in the pool. In that case, + // mDefaultMaxBufferCount is used as the limit. + int mOverrideMaxBufferCount; + + // mDequeueCondition is a condition variable used for dequeueBuffer in + // synchronous mode. + mutable Condition mDequeueCondition; + + // mUseAsyncBuffer indicates whether an extra buffer is used in async mode + // to prevent dequeueBuffer from blocking. + bool mUseAsyncBuffer; + + // mDequeueBufferCannotBlock indicates whether dequeueBuffer is allowed to + // block. This flag is set during connect when both the producer and + // consumer are controlled by the application. + bool mDequeueBufferCannotBlock; + + // mDefaultBufferFormat can be set so it will override the buffer format + // when it isn't specified in dequeueBuffer. + PixelFormat mDefaultBufferFormat; + + // mDefaultWidth holds the default width of allocated buffers. It is used + // in dequeueBuffer if a width and height of 0 are specified. + uint32_t mDefaultWidth; + + // mDefaultHeight holds the default height of allocated buffers. It is used + // in dequeueBuffer if a width and height of 0 are specified. + uint32_t mDefaultHeight; + + // mDefaultBufferDataSpace holds the default dataSpace of queued buffers. + // It is used in queueBuffer if a dataspace of 0 (HAL_DATASPACE_UNKNOWN) + // is specified. + android_dataspace mDefaultBufferDataSpace; + + // mDefaultMaxBufferCount is the default limit on the number of buffers that + // will be allocated at one time. This default limit is set by the consumer. + // The limit (as opposed to the default limit) may be overriden by the + // producer. + int mDefaultMaxBufferCount; + + // mMaxAcquiredBufferCount is the number of buffers that the consumer may + // acquire at one time. It defaults to 1, and can be changed by the consumer + // via setMaxAcquiredBufferCount, but this may only be done while no + // producer is connected to the BufferQueue. This value is used to derive + // the value returned for the MIN_UNDEQUEUED_BUFFERS query to the producer. + int mMaxAcquiredBufferCount; + + // mBufferHasBeenQueued is true once a buffer has been queued. It is reset + // when something causes all buffers to be freed (e.g., changing the buffer + // count). + bool mBufferHasBeenQueued; + + // mFrameCounter is the free running counter, incremented on every + // successful queueBuffer call and buffer allocation. + uint64_t mFrameCounter; + + // mTransformHint is used to optimize for screen rotations. + uint32_t mTransformHint; + + // mSidebandStream is a handle to the sideband buffer stream, if any + sp mSidebandStream; + + // mIsAllocating indicates whether a producer is currently trying to allocate buffers (which + // releases mMutex while doing the allocation proper). Producers should not modify any of the + // FREE slots while this is true. mIsAllocatingCondition is signaled when this value changes to + // false. + bool mIsAllocating; + + // mIsAllocatingCondition is a condition variable used by producers to wait until mIsAllocating + // becomes false. + mutable Condition mIsAllocatingCondition; + + // mAllowAllocation determines whether dequeueBuffer is allowed to allocate + // new buffers + bool mAllowAllocation; + + // mBufferAge tracks the age of the contents of the most recently dequeued + // buffer as the number of frames that have elapsed since it was last queued + uint64_t mBufferAge; + + // mGenerationNumber stores the current generation number of the attached + // producer. Any attempt to attach a buffer with a different generation + // number will fail. + uint32_t mGenerationNumber; + +}; // class BufferQueueCore + +} // namespace android + +#endif diff --git a/phonelibs/android_frameworks_native/include/gui/BufferQueueDefs.h b/phonelibs/android_frameworks_native/include/gui/BufferQueueDefs.h new file mode 100644 index 00000000000000..83e95800378045 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/BufferQueueDefs.h @@ -0,0 +1,35 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERQUEUECOREDEFS_H +#define ANDROID_GUI_BUFFERQUEUECOREDEFS_H + +#include + +namespace android { + class BufferQueueCore; + + namespace BufferQueueDefs { + // BufferQueue will keep track of at most this value of buffers. + // Attempts at runtime to increase the number of buffers past this + // will fail. + enum { NUM_BUFFER_SLOTS = 64 }; + + typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS]; + } // namespace BufferQueueDefs +} // namespace android + +#endif diff --git a/phonelibs/android_frameworks_native/include/gui/BufferQueueProducer.h b/phonelibs/android_frameworks_native/include/gui/BufferQueueProducer.h new file mode 100644 index 00000000000000..9754a89eacc29b --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/BufferQueueProducer.h @@ -0,0 +1,228 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERQUEUEPRODUCER_H +#define ANDROID_GUI_BUFFERQUEUEPRODUCER_H + +#include +#include + +namespace android { + +class BufferSlot; + +class BufferQueueProducer : public BnGraphicBufferProducer, + private IBinder::DeathRecipient { +public: + friend class BufferQueue; // Needed to access binderDied + + BufferQueueProducer(const sp& core); + virtual ~BufferQueueProducer(); + + // requestBuffer returns the GraphicBuffer for slot N. + // + // In normal operation, this is called the first time slot N is returned + // by dequeueBuffer. It must be called again if dequeueBuffer returns + // flags indicating that previously-returned buffers are no longer valid. + virtual status_t requestBuffer(int slot, sp* buf); + + // setBufferCount updates the number of available buffer slots. If this + // method succeeds, buffer slots will be both unallocated and owned by + // the BufferQueue object (i.e. they are not owned by the producer or + // consumer). + // + // This will fail if the producer has dequeued any buffers, or if + // bufferCount is invalid. bufferCount must generally be a value + // between the minimum undequeued buffer count (exclusive) and NUM_BUFFER_SLOTS + // (inclusive). It may also be set to zero (the default) to indicate + // that the producer does not wish to set a value. The minimum value + // can be obtained by calling query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, + // ...). + // + // This may only be called by the producer. The consumer will be told + // to discard buffers through the onBuffersReleased callback. + virtual status_t setBufferCount(int bufferCount); + + // dequeueBuffer gets the next buffer slot index for the producer to use. + // If a buffer slot is available then that slot index is written to the + // location pointed to by the buf argument and a status of OK is returned. + // If no slot is available then a status of -EBUSY is returned and buf is + // unmodified. + // + // The outFence parameter will be updated to hold the fence associated with + // the buffer. The contents of the buffer must not be overwritten until the + // fence signals. If the fence is Fence::NO_FENCE, the buffer may be + // written immediately. + // + // The width and height parameters must be no greater than the minimum of + // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv). + // An error due to invalid dimensions might not be reported until + // updateTexImage() is called. If width and height are both zero, the + // default values specified by setDefaultBufferSize() are used instead. + // + // If the format is 0, the default format will be used. + // + // The usage argument specifies gralloc buffer usage flags. The values + // are enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER. These + // will be merged with the usage flags specified by setConsumerUsageBits. + // + // The return value may be a negative error value or a non-negative + // collection of flags. If the flags are set, the return values are + // valid, but additional actions must be performed. + // + // If IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION is set, the + // producer must discard cached GraphicBuffer references for the slot + // returned in buf. + // If IGraphicBufferProducer::RELEASE_ALL_BUFFERS is set, the producer + // must discard cached GraphicBuffer references for all slots. + // + // In both cases, the producer will need to call requestBuffer to get a + // GraphicBuffer handle for the returned slot. + virtual status_t dequeueBuffer(int *outSlot, sp* outFence, + bool async, uint32_t width, uint32_t height, PixelFormat format, + uint32_t usage); + + // See IGraphicBufferProducer::detachBuffer + virtual status_t detachBuffer(int slot); + + // See IGraphicBufferProducer::detachNextBuffer + virtual status_t detachNextBuffer(sp* outBuffer, + sp* outFence); + + // See IGraphicBufferProducer::attachBuffer + virtual status_t attachBuffer(int* outSlot, const sp& buffer); + + // queueBuffer returns a filled buffer to the BufferQueue. + // + // Additional data is provided in the QueueBufferInput struct. Notably, + // a timestamp must be provided for the buffer. The timestamp is in + // nanoseconds, and must be monotonically increasing. Its other semantics + // (zero point, etc) are producer-specific and should be documented by the + // producer. + // + // The caller may provide a fence that signals when all rendering + // operations have completed. Alternatively, NO_FENCE may be used, + // indicating that the buffer is ready immediately. + // + // Some values are returned in the output struct: the current settings + // for default width and height, the current transform hint, and the + // number of queued buffers. + virtual status_t queueBuffer(int slot, + const QueueBufferInput& input, QueueBufferOutput* output); + + // cancelBuffer returns a dequeued buffer to the BufferQueue, but doesn't + // queue it for use by the consumer. + // + // The buffer will not be overwritten until the fence signals. The fence + // will usually be the one obtained from dequeueBuffer. + virtual void cancelBuffer(int slot, const sp& fence); + + // Query native window attributes. The "what" values are enumerated in + // window.h (e.g. NATIVE_WINDOW_FORMAT). + virtual int query(int what, int* outValue); + + // connect attempts to connect a producer API to the BufferQueue. This + // must be called before any other IGraphicBufferProducer methods are + // called except for getAllocator. A consumer must already be connected. + // + // This method will fail if connect was previously called on the + // BufferQueue and no corresponding disconnect call was made (i.e. if + // it's still connected to a producer). + // + // APIs are enumerated in window.h (e.g. NATIVE_WINDOW_API_CPU). + virtual status_t connect(const sp& listener, + int api, bool producerControlledByApp, QueueBufferOutput* output); + + // disconnect attempts to disconnect a producer API from the BufferQueue. + // Calling this method will cause any subsequent calls to other + // IGraphicBufferProducer methods to fail except for getAllocator and connect. + // Successfully calling connect after this will allow the other methods to + // succeed again. + // + // This method will fail if the the BufferQueue is not currently + // connected to the specified producer API. + virtual status_t disconnect(int api); + + // Attaches a sideband buffer stream to the IGraphicBufferProducer. + // + // A sideband stream is a device-specific mechanism for passing buffers + // from the producer to the consumer without using dequeueBuffer/ + // queueBuffer. If a sideband stream is present, the consumer can choose + // whether to acquire buffers from the sideband stream or from the queued + // buffers. + // + // Passing NULL or a different stream handle will detach the previous + // handle if any. + virtual status_t setSidebandStream(const sp& stream); + + // See IGraphicBufferProducer::allocateBuffers + virtual void allocateBuffers(bool async, uint32_t width, uint32_t height, + PixelFormat format, uint32_t usage); + + // See IGraphicBufferProducer::allowAllocation + virtual status_t allowAllocation(bool allow); + + // See IGraphicBufferProducer::setGenerationNumber + virtual status_t setGenerationNumber(uint32_t generationNumber); + + // See IGraphicBufferProducer::getConsumerName + virtual String8 getConsumerName() const override; + +private: + // This is required by the IBinder::DeathRecipient interface + virtual void binderDied(const wp& who); + + // waitForFreeSlotThenRelock finds the oldest slot in the FREE state. It may + // block if there are no available slots and we are not in non-blocking + // mode (producer and consumer controlled by the application). If it blocks, + // it will release mCore->mMutex while blocked so that other operations on + // the BufferQueue may succeed. + status_t waitForFreeSlotThenRelock(const char* caller, bool async, + int* found, status_t* returnFlags) const; + + sp mCore; + + // This references mCore->mSlots. Lock mCore->mMutex while accessing. + BufferQueueDefs::SlotsType& mSlots; + + // This is a cached copy of the name stored in the BufferQueueCore. + // It's updated during connect and dequeueBuffer (which should catch + // most updates). + String8 mConsumerName; + + uint32_t mStickyTransform; + + // This saves the fence from the last queueBuffer, such that the + // next queueBuffer call can throttle buffer production. The prior + // queueBuffer's fence is not nessessarily available elsewhere, + // since the previous buffer might have already been acquired. + sp mLastQueueBufferFence; + + // Take-a-ticket system for ensuring that onFrame* callbacks are called in + // the order that frames are queued. While the BufferQueue lock + // (mCore->mMutex) is held, a ticket is retained by the producer. After + // dropping the BufferQueue lock, the producer must wait on the condition + // variable until the current callback ticket matches its retained ticket. + Mutex mCallbackMutex; + int mNextCallbackTicket; // Protected by mCore->mMutex + int mCurrentCallbackTicket; // Protected by mCallbackMutex + Condition mCallbackCondition; + +}; // class BufferQueueProducer + +} // namespace android + +#endif diff --git a/phonelibs/android_frameworks_native/include/gui/BufferSlot.h b/phonelibs/android_frameworks_native/include/gui/BufferSlot.h new file mode 100644 index 00000000000000..6085e116a3d614 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/BufferSlot.h @@ -0,0 +1,142 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_BUFFERSLOT_H +#define ANDROID_GUI_BUFFERSLOT_H + +#include +#include + +#include +#include + +#include + +namespace android { + +class Fence; + +struct BufferSlot { + + BufferSlot() + : mEglDisplay(EGL_NO_DISPLAY), + mBufferState(BufferSlot::FREE), + mRequestBufferCalled(false), + mFrameNumber(0), + mEglFence(EGL_NO_SYNC_KHR), + mAcquireCalled(false), + mNeedsCleanupOnRelease(false), + mAttachedByConsumer(false) { + } + + // mGraphicBuffer points to the buffer allocated for this slot or is NULL + // if no buffer has been allocated. + sp mGraphicBuffer; + + // mEglDisplay is the EGLDisplay used to create EGLSyncKHR objects. + EGLDisplay mEglDisplay; + + // BufferState represents the different states in which a buffer slot + // can be. All slots are initially FREE. + enum BufferState { + // FREE indicates that the buffer is available to be dequeued + // by the producer. The buffer may be in use by the consumer for + // a finite time, so the buffer must not be modified until the + // associated fence is signaled. + // + // The slot is "owned" by BufferQueue. It transitions to DEQUEUED + // when dequeueBuffer is called. + FREE = 0, + + // DEQUEUED indicates that the buffer has been dequeued by the + // producer, but has not yet been queued or canceled. The + // producer may modify the buffer's contents as soon as the + // associated ready fence is signaled. + // + // The slot is "owned" by the producer. It can transition to + // QUEUED (via queueBuffer) or back to FREE (via cancelBuffer). + DEQUEUED = 1, + + // QUEUED indicates that the buffer has been filled by the + // producer and queued for use by the consumer. The buffer + // contents may continue to be modified for a finite time, so + // the contents must not be accessed until the associated fence + // is signaled. + // + // The slot is "owned" by BufferQueue. It can transition to + // ACQUIRED (via acquireBuffer) or to FREE (if another buffer is + // queued in asynchronous mode). + QUEUED = 2, + + // ACQUIRED indicates that the buffer has been acquired by the + // consumer. As with QUEUED, the contents must not be accessed + // by the consumer until the fence is signaled. + // + // The slot is "owned" by the consumer. It transitions to FREE + // when releaseBuffer is called. + ACQUIRED = 3 + }; + + static const char* bufferStateName(BufferState state); + + // mBufferState is the current state of this buffer slot. + BufferState mBufferState; + + // mRequestBufferCalled is used for validating that the producer did + // call requestBuffer() when told to do so. Technically this is not + // needed but useful for debugging and catching producer bugs. + bool mRequestBufferCalled; + + // mFrameNumber is the number of the queued frame for this slot. This + // is used to dequeue buffers in LRU order (useful because buffers + // may be released before their release fence is signaled). + uint64_t mFrameNumber; + + // mEglFence is the EGL sync object that must signal before the buffer + // associated with this buffer slot may be dequeued. It is initialized + // to EGL_NO_SYNC_KHR when the buffer is created and may be set to a + // new sync object in releaseBuffer. (This is deprecated in favor of + // mFence, below.) + EGLSyncKHR mEglFence; + + // mFence is a fence which will signal when work initiated by the + // previous owner of the buffer is finished. When the buffer is FREE, + // the fence indicates when the consumer has finished reading + // from the buffer, or when the producer has finished writing if it + // called cancelBuffer after queueing some writes. When the buffer is + // QUEUED, it indicates when the producer has finished filling the + // buffer. When the buffer is DEQUEUED or ACQUIRED, the fence has been + // passed to the consumer or producer along with ownership of the + // buffer, and mFence is set to NO_FENCE. + sp mFence; + + // Indicates whether this buffer has been seen by a consumer yet + bool mAcquireCalled; + + // Indicates whether this buffer needs to be cleaned up by the + // consumer. This is set when a buffer in ACQUIRED state is freed. + // It causes releaseBuffer to return STALE_BUFFER_SLOT. + bool mNeedsCleanupOnRelease; + + // Indicates whether the buffer was attached on the consumer side. + // If so, it needs to set the BUFFER_NEEDS_REALLOCATION flag when dequeued + // to prevent the producer from using a stale cached buffer. + bool mAttachedByConsumer; +}; + +} // namespace android + +#endif diff --git a/phonelibs/android_frameworks_native/include/gui/ConsumerBase.h b/phonelibs/android_frameworks_native/include/gui/ConsumerBase.h new file mode 100644 index 00000000000000..9307a26fb3a11a --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/ConsumerBase.h @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_CONSUMERBASE_H +#define ANDROID_GUI_CONSUMERBASE_H + +#include + +#include + +#include +#include +#include +#include + +namespace android { +// ---------------------------------------------------------------------------- + +class String8; + +// ConsumerBase is a base class for BufferQueue consumer end-points. It +// handles common tasks like management of the connection to the BufferQueue +// and the buffer pool. +class ConsumerBase : public virtual RefBase, + protected ConsumerListener { +public: + struct FrameAvailableListener : public virtual RefBase { + // See IConsumerListener::onFrame{Available,Replaced} + virtual void onFrameAvailable(const BufferItem& item) = 0; + virtual void onFrameReplaced(const BufferItem& /* item */) {} + }; + + virtual ~ConsumerBase(); + + // abandon frees all the buffers and puts the ConsumerBase into the + // 'abandoned' state. Once put in this state the ConsumerBase can never + // leave it. When in the 'abandoned' state, all methods of the + // IGraphicBufferProducer interface will fail with the NO_INIT error. + // + // Note that while calling this method causes all the buffers to be freed + // from the perspective of the the ConsumerBase, if there are additional + // references on the buffers (e.g. if a buffer is referenced by a client + // or by OpenGL ES as a texture) then those buffer will remain allocated. + void abandon(); + + // Returns true if the ConsumerBase is in the 'abandoned' state + bool isAbandoned(); + + // set the name of the ConsumerBase that will be used to identify it in + // log messages. + void setName(const String8& name); + + // dump writes the current state to a string. Child classes should add + // their state to the dump by overriding the dumpLocked method, which is + // called by these methods after locking the mutex. + void dump(String8& result) const; + void dump(String8& result, const char* prefix) const; + + // setFrameAvailableListener sets the listener object that will be notified + // when a new frame becomes available. + void setFrameAvailableListener(const wp& listener); + + // See IGraphicBufferConsumer::detachBuffer + status_t detachBuffer(int slot); + + // See IGraphicBufferConsumer::setDefaultBufferSize + status_t setDefaultBufferSize(uint32_t width, uint32_t height); + + // See IGraphicBufferConsumer::setDefaultBufferFormat + status_t setDefaultBufferFormat(PixelFormat defaultFormat); + + // See IGraphicBufferConsumer::setDefaultBufferDataSpace + status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace); + +private: + ConsumerBase(const ConsumerBase&); + void operator=(const ConsumerBase&); + +protected: + // ConsumerBase constructs a new ConsumerBase object to consume image + // buffers from the given IGraphicBufferConsumer. + // The controlledByApp flag indicates that this consumer is under the application's + // control. + ConsumerBase(const sp& consumer, bool controlledByApp = false); + + // onLastStrongRef gets called by RefBase just before the dtor of the most + // derived class. It is used to clean up the buffers so that ConsumerBase + // can coordinate the clean-up by calling into virtual methods implemented + // by the derived classes. This would not be possible from the + // ConsuemrBase dtor because by the time that gets called the derived + // classes have already been destructed. + // + // This methods should not need to be overridden by derived classes, but + // if they are overridden the ConsumerBase implementation must be called + // from the derived class. + virtual void onLastStrongRef(const void* id); + + // Implementation of the IConsumerListener interface. These + // calls are used to notify the ConsumerBase of asynchronous events in the + // BufferQueue. The onFrameAvailable, onFrameReplaced, and + // onBuffersReleased methods should not need to be overridden by derived + // classes, but if they are overridden the ConsumerBase implementation must + // be called from the derived class. The ConsumerBase version of + // onSidebandStreamChanged does nothing and can be overriden by derived + // classes if they want the notification. + virtual void onFrameAvailable(const BufferItem& item) override; + virtual void onFrameReplaced(const BufferItem& item) override; + virtual void onBuffersReleased() override; + virtual void onSidebandStreamChanged() override; + + // freeBufferLocked frees up the given buffer slot. If the slot has been + // initialized this will release the reference to the GraphicBuffer in that + // slot. Otherwise it has no effect. + // + // Derived classes should override this method to clean up any state they + // keep per slot. If it is overridden, the derived class's implementation + // must call ConsumerBase::freeBufferLocked. + // + // This method must be called with mMutex locked. + virtual void freeBufferLocked(int slotIndex); + + // abandonLocked puts the BufferQueue into the abandoned state, causing + // all future operations on it to fail. This method rather than the public + // abandon method should be overridden by child classes to add abandon- + // time behavior. + // + // Derived classes should override this method to clean up any object + // state they keep (as opposed to per-slot state). If it is overridden, + // the derived class's implementation must call ConsumerBase::abandonLocked. + // + // This method must be called with mMutex locked. + virtual void abandonLocked(); + + // dumpLocked dumps the current state of the ConsumerBase object to the + // result string. Each line is prefixed with the string pointed to by the + // prefix argument. The buffer argument points to a buffer that may be + // used for intermediate formatting data, and the size of that buffer is + // indicated by the size argument. + // + // Derived classes should override this method to dump their internal + // state. If this method is overridden the derived class's implementation + // should call ConsumerBase::dumpLocked. + // + // This method must be called with mMutex locked. + virtual void dumpLocked(String8& result, const char* prefix) const; + + // acquireBufferLocked fetches the next buffer from the BufferQueue and + // updates the buffer slot for the buffer returned. + // + // Derived classes should override this method to perform any + // initialization that must take place the first time a buffer is assigned + // to a slot. If it is overridden the derived class's implementation must + // call ConsumerBase::acquireBufferLocked. + virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen, + uint64_t maxFrameNumber = 0); + + // releaseBufferLocked relinquishes control over a buffer, returning that + // control to the BufferQueue. + // + // Derived classes should override this method to perform any cleanup that + // must take place when a buffer is released back to the BufferQueue. If + // it is overridden the derived class's implementation must call + // ConsumerBase::releaseBufferLocked.e + virtual status_t releaseBufferLocked(int slot, + const sp graphicBuffer, + EGLDisplay display, EGLSyncKHR eglFence); + + // returns true iff the slot still has the graphicBuffer in it. + bool stillTracking(int slot, const sp graphicBuffer); + + // addReleaseFence* adds the sync points associated with a fence to the set + // of sync points that must be reached before the buffer in the given slot + // may be used after the slot has been released. This should be called by + // derived classes each time some asynchronous work is kicked off that + // references the buffer. + status_t addReleaseFence(int slot, + const sp graphicBuffer, const sp& fence); + status_t addReleaseFenceLocked(int slot, + const sp graphicBuffer, const sp& fence); + + // Slot contains the information and object references that + // ConsumerBase maintains about a BufferQueue buffer slot. + struct Slot { + // mGraphicBuffer is the Gralloc buffer store in the slot or NULL if + // no Gralloc buffer is in the slot. + sp mGraphicBuffer; + + // mFence is a fence which will signal when the buffer associated with + // this buffer slot is no longer being used by the consumer and can be + // overwritten. The buffer can be dequeued before the fence signals; + // the producer is responsible for delaying writes until it signals. + sp mFence; + + // the frame number of the last acquired frame for this slot + uint64_t mFrameNumber; + }; + + // mSlots stores the buffers that have been allocated by the BufferQueue + // for each buffer slot. It is initialized to null pointers, and gets + // filled in with the result of BufferQueue::acquire when the + // client dequeues a buffer from a + // slot that has not yet been used. The buffer allocated to a slot will also + // be replaced if the requested buffer usage or geometry differs from that + // of the buffer allocated to a slot. + Slot mSlots[BufferQueue::NUM_BUFFER_SLOTS]; + + // mAbandoned indicates that the BufferQueue will no longer be used to + // consume images buffers pushed to it using the IGraphicBufferProducer + // interface. It is initialized to false, and set to true in the abandon + // method. A BufferQueue that has been abandoned will return the NO_INIT + // error from all IConsumerBase methods capable of returning an error. + bool mAbandoned; + + // mName is a string used to identify the ConsumerBase in log messages. + // It can be set by the setName method. + String8 mName; + + // mFrameAvailableListener is the listener object that will be called when a + // new frame becomes available. If it is not NULL it will be called from + // queueBuffer. + wp mFrameAvailableListener; + + // The ConsumerBase has-a BufferQueue and is responsible for creating this object + // if none is supplied + sp mConsumer; + + // mMutex is the mutex used to prevent concurrent access to the member + // variables of ConsumerBase objects. It must be locked whenever the + // member variables are accessed or when any of the *Locked methods are + // called. + // + // This mutex is intended to be locked by derived classes. + mutable Mutex mMutex; +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_CONSUMERBASE_H diff --git a/phonelibs/android_frameworks_native/include/gui/CpuConsumer.h b/phonelibs/android_frameworks_native/include/gui/CpuConsumer.h new file mode 100644 index 00000000000000..3b07a317501651 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/CpuConsumer.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_CPUCONSUMER_H +#define ANDROID_GUI_CPUCONSUMER_H + +#include + +#include + +#include +#include +#include + + +namespace android { + +class BufferQueue; + +/** + * CpuConsumer is a BufferQueue consumer endpoint that allows direct CPU + * access to the underlying gralloc buffers provided by BufferQueue. Multiple + * buffers may be acquired by it at once, to be used concurrently by the + * CpuConsumer owner. Sets gralloc usage flags to be software-read-only. + * This queue is synchronous by default. + */ + +class CpuConsumer : public ConsumerBase +{ + public: + typedef ConsumerBase::FrameAvailableListener FrameAvailableListener; + + struct LockedBuffer { + uint8_t *data; + uint32_t width; + uint32_t height; + PixelFormat format; + uint32_t stride; + Rect crop; + uint32_t transform; + uint32_t scalingMode; + int64_t timestamp; + android_dataspace dataSpace; + uint64_t frameNumber; + // this is the same as format, except for formats that are compatible with + // a flexible format (e.g. HAL_PIXEL_FORMAT_YCbCr_420_888). In the latter + // case this contains that flexible format + PixelFormat flexFormat; + // Values below are only valid when using HAL_PIXEL_FORMAT_YCbCr_420_888 + // or compatible format, in which case LockedBuffer::data + // contains the Y channel, and stride is the Y channel stride. For other + // formats, these will all be 0. + uint8_t *dataCb; + uint8_t *dataCr; + uint32_t chromaStride; + uint32_t chromaStep; + }; + + // Create a new CPU consumer. The maxLockedBuffers parameter specifies + // how many buffers can be locked for user access at the same time. + CpuConsumer(const sp& bq, + size_t maxLockedBuffers, bool controlledByApp = false); + + virtual ~CpuConsumer(); + + // set the name of the CpuConsumer that will be used to identify it in + // log messages. + void setName(const String8& name); + + // Gets the next graphics buffer from the producer and locks it for CPU use, + // filling out the passed-in locked buffer structure with the native pointer + // and metadata. Returns BAD_VALUE if no new buffer is available, and + // NOT_ENOUGH_DATA if the maximum number of buffers is already locked. + // + // Only a fixed number of buffers can be locked at a time, determined by the + // construction-time maxLockedBuffers parameter. If INVALID_OPERATION is + // returned by lockNextBuffer, then old buffers must be returned to the queue + // by calling unlockBuffer before more buffers can be acquired. + status_t lockNextBuffer(LockedBuffer *nativeBuffer); + + // Returns a locked buffer to the queue, allowing it to be reused. Since + // only a fixed number of buffers may be locked at a time, old buffers must + // be released by calling unlockBuffer to ensure new buffers can be acquired by + // lockNextBuffer. + status_t unlockBuffer(const LockedBuffer &nativeBuffer); + + private: + // Maximum number of buffers that can be locked at a time + size_t mMaxLockedBuffers; + + status_t releaseAcquiredBufferLocked(size_t lockedIdx); + + virtual void freeBufferLocked(int slotIndex); + + // Tracking for buffers acquired by the user + struct AcquiredBuffer { + // Need to track the original mSlot index and the buffer itself because + // the mSlot entry may be freed/reused before the acquired buffer is + // released. + int mSlot; + sp mGraphicBuffer; + void *mBufferPointer; + + AcquiredBuffer() : + mSlot(BufferQueue::INVALID_BUFFER_SLOT), + mBufferPointer(NULL) { + } + }; + Vector mAcquiredBuffers; + + // Count of currently locked buffers + size_t mCurrentLockedBuffers; + +}; + +} // namespace android + +#endif // ANDROID_GUI_CPUCONSUMER_H diff --git a/phonelibs/android_frameworks_native/include/gui/DisplayEventReceiver.h b/phonelibs/android_frameworks_native/include/gui/DisplayEventReceiver.h new file mode 100644 index 00000000000000..a4718b91c6e6b8 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/DisplayEventReceiver.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_DISPLAY_EVENT_H +#define ANDROID_GUI_DISPLAY_EVENT_H + +#include +#include + +#include +#include +#include + +#include + +// ---------------------------------------------------------------------------- + +namespace android { + +// ---------------------------------------------------------------------------- + +class BitTube; +class IDisplayEventConnection; + +// ---------------------------------------------------------------------------- + +class DisplayEventReceiver { +public: + enum { + DISPLAY_EVENT_VSYNC = 'vsyn', + DISPLAY_EVENT_HOTPLUG = 'plug' + }; + + struct Event { + + struct Header { + uint32_t type; + uint32_t id; + nsecs_t timestamp __attribute__((aligned(8))); + }; + + struct VSync { + uint32_t count; + }; + + struct Hotplug { + bool connected; + }; + + Header header; + union { + VSync vsync; + Hotplug hotplug; + }; + }; + +public: + /* + * DisplayEventReceiver creates and registers an event connection with + * SurfaceFlinger. VSync events are disabled by default. Call setVSyncRate + * or requestNextVsync to receive them. + * Other events start being delivered immediately. + */ + DisplayEventReceiver(); + + /* + * ~DisplayEventReceiver severs the connection with SurfaceFlinger, new events + * stop being delivered immediately. Note that the queue could have + * some events pending. These will be delivered. + */ + ~DisplayEventReceiver(); + + /* + * initCheck returns the state of DisplayEventReceiver after construction. + */ + status_t initCheck() const; + + /* + * getFd returns the file descriptor to use to receive events. + * OWNERSHIP IS RETAINED by DisplayEventReceiver. DO NOT CLOSE this + * file-descriptor. + */ + int getFd() const; + + /* + * getEvents reads events from the queue and returns how many events were + * read. Returns 0 if there are no more events or a negative error code. + * If NOT_ENOUGH_DATA is returned, the object has become invalid forever, it + * should be destroyed and getEvents() shouldn't be called again. + */ + ssize_t getEvents(Event* events, size_t count); + static ssize_t getEvents(const sp& dataChannel, + Event* events, size_t count); + + /* + * sendEvents write events to the queue and returns how many events were + * written. + */ + static ssize_t sendEvents(const sp& dataChannel, + Event const* events, size_t count); + + /* + * setVsyncRate() sets the Event::VSync delivery rate. A value of + * 1 returns every Event::VSync. A value of 2 returns every other event, + * etc... a value of 0 returns no event unless requestNextVsync() has + * been called. + */ + status_t setVsyncRate(uint32_t count); + + /* + * requestNextVsync() schedules the next Event::VSync. It has no effect + * if the vsync rate is > 0. + */ + status_t requestNextVsync(); + +private: + sp mEventConnection; + sp mDataChannel; +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_DISPLAY_EVENT_H diff --git a/phonelibs/android_frameworks_native/include/gui/GLConsumer.h b/phonelibs/android_frameworks_native/include/gui/GLConsumer.h new file mode 100644 index 00000000000000..c35c7be064224e --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/GLConsumer.h @@ -0,0 +1,488 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_CONSUMER_H +#define ANDROID_GUI_CONSUMER_H + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +namespace android { +// ---------------------------------------------------------------------------- + + +class String8; + +/* + * GLConsumer consumes buffers of graphics data from a BufferQueue, + * and makes them available to OpenGL as a texture. + * + * A typical usage pattern is to set up the GLConsumer with the + * desired options, and call updateTexImage() when a new frame is desired. + * If a new frame is available, the texture will be updated. If not, + * the previous contents are retained. + * + * By default, the texture is attached to the GL_TEXTURE_EXTERNAL_OES + * texture target, in the EGL context of the first thread that calls + * updateTexImage(). + * + * This class was previously called SurfaceTexture. + */ +class GLConsumer : public ConsumerBase { +public: + enum { TEXTURE_EXTERNAL = 0x8D65 }; // GL_TEXTURE_EXTERNAL_OES + typedef ConsumerBase::FrameAvailableListener FrameAvailableListener; + + // GLConsumer constructs a new GLConsumer object. If the constructor with + // the tex parameter is used, tex indicates the name of the OpenGL ES + // texture to which images are to be streamed. texTarget specifies the + // OpenGL ES texture target to which the texture will be bound in + // updateTexImage. useFenceSync specifies whether fences should be used to + // synchronize access to buffers if that behavior is enabled at + // compile-time. + // + // A GLConsumer may be detached from one OpenGL ES context and then + // attached to a different context using the detachFromContext and + // attachToContext methods, respectively. The intention of these methods is + // purely to allow a GLConsumer to be transferred from one consumer + // context to another. If such a transfer is not needed there is no + // requirement that either of these methods be called. + // + // If the constructor with the tex parameter is used, the GLConsumer is + // created in a state where it is considered attached to an OpenGL ES + // context for the purposes of the attachToContext and detachFromContext + // methods. However, despite being considered "attached" to a context, the + // specific OpenGL ES context doesn't get latched until the first call to + // updateTexImage. After that point, all calls to updateTexImage must be + // made with the same OpenGL ES context current. + // + // If the constructor without the tex parameter is used, the GLConsumer is + // created in a detached state, and attachToContext must be called before + // calls to updateTexImage. + GLConsumer(const sp& bq, + uint32_t tex, uint32_t texureTarget, bool useFenceSync, + bool isControlledByApp); + + GLConsumer(const sp& bq, uint32_t texureTarget, + bool useFenceSync, bool isControlledByApp); + + // updateTexImage acquires the most recently queued buffer, and sets the + // image contents of the target texture to it. + // + // This call may only be made while the OpenGL ES context to which the + // target texture belongs is bound to the calling thread. + // + // This calls doGLFenceWait to ensure proper synchronization. + status_t updateTexImage(); + + // releaseTexImage releases the texture acquired in updateTexImage(). + // This is intended to be used in single buffer mode. + // + // This call may only be made while the OpenGL ES context to which the + // target texture belongs is bound to the calling thread. + status_t releaseTexImage(); + + // setReleaseFence stores a fence that will signal when the current buffer + // is no longer being read. This fence will be returned to the producer + // when the current buffer is released by updateTexImage(). Multiple + // fences can be set for a given buffer; they will be merged into a single + // union fence. + void setReleaseFence(const sp& fence); + + // setDefaultMaxBufferCount sets the default limit on the maximum number + // of buffers that will be allocated at one time. The image producer may + // override the limit. + status_t setDefaultMaxBufferCount(int bufferCount); + + // getTransformMatrix retrieves the 4x4 texture coordinate transform matrix + // associated with the texture image set by the most recent call to + // updateTexImage. + // + // This transform matrix maps 2D homogeneous texture coordinates of the form + // (s, t, 0, 1) with s and t in the inclusive range [0, 1] to the texture + // coordinate that should be used to sample that location from the texture. + // Sampling the texture outside of the range of this transform is undefined. + // + // This transform is necessary to compensate for transforms that the stream + // content producer may implicitly apply to the content. By forcing users of + // a GLConsumer to apply this transform we avoid performing an extra + // copy of the data that would be needed to hide the transform from the + // user. + // + // The matrix is stored in column-major order so that it may be passed + // directly to OpenGL ES via the glLoadMatrixf or glUniformMatrix4fv + // functions. + void getTransformMatrix(float mtx[16]); + + // getTimestamp retrieves the timestamp associated with the texture image + // set by the most recent call to updateTexImage. + // + // The timestamp is in nanoseconds, and is monotonically increasing. Its + // other semantics (zero point, etc) are source-dependent and should be + // documented by the source. + int64_t getTimestamp(); + + // getFrameNumber retrieves the frame number associated with the texture + // image set by the most recent call to updateTexImage. + // + // The frame number is an incrementing counter set to 0 at the creation of + // the BufferQueue associated with this consumer. + uint64_t getFrameNumber(); + + // setDefaultBufferSize is used to set the size of buffers returned by + // requestBuffers when a with and height of zero is requested. + // A call to setDefaultBufferSize() may trigger requestBuffers() to + // be called from the client. + // The width and height parameters must be no greater than the minimum of + // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv). + // An error due to invalid dimensions might not be reported until + // updateTexImage() is called. + status_t setDefaultBufferSize(uint32_t width, uint32_t height); + + // setFilteringEnabled sets whether the transform matrix should be computed + // for use with bilinear filtering. + void setFilteringEnabled(bool enabled); + + // getCurrentBuffer returns the buffer associated with the current image. + sp getCurrentBuffer() const; + + // getCurrentTextureTarget returns the texture target of the current + // texture as returned by updateTexImage(). + uint32_t getCurrentTextureTarget() const; + + // getCurrentCrop returns the cropping rectangle of the current buffer. + Rect getCurrentCrop() const; + + // getCurrentTransform returns the transform of the current buffer. + uint32_t getCurrentTransform() const; + + // getCurrentScalingMode returns the scaling mode of the current buffer. + uint32_t getCurrentScalingMode() const; + + // getCurrentFence returns the fence indicating when the current buffer is + // ready to be read from. + sp getCurrentFence() const; + + // doGLFenceWait inserts a wait command into the OpenGL ES command stream + // to ensure that it is safe for future OpenGL ES commands to access the + // current texture buffer. + status_t doGLFenceWait() const; + + // set the name of the GLConsumer that will be used to identify it in + // log messages. + void setName(const String8& name); + + // These functions call the corresponding BufferQueue implementation + // so the refactoring can proceed smoothly + status_t setDefaultBufferFormat(PixelFormat defaultFormat); + status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace); + status_t setConsumerUsageBits(uint32_t usage); + status_t setTransformHint(uint32_t hint); + + // detachFromContext detaches the GLConsumer from the calling thread's + // current OpenGL ES context. This context must be the same as the context + // that was current for previous calls to updateTexImage. + // + // Detaching a GLConsumer from an OpenGL ES context will result in the + // deletion of the OpenGL ES texture object into which the images were being + // streamed. After a GLConsumer has been detached from the OpenGL ES + // context calls to updateTexImage will fail returning INVALID_OPERATION + // until the GLConsumer is attached to a new OpenGL ES context using the + // attachToContext method. + status_t detachFromContext(); + + // attachToContext attaches a GLConsumer that is currently in the + // 'detached' state to the current OpenGL ES context. A GLConsumer is + // in the 'detached' state iff detachFromContext has successfully been + // called and no calls to attachToContext have succeeded since the last + // detachFromContext call. Calls to attachToContext made on a + // GLConsumer that is not in the 'detached' state will result in an + // INVALID_OPERATION error. + // + // The tex argument specifies the OpenGL ES texture object name in the + // new context into which the image contents will be streamed. A successful + // call to attachToContext will result in this texture object being bound to + // the texture target and populated with the image contents that were + // current at the time of the last call to detachFromContext. + status_t attachToContext(uint32_t tex); + +protected: + + // abandonLocked overrides the ConsumerBase method to clear + // mCurrentTextureImage in addition to the ConsumerBase behavior. + virtual void abandonLocked(); + + // dumpLocked overrides the ConsumerBase method to dump GLConsumer- + // specific info in addition to the ConsumerBase behavior. + virtual void dumpLocked(String8& result, const char* prefix) const; + + // acquireBufferLocked overrides the ConsumerBase method to update the + // mEglSlots array in addition to the ConsumerBase behavior. + virtual status_t acquireBufferLocked(BufferItem *item, nsecs_t presentWhen, + uint64_t maxFrameNumber = 0) override; + + // releaseBufferLocked overrides the ConsumerBase method to update the + // mEglSlots array in addition to the ConsumerBase. + virtual status_t releaseBufferLocked(int slot, + const sp graphicBuffer, + EGLDisplay display, EGLSyncKHR eglFence); + + status_t releaseBufferLocked(int slot, + const sp graphicBuffer, EGLSyncKHR eglFence) { + return releaseBufferLocked(slot, graphicBuffer, mEglDisplay, eglFence); + } + + static bool isExternalFormat(PixelFormat format); + + // This releases the buffer in the slot referenced by mCurrentTexture, + // then updates state to refer to the BufferItem, which must be a + // newly-acquired buffer. + status_t updateAndReleaseLocked(const BufferItem& item); + + // Binds mTexName and the current buffer to mTexTarget. Uses + // mCurrentTexture if it's set, mCurrentTextureImage if not. If the + // bind succeeds, this calls doGLFenceWait. + status_t bindTextureImageLocked(); + + // Gets the current EGLDisplay and EGLContext values, and compares them + // to mEglDisplay and mEglContext. If the fields have been previously + // set, the values must match; if not, the fields are set to the current + // values. + // The contextCheck argument is used to ensure that a GL context is + // properly set; when set to false, the check is not performed. + status_t checkAndUpdateEglStateLocked(bool contextCheck = false); + +private: + // EglImage is a utility class for tracking and creating EGLImageKHRs. There + // is primarily just one image per slot, but there is also special cases: + // - For releaseTexImage, we use a debug image (mReleasedTexImage) + // - After freeBuffer, we must still keep the current image/buffer + // Reference counting EGLImages lets us handle all these cases easily while + // also only creating new EGLImages from buffers when required. + class EglImage : public LightRefBase { + public: + EglImage(sp graphicBuffer); + + // createIfNeeded creates an EGLImage if required (we haven't created + // one yet, or the EGLDisplay or crop-rect has changed). + status_t createIfNeeded(EGLDisplay display, + const Rect& cropRect, + bool forceCreate = false); + + // This calls glEGLImageTargetTexture2DOES to bind the image to the + // texture in the specified texture target. + void bindToTextureTarget(uint32_t texTarget); + + const sp& graphicBuffer() { return mGraphicBuffer; } + const native_handle* graphicBufferHandle() { + return mGraphicBuffer == NULL ? NULL : mGraphicBuffer->handle; + } + + private: + // Only allow instantiation using ref counting. + friend class LightRefBase; + virtual ~EglImage(); + + // createImage creates a new EGLImage from a GraphicBuffer. + EGLImageKHR createImage(EGLDisplay dpy, + const sp& graphicBuffer, const Rect& crop); + + // Disallow copying + EglImage(const EglImage& rhs); + void operator = (const EglImage& rhs); + + // mGraphicBuffer is the buffer that was used to create this image. + sp mGraphicBuffer; + + // mEglImage is the EGLImage created from mGraphicBuffer. + EGLImageKHR mEglImage; + + // mEGLDisplay is the EGLDisplay that was used to create mEglImage. + EGLDisplay mEglDisplay; + + // mCropRect is the crop rectangle passed to EGL when mEglImage + // was created. + Rect mCropRect; + }; + + // freeBufferLocked frees up the given buffer slot. If the slot has been + // initialized this will release the reference to the GraphicBuffer in that + // slot and destroy the EGLImage in that slot. Otherwise it has no effect. + // + // This method must be called with mMutex locked. + virtual void freeBufferLocked(int slotIndex); + + // computeCurrentTransformMatrixLocked computes the transform matrix for the + // current texture. It uses mCurrentTransform and the current GraphicBuffer + // to compute this matrix and stores it in mCurrentTransformMatrix. + // mCurrentTextureImage must not be NULL. + void computeCurrentTransformMatrixLocked(); + + // doGLFenceWaitLocked inserts a wait command into the OpenGL ES command + // stream to ensure that it is safe for future OpenGL ES commands to + // access the current texture buffer. + status_t doGLFenceWaitLocked() const; + + // syncForReleaseLocked performs the synchronization needed to release the + // current slot from an OpenGL ES context. If needed it will set the + // current slot's fence to guard against a producer accessing the buffer + // before the outstanding accesses have completed. + status_t syncForReleaseLocked(EGLDisplay dpy); + + // returns a graphic buffer used when the texture image has been released + static sp getDebugTexImageBuffer(); + + // The default consumer usage flags that GLConsumer always sets on its + // BufferQueue instance; these will be OR:d with any additional flags passed + // from the GLConsumer user. In particular, GLConsumer will always + // consume buffers as hardware textures. + static const uint32_t DEFAULT_USAGE_FLAGS = GraphicBuffer::USAGE_HW_TEXTURE; + + // mCurrentTextureImage is the EglImage/buffer of the current texture. It's + // possible that this buffer is not associated with any buffer slot, so we + // must track it separately in order to support the getCurrentBuffer method. + sp mCurrentTextureImage; + + // mCurrentCrop is the crop rectangle that applies to the current texture. + // It gets set each time updateTexImage is called. + Rect mCurrentCrop; + + // mCurrentTransform is the transform identifier for the current texture. It + // gets set each time updateTexImage is called. + uint32_t mCurrentTransform; + + // mCurrentScalingMode is the scaling mode for the current texture. It gets + // set each time updateTexImage is called. + uint32_t mCurrentScalingMode; + + // mCurrentFence is the fence received from BufferQueue in updateTexImage. + sp mCurrentFence; + + // mCurrentTransformMatrix is the transform matrix for the current texture. + // It gets computed by computeTransformMatrix each time updateTexImage is + // called. + float mCurrentTransformMatrix[16]; + + // mCurrentTimestamp is the timestamp for the current texture. It + // gets set each time updateTexImage is called. + int64_t mCurrentTimestamp; + + // mCurrentFrameNumber is the frame counter for the current texture. + // It gets set each time updateTexImage is called. + uint64_t mCurrentFrameNumber; + + uint32_t mDefaultWidth, mDefaultHeight; + + // mFilteringEnabled indicates whether the transform matrix is computed for + // use with bilinear filtering. It defaults to true and is changed by + // setFilteringEnabled(). + bool mFilteringEnabled; + + // mTexName is the name of the OpenGL texture to which streamed images will + // be bound when updateTexImage is called. It is set at construction time + // and can be changed with a call to attachToContext. + uint32_t mTexName; + + // mUseFenceSync indicates whether creation of the EGL_KHR_fence_sync + // extension should be used to prevent buffers from being dequeued before + // it's safe for them to be written. It gets set at construction time and + // never changes. + const bool mUseFenceSync; + + // mTexTarget is the GL texture target with which the GL texture object is + // associated. It is set in the constructor and never changed. It is + // almost always GL_TEXTURE_EXTERNAL_OES except for one use case in Android + // Browser. In that case it is set to GL_TEXTURE_2D to allow + // glCopyTexSubImage to read from the texture. This is a hack to work + // around a GL driver limitation on the number of FBO attachments, which the + // browser's tile cache exceeds. + const uint32_t mTexTarget; + + // EGLSlot contains the information and object references that + // GLConsumer maintains about a BufferQueue buffer slot. + struct EglSlot { + EglSlot() : mEglFence(EGL_NO_SYNC_KHR) {} + + // mEglImage is the EGLImage created from mGraphicBuffer. + sp mEglImage; + + // mFence is the EGL sync object that must signal before the buffer + // associated with this buffer slot may be dequeued. It is initialized + // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based + // on a compile-time option) set to a new sync object in updateTexImage. + EGLSyncKHR mEglFence; + }; + + // mEglDisplay is the EGLDisplay with which this GLConsumer is currently + // associated. It is intialized to EGL_NO_DISPLAY and gets set to the + // current display when updateTexImage is called for the first time and when + // attachToContext is called. + EGLDisplay mEglDisplay; + + // mEglContext is the OpenGL ES context with which this GLConsumer is + // currently associated. It is initialized to EGL_NO_CONTEXT and gets set + // to the current GL context when updateTexImage is called for the first + // time and when attachToContext is called. + EGLContext mEglContext; + + // mEGLSlots stores the buffers that have been allocated by the BufferQueue + // for each buffer slot. It is initialized to null pointers, and gets + // filled in with the result of BufferQueue::acquire when the + // client dequeues a buffer from a + // slot that has not yet been used. The buffer allocated to a slot will also + // be replaced if the requested buffer usage or geometry differs from that + // of the buffer allocated to a slot. + EglSlot mEglSlots[BufferQueue::NUM_BUFFER_SLOTS]; + + // mCurrentTexture is the buffer slot index of the buffer that is currently + // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT, + // indicating that no buffer slot is currently bound to the texture. Note, + // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean + // that no buffer is bound to the texture. A call to setBufferCount will + // reset mCurrentTexture to INVALID_BUFFER_SLOT. + int mCurrentTexture; + + // mAttached indicates whether the ConsumerBase is currently attached to + // an OpenGL ES context. For legacy reasons, this is initialized to true, + // indicating that the ConsumerBase is considered to be attached to + // whatever context is current at the time of the first updateTexImage call. + // It is set to false by detachFromContext, and then set to true again by + // attachToContext. + bool mAttached; + + // protects static initialization + static Mutex sStaticInitLock; + + // mReleasedTexImageBuffer is a dummy buffer used when in single buffer + // mode and releaseTexImage() has been called + static sp sReleasedTexImageBuffer; + sp mReleasedTexImage; +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_CONSUMER_H diff --git a/phonelibs/android_frameworks_native/include/gui/GraphicBufferAlloc.h b/phonelibs/android_frameworks_native/include/gui/GraphicBufferAlloc.h new file mode 100644 index 00000000000000..69fe51ef932061 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/GraphicBufferAlloc.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H +#define ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H + +#include +#include + +#include +#include +#include + +namespace android { +// --------------------------------------------------------------------------- + +class GraphicBuffer; + +class GraphicBufferAlloc : public BnGraphicBufferAlloc { +public: + GraphicBufferAlloc(); + virtual ~GraphicBufferAlloc(); + virtual sp createGraphicBuffer(uint32_t width, + uint32_t height, PixelFormat format, uint32_t usage, + status_t* error); +}; + + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H diff --git a/phonelibs/android_frameworks_native/include/gui/GuiConfig.h b/phonelibs/android_frameworks_native/include/gui/GuiConfig.h new file mode 100644 index 00000000000000..b020ed9b6a3d13 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/GuiConfig.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_CONFIG_H +#define ANDROID_GUI_CONFIG_H + +#include + +namespace android { + +// Append the libgui configuration details to configStr. +void appendGuiConfigString(String8& configStr); + +}; // namespace android + +#endif /*ANDROID_GUI_CONFIG_H*/ diff --git a/phonelibs/android_frameworks_native/include/gui/IConsumerListener.h b/phonelibs/android_frameworks_native/include/gui/IConsumerListener.h new file mode 100644 index 00000000000000..3f3979956470f6 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/IConsumerListener.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_ICONSUMERLISTENER_H +#define ANDROID_GUI_ICONSUMERLISTENER_H + +#include +#include + +#include +#include + +#include + +namespace android { +// ---------------------------------------------------------------------------- + +class BufferItem; + +// ConsumerListener is the interface through which the BufferQueue notifies +// the consumer of events that the consumer may wish to react to. Because +// the consumer will generally have a mutex that is locked during calls from +// the consumer to the BufferQueue, these calls from the BufferQueue to the +// consumer *MUST* be called only when the BufferQueue mutex is NOT locked. + +class ConsumerListener : public virtual RefBase { +public: + ConsumerListener() { } + virtual ~ConsumerListener() { } + + // onFrameAvailable is called from queueBuffer each time an additional + // frame becomes available for consumption. This means that frames that + // are queued while in asynchronous mode only trigger the callback if no + // previous frames are pending. Frames queued while in synchronous mode + // always trigger the callback. The item passed to the callback will contain + // all of the information about the queued frame except for its + // GraphicBuffer pointer, which will always be null. + // + // This is called without any lock held and can be called concurrently + // by multiple threads. + virtual void onFrameAvailable(const BufferItem& item) = 0; /* Asynchronous */ + + // onFrameReplaced is called from queueBuffer if the frame being queued is + // replacing an existing slot in the queue. Any call to queueBuffer that + // doesn't call onFrameAvailable will call this callback instead. The item + // passed to the callback will contain all of the information about the + // queued frame except for its GraphicBuffer pointer, which will always be + // null. + // + // This is called without any lock held and can be called concurrently + // by multiple threads. + virtual void onFrameReplaced(const BufferItem& /* item */) {} /* Asynchronous */ + + // onBuffersReleased is called to notify the buffer consumer that the + // BufferQueue has released its references to one or more GraphicBuffers + // contained in its slots. The buffer consumer should then call + // BufferQueue::getReleasedBuffers to retrieve the list of buffers + // + // This is called without any lock held and can be called concurrently + // by multiple threads. + virtual void onBuffersReleased() = 0; /* Asynchronous */ + + // onSidebandStreamChanged is called to notify the buffer consumer that the + // BufferQueue's sideband buffer stream has changed. This is called when a + // stream is first attached and when it is either detached or replaced by a + // different stream. + virtual void onSidebandStreamChanged() = 0; /* Asynchronous */ +}; + + +class IConsumerListener : public ConsumerListener, public IInterface +{ +public: + DECLARE_META_INTERFACE(ConsumerListener); +}; + +// ---------------------------------------------------------------------------- + +class BnConsumerListener : public BnInterface +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_ICONSUMERLISTENER_H diff --git a/phonelibs/android_frameworks_native/include/gui/IDisplayEventConnection.h b/phonelibs/android_frameworks_native/include/gui/IDisplayEventConnection.h new file mode 100644 index 00000000000000..86247de62bb0ed --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/IDisplayEventConnection.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_IDISPLAY_EVENT_CONNECTION_H +#define ANDROID_GUI_IDISPLAY_EVENT_CONNECTION_H + +#include +#include + +#include +#include + +#include + +namespace android { +// ---------------------------------------------------------------------------- + +class BitTube; + +class IDisplayEventConnection : public IInterface +{ +public: + + DECLARE_META_INTERFACE(DisplayEventConnection); + + /* + * getDataChannel() returns a BitTube where to receive the events from + */ + virtual sp getDataChannel() const = 0; + + /* + * setVsyncRate() sets the vsync event delivery rate. A value of + * 1 returns every vsync events. A value of 2 returns every other events, + * etc... a value of 0 returns no event unless requestNextVsync() has + * been called. + */ + virtual void setVsyncRate(uint32_t count) = 0; + + /* + * requestNextVsync() schedules the next vsync event. It has no effect + * if the vsync rate is > 0. + */ + virtual void requestNextVsync() = 0; // asynchronous +}; + +// ---------------------------------------------------------------------------- + +class BnDisplayEventConnection : public BnInterface +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_IDISPLAY_EVENT_CONNECTION_H diff --git a/phonelibs/android_frameworks_native/include/gui/IGraphicBufferAlloc.h b/phonelibs/android_frameworks_native/include/gui/IGraphicBufferAlloc.h new file mode 100644 index 00000000000000..f3c46ec2edfa9d --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/IGraphicBufferAlloc.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_IGRAPHIC_BUFFER_ALLOC_H +#define ANDROID_GUI_IGRAPHIC_BUFFER_ALLOC_H + +#include +#include + +#include +#include +#include + +namespace android { +// ---------------------------------------------------------------------------- + +class GraphicBuffer; + +class IGraphicBufferAlloc : public IInterface +{ +public: + DECLARE_META_INTERFACE(GraphicBufferAlloc); + + /* Create a new GraphicBuffer for the client to use. + */ + virtual sp createGraphicBuffer(uint32_t w, uint32_t h, + PixelFormat format, uint32_t usage, status_t* error) = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnGraphicBufferAlloc : public BnInterface +{ +public: + virtual status_t onTransact(uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_GUI_IGRAPHIC_BUFFER_ALLOC_H diff --git a/phonelibs/android_frameworks_native/include/gui/IGraphicBufferConsumer.h b/phonelibs/android_frameworks_native/include/gui/IGraphicBufferConsumer.h new file mode 100644 index 00000000000000..60ec9cc0e91936 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/IGraphicBufferConsumer.h @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_IGRAPHICBUFFERCONSUMER_H +#define ANDROID_GUI_IGRAPHICBUFFERCONSUMER_H + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +namespace android { +// ---------------------------------------------------------------------------- + +class BufferItem; +class Fence; +class GraphicBuffer; +class IConsumerListener; +class NativeHandle; + +class IGraphicBufferConsumer : public IInterface { + +public: + enum { + // Returned by releaseBuffer, after which the consumer must + // free any references to the just-released buffer that it might have. + STALE_BUFFER_SLOT = 1, + // Returned by dequeueBuffer if there are no pending buffers available. + NO_BUFFER_AVAILABLE, + // Returned by dequeueBuffer if it's too early for the buffer to be acquired. + PRESENT_LATER, + }; + + // acquireBuffer attempts to acquire ownership of the next pending buffer in + // the BufferQueue. If no buffer is pending then it returns + // NO_BUFFER_AVAILABLE. If a buffer is successfully acquired, the + // information about the buffer is returned in BufferItem. + // + // If the buffer returned had previously been + // acquired then the BufferItem::mGraphicBuffer field of buffer is set to + // NULL and it is assumed that the consumer still holds a reference to the + // buffer. + // + // If presentWhen is non-zero, it indicates the time when the buffer will + // be displayed on screen. If the buffer's timestamp is farther in the + // future, the buffer won't be acquired, and PRESENT_LATER will be + // returned. The presentation time is in nanoseconds, and the time base + // is CLOCK_MONOTONIC. + // + // If maxFrameNumber is non-zero, it indicates that acquireBuffer should + // only return a buffer with a frame number less than or equal to + // maxFrameNumber. If no such frame is available (such as when a buffer has + // been replaced but the consumer has not received the onFrameReplaced + // callback), then PRESENT_LATER will be returned. + // + // Return of NO_ERROR means the operation completed as normal. + // + // Return of a positive value means the operation could not be completed + // at this time, but the user should try again later: + // * NO_BUFFER_AVAILABLE - no buffer is pending (nothing queued by producer) + // * PRESENT_LATER - the buffer's timestamp is farther in the future + // + // Return of a negative value means an error has occurred: + // * INVALID_OPERATION - too many buffers have been acquired + virtual status_t acquireBuffer(BufferItem* buffer, nsecs_t presentWhen, + uint64_t maxFrameNumber = 0) = 0; + + // detachBuffer attempts to remove all ownership of the buffer in the given + // slot from the buffer queue. If this call succeeds, the slot will be + // freed, and there will be no way to obtain the buffer from this interface. + // The freed slot will remain unallocated until either it is selected to + // hold a freshly allocated buffer in dequeueBuffer or a buffer is attached + // to the slot. The buffer must have already been acquired. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * BAD_VALUE - the given slot number is invalid, either because it is + // out of the range [0, NUM_BUFFER_SLOTS) or because the slot + // it refers to is not currently acquired. + virtual status_t detachBuffer(int slot) = 0; + + // attachBuffer attempts to transfer ownership of a buffer to the buffer + // queue. If this call succeeds, it will be as if this buffer was acquired + // from the returned slot number. As such, this call will fail if attaching + // this buffer would cause too many buffers to be simultaneously acquired. + // + // If the buffer is successfully attached, its frameNumber is initialized + // to 0. This must be passed into the releaseBuffer call or else the buffer + // will be deallocated as stale. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * BAD_VALUE - outSlot or buffer were NULL, or the generation number of + // the buffer did not match the buffer queue. + // * INVALID_OPERATION - cannot attach the buffer because it would cause too + // many buffers to be acquired. + // * NO_MEMORY - no free slots available + virtual status_t attachBuffer(int *outSlot, + const sp& buffer) = 0; + + // releaseBuffer releases a buffer slot from the consumer back to the + // BufferQueue. This may be done while the buffer's contents are still + // being accessed. The fence will signal when the buffer is no longer + // in use. frameNumber is used to indentify the exact buffer returned. + // + // If releaseBuffer returns STALE_BUFFER_SLOT, then the consumer must free + // any references to the just-released buffer that it might have, as if it + // had received a onBuffersReleased() call with a mask set for the released + // buffer. + // + // Note that the dependencies on EGL will be removed once we switch to using + // the Android HW Sync HAL. + // + // Return of NO_ERROR means the operation completed as normal. + // + // Return of a positive value means the operation could not be completed + // at this time, but the user should try again later: + // * STALE_BUFFER_SLOT - see above (second paragraph) + // + // Return of a negative value means an error has occurred: + // * BAD_VALUE - one of the following could've happened: + // * the buffer slot was invalid + // * the fence was NULL + // * the buffer slot specified is not in the acquired state + virtual status_t releaseBuffer(int buf, uint64_t frameNumber, + EGLDisplay display, EGLSyncKHR fence, + const sp& releaseFence) = 0; + + // consumerConnect connects a consumer to the BufferQueue. Only one + // consumer may be connected, and when that consumer disconnects the + // BufferQueue is placed into the "abandoned" state, causing most + // interactions with the BufferQueue by the producer to fail. + // controlledByApp indicates whether the consumer is controlled by + // the application. + // + // consumer may not be NULL. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned + // * BAD_VALUE - a NULL consumer was provided + virtual status_t consumerConnect(const sp& consumer, bool controlledByApp) = 0; + + // consumerDisconnect disconnects a consumer from the BufferQueue. All + // buffers will be freed and the BufferQueue is placed in the "abandoned" + // state, causing most interactions with the BufferQueue by the producer to + // fail. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * BAD_VALUE - no consumer is currently connected + virtual status_t consumerDisconnect() = 0; + + // getReleasedBuffers sets the value pointed to by slotMask to a bit set. + // Each bit index with a 1 corresponds to a released buffer slot with that + // index value. In particular, a released buffer is one that has + // been released by the BufferQueue but have not yet been released by the consumer. + // + // This should be called from the onBuffersReleased() callback. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned. + virtual status_t getReleasedBuffers(uint64_t* slotMask) = 0; + + // setDefaultBufferSize is used to set the size of buffers returned by + // dequeueBuffer when a width and height of zero is requested. Default + // is 1x1. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * BAD_VALUE - either w or h was zero + virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) = 0; + + // setDefaultMaxBufferCount sets the default value for the maximum buffer + // count (the initial default is 2). If the producer has requested a + // buffer count using setBufferCount, the default buffer count will only + // take effect if the producer sets the count back to zero. + // + // The count must be between 2 and NUM_BUFFER_SLOTS, inclusive. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * BAD_VALUE - bufferCount was out of range (see above). + virtual status_t setDefaultMaxBufferCount(int bufferCount) = 0; + + // disableAsyncBuffer disables the extra buffer used in async mode + // (when both producer and consumer have set their "isControlledByApp" + // flag) and has dequeueBuffer() return WOULD_BLOCK instead. + // + // This can only be called before consumerConnect(). + // + // Return of a value other than NO_ERROR means an error has occurred: + // * INVALID_OPERATION - attempting to call this after consumerConnect. + virtual status_t disableAsyncBuffer() = 0; + + // setMaxAcquiredBufferCount sets the maximum number of buffers that can + // be acquired by the consumer at one time (default 1). This call will + // fail if a producer is connected to the BufferQueue. + // + // maxAcquiredBuffers must be (inclusive) between 1 and MAX_MAX_ACQUIRED_BUFFERS. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * BAD_VALUE - maxAcquiredBuffers was out of range (see above). + // * INVALID_OPERATION - attempting to call this after a producer connected. + virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) = 0; + + // setConsumerName sets the name used in logging + virtual void setConsumerName(const String8& name) = 0; + + // setDefaultBufferFormat allows the BufferQueue to create + // GraphicBuffers of a defaultFormat if no format is specified + // in dequeueBuffer. + // The initial default is PIXEL_FORMAT_RGBA_8888. + // + // Return of a value other than NO_ERROR means an unknown error has occurred. + virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat) = 0; + + // setDefaultBufferDataSpace is a request to the producer to provide buffers + // of the indicated dataSpace. The producer may ignore this request. + // The initial default is HAL_DATASPACE_UNKNOWN. + // + // Return of a value other than NO_ERROR means an unknown error has occurred. + virtual status_t setDefaultBufferDataSpace( + android_dataspace defaultDataSpace) = 0; + + // setConsumerUsageBits will turn on additional usage bits for dequeueBuffer. + // These are merged with the bits passed to dequeueBuffer. The values are + // enumerated in gralloc.h, e.g. GRALLOC_USAGE_HW_RENDER; the default is 0. + // + // Return of a value other than NO_ERROR means an unknown error has occurred. + virtual status_t setConsumerUsageBits(uint32_t usage) = 0; + + // setTransformHint bakes in rotation to buffers so overlays can be used. + // The values are enumerated in window.h, e.g. + // NATIVE_WINDOW_TRANSFORM_ROT_90. The default is 0 (no transform). + // + // Return of a value other than NO_ERROR means an unknown error has occurred. + virtual status_t setTransformHint(uint32_t hint) = 0; + + // Retrieve the sideband buffer stream, if any. + virtual sp getSidebandStream() const = 0; + + // dump state into a string + virtual void dump(String8& result, const char* prefix) const = 0; + +public: + DECLARE_META_INTERFACE(GraphicBufferConsumer); +}; + +// ---------------------------------------------------------------------------- + +class BnGraphicBufferConsumer : public BnInterface +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_IGRAPHICBUFFERCONSUMER_H diff --git a/phonelibs/android_frameworks_native/include/gui/IGraphicBufferProducer.h b/phonelibs/android_frameworks_native/include/gui/IGraphicBufferProducer.h new file mode 100644 index 00000000000000..9530de1aa8b434 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/IGraphicBufferProducer.h @@ -0,0 +1,502 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_IGRAPHICBUFFERPRODUCER_H +#define ANDROID_GUI_IGRAPHICBUFFERPRODUCER_H + +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + +namespace android { +// ---------------------------------------------------------------------------- + +class IProducerListener; +class NativeHandle; +class Surface; + +/* + * This class defines the Binder IPC interface for the producer side of + * a queue of graphics buffers. It's used to send graphics data from one + * component to another. For example, a class that decodes video for + * playback might use this to provide frames. This is typically done + * indirectly, through Surface. + * + * The underlying mechanism is a BufferQueue, which implements + * BnGraphicBufferProducer. In normal operation, the producer calls + * dequeueBuffer() to get an empty buffer, fills it with data, then + * calls queueBuffer() to make it available to the consumer. + * + * This class was previously called ISurfaceTexture. + */ +class IGraphicBufferProducer : public IInterface +{ +public: + DECLARE_META_INTERFACE(GraphicBufferProducer); + + enum { + // A flag returned by dequeueBuffer when the client needs to call + // requestBuffer immediately thereafter. + BUFFER_NEEDS_REALLOCATION = 0x1, + // A flag returned by dequeueBuffer when all mirrored slots should be + // released by the client. This flag should always be processed first. + RELEASE_ALL_BUFFERS = 0x2, + }; + + // requestBuffer requests a new buffer for the given index. The server (i.e. + // the IGraphicBufferProducer implementation) assigns the newly created + // buffer to the given slot index, and the client is expected to mirror the + // slot->buffer mapping so that it's not necessary to transfer a + // GraphicBuffer for every dequeue operation. + // + // The slot must be in the range of [0, NUM_BUFFER_SLOTS). + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned. + // * BAD_VALUE - one of the two conditions occurred: + // * slot was out of range (see above) + // * buffer specified by the slot is not dequeued + virtual status_t requestBuffer(int slot, sp* buf) = 0; + + // setBufferCount sets the number of buffer slots available. Calling this + // will also cause all buffer slots to be emptied. The caller should empty + // its mirrored copy of the buffer slots when calling this method. + // + // This function should not be called when there are any dequeued buffer + // slots, doing so will result in a BAD_VALUE error returned. + // + // The buffer count should be at most NUM_BUFFER_SLOTS (inclusive), but at least + // the minimum undequeued buffer count (exclusive). The minimum value + // can be obtained by calling query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS). + // In particular the range is (minUndequeudBuffers, NUM_BUFFER_SLOTS]. + // + // The buffer count may also be set to 0 (the default), to indicate that + // the producer does not wish to set a value. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned. + // * BAD_VALUE - one of the below conditions occurred: + // * bufferCount was out of range (see above) + // * client has one or more buffers dequeued + virtual status_t setBufferCount(int bufferCount) = 0; + + // dequeueBuffer requests a new buffer slot for the client to use. Ownership + // of the slot is transfered to the client, meaning that the server will not + // use the contents of the buffer associated with that slot. + // + // The slot index returned may or may not contain a buffer (client-side). + // If the slot is empty the client should call requestBuffer to assign a new + // buffer to that slot. + // + // Once the client is done filling this buffer, it is expected to transfer + // buffer ownership back to the server with either cancelBuffer on + // the dequeued slot or to fill in the contents of its associated buffer + // contents and call queueBuffer. + // + // If dequeueBuffer returns the BUFFER_NEEDS_REALLOCATION flag, the client is + // expected to call requestBuffer immediately. + // + // If dequeueBuffer returns the RELEASE_ALL_BUFFERS flag, the client is + // expected to release all of the mirrored slot->buffer mappings. + // + // The fence parameter will be updated to hold the fence associated with + // the buffer. The contents of the buffer must not be overwritten until the + // fence signals. If the fence is Fence::NO_FENCE, the buffer may be written + // immediately. + // + // The async parameter sets whether we're in asynchronous mode for this + // dequeueBuffer() call. + // + // The width and height parameters must be no greater than the minimum of + // GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see: glGetIntegerv). + // An error due to invalid dimensions might not be reported until + // updateTexImage() is called. If width and height are both zero, the + // default values specified by setDefaultBufferSize() are used instead. + // + // If the format is 0, the default format will be used. + // + // The usage argument specifies gralloc buffer usage flags. The values + // are enumerated in , e.g. GRALLOC_USAGE_HW_RENDER. These + // will be merged with the usage flags specified by + // IGraphicBufferConsumer::setConsumerUsageBits. + // + // This call will block until a buffer is available to be dequeued. If + // both the producer and consumer are controlled by the app, then this call + // can never block and will return WOULD_BLOCK if no buffer is available. + // + // A non-negative value with flags set (see above) will be returned upon + // success. + // + // Return of a negative means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned. + // * BAD_VALUE - both in async mode and buffer count was less than the + // max numbers of buffers that can be allocated at once. + // * INVALID_OPERATION - cannot attach the buffer because it would cause + // too many buffers to be dequeued, either because + // the producer already has a single buffer dequeued + // and did not set a buffer count, or because a + // buffer count was set and this call would cause + // it to be exceeded. + // * WOULD_BLOCK - no buffer is currently available, and blocking is disabled + // since both the producer/consumer are controlled by app + // * NO_MEMORY - out of memory, cannot allocate the graphics buffer. + // + // All other negative values are an unknown error returned downstream + // from the graphics allocator (typically errno). + virtual status_t dequeueBuffer(int* slot, sp* fence, bool async, + uint32_t w, uint32_t h, PixelFormat format, uint32_t usage) = 0; + + // detachBuffer attempts to remove all ownership of the buffer in the given + // slot from the buffer queue. If this call succeeds, the slot will be + // freed, and there will be no way to obtain the buffer from this interface. + // The freed slot will remain unallocated until either it is selected to + // hold a freshly allocated buffer in dequeueBuffer or a buffer is attached + // to the slot. The buffer must have already been dequeued, and the caller + // must already possesses the sp (i.e., must have called + // requestBuffer). + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned. + // * BAD_VALUE - the given slot number is invalid, either because it is + // out of the range [0, NUM_BUFFER_SLOTS), or because the slot + // it refers to is not currently dequeued and requested. + virtual status_t detachBuffer(int slot) = 0; + + // detachNextBuffer is equivalent to calling dequeueBuffer, requestBuffer, + // and detachBuffer in sequence, except for two things: + // + // 1) It is unnecessary to know the dimensions, format, or usage of the + // next buffer. + // 2) It will not block, since if it cannot find an appropriate buffer to + // return, it will return an error instead. + // + // Only slots that are free but still contain a GraphicBuffer will be + // considered, and the oldest of those will be returned. outBuffer is + // equivalent to outBuffer from the requestBuffer call, and outFence is + // equivalent to fence from the dequeueBuffer call. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned. + // * BAD_VALUE - either outBuffer or outFence were NULL. + // * NO_MEMORY - no slots were found that were both free and contained a + // GraphicBuffer. + virtual status_t detachNextBuffer(sp* outBuffer, + sp* outFence) = 0; + + // attachBuffer attempts to transfer ownership of a buffer to the buffer + // queue. If this call succeeds, it will be as if this buffer was dequeued + // from the returned slot number. As such, this call will fail if attaching + // this buffer would cause too many buffers to be simultaneously dequeued. + // + // If attachBuffer returns the RELEASE_ALL_BUFFERS flag, the caller is + // expected to release all of the mirrored slot->buffer mappings. + // + // A non-negative value with flags set (see above) will be returned upon + // success. + // + // Return of a negative value means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned. + // * BAD_VALUE - outSlot or buffer were NULL, invalid combination of + // async mode and buffer count override, or the generation + // number of the buffer did not match the buffer queue. + // * INVALID_OPERATION - cannot attach the buffer because it would cause + // too many buffers to be dequeued, either because + // the producer already has a single buffer dequeued + // and did not set a buffer count, or because a + // buffer count was set and this call would cause + // it to be exceeded. + // * WOULD_BLOCK - no buffer slot is currently available, and blocking is + // disabled since both the producer/consumer are + // controlled by the app. + virtual status_t attachBuffer(int* outSlot, + const sp& buffer) = 0; + + // queueBuffer indicates that the client has finished filling in the + // contents of the buffer associated with slot and transfers ownership of + // that slot back to the server. + // + // It is not valid to call queueBuffer on a slot that is not owned + // by the client or one for which a buffer associated via requestBuffer + // (an attempt to do so will fail with a return value of BAD_VALUE). + // + // In addition, the input must be described by the client (as documented + // below). Any other properties (zero point, etc) + // are client-dependent, and should be documented by the client. + // + // The slot must be in the range of [0, NUM_BUFFER_SLOTS). + // + // Upon success, the output will be filled with meaningful values + // (refer to the documentation below). + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned. + // * BAD_VALUE - one of the below conditions occurred: + // * fence was NULL + // * scaling mode was unknown + // * both in async mode and buffer count was less than the + // max numbers of buffers that can be allocated at once + // * slot index was out of range (see above). + // * the slot was not in the dequeued state + // * the slot was enqueued without requesting a buffer + // * crop rect is out of bounds of the buffer dimensions + + struct QueueBufferInput : public Flattenable { + friend class Flattenable; + inline QueueBufferInput(const Parcel& parcel); + // timestamp - a monotonically increasing value in nanoseconds + // isAutoTimestamp - if the timestamp was synthesized at queue time + // dataSpace - description of the contents, interpretation depends on format + // crop - a crop rectangle that's used as a hint to the consumer + // scalingMode - a set of flags from NATIVE_WINDOW_SCALING_* in + // transform - a set of flags from NATIVE_WINDOW_TRANSFORM_* in + // async - if the buffer is queued in asynchronous mode + // fence - a fence that the consumer must wait on before reading the buffer, + // set this to Fence::NO_FENCE if the buffer is ready immediately + // sticky - the sticky transform set in Surface (only used by the LEGACY + // camera mode). + inline QueueBufferInput(int64_t timestamp, bool isAutoTimestamp, + android_dataspace dataSpace, const Rect& crop, int scalingMode, + uint32_t transform, bool async, const sp& fence, + uint32_t sticky = 0) + : timestamp(timestamp), isAutoTimestamp(isAutoTimestamp), + dataSpace(dataSpace), crop(crop), scalingMode(scalingMode), + transform(transform), stickyTransform(sticky), + async(async), fence(fence), surfaceDamage() { } + inline void deflate(int64_t* outTimestamp, bool* outIsAutoTimestamp, + android_dataspace* outDataSpace, + Rect* outCrop, int* outScalingMode, + uint32_t* outTransform, bool* outAsync, sp* outFence, + uint32_t* outStickyTransform = NULL) const { + *outTimestamp = timestamp; + *outIsAutoTimestamp = bool(isAutoTimestamp); + *outDataSpace = dataSpace; + *outCrop = crop; + *outScalingMode = scalingMode; + *outTransform = transform; + *outAsync = bool(async); + *outFence = fence; + if (outStickyTransform != NULL) { + *outStickyTransform = stickyTransform; + } + } + + // Flattenable protocol + size_t getFlattenedSize() const; + size_t getFdCount() const; + status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const; + status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count); + + const Region& getSurfaceDamage() const { return surfaceDamage; } + void setSurfaceDamage(const Region& damage) { surfaceDamage = damage; } + + private: + int64_t timestamp; + int isAutoTimestamp; + android_dataspace dataSpace; + Rect crop; + int scalingMode; + uint32_t transform; + uint32_t stickyTransform; + int async; + sp fence; + Region surfaceDamage; + }; + + // QueueBufferOutput must be a POD structure + struct __attribute__ ((__packed__)) QueueBufferOutput { + inline QueueBufferOutput() { } + // outWidth - filled with default width applied to the buffer + // outHeight - filled with default height applied to the buffer + // outTransformHint - filled with default transform applied to the buffer + // outNumPendingBuffers - num buffers queued that haven't yet been acquired + // (counting the currently queued buffer) + inline void deflate(uint32_t* outWidth, + uint32_t* outHeight, + uint32_t* outTransformHint, + uint32_t* outNumPendingBuffers) const { + *outWidth = width; + *outHeight = height; + *outTransformHint = transformHint; + *outNumPendingBuffers = numPendingBuffers; + } + inline void inflate(uint32_t inWidth, uint32_t inHeight, + uint32_t inTransformHint, uint32_t inNumPendingBuffers) { + width = inWidth; + height = inHeight; + transformHint = inTransformHint; + numPendingBuffers = inNumPendingBuffers; + } + private: + uint32_t width; + uint32_t height; + uint32_t transformHint; + uint32_t numPendingBuffers; + }; + + virtual status_t queueBuffer(int slot, + const QueueBufferInput& input, QueueBufferOutput* output) = 0; + + // cancelBuffer indicates that the client does not wish to fill in the + // buffer associated with slot and transfers ownership of the slot back to + // the server. + // + // The buffer is not queued for use by the consumer. + // + // The buffer will not be overwritten until the fence signals. The fence + // will usually be the one obtained from dequeueBuffer. + virtual void cancelBuffer(int slot, const sp& fence) = 0; + + // query retrieves some information for this surface + // 'what' tokens allowed are that of NATIVE_WINDOW_* in + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - the buffer queue has been abandoned. + // * BAD_VALUE - what was out of range + virtual int query(int what, int* value) = 0; + + // connect attempts to connect a client API to the IGraphicBufferProducer. + // This must be called before any other IGraphicBufferProducer methods are + // called except for getAllocator. A consumer must be already connected. + // + // This method will fail if the connect was previously called on the + // IGraphicBufferProducer and no corresponding disconnect call was made. + // + // The listener is an optional binder callback object that can be used if + // the producer wants to be notified when the consumer releases a buffer + // back to the BufferQueue. It is also used to detect the death of the + // producer. If only the latter functionality is desired, there is a + // DummyProducerListener class in IProducerListener.h that can be used. + // + // The api should be one of the NATIVE_WINDOW_API_* values in + // + // The producerControlledByApp should be set to true if the producer is hosted + // by an untrusted process (typically app_process-forked processes). If both + // the producer and the consumer are app-controlled then all buffer queues + // will operate in async mode regardless of the async flag. + // + // Upon success, the output will be filled with meaningful data + // (refer to QueueBufferOutput documentation above). + // + // Return of a value other than NO_ERROR means an error has occurred: + // * NO_INIT - one of the following occurred: + // * the buffer queue was abandoned + // * no consumer has yet connected + // * BAD_VALUE - one of the following has occurred: + // * the producer is already connected + // * api was out of range (see above). + // * output was NULL. + // * DEAD_OBJECT - the token is hosted by an already-dead process + // + // Additional negative errors may be returned by the internals, they + // should be treated as opaque fatal unrecoverable errors. + virtual status_t connect(const sp& listener, + int api, bool producerControlledByApp, QueueBufferOutput* output) = 0; + + // disconnect attempts to disconnect a client API from the + // IGraphicBufferProducer. Calling this method will cause any subsequent + // calls to other IGraphicBufferProducer methods to fail except for + // getAllocator and connect. Successfully calling connect after this will + // allow the other methods to succeed again. + // + // This method will fail if the the IGraphicBufferProducer is not currently + // connected to the specified client API. + // + // The api should be one of the NATIVE_WINDOW_API_* values in + // + // Disconnecting from an abandoned IGraphicBufferProducer is legal and + // is considered a no-op. + // + // Return of a value other than NO_ERROR means an error has occurred: + // * BAD_VALUE - one of the following has occurred: + // * the api specified does not match the one that was connected + // * api was out of range (see above). + // * DEAD_OBJECT - the token is hosted by an already-dead process + virtual status_t disconnect(int api) = 0; + + // Attaches a sideband buffer stream to the IGraphicBufferProducer. + // + // A sideband stream is a device-specific mechanism for passing buffers + // from the producer to the consumer without using dequeueBuffer/ + // queueBuffer. If a sideband stream is present, the consumer can choose + // whether to acquire buffers from the sideband stream or from the queued + // buffers. + // + // Passing NULL or a different stream handle will detach the previous + // handle if any. + virtual status_t setSidebandStream(const sp& stream) = 0; + + // Allocates buffers based on the given dimensions/format. + // + // This function will allocate up to the maximum number of buffers + // permitted by the current BufferQueue configuration. It will use the + // given format, dimensions, and usage bits, which are interpreted in the + // same way as for dequeueBuffer, and the async flag must be set the same + // way as for dequeueBuffer to ensure that the correct number of buffers are + // allocated. This is most useful to avoid an allocation delay during + // dequeueBuffer. If there are already the maximum number of buffers + // allocated, this function has no effect. + virtual void allocateBuffers(bool async, uint32_t width, uint32_t height, + PixelFormat format, uint32_t usage) = 0; + + // Sets whether dequeueBuffer is allowed to allocate new buffers. + // + // Normally dequeueBuffer does not discriminate between free slots which + // already have an allocated buffer and those which do not, and will + // allocate a new buffer if the slot doesn't have a buffer or if the slot's + // buffer doesn't match the requested size, format, or usage. This method + // allows the producer to restrict the eligible slots to those which already + // have an allocated buffer of the correct size, format, and usage. If no + // eligible slot is available, dequeueBuffer will block or return an error + // as usual. + virtual status_t allowAllocation(bool allow) = 0; + + // Sets the current generation number of the BufferQueue. + // + // This generation number will be inserted into any buffers allocated by the + // BufferQueue, and any attempts to attach a buffer with a different + // generation number will fail. Buffers already in the queue are not + // affected and will retain their current generation number. The generation + // number defaults to 0. + virtual status_t setGenerationNumber(uint32_t generationNumber) = 0; + + // Returns the name of the connected consumer. + virtual String8 getConsumerName() const = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnGraphicBufferProducer : public BnInterface +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_IGRAPHICBUFFERPRODUCER_H diff --git a/phonelibs/android_frameworks_native/include/gui/IProducerListener.h b/phonelibs/android_frameworks_native/include/gui/IProducerListener.h new file mode 100644 index 00000000000000..3848a6c850ed69 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/IProducerListener.h @@ -0,0 +1,67 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_IPRODUCERLISTENER_H +#define ANDROID_GUI_IPRODUCERLISTENER_H + +#include + +#include + +namespace android { + +// ProducerListener is the interface through which the BufferQueue notifies the +// producer of events that the producer may wish to react to. Because the +// producer will generally have a mutex that is locked during calls from the +// producer to the BufferQueue, these calls from the BufferQueue to the +// producer *MUST* be called only when the BufferQueue mutex is NOT locked. + +class ProducerListener : public virtual RefBase +{ +public: + ProducerListener() {} + virtual ~ProducerListener() {} + + // onBufferReleased is called from IGraphicBufferConsumer::releaseBuffer to + // notify the producer that a new buffer is free and ready to be dequeued. + // + // This is called without any lock held and can be called concurrently by + // multiple threads. + virtual void onBufferReleased() = 0; // Asynchronous +}; + +class IProducerListener : public ProducerListener, public IInterface +{ +public: + DECLARE_META_INTERFACE(ProducerListener) +}; + +class BnProducerListener : public BnInterface +{ +public: + virtual status_t onTransact(uint32_t code, const Parcel& data, + Parcel* reply, uint32_t flags = 0); +}; + +class DummyProducerListener : public BnProducerListener +{ +public: + virtual void onBufferReleased() {} +}; + +} // namespace android + +#endif diff --git a/phonelibs/android_frameworks_native/include/gui/ISensorEventConnection.h b/phonelibs/android_frameworks_native/include/gui/ISensorEventConnection.h new file mode 100644 index 00000000000000..f64c6b8604ebab --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/ISensorEventConnection.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_ISENSOR_EVENT_CONNECTION_H +#define ANDROID_GUI_ISENSOR_EVENT_CONNECTION_H + +#include +#include + +#include +#include + +#include + +namespace android { +// ---------------------------------------------------------------------------- + +class BitTube; + +class ISensorEventConnection : public IInterface +{ +public: + DECLARE_META_INTERFACE(SensorEventConnection); + + virtual sp getSensorChannel() const = 0; + virtual status_t enableDisable(int handle, bool enabled, nsecs_t samplingPeriodNs, + nsecs_t maxBatchReportLatencyNs, int reservedFlags) = 0; + virtual status_t setEventRate(int handle, nsecs_t ns) = 0; + virtual status_t flush() = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnSensorEventConnection : public BnInterface +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_ISENSOR_EVENT_CONNECTION_H diff --git a/phonelibs/android_frameworks_native/include/gui/ISensorServer.h b/phonelibs/android_frameworks_native/include/gui/ISensorServer.h new file mode 100644 index 00000000000000..3dca2a37398e4a --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/ISensorServer.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_ISENSORSERVER_H +#define ANDROID_GUI_ISENSORSERVER_H + +#include +#include + +#include +#include + +#include + +namespace android { +// ---------------------------------------------------------------------------- + +class Sensor; +class ISensorEventConnection; +class String8; + +class ISensorServer : public IInterface +{ +public: + DECLARE_META_INTERFACE(SensorServer); + + virtual Vector getSensorList(const String16& opPackageName) = 0; + virtual sp createSensorEventConnection(const String8& packageName, + int mode, const String16& opPackageName) = 0; + virtual int32_t isDataInjectionEnabled() = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnSensorServer : public BnInterface +{ +public: + virtual status_t onTransact( uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_ISENSORSERVER_H diff --git a/phonelibs/android_frameworks_native/include/gui/ISurfaceComposer.h b/phonelibs/android_frameworks_native/include/gui/ISurfaceComposer.h new file mode 100644 index 00000000000000..6e3fc5a6decd09 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/ISurfaceComposer.h @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_ISURFACE_COMPOSER_H +#define ANDROID_GUI_ISURFACE_COMPOSER_H + +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#include +#include + +namespace android { +// ---------------------------------------------------------------------------- + +class ComposerState; +class DisplayState; +struct DisplayInfo; +struct DisplayStatInfo; +class IDisplayEventConnection; +class IMemoryHeap; +class Rect; + +/* + * This class defines the Binder IPC interface for accessing various + * SurfaceFlinger features. + */ +class ISurfaceComposer: public IInterface { +public: + DECLARE_META_INTERFACE(SurfaceComposer); + + // flags for setTransactionState() + enum { + eSynchronous = 0x01, + eAnimation = 0x02, + }; + + enum { + eDisplayIdMain = 0, + eDisplayIdHdmi = 1, +#ifdef QTI_BSP + eDisplayIdTertiary = 2 +#endif + }; + + enum Rotation { + eRotateNone = 0, + eRotate90 = 1, + eRotate180 = 2, + eRotate270 = 3 + }; + + /* create connection with surface flinger, requires + * ACCESS_SURFACE_FLINGER permission + */ + virtual sp createConnection() = 0; + + /* create a graphic buffer allocator + */ + virtual sp createGraphicBufferAlloc() = 0; + + /* return an IDisplayEventConnection */ + virtual sp createDisplayEventConnection() = 0; + + /* create a virtual display + * requires ACCESS_SURFACE_FLINGER permission. + */ + virtual sp createDisplay(const String8& displayName, + bool secure) = 0; + + /* destroy a virtual display + * requires ACCESS_SURFACE_FLINGER permission. + */ + virtual void destroyDisplay(const sp& display) = 0; + + /* get the token for the existing default displays. possible values + * for id are eDisplayIdMain and eDisplayIdHdmi. + */ + virtual sp getBuiltInDisplay(int32_t id) = 0; + + /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */ + virtual void setTransactionState(const Vector& state, + const Vector& displays, uint32_t flags) = 0; + + /* signal that we're done booting. + * Requires ACCESS_SURFACE_FLINGER permission + */ + virtual void bootFinished() = 0; + + /* verify that an IGraphicBufferProducer was created by SurfaceFlinger. + */ + virtual bool authenticateSurfaceTexture( + const sp& surface) const = 0; + + /* set display power mode. depending on the mode, it can either trigger + * screen on, off or low power mode and wait for it to complete. + * requires ACCESS_SURFACE_FLINGER permission. + */ + virtual void setPowerMode(const sp& display, int mode) = 0; + + /* returns information for each configuration of the given display + * intended to be used to get information about built-in displays */ + virtual status_t getDisplayConfigs(const sp& display, + Vector* configs) = 0; + + /* returns display statistics for a given display + * intended to be used by the media framework to properly schedule + * video frames */ + virtual status_t getDisplayStats(const sp& display, + DisplayStatInfo* stats) = 0; + + /* indicates which of the configurations returned by getDisplayInfo is + * currently active */ + virtual int getActiveConfig(const sp& display) = 0; + + /* specifies which configuration (of those returned by getDisplayInfo) + * should be used */ + virtual status_t setActiveConfig(const sp& display, int id) = 0; + + /* Capture the specified screen. requires READ_FRAME_BUFFER permission + * This function will fail if there is a secure window on screen. + */ + virtual status_t captureScreen(const sp& display, + const sp& producer, + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ, + bool useIdentityTransform, + Rotation rotation = eRotateNone, + bool isCpuConsumer = false) = 0; + + /* Clears the frame statistics for animations. + * + * Requires the ACCESS_SURFACE_FLINGER permission. + */ + virtual status_t clearAnimationFrameStats() = 0; + + /* Gets the frame statistics for animations. + * + * Requires the ACCESS_SURFACE_FLINGER permission. + */ + virtual status_t getAnimationFrameStats(FrameStats* outStats) const = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnSurfaceComposer: public BnInterface { +public: + enum { + // Note: BOOT_FINISHED must remain this value, it is called from + // Java by ActivityManagerService. + BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION, + CREATE_CONNECTION, + CREATE_GRAPHIC_BUFFER_ALLOC, + CREATE_DISPLAY_EVENT_CONNECTION, + CREATE_DISPLAY, + DESTROY_DISPLAY, + GET_BUILT_IN_DISPLAY, + SET_TRANSACTION_STATE, + AUTHENTICATE_SURFACE, + GET_DISPLAY_CONFIGS, + GET_ACTIVE_CONFIG, + SET_ACTIVE_CONFIG, + CONNECT_DISPLAY, + CAPTURE_SCREEN, + CLEAR_ANIMATION_FRAME_STATS, + GET_ANIMATION_FRAME_STATS, + SET_POWER_MODE, + GET_DISPLAY_STATS, + }; + + virtual status_t onTransact(uint32_t code, const Parcel& data, + Parcel* reply, uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_GUI_ISURFACE_COMPOSER_H diff --git a/phonelibs/android_frameworks_native/include/gui/ISurfaceComposerClient.h b/phonelibs/android_frameworks_native/include/gui/ISurfaceComposerClient.h new file mode 100644 index 00000000000000..d3e8b8ba13f1bc --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/ISurfaceComposerClient.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_ISURFACE_COMPOSER_CLIENT_H +#define ANDROID_GUI_ISURFACE_COMPOSER_CLIENT_H + +#include +#include + +#include +#include + +#include + +#include +#include + +namespace android { +// ---------------------------------------------------------------------------- + +class IGraphicBufferProducer; + +class ISurfaceComposerClient : public IInterface +{ +public: + DECLARE_META_INTERFACE(SurfaceComposerClient); + + // flags for createSurface() + enum { // (keep in sync with Surface.java) + eHidden = 0x00000004, + eDestroyBackbuffer = 0x00000020, + eSecure = 0x00000080, + eNonPremultiplied = 0x00000100, + eOpaque = 0x00000400, + eProtectedByApp = 0x00000800, + eProtectedByDRM = 0x00001000, + eCursorWindow = 0x00002000, + + eFXSurfaceNormal = 0x00000000, + eFXSurfaceBlur = 0x00010000, + eFXSurfaceDim = 0x00020000, + eFXSurfaceMask = 0x000F0000, + }; + + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ + virtual status_t createSurface( + const String8& name, uint32_t w, uint32_t h, + PixelFormat format, uint32_t flags, + sp* handle, + sp* gbp) = 0; + + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ + virtual status_t destroySurface(const sp& handle) = 0; + + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ + virtual status_t clearLayerFrameStats(const sp& handle) const = 0; + + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ + virtual status_t getLayerFrameStats(const sp& handle, FrameStats* outStats) const = 0; +}; + +// ---------------------------------------------------------------------------- + +class BnSurfaceComposerClient: public BnInterface { +public: + virtual status_t onTransact(uint32_t code, const Parcel& data, + Parcel* reply, uint32_t flags = 0); +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_GUI_ISURFACE_COMPOSER_CLIENT_H diff --git a/phonelibs/android_frameworks_native/include/gui/Sensor.h b/phonelibs/android_frameworks_native/include/gui/Sensor.h new file mode 100644 index 00000000000000..8142be635204dc --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/Sensor.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_SENSOR_H +#define ANDROID_GUI_SENSOR_H + +#include +#include + +#include +#include +#include +#include + +#include + +#include + +// ---------------------------------------------------------------------------- +// Concrete types for the NDK +struct ASensor { }; + +// ---------------------------------------------------------------------------- +namespace android { +// ---------------------------------------------------------------------------- + +class Parcel; + +// ---------------------------------------------------------------------------- + +class Sensor : public ASensor, public LightFlattenable +{ +public: + enum { + TYPE_ACCELEROMETER = ASENSOR_TYPE_ACCELEROMETER, + TYPE_MAGNETIC_FIELD = ASENSOR_TYPE_MAGNETIC_FIELD, + TYPE_GYROSCOPE = ASENSOR_TYPE_GYROSCOPE, + TYPE_LIGHT = ASENSOR_TYPE_LIGHT, + TYPE_PROXIMITY = ASENSOR_TYPE_PROXIMITY + }; + + Sensor(); + Sensor(struct sensor_t const* hwSensor, int halVersion = 0); + ~Sensor(); + + const String8& getName() const; + const String8& getVendor() const; + int32_t getHandle() const; + int32_t getType() const; + float getMinValue() const; + float getMaxValue() const; + float getResolution() const; + float getPowerUsage() const; + int32_t getMinDelay() const; + nsecs_t getMinDelayNs() const; + int32_t getVersion() const; + uint32_t getFifoReservedEventCount() const; + uint32_t getFifoMaxEventCount() const; + const String8& getStringType() const; + const String8& getRequiredPermission() const; + bool isRequiredPermissionRuntime() const; + int32_t getRequiredAppOp() const; + int32_t getMaxDelay() const; + uint32_t getFlags() const; + bool isWakeUpSensor() const; + int32_t getReportingMode() const; + + // LightFlattenable protocol + inline bool isFixedSize() const { return false; } + size_t getFlattenedSize() const; + status_t flatten(void* buffer, size_t size) const; + status_t unflatten(void const* buffer, size_t size); + +private: + String8 mName; + String8 mVendor; + int32_t mHandle; + int32_t mType; + float mMinValue; + float mMaxValue; + float mResolution; + float mPower; + int32_t mMinDelay; + int32_t mVersion; + uint32_t mFifoReservedEventCount; + uint32_t mFifoMaxEventCount; + String8 mStringType; + String8 mRequiredPermission; + bool mRequiredPermissionRuntime = false; + int32_t mRequiredAppOp; + int32_t mMaxDelay; + uint32_t mFlags; + static void flattenString8(void*& buffer, size_t& size, const String8& string8); + static bool unflattenString8(void const*& buffer, size_t& size, String8& outputString8); +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_SENSOR_H diff --git a/phonelibs/android_frameworks_native/include/gui/SensorEventQueue.h b/phonelibs/android_frameworks_native/include/gui/SensorEventQueue.h new file mode 100644 index 00000000000000..e5b9fc59847a9b --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/SensorEventQueue.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SENSOR_EVENT_QUEUE_H +#define ANDROID_SENSOR_EVENT_QUEUE_H + +#include +#include + +#include +#include +#include +#include + +#include + +// ---------------------------------------------------------------------------- +#define WAKE_UP_SENSOR_EVENT_NEEDS_ACK (1U << 31) +struct ALooper; +struct ASensorEvent; + +// Concrete types for the NDK +struct ASensorEventQueue { + ALooper* looper; +}; + +// ---------------------------------------------------------------------------- +namespace android { +// ---------------------------------------------------------------------------- + +class ISensorEventConnection; +class Sensor; +class Looper; + +// ---------------------------------------------------------------------------- + +class SensorEventQueue : public ASensorEventQueue, public RefBase +{ +public: + + enum { MAX_RECEIVE_BUFFER_EVENT_COUNT = 256 }; + + SensorEventQueue(const sp& connection); + virtual ~SensorEventQueue(); + virtual void onFirstRef(); + + int getFd() const; + + static ssize_t write(const sp& tube, + ASensorEvent const* events, size_t numEvents); + + ssize_t read(ASensorEvent* events, size_t numEvents); + + status_t waitForEvent() const; + status_t wake() const; + + status_t enableSensor(Sensor const* sensor) const; + status_t disableSensor(Sensor const* sensor) const; + status_t setEventRate(Sensor const* sensor, nsecs_t ns) const; + + // these are here only to support SensorManager.java + status_t enableSensor(int32_t handle, int32_t samplingPeriodUs, int maxBatchReportLatencyUs, + int reservedFlags) const; + status_t disableSensor(int32_t handle) const; + status_t flush() const; + // Send an ack for every wake_up sensor event that is set to WAKE_UP_SENSOR_EVENT_NEEDS_ACK. + void sendAck(const ASensorEvent* events, int count); + + status_t injectSensorEvent(const ASensorEvent& event); +private: + sp getLooper() const; + sp mSensorEventConnection; + sp mSensorChannel; + mutable Mutex mLock; + mutable sp mLooper; + ASensorEvent* mRecBuffer; + size_t mAvailable; + size_t mConsumed; + uint32_t mNumAcksToSend; +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_SENSOR_EVENT_QUEUE_H diff --git a/phonelibs/android_frameworks_native/include/gui/SensorManager.h b/phonelibs/android_frameworks_native/include/gui/SensorManager.h new file mode 100644 index 00000000000000..0cff46c076231f --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/SensorManager.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_SENSOR_MANAGER_H +#define ANDROID_GUI_SENSOR_MANAGER_H + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +// ---------------------------------------------------------------------------- +// Concrete types for the NDK +struct ASensorManager { }; + +// ---------------------------------------------------------------------------- +namespace android { +// ---------------------------------------------------------------------------- + +class ISensorServer; +class Sensor; +class SensorEventQueue; +// ---------------------------------------------------------------------------- + +class SensorManager : + public ASensorManager +{ +public: + static SensorManager& getInstanceForPackage(const String16& packageName); + ~SensorManager(); + + ssize_t getSensorList(Sensor const* const** list) const; + Sensor const* getDefaultSensor(int type); + sp createEventQueue(String8 packageName = String8(""), int mode = 0); + bool isDataInjectionEnabled(); + +private: + // DeathRecipient interface + void sensorManagerDied(); + + SensorManager(const String16& opPackageName); + status_t assertStateLocked() const; + +private: + static Mutex sLock; + static std::map sPackageInstances; + + mutable Mutex mLock; + mutable sp mSensorServer; + mutable Sensor const** mSensorList; + mutable Vector mSensors; + mutable sp mDeathObserver; + const String16 mOpPackageName; +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_SENSOR_MANAGER_H diff --git a/phonelibs/android_frameworks_native/include/gui/StreamSplitter.h b/phonelibs/android_frameworks_native/include/gui/StreamSplitter.h new file mode 100644 index 00000000000000..8f47eb47ac444c --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/StreamSplitter.h @@ -0,0 +1,184 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_STREAMSPLITTER_H +#define ANDROID_GUI_STREAMSPLITTER_H + +#include +#include + +#include +#include +#include +#include + +namespace android { + +class GraphicBuffer; +class IGraphicBufferConsumer; +class IGraphicBufferProducer; + +// StreamSplitter is an autonomous class that manages one input BufferQueue +// and multiple output BufferQueues. By using the buffer attach and detach logic +// in BufferQueue, it is able to present the illusion of a single split +// BufferQueue, where each buffer queued to the input is available to be +// acquired by each of the outputs, and is able to be dequeued by the input +// again only once all of the outputs have released it. +class StreamSplitter : public BnConsumerListener { +public: + // createSplitter creates a new splitter, outSplitter, using inputQueue as + // the input BufferQueue. Output BufferQueues must be added using addOutput + // before queueing any buffers to the input. + // + // A return value other than NO_ERROR means that an error has occurred and + // outSplitter has not been modified. BAD_VALUE is returned if inputQueue or + // outSplitter is NULL. See IGraphicBufferConsumer::consumerConnect for + // explanations of other error codes. + static status_t createSplitter(const sp& inputQueue, + sp* outSplitter); + + // addOutput adds an output BufferQueue to the splitter. The splitter + // connects to outputQueue as a CPU producer, and any buffers queued + // to the input will be queued to each output. It is assumed that all of the + // outputs are added before any buffers are queued on the input. If any + // output is abandoned by its consumer, the splitter will abandon its input + // queue (see onAbandoned). + // + // A return value other than NO_ERROR means that an error has occurred and + // outputQueue has not been added to the splitter. BAD_VALUE is returned if + // outputQueue is NULL. See IGraphicBufferProducer::connect for explanations + // of other error codes. + status_t addOutput(const sp& outputQueue); + + // setName sets the consumer name of the input queue + void setName(const String8& name); + +private: + // From IConsumerListener + // + // During this callback, we store some tracking information, detach the + // buffer from the input, and attach it to each of the outputs. This call + // can block if there are too many outstanding buffers. If it blocks, it + // will resume when onBufferReleasedByOutput releases a buffer back to the + // input. + virtual void onFrameAvailable(const BufferItem& item); + + // From IConsumerListener + // We don't care about released buffers because we detach each buffer as + // soon as we acquire it. See the comment for onBufferReleased below for + // some clarifying notes about the name. + virtual void onBuffersReleased() {} + + // From IConsumerListener + // We don't care about sideband streams, since we won't be splitting them + virtual void onSidebandStreamChanged() {} + + // This is the implementation of the onBufferReleased callback from + // IProducerListener. It gets called from an OutputListener (see below), and + // 'from' is which producer interface from which the callback was received. + // + // During this callback, we detach the buffer from the output queue that + // generated the callback, update our state tracking to see if this is the + // last output releasing the buffer, and if so, release it to the input. + // If we release the buffer to the input, we allow a blocked + // onFrameAvailable call to proceed. + void onBufferReleasedByOutput(const sp& from); + + // When this is called, the splitter disconnects from (i.e., abandons) its + // input queue and signals any waiting onFrameAvailable calls to wake up. + // It still processes callbacks from other outputs, but only detaches their + // buffers so they can continue operating until they run out of buffers to + // acquire. This must be called with mMutex locked. + void onAbandonedLocked(); + + // This is a thin wrapper class that lets us determine which BufferQueue + // the IProducerListener::onBufferReleased callback is associated with. We + // create one of these per output BufferQueue, and then pass the producer + // into onBufferReleasedByOutput above. + class OutputListener : public BnProducerListener, + public IBinder::DeathRecipient { + public: + OutputListener(const sp& splitter, + const sp& output); + virtual ~OutputListener(); + + // From IProducerListener + virtual void onBufferReleased(); + + // From IBinder::DeathRecipient + virtual void binderDied(const wp& who); + + private: + sp mSplitter; + sp mOutput; + }; + + class BufferTracker : public LightRefBase { + public: + BufferTracker(const sp& buffer); + + const sp& getBuffer() const { return mBuffer; } + const sp& getMergedFence() const { return mMergedFence; } + + void mergeFence(const sp& with); + + // Returns the new value + // Only called while mMutex is held + size_t incrementReleaseCountLocked() { return ++mReleaseCount; } + + private: + // Only destroy through LightRefBase + friend LightRefBase; + ~BufferTracker(); + + // Disallow copying + BufferTracker(const BufferTracker& other); + BufferTracker& operator=(const BufferTracker& other); + + sp mBuffer; // One instance that holds this native handle + sp mMergedFence; + size_t mReleaseCount; + }; + + // Only called from createSplitter + StreamSplitter(const sp& inputQueue); + + // Must be accessed through RefBase + virtual ~StreamSplitter(); + + static const int MAX_OUTSTANDING_BUFFERS = 2; + + // mIsAbandoned is set to true when an output dies. Once the StreamSplitter + // has been abandoned, it will continue to detach buffers from other + // outputs, but it will disconnect from the input and not attempt to + // communicate with it further. + bool mIsAbandoned; + + Mutex mMutex; + Condition mReleaseCondition; + int mOutstandingBuffers; + sp mInput; + Vector > mOutputs; + + // Map of GraphicBuffer IDs (GraphicBuffer::getId()) to buffer tracking + // objects (which are mostly for counting how many outputs have released the + // buffer, but also contain merged release fences). + KeyedVector > mBuffers; +}; + +} // namespace android + +#endif diff --git a/phonelibs/android_frameworks_native/include/gui/Surface.h b/phonelibs/android_frameworks_native/include/gui/Surface.h new file mode 100644 index 00000000000000..72f1067076ccd3 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/Surface.h @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_SURFACE_H +#define ANDROID_GUI_SURFACE_H + +#include +#include + +#include +#include + +#include +#include +#include + +struct ANativeWindow_Buffer; + +namespace android { + +/* + * An implementation of ANativeWindow that feeds graphics buffers into a + * BufferQueue. + * + * This is typically used by programs that want to render frames through + * some means (maybe OpenGL, a software renderer, or a hardware decoder) + * and have the frames they create forwarded to SurfaceFlinger for + * compositing. For example, a video decoder could render a frame and call + * eglSwapBuffers(), which invokes ANativeWindow callbacks defined by + * Surface. Surface then forwards the buffers through Binder IPC + * to the BufferQueue's producer interface, providing the new frame to a + * consumer such as GLConsumer. + */ +class Surface + : public ANativeObjectBase +{ +public: + + /* + * creates a Surface from the given IGraphicBufferProducer (which concrete + * implementation is a BufferQueue). + * + * Surface is mainly state-less while it's disconnected, it can be + * viewed as a glorified IGraphicBufferProducer holder. It's therefore + * safe to create other Surfaces from the same IGraphicBufferProducer. + * + * However, once a Surface is connected, it'll prevent other Surfaces + * referring to the same IGraphicBufferProducer to become connected and + * therefore prevent them to be used as actual producers of buffers. + * + * the controlledByApp flag indicates that this Surface (producer) is + * controlled by the application. This flag is used at connect time. + */ + Surface(const sp& bufferProducer, bool controlledByApp = false); + + /* getIGraphicBufferProducer() returns the IGraphicBufferProducer this + * Surface was created with. Usually it's an error to use the + * IGraphicBufferProducer while the Surface is connected. + */ + sp getIGraphicBufferProducer() const; + + /* convenience function to check that the given surface is non NULL as + * well as its IGraphicBufferProducer */ + static bool isValid(const sp& surface) { + return surface != NULL && surface->getIGraphicBufferProducer() != NULL; + } + + /* Attaches a sideband buffer stream to the Surface's IGraphicBufferProducer. + * + * A sideband stream is a device-specific mechanism for passing buffers + * from the producer to the consumer without using dequeueBuffer/ + * queueBuffer. If a sideband stream is present, the consumer can choose + * whether to acquire buffers from the sideband stream or from the queued + * buffers. + * + * Passing NULL or a different stream handle will detach the previous + * handle if any. + */ + void setSidebandStream(const sp& stream); + + /* Allocates buffers based on the current dimensions/format. + * + * This function will allocate up to the maximum number of buffers + * permitted by the current BufferQueue configuration. It will use the + * default format and dimensions. This is most useful to avoid an allocation + * delay during dequeueBuffer. If there are already the maximum number of + * buffers allocated, this function has no effect. + */ + void allocateBuffers(); + + /* Sets the generation number on the IGraphicBufferProducer and updates the + * generation number on any buffers attached to the Surface after this call. + * See IGBP::setGenerationNumber for more information. */ + status_t setGenerationNumber(uint32_t generationNumber); + + // See IGraphicBufferProducer::getConsumerName + String8 getConsumerName() const; + +protected: + virtual ~Surface(); + +private: + // can't be copied + Surface& operator = (const Surface& rhs); + Surface(const Surface& rhs); + + // ANativeWindow hooks + static int hook_cancelBuffer(ANativeWindow* window, + ANativeWindowBuffer* buffer, int fenceFd); + static int hook_dequeueBuffer(ANativeWindow* window, + ANativeWindowBuffer** buffer, int* fenceFd); + static int hook_perform(ANativeWindow* window, int operation, ...); + static int hook_query(const ANativeWindow* window, int what, int* value); + static int hook_queueBuffer(ANativeWindow* window, + ANativeWindowBuffer* buffer, int fenceFd); + static int hook_setSwapInterval(ANativeWindow* window, int interval); + + static int hook_cancelBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer); + static int hook_dequeueBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer** buffer); + static int hook_lockBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer); + static int hook_queueBuffer_DEPRECATED(ANativeWindow* window, + ANativeWindowBuffer* buffer); + + int dispatchConnect(va_list args); + int dispatchDisconnect(va_list args); + int dispatchSetBufferCount(va_list args); + int dispatchSetBuffersGeometry(va_list args); + int dispatchSetBuffersDimensions(va_list args); + int dispatchSetBuffersUserDimensions(va_list args); + int dispatchSetBuffersFormat(va_list args); + int dispatchSetScalingMode(va_list args); + int dispatchSetBuffersTransform(va_list args); + int dispatchSetBuffersStickyTransform(va_list args); + int dispatchSetBuffersTimestamp(va_list args); + int dispatchSetCrop(va_list args); + int dispatchSetPostTransformCrop(va_list args); + int dispatchSetUsage(va_list args); + int dispatchLock(va_list args); + int dispatchUnlockAndPost(va_list args); + int dispatchSetSidebandStream(va_list args); + int dispatchSetBuffersDataSpace(va_list args); + int dispatchSetSurfaceDamage(va_list args); + +protected: + virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd); + virtual int cancelBuffer(ANativeWindowBuffer* buffer, int fenceFd); + virtual int queueBuffer(ANativeWindowBuffer* buffer, int fenceFd); + virtual int perform(int operation, va_list args); + virtual int query(int what, int* value) const; + virtual int setSwapInterval(int interval); + + virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer); + + virtual int connect(int api); + virtual int disconnect(int api); + virtual int setBufferCount(int bufferCount); + virtual int setBuffersDimensions(uint32_t width, uint32_t height); + virtual int setBuffersUserDimensions(uint32_t width, uint32_t height); + virtual int setBuffersFormat(PixelFormat format); + virtual int setScalingMode(int mode); + virtual int setBuffersTransform(uint32_t transform); + virtual int setBuffersStickyTransform(uint32_t transform); + virtual int setBuffersTimestamp(int64_t timestamp); + virtual int setBuffersDataSpace(android_dataspace dataSpace); + virtual int setCrop(Rect const* rect); + virtual int setUsage(uint32_t reqUsage); + virtual void setSurfaceDamage(android_native_rect_t* rects, size_t numRects); + +public: + virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds); + virtual int unlockAndPost(); + + virtual int connect(int api, const sp& listener); + virtual int detachNextBuffer(sp* outBuffer, + sp* outFence); + virtual int attachBuffer(ANativeWindowBuffer*); + +protected: + enum { NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS }; + enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 }; + +private: + void freeAllBuffers(); + int getSlotFromBufferLocked(android_native_buffer_t* buffer) const; + + struct BufferSlot { + sp buffer; + Region dirtyRegion; + }; + + // mSurfaceTexture is the interface to the surface texture server. All + // operations on the surface texture client ultimately translate into + // interactions with the server using this interface. + // TODO: rename to mBufferProducer + sp mGraphicBufferProducer; + + // mSlots stores the buffers that have been allocated for each buffer slot. + // It is initialized to null pointers, and gets filled in with the result of + // IGraphicBufferProducer::requestBuffer when the client dequeues a buffer from a + // slot that has not yet been used. The buffer allocated to a slot will also + // be replaced if the requested buffer usage or geometry differs from that + // of the buffer allocated to a slot. + BufferSlot mSlots[NUM_BUFFER_SLOTS]; + + // mReqWidth is the buffer width that will be requested at the next dequeue + // operation. It is initialized to 1. + uint32_t mReqWidth; + + // mReqHeight is the buffer height that will be requested at the next + // dequeue operation. It is initialized to 1. + uint32_t mReqHeight; + + // mReqFormat is the buffer pixel format that will be requested at the next + // deuque operation. It is initialized to PIXEL_FORMAT_RGBA_8888. + PixelFormat mReqFormat; + + // mReqUsage is the set of buffer usage flags that will be requested + // at the next deuque operation. It is initialized to 0. + uint32_t mReqUsage; + + // mTimestamp is the timestamp that will be used for the next buffer queue + // operation. It defaults to NATIVE_WINDOW_TIMESTAMP_AUTO, which means that + // a timestamp is auto-generated when queueBuffer is called. + int64_t mTimestamp; + + // mDataSpace is the buffer dataSpace that will be used for the next buffer + // queue operation. It defaults to HAL_DATASPACE_UNKNOWN, which + // means that the buffer contains some type of color data. + android_dataspace mDataSpace; + + // mCrop is the crop rectangle that will be used for the next buffer + // that gets queued. It is set by calling setCrop. + Rect mCrop; + + // mScalingMode is the scaling mode that will be used for the next + // buffers that get queued. It is set by calling setScalingMode. + int mScalingMode; + + // mTransform is the transform identifier that will be used for the next + // buffer that gets queued. It is set by calling setTransform. + uint32_t mTransform; + + // mStickyTransform is a transform that is applied on top of mTransform + // in each buffer that is queued. This is typically used to force the + // compositor to apply a transform, and will prevent the transform hint + // from being set by the compositor. + uint32_t mStickyTransform; + + // mDefaultWidth is default width of the buffers, regardless of the + // native_window_set_buffers_dimensions call. + uint32_t mDefaultWidth; + + // mDefaultHeight is default height of the buffers, regardless of the + // native_window_set_buffers_dimensions call. + uint32_t mDefaultHeight; + + // mUserWidth, if non-zero, is an application-specified override + // of mDefaultWidth. This is lower priority than the width set by + // native_window_set_buffers_dimensions. + uint32_t mUserWidth; + + // mUserHeight, if non-zero, is an application-specified override + // of mDefaultHeight. This is lower priority than the height set + // by native_window_set_buffers_dimensions. + uint32_t mUserHeight; + + // mTransformHint is the transform probably applied to buffers of this + // window. this is only a hint, actual transform may differ. + uint32_t mTransformHint; + + // mProducerControlledByApp whether this buffer producer is controlled + // by the application + bool mProducerControlledByApp; + + // mSwapIntervalZero set if we should drop buffers at queue() time to + // achieve an asynchronous swap interval + bool mSwapIntervalZero; + + // mConsumerRunningBehind whether the consumer is running more than + // one buffer behind the producer. + mutable bool mConsumerRunningBehind; + + // mMutex is the mutex used to prevent concurrent access to the member + // variables of Surface objects. It must be locked whenever the + // member variables are accessed. + mutable Mutex mMutex; + + // must be used from the lock/unlock thread + sp mLockedBuffer; + sp mPostedBuffer; + bool mConnectedToCpu; + + // When a CPU producer is attached, this reflects the region that the + // producer wished to update as well as whether the Surface was able to copy + // the previous buffer back to allow a partial update. + // + // When a non-CPU producer is attached, this reflects the surface damage + // (the change since the previous frame) passed in by the producer. + Region mDirtyRegion; + + // Stores the current generation number. See setGenerationNumber and + // IGraphicBufferProducer::setGenerationNumber for more information. + uint32_t mGenerationNumber; +}; + +}; // namespace android + +#endif // ANDROID_GUI_SURFACE_H diff --git a/phonelibs/android_frameworks_native/include/gui/SurfaceComposerClient.h b/phonelibs/android_frameworks_native/include/gui/SurfaceComposerClient.h new file mode 100644 index 00000000000000..9ec3f23491eb23 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/SurfaceComposerClient.h @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H +#define ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +namespace android { + +// --------------------------------------------------------------------------- + +class DisplayInfo; +class Composer; +class ISurfaceComposerClient; +class IGraphicBufferProducer; +class Region; + +// --------------------------------------------------------------------------- + +class SurfaceComposerClient : public RefBase +{ + friend class Composer; +public: + SurfaceComposerClient(); + virtual ~SurfaceComposerClient(); + + // Always make sure we could initialize + status_t initCheck() const; + + // Return the connection of this client + sp connection() const; + + // Forcibly remove connection before all references have gone away. + void dispose(); + + // callback when the composer is dies + status_t linkToComposerDeath(const sp& recipient, + void* cookie = NULL, uint32_t flags = 0); + + // Get a list of supported configurations for a given display + static status_t getDisplayConfigs(const sp& display, + Vector* configs); + + // Get the DisplayInfo for the currently-active configuration + static status_t getDisplayInfo(const sp& display, + DisplayInfo* info); + + // Get the index of the current active configuration (relative to the list + // returned by getDisplayInfo) + static int getActiveConfig(const sp& display); + + // Set a new active configuration using an index relative to the list + // returned by getDisplayInfo + static status_t setActiveConfig(const sp& display, int id); + + /* Triggers screen on/off or low power mode and waits for it to complete */ + static void setDisplayPowerMode(const sp& display, int mode); + + // ------------------------------------------------------------------------ + // surface creation / destruction + + //! Create a surface + sp createSurface( + const String8& name,// name of the surface + uint32_t w, // width in pixel + uint32_t h, // height in pixel + PixelFormat format, // pixel-format desired + uint32_t flags = 0 // usage flags + ); + + //! Create a virtual display + static sp createDisplay(const String8& displayName, bool secure); + + //! Destroy a virtual display + static void destroyDisplay(const sp& display); + + //! Get the token for the existing default displays. + //! Possible values for id are eDisplayIdMain and eDisplayIdHdmi. + static sp getBuiltInDisplay(int32_t id); + + // ------------------------------------------------------------------------ + // Composer parameters + // All composer parameters must be changed within a transaction + // several surfaces can be updated in one transaction, all changes are + // committed at once when the transaction is closed. + // closeGlobalTransaction() requires an IPC with the server. + + //! Open a composer transaction on all active SurfaceComposerClients. + static void openGlobalTransaction(); + + //! Close a composer transaction on all active SurfaceComposerClients. + static void closeGlobalTransaction(bool synchronous = false); + + //! Flag the currently open transaction as an animation transaction. + static void setAnimationTransaction(); + + status_t hide(const sp& id); + status_t show(const sp& id); + status_t setFlags(const sp& id, uint32_t flags, uint32_t mask); + status_t setTransparentRegionHint(const sp& id, const Region& transparent); + status_t setLayer(const sp& id, uint32_t layer); + status_t setAlpha(const sp& id, float alpha=1.0f); + status_t setMatrix(const sp& id, float dsdx, float dtdx, float dsdy, float dtdy); + status_t setPosition(const sp& id, float x, float y); + status_t setSize(const sp& id, uint32_t w, uint32_t h); + status_t setCrop(const sp& id, const Rect& crop); + status_t setLayerStack(const sp& id, uint32_t layerStack); + status_t destroySurface(const sp& id); + + status_t clearLayerFrameStats(const sp& token) const; + status_t getLayerFrameStats(const sp& token, FrameStats* outStats) const; + + static status_t clearAnimationFrameStats(); + static status_t getAnimationFrameStats(FrameStats* outStats); + + static void setDisplaySurface(const sp& token, + const sp& bufferProducer); + static void setDisplayLayerStack(const sp& token, + uint32_t layerStack); + static void setDisplaySize(const sp& token, uint32_t width, uint32_t height); + + /* setDisplayProjection() defines the projection of layer stacks + * to a given display. + * + * - orientation defines the display's orientation. + * - layerStackRect defines which area of the window manager coordinate + * space will be used. + * - displayRect defines where on the display will layerStackRect be + * mapped to. displayRect is specified post-orientation, that is + * it uses the orientation seen by the end-user. + */ + static void setDisplayProjection(const sp& token, + uint32_t orientation, + const Rect& layerStackRect, + const Rect& displayRect); + + status_t setBlur(const sp& id, float blur); + status_t setBlurMaskSurface(const sp& id, const sp& maskSurfaceId); + status_t setBlurMaskSampling(const sp& id, uint32_t blurMaskSampling); + status_t setBlurMaskAlphaThreshold(const sp& id, float alpha); + +private: + virtual void onFirstRef(); + Composer& getComposer(); + + mutable Mutex mLock; + status_t mStatus; + sp mClient; + Composer& mComposer; +}; + +// --------------------------------------------------------------------------- + +class ScreenshotClient +{ +public: + // if cropping isn't required, callers may pass in a default Rect, e.g.: + // capture(display, producer, Rect(), reqWidth, ...); + static status_t capture( + const sp& display, + const sp& producer, + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ, + bool useIdentityTransform); + +private: + mutable sp mCpuConsumer; + mutable sp mProducer; + CpuConsumer::LockedBuffer mBuffer; + bool mHaveBuffer; + +public: + ScreenshotClient(); + ~ScreenshotClient(); + + // frees the previous screenshot and captures a new one + // if cropping isn't required, callers may pass in a default Rect, e.g.: + // update(display, Rect(), useIdentityTransform); + status_t update(const sp& display, + Rect sourceCrop, bool useIdentityTransform); + status_t update(const sp& display, + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + bool useIdentityTransform); + status_t update(const sp& display, + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ, + bool useIdentityTransform); + status_t update(const sp& display, + Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, + uint32_t minLayerZ, uint32_t maxLayerZ, + bool useIdentityTransform, uint32_t rotation); + + sp getCpuConsumer() const; + + // release memory occupied by the screenshot + void release(); + + // pixels are valid until this object is freed or + // release() or update() is called + void const* getPixels() const; + + uint32_t getWidth() const; + uint32_t getHeight() const; + PixelFormat getFormat() const; + uint32_t getStride() const; + // size of allocated memory in bytes + size_t getSize() const; +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H diff --git a/phonelibs/android_frameworks_native/include/gui/SurfaceControl.h b/phonelibs/android_frameworks_native/include/gui/SurfaceControl.h new file mode 100644 index 00000000000000..5fa45d1668b9cf --- /dev/null +++ b/phonelibs/android_frameworks_native/include/gui/SurfaceControl.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_SURFACE_CONTROL_H +#define ANDROID_GUI_SURFACE_CONTROL_H + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +namespace android { + +// --------------------------------------------------------------------------- + +class IGraphicBufferProducer; +class Surface; +class SurfaceComposerClient; + +// --------------------------------------------------------------------------- + +class SurfaceControl : public RefBase +{ +public: + static bool isValid(const sp& surface) { + return (surface != 0) && surface->isValid(); + } + + bool isValid() { + return mHandle!=0 && mClient!=0; + } + + static bool isSameSurface( + const sp& lhs, const sp& rhs); + + // release surface data from java + void clear(); + + status_t setLayerStack(uint32_t layerStack); + status_t setLayer(uint32_t layer); + status_t setPosition(float x, float y); + status_t setSize(uint32_t w, uint32_t h); + status_t hide(); + status_t show(); + status_t setFlags(uint32_t flags, uint32_t mask); + status_t setTransparentRegionHint(const Region& transparent); + status_t setAlpha(float alpha=1.0f); + status_t setMatrix(float dsdx, float dtdx, float dsdy, float dtdy); + status_t setCrop(const Rect& crop); + + static status_t writeSurfaceToParcel( + const sp& control, Parcel* parcel); + + sp getSurface() const; + + status_t clearLayerFrameStats() const; + status_t getLayerFrameStats(FrameStats* outStats) const; + + status_t setBlur(float blur = 0); + status_t setBlurMaskSurface(const sp& maskSurface); + status_t setBlurMaskSampling(uint32_t blurMaskSampling); + status_t setBlurMaskAlphaThreshold(float alpha); + +private: + // can't be copied + SurfaceControl& operator = (SurfaceControl& rhs); + SurfaceControl(const SurfaceControl& rhs); + + friend class SurfaceComposerClient; + friend class Surface; + + SurfaceControl( + const sp& client, + const sp& handle, + const sp& gbp); + + ~SurfaceControl(); + + status_t validate() const; + void destroy(); + + sp mClient; + sp mHandle; + sp mGraphicBufferProducer; + mutable Mutex mLock; + mutable sp mSurfaceData; +}; + +}; // namespace android + +#endif // ANDROID_GUI_SURFACE_CONTROL_H diff --git a/phonelibs/android_frameworks_native/include/input/IInputFlinger.h b/phonelibs/android_frameworks_native/include/input/IInputFlinger.h new file mode 100644 index 00000000000000..629310ff2f236f --- /dev/null +++ b/phonelibs/android_frameworks_native/include/input/IInputFlinger.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBINPUT_IINPUT_FLINGER_H +#define _LIBINPUT_IINPUT_FLINGER_H + +#include +#include + +#include + +namespace android { + +/* + * This class defines the Binder IPC interface for accessing various + * InputFlinger features. + */ +class IInputFlinger : public IInterface { +public: + DECLARE_META_INTERFACE(InputFlinger); +}; + + +/** + * Binder implementation. + */ +class BnInputFlinger : public BnInterface { +public: + enum { + DO_SOMETHING_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, + }; + + virtual status_t onTransact(uint32_t code, const Parcel& data, + Parcel* reply, uint32_t flags = 0); +}; + +} // namespace android + +#endif // _LIBINPUT_IINPUT_FLINGER_H diff --git a/phonelibs/android_frameworks_native/include/input/Input.h b/phonelibs/android_frameworks_native/include/input/Input.h new file mode 100644 index 00000000000000..82fc6599a7f051 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/input/Input.h @@ -0,0 +1,681 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBINPUT_INPUT_H +#define _LIBINPUT_INPUT_H + +/** + * Native input event structures. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Additional private constants not defined in ndk/ui/input.h. + */ +enum { + /* Signifies that the key is being predispatched */ + AKEY_EVENT_FLAG_PREDISPATCH = 0x20000000, + + /* Private control to determine when an app is tracking a key sequence. */ + AKEY_EVENT_FLAG_START_TRACKING = 0x40000000, + + /* Key event is inconsistent with previously sent key events. */ + AKEY_EVENT_FLAG_TAINTED = 0x80000000, +}; + +enum { + + /** + * This flag indicates that the window that received this motion event is partly + * or wholly obscured by another visible window above it. This flag is set to true + * even if the event did not directly pass through the obscured area. + * A security sensitive application can check this flag to identify situations in which + * a malicious application may have covered up part of its content for the purpose + * of misleading the user or hijacking touches. An appropriate response might be + * to drop the suspect touches or to take additional precautions to confirm the user's + * actual intent. + */ + AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED = 0x2, + + /* Motion event is inconsistent with previously sent motion events. */ + AMOTION_EVENT_FLAG_TAINTED = 0x80000000, +}; + +enum { + /* Used when a motion event is not associated with any display. + * Typically used for non-pointer events. */ + ADISPLAY_ID_NONE = -1, + + /* The default display id. */ + ADISPLAY_ID_DEFAULT = 0, +}; + +enum { + /* + * Indicates that an input device has switches. + * This input source flag is hidden from the API because switches are only used by the system + * and applications have no way to interact with them. + */ + AINPUT_SOURCE_SWITCH = 0x80000000, +}; + +enum { + /** + * Constants for LEDs. Hidden from the API since we don't actually expose a way to interact + * with LEDs to developers + * + * NOTE: If you add LEDs here, you must also add them to InputEventLabels.h + */ + + ALED_NUM_LOCK = 0x00, + ALED_CAPS_LOCK = 0x01, + ALED_SCROLL_LOCK = 0x02, + ALED_COMPOSE = 0x03, + ALED_KANA = 0x04, + ALED_SLEEP = 0x05, + ALED_SUSPEND = 0x06, + ALED_MUTE = 0x07, + ALED_MISC = 0x08, + ALED_MAIL = 0x09, + ALED_CHARGING = 0x0a, + ALED_CONTROLLER_1 = 0x10, + ALED_CONTROLLER_2 = 0x11, + ALED_CONTROLLER_3 = 0x12, + ALED_CONTROLLER_4 = 0x13, +}; + +/* Maximum number of controller LEDs we support */ +#define MAX_CONTROLLER_LEDS 4 + +/* + * SystemUiVisibility constants from View. + */ +enum { + ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE = 0, + ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN = 0x00000001, +}; + +/* + * Maximum number of pointers supported per motion event. + * Smallest number of pointers is 1. + * (We want at least 10 but some touch controllers obstensibly configured for 10 pointers + * will occasionally emit 11. There is not much harm making this constant bigger.) + */ +#define MAX_POINTERS 16 + +/* + * Maximum number of samples supported per motion event. + */ +#define MAX_SAMPLES UINT16_MAX + +/* + * Maximum pointer id value supported in a motion event. + * Smallest pointer id is 0. + * (This is limited by our use of BitSet32 to track pointer assignments.) + */ +#define MAX_POINTER_ID 31 + +/* + * Declare a concrete type for the NDK's input event forward declaration. + */ +struct AInputEvent { + virtual ~AInputEvent() { } +}; + +/* + * Declare a concrete type for the NDK's input device forward declaration. + */ +struct AInputDevice { + virtual ~AInputDevice() { } +}; + + +namespace android { + +#ifdef HAVE_ANDROID_OS +class Parcel; +#endif + +/* + * Flags that flow alongside events in the input dispatch system to help with certain + * policy decisions such as waking from device sleep. + * + * These flags are also defined in frameworks/base/core/java/android/view/WindowManagerPolicy.java. + */ +enum { + /* These flags originate in RawEvents and are generally set in the key map. + * NOTE: If you want a flag to be able to set in a keylayout file, then you must add it to + * InputEventLabels.h as well. */ + + // Indicates that the event should wake the device. + POLICY_FLAG_WAKE = 0x00000001, + + // Indicates that the key is virtual, such as a capacitive button, and should + // generate haptic feedback. Virtual keys may be suppressed for some time + // after a recent touch to prevent accidental activation of virtual keys adjacent + // to the touch screen during an edge swipe. + POLICY_FLAG_VIRTUAL = 0x00000002, + + // Indicates that the key is the special function modifier. + POLICY_FLAG_FUNCTION = 0x00000004, + + // Indicates that the key represents a special gesture that has been detected by + // the touch firmware or driver. Causes touch events from the same device to be canceled. + POLICY_FLAG_GESTURE = 0x00000008, + + POLICY_FLAG_RAW_MASK = 0x0000ffff, + + /* These flags are set by the input dispatcher. */ + + // Indicates that the input event was injected. + POLICY_FLAG_INJECTED = 0x01000000, + + // Indicates that the input event is from a trusted source such as a directly attached + // input device or an application with system-wide event injection permission. + POLICY_FLAG_TRUSTED = 0x02000000, + + // Indicates that the input event has passed through an input filter. + POLICY_FLAG_FILTERED = 0x04000000, + + // Disables automatic key repeating behavior. + POLICY_FLAG_DISABLE_KEY_REPEAT = 0x08000000, + + /* These flags are set by the input reader policy as it intercepts each event. */ + + // Indicates that the device was in an interactive state when the + // event was intercepted. + POLICY_FLAG_INTERACTIVE = 0x20000000, + + // Indicates that the event should be dispatched to applications. + // The input event should still be sent to the InputDispatcher so that it can see all + // input events received include those that it will not deliver. + POLICY_FLAG_PASS_TO_USER = 0x40000000, +}; + +/* + * Pointer coordinate data. + */ +struct PointerCoords { + enum { MAX_AXES = 30 }; // 30 so that sizeof(PointerCoords) == 128 + + // Bitfield of axes that are present in this structure. + uint64_t bits __attribute__((aligned(8))); + + // Values of axes that are stored in this structure packed in order by axis id + // for each axis that is present in the structure according to 'bits'. + float values[MAX_AXES]; + + inline void clear() { + BitSet64::clear(bits); + } + + bool isEmpty() const { + return BitSet64::isEmpty(bits); + } + + float getAxisValue(int32_t axis) const; + status_t setAxisValue(int32_t axis, float value); + + void scale(float scale); + void applyOffset(float xOffset, float yOffset); + + inline float getX() const { + return getAxisValue(AMOTION_EVENT_AXIS_X); + } + + inline float getY() const { + return getAxisValue(AMOTION_EVENT_AXIS_Y); + } + +#ifdef HAVE_ANDROID_OS + status_t readFromParcel(Parcel* parcel); + status_t writeToParcel(Parcel* parcel) const; +#endif + + bool operator==(const PointerCoords& other) const; + inline bool operator!=(const PointerCoords& other) const { + return !(*this == other); + } + + void copyFrom(const PointerCoords& other); + +private: + void tooManyAxes(int axis); +}; + +/* + * Pointer property data. + */ +struct PointerProperties { + // The id of the pointer. + int32_t id; + + // The pointer tool type. + int32_t toolType; + + inline void clear() { + id = -1; + toolType = 0; + } + + bool operator==(const PointerProperties& other) const; + inline bool operator!=(const PointerProperties& other) const { + return !(*this == other); + } + + void copyFrom(const PointerProperties& other); +}; + +/* + * Input events. + */ +class InputEvent : public AInputEvent { +public: + virtual ~InputEvent() { } + + virtual int32_t getType() const = 0; + + inline int32_t getDeviceId() const { return mDeviceId; } + + inline int32_t getSource() const { return mSource; } + + inline void setSource(int32_t source) { mSource = source; } + +protected: + void initialize(int32_t deviceId, int32_t source); + void initialize(const InputEvent& from); + + int32_t mDeviceId; + int32_t mSource; +}; + +/* + * Key events. + */ +class KeyEvent : public InputEvent { +public: + virtual ~KeyEvent() { } + + virtual int32_t getType() const { return AINPUT_EVENT_TYPE_KEY; } + + inline int32_t getAction() const { return mAction; } + + inline int32_t getFlags() const { return mFlags; } + + inline void setFlags(int32_t flags) { mFlags = flags; } + + inline int32_t getKeyCode() const { return mKeyCode; } + + inline int32_t getScanCode() const { return mScanCode; } + + inline int32_t getMetaState() const { return mMetaState; } + + inline int32_t getRepeatCount() const { return mRepeatCount; } + + inline nsecs_t getDownTime() const { return mDownTime; } + + inline nsecs_t getEventTime() const { return mEventTime; } + + static const char* getLabel(int32_t keyCode); + static int32_t getKeyCodeFromLabel(const char* label); + + void initialize( + int32_t deviceId, + int32_t source, + int32_t action, + int32_t flags, + int32_t keyCode, + int32_t scanCode, + int32_t metaState, + int32_t repeatCount, + nsecs_t downTime, + nsecs_t eventTime); + void initialize(const KeyEvent& from); + +protected: + int32_t mAction; + int32_t mFlags; + int32_t mKeyCode; + int32_t mScanCode; + int32_t mMetaState; + int32_t mRepeatCount; + nsecs_t mDownTime; + nsecs_t mEventTime; +}; + +/* + * Motion events. + */ +class MotionEvent : public InputEvent { +public: + virtual ~MotionEvent() { } + + virtual int32_t getType() const { return AINPUT_EVENT_TYPE_MOTION; } + + inline int32_t getAction() const { return mAction; } + + inline int32_t getActionMasked() const { return mAction & AMOTION_EVENT_ACTION_MASK; } + + inline int32_t getActionIndex() const { + return (mAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) + >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; + } + + inline void setAction(int32_t action) { mAction = action; } + + inline int32_t getFlags() const { return mFlags; } + + inline void setFlags(int32_t flags) { mFlags = flags; } + + inline int32_t getEdgeFlags() const { return mEdgeFlags; } + + inline void setEdgeFlags(int32_t edgeFlags) { mEdgeFlags = edgeFlags; } + + inline int32_t getMetaState() const { return mMetaState; } + + inline void setMetaState(int32_t metaState) { mMetaState = metaState; } + + inline int32_t getButtonState() const { return mButtonState; } + + inline int32_t setButtonState(int32_t buttonState) { mButtonState = buttonState; } + + inline int32_t getActionButton() const { return mActionButton; } + + inline void setActionButton(int32_t button) { mActionButton = button; } + + inline float getXOffset() const { return mXOffset; } + + inline float getYOffset() const { return mYOffset; } + + inline float getXPrecision() const { return mXPrecision; } + + inline float getYPrecision() const { return mYPrecision; } + + inline nsecs_t getDownTime() const { return mDownTime; } + + inline void setDownTime(nsecs_t downTime) { mDownTime = downTime; } + + inline size_t getPointerCount() const { return mPointerProperties.size(); } + + inline const PointerProperties* getPointerProperties(size_t pointerIndex) const { + return &mPointerProperties[pointerIndex]; + } + + inline int32_t getPointerId(size_t pointerIndex) const { + return mPointerProperties[pointerIndex].id; + } + + inline int32_t getToolType(size_t pointerIndex) const { + return mPointerProperties[pointerIndex].toolType; + } + + inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; } + + const PointerCoords* getRawPointerCoords(size_t pointerIndex) const; + + float getRawAxisValue(int32_t axis, size_t pointerIndex) const; + + inline float getRawX(size_t pointerIndex) const { + return getRawAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex); + } + + inline float getRawY(size_t pointerIndex) const { + return getRawAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex); + } + + float getAxisValue(int32_t axis, size_t pointerIndex) const; + + inline float getX(size_t pointerIndex) const { + return getAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex); + } + + inline float getY(size_t pointerIndex) const { + return getAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex); + } + + inline float getPressure(size_t pointerIndex) const { + return getAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pointerIndex); + } + + inline float getSize(size_t pointerIndex) const { + return getAxisValue(AMOTION_EVENT_AXIS_SIZE, pointerIndex); + } + + inline float getTouchMajor(size_t pointerIndex) const { + return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex); + } + + inline float getTouchMinor(size_t pointerIndex) const { + return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex); + } + + inline float getToolMajor(size_t pointerIndex) const { + return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex); + } + + inline float getToolMinor(size_t pointerIndex) const { + return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex); + } + + inline float getOrientation(size_t pointerIndex) const { + return getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex); + } + + inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; } + + inline nsecs_t getHistoricalEventTime(size_t historicalIndex) const { + return mSampleEventTimes[historicalIndex]; + } + + const PointerCoords* getHistoricalRawPointerCoords( + size_t pointerIndex, size_t historicalIndex) const; + + float getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex, + size_t historicalIndex) const; + + inline float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalRawAxisValue( + AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex); + } + + inline float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalRawAxisValue( + AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex); + } + + float getHistoricalAxisValue(int32_t axis, size_t pointerIndex, size_t historicalIndex) const; + + inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalAxisValue( + AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex); + } + + inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalAxisValue( + AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex); + } + + inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalAxisValue( + AMOTION_EVENT_AXIS_PRESSURE, pointerIndex, historicalIndex); + } + + inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalAxisValue( + AMOTION_EVENT_AXIS_SIZE, pointerIndex, historicalIndex); + } + + inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalAxisValue( + AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex, historicalIndex); + } + + inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalAxisValue( + AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex, historicalIndex); + } + + inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalAxisValue( + AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex, historicalIndex); + } + + inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalAxisValue( + AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex, historicalIndex); + } + + inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalAxisValue( + AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex, historicalIndex); + } + + ssize_t findPointerIndex(int32_t pointerId) const; + + void initialize( + int32_t deviceId, + int32_t source, + int32_t action, + int32_t actionButton, + int32_t flags, + int32_t edgeFlags, + int32_t metaState, + int32_t buttonState, + float xOffset, + float yOffset, + float xPrecision, + float yPrecision, + nsecs_t downTime, + nsecs_t eventTime, + size_t pointerCount, + const PointerProperties* pointerProperties, + const PointerCoords* pointerCoords); + + void copyFrom(const MotionEvent* other, bool keepHistory); + + void addSample( + nsecs_t eventTime, + const PointerCoords* pointerCoords); + + void offsetLocation(float xOffset, float yOffset); + + void scale(float scaleFactor); + + // Apply 3x3 perspective matrix transformation. + // Matrix is in row-major form and compatible with SkMatrix. + void transform(const float matrix[9]); + +#ifdef HAVE_ANDROID_OS + status_t readFromParcel(Parcel* parcel); + status_t writeToParcel(Parcel* parcel) const; +#endif + + static bool isTouchEvent(int32_t source, int32_t action); + inline bool isTouchEvent() const { + return isTouchEvent(mSource, mAction); + } + + // Low-level accessors. + inline const PointerProperties* getPointerProperties() const { + return mPointerProperties.array(); + } + inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.array(); } + inline const PointerCoords* getSamplePointerCoords() const { + return mSamplePointerCoords.array(); + } + + static const char* getLabel(int32_t axis); + static int32_t getAxisFromLabel(const char* label); + +protected: + int32_t mAction; + int32_t mActionButton; + int32_t mFlags; + int32_t mEdgeFlags; + int32_t mMetaState; + int32_t mButtonState; + float mXOffset; + float mYOffset; + float mXPrecision; + float mYPrecision; + nsecs_t mDownTime; + Vector mPointerProperties; + Vector mSampleEventTimes; + Vector mSamplePointerCoords; +}; + +/* + * Input event factory. + */ +class InputEventFactoryInterface { +protected: + virtual ~InputEventFactoryInterface() { } + +public: + InputEventFactoryInterface() { } + + virtual KeyEvent* createKeyEvent() = 0; + virtual MotionEvent* createMotionEvent() = 0; +}; + +/* + * A simple input event factory implementation that uses a single preallocated instance + * of each type of input event that are reused for each request. + */ +class PreallocatedInputEventFactory : public InputEventFactoryInterface { +public: + PreallocatedInputEventFactory() { } + virtual ~PreallocatedInputEventFactory() { } + + virtual KeyEvent* createKeyEvent() { return & mKeyEvent; } + virtual MotionEvent* createMotionEvent() { return & mMotionEvent; } + +private: + KeyEvent mKeyEvent; + MotionEvent mMotionEvent; +}; + +/* + * An input event factory implementation that maintains a pool of input events. + */ +class PooledInputEventFactory : public InputEventFactoryInterface { +public: + PooledInputEventFactory(size_t maxPoolSize = 20); + virtual ~PooledInputEventFactory(); + + virtual KeyEvent* createKeyEvent(); + virtual MotionEvent* createMotionEvent(); + + void recycle(InputEvent* event); + +private: + const size_t mMaxPoolSize; + + Vector mKeyEventPool; + Vector mMotionEventPool; +}; + +} // namespace android + +#endif // _LIBINPUT_INPUT_H diff --git a/phonelibs/android_frameworks_native/include/input/InputDevice.h b/phonelibs/android_frameworks_native/include/input/InputDevice.h new file mode 100644 index 00000000000000..1ea69d352d18d8 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/input/InputDevice.h @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBINPUT_INPUT_DEVICE_H +#define _LIBINPUT_INPUT_DEVICE_H + +#include +#include + +namespace android { + +/* + * Identifies a device. + */ +struct InputDeviceIdentifier { + inline InputDeviceIdentifier() : + bus(0), vendor(0), product(0), version(0) { + } + + // Information provided by the kernel. + String8 name; + String8 location; + String8 uniqueId; + uint16_t bus; + uint16_t vendor; + uint16_t product; + uint16_t version; + + // A composite input device descriptor string that uniquely identifies the device + // even across reboots or reconnections. The value of this field is used by + // upper layers of the input system to associate settings with individual devices. + // It is hashed from whatever kernel provided information is available. + // Ideally, the way this value is computed should not change between Android releases + // because that would invalidate persistent settings that rely on it. + String8 descriptor; + + // A value added to uniquely identify a device in the absence of a unique id. This + // is intended to be a minimum way to distinguish from other active devices and may + // reuse values that are not associated with an input anymore. + uint16_t nonce; +}; + +/* + * Describes the characteristics and capabilities of an input device. + */ +class InputDeviceInfo { +public: + InputDeviceInfo(); + InputDeviceInfo(const InputDeviceInfo& other); + ~InputDeviceInfo(); + + struct MotionRange { + int32_t axis; + uint32_t source; + float min; + float max; + float flat; + float fuzz; + float resolution; + }; + + void initialize(int32_t id, int32_t generation, int32_t controllerNumber, + const InputDeviceIdentifier& identifier, const String8& alias, bool isExternal, + bool hasMic); + + inline int32_t getId() const { return mId; } + inline int32_t getControllerNumber() const { return mControllerNumber; } + inline int32_t getGeneration() const { return mGeneration; } + inline const InputDeviceIdentifier& getIdentifier() const { return mIdentifier; } + inline const String8& getAlias() const { return mAlias; } + inline const String8& getDisplayName() const { + return mAlias.isEmpty() ? mIdentifier.name : mAlias; + } + inline bool isExternal() const { return mIsExternal; } + inline bool hasMic() const { return mHasMic; } + inline uint32_t getSources() const { return mSources; } + + const MotionRange* getMotionRange(int32_t axis, uint32_t source) const; + + void addSource(uint32_t source); + void addMotionRange(int32_t axis, uint32_t source, + float min, float max, float flat, float fuzz, float resolution); + void addMotionRange(const MotionRange& range); + + inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; } + inline int32_t getKeyboardType() const { return mKeyboardType; } + + inline void setKeyCharacterMap(const sp& value) { + mKeyCharacterMap = value; + } + + inline sp getKeyCharacterMap() const { + return mKeyCharacterMap; + } + + inline void setVibrator(bool hasVibrator) { mHasVibrator = hasVibrator; } + inline bool hasVibrator() const { return mHasVibrator; } + + inline void setButtonUnderPad(bool hasButton) { mHasButtonUnderPad = hasButton; } + inline bool hasButtonUnderPad() const { return mHasButtonUnderPad; } + + inline const Vector& getMotionRanges() const { + return mMotionRanges; + } + +private: + int32_t mId; + int32_t mGeneration; + int32_t mControllerNumber; + InputDeviceIdentifier mIdentifier; + String8 mAlias; + bool mIsExternal; + bool mHasMic; + uint32_t mSources; + int32_t mKeyboardType; + sp mKeyCharacterMap; + bool mHasVibrator; + bool mHasButtonUnderPad; + + Vector mMotionRanges; +}; + +/* Types of input device configuration files. */ +enum InputDeviceConfigurationFileType { + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0, /* .idc file */ + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT = 1, /* .kl file */ + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP = 2, /* .kcm file */ +}; + +/* + * Gets the path of an input device configuration file, if one is available. + * Considers both system provided and user installed configuration files. + * + * The device identifier is used to construct several default configuration file + * names to try based on the device name, vendor, product, and version. + * + * Returns an empty string if not found. + */ +extern String8 getInputDeviceConfigurationFilePathByDeviceIdentifier( + const InputDeviceIdentifier& deviceIdentifier, + InputDeviceConfigurationFileType type); + +/* + * Gets the path of an input device configuration file, if one is available. + * Considers both system provided and user installed configuration files. + * + * The name is case-sensitive and is used to construct the filename to resolve. + * All characters except 'a'-'z', 'A'-'Z', '0'-'9', '-', and '_' are replaced by underscores. + * + * Returns an empty string if not found. + */ +extern String8 getInputDeviceConfigurationFilePathByName( + const String8& name, InputDeviceConfigurationFileType type); + +} // namespace android + +#endif // _LIBINPUT_INPUT_DEVICE_H diff --git a/phonelibs/android_frameworks_native/include/input/InputEventLabels.h b/phonelibs/android_frameworks_native/include/input/InputEventLabels.h new file mode 100644 index 00000000000000..c03c0f2d584500 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/input/InputEventLabels.h @@ -0,0 +1,447 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBINPUT_INPUT_EVENT_LABELS_H +#define _LIBINPUT_INPUT_EVENT_LABELS_H + +#include +#include + +#define DEFINE_KEYCODE(key) { #key, AKEYCODE_##key } +#define DEFINE_AXIS(axis) { #axis, AMOTION_EVENT_AXIS_##axis } +#define DEFINE_LED(led) { #led, ALED_##led } +#define DEFINE_FLAG(flag) { #flag, POLICY_FLAG_##flag } + +namespace android { + +template +size_t size(T (&)[N]) { return N; } + +struct InputEventLabel { + const char *literal; + int value; +}; + + +static const InputEventLabel KEYCODES[] = { + // NOTE: If you add a new keycode here you must also add it to several other files. + // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list. + DEFINE_KEYCODE(UNKNOWN), + DEFINE_KEYCODE(SOFT_LEFT), + DEFINE_KEYCODE(SOFT_RIGHT), + DEFINE_KEYCODE(HOME), + DEFINE_KEYCODE(BACK), + DEFINE_KEYCODE(CALL), + DEFINE_KEYCODE(ENDCALL), + DEFINE_KEYCODE(0), + DEFINE_KEYCODE(1), + DEFINE_KEYCODE(2), + DEFINE_KEYCODE(3), + DEFINE_KEYCODE(4), + DEFINE_KEYCODE(5), + DEFINE_KEYCODE(6), + DEFINE_KEYCODE(7), + DEFINE_KEYCODE(8), + DEFINE_KEYCODE(9), + DEFINE_KEYCODE(STAR), + DEFINE_KEYCODE(POUND), + DEFINE_KEYCODE(DPAD_UP), + DEFINE_KEYCODE(DPAD_DOWN), + DEFINE_KEYCODE(DPAD_LEFT), + DEFINE_KEYCODE(DPAD_RIGHT), + DEFINE_KEYCODE(DPAD_CENTER), + DEFINE_KEYCODE(VOLUME_UP), + DEFINE_KEYCODE(VOLUME_DOWN), + DEFINE_KEYCODE(POWER), + DEFINE_KEYCODE(CAMERA), + DEFINE_KEYCODE(CLEAR), + DEFINE_KEYCODE(A), + DEFINE_KEYCODE(B), + DEFINE_KEYCODE(C), + DEFINE_KEYCODE(D), + DEFINE_KEYCODE(E), + DEFINE_KEYCODE(F), + DEFINE_KEYCODE(G), + DEFINE_KEYCODE(H), + DEFINE_KEYCODE(I), + DEFINE_KEYCODE(J), + DEFINE_KEYCODE(K), + DEFINE_KEYCODE(L), + DEFINE_KEYCODE(M), + DEFINE_KEYCODE(N), + DEFINE_KEYCODE(O), + DEFINE_KEYCODE(P), + DEFINE_KEYCODE(Q), + DEFINE_KEYCODE(R), + DEFINE_KEYCODE(S), + DEFINE_KEYCODE(T), + DEFINE_KEYCODE(U), + DEFINE_KEYCODE(V), + DEFINE_KEYCODE(W), + DEFINE_KEYCODE(X), + DEFINE_KEYCODE(Y), + DEFINE_KEYCODE(Z), + DEFINE_KEYCODE(COMMA), + DEFINE_KEYCODE(PERIOD), + DEFINE_KEYCODE(ALT_LEFT), + DEFINE_KEYCODE(ALT_RIGHT), + DEFINE_KEYCODE(SHIFT_LEFT), + DEFINE_KEYCODE(SHIFT_RIGHT), + DEFINE_KEYCODE(TAB), + DEFINE_KEYCODE(SPACE), + DEFINE_KEYCODE(SYM), + DEFINE_KEYCODE(EXPLORER), + DEFINE_KEYCODE(ENVELOPE), + DEFINE_KEYCODE(ENTER), + DEFINE_KEYCODE(DEL), + DEFINE_KEYCODE(GRAVE), + DEFINE_KEYCODE(MINUS), + DEFINE_KEYCODE(EQUALS), + DEFINE_KEYCODE(LEFT_BRACKET), + DEFINE_KEYCODE(RIGHT_BRACKET), + DEFINE_KEYCODE(BACKSLASH), + DEFINE_KEYCODE(SEMICOLON), + DEFINE_KEYCODE(APOSTROPHE), + DEFINE_KEYCODE(SLASH), + DEFINE_KEYCODE(AT), + DEFINE_KEYCODE(NUM), + DEFINE_KEYCODE(HEADSETHOOK), + DEFINE_KEYCODE(FOCUS), // *Camera* focus + DEFINE_KEYCODE(PLUS), + DEFINE_KEYCODE(MENU), + DEFINE_KEYCODE(NOTIFICATION), + DEFINE_KEYCODE(SEARCH), + DEFINE_KEYCODE(MEDIA_PLAY_PAUSE), + DEFINE_KEYCODE(MEDIA_STOP), + DEFINE_KEYCODE(MEDIA_NEXT), + DEFINE_KEYCODE(MEDIA_PREVIOUS), + DEFINE_KEYCODE(MEDIA_REWIND), + DEFINE_KEYCODE(MEDIA_FAST_FORWARD), + DEFINE_KEYCODE(MUTE), + DEFINE_KEYCODE(PAGE_UP), + DEFINE_KEYCODE(PAGE_DOWN), + DEFINE_KEYCODE(PICTSYMBOLS), + DEFINE_KEYCODE(SWITCH_CHARSET), + DEFINE_KEYCODE(BUTTON_A), + DEFINE_KEYCODE(BUTTON_B), + DEFINE_KEYCODE(BUTTON_C), + DEFINE_KEYCODE(BUTTON_X), + DEFINE_KEYCODE(BUTTON_Y), + DEFINE_KEYCODE(BUTTON_Z), + DEFINE_KEYCODE(BUTTON_L1), + DEFINE_KEYCODE(BUTTON_R1), + DEFINE_KEYCODE(BUTTON_L2), + DEFINE_KEYCODE(BUTTON_R2), + DEFINE_KEYCODE(BUTTON_THUMBL), + DEFINE_KEYCODE(BUTTON_THUMBR), + DEFINE_KEYCODE(BUTTON_START), + DEFINE_KEYCODE(BUTTON_SELECT), + DEFINE_KEYCODE(BUTTON_MODE), + DEFINE_KEYCODE(ESCAPE), + DEFINE_KEYCODE(FORWARD_DEL), + DEFINE_KEYCODE(CTRL_LEFT), + DEFINE_KEYCODE(CTRL_RIGHT), + DEFINE_KEYCODE(CAPS_LOCK), + DEFINE_KEYCODE(SCROLL_LOCK), + DEFINE_KEYCODE(META_LEFT), + DEFINE_KEYCODE(META_RIGHT), + DEFINE_KEYCODE(FUNCTION), + DEFINE_KEYCODE(SYSRQ), + DEFINE_KEYCODE(BREAK), + DEFINE_KEYCODE(MOVE_HOME), + DEFINE_KEYCODE(MOVE_END), + DEFINE_KEYCODE(INSERT), + DEFINE_KEYCODE(FORWARD), + DEFINE_KEYCODE(MEDIA_PLAY), + DEFINE_KEYCODE(MEDIA_PAUSE), + DEFINE_KEYCODE(MEDIA_CLOSE), + DEFINE_KEYCODE(MEDIA_EJECT), + DEFINE_KEYCODE(MEDIA_RECORD), + DEFINE_KEYCODE(F1), + DEFINE_KEYCODE(F2), + DEFINE_KEYCODE(F3), + DEFINE_KEYCODE(F4), + DEFINE_KEYCODE(F5), + DEFINE_KEYCODE(F6), + DEFINE_KEYCODE(F7), + DEFINE_KEYCODE(F8), + DEFINE_KEYCODE(F9), + DEFINE_KEYCODE(F10), + DEFINE_KEYCODE(F11), + DEFINE_KEYCODE(F12), + DEFINE_KEYCODE(NUM_LOCK), + DEFINE_KEYCODE(NUMPAD_0), + DEFINE_KEYCODE(NUMPAD_1), + DEFINE_KEYCODE(NUMPAD_2), + DEFINE_KEYCODE(NUMPAD_3), + DEFINE_KEYCODE(NUMPAD_4), + DEFINE_KEYCODE(NUMPAD_5), + DEFINE_KEYCODE(NUMPAD_6), + DEFINE_KEYCODE(NUMPAD_7), + DEFINE_KEYCODE(NUMPAD_8), + DEFINE_KEYCODE(NUMPAD_9), + DEFINE_KEYCODE(NUMPAD_DIVIDE), + DEFINE_KEYCODE(NUMPAD_MULTIPLY), + DEFINE_KEYCODE(NUMPAD_SUBTRACT), + DEFINE_KEYCODE(NUMPAD_ADD), + DEFINE_KEYCODE(NUMPAD_DOT), + DEFINE_KEYCODE(NUMPAD_COMMA), + DEFINE_KEYCODE(NUMPAD_ENTER), + DEFINE_KEYCODE(NUMPAD_EQUALS), + DEFINE_KEYCODE(NUMPAD_LEFT_PAREN), + DEFINE_KEYCODE(NUMPAD_RIGHT_PAREN), + DEFINE_KEYCODE(VOLUME_MUTE), + DEFINE_KEYCODE(INFO), + DEFINE_KEYCODE(CHANNEL_UP), + DEFINE_KEYCODE(CHANNEL_DOWN), + DEFINE_KEYCODE(ZOOM_IN), + DEFINE_KEYCODE(ZOOM_OUT), + DEFINE_KEYCODE(TV), + DEFINE_KEYCODE(WINDOW), + DEFINE_KEYCODE(GUIDE), + DEFINE_KEYCODE(DVR), + DEFINE_KEYCODE(BOOKMARK), + DEFINE_KEYCODE(CAPTIONS), + DEFINE_KEYCODE(SETTINGS), + DEFINE_KEYCODE(TV_POWER), + DEFINE_KEYCODE(TV_INPUT), + DEFINE_KEYCODE(STB_POWER), + DEFINE_KEYCODE(STB_INPUT), + DEFINE_KEYCODE(AVR_POWER), + DEFINE_KEYCODE(AVR_INPUT), + DEFINE_KEYCODE(PROG_RED), + DEFINE_KEYCODE(PROG_GREEN), + DEFINE_KEYCODE(PROG_YELLOW), + DEFINE_KEYCODE(PROG_BLUE), + DEFINE_KEYCODE(APP_SWITCH), + DEFINE_KEYCODE(BUTTON_1), + DEFINE_KEYCODE(BUTTON_2), + DEFINE_KEYCODE(BUTTON_3), + DEFINE_KEYCODE(BUTTON_4), + DEFINE_KEYCODE(BUTTON_5), + DEFINE_KEYCODE(BUTTON_6), + DEFINE_KEYCODE(BUTTON_7), + DEFINE_KEYCODE(BUTTON_8), + DEFINE_KEYCODE(BUTTON_9), + DEFINE_KEYCODE(BUTTON_10), + DEFINE_KEYCODE(BUTTON_11), + DEFINE_KEYCODE(BUTTON_12), + DEFINE_KEYCODE(BUTTON_13), + DEFINE_KEYCODE(BUTTON_14), + DEFINE_KEYCODE(BUTTON_15), + DEFINE_KEYCODE(BUTTON_16), + DEFINE_KEYCODE(LANGUAGE_SWITCH), + DEFINE_KEYCODE(MANNER_MODE), + DEFINE_KEYCODE(3D_MODE), + DEFINE_KEYCODE(CONTACTS), + DEFINE_KEYCODE(CALENDAR), + DEFINE_KEYCODE(MUSIC), + DEFINE_KEYCODE(CALCULATOR), + DEFINE_KEYCODE(ZENKAKU_HANKAKU), + DEFINE_KEYCODE(EISU), + DEFINE_KEYCODE(MUHENKAN), + DEFINE_KEYCODE(HENKAN), + DEFINE_KEYCODE(KATAKANA_HIRAGANA), + DEFINE_KEYCODE(YEN), + DEFINE_KEYCODE(RO), + DEFINE_KEYCODE(KANA), + DEFINE_KEYCODE(ASSIST), + DEFINE_KEYCODE(BRIGHTNESS_DOWN), + DEFINE_KEYCODE(BRIGHTNESS_UP), + DEFINE_KEYCODE(MEDIA_AUDIO_TRACK), + DEFINE_KEYCODE(SLEEP), + DEFINE_KEYCODE(WAKEUP), + DEFINE_KEYCODE(PAIRING), + DEFINE_KEYCODE(MEDIA_TOP_MENU), + DEFINE_KEYCODE(11), + DEFINE_KEYCODE(12), + DEFINE_KEYCODE(LAST_CHANNEL), + DEFINE_KEYCODE(TV_DATA_SERVICE), + DEFINE_KEYCODE(VOICE_ASSIST), + DEFINE_KEYCODE(TV_RADIO_SERVICE), + DEFINE_KEYCODE(TV_TELETEXT), + DEFINE_KEYCODE(TV_NUMBER_ENTRY), + DEFINE_KEYCODE(TV_TERRESTRIAL_ANALOG), + DEFINE_KEYCODE(TV_TERRESTRIAL_DIGITAL), + DEFINE_KEYCODE(TV_SATELLITE), + DEFINE_KEYCODE(TV_SATELLITE_BS), + DEFINE_KEYCODE(TV_SATELLITE_CS), + DEFINE_KEYCODE(TV_SATELLITE_SERVICE), + DEFINE_KEYCODE(TV_NETWORK), + DEFINE_KEYCODE(TV_ANTENNA_CABLE), + DEFINE_KEYCODE(TV_INPUT_HDMI_1), + DEFINE_KEYCODE(TV_INPUT_HDMI_2), + DEFINE_KEYCODE(TV_INPUT_HDMI_3), + DEFINE_KEYCODE(TV_INPUT_HDMI_4), + DEFINE_KEYCODE(TV_INPUT_COMPOSITE_1), + DEFINE_KEYCODE(TV_INPUT_COMPOSITE_2), + DEFINE_KEYCODE(TV_INPUT_COMPONENT_1), + DEFINE_KEYCODE(TV_INPUT_COMPONENT_2), + DEFINE_KEYCODE(TV_INPUT_VGA_1), + DEFINE_KEYCODE(TV_AUDIO_DESCRIPTION), + DEFINE_KEYCODE(TV_AUDIO_DESCRIPTION_MIX_UP), + DEFINE_KEYCODE(TV_AUDIO_DESCRIPTION_MIX_DOWN), + DEFINE_KEYCODE(TV_ZOOM_MODE), + DEFINE_KEYCODE(TV_CONTENTS_MENU), + DEFINE_KEYCODE(TV_MEDIA_CONTEXT_MENU), + DEFINE_KEYCODE(TV_TIMER_PROGRAMMING), + DEFINE_KEYCODE(HELP), + DEFINE_KEYCODE(NAVIGATE_PREVIOUS), + DEFINE_KEYCODE(NAVIGATE_NEXT), + DEFINE_KEYCODE(NAVIGATE_IN), + DEFINE_KEYCODE(NAVIGATE_OUT), + DEFINE_KEYCODE(STEM_PRIMARY), + DEFINE_KEYCODE(STEM_1), + DEFINE_KEYCODE(STEM_2), + DEFINE_KEYCODE(STEM_3), + DEFINE_KEYCODE(MEDIA_SKIP_FORWARD), + DEFINE_KEYCODE(MEDIA_SKIP_BACKWARD), + DEFINE_KEYCODE(MEDIA_STEP_FORWARD), + DEFINE_KEYCODE(MEDIA_STEP_BACKWARD), + DEFINE_KEYCODE(SOFT_SLEEP), + + { NULL, 0 } +}; + +static const InputEventLabel AXES[] = { + DEFINE_AXIS(X), + DEFINE_AXIS(Y), + DEFINE_AXIS(PRESSURE), + DEFINE_AXIS(SIZE), + DEFINE_AXIS(TOUCH_MAJOR), + DEFINE_AXIS(TOUCH_MINOR), + DEFINE_AXIS(TOOL_MAJOR), + DEFINE_AXIS(TOOL_MINOR), + DEFINE_AXIS(ORIENTATION), + DEFINE_AXIS(VSCROLL), + DEFINE_AXIS(HSCROLL), + DEFINE_AXIS(Z), + DEFINE_AXIS(RX), + DEFINE_AXIS(RY), + DEFINE_AXIS(RZ), + DEFINE_AXIS(HAT_X), + DEFINE_AXIS(HAT_Y), + DEFINE_AXIS(LTRIGGER), + DEFINE_AXIS(RTRIGGER), + DEFINE_AXIS(THROTTLE), + DEFINE_AXIS(RUDDER), + DEFINE_AXIS(WHEEL), + DEFINE_AXIS(GAS), + DEFINE_AXIS(BRAKE), + DEFINE_AXIS(DISTANCE), + DEFINE_AXIS(TILT), + DEFINE_AXIS(GENERIC_1), + DEFINE_AXIS(GENERIC_2), + DEFINE_AXIS(GENERIC_3), + DEFINE_AXIS(GENERIC_4), + DEFINE_AXIS(GENERIC_5), + DEFINE_AXIS(GENERIC_6), + DEFINE_AXIS(GENERIC_7), + DEFINE_AXIS(GENERIC_8), + DEFINE_AXIS(GENERIC_9), + DEFINE_AXIS(GENERIC_10), + DEFINE_AXIS(GENERIC_11), + DEFINE_AXIS(GENERIC_12), + DEFINE_AXIS(GENERIC_13), + DEFINE_AXIS(GENERIC_14), + DEFINE_AXIS(GENERIC_15), + DEFINE_AXIS(GENERIC_16), + + // NOTE: If you add a new axis here you must also add it to several other files. + // Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list. + { NULL, 0 } +}; + +static const InputEventLabel LEDS[] = { + DEFINE_LED(NUM_LOCK), + DEFINE_LED(CAPS_LOCK), + DEFINE_LED(SCROLL_LOCK), + DEFINE_LED(COMPOSE), + DEFINE_LED(KANA), + DEFINE_LED(SLEEP), + DEFINE_LED(SUSPEND), + DEFINE_LED(MUTE), + DEFINE_LED(MISC), + DEFINE_LED(MAIL), + DEFINE_LED(CHARGING), + DEFINE_LED(CONTROLLER_1), + DEFINE_LED(CONTROLLER_2), + DEFINE_LED(CONTROLLER_3), + DEFINE_LED(CONTROLLER_4), + + // NOTE: If you add new LEDs here, you must also add them to Input.h + { NULL, 0 } +}; + +static const InputEventLabel FLAGS[] = { + DEFINE_FLAG(WAKE), + DEFINE_FLAG(VIRTUAL), + DEFINE_FLAG(FUNCTION), + DEFINE_FLAG(GESTURE), + + { NULL, 0 } +}; + +static int lookupValueByLabel(const char* literal, const InputEventLabel *list) { + while (list->literal) { + if (strcmp(literal, list->literal) == 0) { + return list->value; + } + list++; + } + return list->value; +} + +static const char* lookupLabelByValue(int value, const InputEventLabel* list) { + while (list->literal) { + if (list->value == value) { + return list->literal; + } + list++; + } + return NULL; +} + +static int32_t getKeyCodeByLabel(const char* label) { + return int32_t(lookupValueByLabel(label, KEYCODES)); +} + +static const char* getLabelByKeyCode(int32_t keyCode) { + if (keyCode >= 0 && keyCode < size(KEYCODES)) { + return KEYCODES[keyCode].literal; + } + return NULL; +} + +static uint32_t getKeyFlagByLabel(const char* label) { + return uint32_t(lookupValueByLabel(label, FLAGS)); +} + +static int32_t getAxisByLabel(const char* label) { + return int32_t(lookupValueByLabel(label, AXES)); +} + +static const char* getAxisLabel(int32_t axisId) { + return lookupLabelByValue(axisId, AXES); +} + +static int32_t getLedByLabel(const char* label) { + return int32_t(lookupValueByLabel(label, LEDS)); +} + + +} // namespace android +#endif // _LIBINPUT_INPUT_EVENT_LABELS_H diff --git a/phonelibs/android_frameworks_native/include/input/InputTransport.h b/phonelibs/android_frameworks_native/include/input/InputTransport.h new file mode 100644 index 00000000000000..f31bceabd75c3a --- /dev/null +++ b/phonelibs/android_frameworks_native/include/input/InputTransport.h @@ -0,0 +1,453 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBINPUT_INPUT_TRANSPORT_H +#define _LIBINPUT_INPUT_TRANSPORT_H + +/** + * Native input transport. + * + * The InputChannel provides a mechanism for exchanging InputMessage structures across processes. + * + * The InputPublisher and InputConsumer each handle one end-point of an input channel. + * The InputPublisher is used by the input dispatcher to send events to the application. + * The InputConsumer is used by the application to receive events from the input dispatcher. + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace android { + +/* + * Intermediate representation used to send input events and related signals. + * + * Note that this structure is used for IPCs so its layout must be identical + * on 64 and 32 bit processes. This is tested in StructLayout_test.cpp. + */ +struct InputMessage { + enum { + TYPE_KEY = 1, + TYPE_MOTION = 2, + TYPE_FINISHED = 3, + }; + + struct Header { + uint32_t type; + // We don't need this field in order to align the body below but we + // leave it here because InputMessage::size() and other functions + // compute the size of this structure as sizeof(Header) + sizeof(Body). + uint32_t padding; + } header; + + // Body *must* be 8 byte aligned. + union Body { + struct Key { + uint32_t seq; + nsecs_t eventTime __attribute__((aligned(8))); + int32_t deviceId; + int32_t source; + int32_t action; + int32_t flags; + int32_t keyCode; + int32_t scanCode; + int32_t metaState; + int32_t repeatCount; + nsecs_t downTime __attribute__((aligned(8))); + + inline size_t size() const { + return sizeof(Key); + } + } key; + + struct Motion { + uint32_t seq; + nsecs_t eventTime __attribute__((aligned(8))); + int32_t deviceId; + int32_t source; + int32_t action; + int32_t actionButton; + int32_t flags; + int32_t metaState; + int32_t buttonState; + int32_t edgeFlags; + nsecs_t downTime __attribute__((aligned(8))); + float xOffset; + float yOffset; + float xPrecision; + float yPrecision; + uint32_t pointerCount; + // Note that PointerCoords requires 8 byte alignment. + struct Pointer { + PointerProperties properties; + PointerCoords coords; + } pointers[MAX_POINTERS]; + + int32_t getActionId() const { + uint32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) + >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; + return pointers[index].properties.id; + } + + inline size_t size() const { + return sizeof(Motion) - sizeof(Pointer) * MAX_POINTERS + + sizeof(Pointer) * pointerCount; + } + } motion; + + struct Finished { + uint32_t seq; + bool handled; + + inline size_t size() const { + return sizeof(Finished); + } + } finished; + } __attribute__((aligned(8))) body; + + bool isValid(size_t actualSize) const; + size_t size() const; +}; + +/* + * An input channel consists of a local unix domain socket used to send and receive + * input messages across processes. Each channel has a descriptive name for debugging purposes. + * + * Each endpoint has its own InputChannel object that specifies its file descriptor. + * + * The input channel is closed when all references to it are released. + */ +class InputChannel : public RefBase { +protected: + virtual ~InputChannel(); + +public: + InputChannel(const String8& name, int fd); + + /* Creates a pair of input channels. + * + * Returns OK on success. + */ + static status_t openInputChannelPair(const String8& name, + sp& outServerChannel, sp& outClientChannel); + + inline String8 getName() const { return mName; } + inline int getFd() const { return mFd; } + + /* Sends a message to the other endpoint. + * + * If the channel is full then the message is guaranteed not to have been sent at all. + * Try again after the consumer has sent a finished signal indicating that it has + * consumed some of the pending messages from the channel. + * + * Returns OK on success. + * Returns WOULD_BLOCK if the channel is full. + * Returns DEAD_OBJECT if the channel's peer has been closed. + * Other errors probably indicate that the channel is broken. + */ + status_t sendMessage(const InputMessage* msg); + + /* Receives a message sent by the other endpoint. + * + * If there is no message present, try again after poll() indicates that the fd + * is readable. + * + * Returns OK on success. + * Returns WOULD_BLOCK if there is no message present. + * Returns DEAD_OBJECT if the channel's peer has been closed. + * Other errors probably indicate that the channel is broken. + */ + status_t receiveMessage(InputMessage* msg); + + /* Returns a new object that has a duplicate of this channel's fd. */ + sp dup() const; + +private: + String8 mName; + int mFd; +}; + +/* + * Publishes input events to an input channel. + */ +class InputPublisher { +public: + /* Creates a publisher associated with an input channel. */ + explicit InputPublisher(const sp& channel); + + /* Destroys the publisher and releases its input channel. */ + ~InputPublisher(); + + /* Gets the underlying input channel. */ + inline sp getChannel() { return mChannel; } + + /* Publishes a key event to the input channel. + * + * Returns OK on success. + * Returns WOULD_BLOCK if the channel is full. + * Returns DEAD_OBJECT if the channel's peer has been closed. + * Returns BAD_VALUE if seq is 0. + * Other errors probably indicate that the channel is broken. + */ + status_t publishKeyEvent( + uint32_t seq, + int32_t deviceId, + int32_t source, + int32_t action, + int32_t flags, + int32_t keyCode, + int32_t scanCode, + int32_t metaState, + int32_t repeatCount, + nsecs_t downTime, + nsecs_t eventTime); + + /* Publishes a motion event to the input channel. + * + * Returns OK on success. + * Returns WOULD_BLOCK if the channel is full. + * Returns DEAD_OBJECT if the channel's peer has been closed. + * Returns BAD_VALUE if seq is 0 or if pointerCount is less than 1 or greater than MAX_POINTERS. + * Other errors probably indicate that the channel is broken. + */ + status_t publishMotionEvent( + uint32_t seq, + int32_t deviceId, + int32_t source, + int32_t action, + int32_t actionButton, + int32_t flags, + int32_t edgeFlags, + int32_t metaState, + int32_t buttonState, + float xOffset, + float yOffset, + float xPrecision, + float yPrecision, + nsecs_t downTime, + nsecs_t eventTime, + uint32_t pointerCount, + const PointerProperties* pointerProperties, + const PointerCoords* pointerCoords); + + /* Receives the finished signal from the consumer in reply to the original dispatch signal. + * If a signal was received, returns the message sequence number, + * and whether the consumer handled the message. + * + * The returned sequence number is never 0 unless the operation failed. + * + * Returns OK on success. + * Returns WOULD_BLOCK if there is no signal present. + * Returns DEAD_OBJECT if the channel's peer has been closed. + * Other errors probably indicate that the channel is broken. + */ + status_t receiveFinishedSignal(uint32_t* outSeq, bool* outHandled); + +private: + sp mChannel; +}; + +/* + * Consumes input events from an input channel. + */ +class InputConsumer { +public: + /* Creates a consumer associated with an input channel. */ + explicit InputConsumer(const sp& channel); + + /* Destroys the consumer and releases its input channel. */ + ~InputConsumer(); + + /* Gets the underlying input channel. */ + inline sp getChannel() { return mChannel; } + + /* Consumes an input event from the input channel and copies its contents into + * an InputEvent object created using the specified factory. + * + * Tries to combine a series of move events into larger batches whenever possible. + * + * If consumeBatches is false, then defers consuming pending batched events if it + * is possible for additional samples to be added to them later. Call hasPendingBatch() + * to determine whether a pending batch is available to be consumed. + * + * If consumeBatches is true, then events are still batched but they are consumed + * immediately as soon as the input channel is exhausted. + * + * The frameTime parameter specifies the time when the current display frame started + * rendering in the CLOCK_MONOTONIC time base, or -1 if unknown. + * + * The returned sequence number is never 0 unless the operation failed. + * + * Returns OK on success. + * Returns WOULD_BLOCK if there is no event present. + * Returns DEAD_OBJECT if the channel's peer has been closed. + * Returns NO_MEMORY if the event could not be created. + * Other errors probably indicate that the channel is broken. + */ + status_t consume(InputEventFactoryInterface* factory, bool consumeBatches, + nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent); + + /* Sends a finished signal to the publisher to inform it that the message + * with the specified sequence number has finished being process and whether + * the message was handled by the consumer. + * + * Returns OK on success. + * Returns BAD_VALUE if seq is 0. + * Other errors probably indicate that the channel is broken. + */ + status_t sendFinishedSignal(uint32_t seq, bool handled); + + /* Returns true if there is a deferred event waiting. + * + * Should be called after calling consume() to determine whether the consumer + * has a deferred event to be processed. Deferred events are somewhat special in + * that they have already been removed from the input channel. If the input channel + * becomes empty, the client may need to do extra work to ensure that it processes + * the deferred event despite the fact that the input channel's file descriptor + * is not readable. + * + * One option is simply to call consume() in a loop until it returns WOULD_BLOCK. + * This guarantees that all deferred events will be processed. + * + * Alternately, the caller can call hasDeferredEvent() to determine whether there is + * a deferred event waiting and then ensure that its event loop wakes up at least + * one more time to consume the deferred event. + */ + bool hasDeferredEvent() const; + + /* Returns true if there is a pending batch. + * + * Should be called after calling consume() with consumeBatches == false to determine + * whether consume() should be called again later on with consumeBatches == true. + */ + bool hasPendingBatch() const; + +private: + // True if touch resampling is enabled. + const bool mResampleTouch; + + // The input channel. + sp mChannel; + + // The current input message. + InputMessage mMsg; + + // True if mMsg contains a valid input message that was deferred from the previous + // call to consume and that still needs to be handled. + bool mMsgDeferred; + + // Batched motion events per device and source. + struct Batch { + Vector samples; + }; + Vector mBatches; + + // Touch state per device and source, only for sources of class pointer. + struct History { + nsecs_t eventTime; + BitSet32 idBits; + int32_t idToIndex[MAX_POINTER_ID + 1]; + PointerCoords pointers[MAX_POINTERS]; + + void initializeFrom(const InputMessage* msg) { + eventTime = msg->body.motion.eventTime; + idBits.clear(); + for (uint32_t i = 0; i < msg->body.motion.pointerCount; i++) { + uint32_t id = msg->body.motion.pointers[i].properties.id; + idBits.markBit(id); + idToIndex[id] = i; + pointers[i].copyFrom(msg->body.motion.pointers[i].coords); + } + } + + const PointerCoords& getPointerById(uint32_t id) const { + return pointers[idToIndex[id]]; + } + }; + struct TouchState { + int32_t deviceId; + int32_t source; + size_t historyCurrent; + size_t historySize; + History history[2]; + History lastResample; + + void initialize(int32_t deviceId, int32_t source) { + this->deviceId = deviceId; + this->source = source; + historyCurrent = 0; + historySize = 0; + lastResample.eventTime = 0; + lastResample.idBits.clear(); + } + + void addHistory(const InputMessage* msg) { + historyCurrent ^= 1; + if (historySize < 2) { + historySize += 1; + } + history[historyCurrent].initializeFrom(msg); + } + + const History* getHistory(size_t index) const { + return &history[(historyCurrent + index) & 1]; + } + }; + Vector mTouchStates; + + // Chain of batched sequence numbers. When multiple input messages are combined into + // a batch, we append a record here that associates the last sequence number in the + // batch with the previous one. When the finished signal is sent, we traverse the + // chain to individually finish all input messages that were part of the batch. + struct SeqChain { + uint32_t seq; // sequence number of batched input message + uint32_t chain; // sequence number of previous batched input message + }; + Vector mSeqChains; + + status_t consumeBatch(InputEventFactoryInterface* factory, + nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent); + status_t consumeSamples(InputEventFactoryInterface* factory, + Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent); + + void updateTouchState(InputMessage* msg); + void rewriteMessage(const TouchState& state, InputMessage* msg); + void resampleTouchState(nsecs_t frameTime, MotionEvent* event, + const InputMessage *next); + + ssize_t findBatch(int32_t deviceId, int32_t source) const; + ssize_t findTouchState(int32_t deviceId, int32_t source) const; + + status_t sendUnchainedFinishedSignal(uint32_t seq, bool handled); + + static void initializeKeyEvent(KeyEvent* event, const InputMessage* msg); + static void initializeMotionEvent(MotionEvent* event, const InputMessage* msg); + static void addSample(MotionEvent* event, const InputMessage* msg); + static bool canAddSample(const Batch& batch, const InputMessage* msg); + static ssize_t findSampleNoLaterThan(const Batch& batch, nsecs_t time); + static bool shouldResampleTool(int32_t toolType); + + static bool isTouchResamplingEnabled(); +}; + +} // namespace android + +#endif // _LIBINPUT_INPUT_TRANSPORT_H diff --git a/phonelibs/android_frameworks_native/include/input/KeyCharacterMap.h b/phonelibs/android_frameworks_native/include/input/KeyCharacterMap.h new file mode 100644 index 00000000000000..3f0914b67e5d9c --- /dev/null +++ b/phonelibs/android_frameworks_native/include/input/KeyCharacterMap.h @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBINPUT_KEY_CHARACTER_MAP_H +#define _LIBINPUT_KEY_CHARACTER_MAP_H + +#include + +#if HAVE_ANDROID_OS +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace android { + +/** + * Describes a mapping from Android key codes to characters. + * Also specifies other functions of the keyboard such as the keyboard type + * and key modifier semantics. + * + * This object is immutable after it has been loaded. + */ +class KeyCharacterMap : public RefBase { +public: + enum KeyboardType { + KEYBOARD_TYPE_UNKNOWN = 0, + KEYBOARD_TYPE_NUMERIC = 1, + KEYBOARD_TYPE_PREDICTIVE = 2, + KEYBOARD_TYPE_ALPHA = 3, + KEYBOARD_TYPE_FULL = 4, + KEYBOARD_TYPE_SPECIAL_FUNCTION = 5, + KEYBOARD_TYPE_OVERLAY = 6, + }; + + enum Format { + // Base keyboard layout, may contain device-specific options, such as "type" declaration. + FORMAT_BASE = 0, + // Overlay keyboard layout, more restrictive, may be published by applications, + // cannot override device-specific options. + FORMAT_OVERLAY = 1, + // Either base or overlay layout ok. + FORMAT_ANY = 2, + }; + + // Substitute key code and meta state for fallback action. + struct FallbackAction { + int32_t keyCode; + int32_t metaState; + }; + + /* Loads a key character map from a file. */ + static status_t load(const String8& filename, Format format, sp* outMap); + + /* Loads a key character map from its string contents. */ + static status_t loadContents(const String8& filename, + const char* contents, Format format, sp* outMap); + + /* Combines a base key character map and an overlay. */ + static sp combine(const sp& base, + const sp& overlay); + + /* Returns an empty key character map. */ + static sp empty(); + + /* Gets the keyboard type. */ + int32_t getKeyboardType() const; + + /* Gets the primary character for this key as in the label physically printed on it. + * Returns 0 if none (eg. for non-printing keys). */ + char16_t getDisplayLabel(int32_t keyCode) const; + + /* Gets the Unicode character for the number or symbol generated by the key + * when the keyboard is used as a dialing pad. + * Returns 0 if no number or symbol is generated. + */ + char16_t getNumber(int32_t keyCode) const; + + /* Gets the Unicode character generated by the key and meta key modifiers. + * Returns 0 if no character is generated. + */ + char16_t getCharacter(int32_t keyCode, int32_t metaState) const; + + /* Gets the fallback action to use by default if the application does not + * handle the specified key. + * Returns true if an action was available, false if none. + */ + bool getFallbackAction(int32_t keyCode, int32_t metaState, + FallbackAction* outFallbackAction) const; + + /* Gets the first matching Unicode character that can be generated by the key, + * preferring the one with the specified meta key modifiers. + * Returns 0 if no matching character is generated. + */ + char16_t getMatch(int32_t keyCode, const char16_t* chars, + size_t numChars, int32_t metaState) const; + + /* Gets a sequence of key events that could plausibly generate the specified + * character sequence. Returns false if some of the characters cannot be generated. + */ + bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars, + Vector& outEvents) const; + + /* Maps a scan code and usage code to a key code, in case this key map overrides + * the mapping in some way. */ + status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const; + + /* Tries to find a replacement key code for a given key code and meta state + * in character map. */ + void tryRemapKey(int32_t scanCode, int32_t metaState, + int32_t* outKeyCode, int32_t* outMetaState) const; + +#if HAVE_ANDROID_OS + /* Reads a key map from a parcel. */ + static sp readFromParcel(Parcel* parcel); + + /* Writes a key map to a parcel. */ + void writeToParcel(Parcel* parcel) const; +#endif + +protected: + virtual ~KeyCharacterMap(); + +private: + struct Behavior { + Behavior(); + Behavior(const Behavior& other); + + /* The next behavior in the list, or NULL if none. */ + Behavior* next; + + /* The meta key modifiers for this behavior. */ + int32_t metaState; + + /* The character to insert. */ + char16_t character; + + /* The fallback keycode if the key is not handled. */ + int32_t fallbackKeyCode; + + /* The replacement keycode if the key has to be replaced outright. */ + int32_t replacementKeyCode; + }; + + struct Key { + Key(); + Key(const Key& other); + ~Key(); + + /* The single character label printed on the key, or 0 if none. */ + char16_t label; + + /* The number or symbol character generated by the key, or 0 if none. */ + char16_t number; + + /* The list of key behaviors sorted from most specific to least specific + * meta key binding. */ + Behavior* firstBehavior; + }; + + class Parser { + enum State { + STATE_TOP = 0, + STATE_KEY = 1, + }; + + enum { + PROPERTY_LABEL = 1, + PROPERTY_NUMBER = 2, + PROPERTY_META = 3, + }; + + struct Property { + inline Property(int32_t property = 0, int32_t metaState = 0) : + property(property), metaState(metaState) { } + + int32_t property; + int32_t metaState; + }; + + KeyCharacterMap* mMap; + Tokenizer* mTokenizer; + Format mFormat; + State mState; + int32_t mKeyCode; + + public: + Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format); + ~Parser(); + status_t parse(); + + private: + status_t parseType(); + status_t parseMap(); + status_t parseMapKey(); + status_t parseKey(); + status_t parseKeyProperty(); + status_t finishKey(Key* key); + status_t parseModifier(const String8& token, int32_t* outMetaState); + status_t parseCharacterLiteral(char16_t* outCharacter); + }; + + static sp sEmpty; + + KeyedVector mKeys; + int mType; + + KeyedVector mKeysByScanCode; + KeyedVector mKeysByUsageCode; + + KeyCharacterMap(); + KeyCharacterMap(const KeyCharacterMap& other); + + bool getKey(int32_t keyCode, const Key** outKey) const; + bool getKeyBehavior(int32_t keyCode, int32_t metaState, + const Key** outKey, const Behavior** outBehavior) const; + static bool matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState); + + bool findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const; + + static status_t load(Tokenizer* tokenizer, Format format, sp* outMap); + + static void addKey(Vector& outEvents, + int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time); + static void addMetaKeys(Vector& outEvents, + int32_t deviceId, int32_t metaState, bool down, nsecs_t time, + int32_t* currentMetaState); + static bool addSingleEphemeralMetaKey(Vector& outEvents, + int32_t deviceId, int32_t metaState, bool down, nsecs_t time, + int32_t keyCode, int32_t keyMetaState, + int32_t* currentMetaState); + static void addDoubleEphemeralMetaKey(Vector& outEvents, + int32_t deviceId, int32_t metaState, bool down, nsecs_t time, + int32_t leftKeyCode, int32_t leftKeyMetaState, + int32_t rightKeyCode, int32_t rightKeyMetaState, + int32_t eitherKeyMetaState, + int32_t* currentMetaState); + static void addLockedMetaKey(Vector& outEvents, + int32_t deviceId, int32_t metaState, nsecs_t time, + int32_t keyCode, int32_t keyMetaState, + int32_t* currentMetaState); +}; + +} // namespace android + +#endif // _LIBINPUT_KEY_CHARACTER_MAP_H diff --git a/phonelibs/android_frameworks_native/include/input/KeyLayoutMap.h b/phonelibs/android_frameworks_native/include/input/KeyLayoutMap.h new file mode 100644 index 00000000000000..1e8de7173bdb5f --- /dev/null +++ b/phonelibs/android_frameworks_native/include/input/KeyLayoutMap.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBINPUT_KEY_LAYOUT_MAP_H +#define _LIBINPUT_KEY_LAYOUT_MAP_H + +#include +#include +#include +#include +#include + +namespace android { + +struct AxisInfo { + enum Mode { + // Axis value is reported directly. + MODE_NORMAL = 0, + // Axis value should be inverted before reporting. + MODE_INVERT = 1, + // Axis value should be split into two axes + MODE_SPLIT = 2, + }; + + // Axis mode. + Mode mode; + + // Axis id. + // When split, this is the axis used for values smaller than the split position. + int32_t axis; + + // When split, this is the axis used for values after higher than the split position. + int32_t highAxis; + + // The split value, or 0 if not split. + int32_t splitValue; + + // The flat value, or -1 if none. + int32_t flatOverride; + + AxisInfo() : mode(MODE_NORMAL), axis(-1), highAxis(-1), splitValue(0), flatOverride(-1) { + } +}; + +/** + * Describes a mapping from keyboard scan codes and joystick axes to Android key codes and axes. + * + * This object is immutable after it has been loaded. + */ +class KeyLayoutMap : public RefBase { +public: + static status_t load(const String8& filename, sp* outMap); + + status_t mapKey(int32_t scanCode, int32_t usageCode, + int32_t* outKeyCode, uint32_t* outFlags) const; + status_t findScanCodesForKey(int32_t keyCode, Vector* outScanCodes) const; + status_t findScanCodeForLed(int32_t ledCode, int32_t* outScanCode) const; + status_t findUsageCodeForLed(int32_t ledCode, int32_t* outUsageCode) const; + + status_t mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const; + +protected: + virtual ~KeyLayoutMap(); + +private: + struct Key { + int32_t keyCode; + uint32_t flags; + }; + + struct Led { + int32_t ledCode; + }; + + + KeyedVector mKeysByScanCode; + KeyedVector mKeysByUsageCode; + KeyedVector mAxes; + KeyedVector mLedsByScanCode; + KeyedVector mLedsByUsageCode; + + KeyLayoutMap(); + + const Key* getKey(int32_t scanCode, int32_t usageCode) const; + + class Parser { + KeyLayoutMap* mMap; + Tokenizer* mTokenizer; + + public: + Parser(KeyLayoutMap* map, Tokenizer* tokenizer); + ~Parser(); + status_t parse(); + + private: + status_t parseKey(); + status_t parseAxis(); + status_t parseLed(); + }; +}; + +} // namespace android + +#endif // _LIBINPUT_KEY_LAYOUT_MAP_H diff --git a/phonelibs/android_frameworks_native/include/input/Keyboard.h b/phonelibs/android_frameworks_native/include/input/Keyboard.h new file mode 100644 index 00000000000000..d4903e98dfe3b6 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/input/Keyboard.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBINPUT_KEYBOARD_H +#define _LIBINPUT_KEYBOARD_H + +#include +#include +#include +#include +#include +#include + +namespace android { + +enum { + /* Device id of the built in keyboard. */ + DEVICE_ID_BUILT_IN_KEYBOARD = 0, + + /* Device id of a generic virtual keyboard with a full layout that can be used + * to synthesize key events. */ + DEVICE_ID_VIRTUAL_KEYBOARD = -1, +}; + +class KeyLayoutMap; +class KeyCharacterMap; + +/** + * Loads the key layout map and key character map for a keyboard device. + */ +class KeyMap { +public: + String8 keyLayoutFile; + sp keyLayoutMap; + + String8 keyCharacterMapFile; + sp keyCharacterMap; + + KeyMap(); + ~KeyMap(); + + status_t load(const InputDeviceIdentifier& deviceIdenfier, + const PropertyMap* deviceConfiguration); + + inline bool haveKeyLayout() const { + return !keyLayoutFile.isEmpty(); + } + + inline bool haveKeyCharacterMap() const { + return !keyCharacterMapFile.isEmpty(); + } + + inline bool isComplete() const { + return haveKeyLayout() && haveKeyCharacterMap(); + } + +private: + bool probeKeyMap(const InputDeviceIdentifier& deviceIdentifier, const String8& name); + status_t loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier, const String8& name); + status_t loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier, + const String8& name); + String8 getPath(const InputDeviceIdentifier& deviceIdentifier, + const String8& name, InputDeviceConfigurationFileType type); +}; + +/** + * Returns true if the keyboard is eligible for use as a built-in keyboard. + */ +extern bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier, + const PropertyMap* deviceConfiguration, const KeyMap* keyMap); + +/** + * Updates a meta state field when a key is pressed or released. + */ +extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState); + +/** + * Normalizes the meta state such that if either the left or right modifier + * meta state bits are set then the result will also include the universal + * bit for that modifier. + */ +extern int32_t normalizeMetaState(int32_t oldMetaState); + +/** + * Returns true if a key is a meta key like ALT or CAPS_LOCK. + */ +extern bool isMetaKey(int32_t keyCode); + +} // namespace android + +#endif // _LIBINPUT_KEYBOARD_H diff --git a/phonelibs/android_frameworks_native/include/input/VelocityControl.h b/phonelibs/android_frameworks_native/include/input/VelocityControl.h new file mode 100644 index 00000000000000..1acc2aef702ad5 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/input/VelocityControl.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBINPUT_VELOCITY_CONTROL_H +#define _LIBINPUT_VELOCITY_CONTROL_H + +#include +#include +#include + +namespace android { + +/* + * Specifies parameters that govern pointer or wheel acceleration. + */ +struct VelocityControlParameters { + // A scale factor that is multiplied with the raw velocity deltas + // prior to applying any other velocity control factors. The scale + // factor should be used to adapt the input device resolution + // (eg. counts per inch) to the output device resolution (eg. pixels per inch). + // + // Must be a positive value. + // Default is 1.0 (no scaling). + float scale; + + // The scaled speed at which acceleration begins to be applied. + // This value establishes the upper bound of a low speed regime for + // small precise motions that are performed without any acceleration. + // + // Must be a non-negative value. + // Default is 0.0 (no low threshold). + float lowThreshold; + + // The scaled speed at which maximum acceleration is applied. + // The difference between highThreshold and lowThreshold controls + // the range of speeds over which the acceleration factor is interpolated. + // The wider the range, the smoother the acceleration. + // + // Must be a non-negative value greater than or equal to lowThreshold. + // Default is 0.0 (no high threshold). + float highThreshold; + + // The acceleration factor. + // When the speed is above the low speed threshold, the velocity will scaled + // by an interpolated value between 1.0 and this amount. + // + // Must be a positive greater than or equal to 1.0. + // Default is 1.0 (no acceleration). + float acceleration; + + VelocityControlParameters() : + scale(1.0f), lowThreshold(0.0f), highThreshold(0.0f), acceleration(1.0f) { + } + + VelocityControlParameters(float scale, float lowThreshold, + float highThreshold, float acceleration) : + scale(scale), lowThreshold(lowThreshold), + highThreshold(highThreshold), acceleration(acceleration) { + } +}; + +/* + * Implements mouse pointer and wheel speed control and acceleration. + */ +class VelocityControl { +public: + VelocityControl(); + + /* Sets the various parameters. */ + void setParameters(const VelocityControlParameters& parameters); + + /* Resets the current movement counters to zero. + * This has the effect of nullifying any acceleration. */ + void reset(); + + /* Translates a raw movement delta into an appropriately + * scaled / accelerated delta based on the current velocity. */ + void move(nsecs_t eventTime, float* deltaX, float* deltaY); + +private: + // If no movements are received within this amount of time, + // we assume the movement has stopped and reset the movement counters. + static const nsecs_t STOP_TIME = 500 * 1000000; // 500 ms + + VelocityControlParameters mParameters; + + nsecs_t mLastMovementTime; + VelocityTracker::Position mRawPosition; + VelocityTracker mVelocityTracker; +}; + +} // namespace android + +#endif // _LIBINPUT_VELOCITY_CONTROL_H diff --git a/phonelibs/android_frameworks_native/include/input/VelocityTracker.h b/phonelibs/android_frameworks_native/include/input/VelocityTracker.h new file mode 100644 index 00000000000000..795f575a2e377d --- /dev/null +++ b/phonelibs/android_frameworks_native/include/input/VelocityTracker.h @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBINPUT_VELOCITY_TRACKER_H +#define _LIBINPUT_VELOCITY_TRACKER_H + +#include +#include +#include + +namespace android { + +class VelocityTrackerStrategy; + +/* + * Calculates the velocity of pointer movements over time. + */ +class VelocityTracker { +public: + struct Position { + float x, y; + }; + + struct Estimator { + static const size_t MAX_DEGREE = 4; + + // Estimator time base. + nsecs_t time; + + // Polynomial coefficients describing motion in X and Y. + float xCoeff[MAX_DEGREE + 1], yCoeff[MAX_DEGREE + 1]; + + // Polynomial degree (number of coefficients), or zero if no information is + // available. + uint32_t degree; + + // Confidence (coefficient of determination), between 0 (no fit) and 1 (perfect fit). + float confidence; + + inline void clear() { + time = 0; + degree = 0; + confidence = 0; + for (size_t i = 0; i <= MAX_DEGREE; i++) { + xCoeff[i] = 0; + yCoeff[i] = 0; + } + } + }; + + // Creates a velocity tracker using the specified strategy. + // If strategy is NULL, uses the default strategy for the platform. + VelocityTracker(const char* strategy = NULL); + + ~VelocityTracker(); + + // Resets the velocity tracker state. + void clear(); + + // Resets the velocity tracker state for specific pointers. + // Call this method when some pointers have changed and may be reusing + // an id that was assigned to a different pointer earlier. + void clearPointers(BitSet32 idBits); + + // Adds movement information for a set of pointers. + // The idBits bitfield specifies the pointer ids of the pointers whose positions + // are included in the movement. + // The positions array contains position information for each pointer in order by + // increasing id. Its size should be equal to the number of one bits in idBits. + void addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions); + + // Adds movement information for all pointers in a MotionEvent, including historical samples. + void addMovement(const MotionEvent* event); + + // Gets the velocity of the specified pointer id in position units per second. + // Returns false and sets the velocity components to zero if there is + // insufficient movement information for the pointer. + bool getVelocity(uint32_t id, float* outVx, float* outVy) const; + + // Gets an estimator for the recent movements of the specified pointer id. + // Returns false and clears the estimator if there is no information available + // about the pointer. + bool getEstimator(uint32_t id, Estimator* outEstimator) const; + + // Gets the active pointer id, or -1 if none. + inline int32_t getActivePointerId() const { return mActivePointerId; } + + // Gets a bitset containing all pointer ids from the most recent movement. + inline BitSet32 getCurrentPointerIdBits() const { return mCurrentPointerIdBits; } + +private: + static const char* DEFAULT_STRATEGY; + + nsecs_t mLastEventTime; + BitSet32 mCurrentPointerIdBits; + int32_t mActivePointerId; + VelocityTrackerStrategy* mStrategy; + + bool configureStrategy(const char* strategy); + + static VelocityTrackerStrategy* createStrategy(const char* strategy); +}; + + +/* + * Implements a particular velocity tracker algorithm. + */ +class VelocityTrackerStrategy { +protected: + VelocityTrackerStrategy() { } + +public: + virtual ~VelocityTrackerStrategy() { } + + virtual void clear() = 0; + virtual void clearPointers(BitSet32 idBits) = 0; + virtual void addMovement(nsecs_t eventTime, BitSet32 idBits, + const VelocityTracker::Position* positions) = 0; + virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const = 0; +}; + + +/* + * Velocity tracker algorithm based on least-squares linear regression. + */ +class LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy { +public: + enum Weighting { + // No weights applied. All data points are equally reliable. + WEIGHTING_NONE, + + // Weight by time delta. Data points clustered together are weighted less. + WEIGHTING_DELTA, + + // Weight such that points within a certain horizon are weighed more than those + // outside of that horizon. + WEIGHTING_CENTRAL, + + // Weight such that points older than a certain amount are weighed less. + WEIGHTING_RECENT, + }; + + // Degree must be no greater than Estimator::MAX_DEGREE. + LeastSquaresVelocityTrackerStrategy(uint32_t degree, Weighting weighting = WEIGHTING_NONE); + virtual ~LeastSquaresVelocityTrackerStrategy(); + + virtual void clear(); + virtual void clearPointers(BitSet32 idBits); + virtual void addMovement(nsecs_t eventTime, BitSet32 idBits, + const VelocityTracker::Position* positions); + virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const; + +private: + // Sample horizon. + // We don't use too much history by default since we want to react to quick + // changes in direction. + static const nsecs_t HORIZON = 100 * 1000000; // 100 ms + + // Number of samples to keep. + static const uint32_t HISTORY_SIZE = 20; + + struct Movement { + nsecs_t eventTime; + BitSet32 idBits; + VelocityTracker::Position positions[MAX_POINTERS]; + + inline const VelocityTracker::Position& getPosition(uint32_t id) const { + return positions[idBits.getIndexOfBit(id)]; + } + }; + + float chooseWeight(uint32_t index) const; + + const uint32_t mDegree; + const Weighting mWeighting; + uint32_t mIndex; + Movement mMovements[HISTORY_SIZE]; +}; + + +/* + * Velocity tracker algorithm that uses an IIR filter. + */ +class IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy { +public: + // Degree must be 1 or 2. + IntegratingVelocityTrackerStrategy(uint32_t degree); + ~IntegratingVelocityTrackerStrategy(); + + virtual void clear(); + virtual void clearPointers(BitSet32 idBits); + virtual void addMovement(nsecs_t eventTime, BitSet32 idBits, + const VelocityTracker::Position* positions); + virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const; + +private: + // Current state estimate for a particular pointer. + struct State { + nsecs_t updateTime; + uint32_t degree; + + float xpos, xvel, xaccel; + float ypos, yvel, yaccel; + }; + + const uint32_t mDegree; + BitSet32 mPointerIdBits; + State mPointerState[MAX_POINTER_ID + 1]; + + void initState(State& state, nsecs_t eventTime, float xpos, float ypos) const; + void updateState(State& state, nsecs_t eventTime, float xpos, float ypos) const; + void populateEstimator(const State& state, VelocityTracker::Estimator* outEstimator) const; +}; + + +/* + * Velocity tracker strategy used prior to ICS. + */ +class LegacyVelocityTrackerStrategy : public VelocityTrackerStrategy { +public: + LegacyVelocityTrackerStrategy(); + virtual ~LegacyVelocityTrackerStrategy(); + + virtual void clear(); + virtual void clearPointers(BitSet32 idBits); + virtual void addMovement(nsecs_t eventTime, BitSet32 idBits, + const VelocityTracker::Position* positions); + virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const; + +private: + // Oldest sample to consider when calculating the velocity. + static const nsecs_t HORIZON = 200 * 1000000; // 100 ms + + // Number of samples to keep. + static const uint32_t HISTORY_SIZE = 20; + + // The minimum duration between samples when estimating velocity. + static const nsecs_t MIN_DURATION = 10 * 1000000; // 10 ms + + struct Movement { + nsecs_t eventTime; + BitSet32 idBits; + VelocityTracker::Position positions[MAX_POINTERS]; + + inline const VelocityTracker::Position& getPosition(uint32_t id) const { + return positions[idBits.getIndexOfBit(id)]; + } + }; + + uint32_t mIndex; + Movement mMovements[HISTORY_SIZE]; +}; + +} // namespace android + +#endif // _LIBINPUT_VELOCITY_TRACKER_H diff --git a/phonelibs/android_frameworks_native/include/input/VirtualKeyMap.h b/phonelibs/android_frameworks_native/include/input/VirtualKeyMap.h new file mode 100644 index 00000000000000..e245ead682ef7e --- /dev/null +++ b/phonelibs/android_frameworks_native/include/input/VirtualKeyMap.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBINPUT_VIRTUAL_KEY_MAP_H +#define _LIBINPUT_VIRTUAL_KEY_MAP_H + +#include + +#include +#include +#include +#include +#include +#include + +namespace android { + +/* Describes a virtual key. */ +struct VirtualKeyDefinition { + int32_t scanCode; + + // configured position data, specified in display coords + int32_t centerX; + int32_t centerY; + int32_t width; + int32_t height; +}; + + +/** + * Describes a collection of virtual keys on a touch screen in terms of + * virtual scan codes and hit rectangles. + * + * This object is immutable after it has been loaded. + */ +class VirtualKeyMap { +public: + ~VirtualKeyMap(); + + static status_t load(const String8& filename, VirtualKeyMap** outMap); + + inline const Vector& getVirtualKeys() const { + return mVirtualKeys; + } + +private: + class Parser { + VirtualKeyMap* mMap; + Tokenizer* mTokenizer; + + public: + Parser(VirtualKeyMap* map, Tokenizer* tokenizer); + ~Parser(); + status_t parse(); + + private: + bool consumeFieldDelimiterAndSkipWhitespace(); + bool parseNextIntField(int32_t* outValue); + }; + + Vector mVirtualKeys; + + VirtualKeyMap(); +}; + +} // namespace android + +#endif // _LIBINPUT_KEY_CHARACTER_MAP_H diff --git a/phonelibs/android_frameworks_native/include/media/drm/DrmAPI.h b/phonelibs/android_frameworks_native/include/media/drm/DrmAPI.h new file mode 100644 index 00000000000000..272881b9f50f55 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/drm/DrmAPI.h @@ -0,0 +1,419 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DRM_API_H_ +#define DRM_API_H_ + +#include +#include +#include +#include +#include +#include +#include + +// Loadable DrmEngine shared libraries should define the entry points +// createDrmFactory and createCryptoFactory as shown below: +// +// extern "C" { +// extern android::DrmFactory *createDrmFactory(); +// extern android::CryptoFactory *createCryptoFactory(); +// } + +namespace android { + + class DrmPlugin; + class DrmPluginListener; + + // DRMs are implemented in DrmEngine plugins, which are dynamically + // loadable shared libraries that implement the entry points + // createDrmFactory and createCryptoFactory. createDrmFactory + // constructs and returns an instance of a DrmFactory object. Similarly, + // createCryptoFactory creates an instance of a CryptoFactory object. + // When a MediaCrypto or MediaDrm object needs to be constructed, all + // available DrmEngines present in the plugins directory on the device + // are scanned for a matching DrmEngine that can support the crypto + // scheme. When a match is found, the DrmEngine's createCryptoPlugin and + // createDrmPlugin methods are used to create CryptoPlugin or + // DrmPlugin instances to support that DRM scheme. + + class DrmFactory { + public: + DrmFactory() {} + virtual ~DrmFactory() {} + + // DrmFactory::isCryptoSchemeSupported can be called to determine + // if the plugin factory is able to construct plugins that support a + // given crypto scheme, which is specified by a UUID. + virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) = 0; + + // DrmFactory::isContentTypeSupported can be called to determine + // if the plugin factory is able to construct plugins that support a + // given media container format specified by mimeType + virtual bool isContentTypeSupported(const String8 &mimeType) = 0; + + // Construct a DrmPlugin for the crypto scheme specified by UUID. + virtual status_t createDrmPlugin( + const uint8_t uuid[16], DrmPlugin **plugin) = 0; + + private: + DrmFactory(const DrmFactory &); + DrmFactory &operator=(const DrmFactory &); + }; + + class DrmPlugin { + public: + enum EventType { + kDrmPluginEventProvisionRequired = 1, + kDrmPluginEventKeyNeeded, + kDrmPluginEventKeyExpired, + kDrmPluginEventVendorDefined, + kDrmPluginEventSessionReclaimed, + kDrmPluginEventExpirationUpdate, + kDrmPluginEventKeysChange, + }; + + // Drm keys can be for offline content or for online streaming. + // Offline keys are persisted on the device and may be used when the device + // is disconnected from the network. The Release type is used to request + // that offline keys be no longer restricted to offline use. + enum KeyType { + kKeyType_Offline, + kKeyType_Streaming, + kKeyType_Release + }; + + // Enumerate KeyRequestTypes to allow an app to determine the + // type of a key request returned from getKeyRequest. + enum KeyRequestType { + kKeyRequestType_Unknown, + kKeyRequestType_Initial, + kKeyRequestType_Renewal, + kKeyRequestType_Release + }; + + // Enumerate KeyStatusTypes which indicate the state of a key + enum KeyStatusType + { + kKeyStatusType_Usable, + kKeyStatusType_Expired, + kKeyStatusType_OutputNotAllowed, + kKeyStatusType_StatusPending, + kKeyStatusType_InternalError + }; + + // Used by sendKeysChange to report the usability status of each + // key to the app. + struct KeyStatus + { + Vector mKeyId; + KeyStatusType mType; + }; + + DrmPlugin() {} + virtual ~DrmPlugin() {} + + // Open a new session with the DrmPlugin object. A session ID is returned + // in the sessionId parameter. + virtual status_t openSession(Vector &sessionId) = 0; + + // Close a session on the DrmPlugin object. + virtual status_t closeSession(Vector const &sessionId) = 0; + + // A key request/response exchange occurs between the app and a License + // Server to obtain the keys required to decrypt the content. getKeyRequest() + // is used to obtain an opaque key request blob that is delivered to the + // license server. + // + // The scope parameter may be a sessionId or a keySetId, depending on the + // specified keyType. When the keyType is kKeyType_Offline or + // kKeyType_Streaming, scope should be set to the sessionId the keys will be + // provided to. When the keyType is kKeyType_Release, scope should be set to + // the keySetId of the keys being released. Releasing keys from a device + // invalidates them for all sessions. + // + // The init data passed to getKeyRequest is container-specific and its + // meaning is interpreted based on the mime type provided in the mimeType + // parameter to getKeyRequest. It could contain, for example, the content + // ID, key ID or other data obtained from the content metadata that is required + // in generating the key request. Init may be null when keyType is + // kKeyType_Release. + // + // mimeType identifies the mime type of the content + // + // keyType specifies if the keys are to be used for streaming or offline content + // + // optionalParameters are included in the key request message to allow a + // client application to provide additional message parameters to the server. + // + // If successful, the opaque key request blob is returned to the caller. + virtual status_t + getKeyRequest(Vector const &scope, + Vector const &initData, + String8 const &mimeType, KeyType keyType, + KeyedVector const &optionalParameters, + Vector &request, String8 &defaultUrl, + KeyRequestType *keyRequestType) = 0; + + // + // After a key response is received by the app, it is provided to the + // Drm plugin using provideKeyResponse. + // + // scope may be a sessionId or a keySetId depending on the type of the + // response. Scope should be set to the sessionId when the response is + // for either streaming or offline key requests. Scope should be set to the + // keySetId when the response is for a release request. + // + // When the response is for an offline key request, a keySetId is returned + // in the keySetId vector parameter that can be used to later restore the + // keys to a new session with the method restoreKeys. When the response is + // for a streaming or release request, no keySetId is returned. + // + virtual status_t provideKeyResponse(Vector const &scope, + Vector const &response, + Vector &keySetId) = 0; + + // Remove the current keys from a session + virtual status_t removeKeys(Vector const &sessionId) = 0; + + // Restore persisted offline keys into a new session. keySetId identifies + // the keys to load, obtained from a prior call to provideKeyResponse(). + virtual status_t restoreKeys(Vector const &sessionId, + Vector const &keySetId) = 0; + + // Request an informative description of the license for the session. The status + // is in the form of {name, value} pairs. Since DRM license policies vary by + // vendor, the specific status field names are determined by each DRM vendor. + // Refer to your DRM provider documentation for definitions of the field names + // for a particular DrmEngine. + virtual status_t + queryKeyStatus(Vector const &sessionId, + KeyedVector &infoMap) const = 0; + + // A provision request/response exchange occurs between the app and a + // provisioning server to retrieve a device certificate. getProvisionRequest + // is used to obtain an opaque key request blob that is delivered to the + // provisioning server. + // + // If successful, the opaque provision request blob is returned to the caller. + virtual status_t getProvisionRequest(String8 const &cert_type, + String8 const &cert_authority, + Vector &request, + String8 &defaultUrl) = 0; + + // After a provision response is received by the app, it is provided to the + // Drm plugin using provideProvisionResponse. + virtual status_t provideProvisionResponse(Vector const &response, + Vector &certificate, + Vector &wrapped_key) = 0; + + // Remove device provisioning. + virtual status_t unprovisionDevice() = 0; + + // A means of enforcing the contractual requirement for a concurrent stream + // limit per subscriber across devices is provided via SecureStop. SecureStop + // is a means of securely monitoring the lifetime of sessions. Since playback + // on a device can be interrupted due to reboot, power failure, etc. a means + // of persisting the lifetime information on the device is needed. + // + // A signed version of the sessionID is written to persistent storage on the + // device when each MediaCrypto object is created. The sessionID is signed by + // the device private key to prevent tampering. + // + // In the normal case, playback will be completed, the session destroyed and + // the Secure Stops will be queried. The App queries secure stops and forwards + // the secure stop message to the server which verifies the signature and + // notifies the server side database that the session destruction has been + // confirmed. The persisted record on the client is only removed after positive + // confirmation that the server received the message using releaseSecureStops(). + virtual status_t getSecureStops(List > &secureStops) = 0; + virtual status_t getSecureStop(Vector const &ssid, Vector &secureStop) = 0; + virtual status_t releaseSecureStops(Vector const &ssRelease) = 0; + virtual status_t releaseAllSecureStops() = 0; + + // Read a property value given the device property string. There are a few forms + // of property access methods, depending on the data type returned. + // Since DRM plugin properties may vary, additional field names may be defined + // by each DRM vendor. Refer to your DRM provider documentation for definitions + // of its additional field names. + // + // Standard values are: + // "vendor" [string] identifies the maker of the plugin + // "version" [string] identifies the version of the plugin + // "description" [string] describes the plugin + // 'deviceUniqueId' [byte array] The device unique identifier is established + // during device provisioning and provides a means of uniquely identifying + // each device. + virtual status_t getPropertyString(String8 const &name, String8 &value ) const = 0; + virtual status_t getPropertyByteArray(String8 const &name, + Vector &value ) const = 0; + + // Write a property value given the device property string. There are a few forms + // of property setting methods, depending on the data type. + // Since DRM plugin properties may vary, additional field names may be defined + // by each DRM vendor. Refer to your DRM provider documentation for definitions + // of its field names. + virtual status_t setPropertyString(String8 const &name, + String8 const &value ) = 0; + virtual status_t setPropertyByteArray(String8 const &name, + Vector const &value ) = 0; + + // The following methods implement operations on a CryptoSession to support + // encrypt, decrypt, sign verify operations on operator-provided + // session keys. + + // + // The algorithm string conforms to JCA Standard Names for Cipher + // Transforms and is case insensitive. For example "AES/CBC/PKCS5Padding". + // + // Return OK if the algorithm is supported, otherwise return BAD_VALUE + // + virtual status_t setCipherAlgorithm(Vector const &sessionId, + String8 const &algorithm) = 0; + + // + // The algorithm string conforms to JCA Standard Names for Mac + // Algorithms and is case insensitive. For example "HmacSHA256". + // + // Return OK if the algorithm is supported, otherwise return BAD_VALUE + // + virtual status_t setMacAlgorithm(Vector const &sessionId, + String8 const &algorithm) = 0; + + // Encrypt the provided input buffer with the cipher algorithm + // specified by setCipherAlgorithm and the key selected by keyId, + // and return the encrypted data. + virtual status_t encrypt(Vector const &sessionId, + Vector const &keyId, + Vector const &input, + Vector const &iv, + Vector &output) = 0; + + // Decrypt the provided input buffer with the cipher algorithm + // specified by setCipherAlgorithm and the key selected by keyId, + // and return the decrypted data. + virtual status_t decrypt(Vector const &sessionId, + Vector const &keyId, + Vector const &input, + Vector const &iv, + Vector &output) = 0; + + // Compute a signature on the provided message using the mac algorithm + // specified by setMacAlgorithm and the key selected by keyId, + // and return the signature. + virtual status_t sign(Vector const &sessionId, + Vector const &keyId, + Vector const &message, + Vector &signature) = 0; + + // Compute a signature on the provided message using the mac algorithm + // specified by setMacAlgorithm and the key selected by keyId, + // and compare with the expected result. Set result to true or + // false depending on the outcome. + virtual status_t verify(Vector const &sessionId, + Vector const &keyId, + Vector const &message, + Vector const &signature, + bool &match) = 0; + + + // Compute an RSA signature on the provided message using the algorithm + // specified by algorithm. + virtual status_t signRSA(Vector const &sessionId, + String8 const &algorithm, + Vector const &message, + Vector const &wrapped_key, + Vector &signature) = 0; + + + status_t setListener(const sp& listener) { + Mutex::Autolock lock(mEventLock); + mListener = listener; + return OK; + } + + protected: + // Plugins call these methods to deliver events to the java app + void sendEvent(EventType eventType, int extra, + Vector const *sessionId, + Vector const *data); + + void sendExpirationUpdate(Vector const *sessionId, + int64_t expiryTimeInMS); + + void sendKeysChange(Vector const *sessionId, + Vector const *keyStatusList, + bool hasNewUsableKey); + + private: + Mutex mEventLock; + sp mListener; + + DISALLOW_EVIL_CONSTRUCTORS(DrmPlugin); + }; + + class DrmPluginListener: virtual public RefBase + { + public: + virtual void sendEvent(DrmPlugin::EventType eventType, int extra, + Vector const *sessionId, + Vector const *data) = 0; + + virtual void sendExpirationUpdate(Vector const *sessionId, + int64_t expiryTimeInMS) = 0; + + virtual void sendKeysChange(Vector const *sessionId, + Vector const *keyStatusList, + bool hasNewUsableKey) = 0; + }; + + inline void DrmPlugin::sendEvent(EventType eventType, int extra, + Vector const *sessionId, + Vector const *data) { + mEventLock.lock(); + sp listener = mListener; + mEventLock.unlock(); + + if (listener != NULL) { + listener->sendEvent(eventType, extra, sessionId, data); + } + } + + inline void DrmPlugin::sendExpirationUpdate(Vector const *sessionId, + int64_t expiryTimeInMS) { + mEventLock.lock(); + sp listener = mListener; + mEventLock.unlock(); + + if (listener != NULL) { + listener->sendExpirationUpdate(sessionId, expiryTimeInMS); + } + } + + inline void DrmPlugin::sendKeysChange(Vector const *sessionId, + Vector const *keyStatusList, + bool hasNewUsableKey) { + mEventLock.lock(); + sp listener = mListener; + mEventLock.unlock(); + + if (listener != NULL) { + listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey); + } + } +} // namespace android + +#endif // DRM_API_H_ diff --git a/phonelibs/android_frameworks_native/include/media/editor/II420ColorConverter.h b/phonelibs/android_frameworks_native/include/media/editor/II420ColorConverter.h new file mode 100644 index 00000000000000..33af61ff9a5276 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/editor/II420ColorConverter.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef II420_COLOR_CONVERTER_H + +#define II420_COLOR_CONVERTER_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct II420ColorConverter { + + /* + * getDecoderOutputFormat + * Returns the color format (OMX_COLOR_FORMATTYPE) of the decoder output. + * If it is I420 (OMX_COLOR_FormatYUV420Planar), no conversion is needed, + * and convertDecoderOutputToI420() can be a no-op. + */ + int (*getDecoderOutputFormat)(); + + /* + * convertDecoderOutputToI420 + * @Desc Converts from the decoder output format to I420 format. + * @note Caller (e.g. VideoEditor) owns the buffers + * @param decoderBits (IN) Pointer to the buffer contains decoder output + * @param decoderWidth (IN) Buffer width, as reported by the decoder + * metadata (kKeyWidth) + * @param decoderHeight (IN) Buffer height, as reported by the decoder + * metadata (kKeyHeight) + * @param decoderRect (IN) The rectangle of the actual frame, as + * reported by decoder metadata (kKeyCropRect) + * @param dstBits (OUT) Pointer to the output I420 buffer + * @return -1 Any error + * @return 0 No Error + */ + int (*convertDecoderOutputToI420)( + void* decoderBits, int decoderWidth, int decoderHeight, + ARect decoderRect, void* dstBits); + + /* + * getEncoderIntputFormat + * Returns the color format (OMX_COLOR_FORMATTYPE) of the encoder input. + * If it is I420 (OMX_COLOR_FormatYUV420Planar), no conversion is needed, + * and convertI420ToEncoderInput() and getEncoderInputBufferInfo() can + * be no-ops. + */ + int (*getEncoderInputFormat)(); + + /* convertI420ToEncoderInput + * @Desc This function converts from I420 to the encoder input format + * @note Caller (e.g. VideoEditor) owns the buffers + * @param srcBits (IN) Pointer to the input I420 buffer + * @param srcWidth (IN) Width of the I420 frame + * @param srcHeight (IN) Height of the I420 frame + * @param encoderWidth (IN) Encoder buffer width, as calculated by + * getEncoderBufferInfo() + * @param encoderHeight (IN) Encoder buffer height, as calculated by + * getEncoderBufferInfo() + * @param encoderRect (IN) Rect coordinates of the actual frame inside + * the encoder buffer, as calculated by + * getEncoderBufferInfo(). + * @param encoderBits (OUT) Pointer to the output buffer. The size of + * this buffer is calculated by + * getEncoderBufferInfo() + * @return -1 Any error + * @return 0 No Error + */ + int (*convertI420ToEncoderInput)( + void* srcBits, int srcWidth, int srcHeight, + int encoderWidth, int encoderHeight, ARect encoderRect, + void* encoderBits); + + /* getEncoderInputBufferInfo + * @Desc This function returns metadata for the encoder input buffer + * based on the actual I420 frame width and height. + * @note This API should be be used to obtain the necessary information + * before calling convertI420ToEncoderInput(). + * VideoEditor knows only the width and height of the I420 buffer, + * but it also needs know the width, height, and size of the + * encoder input buffer. The encoder input buffer width and height + * are used to set the metadata for the encoder. + * @param srcWidth (IN) Width of the I420 frame + * @param srcHeight (IN) Height of the I420 frame + * @param encoderWidth (OUT) Encoder buffer width needed + * @param encoderHeight (OUT) Encoder buffer height needed + * @param encoderRect (OUT) Rect coordinates of the actual frame inside + * the encoder buffer + * @param encoderBufferSize (OUT) The size of the buffer that need to be + * allocated by the caller before invoking + * convertI420ToEncoderInput(). + * @return -1 Any error + * @return 0 No Error + */ + int (*getEncoderInputBufferInfo)( + int srcWidth, int srcHeight, + int* encoderWidth, int* encoderHeight, + ARect* encoderRect, int* encoderBufferSize); + +} II420ColorConverter; + +/* The only function that the shared library needs to expose: It fills the + function pointers in II420ColorConverter */ +void getI420ColorConverter(II420ColorConverter *converter); + +#if defined(__cplusplus) +} +#endif + +#endif // II420_COLOR_CONVERTER_H diff --git a/phonelibs/android_frameworks_native/include/media/hardware/CryptoAPI.h b/phonelibs/android_frameworks_native/include/media/hardware/CryptoAPI.h new file mode 100644 index 00000000000000..3e3257f9568768 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/hardware/CryptoAPI.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#ifndef CRYPTO_API_H_ + +#define CRYPTO_API_H_ + +namespace android { + +struct AString; +struct CryptoPlugin; + +struct CryptoFactory { + CryptoFactory() {} + virtual ~CryptoFactory() {} + + virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) const = 0; + + virtual status_t createPlugin( + const uint8_t uuid[16], const void *data, size_t size, + CryptoPlugin **plugin) = 0; + +private: + CryptoFactory(const CryptoFactory &); + CryptoFactory &operator=(const CryptoFactory &); +}; + +struct CryptoPlugin { + enum Mode { + kMode_Unencrypted = 0, + kMode_AES_CTR = 1, + + // Neither key nor iv are being used in this mode. + // Each subsample is encrypted w/ an iv of all zeroes. + kMode_AES_WV = 2, // FIX constant + }; + + struct SubSample { + uint32_t mNumBytesOfClearData; + uint32_t mNumBytesOfEncryptedData; + }; + + CryptoPlugin() {} + virtual ~CryptoPlugin() {} + + // If this method returns false, a non-secure decoder will be used to + // decode the data after decryption. The decrypt API below will have + // to support insecure decryption of the data (secure = false) for + // media data of the given mime type. + virtual bool requiresSecureDecoderComponent(const char *mime) const = 0; + + // To implement resolution constraints, the crypto plugin needs to know + // the resolution of the video being decrypted. The media player should + // call this method when the resolution is determined and any time it + // is subsequently changed. + + virtual void notifyResolution(uint32_t /* width */, uint32_t /* height */) {} + + // A MediaDrm session may be associated with a MediaCrypto session. The + // associated MediaDrm session is used to load decryption keys + // into the crypto/drm plugin. The keys are then referenced by key-id + // in the 'key' parameter to the decrypt() method. + // Should return NO_ERROR on success, ERROR_DRM_SESSION_NOT_OPENED if + // the session is not opened and a code from MediaErrors.h otherwise. + virtual status_t setMediaDrmSession(const Vector & /*sessionId */) { + return ERROR_UNSUPPORTED; + } + + // If the error returned falls into the range + // ERROR_DRM_VENDOR_MIN..ERROR_DRM_VENDOR_MAX, errorDetailMsg should be + // filled in with an appropriate string. + // At the java level these special errors will then trigger a + // MediaCodec.CryptoException that gives clients access to both + // the error code and the errorDetailMsg. + // Returns a non-negative result to indicate the number of bytes written + // to the dstPtr, or a negative result to indicate an error. + virtual ssize_t decrypt( + bool secure, + const uint8_t key[16], + const uint8_t iv[16], + Mode mode, + const void *srcPtr, + const SubSample *subSamples, size_t numSubSamples, + void *dstPtr, + AString *errorDetailMsg) = 0; + +private: + CryptoPlugin(const CryptoPlugin &); + CryptoPlugin &operator=(const CryptoPlugin &); +}; + +} // namespace android + +extern "C" { + extern android::CryptoFactory *createCryptoFactory(); +} + +#endif // CRYPTO_API_H_ diff --git a/phonelibs/android_frameworks_native/include/media/hardware/HDCPAPI.h b/phonelibs/android_frameworks_native/include/media/hardware/HDCPAPI.h new file mode 100644 index 00000000000000..3a53e9fc9084a9 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/hardware/HDCPAPI.h @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HDCP_API_H_ + +#define HDCP_API_H_ + +#include +#include + +namespace android { + +// Two different kinds of modules are covered under the same HDCPModule +// structure below, a module either implements decryption or encryption. +struct HDCPModule { + typedef void (*ObserverFunc)(void *cookie, int msg, int ext1, int ext2); + + // The msg argument in calls to the observer notification function. + enum { + // Sent in response to a call to "HDCPModule::initAsync" once + // initialization has either been successfully completed, + // i.e. the HDCP session is now fully setup (AKE, Locality Check, + // SKE and any authentication with repeaters completed) or failed. + // ext1 should be a suitable error code (status_t), ext2 is + // unused for ENCRYPTION and in the case of HDCP_INITIALIZATION_COMPLETE + // holds the local TCP port the module is listening on. + HDCP_INITIALIZATION_COMPLETE, + HDCP_INITIALIZATION_FAILED, + + // Sent upon completion of a call to "HDCPModule::shutdownAsync". + // ext1 should be a suitable error code, ext2 is unused. + HDCP_SHUTDOWN_COMPLETE, + HDCP_SHUTDOWN_FAILED, + + HDCP_UNAUTHENTICATED_CONNECTION, + HDCP_UNAUTHORIZED_CONNECTION, + HDCP_REVOKED_CONNECTION, + HDCP_TOPOLOGY_EXECEEDED, + HDCP_UNKNOWN_ERROR, + + // DECRYPTION only: Indicates that a client has successfully connected, + // a secure session established and the module is ready to accept + // future calls to "decrypt". + HDCP_SESSION_ESTABLISHED, + }; + + // HDCPModule capability bit masks + enum { + // HDCP_CAPS_ENCRYPT: mandatory, meaning the HDCP module can encrypt + // from an input byte-array buffer to an output byte-array buffer + HDCP_CAPS_ENCRYPT = (1 << 0), + // HDCP_CAPS_ENCRYPT_NATIVE: the HDCP module supports encryption from + // a native buffer to an output byte-array buffer. The format of the + // input native buffer is specific to vendor's encoder implementation. + // It is the same format as that used by the encoder when + // "storeMetaDataInBuffers" extension is enabled on its output port. + HDCP_CAPS_ENCRYPT_NATIVE = (1 << 1), + }; + + // Module can call the notification function to signal completion/failure + // of asynchronous operations (such as initialization) or out of band + // events. + HDCPModule(void *cookie, ObserverFunc observerNotify) {}; + + virtual ~HDCPModule() {}; + + // ENCRYPTION: Request to setup an HDCP session with the host specified + // by addr and listening on the specified port. + // DECRYPTION: Request to setup an HDCP session, addr is the interface + // address the module should bind its socket to. port will be 0. + // The module will pick the port to listen on itself and report its choice + // in the "ext2" argument of the HDCP_INITIALIZATION_COMPLETE callback. + virtual status_t initAsync(const char *addr, unsigned port) = 0; + + // Request to shutdown the active HDCP session. + virtual status_t shutdownAsync() = 0; + + // Returns the capability bitmask of this HDCP session. + virtual uint32_t getCaps() { + return HDCP_CAPS_ENCRYPT; + } + + // ENCRYPTION only: + // Encrypt data according to the HDCP spec. "size" bytes of data are + // available at "inData" (virtual address), "size" may not be a multiple + // of 128 bits (16 bytes). An equal number of encrypted bytes should be + // written to the buffer at "outData" (virtual address). + // This operation is to be synchronous, i.e. this call does not return + // until outData contains size bytes of encrypted data. + // streamCTR will be assigned by the caller (to 0 for the first PES stream, + // 1 for the second and so on) + // inputCTR _will_be_maintained_by_the_callee_ for each PES stream. + virtual status_t encrypt( + const void *inData, size_t size, uint32_t streamCTR, + uint64_t *outInputCTR, void *outData) { + return INVALID_OPERATION; + } + + // Encrypt data according to the HDCP spec. "size" bytes of data starting + // at location "offset" are available in "buffer" (buffer handle). "size" + // may not be a multiple of 128 bits (16 bytes). An equal number of + // encrypted bytes should be written to the buffer at "outData" (virtual + // address). This operation is to be synchronous, i.e. this call does not + // return until outData contains size bytes of encrypted data. + // streamCTR will be assigned by the caller (to 0 for the first PES stream, + // 1 for the second and so on) + // inputCTR _will_be_maintained_by_the_callee_ for each PES stream. + virtual status_t encryptNative( + buffer_handle_t buffer, size_t offset, size_t size, + uint32_t streamCTR, uint64_t *outInputCTR, void *outData) { + return INVALID_OPERATION; + } + // DECRYPTION only: + // Decrypt data according to the HDCP spec. + // "size" bytes of encrypted data are available at "inData" + // (virtual address), "size" may not be a multiple of 128 bits (16 bytes). + // An equal number of decrypted bytes should be written to the buffer + // at "outData" (virtual address). + // This operation is to be synchronous, i.e. this call does not return + // until outData contains size bytes of decrypted data. + // Both streamCTR and inputCTR will be provided by the caller. + virtual status_t decrypt( + const void *inData, size_t size, + uint32_t streamCTR, uint64_t inputCTR, + void *outData) { + return INVALID_OPERATION; + } + +private: + HDCPModule(const HDCPModule &); + HDCPModule &operator=(const HDCPModule &); +}; + +} // namespace android + +// A shared library exporting the following methods should be included to +// support HDCP functionality. The shared library must be called +// "libstagefright_hdcp.so", it will be dynamically loaded into the +// mediaserver process. +extern "C" { + // Create a module for ENCRYPTION. + extern android::HDCPModule *createHDCPModule( + void *cookie, android::HDCPModule::ObserverFunc); + + // Create a module for DECRYPTION. + extern android::HDCPModule *createHDCPModuleForDecryption( + void *cookie, android::HDCPModule::ObserverFunc); +} + +#endif // HDCP_API_H_ + diff --git a/phonelibs/android_frameworks_native/include/media/hardware/HardwareAPI.h b/phonelibs/android_frameworks_native/include/media/hardware/HardwareAPI.h new file mode 100644 index 00000000000000..1008c22d73ba0b --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/hardware/HardwareAPI.h @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HARDWARE_API_H_ + +#define HARDWARE_API_H_ + +#include +#include +#include +#include + +#include + +namespace android { + +// A pointer to this struct is passed to the OMX_SetParameter when the extension +// index for the 'OMX.google.android.index.enableAndroidNativeBuffers' extension +// is given. +// +// When Android native buffer use is disabled for a port (the default state), +// the OMX node should operate as normal, and expect UseBuffer calls to set its +// buffers. This is the mode that will be used when CPU access to the buffer is +// required. +// +// When Android native buffer use has been enabled for a given port, the video +// color format for the port is to be interpreted as an Android pixel format +// rather than an OMX color format. Enabling Android native buffers may also +// change how the component receives the native buffers. If store-metadata-mode +// is enabled on the port, the component will receive the buffers as specified +// in the section below. Otherwise, unless the node supports the +// 'OMX.google.android.index.useAndroidNativeBuffer2' extension, it should +// expect to receive UseAndroidNativeBuffer calls (via OMX_SetParameter) rather +// than UseBuffer calls for that port. +struct EnableAndroidNativeBuffersParams { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL enable; +}; + +// A pointer to this struct is passed to OMX_SetParameter() when the extension index +// "OMX.google.android.index.storeMetaDataInBuffers" or +// "OMX.google.android.index.storeANWBufferInMetadata" is given. +// +// When meta data is stored in the video buffers passed between OMX clients +// and OMX components, interpretation of the buffer data is up to the +// buffer receiver, and the data may or may not be the actual video data, but +// some information helpful for the receiver to locate the actual data. +// The buffer receiver thus needs to know how to interpret what is stored +// in these buffers, with mechanisms pre-determined externally. How to +// interpret the meta data is outside of the scope of this parameter. +// +// Currently, this is used to pass meta data from video source (camera component, for instance) to +// video encoder to avoid memcpying of input video frame data, as well as to pass dynamic output +// buffer to video decoder. To do this, bStoreMetaData is set to OMX_TRUE. +// +// If bStoreMetaData is set to false, real YUV frame data will be stored in input buffers, and +// the output buffers contain either real YUV frame data, or are themselves native handles as +// directed by enable/use-android-native-buffer parameter settings. +// In addition, if no OMX_SetParameter() call is made on a port with the corresponding extension +// index, the component should not assume that the client is not using metadata mode for the port. +// +// If the component supports this using the "OMX.google.android.index.storeANWBufferInMetadata" +// extension and bStoreMetaData is set to OMX_TRUE, data is passed using the VideoNativeMetadata +// layout as defined below. Each buffer will be accompanied by a fence. The fence must signal +// before the buffer can be used (e.g. read from or written into). When returning such buffer to +// the client, component must provide a new fence that must signal before the returned buffer can +// be used (e.g. read from or written into). The component owns the incoming fenceFd, and must close +// it when fence has signaled. The client will own and close the returned fence file descriptor. +// +// If the component supports this using the "OMX.google.android.index.storeMetaDataInBuffers" +// extension and bStoreMetaData is set to OMX_TRUE, data is passed using VideoGrallocMetadata +// (the layout of which is the VideoGrallocMetadata defined below). Camera input can be also passed +// as "CameraSource", the layout of which is vendor dependent. +// +// Metadata buffers are registered with the component using UseBuffer calls, or can be allocated +// by the component for encoder-metadata-output buffers. +struct StoreMetaDataInBuffersParams { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bStoreMetaData; +}; + +// Meta data buffer layout used to transport output frames to the decoder for +// dynamic buffer handling. +struct VideoGrallocMetadata { + MetadataBufferType eType; // must be kMetadataBufferTypeGrallocSource +#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS + OMX_PTR pHandle; +#else + buffer_handle_t pHandle; +#endif +}; + +// Legacy name for VideoGrallocMetadata struct. +struct VideoDecoderOutputMetaData : public VideoGrallocMetadata {}; + +struct VideoNativeMetadata { + MetadataBufferType eType; // must be kMetadataBufferTypeANWBuffer +#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS + OMX_PTR pBuffer; +#else + struct ANativeWindowBuffer* pBuffer; +#endif + int nFenceFd; // -1 if unused +}; + +// A pointer to this struct is passed to OMX_SetParameter() when the extension +// index "OMX.google.android.index.prepareForAdaptivePlayback" is given. +// +// This method is used to signal a video decoder, that the user has requested +// seamless resolution change support (if bEnable is set to OMX_TRUE). +// nMaxFrameWidth and nMaxFrameHeight are the dimensions of the largest +// anticipated frames in the video. If bEnable is OMX_FALSE, no resolution +// change is expected, and the nMaxFrameWidth/Height fields are unused. +// +// If the decoder supports dynamic output buffers, it may ignore this +// request. Otherwise, it shall request resources in such a way so that it +// avoids full port-reconfiguration (due to output port-definition change) +// during resolution changes. +// +// DO NOT USE THIS STRUCTURE AS IT WILL BE REMOVED. INSTEAD, IMPLEMENT +// METADATA SUPPORT FOR VIDEO DECODERS. +struct PrepareForAdaptivePlaybackParams { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnable; + OMX_U32 nMaxFrameWidth; + OMX_U32 nMaxFrameHeight; +}; + +// A pointer to this struct is passed to OMX_SetParameter when the extension +// index for the 'OMX.google.android.index.useAndroidNativeBuffer' extension is +// given. This call will only be performed if a prior call was made with the +// 'OMX.google.android.index.enableAndroidNativeBuffers' extension index, +// enabling use of Android native buffers. +struct UseAndroidNativeBufferParams { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_PTR pAppPrivate; + OMX_BUFFERHEADERTYPE **bufferHeader; + const sp& nativeBuffer; +}; + +// A pointer to this struct is passed to OMX_GetParameter when the extension +// index for the 'OMX.google.android.index.getAndroidNativeBufferUsage' +// extension is given. The usage bits returned from this query will be used to +// allocate the Gralloc buffers that get passed to the useAndroidNativeBuffer +// command. +struct GetAndroidNativeBufferUsageParams { + OMX_U32 nSize; // IN + OMX_VERSIONTYPE nVersion; // IN + OMX_U32 nPortIndex; // IN + OMX_U32 nUsage; // OUT +}; + +// An enum OMX_COLOR_FormatAndroidOpaque to indicate an opaque colorformat +// is declared in media/stagefright/openmax/OMX_IVCommon.h +// This will inform the encoder that the actual +// colorformat will be relayed by the GRalloc Buffers. +// OMX_COLOR_FormatAndroidOpaque = 0x7F000001, + +// A pointer to this struct is passed to OMX_SetParameter when the extension +// index for the 'OMX.google.android.index.prependSPSPPSToIDRFrames' extension +// is given. +// A successful result indicates that future IDR frames will be prefixed by +// SPS/PPS. +struct PrependSPSPPSToIDRFramesParams { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bEnable; +}; + +// Structure describing a media image (frame) +// Currently only supporting YUV +struct MediaImage { + enum Type { + MEDIA_IMAGE_TYPE_UNKNOWN = 0, + MEDIA_IMAGE_TYPE_YUV, + }; + + enum PlaneIndex { + Y = 0, + U, + V, + MAX_NUM_PLANES + }; + + Type mType; + uint32_t mNumPlanes; // number of planes + uint32_t mWidth; // width of largest plane (unpadded, as in nFrameWidth) + uint32_t mHeight; // height of largest plane (unpadded, as in nFrameHeight) + uint32_t mBitDepth; // useable bit depth + struct PlaneInfo { + uint32_t mOffset; // offset of first pixel of the plane in bytes + // from buffer offset + uint32_t mColInc; // column increment in bytes + uint32_t mRowInc; // row increment in bytes + uint32_t mHorizSubsampling; // subsampling compared to the largest plane + uint32_t mVertSubsampling; // subsampling compared to the largest plane + }; + PlaneInfo mPlane[MAX_NUM_PLANES]; +}; + +// A pointer to this struct is passed to OMX_GetParameter when the extension +// index for the 'OMX.google.android.index.describeColorFormat' +// extension is given. This method can be called from any component state +// other than invalid. The color-format, frame width/height, and stride/ +// slice-height parameters are ones that are associated with a raw video +// port (input or output), but the stride/slice height parameters may be +// incorrect. bUsingNativeBuffers is OMX_TRUE if native android buffers will +// be used (while specifying this color format). +// +// The component shall fill out the MediaImage structure that +// corresponds to the described raw video format, and the potentially corrected +// stride and slice-height info. +// +// The behavior is slightly different if bUsingNativeBuffers is OMX_TRUE, +// though most implementations can ignore this difference. When using native buffers, +// the component may change the configured color format to an optimized format. +// Additionally, when allocating these buffers for flexible usecase, the framework +// will set the SW_READ/WRITE_OFTEN usage flags. In this case (if bUsingNativeBuffers +// is OMX_TRUE), the component shall fill out the MediaImage information for the +// scenario when these SW-readable/writable buffers are locked using gralloc_lock. +// Note, that these buffers may also be locked using gralloc_lock_ycbcr, which must +// be supported for vendor-specific formats. +// +// For non-YUV packed planar/semiplanar image formats, or if bUsingNativeBuffers +// is OMX_TRUE and the component does not support this color format with native +// buffers, the component shall set mNumPlanes to 0, and mType to MEDIA_IMAGE_TYPE_UNKNOWN. +struct DescribeColorFormatParams { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + // input: parameters from OMX_VIDEO_PORTDEFINITIONTYPE + OMX_COLOR_FORMATTYPE eColorFormat; + OMX_U32 nFrameWidth; + OMX_U32 nFrameHeight; + OMX_U32 nStride; + OMX_U32 nSliceHeight; + OMX_BOOL bUsingNativeBuffers; + + // output: fill out the MediaImage fields + MediaImage sMediaImage; +}; + +// A pointer to this struct is passed to OMX_SetParameter or OMX_GetParameter +// when the extension index for the +// 'OMX.google.android.index.configureVideoTunnelMode' extension is given. +// If the extension is supported then tunneled playback mode should be supported +// by the codec. If bTunneled is set to OMX_TRUE then the video decoder should +// operate in "tunneled" mode and output its decoded frames directly to the +// sink. In this case nAudioHwSync is the HW SYNC ID of the audio HAL Output +// stream to sync the video with. If bTunneled is set to OMX_FALSE, "tunneled" +// mode should be disabled and nAudioHwSync should be ignored. +// OMX_GetParameter is used to query tunneling configuration. bTunneled should +// return whether decoder is operating in tunneled mode, and if it is, +// pSidebandWindow should contain the codec allocated sideband window handle. +struct ConfigureVideoTunnelModeParams { + OMX_U32 nSize; // IN + OMX_VERSIONTYPE nVersion; // IN + OMX_U32 nPortIndex; // IN + OMX_BOOL bTunneled; // IN/OUT + OMX_U32 nAudioHwSync; // IN + OMX_PTR pSidebandWindow; // OUT +}; + +} // namespace android + +extern android::OMXPluginBase *createOMXPlugin(); + +#endif // HARDWARE_API_H_ diff --git a/phonelibs/android_frameworks_native/include/media/hardware/MetadataBufferType.h b/phonelibs/android_frameworks_native/include/media/hardware/MetadataBufferType.h new file mode 100644 index 00000000000000..b765203956589a --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/hardware/MetadataBufferType.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef METADATA_BUFFER_TYPE_H +#define METADATA_BUFFER_TYPE_H + +#ifdef __cplusplus +extern "C" { +namespace android { +#endif + +/* + * MetadataBufferType defines the type of the metadata buffers that + * can be passed to video encoder component for encoding, via Stagefright + * media recording framework. To see how to work with the metadata buffers + * in media recording framework, please consult HardwareAPI.h + * + * The creator of metadata buffers and video encoder share common knowledge + * on what is actually being stored in these metadata buffers, and + * how the information can be used by the video encoder component + * to locate the actual pixel data as the source input for video + * encoder, plus whatever other information that is necessary. Stagefright + * media recording framework does not need to know anything specific about the + * metadata buffers, except for receving each individual metadata buffer + * as the source input, making a copy of the metadata buffer, and passing the + * copy via OpenMAX API to the video encoder component. + * + * The creator of the metadata buffers must ensure that the first + * 4 bytes in every metadata buffer indicates its buffer type, + * and the rest of the metadata buffer contains the + * actual metadata information. When a video encoder component receives + * a metadata buffer, it uses the first 4 bytes in that buffer to find + * out the type of the metadata buffer, and takes action appropriate + * to that type of metadata buffers (for instance, locate the actual + * pixel data input and then encoding the input data to produce a + * compressed output buffer). + * + * The following shows the layout of a metadata buffer, + * where buffer type is a 4-byte field of MetadataBufferType, + * and the payload is the metadata information. + * + * -------------------------------------------------------------- + * | buffer type | payload | + * -------------------------------------------------------------- + * + */ +typedef enum { + + /* + * kMetadataBufferTypeCameraSource is used to indicate that + * the source of the metadata buffer is the camera component. + */ + kMetadataBufferTypeCameraSource = 0, + + /* + * kMetadataBufferTypeGrallocSource is used to indicate that + * the payload of the metadata buffers can be interpreted as + * a buffer_handle_t. + * So in this case,the metadata that the encoder receives + * will have a byte stream that consists of two parts: + * 1. First, there is an integer indicating that it is a GRAlloc + * source (kMetadataBufferTypeGrallocSource) + * 2. This is followed by the buffer_handle_t that is a handle to the + * GRalloc buffer. The encoder needs to interpret this GRalloc handle + * and encode the frames. + * -------------------------------------------------------------- + * | kMetadataBufferTypeGrallocSource | buffer_handle_t buffer | + * -------------------------------------------------------------- + * + * See the VideoGrallocMetadata structure. + */ + kMetadataBufferTypeGrallocSource = 1, + + /* + * kMetadataBufferTypeGraphicBuffer is used to indicate that + * the payload of the metadata buffers can be interpreted as + * an ANativeWindowBuffer, and that a fence is provided. + * + * In this case, the metadata will have a byte stream that consists of three parts: + * 1. First, there is an integer indicating that the metadata + * contains an ANativeWindowBuffer (kMetadataBufferTypeANWBuffer) + * 2. This is followed by the pointer to the ANativeWindowBuffer. + * Codec must not free this buffer as it does not actually own this buffer. + * 3. Finally, there is an integer containing a fence file descriptor. + * The codec must wait on the fence before encoding or decoding into this + * buffer. When the buffer is returned, codec must replace this file descriptor + * with a new fence, that will be waited on before the buffer is replaced + * (encoder) or read (decoder). + * --------------------------------- + * | kMetadataBufferTypeANWBuffer | + * --------------------------------- + * | ANativeWindowBuffer *buffer | + * --------------------------------- + * | int fenceFd | + * --------------------------------- + * + * See the VideoNativeMetadata structure. + */ + kMetadataBufferTypeANWBuffer = 2, + + /* This value is used by framework, but is never used inside a metadata buffer */ + kMetadataBufferTypeInvalid = -1, + + + // Add more here... + +} MetadataBufferType; + +#ifdef __cplusplus +} // namespace android +} +#endif + +#endif // METADATA_BUFFER_TYPE_H diff --git a/phonelibs/android_frameworks_native/include/media/hardware/OMXPluginBase.h b/phonelibs/android_frameworks_native/include/media/hardware/OMXPluginBase.h new file mode 100644 index 00000000000000..7bf414739b85dc --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/hardware/OMXPluginBase.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OMX_PLUGIN_BASE_H_ + +#define OMX_PLUGIN_BASE_H_ + +#include + +#include + +#include +#include + +namespace android { + +struct OMXPluginBase { + OMXPluginBase() {} + virtual ~OMXPluginBase() {} + + virtual OMX_ERRORTYPE makeComponentInstance( + const char *name, + const OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData, + OMX_COMPONENTTYPE **component) = 0; + + virtual OMX_ERRORTYPE destroyComponentInstance( + OMX_COMPONENTTYPE *component) = 0; + + virtual OMX_ERRORTYPE enumerateComponents( + OMX_STRING name, + size_t size, + OMX_U32 index) = 0; + + virtual OMX_ERRORTYPE getRolesOfComponent( + const char *name, + Vector *roles) = 0; + +private: + OMXPluginBase(const OMXPluginBase &); + OMXPluginBase &operator=(const OMXPluginBase &); +}; + +} // namespace android + +#endif // OMX_PLUGIN_BASE_H_ diff --git a/phonelibs/android_frameworks_native/include/media/openmax/OMX_AsString.h b/phonelibs/android_frameworks_native/include/media/openmax/OMX_AsString.h new file mode 100644 index 00000000000000..ae8430d856124a --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/openmax/OMX_AsString.h @@ -0,0 +1,947 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* NOTE: This file contains several sections for individual OMX include files. + Each section has its own include guard. This file should be included AFTER + the OMX include files. */ + +#ifdef OMX_Audio_h +/* asString definitions if media/openmax/OMX_Audio.h was included */ + +#ifndef AS_STRING_FOR_OMX_AUDIO_H +#define AS_STRING_FOR_OMX_AUDIO_H + +inline static const char *asString(OMX_AUDIO_CODINGTYPE i, const char *def = "??") { + switch (i) { + case OMX_AUDIO_CodingUnused: return "Unused"; // unused + case OMX_AUDIO_CodingAutoDetect: return "AutoDetect"; // unused + case OMX_AUDIO_CodingPCM: return "PCM"; + case OMX_AUDIO_CodingADPCM: return "ADPCM"; // unused + case OMX_AUDIO_CodingAMR: return "AMR"; + case OMX_AUDIO_CodingGSMFR: return "GSMFR"; + case OMX_AUDIO_CodingGSMEFR: return "GSMEFR"; // unused + case OMX_AUDIO_CodingGSMHR: return "GSMHR"; // unused + case OMX_AUDIO_CodingPDCFR: return "PDCFR"; // unused + case OMX_AUDIO_CodingPDCEFR: return "PDCEFR"; // unused + case OMX_AUDIO_CodingPDCHR: return "PDCHR"; // unused + case OMX_AUDIO_CodingTDMAFR: return "TDMAFR"; // unused + case OMX_AUDIO_CodingTDMAEFR: return "TDMAEFR"; // unused + case OMX_AUDIO_CodingQCELP8: return "QCELP8"; // unused + case OMX_AUDIO_CodingQCELP13: return "QCELP13"; // unused + case OMX_AUDIO_CodingEVRC: return "EVRC"; // unused + case OMX_AUDIO_CodingSMV: return "SMV"; // unused + case OMX_AUDIO_CodingG711: return "G711"; + case OMX_AUDIO_CodingG723: return "G723"; // unused + case OMX_AUDIO_CodingG726: return "G726"; // unused + case OMX_AUDIO_CodingG729: return "G729"; // unused + case OMX_AUDIO_CodingAAC: return "AAC"; + case OMX_AUDIO_CodingMP3: return "MP3"; + case OMX_AUDIO_CodingSBC: return "SBC"; // unused + case OMX_AUDIO_CodingVORBIS: return "VORBIS"; + case OMX_AUDIO_CodingWMA: return "WMA"; // unused + case OMX_AUDIO_CodingRA: return "RA"; // unused + case OMX_AUDIO_CodingMIDI: return "MIDI"; // unused + case OMX_AUDIO_CodingFLAC: return "FLAC"; + default: return def; + } +} + +inline static const char *asString(OMX_AUDIO_PCMMODETYPE i, const char *def = "??") { + switch (i) { + case OMX_AUDIO_PCMModeLinear: return "Linear"; + case OMX_AUDIO_PCMModeALaw: return "ALaw"; + case OMX_AUDIO_PCMModeMULaw: return "MULaw"; + default: return def; + } +} + +inline static const char *asString(OMX_AUDIO_CHANNELTYPE i, const char *def = "??") { + switch (i) { + case OMX_AUDIO_ChannelNone: return "None"; // unused + case OMX_AUDIO_ChannelLF: return "LF"; + case OMX_AUDIO_ChannelRF: return "RF"; + case OMX_AUDIO_ChannelCF: return "CF"; + case OMX_AUDIO_ChannelLS: return "LS"; + case OMX_AUDIO_ChannelRS: return "RS"; + case OMX_AUDIO_ChannelLFE: return "LFE"; + case OMX_AUDIO_ChannelCS: return "CS"; + case OMX_AUDIO_ChannelLR: return "LR"; + case OMX_AUDIO_ChannelRR: return "RR"; + default: return def; + } +} + +inline static const char *asString(OMX_AUDIO_CHANNELMODETYPE i, const char *def = "??") { + switch (i) { + case OMX_AUDIO_ChannelModeStereo: return "Stereo"; +// case OMX_AUDIO_ChannelModeJointStereo: return "JointStereo"; +// case OMX_AUDIO_ChannelModeDual: return "Dual"; + case OMX_AUDIO_ChannelModeMono: return "Mono"; + default: return def; + } +} + +inline static const char *asString(OMX_AUDIO_AACSTREAMFORMATTYPE i, const char *def = "??") { + switch (i) { +// case OMX_AUDIO_AACStreamFormatMP2ADTS: return "MP2ADTS"; + case OMX_AUDIO_AACStreamFormatMP4ADTS: return "MP4ADTS"; +// case OMX_AUDIO_AACStreamFormatMP4LOAS: return "MP4LOAS"; +// case OMX_AUDIO_AACStreamFormatMP4LATM: return "MP4LATM"; +// case OMX_AUDIO_AACStreamFormatADIF: return "ADIF"; + case OMX_AUDIO_AACStreamFormatMP4FF: return "MP4FF"; +// case OMX_AUDIO_AACStreamFormatRAW: return "RAW"; + default: return def; + } +} + +inline static const char *asString(OMX_AUDIO_AMRFRAMEFORMATTYPE i, const char *def = "??") { + switch (i) { +// case OMX_AUDIO_AMRFrameFormatConformance: return "Conformance"; +// case OMX_AUDIO_AMRFrameFormatIF1: return "IF1"; +// case OMX_AUDIO_AMRFrameFormatIF2: return "IF2"; + case OMX_AUDIO_AMRFrameFormatFSF: return "FSF"; +// case OMX_AUDIO_AMRFrameFormatRTPPayload: return "RTPPayload"; +// case OMX_AUDIO_AMRFrameFormatITU: return "ITU"; + default: return def; + } +} + +inline static const char *asString(OMX_AUDIO_AMRBANDMODETYPE i, const char *def = "??") { + switch (i) { + case OMX_AUDIO_AMRBandModeUnused: return "Unused"; + case OMX_AUDIO_AMRBandModeNB0: return "NB0"; + case OMX_AUDIO_AMRBandModeNB1: return "NB1"; + case OMX_AUDIO_AMRBandModeNB2: return "NB2"; + case OMX_AUDIO_AMRBandModeNB3: return "NB3"; + case OMX_AUDIO_AMRBandModeNB4: return "NB4"; + case OMX_AUDIO_AMRBandModeNB5: return "NB5"; + case OMX_AUDIO_AMRBandModeNB6: return "NB6"; + case OMX_AUDIO_AMRBandModeNB7: return "NB7"; + case OMX_AUDIO_AMRBandModeWB0: return "WB0"; + case OMX_AUDIO_AMRBandModeWB1: return "WB1"; + case OMX_AUDIO_AMRBandModeWB2: return "WB2"; + case OMX_AUDIO_AMRBandModeWB3: return "WB3"; + case OMX_AUDIO_AMRBandModeWB4: return "WB4"; + case OMX_AUDIO_AMRBandModeWB5: return "WB5"; + case OMX_AUDIO_AMRBandModeWB6: return "WB6"; + case OMX_AUDIO_AMRBandModeWB7: return "WB7"; + case OMX_AUDIO_AMRBandModeWB8: return "WB8"; + default: return def; + } +} + +inline static const char *asString(OMX_AUDIO_AMRDTXMODETYPE i, const char *def = "??") { + switch (i) { + case OMX_AUDIO_AMRDTXModeOff: return "ModeOff"; +// case OMX_AUDIO_AMRDTXModeOnVAD1: return "ModeOnVAD1"; +// case OMX_AUDIO_AMRDTXModeOnVAD2: return "ModeOnVAD2"; +// case OMX_AUDIO_AMRDTXModeOnAuto: return "ModeOnAuto"; +// case OMX_AUDIO_AMRDTXasEFR: return "asEFR"; + default: return def; + } +} + +#endif // AS_STRING_FOR_OMX_AUDIO_H + +#endif // OMX_Audio_h + +#ifdef OMX_AudioExt_h +/* asString definitions if media/openmax/OMX_AudioExt.h was included */ + +#ifndef AS_STRING_FOR_OMX_AUDIOEXT_H +#define AS_STRING_FOR_OMX_AUDIOEXT_H + +inline static const char *asString(OMX_AUDIO_CODINGEXTTYPE i, const char *def = "??") { + switch (i) { + case OMX_AUDIO_CodingAndroidAC3: return "AndroidAC3"; + case OMX_AUDIO_CodingAndroidOPUS: return "AndroidOPUS"; + default: return asString((OMX_AUDIO_CODINGTYPE)i, def); + } +} + +#endif // AS_STRING_FOR_OMX_AUDIOEXT_H + +#endif // OMX_AudioExt_h + +#ifdef OMX_Component_h +/* asString definitions if media/openmax/OMX_Component.h was included */ + +#ifndef AS_STRING_FOR_OMX_COMPONENT_H +#define AS_STRING_FOR_OMX_COMPONENT_H + +inline static const char *asString(OMX_PORTDOMAINTYPE i, const char *def = "??") { + switch (i) { + case OMX_PortDomainAudio: return "Audio"; + case OMX_PortDomainVideo: return "Video"; + case OMX_PortDomainImage: return "Image"; +// case OMX_PortDomainOther: return "Other"; + default: return def; + } +} + +#endif // AS_STRING_FOR_OMX_COMPONENT_H + +#endif // OMX_Component_h + +#ifdef OMX_Core_h +/* asString definitions if media/openmax/OMX_Core.h was included */ + +#ifndef AS_STRING_FOR_OMX_CORE_H +#define AS_STRING_FOR_OMX_CORE_H + +inline static const char *asString(OMX_COMMANDTYPE i, const char *def = "??") { + switch (i) { + case OMX_CommandStateSet: return "StateSet"; + case OMX_CommandFlush: return "Flush"; + case OMX_CommandPortDisable: return "PortDisable"; + case OMX_CommandPortEnable: return "PortEnable"; +// case OMX_CommandMarkBuffer: return "MarkBuffer"; + default: return def; + } +} + +inline static const char *asString(OMX_STATETYPE i, const char *def = "??") { + switch (i) { + case OMX_StateInvalid: return "Invalid"; + case OMX_StateLoaded: return "Loaded"; + case OMX_StateIdle: return "Idle"; + case OMX_StateExecuting: return "Executing"; +// case OMX_StatePause: return "Pause"; +// case OMX_StateWaitForResources: return "WaitForResources"; + default: return def; + } +} + +inline static const char *asString(OMX_ERRORTYPE i, const char *def = "??") { + switch (i) { + case OMX_ErrorNone: return "None"; + case OMX_ErrorInsufficientResources: return "InsufficientResources"; + case OMX_ErrorUndefined: return "Undefined"; + case OMX_ErrorInvalidComponentName: return "InvalidComponentName"; + case OMX_ErrorComponentNotFound: return "ComponentNotFound"; + case OMX_ErrorInvalidComponent: return "InvalidComponent"; // unused + case OMX_ErrorBadParameter: return "BadParameter"; + case OMX_ErrorNotImplemented: return "NotImplemented"; + case OMX_ErrorUnderflow: return "Underflow"; // unused + case OMX_ErrorOverflow: return "Overflow"; // unused + case OMX_ErrorHardware: return "Hardware"; // unused + case OMX_ErrorInvalidState: return "InvalidState"; + case OMX_ErrorStreamCorrupt: return "StreamCorrupt"; + case OMX_ErrorPortsNotCompatible: return "PortsNotCompatible"; // unused + case OMX_ErrorResourcesLost: return "ResourcesLost"; + case OMX_ErrorNoMore: return "NoMore"; + case OMX_ErrorVersionMismatch: return "VersionMismatch"; // unused + case OMX_ErrorNotReady: return "NotReady"; // unused + case OMX_ErrorTimeout: return "Timeout"; // unused + case OMX_ErrorSameState: return "SameState"; // unused + case OMX_ErrorResourcesPreempted: return "ResourcesPreempted"; // unused + case OMX_ErrorPortUnresponsiveDuringAllocation: + return "PortUnresponsiveDuringAllocation"; // unused + case OMX_ErrorPortUnresponsiveDuringDeallocation: + return "PortUnresponsiveDuringDeallocation"; // unused + case OMX_ErrorPortUnresponsiveDuringStop: + return "PortUnresponsiveDuringStop"; // unused + case OMX_ErrorIncorrectStateTransition: + return "IncorrectStateTransition"; // unused + case OMX_ErrorIncorrectStateOperation: + return "IncorrectStateOperation"; // unused + case OMX_ErrorUnsupportedSetting: return "UnsupportedSetting"; + case OMX_ErrorUnsupportedIndex: return "UnsupportedIndex"; + case OMX_ErrorBadPortIndex: return "BadPortIndex"; + case OMX_ErrorPortUnpopulated: return "PortUnpopulated"; // unused + case OMX_ErrorComponentSuspended: return "ComponentSuspended"; // unused + case OMX_ErrorDynamicResourcesUnavailable: + return "DynamicResourcesUnavailable"; // unused + case OMX_ErrorMbErrorsInFrame: return "MbErrorsInFrame"; // unused + case OMX_ErrorFormatNotDetected: return "FormatNotDetected"; // unused + case OMX_ErrorContentPipeOpenFailed: return "ContentPipeOpenFailed"; // unused + case OMX_ErrorContentPipeCreationFailed: + return "ContentPipeCreationFailed"; // unused + case OMX_ErrorSeperateTablesUsed: return "SeperateTablesUsed"; // unused + case OMX_ErrorTunnelingUnsupported: return "TunnelingUnsupported"; // unused + default: return def; + } +} + +inline static const char *asString(OMX_EVENTTYPE i, const char *def = "??") { + switch (i) { + case OMX_EventCmdComplete: return "CmdComplete"; + case OMX_EventError: return "Error"; +// case OMX_EventMark: return "Mark"; + case OMX_EventPortSettingsChanged: return "PortSettingsChanged"; + case OMX_EventBufferFlag: return "BufferFlag"; +// case OMX_EventResourcesAcquired: return "ResourcesAcquired"; +// case OMX_EventComponentResumed: return "ComponentResumed"; +// case OMX_EventDynamicResourcesAvailable: return "DynamicResourcesAvailable"; +// case OMX_EventPortFormatDetected: return "PortFormatDetected"; + case OMX_EventOutputRendered: return "OutputRendered"; + default: return def; + } +} + +#endif // AS_STRING_FOR_OMX_CORE_H + +#endif // OMX_Core_h + +#ifdef OMX_Image_h +/* asString definitions if media/openmax/OMX_Image.h was included */ + +#ifndef AS_STRING_FOR_OMX_IMAGE_H +#define AS_STRING_FOR_OMX_IMAGE_H + +inline static const char *asString(OMX_IMAGE_CODINGTYPE i, const char *def = "??") { + switch (i) { + case OMX_IMAGE_CodingUnused: return "Unused"; + case OMX_IMAGE_CodingAutoDetect: return "AutoDetect"; // unused + case OMX_IMAGE_CodingJPEG: return "JPEG"; + case OMX_IMAGE_CodingJPEG2K: return "JPEG2K"; // unused + case OMX_IMAGE_CodingEXIF: return "EXIF"; // unused + case OMX_IMAGE_CodingTIFF: return "TIFF"; // unused + case OMX_IMAGE_CodingGIF: return "GIF"; // unused + case OMX_IMAGE_CodingPNG: return "PNG"; // unused + case OMX_IMAGE_CodingLZW: return "LZW"; // unused + case OMX_IMAGE_CodingBMP: return "BMP"; // unused + default: return def; + } +} + +#endif // AS_STRING_FOR_OMX_IMAGE_H + +#endif // OMX_Image_h + +#ifdef OMX_Index_h +/* asString definitions if media/openmax/OMX_Index.h was included */ + +#ifndef AS_STRING_FOR_OMX_INDEX_H +#define AS_STRING_FOR_OMX_INDEX_H + +inline static const char *asString(OMX_INDEXTYPE i, const char *def = "??") { + switch (i) { +// case OMX_IndexParamPriorityMgmt: return "ParamPriorityMgmt"; +// case OMX_IndexParamAudioInit: return "ParamAudioInit"; +// case OMX_IndexParamImageInit: return "ParamImageInit"; +// case OMX_IndexParamVideoInit: return "ParamVideoInit"; +// case OMX_IndexParamOtherInit: return "ParamOtherInit"; +// case OMX_IndexParamNumAvailableStreams: return "ParamNumAvailableStreams"; +// case OMX_IndexParamActiveStream: return "ParamActiveStream"; +// case OMX_IndexParamSuspensionPolicy: return "ParamSuspensionPolicy"; +// case OMX_IndexParamComponentSuspended: return "ParamComponentSuspended"; +// case OMX_IndexConfigCapturing: return "ConfigCapturing"; +// case OMX_IndexConfigCaptureMode: return "ConfigCaptureMode"; +// case OMX_IndexAutoPauseAfterCapture: return "AutoPauseAfterCapture"; +// case OMX_IndexParamContentURI: return "ParamContentURI"; +// case OMX_IndexParamCustomContentPipe: return "ParamCustomContentPipe"; +// case OMX_IndexParamDisableResourceConcealment: +// return "ParamDisableResourceConcealment"; +// case OMX_IndexConfigMetadataItemCount: return "ConfigMetadataItemCount"; +// case OMX_IndexConfigContainerNodeCount: return "ConfigContainerNodeCount"; +// case OMX_IndexConfigMetadataItem: return "ConfigMetadataItem"; +// case OMX_IndexConfigCounterNodeID: return "ConfigCounterNodeID"; +// case OMX_IndexParamMetadataFilterType: return "ParamMetadataFilterType"; +// case OMX_IndexParamMetadataKeyFilter: return "ParamMetadataKeyFilter"; +// case OMX_IndexConfigPriorityMgmt: return "ConfigPriorityMgmt"; + case OMX_IndexParamStandardComponentRole: return "ParamStandardComponentRole"; + case OMX_IndexParamPortDefinition: return "ParamPortDefinition"; +// case OMX_IndexParamCompBufferSupplier: return "ParamCompBufferSupplier"; + case OMX_IndexParamAudioPortFormat: return "ParamAudioPortFormat"; + case OMX_IndexParamAudioPcm: return "ParamAudioPcm"; + case OMX_IndexParamAudioAac: return "ParamAudioAac"; +// case OMX_IndexParamAudioRa: return "ParamAudioRa"; + case OMX_IndexParamAudioMp3: return "ParamAudioMp3"; +// case OMX_IndexParamAudioAdpcm: return "ParamAudioAdpcm"; +// case OMX_IndexParamAudioG723: return "ParamAudioG723"; +// case OMX_IndexParamAudioG729: return "ParamAudioG729"; + case OMX_IndexParamAudioAmr: return "ParamAudioAmr"; +// case OMX_IndexParamAudioWma: return "ParamAudioWma"; +// case OMX_IndexParamAudioSbc: return "ParamAudioSbc"; +// case OMX_IndexParamAudioMidi: return "ParamAudioMidi"; +// case OMX_IndexParamAudioGsm_FR: return "ParamAudioGsm_FR"; +// case OMX_IndexParamAudioMidiLoadUserSound: return "ParamAudioMidiLoadUserSound"; +// case OMX_IndexParamAudioG726: return "ParamAudioG726"; +// case OMX_IndexParamAudioGsm_EFR: return "ParamAudioGsm_EFR"; +// case OMX_IndexParamAudioGsm_HR: return "ParamAudioGsm_HR"; +// case OMX_IndexParamAudioPdc_FR: return "ParamAudioPdc_FR"; +// case OMX_IndexParamAudioPdc_EFR: return "ParamAudioPdc_EFR"; +// case OMX_IndexParamAudioPdc_HR: return "ParamAudioPdc_HR"; +// case OMX_IndexParamAudioTdma_FR: return "ParamAudioTdma_FR"; +// case OMX_IndexParamAudioTdma_EFR: return "ParamAudioTdma_EFR"; +// case OMX_IndexParamAudioQcelp8: return "ParamAudioQcelp8"; +// case OMX_IndexParamAudioQcelp13: return "ParamAudioQcelp13"; +// case OMX_IndexParamAudioEvrc: return "ParamAudioEvrc"; +// case OMX_IndexParamAudioSmv: return "ParamAudioSmv"; + case OMX_IndexParamAudioVorbis: return "ParamAudioVorbis"; + case OMX_IndexParamAudioFlac: return "ParamAudioFlac"; +// case OMX_IndexConfigAudioMidiImmediateEvent: return "ConfigAudioMidiImmediateEvent"; +// case OMX_IndexConfigAudioMidiControl: return "ConfigAudioMidiControl"; +// case OMX_IndexConfigAudioMidiSoundBankProgram: +// return "ConfigAudioMidiSoundBankProgram"; +// case OMX_IndexConfigAudioMidiStatus: return "ConfigAudioMidiStatus"; +// case OMX_IndexConfigAudioMidiMetaEvent: return "ConfigAudioMidiMetaEvent"; +// case OMX_IndexConfigAudioMidiMetaEventData: return "ConfigAudioMidiMetaEventData"; +// case OMX_IndexConfigAudioVolume: return "ConfigAudioVolume"; +// case OMX_IndexConfigAudioBalance: return "ConfigAudioBalance"; +// case OMX_IndexConfigAudioChannelMute: return "ConfigAudioChannelMute"; +// case OMX_IndexConfigAudioMute: return "ConfigAudioMute"; +// case OMX_IndexConfigAudioLoudness: return "ConfigAudioLoudness"; +// case OMX_IndexConfigAudioEchoCancelation: return "ConfigAudioEchoCancelation"; +// case OMX_IndexConfigAudioNoiseReduction: return "ConfigAudioNoiseReduction"; +// case OMX_IndexConfigAudioBass: return "ConfigAudioBass"; +// case OMX_IndexConfigAudioTreble: return "ConfigAudioTreble"; +// case OMX_IndexConfigAudioStereoWidening: return "ConfigAudioStereoWidening"; +// case OMX_IndexConfigAudioChorus: return "ConfigAudioChorus"; +// case OMX_IndexConfigAudioEqualizer: return "ConfigAudioEqualizer"; +// case OMX_IndexConfigAudioReverberation: return "ConfigAudioReverberation"; +// case OMX_IndexConfigAudioChannelVolume: return "ConfigAudioChannelVolume"; +// case OMX_IndexParamImagePortFormat: return "ParamImagePortFormat"; +// case OMX_IndexParamFlashControl: return "ParamFlashControl"; +// case OMX_IndexConfigFocusControl: return "ConfigFocusControl"; +// case OMX_IndexParamQFactor: return "ParamQFactor"; +// case OMX_IndexParamQuantizationTable: return "ParamQuantizationTable"; +// case OMX_IndexParamHuffmanTable: return "ParamHuffmanTable"; +// case OMX_IndexConfigFlashControl: return "ConfigFlashControl"; + case OMX_IndexParamVideoPortFormat: return "ParamVideoPortFormat"; +// case OMX_IndexParamVideoQuantization: return "ParamVideoQuantization"; +// case OMX_IndexParamVideoFastUpdate: return "ParamVideoFastUpdate"; + case OMX_IndexParamVideoBitrate: return "ParamVideoBitrate"; +// case OMX_IndexParamVideoMotionVector: return "ParamVideoMotionVector"; + case OMX_IndexParamVideoIntraRefresh: return "ParamVideoIntraRefresh"; + case OMX_IndexParamVideoErrorCorrection: return "ParamVideoErrorCorrection"; +// case OMX_IndexParamVideoVBSMC: return "ParamVideoVBSMC"; +// case OMX_IndexParamVideoMpeg2: return "ParamVideoMpeg2"; + case OMX_IndexParamVideoMpeg4: return "ParamVideoMpeg4"; +// case OMX_IndexParamVideoWmv: return "ParamVideoWmv"; +// case OMX_IndexParamVideoRv: return "ParamVideoRv"; + case OMX_IndexParamVideoAvc: return "ParamVideoAvc"; + case OMX_IndexParamVideoH263: return "ParamVideoH263"; + case OMX_IndexParamVideoProfileLevelQuerySupported: + return "ParamVideoProfileLevelQuerySupported"; + case OMX_IndexParamVideoProfileLevelCurrent: return "ParamVideoProfileLevelCurrent"; + case OMX_IndexConfigVideoBitrate: return "ConfigVideoBitrate"; +// case OMX_IndexConfigVideoFramerate: return "ConfigVideoFramerate"; + case OMX_IndexConfigVideoIntraVOPRefresh: return "ConfigVideoIntraVOPRefresh"; +// case OMX_IndexConfigVideoIntraMBRefresh: return "ConfigVideoIntraMBRefresh"; +// case OMX_IndexConfigVideoMBErrorReporting: return "ConfigVideoMBErrorReporting"; +// case OMX_IndexParamVideoMacroblocksPerFrame: return "ParamVideoMacroblocksPerFrame"; +// case OMX_IndexConfigVideoMacroBlockErrorMap: return "ConfigVideoMacroBlockErrorMap"; +// case OMX_IndexParamVideoSliceFMO: return "ParamVideoSliceFMO"; +// case OMX_IndexConfigVideoAVCIntraPeriod: return "ConfigVideoAVCIntraPeriod"; +// case OMX_IndexConfigVideoNalSize: return "ConfigVideoNalSize"; +// case OMX_IndexParamCommonDeblocking: return "ParamCommonDeblocking"; +// case OMX_IndexParamCommonSensorMode: return "ParamCommonSensorMode"; +// case OMX_IndexParamCommonInterleave: return "ParamCommonInterleave"; +// case OMX_IndexConfigCommonColorFormatConversion: +// return "ConfigCommonColorFormatConversion"; + case OMX_IndexConfigCommonScale: return "ConfigCommonScale"; +// case OMX_IndexConfigCommonImageFilter: return "ConfigCommonImageFilter"; +// case OMX_IndexConfigCommonColorEnhancement: return "ConfigCommonColorEnhancement"; +// case OMX_IndexConfigCommonColorKey: return "ConfigCommonColorKey"; +// case OMX_IndexConfigCommonColorBlend: return "ConfigCommonColorBlend"; +// case OMX_IndexConfigCommonFrameStabilisation: return "ConfigCommonFrameStabilisation"; +// case OMX_IndexConfigCommonRotate: return "ConfigCommonRotate"; +// case OMX_IndexConfigCommonMirror: return "ConfigCommonMirror"; +// case OMX_IndexConfigCommonOutputPosition: return "ConfigCommonOutputPosition"; + case OMX_IndexConfigCommonInputCrop: return "ConfigCommonInputCrop"; + case OMX_IndexConfigCommonOutputCrop: return "ConfigCommonOutputCrop"; +// case OMX_IndexConfigCommonDigitalZoom: return "ConfigCommonDigitalZoom"; +// case OMX_IndexConfigCommonOpticalZoom: return "ConfigCommonOpticalZoom"; +// case OMX_IndexConfigCommonWhiteBalance: return "ConfigCommonWhiteBalance"; +// case OMX_IndexConfigCommonExposure: return "ConfigCommonExposure"; +// case OMX_IndexConfigCommonContrast: return "ConfigCommonContrast"; +// case OMX_IndexConfigCommonBrightness: return "ConfigCommonBrightness"; +// case OMX_IndexConfigCommonBacklight: return "ConfigCommonBacklight"; +// case OMX_IndexConfigCommonGamma: return "ConfigCommonGamma"; +// case OMX_IndexConfigCommonSaturation: return "ConfigCommonSaturation"; +// case OMX_IndexConfigCommonLightness: return "ConfigCommonLightness"; +// case OMX_IndexConfigCommonExclusionRect: return "ConfigCommonExclusionRect"; +// case OMX_IndexConfigCommonDithering: return "ConfigCommonDithering"; +// case OMX_IndexConfigCommonPlaneBlend: return "ConfigCommonPlaneBlend"; +// case OMX_IndexConfigCommonExposureValue: return "ConfigCommonExposureValue"; +// case OMX_IndexConfigCommonOutputSize: return "ConfigCommonOutputSize"; +// case OMX_IndexParamCommonExtraQuantData: return "ParamCommonExtraQuantData"; +// case OMX_IndexConfigCommonFocusRegion: return "ConfigCommonFocusRegion"; +// case OMX_IndexConfigCommonFocusStatus: return "ConfigCommonFocusStatus"; +// case OMX_IndexConfigCommonTransitionEffect: return "ConfigCommonTransitionEffect"; +// case OMX_IndexParamOtherPortFormat: return "ParamOtherPortFormat"; +// case OMX_IndexConfigOtherPower: return "ConfigOtherPower"; +// case OMX_IndexConfigOtherStats: return "ConfigOtherStats"; +// case OMX_IndexConfigTimeScale: return "ConfigTimeScale"; +// case OMX_IndexConfigTimeClockState: return "ConfigTimeClockState"; +// case OMX_IndexConfigTimeActiveRefClock: return "ConfigTimeActiveRefClock"; +// case OMX_IndexConfigTimeCurrentMediaTime: return "ConfigTimeCurrentMediaTime"; +// case OMX_IndexConfigTimeCurrentWallTime: return "ConfigTimeCurrentWallTime"; +// case OMX_IndexConfigTimeCurrentAudioReference: +// return "ConfigTimeCurrentAudioReference"; +// case OMX_IndexConfigTimeCurrentVideoReference: +// return "ConfigTimeCurrentVideoReference"; +// case OMX_IndexConfigTimeMediaTimeRequest: return "ConfigTimeMediaTimeRequest"; +// case OMX_IndexConfigTimeClientStartTime: return "ConfigTimeClientStartTime"; +// case OMX_IndexConfigTimePosition: return "ConfigTimePosition"; +// case OMX_IndexConfigTimeSeekMode: return "ConfigTimeSeekMode"; + default: return def; + } +} + +#endif // AS_STRING_FOR_OMX_INDEX_H + +#endif // OMX_Index_h + +#ifdef OMX_IndexExt_h +/* asString definitions if media/openmax/OMX_IndexExt.h was included */ + +#ifndef AS_STRING_FOR_OMX_INDEXEXT_H +#define AS_STRING_FOR_OMX_INDEXEXT_H + +inline static const char *asString(OMX_INDEXEXTTYPE i, const char *def = "??") { + switch (i) { +// case OMX_IndexConfigCallbackRequest: return "ConfigCallbackRequest"; +// case OMX_IndexConfigCommitMode: return "ConfigCommitMode"; +// case OMX_IndexConfigCommit: return "ConfigCommit"; + case OMX_IndexParamAudioAndroidAc3: return "ParamAudioAndroidAc3"; + case OMX_IndexParamAudioAndroidOpus: return "ParamAudioAndroidOpus"; + case OMX_IndexParamAudioAndroidAacPresentation: return "ParamAudioAndroidAacPresentation"; +// case OMX_IndexParamNalStreamFormatSupported: return "ParamNalStreamFormatSupported"; +// case OMX_IndexParamNalStreamFormat: return "ParamNalStreamFormat"; +// case OMX_IndexParamNalStreamFormatSelect: return "ParamNalStreamFormatSelect"; + case OMX_IndexParamVideoVp8: return "ParamVideoVp8"; +// case OMX_IndexConfigVideoVp8ReferenceFrame: return "ConfigVideoVp8ReferenceFrame"; +// case OMX_IndexConfigVideoVp8ReferenceFrameType: return "ConfigVideoVp8ReferenceFrameType"; + case OMX_IndexParamVideoAndroidVp8Encoder: return "ParamVideoAndroidVp8Encoder"; + case OMX_IndexParamVideoHevc: return "ParamVideoHevc"; +// case OMX_IndexParamSliceSegments: return "ParamSliceSegments"; + case OMX_IndexConfigAutoFramerateConversion: return "ConfigAutoFramerateConversion"; + case OMX_IndexConfigPriority: return "ConfigPriority"; + case OMX_IndexConfigOperatingRate: return "ConfigOperatingRate"; + case OMX_IndexParamConsumerUsageBits: return "ParamConsumerUsageBits"; + default: return asString((OMX_INDEXTYPE)i, def); + } +} + +#endif // AS_STRING_FOR_OMX_INDEXEXT_H + +#endif // OMX_IndexExt_h + +#ifdef OMX_IVCommon_h +/* asString definitions if media/openmax/OMX_IVCommon.h was included */ + +#ifndef AS_STRING_FOR_OMX_IVCOMMON_H +#define AS_STRING_FOR_OMX_IVCOMMON_H + +inline static const char *asString(OMX_COLOR_FORMATTYPE i, const char *def = "??") { + switch (i) { + case OMX_COLOR_FormatUnused: + return "COLOR_FormatUnused"; + case OMX_COLOR_FormatMonochrome: + return "COLOR_FormatMonochrome"; + case OMX_COLOR_Format8bitRGB332: + return "COLOR_Format8bitRGB332"; + case OMX_COLOR_Format12bitRGB444: + return "COLOR_Format12bitRGB444"; + case OMX_COLOR_Format16bitARGB4444: + return "COLOR_Format16bitARGB4444"; + case OMX_COLOR_Format16bitARGB1555: + return "COLOR_Format16bitARGB1555"; + case OMX_COLOR_Format16bitRGB565: + return "COLOR_Format16bitRGB565"; + case OMX_COLOR_Format16bitBGR565: + return "COLOR_Format16bitBGR565"; + case OMX_COLOR_Format18bitRGB666: + return "COLOR_Format18bitRGB666"; + case OMX_COLOR_Format18bitARGB1665: + return "COLOR_Format18bitARGB1665"; + case OMX_COLOR_Format19bitARGB1666: + return "COLOR_Format19bitARGB1666"; + case OMX_COLOR_Format24bitRGB888: + return "COLOR_Format24bitRGB888"; + case OMX_COLOR_Format24bitBGR888: + return "COLOR_Format24bitBGR888"; + case OMX_COLOR_Format24bitARGB1887: + return "COLOR_Format24bitARGB1887"; + case OMX_COLOR_Format25bitARGB1888: + return "COLOR_Format25bitARGB1888"; + case OMX_COLOR_Format32bitBGRA8888: + return "COLOR_Format32bitBGRA8888"; + case OMX_COLOR_Format32bitARGB8888: + return "COLOR_Format32bitARGB8888"; + case OMX_COLOR_FormatYUV411Planar: + return "COLOR_FormatYUV411Planar"; + case OMX_COLOR_FormatYUV411PackedPlanar: + return "COLOR_FormatYUV411PackedPlanar"; + case OMX_COLOR_FormatYUV420Planar: + return "COLOR_FormatYUV420Planar"; + case OMX_COLOR_FormatYUV420PackedPlanar: + return "COLOR_FormatYUV420PackedPlanar"; + case OMX_COLOR_FormatYUV420SemiPlanar: + return "COLOR_FormatYUV420SemiPlanar"; + case OMX_COLOR_FormatYUV422Planar: + return "COLOR_FormatYUV422Planar"; + case OMX_COLOR_FormatYUV422PackedPlanar: + return "COLOR_FormatYUV422PackedPlanar"; + case OMX_COLOR_FormatYUV422SemiPlanar: + return "COLOR_FormatYUV422SemiPlanar"; + case OMX_COLOR_FormatYCbYCr: + return "COLOR_FormatYCbYCr"; + case OMX_COLOR_FormatYCrYCb: + return "COLOR_FormatYCrYCb"; + case OMX_COLOR_FormatCbYCrY: + return "COLOR_FormatCbYCrY"; + case OMX_COLOR_FormatCrYCbY: + return "COLOR_FormatCrYCbY"; + case OMX_COLOR_FormatYUV444Interleaved: + return "COLOR_FormatYUV444Interleaved"; + case OMX_COLOR_FormatRawBayer8bit: + return "COLOR_FormatRawBayer8bit"; + case OMX_COLOR_FormatRawBayer10bit: + return "COLOR_FormatRawBayer10bit"; + case OMX_COLOR_FormatRawBayer8bitcompressed: + return "COLOR_FormatRawBayer8bitcompressed"; + case OMX_COLOR_FormatL2: + return "COLOR_FormatL2"; + case OMX_COLOR_FormatL4: + return "COLOR_FormatL4"; + case OMX_COLOR_FormatL8: + return "COLOR_FormatL8"; + case OMX_COLOR_FormatL16: + return "COLOR_FormatL16"; + case OMX_COLOR_FormatL24: + return "COLOR_FormatL24"; + case OMX_COLOR_FormatL32: + return "COLOR_FormatL32"; + case OMX_COLOR_FormatYUV420PackedSemiPlanar: + return "COLOR_FormatYUV420PackedSemiPlanar"; + case OMX_COLOR_FormatYUV422PackedSemiPlanar: + return "COLOR_FormatYUV422PackedSemiPlanar"; + case OMX_COLOR_Format18BitBGR666: + return "COLOR_Format18BitBGR666"; + case OMX_COLOR_Format24BitARGB6666: + return "COLOR_Format24BitARGB6666"; + case OMX_COLOR_Format24BitABGR6666: + return "COLOR_Format24BitABGR6666"; + case OMX_COLOR_FormatAndroidOpaque: + return "COLOR_FormatAndroidOpaque"; + case OMX_COLOR_FormatYUV420Flexible: + return "COLOR_FormatYUV420Flexible"; + case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: + return "TI_COLOR_FormatYUV420PackedSemiPlanar"; + case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: + return "QCOM_COLOR_FormatYVU420SemiPlanar"; +// case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka: +// return "QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka"; +// case OMX_SEC_COLOR_FormatNV12Tiled: +// return "SEC_COLOR_FormatNV12Tiled"; +// case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m: +// return "QCOM_COLOR_FormatYUV420PackedSemiPlanar32m"; + default: + return def; + } +} + +#endif // AS_STRING_FOR_OMX_IVCOMMON_H + +#endif // OMX_IVCommon_h + +#ifdef OMX_Types_h +/* asString definitions if media/openmax/OMX_Types.h was included */ + +#ifndef AS_STRING_FOR_OMX_TYPES_H +#define AS_STRING_FOR_OMX_TYPES_H + +inline static const char *asString(OMX_BOOL i, const char *def = "??") { + switch (i) { + case OMX_FALSE: return "FALSE"; + case OMX_TRUE: return "TRUE"; + default: return def; + } +} + +inline static const char *asString(OMX_DIRTYPE i, const char *def = "??") { + switch (i) { + case OMX_DirInput: return "Input"; + case OMX_DirOutput: return "Output"; + default: return def; + } +} + +inline static const char *asString(OMX_ENDIANTYPE i, const char *def = "??") { + switch (i) { + case OMX_EndianBig: return "Big"; +// case OMX_EndianLittle: return "Little"; + default: return def; + } +} + +inline static const char *asString(OMX_NUMERICALDATATYPE i, const char *def = "??") { + switch (i) { + case OMX_NumericalDataSigned: return "Signed"; +// case OMX_NumericalDataUnsigned: return "Unsigned"; + default: return def; + } +} + +#endif // AS_STRING_FOR_OMX_TYPES_H + +#endif // OMX_Types_h + +#ifdef OMX_Video_h +/* asString definitions if media/openmax/OMX_Video.h was included */ + +#ifndef AS_STRING_FOR_OMX_VIDEO_H +#define AS_STRING_FOR_OMX_VIDEO_H + +inline static const char *asString(OMX_VIDEO_CODINGTYPE i, const char *def = "??") { + switch (i) { + case OMX_VIDEO_CodingUnused: return "Unused"; + case OMX_VIDEO_CodingAutoDetect: return "AutoDetect"; // unused + case OMX_VIDEO_CodingMPEG2: return "MPEG2"; + case OMX_VIDEO_CodingH263: return "H263"; + case OMX_VIDEO_CodingMPEG4: return "MPEG4"; + case OMX_VIDEO_CodingWMV: return "WMV"; // unused + case OMX_VIDEO_CodingRV: return "RV"; // unused + case OMX_VIDEO_CodingAVC: return "AVC"; + case OMX_VIDEO_CodingMJPEG: return "MJPEG"; // unused + case OMX_VIDEO_CodingVP8: return "VP8"; + case OMX_VIDEO_CodingVP9: return "VP9"; + case OMX_VIDEO_CodingHEVC: return "HEVC"; + default: return def; + } +} + +inline static const char *asString(OMX_VIDEO_CONTROLRATETYPE i, const char *def = "??") { + switch (i) { +// case OMX_Video_ControlRateDisable: return "Disable"; + case OMX_Video_ControlRateVariable: return "Variable"; + case OMX_Video_ControlRateConstant: return "Constant"; +// case OMX_Video_ControlRateVariableSkipFrames: return "VariableSkipFrames"; +// case OMX_Video_ControlRateConstantSkipFrames: return "ConstantSkipFrames"; + default: return def; + } +} + +inline static const char *asString(OMX_VIDEO_INTRAREFRESHTYPE i, const char *def = "??") { + switch (i) { + case OMX_VIDEO_IntraRefreshCyclic: return "Cyclic"; + case OMX_VIDEO_IntraRefreshAdaptive: return "Adaptive"; + case OMX_VIDEO_IntraRefreshBoth: return "Both"; + default: return def; + } +} + +inline static const char *asString(OMX_VIDEO_H263PROFILETYPE i, const char *def = "??") { + switch (i) { + case OMX_VIDEO_H263ProfileBaseline: return "Baseline"; + case OMX_VIDEO_H263ProfileH320Coding: return "H320Coding"; + case OMX_VIDEO_H263ProfileBackwardCompatible: return "BackwardCompatible"; + case OMX_VIDEO_H263ProfileISWV2: return "ISWV2"; + case OMX_VIDEO_H263ProfileISWV3: return "ISWV3"; + case OMX_VIDEO_H263ProfileHighCompression: return "HighCompression"; + case OMX_VIDEO_H263ProfileInternet: return "Internet"; + case OMX_VIDEO_H263ProfileInterlace: return "Interlace"; + case OMX_VIDEO_H263ProfileHighLatency: return "HighLatency"; + default: return def; + } +} + +inline static const char *asString(OMX_VIDEO_H263LEVELTYPE i, const char *def = "??") { + switch (i) { + case OMX_VIDEO_H263Level10: return "Level10"; + case OMX_VIDEO_H263Level20: return "Level20"; + case OMX_VIDEO_H263Level30: return "Level30"; + case OMX_VIDEO_H263Level40: return "Level40"; + case OMX_VIDEO_H263Level45: return "Level45"; + case OMX_VIDEO_H263Level50: return "Level50"; + case OMX_VIDEO_H263Level60: return "Level60"; + case OMX_VIDEO_H263Level70: return "Level70"; + default: return def; + } +} + +inline static const char *asString(OMX_VIDEO_PICTURETYPE i, const char *def = "??") { + switch (i) { + case OMX_VIDEO_PictureTypeI: return "I"; + case OMX_VIDEO_PictureTypeP: return "P"; + case OMX_VIDEO_PictureTypeB: return "B"; +// case OMX_VIDEO_PictureTypeSI: return "SI"; +// case OMX_VIDEO_PictureTypeSP: return "SP"; +// case OMX_VIDEO_PictureTypeEI: return "EI"; +// case OMX_VIDEO_PictureTypeEP: return "EP"; +// case OMX_VIDEO_PictureTypeS: return "S"; + default: return def; + } +} + +inline static const char *asString(OMX_VIDEO_MPEG4PROFILETYPE i, const char *def = "??") { + switch (i) { + case OMX_VIDEO_MPEG4ProfileSimple: return "Simple"; + case OMX_VIDEO_MPEG4ProfileSimpleScalable: return "SimpleScalable"; + case OMX_VIDEO_MPEG4ProfileCore: return "Core"; + case OMX_VIDEO_MPEG4ProfileMain: return "Main"; + case OMX_VIDEO_MPEG4ProfileNbit: return "Nbit"; + case OMX_VIDEO_MPEG4ProfileScalableTexture: return "ScalableTexture"; + case OMX_VIDEO_MPEG4ProfileSimpleFace: return "SimpleFace"; + case OMX_VIDEO_MPEG4ProfileSimpleFBA: return "SimpleFBA"; + case OMX_VIDEO_MPEG4ProfileBasicAnimated: return "BasicAnimated"; + case OMX_VIDEO_MPEG4ProfileHybrid: return "Hybrid"; + case OMX_VIDEO_MPEG4ProfileAdvancedRealTime: return "AdvancedRealTime"; + case OMX_VIDEO_MPEG4ProfileCoreScalable: return "CoreScalable"; + case OMX_VIDEO_MPEG4ProfileAdvancedCoding: return "AdvancedCoding"; + case OMX_VIDEO_MPEG4ProfileAdvancedCore: return "AdvancedCore"; + case OMX_VIDEO_MPEG4ProfileAdvancedScalable: return "AdvancedScalable"; + case OMX_VIDEO_MPEG4ProfileAdvancedSimple: return "AdvancedSimple"; + default: return def; + } +} + +inline static const char *asString(OMX_VIDEO_MPEG4LEVELTYPE i, const char *def = "??") { + switch (i) { + case OMX_VIDEO_MPEG4Level0: return "Level0"; + case OMX_VIDEO_MPEG4Level0b: return "Level0b"; + case OMX_VIDEO_MPEG4Level1: return "Level1"; + case OMX_VIDEO_MPEG4Level2: return "Level2"; + case OMX_VIDEO_MPEG4Level3: return "Level3"; + case OMX_VIDEO_MPEG4Level4: return "Level4"; + case OMX_VIDEO_MPEG4Level4a: return "Level4a"; + case OMX_VIDEO_MPEG4Level5: return "Level5"; + default: return def; + } +} + +inline static const char *asString(OMX_VIDEO_AVCPROFILETYPE i, const char *def = "??") { + switch (i) { + case OMX_VIDEO_AVCProfileBaseline: return "Baseline"; + case OMX_VIDEO_AVCProfileMain: return "Main"; + case OMX_VIDEO_AVCProfileExtended: return "Extended"; + case OMX_VIDEO_AVCProfileHigh: return "High"; + case OMX_VIDEO_AVCProfileHigh10: return "High10"; + case OMX_VIDEO_AVCProfileHigh422: return "High422"; + case OMX_VIDEO_AVCProfileHigh444: return "High444"; + default: return def; + } +} + +inline static const char *asString(OMX_VIDEO_AVCLEVELTYPE i, const char *def = "??") { + switch (i) { + case OMX_VIDEO_AVCLevel1: return "Level1"; + case OMX_VIDEO_AVCLevel1b: return "Level1b"; + case OMX_VIDEO_AVCLevel11: return "Level11"; + case OMX_VIDEO_AVCLevel12: return "Level12"; + case OMX_VIDEO_AVCLevel13: return "Level13"; + case OMX_VIDEO_AVCLevel2: return "Level2"; + case OMX_VIDEO_AVCLevel21: return "Level21"; + case OMX_VIDEO_AVCLevel22: return "Level22"; + case OMX_VIDEO_AVCLevel3: return "Level3"; + case OMX_VIDEO_AVCLevel31: return "Level31"; + case OMX_VIDEO_AVCLevel32: return "Level32"; + case OMX_VIDEO_AVCLevel4: return "Level4"; + case OMX_VIDEO_AVCLevel41: return "Level41"; + case OMX_VIDEO_AVCLevel42: return "Level42"; + case OMX_VIDEO_AVCLevel5: return "Level5"; + case OMX_VIDEO_AVCLevel51: return "Level51"; + case OMX_VIDEO_AVCLevel52: return "Level52"; + default: return def; + } +} + +inline static const char *asString(OMX_VIDEO_AVCLOOPFILTERTYPE i, const char *def = "??") { + switch (i) { + case OMX_VIDEO_AVCLoopFilterEnable: return "Enable"; +// case OMX_VIDEO_AVCLoopFilterDisable: return "Disable"; +// case OMX_VIDEO_AVCLoopFilterDisableSliceBoundary: return "DisableSliceBoundary"; + default: return def; + } +} + +#endif // AS_STRING_FOR_OMX_VIDEO_H + +#endif // OMX_Video_h + +#ifdef OMX_VideoExt_h +/* asString definitions if media/openmax/OMX_VideoExt.h was included */ + +#ifndef AS_STRING_FOR_OMX_VIDEOEXT_H +#define AS_STRING_FOR_OMX_VIDEOEXT_H + +inline static const char *asString(OMX_VIDEO_VP8PROFILETYPE i, const char *def = "!!") { + switch (i) { + case OMX_VIDEO_VP8ProfileMain: return "Main"; + case OMX_VIDEO_VP8ProfileUnknown: return "Unknown"; // unused + default: return def; + } +} + +inline static const char *asString(OMX_VIDEO_VP8LEVELTYPE i, const char *def = "!!") { + switch (i) { + case OMX_VIDEO_VP8Level_Version0: return "_Version0"; + case OMX_VIDEO_VP8Level_Version1: return "_Version1"; + case OMX_VIDEO_VP8Level_Version2: return "_Version2"; + case OMX_VIDEO_VP8Level_Version3: return "_Version3"; + case OMX_VIDEO_VP8LevelUnknown: return "Unknown"; // unused + default: return def; + } +} + +inline static const char *asString( + OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE i, const char *def = "??") { + switch (i) { + case OMX_VIDEO_VPXTemporalLayerPatternNone: return "VPXTemporalLayerPatternNone"; + case OMX_VIDEO_VPXTemporalLayerPatternWebRTC: return "VPXTemporalLayerPatternWebRTC"; + default: return def; + } +} + +inline static const char *asString(OMX_VIDEO_HEVCPROFILETYPE i, const char *def = "!!") { + switch (i) { + case OMX_VIDEO_HEVCProfileUnknown: return "Unknown"; // unused + case OMX_VIDEO_HEVCProfileMain: return "Main"; + case OMX_VIDEO_HEVCProfileMain10: return "Main10"; + default: return def; + } +} + +inline static const char *asString(OMX_VIDEO_HEVCLEVELTYPE i, const char *def = "!!") { + switch (i) { + case OMX_VIDEO_HEVCLevelUnknown: return "LevelUnknown"; // unused + case OMX_VIDEO_HEVCMainTierLevel1: return "MainTierLevel1"; + case OMX_VIDEO_HEVCHighTierLevel1: return "HighTierLevel1"; + case OMX_VIDEO_HEVCMainTierLevel2: return "MainTierLevel2"; + case OMX_VIDEO_HEVCHighTierLevel2: return "HighTierLevel2"; + case OMX_VIDEO_HEVCMainTierLevel21: return "MainTierLevel21"; + case OMX_VIDEO_HEVCHighTierLevel21: return "HighTierLevel21"; + case OMX_VIDEO_HEVCMainTierLevel3: return "MainTierLevel3"; + case OMX_VIDEO_HEVCHighTierLevel3: return "HighTierLevel3"; + case OMX_VIDEO_HEVCMainTierLevel31: return "MainTierLevel31"; + case OMX_VIDEO_HEVCHighTierLevel31: return "HighTierLevel31"; + case OMX_VIDEO_HEVCMainTierLevel4: return "MainTierLevel4"; + case OMX_VIDEO_HEVCHighTierLevel4: return "HighTierLevel4"; + case OMX_VIDEO_HEVCMainTierLevel41: return "MainTierLevel41"; + case OMX_VIDEO_HEVCHighTierLevel41: return "HighTierLevel41"; + case OMX_VIDEO_HEVCMainTierLevel5: return "MainTierLevel5"; + case OMX_VIDEO_HEVCHighTierLevel5: return "HighTierLevel5"; + case OMX_VIDEO_HEVCMainTierLevel51: return "MainTierLevel51"; + case OMX_VIDEO_HEVCHighTierLevel51: return "HighTierLevel51"; + case OMX_VIDEO_HEVCMainTierLevel52: return "MainTierLevel52"; + case OMX_VIDEO_HEVCHighTierLevel52: return "HighTierLevel52"; + case OMX_VIDEO_HEVCMainTierLevel6: return "MainTierLevel6"; + case OMX_VIDEO_HEVCHighTierLevel6: return "HighTierLevel6"; + case OMX_VIDEO_HEVCMainTierLevel61: return "MainTierLevel61"; + case OMX_VIDEO_HEVCHighTierLevel61: return "HighTierLevel61"; + case OMX_VIDEO_HEVCMainTierLevel62: return "MainTierLevel62"; + case OMX_VIDEO_HEVCHighTierLevel62: return "HighTierLevel62"; + default: return def; + } +} + +#endif // AS_STRING_FOR_OMX_VIDEOEXT_H + +#endif // OMX_VideoExt_h diff --git a/phonelibs/android_frameworks_native/include/media/openmax/OMX_Audio.h b/phonelibs/android_frameworks_native/include/media/openmax/OMX_Audio.h new file mode 100644 index 00000000000000..a0cbd3bb990c0f --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/openmax/OMX_Audio.h @@ -0,0 +1,1342 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** @file OMX_Audio.h - OpenMax IL version 1.1.2 + * The structures needed by Audio components to exchange + * parameters and configuration data with the componenmilts. + */ + +#ifndef OMX_Audio_h +#define OMX_Audio_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + +/** @defgroup midi MIDI + * @ingroup audio + */ + +/** @defgroup effects Audio effects + * @ingroup audio + */ + +/** @defgroup audio OpenMAX IL Audio Domain + * Structures for OpenMAX IL Audio domain + * @{ + */ + +/** Enumeration used to define the possible audio codings. + * If "OMX_AUDIO_CodingUnused" is selected, the coding selection must + * be done in a vendor specific way. Since this is for an audio + * processing element this enum is relevant. However, for another + * type of component other enums would be in this area. + */ +typedef enum OMX_AUDIO_CODINGTYPE { + OMX_AUDIO_CodingUnused = 0, /**< Placeholder value when coding is N/A */ + OMX_AUDIO_CodingAutoDetect, /**< auto detection of audio format */ + OMX_AUDIO_CodingPCM, /**< Any variant of PCM coding */ + OMX_AUDIO_CodingADPCM, /**< Any variant of ADPCM encoded data */ + OMX_AUDIO_CodingAMR, /**< Any variant of AMR encoded data */ + OMX_AUDIO_CodingGSMFR, /**< Any variant of GSM fullrate (i.e. GSM610) */ + OMX_AUDIO_CodingGSMEFR, /**< Any variant of GSM Enhanced Fullrate encoded data*/ + OMX_AUDIO_CodingGSMHR, /**< Any variant of GSM Halfrate encoded data */ + OMX_AUDIO_CodingPDCFR, /**< Any variant of PDC Fullrate encoded data */ + OMX_AUDIO_CodingPDCEFR, /**< Any variant of PDC Enhanced Fullrate encoded data */ + OMX_AUDIO_CodingPDCHR, /**< Any variant of PDC Halfrate encoded data */ + OMX_AUDIO_CodingTDMAFR, /**< Any variant of TDMA Fullrate encoded data (TIA/EIA-136-420) */ + OMX_AUDIO_CodingTDMAEFR, /**< Any variant of TDMA Enhanced Fullrate encoded data (TIA/EIA-136-410) */ + OMX_AUDIO_CodingQCELP8, /**< Any variant of QCELP 8kbps encoded data */ + OMX_AUDIO_CodingQCELP13, /**< Any variant of QCELP 13kbps encoded data */ + OMX_AUDIO_CodingEVRC, /**< Any variant of EVRC encoded data */ + OMX_AUDIO_CodingSMV, /**< Any variant of SMV encoded data */ + OMX_AUDIO_CodingG711, /**< Any variant of G.711 encoded data */ + OMX_AUDIO_CodingG723, /**< Any variant of G.723 dot 1 encoded data */ + OMX_AUDIO_CodingG726, /**< Any variant of G.726 encoded data */ + OMX_AUDIO_CodingG729, /**< Any variant of G.729 encoded data */ + OMX_AUDIO_CodingAAC, /**< Any variant of AAC encoded data */ + OMX_AUDIO_CodingMP3, /**< Any variant of MP3 encoded data */ + OMX_AUDIO_CodingSBC, /**< Any variant of SBC encoded data */ + OMX_AUDIO_CodingVORBIS, /**< Any variant of VORBIS encoded data */ + OMX_AUDIO_CodingWMA, /**< Any variant of WMA encoded data */ + OMX_AUDIO_CodingRA, /**< Any variant of RA encoded data */ + OMX_AUDIO_CodingMIDI, /**< Any variant of MIDI encoded data */ + OMX_AUDIO_CodingFLAC, /**< Any variant of FLAC encoded data */ + OMX_AUDIO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_CodingMax = 0x7FFFFFFF +} OMX_AUDIO_CODINGTYPE; + + +/** The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output audio + * path. If additional information is needed to define the parameters of the + * port (such as frequency), additional structures must be sent such as the + * OMX_AUDIO_PARAM_PCMMODETYPE structure to supply the extra parameters for the port. + */ +typedef struct OMX_AUDIO_PORTDEFINITIONTYPE { + OMX_STRING cMIMEType; /**< MIME type of data for the port */ + OMX_NATIVE_DEVICETYPE pNativeRender; /** < platform specific reference + for an output device, + otherwise this field is 0 */ + OMX_BOOL bFlagErrorConcealment; /**< Turns on error concealment if it is + supported by the OMX component */ + OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this + port (e.g. PCM, AMR, MP3, etc) */ +} OMX_AUDIO_PORTDEFINITIONTYPE; + + +/** Port format parameter. This structure is used to enumerate + * the various data input/output format supported by the port. + */ +typedef struct OMX_AUDIO_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Indicates which port to set */ + OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */ + OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this port (e.g. PCM, AMR, MP3, etc) */ +} OMX_AUDIO_PARAM_PORTFORMATTYPE; + + +/** PCM mode type */ +typedef enum OMX_AUDIO_PCMMODETYPE { + OMX_AUDIO_PCMModeLinear = 0, /**< Linear PCM encoded data */ + OMX_AUDIO_PCMModeALaw, /**< A law PCM encoded data (G.711) */ + OMX_AUDIO_PCMModeMULaw, /**< Mu law PCM encoded data (G.711) */ + OMX_AUDIO_PCMModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_PCMModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_PCMModeMax = 0x7FFFFFFF +} OMX_AUDIO_PCMMODETYPE; + + +typedef enum OMX_AUDIO_CHANNELTYPE { + OMX_AUDIO_ChannelNone = 0x0, /**< Unused or empty */ + OMX_AUDIO_ChannelLF = 0x1, /**< Left front */ + OMX_AUDIO_ChannelRF = 0x2, /**< Right front */ + OMX_AUDIO_ChannelCF = 0x3, /**< Center front */ + OMX_AUDIO_ChannelLS = 0x4, /**< Left surround */ + OMX_AUDIO_ChannelRS = 0x5, /**< Right surround */ + OMX_AUDIO_ChannelLFE = 0x6, /**< Low frequency effects */ + OMX_AUDIO_ChannelCS = 0x7, /**< Back surround */ + OMX_AUDIO_ChannelLR = 0x8, /**< Left rear. */ + OMX_AUDIO_ChannelRR = 0x9, /**< Right rear. */ + OMX_AUDIO_ChannelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_ChannelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_ChannelMax = 0x7FFFFFFF +} OMX_AUDIO_CHANNELTYPE; + +#define OMX_AUDIO_MAXCHANNELS 16 /**< maximum number distinct audio channels that a buffer may contain */ +#define OMX_MIN_PCMPAYLOAD_MSEC 5 /**< Minimum audio buffer payload size for uncompressed (PCM) audio */ + +/** PCM format description */ +typedef struct OMX_AUDIO_PARAM_PCMMODETYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels (e.g. 2 for stereo) */ + OMX_NUMERICALDATATYPE eNumData; /**< indicates PCM data as signed or unsigned */ + OMX_ENDIANTYPE eEndian; /**< indicates PCM data as little or big endian */ + OMX_BOOL bInterleaved; /**< True for normal interleaved data; false for + non-interleaved data (e.g. block data) */ + OMX_U32 nBitPerSample; /**< Bit per sample */ + OMX_U32 nSamplingRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_AUDIO_PCMMODETYPE ePCMMode; /**< PCM mode enumeration */ + OMX_AUDIO_CHANNELTYPE eChannelMapping[OMX_AUDIO_MAXCHANNELS]; /**< Slot i contains channel defined by eChannelMap[i] */ + +} OMX_AUDIO_PARAM_PCMMODETYPE; + + +/** Audio channel mode. This is used by both AAC and MP3, although the names are more appropriate + * for the MP3. For example, JointStereo for MP3 is CouplingChannels for AAC. + */ +typedef enum OMX_AUDIO_CHANNELMODETYPE { + OMX_AUDIO_ChannelModeStereo = 0, /**< 2 channels, the bitrate allocation between those + two channels changes accordingly to each channel information */ + OMX_AUDIO_ChannelModeJointStereo, /**< mode that takes advantage of what is common between + 2 channels for higher compression gain */ + OMX_AUDIO_ChannelModeDual, /**< 2 mono-channels, each channel is encoded with half + the bitrate of the overall bitrate */ + OMX_AUDIO_ChannelModeMono, /**< Mono channel mode */ + OMX_AUDIO_ChannelModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_ChannelModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_ChannelModeMax = 0x7FFFFFFF +} OMX_AUDIO_CHANNELMODETYPE; + + +typedef enum OMX_AUDIO_MP3STREAMFORMATTYPE { + OMX_AUDIO_MP3StreamFormatMP1Layer3 = 0, /**< MP3 Audio MPEG 1 Layer 3 Stream format */ + OMX_AUDIO_MP3StreamFormatMP2Layer3, /**< MP3 Audio MPEG 2 Layer 3 Stream format */ + OMX_AUDIO_MP3StreamFormatMP2_5Layer3, /**< MP3 Audio MPEG2.5 Layer 3 Stream format */ + OMX_AUDIO_MP3StreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MP3StreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MP3StreamFormatMax = 0x7FFFFFFF +} OMX_AUDIO_MP3STREAMFORMATTYPE; + +/** MP3 params */ +typedef struct OMX_AUDIO_PARAM_MP3TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should + limit the audio signal. Use 0 to let encoder decide */ + OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ + OMX_AUDIO_MP3STREAMFORMATTYPE eFormat; /**< MP3 stream format */ +} OMX_AUDIO_PARAM_MP3TYPE; + + +typedef enum OMX_AUDIO_AACSTREAMFORMATTYPE { + OMX_AUDIO_AACStreamFormatMP2ADTS = 0, /**< AAC Audio Data Transport Stream 2 format */ + OMX_AUDIO_AACStreamFormatMP4ADTS, /**< AAC Audio Data Transport Stream 4 format */ + OMX_AUDIO_AACStreamFormatMP4LOAS, /**< AAC Low Overhead Audio Stream format */ + OMX_AUDIO_AACStreamFormatMP4LATM, /**< AAC Low overhead Audio Transport Multiplex */ + OMX_AUDIO_AACStreamFormatADIF, /**< AAC Audio Data Interchange Format */ + OMX_AUDIO_AACStreamFormatMP4FF, /**< AAC inside MPEG-4/ISO File Format */ + OMX_AUDIO_AACStreamFormatRAW, /**< AAC Raw Format */ + OMX_AUDIO_AACStreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AACStreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AACStreamFormatMax = 0x7FFFFFFF +} OMX_AUDIO_AACSTREAMFORMATTYPE; + + +/** AAC mode type. Note that the term profile is used with the MPEG-2 + * standard and the term object type and profile is used with MPEG-4 */ +typedef enum OMX_AUDIO_AACPROFILETYPE{ + OMX_AUDIO_AACObjectNull = 0, /**< Null, not used */ + OMX_AUDIO_AACObjectMain = 1, /**< AAC Main object */ + OMX_AUDIO_AACObjectLC, /**< AAC Low Complexity object (AAC profile) */ + OMX_AUDIO_AACObjectSSR, /**< AAC Scalable Sample Rate object */ + OMX_AUDIO_AACObjectLTP, /**< AAC Long Term Prediction object */ + OMX_AUDIO_AACObjectHE, /**< AAC High Efficiency (object type SBR, HE-AAC profile) */ + OMX_AUDIO_AACObjectScalable, /**< AAC Scalable object */ + OMX_AUDIO_AACObjectERLC = 17, /**< ER AAC Low Complexity object (Error Resilient AAC-LC) */ + OMX_AUDIO_AACObjectLD = 23, /**< AAC Low Delay object (Error Resilient) */ + OMX_AUDIO_AACObjectHE_PS = 29, /**< AAC High Efficiency with Parametric Stereo coding (HE-AAC v2, object type PS) */ + OMX_AUDIO_AACObjectELD = 39, /** AAC Enhanced Low Delay. NOTE: Pending Khronos standardization **/ + OMX_AUDIO_AACObjectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AACObjectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AACObjectMax = 0x7FFFFFFF +} OMX_AUDIO_AACPROFILETYPE; + + +/** AAC tool usage (for nAACtools in OMX_AUDIO_PARAM_AACPROFILETYPE). + * Required for encoder configuration and optional as decoder info output. + * For MP3, OMX_AUDIO_CHANNELMODETYPE is sufficient. */ +#define OMX_AUDIO_AACToolNone 0x00000000 /**< no AAC tools allowed (encoder config) or active (decoder info output) */ +#define OMX_AUDIO_AACToolMS 0x00000001 /**< MS: Mid/side joint coding tool allowed or active */ +#define OMX_AUDIO_AACToolIS 0x00000002 /**< IS: Intensity stereo tool allowed or active */ +#define OMX_AUDIO_AACToolTNS 0x00000004 /**< TNS: Temporal Noise Shaping tool allowed or active */ +#define OMX_AUDIO_AACToolPNS 0x00000008 /**< PNS: MPEG-4 Perceptual Noise substitution tool allowed or active */ +#define OMX_AUDIO_AACToolLTP 0x00000010 /**< LTP: MPEG-4 Long Term Prediction tool allowed or active */ +#define OMX_AUDIO_AACToolVendor 0x00010000 /**< NOT A KHRONOS VALUE, offset for vendor-specific additions */ +#define OMX_AUDIO_AACToolAll 0x7FFFFFFF /**< all AAC tools allowed or active (*/ + +/** MPEG-4 AAC error resilience (ER) tool usage (for nAACERtools in OMX_AUDIO_PARAM_AACPROFILETYPE). + * Required for ER encoder configuration and optional as decoder info output */ +#define OMX_AUDIO_AACERNone 0x00000000 /**< no AAC ER tools allowed/used */ +#define OMX_AUDIO_AACERVCB11 0x00000001 /**< VCB11: Virtual Code Books for AAC section data */ +#define OMX_AUDIO_AACERRVLC 0x00000002 /**< RVLC: Reversible Variable Length Coding */ +#define OMX_AUDIO_AACERHCR 0x00000004 /**< HCR: Huffman Codeword Reordering */ +#define OMX_AUDIO_AACERAll 0x7FFFFFFF /**< all AAC ER tools allowed/used */ + + +/** AAC params */ +typedef struct OMX_AUDIO_PARAM_AACPROFILETYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should + limit the audio signal. Use 0 to let encoder decide */ + OMX_U32 nFrameLength; /**< Frame length (in audio samples per channel) of the codec. + Can be 1024 or 960 (AAC-LC), 2048 (HE-AAC), 480 or 512 (AAC-LD). + Use 0 to let encoder decide */ + OMX_U32 nAACtools; /**< AAC tool usage */ + OMX_U32 nAACERtools; /**< MPEG-4 AAC error resilience tool usage */ + OMX_AUDIO_AACPROFILETYPE eAACProfile; /**< AAC profile enumeration */ + OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat; /**< AAC stream format enumeration */ + OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ +} OMX_AUDIO_PARAM_AACPROFILETYPE; + + +/** VORBIS params */ +typedef struct OMX_AUDIO_PARAM_VORBISTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the encoded data data. Use 0 for variable + rate or unknown bit rates. Encoding is set to the + bitrate closest to specified value (in bps) */ + OMX_U32 nMinBitRate; /**< Sets minimum bitrate (in bps). */ + OMX_U32 nMaxBitRate; /**< Sets maximum bitrate (in bps). */ + + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should + limit the audio signal. Use 0 to let encoder decide */ + OMX_S32 nQuality; /**< Sets encoding quality to n, between -1 (low) and 10 (high). + In the default mode of operation, teh quality level is 3. + Normal quality range is 0 - 10. */ + OMX_BOOL bManaged; /**< Set bitrate management mode. This turns off the + normal VBR encoding, but allows hard or soft bitrate + constraints to be enforced by the encoder. This mode can + be slower, and may also be lower quality. It is + primarily useful for streaming. */ + OMX_BOOL bDownmix; /**< Downmix input from stereo to mono (has no effect on + non-stereo streams). Useful for lower-bitrate encoding. */ +} OMX_AUDIO_PARAM_VORBISTYPE; + + +/** FLAC params */ +typedef struct OMX_AUDIO_PARAM_FLACTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + unknown sampling rate. */ + OMX_U32 nCompressionLevel;/**< FLAC compression level, from 0 (fastest compression) + to 8 (highest compression */ +} OMX_AUDIO_PARAM_FLACTYPE; + + +/** WMA Version */ +typedef enum OMX_AUDIO_WMAFORMATTYPE { + OMX_AUDIO_WMAFormatUnused = 0, /**< format unused or unknown */ + OMX_AUDIO_WMAFormat7, /**< Windows Media Audio format 7 */ + OMX_AUDIO_WMAFormat8, /**< Windows Media Audio format 8 */ + OMX_AUDIO_WMAFormat9, /**< Windows Media Audio format 9 */ + OMX_AUDIO_WMAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_WMAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_WMAFormatMax = 0x7FFFFFFF +} OMX_AUDIO_WMAFORMATTYPE; + + +/** WMA Profile */ +typedef enum OMX_AUDIO_WMAPROFILETYPE { + OMX_AUDIO_WMAProfileUnused = 0, /**< profile unused or unknown */ + OMX_AUDIO_WMAProfileL1, /**< Windows Media audio version 9 profile L1 */ + OMX_AUDIO_WMAProfileL2, /**< Windows Media audio version 9 profile L2 */ + OMX_AUDIO_WMAProfileL3, /**< Windows Media audio version 9 profile L3 */ + OMX_AUDIO_WMAProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_WMAProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_WMAProfileMax = 0x7FFFFFFF +} OMX_AUDIO_WMAPROFILETYPE; + + +/** WMA params */ +typedef struct OMX_AUDIO_PARAM_WMATYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U16 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_AUDIO_WMAFORMATTYPE eFormat; /**< Version of WMA stream / data */ + OMX_AUDIO_WMAPROFILETYPE eProfile; /**< Profile of WMA stream / data */ + OMX_U32 nSamplingRate; /**< Sampling rate of the source data */ + OMX_U16 nBlockAlign; /**< is the block alignment, or block size, in bytes of the audio codec */ + OMX_U16 nEncodeOptions; /**< WMA Type-specific data */ + OMX_U32 nSuperBlockAlign; /**< WMA Type-specific data */ +} OMX_AUDIO_PARAM_WMATYPE; + +/** + * RealAudio format + */ +typedef enum OMX_AUDIO_RAFORMATTYPE { + OMX_AUDIO_RAFormatUnused = 0, /**< Format unused or unknown */ + OMX_AUDIO_RA8, /**< RealAudio 8 codec */ + OMX_AUDIO_RA9, /**< RealAudio 9 codec */ + OMX_AUDIO_RA10_AAC, /**< MPEG-4 AAC codec for bitrates of more than 128kbps */ + OMX_AUDIO_RA10_CODEC, /**< RealAudio codec for bitrates less than 128 kbps */ + OMX_AUDIO_RA10_LOSSLESS, /**< RealAudio Lossless */ + OMX_AUDIO_RA10_MULTICHANNEL, /**< RealAudio Multichannel */ + OMX_AUDIO_RA10_VOICE, /**< RealAudio Voice for bitrates below 15 kbps */ + OMX_AUDIO_RAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_RAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_RAFormatMax = 0x7FFFFFFF +} OMX_AUDIO_RAFORMATTYPE; + +/** RA (Real Audio) params */ +typedef struct OMX_AUDIO_PARAM_RATYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nSamplingRate; /**< is the sampling rate of the source data */ + OMX_U32 nBitsPerFrame; /**< is the value for bits per frame */ + OMX_U32 nSamplePerFrame; /**< is the value for samples per frame */ + OMX_U32 nCouplingQuantBits; /**< is the number of coupling quantization bits in the stream */ + OMX_U32 nCouplingStartRegion; /**< is the coupling start region in the stream */ + OMX_U32 nNumRegions; /**< is the number of regions value */ + OMX_AUDIO_RAFORMATTYPE eFormat; /**< is the RealAudio audio format */ +} OMX_AUDIO_PARAM_RATYPE; + + +/** SBC Allocation Method Type */ +typedef enum OMX_AUDIO_SBCALLOCMETHODTYPE { + OMX_AUDIO_SBCAllocMethodLoudness, /**< Loudness allocation method */ + OMX_AUDIO_SBCAllocMethodSNR, /**< SNR allocation method */ + OMX_AUDIO_SBCAllocMethodKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_SBCAllocMethodVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_SBCAllocMethodMax = 0x7FFFFFFF +} OMX_AUDIO_SBCALLOCMETHODTYPE; + + +/** SBC params */ +typedef struct OMX_AUDIO_PARAM_SBCTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nBlocks; /**< Number of blocks */ + OMX_U32 nSubbands; /**< Number of subbands */ + OMX_U32 nBitPool; /**< Bitpool value */ + OMX_BOOL bEnableBitrate; /**< Use bitrate value instead of bitpool */ + OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ + OMX_AUDIO_SBCALLOCMETHODTYPE eSBCAllocType; /**< SBC Allocation method type */ +} OMX_AUDIO_PARAM_SBCTYPE; + + +/** ADPCM stream format parameters */ +typedef struct OMX_AUDIO_PARAM_ADPCMTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_U32 nBitsPerSample; /**< Number of bits in each sample */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ +} OMX_AUDIO_PARAM_ADPCMTYPE; + + +/** G723 rate */ +typedef enum OMX_AUDIO_G723RATE { + OMX_AUDIO_G723ModeUnused = 0, /**< AMRNB Mode unused / unknown */ + OMX_AUDIO_G723ModeLow, /**< 5300 bps */ + OMX_AUDIO_G723ModeHigh, /**< 6300 bps */ + OMX_AUDIO_G723ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_G723ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_G723ModeMax = 0x7FFFFFFF +} OMX_AUDIO_G723RATE; + + +/** G723 - Sample rate must be 8 KHz */ +typedef struct OMX_AUDIO_PARAM_G723TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_AUDIO_G723RATE eBitRate; /**< todo: Should this be moved to a config? */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ + OMX_BOOL bPostFilter; /**< Enable Post Filter */ +} OMX_AUDIO_PARAM_G723TYPE; + + +/** ITU G726 (ADPCM) rate */ +typedef enum OMX_AUDIO_G726MODE { + OMX_AUDIO_G726ModeUnused = 0, /**< G726 Mode unused / unknown */ + OMX_AUDIO_G726Mode16, /**< 16 kbps */ + OMX_AUDIO_G726Mode24, /**< 24 kbps */ + OMX_AUDIO_G726Mode32, /**< 32 kbps, most common rate, also G721 */ + OMX_AUDIO_G726Mode40, /**< 40 kbps */ + OMX_AUDIO_G726ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_G726ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_G726ModeMax = 0x7FFFFFFF +} OMX_AUDIO_G726MODE; + + +/** G.726 stream format parameters - must be at 8KHz */ +typedef struct OMX_AUDIO_PARAM_G726TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_G726MODE eG726Mode; +} OMX_AUDIO_PARAM_G726TYPE; + + +/** G729 coder type */ +typedef enum OMX_AUDIO_G729TYPE { + OMX_AUDIO_G729 = 0, /**< ITU G.729 encoded data */ + OMX_AUDIO_G729A, /**< ITU G.729 annex A encoded data */ + OMX_AUDIO_G729B, /**< ITU G.729 with annex B encoded data */ + OMX_AUDIO_G729AB, /**< ITU G.729 annexes A and B encoded data */ + OMX_AUDIO_G729KhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_G729VendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_G729Max = 0x7FFFFFFF +} OMX_AUDIO_G729TYPE; + + +/** G729 stream format parameters - fixed 6KHz sample rate */ +typedef struct OMX_AUDIO_PARAM_G729TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_AUDIO_G729TYPE eBitType; +} OMX_AUDIO_PARAM_G729TYPE; + + +/** AMR Frame format */ +typedef enum OMX_AUDIO_AMRFRAMEFORMATTYPE { + OMX_AUDIO_AMRFrameFormatConformance = 0, /**< Frame Format is AMR Conformance + (Standard) Format */ + OMX_AUDIO_AMRFrameFormatIF1, /**< Frame Format is AMR Interface + Format 1 */ + OMX_AUDIO_AMRFrameFormatIF2, /**< Frame Format is AMR Interface + Format 2*/ + OMX_AUDIO_AMRFrameFormatFSF, /**< Frame Format is AMR File Storage + Format */ + OMX_AUDIO_AMRFrameFormatRTPPayload, /**< Frame Format is AMR Real-Time + Transport Protocol Payload Format */ + OMX_AUDIO_AMRFrameFormatITU, /**< Frame Format is ITU Format (added at Motorola request) */ + OMX_AUDIO_AMRFrameFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AMRFrameFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AMRFrameFormatMax = 0x7FFFFFFF +} OMX_AUDIO_AMRFRAMEFORMATTYPE; + + +/** AMR band mode */ +typedef enum OMX_AUDIO_AMRBANDMODETYPE { + OMX_AUDIO_AMRBandModeUnused = 0, /**< AMRNB Mode unused / unknown */ + OMX_AUDIO_AMRBandModeNB0, /**< AMRNB Mode 0 = 4750 bps */ + OMX_AUDIO_AMRBandModeNB1, /**< AMRNB Mode 1 = 5150 bps */ + OMX_AUDIO_AMRBandModeNB2, /**< AMRNB Mode 2 = 5900 bps */ + OMX_AUDIO_AMRBandModeNB3, /**< AMRNB Mode 3 = 6700 bps */ + OMX_AUDIO_AMRBandModeNB4, /**< AMRNB Mode 4 = 7400 bps */ + OMX_AUDIO_AMRBandModeNB5, /**< AMRNB Mode 5 = 7950 bps */ + OMX_AUDIO_AMRBandModeNB6, /**< AMRNB Mode 6 = 10200 bps */ + OMX_AUDIO_AMRBandModeNB7, /**< AMRNB Mode 7 = 12200 bps */ + OMX_AUDIO_AMRBandModeWB0, /**< AMRWB Mode 0 = 6600 bps */ + OMX_AUDIO_AMRBandModeWB1, /**< AMRWB Mode 1 = 8850 bps */ + OMX_AUDIO_AMRBandModeWB2, /**< AMRWB Mode 2 = 12650 bps */ + OMX_AUDIO_AMRBandModeWB3, /**< AMRWB Mode 3 = 14250 bps */ + OMX_AUDIO_AMRBandModeWB4, /**< AMRWB Mode 4 = 15850 bps */ + OMX_AUDIO_AMRBandModeWB5, /**< AMRWB Mode 5 = 18250 bps */ + OMX_AUDIO_AMRBandModeWB6, /**< AMRWB Mode 6 = 19850 bps */ + OMX_AUDIO_AMRBandModeWB7, /**< AMRWB Mode 7 = 23050 bps */ + OMX_AUDIO_AMRBandModeWB8, /**< AMRWB Mode 8 = 23850 bps */ + OMX_AUDIO_AMRBandModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AMRBandModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AMRBandModeMax = 0x7FFFFFFF +} OMX_AUDIO_AMRBANDMODETYPE; + + +/** AMR Discontinuous Transmission mode */ +typedef enum OMX_AUDIO_AMRDTXMODETYPE { + OMX_AUDIO_AMRDTXModeOff = 0, /**< AMR Discontinuous Transmission Mode is disabled */ + OMX_AUDIO_AMRDTXModeOnVAD1, /**< AMR Discontinuous Transmission Mode using + Voice Activity Detector 1 (VAD1) is enabled */ + OMX_AUDIO_AMRDTXModeOnVAD2, /**< AMR Discontinuous Transmission Mode using + Voice Activity Detector 2 (VAD2) is enabled */ + OMX_AUDIO_AMRDTXModeOnAuto, /**< The codec will automatically select between + Off, VAD1 or VAD2 modes */ + + OMX_AUDIO_AMRDTXasEFR, /**< DTX as EFR instead of AMR standard (3GPP 26.101, frame type =8,9,10) */ + + OMX_AUDIO_AMRDTXModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AMRDTXModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AMRDTXModeMax = 0x7FFFFFFF +} OMX_AUDIO_AMRDTXMODETYPE; + + +/** AMR params */ +typedef struct OMX_AUDIO_PARAM_AMRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate read only field */ + OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode; /**< AMR Band Mode enumeration */ + OMX_AUDIO_AMRDTXMODETYPE eAMRDTXMode; /**< AMR DTX Mode enumeration */ + OMX_AUDIO_AMRFRAMEFORMATTYPE eAMRFrameFormat; /**< AMR frame format enumeration */ +} OMX_AUDIO_PARAM_AMRTYPE; + + +/** GSM_FR (ETSI 06.10, 3GPP 46.010) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_GSMFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_GSMFRTYPE; + + +/** GSM-HR (ETSI 06.20, 3GPP 46.020) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_GSMHRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_GSMHRTYPE; + + +/** GSM-EFR (ETSI 06.60, 3GPP 46.060) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_GSMEFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_GSMEFRTYPE; + + +/** TDMA FR (TIA/EIA-136-420, VSELP 7.95kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_TDMAFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_TDMAFRTYPE; + + +/** TDMA EFR (TIA/EIA-136-410, ACELP 7.4kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_TDMAEFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_TDMAEFRTYPE; + + +/** PDC FR ( RCR-27, VSELP 6.7kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_PDCFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_PDCFRTYPE; + + +/** PDC EFR ( RCR-27, ACELP 6.7kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_PDCEFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_PDCEFRTYPE; + +/** PDC HR ( RCR-27, PSI-CELP 3.45kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_PDCHRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_PDCHRTYPE; + + +/** CDMA Rate types */ +typedef enum OMX_AUDIO_CDMARATETYPE { + OMX_AUDIO_CDMARateBlank = 0, /**< CDMA encoded frame is blank */ + OMX_AUDIO_CDMARateFull, /**< CDMA encoded frame in full rate */ + OMX_AUDIO_CDMARateHalf, /**< CDMA encoded frame in half rate */ + OMX_AUDIO_CDMARateQuarter, /**< CDMA encoded frame in quarter rate */ + OMX_AUDIO_CDMARateEighth, /**< CDMA encoded frame in eighth rate (DTX)*/ + OMX_AUDIO_CDMARateErasure, /**< CDMA erasure frame */ + OMX_AUDIO_CDMARateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_CDMARateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_CDMARateMax = 0x7FFFFFFF +} OMX_AUDIO_CDMARATETYPE; + + +/** QCELP8 (TIA/EIA-96, up to 8kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_QCELP8TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ +} OMX_AUDIO_PARAM_QCELP8TYPE; + + +/** QCELP13 ( CDMA, EIA/TIA-733, 13.3kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_QCELP13TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ +} OMX_AUDIO_PARAM_QCELP13TYPE; + + +/** EVRC ( CDMA, EIA/TIA-127, RCELP up to 8.55kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_EVRCTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< actual Frame rate */ + OMX_BOOL bRATE_REDUCon; /**< RATE_REDUCtion is requested for this frame */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ + OMX_BOOL bHiPassFilter; /**< Enable encoder's High Pass Filter */ + OMX_BOOL bNoiseSuppressor; /**< Enable encoder's noise suppressor pre-processing */ + OMX_BOOL bPostFilter; /**< Enable decoder's post Filter */ +} OMX_AUDIO_PARAM_EVRCTYPE; + + +/** SMV ( up to 8.55kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_SMVTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ + OMX_BOOL bRATE_REDUCon; /**< RATE_REDUCtion is requested for this frame */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 ??*/ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 ??*/ + OMX_BOOL bHiPassFilter; /**< Enable encoder's High Pass Filter ??*/ + OMX_BOOL bNoiseSuppressor; /**< Enable encoder's noise suppressor pre-processing */ + OMX_BOOL bPostFilter; /**< Enable decoder's post Filter ??*/ +} OMX_AUDIO_PARAM_SMVTYPE; + + +/** MIDI Format + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDIFORMATTYPE +{ + OMX_AUDIO_MIDIFormatUnknown = 0, /**< MIDI Format unknown or don't care */ + OMX_AUDIO_MIDIFormatSMF0, /**< Standard MIDI File Type 0 */ + OMX_AUDIO_MIDIFormatSMF1, /**< Standard MIDI File Type 1 */ + OMX_AUDIO_MIDIFormatSMF2, /**< Standard MIDI File Type 2 */ + OMX_AUDIO_MIDIFormatSPMIDI, /**< SP-MIDI */ + OMX_AUDIO_MIDIFormatXMF0, /**< eXtensible Music Format type 0 */ + OMX_AUDIO_MIDIFormatXMF1, /**< eXtensible Music Format type 1 */ + OMX_AUDIO_MIDIFormatMobileXMF, /**< Mobile XMF (eXtensible Music Format type 2) */ + OMX_AUDIO_MIDIFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDIFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDIFormatMax = 0x7FFFFFFF +} OMX_AUDIO_MIDIFORMATTYPE; + + +/** MIDI params + * @ingroup midi + */ +typedef struct OMX_AUDIO_PARAM_MIDITYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nFileSize; /**< size of the MIDI file in bytes, where the entire + MIDI file passed in, otherwise if 0x0, the MIDI data + is merged and streamed (instead of passed as an + entire MIDI file) */ + OMX_BU32 sMaxPolyphony; /**< Specifies the maximum simultaneous polyphonic + voices. A value of zero indicates that the default + polyphony of the device is used */ + OMX_BOOL bLoadDefaultSound; /**< Whether to load default sound + bank at initialization */ + OMX_AUDIO_MIDIFORMATTYPE eMidiFormat; /**< Version of the MIDI file */ +} OMX_AUDIO_PARAM_MIDITYPE; + + +/** Type of the MIDI sound bank + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDISOUNDBANKTYPE { + OMX_AUDIO_MIDISoundBankUnused = 0, /**< unused/unknown soundbank type */ + OMX_AUDIO_MIDISoundBankDLS1, /**< DLS version 1 */ + OMX_AUDIO_MIDISoundBankDLS2, /**< DLS version 2 */ + OMX_AUDIO_MIDISoundBankMobileDLSBase, /**< Mobile DLS, using the base functionality */ + OMX_AUDIO_MIDISoundBankMobileDLSPlusOptions, /**< Mobile DLS, using the specification-defined optional feature set */ + OMX_AUDIO_MIDISoundBankKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDISoundBankVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDISoundBankMax = 0x7FFFFFFF +} OMX_AUDIO_MIDISOUNDBANKTYPE; + + +/** Bank Layout describes how bank MSB & LSB are used in the DLS instrument definitions sound bank + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE { + OMX_AUDIO_MIDISoundBankLayoutUnused = 0, /**< unused/unknown soundbank type */ + OMX_AUDIO_MIDISoundBankLayoutGM, /**< GS layout (based on bank MSB 0x00) */ + OMX_AUDIO_MIDISoundBankLayoutGM2, /**< General MIDI 2 layout (using MSB 0x78/0x79, LSB 0x00) */ + OMX_AUDIO_MIDISoundBankLayoutUser, /**< Does not conform to any bank numbering standards */ + OMX_AUDIO_MIDISoundBankLayoutKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDISoundBankLayoutVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDISoundBankLayoutMax = 0x7FFFFFFF +} OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE; + + +/** MIDI params to load/unload user soundbank + * @ingroup midi + */ +typedef struct OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nDLSIndex; /**< DLS file index to be loaded */ + OMX_U32 nDLSSize; /**< Size in bytes */ + OMX_PTR pDLSData; /**< Pointer to DLS file data */ + OMX_AUDIO_MIDISOUNDBANKTYPE eMidiSoundBank; /**< Midi sound bank type enumeration */ + OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE eMidiSoundBankLayout; /**< Midi sound bank layout enumeration */ +} OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE; + + +/** Structure for Live MIDI events and MIP messages. + * (MIP = Maximum Instantaneous Polyphony; part of the SP-MIDI standard.) + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nMidiEventSize; /**< Size of immediate MIDI events or MIP message in bytes */ + OMX_U8 nMidiEvents[1]; /**< MIDI event array to be rendered immediately, or an + array for the MIP message buffer, where the size is + indicated by nMidiEventSize */ +} OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE; + + +/** MIDI sound bank/ program pair in a given channel + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nChannel; /**< Valid channel values range from 1 to 16 */ + OMX_U16 nIDProgram; /**< Valid program ID range is 1 to 128 */ + OMX_U16 nIDSoundBank; /**< Sound bank ID */ + OMX_U32 nUserSoundBankIndex;/**< User soundbank index, easier to access soundbanks + by index if multiple banks are present */ +} OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE; + + +/** MIDI control + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDICONTROLTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BS32 sPitchTransposition; /**< Pitch transposition in semitones, stored as Q22.10 + format based on JAVA MMAPI (JSR-135) requirement */ + OMX_BU32 sPlayBackRate; /**< Relative playback rate, stored as Q14.17 fixed-point + number based on JSR-135 requirement */ + OMX_BU32 sTempo ; /**< Tempo in beats per minute (BPM), stored as Q22.10 + fixed-point number based on JSR-135 requirement */ + OMX_U32 nMaxPolyphony; /**< Specifies the maximum simultaneous polyphonic + voices. A value of zero indicates that the default + polyphony of the device is used */ + OMX_U32 nNumRepeat; /**< Number of times to repeat playback */ + OMX_U32 nStopTime; /**< Time in milliseconds to indicate when playback + will stop automatically. Set to zero if not used */ + OMX_U16 nChannelMuteMask; /**< 16 bit mask for channel mute status */ + OMX_U16 nChannelSoloMask; /**< 16 bit mask for channel solo status */ + OMX_U32 nTrack0031MuteMask; /**< 32 bit mask for track mute status. Note: This is for tracks 0-31 */ + OMX_U32 nTrack3263MuteMask; /**< 32 bit mask for track mute status. Note: This is for tracks 32-63 */ + OMX_U32 nTrack0031SoloMask; /**< 32 bit mask for track solo status. Note: This is for tracks 0-31 */ + OMX_U32 nTrack3263SoloMask; /**< 32 bit mask for track solo status. Note: This is for tracks 32-63 */ + +} OMX_AUDIO_CONFIG_MIDICONTROLTYPE; + + +/** MIDI Playback States + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDIPLAYBACKSTATETYPE { + OMX_AUDIO_MIDIPlayBackStateUnknown = 0, /**< Unknown state or state does not map to + other defined states */ + OMX_AUDIO_MIDIPlayBackStateClosedEngaged, /**< No MIDI resource is currently open. + The MIDI engine is currently processing + MIDI events. */ + OMX_AUDIO_MIDIPlayBackStateParsing, /**< A MIDI resource is open and is being + primed. The MIDI engine is currently + processing MIDI events. */ + OMX_AUDIO_MIDIPlayBackStateOpenEngaged, /**< A MIDI resource is open and primed but + not playing. The MIDI engine is currently + processing MIDI events. The transition to + this state is only possible from the + OMX_AUDIO_MIDIPlayBackStatePlaying state, + when the 'playback head' reaches the end + of media data or the playback stops due + to stop time set.*/ + OMX_AUDIO_MIDIPlayBackStatePlaying, /**< A MIDI resource is open and currently + playing. The MIDI engine is currently + processing MIDI events.*/ + OMX_AUDIO_MIDIPlayBackStatePlayingPartially, /**< Best-effort playback due to SP-MIDI/DLS + resource constraints */ + OMX_AUDIO_MIDIPlayBackStatePlayingSilently, /**< Due to system resource constraints and + SP-MIDI content constraints, there is + no audible MIDI content during playback + currently. The situation may change if + resources are freed later.*/ + OMX_AUDIO_MIDIPlayBackStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDIPlayBackStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDIPlayBackStateMax = 0x7FFFFFFF +} OMX_AUDIO_MIDIPLAYBACKSTATETYPE; + + +/** MIDI status + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDISTATUSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U16 nNumTracks; /**< Number of MIDI tracks in the file, read only field. + NOTE: May not return a meaningful value until the entire + file is parsed and buffered. */ + OMX_U32 nDuration; /**< The length of the currently open MIDI resource + in milliseconds. NOTE: May not return a meaningful value + until the entire file is parsed and buffered. */ + OMX_U32 nPosition; /**< Current Position of the MIDI resource being played + in milliseconds */ + OMX_BOOL bVibra; /**< Does Vibra track exist? NOTE: May not return a meaningful + value until the entire file is parsed and buffered. */ + OMX_U32 nNumMetaEvents; /**< Total number of MIDI Meta Events in the currently + open MIDI resource. NOTE: May not return a meaningful value + until the entire file is parsed and buffered. */ + OMX_U32 nNumActiveVoices; /**< Number of active voices in the currently playing + MIDI resource. NOTE: May not return a meaningful value until + the entire file is parsed and buffered. */ + OMX_AUDIO_MIDIPLAYBACKSTATETYPE eMIDIPlayBackState; /**< MIDI playback state enumeration, read only field */ +} OMX_AUDIO_CONFIG_MIDISTATUSTYPE; + + +/** MIDI Meta Event structure one per Meta Event. + * MIDI Meta Events are like audio metadata, except that they are interspersed + * with the MIDI content throughout the file and are not localized in the header. + * As such, it is necessary to retrieve information about these Meta Events from + * the engine, as it encounters these Meta Events within the MIDI content. + * For example, SMF files can have up to 14 types of MIDI Meta Events (copyright, + * author, default tempo, etc.) scattered throughout the file. + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nIndex; /**< Index of Meta Event */ + OMX_U8 nMetaEventType; /**< Meta Event Type, 7bits (i.e. 0 - 127) */ + OMX_U32 nMetaEventSize; /**< size of the Meta Event in bytes */ + OMX_U32 nTrack; /**< track number for the meta event */ + OMX_U32 nPosition; /**< Position of the meta-event in milliseconds */ +} OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE; + + +/** MIDI Meta Event Data structure - one per Meta Event. + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nIndex; /**< Index of Meta Event */ + OMX_U32 nMetaEventSize; /**< size of the Meta Event in bytes */ + OMX_U8 nData[1]; /**< array of one or more bytes of meta data + as indicated by the nMetaEventSize field */ +} OMX_AUDIO_CONFIG__MIDIMETAEVENTDATATYPE; + + +/** Audio Volume adjustment for a port */ +typedef struct OMX_AUDIO_CONFIG_VOLUMETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's volume. Select the + output port to adjust the master + volume. */ + OMX_BOOL bLinear; /**< Is the volume to be set in linear (0.100) + or logarithmic scale (mB) */ + OMX_BS32 sVolume; /**< Volume linear setting in the 0..100 range, OR + Volume logarithmic setting for this port. The values + for volume are in mB (millibels = 1/100 dB) relative + to a gain of 1 (e.g. the output is the same as the + input level). Values are in mB from nMax + (maximum volume) to nMin mB (typically negative). + Since the volume is "voltage" + and not a "power", it takes a setting of + -600 mB to decrease the volume by 1/2. If + a component cannot accurately set the + volume to the requested value, it must + set the volume to the closest value BELOW + the requested value. When getting the + volume setting, the current actual volume + must be returned. */ +} OMX_AUDIO_CONFIG_VOLUMETYPE; + + +/** Audio Volume adjustment for a channel */ +typedef struct OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's volume. Select the + output port to adjust the master + volume. */ + OMX_U32 nChannel; /**< channel to select from 0 to N-1, + using OMX_ALL to apply volume settings + to all channels */ + OMX_BOOL bLinear; /**< Is the volume to be set in linear (0.100) or + logarithmic scale (mB) */ + OMX_BS32 sVolume; /**< Volume linear setting in the 0..100 range, OR + Volume logarithmic setting for this port. + The values for volume are in mB + (millibels = 1/100 dB) relative to a gain + of 1 (e.g. the output is the same as the + input level). Values are in mB from nMax + (maximum volume) to nMin mB (typically negative). + Since the volume is "voltage" + and not a "power", it takes a setting of + -600 mB to decrease the volume by 1/2. If + a component cannot accurately set the + volume to the requested value, it must + set the volume to the closest value BELOW + the requested value. When getting the + volume setting, the current actual volume + must be returned. */ + OMX_BOOL bIsMIDI; /**< TRUE if nChannel refers to a MIDI channel, + FALSE otherwise */ +} OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE; + + +/** Audio balance setting */ +typedef struct OMX_AUDIO_CONFIG_BALANCETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's balance. Select the + output port to adjust the master + balance. */ + OMX_S32 nBalance; /**< balance setting for this port + (-100 to 100, where -100 indicates + all left, and no right */ +} OMX_AUDIO_CONFIG_BALANCETYPE; + + +/** Audio Port mute */ +typedef struct OMX_AUDIO_CONFIG_MUTETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's mute. Select the + output port to adjust the master + mute. */ + OMX_BOOL bMute; /**< Mute setting for this port */ +} OMX_AUDIO_CONFIG_MUTETYPE; + + +/** Audio Channel mute */ +typedef struct OMX_AUDIO_CONFIG_CHANNELMUTETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannel; /**< channel to select from 0 to N-1, + using OMX_ALL to apply mute settings + to all channels */ + OMX_BOOL bMute; /**< Mute setting for this channel */ + OMX_BOOL bIsMIDI; /**< TRUE if nChannel refers to a MIDI channel, + FALSE otherwise */ +} OMX_AUDIO_CONFIG_CHANNELMUTETYPE; + + + +/** Enable / Disable for loudness control, which boosts bass and to a + * smaller extent high end frequencies to compensate for hearing + * ability at the extreme ends of the audio spectrum + */ +typedef struct OMX_AUDIO_CONFIG_LOUDNESSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bLoudness; /**< Enable/disable for loudness */ +} OMX_AUDIO_CONFIG_LOUDNESSTYPE; + + +/** Enable / Disable for bass, which controls low frequencies + */ +typedef struct OMX_AUDIO_CONFIG_BASSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for bass control */ + OMX_S32 nBass; /**< bass setting for the port, as a + continuous value from -100 to 100 + (0 means no change in bass level)*/ +} OMX_AUDIO_CONFIG_BASSTYPE; + + +/** Enable / Disable for treble, which controls high frequencies tones + */ +typedef struct OMX_AUDIO_CONFIG_TREBLETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for treble control */ + OMX_S32 nTreble; /**< treble setting for the port, as a + continuous value from -100 to 100 + (0 means no change in treble level) */ +} OMX_AUDIO_CONFIG_TREBLETYPE; + + +/** An equalizer is typically used for two reasons: to compensate for an + * sub-optimal frequency response of a system to make it sound more natural + * or to create intentionally some unnatural coloring to the sound to create + * an effect. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_EQUALIZERTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for equalizer */ + OMX_BU32 sBandIndex; /**< Band number to be set. Upper Limit is + N-1, where N is the number of bands, lower limit is 0 */ + OMX_BU32 sCenterFreq; /**< Center frequecies in Hz. This is a + read only element and is used to determine + the lower, center and upper frequency of + this band. */ + OMX_BS32 sBandLevel; /**< band level in millibels */ +} OMX_AUDIO_CONFIG_EQUALIZERTYPE; + + +/** Stereo widening mode type + * @ingroup effects + */ +typedef enum OMX_AUDIO_STEREOWIDENINGTYPE { + OMX_AUDIO_StereoWideningHeadphones, /**< Stereo widening for loudspeakers */ + OMX_AUDIO_StereoWideningLoudspeakers, /**< Stereo widening for closely spaced loudspeakers */ + OMX_AUDIO_StereoWideningKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_StereoWideningVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_StereoWideningMax = 0x7FFFFFFF +} OMX_AUDIO_STEREOWIDENINGTYPE; + + +/** Control for stereo widening, which is a special 2-channel + * case of the audio virtualizer effect. For example, for 5.1-channel + * output, it translates to virtual surround sound. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for stereo widening control */ + OMX_AUDIO_STEREOWIDENINGTYPE eWideningType; /**< Stereo widening algorithm type */ + OMX_U32 nStereoWidening; /**< stereo widening setting for the port, + as a continuous value from 0 to 100 */ +} OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE; + + +/** The chorus effect (or ``choralizer'') is any signal processor which makes + * one sound source (such as a voice) sound like many such sources singing + * (or playing) in unison. Since performance in unison is never exact, chorus + * effects simulate this by making independently modified copies of the input + * signal. Modifications may include (1) delay, (2) frequency shift, and + * (3) amplitude modulation. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_CHORUSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for chorus */ + OMX_BU32 sDelay; /**< average delay in milliseconds */ + OMX_BU32 sModulationRate; /**< rate of modulation in millihertz */ + OMX_U32 nModulationDepth; /**< depth of modulation as a percentage of + delay (i.e. 0 to 100) */ + OMX_BU32 nFeedback; /**< Feedback from chorus output to input in percentage */ +} OMX_AUDIO_CONFIG_CHORUSTYPE; + + +/** Reverberation is part of the reflected sound that follows the early + * reflections. In a typical room, this consists of a dense succession of + * echoes whose energy decays exponentially. The reverberation effect structure + * as defined here includes both (early) reflections as well as (late) reverberations. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_REVERBERATIONTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for reverberation control */ + OMX_BS32 sRoomLevel; /**< Intensity level for the whole room effect + (i.e. both early reflections and late + reverberation) in millibels */ + OMX_BS32 sRoomHighFreqLevel; /**< Attenuation at high frequencies + relative to the intensity at low + frequencies in millibels */ + OMX_BS32 sReflectionsLevel; /**< Intensity level of early reflections + (relative to room value), in millibels */ + OMX_BU32 sReflectionsDelay; /**< Delay time of the first reflection relative + to the direct path, in milliseconds */ + OMX_BS32 sReverbLevel; /**< Intensity level of late reverberation + relative to room level, in millibels */ + OMX_BU32 sReverbDelay; /**< Time delay from the first early reflection + to the beginning of the late reverberation + section, in milliseconds */ + OMX_BU32 sDecayTime; /**< Late reverberation decay time at low + frequencies, in milliseconds */ + OMX_BU32 nDecayHighFreqRatio; /**< Ratio of high frequency decay time relative + to low frequency decay time in percent */ + OMX_U32 nDensity; /**< Modal density in the late reverberation decay, + in percent (i.e. 0 - 100) */ + OMX_U32 nDiffusion; /**< Echo density in the late reverberation decay, + in percent (i.e. 0 - 100) */ + OMX_BU32 sReferenceHighFreq; /**< Reference high frequency in Hertz. This is + the frequency used as the reference for all + the high-frequency settings above */ + +} OMX_AUDIO_CONFIG_REVERBERATIONTYPE; + + +/** Possible settings for the Echo Cancelation structure to use + * @ingroup effects + */ +typedef enum OMX_AUDIO_ECHOCANTYPE { + OMX_AUDIO_EchoCanOff = 0, /**< Echo Cancellation is disabled */ + OMX_AUDIO_EchoCanNormal, /**< Echo Cancellation normal operation - + echo from plastics and face */ + OMX_AUDIO_EchoCanHFree, /**< Echo Cancellation optimized for + Hands Free operation */ + OMX_AUDIO_EchoCanCarKit, /**< Echo Cancellation optimized for + Car Kit (longer echo) */ + OMX_AUDIO_EchoCanKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_EchoCanVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_EchoCanMax = 0x7FFFFFFF +} OMX_AUDIO_ECHOCANTYPE; + + +/** Enable / Disable for echo cancelation, which removes undesired echo's + * from the audio + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_AUDIO_ECHOCANTYPE eEchoCancelation; /**< Echo cancelation settings */ +} OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE; + + +/** Enable / Disable for noise reduction, which undesired noise from + * the audio + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bNoiseReduction; /**< Enable/disable for noise reduction */ +} OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE; + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/phonelibs/android_frameworks_native/include/media/openmax/OMX_AudioExt.h b/phonelibs/android_frameworks_native/include/media/openmax/OMX_AudioExt.h new file mode 100644 index 00000000000000..2a1c3f2e1815ec --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/openmax/OMX_AudioExt.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2010 The Khronos Group Inc. + * + * 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. + * + */ + +/** OMX_AudioExt.h - OpenMax IL version 1.1.2 + * The OMX_AudioExt header file contains extensions to the + * definitions used by both the application and the component to + * access video items. + */ + +#ifndef OMX_AudioExt_h +#define OMX_AudioExt_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Each OMX header shall include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ +#include + +#define OMX_AUDIO_AACToolAndroidSSBR (OMX_AUDIO_AACToolVendor << 0) /**< SSBR: MPEG-4 Single-rate (downsampled) Spectral Band Replication tool allowed or active */ +#define OMX_AUDIO_AACToolAndroidDSBR (OMX_AUDIO_AACToolVendor << 1) /**< DSBR: MPEG-4 Dual-rate Spectral Band Replication tool allowed or active */ + +typedef enum OMX_AUDIO_CODINGEXTTYPE { + OMX_AUDIO_CodingAndroidUnused = OMX_AUDIO_CodingKhronosExtensions + 0x00100000, + OMX_AUDIO_CodingAndroidAC3, /**< AC3 encoded data */ + OMX_AUDIO_CodingAndroidOPUS, /**< OPUS encoded data */ + OMX_AUDIO_CodingAndroidEAC3, /**< EAC3 encoded data */ +} OMX_AUDIO_CODINGEXTTYPE; + +typedef struct OMX_AUDIO_PARAM_ANDROID_AC3TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ +} OMX_AUDIO_PARAM_ANDROID_AC3TYPE; + +typedef struct OMX_AUDIO_PARAM_ANDROID_EAC3TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ +} OMX_AUDIO_PARAM_ANDROID_EAC3TYPE; + +typedef struct OMX_AUDIO_PARAM_ANDROID_OPUSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the encoded data data. Use 0 for variable + rate or unknown bit rates. Encoding is set to the + bitrate closest to specified value (in bps) */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should + limit the audio signal. Use 0 to let encoder decide */ +} OMX_AUDIO_PARAM_ANDROID_OPUSTYPE; + +typedef struct OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_S32 nMaxOutputChannels; /**< Maximum channel count to be output, -1 if unspecified, 0 if downmixing disabled */ + OMX_S32 nDrcCut; /**< The DRC attenuation factor, between 0 and 127, -1 if unspecified */ + OMX_S32 nDrcBoost; /**< The DRC amplification factor, between 0 and 127, -1 if unspecified */ + OMX_S32 nHeavyCompression; /**< 0 for light compression, 1 for heavy compression, -1 if unspecified */ + OMX_S32 nTargetReferenceLevel; /**< Target reference level, between 0 and 127, -1 if unspecified */ + OMX_S32 nEncodedTargetLevel; /**< Target reference level assumed at the encoder, between 0 and 127, -1 if unspecified */ + OMX_S32 nPCMLimiterEnable; /**< Signal level limiting, 0 for disable, 1 for enable, -1 if unspecified */ +} OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* OMX_AudioExt_h */ +/* File EOF */ diff --git a/phonelibs/android_frameworks_native/include/media/openmax/OMX_Component.h b/phonelibs/android_frameworks_native/include/media/openmax/OMX_Component.h new file mode 100644 index 00000000000000..0dc2c769725e76 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/openmax/OMX_Component.h @@ -0,0 +1,596 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** OMX_Component.h - OpenMax IL version 1.1.2 + * The OMX_Component header file contains the definitions used to define + * the public interface of a component. This header file is intended to + * be used by both the application and the component. + */ + +#ifndef OMX_Component_h +#define OMX_Component_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + +/* Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include +#include +#include +#include + +/** @ingroup comp */ +typedef enum OMX_PORTDOMAINTYPE { + OMX_PortDomainAudio, + OMX_PortDomainVideo, + OMX_PortDomainImage, + OMX_PortDomainOther, + OMX_PortDomainKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_PortDomainVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_PortDomainMax = 0x7ffffff +} OMX_PORTDOMAINTYPE; + +/** @ingroup comp */ +typedef struct OMX_PARAM_PORTDEFINITIONTYPE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port number the structure applies to */ + OMX_DIRTYPE eDir; /**< Direction (input or output) of this port */ + OMX_U32 nBufferCountActual; /**< The actual number of buffers allocated on this port */ + OMX_U32 nBufferCountMin; /**< The minimum number of buffers this port requires */ + OMX_U32 nBufferSize; /**< Size, in bytes, for buffers to be used for this channel */ + OMX_BOOL bEnabled; /**< Ports default to enabled and are enabled/disabled by + OMX_CommandPortEnable/OMX_CommandPortDisable. + When disabled a port is unpopulated. A disabled port + is not populated with buffers on a transition to IDLE. */ + OMX_BOOL bPopulated; /**< Port is populated with all of its buffers as indicated by + nBufferCountActual. A disabled port is always unpopulated. + An enabled port is populated on a transition to OMX_StateIdle + and unpopulated on a transition to loaded. */ + OMX_PORTDOMAINTYPE eDomain; /**< Domain of the port. Determines the contents of metadata below. */ + union { + OMX_AUDIO_PORTDEFINITIONTYPE audio; + OMX_VIDEO_PORTDEFINITIONTYPE video; + OMX_IMAGE_PORTDEFINITIONTYPE image; + OMX_OTHER_PORTDEFINITIONTYPE other; + } format; + OMX_BOOL bBuffersContiguous; + OMX_U32 nBufferAlignment; +} OMX_PARAM_PORTDEFINITIONTYPE; + +/** @ingroup comp */ +typedef struct OMX_PARAM_U32TYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nU32; /**< U32 value */ +} OMX_PARAM_U32TYPE; + +/** @ingroup rpm */ +typedef enum OMX_SUSPENSIONPOLICYTYPE { + OMX_SuspensionDisabled, /**< No suspension; v1.0 behavior */ + OMX_SuspensionEnabled, /**< Suspension allowed */ + OMX_SuspensionPolicyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_SuspensionPolicyStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_SuspensionPolicyMax = 0x7fffffff +} OMX_SUSPENSIONPOLICYTYPE; + +/** @ingroup rpm */ +typedef struct OMX_PARAM_SUSPENSIONPOLICYTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_SUSPENSIONPOLICYTYPE ePolicy; +} OMX_PARAM_SUSPENSIONPOLICYTYPE; + +/** @ingroup rpm */ +typedef enum OMX_SUSPENSIONTYPE { + OMX_NotSuspended, /**< component is not suspended */ + OMX_Suspended, /**< component is suspended */ + OMX_SuspensionKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_SuspensionVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_SuspendMax = 0x7FFFFFFF +} OMX_SUSPENSIONTYPE; + +/** @ingroup rpm */ +typedef struct OMX_PARAM_SUSPENSIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_SUSPENSIONTYPE eType; +} OMX_PARAM_SUSPENSIONTYPE ; + +typedef struct OMX_CONFIG_BOOLEANTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bEnabled; +} OMX_CONFIG_BOOLEANTYPE; + +/* Parameter specifying the content uri to use. */ +/** @ingroup cp */ +typedef struct OMX_PARAM_CONTENTURITYPE +{ + OMX_U32 nSize; /**< size of the structure in bytes, including + actual URI name */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U8 contentURI[1]; /**< The URI name */ +} OMX_PARAM_CONTENTURITYPE; + +/* Parameter specifying the pipe to use. */ +/** @ingroup cp */ +typedef struct OMX_PARAM_CONTENTPIPETYPE +{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_HANDLETYPE hPipe; /**< The pipe handle*/ +} OMX_PARAM_CONTENTPIPETYPE; + +/** @ingroup rpm */ +typedef struct OMX_RESOURCECONCEALMENTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_BOOL bResourceConcealmentForbidden; /**< disallow the use of resource concealment + methods (like degrading algorithm quality to + lower resource consumption or functional bypass) + on a component as a resolution to resource conflicts. */ +} OMX_RESOURCECONCEALMENTTYPE; + + +/** @ingroup metadata */ +typedef enum OMX_METADATACHARSETTYPE { + OMX_MetadataCharsetUnknown = 0, + OMX_MetadataCharsetASCII, + OMX_MetadataCharsetBinary, + OMX_MetadataCharsetCodePage1252, + OMX_MetadataCharsetUTF8, + OMX_MetadataCharsetJavaConformantUTF8, + OMX_MetadataCharsetUTF7, + OMX_MetadataCharsetImapUTF7, + OMX_MetadataCharsetUTF16LE, + OMX_MetadataCharsetUTF16BE, + OMX_MetadataCharsetGB12345, + OMX_MetadataCharsetHZGB2312, + OMX_MetadataCharsetGB2312, + OMX_MetadataCharsetGB18030, + OMX_MetadataCharsetGBK, + OMX_MetadataCharsetBig5, + OMX_MetadataCharsetISO88591, + OMX_MetadataCharsetISO88592, + OMX_MetadataCharsetISO88593, + OMX_MetadataCharsetISO88594, + OMX_MetadataCharsetISO88595, + OMX_MetadataCharsetISO88596, + OMX_MetadataCharsetISO88597, + OMX_MetadataCharsetISO88598, + OMX_MetadataCharsetISO88599, + OMX_MetadataCharsetISO885910, + OMX_MetadataCharsetISO885913, + OMX_MetadataCharsetISO885914, + OMX_MetadataCharsetISO885915, + OMX_MetadataCharsetShiftJIS, + OMX_MetadataCharsetISO2022JP, + OMX_MetadataCharsetISO2022JP1, + OMX_MetadataCharsetISOEUCJP, + OMX_MetadataCharsetSMS7Bit, + OMX_MetadataCharsetKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MetadataCharsetVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_MetadataCharsetTypeMax= 0x7FFFFFFF +} OMX_METADATACHARSETTYPE; + +/** @ingroup metadata */ +typedef enum OMX_METADATASCOPETYPE +{ + OMX_MetadataScopeAllLevels, + OMX_MetadataScopeTopLevel, + OMX_MetadataScopePortLevel, + OMX_MetadataScopeNodeLevel, + OMX_MetadataScopeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MetadataScopeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_MetadataScopeTypeMax = 0x7fffffff +} OMX_METADATASCOPETYPE; + +/** @ingroup metadata */ +typedef enum OMX_METADATASEARCHMODETYPE +{ + OMX_MetadataSearchValueSizeByIndex, + OMX_MetadataSearchItemByIndex, + OMX_MetadataSearchNextItemByKey, + OMX_MetadataSearchKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MetadataSearchVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_MetadataSearchTypeMax = 0x7fffffff +} OMX_METADATASEARCHMODETYPE; +/** @ingroup metadata */ +typedef struct OMX_CONFIG_METADATAITEMCOUNTTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_METADATASCOPETYPE eScopeMode; + OMX_U32 nScopeSpecifier; + OMX_U32 nMetadataItemCount; +} OMX_CONFIG_METADATAITEMCOUNTTYPE; + +/** @ingroup metadata */ +typedef struct OMX_CONFIG_METADATAITEMTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_METADATASCOPETYPE eScopeMode; + OMX_U32 nScopeSpecifier; + OMX_U32 nMetadataItemIndex; + OMX_METADATASEARCHMODETYPE eSearchMode; + OMX_METADATACHARSETTYPE eKeyCharset; + OMX_U8 nKeySizeUsed; + OMX_U8 nKey[128]; + OMX_METADATACHARSETTYPE eValueCharset; + OMX_STRING sLanguageCountry; + OMX_U32 nValueMaxSize; + OMX_U32 nValueSizeUsed; + OMX_U8 nValue[1]; +} OMX_CONFIG_METADATAITEMTYPE; + +/* @ingroup metadata */ +typedef struct OMX_CONFIG_CONTAINERNODECOUNTTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bAllKeys; + OMX_U32 nParentNodeID; + OMX_U32 nNumNodes; +} OMX_CONFIG_CONTAINERNODECOUNTTYPE; + +/** @ingroup metadata */ +typedef struct OMX_CONFIG_CONTAINERNODEIDTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bAllKeys; + OMX_U32 nParentNodeID; + OMX_U32 nNodeIndex; + OMX_U32 nNodeID; + OMX_STRING cNodeName; + OMX_BOOL bIsLeafType; +} OMX_CONFIG_CONTAINERNODEIDTYPE; + +/** @ingroup metadata */ +typedef struct OMX_PARAM_METADATAFILTERTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bAllKeys; /* if true then this structure refers to all keys and + * the three key fields below are ignored */ + OMX_METADATACHARSETTYPE eKeyCharset; + OMX_U32 nKeySizeUsed; + OMX_U8 nKey [128]; + OMX_U32 nLanguageCountrySizeUsed; + OMX_U8 nLanguageCountry[128]; + OMX_BOOL bEnabled; /* if true then key is part of filter (e.g. + * retained for query later). If false then + * key is not part of filter */ +} OMX_PARAM_METADATAFILTERTYPE; + +/** The OMX_HANDLETYPE structure defines the component handle. The component + * handle is used to access all of the component's public methods and also + * contains pointers to the component's private data area. The component + * handle is initialized by the OMX core (with help from the component) + * during the process of loading the component. After the component is + * successfully loaded, the application can safely access any of the + * component's public functions (although some may return an error because + * the state is inappropriate for the access). + * + * @ingroup comp + */ +typedef struct OMX_COMPONENTTYPE +{ + /** The size of this structure, in bytes. It is the responsibility + of the allocator of this structure to fill in this value. Since + this structure is allocated by the GetHandle function, this + function will fill in this value. */ + OMX_U32 nSize; + + /** nVersion is the version of the OMX specification that the structure + is built against. It is the responsibility of the creator of this + structure to initialize this value and every user of this structure + should verify that it knows how to use the exact version of + this structure found herein. */ + OMX_VERSIONTYPE nVersion; + + /** pComponentPrivate is a pointer to the component private data area. + This member is allocated and initialized by the component when the + component is first loaded. The application should not access this + data area. */ + OMX_PTR pComponentPrivate; + + /** pApplicationPrivate is a pointer that is a parameter to the + OMX_GetHandle method, and contains an application private value + provided by the IL client. This application private data is + returned to the IL Client by OMX in all callbacks */ + OMX_PTR pApplicationPrivate; + + /** refer to OMX_GetComponentVersion in OMX_core.h or the OMX IL + specification for details on the GetComponentVersion method. + */ + OMX_ERRORTYPE (*GetComponentVersion)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_STRING pComponentName, + OMX_OUT OMX_VERSIONTYPE* pComponentVersion, + OMX_OUT OMX_VERSIONTYPE* pSpecVersion, + OMX_OUT OMX_UUIDTYPE* pComponentUUID); + + /** refer to OMX_SendCommand in OMX_core.h or the OMX IL + specification for details on the SendCommand method. + */ + OMX_ERRORTYPE (*SendCommand)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_COMMANDTYPE Cmd, + OMX_IN OMX_U32 nParam1, + OMX_IN OMX_PTR pCmdData); + + /** refer to OMX_GetParameter in OMX_core.h or the OMX IL + specification for details on the GetParameter method. + */ + OMX_ERRORTYPE (*GetParameter)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure); + + + /** refer to OMX_SetParameter in OMX_core.h or the OMX IL + specification for details on the SetParameter method. + */ + OMX_ERRORTYPE (*SetParameter)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure); + + + /** refer to OMX_GetConfig in OMX_core.h or the OMX IL + specification for details on the GetConfig method. + */ + OMX_ERRORTYPE (*GetConfig)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_INOUT OMX_PTR pComponentConfigStructure); + + + /** refer to OMX_SetConfig in OMX_core.h or the OMX IL + specification for details on the SetConfig method. + */ + OMX_ERRORTYPE (*SetConfig)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure); + + + /** refer to OMX_GetExtensionIndex in OMX_core.h or the OMX IL + specification for details on the GetExtensionIndex method. + */ + OMX_ERRORTYPE (*GetExtensionIndex)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE* pIndexType); + + + /** refer to OMX_GetState in OMX_core.h or the OMX IL + specification for details on the GetState method. + */ + OMX_ERRORTYPE (*GetState)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_STATETYPE* pState); + + + /** The ComponentTunnelRequest method will interact with another OMX + component to determine if tunneling is possible and to setup the + tunneling. The return codes for this method can be used to + determine if tunneling is not possible, or if tunneling is not + supported. + + Base profile components (i.e. non-interop) do not support this + method and should return OMX_ErrorNotImplemented + + The interop profile component MUST support tunneling to another + interop profile component with a compatible port parameters. + A component may also support proprietary communication. + + If proprietary communication is supported the negotiation of + proprietary communication is done outside of OMX in a vendor + specific way. It is only required that the proper result be + returned and the details of how the setup is done is left + to the component implementation. + + When this method is invoked when nPort in an output port, the + component will: + 1. Populate the pTunnelSetup structure with the output port's + requirements and constraints for the tunnel. + + When this method is invoked when nPort in an input port, the + component will: + 1. Query the necessary parameters from the output port to + determine if the ports are compatible for tunneling + 2. If the ports are compatible, the component should store + the tunnel step provided by the output port + 3. Determine which port (either input or output) is the buffer + supplier, and call OMX_SetParameter on the output port to + indicate this selection. + + The component will return from this call within 5 msec. + + @param [in] hComp + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle method. + @param [in] nPort + nPort is used to select the port on the component to be used + for tunneling. + @param [in] hTunneledComp + Handle of the component to tunnel with. This is the component + handle returned by the call to the OMX_GetHandle method. When + this parameter is 0x0 the component should setup the port for + communication with the application / IL Client. + @param [in] nPortOutput + nPortOutput is used indicate the port the component should + tunnel with. + @param [in] pTunnelSetup + Pointer to the tunnel setup structure. When nPort is an output port + the component should populate the fields of this structure. When + When nPort is an input port the component should review the setup + provided by the component with the output port. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup tun + */ + + OMX_ERRORTYPE (*ComponentTunnelRequest)( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 nPort, + OMX_IN OMX_HANDLETYPE hTunneledComp, + OMX_IN OMX_U32 nTunneledPort, + OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup); + + /** refer to OMX_UseBuffer in OMX_core.h or the OMX IL + specification for details on the UseBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*UseBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes, + OMX_IN OMX_U8* pBuffer); + + /** refer to OMX_AllocateBuffer in OMX_core.h or the OMX IL + specification for details on the AllocateBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*AllocateBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes); + + /** refer to OMX_FreeBuffer in OMX_core.h or the OMX IL + specification for details on the FreeBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*FreeBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** refer to OMX_EmptyThisBuffer in OMX_core.h or the OMX IL + specification for details on the EmptyThisBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*EmptyThisBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** refer to OMX_FillThisBuffer in OMX_core.h or the OMX IL + specification for details on the FillThisBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*FillThisBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** The SetCallbacks method is used by the core to specify the callback + structure from the application to the component. This is a blocking + call. The component will return from this call within 5 msec. + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @param [in] pCallbacks + pointer to an OMX_CALLBACKTYPE structure used to provide the + callback information to the component + @param [in] pAppData + pointer to an application defined value. It is anticipated that + the application will pass a pointer to a data structure or a "this + pointer" in this area to allow the callback (in the application) + to determine the context of the call + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + */ + OMX_ERRORTYPE (*SetCallbacks)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_CALLBACKTYPE* pCallbacks, + OMX_IN OMX_PTR pAppData); + + /** ComponentDeInit method is used to deinitialize the component + providing a means to free any resources allocated at component + initialization. NOTE: After this call the component handle is + not valid for further use. + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + */ + OMX_ERRORTYPE (*ComponentDeInit)( + OMX_IN OMX_HANDLETYPE hComponent); + + /** @ingroup buf */ + OMX_ERRORTYPE (*UseEGLImage)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN void* eglImage); + + OMX_ERRORTYPE (*ComponentRoleEnum)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_U8 *cRole, + OMX_IN OMX_U32 nIndex); + +} OMX_COMPONENTTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/phonelibs/android_frameworks_native/include/media/openmax/OMX_ContentPipe.h b/phonelibs/android_frameworks_native/include/media/openmax/OMX_ContentPipe.h new file mode 100644 index 00000000000000..0224c8a2eed1bf --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/openmax/OMX_ContentPipe.h @@ -0,0 +1,212 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** OMX_ContentPipe.h - OpenMax IL version 1.1.2 + * The OMX_ContentPipe header file contains the definitions used to define + * the public interface for content piples. This header file is intended to + * be used by the component. + */ + +#ifndef OMX_CONTENTPIPE_H +#define OMX_CONTENTPIPE_H + +#ifndef KD_EACCES +/* OpenKODE error codes. CPResult values may be zero (indicating success + or one of the following values) */ +#define KD_EACCES (1) +#define KD_EADDRINUSE (2) +#define KD_EAGAIN (5) +#define KD_EBADF (7) +#define KD_EBUSY (8) +#define KD_ECONNREFUSED (9) +#define KD_ECONNRESET (10) +#define KD_EDEADLK (11) +#define KD_EDESTADDRREQ (12) +#define KD_ERANGE (35) +#define KD_EEXIST (13) +#define KD_EFBIG (14) +#define KD_EHOSTUNREACH (15) +#define KD_EINVAL (17) +#define KD_EIO (18) +#define KD_EISCONN (20) +#define KD_EISDIR (21) +#define KD_EMFILE (22) +#define KD_ENAMETOOLONG (23) +#define KD_ENOENT (24) +#define KD_ENOMEM (25) +#define KD_ENOSPC (26) +#define KD_ENOSYS (27) +#define KD_ENOTCONN (28) +#define KD_EPERM (33) +#define KD_ETIMEDOUT (36) +#define KD_EILSEQ (19) +#endif + +/** Map types from OMX standard types only here so interface is as generic as possible. */ +typedef OMX_U32 CPresult; +typedef char * CPstring; +typedef void * CPhandle; +typedef OMX_U32 CPuint; +typedef OMX_S32 CPint; +typedef char CPbyte; +typedef OMX_BOOL CPbool; + +/** enumeration of origin types used in the CP_PIPETYPE's Seek function + * @ingroup cp + */ +typedef enum CP_ORIGINTYPE { + CP_OriginBegin, + CP_OriginCur, + CP_OriginEnd, + CP_OriginKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_OriginVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_OriginMax = 0X7FFFFFFF +} CP_ORIGINTYPE; + +/** enumeration of contact access types used in the CP_PIPETYPE's Open function + * @ingroup cp + */ +typedef enum CP_ACCESSTYPE { + CP_AccessRead, + CP_AccessWrite, + CP_AccessReadWrite, + CP_AccessKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_AccessVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_AccessMax = 0X7FFFFFFF +} CP_ACCESSTYPE; + +/** enumeration of results returned by the CP_PIPETYPE's CheckAvailableBytes function + * @ingroup cp + */ +typedef enum CP_CHECKBYTESRESULTTYPE +{ + CP_CheckBytesOk, /**< There are at least the request number + of bytes available */ + CP_CheckBytesNotReady, /**< The pipe is still retrieving bytes + and presently lacks sufficient bytes. + Client will be called when they are + sufficient bytes are available. */ + CP_CheckBytesInsufficientBytes, /**< The pipe has retrieved all bytes + but those available are less than those + requested */ + CP_CheckBytesAtEndOfStream, /**< The pipe has reached the end of stream + and no more bytes are available. */ + CP_CheckBytesOutOfBuffers, /**< All read/write buffers are currently in use. */ + CP_CheckBytesKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_CheckBytesVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_CheckBytesMax = 0X7FFFFFFF +} CP_CHECKBYTESRESULTTYPE; + +/** enumeration of content pipe events sent to the client callback. + * @ingroup cp + */ +typedef enum CP_EVENTTYPE{ + CP_BytesAvailable, /** bytes requested in a CheckAvailableBytes call are now available*/ + CP_Overflow, /** enumeration of content pipe events sent to the client callback*/ + CP_PipeDisconnected, /** enumeration of content pipe events sent to the client callback*/ + CP_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_EventMax = 0X7FFFFFFF +} CP_EVENTTYPE; + +/** content pipe definition + * @ingroup cp + */ +typedef struct CP_PIPETYPE +{ + /** Open a content stream for reading or writing. */ + CPresult (*Open)( CPhandle* hContent, CPstring szURI, CP_ACCESSTYPE eAccess ); + + /** Close a content stream. */ + CPresult (*Close)( CPhandle hContent ); + + /** Create a content source and open it for writing. */ + CPresult (*Create)( CPhandle *hContent, CPstring szURI ); + + /** Check the that specified number of bytes are available for reading or writing (depending on access type).*/ + CPresult (*CheckAvailableBytes)( CPhandle hContent, CPuint nBytesRequested, CP_CHECKBYTESRESULTTYPE *eResult ); + + /** Seek to certain position in the content relative to the specified origin. */ + CPresult (*SetPosition)( CPhandle hContent, CPint nOffset, CP_ORIGINTYPE eOrigin); + + /** Retrieve the current position relative to the start of the content. */ + CPresult (*GetPosition)( CPhandle hContent, CPuint *pPosition); + + /** Retrieve data of the specified size from the content stream (advance content pointer by size of data). + Note: pipe client provides pointer. This function is appropriate for small high frequency reads. */ + CPresult (*Read)( CPhandle hContent, CPbyte *pData, CPuint nSize); + + /** Retrieve a buffer allocated by the pipe that contains the requested number of bytes. + Buffer contains the next block of bytes, as specified by nSize, of the content. nSize also + returns the size of the block actually read. Content pointer advances the by the returned size. + Note: pipe provides pointer. This function is appropriate for large reads. The client must call + ReleaseReadBuffer when done with buffer. + + In some cases the requested block may not reside in contiguous memory within the + pipe implementation. For instance if the pipe leverages a circular buffer then the requested + block may straddle the boundary of the circular buffer. By default a pipe implementation + performs a copy in this case to provide the block to the pipe client in one contiguous buffer. + If, however, the client sets bForbidCopy, then the pipe returns only those bytes preceding the memory + boundary. Here the client may retrieve the data in segments over successive calls. */ + CPresult (*ReadBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint *nSize, CPbool bForbidCopy); + + /** Release a buffer obtained by ReadBuffer back to the pipe. */ + CPresult (*ReleaseReadBuffer)(CPhandle hContent, CPbyte *pBuffer); + + /** Write data of the specified size to the content (advance content pointer by size of data). + Note: pipe client provides pointer. This function is appropriate for small high frequency writes. */ + CPresult (*Write)( CPhandle hContent, CPbyte *data, CPuint nSize); + + /** Retrieve a buffer allocated by the pipe used to write data to the content. + Client will fill buffer with output data. Note: pipe provides pointer. This function is appropriate + for large writes. The client must call WriteBuffer when done it has filled the buffer with data.*/ + CPresult (*GetWriteBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint nSize); + + /** Deliver a buffer obtained via GetWriteBuffer to the pipe. Pipe will write the + the contents of the buffer to content and advance content pointer by the size of the buffer */ + CPresult (*WriteBuffer)( CPhandle hContent, CPbyte *pBuffer, CPuint nFilledSize); + + /** Register a per-handle client callback with the content pipe. */ + CPresult (*RegisterCallback)( CPhandle hContent, CPresult (*ClientCallback)(CP_EVENTTYPE eEvent, CPuint iParam)); + +} CP_PIPETYPE; + +#endif + diff --git a/phonelibs/android_frameworks_native/include/media/openmax/OMX_Core.h b/phonelibs/android_frameworks_native/include/media/openmax/OMX_Core.h new file mode 100644 index 00000000000000..f746a69d2ad062 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/openmax/OMX_Core.h @@ -0,0 +1,1464 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** OMX_Core.h - OpenMax IL version 1.1.2 + * The OMX_Core header file contains the definitions used by both the + * application and the component to access common items. + */ + +#ifndef OMX_Core_h +#define OMX_Core_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Each OMX header shall include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + + +/** The OMX_COMMANDTYPE enumeration is used to specify the action in the + * OMX_SendCommand macro. + * @ingroup core + */ +typedef enum OMX_COMMANDTYPE +{ + OMX_CommandStateSet, /**< Change the component state */ + OMX_CommandFlush, /**< Flush the data queue(s) of a component */ + OMX_CommandPortDisable, /**< Disable a port on a component. */ + OMX_CommandPortEnable, /**< Enable a port on a component. */ + OMX_CommandMarkBuffer, /**< Mark a component/buffer for observation */ + OMX_CommandKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_CommandVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_CommandMax = 0X7FFFFFFF +} OMX_COMMANDTYPE; + + + +/** The OMX_STATETYPE enumeration is used to indicate or change the component + * state. This enumeration reflects the current state of the component when + * used with the OMX_GetState macro or becomes the parameter in a state change + * command when used with the OMX_SendCommand macro. + * + * The component will be in the Loaded state after the component is initially + * loaded into memory. In the Loaded state, the component is not allowed to + * allocate or hold resources other than to build it's internal parameter + * and configuration tables. The application will send one or more + * SetParameters/GetParameters and SetConfig/GetConfig commands to the + * component and the component will record each of these parameter and + * configuration changes for use later. When the application sends the + * Idle command, the component will acquire the resources needed for the + * specified configuration and will transition to the idle state if the + * allocation is successful. If the component cannot successfully + * transition to the idle state for any reason, the state of the component + * shall be fully rolled back to the Loaded state (e.g. all allocated + * resources shall be released). When the component receives the command + * to go to the Executing state, it shall begin processing buffers by + * sending all input buffers it holds to the application. While + * the component is in the Idle state, the application may also send the + * Pause command. If the component receives the pause command while in the + * Idle state, the component shall send all input buffers it holds to the + * application, but shall not begin processing buffers. This will allow the + * application to prefill buffers. + * + * @ingroup comp + */ + +typedef enum OMX_STATETYPE +{ + OMX_StateInvalid, /**< component has detected that it's internal data + structures are corrupted to the point that + it cannot determine it's state properly */ + OMX_StateLoaded, /**< component has been loaded but has not completed + initialization. The OMX_SetParameter macro + and the OMX_GetParameter macro are the only + valid macros allowed to be sent to the + component in this state. */ + OMX_StateIdle, /**< component initialization has been completed + successfully and the component is ready to + to start. */ + OMX_StateExecuting, /**< component has accepted the start command and + is processing data (if data is available) */ + OMX_StatePause, /**< component has received pause command */ + OMX_StateWaitForResources, /**< component is waiting for resources, either after + preemption or before it gets the resources requested. + See specification for complete details. */ + OMX_StateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_StateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_StateMax = 0X7FFFFFFF +} OMX_STATETYPE; + +/** The OMX_ERRORTYPE enumeration defines the standard OMX Errors. These + * errors should cover most of the common failure cases. However, + * vendors are free to add additional error messages of their own as + * long as they follow these rules: + * 1. Vendor error messages shall be in the range of 0x90000000 to + * 0x9000FFFF. + * 2. Vendor error messages shall be defined in a header file provided + * with the component. No error messages are allowed that are + * not defined. + */ +typedef enum OMX_ERRORTYPE +{ + OMX_ErrorNone = 0, + + /** There were insufficient resources to perform the requested operation */ + OMX_ErrorInsufficientResources = (OMX_S32) 0x80001000, + + /** There was an error, but the cause of the error could not be determined */ + OMX_ErrorUndefined = (OMX_S32) 0x80001001, + + /** The component name string was not valid */ + OMX_ErrorInvalidComponentName = (OMX_S32) 0x80001002, + + /** No component with the specified name string was found */ + OMX_ErrorComponentNotFound = (OMX_S32) 0x80001003, + + /** The component specified did not have a "OMX_ComponentInit" or + "OMX_ComponentDeInit entry point */ + OMX_ErrorInvalidComponent = (OMX_S32) 0x80001004, + + /** One or more parameters were not valid */ + OMX_ErrorBadParameter = (OMX_S32) 0x80001005, + + /** The requested function is not implemented */ + OMX_ErrorNotImplemented = (OMX_S32) 0x80001006, + + /** The buffer was emptied before the next buffer was ready */ + OMX_ErrorUnderflow = (OMX_S32) 0x80001007, + + /** The buffer was not available when it was needed */ + OMX_ErrorOverflow = (OMX_S32) 0x80001008, + + /** The hardware failed to respond as expected */ + OMX_ErrorHardware = (OMX_S32) 0x80001009, + + /** The component is in the state OMX_StateInvalid */ + OMX_ErrorInvalidState = (OMX_S32) 0x8000100A, + + /** Stream is found to be corrupt */ + OMX_ErrorStreamCorrupt = (OMX_S32) 0x8000100B, + + /** Ports being connected are not compatible */ + OMX_ErrorPortsNotCompatible = (OMX_S32) 0x8000100C, + + /** Resources allocated to an idle component have been + lost resulting in the component returning to the loaded state */ + OMX_ErrorResourcesLost = (OMX_S32) 0x8000100D, + + /** No more indicies can be enumerated */ + OMX_ErrorNoMore = (OMX_S32) 0x8000100E, + + /** The component detected a version mismatch */ + OMX_ErrorVersionMismatch = (OMX_S32) 0x8000100F, + + /** The component is not ready to return data at this time */ + OMX_ErrorNotReady = (OMX_S32) 0x80001010, + + /** There was a timeout that occurred */ + OMX_ErrorTimeout = (OMX_S32) 0x80001011, + + /** This error occurs when trying to transition into the state you are already in */ + OMX_ErrorSameState = (OMX_S32) 0x80001012, + + /** Resources allocated to an executing or paused component have been + preempted, causing the component to return to the idle state */ + OMX_ErrorResourcesPreempted = (OMX_S32) 0x80001013, + + /** A non-supplier port sends this error to the IL client (via the EventHandler callback) + during the allocation of buffers (on a transition from the LOADED to the IDLE state or + on a port restart) when it deems that it has waited an unusually long time for the supplier + to send it an allocated buffer via a UseBuffer call. */ + OMX_ErrorPortUnresponsiveDuringAllocation = (OMX_S32) 0x80001014, + + /** A non-supplier port sends this error to the IL client (via the EventHandler callback) + during the deallocation of buffers (on a transition from the IDLE to LOADED state or + on a port stop) when it deems that it has waited an unusually long time for the supplier + to request the deallocation of a buffer header via a FreeBuffer call. */ + OMX_ErrorPortUnresponsiveDuringDeallocation = (OMX_S32) 0x80001015, + + /** A supplier port sends this error to the IL client (via the EventHandler callback) + during the stopping of a port (either on a transition from the IDLE to LOADED + state or a port stop) when it deems that it has waited an unusually long time for + the non-supplier to return a buffer via an EmptyThisBuffer or FillThisBuffer call. */ + OMX_ErrorPortUnresponsiveDuringStop = (OMX_S32) 0x80001016, + + /** Attempting a state transtion that is not allowed */ + OMX_ErrorIncorrectStateTransition = (OMX_S32) 0x80001017, + + /* Attempting a command that is not allowed during the present state. */ + OMX_ErrorIncorrectStateOperation = (OMX_S32) 0x80001018, + + /** The values encapsulated in the parameter or config structure are not supported. */ + OMX_ErrorUnsupportedSetting = (OMX_S32) 0x80001019, + + /** The parameter or config indicated by the given index is not supported. */ + OMX_ErrorUnsupportedIndex = (OMX_S32) 0x8000101A, + + /** The port index supplied is incorrect. */ + OMX_ErrorBadPortIndex = (OMX_S32) 0x8000101B, + + /** The port has lost one or more of its buffers and it thus unpopulated. */ + OMX_ErrorPortUnpopulated = (OMX_S32) 0x8000101C, + + /** Component suspended due to temporary loss of resources */ + OMX_ErrorComponentSuspended = (OMX_S32) 0x8000101D, + + /** Component suspended due to an inability to acquire dynamic resources */ + OMX_ErrorDynamicResourcesUnavailable = (OMX_S32) 0x8000101E, + + /** When the macroblock error reporting is enabled the component returns new error + for every frame that has errors */ + OMX_ErrorMbErrorsInFrame = (OMX_S32) 0x8000101F, + + /** A component reports this error when it cannot parse or determine the format of an input stream. */ + OMX_ErrorFormatNotDetected = (OMX_S32) 0x80001020, + + /** The content open operation failed. */ + OMX_ErrorContentPipeOpenFailed = (OMX_S32) 0x80001021, + + /** The content creation operation failed. */ + OMX_ErrorContentPipeCreationFailed = (OMX_S32) 0x80001022, + + /** Separate table information is being used */ + OMX_ErrorSeperateTablesUsed = (OMX_S32) 0x80001023, + + /** Tunneling is unsupported by the component*/ + OMX_ErrorTunnelingUnsupported = (OMX_S32) 0x80001024, + + OMX_ErrorKhronosExtensions = (OMX_S32)0x8F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_ErrorVendorStartUnused = (OMX_S32)0x90000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_ErrorMax = 0x7FFFFFFF +} OMX_ERRORTYPE; + +/** @ingroup core */ +typedef OMX_ERRORTYPE (* OMX_COMPONENTINITTYPE)(OMX_IN OMX_HANDLETYPE hComponent); + +/** @ingroup core */ +typedef struct OMX_COMPONENTREGISTERTYPE +{ + const char * pName; /* Component name, 128 byte limit (including '\0') applies */ + OMX_COMPONENTINITTYPE pInitialize; /* Component instance initialization function */ +} OMX_COMPONENTREGISTERTYPE; + +/** @ingroup core */ +extern OMX_COMPONENTREGISTERTYPE OMX_ComponentRegistered[]; + +/** @ingroup rpm */ +typedef struct OMX_PRIORITYMGMTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nGroupPriority; /**< Priority of the component group */ + OMX_U32 nGroupID; /**< ID of the component group */ +} OMX_PRIORITYMGMTTYPE; + +/* Component name and Role names are limited to 128 characters including the terminating '\0'. */ +#define OMX_MAX_STRINGNAME_SIZE 128 + +/** @ingroup comp */ +typedef struct OMX_PARAM_COMPONENTROLETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U8 cRole[OMX_MAX_STRINGNAME_SIZE]; /**< name of standard component which defines component role */ +} OMX_PARAM_COMPONENTROLETYPE; + +/** End of Stream Buffer Flag: + * + * A component sets EOS when it has no more data to emit on a particular + * output port. Thus an output port shall set EOS on the last buffer it + * emits. A component's determination of when an output port should + * cease sending data is implemenation specific. + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_EOS 0x00000001 + +/** Start Time Buffer Flag: + * + * The source of a stream (e.g. a demux component) sets the STARTTIME + * flag on the buffer that contains the starting timestamp for the + * stream. The starting timestamp corresponds to the first data that + * should be displayed at startup or after a seek. + * The first timestamp of the stream is not necessarily the start time. + * For instance, in the case of a seek to a particular video frame, + * the target frame may be an interframe. Thus the first buffer of + * the stream will be the intra-frame preceding the target frame and + * the starttime will occur with the target frame (with any other + * required frames required to reconstruct the target intervening). + * + * The STARTTIME flag is directly associated with the buffer's + * timestamp ' thus its association to buffer data and its + * propagation is identical to the timestamp's. + * + * When a Sync Component client receives a buffer with the + * STARTTIME flag it shall perform a SetConfig on its sync port + * using OMX_ConfigTimeClientStartTime and passing the buffer's + * timestamp. + * + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_STARTTIME 0x00000002 + + + +/** Decode Only Buffer Flag: + * + * The source of a stream (e.g. a demux component) sets the DECODEONLY + * flag on any buffer that should shall be decoded but should not be + * displayed. This flag is used, for instance, when a source seeks to + * a target interframe that requires the decode of frames preceding the + * target to facilitate the target's reconstruction. In this case the + * source would emit the frames preceding the target downstream + * but mark them as decode only. + * + * The DECODEONLY is associated with buffer data and propagated in a + * manner identical to the buffer timestamp. + * + * A component that renders data should ignore all buffers with + * the DECODEONLY flag set. + * + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_DECODEONLY 0x00000004 + + +/* Data Corrupt Flag: This flag is set when the IL client believes the data in the associated buffer is corrupt + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_DATACORRUPT 0x00000008 + +/* End of Frame: The buffer contains exactly one end of frame and no data + * occurs after the end of frame. This flag is an optional hint. The absence + * of this flag does not imply the absence of an end of frame within the buffer. + * @ingroup buf +*/ +#define OMX_BUFFERFLAG_ENDOFFRAME 0x00000010 + +/* Sync Frame Flag: This flag is set when the buffer content contains a coded sync frame ' + * a frame that has no dependency on any other frame information + * @ingroup buf + */ +#define OMX_BUFFERFLAG_SYNCFRAME 0x00000020 + +/* Extra data present flag: there is extra data appended to the data stream + * residing in the buffer + * @ingroup buf + */ +#define OMX_BUFFERFLAG_EXTRADATA 0x00000040 + +/** Codec Config Buffer Flag: +* OMX_BUFFERFLAG_CODECCONFIG is an optional flag that is set by an +* output port when all bytes in the buffer form part or all of a set of +* codec specific configuration data. Examples include SPS/PPS nal units +* for OMX_VIDEO_CodingAVC or AudioSpecificConfig data for +* OMX_AUDIO_CodingAAC. Any component that for a given stream sets +* OMX_BUFFERFLAG_CODECCONFIG shall not mix codec configuration bytes +* with frame data in the same buffer, and shall send all buffers +* containing codec configuration bytes before any buffers containing +* frame data that those configurations bytes describe. +* If the stream format for a particular codec has a frame specific +* header at the start of each frame, for example OMX_AUDIO_CodingMP3 or +* OMX_AUDIO_CodingAAC in ADTS mode, then these shall be presented as +* normal without setting OMX_BUFFERFLAG_CODECCONFIG. + * @ingroup buf + */ +#define OMX_BUFFERFLAG_CODECCONFIG 0x00000080 + + + +/** @ingroup buf */ +typedef struct OMX_BUFFERHEADERTYPE +{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U8* pBuffer; /**< Pointer to actual block of memory + that is acting as the buffer */ + OMX_U32 nAllocLen; /**< size of the buffer allocated, in bytes */ + OMX_U32 nFilledLen; /**< number of bytes currently in the + buffer */ + OMX_U32 nOffset; /**< start offset of valid data in bytes from + the start of the buffer */ + OMX_PTR pAppPrivate; /**< pointer to any data the application + wants to associate with this buffer */ + OMX_PTR pPlatformPrivate; /**< pointer to any data the platform + wants to associate with this buffer */ + OMX_PTR pInputPortPrivate; /**< pointer to any data the input port + wants to associate with this buffer */ + OMX_PTR pOutputPortPrivate; /**< pointer to any data the output port + wants to associate with this buffer */ + OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will generate a + mark event upon processing this buffer. */ + OMX_PTR pMarkData; /**< Application specific data associated with + the mark sent on a mark event to disambiguate + this mark from others. */ + OMX_U32 nTickCount; /**< Optional entry that the component and + application can update with a tick count + when they access the component. This + value should be in microseconds. Since + this is a value relative to an arbitrary + starting point, this value cannot be used + to determine absolute time. This is an + optional entry and not all components + will update it.*/ + OMX_TICKS nTimeStamp; /**< Timestamp corresponding to the sample + starting at the first logical sample + boundary in the buffer. Timestamps of + successive samples within the buffer may + be inferred by adding the duration of the + of the preceding buffer to the timestamp + of the preceding buffer.*/ + OMX_U32 nFlags; /**< buffer specific flags */ + OMX_U32 nOutputPortIndex; /**< The index of the output port (if any) using + this buffer */ + OMX_U32 nInputPortIndex; /**< The index of the input port (if any) using + this buffer */ +} OMX_BUFFERHEADERTYPE; + +/** The OMX_EXTRADATATYPE enumeration is used to define the + * possible extra data payload types. + * NB: this enum is binary backwards compatible with the previous + * OMX_EXTRADATA_QUANT define. This should be replaced with + * OMX_ExtraDataQuantization. + */ +typedef enum OMX_EXTRADATATYPE +{ + OMX_ExtraDataNone = 0, /**< Indicates that no more extra data sections follow */ + OMX_ExtraDataQuantization, /**< The data payload contains quantization data */ + OMX_ExtraDataKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_ExtraDataVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_ExtraDataMax = 0x7FFFFFFF +} OMX_EXTRADATATYPE; + + +typedef struct OMX_OTHER_EXTRADATATYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_EXTRADATATYPE eType; /* Extra Data type */ + OMX_U32 nDataSize; /* Size of the supporting data to follow */ + OMX_U8 data[1]; /* Supporting data hint */ +} OMX_OTHER_EXTRADATATYPE; + +/** @ingroup comp */ +typedef struct OMX_PORT_PARAM_TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPorts; /**< The number of ports for this component */ + OMX_U32 nStartPortNumber; /** first port number for this type of port */ +} OMX_PORT_PARAM_TYPE; + +/** @ingroup comp */ +typedef enum OMX_EVENTTYPE +{ + OMX_EventCmdComplete, /**< component has sucessfully completed a command */ + OMX_EventError, /**< component has detected an error condition */ + OMX_EventMark, /**< component has detected a buffer mark */ + OMX_EventPortSettingsChanged, /**< component is reported a port settings change */ + OMX_EventBufferFlag, /**< component has detected an EOS */ + OMX_EventResourcesAcquired, /**< component has been granted resources and is + automatically starting the state change from + OMX_StateWaitForResources to OMX_StateIdle. */ + OMX_EventComponentResumed, /**< Component resumed due to reacquisition of resources */ + OMX_EventDynamicResourcesAvailable, /**< Component has acquired previously unavailable dynamic resources */ + OMX_EventPortFormatDetected, /**< Component has detected a supported format. */ + OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + + /** Event when tunneled decoder has rendered an output or reached EOS + * nData1 must contain the number of timestamps returned + * pEventData must point to an array of the OMX_VIDEO_RENDEREVENTTYPE structs containing the + * render-timestamps of each frame. Component may batch rendered timestamps using this event, + * but must signal the event no more than 40ms after the first frame in the batch. The frames + * must be ordered by system timestamp inside and across batches. + * + * If component is doing frame-rate conversion, it must signal the render time of each + * converted frame, and must interpolate media timestamps for in-between frames. + * + * When the component reached EOS, it must signal an EOS timestamp using the same mechanism. + * This is in addition to the timestamp of the last rendered frame, and should follow that + * frame. + */ + OMX_EventOutputRendered = 0x7F000001, + OMX_EventMax = 0x7FFFFFFF +} OMX_EVENTTYPE; + +typedef struct OMX_CALLBACKTYPE +{ + /** The EventHandler method is used to notify the application when an + event of interest occurs. Events are defined in the OMX_EVENTTYPE + enumeration. Please see that enumeration for details of what will + be returned for each type of event. Callbacks should not return + an error to the component, so if an error occurs, the application + shall handle it internally. This is a blocking call. + + The application should return from this call within 5 msec to avoid + blocking the component for an excessively long period of time. + + @param hComponent + handle of the component to access. This is the component + handle returned by the call to the GetHandle function. + @param pAppData + pointer to an application defined value that was provided in the + pAppData parameter to the OMX_GetHandle method for the component. + This application defined value is provided so that the application + can have a component specific context when receiving the callback. + @param eEvent + Event that the component wants to notify the application about. + @param nData1 + nData will be the OMX_ERRORTYPE for an error event and will be + an OMX_COMMANDTYPE for a command complete event and OMX_INDEXTYPE for a OMX_PortSettingsChanged event. + @param nData2 + nData2 will hold further information related to the event. Can be OMX_STATETYPE for + a OMX_CommandStateSet command or port index for a OMX_PortSettingsChanged event. + Default value is 0 if not used. ) + @param pEventData + Pointer to additional event-specific data (see spec for meaning). + */ + + OMX_ERRORTYPE (*EventHandler)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_EVENTTYPE eEvent, + OMX_IN OMX_U32 nData1, + OMX_IN OMX_U32 nData2, + OMX_IN OMX_PTR pEventData); + + /** The EmptyBufferDone method is used to return emptied buffers from an + input port back to the application for reuse. This is a blocking call + so the application should not attempt to refill the buffers during this + call, but should queue them and refill them in another thread. There + is no error return, so the application shall handle any errors generated + internally. + + The application should return from this call within 5 msec. + + @param hComponent + handle of the component to access. This is the component + handle returned by the call to the GetHandle function. + @param pAppData + pointer to an application defined value that was provided in the + pAppData parameter to the OMX_GetHandle method for the component. + This application defined value is provided so that the application + can have a component specific context when receiving the callback. + @param pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer indicating the buffer that was emptied. + @ingroup buf + */ + OMX_ERRORTYPE (*EmptyBufferDone)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** The FillBufferDone method is used to return filled buffers from an + output port back to the application for emptying and then reuse. + This is a blocking call so the application should not attempt to + empty the buffers during this call, but should queue the buffers + and empty them in another thread. There is no error return, so + the application shall handle any errors generated internally. The + application shall also update the buffer header to indicate the + number of bytes placed into the buffer. + + The application should return from this call within 5 msec. + + @param hComponent + handle of the component to access. This is the component + handle returned by the call to the GetHandle function. + @param pAppData + pointer to an application defined value that was provided in the + pAppData parameter to the OMX_GetHandle method for the component. + This application defined value is provided so that the application + can have a component specific context when receiving the callback. + @param pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer indicating the buffer that was filled. + @ingroup buf + */ + OMX_ERRORTYPE (*FillBufferDone)( + OMX_OUT OMX_HANDLETYPE hComponent, + OMX_OUT OMX_PTR pAppData, + OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer); + +} OMX_CALLBACKTYPE; + +/** The OMX_BUFFERSUPPLIERTYPE enumeration is used to dictate port supplier + preference when tunneling between two ports. + @ingroup tun buf +*/ +typedef enum OMX_BUFFERSUPPLIERTYPE +{ + OMX_BufferSupplyUnspecified = 0x0, /**< port supplying the buffers is unspecified, + or don't care */ + OMX_BufferSupplyInput, /**< input port supplies the buffers */ + OMX_BufferSupplyOutput, /**< output port supplies the buffers */ + OMX_BufferSupplyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_BufferSupplyVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_BufferSupplyMax = 0x7FFFFFFF +} OMX_BUFFERSUPPLIERTYPE; + + +/** buffer supplier parameter + * @ingroup tun + */ +typedef struct OMX_PARAM_BUFFERSUPPLIERTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BUFFERSUPPLIERTYPE eBufferSupplier; /**< buffer supplier */ +} OMX_PARAM_BUFFERSUPPLIERTYPE; + + +/**< indicates that buffers received by an input port of a tunnel + may not modify the data in the buffers + @ingroup tun + */ +#define OMX_PORTTUNNELFLAG_READONLY 0x00000001 + + +/** The OMX_TUNNELSETUPTYPE structure is used to pass data from an output + port to an input port as part the two ComponentTunnelRequest calls + resulting from a OMX_SetupTunnel call from the IL Client. + @ingroup tun + */ +typedef struct OMX_TUNNELSETUPTYPE +{ + OMX_U32 nTunnelFlags; /**< bit flags for tunneling */ + OMX_BUFFERSUPPLIERTYPE eSupplier; /**< supplier preference */ +} OMX_TUNNELSETUPTYPE; + +/* OMX Component headers is included to enable the core to use + macros for functions into the component for OMX release 1.0. + Developers should not access any structures or data from within + the component header directly */ +/* TO BE REMOVED - #include */ + +/** GetComponentVersion will return information about the component. + This is a blocking call. This macro will go directly from the + application to the component (via a core macro). The + component will return from this call within 5 msec. + @param [in] hComponent + handle of component to execute the command + @param [out] pComponentName + pointer to an empty string of length 128 bytes. The component + will write its name into this string. The name will be + terminated by a single zero byte. The name of a component will + be 127 bytes or less to leave room for the trailing zero byte. + An example of a valid component name is "OMX.ABC.ChannelMixer\0". + @param [out] pComponentVersion + pointer to an OMX Version structure that the component will fill + in. The component will fill in a value that indicates the + component version. NOTE: the component version is NOT the same + as the OMX Specification version (found in all structures). The + component version is defined by the vendor of the component and + its value is entirely up to the component vendor. + @param [out] pSpecVersion + pointer to an OMX Version structure that the component will fill + in. The SpecVersion is the version of the specification that the + component was built against. Please note that this value may or + may not match the structure's version. For example, if the + component was built against the 2.0 specification, but the + application (which creates the structure is built against the + 1.0 specification the versions would be different. + @param [out] pComponentUUID + pointer to the UUID of the component which will be filled in by + the component. The UUID is a unique identifier that is set at + RUN time for the component and is unique to each instantion of + the component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetComponentVersion( \ + hComponent, \ + pComponentName, \ + pComponentVersion, \ + pSpecVersion, \ + pComponentUUID) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetComponentVersion( \ + hComponent, \ + pComponentName, \ + pComponentVersion, \ + pSpecVersion, \ + pComponentUUID) /* Macro End */ + + +/** Send a command to the component. This call is a non-blocking call. + The component should check the parameters and then queue the command + to the component thread to be executed. The component thread shall + send the EventHandler() callback at the conclusion of the command. + This macro will go directly from the application to the component (via + a core macro). The component will return from this call within 5 msec. + + When the command is "OMX_CommandStateSet" the component will queue a + state transition to the new state idenfied in nParam. + + When the command is "OMX_CommandFlush", to flush a port's buffer queues, + the command will force the component to return all buffers NOT CURRENTLY + BEING PROCESSED to the application, in the order in which the buffers + were received. + + When the command is "OMX_CommandPortDisable" or + "OMX_CommandPortEnable", the component's port (given by the value of + nParam) will be stopped or restarted. + + When the command "OMX_CommandMarkBuffer" is used to mark a buffer, the + pCmdData will point to a OMX_MARKTYPE structure containing the component + handle of the component to examine the buffer chain for the mark. nParam1 + contains the index of the port on which the buffer mark is applied. + + Specification text for more details. + + @param [in] hComponent + handle of component to execute the command + @param [in] Cmd + Command for the component to execute + @param [in] nParam + Parameter for the command to be executed. When Cmd has the value + OMX_CommandStateSet, value is a member of OMX_STATETYPE. When Cmd has + the value OMX_CommandFlush, value of nParam indicates which port(s) + to flush. -1 is used to flush all ports a single port index will + only flush that port. When Cmd has the value "OMX_CommandPortDisable" + or "OMX_CommandPortEnable", the component's port is given by + the value of nParam. When Cmd has the value "OMX_CommandMarkBuffer" + the components pot is given by the value of nParam. + @param [in] pCmdData + Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value + "OMX_CommandMarkBuffer". + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_SendCommand( \ + hComponent, \ + Cmd, \ + nParam, \ + pCmdData) \ + ((OMX_COMPONENTTYPE*)hComponent)->SendCommand( \ + hComponent, \ + Cmd, \ + nParam, \ + pCmdData) /* Macro End */ + + +/** The OMX_GetParameter macro will get one of the current parameter + settings from the component. This macro cannot only be invoked when + the component is in the OMX_StateInvalid state. The nParamIndex + parameter is used to indicate which structure is being requested from + the component. The application shall allocate the correct structure + and shall fill in the structure size and version information before + invoking this macro. When the parameter applies to a port, the + caller shall fill in the appropriate nPortIndex value indicating the + port on which the parameter applies. If the component has not had + any settings changed, then the component should return a set of + valid DEFAULT parameters for the component. This is a blocking + call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nParamIndex + Index of the structure to be filled. This value is from the + OMX_INDEXTYPE enumeration. + @param [in,out] pComponentParameterStructure + Pointer to application allocated structure to be filled by the + component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) /* Macro End */ + + +/** The OMX_SetParameter macro will send an initialization parameter + structure to a component. Each structure shall be sent one at a time, + in a separate invocation of the macro. This macro can only be + invoked when the component is in the OMX_StateLoaded state, or the + port is disabled (when the parameter applies to a port). The + nParamIndex parameter is used to indicate which structure is being + passed to the component. The application shall allocate the + correct structure and shall fill in the structure size and version + information (as well as the actual data) before invoking this macro. + The application is free to dispose of this structure after the call + as the component is required to copy any data it shall retain. This + is a blocking call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nIndex + Index of the structure to be sent. This value is from the + OMX_INDEXTYPE enumeration. + @param [in] pComponentParameterStructure + pointer to application allocated structure to be used for + initialization by the component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_SetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->SetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) /* Macro End */ + + +/** The OMX_GetConfig macro will get one of the configuration structures + from a component. This macro can be invoked anytime after the + component has been loaded. The nParamIndex call parameter is used to + indicate which structure is being requested from the component. The + application shall allocate the correct structure and shall fill in the + structure size and version information before invoking this macro. + If the component has not had this configuration parameter sent before, + then the component should return a set of valid DEFAULT values for the + component. This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nIndex + Index of the structure to be filled. This value is from the + OMX_INDEXTYPE enumeration. + @param [in,out] pComponentConfigStructure + pointer to application allocated structure to be filled by the + component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp +*/ +#define OMX_GetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) /* Macro End */ + + +/** The OMX_SetConfig macro will send one of the configuration + structures to a component. Each structure shall be sent one at a time, + each in a separate invocation of the macro. This macro can be invoked + anytime after the component has been loaded. The application shall + allocate the correct structure and shall fill in the structure size + and version information (as well as the actual data) before invoking + this macro. The application is free to dispose of this structure after + the call as the component is required to copy any data it shall retain. + This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nConfigIndex + Index of the structure to be sent. This value is from the + OMX_INDEXTYPE enumeration above. + @param [in] pComponentConfigStructure + pointer to application allocated structure to be used for + initialization by the component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_SetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->SetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) /* Macro End */ + + +/** The OMX_GetExtensionIndex macro will invoke a component to translate + a vendor specific configuration or parameter string into an OMX + structure index. There is no requirement for the vendor to support + this command for the indexes already found in the OMX_INDEXTYPE + enumeration (this is done to save space in small components). The + component shall support all vendor supplied extension indexes not found + in the master OMX_INDEXTYPE enumeration. This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @param [in] cParameterName + OMX_STRING that shall be less than 128 characters long including + the trailing null byte. This is the string that will get + translated by the component into a configuration index. + @param [out] pIndexType + a pointer to a OMX_INDEXTYPE to receive the index value. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetExtensionIndex( \ + hComponent, \ + cParameterName, \ + pIndexType) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetExtensionIndex( \ + hComponent, \ + cParameterName, \ + pIndexType) /* Macro End */ + + +/** The OMX_GetState macro will invoke the component to get the current + state of the component and place the state value into the location + pointed to by pState. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] pState + pointer to the location to receive the state. The value returned + is one of the OMX_STATETYPE members + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetState( \ + hComponent, \ + pState) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetState( \ + hComponent, \ + pState) /* Macro End */ + + +/** The OMX_UseBuffer macro will request that the component use + a buffer (and allocate its own buffer header) already allocated + by another component, or by the IL Client. This is a blocking + call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] ppBuffer + pointer to an OMX_BUFFERHEADERTYPE structure used to receive the + pointer to the buffer header + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ + +#define OMX_UseBuffer( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->UseBuffer( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes, \ + pBuffer) + + +/** The OMX_AllocateBuffer macro will request that the component allocate + a new buffer and buffer header. The component will allocate the + buffer and the buffer header and return a pointer to the buffer + header. This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] ppBuffer + pointer to an OMX_BUFFERHEADERTYPE structure used to receive + the pointer to the buffer header + @param [in] nPortIndex + nPortIndex is used to select the port on the component the buffer will + be used with. The port can be found by using the nPortIndex + value as an index into the Port Definition array of the component. + @param [in] pAppPrivate + pAppPrivate is used to initialize the pAppPrivate member of the + buffer header structure. + @param [in] nSizeBytes + size of the buffer to allocate. Used when bAllocateNew is true. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_AllocateBuffer( \ + hComponent, \ + ppBuffer, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes) \ + ((OMX_COMPONENTTYPE*)hComponent)->AllocateBuffer( \ + hComponent, \ + ppBuffer, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes) /* Macro End */ + + +/** The OMX_FreeBuffer macro will release a buffer header from the component + which was allocated using either OMX_AllocateBuffer or OMX_UseBuffer. If + the component allocated the buffer (see the OMX_UseBuffer macro) then + the component shall free the buffer and buffer header. This is a + blocking call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nPortIndex + nPortIndex is used to select the port on the component the buffer will + be used with. + @param [in] pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_FreeBuffer( \ + hComponent, \ + nPortIndex, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->FreeBuffer( \ + hComponent, \ + nPortIndex, \ + pBuffer) /* Macro End */ + + +/** The OMX_EmptyThisBuffer macro will send a buffer full of data to an + input port of a component. The buffer will be emptied by the component + and returned to the application via the EmptyBufferDone call back. + This is a non-blocking call in that the component will record the buffer + and return immediately and then empty the buffer, later, at the proper + time. As expected, this macro may be invoked only while the component + is in the OMX_StateExecuting. If nPortIndex does not specify an input + port, the component shall return an error. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_EmptyThisBuffer( \ + hComponent, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->EmptyThisBuffer( \ + hComponent, \ + pBuffer) /* Macro End */ + + +/** The OMX_FillThisBuffer macro will send an empty buffer to an + output port of a component. The buffer will be filled by the component + and returned to the application via the FillBufferDone call back. + This is a non-blocking call in that the component will record the buffer + and return immediately and then fill the buffer, later, at the proper + time. As expected, this macro may be invoked only while the component + is in the OMX_ExecutingState. If nPortIndex does not specify an output + port, the component shall return an error. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_FillThisBuffer( \ + hComponent, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->FillThisBuffer( \ + hComponent, \ + pBuffer) /* Macro End */ + + + +/** The OMX_UseEGLImage macro will request that the component use + a EGLImage provided by EGL (and allocate its own buffer header) + This is a blocking call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] ppBuffer + pointer to an OMX_BUFFERHEADERTYPE structure used to receive the + pointer to the buffer header. Note that the memory location used + for this buffer is NOT visible to the IL Client. + @param [in] nPortIndex + nPortIndex is used to select the port on the component the buffer will + be used with. The port can be found by using the nPortIndex + value as an index into the Port Definition array of the component. + @param [in] pAppPrivate + pAppPrivate is used to initialize the pAppPrivate member of the + buffer header structure. + @param [in] eglImage + eglImage contains the handle of the EGLImage to use as a buffer on the + specified port. The component is expected to validate properties of + the EGLImage against the configuration of the port to ensure the component + can use the EGLImage as a buffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_UseEGLImage( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + eglImage) \ + ((OMX_COMPONENTTYPE*)hComponent)->UseEGLImage( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + eglImage) + +/** The OMX_Init method is used to initialize the OMX core. It shall be the + first call made into OMX and it should only be executed one time without + an interviening OMX_Deinit call. + + The core should return from this call within 20 msec. + + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void); + + +/** The OMX_Deinit method is used to deinitialize the OMX core. It shall be + the last call made into OMX. In the event that the core determines that + thare are components loaded when this call is made, the core may return + with an error rather than try to unload the components. + + The core should return from this call within 20 msec. + + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void); + + +/** The OMX_ComponentNameEnum method will enumerate through all the names of + recognised valid components in the system. This function is provided + as a means to detect all the components in the system run-time. There is + no strict ordering to the enumeration order of component names, although + each name will only be enumerated once. If the OMX core supports run-time + installation of new components, it is only requried to detect newly + installed components when the first call to enumerate component names + is made (i.e. when nIndex is 0x0). + + The core should return from this call in 20 msec. + + @param [out] cComponentName + pointer to a null terminated string with the component name. The + names of the components are strings less than 127 bytes in length + plus the trailing null for a maximum size of 128 bytes. An example + of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are + assigned by the vendor, but shall start with "OMX." and then have + the Vendor designation next. + @param [in] nNameLength + number of characters in the cComponentName string. With all + component name strings restricted to less than 128 characters + (including the trailing null) it is recomended that the caller + provide a input string for the cComponentName of 128 characters. + @param [in] nIndex + number containing the enumeration index for the component. + Multiple calls to OMX_ComponentNameEnum with increasing values + of nIndex will enumerate through the component names in the + system until OMX_ErrorNoMore is returned. The value of nIndex + is 0 to (N-1), where N is the number of valid installed components + in the system. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. When the value of nIndex exceeds the number of + components in the system minus 1, OMX_ErrorNoMore will be + returned. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum( + OMX_OUT OMX_STRING cComponentName, + OMX_IN OMX_U32 nNameLength, + OMX_IN OMX_U32 nIndex); + + +/** The OMX_GetHandle method will locate the component specified by the + component name given, load that component into memory and then invoke + the component's methods to create an instance of the component. + + The core should return from this call within 20 msec. + + @param [out] pHandle + pointer to an OMX_HANDLETYPE pointer to be filled in by this method. + @param [in] cComponentName + pointer to a null terminated string with the component name. The + names of the components are strings less than 127 bytes in length + plus the trailing null for a maximum size of 128 bytes. An example + of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are + assigned by the vendor, but shall start with "OMX." and then have + the Vendor designation next. + @param [in] pAppData + pointer to an application defined value that will be returned + during callbacks so that the application can identify the source + of the callback. + @param [in] pCallBacks + pointer to a OMX_CALLBACKTYPE structure that will be passed to the + component to initialize it with. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle( + OMX_OUT OMX_HANDLETYPE* pHandle, + OMX_IN OMX_STRING cComponentName, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_CALLBACKTYPE* pCallBacks); + + +/** The OMX_FreeHandle method will free a handle allocated by the OMX_GetHandle + method. If the component reference count goes to zero, the component will + be unloaded from memory. + + The core should return from this call within 20 msec when the component is + in the OMX_StateLoaded state. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle( + OMX_IN OMX_HANDLETYPE hComponent); + + + +/** The OMX_SetupTunnel method will handle the necessary calls to the components + to setup the specified tunnel the two components. NOTE: This is + an actual method (not a #define macro). This method will make calls into + the component ComponentTunnelRequest method to do the actual tunnel + connection. + + The ComponentTunnelRequest method on both components will be called. + This method shall not be called unless the component is in the + OMX_StateLoaded state except when the ports used for the tunnel are + disabled. In this case, the component may be in the OMX_StateExecuting, + OMX_StatePause, or OMX_StateIdle states. + + The core should return from this call within 20 msec. + + @param [in] hOutput + Handle of the component to be accessed. Also this is the handle + of the component whose port, specified in the nPortOutput parameter + will be used the source for the tunnel. This is the component handle + returned by the call to the OMX_GetHandle function. There is a + requirement that hOutput be the source for the data when + tunelling (i.e. nPortOutput is an output port). If 0x0, the component + specified in hInput will have it's port specified in nPortInput + setup for communication with the application / IL client. + @param [in] nPortOutput + nPortOutput is used to select the source port on component to be + used in the tunnel. + @param [in] hInput + This is the component to setup the tunnel with. This is the handle + of the component whose port, specified in the nPortInput parameter + will be used the destination for the tunnel. This is the component handle + returned by the call to the OMX_GetHandle function. There is a + requirement that hInput be the destination for the data when + tunelling (i.e. nPortInut is an input port). If 0x0, the component + specified in hOutput will have it's port specified in nPortPOutput + setup for communication with the application / IL client. + @param [in] nPortInput + nPortInput is used to select the destination port on component to be + used in the tunnel. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + When OMX_ErrorNotImplemented is returned, one or both components is + a non-interop component and does not support tunneling. + + On failure, the ports of both components are setup for communication + with the application / IL Client. + @ingroup core tun + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel( + OMX_IN OMX_HANDLETYPE hOutput, + OMX_IN OMX_U32 nPortOutput, + OMX_IN OMX_HANDLETYPE hInput, + OMX_IN OMX_U32 nPortInput); + +/** @ingroup cp */ +OMX_API OMX_ERRORTYPE OMX_GetContentPipe( + OMX_OUT OMX_HANDLETYPE *hPipe, + OMX_IN OMX_STRING szURI); + +/** The OMX_GetComponentsOfRole method will return the number of components that support the given + role and (if the compNames field is non-NULL) the names of those components. The call will fail if + an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the + client should: + * first call this function with the compNames field NULL to determine the number of component names + * second call this function with the compNames field pointing to an array of names allocated + according to the number returned by the first call. + + The core should return from this call within 5 msec. + + @param [in] role + This is generic standard component name consisting only of component class + name and the type within that class (e.g. 'audio_decoder.aac'). + @param [inout] pNumComps + This is used both as input and output. + + If compNames is NULL, the input is ignored and the output specifies how many components support + the given role. + + If compNames is not NULL, on input it bounds the size of the input structure and + on output, it specifies the number of components string names listed within the compNames parameter. + @param [inout] compNames + If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings which accepts + a list of the names of all physical components that implement the specified standard component name. + Each name is NULL terminated. numComps indicates the number of names. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole ( + OMX_IN OMX_STRING role, + OMX_INOUT OMX_U32 *pNumComps, + OMX_INOUT OMX_U8 **compNames); + +/** The OMX_GetRolesOfComponent method will return the number of roles supported by the given + component and (if the roles field is non-NULL) the names of those roles. The call will fail if + an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the + client should: + * first call this function with the roles field NULL to determine the number of role names + * second call this function with the roles field pointing to an array of names allocated + according to the number returned by the first call. + + The core should return from this call within 5 msec. + + @param [in] compName + This is the name of the component being queried about. + @param [inout] pNumRoles + This is used both as input and output. + + If roles is NULL, the input is ignored and the output specifies how many roles the component supports. + + If compNames is not NULL, on input it bounds the size of the input structure and + on output, it specifies the number of roles string names listed within the roles parameter. + @param [out] roles + If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings + which accepts a list of the names of all standard components roles implemented on the + specified component name. numComps indicates the number of names. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent ( + OMX_IN OMX_STRING compName, + OMX_INOUT OMX_U32 *pNumRoles, + OMX_OUT OMX_U8 **roles); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ + diff --git a/phonelibs/android_frameworks_native/include/media/openmax/OMX_IVCommon.h b/phonelibs/android_frameworks_native/include/media/openmax/OMX_IVCommon.h new file mode 100644 index 00000000000000..f9b6f4b0fd279a --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/openmax/OMX_IVCommon.h @@ -0,0 +1,958 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/** + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** + * @file OMX_IVCommon.h - OpenMax IL version 1.1.2 + * The structures needed by Video and Image components to exchange + * parameters and configuration data with the components. + */ +#ifndef OMX_IVCommon_h +#define OMX_IVCommon_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * Each OMX header must include all required header files to allow the header + * to compile without errors. The includes below are required for this header + * file to compile successfully + */ + +#include + +/** @defgroup iv OpenMAX IL Imaging and Video Domain + * Common structures for OpenMAX IL Imaging and Video domains + * @{ + */ + + +/** + * Enumeration defining possible uncompressed image/video formats. + * + * ENUMS: + * Unused : Placeholder value when format is N/A + * Monochrome : black and white + * 8bitRGB332 : Red 7:5, Green 4:2, Blue 1:0 + * 12bitRGB444 : Red 11:8, Green 7:4, Blue 3:0 + * 16bitARGB4444 : Alpha 15:12, Red 11:8, Green 7:4, Blue 3:0 + * 16bitARGB1555 : Alpha 15, Red 14:10, Green 9:5, Blue 4:0 + * 16bitRGB565 : Red 15:11, Green 10:5, Blue 4:0 + * 16bitBGR565 : Blue 15:11, Green 10:5, Red 4:0 + * 18bitRGB666 : Red 17:12, Green 11:6, Blue 5:0 + * 18bitARGB1665 : Alpha 17, Red 16:11, Green 10:5, Blue 4:0 + * 19bitARGB1666 : Alpha 18, Red 17:12, Green 11:6, Blue 5:0 + * 24bitRGB888 : Red 24:16, Green 15:8, Blue 7:0 + * 24bitBGR888 : Blue 24:16, Green 15:8, Red 7:0 + * 24bitARGB1887 : Alpha 23, Red 22:15, Green 14:7, Blue 6:0 + * 25bitARGB1888 : Alpha 24, Red 23:16, Green 15:8, Blue 7:0 + * 32bitBGRA8888 : Blue 31:24, Green 23:16, Red 15:8, Alpha 7:0 + * 32bitARGB8888 : Alpha 31:24, Red 23:16, Green 15:8, Blue 7:0 + * YUV411Planar : U,Y are subsampled by a factor of 4 horizontally + * YUV411PackedPlanar : packed per payload in planar slices + * YUV420Planar : Three arrays Y,U,V. + * YUV420PackedPlanar : packed per payload in planar slices + * YUV420SemiPlanar : Two arrays, one is all Y, the other is U and V + * YUV422Planar : Three arrays Y,U,V. + * YUV422PackedPlanar : packed per payload in planar slices + * YUV422SemiPlanar : Two arrays, one is all Y, the other is U and V + * YCbYCr : Organized as 16bit YUYV (i.e. YCbYCr) + * YCrYCb : Organized as 16bit YVYU (i.e. YCrYCb) + * CbYCrY : Organized as 16bit UYVY (i.e. CbYCrY) + * CrYCbY : Organized as 16bit VYUY (i.e. CrYCbY) + * YUV444Interleaved : Each pixel contains equal parts YUV + * RawBayer8bit : SMIA camera output format + * RawBayer10bit : SMIA camera output format + * RawBayer8bitcompressed : SMIA camera output format + */ +typedef enum OMX_COLOR_FORMATTYPE { + OMX_COLOR_FormatUnused, + OMX_COLOR_FormatMonochrome, + OMX_COLOR_Format8bitRGB332, + OMX_COLOR_Format12bitRGB444, + OMX_COLOR_Format16bitARGB4444, + OMX_COLOR_Format16bitARGB1555, + OMX_COLOR_Format16bitRGB565, + OMX_COLOR_Format16bitBGR565, + OMX_COLOR_Format18bitRGB666, + OMX_COLOR_Format18bitARGB1665, + OMX_COLOR_Format19bitARGB1666, + OMX_COLOR_Format24bitRGB888, + OMX_COLOR_Format24bitBGR888, + OMX_COLOR_Format24bitARGB1887, + OMX_COLOR_Format25bitARGB1888, + OMX_COLOR_Format32bitBGRA8888, + OMX_COLOR_Format32bitARGB8888, + OMX_COLOR_FormatYUV411Planar, + OMX_COLOR_FormatYUV411PackedPlanar, + OMX_COLOR_FormatYUV420Planar, + OMX_COLOR_FormatYUV420PackedPlanar, + OMX_COLOR_FormatYUV420SemiPlanar, + OMX_COLOR_FormatYUV422Planar, + OMX_COLOR_FormatYUV422PackedPlanar, + OMX_COLOR_FormatYUV422SemiPlanar, + OMX_COLOR_FormatYCbYCr, + OMX_COLOR_FormatYCrYCb, + OMX_COLOR_FormatCbYCrY, + OMX_COLOR_FormatCrYCbY, + OMX_COLOR_FormatYUV444Interleaved, + OMX_COLOR_FormatRawBayer8bit, + OMX_COLOR_FormatRawBayer10bit, + OMX_COLOR_FormatRawBayer8bitcompressed, + OMX_COLOR_FormatL2, + OMX_COLOR_FormatL4, + OMX_COLOR_FormatL8, + OMX_COLOR_FormatL16, + OMX_COLOR_FormatL24, + OMX_COLOR_FormatL32, + OMX_COLOR_FormatYUV420PackedSemiPlanar, + OMX_COLOR_FormatYUV422PackedSemiPlanar, + OMX_COLOR_Format18BitBGR666, + OMX_COLOR_Format24BitARGB6666, + OMX_COLOR_Format24BitABGR6666, + OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_COLOR_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + /** + +/** @defgroup imaging OpenMAX IL Imaging Domain + * @ingroup iv + * Structures for OpenMAX IL Imaging domain + * @{ + */ + +/** + * Enumeration used to define the possible image compression coding. + */ +typedef enum OMX_IMAGE_CODINGTYPE { + OMX_IMAGE_CodingUnused, /**< Value when format is N/A */ + OMX_IMAGE_CodingAutoDetect, /**< Auto detection of image format */ + OMX_IMAGE_CodingJPEG, /**< JPEG/JFIF image format */ + OMX_IMAGE_CodingJPEG2K, /**< JPEG 2000 image format */ + OMX_IMAGE_CodingEXIF, /**< EXIF image format */ + OMX_IMAGE_CodingTIFF, /**< TIFF image format */ + OMX_IMAGE_CodingGIF, /**< Graphics image format */ + OMX_IMAGE_CodingPNG, /**< PNG image format */ + OMX_IMAGE_CodingLZW, /**< LZW image format */ + OMX_IMAGE_CodingBMP, /**< Windows Bitmap format */ + OMX_IMAGE_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_CodingMax = 0x7FFFFFFF +} OMX_IMAGE_CODINGTYPE; + + +/** + * Data structure used to define an image path. The number of image paths + * for input and output will vary by type of the image component. + * + * Input (aka Source) : Zero Inputs, one Output, + * Splitter : One Input, 2 or more Outputs, + * Processing Element : One Input, one output, + * Mixer : 2 or more inputs, one output, + * Output (aka Sink) : One Input, zero outputs. + * + * The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output + * image path. If additional vendor specific data is required, it should + * be transmitted to the component using the CustomCommand function. + * Compliant components will prepopulate this structure with optimal + * values during the OMX_GetParameter() command. + * + * STRUCT MEMBERS: + * cMIMEType : MIME type of data for the port + * pNativeRender : Platform specific reference for a display if a + * sync, otherwise this field is 0 + * nFrameWidth : Width of frame to be used on port if + * uncompressed format is used. Use 0 for + * unknown, don't care or variable + * nFrameHeight : Height of frame to be used on port if + * uncompressed format is used. Use 0 for + * unknown, don't care or variable + * nStride : Number of bytes per span of an image (i.e. + * indicates the number of bytes to get from + * span N to span N+1, where negative stride + * indicates the image is bottom up + * nSliceHeight : Height used when encoding in slices + * bFlagErrorConcealment : Turns on error concealment if it is supported by + * the OMX component + * eCompressionFormat : Compression format used in this instance of + * the component. When OMX_IMAGE_CodingUnused is + * specified, eColorFormat is valid + * eColorFormat : Decompressed format used by this component + * pNativeWindow : Platform specific reference for a window object if a + * display sink , otherwise this field is 0x0. + */ +typedef struct OMX_IMAGE_PORTDEFINITIONTYPE { + OMX_STRING cMIMEType; + OMX_NATIVE_DEVICETYPE pNativeRender; + OMX_U32 nFrameWidth; + OMX_U32 nFrameHeight; + OMX_S32 nStride; + OMX_U32 nSliceHeight; + OMX_BOOL bFlagErrorConcealment; + OMX_IMAGE_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; + OMX_NATIVE_WINDOWTYPE pNativeWindow; +} OMX_IMAGE_PORTDEFINITIONTYPE; + + +/** + * Port format parameter. This structure is used to enumerate the various + * data input/output format supported by the port. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Indicates which port to set + * nIndex : Indicates the enumeration index for the format from + * 0x0 to N-1 + * eCompressionFormat : Compression format used in this instance of the + * component. When OMX_IMAGE_CodingUnused is specified, + * eColorFormat is valid + * eColorFormat : Decompressed format used by this component + */ +typedef struct OMX_IMAGE_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nIndex; + OMX_IMAGE_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; +} OMX_IMAGE_PARAM_PORTFORMATTYPE; + + +/** + * Flash control type + * + * ENUMS + * Torch : Flash forced constantly on + */ +typedef enum OMX_IMAGE_FLASHCONTROLTYPE { + OMX_IMAGE_FlashControlOn = 0, + OMX_IMAGE_FlashControlOff, + OMX_IMAGE_FlashControlAuto, + OMX_IMAGE_FlashControlRedEyeReduction, + OMX_IMAGE_FlashControlFillin, + OMX_IMAGE_FlashControlTorch, + OMX_IMAGE_FlashControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_FlashControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_FlashControlMax = 0x7FFFFFFF +} OMX_IMAGE_FLASHCONTROLTYPE; + + +/** + * Flash control configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFlashControl : Flash control type + */ +typedef struct OMX_IMAGE_PARAM_FLASHCONTROLTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_FLASHCONTROLTYPE eFlashControl; +} OMX_IMAGE_PARAM_FLASHCONTROLTYPE; + + +/** + * Focus control type + */ +typedef enum OMX_IMAGE_FOCUSCONTROLTYPE { + OMX_IMAGE_FocusControlOn = 0, + OMX_IMAGE_FocusControlOff, + OMX_IMAGE_FocusControlAuto, + OMX_IMAGE_FocusControlAutoLock, + OMX_IMAGE_FocusControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_FocusControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_FocusControlMax = 0x7FFFFFFF +} OMX_IMAGE_FOCUSCONTROLTYPE; + + +/** + * Focus control configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFocusControl : Focus control + * nFocusSteps : Focus can take on values from 0 mm to infinity. + * Interest is only in number of steps over this range. + * nFocusStepIndex : Current focus step index + */ +typedef struct OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_FOCUSCONTROLTYPE eFocusControl; + OMX_U32 nFocusSteps; + OMX_U32 nFocusStepIndex; +} OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE; + + +/** + * Q Factor for JPEG compression, which controls the tradeoff between image + * quality and size. Q Factor provides a more simple means of controlling + * JPEG compression quality, without directly programming Quantization + * tables for chroma and luma + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nQFactor : JPEG Q factor value in the range of 1-100. A factor of 1 + * produces the smallest, worst quality images, and a factor + * of 100 produces the largest, best quality images. A + * typical default is 75 for small good quality images + */ +typedef struct OMX_IMAGE_PARAM_QFACTORTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nQFactor; +} OMX_IMAGE_PARAM_QFACTORTYPE; + +/** + * Quantization table type + */ + +typedef enum OMX_IMAGE_QUANTIZATIONTABLETYPE { + OMX_IMAGE_QuantizationTableLuma = 0, + OMX_IMAGE_QuantizationTableChroma, + OMX_IMAGE_QuantizationTableChromaCb, + OMX_IMAGE_QuantizationTableChromaCr, + OMX_IMAGE_QuantizationTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_QuantizationTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_QuantizationTableMax = 0x7FFFFFFF +} OMX_IMAGE_QUANTIZATIONTABLETYPE; + +/** + * JPEG quantization tables are used to determine DCT compression for + * YUV data, as an alternative to specifying Q factor, providing exact + * control of compression + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eQuantizationTable : Quantization table type + * nQuantizationMatrix[64] : JPEG quantization table of coefficients stored + * in increasing columns then by rows of data (i.e. + * row 1, ... row 8). Quantization values are in + * the range 0-255 and stored in linear order + * (i.e. the component will zig-zag the + * quantization table data if required internally) + */ +typedef struct OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_QUANTIZATIONTABLETYPE eQuantizationTable; + OMX_U8 nQuantizationMatrix[64]; +} OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE; + + +/** + * Huffman table type, the same Huffman table is applied for chroma and + * luma component + */ +typedef enum OMX_IMAGE_HUFFMANTABLETYPE { + OMX_IMAGE_HuffmanTableAC = 0, + OMX_IMAGE_HuffmanTableDC, + OMX_IMAGE_HuffmanTableACLuma, + OMX_IMAGE_HuffmanTableACChroma, + OMX_IMAGE_HuffmanTableDCLuma, + OMX_IMAGE_HuffmanTableDCChroma, + OMX_IMAGE_HuffmanTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_HuffmanTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_HuffmanTableMax = 0x7FFFFFFF +} OMX_IMAGE_HUFFMANTABLETYPE; + +/** + * JPEG Huffman table + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eHuffmanTable : Huffman table type + * nNumberOfHuffmanCodeOfLength[16] : 0-16, number of Huffman codes of each + * possible length + * nHuffmanTable[256] : 0-255, the size used for AC and DC + * HuffmanTable are 16 and 162 + */ +typedef struct OMX_IMAGE_PARAM_HUFFMANTTABLETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_HUFFMANTABLETYPE eHuffmanTable; + OMX_U8 nNumberOfHuffmanCodeOfLength[16]; + OMX_U8 nHuffmanTable[256]; +}OMX_IMAGE_PARAM_HUFFMANTTABLETYPE; + +/** @} */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/phonelibs/android_frameworks_native/include/media/openmax/OMX_Index.h b/phonelibs/android_frameworks_native/include/media/openmax/OMX_Index.h new file mode 100644 index 00000000000000..1a2a548e88ad84 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/openmax/OMX_Index.h @@ -0,0 +1,274 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** @file OMX_Index.h - OpenMax IL version 1.1.2 + * The OMX_Index header file contains the definitions for both applications + * and components . + */ + + +#ifndef OMX_Index_h +#define OMX_Index_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ +#include + +/** The OMX_INDEXTYPE enumeration is used to select a structure when either + * getting or setting parameters and/or configuration data. Each entry in + * this enumeration maps to an OMX specified structure. When the + * OMX_GetParameter, OMX_SetParameter, OMX_GetConfig or OMX_SetConfig methods + * are used, the second parameter will always be an entry from this enumeration + * and the third entry will be the structure shown in the comments for the entry. + * For example, if the application is initializing a cropping function, the + * OMX_SetConfig command would have OMX_IndexConfigCommonInputCrop as the second parameter + * and would send a pointer to an initialized OMX_RECTTYPE structure as the + * third parameter. + * + * The enumeration entries named with the OMX_Config prefix are sent using + * the OMX_SetConfig command and the enumeration entries named with the + * OMX_PARAM_ prefix are sent using the OMX_SetParameter command. + */ +typedef enum OMX_INDEXTYPE { + + OMX_IndexComponentStartUnused = 0x01000000, + OMX_IndexParamPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ + OMX_IndexParamAudioInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamImageInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamVideoInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamOtherInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamNumAvailableStreams, /**< reference: OMX_PARAM_U32TYPE */ + OMX_IndexParamActiveStream, /**< reference: OMX_PARAM_U32TYPE */ + OMX_IndexParamSuspensionPolicy, /**< reference: OMX_PARAM_SUSPENSIONPOLICYTYPE */ + OMX_IndexParamComponentSuspended, /**< reference: OMX_PARAM_SUSPENSIONTYPE */ + OMX_IndexConfigCapturing, /**< reference: OMX_CONFIG_BOOLEANTYPE */ + OMX_IndexConfigCaptureMode, /**< reference: OMX_CONFIG_CAPTUREMODETYPE */ + OMX_IndexAutoPauseAfterCapture, /**< reference: OMX_CONFIG_BOOLEANTYPE */ + OMX_IndexParamContentURI, /**< reference: OMX_PARAM_CONTENTURITYPE */ + OMX_IndexParamCustomContentPipe, /**< reference: OMX_PARAM_CONTENTPIPETYPE */ + OMX_IndexParamDisableResourceConcealment, /**< reference: OMX_RESOURCECONCEALMENTTYPE */ + OMX_IndexConfigMetadataItemCount, /**< reference: OMX_CONFIG_METADATAITEMCOUNTTYPE */ + OMX_IndexConfigContainerNodeCount, /**< reference: OMX_CONFIG_CONTAINERNODECOUNTTYPE */ + OMX_IndexConfigMetadataItem, /**< reference: OMX_CONFIG_METADATAITEMTYPE */ + OMX_IndexConfigCounterNodeID, /**< reference: OMX_CONFIG_CONTAINERNODEIDTYPE */ + OMX_IndexParamMetadataFilterType, /**< reference: OMX_PARAM_METADATAFILTERTYPE */ + OMX_IndexParamMetadataKeyFilter, /**< reference: OMX_PARAM_METADATAFILTERTYPE */ + OMX_IndexConfigPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ + OMX_IndexParamStandardComponentRole, /**< reference: OMX_PARAM_COMPONENTROLETYPE */ + + OMX_IndexPortStartUnused = 0x02000000, + OMX_IndexParamPortDefinition, /**< reference: OMX_PARAM_PORTDEFINITIONTYPE */ + OMX_IndexParamCompBufferSupplier, /**< reference: OMX_PARAM_BUFFERSUPPLIERTYPE */ + OMX_IndexReservedStartUnused = 0x03000000, + + /* Audio parameters and configurations */ + OMX_IndexAudioStartUnused = 0x04000000, + OMX_IndexParamAudioPortFormat, /**< reference: OMX_AUDIO_PARAM_PORTFORMATTYPE */ + OMX_IndexParamAudioPcm, /**< reference: OMX_AUDIO_PARAM_PCMMODETYPE */ + OMX_IndexParamAudioAac, /**< reference: OMX_AUDIO_PARAM_AACPROFILETYPE */ + OMX_IndexParamAudioRa, /**< reference: OMX_AUDIO_PARAM_RATYPE */ + OMX_IndexParamAudioMp3, /**< reference: OMX_AUDIO_PARAM_MP3TYPE */ + OMX_IndexParamAudioAdpcm, /**< reference: OMX_AUDIO_PARAM_ADPCMTYPE */ + OMX_IndexParamAudioG723, /**< reference: OMX_AUDIO_PARAM_G723TYPE */ + OMX_IndexParamAudioG729, /**< reference: OMX_AUDIO_PARAM_G729TYPE */ + OMX_IndexParamAudioAmr, /**< reference: OMX_AUDIO_PARAM_AMRTYPE */ + OMX_IndexParamAudioWma, /**< reference: OMX_AUDIO_PARAM_WMATYPE */ + OMX_IndexParamAudioSbc, /**< reference: OMX_AUDIO_PARAM_SBCTYPE */ + OMX_IndexParamAudioMidi, /**< reference: OMX_AUDIO_PARAM_MIDITYPE */ + OMX_IndexParamAudioGsm_FR, /**< reference: OMX_AUDIO_PARAM_GSMFRTYPE */ + OMX_IndexParamAudioMidiLoadUserSound, /**< reference: OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE */ + OMX_IndexParamAudioG726, /**< reference: OMX_AUDIO_PARAM_G726TYPE */ + OMX_IndexParamAudioGsm_EFR, /**< reference: OMX_AUDIO_PARAM_GSMEFRTYPE */ + OMX_IndexParamAudioGsm_HR, /**< reference: OMX_AUDIO_PARAM_GSMHRTYPE */ + OMX_IndexParamAudioPdc_FR, /**< reference: OMX_AUDIO_PARAM_PDCFRTYPE */ + OMX_IndexParamAudioPdc_EFR, /**< reference: OMX_AUDIO_PARAM_PDCEFRTYPE */ + OMX_IndexParamAudioPdc_HR, /**< reference: OMX_AUDIO_PARAM_PDCHRTYPE */ + OMX_IndexParamAudioTdma_FR, /**< reference: OMX_AUDIO_PARAM_TDMAFRTYPE */ + OMX_IndexParamAudioTdma_EFR, /**< reference: OMX_AUDIO_PARAM_TDMAEFRTYPE */ + OMX_IndexParamAudioQcelp8, /**< reference: OMX_AUDIO_PARAM_QCELP8TYPE */ + OMX_IndexParamAudioQcelp13, /**< reference: OMX_AUDIO_PARAM_QCELP13TYPE */ + OMX_IndexParamAudioEvrc, /**< reference: OMX_AUDIO_PARAM_EVRCTYPE */ + OMX_IndexParamAudioSmv, /**< reference: OMX_AUDIO_PARAM_SMVTYPE */ + OMX_IndexParamAudioVorbis, /**< reference: OMX_AUDIO_PARAM_VORBISTYPE */ + OMX_IndexParamAudioFlac, /**< reference: OMX_AUDIO_PARAM_FLACTYPE */ + + OMX_IndexConfigAudioMidiImmediateEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE */ + OMX_IndexConfigAudioMidiControl, /**< reference: OMX_AUDIO_CONFIG_MIDICONTROLTYPE */ + OMX_IndexConfigAudioMidiSoundBankProgram, /**< reference: OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE */ + OMX_IndexConfigAudioMidiStatus, /**< reference: OMX_AUDIO_CONFIG_MIDISTATUSTYPE */ + OMX_IndexConfigAudioMidiMetaEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE */ + OMX_IndexConfigAudioMidiMetaEventData, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE */ + OMX_IndexConfigAudioVolume, /**< reference: OMX_AUDIO_CONFIG_VOLUMETYPE */ + OMX_IndexConfigAudioBalance, /**< reference: OMX_AUDIO_CONFIG_BALANCETYPE */ + OMX_IndexConfigAudioChannelMute, /**< reference: OMX_AUDIO_CONFIG_CHANNELMUTETYPE */ + OMX_IndexConfigAudioMute, /**< reference: OMX_AUDIO_CONFIG_MUTETYPE */ + OMX_IndexConfigAudioLoudness, /**< reference: OMX_AUDIO_CONFIG_LOUDNESSTYPE */ + OMX_IndexConfigAudioEchoCancelation, /**< reference: OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE */ + OMX_IndexConfigAudioNoiseReduction, /**< reference: OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE */ + OMX_IndexConfigAudioBass, /**< reference: OMX_AUDIO_CONFIG_BASSTYPE */ + OMX_IndexConfigAudioTreble, /**< reference: OMX_AUDIO_CONFIG_TREBLETYPE */ + OMX_IndexConfigAudioStereoWidening, /**< reference: OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE */ + OMX_IndexConfigAudioChorus, /**< reference: OMX_AUDIO_CONFIG_CHORUSTYPE */ + OMX_IndexConfigAudioEqualizer, /**< reference: OMX_AUDIO_CONFIG_EQUALIZERTYPE */ + OMX_IndexConfigAudioReverberation, /**< reference: OMX_AUDIO_CONFIG_REVERBERATIONTYPE */ + OMX_IndexConfigAudioChannelVolume, /**< reference: OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE */ + + /* Image specific parameters and configurations */ + OMX_IndexImageStartUnused = 0x05000000, + OMX_IndexParamImagePortFormat, /**< reference: OMX_IMAGE_PARAM_PORTFORMATTYPE */ + OMX_IndexParamFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */ + OMX_IndexConfigFocusControl, /**< reference: OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE */ + OMX_IndexParamQFactor, /**< reference: OMX_IMAGE_PARAM_QFACTORTYPE */ + OMX_IndexParamQuantizationTable, /**< reference: OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE */ + OMX_IndexParamHuffmanTable, /**< reference: OMX_IMAGE_PARAM_HUFFMANTTABLETYPE */ + OMX_IndexConfigFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */ + + /* Video specific parameters and configurations */ + OMX_IndexVideoStartUnused = 0x06000000, + OMX_IndexParamVideoPortFormat, /**< reference: OMX_VIDEO_PARAM_PORTFORMATTYPE */ + OMX_IndexParamVideoQuantization, /**< reference: OMX_VIDEO_PARAM_QUANTIZATIONTYPE */ + OMX_IndexParamVideoFastUpdate, /**< reference: OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE */ + OMX_IndexParamVideoBitrate, /**< reference: OMX_VIDEO_PARAM_BITRATETYPE */ + OMX_IndexParamVideoMotionVector, /**< reference: OMX_VIDEO_PARAM_MOTIONVECTORTYPE */ + OMX_IndexParamVideoIntraRefresh, /**< reference: OMX_VIDEO_PARAM_INTRAREFRESHTYPE */ + OMX_IndexParamVideoErrorCorrection, /**< reference: OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE */ + OMX_IndexParamVideoVBSMC, /**< reference: OMX_VIDEO_PARAM_VBSMCTYPE */ + OMX_IndexParamVideoMpeg2, /**< reference: OMX_VIDEO_PARAM_MPEG2TYPE */ + OMX_IndexParamVideoMpeg4, /**< reference: OMX_VIDEO_PARAM_MPEG4TYPE */ + OMX_IndexParamVideoWmv, /**< reference: OMX_VIDEO_PARAM_WMVTYPE */ + OMX_IndexParamVideoRv, /**< reference: OMX_VIDEO_PARAM_RVTYPE */ + OMX_IndexParamVideoAvc, /**< reference: OMX_VIDEO_PARAM_AVCTYPE */ + OMX_IndexParamVideoH263, /**< reference: OMX_VIDEO_PARAM_H263TYPE */ + OMX_IndexParamVideoProfileLevelQuerySupported, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */ + OMX_IndexParamVideoProfileLevelCurrent, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */ + OMX_IndexConfigVideoBitrate, /**< reference: OMX_VIDEO_CONFIG_BITRATETYPE */ + OMX_IndexConfigVideoFramerate, /**< reference: OMX_CONFIG_FRAMERATETYPE */ + OMX_IndexConfigVideoIntraVOPRefresh, /**< reference: OMX_CONFIG_INTRAREFRESHVOPTYPE */ + OMX_IndexConfigVideoIntraMBRefresh, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */ + OMX_IndexConfigVideoMBErrorReporting, /**< reference: OMX_CONFIG_MBERRORREPORTINGTYPE */ + OMX_IndexParamVideoMacroblocksPerFrame, /**< reference: OMX_PARAM_MACROBLOCKSTYPE */ + OMX_IndexConfigVideoMacroBlockErrorMap, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */ + OMX_IndexParamVideoSliceFMO, /**< reference: OMX_VIDEO_PARAM_AVCSLICEFMO */ + OMX_IndexConfigVideoAVCIntraPeriod, /**< reference: OMX_VIDEO_CONFIG_AVCINTRAPERIOD */ + OMX_IndexConfigVideoNalSize, /**< reference: OMX_VIDEO_CONFIG_NALSIZE */ + + /* Image & Video common Configurations */ + OMX_IndexCommonStartUnused = 0x07000000, + OMX_IndexParamCommonDeblocking, /**< reference: OMX_PARAM_DEBLOCKINGTYPE */ + OMX_IndexParamCommonSensorMode, /**< reference: OMX_PARAM_SENSORMODETYPE */ + OMX_IndexParamCommonInterleave, /**< reference: OMX_PARAM_INTERLEAVETYPE */ + OMX_IndexConfigCommonColorFormatConversion, /**< reference: OMX_CONFIG_COLORCONVERSIONTYPE */ + OMX_IndexConfigCommonScale, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ + OMX_IndexConfigCommonImageFilter, /**< reference: OMX_CONFIG_IMAGEFILTERTYPE */ + OMX_IndexConfigCommonColorEnhancement, /**< reference: OMX_CONFIG_COLORENHANCEMENTTYPE */ + OMX_IndexConfigCommonColorKey, /**< reference: OMX_CONFIG_COLORKEYTYPE */ + OMX_IndexConfigCommonColorBlend, /**< reference: OMX_CONFIG_COLORBLENDTYPE */ + OMX_IndexConfigCommonFrameStabilisation,/**< reference: OMX_CONFIG_FRAMESTABTYPE */ + OMX_IndexConfigCommonRotate, /**< reference: OMX_CONFIG_ROTATIONTYPE */ + OMX_IndexConfigCommonMirror, /**< reference: OMX_CONFIG_MIRRORTYPE */ + OMX_IndexConfigCommonOutputPosition, /**< reference: OMX_CONFIG_POINTTYPE */ + OMX_IndexConfigCommonInputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ + OMX_IndexConfigCommonOutputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ + OMX_IndexConfigCommonDigitalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ + OMX_IndexConfigCommonOpticalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE*/ + OMX_IndexConfigCommonWhiteBalance, /**< reference: OMX_CONFIG_WHITEBALCONTROLTYPE */ + OMX_IndexConfigCommonExposure, /**< reference: OMX_CONFIG_EXPOSURECONTROLTYPE */ + OMX_IndexConfigCommonContrast, /**< reference: OMX_CONFIG_CONTRASTTYPE */ + OMX_IndexConfigCommonBrightness, /**< reference: OMX_CONFIG_BRIGHTNESSTYPE */ + OMX_IndexConfigCommonBacklight, /**< reference: OMX_CONFIG_BACKLIGHTTYPE */ + OMX_IndexConfigCommonGamma, /**< reference: OMX_CONFIG_GAMMATYPE */ + OMX_IndexConfigCommonSaturation, /**< reference: OMX_CONFIG_SATURATIONTYPE */ + OMX_IndexConfigCommonLightness, /**< reference: OMX_CONFIG_LIGHTNESSTYPE */ + OMX_IndexConfigCommonExclusionRect, /**< reference: OMX_CONFIG_RECTTYPE */ + OMX_IndexConfigCommonDithering, /**< reference: OMX_CONFIG_DITHERTYPE */ + OMX_IndexConfigCommonPlaneBlend, /**< reference: OMX_CONFIG_PLANEBLENDTYPE */ + OMX_IndexConfigCommonExposureValue, /**< reference: OMX_CONFIG_EXPOSUREVALUETYPE */ + OMX_IndexConfigCommonOutputSize, /**< reference: OMX_FRAMESIZETYPE */ + OMX_IndexParamCommonExtraQuantData, /**< reference: OMX_OTHER_EXTRADATATYPE */ + OMX_IndexConfigCommonFocusRegion, /**< reference: OMX_CONFIG_FOCUSREGIONTYPE */ + OMX_IndexConfigCommonFocusStatus, /**< reference: OMX_PARAM_FOCUSSTATUSTYPE */ + OMX_IndexConfigCommonTransitionEffect, /**< reference: OMX_CONFIG_TRANSITIONEFFECTTYPE */ + + /* Reserved Configuration range */ + OMX_IndexOtherStartUnused = 0x08000000, + OMX_IndexParamOtherPortFormat, /**< reference: OMX_OTHER_PARAM_PORTFORMATTYPE */ + OMX_IndexConfigOtherPower, /**< reference: OMX_OTHER_CONFIG_POWERTYPE */ + OMX_IndexConfigOtherStats, /**< reference: OMX_OTHER_CONFIG_STATSTYPE */ + + + /* Reserved Time range */ + OMX_IndexTimeStartUnused = 0x09000000, + OMX_IndexConfigTimeScale, /**< reference: OMX_TIME_CONFIG_SCALETYPE */ + OMX_IndexConfigTimeClockState, /**< reference: OMX_TIME_CONFIG_CLOCKSTATETYPE */ + OMX_IndexConfigTimeActiveRefClock, /**< reference: OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE */ + OMX_IndexConfigTimeCurrentMediaTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */ + OMX_IndexConfigTimeCurrentWallTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */ + OMX_IndexConfigTimeCurrentAudioReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ + OMX_IndexConfigTimeCurrentVideoReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ + OMX_IndexConfigTimeMediaTimeRequest, /**< reference: OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE (write only) */ + OMX_IndexConfigTimeClientStartTime, /** + + +/** Khronos standard extension indices. + +This enum lists the current Khronos extension indices to OpenMAX IL. +*/ +typedef enum OMX_INDEXEXTTYPE { + + /* Component parameters and configurations */ + OMX_IndexExtComponentStartUnused = OMX_IndexKhronosExtensions + 0x00100000, + OMX_IndexConfigCallbackRequest, /**< reference: OMX_CONFIG_CALLBACKREQUESTTYPE */ + OMX_IndexConfigCommitMode, /**< reference: OMX_CONFIG_COMMITMODETYPE */ + OMX_IndexConfigCommit, /**< reference: OMX_CONFIG_COMMITTYPE */ + + /* Port parameters and configurations */ + OMX_IndexExtPortStartUnused = OMX_IndexKhronosExtensions + 0x00200000, + + /* Audio parameters and configurations */ + OMX_IndexExtAudioStartUnused = OMX_IndexKhronosExtensions + 0x00400000, + OMX_IndexParamAudioAndroidAc3, /**< reference: OMX_AUDIO_PARAM_ANDROID_AC3TYPE */ + OMX_IndexParamAudioAndroidOpus, /**< reference: OMX_AUDIO_PARAM_ANDROID_OPUSTYPE */ + OMX_IndexParamAudioAndroidAacPresentation, /**< reference: OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE */ + OMX_IndexParamAudioAndroidEac3, /**< reference: OMX_AUDIO_PARAM_ANDROID_EAC3TYPE */ + + /* Image parameters and configurations */ + OMX_IndexExtImageStartUnused = OMX_IndexKhronosExtensions + 0x00500000, + + /* Video parameters and configurations */ + OMX_IndexExtVideoStartUnused = OMX_IndexKhronosExtensions + 0x00600000, + OMX_IndexParamNalStreamFormatSupported, /**< reference: OMX_NALSTREAMFORMATTYPE */ + OMX_IndexParamNalStreamFormat, /**< reference: OMX_NALSTREAMFORMATTYPE */ + OMX_IndexParamNalStreamFormatSelect, /**< reference: OMX_NALSTREAMFORMATTYPE */ + OMX_IndexParamVideoVp8, /**< reference: OMX_VIDEO_PARAM_VP8TYPE */ + OMX_IndexConfigVideoVp8ReferenceFrame, /**< reference: OMX_VIDEO_VP8REFERENCEFRAMETYPE */ + OMX_IndexConfigVideoVp8ReferenceFrameType, /**< reference: OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE */ + OMX_IndexParamVideoAndroidVp8Encoder, /**< reference: OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE */ + OMX_IndexParamVideoHevc, /**< reference: OMX_VIDEO_PARAM_HEVCTYPE */ + OMX_IndexParamSliceSegments, /**< reference: OMX_VIDEO_SLICESEGMENTSTYPE */ + + /* Image & Video common configurations */ + OMX_IndexExtCommonStartUnused = OMX_IndexKhronosExtensions + 0x00700000, + + /* Other configurations */ + OMX_IndexExtOtherStartUnused = OMX_IndexKhronosExtensions + 0x00800000, + OMX_IndexConfigAutoFramerateConversion, /**< reference: OMX_CONFIG_BOOLEANTYPE */ + OMX_IndexConfigPriority, /**< reference: OMX_PARAM_U32TYPE */ + OMX_IndexConfigOperatingRate, /**< reference: OMX_PARAM_U32TYPE in Q16 format for video and in Hz for audio */ + OMX_IndexParamConsumerUsageBits, /**< reference: OMX_PARAM_U32TYPE */ + + /* Time configurations */ + OMX_IndexExtTimeStartUnused = OMX_IndexKhronosExtensions + 0x00900000, + + OMX_IndexExtMax = 0x7FFFFFFF +} OMX_INDEXEXTTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* OMX_IndexExt_h */ +/* File EOF */ diff --git a/phonelibs/android_frameworks_native/include/media/openmax/OMX_Other.h b/phonelibs/android_frameworks_native/include/media/openmax/OMX_Other.h new file mode 100644 index 00000000000000..6072ef62c8614b --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/openmax/OMX_Other.h @@ -0,0 +1,354 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** @file OMX_Other.h - OpenMax IL version 1.1.2 + * The structures needed by Other components to exchange + * parameters and configuration data with the components. + */ + +#ifndef OMX_Other_h +#define OMX_Other_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + + +/** + * Enumeration of possible data types which match to multiple domains or no + * domain at all. For types which are vendor specific, a value above + * OMX_OTHER_VENDORTSTART should be used. + */ +typedef enum OMX_OTHER_FORMATTYPE { + OMX_OTHER_FormatTime = 0, /**< Transmission of various timestamps, elapsed time, + time deltas, etc */ + OMX_OTHER_FormatPower, /**< Perhaps used for enabling/disabling power + management, setting clocks? */ + OMX_OTHER_FormatStats, /**< Could be things such as frame rate, frames + dropped, etc */ + OMX_OTHER_FormatBinary, /**< Arbitrary binary data */ + OMX_OTHER_FormatVendorReserved = 1000, /**< Starting value for vendor specific + formats */ + + OMX_OTHER_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_OTHER_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_OTHER_FormatMax = 0x7FFFFFFF +} OMX_OTHER_FORMATTYPE; + +/** + * Enumeration of seek modes. + */ +typedef enum OMX_TIME_SEEKMODETYPE { + OMX_TIME_SeekModeFast = 0, /**< Prefer seeking to an approximation + * of the requested seek position over + * the actual seek position if it + * results in a faster seek. */ + OMX_TIME_SeekModeAccurate, /**< Prefer seeking to the actual seek + * position over an approximation + * of the requested seek position even + * if it results in a slower seek. */ + OMX_TIME_SeekModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_SeekModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_SeekModeMax = 0x7FFFFFFF +} OMX_TIME_SEEKMODETYPE; + +/* Structure representing the seekmode of the component */ +typedef struct OMX_TIME_CONFIG_SEEKMODETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_TIME_SEEKMODETYPE eType; /**< The seek mode */ +} OMX_TIME_CONFIG_SEEKMODETYPE; + +/** Structure representing a time stamp used with the following configs + * on the Clock Component (CC): + * + * OMX_IndexConfigTimeCurrentWallTime: query of the CC's current wall + * time + * OMX_IndexConfigTimeCurrentMediaTime: query of the CC's current media + * time + * OMX_IndexConfigTimeCurrentAudioReference and + * OMX_IndexConfigTimeCurrentVideoReference: audio/video reference + * clock sending SC its reference time + * OMX_IndexConfigTimeClientStartTime: a Clock Component client sends + * this structure to the Clock Component via a SetConfig on its + * client port when it receives a buffer with + * OMX_BUFFERFLAG_STARTTIME set. It must use the timestamp + * specified by that buffer for nStartTimestamp. + * + * It's also used with the following config on components in general: + * + * OMX_IndexConfigTimePosition: IL client querying component position + * (GetConfig) or commanding a component to seek to the given location + * (SetConfig) + */ +typedef struct OMX_TIME_CONFIG_TIMESTAMPTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version + * information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_TICKS nTimestamp; /**< timestamp .*/ +} OMX_TIME_CONFIG_TIMESTAMPTYPE; + +/** Enumeration of possible reference clocks to the media time. */ +typedef enum OMX_TIME_UPDATETYPE { + OMX_TIME_UpdateRequestFulfillment, /**< Update is the fulfillment of a media time request. */ + OMX_TIME_UpdateScaleChanged, /**< Update was generated because the scale chagned. */ + OMX_TIME_UpdateClockStateChanged, /**< Update was generated because the clock state changed. */ + OMX_TIME_UpdateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_UpdateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_UpdateMax = 0x7FFFFFFF +} OMX_TIME_UPDATETYPE; + +/** Enumeration of possible reference clocks to the media time. */ +typedef enum OMX_TIME_REFCLOCKTYPE { + OMX_TIME_RefClockNone, /**< Use no references. */ + OMX_TIME_RefClockAudio, /**< Use references sent through OMX_IndexConfigTimeCurrentAudioReference */ + OMX_TIME_RefClockVideo, /**< Use references sent through OMX_IndexConfigTimeCurrentVideoReference */ + OMX_TIME_RefClockKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_RefClockVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_RefClockMax = 0x7FFFFFFF +} OMX_TIME_REFCLOCKTYPE; + +/** Enumeration of clock states. */ +typedef enum OMX_TIME_CLOCKSTATE { + OMX_TIME_ClockStateRunning, /**< Clock running. */ + OMX_TIME_ClockStateWaitingForStartTime, /**< Clock waiting until the + * prescribed clients emit their + * start time. */ + OMX_TIME_ClockStateStopped, /**< Clock stopped. */ + OMX_TIME_ClockStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_ClockStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_ClockStateMax = 0x7FFFFFFF +} OMX_TIME_CLOCKSTATE; + +/** Structure representing a media time request to the clock component. + * + * A client component sends this structure to the Clock Component via a SetConfig + * on its client port to specify a media timestamp the Clock Component + * should emit. The Clock Component should fulfill the request by sending a + * OMX_TIME_MEDIATIMETYPE when its media clock matches the requested + * timestamp. + * + * The client may require a media time request be fulfilled slightly + * earlier than the media time specified. In this case the client specifies + * an offset which is equal to the difference between wall time corresponding + * to the requested media time and the wall time when it will be + * fulfilled. + * + * A client component may uses these requests and the OMX_TIME_MEDIATIMETYPE to + * time events according to timestamps. If a client must perform an operation O at + * a time T (e.g. deliver a video frame at its corresponding timestamp), it makes a + * media time request at T (perhaps specifying an offset to ensure the request fulfillment + * is a little early). When the clock component passes the resulting OMX_TIME_MEDIATIMETYPE + * structure back to the client component, the client may perform operation O (perhaps having + * to wait a slight amount more time itself as specified by the return values). + */ + +typedef struct OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_PTR pClientPrivate; /**< Client private data to disabiguate this media time + * from others (e.g. the number of the frame to deliver). + * Duplicated in the media time structure that fulfills + * this request. A value of zero is reserved for time scale + * updates. */ + OMX_TICKS nMediaTimestamp; /**< Media timestamp requested.*/ + OMX_TICKS nOffset; /**< Amount of wall clock time by which this + * request should be fulfilled early */ +} OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE; + +/**< Structure sent from the clock component client either when fulfilling + * a media time request or when the time scale has changed. + * + * In the former case the Clock Component fills this structure and times its emission + * to a client component (via the client port) according to the corresponding media + * time request sent by the client. The Clock Component should time the emission to occur + * when the requested timestamp matches the Clock Component's media time but also the + * prescribed offset early. + * + * Upon scale changes the clock component clears the nClientPrivate data, sends the current + * media time and sets the nScale to the new scale via the client port. It emits a + * OMX_TIME_MEDIATIMETYPE to all clients independent of any requests. This allows clients to + * alter processing to accomodate scaling. For instance a video component might skip inter-frames + * in the case of extreme fastforward. Likewise an audio component might add or remove samples + * from an audio frame to scale audio data. + * + * It is expected that some clock components may not be able to fulfill requests + * at exactly the prescribed time. This is acceptable so long as the request is + * fulfilled at least as early as described and not later. This structure provides + * fields the client may use to wait for the remaining time. + * + * The client may use either the nOffset or nWallTimeAtMedia fields to determine the + * wall time until the nMediaTimestamp actually occurs. In the latter case the + * client can get a more accurate value for offset by getting the current wall + * from the cloc component and subtracting it from nWallTimeAtMedia. + */ + +typedef struct OMX_TIME_MEDIATIMETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nClientPrivate; /**< Client private data to disabiguate this media time + * from others. Copied from the media time request. + * A value of zero is reserved for time scale updates. */ + OMX_TIME_UPDATETYPE eUpdateType; /**< Reason for the update */ + OMX_TICKS nMediaTimestamp; /**< Media time requested. If no media time was + * requested then this is the current media time. */ + OMX_TICKS nOffset; /**< Amount of wall clock time by which this + * request was actually fulfilled early */ + + OMX_TICKS nWallTimeAtMediaTime; /**< Wall time corresponding to nMediaTimeStamp. + * A client may compare this value to current + * media time obtained from the Clock Component to determine + * the wall time until the media timestamp is really + * current. */ + OMX_S32 xScale; /**< Current media time scale in Q16 format. */ + OMX_TIME_CLOCKSTATE eState; /* Seeking Change. Added 7/12.*/ + /**< State of the media time. */ +} OMX_TIME_MEDIATIMETYPE; + +/** Structure representing the current media time scale factor. Applicable only to clock + * component, other components see scale changes via OMX_TIME_MEDIATIMETYPE buffers sent via + * the clock component client ports. Upon recieving this config the clock component changes + * the rate by which the media time increases or decreases effectively implementing trick modes. + */ +typedef struct OMX_TIME_CONFIG_SCALETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_S32 xScale; /**< This is a value in Q16 format which is used for + * scaling the media time */ +} OMX_TIME_CONFIG_SCALETYPE; + +/** Bits used to identify a clock port. Used in OMX_TIME_CONFIG_CLOCKSTATETYPE's nWaitMask field */ +#define OMX_CLOCKPORT0 0x00000001 +#define OMX_CLOCKPORT1 0x00000002 +#define OMX_CLOCKPORT2 0x00000004 +#define OMX_CLOCKPORT3 0x00000008 +#define OMX_CLOCKPORT4 0x00000010 +#define OMX_CLOCKPORT5 0x00000020 +#define OMX_CLOCKPORT6 0x00000040 +#define OMX_CLOCKPORT7 0x00000080 + +/** Structure representing the current mode of the media clock. + * IL Client uses this config to change or query the mode of the + * media clock of the clock component. Applicable only to clock + * component. + * + * On a SetConfig if eState is OMX_TIME_ClockStateRunning media time + * starts immediately at the prescribed start time. If + * OMX_TIME_ClockStateWaitingForStartTime the Clock Component ignores + * the given nStartTime and waits for all clients specified in the + * nWaitMask to send starttimes (via + * OMX_IndexConfigTimeClientStartTime). The Clock Component then starts + * the media clock using the earliest start time supplied. */ +typedef struct OMX_TIME_CONFIG_CLOCKSTATETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version + * information */ + OMX_TIME_CLOCKSTATE eState; /**< State of the media time. */ + OMX_TICKS nStartTime; /**< Start time of the media time. */ + OMX_TICKS nOffset; /**< Time to offset the media time by + * (e.g. preroll). Media time will be + * reported to be nOffset ticks earlier. + */ + OMX_U32 nWaitMask; /**< Mask of OMX_CLOCKPORT values. */ +} OMX_TIME_CONFIG_CLOCKSTATETYPE; + +/** Structure representing the reference clock currently being used to + * compute media time. IL client uses this config to change or query the + * clock component's active reference clock */ +typedef struct OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_TIME_REFCLOCKTYPE eClock; /**< Reference clock used to compute media time */ +} OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE; + +/** Descriptor for setting specifics of power type. + * Note: this structure is listed for backwards compatibility. */ +typedef struct OMX_OTHER_CONFIG_POWERTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_BOOL bEnablePM; /**< Flag to enable Power Management */ +} OMX_OTHER_CONFIG_POWERTYPE; + + +/** Descriptor for setting specifics of stats type. + * Note: this structure is listed for backwards compatibility. */ +typedef struct OMX_OTHER_CONFIG_STATSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + /* what goes here */ +} OMX_OTHER_CONFIG_STATSTYPE; + + +/** + * The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output other + * path. + */ +typedef struct OMX_OTHER_PORTDEFINITIONTYPE { + OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */ +} OMX_OTHER_PORTDEFINITIONTYPE; + +/** Port format parameter. This structure is used to enumerate + * the various data input/output format supported by the port. + */ +typedef struct OMX_OTHER_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Indicates which port to set */ + OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */ + OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */ +} OMX_OTHER_PARAM_PORTFORMATTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/phonelibs/android_frameworks_native/include/media/openmax/OMX_Types.h b/phonelibs/android_frameworks_native/include/media/openmax/OMX_Types.h new file mode 100644 index 00000000000000..5afaba057c7ad4 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/openmax/OMX_Types.h @@ -0,0 +1,387 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** OMX_Types.h - OpenMax IL version 1.1.2 + * The OMX_Types header file contains the primitive type definitions used by + * the core, the application and the component. This file may need to be + * modified to be used on systems that do not have "char" set to 8 bits, + * "short" set to 16 bits and "long" set to 32 bits. + */ + +#ifndef OMX_Types_h +#define OMX_Types_h + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** The OMX_API and OMX_APIENTRY are platform specific definitions used + * to declare OMX function prototypes. They are modified to meet the + * requirements for a particular platform */ +#ifdef __SYMBIAN32__ +# ifdef __OMX_EXPORTS +# define OMX_API __declspec(dllexport) +# else +# ifdef _WIN32 +# define OMX_API __declspec(dllexport) +# else +# define OMX_API __declspec(dllimport) +# endif +# endif +#else +# ifdef _WIN32 +# ifdef __OMX_EXPORTS +# define OMX_API __declspec(dllexport) +# else +//# define OMX_API __declspec(dllimport) +#define OMX_API +# endif +# else +# ifdef __OMX_EXPORTS +# define OMX_API +# else +# define OMX_API extern +# endif +# endif +#endif + +#ifndef OMX_APIENTRY +#define OMX_APIENTRY +#endif + +/** OMX_IN is used to identify inputs to an OMX function. This designation + will also be used in the case of a pointer that points to a parameter + that is used as an output. */ +#ifndef OMX_IN +#define OMX_IN +#endif + +/** OMX_OUT is used to identify outputs from an OMX function. This + designation will also be used in the case of a pointer that points + to a parameter that is used as an input. */ +#ifndef OMX_OUT +#define OMX_OUT +#endif + + +/** OMX_INOUT is used to identify parameters that may be either inputs or + outputs from an OMX function at the same time. This designation will + also be used in the case of a pointer that points to a parameter that + is used both as an input and an output. */ +#ifndef OMX_INOUT +#define OMX_INOUT +#endif + +/** OMX_ALL is used to as a wildcard to select all entities of the same type + * when specifying the index, or referring to a object by an index. (i.e. + * use OMX_ALL to indicate all N channels). When used as a port index + * for a config or parameter this OMX_ALL denotes that the config or + * parameter applies to the entire component not just one port. */ +#define OMX_ALL 0xFFFFFFFF + +/** In the following we define groups that help building doxygen documentation */ + +/** @defgroup core OpenMAX IL core + * Functions and structure related to the OMX IL core + */ + + /** @defgroup comp OpenMAX IL component + * Functions and structure related to the OMX IL component + */ + +/** @defgroup rpm Resource and Policy Management + * Structures for resource and policy management of components + */ + +/** @defgroup buf Buffer Management + * Buffer handling functions and structures + */ + +/** @defgroup tun Tunneling + * @ingroup core comp + * Structures and functions to manage tunnels among component ports + */ + +/** @defgroup cp Content Pipes + * @ingroup core + */ + + /** @defgroup metadata Metadata handling + * + */ + +/** OMX_U8 is an 8 bit unsigned quantity that is byte aligned */ +typedef unsigned char OMX_U8; + +/** OMX_S8 is an 8 bit signed quantity that is byte aligned */ +typedef signed char OMX_S8; + +/** OMX_U16 is a 16 bit unsigned quantity that is 16 bit word aligned */ +typedef unsigned short OMX_U16; + +/** OMX_S16 is a 16 bit signed quantity that is 16 bit word aligned */ +typedef signed short OMX_S16; + +/** OMX_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */ +typedef uint32_t OMX_U32; + +/** OMX_S32 is a 32 bit signed quantity that is 32 bit word aligned */ +typedef int32_t OMX_S32; + + +/* Users with compilers that cannot accept the "long long" designation should + define the OMX_SKIP64BIT macro. It should be noted that this may cause + some components to fail to compile if the component was written to require + 64 bit integral types. However, these components would NOT compile anyway + since the compiler does not support the way the component was written. +*/ +#ifndef OMX_SKIP64BIT +#ifdef __SYMBIAN32__ +/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ +typedef unsigned long long OMX_U64; + +/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ +typedef signed long long OMX_S64; + +#elif defined(WIN32) + +/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ +typedef unsigned __int64 OMX_U64; + +/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ +typedef signed __int64 OMX_S64; + +#else /* WIN32 */ + +/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ +typedef unsigned long long OMX_U64; + +/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ +typedef signed long long OMX_S64; + +#endif /* WIN32 */ +#endif + + +/** The OMX_BOOL type is intended to be used to represent a true or a false + value when passing parameters to and from the OMX core and components. The + OMX_BOOL is a 32 bit quantity and is aligned on a 32 bit word boundary. + */ +typedef enum OMX_BOOL { + OMX_FALSE = 0, + OMX_TRUE = !OMX_FALSE, + OMX_BOOL_MAX = 0x7FFFFFFF +} OMX_BOOL; + +/* + * Temporary Android 64 bit modification + * + * #define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS + * overrides all OMX pointer types to be uint32_t. + * + * After this change, OMX codecs will work in 32 bit only, so 64 bit processes + * must communicate to a remote 32 bit process for OMX to work. + */ + +#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS + +typedef uint32_t OMX_PTR; +typedef OMX_PTR OMX_STRING; +typedef OMX_PTR OMX_BYTE; + +#else /* OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS */ + +/** The OMX_PTR type is intended to be used to pass pointers between the OMX + applications and the OMX Core and components. This is a 32 bit pointer and + is aligned on a 32 bit boundary. + */ +typedef void* OMX_PTR; + +/** The OMX_STRING type is intended to be used to pass "C" type strings between + the application and the core and component. The OMX_STRING type is a 32 + bit pointer to a zero terminated string. The pointer is word aligned and + the string is byte aligned. + */ +typedef char* OMX_STRING; + +/** The OMX_BYTE type is intended to be used to pass arrays of bytes such as + buffers between the application and the component and core. The OMX_BYTE + type is a 32 bit pointer to a zero terminated string. The pointer is word + aligned and the string is byte aligned. + */ +typedef unsigned char* OMX_BYTE; + +#endif /* OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS */ + +/** OMX_UUIDTYPE is a very long unique identifier to uniquely identify + at runtime. This identifier should be generated by a component in a way + that guarantees that every instance of the identifier running on the system + is unique. */ +typedef unsigned char OMX_UUIDTYPE[128]; + +/** The OMX_DIRTYPE enumeration is used to indicate if a port is an input or + an output port. This enumeration is common across all component types. + */ +typedef enum OMX_DIRTYPE +{ + OMX_DirInput, /**< Port is an input port */ + OMX_DirOutput, /**< Port is an output port */ + OMX_DirMax = 0x7FFFFFFF +} OMX_DIRTYPE; + +/** The OMX_ENDIANTYPE enumeration is used to indicate the bit ordering + for numerical data (i.e. big endian, or little endian). + */ +typedef enum OMX_ENDIANTYPE +{ + OMX_EndianBig, /**< big endian */ + OMX_EndianLittle, /**< little endian */ + OMX_EndianMax = 0x7FFFFFFF +} OMX_ENDIANTYPE; + + +/** The OMX_NUMERICALDATATYPE enumeration is used to indicate if data + is signed or unsigned + */ +typedef enum OMX_NUMERICALDATATYPE +{ + OMX_NumericalDataSigned, /**< signed data */ + OMX_NumericalDataUnsigned, /**< unsigned data */ + OMX_NumercialDataMax = 0x7FFFFFFF +} OMX_NUMERICALDATATYPE; + + +/** Unsigned bounded value type */ +typedef struct OMX_BU32 { + OMX_U32 nValue; /**< actual value */ + OMX_U32 nMin; /**< minimum for value (i.e. nValue >= nMin) */ + OMX_U32 nMax; /**< maximum for value (i.e. nValue <= nMax) */ +} OMX_BU32; + + +/** Signed bounded value type */ +typedef struct OMX_BS32 { + OMX_S32 nValue; /**< actual value */ + OMX_S32 nMin; /**< minimum for value (i.e. nValue >= nMin) */ + OMX_S32 nMax; /**< maximum for value (i.e. nValue <= nMax) */ +} OMX_BS32; + + +/** Structure representing some time or duration in microseconds. This structure + * must be interpreted as a signed 64 bit value. The quantity is signed to accommodate + * negative deltas and preroll scenarios. The quantity is represented in microseconds + * to accomodate high resolution timestamps (e.g. DVD presentation timestamps based + * on a 90kHz clock) and to allow more accurate and synchronized delivery (e.g. + * individual audio samples delivered at 192 kHz). The quantity is 64 bit to + * accommodate a large dynamic range (signed 32 bit values would allow only for plus + * or minus 35 minutes). + * + * Implementations with limited precision may convert the signed 64 bit value to + * a signed 32 bit value internally but risk loss of precision. + */ +#ifndef OMX_SKIP64BIT +typedef OMX_S64 OMX_TICKS; +#else +typedef struct OMX_TICKS +{ + OMX_U32 nLowPart; /** low bits of the signed 64 bit tick value */ + OMX_U32 nHighPart; /** high bits of the signed 64 bit tick value */ +} OMX_TICKS; +#endif +#define OMX_TICKS_PER_SECOND 1000000 + +/** Define the public interface for the OMX Handle. The core will not use + this value internally, but the application should only use this value. + */ +typedef OMX_PTR OMX_HANDLETYPE; + +typedef struct OMX_MARKTYPE +{ + OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will + generate a mark event upon + processing the mark. */ + OMX_PTR pMarkData; /**< Application specific data associated with + the mark sent on a mark event to disambiguate + this mark from others. */ +} OMX_MARKTYPE; + + +/** OMX_NATIVE_DEVICETYPE is used to map a OMX video port to the + * platform & operating specific object used to reference the display + * or can be used by a audio port for native audio rendering */ +typedef OMX_PTR OMX_NATIVE_DEVICETYPE; + +/** OMX_NATIVE_WINDOWTYPE is used to map a OMX video port to the + * platform & operating specific object used to reference the window */ +typedef OMX_PTR OMX_NATIVE_WINDOWTYPE; + +/** The OMX_VERSIONTYPE union is used to specify the version for + a structure or component. For a component, the version is entirely + specified by the component vendor. Components doing the same function + from different vendors may or may not have the same version. For + structures, the version shall be set by the entity that allocates the + structure. For structures specified in the OMX 1.1 specification, the + value of the version shall be set to 1.1.0.0 in all cases. Access to the + OMX_VERSIONTYPE can be by a single 32 bit access (e.g. by nVersion) or + by accessing one of the structure elements to, for example, check only + the Major revision. + */ +typedef union OMX_VERSIONTYPE +{ + struct + { + OMX_U8 nVersionMajor; /**< Major version accessor element */ + OMX_U8 nVersionMinor; /**< Minor version accessor element */ + OMX_U8 nRevision; /**< Revision version accessor element */ + OMX_U8 nStep; /**< Step version accessor element */ + } s; + OMX_U32 nVersion; /**< 32 bit value to make accessing the + version easily done in a single word + size copy/compare operation */ +} OMX_VERSIONTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/phonelibs/android_frameworks_native/include/media/openmax/OMX_Video.h b/phonelibs/android_frameworks_native/include/media/openmax/OMX_Video.h new file mode 100644 index 00000000000000..decc410ba945a2 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/openmax/OMX_Video.h @@ -0,0 +1,1081 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/** + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** + * @file OMX_Video.h - OpenMax IL version 1.1.2 + * The structures is needed by Video components to exchange parameters + * and configuration data with OMX components. + */ +#ifndef OMX_Video_h +#define OMX_Video_h + +/** @defgroup video OpenMAX IL Video Domain + * @ingroup iv + * Structures for OpenMAX IL Video domain + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + * Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + + +/** + * Enumeration used to define the possible video compression codings. + * NOTE: This essentially refers to file extensions. If the coding is + * being used to specify the ENCODE type, then additional work + * must be done to configure the exact flavor of the compression + * to be used. For decode cases where the user application can + * not differentiate between MPEG-4 and H.264 bit streams, it is + * up to the codec to handle this. + */ +typedef enum OMX_VIDEO_CODINGTYPE { + OMX_VIDEO_CodingUnused, /**< Value when coding is N/A */ + OMX_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */ + OMX_VIDEO_CodingMPEG2, /**< AKA: H.262 */ + OMX_VIDEO_CodingH263, /**< H.263 */ + OMX_VIDEO_CodingMPEG4, /**< MPEG-4 */ + OMX_VIDEO_CodingWMV, /**< all versions of Windows Media Video */ + OMX_VIDEO_CodingRV, /**< all versions of Real Video */ + OMX_VIDEO_CodingAVC, /**< H.264/AVC */ + OMX_VIDEO_CodingMJPEG, /**< Motion JPEG */ + OMX_VIDEO_CodingVP8, /**< Google VP8, formerly known as On2 VP8 */ + OMX_VIDEO_CodingVP9, /**< Google VP9 */ + OMX_VIDEO_CodingHEVC, /**< ITU H.265/HEVC */ + OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_CodingMax = 0x7FFFFFFF +} OMX_VIDEO_CODINGTYPE; + + +/** + * Data structure used to define a video path. The number of Video paths for + * input and output will vary by type of the Video component. + * + * Input (aka Source) : zero Inputs, one Output, + * Splitter : one Input, 2 or more Outputs, + * Processing Element : one Input, one output, + * Mixer : 2 or more inputs, one output, + * Output (aka Sink) : one Input, zero outputs. + * + * The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output video + * path. If additional vendor specific data is required, it should be + * transmitted to the component using the CustomCommand function. Compliant + * components will prepopulate this structure with optimal values during the + * GetDefaultInitParams command. + * + * STRUCT MEMBERS: + * cMIMEType : MIME type of data for the port + * pNativeRender : Platform specific reference for a display if a + * sync, otherwise this field is 0 + * nFrameWidth : Width of frame to be used on channel if + * uncompressed format is used. Use 0 for unknown, + * don't care or variable + * nFrameHeight : Height of frame to be used on channel if + * uncompressed format is used. Use 0 for unknown, + * don't care or variable + * nStride : Number of bytes per span of an image + * (i.e. indicates the number of bytes to get + * from span N to span N+1, where negative stride + * indicates the image is bottom up + * nSliceHeight : Height used when encoding in slices + * nBitrate : Bit rate of frame to be used on channel if + * compressed format is used. Use 0 for unknown, + * don't care or variable + * xFramerate : Frame rate to be used on channel if uncompressed + * format is used. Use 0 for unknown, don't care or + * variable. Units are Q16 frames per second. + * bFlagErrorConcealment : Turns on error concealment if it is supported by + * the OMX component + * eCompressionFormat : Compression format used in this instance of the + * component. When OMX_VIDEO_CodingUnused is + * specified, eColorFormat is used + * eColorFormat : Decompressed format used by this component + * pNativeWindow : Platform specific reference for a window object if a + * display sink , otherwise this field is 0x0. + */ +typedef struct OMX_VIDEO_PORTDEFINITIONTYPE { + OMX_STRING cMIMEType; + OMX_NATIVE_DEVICETYPE pNativeRender; + OMX_U32 nFrameWidth; + OMX_U32 nFrameHeight; + OMX_S32 nStride; + OMX_U32 nSliceHeight; + OMX_U32 nBitrate; + OMX_U32 xFramerate; + OMX_BOOL bFlagErrorConcealment; + OMX_VIDEO_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; + OMX_NATIVE_WINDOWTYPE pNativeWindow; +} OMX_VIDEO_PORTDEFINITIONTYPE; + +/** + * Port format parameter. This structure is used to enumerate the various + * data input/output format supported by the port. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Indicates which port to set + * nIndex : Indicates the enumeration index for the format from + * 0x0 to N-1 + * eCompressionFormat : Compression format used in this instance of the + * component. When OMX_VIDEO_CodingUnused is specified, + * eColorFormat is used + * eColorFormat : Decompressed format used by this component + * xFrameRate : Indicates the video frame rate in Q16 format + */ +typedef struct OMX_VIDEO_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nIndex; + OMX_VIDEO_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; + OMX_U32 xFramerate; +} OMX_VIDEO_PARAM_PORTFORMATTYPE; + + +/** + * This is a structure for configuring video compression quantization + * parameter values. Codecs may support different QP values for different + * frame types. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version info + * nPortIndex : Port that this structure applies to + * nQpI : QP value to use for index frames + * nQpP : QP value to use for P frames + * nQpB : QP values to use for bidirectional frames + */ +typedef struct OMX_VIDEO_PARAM_QUANTIZATIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nQpI; + OMX_U32 nQpP; + OMX_U32 nQpB; +} OMX_VIDEO_PARAM_QUANTIZATIONTYPE; + + +/** + * Structure for configuration of video fast update parameters. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version info + * nPortIndex : Port that this structure applies to + * bEnableVFU : Enable/Disable video fast update + * nFirstGOB : Specifies the number of the first macroblock row + * nFirstMB : specifies the first MB relative to the specified first GOB + * nNumMBs : Specifies the number of MBs to be refreshed from nFirstGOB + * and nFirstMB + */ +typedef struct OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnableVFU; + OMX_U32 nFirstGOB; + OMX_U32 nFirstMB; + OMX_U32 nNumMBs; +} OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE; + + +/** + * Enumeration of possible bitrate control types + */ +typedef enum OMX_VIDEO_CONTROLRATETYPE { + OMX_Video_ControlRateDisable, + OMX_Video_ControlRateVariable, + OMX_Video_ControlRateConstant, + OMX_Video_ControlRateVariableSkipFrames, + OMX_Video_ControlRateConstantSkipFrames, + OMX_Video_ControlRateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_Video_ControlRateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_Video_ControlRateMax = 0x7FFFFFFF +} OMX_VIDEO_CONTROLRATETYPE; + + +/** + * Structure for configuring bitrate mode of a codec. + * + * STRUCT MEMBERS: + * nSize : Size of the struct in bytes + * nVersion : OMX spec version info + * nPortIndex : Port that this struct applies to + * eControlRate : Control rate type enum + * nTargetBitrate : Target bitrate to encode with + */ +typedef struct OMX_VIDEO_PARAM_BITRATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_CONTROLRATETYPE eControlRate; + OMX_U32 nTargetBitrate; +} OMX_VIDEO_PARAM_BITRATETYPE; + + +/** + * Enumeration of possible motion vector (MV) types + */ +typedef enum OMX_VIDEO_MOTIONVECTORTYPE { + OMX_Video_MotionVectorPixel, + OMX_Video_MotionVectorHalfPel, + OMX_Video_MotionVectorQuarterPel, + OMX_Video_MotionVectorEighthPel, + OMX_Video_MotionVectorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_Video_MotionVectorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_Video_MotionVectorMax = 0x7FFFFFFF +} OMX_VIDEO_MOTIONVECTORTYPE; + + +/** + * Structure for configuring the number of motion vectors used as well + * as their accuracy. + * + * STRUCT MEMBERS: + * nSize : Size of the struct in bytes + * nVersion : OMX spec version info + * nPortIndex : port that this structure applies to + * eAccuracy : Enumerated MV accuracy + * bUnrestrictedMVs : Allow unrestricted MVs + * bFourMV : Allow use of 4 MVs + * sXSearchRange : Search range in horizontal direction for MVs + * sYSearchRange : Search range in vertical direction for MVs + */ +typedef struct OMX_VIDEO_PARAM_MOTIONVECTORTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_MOTIONVECTORTYPE eAccuracy; + OMX_BOOL bUnrestrictedMVs; + OMX_BOOL bFourMV; + OMX_S32 sXSearchRange; + OMX_S32 sYSearchRange; +} OMX_VIDEO_PARAM_MOTIONVECTORTYPE; + + +/** + * Enumeration of possible methods to use for Intra Refresh + */ +typedef enum OMX_VIDEO_INTRAREFRESHTYPE { + OMX_VIDEO_IntraRefreshCyclic, + OMX_VIDEO_IntraRefreshAdaptive, + OMX_VIDEO_IntraRefreshBoth, + OMX_VIDEO_IntraRefreshKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_IntraRefreshVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_IntraRefreshMax = 0x7FFFFFFF +} OMX_VIDEO_INTRAREFRESHTYPE; + + +/** + * Structure for configuring intra refresh mode + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eRefreshMode : Cyclic, Adaptive, or Both + * nAirMBs : Number of intra macroblocks to refresh in a frame when + * AIR is enabled + * nAirRef : Number of times a motion marked macroblock has to be + * intra coded + * nCirMBs : Number of consecutive macroblocks to be coded as "intra" + * when CIR is enabled + */ +typedef struct OMX_VIDEO_PARAM_INTRAREFRESHTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_INTRAREFRESHTYPE eRefreshMode; + OMX_U32 nAirMBs; + OMX_U32 nAirRef; + OMX_U32 nCirMBs; +} OMX_VIDEO_PARAM_INTRAREFRESHTYPE; + + +/** + * Structure for enabling various error correction methods for video + * compression. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * bEnableHEC : Enable/disable header extension codes (HEC) + * bEnableResync : Enable/disable resynchronization markers + * nResynchMarkerSpacing : Resynch markers interval (in bits) to be + * applied in the stream + * bEnableDataPartitioning : Enable/disable data partitioning + * bEnableRVLC : Enable/disable reversible variable length + * coding + */ +typedef struct OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnableHEC; + OMX_BOOL bEnableResync; + OMX_U32 nResynchMarkerSpacing; + OMX_BOOL bEnableDataPartitioning; + OMX_BOOL bEnableRVLC; +} OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE; + + +/** + * Configuration of variable block-size motion compensation (VBSMC) + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * b16x16 : Enable inter block search 16x16 + * b16x8 : Enable inter block search 16x8 + * b8x16 : Enable inter block search 8x16 + * b8x8 : Enable inter block search 8x8 + * b8x4 : Enable inter block search 8x4 + * b4x8 : Enable inter block search 4x8 + * b4x4 : Enable inter block search 4x4 + */ +typedef struct OMX_VIDEO_PARAM_VBSMCTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL b16x16; + OMX_BOOL b16x8; + OMX_BOOL b8x16; + OMX_BOOL b8x8; + OMX_BOOL b8x4; + OMX_BOOL b4x8; + OMX_BOOL b4x4; +} OMX_VIDEO_PARAM_VBSMCTYPE; + + +/** + * H.263 profile types, each profile indicates support for various + * performance bounds and different annexes. + * + * ENUMS: + * Baseline : Baseline Profile: H.263 (V1), no optional modes + * H320 Coding : H.320 Coding Efficiency Backward Compatibility + * Profile: H.263+ (V2), includes annexes I, J, L.4 + * and T + * BackwardCompatible : Backward Compatibility Profile: H.263 (V1), + * includes annex F + * ISWV2 : Interactive Streaming Wireless Profile: H.263+ + * (V2), includes annexes I, J, K and T + * ISWV3 : Interactive Streaming Wireless Profile: H.263++ + * (V3), includes profile 3 and annexes V and W.6.3.8 + * HighCompression : Conversational High Compression Profile: H.263++ + * (V3), includes profiles 1 & 2 and annexes D and U + * Internet : Conversational Internet Profile: H.263++ (V3), + * includes profile 5 and annex K + * Interlace : Conversational Interlace Profile: H.263++ (V3), + * includes profile 5 and annex W.6.3.11 + * HighLatency : High Latency Profile: H.263++ (V3), includes + * profile 6 and annexes O.1 and P.5 + */ +typedef enum OMX_VIDEO_H263PROFILETYPE { + OMX_VIDEO_H263ProfileBaseline = 0x01, + OMX_VIDEO_H263ProfileH320Coding = 0x02, + OMX_VIDEO_H263ProfileBackwardCompatible = 0x04, + OMX_VIDEO_H263ProfileISWV2 = 0x08, + OMX_VIDEO_H263ProfileISWV3 = 0x10, + OMX_VIDEO_H263ProfileHighCompression = 0x20, + OMX_VIDEO_H263ProfileInternet = 0x40, + OMX_VIDEO_H263ProfileInterlace = 0x80, + OMX_VIDEO_H263ProfileHighLatency = 0x100, + OMX_VIDEO_H263ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_H263ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_H263ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_H263PROFILETYPE; + + +/** + * H.263 level types, each level indicates support for various frame sizes, + * bit rates, decoder frame rates. + */ +typedef enum OMX_VIDEO_H263LEVELTYPE { + OMX_VIDEO_H263Level10 = 0x01, + OMX_VIDEO_H263Level20 = 0x02, + OMX_VIDEO_H263Level30 = 0x04, + OMX_VIDEO_H263Level40 = 0x08, + OMX_VIDEO_H263Level45 = 0x10, + OMX_VIDEO_H263Level50 = 0x20, + OMX_VIDEO_H263Level60 = 0x40, + OMX_VIDEO_H263Level70 = 0x80, + OMX_VIDEO_H263LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_H263LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_H263LevelMax = 0x7FFFFFFF +} OMX_VIDEO_H263LEVELTYPE; + + +/** + * Specifies the picture type. These values should be OR'd to signal all + * pictures types which are allowed. + * + * ENUMS: + * Generic Picture Types: I, P and B + * H.263 Specific Picture Types: SI and SP + * H.264 Specific Picture Types: EI and EP + * MPEG-4 Specific Picture Types: S + */ +typedef enum OMX_VIDEO_PICTURETYPE { + OMX_VIDEO_PictureTypeI = 0x01, + OMX_VIDEO_PictureTypeP = 0x02, + OMX_VIDEO_PictureTypeB = 0x04, + OMX_VIDEO_PictureTypeSI = 0x08, + OMX_VIDEO_PictureTypeSP = 0x10, + OMX_VIDEO_PictureTypeEI = 0x11, + OMX_VIDEO_PictureTypeEP = 0x12, + OMX_VIDEO_PictureTypeS = 0x14, + OMX_VIDEO_PictureTypeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_PictureTypeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_PictureTypeMax = 0x7FFFFFFF +} OMX_VIDEO_PICTURETYPE; + + +/** + * H.263 Params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nPFrames : Number of P frames between each I frame + * nBFrames : Number of B frames between each I frame + * eProfile : H.263 profile(s) to use + * eLevel : H.263 level(s) to use + * bPLUSPTYPEAllowed : Indicating that it is allowed to use PLUSPTYPE + * (specified in the 1998 version of H.263) to + * indicate custom picture sizes or clock + * frequencies + * nAllowedPictureTypes : Specifies the picture types allowed in the + * bitstream + * bForceRoundingTypeToZero : value of the RTYPE bit (bit 6 of MPPTYPE) is + * not constrained. It is recommended to change + * the value of the RTYPE bit for each reference + * picture in error-free communication + * nPictureHeaderRepetition : Specifies the frequency of picture header + * repetition + * nGOBHeaderInterval : Specifies the interval of non-empty GOB + * headers in units of GOBs + */ +typedef struct OMX_VIDEO_PARAM_H263TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_VIDEO_H263PROFILETYPE eProfile; + OMX_VIDEO_H263LEVELTYPE eLevel; + OMX_BOOL bPLUSPTYPEAllowed; + OMX_U32 nAllowedPictureTypes; + OMX_BOOL bForceRoundingTypeToZero; + OMX_U32 nPictureHeaderRepetition; + OMX_U32 nGOBHeaderInterval; +} OMX_VIDEO_PARAM_H263TYPE; + + +/** + * MPEG-2 profile types, each profile indicates support for various + * performance bounds and different annexes. + */ +typedef enum OMX_VIDEO_MPEG2PROFILETYPE { + OMX_VIDEO_MPEG2ProfileSimple = 0, /**< Simple Profile */ + OMX_VIDEO_MPEG2ProfileMain, /**< Main Profile */ + OMX_VIDEO_MPEG2Profile422, /**< 4:2:2 Profile */ + OMX_VIDEO_MPEG2ProfileSNR, /**< SNR Profile */ + OMX_VIDEO_MPEG2ProfileSpatial, /**< Spatial Profile */ + OMX_VIDEO_MPEG2ProfileHigh, /**< High Profile */ + OMX_VIDEO_MPEG2ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG2ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG2ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG2PROFILETYPE; + + +/** + * MPEG-2 level types, each level indicates support for various frame + * sizes, bit rates, decoder frame rates. No need + */ +typedef enum OMX_VIDEO_MPEG2LEVELTYPE { + OMX_VIDEO_MPEG2LevelLL = 0, /**< Low Level */ + OMX_VIDEO_MPEG2LevelML, /**< Main Level */ + OMX_VIDEO_MPEG2LevelH14, /**< High 1440 */ + OMX_VIDEO_MPEG2LevelHL, /**< High Level */ + OMX_VIDEO_MPEG2LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG2LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG2LevelMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG2LEVELTYPE; + + +/** + * MPEG-2 params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nPFrames : Number of P frames between each I frame + * nBFrames : Number of B frames between each I frame + * eProfile : MPEG-2 profile(s) to use + * eLevel : MPEG-2 levels(s) to use + */ +typedef struct OMX_VIDEO_PARAM_MPEG2TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_VIDEO_MPEG2PROFILETYPE eProfile; + OMX_VIDEO_MPEG2LEVELTYPE eLevel; +} OMX_VIDEO_PARAM_MPEG2TYPE; + + +/** + * MPEG-4 profile types, each profile indicates support for various + * performance bounds and different annexes. + * + * ENUMS: + * - Simple Profile, Levels 1-3 + * - Simple Scalable Profile, Levels 1-2 + * - Core Profile, Levels 1-2 + * - Main Profile, Levels 2-4 + * - N-bit Profile, Level 2 + * - Scalable Texture Profile, Level 1 + * - Simple Face Animation Profile, Levels 1-2 + * - Simple Face and Body Animation (FBA) Profile, Levels 1-2 + * - Basic Animated Texture Profile, Levels 1-2 + * - Hybrid Profile, Levels 1-2 + * - Advanced Real Time Simple Profiles, Levels 1-4 + * - Core Scalable Profile, Levels 1-3 + * - Advanced Coding Efficiency Profile, Levels 1-4 + * - Advanced Core Profile, Levels 1-2 + * - Advanced Scalable Texture, Levels 2-3 + */ +typedef enum OMX_VIDEO_MPEG4PROFILETYPE { + OMX_VIDEO_MPEG4ProfileSimple = 0x01, + OMX_VIDEO_MPEG4ProfileSimpleScalable = 0x02, + OMX_VIDEO_MPEG4ProfileCore = 0x04, + OMX_VIDEO_MPEG4ProfileMain = 0x08, + OMX_VIDEO_MPEG4ProfileNbit = 0x10, + OMX_VIDEO_MPEG4ProfileScalableTexture = 0x20, + OMX_VIDEO_MPEG4ProfileSimpleFace = 0x40, + OMX_VIDEO_MPEG4ProfileSimpleFBA = 0x80, + OMX_VIDEO_MPEG4ProfileBasicAnimated = 0x100, + OMX_VIDEO_MPEG4ProfileHybrid = 0x200, + OMX_VIDEO_MPEG4ProfileAdvancedRealTime = 0x400, + OMX_VIDEO_MPEG4ProfileCoreScalable = 0x800, + OMX_VIDEO_MPEG4ProfileAdvancedCoding = 0x1000, + OMX_VIDEO_MPEG4ProfileAdvancedCore = 0x2000, + OMX_VIDEO_MPEG4ProfileAdvancedScalable = 0x4000, + OMX_VIDEO_MPEG4ProfileAdvancedSimple = 0x8000, + OMX_VIDEO_MPEG4ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG4ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG4ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG4PROFILETYPE; + + +/** + * MPEG-4 level types, each level indicates support for various frame + * sizes, bit rates, decoder frame rates. No need + */ +typedef enum OMX_VIDEO_MPEG4LEVELTYPE { + OMX_VIDEO_MPEG4Level0 = 0x01, /**< Level 0 */ + OMX_VIDEO_MPEG4Level0b = 0x02, /**< Level 0b */ + OMX_VIDEO_MPEG4Level1 = 0x04, /**< Level 1 */ + OMX_VIDEO_MPEG4Level2 = 0x08, /**< Level 2 */ + OMX_VIDEO_MPEG4Level3 = 0x10, /**< Level 3 */ + OMX_VIDEO_MPEG4Level4 = 0x20, /**< Level 4 */ + OMX_VIDEO_MPEG4Level4a = 0x40, /**< Level 4a */ + OMX_VIDEO_MPEG4Level5 = 0x80, /**< Level 5 */ + OMX_VIDEO_MPEG4LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG4LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG4LevelMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG4LEVELTYPE; + + +/** + * MPEG-4 configuration. This structure handles configuration options + * which are specific to MPEG4 algorithms + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nSliceHeaderSpacing : Number of macroblocks between slice header (H263+ + * Annex K). Put zero if not used + * bSVH : Enable Short Video Header mode + * bGov : Flag to enable GOV + * nPFrames : Number of P frames between each I frame (also called + * GOV period) + * nBFrames : Number of B frames between each I frame + * nIDCVLCThreshold : Value of intra DC VLC threshold + * bACPred : Flag to use ac prediction + * nMaxPacketSize : Maximum size of packet in bytes. + * nTimeIncRes : Used to pass VOP time increment resolution for MPEG4. + * Interpreted as described in MPEG4 standard. + * eProfile : MPEG-4 profile(s) to use. + * eLevel : MPEG-4 level(s) to use. + * nAllowedPictureTypes : Specifies the picture types allowed in the bitstream + * nHeaderExtension : Specifies the number of consecutive video packet + * headers within a VOP + * bReversibleVLC : Specifies whether reversible variable length coding + * is in use + */ +typedef struct OMX_VIDEO_PARAM_MPEG4TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nSliceHeaderSpacing; + OMX_BOOL bSVH; + OMX_BOOL bGov; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_U32 nIDCVLCThreshold; + OMX_BOOL bACPred; + OMX_U32 nMaxPacketSize; + OMX_U32 nTimeIncRes; + OMX_VIDEO_MPEG4PROFILETYPE eProfile; + OMX_VIDEO_MPEG4LEVELTYPE eLevel; + OMX_U32 nAllowedPictureTypes; + OMX_U32 nHeaderExtension; + OMX_BOOL bReversibleVLC; +} OMX_VIDEO_PARAM_MPEG4TYPE; + + +/** + * WMV Versions + */ +typedef enum OMX_VIDEO_WMVFORMATTYPE { + OMX_VIDEO_WMVFormatUnused = 0x01, /**< Format unused or unknown */ + OMX_VIDEO_WMVFormat7 = 0x02, /**< Windows Media Video format 7 */ + OMX_VIDEO_WMVFormat8 = 0x04, /**< Windows Media Video format 8 */ + OMX_VIDEO_WMVFormat9 = 0x08, /**< Windows Media Video format 9 */ + OMX_VIDEO_WMFFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_WMFFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_WMVFormatMax = 0x7FFFFFFF +} OMX_VIDEO_WMVFORMATTYPE; + + +/** + * WMV Params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFormat : Version of WMV stream / data + */ +typedef struct OMX_VIDEO_PARAM_WMVTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_WMVFORMATTYPE eFormat; +} OMX_VIDEO_PARAM_WMVTYPE; + + +/** + * Real Video Version + */ +typedef enum OMX_VIDEO_RVFORMATTYPE { + OMX_VIDEO_RVFormatUnused = 0, /**< Format unused or unknown */ + OMX_VIDEO_RVFormat8, /**< Real Video format 8 */ + OMX_VIDEO_RVFormat9, /**< Real Video format 9 */ + OMX_VIDEO_RVFormatG2, /**< Real Video Format G2 */ + OMX_VIDEO_RVFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_RVFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_RVFormatMax = 0x7FFFFFFF +} OMX_VIDEO_RVFORMATTYPE; + + +/** + * Real Video Params + * + * STUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFormat : Version of RV stream / data + * nBitsPerPixel : Bits per pixel coded in the frame + * nPaddedWidth : Padded width in pixel of a video frame + * nPaddedHeight : Padded Height in pixels of a video frame + * nFrameRate : Rate of video in frames per second + * nBitstreamFlags : Flags which internal information about the bitstream + * nBitstreamVersion : Bitstream version + * nMaxEncodeFrameSize: Max encoded frame size + * bEnablePostFilter : Turn on/off post filter + * bEnableTemporalInterpolation : Turn on/off temporal interpolation + * bEnableLatencyMode : When enabled, the decoder does not display a decoded + * frame until it has detected that no enhancement layer + * frames or dependent B frames will be coming. This + * detection usually occurs when a subsequent non-B + * frame is encountered + */ +typedef struct OMX_VIDEO_PARAM_RVTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_RVFORMATTYPE eFormat; + OMX_U16 nBitsPerPixel; + OMX_U16 nPaddedWidth; + OMX_U16 nPaddedHeight; + OMX_U32 nFrameRate; + OMX_U32 nBitstreamFlags; + OMX_U32 nBitstreamVersion; + OMX_U32 nMaxEncodeFrameSize; + OMX_BOOL bEnablePostFilter; + OMX_BOOL bEnableTemporalInterpolation; + OMX_BOOL bEnableLatencyMode; +} OMX_VIDEO_PARAM_RVTYPE; + + +/** + * AVC profile types, each profile indicates support for various + * performance bounds and different annexes. + */ +typedef enum OMX_VIDEO_AVCPROFILETYPE { + OMX_VIDEO_AVCProfileBaseline = 0x01, /**< Baseline profile */ + OMX_VIDEO_AVCProfileMain = 0x02, /**< Main profile */ + OMX_VIDEO_AVCProfileExtended = 0x04, /**< Extended profile */ + OMX_VIDEO_AVCProfileHigh = 0x08, /**< High profile */ + OMX_VIDEO_AVCProfileHigh10 = 0x10, /**< High 10 profile */ + OMX_VIDEO_AVCProfileHigh422 = 0x20, /**< High 4:2:2 profile */ + OMX_VIDEO_AVCProfileHigh444 = 0x40, /**< High 4:4:4 profile */ + OMX_VIDEO_AVCProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_AVCProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_AVCProfileMax = 0x7FFFFFFF +} OMX_VIDEO_AVCPROFILETYPE; + + +/** + * AVC level types, each level indicates support for various frame sizes, + * bit rates, decoder frame rates. No need + */ +typedef enum OMX_VIDEO_AVCLEVELTYPE { + OMX_VIDEO_AVCLevel1 = 0x01, /**< Level 1 */ + OMX_VIDEO_AVCLevel1b = 0x02, /**< Level 1b */ + OMX_VIDEO_AVCLevel11 = 0x04, /**< Level 1.1 */ + OMX_VIDEO_AVCLevel12 = 0x08, /**< Level 1.2 */ + OMX_VIDEO_AVCLevel13 = 0x10, /**< Level 1.3 */ + OMX_VIDEO_AVCLevel2 = 0x20, /**< Level 2 */ + OMX_VIDEO_AVCLevel21 = 0x40, /**< Level 2.1 */ + OMX_VIDEO_AVCLevel22 = 0x80, /**< Level 2.2 */ + OMX_VIDEO_AVCLevel3 = 0x100, /**< Level 3 */ + OMX_VIDEO_AVCLevel31 = 0x200, /**< Level 3.1 */ + OMX_VIDEO_AVCLevel32 = 0x400, /**< Level 3.2 */ + OMX_VIDEO_AVCLevel4 = 0x800, /**< Level 4 */ + OMX_VIDEO_AVCLevel41 = 0x1000, /**< Level 4.1 */ + OMX_VIDEO_AVCLevel42 = 0x2000, /**< Level 4.2 */ + OMX_VIDEO_AVCLevel5 = 0x4000, /**< Level 5 */ + OMX_VIDEO_AVCLevel51 = 0x8000, /**< Level 5.1 */ + OMX_VIDEO_AVCLevel52 = 0x10000, /**< Level 5.2 */ + OMX_VIDEO_AVCLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_AVCLevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_AVCLevelMax = 0x7FFFFFFF +} OMX_VIDEO_AVCLEVELTYPE; + + +/** + * AVC loop filter modes + * + * OMX_VIDEO_AVCLoopFilterEnable : Enable + * OMX_VIDEO_AVCLoopFilterDisable : Disable + * OMX_VIDEO_AVCLoopFilterDisableSliceBoundary : Disabled on slice boundaries + */ +typedef enum OMX_VIDEO_AVCLOOPFILTERTYPE { + OMX_VIDEO_AVCLoopFilterEnable = 0, + OMX_VIDEO_AVCLoopFilterDisable, + OMX_VIDEO_AVCLoopFilterDisableSliceBoundary, + OMX_VIDEO_AVCLoopFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_AVCLoopFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_AVCLoopFilterMax = 0x7FFFFFFF +} OMX_VIDEO_AVCLOOPFILTERTYPE; + + +/** + * AVC params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nSliceHeaderSpacing : Number of macroblocks between slice header, put + * zero if not used + * nPFrames : Number of P frames between each I frame + * nBFrames : Number of B frames between each I frame + * bUseHadamard : Enable/disable Hadamard transform + * nRefFrames : Max number of reference frames to use for inter + * motion search (1-16) + * nRefIdxTrailing : Pic param set ref frame index (index into ref + * frame buffer of trailing frames list), B frame + * support + * nRefIdxForward : Pic param set ref frame index (index into ref + * frame buffer of forward frames list), B frame + * support + * bEnableUEP : Enable/disable unequal error protection. This + * is only valid of data partitioning is enabled. + * bEnableFMO : Enable/disable flexible macroblock ordering + * bEnableASO : Enable/disable arbitrary slice ordering + * bEnableRS : Enable/disable sending of redundant slices + * eProfile : AVC profile(s) to use + * eLevel : AVC level(s) to use + * nAllowedPictureTypes : Specifies the picture types allowed in the + * bitstream + * bFrameMBsOnly : specifies that every coded picture of the + * coded video sequence is a coded frame + * containing only frame macroblocks + * bMBAFF : Enable/disable switching between frame and + * field macroblocks within a picture + * bEntropyCodingCABAC : Entropy decoding method to be applied for the + * syntax elements for which two descriptors appear + * in the syntax tables + * bWeightedPPrediction : Enable/disable weighted prediction shall not + * be applied to P and SP slices + * nWeightedBipredicitonMode : Default weighted prediction is applied to B + * slices + * bconstIpred : Enable/disable intra prediction + * bDirect8x8Inference : Specifies the method used in the derivation + * process for luma motion vectors for B_Skip, + * B_Direct_16x16 and B_Direct_8x8 as specified + * in subclause 8.4.1.2 of the AVC spec + * bDirectSpatialTemporal : Flag indicating spatial or temporal direct + * mode used in B slice coding (related to + * bDirect8x8Inference) . Spatial direct mode is + * more common and should be the default. + * nCabacInitIdx : Index used to init CABAC contexts + * eLoopFilterMode : Enable/disable loop filter + */ +typedef struct OMX_VIDEO_PARAM_AVCTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nSliceHeaderSpacing; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_BOOL bUseHadamard; + OMX_U32 nRefFrames; + OMX_U32 nRefIdx10ActiveMinus1; + OMX_U32 nRefIdx11ActiveMinus1; + OMX_BOOL bEnableUEP; + OMX_BOOL bEnableFMO; + OMX_BOOL bEnableASO; + OMX_BOOL bEnableRS; + OMX_VIDEO_AVCPROFILETYPE eProfile; + OMX_VIDEO_AVCLEVELTYPE eLevel; + OMX_U32 nAllowedPictureTypes; + OMX_BOOL bFrameMBsOnly; + OMX_BOOL bMBAFF; + OMX_BOOL bEntropyCodingCABAC; + OMX_BOOL bWeightedPPrediction; + OMX_U32 nWeightedBipredicitonMode; + OMX_BOOL bconstIpred ; + OMX_BOOL bDirect8x8Inference; + OMX_BOOL bDirectSpatialTemporal; + OMX_U32 nCabacInitIdc; + OMX_VIDEO_AVCLOOPFILTERTYPE eLoopFilterMode; +} OMX_VIDEO_PARAM_AVCTYPE; + +typedef struct OMX_VIDEO_PARAM_PROFILELEVELTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 eProfile; /**< type is OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE, + or OMX_VIDEO_MPEG4PROFILETYPE depending on context */ + OMX_U32 eLevel; /**< type is OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE, + or OMX_VIDEO_MPEG4PROFILETYPE depending on context */ + OMX_U32 nProfileIndex; /**< Used to query for individual profile support information, + This parameter is valid only for + OMX_IndexParamVideoProfileLevelQuerySupported index, + For all other indices this parameter is to be ignored. */ +} OMX_VIDEO_PARAM_PROFILELEVELTYPE; + +/** + * Structure for dynamically configuring bitrate mode of a codec. + * + * STRUCT MEMBERS: + * nSize : Size of the struct in bytes + * nVersion : OMX spec version info + * nPortIndex : Port that this struct applies to + * nEncodeBitrate : Target average bitrate to be generated in bps + */ +typedef struct OMX_VIDEO_CONFIG_BITRATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nEncodeBitrate; +} OMX_VIDEO_CONFIG_BITRATETYPE; + +/** + * Defines Encoder Frame Rate setting + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * xEncodeFramerate : Encoding framerate represented in Q16 format + */ +typedef struct OMX_CONFIG_FRAMERATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 xEncodeFramerate; /* Q16 format */ +} OMX_CONFIG_FRAMERATETYPE; + +typedef struct OMX_CONFIG_INTRAREFRESHVOPTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL IntraRefreshVOP; +} OMX_CONFIG_INTRAREFRESHVOPTYPE; + +typedef struct OMX_CONFIG_MACROBLOCKERRORMAPTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nErrMapSize; /* Size of the Error Map in bytes */ + OMX_U8 ErrMap[1]; /* Error map hint */ +} OMX_CONFIG_MACROBLOCKERRORMAPTYPE; + +typedef struct OMX_CONFIG_MBERRORREPORTINGTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnabled; +} OMX_CONFIG_MBERRORREPORTINGTYPE; + +typedef struct OMX_PARAM_MACROBLOCKSTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nMacroblocks; +} OMX_PARAM_MACROBLOCKSTYPE; + +/** + * AVC Slice Mode modes + * + * OMX_VIDEO_SLICEMODE_AVCDefault : Normal frame encoding, one slice per frame + * OMX_VIDEO_SLICEMODE_AVCMBSlice : NAL mode, number of MBs per frame + * OMX_VIDEO_SLICEMODE_AVCByteSlice : NAL mode, number of bytes per frame + */ +typedef enum OMX_VIDEO_AVCSLICEMODETYPE { + OMX_VIDEO_SLICEMODE_AVCDefault = 0, + OMX_VIDEO_SLICEMODE_AVCMBSlice, + OMX_VIDEO_SLICEMODE_AVCByteSlice, + OMX_VIDEO_SLICEMODE_AVCKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_SLICEMODE_AVCVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_SLICEMODE_AVCLevelMax = 0x7FFFFFFF +} OMX_VIDEO_AVCSLICEMODETYPE; + +/** + * AVC FMO Slice Mode Params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nNumSliceGroups : Specifies the number of slice groups + * nSliceGroupMapType : Specifies the type of slice groups + * eSliceMode : Specifies the type of slice + */ +typedef struct OMX_VIDEO_PARAM_AVCSLICEFMO { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U8 nNumSliceGroups; + OMX_U8 nSliceGroupMapType; + OMX_VIDEO_AVCSLICEMODETYPE eSliceMode; +} OMX_VIDEO_PARAM_AVCSLICEFMO; + +/** + * AVC IDR Period Configs + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nIDRPeriod : Specifies periodicity of IDR frames + * nPFrames : Specifies internal of coding Intra frames + */ +typedef struct OMX_VIDEO_CONFIG_AVCINTRAPERIOD { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nIDRPeriod; + OMX_U32 nPFrames; +} OMX_VIDEO_CONFIG_AVCINTRAPERIOD; + +/** + * AVC NAL Size Configs + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nNaluBytes : Specifies the NAL unit size + */ +typedef struct OMX_VIDEO_CONFIG_NALSIZE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nNaluBytes; +} OMX_VIDEO_CONFIG_NALSIZE; + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ + diff --git a/phonelibs/android_frameworks_native/include/media/openmax/OMX_VideoExt.h b/phonelibs/android_frameworks_native/include/media/openmax/OMX_VideoExt.h new file mode 100644 index 00000000000000..3971bc5cc366d1 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/media/openmax/OMX_VideoExt.h @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2010 The Khronos Group Inc. + * + * 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. + * + */ + +/** OMX_VideoExt.h - OpenMax IL version 1.1.2 + * The OMX_VideoExt header file contains extensions to the + * definitions used by both the application and the component to + * access video items. + */ + +#ifndef OMX_VideoExt_h +#define OMX_VideoExt_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Each OMX header shall include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ +#include + +/** NALU Formats */ +typedef enum OMX_NALUFORMATSTYPE { + OMX_NaluFormatStartCodes = 1, + OMX_NaluFormatOneNaluPerBuffer = 2, + OMX_NaluFormatOneByteInterleaveLength = 4, + OMX_NaluFormatTwoByteInterleaveLength = 8, + OMX_NaluFormatFourByteInterleaveLength = 16, + OMX_NaluFormatCodingMax = 0x7FFFFFFF +} OMX_NALUFORMATSTYPE; + +/** NAL Stream Format */ +typedef struct OMX_NALSTREAMFORMATTYPE{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_NALUFORMATSTYPE eNaluFormat; +} OMX_NALSTREAMFORMATTYPE; + +/** VP8 profiles */ +typedef enum OMX_VIDEO_VP8PROFILETYPE { + OMX_VIDEO_VP8ProfileMain = 0x01, + OMX_VIDEO_VP8ProfileUnknown = 0x6EFFFFFF, + OMX_VIDEO_VP8ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_VP8PROFILETYPE; + +/** VP8 levels */ +typedef enum OMX_VIDEO_VP8LEVELTYPE { + OMX_VIDEO_VP8Level_Version0 = 0x01, + OMX_VIDEO_VP8Level_Version1 = 0x02, + OMX_VIDEO_VP8Level_Version2 = 0x04, + OMX_VIDEO_VP8Level_Version3 = 0x08, + OMX_VIDEO_VP8LevelUnknown = 0x6EFFFFFF, + OMX_VIDEO_VP8LevelMax = 0x7FFFFFFF +} OMX_VIDEO_VP8LEVELTYPE; + +/** VP8 Param */ +typedef struct OMX_VIDEO_PARAM_VP8TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_VP8PROFILETYPE eProfile; + OMX_VIDEO_VP8LEVELTYPE eLevel; + OMX_U32 nDCTPartitions; + OMX_BOOL bErrorResilientMode; +} OMX_VIDEO_PARAM_VP8TYPE; + +/** Structure for configuring VP8 reference frames */ +typedef struct OMX_VIDEO_VP8REFERENCEFRAMETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bPreviousFrameRefresh; + OMX_BOOL bGoldenFrameRefresh; + OMX_BOOL bAlternateFrameRefresh; + OMX_BOOL bUsePreviousFrame; + OMX_BOOL bUseGoldenFrame; + OMX_BOOL bUseAlternateFrame; +} OMX_VIDEO_VP8REFERENCEFRAMETYPE; + +/** Structure for querying VP8 reference frame type */ +typedef struct OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bIsIntraFrame; + OMX_BOOL bIsGoldenOrAlternateFrame; +} OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE; + +/** Maximum number of VP8 temporal layers */ +#define OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS 3 + +/** VP8 temporal layer patterns */ +typedef enum OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE { + OMX_VIDEO_VPXTemporalLayerPatternNone = 0, + OMX_VIDEO_VPXTemporalLayerPatternWebRTC = 1, + OMX_VIDEO_VPXTemporalLayerPatternMax = 0x7FFFFFFF +} OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE; + +/** + * Android specific VP8 encoder params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nKeyFrameInterval : Key frame interval in frames + * eTemporalPattern : Type of temporal layer pattern + * nTemporalLayerCount : Number of temporal coding layers + * nTemporalLayerBitrateRatio : Bitrate ratio allocation between temporal + * streams in percentage + * nMinQuantizer : Minimum (best quality) quantizer + * nMaxQuantizer : Maximum (worst quality) quantizer + */ +typedef struct OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nKeyFrameInterval; + OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE eTemporalPattern; + OMX_U32 nTemporalLayerCount; + OMX_U32 nTemporalLayerBitrateRatio[OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]; + OMX_U32 nMinQuantizer; + OMX_U32 nMaxQuantizer; +} OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE; + +/** HEVC Profile enum type */ +typedef enum OMX_VIDEO_HEVCPROFILETYPE { + OMX_VIDEO_HEVCProfileUnknown = 0x0, + OMX_VIDEO_HEVCProfileMain = 0x1, + OMX_VIDEO_HEVCProfileMain10 = 0x2, + OMX_VIDEO_HEVCProfileMax = 0x7FFFFFFF +} OMX_VIDEO_HEVCPROFILETYPE; + +/** HEVC Level enum type */ +typedef enum OMX_VIDEO_HEVCLEVELTYPE { + OMX_VIDEO_HEVCLevelUnknown = 0x0, + OMX_VIDEO_HEVCMainTierLevel1 = 0x1, + OMX_VIDEO_HEVCHighTierLevel1 = 0x2, + OMX_VIDEO_HEVCMainTierLevel2 = 0x4, + OMX_VIDEO_HEVCHighTierLevel2 = 0x8, + OMX_VIDEO_HEVCMainTierLevel21 = 0x10, + OMX_VIDEO_HEVCHighTierLevel21 = 0x20, + OMX_VIDEO_HEVCMainTierLevel3 = 0x40, + OMX_VIDEO_HEVCHighTierLevel3 = 0x80, + OMX_VIDEO_HEVCMainTierLevel31 = 0x100, + OMX_VIDEO_HEVCHighTierLevel31 = 0x200, + OMX_VIDEO_HEVCMainTierLevel4 = 0x400, + OMX_VIDEO_HEVCHighTierLevel4 = 0x800, + OMX_VIDEO_HEVCMainTierLevel41 = 0x1000, + OMX_VIDEO_HEVCHighTierLevel41 = 0x2000, + OMX_VIDEO_HEVCMainTierLevel5 = 0x4000, + OMX_VIDEO_HEVCHighTierLevel5 = 0x8000, + OMX_VIDEO_HEVCMainTierLevel51 = 0x10000, + OMX_VIDEO_HEVCHighTierLevel51 = 0x20000, + OMX_VIDEO_HEVCMainTierLevel52 = 0x40000, + OMX_VIDEO_HEVCHighTierLevel52 = 0x80000, + OMX_VIDEO_HEVCMainTierLevel6 = 0x100000, + OMX_VIDEO_HEVCHighTierLevel6 = 0x200000, + OMX_VIDEO_HEVCMainTierLevel61 = 0x400000, + OMX_VIDEO_HEVCHighTierLevel61 = 0x800000, + OMX_VIDEO_HEVCMainTierLevel62 = 0x1000000, + OMX_VIDEO_HEVCHighTierLevel62 = 0x2000000, + OMX_VIDEO_HEVCHighTiermax = 0x7FFFFFFF +} OMX_VIDEO_HEVCLEVELTYPE; + +/** Structure for controlling HEVC video encoding and decoding */ +typedef struct OMX_VIDEO_PARAM_HEVCTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_HEVCPROFILETYPE eProfile; + OMX_VIDEO_HEVCLEVELTYPE eLevel; +} OMX_VIDEO_PARAM_HEVCTYPE; + +/** Structure to define if dependent slice segments should be used */ +typedef struct OMX_VIDEO_SLICESEGMENTSTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bDepedentSegments; + OMX_BOOL bEnableLoopFilterAcrossSlices; +} OMX_VIDEO_SLICESEGMENTSTYPE; + +/** Structure to return timestamps of rendered output frames as well as EOS + * for tunneled components. + */ +typedef struct OMX_VIDEO_RENDEREVENTTYPE { + OMX_S64 nMediaTimeUs; // timestamp of rendered video frame + OMX_S64 nSystemTimeNs; // system monotonic time at the time frame was rendered + // Use INT64_MAX for nMediaTimeUs to signal that the EOS + // has been reached. In this case, nSystemTimeNs MUST be + // the system time when the last frame was rendered. + // This MUST be done in addition to returning (and + // following) the render information for the last frame. +} OMX_VIDEO_RENDEREVENTTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* OMX_VideoExt_h */ +/* File EOF */ diff --git a/phonelibs/android_frameworks_native/include/powermanager/IPowerManager.h b/phonelibs/android_frameworks_native/include/powermanager/IPowerManager.h new file mode 100644 index 00000000000000..91ecc5aa31e372 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/powermanager/IPowerManager.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_IPOWERMANAGER_H +#define ANDROID_IPOWERMANAGER_H + +#include +#include +#include + +namespace android { + +// ---------------------------------------------------------------------------- + +// must be kept in sync with interface defined in IPowerManager.aidl +class IPowerManager : public IInterface +{ +public: + DECLARE_META_INTERFACE(PowerManager); + + // FIXME remove the bool isOneWay parameters as they are not oneway in the .aidl + virtual status_t acquireWakeLock(int flags, const sp& lock, const String16& tag, + const String16& packageName, bool isOneWay = false) = 0; + virtual status_t acquireWakeLockWithUid(int flags, const sp& lock, const String16& tag, + const String16& packageName, int uid, bool isOneWay = false) = 0; + virtual status_t releaseWakeLock(const sp& lock, int flags, bool isOneWay = false) = 0; + virtual status_t updateWakeLockUids(const sp& lock, int len, const int *uids, + bool isOneWay = false) = 0; + // oneway in the .aidl + virtual status_t powerHint(int hintId, int data) = 0; +}; + +// ---------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_IPOWERMANAGER_H diff --git a/phonelibs/android_frameworks_native/include/powermanager/PowerManager.h b/phonelibs/android_frameworks_native/include/powermanager/PowerManager.h new file mode 100644 index 00000000000000..cbddc11536c4e0 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/powermanager/PowerManager.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_POWERMANAGER_H +#define ANDROID_POWERMANAGER_H + +namespace android { + +// must be kept in sync with definitions in PowerManager.java +enum { + POWERMANAGER_PARTIAL_WAKE_LOCK = 1, // equals PowerManager.PARTIAL_WAKE_LOCK constant +}; + +enum { + USER_ACTIVITY_EVENT_OTHER = 0, + USER_ACTIVITY_EVENT_BUTTON = 1, + USER_ACTIVITY_EVENT_TOUCH = 2, + + USER_ACTIVITY_EVENT_LAST = USER_ACTIVITY_EVENT_TOUCH, // Last valid event code. +}; + +}; // namespace android + +#endif // ANDROID_POWERMANAGER_H diff --git a/phonelibs/android_frameworks_native/include/private/binder/Static.h b/phonelibs/android_frameworks_native/include/private/binder/Static.h new file mode 100644 index 00000000000000..d1046468043166 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/private/binder/Static.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// All static variables go here, to control initialization and +// destruction order in the library. + +#include + +#include +#include +#include +#include +#include + +namespace android { + +// For TextStream.cpp +extern Vector gTextBuffers; + +// For ProcessState.cpp +extern Mutex gProcessMutex; +extern sp gProcess; + +// For IServiceManager.cpp +extern Mutex gDefaultServiceManagerLock; +extern sp gDefaultServiceManager; +extern sp gPermissionController; + +} // namespace android diff --git a/phonelibs/android_frameworks_native/include/private/binder/binder_module.h b/phonelibs/android_frameworks_native/include/private/binder/binder_module.h new file mode 100644 index 00000000000000..a8dd64f235bbd6 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/private/binder/binder_module.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _BINDER_MODULE_H_ +#define _BINDER_MODULE_H_ + +#ifdef __cplusplus +namespace android { +#endif + +/* obtain structures and constants from the kernel header */ + +#include +#include + +#ifdef __cplusplus +} // namespace android +#endif + +#endif // _BINDER_MODULE_H_ diff --git a/phonelibs/android_frameworks_native/include/private/gui/ComposerService.h b/phonelibs/android_frameworks_native/include/private/gui/ComposerService.h new file mode 100644 index 00000000000000..ff2f9bf0f7371e --- /dev/null +++ b/phonelibs/android_frameworks_native/include/private/gui/ComposerService.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_PRIVATE_GUI_COMPOSER_SERVICE_H +#define ANDROID_PRIVATE_GUI_COMPOSER_SERVICE_H + +#include +#include + +#include +#include + + +namespace android { + +// --------------------------------------------------------------------------- + +class IMemoryHeap; +class ISurfaceComposer; + +// --------------------------------------------------------------------------- + +// This holds our connection to the composer service (i.e. SurfaceFlinger). +// If the remote side goes away, we will re-establish the connection. +// Users of this class should not retain the value from +// getComposerService() for an extended period. +// +// (It's not clear that using Singleton is useful here anymore.) +class ComposerService : public Singleton +{ + sp mComposerService; + sp mDeathObserver; + Mutex mLock; + + ComposerService(); + void connectLocked(); + void composerServiceDied(); + friend class Singleton; +public: + + // Get a connection to the Composer Service. This will block until + // a connection is established. + static sp getComposerService(); +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_PRIVATE_GUI_COMPOSER_SERVICE_H diff --git a/phonelibs/android_frameworks_native/include/private/gui/LayerState.h b/phonelibs/android_frameworks_native/include/private/gui/LayerState.h new file mode 100644 index 00000000000000..9ff840991fa9cb --- /dev/null +++ b/phonelibs/android_frameworks_native/include/private/gui/LayerState.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SF_LAYER_STATE_H +#define ANDROID_SF_LAYER_STATE_H + +#include +#include + +#include + +#include +#include + +namespace android { + +class Parcel; +class ISurfaceComposerClient; + +/* + * Used to communicate layer information between SurfaceFlinger and its clients. + */ +struct layer_state_t { + + + enum { + eLayerHidden = 0x01, // SURFACE_HIDDEN in SurfaceControl.java + eLayerOpaque = 0x02, // SURFACE_OPAQUE + eLayerSecure = 0x80, // SECURE + }; + + enum { + ePositionChanged = 0x00000001, + eLayerChanged = 0x00000002, + eSizeChanged = 0x00000004, + eAlphaChanged = 0x00000008, + eMatrixChanged = 0x00000010, + eTransparentRegionChanged = 0x00000020, + eFlagsChanged = 0x00000040, + eLayerStackChanged = 0x00000080, + eCropChanged = 0x00000100, + eBlurChanged = 0x00400000, + eBlurMaskSurfaceChanged = 0x00800000, + eBlurMaskSamplingChanged = 0x01000000, + eBlurMaskAlphaThresholdChanged = 0x02000000, + }; + + layer_state_t() + : what(0), + x(0), y(0), z(0), w(0), h(0), layerStack(0), blur(0), + blurMaskSampling(0), blurMaskAlphaThreshold(0), alpha(0), flags(0), mask(0), + reserved(0) + { + matrix.dsdx = matrix.dtdy = 1.0f; + matrix.dsdy = matrix.dtdx = 0.0f; + crop.makeInvalid(); + } + + status_t write(Parcel& output) const; + status_t read(const Parcel& input); + + struct matrix22_t { + float dsdx; + float dtdx; + float dsdy; + float dtdy; + }; + sp surface; + uint32_t what; + float x; + float y; + uint32_t z; + uint32_t w; + uint32_t h; + uint32_t layerStack; + float blur; + sp blurMaskSurface; + uint32_t blurMaskSampling; + float blurMaskAlphaThreshold; + float alpha; + uint8_t flags; + uint8_t mask; + uint8_t reserved; + matrix22_t matrix; + Rect crop; + // non POD must be last. see write/read + Region transparentRegion; +}; + +struct ComposerState { + sp client; + layer_state_t state; + status_t write(Parcel& output) const; + status_t read(const Parcel& input); +}; + +struct DisplayState { + + enum { + eOrientationDefault = 0, + eOrientation90 = 1, + eOrientation180 = 2, + eOrientation270 = 3, + eOrientationUnchanged = 4, + eOrientationSwapMask = 0x01 + }; + + enum { + eSurfaceChanged = 0x01, + eLayerStackChanged = 0x02, + eDisplayProjectionChanged = 0x04, + eDisplaySizeChanged = 0x08 + }; + + uint32_t what; + sp token; + sp surface; + uint32_t layerStack; + uint32_t orientation; + Rect viewport; + Rect frame; + uint32_t width, height; + status_t write(Parcel& output) const; + status_t read(const Parcel& input); +}; + +}; // namespace android + +#endif // ANDROID_SF_LAYER_STATE_H + diff --git a/phonelibs/android_frameworks_native/include/private/gui/SyncFeatures.h b/phonelibs/android_frameworks_native/include/private/gui/SyncFeatures.h new file mode 100644 index 00000000000000..79fb75bcbeb143 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/private/gui/SyncFeatures.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GUI_SYNC_FEATURES_H +#define ANDROID_GUI_SYNC_FEATURES_H + +#include +#include + + +namespace android { +// ---------------------------------------------------------------------------- + +class SyncFeatures : public Singleton { + friend class Singleton; + bool mHasNativeFenceSync; + bool mHasFenceSync; + bool mHasWaitSync; + String8 mString; + SyncFeatures(); + +public: + bool useNativeFenceSync() const; + bool useFenceSync() const; + bool useWaitSync() const; + String8 toString() const; +}; + +// ---------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_GUI_SYNC_FEATURES_H diff --git a/phonelibs/android_frameworks_native/include/private/ui/RegionHelper.h b/phonelibs/android_frameworks_native/include/private/ui/RegionHelper.h new file mode 100644 index 00000000000000..8c190dd40b0007 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/private/ui/RegionHelper.h @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UI_PRIVATE_REGION_HELPER_H +#define ANDROID_UI_PRIVATE_REGION_HELPER_H + +#include +#include + +namespace android { +// ---------------------------------------------------------------------------- + +template +class region_operator +{ +public: + typedef typename RECT::value_type TYPE; + static const TYPE max_value = 0x7FFFFFF; + + /* + * Common boolean operations: + * value is computed as 0b101 op 0b110 + * other boolean operation are possible, simply compute + * their corresponding value with the above formulae and use + * it when instantiating a region_operator. + */ + static const uint32_t LHS = 0x5; // 0b101 + static const uint32_t RHS = 0x6; // 0b110 + enum { + op_nand = LHS & ~RHS, + op_and = LHS & RHS, + op_or = LHS | RHS, + op_xor = LHS ^ RHS + }; + + struct region { + RECT const* rects; + size_t count; + TYPE dx; + TYPE dy; + inline region(const region& rhs) + : rects(rhs.rects), count(rhs.count), dx(rhs.dx), dy(rhs.dy) { } + inline region(RECT const* r, size_t c) + : rects(r), count(c), dx(), dy() { } + inline region(RECT const* r, size_t c, TYPE dx, TYPE dy) + : rects(r), count(c), dx(dx), dy(dy) { } + }; + + class region_rasterizer { + friend class region_operator; + virtual void operator()(const RECT& rect) = 0; + public: + virtual ~region_rasterizer() { }; + }; + + inline region_operator(int op, const region& lhs, const region& rhs) + : op_mask(op), spanner(lhs, rhs) + { + } + + void operator()(region_rasterizer& rasterizer) { + RECT current; + do { + SpannerInner spannerInner(spanner.lhs, spanner.rhs); + int inside = spanner.next(current.top, current.bottom); + spannerInner.prepare(inside); + do { + TYPE left, right; + int inside = spannerInner.next(current.left, current.right); + if ((op_mask >> inside) & 1) { + if (current.left < current.right && + current.top < current.bottom) { + rasterizer(current); + } + } + } while(!spannerInner.isDone()); + } while(!spanner.isDone()); + } + +private: + uint32_t op_mask; + + class SpannerBase + { + public: + SpannerBase() + : lhs_head(max_value), lhs_tail(max_value), + rhs_head(max_value), rhs_tail(max_value) { + } + + enum { + lhs_before_rhs = 0, + lhs_after_rhs = 1, + lhs_coincide_rhs = 2 + }; + + protected: + TYPE lhs_head; + TYPE lhs_tail; + TYPE rhs_head; + TYPE rhs_tail; + + inline int next(TYPE& head, TYPE& tail, + bool& more_lhs, bool& more_rhs) + { + int inside; + more_lhs = false; + more_rhs = false; + if (lhs_head < rhs_head) { + inside = lhs_before_rhs; + head = lhs_head; + if (lhs_tail <= rhs_head) { + tail = lhs_tail; + more_lhs = true; + } else { + lhs_head = rhs_head; + tail = rhs_head; + } + } else if (rhs_head < lhs_head) { + inside = lhs_after_rhs; + head = rhs_head; + if (rhs_tail <= lhs_head) { + tail = rhs_tail; + more_rhs = true; + } else { + rhs_head = lhs_head; + tail = lhs_head; + } + } else { + inside = lhs_coincide_rhs; + head = lhs_head; + if (lhs_tail <= rhs_tail) { + tail = rhs_head = lhs_tail; + more_lhs = true; + } + if (rhs_tail <= lhs_tail) { + tail = lhs_head = rhs_tail; + more_rhs = true; + } + } + return inside; + } + }; + + class Spanner : protected SpannerBase + { + friend class region_operator; + region lhs; + region rhs; + + public: + inline Spanner(const region& lhs, const region& rhs) + : lhs(lhs), rhs(rhs) + { + if (lhs.count) { + SpannerBase::lhs_head = lhs.rects->top + lhs.dy; + SpannerBase::lhs_tail = lhs.rects->bottom + lhs.dy; + } + if (rhs.count) { + SpannerBase::rhs_head = rhs.rects->top + rhs.dy; + SpannerBase::rhs_tail = rhs.rects->bottom + rhs.dy; + } + } + + inline bool isDone() const { + return !rhs.count && !lhs.count; + } + + inline int next(TYPE& top, TYPE& bottom) + { + bool more_lhs = false; + bool more_rhs = false; + int inside = SpannerBase::next(top, bottom, more_lhs, more_rhs); + if (more_lhs) { + advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail); + } + if (more_rhs) { + advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail); + } + return inside; + } + + private: + static inline + void advance(region& reg, TYPE& aTop, TYPE& aBottom) { + // got to next span + size_t count = reg.count; + RECT const * rects = reg.rects; + RECT const * const end = rects + count; + const int top = rects->top; + while (rects != end && rects->top == top) { + rects++; + count--; + } + if (rects != end) { + aTop = rects->top + reg.dy; + aBottom = rects->bottom + reg.dy; + } else { + aTop = max_value; + aBottom = max_value; + } + reg.rects = rects; + reg.count = count; + } + }; + + class SpannerInner : protected SpannerBase + { + region lhs; + region rhs; + + public: + inline SpannerInner(const region& lhs, const region& rhs) + : lhs(lhs), rhs(rhs) + { + } + + inline void prepare(int inside) { + if (inside == SpannerBase::lhs_before_rhs) { + if (lhs.count) { + SpannerBase::lhs_head = lhs.rects->left + lhs.dx; + SpannerBase::lhs_tail = lhs.rects->right + lhs.dx; + } + SpannerBase::rhs_head = max_value; + SpannerBase::rhs_tail = max_value; + } else if (inside == SpannerBase::lhs_after_rhs) { + SpannerBase::lhs_head = max_value; + SpannerBase::lhs_tail = max_value; + if (rhs.count) { + SpannerBase::rhs_head = rhs.rects->left + rhs.dx; + SpannerBase::rhs_tail = rhs.rects->right + rhs.dx; + } + } else { + if (lhs.count) { + SpannerBase::lhs_head = lhs.rects->left + lhs.dx; + SpannerBase::lhs_tail = lhs.rects->right + lhs.dx; + } + if (rhs.count) { + SpannerBase::rhs_head = rhs.rects->left + rhs.dx; + SpannerBase::rhs_tail = rhs.rects->right + rhs.dx; + } + } + } + + inline bool isDone() const { + return SpannerBase::lhs_head == max_value && + SpannerBase::rhs_head == max_value; + } + + inline int next(TYPE& left, TYPE& right) + { + bool more_lhs = false; + bool more_rhs = false; + int inside = SpannerBase::next(left, right, more_lhs, more_rhs); + if (more_lhs) { + advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail); + } + if (more_rhs) { + advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail); + } + return inside; + } + + private: + static inline + void advance(region& reg, TYPE& left, TYPE& right) { + if (reg.rects && reg.count) { + const int cur_span_top = reg.rects->top; + reg.rects++; + reg.count--; + if (!reg.count || reg.rects->top != cur_span_top) { + left = max_value; + right = max_value; + } else { + left = reg.rects->left + reg.dx; + right = reg.rects->right + reg.dx; + } + } + } + }; + + Spanner spanner; +}; + +// ---------------------------------------------------------------------------- +}; + +#endif /* ANDROID_UI_PRIVATE_REGION_HELPER_H */ diff --git a/phonelibs/android_frameworks_native/include/ui/ANativeObjectBase.h b/phonelibs/android_frameworks_native/include/ui/ANativeObjectBase.h new file mode 100644 index 00000000000000..76e850fa279aba --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/ANativeObjectBase.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_ANDROID_NATIVES_H +#define ANDROID_ANDROID_NATIVES_H + +#include +#include + +#include +#include + +// --------------------------------------------------------------------------- + +/* FIXME: this is legacy for pixmaps */ +typedef struct egl_native_pixmap_t +{ + int32_t version; /* must be 32 */ + int32_t width; + int32_t height; + int32_t stride; + uint8_t* data; + uint8_t format; + uint8_t rfu[3]; + union { + uint32_t compressedFormat; + int32_t vstride; + }; + int32_t reserved; +} egl_native_pixmap_t; + +/*****************************************************************************/ + +#ifdef __cplusplus + +#include + +namespace android { + +/* + * This helper class turns a ANativeXXX object type into a C++ + * reference-counted object; with proper type conversions. + */ +template +class ANativeObjectBase : public NATIVE_TYPE, public REF +{ +public: + // Disambiguate between the incStrong in REF and NATIVE_TYPE + void incStrong(const void* id) const { + REF::incStrong(id); + } + void decStrong(const void* id) const { + REF::decStrong(id); + } + +protected: + typedef ANativeObjectBase BASE; + ANativeObjectBase() : NATIVE_TYPE(), REF() { + NATIVE_TYPE::common.incRef = incRef; + NATIVE_TYPE::common.decRef = decRef; + } + static inline TYPE* getSelf(NATIVE_TYPE* self) { + return static_cast(self); + } + static inline TYPE const* getSelf(NATIVE_TYPE const* self) { + return static_cast(self); + } + static inline TYPE* getSelf(android_native_base_t* base) { + return getSelf(reinterpret_cast(base)); + } + static inline TYPE const * getSelf(android_native_base_t const* base) { + return getSelf(reinterpret_cast(base)); + } + static void incRef(android_native_base_t* base) { + ANativeObjectBase* self = getSelf(base); + self->incStrong(self); + } + static void decRef(android_native_base_t* base) { + ANativeObjectBase* self = getSelf(base); + self->decStrong(self); + } +}; + +} // namespace android +#endif // __cplusplus + +/*****************************************************************************/ + +#endif /* ANDROID_ANDROID_NATIVES_H */ diff --git a/phonelibs/android_frameworks_native/include/ui/DisplayInfo.h b/phonelibs/android_frameworks_native/include/ui/DisplayInfo.h new file mode 100644 index 00000000000000..ad73ee72f98063 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/DisplayInfo.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UI_DISPLAY_INFO_H +#define ANDROID_UI_DISPLAY_INFO_H + +#include +#include +#include + +#include + +namespace android { + +struct DisplayInfo { + uint32_t w; + uint32_t h; + float xdpi; + float ydpi; + float fps; + float density; + uint8_t orientation; + bool secure; + nsecs_t appVsyncOffset; + nsecs_t presentationDeadline; + int colorTransform; +}; + +/* Display orientations as defined in Surface.java and ISurfaceComposer.h. */ +enum { + DISPLAY_ORIENTATION_0 = 0, + DISPLAY_ORIENTATION_90 = 1, + DISPLAY_ORIENTATION_180 = 2, + DISPLAY_ORIENTATION_270 = 3 +}; + +}; // namespace android + +#endif // ANDROID_COMPOSER_DISPLAY_INFO_H diff --git a/phonelibs/android_frameworks_native/include/ui/DisplayStatInfo.h b/phonelibs/android_frameworks_native/include/ui/DisplayStatInfo.h new file mode 100644 index 00000000000000..0549a832b5274c --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/DisplayStatInfo.h @@ -0,0 +1,31 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UI_DISPLAY_STAT_INFO_H +#define ANDROID_UI_DISPLAY_STAT_INFO_H + +#include + +namespace android { + +struct DisplayStatInfo { + nsecs_t vsyncTime; + nsecs_t vsyncPeriod; +}; + +}; // namespace android + +#endif // ANDROID_COMPOSER_DISPLAY_STAT_INFO_H diff --git a/phonelibs/android_frameworks_native/include/ui/Fence.h b/phonelibs/android_frameworks_native/include/ui/Fence.h new file mode 100644 index 00000000000000..b431bd52aa18fd --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/Fence.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_FENCE_H +#define ANDROID_FENCE_H + +#include +#include + +#include +#include +#include +#include +#include +#include + +struct ANativeWindowBuffer; + +namespace android { + +// =========================================================================== +// Fence +// =========================================================================== + +class Fence + : public LightRefBase, public Flattenable +{ +public: + static const sp NO_FENCE; + + // TIMEOUT_NEVER may be passed to the wait method to indicate that it + // should wait indefinitely for the fence to signal. + enum { TIMEOUT_NEVER = -1 }; + + // Construct a new Fence object with an invalid file descriptor. This + // should be done when the Fence object will be set up by unflattening + // serialized data. + Fence(); + + // Construct a new Fence object to manage a given fence file descriptor. + // When the new Fence object is destructed the file descriptor will be + // closed. + Fence(int fenceFd); + + // Check whether the Fence has an open fence file descriptor. Most Fence + // methods treat an invalid file descriptor just like a valid fence that + // is already signalled, so using this is usually not necessary. + bool isValid() const { return mFenceFd != -1; } + + // wait waits for up to timeout milliseconds for the fence to signal. If + // the fence signals then NO_ERROR is returned. If the timeout expires + // before the fence signals then -ETIME is returned. A timeout of + // TIMEOUT_NEVER may be used to indicate that the call should wait + // indefinitely for the fence to signal. + status_t wait(int timeout); + + // waitForever is a convenience function for waiting forever for a fence to + // signal (just like wait(TIMEOUT_NEVER)), but issuing an error to the + // system log and fence state to the kernel log if the wait lasts longer + // than a warning timeout. + // The logname argument should be a string identifying + // the caller and will be included in the log message. + status_t waitForever(const char* logname); + + // merge combines two Fence objects, creating a new Fence object that + // becomes signaled when both f1 and f2 are signaled (even if f1 or f2 is + // destroyed before it becomes signaled). The name argument specifies the + // human-readable name to associated with the new Fence object. + static sp merge(const String8& name, const sp& f1, + const sp& f2); + + // Return a duplicate of the fence file descriptor. The caller is + // responsible for closing the returned file descriptor. On error, -1 will + // be returned and errno will indicate the problem. + int dup() const; + + // getSignalTime returns the system monotonic clock time at which the + // fence transitioned to the signaled state. If the fence is not signaled + // then INT64_MAX is returned. If the fence is invalid or if an error + // occurs then -1 is returned. + nsecs_t getSignalTime() const; + + // Flattenable interface + size_t getFlattenedSize() const; + size_t getFdCount() const; + status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const; + status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count); + +private: + // Only allow instantiation using ref counting. + friend class LightRefBase; + ~Fence(); + + // Disallow copying + Fence(const Fence& rhs); + Fence& operator = (const Fence& rhs); + const Fence& operator = (const Fence& rhs) const; + + int mFenceFd; +}; + +}; // namespace android + +#endif // ANDROID_FENCE_H diff --git a/phonelibs/android_frameworks_native/include/ui/FrameStats.h b/phonelibs/android_frameworks_native/include/ui/FrameStats.h new file mode 100644 index 00000000000000..6bfe635c726304 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/FrameStats.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UI_FRAME_STATS_H +#define ANDROID_UI_FRAME_STATS_H + +#include +#include +#include + +namespace android { + +class FrameStats : public LightFlattenable { +public: + FrameStats() : refreshPeriodNano(0) {}; + + /* + * Approximate refresh time, in nanoseconds. + */ + nsecs_t refreshPeriodNano; + + /* + * The times in nanoseconds for when the frame contents were posted by the producer (e.g. + * the application). They are either explicitly set or defaulted to the time when + * Surface::queueBuffer() was called. + */ + Vector desiredPresentTimesNano; + + /* + * The times in milliseconds for when the frame contents were presented on the screen. + */ + Vector actualPresentTimesNano; + + /* + * The times in nanoseconds for when the frame contents were ready to be presented. Note that + * a frame can be posted and still it contents being rendered asynchronously in GL. In such a + * case these are the times when the frame contents were completely rendered (i.e. their fences + * signaled). + */ + Vector frameReadyTimesNano; + + // LightFlattenable + bool isFixedSize() const; + size_t getFlattenedSize() const; + status_t flatten(void* buffer, size_t size) const; + status_t unflatten(void const* buffer, size_t size); +}; + +}; // namespace android + +#endif // ANDROID_UI_FRAME_STATS_H diff --git a/phonelibs/android_frameworks_native/include/ui/FramebufferNativeWindow.h b/phonelibs/android_frameworks_native/include/ui/FramebufferNativeWindow.h new file mode 100644 index 00000000000000..6b66d5f66b0284 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/FramebufferNativeWindow.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDED_FROM_FRAMEBUFFER_NATIVE_WINDOW_CPP +#warning "FramebufferNativeWindow is deprecated" +#endif + +#ifndef ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H +#define ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H + +#include +#include + +#include + +#include +#include + +#include +#include + +#define MIN_NUM_FRAME_BUFFERS 2 +#define MAX_NUM_FRAME_BUFFERS 3 + +extern "C" EGLNativeWindowType android_createDisplaySurface(void); + +// --------------------------------------------------------------------------- +namespace android { +// --------------------------------------------------------------------------- + +class Surface; +class NativeBuffer; + +// --------------------------------------------------------------------------- + +class FramebufferNativeWindow + : public ANativeObjectBase< + ANativeWindow, + FramebufferNativeWindow, + LightRefBase > +{ +public: + FramebufferNativeWindow(); + + framebuffer_device_t const * getDevice() const { return fbDev; } + + bool isUpdateOnDemand() const { return mUpdateOnDemand; } + status_t setUpdateRectangle(const Rect& updateRect); + status_t compositionComplete(); + + void dump(String8& result); + + // for debugging only + int getCurrentBufferIndex() const; + +private: + friend class LightRefBase; + ~FramebufferNativeWindow(); // this class cannot be overloaded + static int setSwapInterval(ANativeWindow* window, int interval); + static int dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer, int* fenceFd); + static int queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd); + static int query(const ANativeWindow* window, int what, int* value); + static int perform(ANativeWindow* window, int operation, ...); + + static int dequeueBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer** buffer); + static int queueBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer* buffer); + static int lockBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer* buffer); + + framebuffer_device_t* fbDev; + alloc_device_t* grDev; + + sp buffers[MAX_NUM_FRAME_BUFFERS]; + sp front; + + mutable Mutex mutex; + Condition mCondition; + int32_t mNumBuffers; + int32_t mNumFreeBuffers; + int32_t mBufferHead; + int32_t mCurrentBufferIndex; + bool mUpdateOnDemand; +}; + +// --------------------------------------------------------------------------- +}; // namespace android +// --------------------------------------------------------------------------- + +#endif // ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H + diff --git a/phonelibs/android_frameworks_native/include/ui/GraphicBuffer.h b/phonelibs/android_frameworks_native/include/ui/GraphicBuffer.h new file mode 100644 index 00000000000000..3da720ff376c69 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/GraphicBuffer.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_GRAPHIC_BUFFER_H +#define ANDROID_GRAPHIC_BUFFER_H + +#include +#include + +#include +#include +#include +#include +#include + + +struct ANativeWindowBuffer; + +namespace android { + +class GraphicBufferMapper; + +// =========================================================================== +// GraphicBuffer +// =========================================================================== + +class GraphicBuffer + : public ANativeObjectBase< ANativeWindowBuffer, GraphicBuffer, RefBase >, + public Flattenable +{ + friend class Flattenable; +public: + + enum { + USAGE_SW_READ_NEVER = GRALLOC_USAGE_SW_READ_NEVER, + USAGE_SW_READ_RARELY = GRALLOC_USAGE_SW_READ_RARELY, + USAGE_SW_READ_OFTEN = GRALLOC_USAGE_SW_READ_OFTEN, + USAGE_SW_READ_MASK = GRALLOC_USAGE_SW_READ_MASK, + + USAGE_SW_WRITE_NEVER = GRALLOC_USAGE_SW_WRITE_NEVER, + USAGE_SW_WRITE_RARELY = GRALLOC_USAGE_SW_WRITE_RARELY, + USAGE_SW_WRITE_OFTEN = GRALLOC_USAGE_SW_WRITE_OFTEN, + USAGE_SW_WRITE_MASK = GRALLOC_USAGE_SW_WRITE_MASK, + + USAGE_SOFTWARE_MASK = USAGE_SW_READ_MASK|USAGE_SW_WRITE_MASK, + + USAGE_PROTECTED = GRALLOC_USAGE_PROTECTED, + + USAGE_HW_TEXTURE = GRALLOC_USAGE_HW_TEXTURE, + USAGE_HW_RENDER = GRALLOC_USAGE_HW_RENDER, + USAGE_HW_2D = GRALLOC_USAGE_HW_2D, + USAGE_HW_COMPOSER = GRALLOC_USAGE_HW_COMPOSER, + USAGE_HW_VIDEO_ENCODER = GRALLOC_USAGE_HW_VIDEO_ENCODER, + USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK, + + USAGE_CURSOR = GRALLOC_USAGE_CURSOR, + }; + + GraphicBuffer(); + + // creates w * h buffer + GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, + uint32_t inUsage); + + // create a buffer from an existing handle + GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, + uint32_t inUsage, uint32_t inStride, native_handle_t* inHandle, + bool keepOwnership); + + // create a buffer from an existing ANativeWindowBuffer + GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership); + + // return status + status_t initCheck() const; + + uint32_t getWidth() const { return static_cast(width); } + uint32_t getHeight() const { return static_cast(height); } + uint32_t getStride() const { return static_cast(stride); } + uint32_t getUsage() const { return static_cast(usage); } + PixelFormat getPixelFormat() const { return format; } + Rect getBounds() const { return Rect(width, height); } + uint64_t getId() const { return mId; } + + uint32_t getGenerationNumber() const { return mGenerationNumber; } + void setGenerationNumber(uint32_t generation) { + mGenerationNumber = generation; + } + + status_t reallocate(uint32_t inWidth, uint32_t inHeight, + PixelFormat inFormat, uint32_t inUsage); + + bool needsReallocation(uint32_t inWidth, uint32_t inHeight, + PixelFormat inFormat, uint32_t inUsage); + + status_t lock(uint32_t inUsage, void** vaddr); + status_t lock(uint32_t inUsage, const Rect& rect, void** vaddr); + // For HAL_PIXEL_FORMAT_YCbCr_420_888 + status_t lockYCbCr(uint32_t inUsage, android_ycbcr *ycbcr); + status_t lockYCbCr(uint32_t inUsage, const Rect& rect, + android_ycbcr *ycbcr); + status_t unlock(); + status_t lockAsync(uint32_t inUsage, void** vaddr, int fenceFd); + status_t lockAsync(uint32_t inUsage, const Rect& rect, void** vaddr, + int fenceFd); + status_t lockAsyncYCbCr(uint32_t inUsage, android_ycbcr *ycbcr, + int fenceFd); + status_t lockAsyncYCbCr(uint32_t inUsage, const Rect& rect, + android_ycbcr *ycbcr, int fenceFd); + status_t unlockAsync(int *fenceFd); + + ANativeWindowBuffer* getNativeBuffer() const; + + // for debugging + static void dumpAllocationsToSystemLog(); + + // Flattenable protocol + size_t getFlattenedSize() const; + size_t getFdCount() const; + status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const; + status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count); + +private: + ~GraphicBuffer(); + + enum { + ownNone = 0, + ownHandle = 1, + ownData = 2, + }; + + inline const GraphicBufferMapper& getBufferMapper() const { + return mBufferMapper; + } + inline GraphicBufferMapper& getBufferMapper() { + return mBufferMapper; + } + uint8_t mOwner; + +private: + friend class Surface; + friend class BpSurface; + friend class BnSurface; + friend class LightRefBase; + GraphicBuffer(const GraphicBuffer& rhs); + GraphicBuffer& operator = (const GraphicBuffer& rhs); + const GraphicBuffer& operator = (const GraphicBuffer& rhs) const; + + status_t initSize(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, + uint32_t inUsage); + + void free_handle(); + + GraphicBufferMapper& mBufferMapper; + ssize_t mInitCheck; + + // If we're wrapping another buffer then this reference will make sure it + // doesn't get freed. + sp mWrappedBuffer; + + uint64_t mId; + + // Stores the generation number of this buffer. If this number does not + // match the BufferQueue's internal generation number (set through + // IGBP::setGenerationNumber), attempts to attach the buffer will fail. + uint32_t mGenerationNumber; +}; + +}; // namespace android + +#endif // ANDROID_GRAPHIC_BUFFER_H diff --git a/phonelibs/android_frameworks_native/include/ui/GraphicBufferAllocator.h b/phonelibs/android_frameworks_native/include/ui/GraphicBufferAllocator.h new file mode 100644 index 00000000000000..5443f09a104d6c --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/GraphicBufferAllocator.h @@ -0,0 +1,95 @@ +/* +** +** Copyright 2009, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#ifndef ANDROID_BUFFER_ALLOCATOR_H +#define ANDROID_BUFFER_ALLOCATOR_H + +#include + +#include + +#include +#include +#include +#include + +#include + +#include + + +namespace android { +// --------------------------------------------------------------------------- + +class String8; + +class GraphicBufferAllocator : public Singleton +{ +public: + enum { + USAGE_SW_READ_NEVER = GRALLOC_USAGE_SW_READ_NEVER, + USAGE_SW_READ_RARELY = GRALLOC_USAGE_SW_READ_RARELY, + USAGE_SW_READ_OFTEN = GRALLOC_USAGE_SW_READ_OFTEN, + USAGE_SW_READ_MASK = GRALLOC_USAGE_SW_READ_MASK, + + USAGE_SW_WRITE_NEVER = GRALLOC_USAGE_SW_WRITE_NEVER, + USAGE_SW_WRITE_RARELY = GRALLOC_USAGE_SW_WRITE_RARELY, + USAGE_SW_WRITE_OFTEN = GRALLOC_USAGE_SW_WRITE_OFTEN, + USAGE_SW_WRITE_MASK = GRALLOC_USAGE_SW_WRITE_MASK, + + USAGE_SOFTWARE_MASK = USAGE_SW_READ_MASK|USAGE_SW_WRITE_MASK, + + USAGE_HW_TEXTURE = GRALLOC_USAGE_HW_TEXTURE, + USAGE_HW_RENDER = GRALLOC_USAGE_HW_RENDER, + USAGE_HW_2D = GRALLOC_USAGE_HW_2D, + USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK + }; + + static inline GraphicBufferAllocator& get() { return getInstance(); } + + status_t alloc(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage, + buffer_handle_t* handle, uint32_t* stride); + + status_t free(buffer_handle_t handle); + + void dump(String8& res) const; + static void dumpToSystemLog(); + +private: + struct alloc_rec_t { + uint32_t width; + uint32_t height; + uint32_t stride; + PixelFormat format; + uint32_t usage; + size_t size; + }; + + static Mutex sLock; + static KeyedVector sAllocList; + + friend class Singleton; + GraphicBufferAllocator(); + ~GraphicBufferAllocator(); + + alloc_device_t *mAllocDev; +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_BUFFER_ALLOCATOR_H diff --git a/phonelibs/android_frameworks_native/include/ui/GraphicBufferMapper.h b/phonelibs/android_frameworks_native/include/ui/GraphicBufferMapper.h new file mode 100644 index 00000000000000..99006248275828 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/GraphicBufferMapper.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UI_BUFFER_MAPPER_H +#define ANDROID_UI_BUFFER_MAPPER_H + +#include +#include + +#include + +#include + + +struct gralloc_module_t; + +namespace android { + +// --------------------------------------------------------------------------- + +class Rect; + +class GraphicBufferMapper : public Singleton +{ +public: + static inline GraphicBufferMapper& get() { return getInstance(); } + + status_t registerBuffer(buffer_handle_t handle); + + status_t unregisterBuffer(buffer_handle_t handle); + + status_t lock(buffer_handle_t handle, + uint32_t usage, const Rect& bounds, void** vaddr); + + status_t lockYCbCr(buffer_handle_t handle, + uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr); + + status_t unlock(buffer_handle_t handle); + + status_t lockAsync(buffer_handle_t handle, + uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd); + + status_t lockAsyncYCbCr(buffer_handle_t handle, + uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr, + int fenceFd); + + status_t unlockAsync(buffer_handle_t handle, int *fenceFd); + +#ifdef EXYNOS4_ENHANCEMENTS + status_t getphys(buffer_handle_t handle, void** paddr); +#endif + + // dumps information about the mapping of this handle + void dump(buffer_handle_t handle); + +private: + friend class Singleton; + GraphicBufferMapper(); + gralloc_module_t const *mAllocMod; +}; + +// --------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_UI_BUFFER_MAPPER_H + diff --git a/phonelibs/android_frameworks_native/include/ui/PixelFormat.h b/phonelibs/android_frameworks_native/include/ui/PixelFormat.h new file mode 100644 index 00000000000000..f26fecb8b14709 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/PixelFormat.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// + +// Pixel formats used across the system. +// These formats might not all be supported by all renderers, for instance +// skia or SurfaceFlinger are not required to support all of these formats +// (either as source or destination) + + +#ifndef UI_PIXELFORMAT_H +#define UI_PIXELFORMAT_H + +#include + +namespace android { + +enum { + // + // these constants need to match those + // in graphics/PixelFormat.java & pixelflinger/format.h + // + PIXEL_FORMAT_UNKNOWN = 0, + PIXEL_FORMAT_NONE = 0, + + // logical pixel formats used by the SurfaceFlinger ----------------------- + PIXEL_FORMAT_CUSTOM = -4, + // Custom pixel-format described by a PixelFormatInfo structure + + PIXEL_FORMAT_TRANSLUCENT = -3, + // System chooses a format that supports translucency (many alpha bits) + + PIXEL_FORMAT_TRANSPARENT = -2, + // System chooses a format that supports transparency + // (at least 1 alpha bit) + + PIXEL_FORMAT_OPAQUE = -1, + // System chooses an opaque format (no alpha bits required) + + // real pixel formats supported for rendering ----------------------------- + + PIXEL_FORMAT_RGBA_8888 = HAL_PIXEL_FORMAT_RGBA_8888, // 4x8-bit RGBA + PIXEL_FORMAT_RGBX_8888 = HAL_PIXEL_FORMAT_RGBX_8888, // 4x8-bit RGB0 + PIXEL_FORMAT_RGB_888 = HAL_PIXEL_FORMAT_RGB_888, // 3x8-bit RGB + PIXEL_FORMAT_RGB_565 = HAL_PIXEL_FORMAT_RGB_565, // 16-bit RGB + PIXEL_FORMAT_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888, // 4x8-bit BGRA + PIXEL_FORMAT_RGBA_5551 = 6, // 16-bit ARGB + PIXEL_FORMAT_RGBA_4444 = 7, // 16-bit ARGB +}; + +typedef int32_t PixelFormat; + +uint32_t bytesPerPixel(PixelFormat format); +uint32_t bitsPerPixel(PixelFormat format); + +}; // namespace android + +#endif // UI_PIXELFORMAT_H diff --git a/phonelibs/android_frameworks_native/include/ui/Point.h b/phonelibs/android_frameworks_native/include/ui/Point.h new file mode 100644 index 00000000000000..1d7f64d30732c0 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/Point.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UI_POINT +#define ANDROID_UI_POINT + +#include +#include + +namespace android { + +class Point : public LightFlattenablePod +{ +public: + int x; + int y; + + // we don't provide copy-ctor and operator= on purpose + // because we want the compiler generated versions + + // Default constructor doesn't initialize the Point + inline Point() { + } + inline Point(int x, int y) : x(x), y(y) { + } + + inline bool operator == (const Point& rhs) const { + return (x == rhs.x) && (y == rhs.y); + } + inline bool operator != (const Point& rhs) const { + return !operator == (rhs); + } + + inline bool isOrigin() const { + return !(x|y); + } + + // operator < defines an order which allows to use points in sorted + // vectors. + bool operator < (const Point& rhs) const { + return y +#include +#include +#include + +#include + +namespace android { + +class Rect : public ARect, public LightFlattenablePod +{ +public: + typedef ARect::value_type value_type; + + static const Rect INVALID_RECT; + + // we don't provide copy-ctor and operator= on purpose + // because we want the compiler generated versions + + inline Rect() { + left = right = top = bottom = 0; + } + + inline Rect(int32_t w, int32_t h) { + left = top = 0; + right = w; + bottom = h; + } + + inline Rect(uint32_t w, uint32_t h) { + if (w > INT32_MAX) { + ALOG(LOG_WARN, "Rect", + "Width %u too large for Rect class, clamping", w); + w = INT32_MAX; + } + if (h > INT32_MAX) { + ALOG(LOG_WARN, "Rect", + "Height %u too large for Rect class, clamping", h); + h = INT32_MAX; + } + left = top = 0; + right = w; + bottom = h; + } + + inline Rect(int32_t l, int32_t t, int32_t r, int32_t b) { + left = l; + top = t; + right = r; + bottom = b; + } + + inline Rect(const Point& lt, const Point& rb) { + left = lt.x; + top = lt.y; + right = rb.x; + bottom = rb.y; + } + + void makeInvalid(); + + inline void clear() { + left = top = right = bottom = 0; + } + + // a valid rectangle has a non negative width and height + inline bool isValid() const { + return (getWidth() >= 0) && (getHeight() >= 0); + } + + // an empty rect has a zero width or height, or is invalid + inline bool isEmpty() const { + return (getWidth() <= 0) || (getHeight() <= 0); + } + + // rectangle's width + inline int32_t getWidth() const { + return right - left; + } + + // rectangle's height + inline int32_t getHeight() const { + return bottom - top; + } + + inline Rect getBounds() const { + return Rect(right - left, bottom - top); + } + + void setLeftTop(const Point& lt) { + left = lt.x; + top = lt.y; + } + + void setRightBottom(const Point& rb) { + right = rb.x; + bottom = rb.y; + } + + // the following 4 functions return the 4 corners of the rect as Point + Point leftTop() const { + return Point(left, top); + } + Point rightBottom() const { + return Point(right, bottom); + } + Point rightTop() const { + return Point(right, top); + } + Point leftBottom() const { + return Point(left, bottom); + } + + // comparisons + inline bool operator == (const Rect& rhs) const { + return (left == rhs.left) && (top == rhs.top) && + (right == rhs.right) && (bottom == rhs.bottom); + } + + inline bool operator != (const Rect& rhs) const { + return !operator == (rhs); + } + + // operator < defines an order which allows to use rectangles in sorted + // vectors. + bool operator < (const Rect& rhs) const; + + const Rect operator + (const Point& rhs) const; + const Rect operator - (const Point& rhs) const; + + Rect& operator += (const Point& rhs) { + return offsetBy(rhs.x, rhs.y); + } + Rect& operator -= (const Point& rhs) { + return offsetBy(-rhs.x, -rhs.y); + } + + Rect& offsetToOrigin() { + right -= left; + bottom -= top; + left = top = 0; + return *this; + } + Rect& offsetTo(const Point& p) { + return offsetTo(p.x, p.y); + } + Rect& offsetBy(const Point& dp) { + return offsetBy(dp.x, dp.y); + } + + Rect& offsetTo(int32_t x, int32_t y); + Rect& offsetBy(int32_t x, int32_t y); + + bool intersect(const Rect& with, Rect* result) const; + + // Create a new Rect by transforming this one using a graphics HAL + // transform. This rectangle is defined in a coordinate space starting at + // the origin and extending to (width, height). If the transform includes + // a ROT90 then the output rectangle is defined in a space extending to + // (height, width). Otherwise the output rectangle is in the same space as + // the input. + Rect transform(uint32_t xform, int32_t width, int32_t height) const; + + // this calculates (Region(*this) - exclude).bounds() efficiently + Rect reduce(const Rect& exclude) const; + + + // for backward compatibility + inline int32_t width() const { return getWidth(); } + inline int32_t height() const { return getHeight(); } + inline void set(const Rect& rhs) { operator = (rhs); } +}; + +ANDROID_BASIC_TYPES_TRAITS(Rect) + +}; // namespace android + +#endif // ANDROID_UI_RECT diff --git a/phonelibs/android_frameworks_native/include/ui/Region.h b/phonelibs/android_frameworks_native/include/ui/Region.h new file mode 100644 index 00000000000000..2a1491837dc78e --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/Region.h @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UI_REGION_H +#define ANDROID_UI_REGION_H + +#include +#include + +#include + +#include +#include + +namespace android { +// --------------------------------------------------------------------------- + +class SharedBuffer; +class String8; + +// --------------------------------------------------------------------------- +class Region : public LightFlattenable +{ +public: + static const Region INVALID_REGION; + + Region(); + Region(const Region& rhs); + explicit Region(const Rect& rhs); + ~Region(); + + static Region createTJunctionFreeRegion(const Region& r); + + Region& operator = (const Region& rhs); + + inline bool isEmpty() const { return getBounds().isEmpty(); } + inline bool isRect() const { return mStorage.size() == 1; } + + inline Rect getBounds() const { return mStorage[mStorage.size() - 1]; } + inline Rect bounds() const { return getBounds(); } + + bool contains(const Point& point) const; + bool contains(int x, int y) const; + + // the region becomes its bounds + Region& makeBoundsSelf(); + + void clear(); + void set(const Rect& r); + void set(int32_t w, int32_t h); + void set(uint32_t w, uint32_t h); + + Region& orSelf(const Rect& rhs); + Region& xorSelf(const Rect& rhs); + Region& andSelf(const Rect& rhs); + Region& subtractSelf(const Rect& rhs); + + // boolean operators, applied on this + Region& orSelf(const Region& rhs); + Region& xorSelf(const Region& rhs); + Region& andSelf(const Region& rhs); + Region& subtractSelf(const Region& rhs); + + // boolean operators + const Region merge(const Rect& rhs) const; + const Region mergeExclusive(const Rect& rhs) const; + const Region intersect(const Rect& rhs) const; + const Region subtract(const Rect& rhs) const; + + // boolean operators + const Region merge(const Region& rhs) const; + const Region mergeExclusive(const Region& rhs) const; + const Region intersect(const Region& rhs) const; + const Region subtract(const Region& rhs) const; + + // these translate rhs first + Region& translateSelf(int dx, int dy); + Region& orSelf(const Region& rhs, int dx, int dy); + Region& xorSelf(const Region& rhs, int dx, int dy); + Region& andSelf(const Region& rhs, int dx, int dy); + Region& subtractSelf(const Region& rhs, int dx, int dy); + + // these translate rhs first + const Region translate(int dx, int dy) const; + const Region merge(const Region& rhs, int dx, int dy) const; + const Region mergeExclusive(const Region& rhs, int dx, int dy) const; + const Region intersect(const Region& rhs, int dx, int dy) const; + const Region subtract(const Region& rhs, int dx, int dy) const; + + // convenience operators overloads + inline const Region operator | (const Region& rhs) const; + inline const Region operator ^ (const Region& rhs) const; + inline const Region operator & (const Region& rhs) const; + inline const Region operator - (const Region& rhs) const; + inline const Region operator + (const Point& pt) const; + + inline Region& operator |= (const Region& rhs); + inline Region& operator ^= (const Region& rhs); + inline Region& operator &= (const Region& rhs); + inline Region& operator -= (const Region& rhs); + inline Region& operator += (const Point& pt); + + + // returns true if the regions share the same underlying storage + bool isTriviallyEqual(const Region& region) const; + + + /* various ways to access the rectangle list */ + + + // STL-like iterators + typedef Rect const* const_iterator; + const_iterator begin() const; + const_iterator end() const; + + // returns an array of rect which has the same life-time has this + // Region object. + Rect const* getArray(size_t* count) const; + + // returns a SharedBuffer as well as the number of rects. + // ownership is transfered to the caller. + // the caller must call SharedBuffer::release() to free the memory. + SharedBuffer const* getSharedBuffer(size_t* count) const; + + /* no user serviceable parts here... */ + + // add a rectangle to the internal list. This rectangle must + // be sorted in Y and X and must not make the region invalid. + void addRectUnchecked(int l, int t, int r, int b); + + inline bool isFixedSize() const { return false; } + size_t getFlattenedSize() const; + status_t flatten(void* buffer, size_t size) const; + status_t unflatten(void const* buffer, size_t size); + + void dump(String8& out, const char* what, uint32_t flags=0) const; + void dump(const char* what, uint32_t flags=0) const; + +private: + class rasterizer; + friend class rasterizer; + + Region& operationSelf(const Rect& r, int op); + Region& operationSelf(const Region& r, int op); + Region& operationSelf(const Region& r, int dx, int dy, int op); + const Region operation(const Rect& rhs, int op) const; + const Region operation(const Region& rhs, int op) const; + const Region operation(const Region& rhs, int dx, int dy, int op) const; + + static void boolean_operation(int op, Region& dst, + const Region& lhs, const Region& rhs, int dx, int dy); + static void boolean_operation(int op, Region& dst, + const Region& lhs, const Rect& rhs, int dx, int dy); + + static void boolean_operation(int op, Region& dst, + const Region& lhs, const Region& rhs); + static void boolean_operation(int op, Region& dst, + const Region& lhs, const Rect& rhs); + + static void translate(Region& reg, int dx, int dy); + static void translate(Region& dst, const Region& reg, int dx, int dy); + + static bool validate(const Region& reg, + const char* name, bool silent = false); + + // mStorage is a (manually) sorted array of Rects describing the region + // with an extra Rect as the last element which is set to the + // bounds of the region. However, if the region is + // a simple Rect then mStorage contains only that rect. + Vector mStorage; +}; + + +const Region Region::operator | (const Region& rhs) const { + return merge(rhs); +} +const Region Region::operator ^ (const Region& rhs) const { + return mergeExclusive(rhs); +} +const Region Region::operator & (const Region& rhs) const { + return intersect(rhs); +} +const Region Region::operator - (const Region& rhs) const { + return subtract(rhs); +} +const Region Region::operator + (const Point& pt) const { + return translate(pt.x, pt.y); +} + + +Region& Region::operator |= (const Region& rhs) { + return orSelf(rhs); +} +Region& Region::operator ^= (const Region& rhs) { + return xorSelf(rhs); +} +Region& Region::operator &= (const Region& rhs) { + return andSelf(rhs); +} +Region& Region::operator -= (const Region& rhs) { + return subtractSelf(rhs); +} +Region& Region::operator += (const Point& pt) { + return translateSelf(pt.x, pt.y); +} +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_UI_REGION_H + diff --git a/phonelibs/android_frameworks_native/include/ui/TMatHelpers.h b/phonelibs/android_frameworks_native/include/ui/TMatHelpers.h new file mode 100644 index 00000000000000..a6aadcad4096b3 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/TMatHelpers.h @@ -0,0 +1,257 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TMAT_IMPLEMENTATION +#error "Don't include TMatHelpers.h directly. use ui/mat*.h instead" +#else +#undef TMAT_IMPLEMENTATION +#endif + + +#ifndef UI_TMAT_HELPERS_H +#define UI_TMAT_HELPERS_H + +#include +#include +#include +#include +#include + +#define PURE __attribute__((pure)) + +namespace android { +// ------------------------------------------------------------------------------------- + +/* + * No user serviceable parts here. + * + * Don't use this file directly, instead include ui/mat*.h + */ + + +/* + * Matrix utilities + */ + +namespace matrix { + +inline int PURE transpose(int v) { return v; } +inline float PURE transpose(float v) { return v; } +inline double PURE transpose(double v) { return v; } + +inline int PURE trace(int v) { return v; } +inline float PURE trace(float v) { return v; } +inline double PURE trace(double v) { return v; } + +template +MATRIX PURE inverse(const MATRIX& src) { + + COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::COL_SIZE == MATRIX::ROW_SIZE ); + + typename MATRIX::value_type t; + const size_t N = MATRIX::col_size(); + size_t swap; + MATRIX tmp(src); + MATRIX inverse(1); + + for (size_t i=0 ; i fabs(tmp[i][i])) { + swap = j; + } + } + + if (swap != i) { + /* swap rows. */ + for (size_t k=0 ; k +MATRIX_R PURE multiply(const MATRIX_A& lhs, const MATRIX_B& rhs) { + // pre-requisite: + // lhs : D columns, R rows + // rhs : C columns, D rows + // res : C columns, R rows + + COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_A::ROW_SIZE == MATRIX_B::COL_SIZE ); + COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_R::ROW_SIZE == MATRIX_B::ROW_SIZE ); + COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_R::COL_SIZE == MATRIX_A::COL_SIZE ); + + MATRIX_R res(MATRIX_R::NO_INIT); + for (size_t r=0 ; r +MATRIX PURE transpose(const MATRIX& m) { + // for now we only handle square matrix transpose + COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE ); + MATRIX result(MATRIX::NO_INIT); + for (size_t r=0 ; r +typename MATRIX::value_type PURE trace(const MATRIX& m) { + COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE ); + typename MATRIX::value_type result(0); + for (size_t r=0 ; r +typename MATRIX::col_type PURE diag(const MATRIX& m) { + COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE ); + typename MATRIX::col_type result(MATRIX::col_type::NO_INIT); + for (size_t r=0 ; r +String8 asString(const MATRIX& m) { + String8 s; + for (size_t c=0 ; c. + * + * BASE only needs to implement operator[] and size(). + * By simply inheriting from TMatProductOperators BASE will automatically + * get all the functionality here. + */ + +template class BASE, typename T> +class TMatProductOperators { +public: + // multiply by a scalar + BASE& operator *= (T v) { + BASE& lhs(static_cast< BASE& >(*this)); + for (size_t r=0 ; r& operator /= (T v) { + BASE& lhs(static_cast< BASE& >(*this)); + for (size_t r=0 ; r + friend BASE PURE operator *(const BASE& lhs, const BASE& rhs) { + return matrix::multiply >(lhs, rhs); + } +}; + + +/* + * TMatSquareFunctions implements functions on a matrix of type BASE. + * + * BASE only needs to implement: + * - operator[] + * - col_type + * - row_type + * - COL_SIZE + * - ROW_SIZE + * + * By simply inheriting from TMatSquareFunctions BASE will automatically + * get all the functionality here. + */ + +template class BASE, typename T> +class TMatSquareFunctions { +public: + /* + * NOTE: the functions below ARE NOT member methods. They are friend functions + * with they definition inlined with their declaration. This makes these + * template functions available to the compiler when (and only when) this class + * is instantiated, at which point they're only templated on the 2nd parameter + * (the first one, BASE being known). + */ + friend BASE PURE inverse(const BASE& m) { return matrix::inverse(m); } + friend BASE PURE transpose(const BASE& m) { return matrix::transpose(m); } + friend T PURE trace(const BASE& m) { return matrix::trace(m); } +}; + +template class BASE, typename T> +class TMatDebug { +public: + String8 asString() const { + return matrix::asString( static_cast< const BASE& >(*this) ); + } +}; + +// ------------------------------------------------------------------------------------- +}; // namespace android + +#undef PURE + +#endif /* UI_TMAT_HELPERS_H */ diff --git a/phonelibs/android_frameworks_native/include/ui/TVecHelpers.h b/phonelibs/android_frameworks_native/include/ui/TVecHelpers.h new file mode 100644 index 00000000000000..bb7dbfc2b893b9 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/TVecHelpers.h @@ -0,0 +1,381 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TVEC_IMPLEMENTATION +#error "Don't include TVecHelpers.h directly. use ui/vec*.h instead" +#else +#undef TVEC_IMPLEMENTATION +#endif + + +#ifndef UI_TVEC_HELPERS_H +#define UI_TVEC_HELPERS_H + +#include +#include + +#define PURE __attribute__((pure)) + +namespace android { +// ------------------------------------------------------------------------------------- + +/* + * No user serviceable parts here. + * + * Don't use this file directly, instead include ui/vec{2|3|4}.h + */ + +/* + * This class casts itself into anything and assign itself from anything! + * Use with caution! + */ +template +struct Impersonator { + Impersonator& operator = (const TYPE& rhs) { + reinterpret_cast(*this) = rhs; + return *this; + } + operator TYPE& () { + return reinterpret_cast(*this); + } + operator TYPE const& () const { + return reinterpret_cast(*this); + } +}; + +/* + * TVec{Add|Product}Operators implements basic arithmetic and basic compound assignments + * operators on a vector of type BASE. + * + * BASE only needs to implement operator[] and size(). + * By simply inheriting from TVec{Add|Product}Operators BASE will automatically + * get all the functionality here. + */ + +template class BASE, typename T> +class TVecAddOperators { +public: + /* compound assignment from a another vector of the same size but different + * element type. + */ + template + BASE& operator += (const BASE& v) { + BASE& rhs = static_cast&>(*this); + for (size_t i=0 ; i::size() ; i++) { + rhs[i] += v[i]; + } + return rhs; + } + template + BASE& operator -= (const BASE& v) { + BASE& rhs = static_cast&>(*this); + for (size_t i=0 ; i::size() ; i++) { + rhs[i] -= v[i]; + } + return rhs; + } + + /* compound assignment from a another vector of the same type. + * These operators can be used for implicit conversion and handle operations + * like "vector *= scalar" by letting the compiler implicitly convert a scalar + * to a vector (assuming the BASE allows it). + */ + BASE& operator += (const BASE& v) { + BASE& rhs = static_cast&>(*this); + for (size_t i=0 ; i::size() ; i++) { + rhs[i] += v[i]; + } + return rhs; + } + BASE& operator -= (const BASE& v) { + BASE& rhs = static_cast&>(*this); + for (size_t i=0 ; i::size() ; i++) { + rhs[i] -= v[i]; + } + return rhs; + } + + /* + * NOTE: the functions below ARE NOT member methods. They are friend functions + * with they definition inlined with their declaration. This makes these + * template functions available to the compiler when (and only when) this class + * is instantiated, at which point they're only templated on the 2nd parameter + * (the first one, BASE being known). + */ + + /* The operators below handle operation between vectors of the same side + * but of a different element type. + */ + template + friend inline + BASE PURE operator +(const BASE& lv, const BASE& rv) { + return BASE(lv) += rv; + } + template + friend inline + BASE PURE operator -(const BASE& lv, const BASE& rv) { + return BASE(lv) -= rv; + } + + /* The operators below (which are not templates once this class is instanced, + * i.e.: BASE is known) can be used for implicit conversion on both sides. + * These handle operations like "vector * scalar" and "scalar * vector" by + * letting the compiler implicitly convert a scalar to a vector (assuming + * the BASE allows it). + */ + friend inline + BASE PURE operator +(const BASE& lv, const BASE& rv) { + return BASE(lv) += rv; + } + friend inline + BASE PURE operator -(const BASE& lv, const BASE& rv) { + return BASE(lv) -= rv; + } +}; + +template class BASE, typename T> +class TVecProductOperators { +public: + /* compound assignment from a another vector of the same size but different + * element type. + */ + template + BASE& operator *= (const BASE& v) { + BASE& rhs = static_cast&>(*this); + for (size_t i=0 ; i::size() ; i++) { + rhs[i] *= v[i]; + } + return rhs; + } + template + BASE& operator /= (const BASE& v) { + BASE& rhs = static_cast&>(*this); + for (size_t i=0 ; i::size() ; i++) { + rhs[i] /= v[i]; + } + return rhs; + } + + /* compound assignment from a another vector of the same type. + * These operators can be used for implicit conversion and handle operations + * like "vector *= scalar" by letting the compiler implicitly convert a scalar + * to a vector (assuming the BASE allows it). + */ + BASE& operator *= (const BASE& v) { + BASE& rhs = static_cast&>(*this); + for (size_t i=0 ; i::size() ; i++) { + rhs[i] *= v[i]; + } + return rhs; + } + BASE& operator /= (const BASE& v) { + BASE& rhs = static_cast&>(*this); + for (size_t i=0 ; i::size() ; i++) { + rhs[i] /= v[i]; + } + return rhs; + } + + /* + * NOTE: the functions below ARE NOT member methods. They are friend functions + * with they definition inlined with their declaration. This makes these + * template functions available to the compiler when (and only when) this class + * is instantiated, at which point they're only templated on the 2nd parameter + * (the first one, BASE being known). + */ + + /* The operators below handle operation between vectors of the same side + * but of a different element type. + */ + template + friend inline + BASE PURE operator *(const BASE& lv, const BASE& rv) { + return BASE(lv) *= rv; + } + template + friend inline + BASE PURE operator /(const BASE& lv, const BASE& rv) { + return BASE(lv) /= rv; + } + + /* The operators below (which are not templates once this class is instanced, + * i.e.: BASE is known) can be used for implicit conversion on both sides. + * These handle operations like "vector * scalar" and "scalar * vector" by + * letting the compiler implicitly convert a scalar to a vector (assuming + * the BASE allows it). + */ + friend inline + BASE PURE operator *(const BASE& lv, const BASE& rv) { + return BASE(lv) *= rv; + } + friend inline + BASE PURE operator /(const BASE& lv, const BASE& rv) { + return BASE(lv) /= rv; + } +}; + +/* + * TVecUnaryOperators implements unary operators on a vector of type BASE. + * + * BASE only needs to implement operator[] and size(). + * By simply inheriting from TVecUnaryOperators BASE will automatically + * get all the functionality here. + * + * These operators are implemented as friend functions of TVecUnaryOperators + */ +template class BASE, typename T> +class TVecUnaryOperators { +public: + BASE& operator ++ () { + BASE& rhs = static_cast&>(*this); + for (size_t i=0 ; i::size() ; i++) { + ++rhs[i]; + } + return rhs; + } + BASE& operator -- () { + BASE& rhs = static_cast&>(*this); + for (size_t i=0 ; i::size() ; i++) { + --rhs[i]; + } + return rhs; + } + BASE operator - () const { + BASE r(BASE::NO_INIT); + BASE const& rv(static_cast const&>(*this)); + for (size_t i=0 ; i::size() ; i++) { + r[i] = -rv[i]; + } + return r; + } +}; + + +/* + * TVecComparisonOperators implements relational/comparison operators + * on a vector of type BASE. + * + * BASE only needs to implement operator[] and size(). + * By simply inheriting from TVecComparisonOperators BASE will automatically + * get all the functionality here. + */ +template class BASE, typename T> +class TVecComparisonOperators { +public: + /* + * NOTE: the functions below ARE NOT member methods. They are friend functions + * with they definition inlined with their declaration. This makes these + * template functions available to the compiler when (and only when) this class + * is instantiated, at which point they're only templated on the 2nd parameter + * (the first one, BASE being known). + */ + template + friend inline + bool PURE operator ==(const BASE& lv, const BASE& rv) { + for (size_t i = 0; i < BASE::size(); i++) + if (lv[i] != rv[i]) + return false; + return true; + } + + template + friend inline + bool PURE operator !=(const BASE& lv, const BASE& rv) { + return !operator ==(lv, rv); + } + + template + friend inline + bool PURE operator >(const BASE& lv, const BASE& rv) { + for (size_t i = 0; i < BASE::size(); i++) + if (lv[i] <= rv[i]) + return false; + return true; + } + + template + friend inline + bool PURE operator <=(const BASE& lv, const BASE& rv) { + return !(lv > rv); + } + + template + friend inline + bool PURE operator <(const BASE& lv, const BASE& rv) { + for (size_t i = 0; i < BASE::size(); i++) + if (lv[i] >= rv[i]) + return false; + return true; + } + + template + friend inline + bool PURE operator >=(const BASE& lv, const BASE& rv) { + return !(lv < rv); + } +}; + + +/* + * TVecFunctions implements functions on a vector of type BASE. + * + * BASE only needs to implement operator[] and size(). + * By simply inheriting from TVecFunctions BASE will automatically + * get all the functionality here. + */ +template class BASE, typename T> +class TVecFunctions { +public: + /* + * NOTE: the functions below ARE NOT member methods. They are friend functions + * with they definition inlined with their declaration. This makes these + * template functions available to the compiler when (and only when) this class + * is instantiated, at which point they're only templated on the 2nd parameter + * (the first one, BASE being known). + */ + template + friend inline + T PURE dot(const BASE& lv, const BASE& rv) { + T r(0); + for (size_t i = 0; i < BASE::size(); i++) + r += lv[i]*rv[i]; + return r; + } + + friend inline + T PURE length(const BASE& lv) { + return sqrt( dot(lv, lv) ); + } + + template + friend inline + T PURE distance(const BASE& lv, const BASE& rv) { + return length(rv - lv); + } + + friend inline + BASE PURE normalize(const BASE& lv) { + return lv * (1 / length(lv)); + } +}; + +#undef PURE + +// ------------------------------------------------------------------------------------- +}; // namespace android + + +#endif /* UI_TVEC_HELPERS_H */ diff --git a/phonelibs/android_frameworks_native/include/ui/UiConfig.h b/phonelibs/android_frameworks_native/include/ui/UiConfig.h new file mode 100644 index 00000000000000..fcf8ed5d6bcce1 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/UiConfig.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UI_CONFIG_H +#define ANDROID_UI_CONFIG_H + +#include + +namespace android { + +// Append the libui configuration details to configStr. +void appendUiConfigString(String8& configStr); + +}; // namespace android + +#endif /*ANDROID_UI_CONFIG_H*/ diff --git a/phonelibs/android_frameworks_native/include/ui/mat4.h b/phonelibs/android_frameworks_native/include/ui/mat4.h new file mode 100644 index 00000000000000..4fd1effd71a1e6 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/mat4.h @@ -0,0 +1,395 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_MAT4_H +#define UI_MAT4_H + +#include +#include + +#include +#include + +#define TMAT_IMPLEMENTATION +#include + +#define PURE __attribute__((pure)) + +namespace android { +// ------------------------------------------------------------------------------------- + +template +class tmat44 : public TVecUnaryOperators, + public TVecComparisonOperators, + public TVecAddOperators, + public TMatProductOperators, + public TMatSquareFunctions, + public TMatDebug +{ +public: + enum no_init { NO_INIT }; + typedef T value_type; + typedef T& reference; + typedef T const& const_reference; + typedef size_t size_type; + typedef tvec4 col_type; + typedef tvec4 row_type; + + // size of a column (i.e.: number of rows) + enum { COL_SIZE = col_type::SIZE }; + static inline size_t col_size() { return COL_SIZE; } + + // size of a row (i.e.: number of columns) + enum { ROW_SIZE = row_type::SIZE }; + static inline size_t row_size() { return ROW_SIZE; } + static inline size_t size() { return row_size(); } // for TVec*<> + +private: + + /* + * <-- N columns --> + * + * a00 a10 a20 ... aN0 ^ + * a01 a11 a21 ... aN1 | + * a02 a12 a22 ... aN2 M rows + * ... | + * a0M a1M a2M ... aNM v + * + * COL_SIZE = M + * ROW_SIZE = N + * m[0] = [a00 a01 a02 ... a01M] + */ + + col_type mValue[ROW_SIZE]; + +public: + // array access + inline col_type const& operator [] (size_t i) const { return mValue[i]; } + inline col_type& operator [] (size_t i) { return mValue[i]; } + + T const* asArray() const { return &mValue[0][0]; } + + // ----------------------------------------------------------------------- + // we don't provide copy-ctor and operator= on purpose + // because we want the compiler generated versions + + /* + * constructors + */ + + // leaves object uninitialized. use with caution. + explicit tmat44(no_init) { } + + // initialize to identity + tmat44(); + + // initialize to Identity*scalar. + template + explicit tmat44(U v); + + // sets the diagonal to the passed vector + template + explicit tmat44(const tvec4& rhs); + + // construct from another matrix of the same size + template + explicit tmat44(const tmat44& rhs); + + // construct from 4 column vectors + template + tmat44(const tvec4& v0, const tvec4& v1, const tvec4& v2, const tvec4& v3); + + // construct from 16 scalars + template < + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, + typename I, typename J, typename K, typename L, + typename M, typename N, typename O, typename P> + tmat44( A m00, B m01, C m02, D m03, + E m10, F m11, G m12, H m13, + I m20, J m21, K m22, L m23, + M m30, N m31, O m32, P m33); + + // construct from a C array + template + explicit tmat44(U const* rawArray); + + /* + * helpers + */ + + static tmat44 ortho(T left, T right, T bottom, T top, T near, T far); + + static tmat44 frustum(T left, T right, T bottom, T top, T near, T far); + + template + static tmat44 lookAt(const tvec3& eye, const tvec3& center, const tvec3& up); + + template + static tmat44 translate(const tvec4& t); + + template + static tmat44 scale(const tvec4& s); + + template + static tmat44 rotate(A radian, const tvec3& about); +}; + +// ---------------------------------------------------------------------------------------- +// Constructors +// ---------------------------------------------------------------------------------------- + +/* + * Since the matrix code could become pretty big quickly, we don't inline most + * operations. + */ + +template +tmat44::tmat44() { + mValue[0] = col_type(1,0,0,0); + mValue[1] = col_type(0,1,0,0); + mValue[2] = col_type(0,0,1,0); + mValue[3] = col_type(0,0,0,1); +} + +template +template +tmat44::tmat44(U v) { + mValue[0] = col_type(v,0,0,0); + mValue[1] = col_type(0,v,0,0); + mValue[2] = col_type(0,0,v,0); + mValue[3] = col_type(0,0,0,v); +} + +template +template +tmat44::tmat44(const tvec4& v) { + mValue[0] = col_type(v.x,0,0,0); + mValue[1] = col_type(0,v.y,0,0); + mValue[2] = col_type(0,0,v.z,0); + mValue[3] = col_type(0,0,0,v.w); +} + +// construct from 16 scalars +template +template < + typename A, typename B, typename C, typename D, + typename E, typename F, typename G, typename H, + typename I, typename J, typename K, typename L, + typename M, typename N, typename O, typename P> +tmat44::tmat44( A m00, B m01, C m02, D m03, + E m10, F m11, G m12, H m13, + I m20, J m21, K m22, L m23, + M m30, N m31, O m32, P m33) { + mValue[0] = col_type(m00, m01, m02, m03); + mValue[1] = col_type(m10, m11, m12, m13); + mValue[2] = col_type(m20, m21, m22, m23); + mValue[3] = col_type(m30, m31, m32, m33); +} + +template +template +tmat44::tmat44(const tmat44& rhs) { + for (size_t r=0 ; r +template +tmat44::tmat44(const tvec4& v0, const tvec4& v1, const tvec4& v2, const tvec4& v3) { + mValue[0] = v0; + mValue[1] = v1; + mValue[2] = v2; + mValue[3] = v3; +} + +template +template +tmat44::tmat44(U const* rawArray) { + for (size_t r=0 ; r +tmat44 tmat44::ortho(T left, T right, T bottom, T top, T near, T far) { + tmat44 m; + m[0][0] = 2 / (right - left); + m[1][1] = 2 / (top - bottom); + m[2][2] = -2 / (far - near); + m[3][0] = -(right + left) / (right - left); + m[3][1] = -(top + bottom) / (top - bottom); + m[3][2] = -(far + near) / (far - near); + return m; +} + +template +tmat44 tmat44::frustum(T left, T right, T bottom, T top, T near, T far) { + tmat44 m; + T A = (right + left) / (right - left); + T B = (top + bottom) / (top - bottom); + T C = (far + near) / (far - near); + T D = (2 * far * near) / (far - near); + m[0][0] = (2 * near) / (right - left); + m[1][1] = (2 * near) / (top - bottom); + m[2][0] = A; + m[2][1] = B; + m[2][2] = C; + m[2][3] =-1; + m[3][2] = D; + m[3][3] = 0; + return m; +} + +template +template +tmat44 tmat44::lookAt(const tvec3& eye, const tvec3& center, const tvec3& up) { + tvec3 L(normalize(center - eye)); + tvec3 S(normalize( cross(L, up) )); + tvec3 U(cross(S, L)); + return tmat44( + tvec4( S, 0), + tvec4( U, 0), + tvec4(-L, 0), + tvec4(-eye, 1)); +} + +template +template +tmat44 tmat44::translate(const tvec4& t) { + tmat44 r; + r[3] = t; + return r; +} + +template +template +tmat44 tmat44::scale(const tvec4& s) { + tmat44 r; + r[0][0] = s[0]; + r[1][1] = s[1]; + r[2][2] = s[2]; + r[3][3] = s[3]; + return r; +} + +template +template +tmat44 tmat44::rotate(A radian, const tvec3& about) { + tmat44 rotation; + T* r = const_cast(rotation.asArray()); + T c = cos(radian); + T s = sin(radian); + if (about.x==1 && about.y==0 && about.z==0) { + r[5] = c; r[10]= c; + r[6] = s; r[9] = -s; + } else if (about.x==0 && about.y==1 && about.z==0) { + r[0] = c; r[10]= c; + r[8] = s; r[2] = -s; + } else if (about.x==0 && about.y==0 && about.z==1) { + r[0] = c; r[5] = c; + r[1] = s; r[4] = -s; + } else { + tvec3 nabout = normalize(about); + B x = nabout.x; + B y = nabout.y; + B z = nabout.z; + T nc = 1 - c; + T xy = x * y; + T yz = y * z; + T zx = z * x; + T xs = x * s; + T ys = y * s; + T zs = z * s; + r[ 0] = x*x*nc + c; r[ 4] = xy*nc - zs; r[ 8] = zx*nc + ys; + r[ 1] = xy*nc + zs; r[ 5] = y*y*nc + c; r[ 9] = yz*nc - xs; + r[ 2] = zx*nc - ys; r[ 6] = yz*nc + xs; r[10] = z*z*nc + c; + } + return rotation; +} + +// ---------------------------------------------------------------------------------------- +// Arithmetic operators outside of class +// ---------------------------------------------------------------------------------------- + +/* We use non-friend functions here to prevent the compiler from using + * implicit conversions, for instance of a scalar to a vector. The result would + * not be what the caller expects. + * + * Also note that the order of the arguments in the inner loop is important since + * it determines the output type (only relevant when T != U). + */ + +// matrix * vector, result is a vector of the same type than the input vector +template +typename tmat44::col_type PURE operator *(const tmat44& lv, const tvec4& rv) { + typename tmat44::col_type result; + for (size_t r=0 ; r::row_size() ; r++) + result += rv[r]*lv[r]; + return result; +} + +// vector * matrix, result is a vector of the same type than the input vector +template +typename tmat44::row_type PURE operator *(const tvec4& rv, const tmat44& lv) { + typename tmat44::row_type result(tmat44::row_type::NO_INIT); + for (size_t r=0 ; r::row_size() ; r++) + result[r] = dot(rv, lv[r]); + return result; +} + +// matrix * scalar, result is a matrix of the same type than the input matrix +template +tmat44 PURE operator *(const tmat44& lv, U rv) { + tmat44 result(tmat44::NO_INIT); + for (size_t r=0 ; r::row_size() ; r++) + result[r] = lv[r]*rv; + return result; +} + +// scalar * matrix, result is a matrix of the same type than the input matrix +template +tmat44 PURE operator *(U rv, const tmat44& lv) { + tmat44 result(tmat44::NO_INIT); + for (size_t r=0 ; r::row_size() ; r++) + result[r] = lv[r]*rv; + return result; +} + +// ---------------------------------------------------------------------------------------- + +/* FIXME: this should go into TMatSquareFunctions<> but for some reason + * BASE::col_type is not accessible from there (???) + */ +template +typename tmat44::col_type PURE diag(const tmat44& m) { + return matrix::diag(m); +} + +// ---------------------------------------------------------------------------------------- + +typedef tmat44 mat4; + +// ---------------------------------------------------------------------------------------- +}; // namespace android + +#undef PURE + +#endif /* UI_MAT4_H */ diff --git a/phonelibs/android_frameworks_native/include/ui/vec2.h b/phonelibs/android_frameworks_native/include/ui/vec2.h new file mode 100644 index 00000000000000..c31d0e43e38934 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/vec2.h @@ -0,0 +1,91 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_VEC2_H +#define UI_VEC2_H + +#include +#include + +#define TVEC_IMPLEMENTATION +#include + +namespace android { +// ------------------------------------------------------------------------------------- + +template +class tvec2 : public TVecProductOperators, + public TVecAddOperators, + public TVecUnaryOperators, + public TVecComparisonOperators, + public TVecFunctions +{ +public: + enum no_init { NO_INIT }; + typedef T value_type; + typedef T& reference; + typedef T const& const_reference; + typedef size_t size_type; + + union { + struct { T x, y; }; + struct { T s, t; }; + struct { T r, g; }; + }; + + enum { SIZE = 2 }; + inline static size_type size() { return SIZE; } + + // array access + inline T const& operator [] (size_t i) const { return (&x)[i]; } + inline T& operator [] (size_t i) { return (&x)[i]; } + + // ----------------------------------------------------------------------- + // we don't provide copy-ctor and operator= on purpose + // because we want the compiler generated versions + + // constructors + + // leaves object uninitialized. use with caution. + explicit tvec2(no_init) { } + + // default constructor + tvec2() : x(0), y(0) { } + + // handles implicit conversion to a tvec4. must not be explicit. + template + tvec2(A v) : x(v), y(v) { } + + template + tvec2(A x, B y) : x(x), y(y) { } + + template + explicit tvec2(const tvec2& v) : x(v.x), y(v.y) { } + + template + tvec2(const Impersonator< tvec2 >& v) + : x(((const tvec2&)v).x), + y(((const tvec2&)v).y) { } +}; + +// ---------------------------------------------------------------------------------------- + +typedef tvec2 vec2; + +// ---------------------------------------------------------------------------------------- +}; // namespace android + +#endif /* UI_VEC4_H */ diff --git a/phonelibs/android_frameworks_native/include/ui/vec3.h b/phonelibs/android_frameworks_native/include/ui/vec3.h new file mode 100644 index 00000000000000..dde59a96fbe631 --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/vec3.h @@ -0,0 +1,113 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_VEC3_H +#define UI_VEC3_H + +#include +#include + +#include + +namespace android { +// ------------------------------------------------------------------------------------- + +template +class tvec3 : public TVecProductOperators, + public TVecAddOperators, + public TVecUnaryOperators, + public TVecComparisonOperators, + public TVecFunctions +{ +public: + enum no_init { NO_INIT }; + typedef T value_type; + typedef T& reference; + typedef T const& const_reference; + typedef size_t size_type; + + union { + struct { T x, y, z; }; + struct { T s, t, p; }; + struct { T r, g, b; }; + Impersonator< tvec2 > xy; + Impersonator< tvec2 > st; + Impersonator< tvec2 > rg; + }; + + enum { SIZE = 3 }; + inline static size_type size() { return SIZE; } + + // array access + inline T const& operator [] (size_t i) const { return (&x)[i]; } + inline T& operator [] (size_t i) { return (&x)[i]; } + + // ----------------------------------------------------------------------- + // we don't provide copy-ctor and operator= on purpose + // because we want the compiler generated versions + + // constructors + // leaves object uninitialized. use with caution. + explicit tvec3(no_init) { } + + // default constructor + tvec3() : x(0), y(0), z(0) { } + + // handles implicit conversion to a tvec4. must not be explicit. + template + tvec3(A v) : x(v), y(v), z(v) { } + + template + tvec3(A x, B y, C z) : x(x), y(y), z(z) { } + + template + tvec3(const tvec2& v, B z) : x(v.x), y(v.y), z(z) { } + + template + explicit tvec3(const tvec3& v) : x(v.x), y(v.y), z(v.z) { } + + template + tvec3(const Impersonator< tvec3 >& v) + : x(((const tvec3&)v).x), + y(((const tvec3&)v).y), + z(((const tvec3&)v).z) { } + + template + tvec3(const Impersonator< tvec2 >& v, B z) + : x(((const tvec2&)v).x), + y(((const tvec2&)v).y), + z(z) { } + + // cross product works only on vectors of size 3 + template + friend inline + tvec3 __attribute__((pure)) cross(const tvec3& u, const tvec3& v) { + return tvec3( + u.y*v.z - u.z*v.y, + u.z*v.x - u.x*v.z, + u.x*v.y - u.y*v.x); + } +}; + + +// ---------------------------------------------------------------------------------------- + +typedef tvec3 vec3; + +// ---------------------------------------------------------------------------------------- +}; // namespace android + +#endif /* UI_VEC4_H */ diff --git a/phonelibs/android_frameworks_native/include/ui/vec4.h b/phonelibs/android_frameworks_native/include/ui/vec4.h new file mode 100644 index 00000000000000..e03d331fb353ff --- /dev/null +++ b/phonelibs/android_frameworks_native/include/ui/vec4.h @@ -0,0 +1,118 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_VEC4_H +#define UI_VEC4_H + +#include +#include + +#include + +namespace android { +// ------------------------------------------------------------------------------------- + +template +class tvec4 : public TVecProductOperators, + public TVecAddOperators, + public TVecUnaryOperators, + public TVecComparisonOperators, + public TVecFunctions +{ +public: + enum no_init { NO_INIT }; + typedef T value_type; + typedef T& reference; + typedef T const& const_reference; + typedef size_t size_type; + + union { + struct { T x, y, z, w; }; + struct { T s, t, p, q; }; + struct { T r, g, b, a; }; + Impersonator< tvec2 > xy; + Impersonator< tvec2 > st; + Impersonator< tvec2 > rg; + Impersonator< tvec3 > xyz; + Impersonator< tvec3 > stp; + Impersonator< tvec3 > rgb; + }; + + enum { SIZE = 4 }; + inline static size_type size() { return SIZE; } + + // array access + inline T const& operator [] (size_t i) const { return (&x)[i]; } + inline T& operator [] (size_t i) { return (&x)[i]; } + + // ----------------------------------------------------------------------- + // we don't provide copy-ctor and operator= on purpose + // because we want the compiler generated versions + + // constructors + + // leaves object uninitialized. use with caution. + explicit tvec4(no_init) { } + + // default constructor + tvec4() : x(0), y(0), z(0), w(0) { } + + // handles implicit conversion to a tvec4. must not be explicit. + template + tvec4(A v) : x(v), y(v), z(v), w(v) { } + + template + tvec4(A x, B y, C z, D w) : x(x), y(y), z(z), w(w) { } + + template + tvec4(const tvec2& v, B z, C w) : x(v.x), y(v.y), z(z), w(w) { } + + template + tvec4(const tvec3& v, B w) : x(v.x), y(v.y), z(v.z), w(w) { } + + template + explicit tvec4(const tvec4& v) : x(v.x), y(v.y), z(v.z), w(v.w) { } + + template + tvec4(const Impersonator< tvec4 >& v) + : x(((const tvec4&)v).x), + y(((const tvec4&)v).y), + z(((const tvec4&)v).z), + w(((const tvec4&)v).w) { } + + template + tvec4(const Impersonator< tvec3 >& v, B w) + : x(((const tvec3&)v).x), + y(((const tvec3&)v).y), + z(((const tvec3&)v).z), + w(w) { } + + template + tvec4(const Impersonator< tvec2 >& v, B z, C w) + : x(((const tvec2&)v).x), + y(((const tvec2&)v).y), + z(z), + w(w) { } +}; + +// ---------------------------------------------------------------------------------------- + +typedef tvec4 vec4; + +// ---------------------------------------------------------------------------------------- +}; // namespace android + +#endif /* UI_VEC4_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/activity_recognition.h b/phonelibs/android_hardware_libhardware/include/hardware/activity_recognition.h new file mode 100644 index 00000000000000..8f9945982ded2a --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/activity_recognition.h @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Activity Recognition HAL. The goal is to provide low power, low latency, always-on activity + * recognition implemented in hardware (i.e. these activity recognition algorithms/classifers + * should NOT be run on the AP). By low power we mean that this may be activated 24/7 without + * impacting the battery drain speed (goal in order of 1mW including the power for sensors). + * This HAL does not specify the input sources that are used towards detecting these activities. + * It has one monitor interface which can be used to batch activities for always-on + * activity_recognition and if the latency is zero, the same interface can be used for low latency + * detection. + */ + +#ifndef ANDROID_ACTIVITY_RECOGNITION_INTERFACE_H +#define ANDROID_ACTIVITY_RECOGNITION_INTERFACE_H + +#include + +__BEGIN_DECLS + +#define ACTIVITY_RECOGNITION_HEADER_VERSION 1 +#define ACTIVITY_RECOGNITION_API_VERSION_0_1 HARDWARE_DEVICE_API_VERSION_2(0, 1, ACTIVITY_RECOGNITION_HEADER_VERSION) + +#define ACTIVITY_RECOGNITION_HARDWARE_MODULE_ID "activity_recognition" +#define ACTIVITY_RECOGNITION_HARDWARE_INTERFACE "activity_recognition_hw_if" + +/* + * Define types for various activities. Multiple activities may be active at the same time and + * sometimes none of these activities may be active. + * + * Each activity has a corresponding type. Only activities that are defined here should use + * android.activity_recognition.* prefix. OEM defined activities should not use this prefix. + * Activity type of OEM-defined activities should start with the reverse domain name of the entity + * defining the activity. + * + * When android introduces a new activity type that can potentially replace an OEM-defined activity + * type, the OEM must use the official activity type on versions of the HAL that support this new + * official activity type. + * + * Example (made up): Suppose Google's Glass team wants to detect nodding activity. + * - Such an activity is not officially supported in android L + * - Glass devices launching on L can implement a custom activity with + * type = "com.google.glass.nodding" + * - In M android release, if android decides to define ACITIVITY_TYPE_NODDING, those types + * should replace the Glass-team-specific types in all future launches. + * - When launching glass on the M release, Google should now use the official activity type + * - This way, other applications can use this activity. + */ + +#define ACTIVITY_TYPE_IN_VEHICLE "android.activity_recognition.in_vehicle" + +#define ACTIVITY_TYPE_ON_BICYCLE "android.activity_recognition.on_bicycle" + +#define ACTIVITY_TYPE_WALKING "android.activity_recognition.walking" + +#define ACTIVITY_TYPE_RUNNING "android.activity_recognition.running" + +#define ACTIVITY_TYPE_STILL "android.activity_recognition.still" + +#define ACTIVITY_TYPE_TILTING "android.activity_recognition.tilting" + +/* Values for activity_event.event_types. */ +enum { + /* + * A flush_complete event which indicates that a flush() has been successfully completed. This + * does not correspond to any activity/event. An event of this type should be added to the end + * of a batch FIFO and it indicates that all the events in the batch FIFO have been successfully + * reported to the framework. An event of this type should be generated only if flush() has been + * explicitly called and if the FIFO is empty at the time flush() is called it should trivially + * return a flush_complete_event to indicate that the FIFO is empty. + * + * A flush complete event should have the following parameters set. + * activity_event_t.event_type = ACTIVITY_EVENT_FLUSH_COMPLETE + * activity_event_t.activity = 0 + * activity_event_t.timestamp = 0 + * activity_event_t.reserved = 0 + * See (*flush)() for more details. + */ + ACTIVITY_EVENT_FLUSH_COMPLETE = 0, + + /* Signifies entering an activity. */ + ACTIVITY_EVENT_ENTER = 1, + + /* Signifies exiting an activity. */ + ACTIVITY_EVENT_EXIT = 2 +}; + +/* + * Each event is a separate activity with event_type indicating whether this activity has started + * or ended. Eg event: (event_type="enter", activity="ON_FOOT", timestamp) + */ +typedef struct activity_event { + /* One of the ACTIVITY_EVENT_* constants defined above. */ + uint32_t event_type; + + /* + * Index of the activity in the list returned by get_supported_activities_list. If this event + * is a flush complete event, this should be set to zero. + */ + uint32_t activity; + + /* Time at which the transition/event has occurred in nanoseconds using elapsedRealTimeNano. */ + int64_t timestamp; + + /* Set to zero. */ + int32_t reserved[4]; +} activity_event_t; + +typedef struct activity_recognition_module { + /** + * Common methods of the activity recognition module. This *must* be the first member of + * activity_recognition_module as users of this structure will cast a hw_module_t to + * activity_recognition_module pointer in contexts where it's known the hw_module_t + * references an activity_recognition_module. + */ + hw_module_t common; + + /* + * List of all activities supported by this module including OEM defined activities. Each + * activity is represented using a string defined above. Each string should be null terminated. + * The index of the activity in this array is used as a "handle" for enabling/disabling and + * event delivery. + * Return value is the size of this list. + */ + int (*get_supported_activities_list)(struct activity_recognition_module* module, + char const* const* *activity_list); +} activity_recognition_module_t; + +struct activity_recognition_device; + +typedef struct activity_recognition_callback_procs { + // Callback for activity_data. This is guaranteed to not invoke any HAL methods. + // Memory allocated for the events can be reused after this method returns. + // events - Array of activity_event_t s that are reported. + // count - size of the array. + void (*activity_callback)(const struct activity_recognition_callback_procs* procs, + const activity_event_t* events, int count); +} activity_recognition_callback_procs_t; + +typedef struct activity_recognition_device { + /** + * Common methods of the activity recognition device. This *must* be the first member of + * activity_recognition_device as users of this structure will cast a hw_device_t to + * activity_recognition_device pointer in contexts where it's known the hw_device_t + * references an activity_recognition_device. + */ + hw_device_t common; + + /* + * Sets the callback to invoke when there are events to report. This call overwrites the + * previously registered callback (if any). + */ + void (*register_activity_callback)(const struct activity_recognition_device* dev, + const activity_recognition_callback_procs_t* callback); + + /* + * Activates monitoring of activity transitions. Activities need not be reported as soon as they + * are detected. The detected activities are stored in a FIFO and reported in batches when the + * "max_batch_report_latency" expires or when the batch FIFO is full. The implementation should + * allow the AP to go into suspend mode while the activities are detected and stored in the + * batch FIFO. Whenever events need to be reported (like when the FIFO is full or when the + * max_batch_report_latency has expired for an activity, event pair), it should wake_up the AP + * so that no events are lost. Activities are stored as transitions and they are allowed to + * overlap with each other. Each (activity, event_type) pair can be activated or deactivated + * independently of the other. The HAL implementation needs to keep track of which pairs are + * currently active and needs to detect only those pairs. + * + * activity_handle - Index of the specific activity that needs to be detected in the list + * returned by get_supported_activities_list. + * event_type - Specific transition of the activity that needs to be detected. + * max_batch_report_latency_ns - a transition can be delayed by at most + * “max_batch_report_latency†nanoseconds. + * Return 0 on success, negative errno code otherwise. + */ + int (*enable_activity_event)(const struct activity_recognition_device* dev, + uint32_t activity_handle, uint32_t event_type, int64_t max_batch_report_latency_ns); + + /* + * Disables detection of a specific (activity, event_type) pair. + */ + int (*disable_activity_event)(const struct activity_recognition_device* dev, + uint32_t activity_handle, uint32_t event_type); + + /* + * Flush all the batch FIFOs. Report all the activities that were stored in the FIFO so far as + * if max_batch_report_latency had expired. This shouldn't change the latency in any way. Add + * a flush_complete_event to indicate the end of the FIFO after all events are delivered. + * See ACTIVITY_EVENT_FLUSH_COMPLETE for more details. + * Return 0 on success, negative errno code otherwise. + */ + int (*flush)(const struct activity_recognition_device* dev); + + // Must be set to NULL. + void (*reserved_procs[16 - 4])(void); +} activity_recognition_device_t; + +static inline int activity_recognition_open(const hw_module_t* module, + activity_recognition_device_t** device) { + return module->methods->open(module, + ACTIVITY_RECOGNITION_HARDWARE_INTERFACE, (hw_device_t**)device); +} + +static inline int activity_recognition_close(activity_recognition_device_t* device) { + return device->common.close(&device->common); +} + +__END_DECLS + +#endif // ANDROID_ACTIVITY_RECOGNITION_INTERFACE_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/audio.h b/phonelibs/android_hardware_libhardware/include/hardware/audio.h new file mode 100644 index 00000000000000..22e74197694920 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/audio.h @@ -0,0 +1,700 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_AUDIO_HAL_INTERFACE_H +#define ANDROID_AUDIO_HAL_INTERFACE_H + +#include +#include +#include +#include + +#include + +#include +#include +#include +#ifdef AUDIO_LISTEN_ENABLED +#include +#endif + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define AUDIO_HARDWARE_MODULE_ID "audio" + +/** + * Name of the audio devices to open + */ +#define AUDIO_HARDWARE_INTERFACE "audio_hw_if" + + +/* Use version 0.1 to be compatible with first generation of audio hw module with version_major + * hardcoded to 1. No audio module API change. + */ +#define AUDIO_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1) +#define AUDIO_MODULE_API_VERSION_CURRENT AUDIO_MODULE_API_VERSION_0_1 + +/* First generation of audio devices had version hardcoded to 0. all devices with versions < 1.0 + * will be considered of first generation API. + */ +#define AUDIO_DEVICE_API_VERSION_0_0 HARDWARE_DEVICE_API_VERSION(0, 0) +#define AUDIO_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0) +#define AUDIO_DEVICE_API_VERSION_2_0 HARDWARE_DEVICE_API_VERSION(2, 0) +#define AUDIO_DEVICE_API_VERSION_3_0 HARDWARE_DEVICE_API_VERSION(3, 0) +#define AUDIO_DEVICE_API_VERSION_CURRENT AUDIO_DEVICE_API_VERSION_3_0 +/* Minimal audio HAL version supported by the audio framework */ +#define AUDIO_DEVICE_API_VERSION_MIN AUDIO_DEVICE_API_VERSION_2_0 + +/** + * List of known audio HAL modules. This is the base name of the audio HAL + * library composed of the "audio." prefix, one of the base names below and + * a suffix specific to the device. + * e.g: audio.primary.goldfish.so or audio.a2dp.default.so + */ + +#define AUDIO_HARDWARE_MODULE_ID_PRIMARY "primary" +#define AUDIO_HARDWARE_MODULE_ID_A2DP "a2dp" +#define AUDIO_HARDWARE_MODULE_ID_USB "usb" +#define AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX "r_submix" +#define AUDIO_HARDWARE_MODULE_ID_CODEC_OFFLOAD "codec_offload" + +/**************************************/ + +/** + * standard audio parameters that the HAL may need to handle + */ + +/** + * audio device parameters + */ + +/* BT SCO Noise Reduction + Echo Cancellation parameters */ +#define AUDIO_PARAMETER_KEY_BT_NREC "bt_headset_nrec" +#define AUDIO_PARAMETER_VALUE_ON "on" +#define AUDIO_PARAMETER_VALUE_OFF "off" + +/* TTY mode selection */ +#define AUDIO_PARAMETER_KEY_TTY_MODE "tty_mode" +#define AUDIO_PARAMETER_VALUE_TTY_OFF "tty_off" +#define AUDIO_PARAMETER_VALUE_TTY_VCO "tty_vco" +#define AUDIO_PARAMETER_VALUE_TTY_HCO "tty_hco" +#define AUDIO_PARAMETER_VALUE_TTY_FULL "tty_full" + +/* Hearing Aid Compatibility - Telecoil (HAC-T) mode on/off + Strings must be in sync with CallFeaturesSetting.java */ +#define AUDIO_PARAMETER_KEY_HAC "HACSetting" +#define AUDIO_PARAMETER_VALUE_HAC_ON "ON" +#define AUDIO_PARAMETER_VALUE_HAC_OFF "OFF" + +/* A2DP sink address set by framework */ +#define AUDIO_PARAMETER_A2DP_SINK_ADDRESS "a2dp_sink_address" + +/* A2DP source address set by framework */ +#define AUDIO_PARAMETER_A2DP_SOURCE_ADDRESS "a2dp_source_address" + +/* Screen state */ +#define AUDIO_PARAMETER_KEY_SCREEN_STATE "screen_state" + +/* Bluetooth SCO wideband */ +#define AUDIO_PARAMETER_KEY_BT_SCO_WB "bt_wbs" + +/* Get a new HW synchronization source identifier. + * Return a valid source (positive integer) or AUDIO_HW_SYNC_INVALID if an error occurs + * or no HW sync is available. */ +#define AUDIO_PARAMETER_HW_AV_SYNC "hw_av_sync" + +/* Device state*/ +#define AUDIO_PARAMETER_KEY_DEV_SHUTDOWN "dev_shutdown" + +/** + * audio stream parameters + */ + +#define AUDIO_PARAMETER_STREAM_ROUTING "routing" /* audio_devices_t */ +#define AUDIO_PARAMETER_STREAM_FORMAT "format" /* audio_format_t */ +#define AUDIO_PARAMETER_STREAM_CHANNELS "channels" /* audio_channel_mask_t */ +#define AUDIO_PARAMETER_STREAM_FRAME_COUNT "frame_count" /* size_t */ +#define AUDIO_PARAMETER_STREAM_INPUT_SOURCE "input_source" /* audio_source_t */ +#define AUDIO_PARAMETER_STREAM_SAMPLING_RATE "sampling_rate" /* uint32_t */ + +#define AUDIO_PARAMETER_DEVICE_CONNECT "connect" /* audio_devices_t */ +#define AUDIO_PARAMETER_DEVICE_DISCONNECT "disconnect" /* audio_devices_t */ + +/* Query supported formats. The response is a '|' separated list of strings from + * audio_format_t enum e.g: "sup_formats=AUDIO_FORMAT_PCM_16_BIT" */ +#define AUDIO_PARAMETER_STREAM_SUP_FORMATS "sup_formats" +/* Query supported channel masks. The response is a '|' separated list of strings from + * audio_channel_mask_t enum e.g: "sup_channels=AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_MONO" */ +#define AUDIO_PARAMETER_STREAM_SUP_CHANNELS "sup_channels" +/* Query supported sampling rates. The response is a '|' separated list of integer values e.g: + * "sup_sampling_rates=44100|48000" */ +#define AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES "sup_sampling_rates" + +/* Set the HW synchronization source for an output stream. */ +#define AUDIO_PARAMETER_STREAM_HW_AV_SYNC "hw_av_sync" + +/** + * audio codec parameters + */ + +#define AUDIO_OFFLOAD_CODEC_PARAMS "music_offload_codec_param" +#define AUDIO_OFFLOAD_CODEC_BIT_PER_SAMPLE "music_offload_bit_per_sample" +#define AUDIO_OFFLOAD_CODEC_BIT_RATE "music_offload_bit_rate" +#define AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE "music_offload_avg_bit_rate" +#define AUDIO_OFFLOAD_CODEC_ID "music_offload_codec_id" +#define AUDIO_OFFLOAD_CODEC_BLOCK_ALIGN "music_offload_block_align" +#define AUDIO_OFFLOAD_CODEC_SAMPLE_RATE "music_offload_sample_rate" +#define AUDIO_OFFLOAD_CODEC_ENCODE_OPTION "music_offload_encode_option" +#define AUDIO_OFFLOAD_CODEC_NUM_CHANNEL "music_offload_num_channels" +#define AUDIO_OFFLOAD_CODEC_DOWN_SAMPLING "music_offload_down_sampling" +#define AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES "delay_samples" +#define AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES "padding_samples" + +/**************************************/ + +/* common audio stream parameters and operations */ +struct audio_stream { + + /** + * Return the sampling rate in Hz - eg. 44100. + */ + uint32_t (*get_sample_rate)(const struct audio_stream *stream); + + /* currently unused - use set_parameters with key + * AUDIO_PARAMETER_STREAM_SAMPLING_RATE + */ + int (*set_sample_rate)(struct audio_stream *stream, uint32_t rate); + + /** + * Return size of input/output buffer in bytes for this stream - eg. 4800. + * It should be a multiple of the frame size. See also get_input_buffer_size. + */ + size_t (*get_buffer_size)(const struct audio_stream *stream); + + /** + * Return the channel mask - + * e.g. AUDIO_CHANNEL_OUT_STEREO or AUDIO_CHANNEL_IN_STEREO + */ + audio_channel_mask_t (*get_channels)(const struct audio_stream *stream); + + /** + * Return the audio format - e.g. AUDIO_FORMAT_PCM_16_BIT + */ + audio_format_t (*get_format)(const struct audio_stream *stream); + + /* currently unused - use set_parameters with key + * AUDIO_PARAMETER_STREAM_FORMAT + */ + int (*set_format)(struct audio_stream *stream, audio_format_t format); + + /** + * Put the audio hardware input/output into standby mode. + * Driver should exit from standby mode at the next I/O operation. + * Returns 0 on success and <0 on failure. + */ + int (*standby)(struct audio_stream *stream); + + /** dump the state of the audio input/output device */ + int (*dump)(const struct audio_stream *stream, int fd); + + /** Return the set of device(s) which this stream is connected to */ + audio_devices_t (*get_device)(const struct audio_stream *stream); + + /** + * Currently unused - set_device() corresponds to set_parameters() with key + * AUDIO_PARAMETER_STREAM_ROUTING for both input and output. + * AUDIO_PARAMETER_STREAM_INPUT_SOURCE is an additional information used by + * input streams only. + */ + int (*set_device)(struct audio_stream *stream, audio_devices_t device); + + /** + * set/get audio stream parameters. The function accepts a list of + * parameter key value pairs in the form: key1=value1;key2=value2;... + * + * Some keys are reserved for standard parameters (See AudioParameter class) + * + * If the implementation does not accept a parameter change while + * the output is active but the parameter is acceptable otherwise, it must + * return -ENOSYS. + * + * The audio flinger will put the stream in standby and then change the + * parameter value. + */ + int (*set_parameters)(struct audio_stream *stream, const char *kv_pairs); + + /* + * Returns a pointer to a heap allocated string. The caller is responsible + * for freeing the memory for it using free(). + */ + char * (*get_parameters)(const struct audio_stream *stream, + const char *keys); + int (*add_audio_effect)(const struct audio_stream *stream, + effect_handle_t effect); + int (*remove_audio_effect)(const struct audio_stream *stream, + effect_handle_t effect); +}; +typedef struct audio_stream audio_stream_t; + +/* type of asynchronous write callback events. Mutually exclusive */ +typedef enum { + STREAM_CBK_EVENT_WRITE_READY, /* non blocking write completed */ + STREAM_CBK_EVENT_DRAIN_READY /* drain completed */ +} stream_callback_event_t; + +typedef int (*stream_callback_t)(stream_callback_event_t event, void *param, void *cookie); + +/* type of drain requested to audio_stream_out->drain(). Mutually exclusive */ +typedef enum { + AUDIO_DRAIN_ALL, /* drain() returns when all data has been played */ + AUDIO_DRAIN_EARLY_NOTIFY /* drain() returns a short time before all data + from the current track has been played to + give time for gapless track switch */ +} audio_drain_type_t; + +/** + * audio_stream_out is the abstraction interface for the audio output hardware. + * + * It provides information about various properties of the audio output + * hardware driver. + */ + +struct audio_stream_out { + /** + * Common methods of the audio stream out. This *must* be the first member of audio_stream_out + * as users of this structure will cast a audio_stream to audio_stream_out pointer in contexts + * where it's known the audio_stream references an audio_stream_out. + */ + struct audio_stream common; + + /** + * Return the audio hardware driver estimated latency in milliseconds. + */ + uint32_t (*get_latency)(const struct audio_stream_out *stream); + + /** + * Use this method in situations where audio mixing is done in the + * hardware. This method serves as a direct interface with hardware, + * allowing you to directly set the volume as apposed to via the framework. + * This method might produce multiple PCM outputs or hardware accelerated + * codecs, such as MP3 or AAC. + */ + int (*set_volume)(struct audio_stream_out *stream, float left, float right); + + /** + * Write audio buffer to driver. Returns number of bytes written, or a + * negative status_t. If at least one frame was written successfully prior to the error, + * it is suggested that the driver return that successful (short) byte count + * and then return an error in the subsequent call. + * + * If set_callback() has previously been called to enable non-blocking mode + * the write() is not allowed to block. It must write only the number of + * bytes that currently fit in the driver/hardware buffer and then return + * this byte count. If this is less than the requested write size the + * callback function must be called when more space is available in the + * driver/hardware buffer. + */ + ssize_t (*write)(struct audio_stream_out *stream, const void* buffer, + size_t bytes); + + /* return the number of audio frames written by the audio dsp to DAC since + * the output has exited standby + */ + int (*get_render_position)(const struct audio_stream_out *stream, + uint32_t *dsp_frames); + + /** + * get the local time at which the next write to the audio driver will be presented. + * The units are microseconds, where the epoch is decided by the local audio HAL. + */ + int (*get_next_write_timestamp)(const struct audio_stream_out *stream, + int64_t *timestamp); + + /** + * set the callback function for notifying completion of non-blocking + * write and drain. + * Calling this function implies that all future write() and drain() + * must be non-blocking and use the callback to signal completion. + */ + int (*set_callback)(struct audio_stream_out *stream, + stream_callback_t callback, void *cookie); + + /** + * Notifies to the audio driver to stop playback however the queued buffers are + * retained by the hardware. Useful for implementing pause/resume. Empty implementation + * if not supported however should be implemented for hardware with non-trivial + * latency. In the pause state audio hardware could still be using power. User may + * consider calling suspend after a timeout. + * + * Implementation of this function is mandatory for offloaded playback. + */ + int (*pause)(struct audio_stream_out* stream); + + /** + * Notifies to the audio driver to resume playback following a pause. + * Returns error if called without matching pause. + * + * Implementation of this function is mandatory for offloaded playback. + */ + int (*resume)(struct audio_stream_out* stream); + + /** + * Requests notification when data buffered by the driver/hardware has + * been played. If set_callback() has previously been called to enable + * non-blocking mode, the drain() must not block, instead it should return + * quickly and completion of the drain is notified through the callback. + * If set_callback() has not been called, the drain() must block until + * completion. + * If type==AUDIO_DRAIN_ALL, the drain completes when all previously written + * data has been played. + * If type==AUDIO_DRAIN_EARLY_NOTIFY, the drain completes shortly before all + * data for the current track has played to allow time for the framework + * to perform a gapless track switch. + * + * Drain must return immediately on stop() and flush() call + * + * Implementation of this function is mandatory for offloaded playback. + */ + int (*drain)(struct audio_stream_out* stream, audio_drain_type_t type ); + + /** + * Notifies to the audio driver to flush the queued data. Stream must already + * be paused before calling flush(). + * + * Implementation of this function is mandatory for offloaded playback. + */ + int (*flush)(struct audio_stream_out* stream); + + /** + * Return a recent count of the number of audio frames presented to an external observer. + * This excludes frames which have been written but are still in the pipeline. + * The count is not reset to zero when output enters standby. + * Also returns the value of CLOCK_MONOTONIC as of this presentation count. + * The returned count is expected to be 'recent', + * but does not need to be the most recent possible value. + * However, the associated time should correspond to whatever count is returned. + * Example: assume that N+M frames have been presented, where M is a 'small' number. + * Then it is permissible to return N instead of N+M, + * and the timestamp should correspond to N rather than N+M. + * The terms 'recent' and 'small' are not defined. + * They reflect the quality of the implementation. + * + * 3.0 and higher only. + */ + int (*get_presentation_position)(const struct audio_stream_out *stream, + uint64_t *frames, struct timespec *timestamp); + +}; +typedef struct audio_stream_out audio_stream_out_t; + +struct audio_stream_in { + /** + * Common methods of the audio stream in. This *must* be the first member of audio_stream_in + * as users of this structure will cast a audio_stream to audio_stream_in pointer in contexts + * where it's known the audio_stream references an audio_stream_in. + */ + struct audio_stream common; + + /** set the input gain for the audio driver. This method is for + * for future use */ + int (*set_gain)(struct audio_stream_in *stream, float gain); + + /** Read audio buffer in from audio driver. Returns number of bytes read, or a + * negative status_t. If at least one frame was read prior to the error, + * read should return that byte count and then return an error in the subsequent call. + */ + ssize_t (*read)(struct audio_stream_in *stream, void* buffer, + size_t bytes); + + /** + * Return the amount of input frames lost in the audio driver since the + * last call of this function. + * Audio driver is expected to reset the value to 0 and restart counting + * upon returning the current value by this function call. + * Such loss typically occurs when the user space process is blocked + * longer than the capacity of audio driver buffers. + * + * Unit: the number of input audio frames + */ + uint32_t (*get_input_frames_lost)(struct audio_stream_in *stream); +}; +typedef struct audio_stream_in audio_stream_in_t; + +/** + * return the frame size (number of bytes per sample). + * + * Deprecated: use audio_stream_out_frame_size() or audio_stream_in_frame_size() instead. + */ +__attribute__((__deprecated__)) +static inline size_t audio_stream_frame_size(const struct audio_stream *s) +{ + size_t chan_samp_sz; + audio_format_t format = s->get_format(s); + + if (audio_is_linear_pcm(format)) { + chan_samp_sz = audio_bytes_per_sample(format); + return popcount(s->get_channels(s)) * chan_samp_sz; + } + + return sizeof(int8_t); +} + +/** + * return the frame size (number of bytes per sample) of an output stream. + */ +static inline size_t audio_stream_out_frame_size(const struct audio_stream_out *s) +{ + size_t chan_samp_sz; + audio_format_t format = s->common.get_format(&s->common); + + if (audio_is_linear_pcm(format)) { + chan_samp_sz = audio_bytes_per_sample(format); + return audio_channel_count_from_out_mask(s->common.get_channels(&s->common)) * chan_samp_sz; + } + + return sizeof(int8_t); +} + +/** + * return the frame size (number of bytes per sample) of an input stream. + */ +static inline size_t audio_stream_in_frame_size(const struct audio_stream_in *s) +{ + size_t chan_samp_sz; + audio_format_t format = s->common.get_format(&s->common); + + if (audio_is_linear_pcm(format)) { + chan_samp_sz = audio_bytes_per_sample(format); + return audio_channel_count_from_in_mask(s->common.get_channels(&s->common)) * chan_samp_sz; + } + + return sizeof(int8_t); +} + +/**********************************************************************/ + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +struct audio_module { + struct hw_module_t common; +}; + +struct audio_hw_device { + /** + * Common methods of the audio device. This *must* be the first member of audio_hw_device + * as users of this structure will cast a hw_device_t to audio_hw_device pointer in contexts + * where it's known the hw_device_t references an audio_hw_device. + */ + struct hw_device_t common; + + /** + * used by audio flinger to enumerate what devices are supported by + * each audio_hw_device implementation. + * + * Return value is a bitmask of 1 or more values of audio_devices_t + * + * NOTE: audio HAL implementations starting with + * AUDIO_DEVICE_API_VERSION_2_0 do not implement this function. + * All supported devices should be listed in audio_policy.conf + * file and the audio policy manager must choose the appropriate + * audio module based on information in this file. + */ + uint32_t (*get_supported_devices)(const struct audio_hw_device *dev); + + /** + * check to see if the audio hardware interface has been initialized. + * returns 0 on success, -ENODEV on failure. + */ + int (*init_check)(const struct audio_hw_device *dev); + + /** set the audio volume of a voice call. Range is between 0.0 and 1.0 */ + int (*set_voice_volume)(struct audio_hw_device *dev, float volume); + + /** + * set the audio volume for all audio activities other than voice call. + * Range between 0.0 and 1.0. If any value other than 0 is returned, + * the software mixer will emulate this capability. + */ + int (*set_master_volume)(struct audio_hw_device *dev, float volume); + + /** + * Get the current master volume value for the HAL, if the HAL supports + * master volume control. AudioFlinger will query this value from the + * primary audio HAL when the service starts and use the value for setting + * the initial master volume across all HALs. HALs which do not support + * this method may leave it set to NULL. + */ + int (*get_master_volume)(struct audio_hw_device *dev, float *volume); + + /** + * set_mode is called when the audio mode changes. AUDIO_MODE_NORMAL mode + * is for standard audio playback, AUDIO_MODE_RINGTONE when a ringtone is + * playing, and AUDIO_MODE_IN_CALL when a call is in progress. + */ + int (*set_mode)(struct audio_hw_device *dev, audio_mode_t mode); + + /* mic mute */ + int (*set_mic_mute)(struct audio_hw_device *dev, bool state); + int (*get_mic_mute)(const struct audio_hw_device *dev, bool *state); + + /* set/get global audio parameters */ + int (*set_parameters)(struct audio_hw_device *dev, const char *kv_pairs); + + /* + * Returns a pointer to a heap allocated string. The caller is responsible + * for freeing the memory for it using free(). + */ + char * (*get_parameters)(const struct audio_hw_device *dev, + const char *keys); + + /* Returns audio input buffer size according to parameters passed or + * 0 if one of the parameters is not supported. + * See also get_buffer_size which is for a particular stream. + */ + size_t (*get_input_buffer_size)(const struct audio_hw_device *dev, + const struct audio_config *config); + + /** This method creates and opens the audio hardware output stream. + * The "address" parameter qualifies the "devices" audio device type if needed. + * The format format depends on the device type: + * - Bluetooth devices use the MAC address of the device in the form "00:11:22:AA:BB:CC" + * - USB devices use the ALSA card and device numbers in the form "card=X;device=Y" + * - Other devices may use a number or any other string. + */ + + int (*open_output_stream)(struct audio_hw_device *dev, + audio_io_handle_t handle, + audio_devices_t devices, + audio_output_flags_t flags, + struct audio_config *config, + struct audio_stream_out **stream_out, + const char *address); + + void (*close_output_stream)(struct audio_hw_device *dev, + struct audio_stream_out* stream_out); + + /** This method creates and opens the audio hardware input stream */ + int (*open_input_stream)(struct audio_hw_device *dev, + audio_io_handle_t handle, + audio_devices_t devices, + struct audio_config *config, + struct audio_stream_in **stream_in, + audio_input_flags_t flags, + const char *address, + audio_source_t source); + + void (*close_input_stream)(struct audio_hw_device *dev, + struct audio_stream_in *stream_in); + + /** This method dumps the state of the audio hardware */ + int (*dump)(const struct audio_hw_device *dev, int fd); + + /** + * set the audio mute status for all audio activities. If any value other + * than 0 is returned, the software mixer will emulate this capability. + */ + int (*set_master_mute)(struct audio_hw_device *dev, bool mute); + + /** + * Get the current master mute status for the HAL, if the HAL supports + * master mute control. AudioFlinger will query this value from the primary + * audio HAL when the service starts and use the value for setting the + * initial master mute across all HALs. HALs which do not support this + * method may leave it set to NULL. + */ + int (*get_master_mute)(struct audio_hw_device *dev, bool *mute); + + /** + * Routing control + */ + + /* Creates an audio patch between several source and sink ports. + * The handle is allocated by the HAL and should be unique for this + * audio HAL module. */ + int (*create_audio_patch)(struct audio_hw_device *dev, + unsigned int num_sources, + const struct audio_port_config *sources, + unsigned int num_sinks, + const struct audio_port_config *sinks, + audio_patch_handle_t *handle); + + /* Release an audio patch */ + int (*release_audio_patch)(struct audio_hw_device *dev, + audio_patch_handle_t handle); + + /* Fills the list of supported attributes for a given audio port. + * As input, "port" contains the information (type, role, address etc...) + * needed by the HAL to identify the port. + * As output, "port" contains possible attributes (sampling rates, formats, + * channel masks, gain controllers...) for this port. + */ + int (*get_audio_port)(struct audio_hw_device *dev, + struct audio_port *port); + + /* Set audio port configuration */ + int (*set_audio_port_config)(struct audio_hw_device *dev, + const struct audio_port_config *config); + +#ifdef AUDIO_LISTEN_ENABLED + /** This method creates the listen session and returns handle */ + int (*open_listen_session)(struct audio_hw_device *dev, + listen_open_params_t *params, + struct listen_session** handle); + + /** This method closes the listen session */ + int (*close_listen_session)(struct audio_hw_device *dev, + struct listen_session* handle); + + /** This method sets the mad observer callback */ + int (*set_mad_observer)(struct audio_hw_device *dev, + listen_callback_t cb_func); + + /** + * This method is used for setting listen hal specfic parameters. + * If multiple paramets are set in one call and setting any one of them + * fails it will return failure. + */ + int (*listen_set_parameters)(struct audio_hw_device *dev, + const char *kv_pairs); +#endif +}; +typedef struct audio_hw_device audio_hw_device_t; + +/** convenience API for opening and closing a supported device */ + +static inline int audio_hw_device_open(const struct hw_module_t* module, + struct audio_hw_device** device) +{ + return module->methods->open(module, AUDIO_HARDWARE_INTERFACE, + (struct hw_device_t**)device); +} + +static inline int audio_hw_device_close(struct audio_hw_device* device) +{ + return device->common.close(&device->common); +} + + +__END_DECLS + +#endif // ANDROID_AUDIO_INTERFACE_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/audio_alsaops.h b/phonelibs/android_hardware_libhardware/include/hardware/audio_alsaops.h new file mode 100644 index 00000000000000..0d266ff554b2b5 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/audio_alsaops.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* This file contains shared utility functions to handle the tinyalsa + * implementation for Android internal audio, generally in the hardware layer. + * Some routines may log a fatal error on failure, as noted. + */ + +#ifndef ANDROID_AUDIO_ALSAOPS_H +#define ANDROID_AUDIO_ALSAOPS_H + +#include +#include +#include + +__BEGIN_DECLS + +/* Converts audio_format to pcm_format. + * Parameters: + * format the audio_format_t to convert + * + * Logs a fatal error if format is not a valid convertible audio_format_t. + */ +static inline enum pcm_format pcm_format_from_audio_format(audio_format_t format) +{ + switch (format) { +#ifdef HAVE_BIG_ENDIAN + case AUDIO_FORMAT_PCM_16_BIT: + return PCM_FORMAT_S16_BE; + case AUDIO_FORMAT_PCM_24_BIT_PACKED: + return PCM_FORMAT_S24_3BE; + case AUDIO_FORMAT_PCM_32_BIT: + return PCM_FORMAT_S32_BE; + case AUDIO_FORMAT_PCM_8_24_BIT: + return PCM_FORMAT_S24_BE; +#else + case AUDIO_FORMAT_PCM_16_BIT: + return PCM_FORMAT_S16_LE; + case AUDIO_FORMAT_PCM_24_BIT_PACKED: + return PCM_FORMAT_S24_3LE; + case AUDIO_FORMAT_PCM_32_BIT: + return PCM_FORMAT_S32_LE; + case AUDIO_FORMAT_PCM_8_24_BIT: + return PCM_FORMAT_S24_LE; +#endif + case AUDIO_FORMAT_PCM_FLOAT: /* there is no equivalent for float */ + default: + LOG_ALWAYS_FATAL("pcm_format_from_audio_format: invalid audio format %#x", format); + return 0; + } +} + +/* Converts pcm_format to audio_format. + * Parameters: + * format the pcm_format to convert + * + * Logs a fatal error if format is not a valid convertible pcm_format. + */ +static inline audio_format_t audio_format_from_pcm_format(enum pcm_format format) +{ + switch (format) { +#ifdef HAVE_BIG_ENDIAN + case PCM_FORMAT_S16_BE: + return AUDIO_FORMAT_PCM_16_BIT; + case PCM_FORMAT_S24_3BE: + return AUDIO_FORMAT_PCM_24_BIT_PACKED; + case PCM_FORMAT_S24_BE: + return AUDIO_FORMAT_PCM_8_24_BIT; + case PCM_FORMAT_S32_BE: + return AUDIO_FORMAT_PCM_32_BIT; +#else + case PCM_FORMAT_S16_LE: + return AUDIO_FORMAT_PCM_16_BIT; + case PCM_FORMAT_S24_3LE: + return AUDIO_FORMAT_PCM_24_BIT_PACKED; + case PCM_FORMAT_S24_LE: + return AUDIO_FORMAT_PCM_8_24_BIT; + case PCM_FORMAT_S32_LE: + return AUDIO_FORMAT_PCM_32_BIT; +#endif + default: + LOG_ALWAYS_FATAL("audio_format_from_pcm_format: invalid pcm format %#x", format); + return 0; + } +} + +__END_DECLS + +#endif /* ANDROID_AUDIO_ALSAOPS_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/audio_amplifier.h b/phonelibs/android_hardware_libhardware/include/hardware/audio_amplifier.h new file mode 100644 index 00000000000000..e3477d52ad572b --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/audio_amplifier.h @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2015, The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_AUDIO_AMPLIFIER_INTERFACE_H +#define CM_AUDIO_AMPLIFIER_INTERFACE_H + +#include +#include +#include + +#include +#include + +#include + +__BEGIN_DECLS + +#define AMPLIFIER_HARDWARE_MODULE_ID "audio_amplifier" + +#define AMPLIFIER_HARDWARE_INTERFACE "audio_amplifier_hw_if" + +#define AMPLIFIER_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1) + +#define AMPLIFIER_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0) +#define AMPLIFIER_DEVICE_API_VERSION_2_0 HARDWARE_DEVICE_API_VERSION(2, 0) +#define AMPLIFIER_DEVICE_API_VERSION_CURRENT AMPLIFIER_DEVICE_API_VERSION_2_0 + +struct str_parms; + +typedef struct amplifier_device { + /** + * Common methods of the amplifier device. This *must* be the first member + * of amplifier_device as users of this structure will cast a hw_device_t + * to amplifier_device pointer in contexts where it's known + * the hw_device_t references a amplifier_device. + */ + struct hw_device_t common; + + /** + * Notify amplifier device of current input devices + * + * This function should handle only input devices. + */ + int (*set_input_devices)(struct amplifier_device *device, uint32_t devices); + + /** + * Notify amplifier device of current output devices + * + * This function should handle only output devices. + */ + int (*set_output_devices)(struct amplifier_device *device, uint32_t devices); + + /** + * Notify amplifier device of output device enable/disable + * + * This function should handle only output devices. + */ + int (*enable_output_devices)(struct amplifier_device *device, + uint32_t devices, bool enable); + + /** + * Notify amplifier device of input device enable/disable + * + * This function should handle only input devices. + */ + int (*enable_input_devices)(struct amplifier_device *device, + uint32_t devices, bool enable); + + /** + * Notify amplifier device about current audio mode + */ + int (*set_mode)(struct amplifier_device *device, audio_mode_t mode); + + /** + * Notify amplifier device that an output stream has started + */ + int (*output_stream_start)(struct amplifier_device *device, + struct audio_stream_out *stream, bool offload); + + /** + * Notify amplifier device that an input stream has started + */ + int (*input_stream_start)(struct amplifier_device *device, + struct audio_stream_in *stream); + + /** + * Notify amplifier device that an output stream has stopped + */ + int (*output_stream_standby)(struct amplifier_device *device, + struct audio_stream_out *stream); + + /** + * Notify amplifier device that an input stream has stopped + */ + int (*input_stream_standby)(struct amplifier_device *device, + struct audio_stream_in *stream); + + /** + * set/get output audio device parameters. + */ + int (*set_parameters)(struct amplifier_device *device, + struct str_parms *parms); +} amplifier_device_t; + +typedef struct amplifier_module { + /** + * Common methods of the amplifier module. This *must* be the first member + * of amplifier_module as users of this structure will cast a hw_module_t + * to amplifier_module pointer in contexts where it's known + * the hw_module_t references a amplifier_module. + */ + struct hw_module_t common; +} amplifier_module_t; + +/** convenience API for opening and closing a supported device */ + +static inline int amplifier_device_open(const struct hw_module_t *module, + struct amplifier_device **device) +{ + return module->methods->open(module, AMPLIFIER_HARDWARE_INTERFACE, + (struct hw_device_t **) device); +} + +static inline int amplifier_device_close(struct amplifier_device *device) +{ + return device->common.close(&device->common); +} + +__END_DECLS + +#endif // CM_AUDIO_AMPLIFIER_INTERFACE_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/audio_effect.h b/phonelibs/android_hardware_libhardware/include/hardware/audio_effect.h new file mode 100644 index 00000000000000..41cd2e6146adc4 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/audio_effect.h @@ -0,0 +1,1014 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_AUDIO_EFFECT_H +#define ANDROID_AUDIO_EFFECT_H + +#include +#include +#include +#include +#include + +#include + +#include + + +__BEGIN_DECLS + + +///////////////////////////////////////////////// +// Common Definitions +///////////////////////////////////////////////// + +// +//--- Effect descriptor structure effect_descriptor_t +// + +// Unique effect ID (can be generated from the following site: +// http://www.itu.int/ITU-T/asn1/uuid.html) +// This format is used for both "type" and "uuid" fields of the effect descriptor structure. +// - When used for effect type and the engine is implementing and effect corresponding to a standard +// OpenSL ES interface, this ID must be the one defined in OpenSLES_IID.h for that interface. +// - When used as uuid, it should be a unique UUID for this particular implementation. +typedef struct effect_uuid_s { + uint32_t timeLow; + uint16_t timeMid; + uint16_t timeHiAndVersion; + uint16_t clockSeq; + uint8_t node[6]; +} effect_uuid_t; + +// Maximum length of character strings in structures defines by this API. +#define EFFECT_STRING_LEN_MAX 64 + +// NULL UUID definition (matches SL_IID_NULL_) +#define EFFECT_UUID_INITIALIZER { 0xec7178ec, 0xe5e1, 0x4432, 0xa3f4, \ + { 0x46, 0x57, 0xe6, 0x79, 0x52, 0x10 } } +static const effect_uuid_t EFFECT_UUID_NULL_ = EFFECT_UUID_INITIALIZER; +static const effect_uuid_t * const EFFECT_UUID_NULL = &EFFECT_UUID_NULL_; +static const char * const EFFECT_UUID_NULL_STR = "ec7178ec-e5e1-4432-a3f4-4657e6795210"; + + +// The effect descriptor contains necessary information to facilitate the enumeration of the effect +// engines present in a library. +typedef struct effect_descriptor_s { + effect_uuid_t type; // UUID of to the OpenSL ES interface implemented by this effect + effect_uuid_t uuid; // UUID for this particular implementation + uint32_t apiVersion; // Version of the effect control API implemented + uint32_t flags; // effect engine capabilities/requirements flags (see below) + uint16_t cpuLoad; // CPU load indication (see below) + uint16_t memoryUsage; // Data Memory usage (see below) + char name[EFFECT_STRING_LEN_MAX]; // human readable effect name + char implementor[EFFECT_STRING_LEN_MAX]; // human readable effect implementor name +} effect_descriptor_t; + +// CPU load and memory usage indication: each effect implementation must provide an indication of +// its CPU and memory usage for the audio effect framework to limit the number of effects +// instantiated at a given time on a given platform. +// The CPU load is expressed in 0.1 MIPS units as estimated on an ARM9E core (ARMv5TE) with 0 WS. +// The memory usage is expressed in KB and includes only dynamically allocated memory + +// Definitions for flags field of effect descriptor. +// +---------------------------+-----------+----------------------------------- +// | description | bits | values +// +---------------------------+-----------+----------------------------------- +// | connection mode | 0..2 | 0 insert: after track process +// | | | 1 auxiliary: connect to track auxiliary +// | | | output and use send level +// | | | 2 replace: replaces track process function; +// | | | must implement SRC, volume and mono to stereo. +// | | | 3 pre processing: applied below audio HAL on input +// | | | 4 post processing: applied below audio HAL on output +// | | | 5 - 7 reserved +// +---------------------------+-----------+----------------------------------- +// | insertion preference | 3..5 | 0 none +// | | | 1 first of the chain +// | | | 2 last of the chain +// | | | 3 exclusive (only effect in the insert chain) +// | | | 4..7 reserved +// +---------------------------+-----------+----------------------------------- +// | Volume management | 6..8 | 0 none +// | | | 1 implements volume control +// | | | 2 requires volume indication +// | | | 4 reserved +// +---------------------------+-----------+----------------------------------- +// | Device indication | 9..11 | 0 none +// | | | 1 requires device updates +// | | | 2, 4 reserved +// +---------------------------+-----------+----------------------------------- +// | Sample input mode | 12..13 | 1 direct: process() function or EFFECT_CMD_SET_CONFIG +// | | | command must specify a buffer descriptor +// | | | 2 provider: process() function uses the +// | | | bufferProvider indicated by the +// | | | EFFECT_CMD_SET_CONFIG command to request input. +// | | | buffers. +// | | | 3 both: both input modes are supported +// +---------------------------+-----------+----------------------------------- +// | Sample output mode | 14..15 | 1 direct: process() function or EFFECT_CMD_SET_CONFIG +// | | | command must specify a buffer descriptor +// | | | 2 provider: process() function uses the +// | | | bufferProvider indicated by the +// | | | EFFECT_CMD_SET_CONFIG command to request output +// | | | buffers. +// | | | 3 both: both output modes are supported +// +---------------------------+-----------+----------------------------------- +// | Hardware acceleration | 16..17 | 0 No hardware acceleration +// | | | 1 non tunneled hw acceleration: the process() function +// | | | reads the samples, send them to HW accelerated +// | | | effect processor, reads back the processed samples +// | | | and returns them to the output buffer. +// | | | 2 tunneled hw acceleration: the process() function is +// | | | transparent. The effect interface is only used to +// | | | control the effect engine. This mode is relevant for +// | | | global effects actually applied by the audio +// | | | hardware on the output stream. +// +---------------------------+-----------+----------------------------------- +// | Audio Mode indication | 18..19 | 0 none +// | | | 1 requires audio mode updates +// | | | 2..3 reserved +// +---------------------------+-----------+----------------------------------- +// | Audio source indication | 20..21 | 0 none +// | | | 1 requires audio source updates +// | | | 2..3 reserved +// +---------------------------+-----------+----------------------------------- +// | Effect offload supported | 22 | 0 The effect cannot be offloaded to an audio DSP +// | | | 1 The effect can be offloaded to an audio DSP +// +---------------------------+-----------+----------------------------------- + +// Insert mode +#define EFFECT_FLAG_TYPE_SHIFT 0 +#define EFFECT_FLAG_TYPE_SIZE 3 +#define EFFECT_FLAG_TYPE_MASK (((1 << EFFECT_FLAG_TYPE_SIZE) -1) \ + << EFFECT_FLAG_TYPE_SHIFT) +#define EFFECT_FLAG_TYPE_INSERT (0 << EFFECT_FLAG_TYPE_SHIFT) +#define EFFECT_FLAG_TYPE_AUXILIARY (1 << EFFECT_FLAG_TYPE_SHIFT) +#define EFFECT_FLAG_TYPE_REPLACE (2 << EFFECT_FLAG_TYPE_SHIFT) +#define EFFECT_FLAG_TYPE_PRE_PROC (3 << EFFECT_FLAG_TYPE_SHIFT) +#define EFFECT_FLAG_TYPE_POST_PROC (4 << EFFECT_FLAG_TYPE_SHIFT) + +// Insert preference +#define EFFECT_FLAG_INSERT_SHIFT (EFFECT_FLAG_TYPE_SHIFT + EFFECT_FLAG_TYPE_SIZE) +#define EFFECT_FLAG_INSERT_SIZE 3 +#define EFFECT_FLAG_INSERT_MASK (((1 << EFFECT_FLAG_INSERT_SIZE) -1) \ + << EFFECT_FLAG_INSERT_SHIFT) +#define EFFECT_FLAG_INSERT_ANY (0 << EFFECT_FLAG_INSERT_SHIFT) +#define EFFECT_FLAG_INSERT_FIRST (1 << EFFECT_FLAG_INSERT_SHIFT) +#define EFFECT_FLAG_INSERT_LAST (2 << EFFECT_FLAG_INSERT_SHIFT) +#define EFFECT_FLAG_INSERT_EXCLUSIVE (3 << EFFECT_FLAG_INSERT_SHIFT) + + +// Volume control +#define EFFECT_FLAG_VOLUME_SHIFT (EFFECT_FLAG_INSERT_SHIFT + EFFECT_FLAG_INSERT_SIZE) +#define EFFECT_FLAG_VOLUME_SIZE 3 +#define EFFECT_FLAG_VOLUME_MASK (((1 << EFFECT_FLAG_VOLUME_SIZE) -1) \ + << EFFECT_FLAG_VOLUME_SHIFT) +#define EFFECT_FLAG_VOLUME_CTRL (1 << EFFECT_FLAG_VOLUME_SHIFT) +#define EFFECT_FLAG_VOLUME_IND (2 << EFFECT_FLAG_VOLUME_SHIFT) +#define EFFECT_FLAG_VOLUME_NONE (0 << EFFECT_FLAG_VOLUME_SHIFT) + +// Device indication +#define EFFECT_FLAG_DEVICE_SHIFT (EFFECT_FLAG_VOLUME_SHIFT + EFFECT_FLAG_VOLUME_SIZE) +#define EFFECT_FLAG_DEVICE_SIZE 3 +#define EFFECT_FLAG_DEVICE_MASK (((1 << EFFECT_FLAG_DEVICE_SIZE) -1) \ + << EFFECT_FLAG_DEVICE_SHIFT) +#define EFFECT_FLAG_DEVICE_IND (1 << EFFECT_FLAG_DEVICE_SHIFT) +#define EFFECT_FLAG_DEVICE_NONE (0 << EFFECT_FLAG_DEVICE_SHIFT) + +// Sample input modes +#define EFFECT_FLAG_INPUT_SHIFT (EFFECT_FLAG_DEVICE_SHIFT + EFFECT_FLAG_DEVICE_SIZE) +#define EFFECT_FLAG_INPUT_SIZE 2 +#define EFFECT_FLAG_INPUT_MASK (((1 << EFFECT_FLAG_INPUT_SIZE) -1) \ + << EFFECT_FLAG_INPUT_SHIFT) +#define EFFECT_FLAG_INPUT_DIRECT (1 << EFFECT_FLAG_INPUT_SHIFT) +#define EFFECT_FLAG_INPUT_PROVIDER (2 << EFFECT_FLAG_INPUT_SHIFT) +#define EFFECT_FLAG_INPUT_BOTH (3 << EFFECT_FLAG_INPUT_SHIFT) + +// Sample output modes +#define EFFECT_FLAG_OUTPUT_SHIFT (EFFECT_FLAG_INPUT_SHIFT + EFFECT_FLAG_INPUT_SIZE) +#define EFFECT_FLAG_OUTPUT_SIZE 2 +#define EFFECT_FLAG_OUTPUT_MASK (((1 << EFFECT_FLAG_OUTPUT_SIZE) -1) \ + << EFFECT_FLAG_OUTPUT_SHIFT) +#define EFFECT_FLAG_OUTPUT_DIRECT (1 << EFFECT_FLAG_OUTPUT_SHIFT) +#define EFFECT_FLAG_OUTPUT_PROVIDER (2 << EFFECT_FLAG_OUTPUT_SHIFT) +#define EFFECT_FLAG_OUTPUT_BOTH (3 << EFFECT_FLAG_OUTPUT_SHIFT) + +// Hardware acceleration mode +#define EFFECT_FLAG_HW_ACC_SHIFT (EFFECT_FLAG_OUTPUT_SHIFT + EFFECT_FLAG_OUTPUT_SIZE) +#define EFFECT_FLAG_HW_ACC_SIZE 2 +#define EFFECT_FLAG_HW_ACC_MASK (((1 << EFFECT_FLAG_HW_ACC_SIZE) -1) \ + << EFFECT_FLAG_HW_ACC_SHIFT) +#define EFFECT_FLAG_HW_ACC_SIMPLE (1 << EFFECT_FLAG_HW_ACC_SHIFT) +#define EFFECT_FLAG_HW_ACC_TUNNEL (2 << EFFECT_FLAG_HW_ACC_SHIFT) + +// Audio mode indication +#define EFFECT_FLAG_AUDIO_MODE_SHIFT (EFFECT_FLAG_HW_ACC_SHIFT + EFFECT_FLAG_HW_ACC_SIZE) +#define EFFECT_FLAG_AUDIO_MODE_SIZE 2 +#define EFFECT_FLAG_AUDIO_MODE_MASK (((1 << EFFECT_FLAG_AUDIO_MODE_SIZE) -1) \ + << EFFECT_FLAG_AUDIO_MODE_SHIFT) +#define EFFECT_FLAG_AUDIO_MODE_IND (1 << EFFECT_FLAG_AUDIO_MODE_SHIFT) +#define EFFECT_FLAG_AUDIO_MODE_NONE (0 << EFFECT_FLAG_AUDIO_MODE_SHIFT) + +// Audio source indication +#define EFFECT_FLAG_AUDIO_SOURCE_SHIFT (EFFECT_FLAG_AUDIO_MODE_SHIFT + EFFECT_FLAG_AUDIO_MODE_SIZE) +#define EFFECT_FLAG_AUDIO_SOURCE_SIZE 2 +#define EFFECT_FLAG_AUDIO_SOURCE_MASK (((1 << EFFECT_FLAG_AUDIO_SOURCE_SIZE) -1) \ + << EFFECT_FLAG_AUDIO_SOURCE_SHIFT) +#define EFFECT_FLAG_AUDIO_SOURCE_IND (1 << EFFECT_FLAG_AUDIO_SOURCE_SHIFT) +#define EFFECT_FLAG_AUDIO_SOURCE_NONE (0 << EFFECT_FLAG_AUDIO_SOURCE_SHIFT) + +// Effect offload indication +#define EFFECT_FLAG_OFFLOAD_SHIFT (EFFECT_FLAG_AUDIO_SOURCE_SHIFT + \ + EFFECT_FLAG_AUDIO_SOURCE_SIZE) +#define EFFECT_FLAG_OFFLOAD_SIZE 1 +#define EFFECT_FLAG_OFFLOAD_MASK (((1 << EFFECT_FLAG_OFFLOAD_SIZE) -1) \ + << EFFECT_FLAG_OFFLOAD_SHIFT) +#define EFFECT_FLAG_OFFLOAD_SUPPORTED (1 << EFFECT_FLAG_OFFLOAD_SHIFT) + +#define EFFECT_MAKE_API_VERSION(M, m) (((M)<<16) | ((m) & 0xFFFF)) +#define EFFECT_API_VERSION_MAJOR(v) ((v)>>16) +#define EFFECT_API_VERSION_MINOR(v) ((m) & 0xFFFF) + + + +///////////////////////////////////////////////// +// Effect control interface +///////////////////////////////////////////////// + +// Effect control interface version 2.0 +#define EFFECT_CONTROL_API_VERSION EFFECT_MAKE_API_VERSION(2,0) + +// Effect control interface structure: effect_interface_s +// The effect control interface is exposed by each effect engine implementation. It consists of +// a set of functions controlling the configuration, activation and process of the engine. +// The functions are grouped in a structure of type effect_interface_s. +// +// Effect control interface handle: effect_handle_t +// The effect_handle_t serves two purposes regarding the implementation of the effect engine: +// - 1 it is the address of a pointer to an effect_interface_s structure where the functions +// of the effect control API for a particular effect are located. +// - 2 it is the address of the context of a particular effect instance. +// A typical implementation in the effect library would define a structure as follows: +// struct effect_module_s { +// const struct effect_interface_s *itfe; +// effect_config_t config; +// effect_context_t context; +// } +// The implementation of EffectCreate() function would then allocate a structure of this +// type and return its address as effect_handle_t +typedef struct effect_interface_s **effect_handle_t; + + +// Forward definition of type audio_buffer_t +typedef struct audio_buffer_s audio_buffer_t; + + + + + + +// Effect control interface definition +struct effect_interface_s { + //////////////////////////////////////////////////////////////////////////////// + // + // Function: process + // + // Description: Effect process function. Takes input samples as specified + // (count and location) in input buffer descriptor and output processed + // samples as specified in output buffer descriptor. If the buffer descriptor + // is not specified the function must use either the buffer or the + // buffer provider function installed by the EFFECT_CMD_SET_CONFIG command. + // The effect framework will call the process() function after the EFFECT_CMD_ENABLE + // command is received and until the EFFECT_CMD_DISABLE is received. When the engine + // receives the EFFECT_CMD_DISABLE command it should turn off the effect gracefully + // and when done indicate that it is OK to stop calling the process() function by + // returning the -ENODATA status. + // + // NOTE: the process() function implementation should be "real-time safe" that is + // it should not perform blocking calls: malloc/free, sleep, read/write/open/close, + // pthread_cond_wait/pthread_mutex_lock... + // + // Input: + // self: handle to the effect interface this function + // is called on. + // inBuffer: buffer descriptor indicating where to read samples to process. + // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG command. + // + // outBuffer: buffer descriptor indicating where to write processed samples. + // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG command. + // + // Output: + // returned value: 0 successful operation + // -ENODATA the engine has finished the disable phase and the framework + // can stop calling process() + // -EINVAL invalid interface handle or + // invalid input/output buffer description + //////////////////////////////////////////////////////////////////////////////// + int32_t (*process)(effect_handle_t self, + audio_buffer_t *inBuffer, + audio_buffer_t *outBuffer); + //////////////////////////////////////////////////////////////////////////////// + // + // Function: command + // + // Description: Send a command and receive a response to/from effect engine. + // + // Input: + // self: handle to the effect interface this function + // is called on. + // cmdCode: command code: the command can be a standardized command defined in + // effect_command_e (see below) or a proprietary command. + // cmdSize: size of command in bytes + // pCmdData: pointer to command data + // pReplyData: pointer to reply data + // + // Input/Output: + // replySize: maximum size of reply data as input + // actual size of reply data as output + // + // Output: + // returned value: 0 successful operation + // -EINVAL invalid interface handle or + // invalid command/reply size or format according to + // command code + // The return code should be restricted to indicate problems related to this API + // specification. Status related to the execution of a particular command should be + // indicated as part of the reply field. + // + // *pReplyData updated with command response + // + //////////////////////////////////////////////////////////////////////////////// + int32_t (*command)(effect_handle_t self, + uint32_t cmdCode, + uint32_t cmdSize, + void *pCmdData, + uint32_t *replySize, + void *pReplyData); + //////////////////////////////////////////////////////////////////////////////// + // + // Function: get_descriptor + // + // Description: Returns the effect descriptor + // + // Input: + // self: handle to the effect interface this function + // is called on. + // + // Input/Output: + // pDescriptor: address where to return the effect descriptor. + // + // Output: + // returned value: 0 successful operation. + // -EINVAL invalid interface handle or invalid pDescriptor + // *pDescriptor: updated with the effect descriptor. + // + //////////////////////////////////////////////////////////////////////////////// + int32_t (*get_descriptor)(effect_handle_t self, + effect_descriptor_t *pDescriptor); + //////////////////////////////////////////////////////////////////////////////// + // + // Function: process_reverse + // + // Description: Process reverse stream function. This function is used to pass + // a reference stream to the effect engine. If the engine does not need a reference + // stream, this function pointer can be set to NULL. + // This function would typically implemented by an Echo Canceler. + // + // Input: + // self: handle to the effect interface this function + // is called on. + // inBuffer: buffer descriptor indicating where to read samples to process. + // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG_REVERSE command. + // + // outBuffer: buffer descriptor indicating where to write processed samples. + // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG_REVERSE command. + // If the buffer and buffer provider in the configuration received by + // EFFECT_CMD_SET_CONFIG_REVERSE are also NULL, do not return modified reverse + // stream data + // + // Output: + // returned value: 0 successful operation + // -ENODATA the engine has finished the disable phase and the framework + // can stop calling process_reverse() + // -EINVAL invalid interface handle or + // invalid input/output buffer description + //////////////////////////////////////////////////////////////////////////////// + int32_t (*process_reverse)(effect_handle_t self, + audio_buffer_t *inBuffer, + audio_buffer_t *outBuffer); +}; + + +// +//--- Standardized command codes for command() function +// +enum effect_command_e { + EFFECT_CMD_INIT, // initialize effect engine + EFFECT_CMD_SET_CONFIG, // configure effect engine (see effect_config_t) + EFFECT_CMD_RESET, // reset effect engine + EFFECT_CMD_ENABLE, // enable effect process + EFFECT_CMD_DISABLE, // disable effect process + EFFECT_CMD_SET_PARAM, // set parameter immediately (see effect_param_t) + EFFECT_CMD_SET_PARAM_DEFERRED, // set parameter deferred + EFFECT_CMD_SET_PARAM_COMMIT, // commit previous set parameter deferred + EFFECT_CMD_GET_PARAM, // get parameter + EFFECT_CMD_SET_DEVICE, // set audio device (see audio.h, audio_devices_t) + EFFECT_CMD_SET_VOLUME, // set volume + EFFECT_CMD_SET_AUDIO_MODE, // set the audio mode (normal, ring, ...) + EFFECT_CMD_SET_CONFIG_REVERSE, // configure effect engine reverse stream(see effect_config_t) + EFFECT_CMD_SET_INPUT_DEVICE, // set capture device (see audio.h, audio_devices_t) + EFFECT_CMD_GET_CONFIG, // read effect engine configuration + EFFECT_CMD_GET_CONFIG_REVERSE, // read configure effect engine reverse stream configuration + EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,// get all supported configurations for a feature. + EFFECT_CMD_GET_FEATURE_CONFIG, // get current feature configuration + EFFECT_CMD_SET_FEATURE_CONFIG, // set current feature configuration + EFFECT_CMD_SET_AUDIO_SOURCE, // set the audio source (see audio.h, audio_source_t) + EFFECT_CMD_OFFLOAD, // set if effect thread is an offload one, + // send the ioHandle of the effect thread + EFFECT_CMD_FIRST_PROPRIETARY = 0x10000 // first proprietary command code +}; + +//================================================================================================== +// command: EFFECT_CMD_INIT +//-------------------------------------------------------------------------------------------------- +// description: +// Initialize effect engine: All configurations return to default +//-------------------------------------------------------------------------------------------------- +// command format: +// size: 0 +// data: N/A +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: sizeof(int) +// data: status +//================================================================================================== +// command: EFFECT_CMD_SET_CONFIG +//-------------------------------------------------------------------------------------------------- +// description: +// Apply new audio parameters configurations for input and output buffers +//-------------------------------------------------------------------------------------------------- +// command format: +// size: sizeof(effect_config_t) +// data: effect_config_t +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: sizeof(int) +// data: status +//================================================================================================== +// command: EFFECT_CMD_RESET +//-------------------------------------------------------------------------------------------------- +// description: +// Reset the effect engine. Keep configuration but resets state and buffer content +//-------------------------------------------------------------------------------------------------- +// command format: +// size: 0 +// data: N/A +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: 0 +// data: N/A +//================================================================================================== +// command: EFFECT_CMD_ENABLE +//-------------------------------------------------------------------------------------------------- +// description: +// Enable the process. Called by the framework before the first call to process() +//-------------------------------------------------------------------------------------------------- +// command format: +// size: 0 +// data: N/A +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: sizeof(int) +// data: status +//================================================================================================== +// command: EFFECT_CMD_DISABLE +//-------------------------------------------------------------------------------------------------- +// description: +// Disable the process. Called by the framework after the last call to process() +//-------------------------------------------------------------------------------------------------- +// command format: +// size: 0 +// data: N/A +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: sizeof(int) +// data: status +//================================================================================================== +// command: EFFECT_CMD_SET_PARAM +//-------------------------------------------------------------------------------------------------- +// description: +// Set a parameter and apply it immediately +//-------------------------------------------------------------------------------------------------- +// command format: +// size: sizeof(effect_param_t) + size of param and value +// data: effect_param_t + param + value. See effect_param_t definition below for value offset +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: sizeof(int) +// data: status +//================================================================================================== +// command: EFFECT_CMD_SET_PARAM_DEFERRED +//-------------------------------------------------------------------------------------------------- +// description: +// Set a parameter but apply it only when receiving EFFECT_CMD_SET_PARAM_COMMIT command +//-------------------------------------------------------------------------------------------------- +// command format: +// size: sizeof(effect_param_t) + size of param and value +// data: effect_param_t + param + value. See effect_param_t definition below for value offset +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: 0 +// data: N/A +//================================================================================================== +// command: EFFECT_CMD_SET_PARAM_COMMIT +//-------------------------------------------------------------------------------------------------- +// description: +// Apply all previously received EFFECT_CMD_SET_PARAM_DEFERRED commands +//-------------------------------------------------------------------------------------------------- +// command format: +// size: 0 +// data: N/A +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: sizeof(int) +// data: status +//================================================================================================== +// command: EFFECT_CMD_GET_PARAM +//-------------------------------------------------------------------------------------------------- +// description: +// Get a parameter value +//-------------------------------------------------------------------------------------------------- +// command format: +// size: sizeof(effect_param_t) + size of param +// data: effect_param_t + param +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: sizeof(effect_param_t) + size of param and value +// data: effect_param_t + param + value. See effect_param_t definition below for value offset +//================================================================================================== +// command: EFFECT_CMD_SET_DEVICE +//-------------------------------------------------------------------------------------------------- +// description: +// Set the rendering device the audio output path is connected to. See audio.h, audio_devices_t +// for device values. +// The effect implementation must set EFFECT_FLAG_DEVICE_IND flag in its descriptor to receive this +// command when the device changes +//-------------------------------------------------------------------------------------------------- +// command format: +// size: sizeof(uint32_t) +// data: uint32_t +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: 0 +// data: N/A +//================================================================================================== +// command: EFFECT_CMD_SET_VOLUME +//-------------------------------------------------------------------------------------------------- +// description: +// Set and get volume. Used by audio framework to delegate volume control to effect engine. +// The effect implementation must set EFFECT_FLAG_VOLUME_IND or EFFECT_FLAG_VOLUME_CTRL flag in +// its descriptor to receive this command before every call to process() function +// If EFFECT_FLAG_VOLUME_CTRL flag is set in the effect descriptor, the effect engine must return +// the volume that should be applied before the effect is processed. The overall volume (the volume +// actually applied by the effect engine multiplied by the returned value) should match the value +// indicated in the command. +//-------------------------------------------------------------------------------------------------- +// command format: +// size: n * sizeof(uint32_t) +// data: volume for each channel defined in effect_config_t for output buffer expressed in +// 8.24 fixed point format +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: n * sizeof(uint32_t) / 0 +// data: - if EFFECT_FLAG_VOLUME_CTRL is set in effect descriptor: +// volume for each channel defined in effect_config_t for output buffer expressed in +// 8.24 fixed point format +// - if EFFECT_FLAG_VOLUME_CTRL is not set in effect descriptor: +// N/A +// It is legal to receive a null pointer as pReplyData in which case the effect framework has +// delegated volume control to another effect +//================================================================================================== +// command: EFFECT_CMD_SET_AUDIO_MODE +//-------------------------------------------------------------------------------------------------- +// description: +// Set the audio mode. The effect implementation must set EFFECT_FLAG_AUDIO_MODE_IND flag in its +// descriptor to receive this command when the audio mode changes. +//-------------------------------------------------------------------------------------------------- +// command format: +// size: sizeof(uint32_t) +// data: audio_mode_t +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: 0 +// data: N/A +//================================================================================================== +// command: EFFECT_CMD_SET_CONFIG_REVERSE +//-------------------------------------------------------------------------------------------------- +// description: +// Apply new audio parameters configurations for input and output buffers of reverse stream. +// An example of reverse stream is the echo reference supplied to an Acoustic Echo Canceler. +//-------------------------------------------------------------------------------------------------- +// command format: +// size: sizeof(effect_config_t) +// data: effect_config_t +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: sizeof(int) +// data: status +//================================================================================================== +// command: EFFECT_CMD_SET_INPUT_DEVICE +//-------------------------------------------------------------------------------------------------- +// description: +// Set the capture device the audio input path is connected to. See audio.h, audio_devices_t +// for device values. +// The effect implementation must set EFFECT_FLAG_DEVICE_IND flag in its descriptor to receive this +// command when the device changes +//-------------------------------------------------------------------------------------------------- +// command format: +// size: sizeof(uint32_t) +// data: uint32_t +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: 0 +// data: N/A +//================================================================================================== +// command: EFFECT_CMD_GET_CONFIG +//-------------------------------------------------------------------------------------------------- +// description: +// Read audio parameters configurations for input and output buffers +//-------------------------------------------------------------------------------------------------- +// command format: +// size: 0 +// data: N/A +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: sizeof(effect_config_t) +// data: effect_config_t +//================================================================================================== +// command: EFFECT_CMD_GET_CONFIG_REVERSE +//-------------------------------------------------------------------------------------------------- +// description: +// Read audio parameters configurations for input and output buffers of reverse stream +//-------------------------------------------------------------------------------------------------- +// command format: +// size: 0 +// data: N/A +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: sizeof(effect_config_t) +// data: effect_config_t +//================================================================================================== +// command: EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS +//-------------------------------------------------------------------------------------------------- +// description: +// Queries for supported configurations for a particular feature (e.g. get the supported +// combinations of main and auxiliary channels for a noise suppressor). +// The command parameter is the feature identifier (See effect_feature_e for a list of defined +// features) followed by the maximum number of configuration descriptor to return. +// The reply is composed of: +// - status (uint32_t): +// - 0 if feature is supported +// - -ENOSYS if the feature is not supported, +// - -ENOMEM if the feature is supported but the total number of supported configurations +// exceeds the maximum number indicated by the caller. +// - total number of supported configurations (uint32_t) +// - an array of configuration descriptors. +// The actual number of descriptors returned must not exceed the maximum number indicated by +// the caller. +//-------------------------------------------------------------------------------------------------- +// command format: +// size: 2 x sizeof(uint32_t) +// data: effect_feature_e + maximum number of configurations to return +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: 2 x sizeof(uint32_t) + n x sizeof () +// data: status + total number of configurations supported + array of n config descriptors +//================================================================================================== +// command: EFFECT_CMD_GET_FEATURE_CONFIG +//-------------------------------------------------------------------------------------------------- +// description: +// Retrieves current configuration for a given feature. +// The reply status is: +// - 0 if feature is supported +// - -ENOSYS if the feature is not supported, +//-------------------------------------------------------------------------------------------------- +// command format: +// size: sizeof(uint32_t) +// data: effect_feature_e +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: sizeof(uint32_t) + sizeof () +// data: status + config descriptor +//================================================================================================== +// command: EFFECT_CMD_SET_FEATURE_CONFIG +//-------------------------------------------------------------------------------------------------- +// description: +// Sets current configuration for a given feature. +// The reply status is: +// - 0 if feature is supported +// - -ENOSYS if the feature is not supported, +// - -EINVAL if the configuration is invalid +//-------------------------------------------------------------------------------------------------- +// command format: +// size: sizeof(uint32_t) + sizeof () +// data: effect_feature_e + config descriptor +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: sizeof(uint32_t) +// data: status +//================================================================================================== +// command: EFFECT_CMD_SET_AUDIO_SOURCE +//-------------------------------------------------------------------------------------------------- +// description: +// Set the audio source the capture path is configured for (Camcorder, voice recognition...). +// See audio.h, audio_source_t for values. +//-------------------------------------------------------------------------------------------------- +// command format: +// size: sizeof(uint32_t) +// data: uint32_t +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: 0 +// data: N/A +//================================================================================================== +// command: EFFECT_CMD_OFFLOAD +//-------------------------------------------------------------------------------------------------- +// description: +// 1.indicate if the playback thread the effect is attached to is offloaded or not +// 2.update the io handle of the playback thread the effect is attached to +//-------------------------------------------------------------------------------------------------- +// command format: +// size: sizeof(effect_offload_param_t) +// data: effect_offload_param_t +//-------------------------------------------------------------------------------------------------- +// reply format: +// size: sizeof(uint32_t) +// data: uint32_t +//-------------------------------------------------------------------------------------------------- +// command: EFFECT_CMD_FIRST_PROPRIETARY +//-------------------------------------------------------------------------------------------------- +// description: +// All proprietary effect commands must use command codes above this value. The size and format of +// command and response fields is free in this case +//================================================================================================== + + +// Audio buffer descriptor used by process(), bufferProvider() functions and buffer_config_t +// structure. Multi-channel audio is always interleaved. The channel order is from LSB to MSB with +// regard to the channel mask definition in audio.h, audio_channel_mask_t e.g : +// Stereo: left, right +// 5 point 1: front left, front right, front center, low frequency, back left, back right +// The buffer size is expressed in frame count, a frame being composed of samples for all +// channels at a given time. Frame size for unspecified format (AUDIO_FORMAT_OTHER) is 8 bit by +// definition +struct audio_buffer_s { + size_t frameCount; // number of frames in buffer + union { + void* raw; // raw pointer to start of buffer + int32_t* s32; // pointer to signed 32 bit data at start of buffer + int16_t* s16; // pointer to signed 16 bit data at start of buffer + uint8_t* u8; // pointer to unsigned 8 bit data at start of buffer + }; +}; + +// The buffer_provider_s structure contains functions that can be used +// by the effect engine process() function to query and release input +// or output audio buffer. +// The getBuffer() function is called to retrieve a buffer where data +// should read from or written to by process() function. +// The releaseBuffer() function MUST be called when the buffer retrieved +// with getBuffer() is not needed anymore. +// The process function should use the buffer provider mechanism to retrieve +// input or output buffer if the inBuffer or outBuffer passed as argument is NULL +// and the buffer configuration (buffer_config_t) given by the EFFECT_CMD_SET_CONFIG +// command did not specify an audio buffer. + +typedef int32_t (* buffer_function_t)(void *cookie, audio_buffer_t *buffer); + +typedef struct buffer_provider_s { + buffer_function_t getBuffer; // retrieve next buffer + buffer_function_t releaseBuffer; // release used buffer + void *cookie; // for use by client of buffer provider functions +} buffer_provider_t; + + +// The buffer_config_s structure specifies the input or output audio format +// to be used by the effect engine. It is part of the effect_config_t +// structure that defines both input and output buffer configurations and is +// passed by the EFFECT_CMD_SET_CONFIG or EFFECT_CMD_SET_CONFIG_REVERSE command. +typedef struct buffer_config_s { + audio_buffer_t buffer; // buffer for use by process() function if not passed explicitly + uint32_t samplingRate; // sampling rate + uint32_t channels; // channel mask (see audio_channel_mask_t in audio.h) + buffer_provider_t bufferProvider; // buffer provider + uint8_t format; // Audio format (see audio_format_t in audio.h) + uint8_t accessMode; // read/write or accumulate in buffer (effect_buffer_access_e) + uint16_t mask; // indicates which of the above fields is valid +} buffer_config_t; + +// Values for "accessMode" field of buffer_config_t: +// overwrite, read only, accumulate (read/modify/write) +enum effect_buffer_access_e { + EFFECT_BUFFER_ACCESS_WRITE, + EFFECT_BUFFER_ACCESS_READ, + EFFECT_BUFFER_ACCESS_ACCUMULATE + +}; + +// feature identifiers for EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS command +enum effect_feature_e { + EFFECT_FEATURE_AUX_CHANNELS, // supports auxiliary channels (e.g. dual mic noise suppressor) + EFFECT_FEATURE_CNT +}; + +// EFFECT_FEATURE_AUX_CHANNELS feature configuration descriptor. Describe a combination +// of main and auxiliary channels supported +typedef struct channel_config_s { + audio_channel_mask_t main_channels; // channel mask for main channels + audio_channel_mask_t aux_channels; // channel mask for auxiliary channels +} channel_config_t; + + +// Values for bit field "mask" in buffer_config_t. If a bit is set, the corresponding field +// in buffer_config_t must be taken into account when executing the EFFECT_CMD_SET_CONFIG command +#define EFFECT_CONFIG_BUFFER 0x0001 // buffer field must be taken into account +#define EFFECT_CONFIG_SMP_RATE 0x0002 // samplingRate field must be taken into account +#define EFFECT_CONFIG_CHANNELS 0x0004 // channels field must be taken into account +#define EFFECT_CONFIG_FORMAT 0x0008 // format field must be taken into account +#define EFFECT_CONFIG_ACC_MODE 0x0010 // accessMode field must be taken into account +#define EFFECT_CONFIG_PROVIDER 0x0020 // bufferProvider field must be taken into account +#define EFFECT_CONFIG_ALL (EFFECT_CONFIG_BUFFER | EFFECT_CONFIG_SMP_RATE | \ + EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT | \ + EFFECT_CONFIG_ACC_MODE | EFFECT_CONFIG_PROVIDER) + + +// effect_config_s structure describes the format of the pCmdData argument of EFFECT_CMD_SET_CONFIG +// command to configure audio parameters and buffers for effect engine input and output. +typedef struct effect_config_s { + buffer_config_t inputCfg; + buffer_config_t outputCfg; +} effect_config_t; + + +// effect_param_s structure describes the format of the pCmdData argument of EFFECT_CMD_SET_PARAM +// command and pCmdData and pReplyData of EFFECT_CMD_GET_PARAM command. +// psize and vsize represent the actual size of parameter and value. +// +// NOTE: the start of value field inside the data field is always on a 32 bit boundary: +// +// +-----------+ +// | status | sizeof(int) +// +-----------+ +// | psize | sizeof(int) +// +-----------+ +// | vsize | sizeof(int) +// +-----------+ +// | | | | +// ~ parameter ~ > psize | +// | | | > ((psize - 1)/sizeof(int) + 1) * sizeof(int) +// +-----------+ | +// | padding | | +// +-----------+ +// | | | +// ~ value ~ > vsize +// | | | +// +-----------+ + +typedef struct effect_param_s { + int32_t status; // Transaction status (unused for command, used for reply) + uint32_t psize; // Parameter size + uint32_t vsize; // Value size + char data[]; // Start of Parameter + Value data +} effect_param_t; + +// structure used by EFFECT_CMD_OFFLOAD command +typedef struct effect_offload_param_s { + bool isOffload; // true if the playback thread the effect is attached to is offloaded + int ioHandle; // io handle of the playback thread the effect is attached to +} effect_offload_param_t; + + +///////////////////////////////////////////////// +// Effect library interface +///////////////////////////////////////////////// + +// Effect library interface version 3.0 +// Note that EffectsFactory.c only checks the major version component, so changes to the minor +// number can only be used for fully backwards compatible changes +#define EFFECT_LIBRARY_API_VERSION EFFECT_MAKE_API_VERSION(3,0) + +#define AUDIO_EFFECT_LIBRARY_TAG ((('A') << 24) | (('E') << 16) | (('L') << 8) | ('T')) + +// Every effect library must have a data structure named AUDIO_EFFECT_LIBRARY_INFO_SYM +// and the fields of this data structure must begin with audio_effect_library_t + +typedef struct audio_effect_library_s { + // tag must be initialized to AUDIO_EFFECT_LIBRARY_TAG + uint32_t tag; + // Version of the effect library API : 0xMMMMmmmm MMMM: Major, mmmm: minor + uint32_t version; + // Name of this library + const char *name; + // Author/owner/implementor of the library + const char *implementor; + + //////////////////////////////////////////////////////////////////////////////// + // + // Function: create_effect + // + // Description: Creates an effect engine of the specified implementation uuid and + // returns an effect control interface on this engine. The function will allocate the + // resources for an instance of the requested effect engine and return + // a handle on the effect control interface. + // + // Input: + // uuid: pointer to the effect uuid. + // sessionId: audio session to which this effect instance will be attached. + // All effects created with the same session ID are connected in series and process + // the same signal stream. Knowing that two effects are part of the same effect + // chain can help the library implement some kind of optimizations. + // ioId: identifies the output or input stream this effect is directed to in + // audio HAL. + // For future use especially with tunneled HW accelerated effects + // + // Input/Output: + // pHandle: address where to return the effect interface handle. + // + // Output: + // returned value: 0 successful operation. + // -ENODEV library failed to initialize + // -EINVAL invalid pEffectUuid or pHandle + // -ENOENT no effect with this uuid found + // *pHandle: updated with the effect interface handle. + // + //////////////////////////////////////////////////////////////////////////////// + int32_t (*create_effect)(const effect_uuid_t *uuid, + int32_t sessionId, + int32_t ioId, + effect_handle_t *pHandle); + + //////////////////////////////////////////////////////////////////////////////// + // + // Function: release_effect + // + // Description: Releases the effect engine whose handle is given as argument. + // All resources allocated to this particular instance of the effect are + // released. + // + // Input: + // handle: handle on the effect interface to be released. + // + // Output: + // returned value: 0 successful operation. + // -ENODEV library failed to initialize + // -EINVAL invalid interface handle + // + //////////////////////////////////////////////////////////////////////////////// + int32_t (*release_effect)(effect_handle_t handle); + + //////////////////////////////////////////////////////////////////////////////// + // + // Function: get_descriptor + // + // Description: Returns the descriptor of the effect engine which implementation UUID is + // given as argument. + // + // Input/Output: + // uuid: pointer to the effect uuid. + // pDescriptor: address where to return the effect descriptor. + // + // Output: + // returned value: 0 successful operation. + // -ENODEV library failed to initialize + // -EINVAL invalid pDescriptor or uuid + // *pDescriptor: updated with the effect descriptor. + // + //////////////////////////////////////////////////////////////////////////////// + int32_t (*get_descriptor)(const effect_uuid_t *uuid, + effect_descriptor_t *pDescriptor); +} audio_effect_library_t; + +// Name of the hal_module_info +#define AUDIO_EFFECT_LIBRARY_INFO_SYM AELI + +// Name of the hal_module_info as a string +#define AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR "AELI" + +__END_DECLS + +#endif // ANDROID_AUDIO_EFFECT_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/audio_policy.h b/phonelibs/android_hardware_libhardware/include/hardware/audio_policy.h new file mode 100644 index 00000000000000..99cb0449fba4c3 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/audio_policy.h @@ -0,0 +1,457 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_AUDIO_POLICY_INTERFACE_H +#define ANDROID_AUDIO_POLICY_INTERFACE_H + +#include +#include +#include + +#include + +#include +#include + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define AUDIO_POLICY_HARDWARE_MODULE_ID "audio_policy" + +/** + * Name of the audio devices to open + */ +#define AUDIO_POLICY_INTERFACE "policy" + +/* ---------------------------------------------------------------------------- */ + +/* + * The audio_policy and audio_policy_service_ops structs define the + * communication interfaces between the platform specific audio policy manager + * and Android generic audio policy manager. + * The platform specific audio policy manager must implement methods of the + * audio_policy struct. + * This implementation makes use of the audio_policy_service_ops to control + * the activity and configuration of audio input and output streams. + * + * The platform specific audio policy manager is in charge of the audio + * routing and volume control policies for a given platform. + * The main roles of this module are: + * - keep track of current system state (removable device connections, phone + * state, user requests...). + * System state changes and user actions are notified to audio policy + * manager with methods of the audio_policy. + * + * - process get_output() queries received when AudioTrack objects are + * created: Those queries return a handler on an output that has been + * selected, configured and opened by the audio policy manager and that + * must be used by the AudioTrack when registering to the AudioFlinger + * with the createTrack() method. + * When the AudioTrack object is released, a release_output() query + * is received and the audio policy manager can decide to close or + * reconfigure the output depending on other streams using this output and + * current system state. + * + * - similarly process get_input() and release_input() queries received from + * AudioRecord objects and configure audio inputs. + * - process volume control requests: the stream volume is converted from + * an index value (received from UI) to a float value applicable to each + * output as a function of platform specific settings and current output + * route (destination device). It also make sure that streams are not + * muted if not allowed (e.g. camera shutter sound in some countries). + */ + +/* XXX: this should be defined OUTSIDE of frameworks/base */ +struct effect_descriptor_s; + +struct audio_policy { + /* + * configuration functions + */ + + /* indicate a change in device connection status */ + int (*set_device_connection_state)(struct audio_policy *pol, + audio_devices_t device, + audio_policy_dev_state_t state, + const char *device_address); + + /* retrieve a device connection status */ + audio_policy_dev_state_t (*get_device_connection_state)( + const struct audio_policy *pol, + audio_devices_t device, + const char *device_address); + + /* indicate a change in phone state. Valid phones states are defined + * by audio_mode_t */ + void (*set_phone_state)(struct audio_policy *pol, audio_mode_t state); + + /* deprecated, never called (was "indicate a change in ringer mode") */ + void (*set_ringer_mode)(struct audio_policy *pol, uint32_t mode, + uint32_t mask); + + /* force using a specific device category for the specified usage */ + void (*set_force_use)(struct audio_policy *pol, + audio_policy_force_use_t usage, + audio_policy_forced_cfg_t config); + + /* retrieve current device category forced for a given usage */ + audio_policy_forced_cfg_t (*get_force_use)(const struct audio_policy *pol, + audio_policy_force_use_t usage); + + /* if can_mute is true, then audio streams that are marked ENFORCED_AUDIBLE + * can still be muted. */ + void (*set_can_mute_enforced_audible)(struct audio_policy *pol, + bool can_mute); + + /* check proper initialization */ + int (*init_check)(const struct audio_policy *pol); + + /* + * Audio routing query functions + */ + + /* request an output appropriate for playback of the supplied stream type and + * parameters */ + audio_io_handle_t (*get_output)(struct audio_policy *pol, + audio_stream_type_t stream, + uint32_t samplingRate, + audio_format_t format, + audio_channel_mask_t channelMask, + audio_output_flags_t flags, + const audio_offload_info_t *offloadInfo); + + /* indicates to the audio policy manager that the output starts being used + * by corresponding stream. */ + int (*start_output)(struct audio_policy *pol, + audio_io_handle_t output, + audio_stream_type_t stream, + int session); + + /* indicates to the audio policy manager that the output stops being used + * by corresponding stream. */ + int (*stop_output)(struct audio_policy *pol, + audio_io_handle_t output, + audio_stream_type_t stream, + int session); + + /* releases the output. */ + void (*release_output)(struct audio_policy *pol, audio_io_handle_t output); + + /* request an input appropriate for record from the supplied device with + * supplied parameters. */ + audio_io_handle_t (*get_input)(struct audio_policy *pol, audio_source_t inputSource, + uint32_t samplingRate, + audio_format_t format, + audio_channel_mask_t channelMask, + audio_in_acoustics_t acoustics); + + /* indicates to the audio policy manager that the input starts being used */ + int (*start_input)(struct audio_policy *pol, audio_io_handle_t input); + + /* indicates to the audio policy manager that the input stops being used. */ + int (*stop_input)(struct audio_policy *pol, audio_io_handle_t input); + + /* releases the input. */ + void (*release_input)(struct audio_policy *pol, audio_io_handle_t input); + + /* + * volume control functions + */ + + /* initialises stream volume conversion parameters by specifying volume + * index range. The index range for each stream is defined by AudioService. */ + void (*init_stream_volume)(struct audio_policy *pol, + audio_stream_type_t stream, + int index_min, + int index_max); + + /* sets the new stream volume at a level corresponding to the supplied + * index. The index is within the range specified by init_stream_volume() */ + int (*set_stream_volume_index)(struct audio_policy *pol, + audio_stream_type_t stream, + int index); + + /* retrieve current volume index for the specified stream */ + int (*get_stream_volume_index)(const struct audio_policy *pol, + audio_stream_type_t stream, + int *index); + + /* sets the new stream volume at a level corresponding to the supplied + * index for the specified device. + * The index is within the range specified by init_stream_volume() */ + int (*set_stream_volume_index_for_device)(struct audio_policy *pol, + audio_stream_type_t stream, + int index, + audio_devices_t device); + + /* retrieve current volume index for the specified stream for the specified device */ + int (*get_stream_volume_index_for_device)(const struct audio_policy *pol, + audio_stream_type_t stream, + int *index, + audio_devices_t device); + + /* return the strategy corresponding to a given stream type */ + uint32_t (*get_strategy_for_stream)(const struct audio_policy *pol, + audio_stream_type_t stream); + + /* return the enabled output devices for the given stream type */ + audio_devices_t (*get_devices_for_stream)(const struct audio_policy *pol, + audio_stream_type_t stream); + + /* Audio effect management */ + audio_io_handle_t (*get_output_for_effect)(struct audio_policy *pol, + const struct effect_descriptor_s *desc); + + int (*register_effect)(struct audio_policy *pol, + const struct effect_descriptor_s *desc, + audio_io_handle_t output, + uint32_t strategy, + int session, + int id); + + int (*unregister_effect)(struct audio_policy *pol, int id); + + int (*set_effect_enabled)(struct audio_policy *pol, int id, bool enabled); + + bool (*is_stream_active)(const struct audio_policy *pol, + audio_stream_type_t stream, + uint32_t in_past_ms); + + bool (*is_stream_active_remotely)(const struct audio_policy *pol, + audio_stream_type_t stream, + uint32_t in_past_ms); + + bool (*is_source_active)(const struct audio_policy *pol, + audio_source_t source); + + /* dump state */ + int (*dump)(const struct audio_policy *pol, int fd); + + /* check if offload is possible for given sample rate, bitrate, duration, ... */ + bool (*is_offload_supported)(const struct audio_policy *pol, + const audio_offload_info_t *info); +}; + + +struct audio_policy_service_ops { + /* + * Audio output Control functions + */ + + /* Opens an audio output with the requested parameters. + * + * The parameter values can indicate to use the default values in case the + * audio policy manager has no specific requirements for the output being + * opened. + * + * When the function returns, the parameter values reflect the actual + * values used by the audio hardware output stream. + * + * The audio policy manager can check if the proposed parameters are + * suitable or not and act accordingly. + */ + audio_io_handle_t (*open_output)(void *service, + audio_devices_t *pDevices, + uint32_t *pSamplingRate, + audio_format_t *pFormat, + audio_channel_mask_t *pChannelMask, + uint32_t *pLatencyMs, + audio_output_flags_t flags); + + /* creates a special output that is duplicated to the two outputs passed as + * arguments. The duplication is performed by + * a special mixer thread in the AudioFlinger. + */ + audio_io_handle_t (*open_duplicate_output)(void *service, + audio_io_handle_t output1, + audio_io_handle_t output2); + + /* closes the output stream */ + int (*close_output)(void *service, audio_io_handle_t output); + + /* suspends the output. + * + * When an output is suspended, the corresponding audio hardware output + * stream is placed in standby and the AudioTracks attached to the mixer + * thread are still processed but the output mix is discarded. + */ + int (*suspend_output)(void *service, audio_io_handle_t output); + + /* restores a suspended output. */ + int (*restore_output)(void *service, audio_io_handle_t output); + + /* */ + /* Audio input Control functions */ + /* */ + + /* opens an audio input + * deprecated - new implementations should use open_input_on_module, + * and the acoustics parameter is ignored + */ + audio_io_handle_t (*open_input)(void *service, + audio_devices_t *pDevices, + uint32_t *pSamplingRate, + audio_format_t *pFormat, + audio_channel_mask_t *pChannelMask, + audio_in_acoustics_t acoustics); + + /* closes an audio input */ + int (*close_input)(void *service, audio_io_handle_t input); + + /* */ + /* misc control functions */ + /* */ + + /* set a stream volume for a particular output. + * + * For the same user setting, a given stream type can have different + * volumes for each output (destination device) it is attached to. + */ + int (*set_stream_volume)(void *service, + audio_stream_type_t stream, + float volume, + audio_io_handle_t output, + int delay_ms); + + /* invalidate a stream type, causing a reroute to an unspecified new output */ + int (*invalidate_stream)(void *service, + audio_stream_type_t stream); + + /* function enabling to send proprietary informations directly from audio + * policy manager to audio hardware interface. */ + void (*set_parameters)(void *service, + audio_io_handle_t io_handle, + const char *kv_pairs, + int delay_ms); + + /* function enabling to receive proprietary informations directly from + * audio hardware interface to audio policy manager. + * + * Returns a pointer to a heap allocated string. The caller is responsible + * for freeing the memory for it using free(). + */ + + char * (*get_parameters)(void *service, audio_io_handle_t io_handle, + const char *keys); + + /* request the playback of a tone on the specified stream. + * used for instance to replace notification sounds when playing over a + * telephony device during a phone call. + */ + int (*start_tone)(void *service, + audio_policy_tone_t tone, + audio_stream_type_t stream); + + int (*stop_tone)(void *service); + + /* set down link audio volume. */ + int (*set_voice_volume)(void *service, + float volume, + int delay_ms); + + /* move effect to the specified output */ + int (*move_effects)(void *service, + int session, + audio_io_handle_t src_output, + audio_io_handle_t dst_output); + + /* loads an audio hw module. + * + * The module name passed is the base name of the HW module library, e.g "primary" or "a2dp". + * The function returns a handle on the module that will be used to specify a particular + * module when calling open_output_on_module() or open_input_on_module() + */ + audio_module_handle_t (*load_hw_module)(void *service, + const char *name); + + /* Opens an audio output on a particular HW module. + * + * Same as open_output() but specifying a specific HW module on which the output must be opened. + */ + audio_io_handle_t (*open_output_on_module)(void *service, + audio_module_handle_t module, + audio_devices_t *pDevices, + uint32_t *pSamplingRate, + audio_format_t *pFormat, + audio_channel_mask_t *pChannelMask, + uint32_t *pLatencyMs, + audio_output_flags_t flags, + const audio_offload_info_t *offloadInfo); + + /* Opens an audio input on a particular HW module. + * + * Same as open_input() but specifying a specific HW module on which the input must be opened. + * Also removed deprecated acoustics parameter + */ + audio_io_handle_t (*open_input_on_module)(void *service, + audio_module_handle_t module, + audio_devices_t *pDevices, + uint32_t *pSamplingRate, + audio_format_t *pFormat, + audio_channel_mask_t *pChannelMask); + +}; + +/**********************************************************************/ + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +typedef struct audio_policy_module { + struct hw_module_t common; +} audio_policy_module_t; + +struct audio_policy_device { + /** + * Common methods of the audio policy device. This *must* be the first member of + * audio_policy_device as users of this structure will cast a hw_device_t to + * audio_policy_device pointer in contexts where it's known the hw_device_t references an + * audio_policy_device. + */ + struct hw_device_t common; + + int (*create_audio_policy)(const struct audio_policy_device *device, + struct audio_policy_service_ops *aps_ops, + void *service, + struct audio_policy **ap); + + int (*destroy_audio_policy)(const struct audio_policy_device *device, + struct audio_policy *ap); +}; + +/** convenience API for opening and closing a supported device */ + +static inline int audio_policy_dev_open(const hw_module_t* module, + struct audio_policy_device** device) +{ + return module->methods->open(module, AUDIO_POLICY_INTERFACE, + (hw_device_t**)device); +} + +static inline int audio_policy_dev_close(struct audio_policy_device* device) +{ + return device->common.close(&device->common); +} + + +__END_DECLS + +#endif // ANDROID_AUDIO_POLICY_INTERFACE_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bluetooth.h b/phonelibs/android_hardware_libhardware/include/hardware/bluetooth.h new file mode 100644 index 00000000000000..5e8b468d64abdf --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bluetooth.h @@ -0,0 +1,595 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_BLUETOOTH_H +#define ANDROID_INCLUDE_BLUETOOTH_H + +#include +#include +#include +#include + +#include + +__BEGIN_DECLS + +/** + * The Bluetooth Hardware Module ID + */ + +#define BT_HARDWARE_MODULE_ID "bluetooth" +#define BT_STACK_MODULE_ID "bluetooth" +#define BT_STACK_TEST_MODULE_ID "bluetooth_test" + + +/* Bluetooth profile interface IDs */ + +#define BT_PROFILE_HANDSFREE_ID "handsfree" +#define BT_PROFILE_HANDSFREE_CLIENT_ID "handsfree_client" +#define BT_PROFILE_ADVANCED_AUDIO_ID "a2dp" +#define BT_PROFILE_ADVANCED_AUDIO_SINK_ID "a2dp_sink" +#define BT_PROFILE_HEALTH_ID "health" +#define BT_PROFILE_SOCKETS_ID "socket" +#define BT_PROFILE_HIDHOST_ID "hidhost" +#define BT_PROFILE_HIDDEV_ID "hiddev" +#define BT_PROFILE_PAN_ID "pan" +#define BT_PROFILE_MAP_CLIENT_ID "map_client" +#define BT_PROFILE_SDP_CLIENT_ID "sdp" +#define BT_PROFILE_GATT_ID "gatt" +#define BT_PROFILE_AV_RC_ID "avrcp" +#define WIPOWER_PROFILE_ID "wipower" +#define BT_PROFILE_AV_RC_CTRL_ID "avrcp_ctrl" + +/** Bluetooth Address */ +typedef struct { + uint8_t address[6]; +} __attribute__((packed))bt_bdaddr_t; + +/** Bluetooth Device Name */ +typedef struct { + uint8_t name[249]; +} __attribute__((packed))bt_bdname_t; + +/** Bluetooth Adapter Visibility Modes*/ +typedef enum { + BT_SCAN_MODE_NONE, + BT_SCAN_MODE_CONNECTABLE, + BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE +} bt_scan_mode_t; + +/** Bluetooth Adapter State */ +typedef enum { + BT_STATE_OFF, + BT_STATE_ON +} bt_state_t; + +/** Bluetooth Error Status */ +/** We need to build on this */ + +typedef enum { + BT_STATUS_SUCCESS, + BT_STATUS_FAIL, + BT_STATUS_NOT_READY, + BT_STATUS_NOMEM, + BT_STATUS_BUSY, + BT_STATUS_DONE, /* request already completed */ + BT_STATUS_UNSUPPORTED, + BT_STATUS_PARM_INVALID, + BT_STATUS_UNHANDLED, + BT_STATUS_AUTH_FAILURE, + BT_STATUS_RMT_DEV_DOWN, + BT_STATUS_AUTH_REJECTED + +} bt_status_t; + +/** Bluetooth PinKey Code */ +typedef struct { + uint8_t pin[16]; +} __attribute__((packed))bt_pin_code_t; + +typedef struct { + uint8_t status; + uint8_t ctrl_state; /* stack reported state */ + uint64_t tx_time; /* in ms */ + uint64_t rx_time; /* in ms */ + uint64_t idle_time; /* in ms */ + uint64_t energy_used; /* a product of mA, V and ms */ +} __attribute__((packed))bt_activity_energy_info; + +/** Bluetooth Adapter Discovery state */ +typedef enum { + BT_DISCOVERY_STOPPED, + BT_DISCOVERY_STARTED +} bt_discovery_state_t; + +/** Bluetooth ACL connection state */ +typedef enum { + BT_ACL_STATE_CONNECTED, + BT_ACL_STATE_DISCONNECTED +} bt_acl_state_t; + +/** Bluetooth 128-bit UUID */ +typedef struct { + uint8_t uu[16]; +} bt_uuid_t; + +/** Bluetooth SDP service record */ +typedef struct +{ + bt_uuid_t uuid; + uint16_t channel; + char name[256]; // what's the maximum length +} bt_service_record_t; + + +/** Bluetooth Remote Version info */ +typedef struct +{ + int version; + int sub_ver; + int manufacturer; +} bt_remote_version_t; + +typedef struct +{ + uint16_t version_supported; + uint8_t local_privacy_enabled; + uint8_t max_adv_instance; + uint8_t rpa_offload_supported; + uint8_t max_irk_list_size; + uint8_t max_adv_filter_supported; + uint8_t activity_energy_info_supported; + uint16_t scan_result_storage_size; + uint16_t total_trackable_advertisers; + bool extended_scan_support; + bool debug_logging_supported; +}bt_local_le_features_t; + +/* Bluetooth Adapter and Remote Device property types */ +typedef enum { + /* Properties common to both adapter and remote device */ + /** + * Description - Bluetooth Device Name + * Access mode - Adapter name can be GET/SET. Remote device can be GET + * Data type - bt_bdname_t + */ + BT_PROPERTY_BDNAME = 0x1, + /** + * Description - Bluetooth Device Address + * Access mode - Only GET. + * Data type - bt_bdaddr_t + */ + BT_PROPERTY_BDADDR, + /** + * Description - Bluetooth Service 128-bit UUIDs + * Access mode - Only GET. + * Data type - Array of bt_uuid_t (Array size inferred from property length). + */ + BT_PROPERTY_UUIDS, + /** + * Description - Bluetooth Class of Device as found in Assigned Numbers + * Access mode - Only GET. + * Data type - uint32_t. + */ + BT_PROPERTY_CLASS_OF_DEVICE, + /** + * Description - Device Type - BREDR, BLE or DUAL Mode + * Access mode - Only GET. + * Data type - bt_device_type_t + */ + BT_PROPERTY_TYPE_OF_DEVICE, + /** + * Description - Bluetooth Service Record + * Access mode - Only GET. + * Data type - bt_service_record_t + */ + BT_PROPERTY_SERVICE_RECORD, + + /* Properties unique to adapter */ + /** + * Description - Bluetooth Adapter scan mode + * Access mode - GET and SET + * Data type - bt_scan_mode_t. + */ + BT_PROPERTY_ADAPTER_SCAN_MODE, + /** + * Description - List of bonded devices + * Access mode - Only GET. + * Data type - Array of bt_bdaddr_t of the bonded remote devices + * (Array size inferred from property length). + */ + BT_PROPERTY_ADAPTER_BONDED_DEVICES, + /** + * Description - Bluetooth Adapter Discovery timeout (in seconds) + * Access mode - GET and SET + * Data type - uint32_t + */ + BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT, + + /* Properties unique to remote device */ + /** + * Description - User defined friendly name of the remote device + * Access mode - GET and SET + * Data type - bt_bdname_t. + */ + BT_PROPERTY_REMOTE_FRIENDLY_NAME, + /** + * Description - RSSI value of the inquired remote device + * Access mode - Only GET. + * Data type - int32_t. + */ + BT_PROPERTY_REMOTE_RSSI, + /** + * Description - Remote version info + * Access mode - SET/GET. + * Data type - bt_remote_version_t. + */ + + BT_PROPERTY_REMOTE_VERSION_INFO, + + /** + * Description - Local LE features + * Access mode - GET. + * Data type - bt_local_le_features_t. + */ + BT_PROPERTY_LOCAL_LE_FEATURES, + + BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP = 0xFF, +} bt_property_type_t; + +/** Bluetooth Adapter Property data structure */ +typedef struct +{ + bt_property_type_t type; + int len; + void *val; +} bt_property_t; + + +/** Bluetooth Device Type */ +typedef enum { + BT_DEVICE_DEVTYPE_BREDR = 0x1, + BT_DEVICE_DEVTYPE_BLE, + BT_DEVICE_DEVTYPE_DUAL +} bt_device_type_t; +/** Bluetooth Bond state */ +typedef enum { + BT_BOND_STATE_NONE, + BT_BOND_STATE_BONDING, + BT_BOND_STATE_BONDED +} bt_bond_state_t; + +/** Bluetooth SSP Bonding Variant */ +typedef enum { + BT_SSP_VARIANT_PASSKEY_CONFIRMATION, + BT_SSP_VARIANT_PASSKEY_ENTRY, + BT_SSP_VARIANT_CONSENT, + BT_SSP_VARIANT_PASSKEY_NOTIFICATION +} bt_ssp_variant_t; + +#define BT_MAX_NUM_UUIDS 32 + +/** Bluetooth Interface callbacks */ + +/** Bluetooth Enable/Disable Callback. */ +typedef void (*adapter_state_changed_callback)(bt_state_t state); + +/** GET/SET Adapter Properties callback */ +/* TODO: For the GET/SET property APIs/callbacks, we may need a session + * identifier to associate the call with the callback. This would be needed + * whenever more than one simultaneous instance of the same adapter_type + * is get/set. + * + * If this is going to be handled in the Java framework, then we do not need + * to manage sessions here. + */ +typedef void (*adapter_properties_callback)(bt_status_t status, + int num_properties, + bt_property_t *properties); + +/** GET/SET Remote Device Properties callback */ +/** TODO: For remote device properties, do not see a need to get/set + * multiple properties - num_properties shall be 1 + */ +typedef void (*remote_device_properties_callback)(bt_status_t status, + bt_bdaddr_t *bd_addr, + int num_properties, + bt_property_t *properties); + +/** New device discovered callback */ +/** If EIR data is not present, then BD_NAME and RSSI shall be NULL and -1 + * respectively */ +typedef void (*device_found_callback)(int num_properties, + bt_property_t *properties); + +/** Discovery state changed callback */ +typedef void (*discovery_state_changed_callback)(bt_discovery_state_t state); + +/** Bluetooth Legacy PinKey Request callback */ +typedef void (*pin_request_callback)(bt_bdaddr_t *remote_bd_addr, + bt_bdname_t *bd_name, uint32_t cod, bool min_16_digit); + +/** Bluetooth SSP Request callback - Just Works & Numeric Comparison*/ +/** pass_key - Shall be 0 for BT_SSP_PAIRING_VARIANT_CONSENT & + * BT_SSP_PAIRING_PASSKEY_ENTRY */ +/* TODO: Passkey request callback shall not be needed for devices with display + * capability. We still need support this in the stack for completeness */ +typedef void (*ssp_request_callback)(bt_bdaddr_t *remote_bd_addr, + bt_bdname_t *bd_name, + uint32_t cod, + bt_ssp_variant_t pairing_variant, + uint32_t pass_key); + +/** Bluetooth Bond state changed callback */ +/* Invoked in response to create_bond, cancel_bond or remove_bond */ +typedef void (*bond_state_changed_callback)(bt_status_t status, + bt_bdaddr_t *remote_bd_addr, + bt_bond_state_t state); + +/** Bluetooth ACL connection state changed callback */ +typedef void (*acl_state_changed_callback)(bt_status_t status, bt_bdaddr_t *remote_bd_addr, + bt_acl_state_t state); + +typedef enum { + ASSOCIATE_JVM, + DISASSOCIATE_JVM +} bt_cb_thread_evt; + +/** Thread Associate/Disassociate JVM Callback */ +/* Callback that is invoked by the callback thread to allow upper layer to attach/detach to/from + * the JVM */ +typedef void (*callback_thread_event)(bt_cb_thread_evt evt); + +/** Bluetooth Test Mode Callback */ +/* Receive any HCI event from controller. Must be in DUT Mode for this callback to be received */ +typedef void (*dut_mode_recv_callback)(uint16_t opcode, uint8_t *buf, uint8_t len); + +/** Bluetooth HCI event Callback */ +/* Receive any HCI event from controller for raw commands */ +typedef void (*hci_event_recv_callback)(uint8_t event_code, uint8_t *buf, uint8_t len); + +/* LE Test mode callbacks +* This callback shall be invoked whenever the le_tx_test, le_rx_test or le_test_end is invoked +* The num_packets is valid only for le_test_end command */ +typedef void (*le_test_mode_callback)(bt_status_t status, uint16_t num_packets); + +/** Callback invoked when energy details are obtained */ +/* Ctrl_state-Current controller state-Active-1,scan-2,or idle-3 state as defined by HCI spec. + * If the ctrl_state value is 0, it means the API call failed + * Time values-In milliseconds as returned by the controller + * Energy used-Value as returned by the controller + * Status-Provides the status of the read_energy_info API call */ +typedef void (*energy_info_callback)(bt_activity_energy_info *energy_info); + +/** TODO: Add callbacks for Link Up/Down and other generic + * notifications/callbacks */ + +/** Bluetooth DM callback structure. */ +typedef struct { + /** set to sizeof(bt_callbacks_t) */ + size_t size; + adapter_state_changed_callback adapter_state_changed_cb; + adapter_properties_callback adapter_properties_cb; + remote_device_properties_callback remote_device_properties_cb; + device_found_callback device_found_cb; + discovery_state_changed_callback discovery_state_changed_cb; + pin_request_callback pin_request_cb; + ssp_request_callback ssp_request_cb; + bond_state_changed_callback bond_state_changed_cb; + acl_state_changed_callback acl_state_changed_cb; + callback_thread_event thread_evt_cb; + dut_mode_recv_callback dut_mode_recv_cb; + le_test_mode_callback le_test_mode_cb; + energy_info_callback energy_info_cb; + hci_event_recv_callback hci_event_recv_cb; +} bt_callbacks_t; + +typedef void (*alarm_cb)(void *data); +typedef bool (*set_wake_alarm_callout)(uint64_t delay_millis, bool should_wake, alarm_cb cb, void *data); +typedef int (*acquire_wake_lock_callout)(const char *lock_name); +typedef int (*release_wake_lock_callout)(const char *lock_name); + +/** The set of functions required by bluedroid to set wake alarms and + * grab wake locks. This struct is passed into the stack through the + * |set_os_callouts| function on |bt_interface_t|. + */ +typedef struct { + /* set to sizeof(bt_os_callouts_t) */ + size_t size; + + set_wake_alarm_callout set_wake_alarm; + acquire_wake_lock_callout acquire_wake_lock; + release_wake_lock_callout release_wake_lock; +} bt_os_callouts_t; + +/** NOTE: By default, no profiles are initialized at the time of init/enable. + * Whenever the application invokes the 'init' API of a profile, then one of + * the following shall occur: + * + * 1.) If Bluetooth is not enabled, then the Bluetooth core shall mark the + * profile as enabled. Subsequently, when the application invokes the + * Bluetooth 'enable', as part of the enable sequence the profile that were + * marked shall be enabled by calling appropriate stack APIs. The + * 'adapter_properties_cb' shall return the list of UUIDs of the + * enabled profiles. + * + * 2.) If Bluetooth is enabled, then the Bluetooth core shall invoke the stack + * profile API to initialize the profile and trigger a + * 'adapter_properties_cb' with the current list of UUIDs including the + * newly added profile's UUID. + * + * The reverse shall occur whenever the profile 'cleanup' APIs are invoked + */ + +/** Represents the standard Bluetooth DM interface. */ +typedef struct { + /** set to sizeof(bt_interface_t) */ + size_t size; + /** + * Opens the interface and provides the callback routines + * to the implemenation of this interface. + */ + int (*init)(bt_callbacks_t* callbacks ); + + /** Enable Bluetooth. */ + int (*enable)(bool guest_mode); + + /** Disable Bluetooth. */ + int (*disable)(void); + + /** Closes the interface. */ + void (*cleanup)(void); + + /** SSR cleanup. */ + void (*ssrcleanup)(void); + + /** Get all Bluetooth Adapter properties at init */ + int (*get_adapter_properties)(void); + + /** Get Bluetooth Adapter property of 'type' */ + int (*get_adapter_property)(bt_property_type_t type); + + /** Set Bluetooth Adapter property of 'type' */ + /* Based on the type, val shall be one of + * bt_bdaddr_t or bt_bdname_t or bt_scanmode_t etc + */ + int (*set_adapter_property)(const bt_property_t *property); + + /** Get all Remote Device properties */ + int (*get_remote_device_properties)(bt_bdaddr_t *remote_addr); + + /** Get Remote Device property of 'type' */ + int (*get_remote_device_property)(bt_bdaddr_t *remote_addr, + bt_property_type_t type); + + /** Set Remote Device property of 'type' */ + int (*set_remote_device_property)(bt_bdaddr_t *remote_addr, + const bt_property_t *property); + + /** Get Remote Device's service record for the given UUID */ + int (*get_remote_service_record)(bt_bdaddr_t *remote_addr, + bt_uuid_t *uuid); + + /** Start SDP to get remote services */ + int (*get_remote_services)(bt_bdaddr_t *remote_addr); + + /** Start Discovery */ + int (*start_discovery)(void); + + /** Cancel Discovery */ + int (*cancel_discovery)(void); + + /** Create Bluetooth Bonding */ + int (*create_bond)(const bt_bdaddr_t *bd_addr, int transport); + + /** Remove Bond */ + int (*remove_bond)(const bt_bdaddr_t *bd_addr); + + /** Cancel Bond */ + int (*cancel_bond)(const bt_bdaddr_t *bd_addr); + + /** + * Get the connection status for a given remote device. + * return value of 0 means the device is not connected, + * non-zero return status indicates an active connection. + */ + int (*get_connection_state)(const bt_bdaddr_t *bd_addr); + + /** BT Legacy PinKey Reply */ + /** If accept==FALSE, then pin_len and pin_code shall be 0x0 */ + int (*pin_reply)(const bt_bdaddr_t *bd_addr, uint8_t accept, + uint8_t pin_len, bt_pin_code_t *pin_code); + + /** BT SSP Reply - Just Works, Numeric Comparison and Passkey + * passkey shall be zero for BT_SSP_VARIANT_PASSKEY_COMPARISON & + * BT_SSP_VARIANT_CONSENT + * For BT_SSP_VARIANT_PASSKEY_ENTRY, if accept==FALSE, then passkey + * shall be zero */ + int (*ssp_reply)(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant, + uint8_t accept, uint32_t passkey); + + /** Get Bluetooth profile interface */ + const void* (*get_profile_interface) (const char *profile_id); + + /** Bluetooth Test Mode APIs - Bluetooth must be enabled for these APIs */ + /* Configure DUT Mode - Use this mode to enter/exit DUT mode */ + int (*dut_mode_configure)(uint8_t enable); + + /* Send any test HCI (vendor-specific) command to the controller. Must be in DUT Mode */ + int (*dut_mode_send)(uint16_t opcode, uint8_t *buf, uint8_t len); + + /* Send any test HCI command to the controller. */ + int (*hci_cmd_send)(uint16_t opcode, uint8_t *buf, uint8_t len); + + /** BLE Test Mode APIs */ + /* opcode MUST be one of: LE_Receiver_Test, LE_Transmitter_Test, LE_Test_End */ + int (*le_test_mode)(uint16_t opcode, uint8_t *buf, uint8_t len); + + /* enable or disable bluetooth HCI snoop log */ + int (*config_hci_snoop_log)(uint8_t enable); + + /** Sets the OS call-out functions that bluedroid needs for alarms and wake locks. + * This should be called immediately after a successful |init|. + */ + int (*set_os_callouts)(bt_os_callouts_t *callouts); + + /** Read Energy info details - return value indicates BT_STATUS_SUCCESS or BT_STATUS_NOT_READY + * Success indicates that the VSC command was sent to controller + */ + int (*read_energy_info)(); + + /** + * Native support for dumpsys function + * Function is synchronous and |fd| is owned by caller. + */ + void (*dump)(int fd); + + /** + * Clear /data/misc/bt_config.conf and erase all stored connections + */ + int (*config_clear)(void); + + /** BT stack Test interface */ + const void* (*get_testapp_interface)(int test_app_profile); + + /** + * Clear (reset) the dynamic portion of the device interoperability database. + */ + void (*interop_database_clear)(void); + + /** + * Add a new device interoperability workaround for a remote device whose + * first |len| bytes of the its device address match |addr|. + * NOTE: |feature| has to match an item defined in interop_feature_t (interop.h). + */ + void (*interop_database_add)(uint16_t feature, const bt_bdaddr_t *addr, size_t len); +} bt_interface_t; + +/** TODO: Need to add APIs for Service Discovery, Service authorization and + * connection management. Also need to add APIs for configuring + * properties of remote bonded devices such as name, UUID etc. */ + +typedef struct { + struct hw_device_t common; + const bt_interface_t* (*get_bluetooth_interface)(); +} bluetooth_device_t; + +typedef bluetooth_device_t bluetooth_module_t; + + +__END_DECLS + +#endif /* ANDROID_INCLUDE_BLUETOOTH_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_av.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_av.h new file mode 100644 index 00000000000000..be82fbeffdbb2c --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_av.h @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2013-2014, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_BT_AV_H +#define ANDROID_INCLUDE_BT_AV_H + +__BEGIN_DECLS + +/* Bluetooth AV connection states */ +typedef enum { + BTAV_CONNECTION_STATE_DISCONNECTED = 0, + BTAV_CONNECTION_STATE_CONNECTING, + BTAV_CONNECTION_STATE_CONNECTED, + BTAV_CONNECTION_STATE_DISCONNECTING +} btav_connection_state_t; + +/* Bluetooth AV datapath states */ +typedef enum { + BTAV_AUDIO_STATE_REMOTE_SUSPEND = 0, + BTAV_AUDIO_STATE_STOPPED, + BTAV_AUDIO_STATE_STARTED, +} btav_audio_state_t; + + +/** Callback for connection state change. + * state will have one of the values from btav_connection_state_t + */ +typedef void (* btav_connection_state_callback)(btav_connection_state_t state, + bt_bdaddr_t *bd_addr); + +/** Callback for audiopath state change. + * state will have one of the values from btav_audio_state_t + */ +typedef void (* btav_audio_state_callback)(btav_audio_state_t state, + bt_bdaddr_t *bd_addr); + +/** Callback for connection priority of device for incoming connection + * btav_connection_priority_t + */ +typedef void (* btav_connection_priority_callback)(bt_bdaddr_t *bd_addr); + +/** Callback for audio configuration change. + * Used only for the A2DP sink interface. + * state will have one of the values from btav_audio_state_t + * sample_rate: sample rate in Hz + * channel_count: number of channels (1 for mono, 2 for stereo) + */ +typedef void (* btav_audio_config_callback)(bt_bdaddr_t *bd_addr, + uint32_t sample_rate, + uint8_t channel_count); + +/** Callback for updating apps for A2dp multicast state. + */ + +typedef void (* btav_is_multicast_enabled_callback)(int state); + +/* + * Callback for audio focus request to be used only in + * case of A2DP Sink. This is required because we are using + * AudioTrack approach for audio data rendering. + */ +typedef void (* btav_audio_focus_request_callback)(bt_bdaddr_t *bd_addr); + +/** BT-AV callback structure. */ +typedef struct { + /** set to sizeof(btav_callbacks_t) */ + size_t size; + btav_connection_state_callback connection_state_cb; + btav_audio_state_callback audio_state_cb; + btav_audio_config_callback audio_config_cb; + btav_connection_priority_callback connection_priority_cb; + btav_is_multicast_enabled_callback multicast_state_cb; + btav_audio_focus_request_callback audio_focus_request_cb; +} btav_callbacks_t; + +/** + * NOTE: + * + * 1. AVRCP 1.0 shall be supported initially. AVRCP passthrough commands + * shall be handled internally via uinput + * + * 2. A2DP data path shall be handled via a socket pipe between the AudioFlinger + * android_audio_hw library and the Bluetooth stack. + * + */ +/** Represents the standard BT-AV interface. + * Used for both the A2DP source and sink interfaces. + */ +typedef struct { + + /** set to sizeof(btav_interface_t) */ + size_t size; + /** + * Register the BtAv callbacks + */ + bt_status_t (*init)( btav_callbacks_t* callbacks , int max_a2dp_connections, + int a2dp_multicast_state); + + /** connect to headset */ + bt_status_t (*connect)( bt_bdaddr_t *bd_addr ); + + /** dis-connect from headset */ + bt_status_t (*disconnect)( bt_bdaddr_t *bd_addr ); + + /** Closes the interface. */ + void (*cleanup)( void ); + + /** Send priority of device to stack*/ + void (*allow_connection)( int is_valid , bt_bdaddr_t *bd_addr); + + /** Sends Audio Focus State. */ + void (*audio_focus_state)( int focus_state ); +} btav_interface_t; + +__END_DECLS + +#endif /* ANDROID_INCLUDE_BT_AV_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_common_types.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_common_types.h new file mode 100644 index 00000000000000..e30ac24e3c0a39 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_common_types.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************** + * + * This file contains constants and definitions that can be used commonly between JNI and stack layer + * + ******************************************************************************/ +#ifndef ANDROID_INCLUDE_BT_COMMON_TYPES_H +#define ANDROID_INCLUDE_BT_COMMON_TYPES_H + +#include "bluetooth.h" + +typedef struct +{ + uint8_t client_if; + uint8_t filt_index; + uint8_t advertiser_state; + uint8_t advertiser_info_present; + uint8_t addr_type; + uint8_t tx_power; + int8_t rssi_value; + uint16_t time_stamp; + bt_bdaddr_t bd_addr; + uint8_t adv_pkt_len; + uint8_t *p_adv_pkt_data; + uint8_t scan_rsp_len; + uint8_t *p_scan_rsp_data; +} btgatt_track_adv_info_t; + +#endif /* ANDROID_INCLUDE_BT_COMMON_TYPES_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_gatt.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_gatt.h new file mode 100644 index 00000000000000..42e14c2f15e483 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_gatt.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_INCLUDE_BT_GATT_H +#define ANDROID_INCLUDE_BT_GATT_H + +#include +#include "bt_gatt_client.h" +#include "bt_gatt_server.h" + +__BEGIN_DECLS + +/** BT-GATT callbacks */ +typedef struct { + /** Set to sizeof(btgatt_callbacks_t) */ + size_t size; + + /** GATT Client callbacks */ + const btgatt_client_callbacks_t* client; + + /** GATT Server callbacks */ + const btgatt_server_callbacks_t* server; +} btgatt_callbacks_t; + +/** Represents the standard Bluetooth GATT interface. */ +typedef struct { + /** Set to sizeof(btgatt_interface_t) */ + size_t size; + + /** + * Initializes the interface and provides callback routines + */ + bt_status_t (*init)( const btgatt_callbacks_t* callbacks ); + + /** Closes the interface */ + void (*cleanup)( void ); + + /** Pointer to the GATT client interface methods.*/ + const btgatt_client_interface_t* client; + + /** Pointer to the GATT server interface methods.*/ + const btgatt_server_interface_t* server; +} btgatt_interface_t; + +__END_DECLS + +#endif /* ANDROID_INCLUDE_BT_GATT_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_gatt_client.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_gatt_client.h new file mode 100644 index 00000000000000..e7e8e82bb97bec --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_gatt_client.h @@ -0,0 +1,455 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_INCLUDE_BT_GATT_CLIENT_H +#define ANDROID_INCLUDE_BT_GATT_CLIENT_H + +#include +#include "bt_gatt_types.h" +#include "bt_common_types.h" + +__BEGIN_DECLS + +/** + * Buffer sizes for maximum attribute length and maximum read/write + * operation buffer size. + */ +#define BTGATT_MAX_ATTR_LEN 600 + +/** Buffer type for unformatted reads/writes */ +typedef struct +{ + uint8_t value[BTGATT_MAX_ATTR_LEN]; + uint16_t len; +} btgatt_unformatted_value_t; + +/** Parameters for GATT read operations */ +typedef struct +{ + btgatt_srvc_id_t srvc_id; + btgatt_gatt_id_t char_id; + btgatt_gatt_id_t descr_id; + btgatt_unformatted_value_t value; + uint16_t value_type; + uint8_t status; +} btgatt_read_params_t; + +/** Parameters for GATT write operations */ +typedef struct +{ + btgatt_srvc_id_t srvc_id; + btgatt_gatt_id_t char_id; + btgatt_gatt_id_t descr_id; + uint8_t status; +} btgatt_write_params_t; + +/** Attribute change notification parameters */ +typedef struct +{ + uint8_t value[BTGATT_MAX_ATTR_LEN]; + bt_bdaddr_t bda; + btgatt_srvc_id_t srvc_id; + btgatt_gatt_id_t char_id; + uint16_t len; + uint8_t is_notify; +} btgatt_notify_params_t; + +typedef struct +{ + uint8_t client_if; + uint8_t action; + uint8_t filt_index; + uint16_t feat_seln; + uint16_t list_logic_type; + uint8_t filt_logic_type; + uint8_t rssi_high_thres; + uint8_t rssi_low_thres; + uint8_t dely_mode; + uint16_t found_timeout; + uint16_t lost_timeout; + uint8_t found_timeout_cnt; + uint16_t num_of_tracking_entries; +} btgatt_filt_param_setup_t; + +typedef struct +{ + bt_bdaddr_t *bda1; + bt_uuid_t *uuid1; + uint16_t u1; + uint16_t u2; + uint16_t u3; + uint16_t u4; + uint16_t u5; +} btgatt_test_params_t; + +/* BT GATT client error codes */ +typedef enum +{ + BT_GATTC_COMMAND_SUCCESS = 0, /* 0 Command succeeded */ + BT_GATTC_COMMAND_STARTED, /* 1 Command started OK. */ + BT_GATTC_COMMAND_BUSY, /* 2 Device busy with another command */ + BT_GATTC_COMMAND_STORED, /* 3 request is stored in control block */ + BT_GATTC_NO_RESOURCES, /* 4 No resources to issue command */ + BT_GATTC_MODE_UNSUPPORTED, /* 5 Request for 1 or more unsupported modes */ + BT_GATTC_ILLEGAL_VALUE, /* 6 Illegal command /parameter value */ + BT_GATTC_INCORRECT_STATE, /* 7 Device in wrong state for request */ + BT_GATTC_UNKNOWN_ADDR, /* 8 Unknown remote BD address */ + BT_GATTC_DEVICE_TIMEOUT, /* 9 Device timeout */ + BT_GATTC_INVALID_CONTROLLER_OUTPUT,/* 10 An incorrect value was received from HCI */ + BT_GATTC_SECURITY_ERROR, /* 11 Authorization or security failure or not authorized */ + BT_GATTC_DELAYED_ENCRYPTION_CHECK, /*12 Delayed encryption check */ + BT_GATTC_ERR_PROCESSING /* 12 Generic error */ +} btgattc_error_t; + +/** BT-GATT Client callback structure. */ + +/** Callback invoked in response to register_client */ +typedef void (*register_client_callback)(int status, int client_if, + bt_uuid_t *app_uuid); + +/** Callback for scan results */ +typedef void (*scan_result_callback)(bt_bdaddr_t* bda, int rssi, uint8_t* adv_data); + +/** GATT open callback invoked in response to open */ +typedef void (*connect_callback)(int conn_id, int status, int client_if, bt_bdaddr_t* bda); + +/** Callback invoked in response to close */ +typedef void (*disconnect_callback)(int conn_id, int status, + int client_if, bt_bdaddr_t* bda); + +/** + * Invoked in response to search_service when the GATT service search + * has been completed. + */ +typedef void (*search_complete_callback)(int conn_id, int status); + +/** Reports GATT services on a remote device */ +typedef void (*search_result_callback)( int conn_id, btgatt_srvc_id_t *srvc_id); + +/** GATT characteristic enumeration result callback */ +typedef void (*get_characteristic_callback)(int conn_id, int status, + btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, + int char_prop); + +/** GATT descriptor enumeration result callback */ +typedef void (*get_descriptor_callback)(int conn_id, int status, + btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, + btgatt_gatt_id_t *descr_id); + +/** GATT included service enumeration result callback */ +typedef void (*get_included_service_callback)(int conn_id, int status, + btgatt_srvc_id_t *srvc_id, btgatt_srvc_id_t *incl_srvc_id); + +/** Callback invoked in response to [de]register_for_notification */ +typedef void (*register_for_notification_callback)(int conn_id, + int registered, int status, btgatt_srvc_id_t *srvc_id, + btgatt_gatt_id_t *char_id); + +/** + * Remote device notification callback, invoked when a remote device sends + * a notification or indication that a client has registered for. + */ +typedef void (*notify_callback)(int conn_id, btgatt_notify_params_t *p_data); + +/** Reports result of a GATT read operation */ +typedef void (*read_characteristic_callback)(int conn_id, int status, + btgatt_read_params_t *p_data); + +/** GATT write characteristic operation callback */ +typedef void (*write_characteristic_callback)(int conn_id, int status, + btgatt_write_params_t *p_data); + +/** GATT execute prepared write callback */ +typedef void (*execute_write_callback)(int conn_id, int status); + +/** Callback invoked in response to read_descriptor */ +typedef void (*read_descriptor_callback)(int conn_id, int status, + btgatt_read_params_t *p_data); + +/** Callback invoked in response to write_descriptor */ +typedef void (*write_descriptor_callback)(int conn_id, int status, + btgatt_write_params_t *p_data); + +/** Callback triggered in response to read_remote_rssi */ +typedef void (*read_remote_rssi_callback)(int client_if, bt_bdaddr_t* bda, + int rssi, int status); + +/** + * Callback indicating the status of a listen() operation + */ +typedef void (*listen_callback)(int status, int server_if); + +/** Callback invoked when the MTU for a given connection changes */ +typedef void (*configure_mtu_callback)(int conn_id, int status, int mtu); + +/** Callback invoked when a scan filter configuration command has completed */ +typedef void (*scan_filter_cfg_callback)(int action, int client_if, int status, int filt_type, + int avbl_space); + +/** Callback invoked when scan param has been added, cleared, or deleted */ +typedef void (*scan_filter_param_callback)(int action, int client_if, int status, + int avbl_space); + +/** Callback invoked when a scan filter configuration command has completed */ +typedef void (*scan_filter_status_callback)(int enable, int client_if, int status); + +/** Callback invoked when multi-adv enable operation has completed */ +typedef void (*multi_adv_enable_callback)(int client_if, int status); + +/** Callback invoked when multi-adv param update operation has completed */ +typedef void (*multi_adv_update_callback)(int client_if, int status); + +/** Callback invoked when multi-adv instance data set operation has completed */ +typedef void (*multi_adv_data_callback)(int client_if, int status); + +/** Callback invoked when multi-adv disable operation has completed */ +typedef void (*multi_adv_disable_callback)(int client_if, int status); + +/** + * Callback notifying an application that a remote device connection is currently congested + * and cannot receive any more data. An application should avoid sending more data until + * a further callback is received indicating the congestion status has been cleared. + */ +typedef void (*congestion_callback)(int conn_id, bool congested); +/** Callback invoked when batchscan storage config operation has completed */ +typedef void (*batchscan_cfg_storage_callback)(int client_if, int status); + +/** Callback invoked when batchscan enable / disable operation has completed */ +typedef void (*batchscan_enable_disable_callback)(int action, int client_if, int status); + +/** Callback invoked when batchscan reports are obtained */ +typedef void (*batchscan_reports_callback)(int client_if, int status, int report_format, + int num_records, int data_len, uint8_t* rep_data); + +/** Callback invoked when batchscan storage threshold limit is crossed */ +typedef void (*batchscan_threshold_callback)(int client_if); + +/** Track ADV VSE callback invoked when tracked device is found or lost */ +typedef void (*track_adv_event_callback)(btgatt_track_adv_info_t *p_track_adv_info); + +/** Callback invoked when scan parameter setup has completed */ +typedef void (*scan_parameter_setup_completed_callback)(int client_if, + btgattc_error_t status); + +typedef struct { + register_client_callback register_client_cb; + scan_result_callback scan_result_cb; + connect_callback open_cb; + disconnect_callback close_cb; + search_complete_callback search_complete_cb; + search_result_callback search_result_cb; + get_characteristic_callback get_characteristic_cb; + get_descriptor_callback get_descriptor_cb; + get_included_service_callback get_included_service_cb; + register_for_notification_callback register_for_notification_cb; + notify_callback notify_cb; + read_characteristic_callback read_characteristic_cb; + write_characteristic_callback write_characteristic_cb; + read_descriptor_callback read_descriptor_cb; + write_descriptor_callback write_descriptor_cb; + execute_write_callback execute_write_cb; + read_remote_rssi_callback read_remote_rssi_cb; + listen_callback listen_cb; + configure_mtu_callback configure_mtu_cb; + scan_filter_cfg_callback scan_filter_cfg_cb; + scan_filter_param_callback scan_filter_param_cb; + scan_filter_status_callback scan_filter_status_cb; + multi_adv_enable_callback multi_adv_enable_cb; + multi_adv_update_callback multi_adv_update_cb; + multi_adv_data_callback multi_adv_data_cb; + multi_adv_disable_callback multi_adv_disable_cb; + congestion_callback congestion_cb; + batchscan_cfg_storage_callback batchscan_cfg_storage_cb; + batchscan_enable_disable_callback batchscan_enb_disable_cb; + batchscan_reports_callback batchscan_reports_cb; + batchscan_threshold_callback batchscan_threshold_cb; + track_adv_event_callback track_adv_event_cb; + scan_parameter_setup_completed_callback scan_parameter_setup_completed_cb; +} btgatt_client_callbacks_t; + +/** Represents the standard BT-GATT client interface. */ + +typedef struct { + /** Registers a GATT client application with the stack */ + bt_status_t (*register_client)( bt_uuid_t *uuid ); + + /** Unregister a client application from the stack */ + bt_status_t (*unregister_client)(int client_if ); + + /** Start or stop LE device scanning */ + bt_status_t (*scan)( bool start ); + + /** Create a connection to a remote LE or dual-mode device */ + bt_status_t (*connect)( int client_if, const bt_bdaddr_t *bd_addr, + bool is_direct, int transport ); + + /** Disconnect a remote device or cancel a pending connection */ + bt_status_t (*disconnect)( int client_if, const bt_bdaddr_t *bd_addr, + int conn_id); + + /** Start or stop advertisements to listen for incoming connections */ + bt_status_t (*listen)(int client_if, bool start); + + /** Clear the attribute cache for a given device */ + bt_status_t (*refresh)( int client_if, const bt_bdaddr_t *bd_addr ); + + /** + * Enumerate all GATT services on a connected device. + * Optionally, the results can be filtered for a given UUID. + */ + bt_status_t (*search_service)(int conn_id, bt_uuid_t *filter_uuid ); + + /** + * Enumerate included services for a given service. + * Set start_incl_srvc_id to NULL to get the first included service. + */ + bt_status_t (*get_included_service)( int conn_id, btgatt_srvc_id_t *srvc_id, + btgatt_srvc_id_t *start_incl_srvc_id); + + /** + * Enumerate characteristics for a given service. + * Set start_char_id to NULL to get the first characteristic. + */ + bt_status_t (*get_characteristic)( int conn_id, + btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *start_char_id); + + /** + * Enumerate descriptors for a given characteristic. + * Set start_descr_id to NULL to get the first descriptor. + */ + bt_status_t (*get_descriptor)( int conn_id, + btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, + btgatt_gatt_id_t *start_descr_id); + + /** Read a characteristic on a remote device */ + bt_status_t (*read_characteristic)( int conn_id, + btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, + int auth_req ); + + /** Write a remote characteristic */ + bt_status_t (*write_characteristic)(int conn_id, + btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, + int write_type, int len, int auth_req, + char* p_value); + + /** Read the descriptor for a given characteristic */ + bt_status_t (*read_descriptor)(int conn_id, + btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, + btgatt_gatt_id_t *descr_id, int auth_req); + + /** Write a remote descriptor for a given characteristic */ + bt_status_t (*write_descriptor)( int conn_id, + btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, + btgatt_gatt_id_t *descr_id, int write_type, int len, + int auth_req, char* p_value); + + /** Execute a prepared write operation */ + bt_status_t (*execute_write)(int conn_id, int execute); + + /** + * Register to receive notifications or indications for a given + * characteristic + */ + bt_status_t (*register_for_notification)( int client_if, + const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id, + btgatt_gatt_id_t *char_id); + + /** Deregister a previous request for notifications/indications */ + bt_status_t (*deregister_for_notification)( int client_if, + const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id, + btgatt_gatt_id_t *char_id); + + /** Request RSSI for a given remote device */ + bt_status_t (*read_remote_rssi)( int client_if, const bt_bdaddr_t *bd_addr); + + /** Setup scan filter params */ + bt_status_t (*scan_filter_param_setup)(btgatt_filt_param_setup_t filt_param); + + + /** Configure a scan filter condition */ + bt_status_t (*scan_filter_add_remove)(int client_if, int action, int filt_type, + int filt_index, int company_id, + int company_id_mask, const bt_uuid_t *p_uuid, + const bt_uuid_t *p_uuid_mask, const bt_bdaddr_t *bd_addr, + char addr_type, int data_len, char* p_data, int mask_len, + char* p_mask); + + /** Clear all scan filter conditions for specific filter index*/ + bt_status_t (*scan_filter_clear)(int client_if, int filt_index); + + /** Enable / disable scan filter feature*/ + bt_status_t (*scan_filter_enable)(int client_if, bool enable); + + /** Determine the type of the remote device (LE, BR/EDR, Dual-mode) */ + int (*get_device_type)( const bt_bdaddr_t *bd_addr ); + + /** Set the advertising data or scan response data */ + bt_status_t (*set_adv_data)(int client_if, bool set_scan_rsp, bool include_name, + bool include_txpower, int min_interval, int max_interval, int appearance, + uint16_t manufacturer_len, char* manufacturer_data, + uint16_t service_data_len, char* service_data, + uint16_t service_uuid_len, char* service_uuid); + + /** Configure the MTU for a given connection */ + bt_status_t (*configure_mtu)(int conn_id, int mtu); + + /** Request a connection parameter update */ + bt_status_t (*conn_parameter_update)(const bt_bdaddr_t *bd_addr, int min_interval, + int max_interval, int latency, int timeout); + + /** Sets the LE scan interval and window in units of N*0.625 msec */ + bt_status_t (*set_scan_parameters)(int client_if, int scan_interval, int scan_window); + + /* Setup the parameters as per spec, user manual specified values and enable multi ADV */ + bt_status_t (*multi_adv_enable)(int client_if, int min_interval,int max_interval,int adv_type, + int chnl_map, int tx_power, int timeout_s); + + /* Update the parameters as per spec, user manual specified values and restart multi ADV */ + bt_status_t (*multi_adv_update)(int client_if, int min_interval,int max_interval,int adv_type, + int chnl_map, int tx_power, int timeout_s); + + /* Setup the data for the specified instance */ + bt_status_t (*multi_adv_set_inst_data)(int client_if, bool set_scan_rsp, bool include_name, + bool incl_txpower, int appearance, int manufacturer_len, + char* manufacturer_data, int service_data_len, + char* service_data, int service_uuid_len, char* service_uuid); + + /* Disable the multi adv instance */ + bt_status_t (*multi_adv_disable)(int client_if); + + /* Configure the batchscan storage */ + bt_status_t (*batchscan_cfg_storage)(int client_if, int batch_scan_full_max, + int batch_scan_trunc_max, int batch_scan_notify_threshold); + + /* Enable batchscan */ + bt_status_t (*batchscan_enb_batch_scan)(int client_if, int scan_mode, + int scan_interval, int scan_window, int addr_type, int discard_rule); + + /* Disable batchscan */ + bt_status_t (*batchscan_dis_batch_scan)(int client_if); + + /* Read out batchscan reports */ + bt_status_t (*batchscan_read_reports)(int client_if, int scan_mode); + + /** Test mode interface */ + bt_status_t (*test_command)( int command, btgatt_test_params_t* params); + +} btgatt_client_interface_t; + +__END_DECLS + +#endif /* ANDROID_INCLUDE_BT_GATT_CLIENT_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_gatt_server.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_gatt_server.h new file mode 100644 index 00000000000000..0d6cc1e8d65183 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_gatt_server.h @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_INCLUDE_BT_GATT_SERVER_H +#define ANDROID_INCLUDE_BT_GATT_SERVER_H + +#include + +#include "bt_gatt_types.h" + +__BEGIN_DECLS + +/** GATT value type used in response to remote read requests */ +typedef struct +{ + uint8_t value[BTGATT_MAX_ATTR_LEN]; + uint16_t handle; + uint16_t offset; + uint16_t len; + uint8_t auth_req; +} btgatt_value_t; + +/** GATT remote read request response type */ +typedef union +{ + btgatt_value_t attr_value; + uint16_t handle; +} btgatt_response_t; + +/** BT-GATT Server callback structure. */ + +/** Callback invoked in response to register_server */ +typedef void (*register_server_callback)(int status, int server_if, + bt_uuid_t *app_uuid); + +/** Callback indicating that a remote device has connected or been disconnected */ +typedef void (*connection_callback)(int conn_id, int server_if, int connected, + bt_bdaddr_t *bda); + +/** Callback invoked in response to create_service */ +typedef void (*service_added_callback)(int status, int server_if, + btgatt_srvc_id_t *srvc_id, int srvc_handle); + +/** Callback indicating that an included service has been added to a service */ +typedef void (*included_service_added_callback)(int status, int server_if, + int srvc_handle, int incl_srvc_handle); + +/** Callback invoked when a characteristic has been added to a service */ +typedef void (*characteristic_added_callback)(int status, int server_if, + bt_uuid_t *uuid, int srvc_handle, int char_handle); + +/** Callback invoked when a descriptor has been added to a characteristic */ +typedef void (*descriptor_added_callback)(int status, int server_if, + bt_uuid_t *uuid, int srvc_handle, int descr_handle); + +/** Callback invoked in response to start_service */ +typedef void (*service_started_callback)(int status, int server_if, + int srvc_handle); + +/** Callback invoked in response to stop_service */ +typedef void (*service_stopped_callback)(int status, int server_if, + int srvc_handle); + +/** Callback triggered when a service has been deleted */ +typedef void (*service_deleted_callback)(int status, int server_if, + int srvc_handle); + +/** + * Callback invoked when a remote device has requested to read a characteristic + * or descriptor. The application must respond by calling send_response + */ +typedef void (*request_read_callback)(int conn_id, int trans_id, bt_bdaddr_t *bda, + int attr_handle, int offset, bool is_long); + +/** + * Callback invoked when a remote device has requested to write to a + * characteristic or descriptor. + */ +typedef void (*request_write_callback)(int conn_id, int trans_id, bt_bdaddr_t *bda, + int attr_handle, int offset, int length, + bool need_rsp, bool is_prep, uint8_t* value); + +/** Callback invoked when a previously prepared write is to be executed */ +typedef void (*request_exec_write_callback)(int conn_id, int trans_id, + bt_bdaddr_t *bda, int exec_write); + +/** + * Callback triggered in response to send_response if the remote device + * sends a confirmation. + */ +typedef void (*response_confirmation_callback)(int status, int handle); + +/** + * Callback confirming that a notification or indication has been sent + * to a remote device. + */ +typedef void (*indication_sent_callback)(int conn_id, int status); + +/** + * Callback notifying an application that a remote device connection is currently congested + * and cannot receive any more data. An application should avoid sending more data until + * a further callback is received indicating the congestion status has been cleared. + */ +typedef void (*congestion_callback)(int conn_id, bool congested); + +/** Callback invoked when the MTU for a given connection changes */ +typedef void (*mtu_changed_callback)(int conn_id, int mtu); + +typedef struct { + register_server_callback register_server_cb; + connection_callback connection_cb; + service_added_callback service_added_cb; + included_service_added_callback included_service_added_cb; + characteristic_added_callback characteristic_added_cb; + descriptor_added_callback descriptor_added_cb; + service_started_callback service_started_cb; + service_stopped_callback service_stopped_cb; + service_deleted_callback service_deleted_cb; + request_read_callback request_read_cb; + request_write_callback request_write_cb; + request_exec_write_callback request_exec_write_cb; + response_confirmation_callback response_confirmation_cb; + indication_sent_callback indication_sent_cb; + congestion_callback congestion_cb; + mtu_changed_callback mtu_changed_cb; +} btgatt_server_callbacks_t; + +/** Represents the standard BT-GATT server interface. */ +typedef struct { + /** Registers a GATT server application with the stack */ + bt_status_t (*register_server)( bt_uuid_t *uuid ); + + /** Unregister a server application from the stack */ + bt_status_t (*unregister_server)(int server_if ); + + /** Create a connection to a remote peripheral */ + bt_status_t (*connect)(int server_if, const bt_bdaddr_t *bd_addr, + bool is_direct, int transport); + + /** Disconnect an established connection or cancel a pending one */ + bt_status_t (*disconnect)(int server_if, const bt_bdaddr_t *bd_addr, + int conn_id ); + + /** Create a new service */ + bt_status_t (*add_service)( int server_if, btgatt_srvc_id_t *srvc_id, int num_handles); + + /** Assign an included service to it's parent service */ + bt_status_t (*add_included_service)( int server_if, int service_handle, int included_handle); + + /** Add a characteristic to a service */ + bt_status_t (*add_characteristic)( int server_if, + int service_handle, bt_uuid_t *uuid, + int properties, int permissions); + + /** Add a descriptor to a given service */ + bt_status_t (*add_descriptor)(int server_if, int service_handle, + bt_uuid_t *uuid, int permissions); + + /** Starts a local service */ + bt_status_t (*start_service)(int server_if, int service_handle, + int transport); + + /** Stops a local service */ + bt_status_t (*stop_service)(int server_if, int service_handle); + + /** Delete a local service */ + bt_status_t (*delete_service)(int server_if, int service_handle); + + /** Send value indication to a remote device */ + bt_status_t (*send_indication)(int server_if, int attribute_handle, + int conn_id, int len, int confirm, + char* p_value); + + /** Send a response to a read/write operation */ + bt_status_t (*send_response)(int conn_id, int trans_id, + int status, btgatt_response_t *response); + +} btgatt_server_interface_t; + +__END_DECLS + +#endif /* ANDROID_INCLUDE_BT_GATT_CLIENT_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_gatt_types.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_gatt_types.h new file mode 100644 index 00000000000000..e037ddcdbba7b3 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_gatt_types.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_INCLUDE_BT_GATT_TYPES_H +#define ANDROID_INCLUDE_BT_GATT_TYPES_H + +#include +#include + +__BEGIN_DECLS + +/** + * GATT Service types + */ +#define BTGATT_SERVICE_TYPE_PRIMARY 0 +#define BTGATT_SERVICE_TYPE_SECONDARY 1 + +/** GATT ID adding instance id tracking to the UUID */ +typedef struct +{ + bt_uuid_t uuid; + uint8_t inst_id; +} btgatt_gatt_id_t; + +/** GATT Service ID also identifies the service type (primary/secondary) */ +typedef struct +{ + btgatt_gatt_id_t id; + uint8_t is_primary; +} btgatt_srvc_id_t; + +/** Preferred physical Transport for GATT connection */ +typedef enum +{ + GATT_TRANSPORT_AUTO, + GATT_TRANSPORT_BREDR, + GATT_TRANSPORT_LE +} btgatt_transport_t; + +__END_DECLS + +#endif /* ANDROID_INCLUDE_BT_GATT_TYPES_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_hd.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_hd.h new file mode 100644 index 00000000000000..6ba5b097d039b7 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_hd.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013, The Linux Foundation. All rights reserved. + * Not a Contribution + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_BT_HD_H +#define ANDROID_INCLUDE_BT_HD_H + +#include + +__BEGIN_DECLS + +typedef enum +{ + BTHD_REPORT_TYPE_OTHER = 0, + BTHD_REPORT_TYPE_INPUT, + BTHD_REPORT_TYPE_OUTPUT, + BTHD_REPORT_TYPE_FEATURE, + BTHD_REPORT_TYPE_INTRDATA // special value for reports to be sent on INTR (INPUT is assumed) +} bthd_report_type_t; + +typedef enum +{ + BTHD_APP_STATE_NOT_REGISTERED, + BTHD_APP_STATE_REGISTERED +} bthd_application_state_t; + +typedef enum +{ + BTHD_CONN_STATE_CONNECTED, + BTHD_CONN_STATE_CONNECTING, + BTHD_CONN_STATE_DISCONNECTED, + BTHD_CONN_STATE_DISCONNECTING, + BTHD_CONN_STATE_UNKNOWN +} bthd_connection_state_t; + +typedef struct +{ + const char *name; + const char *description; + const char *provider; + uint8_t subclass; + uint8_t *desc_list; + int desc_list_len; +} bthd_app_param_t; + +typedef struct +{ + uint8_t service_type; + uint32_t token_rate; + uint32_t token_bucket_size; + uint32_t peak_bandwidth; + uint32_t access_latency; + uint32_t delay_variation; +} bthd_qos_param_t; + +typedef void (* bthd_application_state_callback)(bt_bdaddr_t *bd_addr, bthd_application_state_t state); +typedef void (* bthd_connection_state_callback)(bt_bdaddr_t *bd_addr, bthd_connection_state_t state); +typedef void (* bthd_get_report_callback)(uint8_t type, uint8_t id, uint16_t buffer_size); +typedef void (* bthd_set_report_callback)(uint8_t type, uint8_t id, uint16_t len, uint8_t *p_data); +typedef void (* bthd_set_protocol_callback)(uint8_t protocol); +typedef void (* bthd_intr_data_callback)(uint8_t report_id, uint16_t len, uint8_t *p_data); +typedef void (* bthd_vc_unplug_callback)(void); + +/** BT-HD callbacks */ +typedef struct { + size_t size; + + bthd_application_state_callback application_state_cb; + bthd_connection_state_callback connection_state_cb; + bthd_get_report_callback get_report_cb; + bthd_set_report_callback set_report_cb; + bthd_set_protocol_callback set_protocol_cb; + bthd_intr_data_callback intr_data_cb; + bthd_vc_unplug_callback vc_unplug_cb; +} bthd_callbacks_t; + +/** BT-HD interface */ +typedef struct { + + size_t size; + + /** init interface and register callbacks */ + bt_status_t (*init)(bthd_callbacks_t* callbacks); + + /** close interface */ + void (*cleanup)(void); + + /** register application */ + bt_status_t (*register_app)(bthd_app_param_t *app_param, bthd_qos_param_t *in_qos, + bthd_qos_param_t *out_qos); + + /** unregister application */ + bt_status_t (*unregister_app)(void); + + /** connects to host with virtual cable */ + bt_status_t (*connect)(void); + + /** disconnects from currently connected host */ + bt_status_t (*disconnect)(void); + + /** send report */ + bt_status_t (*send_report)(bthd_report_type_t type, uint8_t id, uint16_t len, uint8_t *p_data); + + /** notifies error for invalid SET_REPORT */ + bt_status_t (*report_error)(uint8_t error); + + /** send Virtual Cable Unplug */ + bt_status_t (*virtual_cable_unplug)(void); + +} bthd_interface_t; + +__END_DECLS + +#endif /* ANDROID_INCLUDE_BT_HD_H */ + diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_hf.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_hf.h new file mode 100644 index 00000000000000..dbac061308daca --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_hf.h @@ -0,0 +1,348 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_BT_HF_H +#define ANDROID_INCLUDE_BT_HF_H + +__BEGIN_DECLS + +/* AT response code - OK/Error */ +typedef enum { + BTHF_AT_RESPONSE_ERROR = 0, + BTHF_AT_RESPONSE_OK +} bthf_at_response_t; + +typedef enum { + BTHF_CONNECTION_STATE_DISCONNECTED = 0, + BTHF_CONNECTION_STATE_CONNECTING, + BTHF_CONNECTION_STATE_CONNECTED, + BTHF_CONNECTION_STATE_SLC_CONNECTED, + BTHF_CONNECTION_STATE_DISCONNECTING +} bthf_connection_state_t; + +typedef enum { + BTHF_AUDIO_STATE_DISCONNECTED = 0, + BTHF_AUDIO_STATE_CONNECTING, + BTHF_AUDIO_STATE_CONNECTED, + BTHF_AUDIO_STATE_DISCONNECTING +} bthf_audio_state_t; + +typedef enum { + BTHF_VR_STATE_STOPPED = 0, + BTHF_VR_STATE_STARTED +} bthf_vr_state_t; + +typedef enum { + BTHF_VOLUME_TYPE_SPK = 0, + BTHF_VOLUME_TYPE_MIC +} bthf_volume_type_t; + +/* Noise Reduction and Echo Cancellation */ +typedef enum +{ + BTHF_NREC_STOP, + BTHF_NREC_START +} bthf_nrec_t; + +/* WBS codec setting */ +typedef enum +{ + BTHF_WBS_NONE, + BTHF_WBS_NO, + BTHF_WBS_YES +}bthf_wbs_config_t; + +/* BIND type*/ +typedef enum +{ + BTHF_BIND_SET, + BTHF_BIND_READ, + BTHF_BIND_TEST +}bthf_bind_type_t; + + +/* CHLD - Call held handling */ +typedef enum +{ + BTHF_CHLD_TYPE_RELEASEHELD, // Terminate all held or set UDUB("busy") to a waiting call + BTHF_CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD, // Terminate all active calls and accepts a waiting/held call + BTHF_CHLD_TYPE_HOLDACTIVE_ACCEPTHELD, // Hold all active calls and accepts a waiting/held call + BTHF_CHLD_TYPE_ADDHELDTOCONF, // Add all held calls to a conference +} bthf_chld_type_t; + +/** Callback for connection state change. + * state will have one of the values from BtHfConnectionState + */ +typedef void (* bthf_connection_state_callback)(bthf_connection_state_t state, bt_bdaddr_t *bd_addr); + +/** Callback for audio connection state change. + * state will have one of the values from BtHfAudioState + */ +typedef void (* bthf_audio_state_callback)(bthf_audio_state_t state, bt_bdaddr_t *bd_addr); + +/** Callback for VR connection state change. + * state will have one of the values from BtHfVRState + */ +typedef void (* bthf_vr_cmd_callback)(bthf_vr_state_t state, bt_bdaddr_t *bd_addr); + +/** Callback for answer incoming call (ATA) + */ +typedef void (* bthf_answer_call_cmd_callback)(bt_bdaddr_t *bd_addr); + +/** Callback for disconnect call (AT+CHUP) + */ +typedef void (* bthf_hangup_call_cmd_callback)(bt_bdaddr_t *bd_addr); + +/** Callback for disconnect call (AT+CHUP) + * type will denote Speaker/Mic gain (BtHfVolumeControl). + */ +typedef void (* bthf_volume_cmd_callback)(bthf_volume_type_t type, int volume, bt_bdaddr_t *bd_addr); + +/** Callback for dialing an outgoing call + * If number is NULL, redial + */ +typedef void (* bthf_dial_call_cmd_callback)(char *number, bt_bdaddr_t *bd_addr); + +/** Callback for sending DTMF tones + * tone contains the dtmf character to be sent + */ +typedef void (* bthf_dtmf_cmd_callback)(char tone, bt_bdaddr_t *bd_addr); + +/** Callback for enabling/disabling noise reduction/echo cancellation + * value will be 1 to enable, 0 to disable + */ +typedef void (* bthf_nrec_cmd_callback)(bthf_nrec_t nrec, bt_bdaddr_t *bd_addr); + +/** Callback for AT+BCS and event from BAC + * WBS enable, WBS disable + */ +typedef void (* bthf_wbs_callback)(bthf_wbs_config_t wbs, bt_bdaddr_t *bd_addr); + +/** Callback for call hold handling (AT+CHLD) + * value will contain the call hold command (0, 1, 2, 3) + */ +typedef void (* bthf_chld_cmd_callback)(bthf_chld_type_t chld, bt_bdaddr_t *bd_addr); + +/** Callback for CNUM (subscriber number) + */ +typedef void (* bthf_cnum_cmd_callback)(bt_bdaddr_t *bd_addr); + +/** Callback for indicators (CIND) + */ +typedef void (* bthf_cind_cmd_callback)(bt_bdaddr_t *bd_addr); + +/** Callback for operator selection (COPS) + */ +typedef void (* bthf_cops_cmd_callback)(bt_bdaddr_t *bd_addr); + +/** Callback for call list (AT+CLCC) + */ +typedef void (* bthf_clcc_cmd_callback) (bt_bdaddr_t *bd_addr); + +/** Callback for unknown AT command recd from HF + * at_string will contain the unparsed AT string + */ +typedef void (* bthf_unknown_at_cmd_callback)(char *at_string, bt_bdaddr_t *bd_addr); + +/** Callback for keypressed (HSP) event. + */ +typedef void (* bthf_key_pressed_cmd_callback)(bt_bdaddr_t *bd_addr); + +/** Callback for HF indicators (BIND) + */ +typedef void (* bthf_bind_cmd_callback)(char* hf_ind, bthf_bind_type_t type, bt_bdaddr_t *bd_addr); + +/** Callback for HF indicator value (BIEV) + */ +typedef void (* bthf_biev_cmd_callback)(char* hf_ind_val, bt_bdaddr_t *bd_addr); + + +/** BT-HF callback structure. */ +typedef struct { + /** set to sizeof(BtHfCallbacks) */ + size_t size; + bthf_connection_state_callback connection_state_cb; + bthf_audio_state_callback audio_state_cb; + bthf_vr_cmd_callback vr_cmd_cb; + bthf_answer_call_cmd_callback answer_call_cmd_cb; + bthf_hangup_call_cmd_callback hangup_call_cmd_cb; + bthf_volume_cmd_callback volume_cmd_cb; + bthf_dial_call_cmd_callback dial_call_cmd_cb; + bthf_dtmf_cmd_callback dtmf_cmd_cb; + bthf_nrec_cmd_callback nrec_cmd_cb; + bthf_wbs_callback wbs_cb; + bthf_chld_cmd_callback chld_cmd_cb; + bthf_cnum_cmd_callback cnum_cmd_cb; + bthf_cind_cmd_callback cind_cmd_cb; + bthf_cops_cmd_callback cops_cmd_cb; + bthf_clcc_cmd_callback clcc_cmd_cb; + bthf_unknown_at_cmd_callback unknown_at_cmd_cb; + bthf_key_pressed_cmd_callback key_pressed_cmd_cb; + bthf_bind_cmd_callback bind_cmd_cb; + bthf_biev_cmd_callback biev_cmd_cb; +} bthf_callbacks_t; + +/** Network Status */ +typedef enum +{ + BTHF_NETWORK_STATE_NOT_AVAILABLE = 0, + BTHF_NETWORK_STATE_AVAILABLE +} bthf_network_state_t; + +/** Service type */ +typedef enum +{ + BTHF_SERVICE_TYPE_HOME = 0, + BTHF_SERVICE_TYPE_ROAMING +} bthf_service_type_t; + +typedef enum { + BTHF_CALL_STATE_ACTIVE = 0, + BTHF_CALL_STATE_HELD, + BTHF_CALL_STATE_DIALING, + BTHF_CALL_STATE_ALERTING, + BTHF_CALL_STATE_INCOMING, + BTHF_CALL_STATE_WAITING, + BTHF_CALL_STATE_IDLE +} bthf_call_state_t; + +typedef enum { + BTHF_CALL_DIRECTION_OUTGOING = 0, + BTHF_CALL_DIRECTION_INCOMING +} bthf_call_direction_t; + +typedef enum { + BTHF_CALL_TYPE_VOICE = 0, + BTHF_CALL_TYPE_DATA, + BTHF_CALL_TYPE_FAX +} bthf_call_mode_t; + +typedef enum { + BTHF_CALL_MPTY_TYPE_SINGLE = 0, + BTHF_CALL_MPTY_TYPE_MULTI +} bthf_call_mpty_type_t; + +typedef enum { + BTHF_HF_INDICATOR_STATE_DISABLED = 0, + BTHF_HF_INDICATOR_STATE_ENABLED +} bthf_hf_indicator_status_t; + +typedef enum { + BTHF_CALL_ADDRTYPE_UNKNOWN = 0x81, + BTHF_CALL_ADDRTYPE_INTERNATIONAL = 0x91 +} bthf_call_addrtype_t; + +typedef enum { + BTHF_VOIP_CALL_NETWORK_TYPE_MOBILE = 0, + BTHF_VOIP_CALL_NETWORK_TYPE_WIFI +} bthf_voip_call_network_type_t; + +typedef enum { + BTHF_VOIP_STATE_STOPPED = 0, + BTHF_VOIP_STATE_STARTED +} bthf_voip_state_t; + +/** Represents the standard BT-HF interface. */ +typedef struct { + + /** set to sizeof(BtHfInterface) */ + size_t size; + /** + * Register the BtHf callbacks + */ + bt_status_t (*init)( bthf_callbacks_t* callbacks, int max_hf_clients); + + /** connect to headset */ + bt_status_t (*connect)( bt_bdaddr_t *bd_addr ); + + /** dis-connect from headset */ + bt_status_t (*disconnect)( bt_bdaddr_t *bd_addr ); + + /** create an audio connection */ + bt_status_t (*connect_audio)( bt_bdaddr_t *bd_addr ); + + /** close the audio connection */ + bt_status_t (*disconnect_audio)( bt_bdaddr_t *bd_addr ); + + /** start voice recognition */ + bt_status_t (*start_voice_recognition)( bt_bdaddr_t *bd_addr ); + + /** stop voice recognition */ + bt_status_t (*stop_voice_recognition)( bt_bdaddr_t *bd_addr ); + + /** volume control */ + bt_status_t (*volume_control) (bthf_volume_type_t type, int volume, bt_bdaddr_t *bd_addr ); + + /** Combined device status change notification */ + bt_status_t (*device_status_notification)(bthf_network_state_t ntk_state, bthf_service_type_t svc_type, int signal, + int batt_chg); + + /** Response for COPS command */ + bt_status_t (*cops_response)(const char *cops, bt_bdaddr_t *bd_addr ); + + /** Response for CIND command */ + bt_status_t (*cind_response)(int svc, int num_active, int num_held, bthf_call_state_t call_setup_state, + int signal, int roam, int batt_chg, bt_bdaddr_t *bd_addr ); + + /** Pre-formatted AT response, typically in response to unknown AT cmd */ + bt_status_t (*formatted_at_response)(const char *rsp, bt_bdaddr_t *bd_addr ); + + /** ok/error response + * ERROR (0) + * OK (1) + */ + bt_status_t (*at_response) (bthf_at_response_t response_code, int error_code, bt_bdaddr_t *bd_addr ); + + /** response for CLCC command + * Can be iteratively called for each call index + * Call index of 0 will be treated as NULL termination (Completes response) + */ + bt_status_t (*clcc_response) (int index, bthf_call_direction_t dir, + bthf_call_state_t state, bthf_call_mode_t mode, + bthf_call_mpty_type_t mpty, const char *number, + bthf_call_addrtype_t type, bt_bdaddr_t *bd_addr ); + + /** notify of a call state change + * Each update notifies + * 1. Number of active/held/ringing calls + * 2. call_state: This denotes the state change that triggered this msg + * This will take one of the values from BtHfCallState + * 3. number & type: valid only for incoming & waiting call + */ + bt_status_t (*phone_state_change) (int num_active, int num_held, bthf_call_state_t call_setup_state, + const char *number, bthf_call_addrtype_t type); + + /** Closes the interface. */ + void (*cleanup)( void ); + + /** configureation for the SCO codec */ + bt_status_t (*configure_wbs)( bt_bdaddr_t *bd_addr ,bthf_wbs_config_t config ); + + /** Response for BIND READ command and activation/deactivation of HF indicator */ + bt_status_t (*bind_response) (int anum, bthf_hf_indicator_status_t status, + bt_bdaddr_t *bd_addr); + + /** Response for BIND TEST command */ + bt_status_t (*bind_string_response) (const char* result, bt_bdaddr_t *bd_addr); + + /** Sends connectivity network type used by Voip currently to stack */ + bt_status_t (*voip_network_type_wifi) (bthf_voip_state_t is_voip_started, + bthf_voip_call_network_type_t is_network_wifi); +} bthf_interface_t; + +__END_DECLS + +#endif /* ANDROID_INCLUDE_BT_HF_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_hf_client.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_hf_client.h new file mode 100644 index 00000000000000..0577e97d4b56d0 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_hf_client.h @@ -0,0 +1,375 @@ +/* + * Copyright (C) 2012-2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_BT_HF_CLIENT_H +#define ANDROID_INCLUDE_BT_HF_CLIENT_H + +__BEGIN_DECLS + +typedef enum { + BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED = 0, + BTHF_CLIENT_CONNECTION_STATE_CONNECTING, + BTHF_CLIENT_CONNECTION_STATE_CONNECTED, + BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED, + BTHF_CLIENT_CONNECTION_STATE_DISCONNECTING +} bthf_client_connection_state_t; + +typedef enum { + BTHF_CLIENT_AUDIO_STATE_DISCONNECTED = 0, + BTHF_CLIENT_AUDIO_STATE_CONNECTING, + BTHF_CLIENT_AUDIO_STATE_CONNECTED, + BTHF_CLIENT_AUDIO_STATE_CONNECTED_MSBC, +} bthf_client_audio_state_t; + +typedef enum { + BTHF_CLIENT_VR_STATE_STOPPED = 0, + BTHF_CLIENT_VR_STATE_STARTED +} bthf_client_vr_state_t; + +typedef enum { + BTHF_CLIENT_VOLUME_TYPE_SPK = 0, + BTHF_CLIENT_VOLUME_TYPE_MIC +} bthf_client_volume_type_t; + +typedef enum +{ + BTHF_CLIENT_NETWORK_STATE_NOT_AVAILABLE = 0, + BTHF_CLIENT_NETWORK_STATE_AVAILABLE +} bthf_client_network_state_t; + +typedef enum +{ + BTHF_CLIENT_SERVICE_TYPE_HOME = 0, + BTHF_CLIENT_SERVICE_TYPE_ROAMING +} bthf_client_service_type_t; + +typedef enum { + BTHF_CLIENT_CALL_STATE_ACTIVE = 0, + BTHF_CLIENT_CALL_STATE_HELD, + BTHF_CLIENT_CALL_STATE_DIALING, + BTHF_CLIENT_CALL_STATE_ALERTING, + BTHF_CLIENT_CALL_STATE_INCOMING, + BTHF_CLIENT_CALL_STATE_WAITING, + BTHF_CLIENT_CALL_STATE_HELD_BY_RESP_HOLD, +} bthf_client_call_state_t; + +typedef enum { + BTHF_CLIENT_CALL_NO_CALLS_IN_PROGRESS = 0, + BTHF_CLIENT_CALL_CALLS_IN_PROGRESS +} bthf_client_call_t; + +typedef enum { + BTHF_CLIENT_CALLSETUP_NONE = 0, + BTHF_CLIENT_CALLSETUP_INCOMING, + BTHF_CLIENT_CALLSETUP_OUTGOING, + BTHF_CLIENT_CALLSETUP_ALERTING + +} bthf_client_callsetup_t; + +typedef enum { + BTHF_CLIENT_CALLHELD_NONE = 0, + BTHF_CLIENT_CALLHELD_HOLD_AND_ACTIVE, + BTHF_CLIENT_CALLHELD_HOLD, +} bthf_client_callheld_t; + +typedef enum { + BTHF_CLIENT_RESP_AND_HOLD_HELD = 0, + BTRH_CLIENT_RESP_AND_HOLD_ACCEPT, + BTRH_CLIENT_RESP_AND_HOLD_REJECT, +} bthf_client_resp_and_hold_t; + +typedef enum { + BTHF_CLIENT_CALL_DIRECTION_OUTGOING = 0, + BTHF_CLIENT_CALL_DIRECTION_INCOMING +} bthf_client_call_direction_t; + +typedef enum { + BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE = 0, + BTHF_CLIENT_CALL_MPTY_TYPE_MULTI +} bthf_client_call_mpty_type_t; + +typedef enum { + BTHF_CLIENT_CMD_COMPLETE_OK = 0, + BTHF_CLIENT_CMD_COMPLETE_ERROR, + BTHF_CLIENT_CMD_COMPLETE_ERROR_NO_CARRIER, + BTHF_CLIENT_CMD_COMPLETE_ERROR_BUSY, + BTHF_CLIENT_CMD_COMPLETE_ERROR_NO_ANSWER, + BTHF_CLIENT_CMD_COMPLETE_ERROR_DELAYED, + BTHF_CLIENT_CMD_COMPLETE_ERROR_BLACKLISTED, + BTHF_CLIENT_CMD_COMPLETE_ERROR_CME +} bthf_client_cmd_complete_t; + +typedef enum { + BTHF_CLIENT_CALL_ACTION_CHLD_0 = 0, + BTHF_CLIENT_CALL_ACTION_CHLD_1, + BTHF_CLIENT_CALL_ACTION_CHLD_2, + BTHF_CLIENT_CALL_ACTION_CHLD_3, + BTHF_CLIENT_CALL_ACTION_CHLD_4, + BTHF_CLIENT_CALL_ACTION_CHLD_1x, + BTHF_CLIENT_CALL_ACTION_CHLD_2x, + BTHF_CLIENT_CALL_ACTION_ATA, + BTHF_CLIENT_CALL_ACTION_CHUP, + BTHF_CLIENT_CALL_ACTION_BTRH_0, + BTHF_CLIENT_CALL_ACTION_BTRH_1, + BTHF_CLIENT_CALL_ACTION_BTRH_2, +} bthf_client_call_action_t; + +typedef enum { + BTHF_CLIENT_SERVICE_UNKNOWN = 0, + BTHF_CLIENT_SERVICE_VOICE, + BTHF_CLIENT_SERVICE_FAX +} bthf_client_subscriber_service_type_t; + +typedef enum { + BTHF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED = 0, + BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED, +} bthf_client_in_band_ring_state_t; + +/* Peer features masks */ +#define BTHF_CLIENT_PEER_FEAT_3WAY 0x00000001 /* Three-way calling */ +#define BTHF_CLIENT_PEER_FEAT_ECNR 0x00000002 /* Echo cancellation and/or noise reduction */ +#define BTHF_CLIENT_PEER_FEAT_VREC 0x00000004 /* Voice recognition */ +#define BTHF_CLIENT_PEER_FEAT_INBAND 0x00000008 /* In-band ring tone */ +#define BTHF_CLIENT_PEER_FEAT_VTAG 0x00000010 /* Attach a phone number to a voice tag */ +#define BTHF_CLIENT_PEER_FEAT_REJECT 0x00000020 /* Ability to reject incoming call */ +#define BTHF_CLIENT_PEER_FEAT_ECS 0x00000040 /* Enhanced Call Status */ +#define BTHF_CLIENT_PEER_FEAT_ECC 0x00000080 /* Enhanced Call Control */ +#define BTHF_CLIENT_PEER_FEAT_EXTERR 0x00000100 /* Extended error codes */ +#define BTHF_CLIENT_PEER_FEAT_CODEC 0x00000200 /* Codec Negotiation */ + +/* Peer call handling features masks */ +#define BTHF_CLIENT_CHLD_FEAT_REL 0x00000001 /* 0 Release waiting call or held calls */ +#define BTHF_CLIENT_CHLD_FEAT_REL_ACC 0x00000002 /* 1 Release active calls and accept other + (waiting or held) cal */ +#define BTHF_CLIENT_CHLD_FEAT_REL_X 0x00000004 /* 1x Release specified active call only */ +#define BTHF_CLIENT_CHLD_FEAT_HOLD_ACC 0x00000008 /* 2 Active calls on hold and accept other + (waiting or held) call */ +#define BTHF_CLIENT_CHLD_FEAT_PRIV_X 0x00000010 /* 2x Request private mode with specified + call (put the rest on hold) */ +#define BTHF_CLIENT_CHLD_FEAT_MERGE 0x00000020 /* 3 Add held call to multiparty */ +#define BTHF_CLIENT_CHLD_FEAT_MERGE_DETACH 0x00000040 /* 4 Connect two calls and leave + (disconnect from) multiparty */ + +/** Callback for connection state change. + * state will have one of the values from BtHfConnectionState + * peer/chld_features are valid only for BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED state + */ +typedef void (* bthf_client_connection_state_callback)(bthf_client_connection_state_t state, + unsigned int peer_feat, + unsigned int chld_feat, + bt_bdaddr_t *bd_addr); + +/** Callback for audio connection state change. + * state will have one of the values from BtHfAudioState + */ +typedef void (* bthf_client_audio_state_callback)(bthf_client_audio_state_t state, + bt_bdaddr_t *bd_addr); + +/** Callback for VR connection state change. + * state will have one of the values from BtHfVRState + */ +typedef void (* bthf_client_vr_cmd_callback)(bthf_client_vr_state_t state); + +/** Callback for network state change + */ +typedef void (* bthf_client_network_state_callback) (bthf_client_network_state_t state); + +/** Callback for network roaming status change + */ +typedef void (* bthf_client_network_roaming_callback) (bthf_client_service_type_t type); + +/** Callback for signal strength indication + */ +typedef void (* bthf_client_network_signal_callback) (int signal_strength); + +/** Callback for battery level indication + */ +typedef void (* bthf_client_battery_level_callback) (int battery_level); + +/** Callback for current operator name + */ +typedef void (* bthf_client_current_operator_callback) (const char *name); + +/** Callback for call indicator + */ +typedef void (* bthf_client_call_callback) (bthf_client_call_t call); + +/** Callback for callsetup indicator + */ +typedef void (* bthf_client_callsetup_callback) (bthf_client_callsetup_t callsetup); + +/** Callback for callheld indicator + */ +typedef void (* bthf_client_callheld_callback) (bthf_client_callheld_t callheld); + +/** Callback for response and hold + */ +typedef void (* bthf_client_resp_and_hold_callback) (bthf_client_resp_and_hold_t resp_and_hold); + +/** Callback for Calling Line Identification notification + * Will be called only when there is an incoming call and number is provided. + */ +typedef void (* bthf_client_clip_callback) (const char *number); + +/** + * Callback for Call Waiting notification + */ +typedef void (* bthf_client_call_waiting_callback) (const char *number); + +/** + * Callback for listing current calls. Can be called multiple time. + * If number is unknown NULL is passed. + */ +typedef void (*bthf_client_current_calls) (int index, bthf_client_call_direction_t dir, + bthf_client_call_state_t state, + bthf_client_call_mpty_type_t mpty, + const char *number); + +/** Callback for audio volume change + */ +typedef void (*bthf_client_volume_change_callback) (bthf_client_volume_type_t type, int volume); + +/** Callback for command complete event + * cme is valid only for BTHF_CLIENT_CMD_COMPLETE_ERROR_CME type + */ +typedef void (*bthf_client_cmd_complete_callback) (bthf_client_cmd_complete_t type, int cme); + +/** Callback for subscriber information + */ +typedef void (* bthf_client_subscriber_info_callback) (const char *name, + bthf_client_subscriber_service_type_t type); + +/** Callback for in-band ring tone settings + */ +typedef void (* bthf_client_in_band_ring_tone_callback) (bthf_client_in_band_ring_state_t state); + +/** + * Callback for requested number from AG + */ +typedef void (* bthf_client_last_voice_tag_number_callback) (const char *number); + +/** + * Callback for sending ring indication to app + */ +typedef void (* bthf_client_ring_indication_callback) (void); + +/** + * Callback for sending cgmi indication to app + */ +typedef void (* bthf_client_cgmi_indication_callback) (const char *str); + +/** + * Callback for sending cgmm indication to app + */ +typedef void (* bthf_client_cgmm_indication_callback) (const char *str); + +/** BT-HF callback structure. */ +typedef struct { + /** set to sizeof(BtHfClientCallbacks) */ + size_t size; + bthf_client_connection_state_callback connection_state_cb; + bthf_client_audio_state_callback audio_state_cb; + bthf_client_vr_cmd_callback vr_cmd_cb; + bthf_client_network_state_callback network_state_cb; + bthf_client_network_roaming_callback network_roaming_cb; + bthf_client_network_signal_callback network_signal_cb; + bthf_client_battery_level_callback battery_level_cb; + bthf_client_current_operator_callback current_operator_cb; + bthf_client_call_callback call_cb; + bthf_client_callsetup_callback callsetup_cb; + bthf_client_callheld_callback callheld_cb; + bthf_client_resp_and_hold_callback resp_and_hold_cb; + bthf_client_clip_callback clip_cb; + bthf_client_call_waiting_callback call_waiting_cb; + bthf_client_current_calls current_calls_cb; + bthf_client_volume_change_callback volume_change_cb; + bthf_client_cmd_complete_callback cmd_complete_cb; + bthf_client_subscriber_info_callback subscriber_info_cb; + bthf_client_in_band_ring_tone_callback in_band_ring_tone_cb; + bthf_client_last_voice_tag_number_callback last_voice_tag_number_callback; + bthf_client_ring_indication_callback ring_indication_cb; + bthf_client_cgmi_indication_callback cgmi_cb; + bthf_client_cgmm_indication_callback cgmm_cb; +} bthf_client_callbacks_t; + +/** Represents the standard BT-HF interface. */ +typedef struct { + + /** set to sizeof(BtHfClientInterface) */ + size_t size; + /** + * Register the BtHf callbacks + */ + bt_status_t (*init)(bthf_client_callbacks_t* callbacks); + + /** connect to audio gateway */ + bt_status_t (*connect)(bt_bdaddr_t *bd_addr); + + /** disconnect from audio gateway */ + bt_status_t (*disconnect)(bt_bdaddr_t *bd_addr); + + /** create an audio connection */ + bt_status_t (*connect_audio)(bt_bdaddr_t *bd_addr); + + /** close the audio connection */ + bt_status_t (*disconnect_audio)(bt_bdaddr_t *bd_addr); + + /** start voice recognition */ + bt_status_t (*start_voice_recognition)(void); + + /** stop voice recognition */ + bt_status_t (*stop_voice_recognition)(void); + + /** volume control */ + bt_status_t (*volume_control) (bthf_client_volume_type_t type, int volume); + + /** place a call with number a number + * if number is NULL last called number is called (aka re-dial)*/ + bt_status_t (*dial) (const char *number); + + /** place a call with number specified by location (speed dial) */ + bt_status_t (*dial_memory) (int location); + + /** perform specified call related action + * idx is limited only for enhanced call control related action + */ + bt_status_t (*handle_call_action) (bthf_client_call_action_t action, int idx); + + /** query list of current calls */ + bt_status_t (*query_current_calls) (void); + + /** query name of current selected operator */ + bt_status_t (*query_current_operator_name) (void); + + /** Retrieve subscriber information */ + bt_status_t (*retrieve_subscriber_info) (void); + + /** Send DTMF code*/ + bt_status_t (*send_dtmf) (char code); + + /** Request a phone number from AG corresponding to last voice tag recorded */ + bt_status_t (*request_last_voice_tag_number) (void); + + /** Closes the interface. */ + void (*cleanup)(void); + + /** Send AT Command. */ + bt_status_t (*send_at_cmd) (int cmd, int val1, int val2, const char *arg); +} bthf_client_interface_t; + +__END_DECLS + +#endif /* ANDROID_INCLUDE_BT_HF_CLIENT_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_hh.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_hh.h new file mode 100644 index 00000000000000..ece3c11428db54 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_hh.h @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_BT_HH_H +#define ANDROID_INCLUDE_BT_HH_H + +#include + +__BEGIN_DECLS + +#define BTHH_MAX_DSC_LEN 884 + +/* HH connection states */ +typedef enum +{ + BTHH_CONN_STATE_CONNECTED = 0, + BTHH_CONN_STATE_CONNECTING, + BTHH_CONN_STATE_DISCONNECTED, + BTHH_CONN_STATE_DISCONNECTING, + BTHH_CONN_STATE_FAILED_MOUSE_FROM_HOST, + BTHH_CONN_STATE_FAILED_KBD_FROM_HOST, + BTHH_CONN_STATE_FAILED_TOO_MANY_DEVICES, + BTHH_CONN_STATE_FAILED_NO_BTHID_DRIVER, + BTHH_CONN_STATE_FAILED_GENERIC, + BTHH_CONN_STATE_UNKNOWN +} bthh_connection_state_t; + +typedef enum +{ + BTHH_OK = 0, + BTHH_HS_HID_NOT_READY, /* handshake error : device not ready */ + BTHH_HS_INVALID_RPT_ID, /* handshake error : invalid report ID */ + BTHH_HS_TRANS_NOT_SPT, /* handshake error : transaction not spt */ + BTHH_HS_INVALID_PARAM, /* handshake error : invalid paremter */ + BTHH_HS_ERROR, /* handshake error : unspecified HS error */ + BTHH_ERR, /* general BTA HH error */ + BTHH_ERR_SDP, /* SDP error */ + BTHH_ERR_PROTO, /* SET_Protocol error, + only used in BTA_HH_OPEN_EVT callback */ + BTHH_ERR_DB_FULL, /* device database full error, used */ + BTHH_ERR_TOD_UNSPT, /* type of device not supported */ + BTHH_ERR_NO_RES, /* out of system resources */ + BTHH_ERR_AUTH_FAILED, /* authentication fail */ + BTHH_ERR_HDL +}bthh_status_t; + +/* Protocol modes */ +typedef enum { + BTHH_REPORT_MODE = 0x00, + BTHH_BOOT_MODE = 0x01, + BTHH_UNSUPPORTED_MODE = 0xff +}bthh_protocol_mode_t; + +/* Report types */ +typedef enum { + BTHH_INPUT_REPORT = 1, + BTHH_OUTPUT_REPORT, + BTHH_FEATURE_REPORT +}bthh_report_type_t; + +typedef struct +{ + int attr_mask; + uint8_t sub_class; + uint8_t app_id; + int vendor_id; + int product_id; + int version; + uint8_t ctry_code; + int dl_len; + uint8_t dsc_list[BTHH_MAX_DSC_LEN]; +} bthh_hid_info_t; + +/** Callback for connection state change. + * state will have one of the values from bthh_connection_state_t + */ +typedef void (* bthh_connection_state_callback)(bt_bdaddr_t *bd_addr, bthh_connection_state_t state); + +/** Callback for vitual unplug api. + * the status of the vitual unplug + */ +typedef void (* bthh_virtual_unplug_callback)(bt_bdaddr_t *bd_addr, bthh_status_t hh_status); + +/** Callback for get hid info + * hid_info will contain attr_mask, sub_class, app_id, vendor_id, product_id, version, ctry_code, len + */ +typedef void (* bthh_hid_info_callback)(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info); + +/** Callback for get protocol api. + * the protocol mode is one of the value from bthh_protocol_mode_t + */ +typedef void (* bthh_protocol_mode_callback)(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, bthh_protocol_mode_t mode); + +/** Callback for get/set_idle_time api. + */ +typedef void (* bthh_idle_time_callback)(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, int idle_rate); + + +/** Callback for get report api. + * if staus is ok rpt_data contains the report data + */ +typedef void (* bthh_get_report_callback)(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, uint8_t* rpt_data, int rpt_size); + +/** Callback for set_report/set_protocol api and if error + * occurs for get_report/get_protocol api. + */ +typedef void (* bthh_handshake_callback)(bt_bdaddr_t *bd_addr, bthh_status_t hh_status); + + +/** BT-HH callback structure. */ +typedef struct { + /** set to sizeof(BtHfCallbacks) */ + size_t size; + bthh_connection_state_callback connection_state_cb; + bthh_hid_info_callback hid_info_cb; + bthh_protocol_mode_callback protocol_mode_cb; + bthh_idle_time_callback idle_time_cb; + bthh_get_report_callback get_report_cb; + bthh_virtual_unplug_callback virtual_unplug_cb; + bthh_handshake_callback handshake_cb; + +} bthh_callbacks_t; + + + +/** Represents the standard BT-HH interface. */ +typedef struct { + + /** set to sizeof(BtHhInterface) */ + size_t size; + + /** + * Register the BtHh callbacks + */ + bt_status_t (*init)( bthh_callbacks_t* callbacks ); + + /** connect to hid device */ + bt_status_t (*connect)( bt_bdaddr_t *bd_addr); + + /** dis-connect from hid device */ + bt_status_t (*disconnect)( bt_bdaddr_t *bd_addr ); + + /** Virtual UnPlug (VUP) the specified HID device */ + bt_status_t (*virtual_unplug)(bt_bdaddr_t *bd_addr); + + /** Set the HID device descriptor for the specified HID device. */ + bt_status_t (*set_info)(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info ); + + /** Get the HID proto mode. */ + bt_status_t (*get_protocol) (bt_bdaddr_t *bd_addr, bthh_protocol_mode_t protocolMode); + + /** Set the HID proto mode. */ + bt_status_t (*set_protocol)(bt_bdaddr_t *bd_addr, bthh_protocol_mode_t protocolMode); + + /** Get the HID Idle Time */ + bt_status_t (*get_idle_time)(bt_bdaddr_t *bd_addr); + + /** Set the HID Idle Time */ + bt_status_t (*set_idle_time)(bt_bdaddr_t *bd_addr, uint8_t idleTime); + + /** Send a GET_REPORT to HID device. */ + bt_status_t (*get_report)(bt_bdaddr_t *bd_addr, bthh_report_type_t reportType, uint8_t reportId, int bufferSize); + + /** Send a SET_REPORT to HID device. */ + bt_status_t (*set_report)(bt_bdaddr_t *bd_addr, bthh_report_type_t reportType, char* report); + + /** Send data to HID device. */ + bt_status_t (*send_data)(bt_bdaddr_t *bd_addr, char* data); + + /** Closes the interface. */ + void (*cleanup)( void ); + +} bthh_interface_t; +__END_DECLS + +#endif /* ANDROID_INCLUDE_BT_HH_H */ + + diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_hl.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_hl.h new file mode 100644 index 00000000000000..bd29e3abf52d70 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_hl.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_BT_HL_H +#define ANDROID_INCLUDE_BT_HL_H + +__BEGIN_DECLS + +/* HL connection states */ + +typedef enum +{ + BTHL_MDEP_ROLE_SOURCE, + BTHL_MDEP_ROLE_SINK +} bthl_mdep_role_t; + +typedef enum { + BTHL_APP_REG_STATE_REG_SUCCESS, + BTHL_APP_REG_STATE_REG_FAILED, + BTHL_APP_REG_STATE_DEREG_SUCCESS, + BTHL_APP_REG_STATE_DEREG_FAILED +} bthl_app_reg_state_t; + +typedef enum +{ + BTHL_CHANNEL_TYPE_RELIABLE, + BTHL_CHANNEL_TYPE_STREAMING, + BTHL_CHANNEL_TYPE_ANY +} bthl_channel_type_t; + + +/* HL connection states */ +typedef enum { + BTHL_CONN_STATE_CONNECTING, + BTHL_CONN_STATE_CONNECTED, + BTHL_CONN_STATE_DISCONNECTING, + BTHL_CONN_STATE_DISCONNECTED, + BTHL_CONN_STATE_DESTROYED +} bthl_channel_state_t; + +typedef struct +{ + bthl_mdep_role_t mdep_role; + int data_type; + bthl_channel_type_t channel_type; + const char *mdep_description; /* MDEP description to be used in the SDP (optional); null terminated */ +} bthl_mdep_cfg_t; + +typedef struct +{ + const char *application_name; + const char *provider_name; /* provider name to be used in the SDP (optional); null terminated */ + const char *srv_name; /* service name to be used in the SDP (optional); null terminated*/ + const char *srv_desp; /* service description to be used in the SDP (optional); null terminated */ + int number_of_mdeps; + bthl_mdep_cfg_t *mdep_cfg; /* Dynamic array */ +} bthl_reg_param_t; + +/** Callback for application registration status. + * state will have one of the values from bthl_app_reg_state_t + */ +typedef void (* bthl_app_reg_state_callback)(int app_id, bthl_app_reg_state_t state); + +/** Callback for channel connection state change. + * state will have one of the values from + * bthl_connection_state_t and fd (file descriptor) + */ +typedef void (* bthl_channel_state_callback)(int app_id, bt_bdaddr_t *bd_addr, int mdep_cfg_index, int channel_id, bthl_channel_state_t state, int fd); + +/** BT-HL callback structure. */ +typedef struct { + /** set to sizeof(bthl_callbacks_t) */ + size_t size; + bthl_app_reg_state_callback app_reg_state_cb; + bthl_channel_state_callback channel_state_cb; +} bthl_callbacks_t; + + +/** Represents the standard BT-HL interface. */ +typedef struct { + + /** set to sizeof(bthl_interface_t) */ + size_t size; + + /** + * Register the Bthl callbacks + */ + bt_status_t (*init)( bthl_callbacks_t* callbacks ); + + /** Register HL application */ + bt_status_t (*register_application) ( bthl_reg_param_t *p_reg_param, int *app_id); + + /** Unregister HL application */ + bt_status_t (*unregister_application) (int app_id); + + /** connect channel */ + bt_status_t (*connect_channel)(int app_id, bt_bdaddr_t *bd_addr, int mdep_cfg_index, int *channel_id); + + /** destroy channel */ + bt_status_t (*destroy_channel)(int channel_id); + + /** Close the Bthl callback **/ + void (*cleanup)(void); + +} bthl_interface_t; +__END_DECLS + +#endif /* ANDROID_INCLUDE_BT_HL_H */ + + diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_mce.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_mce.h new file mode 100644 index 00000000000000..5d159b336df78f --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_mce.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_BT_MCE_H +#define ANDROID_INCLUDE_BT_MCE_H + +__BEGIN_DECLS + +/** MAS instance description */ +typedef struct +{ + int id; + int scn; + int msg_types; + char *p_name; +} btmce_mas_instance_t; + +/** callback for get_remote_mas_instances */ +typedef void (*btmce_remote_mas_instances_callback)(bt_status_t status, bt_bdaddr_t *bd_addr, + int num_instances, btmce_mas_instance_t *instances); + +typedef struct { + /** set to sizeof(btmce_callbacks_t) */ + size_t size; + btmce_remote_mas_instances_callback remote_mas_instances_cb; +} btmce_callbacks_t; + +typedef struct { + /** set to size of this struct */ + size_t size; + + /** register BT MCE callbacks */ + bt_status_t (*init)(btmce_callbacks_t *callbacks); + + /** search for MAS instances on remote device */ + bt_status_t (*get_remote_mas_instances)(bt_bdaddr_t *bd_addr); +} btmce_interface_t; + +__END_DECLS + +#endif /* ANDROID_INCLUDE_BT_MCE_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_pan.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_pan.h new file mode 100644 index 00000000000000..83e7949b216d96 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_pan.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_BT_PAN_H +#define ANDROID_INCLUDE_BT_PAN_H + +__BEGIN_DECLS + +#define BTPAN_ROLE_NONE 0 +#define BTPAN_ROLE_PANNAP 1 +#define BTPAN_ROLE_PANU 2 + +typedef enum { + BTPAN_STATE_CONNECTED = 0, + BTPAN_STATE_CONNECTING = 1, + BTPAN_STATE_DISCONNECTED = 2, + BTPAN_STATE_DISCONNECTING = 3 +} btpan_connection_state_t; + +typedef enum { + BTPAN_STATE_ENABLED = 0, + BTPAN_STATE_DISABLED = 1 +} btpan_control_state_t; + +/** +* Callback for pan connection state +*/ +typedef void (*btpan_connection_state_callback)(btpan_connection_state_t state, bt_status_t error, + const bt_bdaddr_t *bd_addr, int local_role, int remote_role); +typedef void (*btpan_control_state_callback)(btpan_control_state_t state, int local_role, + bt_status_t error, const char* ifname); + +typedef struct { + size_t size; + btpan_control_state_callback control_state_cb; + btpan_connection_state_callback connection_state_cb; +} btpan_callbacks_t; +typedef struct { + /** set to size of this struct*/ + size_t size; + /** + * Initialize the pan interface and register the btpan callbacks + */ + bt_status_t (*init)(const btpan_callbacks_t* callbacks); + /* + * enable the pan service by specified role. The result state of + * enabl will be returned by btpan_control_state_callback. when pan-nap is enabled, + * the state of connecting panu device will be notified by btpan_connection_state_callback + */ + bt_status_t (*enable)(int local_role); + /* + * get current pan local role + */ + int (*get_local_role)(void); + /** + * start bluetooth pan connection to the remote device by specified pan role. The result state will be + * returned by btpan_connection_state_callback + */ + bt_status_t (*connect)(const bt_bdaddr_t *bd_addr, int local_role, int remote_role); + /** + * stop bluetooth pan connection. The result state will be returned by btpan_connection_state_callback + */ + bt_status_t (*disconnect)(const bt_bdaddr_t *bd_addr); + + /** + * Cleanup the pan interface + */ + void (*cleanup)(void); + +} btpan_interface_t; + +__END_DECLS + +#endif /* ANDROID_INCLUDE_BT_PAN_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_rc.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_rc.h new file mode 100644 index 00000000000000..6e1109d3817632 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_rc.h @@ -0,0 +1,527 @@ +/* + * Copyright (C) 2013-2014, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_BT_RC_H +#define ANDROID_INCLUDE_BT_RC_H + +__BEGIN_DECLS + +/* Macros */ +#define BTRC_MAX_ATTR_STR_LEN 255 +#define BTRC_UID_SIZE 8 +#define BTRC_MAX_APP_SETTINGS 8 +#define BTRC_MAX_FOLDER_DEPTH 4 +#define BTRC_MAX_APP_ATTR_SIZE 16 +#define BTRC_MAX_ELEM_ATTR_SIZE 7 +#define BTRC_CHARSET_UTF8 0x006A + +typedef uint8_t btrc_uid_t[BTRC_UID_SIZE]; + +typedef enum { + BTRC_FEAT_NONE = 0x00, /* AVRCP 1.0 */ + BTRC_FEAT_METADATA = 0x01, /* AVRCP 1.3 */ + BTRC_FEAT_ABSOLUTE_VOLUME = 0x02, /* Supports TG role and volume sync */ + BTRC_FEAT_BROWSE = 0x04, /* AVRCP 1.4 and up, with Browsing support */ +} btrc_remote_features_t; + +typedef enum { + BTRC_PLAYSTATE_STOPPED = 0x00, /* Stopped */ + BTRC_PLAYSTATE_PLAYING = 0x01, /* Playing */ + BTRC_PLAYSTATE_PAUSED = 0x02, /* Paused */ + BTRC_PLAYSTATE_FWD_SEEK = 0x03, /* Fwd Seek*/ + BTRC_PLAYSTATE_REV_SEEK = 0x04, /* Rev Seek*/ + BTRC_PLAYSTATE_ERROR = 0xFF, /* Error */ +} btrc_play_status_t; + +typedef enum { + BTRC_EVT_PLAY_STATUS_CHANGED = 0x01, + BTRC_EVT_TRACK_CHANGE = 0x02, + BTRC_EVT_TRACK_REACHED_END = 0x03, + BTRC_EVT_TRACK_REACHED_START = 0x04, + BTRC_EVT_PLAY_POS_CHANGED = 0x05, + BTRC_EVT_APP_SETTINGS_CHANGED = 0x08, + BTRC_EVT_NOW_PLAYING_CONTENT_CHANGED = 0x09, + BTRC_EVT_AVAILABLE_PLAYERS_CHANGED = 0x0a, + BTRC_EVT_ADDRESSED_PLAYER_CHANGED = 0x0b, +} btrc_event_id_t; + +//used for Scope +typedef enum { + BTRC_EVT_MEDIA_PLAYLIST = 0, + BTRC_EVT_MEDIA_VIRTUALFILESYST = 1, + BTRC_EVT_SEARCH = 2, + BTRC_EVT_NOWPLAYING = 3, + BTRC_EVT_MAX_BROWSE = 4, +} btrc_browse_folderitem_t; + +typedef enum { + BTRC_NOTIFICATION_TYPE_INTERIM = 0, + BTRC_NOTIFICATION_TYPE_CHANGED = 1, + BTRC_NOTIFICATION_TYPE_REJECT = 2, +} btrc_notification_type_t; + +typedef enum { + BTRC_PLAYER_ATTR_EQUALIZER = 0x01, + BTRC_PLAYER_ATTR_REPEAT = 0x02, + BTRC_PLAYER_ATTR_SHUFFLE = 0x03, + BTRC_PLAYER_ATTR_SCAN = 0x04, +} btrc_player_attr_t; + +typedef enum { + BTRC_MEDIA_ATTR_TITLE = 0x01, + BTRC_MEDIA_ATTR_ARTIST = 0x02, + BTRC_MEDIA_ATTR_ALBUM = 0x03, + BTRC_MEDIA_ATTR_TRACK_NUM = 0x04, + BTRC_MEDIA_ATTR_NUM_TRACKS = 0x05, + BTRC_MEDIA_ATTR_GENRE = 0x06, + BTRC_MEDIA_ATTR_PLAYING_TIME = 0x07, +} btrc_media_attr_t; + +typedef enum { + BTRC_PLAYER_VAL_OFF_REPEAT = 0x01, + BTRC_PLAYER_VAL_SINGLE_REPEAT = 0x02, + BTRC_PLAYER_VAL_ALL_REPEAT = 0x03, + BTRC_PLAYER_VAL_GROUP_REPEAT = 0x04 +} btrc_player_repeat_val_t; + +typedef enum { + BTRC_PLAYER_VAL_OFF_SHUFFLE = 0x01, + BTRC_PLAYER_VAL_ALL_SHUFFLE = 0x02, + BTRC_PLAYER_VAL_GROUP_SHUFFLE = 0x03 +} btrc_player_shuffle_val_t; + +typedef enum { + BTRC_STS_BAD_CMD = 0x00, /* Invalid command */ + BTRC_STS_BAD_PARAM = 0x01, /* Invalid parameter */ + BTRC_STS_NOT_FOUND = 0x02, /* Specified parameter is wrong or not found */ + BTRC_STS_INTERNAL_ERR = 0x03, /* Internal Error */ + BTRC_STS_NO_ERROR = 0x04 /* Operation Success */ +} btrc_status_t; + +typedef enum { + BTRC_TYPE_MEDIA_PLAYER = 0x01, + BTRC_TYPE_FOLDER = 0x02, + BTRC_TYPE_MEDIA_ELEMENT = 0x03 +} btrc_folder_list_item_type_t; + +typedef struct { + uint8_t num_attr; + uint8_t attr_ids[BTRC_MAX_APP_SETTINGS]; + uint8_t attr_values[BTRC_MAX_APP_SETTINGS]; +} btrc_player_settings_t; + +typedef struct { + uint32_t start_item; + uint32_t end_item; + uint32_t size; + uint32_t attrs[BTRC_MAX_ELEM_ATTR_SIZE]; + uint8_t attr_count; +}btrc_getfolderitem_t; + +typedef union +{ + btrc_play_status_t play_status; + btrc_uid_t track; /* queue position in NowPlaying */ + uint32_t song_pos; + btrc_player_settings_t player_setting; + uint16_t player_id; +} btrc_register_notification_t; + +typedef struct { + uint8_t id; /* can be attr_id or value_id */ + uint8_t text[BTRC_MAX_ATTR_STR_LEN]; +} btrc_player_setting_text_t; + +typedef struct { + uint32_t attr_id; + uint8_t text[BTRC_MAX_ATTR_STR_LEN]; +} btrc_element_attr_val_t; + +/** Callback for the controller's supported feautres */ +typedef void (* btrc_remote_features_callback)(bt_bdaddr_t *bd_addr, + btrc_remote_features_t features); +#define BTRC_FEATURE_MASK_SIZE 16 + +typedef uint8_t btrc_feature_mask_t[BTRC_FEATURE_MASK_SIZE]; + +typedef struct { + uint16_t charset_id; + uint16_t str_len; + uint8_t *p_str; +} btrc_player_full_name_t; + +typedef struct +{ + uint32_t sub_type; + uint16_t player_id; + uint8_t major_type; + uint8_t play_status; + btrc_feature_mask_t features; /* Supported feature bit mask*/ + btrc_player_full_name_t name; /* The player name, name length and character set id.*/ +} btrc_folder_list_item_player_t; + +typedef struct +{ + uint64_t uid; + uint8_t type; + uint8_t playable; + btrc_player_full_name_t name; +} btrc_folder_list_item_folder_t; + +typedef struct +{ + uint32_t attr_id; + btrc_player_full_name_t name; +} btrc_attr_entry_t; + +typedef struct +{ + uint64_t uid; + uint8_t type; + uint8_t attr_count; + btrc_player_full_name_t name; + btrc_attr_entry_t* p_attr_list; +} btrc_folder_list_item_media_t; + +typedef struct { + uint16_t str_len; + uint8_t *p_str; +} btrc_name_t; + +/* SetBrowsedPlayer */ +typedef struct +{ + uint32_t num_items; + uint16_t uid_counter; + uint16_t charset_id; + uint8_t status; + uint8_t folder_depth; + btrc_name_t *p_folders; +} btrc_set_browsed_player_rsp_t; + +typedef struct +{ + uint8_t item_type; + union + { + btrc_folder_list_item_player_t player; + btrc_folder_list_item_folder_t folder; + btrc_folder_list_item_media_t media; + } u; +} btrc_folder_list_item_t; + +/* GetFolderItems */ +typedef struct +{ + uint16_t uid_counter; + uint16_t item_count; + uint8_t status; + btrc_folder_list_item_t *p_item_list; +} btrc_folder_list_entries_t; + +/** Callback for play status request */ +typedef void (* btrc_get_play_status_callback)(bt_bdaddr_t *bd_addr); + +/** Callback for list player application attributes (Shuffle, Repeat,...) */ +typedef void (* btrc_list_player_app_attr_callback)(bt_bdaddr_t *bd_addr); + +/** Callback for list player application attributes (Shuffle, Repeat,...) */ +typedef void (* btrc_list_player_app_values_callback)(btrc_player_attr_t attr_id, + bt_bdaddr_t *bd_addr); + +/** Callback for getting the current player application settings value +** num_attr: specifies the number of attribute ids contained in p_attrs +*/ +typedef void (* btrc_get_player_app_value_callback) (uint8_t num_attr, btrc_player_attr_t *p_attrs, + bt_bdaddr_t *bd_addr); + +/** Callback for getting the player application settings attributes' text +** num_attr: specifies the number of attribute ids contained in p_attrs +*/ +typedef void (* btrc_get_player_app_attrs_text_callback) (uint8_t num_attr, + btrc_player_attr_t *p_attrs, bt_bdaddr_t *bd_addr); + +/** Callback for getting the player application settings values' text +** num_attr: specifies the number of value ids contained in p_vals +*/ +typedef void (* btrc_get_player_app_values_text_callback) (uint8_t attr_id, + uint8_t num_val, uint8_t *p_vals, bt_bdaddr_t *bd_addr); + +/** Callback for setting the player application settings values */ +typedef void (* btrc_set_player_app_value_callback) (btrc_player_settings_t *p_vals, + bt_bdaddr_t *bd_addr); + +/** Callback to fetch the get element attributes of the current song +** num_attr: specifies the number of attributes requested in p_attrs +*/ +typedef void (* btrc_get_element_attr_callback) (uint8_t num_attr, btrc_media_attr_t *p_attrs, + bt_bdaddr_t *bd_addr); + +/** Callback for register notification (Play state change/track change/...) +** param: Is only valid if event_id is BTRC_EVT_PLAY_POS_CHANGED +*/ +typedef void (* btrc_register_notification_callback) (btrc_event_id_t event_id, uint32_t param, + bt_bdaddr_t *bd_addr); + +/* AVRCP 1.4 Enhancements */ +/** Callback for volume change on CT +** volume: Current volume setting on the CT (0-127) +*/ +typedef void (* btrc_volume_change_callback) (uint8_t volume, uint8_t ctype, bt_bdaddr_t *bd_addr); + +/** Callback for passthrough commands */ +typedef void (* btrc_passthrough_cmd_callback) (int id, int key_state, bt_bdaddr_t *bd_addr); + +/** BT-RC Target callback structure. */ + +typedef void (* btrc_get_folder_items_callback) (btrc_browse_folderitem_t id, + btrc_getfolderitem_t *param, bt_bdaddr_t *bd_addr); + +typedef void (* btrc_set_addressed_player_callback) (uint32_t player_id, bt_bdaddr_t *bd_addr); + +typedef void (* btrc_set_browsed_player_callback) (uint32_t player_id, bt_bdaddr_t *bd_addr); + +typedef void (* btrc_change_path_callback) (uint8_t direction, uint64_t uid, bt_bdaddr_t *bd_addr); + +typedef void (* btrc_play_item_callback) (uint8_t scope, uint64_t uid, bt_bdaddr_t *bd_addr); + +typedef void (* btrc_get_item_attr_callback) (uint8_t scope, uint64_t uid, + uint8_t num_attr, btrc_media_attr_t *p_attrs, bt_bdaddr_t *bd_addr); + +typedef void (* btrc_connection_state_callback) (bool state, bt_bdaddr_t *bd_addr); + +typedef struct { + /** set to sizeof(BtRcCallbacks) */ + size_t size; + btrc_remote_features_callback remote_features_cb; + btrc_get_play_status_callback get_play_status_cb; + btrc_list_player_app_attr_callback list_player_app_attr_cb; + btrc_list_player_app_values_callback list_player_app_values_cb; + btrc_get_player_app_value_callback get_player_app_value_cb; + btrc_get_player_app_attrs_text_callback get_player_app_attrs_text_cb; + btrc_get_player_app_values_text_callback get_player_app_values_text_cb; + btrc_set_player_app_value_callback set_player_app_value_cb; + btrc_get_element_attr_callback get_element_attr_cb; + btrc_register_notification_callback register_notification_cb; + btrc_volume_change_callback volume_change_cb; + btrc_passthrough_cmd_callback passthrough_cmd_cb; + btrc_get_folder_items_callback get_folderitems_cb; + btrc_set_addressed_player_callback set_addrplayer_cb; + btrc_set_browsed_player_callback set_browsed_player_cb; + btrc_change_path_callback change_path_cb; + btrc_play_item_callback play_item_cb; + btrc_get_item_attr_callback get_item_attr_cb; + btrc_connection_state_callback connection_state_cb; +} btrc_callbacks_t; + +/** Represents the standard BT-RC AVRCP Target interface. */ +typedef struct { + + /** set to sizeof(BtRcInterface) */ + size_t size; + /** + * Register the BtRc callbacks + */ + bt_status_t (*init)( btrc_callbacks_t* callbacks , int max_avrcp_connections); + + /** Respose to GetPlayStatus request. Contains the current + ** 1. Play status + ** 2. Song duration/length + ** 3. Song position + */ + bt_status_t (*get_play_status_rsp)( btrc_play_status_t play_status, uint32_t song_len, + uint32_t song_pos, bt_bdaddr_t *bd_addr); + + /** Lists the support player application attributes (Shuffle/Repeat/...) + ** num_attr: Specifies the number of attributes contained in the pointer p_attrs + */ + bt_status_t (*list_player_app_attr_rsp)( uint8_t num_attr, btrc_player_attr_t *p_attrs, + bt_bdaddr_t *bd_addr); + + /** Lists the support player application attributes (Shuffle Off/On/Group) + ** num_val: Specifies the number of values contained in the pointer p_vals + */ + bt_status_t (*list_player_app_value_rsp)( uint8_t num_val, uint8_t *p_vals, + bt_bdaddr_t *bd_addr); + + /** Returns the current application attribute values for each of the specified attr_id */ + bt_status_t (*get_player_app_value_rsp)( btrc_player_settings_t *p_vals, + bt_bdaddr_t *bd_addr); + + /** Returns the application attributes text ("Shuffle"/"Repeat"/...) + ** num_attr: Specifies the number of attributes' text contained in the pointer p_attrs + */ + bt_status_t (*get_player_app_attr_text_rsp)( int num_attr, btrc_player_setting_text_t *p_attrs, + bt_bdaddr_t *bd_addr); + + /** Returns the application attributes text ("Shuffle"/"Repeat"/...) + ** num_attr: Specifies the number of attribute values' text contained in the pointer p_vals + */ + bt_status_t (*get_player_app_value_text_rsp)( int num_val, btrc_player_setting_text_t *p_vals, + bt_bdaddr_t *bd_addr); + + /** Returns the current songs' element attributes text ("Title"/"Album"/"Artist") + ** num_attr: Specifies the number of attributes' text contained in the pointer p_attrs + */ + bt_status_t (*get_element_attr_rsp)( uint8_t num_attr, btrc_element_attr_val_t *p_attrs, + bt_bdaddr_t *bd_addr); + + /** Response to set player attribute request ("Shuffle"/"Repeat") + ** rsp_status: Status of setting the player attributes for the current media player + */ + bt_status_t (*set_player_app_value_rsp)(btrc_status_t rsp_status, bt_bdaddr_t *bd_addr); + + /* Response to the register notification request (Play state change/track change/...). + ** event_id: Refers to the event_id this notification change corresponds too + ** type: Response type - interim/changed + ** p_params: Based on the event_id, this parameter should be populated + */ + bt_status_t (*register_notification_rsp)(btrc_event_id_t event_id, + btrc_notification_type_t type, + btrc_register_notification_t *p_param, + bt_bdaddr_t *bd_addr); + + /* AVRCP 1.4 enhancements */ + + /**Send current volume setting to remote side. Support limited to SetAbsoluteVolume + ** This can be enhanced to support Relative Volume (AVRCP 1.0). + ** With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN opposed to absolute volume level + ** volume: Should be in the range 0-127. bit7 is reseved and cannot be set + */ + bt_status_t (*set_volume)(uint8_t volume, bt_bdaddr_t *bd_addr); + bt_status_t (*get_folder_items_rsp) (btrc_folder_list_entries_t *p_param, bt_bdaddr_t *bd_addr); + + bt_status_t (*set_addressed_player_rsp) (btrc_status_t status_code, bt_bdaddr_t *bd_addr); + bt_status_t (*set_browsed_player_rsp) (btrc_set_browsed_player_rsp_t *p_param, + bt_bdaddr_t *bd_addr); + bt_status_t (*change_path_rsp) (uint8_t status_code, uint32_t item_count, + bt_bdaddr_t *bd_addr); + bt_status_t (*play_item_rsp) (uint8_t status_code, bt_bdaddr_t *bd_addr); + bt_status_t (*get_item_attr_rsp)( uint8_t num_attr, btrc_element_attr_val_t *p_attrs, + bt_bdaddr_t *bd_addr); + bt_status_t (*is_device_active_in_handoff) (bt_bdaddr_t *bd_addr); + + /** Closes the interface. */ + void (*cleanup)( void ); +} btrc_interface_t; + + +typedef void (* btrc_passthrough_rsp_callback) (int id, int key_state); + +typedef void (* btrc_connection_state_callback) (bool state, bt_bdaddr_t *bd_addr); + +typedef void (* btrc_ctrl_getrcfeatures_callback) (bt_bdaddr_t *bd_addr, int features); + +typedef void (* btrc_ctrl_getcapability_rsp_callback) (bt_bdaddr_t *bd_addr, int cap_id, + uint32_t* supported_values, int num_supported, uint8_t rsp_type); + +typedef void (* btrc_ctrl_listplayerappsettingattrib_rsp_callback) (bt_bdaddr_t *bd_addr, + uint8_t* supported_attribs, int num_attrib, uint8_t rsp_type); + +typedef void (* btrc_ctrl_listplayerappsettingvalue_rsp_callback) (bt_bdaddr_t *bd_addr, + uint8_t* supported_val, uint8_t num_supported, uint8_t rsp_type); + +typedef void (* btrc_ctrl_currentplayerappsetting_rsp_callback) (bt_bdaddr_t *bd_addr,uint8_t* supported_ids, + uint8_t* supported_val, uint8_t num_attrib, uint8_t rsp_type); + +typedef void (* btrc_ctrl_setplayerapplicationsetting_rsp_callback) (bt_bdaddr_t *bd_addr,uint8_t rsp_type); + +typedef void (* btrc_ctrl_notification_rsp_callback) (bt_bdaddr_t *bd_addr, uint8_t rsp_type, + int rsp_len, uint8_t* notification_rsp); + +typedef void (* btrc_ctrl_getelementattrib_rsp_callback) (bt_bdaddr_t *bd_addr, uint8_t num_attributes, + int rsp_len, uint8_t* attrib_rsp, uint8_t rsp_type); + +typedef void (* btrc_ctrl_getplaystatus_rsp_callback) (bt_bdaddr_t *bd_addr, int param_len, uint8_t* play_status_rsp + ,uint8_t rsp_type); + +typedef void (* btrc_ctrl_setabsvol_cmd_callback) (bt_bdaddr_t *bd_addr, uint8_t abs_vol); + +typedef void (* btrc_ctrl_registernotification_abs_vol_callback) (bt_bdaddr_t *bd_addr); +/** BT-RC Controller callback structure. */ +typedef struct { + /** set to sizeof(BtRcCallbacks) */ + size_t size; + btrc_passthrough_rsp_callback passthrough_rsp_cb; + btrc_connection_state_callback connection_state_cb; + btrc_ctrl_getrcfeatures_callback getrcfeatures_cb; + btrc_ctrl_getcapability_rsp_callback getcap_rsp_cb; + btrc_ctrl_listplayerappsettingattrib_rsp_callback listplayerappsettingattrib_rsp_cb; + btrc_ctrl_listplayerappsettingvalue_rsp_callback listplayerappsettingvalue_rsp_cb; + btrc_ctrl_currentplayerappsetting_rsp_callback currentplayerappsetting_rsp_cb; + btrc_ctrl_setplayerapplicationsetting_rsp_callback setplayerappsetting_rsp_cb; + btrc_ctrl_notification_rsp_callback notification_rsp_cb; + btrc_ctrl_getelementattrib_rsp_callback getelementattrib_rsp_cb; + btrc_ctrl_getplaystatus_rsp_callback getplaystatus_rsp_cb; + btrc_ctrl_setabsvol_cmd_callback setabsvol_cmd_cb; + btrc_ctrl_registernotification_abs_vol_callback registernotification_absvol_cb; +} btrc_ctrl_callbacks_t; + +/** Represents the standard BT-RC AVRCP Controller interface. */ +typedef struct { + + /** set to sizeof(BtRcInterface) */ + size_t size; + /** + * Register the BtRc callbacks + */ + bt_status_t (*init)( btrc_ctrl_callbacks_t* callbacks ); + + /** send pass through command to target */ + bt_status_t (*send_pass_through_cmd) ( bt_bdaddr_t *bd_addr, uint8_t key_code, + uint8_t key_state ); + + /** send get_cap command to target */ + bt_status_t (*getcapabilities_cmd) (uint8_t cap_id); + + /** send command to get supported player application settings to target */ + bt_status_t (*list_player_app_setting_attrib_cmd) (void); + + /** send command to get supported values of player application settings for a + * particular attribute to target */ + bt_status_t (*list_player_app_setting_value_cmd) (uint8_t attrib_id); + + /** send command to get current player attributes to target */ + bt_status_t (*get_player_app_setting_cmd) (uint8_t num_attrib, uint8_t* attrib_ids); + + /** send command to set player applicaiton setting attributes to target */ + bt_status_t (*set_player_app_setting_cmd) (uint8_t num_attrib, uint8_t* attrib_ids, uint8_t* attrib_vals); + + /** send command to register for supported notificaiton events to target */ + bt_status_t (*register_notification_cmd) (uint8_t event_id, uint32_t event_value); + + /** send command to get element attribute to target */ + bt_status_t (*get_element_attribute_cmd) (uint8_t num_attribute, uint32_t attribute_id); + + /** send command to get play status to target */ + bt_status_t (*get_play_status_cmd) (void); + + /** send rsp to set_abs_vol received from target */ + bt_status_t (*send_abs_vol_rsp) (uint8_t abs_vol); + + /** send notificaiton rsp for abs vol to target */ + bt_status_t (*send_register_abs_vol_rsp) (uint8_t rsp_type, uint8_t abs_vol); + + /** Closes the interface. */ + void (*cleanup)( void ); +} btrc_ctrl_interface_t; + +__END_DECLS + +#endif /* ANDROID_INCLUDE_BT_RC_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_sdp.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_sdp.h new file mode 100644 index 00000000000000..8f39bc5bdc467c --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_sdp.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "bluetooth.h" + +#define SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH 15 + +__BEGIN_DECLS + +/** + * These events are handled by the state machine + */ +typedef enum { + SDP_TYPE_RAW, // Used to carry raw SDP search data for unknown UUIDs + SDP_TYPE_MAP_MAS, // Message Access Profile - Server + SDP_TYPE_MAP_MNS, // Message Access Profile - Client (Notification Server) + SDP_TYPE_PBAP_PSE, // Phone Book Profile - Server + SDP_TYPE_PBAP_PCE, // Phone Book Profile - Client + SDP_TYPE_OPP_SERVER, // Object Push Profile + SDP_TYPE_SAP_SERVER // SIM Access Profile +} bluetooth_sdp_types; + +typedef struct _bluetooth_sdp_hdr { + bluetooth_sdp_types type; + bt_uuid_t uuid; + uint32_t service_name_length; + char *service_name; + int32_t rfcomm_channel_number; + int32_t l2cap_psm; + int32_t profile_version; +} bluetooth_sdp_hdr; + +/** + * Some signals need additional pointers, hence we introduce a + * generic way to handle these pointers. + */ +typedef struct _bluetooth_sdp_hdr_overlay { + bluetooth_sdp_types type; + bt_uuid_t uuid; + uint32_t service_name_length; + char *service_name; + int32_t rfcomm_channel_number; + int32_t l2cap_psm; + int32_t profile_version; + + // User pointers, only used for some signals - see bluetooth_sdp_ops_record + int user1_ptr_len; + uint8_t *user1_ptr; + int user2_ptr_len; + uint8_t *user2_ptr; +} bluetooth_sdp_hdr_overlay; + +typedef struct _bluetooth_sdp_mas_record { + bluetooth_sdp_hdr_overlay hdr; + uint32_t mas_instance_id; + uint32_t supported_features; + uint32_t supported_message_types; +} bluetooth_sdp_mas_record; + +typedef struct _bluetooth_sdp_mns_record { + bluetooth_sdp_hdr_overlay hdr; + uint32_t supported_features; +} bluetooth_sdp_mns_record; + +typedef struct _bluetooth_sdp_pse_record { + bluetooth_sdp_hdr_overlay hdr; + uint32_t supported_features; + uint32_t supported_repositories; +} bluetooth_sdp_pse_record; + +typedef struct _bluetooth_sdp_pce_record { + bluetooth_sdp_hdr_overlay hdr; +} bluetooth_sdp_pce_record; + +typedef struct _bluetooth_sdp_ops_record { + bluetooth_sdp_hdr_overlay hdr; + int supported_formats_list_len; + uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH]; +} bluetooth_sdp_ops_record; + +typedef struct _bluetooth_sdp_sap_record { + bluetooth_sdp_hdr_overlay hdr; +} bluetooth_sdp_sap_record; + +typedef union { + bluetooth_sdp_hdr_overlay hdr; + bluetooth_sdp_mas_record mas; + bluetooth_sdp_mns_record mns; + bluetooth_sdp_pse_record pse; + bluetooth_sdp_pce_record pce; + bluetooth_sdp_ops_record ops; + bluetooth_sdp_sap_record sap; +} bluetooth_sdp_record; + + +/** Callback for SDP search */ +typedef void (*btsdp_search_callback)(bt_status_t status, bt_bdaddr_t *bd_addr, uint8_t* uuid, int num_records, bluetooth_sdp_record *records); + +typedef struct { + /** Set to sizeof(btsdp_callbacks_t) */ + size_t size; + btsdp_search_callback sdp_search_cb; +} btsdp_callbacks_t; + +typedef struct { + /** Set to size of this struct */ + size_t size; + + /** Register BT SDP search callbacks */ + bt_status_t (*init)(btsdp_callbacks_t *callbacks); + + /** Unregister BT SDP */ + bt_status_t (*deinit)(); + + /** Search for SDP records with specific uuid on remote device */ + bt_status_t (*sdp_search)(bt_bdaddr_t *bd_addr, const uint8_t* uuid); + + /** + * Use listen in the socket interface to create rfcomm and/or l2cap PSM channels, + * (without UUID and service_name and set the BTSOCK_FLAG_NO_SDP flag in flags). + * Then use createSdpRecord to create the SDP record associated with the rfcomm/l2cap channels. + * + * Returns a handle to the SDP record, which can be parsed to remove_sdp_record. + * + * record (in) The SDP record to create + * record_handle (out)The corresponding record handle will be written to this pointer. + */ + bt_status_t (*create_sdp_record)(bluetooth_sdp_record *record, int* record_handle); + + /** Remove a SDP record created by createSdpRecord */ + bt_status_t (*remove_sdp_record)(int sdp_handle); +} btsdp_interface_t; + +__END_DECLS + diff --git a/phonelibs/android_hardware_libhardware/include/hardware/bt_sock.h b/phonelibs/android_hardware_libhardware/include/hardware/bt_sock.h new file mode 100644 index 00000000000000..9dd83bb1c9f9f2 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/bt_sock.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +__BEGIN_DECLS + +#define BTSOCK_FLAG_ENCRYPT 1 +#define BTSOCK_FLAG_AUTH (1 << 1) +#define BTSOCK_FLAG_NO_SDP (1 << 2) +#define BTSOCK_FLAG_AUTH_MITM (1 << 3) +#define BTSOCK_FLAG_AUTH_16_DIGIT (1 << 4) + +typedef enum { + BTSOCK_RFCOMM = 1, + BTSOCK_SCO = 2, + BTSOCK_L2CAP = 3 +} btsock_type_t; + +typedef enum { + BTSOCK_OPT_GET_MODEM_BITS = 1, + BTSOCK_OPT_SET_MODEM_BITS = 2, + BTSOCK_OPT_CLR_MODEM_BITS = 3, +} btsock_option_type_t; + +/** Represents the standard BT SOCKET interface. */ +typedef struct { + short size; + bt_bdaddr_t bd_addr; + int channel; + int status; + + // The writer must make writes using a buffer of this maximum size + // to avoid loosing data. (L2CAP only) + unsigned short max_tx_packet_size; + + // The reader must read using a buffer of at least this size to avoid + // loosing data. (L2CAP only) + unsigned short max_rx_packet_size; +} __attribute__((packed)) sock_connect_signal_t; + +typedef struct { + /** set to size of this struct*/ + size_t size; + + /** + * Listen to a RFCOMM UUID or channel. It returns the socket fd from which + * btsock_connect_signal can be read out when a remote device connected. + * If neither a UUID nor a channel is provided, a channel will be allocated + * and a service record can be created providing the channel number to + * create_sdp_record(...) in bt_sdp. + */ + bt_status_t (*listen)(btsock_type_t type, const char* service_name, + const uint8_t* service_uuid, int channel, int* sock_fd, int flags); + + /** + * Connect to a RFCOMM UUID channel of remote device, It returns the socket fd from which + * the btsock_connect_signal and a new socket fd to be accepted can be read out when connected + */ + bt_status_t (*connect)(const bt_bdaddr_t *bd_addr, btsock_type_t type, const uint8_t* uuid, + int channel, int* sock_fd, int flags); + + /* + * get socket option of rfcomm channel socket. + */ + bt_status_t (*get_sock_opt)(btsock_type_t type, int channel, btsock_option_type_t option_name, + void *option_value, int *option_len); + /* + + * set socket option of rfcomm channel socket. + */ + bt_status_t (*set_sock_opt)(btsock_type_t type, int channel, btsock_option_type_t option_name, + void *option_value, int option_len); + +} btsock_interface_t; + +__END_DECLS + diff --git a/phonelibs/android_hardware_libhardware/include/hardware/camera.h b/phonelibs/android_hardware_libhardware/include/hardware/camera.h new file mode 100644 index 00000000000000..b1f18fffce38f3 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/camera.h @@ -0,0 +1,298 @@ +/* + * Copyright (C) 2010-2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_CAMERA_H +#define ANDROID_INCLUDE_CAMERA_H + +#include "camera_common.h" + +/** + * Camera device HAL, initial version [ CAMERA_DEVICE_API_VERSION_1_0 ] + * + * DEPRECATED. New devices should use Camera HAL v3.2 or newer. + * + * Supports the android.hardware.Camera API, and the android.hardware.camera2 + * API in legacy mode only. + * + * Camera devices that support this version of the HAL must return a value in + * the range HARDWARE_DEVICE_API_VERSION(0,0)-(1,FF) in + * camera_device_t.common.version. CAMERA_DEVICE_API_VERSION_1_0 is the + * recommended value. + * + * Camera modules that implement version 2.0 or higher of camera_module_t must + * also return the value of camera_device_t.common.version in + * camera_info_t.device_version. + * + * See camera_common.h for more details. + */ + +__BEGIN_DECLS + +struct camera_memory; +typedef void (*camera_release_memory)(struct camera_memory *mem); + +typedef struct camera_memory { + void *data; + size_t size; + void *handle; + camera_release_memory release; +} camera_memory_t; + +typedef camera_memory_t* (*camera_request_memory)(int fd, size_t buf_size, unsigned int num_bufs, + void *user); + +typedef void (*camera_notify_callback)(int32_t msg_type, + int32_t ext1, + int32_t ext2, + void *user); + +typedef void (*camera_data_callback)(int32_t msg_type, + const camera_memory_t *data, unsigned int index, + camera_frame_metadata_t *metadata, void *user); + +typedef void (*camera_data_timestamp_callback)(int64_t timestamp, + int32_t msg_type, + const camera_memory_t *data, unsigned int index, + void *user); + +#define HAL_CAMERA_PREVIEW_WINDOW_TAG 0xcafed00d + +typedef struct preview_stream_ops { + int (*dequeue_buffer)(struct preview_stream_ops* w, + buffer_handle_t** buffer, int *stride); + int (*enqueue_buffer)(struct preview_stream_ops* w, + buffer_handle_t* buffer); + int (*cancel_buffer)(struct preview_stream_ops* w, + buffer_handle_t* buffer); + int (*set_buffer_count)(struct preview_stream_ops* w, int count); + int (*set_buffers_geometry)(struct preview_stream_ops* pw, + int w, int h, int format); + int (*set_crop)(struct preview_stream_ops *w, + int left, int top, int right, int bottom); + int (*set_usage)(struct preview_stream_ops* w, int usage); + int (*set_swap_interval)(struct preview_stream_ops *w, int interval); + int (*get_min_undequeued_buffer_count)(const struct preview_stream_ops *w, + int *count); + int (*lock_buffer)(struct preview_stream_ops* w, + buffer_handle_t* buffer); + // Timestamps are measured in nanoseconds, and must be comparable + // and monotonically increasing between two frames in the same + // preview stream. They do not need to be comparable between + // consecutive or parallel preview streams, cameras, or app runs. + int (*set_timestamp)(struct preview_stream_ops *w, int64_t timestamp); +} preview_stream_ops_t; + +struct camera_device; +typedef struct camera_device_ops { + /** Set the ANativeWindow to which preview frames are sent */ + int (*set_preview_window)(struct camera_device *, + struct preview_stream_ops *window); + + /** Set the notification and data callbacks */ + void (*set_callbacks)(struct camera_device *, + camera_notify_callback notify_cb, + camera_data_callback data_cb, + camera_data_timestamp_callback data_cb_timestamp, + camera_request_memory get_memory, + void *user); + + /** + * The following three functions all take a msg_type, which is a bitmask of + * the messages defined in include/ui/Camera.h + */ + + /** + * Enable a message, or set of messages. + */ + void (*enable_msg_type)(struct camera_device *, int32_t msg_type); + + /** + * Disable a message, or a set of messages. + * + * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera + * HAL should not rely on its client to call releaseRecordingFrame() to + * release video recording frames sent out by the cameral HAL before and + * after the disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera HAL + * clients must not modify/access any video recording frame after calling + * disableMsgType(CAMERA_MSG_VIDEO_FRAME). + */ + void (*disable_msg_type)(struct camera_device *, int32_t msg_type); + + /** + * Query whether a message, or a set of messages, is enabled. Note that + * this is operates as an AND, if any of the messages queried are off, this + * will return false. + */ + int (*msg_type_enabled)(struct camera_device *, int32_t msg_type); + + /** + * Start preview mode. + */ + int (*start_preview)(struct camera_device *); + + /** + * Stop a previously started preview. + */ + void (*stop_preview)(struct camera_device *); + + /** + * Returns true if preview is enabled. + */ + int (*preview_enabled)(struct camera_device *); + + /** + * Request the camera HAL to store meta data or real YUV data in the video + * buffers sent out via CAMERA_MSG_VIDEO_FRAME for a recording session. If + * it is not called, the default camera HAL behavior is to store real YUV + * data in the video buffers. + * + * This method should be called before startRecording() in order to be + * effective. + * + * If meta data is stored in the video buffers, it is up to the receiver of + * the video buffers to interpret the contents and to find the actual frame + * data with the help of the meta data in the buffer. How this is done is + * outside of the scope of this method. + * + * Some camera HALs may not support storing meta data in the video buffers, + * but all camera HALs should support storing real YUV data in the video + * buffers. If the camera HAL does not support storing the meta data in the + * video buffers when it is requested to do do, INVALID_OPERATION must be + * returned. It is very useful for the camera HAL to pass meta data rather + * than the actual frame data directly to the video encoder, since the + * amount of the uncompressed frame data can be very large if video size is + * large. + * + * @param enable if true to instruct the camera HAL to store + * meta data in the video buffers; false to instruct + * the camera HAL to store real YUV data in the video + * buffers. + * + * @return OK on success. + */ + int (*store_meta_data_in_buffers)(struct camera_device *, int enable); + + /** + * Start record mode. When a record image is available, a + * CAMERA_MSG_VIDEO_FRAME message is sent with the corresponding + * frame. Every record frame must be released by a camera HAL client via + * releaseRecordingFrame() before the client calls + * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls + * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's + * responsibility to manage the life-cycle of the video recording frames, + * and the client must not modify/access any video recording frames. + */ + int (*start_recording)(struct camera_device *); + + /** + * Stop a previously started recording. + */ + void (*stop_recording)(struct camera_device *); + + /** + * Returns true if recording is enabled. + */ + int (*recording_enabled)(struct camera_device *); + + /** + * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME. + * + * It is camera HAL client's responsibility to release video recording + * frames sent out by the camera HAL before the camera HAL receives a call + * to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives the call to + * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is the camera HAL's + * responsibility to manage the life-cycle of the video recording frames. + */ + void (*release_recording_frame)(struct camera_device *, + const void *opaque); + + /** + * Start auto focus, the notification callback routine is called with + * CAMERA_MSG_FOCUS once when focusing is complete. autoFocus() will be + * called again if another auto focus is needed. + */ + int (*auto_focus)(struct camera_device *); + + /** + * Cancels auto-focus function. If the auto-focus is still in progress, + * this function will cancel it. Whether the auto-focus is in progress or + * not, this function will return the focus position to the default. If + * the camera does not support auto-focus, this is a no-op. + */ + int (*cancel_auto_focus)(struct camera_device *); + + /** + * Take a picture. + */ + int (*take_picture)(struct camera_device *); + + /** + * Cancel a picture that was started with takePicture. Calling this method + * when no picture is being taken is a no-op. + */ + int (*cancel_picture)(struct camera_device *); + + /** + * Set the camera parameters. This returns BAD_VALUE if any parameter is + * invalid or not supported. + */ + int (*set_parameters)(struct camera_device *, const char *parms); + + /** Retrieve the camera parameters. The buffer returned by the camera HAL + must be returned back to it with put_parameters, if put_parameters + is not NULL. + */ + char *(*get_parameters)(struct camera_device *); + + /** The camera HAL uses its own memory to pass us the parameters when we + call get_parameters. Use this function to return the memory back to + the camera HAL, if put_parameters is not NULL. If put_parameters + is NULL, then you have to use free() to release the memory. + */ + void (*put_parameters)(struct camera_device *, char *); + + /** + * Send command to camera driver. + */ + int (*send_command)(struct camera_device *, + int32_t cmd, int32_t arg1, int32_t arg2); + + /** + * Release the hardware resources owned by this object. Note that this is + * *not* done in the destructor. + */ + void (*release)(struct camera_device *); + + /** + * Dump state of the camera hardware + */ + int (*dump)(struct camera_device *, int fd); +} camera_device_ops_t; + +typedef struct camera_device { + /** + * camera_device.common.version must be in the range + * HARDWARE_DEVICE_API_VERSION(0,0)-(1,FF). CAMERA_DEVICE_API_VERSION_1_0 is + * recommended. + */ + hw_device_t common; + camera_device_ops_t *ops; + void *priv; +} camera_device_t; + +__END_DECLS + +#endif /* #ifdef ANDROID_INCLUDE_CAMERA_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/camera2.h b/phonelibs/android_hardware_libhardware/include/hardware/camera2.h new file mode 100644 index 00000000000000..d920d4b65cbd05 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/camera2.h @@ -0,0 +1,839 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_CAMERA2_H +#define ANDROID_INCLUDE_CAMERA2_H + +#include "camera_common.h" +#include "system/camera_metadata.h" + +/** + * Camera device HAL 2.1 [ CAMERA_DEVICE_API_VERSION_2_0, CAMERA_DEVICE_API_VERSION_2_1 ] + * + * DEPRECATED. New devices should use Camera HAL v3.2 or newer. + * + * Supports the android.hardware.Camera API, and the android.hardware.camera2 + * API in legacy mode only. + * + * Camera devices that support this version of the HAL must return + * CAMERA_DEVICE_API_VERSION_2_1 in camera_device_t.common.version and in + * camera_info_t.device_version (from camera_module_t.get_camera_info). + * + * Camera modules that may contain version 2.x devices must implement at least + * version 2.0 of the camera module interface (as defined by + * camera_module_t.common.module_api_version). + * + * See camera_common.h for more versioning details. + * + * Version history: + * + * 2.0: CAMERA_DEVICE_API_VERSION_2_0. Initial release (Android 4.2): + * - Sufficient for implementing existing android.hardware.Camera API. + * - Allows for ZSL queue in camera service layer + * - Not tested for any new features such manual capture control, + * Bayer RAW capture, reprocessing of RAW data. + * + * 2.1: CAMERA_DEVICE_API_VERSION_2_1. Support per-device static metadata: + * - Add get_instance_metadata() method to retrieve metadata that is fixed + * after device open, but may be variable between open() calls. + */ + +__BEGIN_DECLS + +struct camera2_device; + +/********************************************************************** + * + * Input/output stream buffer queue interface definitions + * + */ + +/** + * Output image stream queue interface. A set of these methods is provided to + * the HAL device in allocate_stream(), and are used to interact with the + * gralloc buffer queue for that stream. They may not be called until after + * allocate_stream returns. + */ +typedef struct camera2_stream_ops { + /** + * Get a buffer to fill from the queue. The size and format of the buffer + * are fixed for a given stream (defined in allocate_stream), and the stride + * should be queried from the platform gralloc module. The gralloc buffer + * will have been allocated based on the usage flags provided by + * allocate_stream, and will be locked for use. + */ + int (*dequeue_buffer)(const struct camera2_stream_ops* w, + buffer_handle_t** buffer); + + /** + * Push a filled buffer to the stream to be used by the consumer. + * + * The timestamp represents the time at start of exposure of the first row + * of the image; it must be from a monotonic clock, and is measured in + * nanoseconds. The timestamps do not need to be comparable between + * different cameras, or consecutive instances of the same camera. However, + * they must be comparable between streams from the same camera. If one + * capture produces buffers for multiple streams, each stream must have the + * same timestamp for that buffer, and that timestamp must match the + * timestamp in the output frame metadata. + */ + int (*enqueue_buffer)(const struct camera2_stream_ops* w, + int64_t timestamp, + buffer_handle_t* buffer); + /** + * Return a buffer to the queue without marking it as filled. + */ + int (*cancel_buffer)(const struct camera2_stream_ops* w, + buffer_handle_t* buffer); + /** + * Set the crop window for subsequently enqueued buffers. The parameters are + * measured in pixels relative to the buffer width and height. + */ + int (*set_crop)(const struct camera2_stream_ops *w, + int left, int top, int right, int bottom); + +} camera2_stream_ops_t; + +/** + * Temporary definition during transition. + * + * These formats will be removed and replaced with + * HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED. To maximize forward compatibility, + * HAL implementations are strongly recommended to treat FORMAT_OPAQUE and + * FORMAT_ZSL as equivalent to HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, and + * return HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED in the format_actual output + * parameter of allocate_stream, allowing the gralloc module to select the + * specific format based on the usage flags from the camera and the stream + * consumer. + */ +enum { + CAMERA2_HAL_PIXEL_FORMAT_OPAQUE = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, + CAMERA2_HAL_PIXEL_FORMAT_ZSL = -1 +}; + +/** + * Transport header for compressed JPEG buffers in output streams. + * + * To capture JPEG images, a stream is created using the pixel format + * HAL_PIXEL_FORMAT_BLOB, and the static metadata field android.jpeg.maxSize is + * used as the buffer size. Since compressed JPEG images are of variable size, + * the HAL needs to include the final size of the compressed image using this + * structure inside the output stream buffer. The JPEG blob ID field must be set + * to CAMERA2_JPEG_BLOB_ID. + * + * Transport header should be at the end of the JPEG output stream buffer. That + * means the jpeg_blob_id must start at byte[android.jpeg.maxSize - + * sizeof(camera2_jpeg_blob)]. Any HAL using this transport header must + * account for it in android.jpeg.maxSize. The JPEG data itself starts at + * byte[0] and should be jpeg_size bytes long. + */ +typedef struct camera2_jpeg_blob { + uint16_t jpeg_blob_id; + uint32_t jpeg_size; +}; + +enum { + CAMERA2_JPEG_BLOB_ID = 0x00FF +}; + +/** + * Input reprocess stream queue management. A set of these methods is provided + * to the HAL device in allocate_reprocess_stream(); they are used to interact + * with the reprocess stream's input gralloc buffer queue. + */ +typedef struct camera2_stream_in_ops { + /** + * Get the next buffer of image data to reprocess. The width, height, and + * format of the buffer is fixed in allocate_reprocess_stream(), and the + * stride and other details should be queried from the platform gralloc + * module as needed. The buffer will already be locked for use. + */ + int (*acquire_buffer)(const struct camera2_stream_in_ops *w, + buffer_handle_t** buffer); + /** + * Return a used buffer to the buffer queue for reuse. + */ + int (*release_buffer)(const struct camera2_stream_in_ops *w, + buffer_handle_t* buffer); + +} camera2_stream_in_ops_t; + +/********************************************************************** + * + * Metadata queue management, used for requests sent to HAL module, and for + * frames produced by the HAL. + * + */ + +enum { + CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS = -1 +}; + +/** + * Request input queue protocol: + * + * The framework holds the queue and its contents. At start, the queue is empty. + * + * 1. When the first metadata buffer is placed into the queue, the framework + * signals the device by calling notify_request_queue_not_empty(). + * + * 2. After receiving notify_request_queue_not_empty, the device must call + * dequeue() once it's ready to handle the next buffer. + * + * 3. Once the device has processed a buffer, and is ready for the next buffer, + * it must call dequeue() again instead of waiting for a notification. If + * there are no more buffers available, dequeue() will return NULL. After + * this point, when a buffer becomes available, the framework must call + * notify_request_queue_not_empty() again. If the device receives a NULL + * return from dequeue, it does not need to query the queue again until a + * notify_request_queue_not_empty() call is received from the source. + * + * 4. If the device calls buffer_count() and receives 0, this does not mean that + * the framework will provide a notify_request_queue_not_empty() call. The + * framework will only provide such a notification after the device has + * received a NULL from dequeue, or on initial startup. + * + * 5. The dequeue() call in response to notify_request_queue_not_empty() may be + * on the same thread as the notify_request_queue_not_empty() call, and may + * be performed from within the notify call. + * + * 6. All dequeued request buffers must be returned to the framework by calling + * free_request, including when errors occur, a device flush is requested, or + * when the device is shutting down. + */ +typedef struct camera2_request_queue_src_ops { + /** + * Get the count of request buffers pending in the queue. May return + * CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS if a repeating request (stream + * request) is currently configured. Calling this method has no effect on + * whether the notify_request_queue_not_empty() method will be called by the + * framework. + */ + int (*request_count)(const struct camera2_request_queue_src_ops *q); + + /** + * Get a metadata buffer from the framework. Returns OK if there is no + * error. If the queue is empty, returns NULL in buffer. In that case, the + * device must wait for a notify_request_queue_not_empty() message before + * attempting to dequeue again. Buffers obtained in this way must be + * returned to the framework with free_request(). + */ + int (*dequeue_request)(const struct camera2_request_queue_src_ops *q, + camera_metadata_t **buffer); + /** + * Return a metadata buffer to the framework once it has been used, or if + * an error or shutdown occurs. + */ + int (*free_request)(const struct camera2_request_queue_src_ops *q, + camera_metadata_t *old_buffer); + +} camera2_request_queue_src_ops_t; + +/** + * Frame output queue protocol: + * + * The framework holds the queue and its contents. At start, the queue is empty. + * + * 1. When the device is ready to fill an output metadata frame, it must dequeue + * a metadata buffer of the required size. + * + * 2. It should then fill the metadata buffer, and place it on the frame queue + * using enqueue_frame. The framework takes ownership of the frame. + * + * 3. In case of an error, a request to flush the pipeline, or shutdown, the + * device must return any affected dequeued frames to the framework by + * calling cancel_frame. + */ +typedef struct camera2_frame_queue_dst_ops { + /** + * Get an empty metadata buffer to fill from the framework. The new metadata + * buffer will have room for entries number of metadata entries, plus + * data_bytes worth of extra storage. Frames dequeued here must be returned + * to the framework with either cancel_frame or enqueue_frame. + */ + int (*dequeue_frame)(const struct camera2_frame_queue_dst_ops *q, + size_t entries, size_t data_bytes, + camera_metadata_t **buffer); + + /** + * Return a dequeued metadata buffer to the framework for reuse; do not mark it as + * filled. Use when encountering errors, or flushing the internal request queue. + */ + int (*cancel_frame)(const struct camera2_frame_queue_dst_ops *q, + camera_metadata_t *buffer); + + /** + * Place a completed metadata frame on the frame output queue. + */ + int (*enqueue_frame)(const struct camera2_frame_queue_dst_ops *q, + camera_metadata_t *buffer); + +} camera2_frame_queue_dst_ops_t; + +/********************************************************************** + * + * Notification callback and message definition, and trigger definitions + * + */ + +/** + * Asynchronous notification callback from the HAL, fired for various + * reasons. Only for information independent of frame capture, or that require + * specific timing. The user pointer must be the same one that was passed to the + * device in set_notify_callback(). + */ +typedef void (*camera2_notify_callback)(int32_t msg_type, + int32_t ext1, + int32_t ext2, + int32_t ext3, + void *user); + +/** + * Possible message types for camera2_notify_callback + */ +enum { + /** + * An error has occurred. Argument ext1 contains the error code, and + * ext2 and ext3 contain any error-specific information. + */ + CAMERA2_MSG_ERROR = 0x0001, + /** + * The exposure of a given request has begun. Argument ext1 contains the + * frame number, and ext2 and ext3 contain the low-order and high-order + * bytes of the timestamp for when exposure began. + * (timestamp = (ext3 << 32 | ext2)) + */ + CAMERA2_MSG_SHUTTER = 0x0010, + /** + * The autofocus routine has changed state. Argument ext1 contains the new + * state; the values are the same as those for the metadata field + * android.control.afState. Ext2 contains the latest trigger ID passed to + * trigger_action(CAMERA2_TRIGGER_AUTOFOCUS) or + * trigger_action(CAMERA2_TRIGGER_CANCEL_AUTOFOCUS), or 0 if trigger has not + * been called with either of those actions. + */ + CAMERA2_MSG_AUTOFOCUS = 0x0020, + /** + * The autoexposure routine has changed state. Argument ext1 contains the + * new state; the values are the same as those for the metadata field + * android.control.aeState. Ext2 contains the latest trigger ID value passed to + * trigger_action(CAMERA2_TRIGGER_PRECAPTURE_METERING), or 0 if that method + * has not been called. + */ + CAMERA2_MSG_AUTOEXPOSURE = 0x0021, + /** + * The auto-whitebalance routine has changed state. Argument ext1 contains + * the new state; the values are the same as those for the metadata field + * android.control.awbState. Ext2 contains the latest trigger ID passed to + * trigger_action(CAMERA2_TRIGGER_PRECAPTURE_METERING), or 0 if that method + * has not been called. + */ + CAMERA2_MSG_AUTOWB = 0x0022 +}; + +/** + * Error codes for CAMERA_MSG_ERROR + */ +enum { + /** + * A serious failure occured. Camera device may not work without reboot, and + * no further frames or buffer streams will be produced by the + * device. Device should be treated as closed. + */ + CAMERA2_MSG_ERROR_HARDWARE = 0x0001, + /** + * A serious failure occured. No further frames or buffer streams will be + * produced by the device. Device should be treated as closed. The client + * must reopen the device to use it again. + */ + CAMERA2_MSG_ERROR_DEVICE, + /** + * An error has occurred in processing a request. No output (metadata or + * buffers) will be produced for this request. ext2 contains the frame + * number of the request. Subsequent requests are unaffected, and the device + * remains operational. + */ + CAMERA2_MSG_ERROR_REQUEST, + /** + * An error has occurred in producing an output frame metadata buffer for a + * request, but image buffers for it will still be available. Subsequent + * requests are unaffected, and the device remains operational. ext2 + * contains the frame number of the request. + */ + CAMERA2_MSG_ERROR_FRAME, + /** + * An error has occurred in placing an output buffer into a stream for a + * request. The frame metadata and other buffers may still be + * available. Subsequent requests are unaffected, and the device remains + * operational. ext2 contains the frame number of the request, and ext3 + * contains the stream id. + */ + CAMERA2_MSG_ERROR_STREAM, + /** + * Number of error types + */ + CAMERA2_MSG_NUM_ERRORS +}; + +/** + * Possible trigger ids for trigger_action() + */ +enum { + /** + * Trigger an autofocus cycle. The effect of the trigger depends on the + * autofocus mode in effect when the trigger is received, which is the mode + * listed in the latest capture request to be dequeued by the HAL. If the + * mode is OFF, EDOF, or FIXED, the trigger has no effect. In AUTO, MACRO, + * or CONTINUOUS_* modes, see below for the expected behavior. The state of + * the autofocus cycle can be tracked in android.control.afMode and the + * corresponding notifications. + * + ** + * In AUTO or MACRO mode, the AF state transitions (and notifications) + * when calling with trigger ID = N with the previous ID being K are: + * + * Initial state Transitions + * INACTIVE (K) -> ACTIVE_SCAN (N) -> AF_FOCUSED (N) or AF_NOT_FOCUSED (N) + * AF_FOCUSED (K) -> ACTIVE_SCAN (N) -> AF_FOCUSED (N) or AF_NOT_FOCUSED (N) + * AF_NOT_FOCUSED (K) -> ACTIVE_SCAN (N) -> AF_FOCUSED (N) or AF_NOT_FOCUSED (N) + * ACTIVE_SCAN (K) -> AF_FOCUSED(N) or AF_NOT_FOCUSED(N) + * PASSIVE_SCAN (K) Not used in AUTO/MACRO mode + * PASSIVE_FOCUSED (K) Not used in AUTO/MACRO mode + * + ** + * In CONTINUOUS_PICTURE mode, triggering AF must lock the AF to the current + * lens position and transition the AF state to either AF_FOCUSED or + * NOT_FOCUSED. If a passive scan is underway, that scan must complete and + * then lock the lens position and change AF state. TRIGGER_CANCEL_AUTOFOCUS + * will allow the AF to restart its operation. + * + * Initial state Transitions + * INACTIVE (K) -> immediate AF_FOCUSED (N) or AF_NOT_FOCUSED (N) + * PASSIVE_FOCUSED (K) -> immediate AF_FOCUSED (N) or AF_NOT_FOCUSED (N) + * PASSIVE_SCAN (K) -> AF_FOCUSED (N) or AF_NOT_FOCUSED (N) + * AF_FOCUSED (K) no effect except to change next notification ID to N + * AF_NOT_FOCUSED (K) no effect except to change next notification ID to N + * + ** + * In CONTINUOUS_VIDEO mode, triggering AF must lock the AF to the current + * lens position and transition the AF state to either AF_FOCUSED or + * NOT_FOCUSED. If a passive scan is underway, it must immediately halt, in + * contrast with CONTINUOUS_PICTURE mode. TRIGGER_CANCEL_AUTOFOCUS will + * allow the AF to restart its operation. + * + * Initial state Transitions + * INACTIVE (K) -> immediate AF_FOCUSED (N) or AF_NOT_FOCUSED (N) + * PASSIVE_FOCUSED (K) -> immediate AF_FOCUSED (N) or AF_NOT_FOCUSED (N) + * PASSIVE_SCAN (K) -> immediate AF_FOCUSED (N) or AF_NOT_FOCUSED (N) + * AF_FOCUSED (K) no effect except to change next notification ID to N + * AF_NOT_FOCUSED (K) no effect except to change next notification ID to N + * + * Ext1 is an ID that must be returned in subsequent auto-focus state change + * notifications through camera2_notify_callback() and stored in + * android.control.afTriggerId. + */ + CAMERA2_TRIGGER_AUTOFOCUS = 0x0001, + /** + * Send a cancel message to the autofocus algorithm. The effect of the + * cancellation depends on the autofocus mode in effect when the trigger is + * received, which is the mode listed in the latest capture request to be + * dequeued by the HAL. If the AF mode is OFF or EDOF, the cancel has no + * effect. For other modes, the lens should return to its default position, + * any current autofocus scan must be canceled, and the AF state should be + * set to INACTIVE. + * + * The state of the autofocus cycle can be tracked in android.control.afMode + * and the corresponding notification. Continuous autofocus modes may resume + * focusing operations thereafter exactly as if the camera had just been set + * to a continuous AF mode. + * + * Ext1 is an ID that must be returned in subsequent auto-focus state change + * notifications through camera2_notify_callback() and stored in + * android.control.afTriggerId. + */ + CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, + /** + * Trigger a pre-capture metering cycle, which may include firing the flash + * to determine proper capture parameters. Typically, this trigger would be + * fired for a half-depress of a camera shutter key, or before a snapshot + * capture in general. The state of the metering cycle can be tracked in + * android.control.aeMode and the corresponding notification. If the + * auto-exposure mode is OFF, the trigger does nothing. + * + * Ext1 is an ID that must be returned in subsequent + * auto-exposure/auto-white balance state change notifications through + * camera2_notify_callback() and stored in android.control.aePrecaptureId. + */ + CAMERA2_TRIGGER_PRECAPTURE_METERING +}; + +/** + * Possible template types for construct_default_request() + */ +enum { + /** + * Standard camera preview operation with 3A on auto. + */ + CAMERA2_TEMPLATE_PREVIEW = 1, + /** + * Standard camera high-quality still capture with 3A and flash on auto. + */ + CAMERA2_TEMPLATE_STILL_CAPTURE, + /** + * Standard video recording plus preview with 3A on auto, torch off. + */ + CAMERA2_TEMPLATE_VIDEO_RECORD, + /** + * High-quality still capture while recording video. Application will + * include preview, video record, and full-resolution YUV or JPEG streams in + * request. Must not cause stuttering on video stream. 3A on auto. + */ + CAMERA2_TEMPLATE_VIDEO_SNAPSHOT, + /** + * Zero-shutter-lag mode. Application will request preview and + * full-resolution data for each frame, and reprocess it to JPEG when a + * still image is requested by user. Settings should provide highest-quality + * full-resolution images without compromising preview frame rate. 3A on + * auto. + */ + CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG, + + /* Total number of templates */ + CAMERA2_TEMPLATE_COUNT +}; + + +/********************************************************************** + * + * Camera device operations + * + */ +typedef struct camera2_device_ops { + + /********************************************************************** + * Request and frame queue setup and management methods + */ + + /** + * Pass in input request queue interface methods. + */ + int (*set_request_queue_src_ops)(const struct camera2_device *, + const camera2_request_queue_src_ops_t *request_src_ops); + + /** + * Notify device that the request queue is no longer empty. Must only be + * called when the first buffer is added a new queue, or after the source + * has returned NULL in response to a dequeue call. + */ + int (*notify_request_queue_not_empty)(const struct camera2_device *); + + /** + * Pass in output frame queue interface methods + */ + int (*set_frame_queue_dst_ops)(const struct camera2_device *, + const camera2_frame_queue_dst_ops_t *frame_dst_ops); + + /** + * Number of camera requests being processed by the device at the moment + * (captures/reprocesses that have had their request dequeued, but have not + * yet been enqueued onto output pipeline(s) ). No streams may be released + * by the framework until the in-progress count is 0. + */ + int (*get_in_progress_count)(const struct camera2_device *); + + /** + * Flush all in-progress captures. This includes all dequeued requests + * (regular or reprocessing) that have not yet placed any outputs into a + * stream or the frame queue. Partially completed captures must be completed + * normally. No new requests may be dequeued from the request queue until + * the flush completes. + */ + int (*flush_captures_in_progress)(const struct camera2_device *); + + /** + * Create a filled-in default request for standard camera use cases. + * + * The device must return a complete request that is configured to meet the + * requested use case, which must be one of the CAMERA2_TEMPLATE_* + * enums. All request control fields must be included, except for + * android.request.outputStreams. + * + * The metadata buffer returned must be allocated with + * allocate_camera_metadata. The framework takes ownership of the buffer. + */ + int (*construct_default_request)(const struct camera2_device *, + int request_template, + camera_metadata_t **request); + + /********************************************************************** + * Stream management + */ + + /** + * allocate_stream: + * + * Allocate a new output stream for use, defined by the output buffer width, + * height, target, and possibly the pixel format. Returns the new stream's + * ID, gralloc usage flags, minimum queue buffer count, and possibly the + * pixel format, on success. Error conditions: + * + * - Requesting a width/height/format combination not listed as + * supported by the sensor's static characteristics + * + * - Asking for too many streams of a given format type (2 bayer raw + * streams, for example). + * + * Input parameters: + * + * - width, height, format: Specification for the buffers to be sent through + * this stream. Format is a value from the HAL_PIXEL_FORMAT_* list. If + * HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED is used, then the platform + * gralloc module will select a format based on the usage flags provided + * by the camera HAL and the consumer of the stream. The camera HAL should + * inspect the buffers handed to it in the register_stream_buffers call to + * obtain the implementation-specific format if necessary. + * + * - stream_ops: A structure of function pointers for obtaining and queuing + * up buffers for this stream. The underlying stream will be configured + * based on the usage and max_buffers outputs. The methods in this + * structure may not be called until after allocate_stream returns. + * + * Output parameters: + * + * - stream_id: An unsigned integer identifying this stream. This value is + * used in incoming requests to identify the stream, and in releasing the + * stream. + * + * - usage: The gralloc usage mask needed by the HAL device for producing + * the requested type of data. This is used in allocating new gralloc + * buffers for the stream buffer queue. + * + * - max_buffers: The maximum number of buffers the HAL device may need to + * have dequeued at the same time. The device may not dequeue more buffers + * than this value at the same time. + * + */ + int (*allocate_stream)( + const struct camera2_device *, + // inputs + uint32_t width, + uint32_t height, + int format, + const camera2_stream_ops_t *stream_ops, + // outputs + uint32_t *stream_id, + uint32_t *format_actual, // IGNORED, will be removed + uint32_t *usage, + uint32_t *max_buffers); + + /** + * Register buffers for a given stream. This is called after a successful + * allocate_stream call, and before the first request referencing the stream + * is enqueued. This method is intended to allow the HAL device to map or + * otherwise prepare the buffers for later use. num_buffers is guaranteed to + * be at least max_buffers (from allocate_stream), but may be larger. The + * buffers will already be locked for use. At the end of the call, all the + * buffers must be ready to be returned to the queue. If the stream format + * was set to HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, the camera HAL should + * inspect the passed-in buffers here to determine any platform-private + * pixel format information. + */ + int (*register_stream_buffers)( + const struct camera2_device *, + uint32_t stream_id, + int num_buffers, + buffer_handle_t *buffers); + + /** + * Release a stream. Returns an error if called when get_in_progress_count + * is non-zero, or if the stream id is invalid. + */ + int (*release_stream)( + const struct camera2_device *, + uint32_t stream_id); + + /** + * allocate_reprocess_stream: + * + * Allocate a new input stream for use, defined by the output buffer width, + * height, and the pixel format. Returns the new stream's ID, gralloc usage + * flags, and required simultaneously acquirable buffer count, on + * success. Error conditions: + * + * - Requesting a width/height/format combination not listed as + * supported by the sensor's static characteristics + * + * - Asking for too many reprocessing streams to be configured at once. + * + * Input parameters: + * + * - width, height, format: Specification for the buffers to be sent through + * this stream. Format must be a value from the HAL_PIXEL_FORMAT_* list. + * + * - reprocess_stream_ops: A structure of function pointers for acquiring + * and releasing buffers for this stream. The underlying stream will be + * configured based on the usage and max_buffers outputs. + * + * Output parameters: + * + * - stream_id: An unsigned integer identifying this stream. This value is + * used in incoming requests to identify the stream, and in releasing the + * stream. These ids are numbered separately from the input stream ids. + * + * - consumer_usage: The gralloc usage mask needed by the HAL device for + * consuming the requested type of data. This is used in allocating new + * gralloc buffers for the stream buffer queue. + * + * - max_buffers: The maximum number of buffers the HAL device may need to + * have acquired at the same time. The device may not have more buffers + * acquired at the same time than this value. + * + */ + int (*allocate_reprocess_stream)(const struct camera2_device *, + uint32_t width, + uint32_t height, + uint32_t format, + const camera2_stream_in_ops_t *reprocess_stream_ops, + // outputs + uint32_t *stream_id, + uint32_t *consumer_usage, + uint32_t *max_buffers); + + /** + * allocate_reprocess_stream_from_stream: + * + * Allocate a new input stream for use, which will use the buffers allocated + * for an existing output stream. That is, after the HAL enqueues a buffer + * onto the output stream, it may see that same buffer handed to it from + * this input reprocessing stream. After the HAL releases the buffer back to + * the reprocessing stream, it will be returned to the output queue for + * reuse. + * + * Error conditions: + * + * - Using an output stream of unsuitable size/format for the basis of the + * reprocessing stream. + * + * - Attempting to allocatee too many reprocessing streams at once. + * + * Input parameters: + * + * - output_stream_id: The ID of an existing output stream which has + * a size and format suitable for reprocessing. + * + * - reprocess_stream_ops: A structure of function pointers for acquiring + * and releasing buffers for this stream. The underlying stream will use + * the same graphics buffer handles as the output stream uses. + * + * Output parameters: + * + * - stream_id: An unsigned integer identifying this stream. This value is + * used in incoming requests to identify the stream, and in releasing the + * stream. These ids are numbered separately from the input stream ids. + * + * The HAL client must always release the reprocessing stream before it + * releases the output stream it is based on. + * + */ + int (*allocate_reprocess_stream_from_stream)(const struct camera2_device *, + uint32_t output_stream_id, + const camera2_stream_in_ops_t *reprocess_stream_ops, + // outputs + uint32_t *stream_id); + + /** + * Release a reprocessing stream. Returns an error if called when + * get_in_progress_count is non-zero, or if the stream id is not + * valid. + */ + int (*release_reprocess_stream)( + const struct camera2_device *, + uint32_t stream_id); + + /********************************************************************** + * Miscellaneous methods + */ + + /** + * Trigger asynchronous activity. This is used for triggering special + * behaviors of the camera 3A routines when they are in use. See the + * documentation for CAMERA2_TRIGGER_* above for details of the trigger ids + * and their arguments. + */ + int (*trigger_action)(const struct camera2_device *, + uint32_t trigger_id, + int32_t ext1, + int32_t ext2); + + /** + * Notification callback setup + */ + int (*set_notify_callback)(const struct camera2_device *, + camera2_notify_callback notify_cb, + void *user); + + /** + * Get methods to query for vendor extension metadata tag infomation. May + * set ops to NULL if no vendor extension tags are defined. + */ + int (*get_metadata_vendor_tag_ops)(const struct camera2_device*, + vendor_tag_query_ops_t **ops); + + /** + * Dump state of the camera hardware + */ + int (*dump)(const struct camera2_device *, int fd); + + /** + * Get device-instance-specific metadata. This metadata must be constant for + * a single instance of the camera device, but may be different between + * open() calls. The returned camera_metadata pointer must be valid until + * the device close() method is called. + * + * Version information: + * + * CAMERA_DEVICE_API_VERSION_2_0: + * + * Not available. Framework may not access this function pointer. + * + * CAMERA_DEVICE_API_VERSION_2_1: + * + * Valid. Can be called by the framework. + * + */ + int (*get_instance_metadata)(const struct camera2_device *, + camera_metadata **instance_metadata); + +} camera2_device_ops_t; + +/********************************************************************** + * + * Camera device definition + * + */ +typedef struct camera2_device { + /** + * common.version must equal CAMERA_DEVICE_API_VERSION_2_0 to identify + * this device as implementing version 2.0 of the camera device HAL. + */ + hw_device_t common; + camera2_device_ops_t *ops; + void *priv; +} camera2_device_t; + +__END_DECLS + +#endif /* #ifdef ANDROID_INCLUDE_CAMERA2_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/camera3.h b/phonelibs/android_hardware_libhardware/include/hardware/camera3.h new file mode 100644 index 00000000000000..3ef6d6fadae51c --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/camera3.h @@ -0,0 +1,3077 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_CAMERA3_H +#define ANDROID_INCLUDE_CAMERA3_H + +#include +#include "camera_common.h" + +/** + * Camera device HAL 3.3 [ CAMERA_DEVICE_API_VERSION_3_3 ] + * + * This is the current recommended version of the camera device HAL. + * + * Supports the android.hardware.Camera API, and as of v3.2, the + * android.hardware.camera2 API in LIMITED or FULL modes. + * + * Camera devices that support this version of the HAL must return + * CAMERA_DEVICE_API_VERSION_3_3 in camera_device_t.common.version and in + * camera_info_t.device_version (from camera_module_t.get_camera_info). + * + * CAMERA_DEVICE_API_VERSION_3_3: + * Camera modules that may contain version 3.3 devices must implement at + * least version 2.2 of the camera module interface (as defined by + * camera_module_t.common.module_api_version). + * + * CAMERA_DEVICE_API_VERSION_3_2: + * Camera modules that may contain version 3.2 devices must implement at + * least version 2.2 of the camera module interface (as defined by + * camera_module_t.common.module_api_version). + * + * <= CAMERA_DEVICE_API_VERSION_3_1: + * Camera modules that may contain version 3.1 (or 3.0) devices must + * implement at least version 2.0 of the camera module interface + * (as defined by camera_module_t.common.module_api_version). + * + * See camera_common.h for more versioning details. + * + * Documentation index: + * S1. Version history + * S2. Startup and operation sequencing + * S3. Operational modes + * S4. 3A modes and state machines + * S5. Cropping + * S6. Error management + * S7. Key Performance Indicator (KPI) glossary + * S8. Sample Use Cases + * S9. Notes on Controls and Metadata + * S10. Reprocessing flow and controls + */ + +/** + * S1. Version history: + * + * 1.0: Initial Android camera HAL (Android 4.0) [camera.h]: + * + * - Converted from C++ CameraHardwareInterface abstraction layer. + * + * - Supports android.hardware.Camera API. + * + * 2.0: Initial release of expanded-capability HAL (Android 4.2) [camera2.h]: + * + * - Sufficient for implementing existing android.hardware.Camera API. + * + * - Allows for ZSL queue in camera service layer + * + * - Not tested for any new features such manual capture control, Bayer RAW + * capture, reprocessing of RAW data. + * + * 3.0: First revision of expanded-capability HAL: + * + * - Major version change since the ABI is completely different. No change to + * the required hardware capabilities or operational model from 2.0. + * + * - Reworked input request and stream queue interfaces: Framework calls into + * HAL with next request and stream buffers already dequeued. Sync framework + * support is included, necessary for efficient implementations. + * + * - Moved triggers into requests, most notifications into results. + * + * - Consolidated all callbacks into framework into one structure, and all + * setup methods into a single initialize() call. + * + * - Made stream configuration into a single call to simplify stream + * management. Bidirectional streams replace STREAM_FROM_STREAM construct. + * + * - Limited mode semantics for older/limited hardware devices. + * + * 3.1: Minor revision of expanded-capability HAL: + * + * - configure_streams passes consumer usage flags to the HAL. + * + * - flush call to drop all in-flight requests/buffers as fast as possible. + * + * 3.2: Minor revision of expanded-capability HAL: + * + * - Deprecates get_metadata_vendor_tag_ops. Please use get_vendor_tag_ops + * in camera_common.h instead. + * + * - register_stream_buffers deprecated. All gralloc buffers provided + * by framework to HAL in process_capture_request may be new at any time. + * + * - add partial result support. process_capture_result may be called + * multiple times with a subset of the available result before the full + * result is available. + * + * - add manual template to camera3_request_template. The applications may + * use this template to control the capture settings directly. + * + * - Rework the bidirectional and input stream specifications. + * + * - change the input buffer return path. The buffer is returned in + * process_capture_result instead of process_capture_request. + * + * 3.3: Minor revision of expanded-capability HAL: + * + * - OPAQUE and YUV reprocessing API updates. + * + * - Basic support for depth output buffers. + * + * - Addition of data_space field to camera3_stream_t. + * + * - Addition of rotation field to camera3_stream_t. + * + * - Addition of camera3 stream configuration operation mode to camera3_stream_configuration_t + * + */ + +/** + * S2. Startup and general expected operation sequence: + * + * 1. Framework calls camera_module_t->common.open(), which returns a + * hardware_device_t structure. + * + * 2. Framework inspects the hardware_device_t->version field, and instantiates + * the appropriate handler for that version of the camera hardware device. In + * case the version is CAMERA_DEVICE_API_VERSION_3_0, the device is cast to + * a camera3_device_t. + * + * 3. Framework calls camera3_device_t->ops->initialize() with the framework + * callback function pointers. This will only be called this one time after + * open(), before any other functions in the ops structure are called. + * + * 4. The framework calls camera3_device_t->ops->configure_streams() with a list + * of input/output streams to the HAL device. + * + * 5. <= CAMERA_DEVICE_API_VERSION_3_1: + * + * The framework allocates gralloc buffers and calls + * camera3_device_t->ops->register_stream_buffers() for at least one of the + * output streams listed in configure_streams. The same stream is registered + * only once. + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * camera3_device_t->ops->register_stream_buffers() is not called and must + * be NULL. + * + * 6. The framework requests default settings for some number of use cases with + * calls to camera3_device_t->ops->construct_default_request_settings(). This + * may occur any time after step 3. + * + * 7. The framework constructs and sends the first capture request to the HAL, + * with settings based on one of the sets of default settings, and with at + * least one output stream, which has been registered earlier by the + * framework. This is sent to the HAL with + * camera3_device_t->ops->process_capture_request(). The HAL must block the + * return of this call until it is ready for the next request to be sent. + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * The buffer_handle_t provided in the camera3_stream_buffer_t array + * in the camera3_capture_request_t may be new and never-before-seen + * by the HAL on any given new request. + * + * 8. The framework continues to submit requests, and call + * construct_default_request_settings to get default settings buffers for + * other use cases. + * + * <= CAMERA_DEVICE_API_VERSION_3_1: + * + * The framework may call register_stream_buffers() at this time for + * not-yet-registered streams. + * + * 9. When the capture of a request begins (sensor starts exposing for the + * capture) or processing a reprocess request begins, the HAL + * calls camera3_callback_ops_t->notify() with the SHUTTER event, including + * the frame number and the timestamp for start of exposure. For a reprocess + * request, the timestamp must be the start of exposure of the input image + * which can be looked up with android.sensor.timestamp from + * camera3_capture_request_t.settings when process_capture_request() is + * called. + * + * <= CAMERA_DEVICE_API_VERSION_3_1: + * + * This notify call must be made before the first call to + * process_capture_result() for that frame number. + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * The camera3_callback_ops_t->notify() call with the SHUTTER event should + * be made as early as possible since the framework will be unable to + * deliver gralloc buffers to the application layer (for that frame) until + * it has a valid timestamp for the start of exposure (or the input image's + * start of exposure for a reprocess request). + * + * Both partial metadata results and the gralloc buffers may be sent to the + * framework at any time before or after the SHUTTER event. + * + * 10. After some pipeline delay, the HAL begins to return completed captures to + * the framework with camera3_callback_ops_t->process_capture_result(). These + * are returned in the same order as the requests were submitted. Multiple + * requests can be in flight at once, depending on the pipeline depth of the + * camera HAL device. + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * Once a buffer is returned by process_capture_result as part of the + * camera3_stream_buffer_t array, and the fence specified by release_fence + * has been signaled (this is a no-op for -1 fences), the ownership of that + * buffer is considered to be transferred back to the framework. After that, + * the HAL must no longer retain that particular buffer, and the + * framework may clean up the memory for it immediately. + * + * process_capture_result may be called multiple times for a single frame, + * each time with a new disjoint piece of metadata and/or set of gralloc + * buffers. The framework will accumulate these partial metadata results + * into one result. + * + * In particular, it is legal for a process_capture_result to be called + * simultaneously for both a frame N and a frame N+1 as long as the + * above rule holds for gralloc buffers (both input and output). + * + * 11. After some time, the framework may stop submitting new requests, wait for + * the existing captures to complete (all buffers filled, all results + * returned), and then call configure_streams() again. This resets the camera + * hardware and pipeline for a new set of input/output streams. Some streams + * may be reused from the previous configuration; if these streams' buffers + * had already been registered with the HAL, they will not be registered + * again. The framework then continues from step 7, if at least one + * registered output stream remains (otherwise, step 5 is required first). + * + * 12. Alternatively, the framework may call camera3_device_t->common->close() + * to end the camera session. This may be called at any time when no other + * calls from the framework are active, although the call may block until all + * in-flight captures have completed (all results returned, all buffers + * filled). After the close call returns, no more calls to the + * camera3_callback_ops_t functions are allowed from the HAL. Once the + * close() call is underway, the framework may not call any other HAL device + * functions. + * + * 13. In case of an error or other asynchronous event, the HAL must call + * camera3_callback_ops_t->notify() with the appropriate error/event + * message. After returning from a fatal device-wide error notification, the + * HAL should act as if close() had been called on it. However, the HAL must + * either cancel or complete all outstanding captures before calling + * notify(), so that once notify() is called with a fatal error, the + * framework will not receive further callbacks from the device. Methods + * besides close() should return -ENODEV or NULL after the notify() method + * returns from a fatal error message. + */ + +/** + * S3. Operational modes: + * + * The camera 3 HAL device can implement one of two possible operational modes; + * limited and full. Full support is expected from new higher-end + * devices. Limited mode has hardware requirements roughly in line with those + * for a camera HAL device v1 implementation, and is expected from older or + * inexpensive devices. Full is a strict superset of limited, and they share the + * same essential operational flow, as documented above. + * + * The HAL must indicate its level of support with the + * android.info.supportedHardwareLevel static metadata entry, with 0 indicating + * limited mode, and 1 indicating full mode support. + * + * Roughly speaking, limited-mode devices do not allow for application control + * of capture settings (3A control only), high-rate capture of high-resolution + * images, raw sensor readout, or support for YUV output streams above maximum + * recording resolution (JPEG only for large images). + * + * ** Details of limited mode behavior: + * + * - Limited-mode devices do not need to implement accurate synchronization + * between capture request settings and the actual image data + * captured. Instead, changes to settings may take effect some time in the + * future, and possibly not for the same output frame for each settings + * entry. Rapid changes in settings may result in some settings never being + * used for a capture. However, captures that include high-resolution output + * buffers ( > 1080p ) have to use the settings as specified (but see below + * for processing rate). + * + * - Limited-mode devices do not need to support most of the + * settings/result/static info metadata. Specifically, only the following settings + * are expected to be consumed or produced by a limited-mode HAL device: + * + * android.control.aeAntibandingMode (controls and dynamic) + * android.control.aeExposureCompensation (controls and dynamic) + * android.control.aeLock (controls and dynamic) + * android.control.aeMode (controls and dynamic) + * android.control.aeRegions (controls and dynamic) + * android.control.aeTargetFpsRange (controls and dynamic) + * android.control.aePrecaptureTrigger (controls and dynamic) + * android.control.afMode (controls and dynamic) + * android.control.afRegions (controls and dynamic) + * android.control.awbLock (controls and dynamic) + * android.control.awbMode (controls and dynamic) + * android.control.awbRegions (controls and dynamic) + * android.control.captureIntent (controls and dynamic) + * android.control.effectMode (controls and dynamic) + * android.control.mode (controls and dynamic) + * android.control.sceneMode (controls and dynamic) + * android.control.videoStabilizationMode (controls and dynamic) + * android.control.aeAvailableAntibandingModes (static) + * android.control.aeAvailableModes (static) + * android.control.aeAvailableTargetFpsRanges (static) + * android.control.aeCompensationRange (static) + * android.control.aeCompensationStep (static) + * android.control.afAvailableModes (static) + * android.control.availableEffects (static) + * android.control.availableSceneModes (static) + * android.control.availableVideoStabilizationModes (static) + * android.control.awbAvailableModes (static) + * android.control.maxRegions (static) + * android.control.sceneModeOverrides (static) + * android.control.aeState (dynamic) + * android.control.afState (dynamic) + * android.control.awbState (dynamic) + * + * android.flash.mode (controls and dynamic) + * android.flash.info.available (static) + * + * android.info.supportedHardwareLevel (static) + * + * android.jpeg.gpsCoordinates (controls and dynamic) + * android.jpeg.gpsProcessingMethod (controls and dynamic) + * android.jpeg.gpsTimestamp (controls and dynamic) + * android.jpeg.orientation (controls and dynamic) + * android.jpeg.quality (controls and dynamic) + * android.jpeg.thumbnailQuality (controls and dynamic) + * android.jpeg.thumbnailSize (controls and dynamic) + * android.jpeg.availableThumbnailSizes (static) + * android.jpeg.maxSize (static) + * + * android.lens.info.minimumFocusDistance (static) + * + * android.request.id (controls and dynamic) + * + * android.scaler.cropRegion (controls and dynamic) + * android.scaler.availableStreamConfigurations (static) + * android.scaler.availableMinFrameDurations (static) + * android.scaler.availableStallDurations (static) + * android.scaler.availableMaxDigitalZoom (static) + * android.scaler.maxDigitalZoom (static) + * android.scaler.croppingType (static) + * + * android.sensor.orientation (static) + * android.sensor.timestamp (dynamic) + * + * android.statistics.faceDetectMode (controls and dynamic) + * android.statistics.info.availableFaceDetectModes (static) + * android.statistics.faceIds (dynamic) + * android.statistics.faceLandmarks (dynamic) + * android.statistics.faceRectangles (dynamic) + * android.statistics.faceScores (dynamic) + * + * android.sync.frameNumber (dynamic) + * android.sync.maxLatency (static) + * + * - Captures in limited mode that include high-resolution (> 1080p) output + * buffers may block in process_capture_request() until all the output buffers + * have been filled. A full-mode HAL device must process sequences of + * high-resolution requests at the rate indicated in the static metadata for + * that pixel format. The HAL must still call process_capture_result() to + * provide the output; the framework must simply be prepared for + * process_capture_request() to block until after process_capture_result() for + * that request completes for high-resolution captures for limited-mode + * devices. + * + * - Full-mode devices must support below additional capabilities: + * - 30fps at maximum resolution is preferred, more than 20fps is required. + * - Per frame control (android.sync.maxLatency == PER_FRAME_CONTROL). + * - Sensor manual control metadata. See MANUAL_SENSOR defined in + * android.request.availableCapabilities. + * - Post-processing manual control metadata. See MANUAL_POST_PROCESSING defined + * in android.request.availableCapabilities. + * + */ + +/** + * S4. 3A modes and state machines: + * + * While the actual 3A algorithms are up to the HAL implementation, a high-level + * state machine description is defined by the HAL interface, to allow the HAL + * device and the framework to communicate about the current state of 3A, and to + * trigger 3A events. + * + * When the device is opened, all the individual 3A states must be + * STATE_INACTIVE. Stream configuration does not reset 3A. For example, locked + * focus must be maintained across the configure() call. + * + * Triggering a 3A action involves simply setting the relevant trigger entry in + * the settings for the next request to indicate start of trigger. For example, + * the trigger for starting an autofocus scan is setting the entry + * ANDROID_CONTROL_AF_TRIGGER to ANDROID_CONTROL_AF_TRIGGER_START for one + * request, and cancelling an autofocus scan is triggered by setting + * ANDROID_CONTROL_AF_TRIGGER to ANDROID_CONTRL_AF_TRIGGER_CANCEL. Otherwise, + * the entry will not exist, or be set to ANDROID_CONTROL_AF_TRIGGER_IDLE. Each + * request with a trigger entry set to a non-IDLE value will be treated as an + * independent triggering event. + * + * At the top level, 3A is controlled by the ANDROID_CONTROL_MODE setting, which + * selects between no 3A (ANDROID_CONTROL_MODE_OFF), normal AUTO mode + * (ANDROID_CONTROL_MODE_AUTO), and using the scene mode setting + * (ANDROID_CONTROL_USE_SCENE_MODE). + * + * - In OFF mode, each of the individual AE/AF/AWB modes are effectively OFF, + * and none of the capture controls may be overridden by the 3A routines. + * + * - In AUTO mode, Auto-focus, auto-exposure, and auto-whitebalance all run + * their own independent algorithms, and have their own mode, state, and + * trigger metadata entries, as listed in the next section. + * + * - In USE_SCENE_MODE, the value of the ANDROID_CONTROL_SCENE_MODE entry must + * be used to determine the behavior of 3A routines. In SCENE_MODEs other than + * FACE_PRIORITY, the HAL must override the values of + * ANDROId_CONTROL_AE/AWB/AF_MODE to be the mode it prefers for the selected + * SCENE_MODE. For example, the HAL may prefer SCENE_MODE_NIGHT to use + * CONTINUOUS_FOCUS AF mode. Any user selection of AE/AWB/AF_MODE when scene + * must be ignored for these scene modes. + * + * - For SCENE_MODE_FACE_PRIORITY, the AE/AWB/AF_MODE controls work as in + * ANDROID_CONTROL_MODE_AUTO, but the 3A routines must bias toward metering + * and focusing on any detected faces in the scene. + * + * S4.1. Auto-focus settings and result entries: + * + * Main metadata entries: + * + * ANDROID_CONTROL_AF_MODE: Control for selecting the current autofocus + * mode. Set by the framework in the request settings. + * + * AF_MODE_OFF: AF is disabled; the framework/app directly controls lens + * position. + * + * AF_MODE_AUTO: Single-sweep autofocus. No lens movement unless AF is + * triggered. + * + * AF_MODE_MACRO: Single-sweep up-close autofocus. No lens movement unless + * AF is triggered. + * + * AF_MODE_CONTINUOUS_VIDEO: Smooth continuous focusing, for recording + * video. Triggering immediately locks focus in current + * position. Canceling resumes cotinuous focusing. + * + * AF_MODE_CONTINUOUS_PICTURE: Fast continuous focusing, for + * zero-shutter-lag still capture. Triggering locks focus once currently + * active sweep concludes. Canceling resumes continuous focusing. + * + * AF_MODE_EDOF: Advanced extended depth of field focusing. There is no + * autofocus scan, so triggering one or canceling one has no effect. + * Images are focused automatically by the HAL. + * + * ANDROID_CONTROL_AF_STATE: Dynamic metadata describing the current AF + * algorithm state, reported by the HAL in the result metadata. + * + * AF_STATE_INACTIVE: No focusing has been done, or algorithm was + * reset. Lens is not moving. Always the state for MODE_OFF or MODE_EDOF. + * When the device is opened, it must start in this state. + * + * AF_STATE_PASSIVE_SCAN: A continuous focus algorithm is currently scanning + * for good focus. The lens is moving. + * + * AF_STATE_PASSIVE_FOCUSED: A continuous focus algorithm believes it is + * well focused. The lens is not moving. The HAL may spontaneously leave + * this state. + * + * AF_STATE_PASSIVE_UNFOCUSED: A continuous focus algorithm believes it is + * not well focused. The lens is not moving. The HAL may spontaneously + * leave this state. + * + * AF_STATE_ACTIVE_SCAN: A scan triggered by the user is underway. + * + * AF_STATE_FOCUSED_LOCKED: The AF algorithm believes it is focused. The + * lens is not moving. + * + * AF_STATE_NOT_FOCUSED_LOCKED: The AF algorithm has been unable to + * focus. The lens is not moving. + * + * ANDROID_CONTROL_AF_TRIGGER: Control for starting an autofocus scan, the + * meaning of which is mode- and state- dependent. Set by the framework in + * the request settings. + * + * AF_TRIGGER_IDLE: No current trigger. + * + * AF_TRIGGER_START: Trigger start of AF scan. Effect is mode and state + * dependent. + * + * AF_TRIGGER_CANCEL: Cancel current AF scan if any, and reset algorithm to + * default. + * + * Additional metadata entries: + * + * ANDROID_CONTROL_AF_REGIONS: Control for selecting the regions of the FOV + * that should be used to determine good focus. This applies to all AF + * modes that scan for focus. Set by the framework in the request + * settings. + * + * S4.2. Auto-exposure settings and result entries: + * + * Main metadata entries: + * + * ANDROID_CONTROL_AE_MODE: Control for selecting the current auto-exposure + * mode. Set by the framework in the request settings. + * + * AE_MODE_OFF: Autoexposure is disabled; the user controls exposure, gain, + * frame duration, and flash. + * + * AE_MODE_ON: Standard autoexposure, with flash control disabled. User may + * set flash to fire or to torch mode. + * + * AE_MODE_ON_AUTO_FLASH: Standard autoexposure, with flash on at HAL's + * discretion for precapture and still capture. User control of flash + * disabled. + * + * AE_MODE_ON_ALWAYS_FLASH: Standard autoexposure, with flash always fired + * for capture, and at HAL's discretion for precapture.. User control of + * flash disabled. + * + * AE_MODE_ON_AUTO_FLASH_REDEYE: Standard autoexposure, with flash on at + * HAL's discretion for precapture and still capture. Use a flash burst + * at end of precapture sequence to reduce redeye in the final + * picture. User control of flash disabled. + * + * ANDROID_CONTROL_AE_STATE: Dynamic metadata describing the current AE + * algorithm state, reported by the HAL in the result metadata. + * + * AE_STATE_INACTIVE: Initial AE state after mode switch. When the device is + * opened, it must start in this state. + * + * AE_STATE_SEARCHING: AE is not converged to a good value, and is adjusting + * exposure parameters. + * + * AE_STATE_CONVERGED: AE has found good exposure values for the current + * scene, and the exposure parameters are not changing. HAL may + * spontaneously leave this state to search for better solution. + * + * AE_STATE_LOCKED: AE has been locked with the AE_LOCK control. Exposure + * values are not changing. + * + * AE_STATE_FLASH_REQUIRED: The HAL has converged exposure, but believes + * flash is required for a sufficiently bright picture. Used for + * determining if a zero-shutter-lag frame can be used. + * + * AE_STATE_PRECAPTURE: The HAL is in the middle of a precapture + * sequence. Depending on AE mode, this mode may involve firing the + * flash for metering, or a burst of flash pulses for redeye reduction. + * + * ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER: Control for starting a metering + * sequence before capturing a high-quality image. Set by the framework in + * the request settings. + * + * PRECAPTURE_TRIGGER_IDLE: No current trigger. + * + * PRECAPTURE_TRIGGER_START: Start a precapture sequence. The HAL should + * use the subsequent requests to measure good exposure/white balance + * for an upcoming high-resolution capture. + * + * Additional metadata entries: + * + * ANDROID_CONTROL_AE_LOCK: Control for locking AE controls to their current + * values + * + * ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION: Control for adjusting AE + * algorithm target brightness point. + * + * ANDROID_CONTROL_AE_TARGET_FPS_RANGE: Control for selecting the target frame + * rate range for the AE algorithm. The AE routine cannot change the frame + * rate to be outside these bounds. + * + * ANDROID_CONTROL_AE_REGIONS: Control for selecting the regions of the FOV + * that should be used to determine good exposure levels. This applies to + * all AE modes besides OFF. + * + * S4.3. Auto-whitebalance settings and result entries: + * + * Main metadata entries: + * + * ANDROID_CONTROL_AWB_MODE: Control for selecting the current white-balance + * mode. + * + * AWB_MODE_OFF: Auto-whitebalance is disabled. User controls color matrix. + * + * AWB_MODE_AUTO: Automatic white balance is enabled; 3A controls color + * transform, possibly using more complex transforms than a simple + * matrix. + * + * AWB_MODE_INCANDESCENT: Fixed white balance settings good for indoor + * incandescent (tungsten) lighting, roughly 2700K. + * + * AWB_MODE_FLUORESCENT: Fixed white balance settings good for fluorescent + * lighting, roughly 5000K. + * + * AWB_MODE_WARM_FLUORESCENT: Fixed white balance settings good for + * fluorescent lighting, roughly 3000K. + * + * AWB_MODE_DAYLIGHT: Fixed white balance settings good for daylight, + * roughly 5500K. + * + * AWB_MODE_CLOUDY_DAYLIGHT: Fixed white balance settings good for clouded + * daylight, roughly 6500K. + * + * AWB_MODE_TWILIGHT: Fixed white balance settings good for + * near-sunset/sunrise, roughly 15000K. + * + * AWB_MODE_SHADE: Fixed white balance settings good for areas indirectly + * lit by the sun, roughly 7500K. + * + * ANDROID_CONTROL_AWB_STATE: Dynamic metadata describing the current AWB + * algorithm state, reported by the HAL in the result metadata. + * + * AWB_STATE_INACTIVE: Initial AWB state after mode switch. When the device + * is opened, it must start in this state. + * + * AWB_STATE_SEARCHING: AWB is not converged to a good value, and is + * changing color adjustment parameters. + * + * AWB_STATE_CONVERGED: AWB has found good color adjustment values for the + * current scene, and the parameters are not changing. HAL may + * spontaneously leave this state to search for better solution. + * + * AWB_STATE_LOCKED: AWB has been locked with the AWB_LOCK control. Color + * adjustment values are not changing. + * + * Additional metadata entries: + * + * ANDROID_CONTROL_AWB_LOCK: Control for locking AWB color adjustments to + * their current values. + * + * ANDROID_CONTROL_AWB_REGIONS: Control for selecting the regions of the FOV + * that should be used to determine good color balance. This applies only + * to auto-WB mode. + * + * S4.4. General state machine transition notes + * + * Switching between AF, AE, or AWB modes always resets the algorithm's state + * to INACTIVE. Similarly, switching between CONTROL_MODE or + * CONTROL_SCENE_MODE if CONTROL_MODE == USE_SCENE_MODE resets all the + * algorithm states to INACTIVE. + * + * The tables below are per-mode. + * + * S4.5. AF state machines + * + * when enabling AF or changing AF mode + *| state | trans. cause | new state | notes | + *+--------------------+---------------+--------------------+------------------+ + *| Any | AF mode change| INACTIVE | | + *+--------------------+---------------+--------------------+------------------+ + * + * mode = AF_MODE_OFF or AF_MODE_EDOF + *| state | trans. cause | new state | notes | + *+--------------------+---------------+--------------------+------------------+ + *| INACTIVE | | INACTIVE | Never changes | + *+--------------------+---------------+--------------------+------------------+ + * + * mode = AF_MODE_AUTO or AF_MODE_MACRO + *| state | trans. cause | new state | notes | + *+--------------------+---------------+--------------------+------------------+ + *| INACTIVE | AF_TRIGGER | ACTIVE_SCAN | Start AF sweep | + *| | | | Lens now moving | + *+--------------------+---------------+--------------------+------------------+ + *| ACTIVE_SCAN | AF sweep done | FOCUSED_LOCKED | If AF successful | + *| | | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| ACTIVE_SCAN | AF sweep done | NOT_FOCUSED_LOCKED | If AF successful | + *| | | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| ACTIVE_SCAN | AF_CANCEL | INACTIVE | Cancel/reset AF | + *| | | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| FOCUSED_LOCKED | AF_CANCEL | INACTIVE | Cancel/reset AF | + *+--------------------+---------------+--------------------+------------------+ + *| FOCUSED_LOCKED | AF_TRIGGER | ACTIVE_SCAN | Start new sweep | + *| | | | Lens now moving | + *+--------------------+---------------+--------------------+------------------+ + *| NOT_FOCUSED_LOCKED | AF_CANCEL | INACTIVE | Cancel/reset AF | + *+--------------------+---------------+--------------------+------------------+ + *| NOT_FOCUSED_LOCKED | AF_TRIGGER | ACTIVE_SCAN | Start new sweep | + *| | | | Lens now moving | + *+--------------------+---------------+--------------------+------------------+ + *| All states | mode change | INACTIVE | | + *+--------------------+---------------+--------------------+------------------+ + * + * mode = AF_MODE_CONTINUOUS_VIDEO + *| state | trans. cause | new state | notes | + *+--------------------+---------------+--------------------+------------------+ + *| INACTIVE | HAL initiates | PASSIVE_SCAN | Start AF scan | + *| | new scan | | Lens now moving | + *+--------------------+---------------+--------------------+------------------+ + *| INACTIVE | AF_TRIGGER | NOT_FOCUSED_LOCKED | AF state query | + *| | | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_SCAN | HAL completes | PASSIVE_FOCUSED | End AF scan | + *| | current scan | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_SCAN | HAL fails | PASSIVE_UNFOCUSED | End AF scan | + *| | current scan | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_SCAN | AF_TRIGGER | FOCUSED_LOCKED | Immediate trans. | + *| | | | if focus is good | + *| | | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_SCAN | AF_TRIGGER | NOT_FOCUSED_LOCKED | Immediate trans. | + *| | | | if focus is bad | + *| | | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_SCAN | AF_CANCEL | INACTIVE | Reset lens | + *| | | | position | + *| | | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_FOCUSED | HAL initiates | PASSIVE_SCAN | Start AF scan | + *| | new scan | | Lens now moving | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_UNFOCUSED | HAL initiates | PASSIVE_SCAN | Start AF scan | + *| | new scan | | Lens now moving | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_FOCUSED | AF_TRIGGER | FOCUSED_LOCKED | Immediate trans. | + *| | | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_UNFOCUSED | AF_TRIGGER | NOT_FOCUSED_LOCKED | Immediate trans. | + *| | | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| FOCUSED_LOCKED | AF_TRIGGER | FOCUSED_LOCKED | No effect | + *+--------------------+---------------+--------------------+------------------+ + *| FOCUSED_LOCKED | AF_CANCEL | INACTIVE | Restart AF scan | + *+--------------------+---------------+--------------------+------------------+ + *| NOT_FOCUSED_LOCKED | AF_TRIGGER | NOT_FOCUSED_LOCKED | No effect | + *+--------------------+---------------+--------------------+------------------+ + *| NOT_FOCUSED_LOCKED | AF_CANCEL | INACTIVE | Restart AF scan | + *+--------------------+---------------+--------------------+------------------+ + * + * mode = AF_MODE_CONTINUOUS_PICTURE + *| state | trans. cause | new state | notes | + *+--------------------+---------------+--------------------+------------------+ + *| INACTIVE | HAL initiates | PASSIVE_SCAN | Start AF scan | + *| | new scan | | Lens now moving | + *+--------------------+---------------+--------------------+------------------+ + *| INACTIVE | AF_TRIGGER | NOT_FOCUSED_LOCKED | AF state query | + *| | | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_SCAN | HAL completes | PASSIVE_FOCUSED | End AF scan | + *| | current scan | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_SCAN | HAL fails | PASSIVE_UNFOCUSED | End AF scan | + *| | current scan | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_SCAN | AF_TRIGGER | FOCUSED_LOCKED | Eventual trans. | + *| | | | once focus good | + *| | | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_SCAN | AF_TRIGGER | NOT_FOCUSED_LOCKED | Eventual trans. | + *| | | | if cannot focus | + *| | | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_SCAN | AF_CANCEL | INACTIVE | Reset lens | + *| | | | position | + *| | | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_FOCUSED | HAL initiates | PASSIVE_SCAN | Start AF scan | + *| | new scan | | Lens now moving | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_UNFOCUSED | HAL initiates | PASSIVE_SCAN | Start AF scan | + *| | new scan | | Lens now moving | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_FOCUSED | AF_TRIGGER | FOCUSED_LOCKED | Immediate trans. | + *| | | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| PASSIVE_UNFOCUSED | AF_TRIGGER | NOT_FOCUSED_LOCKED | Immediate trans. | + *| | | | Lens now locked | + *+--------------------+---------------+--------------------+------------------+ + *| FOCUSED_LOCKED | AF_TRIGGER | FOCUSED_LOCKED | No effect | + *+--------------------+---------------+--------------------+------------------+ + *| FOCUSED_LOCKED | AF_CANCEL | INACTIVE | Restart AF scan | + *+--------------------+---------------+--------------------+------------------+ + *| NOT_FOCUSED_LOCKED | AF_TRIGGER | NOT_FOCUSED_LOCKED | No effect | + *+--------------------+---------------+--------------------+------------------+ + *| NOT_FOCUSED_LOCKED | AF_CANCEL | INACTIVE | Restart AF scan | + *+--------------------+---------------+--------------------+------------------+ + * + * S4.6. AE and AWB state machines + * + * The AE and AWB state machines are mostly identical. AE has additional + * FLASH_REQUIRED and PRECAPTURE states. So rows below that refer to those two + * states should be ignored for the AWB state machine. + * + * when enabling AE/AWB or changing AE/AWB mode + *| state | trans. cause | new state | notes | + *+--------------------+---------------+--------------------+------------------+ + *| Any | mode change | INACTIVE | | + *+--------------------+---------------+--------------------+------------------+ + * + * mode = AE_MODE_OFF / AWB mode not AUTO + *| state | trans. cause | new state | notes | + *+--------------------+---------------+--------------------+------------------+ + *| INACTIVE | | INACTIVE | AE/AWB disabled | + *+--------------------+---------------+--------------------+------------------+ + * + * mode = AE_MODE_ON_* / AWB_MODE_AUTO + *| state | trans. cause | new state | notes | + *+--------------------+---------------+--------------------+------------------+ + *| INACTIVE | HAL initiates | SEARCHING | | + *| | AE/AWB scan | | | + *+--------------------+---------------+--------------------+------------------+ + *| INACTIVE | AE/AWB_LOCK | LOCKED | values locked | + *| | on | | | + *+--------------------+---------------+--------------------+------------------+ + *| SEARCHING | HAL finishes | CONVERGED | good values, not | + *| | AE/AWB scan | | changing | + *+--------------------+---------------+--------------------+------------------+ + *| SEARCHING | HAL finishes | FLASH_REQUIRED | converged but too| + *| | AE scan | | dark w/o flash | + *+--------------------+---------------+--------------------+------------------+ + *| SEARCHING | AE/AWB_LOCK | LOCKED | values locked | + *| | on | | | + *+--------------------+---------------+--------------------+------------------+ + *| CONVERGED | HAL initiates | SEARCHING | values locked | + *| | AE/AWB scan | | | + *+--------------------+---------------+--------------------+------------------+ + *| CONVERGED | AE/AWB_LOCK | LOCKED | values locked | + *| | on | | | + *+--------------------+---------------+--------------------+------------------+ + *| FLASH_REQUIRED | HAL initiates | SEARCHING | values locked | + *| | AE/AWB scan | | | + *+--------------------+---------------+--------------------+------------------+ + *| FLASH_REQUIRED | AE/AWB_LOCK | LOCKED | values locked | + *| | on | | | + *+--------------------+---------------+--------------------+------------------+ + *| LOCKED | AE/AWB_LOCK | SEARCHING | values not good | + *| | off | | after unlock | + *+--------------------+---------------+--------------------+------------------+ + *| LOCKED | AE/AWB_LOCK | CONVERGED | values good | + *| | off | | after unlock | + *+--------------------+---------------+--------------------+------------------+ + *| LOCKED | AE_LOCK | FLASH_REQUIRED | exposure good, | + *| | off | | but too dark | + *+--------------------+---------------+--------------------+------------------+ + *| All AE states | PRECAPTURE_ | PRECAPTURE | Start precapture | + *| | START | | sequence | + *+--------------------+---------------+--------------------+------------------+ + *| PRECAPTURE | Sequence done.| CONVERGED | Ready for high- | + *| | AE_LOCK off | | quality capture | + *+--------------------+---------------+--------------------+------------------+ + *| PRECAPTURE | Sequence done.| LOCKED | Ready for high- | + *| | AE_LOCK on | | quality capture | + *+--------------------+---------------+--------------------+------------------+ + * + */ + +/** + * S5. Cropping: + * + * Cropping of the full pixel array (for digital zoom and other use cases where + * a smaller FOV is desirable) is communicated through the + * ANDROID_SCALER_CROP_REGION setting. This is a per-request setting, and can + * change on a per-request basis, which is critical for implementing smooth + * digital zoom. + * + * The region is defined as a rectangle (x, y, width, height), with (x, y) + * describing the top-left corner of the rectangle. The rectangle is defined on + * the coordinate system of the sensor active pixel array, with (0,0) being the + * top-left pixel of the active pixel array. Therefore, the width and height + * cannot be larger than the dimensions reported in the + * ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY static info field. The minimum allowed + * width and height are reported by the HAL through the + * ANDROID_SCALER_MAX_DIGITAL_ZOOM static info field, which describes the + * maximum supported zoom factor. Therefore, the minimum crop region width and + * height are: + * + * {width, height} = + * { floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[0] / + * ANDROID_SCALER_MAX_DIGITAL_ZOOM), + * floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[1] / + * ANDROID_SCALER_MAX_DIGITAL_ZOOM) } + * + * If the crop region needs to fulfill specific requirements (for example, it + * needs to start on even coordinates, and its width/height needs to be even), + * the HAL must do the necessary rounding and write out the final crop region + * used in the output result metadata. Similarly, if the HAL implements video + * stabilization, it must adjust the result crop region to describe the region + * actually included in the output after video stabilization is applied. In + * general, a camera-using application must be able to determine the field of + * view it is receiving based on the crop region, the dimensions of the image + * sensor, and the lens focal length. + * + * It is assumed that the cropping is applied after raw to other color space + * conversion. Raw streams (RAW16 and RAW_OPAQUE) don't have this conversion stage, + * and are not croppable. Therefore, the crop region must be ignored by the HAL + * for raw streams. + * + * Since the crop region applies to all non-raw streams, which may have different aspect + * ratios than the crop region, the exact sensor region used for each stream may + * be smaller than the crop region. Specifically, each stream should maintain + * square pixels and its aspect ratio by minimally further cropping the defined + * crop region. If the stream's aspect ratio is wider than the crop region, the + * stream should be further cropped vertically, and if the stream's aspect ratio + * is narrower than the crop region, the stream should be further cropped + * horizontally. + * + * In all cases, the stream crop must be centered within the full crop region, + * and each stream is only either cropped horizontally or vertical relative to + * the full crop region, never both. + * + * For example, if two streams are defined, a 640x480 stream (4:3 aspect), and a + * 1280x720 stream (16:9 aspect), below demonstrates the expected output regions + * for each stream for a few sample crop regions, on a hypothetical 3 MP (2000 x + * 1500 pixel array) sensor. + * + * Crop region: (500, 375, 1000, 750) (4:3 aspect ratio) + * + * 640x480 stream crop: (500, 375, 1000, 750) (equal to crop region) + * 1280x720 stream crop: (500, 469, 1000, 562) (marked with =) + * + * 0 1000 2000 + * +---------+---------+---------+----------+ + * | Active pixel array | + * | | + * | | + * + +-------------------+ + 375 + * | | | | + * | O===================O | + * | I 1280x720 stream I | + * + I I + 750 + * | I I | + * | O===================O | + * | | | | + * + +-------------------+ + 1125 + * | Crop region, 640x480 stream | + * | | + * | | + * +---------+---------+---------+----------+ 1500 + * + * Crop region: (500, 375, 1333, 750) (16:9 aspect ratio) + * + * 640x480 stream crop: (666, 375, 1000, 750) (marked with =) + * 1280x720 stream crop: (500, 375, 1333, 750) (equal to crop region) + * + * 0 1000 2000 + * +---------+---------+---------+----------+ + * | Active pixel array | + * | | + * | | + * + +---O==================O---+ + 375 + * | | I 640x480 stream I | | + * | | I I | | + * | | I I | | + * + | I I | + 750 + * | | I I | | + * | | I I | | + * | | I I | | + * + +---O==================O---+ + 1125 + * | Crop region, 1280x720 stream | + * | | + * | | + * +---------+---------+---------+----------+ 1500 + * + * Crop region: (500, 375, 750, 750) (1:1 aspect ratio) + * + * 640x480 stream crop: (500, 469, 750, 562) (marked with =) + * 1280x720 stream crop: (500, 543, 750, 414) (marged with #) + * + * 0 1000 2000 + * +---------+---------+---------+----------+ + * | Active pixel array | + * | | + * | | + * + +--------------+ + 375 + * | O==============O | + * | ################ | + * | # # | + * + # # + 750 + * | # # | + * | ################ 1280x720 | + * | O==============O 640x480 | + * + +--------------+ + 1125 + * | Crop region | + * | | + * | | + * +---------+---------+---------+----------+ 1500 + * + * And a final example, a 1024x1024 square aspect ratio stream instead of the + * 480p stream: + * + * Crop region: (500, 375, 1000, 750) (4:3 aspect ratio) + * + * 1024x1024 stream crop: (625, 375, 750, 750) (marked with #) + * 1280x720 stream crop: (500, 469, 1000, 562) (marked with =) + * + * 0 1000 2000 + * +---------+---------+---------+----------+ + * | Active pixel array | + * | | + * | 1024x1024 stream | + * + +--###############--+ + 375 + * | | # # | | + * | O===================O | + * | I 1280x720 stream I | + * + I I + 750 + * | I I | + * | O===================O | + * | | # # | | + * + +--###############--+ + 1125 + * | Crop region | + * | | + * | | + * +---------+---------+---------+----------+ 1500 + * + */ + +/** + * S6. Error management: + * + * Camera HAL device ops functions that have a return value will all return + * -ENODEV / NULL in case of a serious error. This means the device cannot + * continue operation, and must be closed by the framework. Once this error is + * returned by some method, or if notify() is called with ERROR_DEVICE, only + * the close() method can be called successfully. All other methods will return + * -ENODEV / NULL. + * + * If a device op is called in the wrong sequence, for example if the framework + * calls configure_streams() is called before initialize(), the device must + * return -ENOSYS from the call, and do nothing. + * + * Transient errors in image capture must be reported through notify() as follows: + * + * - The failure of an entire capture to occur must be reported by the HAL by + * calling notify() with ERROR_REQUEST. Individual errors for the result + * metadata or the output buffers must not be reported in this case. + * + * - If the metadata for a capture cannot be produced, but some image buffers + * were filled, the HAL must call notify() with ERROR_RESULT. + * + * - If an output image buffer could not be filled, but either the metadata was + * produced or some other buffers were filled, the HAL must call notify() with + * ERROR_BUFFER for each failed buffer. + * + * In each of these transient failure cases, the HAL must still call + * process_capture_result, with valid output and input (if an input buffer was + * submitted) buffer_handle_t. If the result metadata could not be produced, it + * should be NULL. If some buffers could not be filled, they must be returned with + * process_capture_result in the error state, their release fences must be set to + * the acquire fences passed by the framework, or -1 if they have been waited on by + * the HAL already. + * + * Invalid input arguments result in -EINVAL from the appropriate methods. In + * that case, the framework must act as if that call had never been made. + * + */ + +/** + * S7. Key Performance Indicator (KPI) glossary: + * + * This includes some critical definitions that are used by KPI metrics. + * + * Pipeline Latency: + * For a given capture request, the duration from the framework calling + * process_capture_request to the HAL sending capture result and all buffers + * back by process_capture_result call. To make the Pipeline Latency measure + * independent of frame rate, it is measured by frame count. + * + * For example, when frame rate is 30 (fps), the frame duration (time interval + * between adjacent frame capture time) is 33 (ms). + * If it takes 5 frames for framework to get the result and buffers back for + * a given request, then the Pipeline Latency is 5 (frames), instead of + * 5 x 33 = 165 (ms). + * + * The Pipeline Latency is determined by android.request.pipelineDepth and + * android.request.pipelineMaxDepth, see their definitions for more details. + * + */ + +/** + * S8. Sample Use Cases: + * + * This includes some typical use case examples the camera HAL may support. + * + * S8.1 Zero Shutter Lag (ZSL) with CAMERA3_STREAM_BIDIRECTIONAL stream. + * + * For this use case, the bidirectional stream will be used by the framework as follows: + * + * 1. The framework includes a buffer from this stream as output buffer in a + * request as normal. + * + * 2. Once the HAL device returns a filled output buffer to the framework, + * the framework may do one of two things with the filled buffer: + * + * 2. a. The framework uses the filled data, and returns the now-used buffer + * to the stream queue for reuse. This behavior exactly matches the + * OUTPUT type of stream. + * + * 2. b. The framework wants to reprocess the filled data, and uses the + * buffer as an input buffer for a request. Once the HAL device has + * used the reprocessing buffer, it then returns it to the + * framework. The framework then returns the now-used buffer to the + * stream queue for reuse. + * + * 3. The HAL device will be given the buffer again as an output buffer for + * a request at some future point. + * + * For ZSL use case, the pixel format for bidirectional stream will be + * HAL_PIXEL_FORMAT_RAW_OPAQUE or HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED if it + * is listed in android.scaler.availableInputOutputFormatsMap. When + * HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED is used, the gralloc + * usage flags for the consumer endpoint will be set to GRALLOC_USAGE_HW_CAMERA_ZSL. + * A configuration stream list that has BIDIRECTIONAL stream used as input, will + * usually also have a distinct OUTPUT stream to get the reprocessing data. For example, + * for the ZSL use case, the stream list might be configured with the following: + * + * - A HAL_PIXEL_FORMAT_RAW_OPAQUE bidirectional stream is used + * as input. + * - And a HAL_PIXEL_FORMAT_BLOB (JPEG) output stream. + * + * S8.2 ZSL (OPAQUE) reprocessing with CAMERA3_STREAM_INPUT stream. + * + * CAMERA_DEVICE_API_VERSION_3_3: + * When OPAQUE_REPROCESSING capability is supported by the camera device, the INPUT stream + * can be used for application/framework implemented use case like Zero Shutter Lag (ZSL). + * This kind of stream will be used by the framework as follows: + * + * 1. Application/framework configures an opaque (RAW or YUV based) format output stream that is + * used to produce the ZSL output buffers. The stream pixel format will be + * HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED. + * + * 2. Application/framework configures an opaque format input stream that is used to + * send the reprocessing ZSL buffers to the HAL. The stream pixel format will + * also be HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED. + * + * 3. Application/framework configures a YUV/JPEG output stream that is used to receive the + * reprocessed data. The stream pixel format will be YCbCr_420/HAL_PIXEL_FORMAT_BLOB. + * + * 4. Application/framework picks a ZSL buffer from the ZSL output stream when a ZSL capture is + * issued by the application, and sends the data back as an input buffer in a + * reprocessing request, then sends to the HAL for reprocessing. + * + * 5. The HAL sends back the output YUV/JPEG result to framework. + * + * The HAL can select the actual opaque buffer format and configure the ISP pipeline + * appropriately based on the HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED format and + * the gralloc usage flag GRALLOC_USAGE_HW_CAMERA_ZSL. + + * S8.3 YUV reprocessing with CAMERA3_STREAM_INPUT stream. + * + * When YUV reprocessing is supported by the HAL, the INPUT stream + * can be used for the YUV reprocessing use cases like lucky-shot and image fusion. + * This kind of stream will be used by the framework as follows: + * + * 1. Application/framework configures an YCbCr_420 format output stream that is + * used to produce the output buffers. + * + * 2. Application/framework configures an YCbCr_420 format input stream that is used to + * send the reprocessing YUV buffers to the HAL. + * + * 3. Application/framework configures a YUV/JPEG output stream that is used to receive the + * reprocessed data. The stream pixel format will be YCbCr_420/HAL_PIXEL_FORMAT_BLOB. + * + * 4. Application/framework processes the output buffers (could be as simple as picking + * an output buffer directly) from the output stream when a capture is issued, and sends + * the data back as an input buffer in a reprocessing request, then sends to the HAL + * for reprocessing. + * + * 5. The HAL sends back the output YUV/JPEG result to framework. + * + */ + +/** + * S9. Notes on Controls and Metadata + * + * This section contains notes about the interpretation and usage of various metadata tags. + * + * S9.1 HIGH_QUALITY and FAST modes. + * + * Many camera post-processing blocks may be listed as having HIGH_QUALITY, + * FAST, and OFF operating modes. These blocks will typically also have an + * 'available modes' tag representing which of these operating modes are + * available on a given device. The general policy regarding implementing + * these modes is as follows: + * + * 1. Operating mode controls of hardware blocks that cannot be disabled + * must not list OFF in their corresponding 'available modes' tags. + * + * 2. OFF will always be included in their corresponding 'available modes' + * tag if it is possible to disable that hardware block. + * + * 3. FAST must always be included in the 'available modes' tags for all + * post-processing blocks supported on the device. If a post-processing + * block also has a slower and higher quality operating mode that does + * not meet the framerate requirements for FAST mode, HIGH_QUALITY should + * be included in the 'available modes' tag to represent this operating + * mode. + */ + +/** + * S10. Reprocessing flow and controls + * + * This section describes the OPAQUE and YUV reprocessing flow and controls. OPAQUE reprocessing + * uses an opaque format that is not directly application-visible, and the application can + * only select some of the output buffers and send back to HAL for reprocessing, while YUV + * reprocessing gives the application opportunity to process the buffers before reprocessing. + * + * S8 gives the stream configurations for the typical reprocessing uses cases, + * this section specifies the buffer flow and controls in more details. + * + * S10.1 OPAQUE (typically for ZSL use case) reprocessing flow and controls + * + * For OPAQUE reprocessing (e.g. ZSL) use case, after the application creates the specific + * output and input streams, runtime buffer flow and controls are specified as below: + * + * 1. Application starts output streaming by sending repeating requests for output + * opaque buffers and preview. The buffers are held by an application + * maintained circular buffer. The requests are based on CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG + * capture template, which should have all necessary settings that guarantee output + * frame rate is not slowed down relative to sensor output frame rate. + * + * 2. When a capture is issued, the application selects one output buffer based + * on application buffer selection logic, e.g. good AE and AF statistics etc. + * Application then creates an reprocess request based on the capture result associated + * with this selected buffer. The selected output buffer is now added to this reprocess + * request as an input buffer, the output buffer of this reprocess request should be + * either JPEG output buffer or YUV output buffer, or both, depending on the application + * choice. + * + * 3. Application then alters the reprocess settings to get best image quality. The HAL must + * support and only support below controls if the HAL support OPAQUE_REPROCESSING capability: + * - android.jpeg.* (if JPEG buffer is included as one of the output) + * - android.noiseReduction.mode (change to HIGH_QUALITY if it is supported) + * - android.edge.mode (change to HIGH_QUALITY if it is supported) + * All other controls must be ignored by the HAL. + * 4. HAL processed the input buffer and return the output buffers in the capture results + * as normal. + * + * S10.2 YUV reprocessing flow and controls + * + * The YUV reprocessing buffer flow is similar as OPAQUE reprocessing, with below difference: + * + * 1. Application may want to have finer granularity control of the intermediate YUV images + * (before reprocessing). For example, application may choose + * - android.noiseReduction.mode == MINIMAL + * to make sure the no YUV domain noise reduction has applied to the output YUV buffers, + * then it can do its own advanced noise reduction on them. For OPAQUE reprocessing case, this + * doesn't matter, as long as the final reprocessed image has the best quality. + * 2. Application may modify the YUV output buffer data. For example, for image fusion use + * case, where multiple output images are merged together to improve the signal-to-noise + * ratio (SNR). The input buffer may be generated from multiple buffers by the application. + * To avoid excessive amount of noise reduction and insufficient amount of edge enhancement + * being applied to the input buffer, the application can hint the HAL how much effective + * exposure time improvement has been done by the application, then the HAL can adjust the + * noise reduction and edge enhancement paramters to get best reprocessed image quality. + * Below tag can be used for this purpose: + * - android.reprocess.effectiveExposureFactor + * The value would be exposure time increase factor applied to the original output image, + * for example, if there are N image merged, the exposure time increase factor would be up + * to sqrt(N). See this tag spec for more details. + * + * S10.3 Reprocessing pipeline characteristics + * + * Reprocessing pipeline has below different characteristics comparing with normal output + * pipeline: + * + * 1. The reprocessing result can be returned ahead of the pending normal output results. But + * the FIFO ordering must be maintained for all reprocessing results. For example, there are + * below requests (A stands for output requests, B stands for reprocessing requests) + * being processed by the HAL: + * A1, A2, A3, A4, B1, A5, B2, A6... + * result of B1 can be returned before A1-A4, but result of B2 must be returned after B1. + * 2. Single input rule: For a given reprocessing request, all output buffers must be from the + * input buffer, rather than sensor output. For example, if a reprocess request include both + * JPEG and preview buffers, all output buffers must be produced from the input buffer + * included by the reprocessing request, rather than sensor. The HAL must not output preview + * buffers from sensor, while output JPEG buffer from the input buffer. + * 3. Input buffer will be from camera output directly (ZSL case) or indirectly(image fusion + * case). For the case where buffer is modified, the size will remain same. The HAL can + * notify CAMERA3_MSG_ERROR_REQUEST if buffer from unknown source is sent. + * 4. Result as reprocessing request: The HAL can expect that a reprocessing request is a copy + * of one of the output results with minor allowed setting changes. The HAL can notify + * CAMERA3_MSG_ERROR_REQUEST if a request from unknown source is issued. + * 5. Output buffers may not be used as inputs across the configure stream boundary, This is + * because an opaque stream like the ZSL output stream may have different actual image size + * inside of the ZSL buffer to save power and bandwidth for smaller resolution JPEG capture. + * The HAL may notify CAMERA3_MSG_ERROR_REQUEST if this case occurs. + * 6. HAL Reprocess requests error reporting during flush should follow the same rule specified + * by flush() method. + * + */ + +__BEGIN_DECLS + +struct camera3_device; + +/********************************************************************** + * + * Camera3 stream and stream buffer definitions. + * + * These structs and enums define the handles and contents of the input and + * output streams connecting the HAL to various framework and application buffer + * consumers. Each stream is backed by a gralloc buffer queue. + * + */ + +/** + * camera3_stream_type_t: + * + * The type of the camera stream, which defines whether the camera HAL device is + * the producer or the consumer for that stream, and how the buffers of the + * stream relate to the other streams. + */ +typedef enum camera3_stream_type { + /** + * This stream is an output stream; the camera HAL device will be + * responsible for filling buffers from this stream with newly captured or + * reprocessed image data. + */ + CAMERA3_STREAM_OUTPUT = 0, + + /** + * This stream is an input stream; the camera HAL device will be responsible + * for reading buffers from this stream and sending them through the camera + * processing pipeline, as if the buffer was a newly captured image from the + * imager. + * + * The pixel format for input stream can be any format reported by + * android.scaler.availableInputOutputFormatsMap. The pixel format of the + * output stream that is used to produce the reprocessing data may be any + * format reported by android.scaler.availableStreamConfigurations. The + * supported input/output stream combinations depends the camera device + * capabilities, see android.scaler.availableInputOutputFormatsMap for + * stream map details. + * + * This kind of stream is generally used to reprocess data into higher + * quality images (that otherwise would cause a frame rate performance + * loss), or to do off-line reprocessing. + * + * CAMERA_DEVICE_API_VERSION_3_3: + * The typical use cases are OPAQUE (typically ZSL) and YUV reprocessing, + * see S8.2, S8.3 and S10 for more details. + */ + CAMERA3_STREAM_INPUT = 1, + + /** + * This stream can be used for input and output. Typically, the stream is + * used as an output stream, but occasionally one already-filled buffer may + * be sent back to the HAL device for reprocessing. + * + * This kind of stream is meant generally for Zero Shutter Lag (ZSL) + * features, where copying the captured image from the output buffer to the + * reprocessing input buffer would be expensive. See S8.1 for more details. + * + * Note that the HAL will always be reprocessing data it produced. + * + */ + CAMERA3_STREAM_BIDIRECTIONAL = 2, + + /** + * Total number of framework-defined stream types + */ + CAMERA3_NUM_STREAM_TYPES + +} camera3_stream_type_t; + +/** + * camera3_stream_rotation_t: + * + * The required counterclockwise rotation of camera stream. + */ +typedef enum camera3_stream_rotation { + /* No rotation */ + CAMERA3_STREAM_ROTATION_0 = 0, + + /* Rotate by 90 degree counterclockwise */ + CAMERA3_STREAM_ROTATION_90 = 1, + + /* Rotate by 180 degree counterclockwise */ + CAMERA3_STREAM_ROTATION_180 = 2, + + /* Rotate by 270 degree counterclockwise */ + CAMERA3_STREAM_ROTATION_270 = 3 +} camera3_stream_rotation_t; + +/** + * camera3_stream_configuration_mode_t: + * + * This defines the general operation mode for the HAL (for a given stream configuration), where + * modes besides NORMAL have different semantics, and usually limit the generality of the API in + * exchange for higher performance in some particular area. + */ +typedef enum camera3_stream_configuration_mode { + /** + * Normal stream configuration operation mode. This is the default camera operation mode, + * where all semantics of HAL APIs and metadata controls apply. + */ + CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE = 0, + + /** + * Special constrained high speed operation mode for devices that can not support high + * speed output in NORMAL mode. All streams in this configuration are operating at high speed + * mode and have different characteristics and limitations to achieve high speed output. + * The NORMAL mode can still be used for high speed output if the HAL can support high speed + * output while satisfying all the semantics of HAL APIs and metadata controls. It is + * recommended for the HAL to support high speed output in NORMAL mode (by advertising the high + * speed FPS ranges in android.control.aeAvailableTargetFpsRanges) if possible. + * + * This mode has below limitations/requirements: + * + * 1. The HAL must support up to 2 streams with sizes reported by + * android.control.availableHighSpeedVideoConfigurations. + * 2. In this mode, the HAL is expected to output up to 120fps or higher. This mode must + * support the targeted FPS range and size configurations reported by + * android.control.availableHighSpeedVideoConfigurations. + * 3. The HAL must support HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED output stream format. + * 4. To achieve efficient high speed streaming, the HAL may have to aggregate + * multiple frames together and send to camera device for processing where the request + * controls are same for all the frames in this batch (batch mode). The HAL must support + * max batch size and the max batch size requirements defined by + * android.control.availableHighSpeedVideoConfigurations. + * 5. In this mode, the HAL must override aeMode, awbMode, and afMode to ON, ON, and + * CONTINUOUS_VIDEO, respectively. All post-processing block mode controls must be + * overridden to be FAST. Therefore, no manual control of capture and post-processing + * parameters is possible. All other controls operate the same as when + * android.control.mode == AUTO. This means that all other android.control.* fields + * must continue to work, such as + * + * android.control.aeTargetFpsRange + * android.control.aeExposureCompensation + * android.control.aeLock + * android.control.awbLock + * android.control.effectMode + * android.control.aeRegions + * android.control.afRegions + * android.control.awbRegions + * android.control.afTrigger + * android.control.aePrecaptureTrigger + * + * Outside of android.control.*, the following controls must work: + * + * android.flash.mode (TORCH mode only, automatic flash for still capture will not work + * since aeMode is ON) + * android.lens.opticalStabilizationMode (if it is supported) + * android.scaler.cropRegion + * android.statistics.faceDetectMode (if it is supported) + * + * For more details about high speed stream requirements, see + * android.control.availableHighSpeedVideoConfigurations and CONSTRAINED_HIGH_SPEED_VIDEO + * capability defined in android.request.availableCapabilities. + * + * This mode only needs to be supported by HALs that include CONSTRAINED_HIGH_SPEED_VIDEO in + * the android.request.availableCapabilities static metadata. + */ + CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE = 1, + + /** + * First value for vendor-defined stream configuration modes. + */ + CAMERA3_VENDOR_STREAM_CONFIGURATION_MODE_START = 0x8000 +} camera3_stream_configuration_mode_t; + +/** + * camera3_stream_t: + * + * A handle to a single camera input or output stream. A stream is defined by + * the framework by its buffer resolution and format, and additionally by the + * HAL with the gralloc usage flags and the maximum in-flight buffer count. + * + * The stream structures are owned by the framework, but pointers to a + * camera3_stream passed into the HAL by configure_streams() are valid until the + * end of the first subsequent configure_streams() call that _does not_ include + * that camera3_stream as an argument, or until the end of the close() call. + * + * All camera3_stream framework-controlled members are immutable once the + * camera3_stream is passed into configure_streams(). The HAL may only change + * the HAL-controlled parameters during a configure_streams() call, except for + * the contents of the private pointer. + * + * If a configure_streams() call returns a non-fatal error, all active streams + * remain valid as if configure_streams() had not been called. + * + * The endpoint of the stream is not visible to the camera HAL device. + * In DEVICE_API_VERSION_3_1, this was changed to share consumer usage flags + * on streams where the camera is a producer (OUTPUT and BIDIRECTIONAL stream + * types) see the usage field below. + */ +typedef struct camera3_stream { + + /***** + * Set by framework before configure_streams() + */ + + /** + * The type of the stream, one of the camera3_stream_type_t values. + */ + int stream_type; + + /** + * The width in pixels of the buffers in this stream + */ + uint32_t width; + + /** + * The height in pixels of the buffers in this stream + */ + uint32_t height; + + /** + * The pixel format for the buffers in this stream. Format is a value from + * the HAL_PIXEL_FORMAT_* list in system/core/include/system/graphics.h, or + * from device-specific headers. + * + * If HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED is used, then the platform + * gralloc module will select a format based on the usage flags provided by + * the camera device and the other endpoint of the stream. + * + * <= CAMERA_DEVICE_API_VERSION_3_1: + * + * The camera HAL device must inspect the buffers handed to it in the + * subsequent register_stream_buffers() call to obtain the + * implementation-specific format details, if necessary. + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * register_stream_buffers() won't be called by the framework, so the HAL + * should configure the ISP and sensor pipeline based purely on the sizes, + * usage flags, and formats for the configured streams. + */ + int format; + + /***** + * Set by HAL during configure_streams(). + */ + + /** + * The gralloc usage flags for this stream, as needed by the HAL. The usage + * flags are defined in gralloc.h (GRALLOC_USAGE_*), or in device-specific + * headers. + * + * For output streams, these are the HAL's producer usage flags. For input + * streams, these are the HAL's consumer usage flags. The usage flags from + * the producer and the consumer will be combined together and then passed + * to the platform gralloc HAL module for allocating the gralloc buffers for + * each stream. + * + * Version information: + * + * == CAMERA_DEVICE_API_VERSION_3_0: + * + * No initial value guaranteed when passed via configure_streams(). + * HAL may not use this field as input, and must write over this field + * with its usage flags. + * + * >= CAMERA_DEVICE_API_VERSION_3_1: + * + * For stream_type OUTPUT and BIDIRECTIONAL, when passed via + * configure_streams(), the initial value of this is the consumer's + * usage flags. The HAL may use these consumer flags to decide stream + * configuration. + * For stream_type INPUT, when passed via configure_streams(), the initial + * value of this is 0. + * For all streams passed via configure_streams(), the HAL must write + * over this field with its usage flags. + */ + uint32_t usage; + + /** + * The maximum number of buffers the HAL device may need to have dequeued at + * the same time. The HAL device may not have more buffers in-flight from + * this stream than this value. + */ + uint32_t max_buffers; + + /** + * A handle to HAL-private information for the stream. Will not be inspected + * by the framework code. + */ + void *priv; + + /** + * A field that describes the contents of the buffer. The format and buffer + * dimensions define the memory layout and structure of the stream buffers, + * while dataSpace defines the meaning of the data within the buffer. + * + * For most formats, dataSpace defines the color space of the image data. + * In addition, for some formats, dataSpace indicates whether image- or + * depth-based data is requested. See system/core/include/system/graphics.h + * for details of formats and valid dataSpace values for each format. + * + * Version information: + * + * < CAMERA_DEVICE_API_VERSION_3_3: + * + * Not defined and should not be accessed. dataSpace should be assumed to + * be HAL_DATASPACE_UNKNOWN, and the appropriate color space, etc, should + * be determined from the usage flags and the format. + * + * >= CAMERA_DEVICE_API_VERSION_3_3: + * + * Always set by the camera service. HAL must use this dataSpace to + * configure the stream to the correct colorspace, or to select between + * color and depth outputs if supported. + */ + android_dataspace_t data_space; + + /** + * The required output rotation of the stream, one of + * the camera3_stream_rotation_t values. This must be inspected by HAL along + * with stream width and height. For example, if the rotation is 90 degree + * and the stream width and height is 720 and 1280 respectively, camera service + * will supply buffers of size 720x1280, and HAL should capture a 1280x720 image + * and rotate the image by 90 degree counterclockwise. The rotation field is + * no-op when the stream type is input. Camera HAL must ignore the rotation + * field for an input stream. + * + * <= CAMERA_DEVICE_API_VERSION_3_2: + * + * Not defined and must not be accessed. HAL must not apply any rotation + * on output images. + * + * >= CAMERA_DEVICE_API_VERSION_3_3: + * + * Always set by camera service. HAL must inspect this field during stream + * configuration and returns -EINVAL if HAL cannot perform such rotation. + * HAL must always support CAMERA3_STREAM_ROTATION_0, so a + * configure_streams() call must not fail for unsupported rotation if + * rotation field of all streams is CAMERA3_STREAM_ROTATION_0. + * + */ + int rotation; + + /* reserved for future use */ + void *reserved[7]; + +} camera3_stream_t; + +/** + * camera3_stream_configuration_t: + * + * A structure of stream definitions, used by configure_streams(). This + * structure defines all the output streams and the reprocessing input + * stream for the current camera use case. + */ +typedef struct camera3_stream_configuration { + /** + * The total number of streams requested by the framework. This includes + * both input and output streams. The number of streams will be at least 1, + * and there will be at least one output-capable stream. + */ + uint32_t num_streams; + + /** + * An array of camera stream pointers, defining the input/output + * configuration for the camera HAL device. + * + * At most one input-capable stream may be defined (INPUT or BIDIRECTIONAL) + * in a single configuration. + * + * At least one output-capable stream must be defined (OUTPUT or + * BIDIRECTIONAL). + */ + camera3_stream_t **streams; + + /** + * >= CAMERA_DEVICE_API_VERSION_3_3: + * + * The operation mode of streams in this configuration, one of the value defined in + * camera3_stream_configuration_mode_t. + * The HAL can use this mode as an indicator to set the stream property (e.g., + * camera3_stream->max_buffers) appropriately. For example, if the configuration is + * CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE, the HAL may want to set aside more + * buffers for batch mode operation (see android.control.availableHighSpeedVideoConfigurations + * for batch mode definition). + * + */ + uint32_t operation_mode; +} camera3_stream_configuration_t; + +/** + * camera3_buffer_status_t: + * + * The current status of a single stream buffer. + */ +typedef enum camera3_buffer_status { + /** + * The buffer is in a normal state, and can be used after waiting on its + * sync fence. + */ + CAMERA3_BUFFER_STATUS_OK = 0, + + /** + * The buffer does not contain valid data, and the data in it should not be + * used. The sync fence must still be waited on before reusing the buffer. + */ + CAMERA3_BUFFER_STATUS_ERROR = 1 + +} camera3_buffer_status_t; + +/** + * camera3_stream_buffer_t: + * + * A single buffer from a camera3 stream. It includes a handle to its parent + * stream, the handle to the gralloc buffer itself, and sync fences + * + * The buffer does not specify whether it is to be used for input or output; + * that is determined by its parent stream type and how the buffer is passed to + * the HAL device. + */ +typedef struct camera3_stream_buffer { + /** + * The handle of the stream this buffer is associated with + */ + camera3_stream_t *stream; + + /** + * The native handle to the buffer + */ + buffer_handle_t *buffer; + + /** + * Current state of the buffer, one of the camera3_buffer_status_t + * values. The framework will not pass buffers to the HAL that are in an + * error state. In case a buffer could not be filled by the HAL, it must + * have its status set to CAMERA3_BUFFER_STATUS_ERROR when returned to the + * framework with process_capture_result(). + */ + int status; + + /** + * The acquire sync fence for this buffer. The HAL must wait on this fence + * fd before attempting to read from or write to this buffer. + * + * The framework may be set to -1 to indicate that no waiting is necessary + * for this buffer. + * + * When the HAL returns an output buffer to the framework with + * process_capture_result(), the acquire_fence must be set to -1. If the HAL + * never waits on the acquire_fence due to an error in filling a buffer, + * when calling process_capture_result() the HAL must set the release_fence + * of the buffer to be the acquire_fence passed to it by the framework. This + * will allow the framework to wait on the fence before reusing the buffer. + * + * For input buffers, the HAL must not change the acquire_fence field during + * the process_capture_request() call. + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * When the HAL returns an input buffer to the framework with + * process_capture_result(), the acquire_fence must be set to -1. If the HAL + * never waits on input buffer acquire fence due to an error, the sync + * fences should be handled similarly to the way they are handled for output + * buffers. + */ + int acquire_fence; + + /** + * The release sync fence for this buffer. The HAL must set this fence when + * returning buffers to the framework, or write -1 to indicate that no + * waiting is required for this buffer. + * + * For the output buffers, the fences must be set in the output_buffers + * array passed to process_capture_result(). + * + * <= CAMERA_DEVICE_API_VERSION_3_1: + * + * For the input buffer, the release fence must be set by the + * process_capture_request() call. + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * For the input buffer, the fences must be set in the input_buffer + * passed to process_capture_result(). + * + * After signaling the release_fence for this buffer, the HAL + * should not make any further attempts to access this buffer as the + * ownership has been fully transferred back to the framework. + * + * If a fence of -1 was specified then the ownership of this buffer + * is transferred back immediately upon the call of process_capture_result. + */ + int release_fence; + +} camera3_stream_buffer_t; + +/** + * camera3_stream_buffer_set_t: + * + * The complete set of gralloc buffers for a stream. This structure is given to + * register_stream_buffers() to allow the camera HAL device to register/map/etc + * newly allocated stream buffers. + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * Deprecated (and not used). In particular, + * register_stream_buffers is also deprecated and will never be invoked. + * + */ +typedef struct camera3_stream_buffer_set { + /** + * The stream handle for the stream these buffers belong to + */ + camera3_stream_t *stream; + + /** + * The number of buffers in this stream. It is guaranteed to be at least + * stream->max_buffers. + */ + uint32_t num_buffers; + + /** + * The array of gralloc buffer handles for this stream. If the stream format + * is set to HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, the camera HAL device + * should inspect the passed-in buffers to determine any platform-private + * pixel format information. + */ + buffer_handle_t **buffers; + +} camera3_stream_buffer_set_t; + +/** + * camera3_jpeg_blob: + * + * Transport header for compressed JPEG buffers in output streams. + * + * To capture JPEG images, a stream is created using the pixel format + * HAL_PIXEL_FORMAT_BLOB. The buffer size for the stream is calculated by the + * framework, based on the static metadata field android.jpeg.maxSize. Since + * compressed JPEG images are of variable size, the HAL needs to include the + * final size of the compressed image using this structure inside the output + * stream buffer. The JPEG blob ID field must be set to CAMERA3_JPEG_BLOB_ID. + * + * Transport header should be at the end of the JPEG output stream buffer. That + * means the jpeg_blob_id must start at byte[buffer_size - + * sizeof(camera3_jpeg_blob)], where the buffer_size is the size of gralloc buffer. + * Any HAL using this transport header must account for it in android.jpeg.maxSize + * The JPEG data itself starts at the beginning of the buffer and should be + * jpeg_size bytes long. + */ +typedef struct camera3_jpeg_blob { + uint16_t jpeg_blob_id; + uint32_t jpeg_size; +} camera3_jpeg_blob_t; + +enum { + CAMERA3_JPEG_BLOB_ID = 0x00FF +}; + +/********************************************************************** + * + * Message definitions for the HAL notify() callback. + * + * These definitions are used for the HAL notify callback, to signal + * asynchronous events from the HAL device to the Android framework. + * + */ + +/** + * camera3_msg_type: + * + * Indicates the type of message sent, which specifies which member of the + * message union is valid. + * + */ +typedef enum camera3_msg_type { + /** + * An error has occurred. camera3_notify_msg.message.error contains the + * error information. + */ + CAMERA3_MSG_ERROR = 1, + + /** + * The exposure of a given request or processing a reprocess request has + * begun. camera3_notify_msg.message.shutter contains the information + * the capture. + */ + CAMERA3_MSG_SHUTTER = 2, + + /** + * Number of framework message types + */ + CAMERA3_NUM_MESSAGES + +} camera3_msg_type_t; + +/** + * Defined error codes for CAMERA_MSG_ERROR + */ +typedef enum camera3_error_msg_code { + /** + * A serious failure occured. No further frames or buffer streams will + * be produced by the device. Device should be treated as closed. The + * client must reopen the device to use it again. The frame_number field + * is unused. + */ + CAMERA3_MSG_ERROR_DEVICE = 1, + + /** + * An error has occurred in processing a request. No output (metadata or + * buffers) will be produced for this request. The frame_number field + * specifies which request has been dropped. Subsequent requests are + * unaffected, and the device remains operational. + */ + CAMERA3_MSG_ERROR_REQUEST = 2, + + /** + * An error has occurred in producing an output result metadata buffer + * for a request, but output stream buffers for it will still be + * available. Subsequent requests are unaffected, and the device remains + * operational. The frame_number field specifies the request for which + * result metadata won't be available. + */ + CAMERA3_MSG_ERROR_RESULT = 3, + + /** + * An error has occurred in placing an output buffer into a stream for a + * request. The frame metadata and other buffers may still be + * available. Subsequent requests are unaffected, and the device remains + * operational. The frame_number field specifies the request for which the + * buffer was dropped, and error_stream contains a pointer to the stream + * that dropped the frame.u + */ + CAMERA3_MSG_ERROR_BUFFER = 4, + + /** + * Number of error types + */ + CAMERA3_MSG_NUM_ERRORS + +} camera3_error_msg_code_t; + +/** + * camera3_error_msg_t: + * + * Message contents for CAMERA3_MSG_ERROR + */ +typedef struct camera3_error_msg { + /** + * Frame number of the request the error applies to. 0 if the frame number + * isn't applicable to the error. + */ + uint32_t frame_number; + + /** + * Pointer to the stream that had a failure. NULL if the stream isn't + * applicable to the error. + */ + camera3_stream_t *error_stream; + + /** + * The code for this error; one of the CAMERA_MSG_ERROR enum values. + */ + int error_code; + +} camera3_error_msg_t; + +/** + * camera3_shutter_msg_t: + * + * Message contents for CAMERA3_MSG_SHUTTER + */ +typedef struct camera3_shutter_msg { + /** + * Frame number of the request that has begun exposure or reprocessing. + */ + uint32_t frame_number; + + /** + * Timestamp for the start of capture. For a reprocess request, this must + * be input image's start of capture. This must match the capture result + * metadata's sensor exposure start timestamp. + */ + uint64_t timestamp; + +} camera3_shutter_msg_t; + +/** + * camera3_notify_msg_t: + * + * The message structure sent to camera3_callback_ops_t.notify() + */ +typedef struct camera3_notify_msg { + + /** + * The message type. One of camera3_notify_msg_type, or a private extension. + */ + int type; + + union { + /** + * Error message contents. Valid if type is CAMERA3_MSG_ERROR + */ + camera3_error_msg_t error; + + /** + * Shutter message contents. Valid if type is CAMERA3_MSG_SHUTTER + */ + camera3_shutter_msg_t shutter; + + /** + * Generic message contents. Used to ensure a minimum size for custom + * message types. + */ + uint8_t generic[32]; + } message; + +} camera3_notify_msg_t; + +/********************************************************************** + * + * Capture request/result definitions for the HAL process_capture_request() + * method, and the process_capture_result() callback. + * + */ + +/** + * camera3_request_template_t: + * + * Available template types for + * camera3_device_ops.construct_default_request_settings() + */ +typedef enum camera3_request_template { + /** + * Standard camera preview operation with 3A on auto. + */ + CAMERA3_TEMPLATE_PREVIEW = 1, + + /** + * Standard camera high-quality still capture with 3A and flash on auto. + */ + CAMERA3_TEMPLATE_STILL_CAPTURE = 2, + + /** + * Standard video recording plus preview with 3A on auto, torch off. + */ + CAMERA3_TEMPLATE_VIDEO_RECORD = 3, + + /** + * High-quality still capture while recording video. Application will + * include preview, video record, and full-resolution YUV or JPEG streams in + * request. Must not cause stuttering on video stream. 3A on auto. + */ + CAMERA3_TEMPLATE_VIDEO_SNAPSHOT = 4, + + /** + * Zero-shutter-lag mode. Application will request preview and + * full-resolution data for each frame, and reprocess it to JPEG when a + * still image is requested by user. Settings should provide highest-quality + * full-resolution images without compromising preview frame rate. 3A on + * auto. + */ + CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG = 5, + + /** + * A basic template for direct application control of capture + * parameters. All automatic control is disabled (auto-exposure, auto-white + * balance, auto-focus), and post-processing parameters are set to preview + * quality. The manual capture parameters (exposure, sensitivity, etc.) + * are set to reasonable defaults, but should be overridden by the + * application depending on the intended use case. + */ + CAMERA3_TEMPLATE_MANUAL = 6, + + /* Total number of templates */ + CAMERA3_TEMPLATE_COUNT, + + /** + * First value for vendor-defined request templates + */ + CAMERA3_VENDOR_TEMPLATE_START = 0x40000000 + +} camera3_request_template_t; + +/** + * camera3_capture_request_t: + * + * A single request for image capture/buffer reprocessing, sent to the Camera + * HAL device by the framework in process_capture_request(). + * + * The request contains the settings to be used for this capture, and the set of + * output buffers to write the resulting image data in. It may optionally + * contain an input buffer, in which case the request is for reprocessing that + * input buffer instead of capturing a new image with the camera sensor. The + * capture is identified by the frame_number. + * + * In response, the camera HAL device must send a camera3_capture_result + * structure asynchronously to the framework, using the process_capture_result() + * callback. + */ +typedef struct camera3_capture_request { + /** + * The frame number is an incrementing integer set by the framework to + * uniquely identify this capture. It needs to be returned in the result + * call, and is also used to identify the request in asynchronous + * notifications sent to camera3_callback_ops_t.notify(). + */ + uint32_t frame_number; + + /** + * The settings buffer contains the capture and processing parameters for + * the request. As a special case, a NULL settings buffer indicates that the + * settings are identical to the most-recently submitted capture request. A + * NULL buffer cannot be used as the first submitted request after a + * configure_streams() call. + */ + const camera_metadata_t *settings; + + /** + * The input stream buffer to use for this request, if any. + * + * If input_buffer is NULL, then the request is for a new capture from the + * imager. If input_buffer is valid, the request is for reprocessing the + * image contained in input_buffer. + * + * In the latter case, the HAL must set the release_fence of the + * input_buffer to a valid sync fence, or to -1 if the HAL does not support + * sync, before process_capture_request() returns. + * + * The HAL is required to wait on the acquire sync fence of the input buffer + * before accessing it. + * + * <= CAMERA_DEVICE_API_VERSION_3_1: + * + * Any input buffer included here will have been registered with the HAL + * through register_stream_buffers() before its inclusion in a request. + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * The buffers will not have been pre-registered with the HAL. + * Subsequent requests may reuse buffers, or provide entirely new buffers. + */ + camera3_stream_buffer_t *input_buffer; + + /** + * The number of output buffers for this capture request. Must be at least + * 1. + */ + uint32_t num_output_buffers; + + /** + * An array of num_output_buffers stream buffers, to be filled with image + * data from this capture/reprocess. The HAL must wait on the acquire fences + * of each stream buffer before writing to them. + * + * The HAL takes ownership of the actual buffer_handle_t entries in + * output_buffers; the framework does not access them until they are + * returned in a camera3_capture_result_t. + * + * <= CAMERA_DEVICE_API_VERSION_3_1: + * + * All the buffers included here will have been registered with the HAL + * through register_stream_buffers() before their inclusion in a request. + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * Any or all of the buffers included here may be brand new in this + * request (having never before seen by the HAL). + */ + const camera3_stream_buffer_t *output_buffers; + +} camera3_capture_request_t; + +/** + * camera3_capture_result_t: + * + * The result of a single capture/reprocess by the camera HAL device. This is + * sent to the framework asynchronously with process_capture_result(), in + * response to a single capture request sent to the HAL with + * process_capture_request(). Multiple process_capture_result() calls may be + * performed by the HAL for each request. + * + * Each call, all with the same frame + * number, may contain some subset of the output buffers, and/or the result + * metadata. The metadata may only be provided once for a given frame number; + * all other calls must set the result metadata to NULL. + * + * The result structure contains the output metadata from this capture, and the + * set of output buffers that have been/will be filled for this capture. Each + * output buffer may come with a release sync fence that the framework will wait + * on before reading, in case the buffer has not yet been filled by the HAL. + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * The metadata may be provided multiple times for a single frame number. The + * framework will accumulate together the final result set by combining each + * partial result together into the total result set. + * + * If an input buffer is given in a request, the HAL must return it in one of + * the process_capture_result calls, and the call may be to just return the input + * buffer, without metadata and output buffers; the sync fences must be handled + * the same way they are done for output buffers. + * + * + * Performance considerations: + * + * Applications will also receive these partial results immediately, so sending + * partial results is a highly recommended performance optimization to avoid + * the total pipeline latency before sending the results for what is known very + * early on in the pipeline. + * + * A typical use case might be calculating the AF state halfway through the + * pipeline; by sending the state back to the framework immediately, we get a + * 50% performance increase and perceived responsiveness of the auto-focus. + * + */ +typedef struct camera3_capture_result { + /** + * The frame number is an incrementing integer set by the framework in the + * submitted request to uniquely identify this capture. It is also used to + * identify the request in asynchronous notifications sent to + * camera3_callback_ops_t.notify(). + */ + uint32_t frame_number; + + /** + * The result metadata for this capture. This contains information about the + * final capture parameters, the state of the capture and post-processing + * hardware, the state of the 3A algorithms, if enabled, and the output of + * any enabled statistics units. + * + * Only one call to process_capture_result() with a given frame_number may + * include the result metadata. All other calls for the same frame_number + * must set this to NULL. + * + * If there was an error producing the result metadata, result must be an + * empty metadata buffer, and notify() must be called with ERROR_RESULT. + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * Multiple calls to process_capture_result() with a given frame_number + * may include the result metadata. + * + * Partial metadata submitted should not include any metadata key returned + * in a previous partial result for a given frame. Each new partial result + * for that frame must also set a distinct partial_result value. + * + * If notify has been called with ERROR_RESULT, all further partial + * results for that frame are ignored by the framework. + */ + const camera_metadata_t *result; + + /** + * The number of output buffers returned in this result structure. Must be + * less than or equal to the matching capture request's count. If this is + * less than the buffer count in the capture request, at least one more call + * to process_capture_result with the same frame_number must be made, to + * return the remaining output buffers to the framework. This may only be + * zero if the structure includes valid result metadata or an input buffer + * is returned in this result. + */ + uint32_t num_output_buffers; + + /** + * The handles for the output stream buffers for this capture. They may not + * yet be filled at the time the HAL calls process_capture_result(); the + * framework will wait on the release sync fences provided by the HAL before + * reading the buffers. + * + * The HAL must set the stream buffer's release sync fence to a valid sync + * fd, or to -1 if the buffer has already been filled. + * + * If the HAL encounters an error while processing the buffer, and the + * buffer is not filled, the buffer's status field must be set to + * CAMERA3_BUFFER_STATUS_ERROR. If the HAL did not wait on the acquire fence + * before encountering the error, the acquire fence should be copied into + * the release fence, to allow the framework to wait on the fence before + * reusing the buffer. + * + * The acquire fence must be set to -1 for all output buffers. If + * num_output_buffers is zero, this may be NULL. In that case, at least one + * more process_capture_result call must be made by the HAL to provide the + * output buffers. + * + * When process_capture_result is called with a new buffer for a frame, + * all previous frames' buffers for that corresponding stream must have been + * already delivered (the fences need not have yet been signaled). + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * Gralloc buffers for a frame may be sent to framework before the + * corresponding SHUTTER-notify. + * + * Performance considerations: + * + * Buffers delivered to the framework will not be dispatched to the + * application layer until a start of exposure timestamp has been received + * via a SHUTTER notify() call. It is highly recommended to + * dispatch that call as early as possible. + */ + const camera3_stream_buffer_t *output_buffers; + + /** + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * The handle for the input stream buffer for this capture. It may not + * yet be consumed at the time the HAL calls process_capture_result(); the + * framework will wait on the release sync fences provided by the HAL before + * reusing the buffer. + * + * The HAL should handle the sync fences the same way they are done for + * output_buffers. + * + * Only one input buffer is allowed to be sent per request. Similarly to + * output buffers, the ordering of returned input buffers must be + * maintained by the HAL. + * + * Performance considerations: + * + * The input buffer should be returned as early as possible. If the HAL + * supports sync fences, it can call process_capture_result to hand it back + * with sync fences being set appropriately. If the sync fences are not + * supported, the buffer can only be returned when it is consumed, which + * may take long time; the HAL may choose to copy this input buffer to make + * the buffer return sooner. + */ + const camera3_stream_buffer_t *input_buffer; + + /** + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * In order to take advantage of partial results, the HAL must set the + * static metadata android.request.partialResultCount to the number of + * partial results it will send for each frame. + * + * Each new capture result with a partial result must set + * this field (partial_result) to a distinct inclusive value between + * 1 and android.request.partialResultCount. + * + * HALs not wishing to take advantage of this feature must not + * set an android.request.partialResultCount or partial_result to a value + * other than 1. + * + * This value must be set to 0 when a capture result contains buffers only + * and no metadata. + */ + uint32_t partial_result; + +} camera3_capture_result_t; + +/********************************************************************** + * + * Callback methods for the HAL to call into the framework. + * + * These methods are used to return metadata and image buffers for a completed + * or failed captures, and to notify the framework of asynchronous events such + * as errors. + * + * The framework will not call back into the HAL from within these callbacks, + * and these calls will not block for extended periods. + * + */ +typedef struct camera3_callback_ops { + + /** + * process_capture_result: + * + * Send results from a completed capture to the framework. + * process_capture_result() may be invoked multiple times by the HAL in + * response to a single capture request. This allows, for example, the + * metadata and low-resolution buffers to be returned in one call, and + * post-processed JPEG buffers in a later call, once it is available. Each + * call must include the frame number of the request it is returning + * metadata or buffers for. + * + * A component (buffer or metadata) of the complete result may only be + * included in one process_capture_result call. A buffer for each stream, + * and the result metadata, must be returned by the HAL for each request in + * one of the process_capture_result calls, even in case of errors producing + * some of the output. A call to process_capture_result() with neither + * output buffers or result metadata is not allowed. + * + * The order of returning metadata and buffers for a single result does not + * matter, but buffers for a given stream must be returned in FIFO order. So + * the buffer for request 5 for stream A must always be returned before the + * buffer for request 6 for stream A. This also applies to the result + * metadata; the metadata for request 5 must be returned before the metadata + * for request 6. + * + * However, different streams are independent of each other, so it is + * acceptable and expected that the buffer for request 5 for stream A may be + * returned after the buffer for request 6 for stream B is. And it is + * acceptable that the result metadata for request 6 for stream B is + * returned before the buffer for request 5 for stream A is. + * + * The HAL retains ownership of result structure, which only needs to be + * valid to access during this call. The framework will copy whatever it + * needs before this call returns. + * + * The output buffers do not need to be filled yet; the framework will wait + * on the stream buffer release sync fence before reading the buffer + * data. Therefore, this method should be called by the HAL as soon as + * possible, even if some or all of the output buffers are still in + * being filled. The HAL must include valid release sync fences into each + * output_buffers stream buffer entry, or -1 if that stream buffer is + * already filled. + * + * If the result buffer cannot be constructed for a request, the HAL should + * return an empty metadata buffer, but still provide the output buffers and + * their sync fences. In addition, notify() must be called with an + * ERROR_RESULT message. + * + * If an output buffer cannot be filled, its status field must be set to + * STATUS_ERROR. In addition, notify() must be called with a ERROR_BUFFER + * message. + * + * If the entire capture has failed, then this method still needs to be + * called to return the output buffers to the framework. All the buffer + * statuses should be STATUS_ERROR, and the result metadata should be an + * empty buffer. In addition, notify() must be called with a ERROR_REQUEST + * message. In this case, individual ERROR_RESULT/ERROR_BUFFER messages + * should not be sent. + * + * Performance requirements: + * + * This is a non-blocking call. The framework will return this call in 5ms. + * + * The pipeline latency (see S7 for definition) should be less than or equal to + * 4 frame intervals, and must be less than or equal to 8 frame intervals. + * + */ + void (*process_capture_result)(const struct camera3_callback_ops *, + const camera3_capture_result_t *result); + + /** + * notify: + * + * Asynchronous notification callback from the HAL, fired for various + * reasons. Only for information independent of frame capture, or that + * require specific timing. The ownership of the message structure remains + * with the HAL, and the msg only needs to be valid for the duration of this + * call. + * + * Multiple threads may call notify() simultaneously. + * + * <= CAMERA_DEVICE_API_VERSION_3_1: + * + * The notification for the start of exposure for a given request must be + * sent by the HAL before the first call to process_capture_result() for + * that request is made. + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * Buffers delivered to the framework will not be dispatched to the + * application layer until a start of exposure timestamp (or input image's + * start of exposure timestamp for a reprocess request) has been received + * via a SHUTTER notify() call. It is highly recommended to dispatch this + * call as early as possible. + * + * ------------------------------------------------------------------------ + * Performance requirements: + * + * This is a non-blocking call. The framework will return this call in 5ms. + */ + void (*notify)(const struct camera3_callback_ops *, + const camera3_notify_msg_t *msg); + +} camera3_callback_ops_t; + +/********************************************************************** + * + * Camera device operations + * + */ +typedef struct camera3_device_ops { + + /** + * initialize: + * + * One-time initialization to pass framework callback function pointers to + * the HAL. Will be called once after a successful open() call, before any + * other functions are called on the camera3_device_ops structure. + * + * Performance requirements: + * + * This should be a non-blocking call. The HAL should return from this call + * in 5ms, and must return from this call in 10ms. + * + * Return values: + * + * 0: On successful initialization + * + * -ENODEV: If initialization fails. Only close() can be called successfully + * by the framework after this. + */ + int (*initialize)(const struct camera3_device *, + const camera3_callback_ops_t *callback_ops); + + /********************************************************************** + * Stream management + */ + + /** + * configure_streams: + * + * CAMERA_DEVICE_API_VERSION_3_0 only: + * + * Reset the HAL camera device processing pipeline and set up new input and + * output streams. This call replaces any existing stream configuration with + * the streams defined in the stream_list. This method will be called at + * least once after initialize() before a request is submitted with + * process_capture_request(). + * + * The stream_list must contain at least one output-capable stream, and may + * not contain more than one input-capable stream. + * + * The stream_list may contain streams that are also in the currently-active + * set of streams (from the previous call to configure_stream()). These + * streams will already have valid values for usage, max_buffers, and the + * private pointer. + * + * If such a stream has already had its buffers registered, + * register_stream_buffers() will not be called again for the stream, and + * buffers from the stream can be immediately included in input requests. + * + * If the HAL needs to change the stream configuration for an existing + * stream due to the new configuration, it may rewrite the values of usage + * and/or max_buffers during the configure call. + * + * The framework will detect such a change, and will then reallocate the + * stream buffers, and call register_stream_buffers() again before using + * buffers from that stream in a request. + * + * If a currently-active stream is not included in stream_list, the HAL may + * safely remove any references to that stream. It will not be reused in a + * later configure() call by the framework, and all the gralloc buffers for + * it will be freed after the configure_streams() call returns. + * + * The stream_list structure is owned by the framework, and may not be + * accessed once this call completes. The address of an individual + * camera3_stream_t structure will remain valid for access by the HAL until + * the end of the first configure_stream() call which no longer includes + * that camera3_stream_t in the stream_list argument. The HAL may not change + * values in the stream structure outside of the private pointer, except for + * the usage and max_buffers members during the configure_streams() call + * itself. + * + * If the stream is new, the usage, max_buffer, and private pointer fields + * of the stream structure will all be set to 0. The HAL device must set + * these fields before the configure_streams() call returns. These fields + * are then used by the framework and the platform gralloc module to + * allocate the gralloc buffers for each stream. + * + * Before such a new stream can have its buffers included in a capture + * request, the framework will call register_stream_buffers() with that + * stream. However, the framework is not required to register buffers for + * _all_ streams before submitting a request. This allows for quick startup + * of (for example) a preview stream, with allocation for other streams + * happening later or concurrently. + * + * ------------------------------------------------------------------------ + * CAMERA_DEVICE_API_VERSION_3_1 only: + * + * Reset the HAL camera device processing pipeline and set up new input and + * output streams. This call replaces any existing stream configuration with + * the streams defined in the stream_list. This method will be called at + * least once after initialize() before a request is submitted with + * process_capture_request(). + * + * The stream_list must contain at least one output-capable stream, and may + * not contain more than one input-capable stream. + * + * The stream_list may contain streams that are also in the currently-active + * set of streams (from the previous call to configure_stream()). These + * streams will already have valid values for usage, max_buffers, and the + * private pointer. + * + * If such a stream has already had its buffers registered, + * register_stream_buffers() will not be called again for the stream, and + * buffers from the stream can be immediately included in input requests. + * + * If the HAL needs to change the stream configuration for an existing + * stream due to the new configuration, it may rewrite the values of usage + * and/or max_buffers during the configure call. + * + * The framework will detect such a change, and will then reallocate the + * stream buffers, and call register_stream_buffers() again before using + * buffers from that stream in a request. + * + * If a currently-active stream is not included in stream_list, the HAL may + * safely remove any references to that stream. It will not be reused in a + * later configure() call by the framework, and all the gralloc buffers for + * it will be freed after the configure_streams() call returns. + * + * The stream_list structure is owned by the framework, and may not be + * accessed once this call completes. The address of an individual + * camera3_stream_t structure will remain valid for access by the HAL until + * the end of the first configure_stream() call which no longer includes + * that camera3_stream_t in the stream_list argument. The HAL may not change + * values in the stream structure outside of the private pointer, except for + * the usage and max_buffers members during the configure_streams() call + * itself. + * + * If the stream is new, max_buffer, and private pointer fields of the + * stream structure will all be set to 0. The usage will be set to the + * consumer usage flags. The HAL device must set these fields before the + * configure_streams() call returns. These fields are then used by the + * framework and the platform gralloc module to allocate the gralloc + * buffers for each stream. + * + * Before such a new stream can have its buffers included in a capture + * request, the framework will call register_stream_buffers() with that + * stream. However, the framework is not required to register buffers for + * _all_ streams before submitting a request. This allows for quick startup + * of (for example) a preview stream, with allocation for other streams + * happening later or concurrently. + * + * ------------------------------------------------------------------------ + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * Reset the HAL camera device processing pipeline and set up new input and + * output streams. This call replaces any existing stream configuration with + * the streams defined in the stream_list. This method will be called at + * least once after initialize() before a request is submitted with + * process_capture_request(). + * + * The stream_list must contain at least one output-capable stream, and may + * not contain more than one input-capable stream. + * + * The stream_list may contain streams that are also in the currently-active + * set of streams (from the previous call to configure_stream()). These + * streams will already have valid values for usage, max_buffers, and the + * private pointer. + * + * If the HAL needs to change the stream configuration for an existing + * stream due to the new configuration, it may rewrite the values of usage + * and/or max_buffers during the configure call. + * + * The framework will detect such a change, and may then reallocate the + * stream buffers before using buffers from that stream in a request. + * + * If a currently-active stream is not included in stream_list, the HAL may + * safely remove any references to that stream. It will not be reused in a + * later configure() call by the framework, and all the gralloc buffers for + * it will be freed after the configure_streams() call returns. + * + * The stream_list structure is owned by the framework, and may not be + * accessed once this call completes. The address of an individual + * camera3_stream_t structure will remain valid for access by the HAL until + * the end of the first configure_stream() call which no longer includes + * that camera3_stream_t in the stream_list argument. The HAL may not change + * values in the stream structure outside of the private pointer, except for + * the usage and max_buffers members during the configure_streams() call + * itself. + * + * If the stream is new, max_buffer, and private pointer fields of the + * stream structure will all be set to 0. The usage will be set to the + * consumer usage flags. The HAL device must set these fields before the + * configure_streams() call returns. These fields are then used by the + * framework and the platform gralloc module to allocate the gralloc + * buffers for each stream. + * + * Newly allocated buffers may be included in a capture request at any time + * by the framework. Once a gralloc buffer is returned to the framework + * with process_capture_result (and its respective release_fence has been + * signaled) the framework may free or reuse it at any time. + * + * ------------------------------------------------------------------------ + * + * Preconditions: + * + * The framework will only call this method when no captures are being + * processed. That is, all results have been returned to the framework, and + * all in-flight input and output buffers have been returned and their + * release sync fences have been signaled by the HAL. The framework will not + * submit new requests for capture while the configure_streams() call is + * underway. + * + * Postconditions: + * + * The HAL device must configure itself to provide maximum possible output + * frame rate given the sizes and formats of the output streams, as + * documented in the camera device's static metadata. + * + * Performance requirements: + * + * This call is expected to be heavyweight and possibly take several hundred + * milliseconds to complete, since it may require resetting and + * reconfiguring the image sensor and the camera processing pipeline. + * Nevertheless, the HAL device should attempt to minimize the + * reconfiguration delay to minimize the user-visible pauses during + * application operational mode changes (such as switching from still + * capture to video recording). + * + * The HAL should return from this call in 500ms, and must return from this + * call in 1000ms. + * + * Return values: + * + * 0: On successful stream configuration + * + * -EINVAL: If the requested stream configuration is invalid. Some examples + * of invalid stream configurations include: + * + * - Including more than 1 input-capable stream (INPUT or + * BIDIRECTIONAL) + * + * - Not including any output-capable streams (OUTPUT or + * BIDIRECTIONAL) + * + * - Including streams with unsupported formats, or an unsupported + * size for that format. + * + * - Including too many output streams of a certain format. + * + * - Unsupported rotation configuration (only applies to + * devices with version >= CAMERA_DEVICE_API_VERSION_3_3) + * + * - Stream sizes/formats don't satisfy the + * camera3_stream_configuration_t->operation_mode requirements for non-NORMAL mode, + * or the requested operation_mode is not supported by the HAL. + * (only applies to devices with version >= CAMERA_DEVICE_API_VERSION_3_3) + * + * Note that the framework submitting an invalid stream + * configuration is not normal operation, since stream + * configurations are checked before configure. An invalid + * configuration means that a bug exists in the framework code, or + * there is a mismatch between the HAL's static metadata and the + * requirements on streams. + * + * -ENODEV: If there has been a fatal error and the device is no longer + * operational. Only close() can be called successfully by the + * framework after this error is returned. + */ + int (*configure_streams)(const struct camera3_device *, + camera3_stream_configuration_t *stream_list); + + /** + * register_stream_buffers: + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * DEPRECATED. This will not be called and must be set to NULL. + * + * <= CAMERA_DEVICE_API_VERSION_3_1: + * + * Register buffers for a given stream with the HAL device. This method is + * called by the framework after a new stream is defined by + * configure_streams, and before buffers from that stream are included in a + * capture request. If the same stream is listed in a subsequent + * configure_streams() call, register_stream_buffers will _not_ be called + * again for that stream. + * + * The framework does not need to register buffers for all configured + * streams before it submits the first capture request. This allows quick + * startup for preview (or similar use cases) while other streams are still + * being allocated. + * + * This method is intended to allow the HAL device to map or otherwise + * prepare the buffers for later use. The buffers passed in will already be + * locked for use. At the end of the call, all the buffers must be ready to + * be returned to the stream. The buffer_set argument is only valid for the + * duration of this call. + * + * If the stream format was set to HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, + * the camera HAL should inspect the passed-in buffers here to determine any + * platform-private pixel format information. + * + * Performance requirements: + * + * This should be a non-blocking call. The HAL should return from this call + * in 1ms, and must return from this call in 5ms. + * + * Return values: + * + * 0: On successful registration of the new stream buffers + * + * -EINVAL: If the stream_buffer_set does not refer to a valid active + * stream, or if the buffers array is invalid. + * + * -ENOMEM: If there was a failure in registering the buffers. The framework + * must consider all the stream buffers to be unregistered, and can + * try to register again later. + * + * -ENODEV: If there is a fatal error, and the device is no longer + * operational. Only close() can be called successfully by the + * framework after this error is returned. + */ + int (*register_stream_buffers)(const struct camera3_device *, + const camera3_stream_buffer_set_t *buffer_set); + + /********************************************************************** + * Request creation and submission + */ + + /** + * construct_default_request_settings: + * + * Create capture settings for standard camera use cases. + * + * The device must return a settings buffer that is configured to meet the + * requested use case, which must be one of the CAMERA3_TEMPLATE_* + * enums. All request control fields must be included. + * + * The HAL retains ownership of this structure, but the pointer to the + * structure must be valid until the device is closed. The framework and the + * HAL may not modify the buffer once it is returned by this call. The same + * buffer may be returned for subsequent calls for the same template, or for + * other templates. + * + * Performance requirements: + * + * This should be a non-blocking call. The HAL should return from this call + * in 1ms, and must return from this call in 5ms. + * + * Return values: + * + * Valid metadata: On successful creation of a default settings + * buffer. + * + * NULL: In case of a fatal error. After this is returned, only + * the close() method can be called successfully by the + * framework. + */ + const camera_metadata_t* (*construct_default_request_settings)( + const struct camera3_device *, + int type); + + /** + * process_capture_request: + * + * Send a new capture request to the HAL. The HAL should not return from + * this call until it is ready to accept the next request to process. Only + * one call to process_capture_request() will be made at a time by the + * framework, and the calls will all be from the same thread. The next call + * to process_capture_request() will be made as soon as a new request and + * its associated buffers are available. In a normal preview scenario, this + * means the function will be called again by the framework almost + * instantly. + * + * The actual request processing is asynchronous, with the results of + * capture being returned by the HAL through the process_capture_result() + * call. This call requires the result metadata to be available, but output + * buffers may simply provide sync fences to wait on. Multiple requests are + * expected to be in flight at once, to maintain full output frame rate. + * + * The framework retains ownership of the request structure. It is only + * guaranteed to be valid during this call. The HAL device must make copies + * of the information it needs to retain for the capture processing. The HAL + * is responsible for waiting on and closing the buffers' fences and + * returning the buffer handles to the framework. + * + * The HAL must write the file descriptor for the input buffer's release + * sync fence into input_buffer->release_fence, if input_buffer is not + * NULL. If the HAL returns -1 for the input buffer release sync fence, the + * framework is free to immediately reuse the input buffer. Otherwise, the + * framework will wait on the sync fence before refilling and reusing the + * input buffer. + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * + * The input/output buffers provided by the framework in each request + * may be brand new (having never before seen by the HAL). + * + * ------------------------------------------------------------------------ + * Performance considerations: + * + * Handling a new buffer should be extremely lightweight and there should be + * no frame rate degradation or frame jitter introduced. + * + * This call must return fast enough to ensure that the requested frame + * rate can be sustained, especially for streaming cases (post-processing + * quality settings set to FAST). The HAL should return this call in 1 + * frame interval, and must return from this call in 4 frame intervals. + * + * Return values: + * + * 0: On a successful start to processing the capture request + * + * -EINVAL: If the input is malformed (the settings are NULL when not + * allowed, there are 0 output buffers, etc) and capture processing + * cannot start. Failures during request processing should be + * handled by calling camera3_callback_ops_t.notify(). In case of + * this error, the framework will retain responsibility for the + * stream buffers' fences and the buffer handles; the HAL should + * not close the fences or return these buffers with + * process_capture_result. + * + * -ENODEV: If the camera device has encountered a serious error. After this + * error is returned, only the close() method can be successfully + * called by the framework. + * + */ + int (*process_capture_request)(const struct camera3_device *, + camera3_capture_request_t *request); + + /********************************************************************** + * Miscellaneous methods + */ + + /** + * get_metadata_vendor_tag_ops: + * + * Get methods to query for vendor extension metadata tag information. The + * HAL should fill in all the vendor tag operation methods, or leave ops + * unchanged if no vendor tags are defined. + * + * The definition of vendor_tag_query_ops_t can be found in + * system/media/camera/include/system/camera_metadata.h. + * + * >= CAMERA_DEVICE_API_VERSION_3_2: + * DEPRECATED. This function has been deprecated and should be set to + * NULL by the HAL. Please implement get_vendor_tag_ops in camera_common.h + * instead. + */ + void (*get_metadata_vendor_tag_ops)(const struct camera3_device*, + vendor_tag_query_ops_t* ops); + + /** + * dump: + * + * Print out debugging state for the camera device. This will be called by + * the framework when the camera service is asked for a debug dump, which + * happens when using the dumpsys tool, or when capturing a bugreport. + * + * The passed-in file descriptor can be used to write debugging text using + * dprintf() or write(). The text should be in ASCII encoding only. + * + * Performance requirements: + * + * This must be a non-blocking call. The HAL should return from this call + * in 1ms, must return from this call in 10ms. This call must avoid + * deadlocks, as it may be called at any point during camera operation. + * Any synchronization primitives used (such as mutex locks or semaphores) + * should be acquired with a timeout. + */ + void (*dump)(const struct camera3_device *, int fd); + + /** + * flush: + * + * Flush all currently in-process captures and all buffers in the pipeline + * on the given device. The framework will use this to dump all state as + * quickly as possible in order to prepare for a configure_streams() call. + * + * No buffers are required to be successfully returned, so every buffer + * held at the time of flush() (whether successfully filled or not) may be + * returned with CAMERA3_BUFFER_STATUS_ERROR. Note the HAL is still allowed + * to return valid (CAMERA3_BUFFER_STATUS_OK) buffers during this call, + * provided they are successfully filled. + * + * All requests currently in the HAL are expected to be returned as soon as + * possible. Not-in-process requests should return errors immediately. Any + * interruptible hardware blocks should be stopped, and any uninterruptible + * blocks should be waited on. + * + * flush() may be called concurrently to process_capture_request(), with the expectation that + * process_capture_request will return quickly and the request submitted in that + * process_capture_request call is treated like all other in-flight requests. Due to + * concurrency issues, it is possible that from the HAL's point of view, a + * process_capture_request() call may be started after flush has been invoked but has not + * returned yet. If such a call happens before flush() returns, the HAL should treat the new + * capture request like other in-flight pending requests (see #4 below). + * + * More specifically, the HAL must follow below requirements for various cases: + * + * 1. For captures that are too late for the HAL to cancel/stop, and will be + * completed normally by the HAL; i.e. the HAL can send shutter/notify and + * process_capture_result and buffers as normal. + * + * 2. For pending requests that have not done any processing, the HAL must call notify + * CAMERA3_MSG_ERROR_REQUEST, and return all the output buffers with + * process_capture_result in the error state (CAMERA3_BUFFER_STATUS_ERROR). + * The HAL must not place the release fence into an error state, instead, + * the release fences must be set to the acquire fences passed by the framework, + * or -1 if they have been waited on by the HAL already. This is also the path + * to follow for any captures for which the HAL already called notify() with + * CAMERA3_MSG_SHUTTER but won't be producing any metadata/valid buffers for. + * After CAMERA3_MSG_ERROR_REQUEST, for a given frame, only process_capture_results with + * buffers in CAMERA3_BUFFER_STATUS_ERROR are allowed. No further notifys or + * process_capture_result with non-null metadata is allowed. + * + * 3. For partially completed pending requests that will not have all the output + * buffers or perhaps missing metadata, the HAL should follow below: + * + * 3.1. Call notify with CAMERA3_MSG_ERROR_RESULT if some of the expected result + * metadata (i.e. one or more partial metadata) won't be available for the capture. + * + * 3.2. Call notify with CAMERA3_MSG_ERROR_BUFFER for every buffer that won't + * be produced for the capture. + * + * 3.3 Call notify with CAMERA3_MSG_SHUTTER with the capture timestamp before + * any buffers/metadata are returned with process_capture_result. + * + * 3.4 For captures that will produce some results, the HAL must not call + * CAMERA3_MSG_ERROR_REQUEST, since that indicates complete failure. + * + * 3.5. Valid buffers/metadata should be passed to the framework as normal. + * + * 3.6. Failed buffers should be returned to the framework as described for case 2. + * But failed buffers do not have to follow the strict ordering valid buffers do, + * and may be out-of-order with respect to valid buffers. For example, if buffers + * A, B, C, D, E are sent, D and E are failed, then A, E, B, D, C is an acceptable + * return order. + * + * 3.7. For fully-missing metadata, calling CAMERA3_MSG_ERROR_RESULT is sufficient, no + * need to call process_capture_result with NULL metadata or equivalent. + * + * 4. If a flush() is invoked while a process_capture_request() invocation is active, that + * process call should return as soon as possible. In addition, if a process_capture_request() + * call is made after flush() has been invoked but before flush() has returned, the + * capture request provided by the late process_capture_request call should be treated like + * a pending request in case #2 above. + * + * flush() should only return when there are no more outstanding buffers or + * requests left in the HAL. The framework may call configure_streams (as + * the HAL state is now quiesced) or may issue new requests. + * + * Note that it's sufficient to only support fully-succeeded and fully-failed result cases. + * However, it is highly desirable to support the partial failure cases as well, as it + * could help improve the flush call overall performance. + * + * Performance requirements: + * + * The HAL should return from this call in 100ms, and must return from this + * call in 1000ms. And this call must not be blocked longer than pipeline + * latency (see S7 for definition). + * + * Version information: + * + * only available if device version >= CAMERA_DEVICE_API_VERSION_3_1. + * + * Return values: + * + * 0: On a successful flush of the camera HAL. + * + * -EINVAL: If the input is malformed (the device is not valid). + * + * -ENODEV: If the camera device has encountered a serious error. After this + * error is returned, only the close() method can be successfully + * called by the framework. + */ + int (*flush)(const struct camera3_device *); + + /* reserved for future use */ + void *reserved[8]; +} camera3_device_ops_t; + +/********************************************************************** + * + * Camera device definition + * + */ +typedef struct camera3_device { + /** + * common.version must equal CAMERA_DEVICE_API_VERSION_3_0 to identify this + * device as implementing version 3.0 of the camera device HAL. + * + * Performance requirements: + * + * Camera open (common.module->common.methods->open) should return in 200ms, and must return + * in 500ms. + * Camera close (common.close) should return in 200ms, and must return in 500ms. + * + */ + hw_device_t common; + camera3_device_ops_t *ops; + void *priv; +} camera3_device_t; + +__END_DECLS + +#endif /* #ifdef ANDROID_INCLUDE_CAMERA3_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/camera_common.h b/phonelibs/android_hardware_libhardware/include/hardware/camera_common.h new file mode 100644 index 00000000000000..7658dd4062f39e --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/camera_common.h @@ -0,0 +1,916 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// FIXME: add well-defined names for cameras + +#ifndef ANDROID_INCLUDE_CAMERA_COMMON_H +#define ANDROID_INCLUDE_CAMERA_COMMON_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define CAMERA_HARDWARE_MODULE_ID "camera" + +/** + * Module versioning information for the Camera hardware module, based on + * camera_module_t.common.module_api_version. The two most significant hex + * digits represent the major version, and the two least significant represent + * the minor version. + * + ******************************************************************************* + * Versions: 0.X - 1.X [CAMERA_MODULE_API_VERSION_1_0] + * + * Camera modules that report these version numbers implement the initial + * camera module HAL interface. All camera devices openable through this + * module support only version 1 of the camera device HAL. The device_version + * and static_camera_characteristics fields of camera_info are not valid. Only + * the android.hardware.Camera API can be supported by this module and its + * devices. + * + ******************************************************************************* + * Version: 2.0 [CAMERA_MODULE_API_VERSION_2_0] + * + * Camera modules that report this version number implement the second version + * of the camera module HAL interface. Camera devices openable through this + * module may support either version 1.0 or version 2.0 of the camera device + * HAL interface. The device_version field of camera_info is always valid; the + * static_camera_characteristics field of camera_info is valid if the + * device_version field is 2.0 or higher. + * + ******************************************************************************* + * Version: 2.1 [CAMERA_MODULE_API_VERSION_2_1] + * + * This camera module version adds support for asynchronous callbacks to the + * framework from the camera HAL module, which is used to notify the framework + * about changes to the camera module state. Modules that provide a valid + * set_callbacks() method must report at least this version number. + * + ******************************************************************************* + * Version: 2.2 [CAMERA_MODULE_API_VERSION_2_2] + * + * This camera module version adds vendor tag support from the module, and + * deprecates the old vendor_tag_query_ops that were previously only + * accessible with a device open. + * + ******************************************************************************* + * Version: 2.3 [CAMERA_MODULE_API_VERSION_2_3] + * + * This camera module version adds open legacy camera HAL device support. + * Framework can use it to open the camera device as lower device HAL version + * HAL device if the same device can support multiple device API versions. + * The standard hardware module open call (common.methods->open) continues + * to open the camera device with the latest supported version, which is + * also the version listed in camera_info_t.device_version. + * + ******************************************************************************* + * Version: 2.4 [CAMERA_MODULE_API_VERSION_2_4] + * + * This camera module version adds below API changes: + * + * 1. Torch mode support. The framework can use it to turn on torch mode for + * any camera device that has a flash unit, without opening a camera device. The + * camera device has a higher priority accessing the flash unit than the camera + * module; opening a camera device will turn off the torch if it had been enabled + * through the module interface. When there are any resource conflicts, such as + * open() is called to open a camera device, the camera HAL module must notify the + * framework through the torch mode status callback that the torch mode has been + * turned off. + * + * 2. External camera (e.g. USB hot-plug camera) support. The API updates specify that + * the camera static info is only available when camera is connected and ready to + * use for external hot-plug cameras. Calls to get static info will be invalid + * calls when camera status is not CAMERA_DEVICE_STATUS_PRESENT. The frameworks + * will only count on device status change callbacks to manage the available external + * camera list. + * + * 3. Camera arbitration hints. This module version adds support for explicitly + * indicating the number of camera devices that can be simultaneously opened and used. + * To specify valid combinations of devices, the resource_cost and conflicting_devices + * fields should always be set in the camera_info structure returned by the + * get_camera_info call. + * + * 4. Module initialization method. This will be called by the camera service + * right after the HAL module is loaded, to allow for one-time initialization + * of the HAL. It is called before any other module methods are invoked. + */ + +/** + * Predefined macros for currently-defined version numbers + */ + +/** + * All module versions <= HARDWARE_MODULE_API_VERSION(1, 0xFF) must be treated + * as CAMERA_MODULE_API_VERSION_1_0 + */ +#define CAMERA_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0) +#define CAMERA_MODULE_API_VERSION_2_0 HARDWARE_MODULE_API_VERSION(2, 0) +#define CAMERA_MODULE_API_VERSION_2_1 HARDWARE_MODULE_API_VERSION(2, 1) +#define CAMERA_MODULE_API_VERSION_2_2 HARDWARE_MODULE_API_VERSION(2, 2) +#define CAMERA_MODULE_API_VERSION_2_3 HARDWARE_MODULE_API_VERSION(2, 3) +#define CAMERA_MODULE_API_VERSION_2_4 HARDWARE_MODULE_API_VERSION(2, 4) + +#define CAMERA_MODULE_API_VERSION_CURRENT CAMERA_MODULE_API_VERSION_2_4 + +/** + * All device versions <= HARDWARE_DEVICE_API_VERSION(1, 0xFF) must be treated + * as CAMERA_DEVICE_API_VERSION_1_0 + */ +#define CAMERA_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0) +#define CAMERA_DEVICE_API_VERSION_2_0 HARDWARE_DEVICE_API_VERSION(2, 0) +#define CAMERA_DEVICE_API_VERSION_2_1 HARDWARE_DEVICE_API_VERSION(2, 1) +#define CAMERA_DEVICE_API_VERSION_3_0 HARDWARE_DEVICE_API_VERSION(3, 0) +#define CAMERA_DEVICE_API_VERSION_3_1 HARDWARE_DEVICE_API_VERSION(3, 1) +#define CAMERA_DEVICE_API_VERSION_3_2 HARDWARE_DEVICE_API_VERSION(3, 2) +#define CAMERA_DEVICE_API_VERSION_3_3 HARDWARE_DEVICE_API_VERSION(3, 3) + +// Device version 3.3 is current, older HAL camera device versions are not +// recommended for new devices. +#define CAMERA_DEVICE_API_VERSION_CURRENT CAMERA_DEVICE_API_VERSION_3_3 + +/** + * Defined in /system/media/camera/include/system/camera_metadata.h + */ +typedef struct camera_metadata camera_metadata_t; + +typedef struct camera_info { + /** + * The direction that the camera faces to. See system/core/include/system/camera.h + * for camera facing definitions. + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_2_3 or lower: + * + * It should be CAMERA_FACING_BACK or CAMERA_FACING_FRONT. + * + * CAMERA_MODULE_API_VERSION_2_4 or higher: + * + * It should be CAMERA_FACING_BACK, CAMERA_FACING_FRONT or + * CAMERA_FACING_EXTERNAL. + */ + int facing; + + /** + * The orientation of the camera image. The value is the angle that the + * camera image needs to be rotated clockwise so it shows correctly on the + * display in its natural orientation. It should be 0, 90, 180, or 270. + * + * For example, suppose a device has a naturally tall screen. The + * back-facing camera sensor is mounted in landscape. You are looking at the + * screen. If the top side of the camera sensor is aligned with the right + * edge of the screen in natural orientation, the value should be 90. If the + * top side of a front-facing camera sensor is aligned with the right of the + * screen, the value should be 270. + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_2_3 or lower: + * + * Valid in all camera_module versions. + * + * CAMERA_MODULE_API_VERSION_2_4 or higher: + * + * Valid if camera facing is CAMERA_FACING_BACK or CAMERA_FACING_FRONT, + * not valid if camera facing is CAMERA_FACING_EXTERNAL. + */ + int orientation; + + /** + * The value of camera_device_t.common.version. + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_1_0: + * + * Not valid. Can be assumed to be CAMERA_DEVICE_API_VERSION_1_0. Do + * not read this field. + * + * CAMERA_MODULE_API_VERSION_2_0 or higher: + * + * Always valid + * + */ + uint32_t device_version; + + /** + * The camera's fixed characteristics, which include all static camera metadata + * specified in system/media/camera/docs/docs.html. This should be a sorted metadata + * buffer, and may not be modified or freed by the caller. The pointer should remain + * valid for the lifetime of the camera module, and values in it may not + * change after it is returned by get_camera_info(). + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_1_0: + * + * Not valid. Extra characteristics are not available. Do not read this + * field. + * + * CAMERA_MODULE_API_VERSION_2_0 or higher: + * + * Valid if device_version >= CAMERA_DEVICE_API_VERSION_2_0. Do not read + * otherwise. + * + */ + const camera_metadata_t *static_camera_characteristics; + + /** + * The total resource "cost" of using this camera, represented as an integer + * value in the range [0, 100] where 100 represents total usage of the shared + * resource that is the limiting bottleneck of the camera subsystem. This may + * be a very rough estimate, and is used as a hint to the camera service to + * determine when to disallow multiple applications from simultaneously + * opening different cameras advertised by the camera service. + * + * The camera service must be able to simultaneously open and use any + * combination of camera devices exposed by the HAL where the sum of + * the resource costs of these cameras is <= 100. For determining cost, + * each camera device must be assumed to be configured and operating at + * the maximally resource-consuming framerate and stream size settings + * available in the configuration settings exposed for that device through + * the camera metadata. + * + * The camera service may still attempt to simultaneously open combinations + * of camera devices with a total resource cost > 100. This may succeed or + * fail. If this succeeds, combinations of configurations that are not + * supported due to resource constraints from having multiple open devices + * should fail during the configure calls. If the total resource cost is + * <= 100, open and configure should never fail for any stream configuration + * settings or other device capabilities that would normally succeed for a + * device when it is the only open camera device. + * + * This field will be used to determine whether background applications are + * allowed to use this camera device while other applications are using other + * camera devices. Note: multiple applications will never be allowed by the + * camera service to simultaneously open the same camera device. + * + * Example use cases: + * + * Ex. 1: Camera Device 0 = Back Camera + * Camera Device 1 = Front Camera + * - Using both camera devices causes a large framerate slowdown due to + * limited ISP bandwidth. + * + * Configuration: + * + * Camera Device 0 - resource_cost = 51 + * conflicting_devices = null + * Camera Device 1 - resource_cost = 51 + * conflicting_devices = null + * + * Result: + * + * Since the sum of the resource costs is > 100, if a higher-priority + * application has either device open, no lower-priority applications will be + * allowed by the camera service to open either device. If a lower-priority + * application is using a device that a higher-priority subsequently attempts + * to open, the lower-priority application will be forced to disconnect the + * the device. + * + * If the highest-priority application chooses, it may still attempt to open + * both devices (since these devices are not listed as conflicting in the + * conflicting_devices fields), but usage of these devices may fail in the + * open or configure calls. + * + * Ex. 2: Camera Device 0 = Left Back Camera + * Camera Device 1 = Right Back Camera + * Camera Device 2 = Combined stereo camera using both right and left + * back camera sensors used by devices 0, and 1 + * Camera Device 3 = Front Camera + * - Due to do hardware constraints, up to two cameras may be open at once. The + * combined stereo camera may never be used at the same time as either of the + * two back camera devices (device 0, 1), and typically requires too much + * bandwidth to use at the same time as the front camera (device 3). + * + * Configuration: + * + * Camera Device 0 - resource_cost = 50 + * conflicting_devices = { 2 } + * Camera Device 1 - resource_cost = 50 + * conflicting_devices = { 2 } + * Camera Device 2 - resource_cost = 100 + * conflicting_devices = { 0, 1 } + * Camera Device 3 - resource_cost = 50 + * conflicting_devices = null + * + * Result: + * + * Based on the conflicting_devices fields, the camera service guarantees that + * the following sets of open devices will never be allowed: { 1, 2 }, { 0, 2 }. + * + * Based on the resource_cost fields, if a high-priority foreground application + * is using camera device 0, a background application would be allowed to open + * camera device 1 or 3 (but would be forced to disconnect it again if the + * foreground application opened another device). + * + * The highest priority application may still attempt to simultaneously open + * devices 0, 2, and 3, but the HAL may fail in open or configure calls for + * this combination. + * + * Ex. 3: Camera Device 0 = Back Camera + * Camera Device 1 = Front Camera + * Camera Device 2 = Low-power Front Camera that uses the same + * sensor as device 1, but only exposes image stream + * resolutions that can be used in low-power mode + * - Using both front cameras (device 1, 2) at the same time is impossible due + * a shared physical sensor. Using the back and "high-power" front camera + * (device 1) may be impossible for some stream configurations due to hardware + * limitations, but the "low-power" front camera option may always be used as + * it has special dedicated hardware. + * + * Configuration: + * + * Camera Device 0 - resource_cost = 100 + * conflicting_devices = null + * Camera Device 1 - resource_cost = 100 + * conflicting_devices = { 2 } + * Camera Device 2 - resource_cost = 0 + * conflicting_devices = { 1 } + * Result: + * + * Based on the conflicting_devices fields, the camera service guarantees that + * the following sets of open devices will never be allowed: { 1, 2 }. + * + * Based on the resource_cost fields, only the highest priority application + * may attempt to open both device 0 and 1 at the same time. If a higher-priority + * application is not using device 1 or 2, a low-priority background application + * may open device 2 (but will be forced to disconnect it if a higher-priority + * application subsequently opens device 1 or 2). + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_2_3 or lower: + * + * Not valid. Can be assumed to be 100. Do not read this field. + * + * CAMERA_MODULE_API_VERSION_2_4 or higher: + * + * Always valid. + */ + int resource_cost; + + /** + * An array of camera device IDs represented as NULL-terminated strings + * indicating other devices that cannot be simultaneously opened while this + * camera device is in use. + * + * This field is intended to be used to indicate that this camera device + * is a composite of several other camera devices, or otherwise has + * hardware dependencies that prohibit simultaneous usage. If there are no + * dependencies, a NULL may be returned in this field to indicate this. + * + * The camera service will never simultaneously open any of the devices + * in this list while this camera device is open. + * + * The strings pointed to in this field will not be cleaned up by the camera + * service, and must remain while this device is plugged in. + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_2_3 or lower: + * + * Not valid. Can be assumed to be NULL. Do not read this field. + * + * CAMERA_MODULE_API_VERSION_2_4 or higher: + * + * Always valid. + */ + char** conflicting_devices; + + /** + * The length of the array given in the conflicting_devices field. + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_2_3 or lower: + * + * Not valid. Can be assumed to be 0. Do not read this field. + * + * CAMERA_MODULE_API_VERSION_2_4 or higher: + * + * Always valid. + */ + size_t conflicting_devices_length; + +} camera_info_t; + +/** + * camera_device_status_t: + * + * The current status of the camera device, as provided by the HAL through the + * camera_module_callbacks.camera_device_status_change() call. + * + * At module load time, the framework will assume all camera devices are in the + * CAMERA_DEVICE_STATUS_PRESENT state. The HAL should invoke + * camera_module_callbacks::camera_device_status_change to inform the framework + * of any initially NOT_PRESENT devices. + * + * Allowed transitions: + * PRESENT -> NOT_PRESENT + * NOT_PRESENT -> ENUMERATING + * NOT_PRESENT -> PRESENT + * ENUMERATING -> PRESENT + * ENUMERATING -> NOT_PRESENT + */ +typedef enum camera_device_status { + /** + * The camera device is not currently connected, and opening it will return + * failure. + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_2_3 or lower: + * + * Calls to get_camera_info must still succeed, and provide the same information + * it would if the camera were connected. + * + * CAMERA_MODULE_API_VERSION_2_4: + * + * The camera device at this status must return -EINVAL for get_camera_info call, + * as the device is not connected. + */ + CAMERA_DEVICE_STATUS_NOT_PRESENT = 0, + + /** + * The camera device is connected, and opening it will succeed. + * + * CAMERA_MODULE_API_VERSION_2_3 or lower: + * + * The information returned by get_camera_info cannot change due to this status + * change. By default, the framework will assume all devices are in this state. + * + * CAMERA_MODULE_API_VERSION_2_4: + * + * The information returned by get_camera_info will become valid after a device's + * status changes to this. By default, the framework will assume all devices are in + * this state. + */ + CAMERA_DEVICE_STATUS_PRESENT = 1, + + /** + * The camera device is connected, but it is undergoing an enumeration and + * so opening the device will return -EBUSY. + * + * CAMERA_MODULE_API_VERSION_2_3 or lower: + * + * Calls to get_camera_info must still succeed, as if the camera was in the + * PRESENT status. + * + * CAMERA_MODULE_API_VERSION_2_4: + * + * The camera device at this status must return -EINVAL for get_camera_info for call, + * as the device is not ready. + */ + CAMERA_DEVICE_STATUS_ENUMERATING = 2, + +} camera_device_status_t; + +/** + * torch_mode_status_t: + * + * The current status of the torch mode, as provided by the HAL through the + * camera_module_callbacks.torch_mode_status_change() call. + * + * The torch mode status of a camera device is applicable only when the camera + * device is present. The framework will not call set_torch_mode() to turn on + * torch mode of a camera device if the camera device is not present. At module + * load time, the framework will assume torch modes are in the + * TORCH_MODE_STATUS_AVAILABLE_OFF state if the camera device is present and + * android.flash.info.available is reported as true via get_camera_info() call. + * + * The behaviors of the camera HAL module that the framework expects in the + * following situations when a camera device's status changes: + * 1. A previously-disconnected camera device becomes connected. + * After camera_module_callbacks::camera_device_status_change() is invoked + * to inform the framework that the camera device is present, the framework + * will assume the camera device's torch mode is in + * TORCH_MODE_STATUS_AVAILABLE_OFF state. The camera HAL module does not need + * to invoke camera_module_callbacks::torch_mode_status_change() unless the + * flash unit is unavailable to use by set_torch_mode(). + * + * 2. A previously-connected camera becomes disconnected. + * After camera_module_callbacks::camera_device_status_change() is invoked + * to inform the framework that the camera device is not present, the + * framework will not call set_torch_mode() for the disconnected camera + * device until its flash unit becomes available again. The camera HAL + * module does not need to invoke + * camera_module_callbacks::torch_mode_status_change() separately to inform + * that the flash unit has become unavailable. + * + * 3. open() is called to open a camera device. + * The camera HAL module must invoke + * camera_module_callbacks::torch_mode_status_change() for all flash units + * that have entered TORCH_MODE_STATUS_NOT_AVAILABLE state and can not be + * turned on by calling set_torch_mode() anymore due to this open() call. + * open() must not trigger TORCH_MODE_STATUS_AVAILABLE_OFF before + * TORCH_MODE_STATUS_NOT_AVAILABLE for all flash units that have become + * unavailable. + * + * 4. close() is called to close a camera device. + * The camera HAL module must invoke + * camera_module_callbacks::torch_mode_status_change() for all flash units + * that have entered TORCH_MODE_STATUS_AVAILABLE_OFF state and can be turned + * on by calling set_torch_mode() again because of enough resources freed + * up by this close() call. + * + * Note that the framework calling set_torch_mode() successfully must trigger + * TORCH_MODE_STATUS_AVAILABLE_OFF or TORCH_MODE_STATUS_AVAILABLE_ON callback + * for the given camera device. Additionally it must trigger + * TORCH_MODE_STATUS_AVAILABLE_OFF callbacks for other previously-on torch + * modes if HAL cannot keep multiple torch modes on simultaneously. + */ +typedef enum torch_mode_status { + + /** + * The flash unit is no longer available and the torch mode can not be + * turned on by calling set_torch_mode(). If the torch mode is on, it + * will be turned off by HAL before HAL calls torch_mode_status_change(). + */ + TORCH_MODE_STATUS_NOT_AVAILABLE = 0, + + /** + * A torch mode has become off and available to be turned on via + * set_torch_mode(). This may happen in the following + * cases: + * 1. After the resources to turn on the torch mode have become available. + * 2. After set_torch_mode() is called to turn off the torch mode. + * 3. After the framework turned on the torch mode of some other camera + * device and HAL had to turn off the torch modes of any camera devices + * that were previously on. + */ + TORCH_MODE_STATUS_AVAILABLE_OFF = 1, + + /** + * A torch mode has become on and available to be turned off via + * set_torch_mode(). This can happen only after set_torch_mode() is called + * to turn on the torch mode. + */ + TORCH_MODE_STATUS_AVAILABLE_ON = 2, + +} torch_mode_status_t; + +/** + * Callback functions for the camera HAL module to use to inform the framework + * of changes to the camera subsystem. + * + * Version information (based on camera_module_t.common.module_api_version): + * + * Each callback is called only by HAL modules implementing the indicated + * version or higher of the HAL module API interface. + * + * CAMERA_MODULE_API_VERSION_2_1: + * camera_device_status_change() + * + * CAMERA_MODULE_API_VERSION_2_4: + * torch_mode_status_change() + + */ +typedef struct camera_module_callbacks { + + /** + * camera_device_status_change: + * + * Callback to the framework to indicate that the state of a specific camera + * device has changed. At module load time, the framework will assume all + * camera devices are in the CAMERA_DEVICE_STATUS_PRESENT state. The HAL + * must call this method to inform the framework of any initially + * NOT_PRESENT devices. + * + * This callback is added for CAMERA_MODULE_API_VERSION_2_1. + * + * camera_module_callbacks: The instance of camera_module_callbacks_t passed + * to the module with set_callbacks. + * + * camera_id: The ID of the camera device that has a new status. + * + * new_status: The new status code, one of the camera_device_status_t enums, + * or a platform-specific status. + * + */ + void (*camera_device_status_change)(const struct camera_module_callbacks*, + int camera_id, + int new_status); + + /** + * torch_mode_status_change: + * + * Callback to the framework to indicate that the state of the torch mode + * of the flash unit associated with a specific camera device has changed. + * At module load time, the framework will assume the torch modes are in + * the TORCH_MODE_STATUS_AVAILABLE_OFF state if android.flash.info.available + * is reported as true via get_camera_info() call. + * + * This callback is added for CAMERA_MODULE_API_VERSION_2_4. + * + * camera_module_callbacks: The instance of camera_module_callbacks_t + * passed to the module with set_callbacks. + * + * camera_id: The ID of camera device whose flash unit has a new torch mode + * status. + * + * new_status: The new status code, one of the torch_mode_status_t enums. + */ + void (*torch_mode_status_change)(const struct camera_module_callbacks*, + const char* camera_id, + int new_status); + + +} camera_module_callbacks_t; + +typedef struct camera_module { + /** + * Common methods of the camera module. This *must* be the first member of + * camera_module as users of this structure will cast a hw_module_t to + * camera_module pointer in contexts where it's known the hw_module_t + * references a camera_module. + * + * The return values for common.methods->open for camera_module are: + * + * 0: On a successful open of the camera device. + * + * -ENODEV: The camera device cannot be opened due to an internal + * error. + * + * -EINVAL: The input arguments are invalid, i.e. the id is invalid, + * and/or the module is invalid. + * + * -EBUSY: The camera device was already opened for this camera id + * (by using this method or open_legacy), + * regardless of the device HAL version it was opened as. + * + * -EUSERS: The maximal number of camera devices that can be + * opened concurrently were opened already, either by + * this method or the open_legacy method. + * + * All other return values from common.methods->open will be treated as + * -ENODEV. + */ + hw_module_t common; + + /** + * get_number_of_cameras: + * + * Returns the number of camera devices accessible through the camera + * module. The camera devices are numbered 0 through N-1, where N is the + * value returned by this call. The name of the camera device for open() is + * simply the number converted to a string. That is, "0" for camera ID 0, + * "1" for camera ID 1. + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_2_3 or lower: + * + * The value here must be static, and cannot change after the first call + * to this method. + * + * CAMERA_MODULE_API_VERSION_2_4 or higher: + * + * The value here must be static, and must count only built-in cameras, + * which have CAMERA_FACING_BACK or CAMERA_FACING_FRONT camera facing values + * (camera_info.facing). The HAL must not include the external cameras + * (camera_info.facing == CAMERA_FACING_EXTERNAL) into the return value + * of this call. Frameworks will use camera_device_status_change callback + * to manage number of external cameras. + */ + int (*get_number_of_cameras)(void); + + /** + * get_camera_info: + * + * Return the static camera information for a given camera device. This + * information may not change for a camera device. + * + * Return values: + * + * 0: On a successful operation + * + * -ENODEV: The information cannot be provided due to an internal + * error. + * + * -EINVAL: The input arguments are invalid, i.e. the id is invalid, + * and/or the module is invalid. + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_2_4 or higher: + * + * When a camera is disconnected, its camera id becomes invalid. Calling this + * this method with this invalid camera id will get -EINVAL and NULL camera + * static metadata (camera_info.static_camera_characteristics). + */ + int (*get_camera_info)(int camera_id, struct camera_info *info); + + /** + * set_callbacks: + * + * Provide callback function pointers to the HAL module to inform framework + * of asynchronous camera module events. The framework will call this + * function once after initial camera HAL module load, after the + * get_number_of_cameras() method is called for the first time, and before + * any other calls to the module. + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_1_0, CAMERA_MODULE_API_VERSION_2_0: + * + * Not provided by HAL module. Framework may not call this function. + * + * CAMERA_MODULE_API_VERSION_2_1: + * + * Valid to be called by the framework. + * + * Return values: + * + * 0: On a successful operation + * + * -ENODEV: The operation cannot be completed due to an internal + * error. + * + * -EINVAL: The input arguments are invalid, i.e. the callbacks are + * null + */ + int (*set_callbacks)(const camera_module_callbacks_t *callbacks); + + /** + * get_vendor_tag_ops: + * + * Get methods to query for vendor extension metadata tag information. The + * HAL should fill in all the vendor tag operation methods, or leave ops + * unchanged if no vendor tags are defined. + * + * The vendor_tag_ops structure used here is defined in: + * system/media/camera/include/system/vendor_tags.h + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_1_x/2_0/2_1: + * Not provided by HAL module. Framework may not call this function. + * + * CAMERA_MODULE_API_VERSION_2_2: + * Valid to be called by the framework. + */ + void (*get_vendor_tag_ops)(vendor_tag_ops_t* ops); + + /** + * open_legacy: + * + * Open a specific legacy camera HAL device if multiple device HAL API + * versions are supported by this camera HAL module. For example, if the + * camera module supports both CAMERA_DEVICE_API_VERSION_1_0 and + * CAMERA_DEVICE_API_VERSION_3_2 device API for the same camera id, + * framework can call this function to open the camera device as + * CAMERA_DEVICE_API_VERSION_1_0 device. + * + * This is an optional method. A Camera HAL module does not need to support + * more than one device HAL version per device, and such modules may return + * -ENOSYS for all calls to this method. For all older HAL device API + * versions that are not supported, it may return -EOPNOTSUPP. When above + * cases occur, The normal open() method (common.methods->open) will be + * used by the framework instead. + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_1_x/2_0/2_1/2_2: + * Not provided by HAL module. Framework will not call this function. + * + * CAMERA_MODULE_API_VERSION_2_3: + * Valid to be called by the framework. + * + * Return values: + * + * 0: On a successful open of the camera device. + * + * -ENOSYS This method is not supported. + * + * -EOPNOTSUPP: The requested HAL version is not supported by this method. + * + * -EINVAL: The input arguments are invalid, i.e. the id is invalid, + * and/or the module is invalid. + * + * -EBUSY: The camera device was already opened for this camera id + * (by using this method or common.methods->open method), + * regardless of the device HAL version it was opened as. + * + * -EUSERS: The maximal number of camera devices that can be + * opened concurrently were opened already, either by + * this method or common.methods->open method. + */ + int (*open_legacy)(const struct hw_module_t* module, const char* id, + uint32_t halVersion, struct hw_device_t** device); + + /** + * set_torch_mode: + * + * Turn on or off the torch mode of the flash unit associated with a given + * camera ID. If the operation is successful, HAL must notify the framework + * torch state by invoking + * camera_module_callbacks.torch_mode_status_change() with the new state. + * + * The camera device has a higher priority accessing the flash unit. When + * there are any resource conflicts, such as open() is called to open a + * camera device, HAL module must notify the framework through + * camera_module_callbacks.torch_mode_status_change() that the + * torch mode has been turned off and the torch mode state has become + * TORCH_MODE_STATUS_NOT_AVAILABLE. When resources to turn on torch mode + * become available again, HAL module must notify the framework through + * camera_module_callbacks.torch_mode_status_change() that the torch mode + * state has become TORCH_MODE_STATUS_AVAILABLE_OFF for set_torch_mode() to + * be called. + * + * When the framework calls set_torch_mode() to turn on the torch mode of a + * flash unit, if HAL cannot keep multiple torch modes on simultaneously, + * HAL should turn off the torch mode that was turned on by + * a previous set_torch_mode() call and notify the framework that the torch + * mode state of that flash unit has become TORCH_MODE_STATUS_AVAILABLE_OFF. + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_1_x/2_0/2_1/2_2/2_3: + * Not provided by HAL module. Framework will not call this function. + * + * CAMERA_MODULE_API_VERSION_2_4: + * Valid to be called by the framework. + * + * Return values: + * + * 0: On a successful operation. + * + * -ENOSYS: The camera device does not support this operation. It is + * returned if and only if android.flash.info.available is + * false. + * + * -EBUSY: The camera device is already in use. + * + * -EUSERS: The resources needed to turn on the torch mode are not + * available, typically because other camera devices are + * holding the resources to make using the flash unit not + * possible. + * + * -EINVAL: camera_id is invalid. + * + */ + int (*set_torch_mode)(const char* camera_id, bool enabled); + + /** + * init: + * + * This method is called by the camera service before any other methods + * are invoked, right after the camera HAL library has been successfully + * loaded. It may be left as NULL by the HAL module, if no initialization + * in needed. + * + * It can be used by HAL implementations to perform initialization and + * other one-time operations. + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_1_x/2_0/2_1/2_2/2_3: + * Not provided by HAL module. Framework will not call this function. + * + * CAMERA_MODULE_API_VERSION_2_4: + * If not NULL, will always be called by the framework once after the HAL + * module is loaded, before any other HAL module method is called. + * + * Return values: + * + * 0: On a successful operation. + * + * -ENODEV: Initialization cannot be completed due to an internal + * error. The HAL must be assumed to be in a nonfunctional + * state. + * + */ + int (*init)(); + + /* reserved for future use */ + void* reserved[5]; +} camera_module_t; + +__END_DECLS + +#endif /* ANDROID_INCLUDE_CAMERA_COMMON_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/consumerir.h b/phonelibs/android_hardware_libhardware/include/hardware/consumerir.h new file mode 100644 index 00000000000000..15334c1111637a --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/consumerir.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_HARDWARE_CONSUMERIR_H +#define ANDROID_INCLUDE_HARDWARE_CONSUMERIR_H + +#include +#include +#include +#include + +#define CONSUMERIR_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0) +#define CONSUMERIR_HARDWARE_MODULE_ID "consumerir" +#define CONSUMERIR_TRANSMITTER "transmitter" + +typedef struct consumerir_freq_range { + int min; + int max; +} consumerir_freq_range_t; + +typedef struct consumerir_module { + /** + * Common methods of the consumer IR module. This *must* be the first member of + * consumerir_module as users of this structure will cast a hw_module_t to + * consumerir_module pointer in contexts where it's known the hw_module_t references a + * consumerir_module. + */ + struct hw_module_t common; +} consumerir_module_t; + +typedef struct consumerir_device { + /** + * Common methods of the consumer IR device. This *must* be the first member of + * consumerir_device as users of this structure will cast a hw_device_t to + * consumerir_device pointer in contexts where it's known the hw_device_t references a + * consumerir_device. + */ + struct hw_device_t common; + + /* + * (*transmit)() is called to by the ConsumerIrService to send an IR pattern + * at a given carrier_freq. + * + * The pattern is alternating series of carrier on and off periods measured in + * microseconds. The carrier should be turned off at the end of a transmit + * even if there are and odd number of entries in the pattern array. + * + * This call should return when the transmit is complete or encounters an error. + * + * returns: 0 on success. A negative error code on error. + */ + int (*transmit)(struct consumerir_device *dev, int carrier_freq, + const int pattern[], int pattern_len); + + /* + * (*get_num_carrier_freqs)() is called by the ConsumerIrService to get the + * number of carrier freqs to allocate space for, which is then filled by + * a subsequent call to (*get_carrier_freqs)(). + * + * returns: the number of ranges on success. A negative error code on error. + */ + int (*get_num_carrier_freqs)(struct consumerir_device *dev); + + /* + * (*get_carrier_freqs)() is called by the ConsumerIrService to enumerate + * which frequencies the IR transmitter supports. The HAL implementation + * should fill an array of consumerir_freq_range structs with the + * appropriate values for the transmitter, up to len elements. + * + * returns: the number of ranges on success. A negative error code on error. + */ + int (*get_carrier_freqs)(struct consumerir_device *dev, + size_t len, consumerir_freq_range_t *ranges); + + /* Reserved for future use. Must be NULL. */ + void* reserved[8 - 3]; +} consumerir_device_t; + +#endif /* ANDROID_INCLUDE_HARDWARE_CONSUMERIR_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/display_defs.h b/phonelibs/android_hardware_libhardware/include/hardware/display_defs.h new file mode 100644 index 00000000000000..669ef78c4e96be --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/display_defs.h @@ -0,0 +1,67 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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. + */ + +#ifndef ANDROID_INCLUDE_DISPLAY_DEFS_H +#define ANDROID_INCLUDE_DISPLAY_DEFS_H + +#include +#include + +#include + +__BEGIN_DECLS + +/* Will need to update below enums if hwcomposer_defs.h is updated */ + +/* Extended events for hwc_methods::eventControl() */ +enum { + HWC_EVENT_ORIENTATION = HWC_EVENT_VSYNC + 1 +}; + + +/* Extended hwc_layer_t::compositionType values */ +enum { + /* this layer will be handled in the HWC, using a blit engine */ + HWC_BLIT = 0xFF +}; + +/* Extended hwc_layer_t::flags values + * Flags are set by SurfaceFlinger and read by the HAL + */ +enum { + /* + * HWC_SCREENSHOT_ANIMATOR_LAYER is set by surfaceflinger to indicate + * that this layer is a screenshot animating layer. HWC uses this + * info to disable rotation animation on External Display + */ + HWC_SCREENSHOT_ANIMATOR_LAYER = 0x00000004 +}; + +__END_DECLS + +#endif /* ANDROID_INCLUDE_DISPLAY_DEFS_H*/ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/fb.h b/phonelibs/android_hardware_libhardware/include/hardware/fb.h new file mode 100644 index 00000000000000..9df94165b9b1bf --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/fb.h @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_FB_INTERFACE_H +#define ANDROID_FB_INTERFACE_H + +#include +#include +#include + +#include + +#include + +__BEGIN_DECLS + +#define GRALLOC_HARDWARE_FB0 "fb0" + +/*****************************************************************************/ + + +/*****************************************************************************/ + +typedef struct framebuffer_device_t { + /** + * Common methods of the framebuffer device. This *must* be the first member of + * framebuffer_device_t as users of this structure will cast a hw_device_t to + * framebuffer_device_t pointer in contexts where it's known the hw_device_t references a + * framebuffer_device_t. + */ + struct hw_device_t common; + + /* flags describing some attributes of the framebuffer */ + const uint32_t flags; + + /* dimensions of the framebuffer in pixels */ + const uint32_t width; + const uint32_t height; + + /* frambuffer stride in pixels */ + const int stride; + + /* framebuffer pixel format */ + const int format; + + /* resolution of the framebuffer's display panel in pixel per inch*/ + const float xdpi; + const float ydpi; + + /* framebuffer's display panel refresh rate in frames per second */ + const float fps; + + /* min swap interval supported by this framebuffer */ + const int minSwapInterval; + + /* max swap interval supported by this framebuffer */ + const int maxSwapInterval; + + /* Number of framebuffers supported*/ + const int numFramebuffers; + + int reserved[7]; + + /* + * requests a specific swap-interval (same definition than EGL) + * + * Returns 0 on success or -errno on error. + */ + int (*setSwapInterval)(struct framebuffer_device_t* window, + int interval); + + /* + * This hook is OPTIONAL. + * + * It is non NULL If the framebuffer driver supports "update-on-demand" + * and the given rectangle is the area of the screen that gets + * updated during (*post)(). + * + * This is useful on devices that are able to DMA only a portion of + * the screen to the display panel, upon demand -- as opposed to + * constantly refreshing the panel 60 times per second, for instance. + * + * Only the area defined by this rectangle is guaranteed to be valid, that + * is, the driver is not allowed to post anything outside of this + * rectangle. + * + * The rectangle evaluated during (*post)() and specifies which area + * of the buffer passed in (*post)() shall to be posted. + * + * return -EINVAL if width or height <=0, or if left or top < 0 + */ + int (*setUpdateRect)(struct framebuffer_device_t* window, + int left, int top, int width, int height); + + /* + * Post to the display (display it on the screen) + * The buffer must have been allocated with the + * GRALLOC_USAGE_HW_FB usage flag. + * buffer must be the same width and height as the display and must NOT + * be locked. + * + * The buffer is shown during the next VSYNC. + * + * If the same buffer is posted again (possibly after some other buffer), + * post() will block until the the first post is completed. + * + * Internally, post() is expected to lock the buffer so that a + * subsequent call to gralloc_module_t::(*lock)() with USAGE_RENDER or + * USAGE_*_WRITE will block until it is safe; that is typically once this + * buffer is shown and another buffer has been posted. + * + * Returns 0 on success or -errno on error. + */ + int (*post)(struct framebuffer_device_t* dev, buffer_handle_t buffer); + + + /* + * The (*compositionComplete)() method must be called after the + * compositor has finished issuing GL commands for client buffers. + */ + + int (*compositionComplete)(struct framebuffer_device_t* dev); + + /* + * This hook is OPTIONAL. + * + * If non NULL it will be caused by SurfaceFlinger on dumpsys + */ + void (*dump)(struct framebuffer_device_t* dev, char *buff, int buff_len); + + /* + * (*enableScreen)() is used to either blank (enable=0) or + * unblank (enable=1) the screen this framebuffer is attached to. + * + * Returns 0 on success or -errno on error. + */ + int (*enableScreen)(struct framebuffer_device_t* dev, int enable); + + void* reserved_proc[6]; + +} framebuffer_device_t; + + +/** convenience API for opening and closing a supported device */ + +static inline int framebuffer_open(const struct hw_module_t* module, + struct framebuffer_device_t** device) { + return module->methods->open(module, + GRALLOC_HARDWARE_FB0, (struct hw_device_t**)device); +} + +static inline int framebuffer_close(struct framebuffer_device_t* device) { + return device->common.close(&device->common); +} + + +__END_DECLS + +#endif // ANDROID_FB_INTERFACE_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/fingerprint.h b/phonelibs/android_hardware_libhardware/include/hardware/fingerprint.h new file mode 100644 index 00000000000000..ac88c10322c5c9 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/fingerprint.h @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_HARDWARE_FINGERPRINT_H +#define ANDROID_INCLUDE_HARDWARE_FINGERPRINT_H + +#include + +#define FINGERPRINT_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0) +#define FINGERPRINT_MODULE_API_VERSION_2_0 HARDWARE_MODULE_API_VERSION(2, 0) +#define FINGERPRINT_HARDWARE_MODULE_ID "fingerprint" + +typedef enum fingerprint_msg_type { + FINGERPRINT_ERROR = -1, + FINGERPRINT_ACQUIRED = 1, + FINGERPRINT_TEMPLATE_ENROLLING = 3, + FINGERPRINT_TEMPLATE_REMOVED = 4, + FINGERPRINT_AUTHENTICATED = 5 +} fingerprint_msg_type_t; + +/* + * Fingerprint errors are meant to tell the framework to terminate the current operation and ask + * for the user to correct the situation. These will almost always result in messaging and user + * interaction to correct the problem. + * + * For example, FINGERPRINT_ERROR_CANCELED should follow any acquisition message that results in + * a situation where the current operation can't continue without user interaction. For example, + * if the sensor is dirty during enrollment and no further enrollment progress can be made, + * send FINGERPRINT_ACQUIRED_IMAGER_DIRTY followed by FINGERPRINT_ERROR_CANCELED. + */ +typedef enum fingerprint_error { + FINGERPRINT_ERROR_HW_UNAVAILABLE = 1, /* The hardware has an error that can't be resolved. */ + FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2, /* Bad data; operation can't continue */ + FINGERPRINT_ERROR_TIMEOUT = 3, /* The operation has timed out waiting for user input. */ + FINGERPRINT_ERROR_NO_SPACE = 4, /* No space available to store a template */ + FINGERPRINT_ERROR_CANCELED = 5, /* The current operation can't proceed. See above. */ + FINGERPRINT_ERROR_UNABLE_TO_REMOVE = 6, /* fingerprint with given id can't be removed */ + FINGERPRINT_ERROR_VENDOR_BASE = 1000 /* vendor-specific error messages start here */ +} fingerprint_error_t; + +/* + * Fingerprint acquisition info is meant as feedback for the current operation. Anything but + * FINGERPRINT_ACQUIRED_GOOD will be shown to the user as feedback on how to take action on the + * current operation. For example, FINGERPRINT_ACQUIRED_IMAGER_DIRTY can be used to tell the user + * to clean the sensor. If this will cause the current operation to fail, an additional + * FINGERPRINT_ERROR_CANCELED can be sent to stop the operation in progress (e.g. enrollment). + * In general, these messages will result in a "Try again" message. + */ +typedef enum fingerprint_acquired_info { + FINGERPRINT_ACQUIRED_GOOD = 0, + FINGERPRINT_ACQUIRED_PARTIAL = 1, /* sensor needs more data, i.e. longer swipe. */ + FINGERPRINT_ACQUIRED_INSUFFICIENT = 2, /* image doesn't contain enough detail for recognition*/ + FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 3, /* sensor needs to be cleaned */ + FINGERPRINT_ACQUIRED_TOO_SLOW = 4, /* mostly swipe-type sensors; not enough data collected */ + FINGERPRINT_ACQUIRED_TOO_FAST = 5, /* for swipe and area sensors; tell user to slow down*/ + FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000 /* vendor-specific acquisition messages start here */ +} fingerprint_acquired_info_t; + +typedef struct fingerprint_finger_id { + uint32_t gid; + uint32_t fid; +} fingerprint_finger_id_t; + +typedef struct fingerprint_enroll { + fingerprint_finger_id_t finger; + /* samples_remaining goes from N (no data collected, but N scans needed) + * to 0 (no more data is needed to build a template). */ + uint32_t samples_remaining; + uint64_t msg; /* Vendor specific message. Used for user guidance */ +} fingerprint_enroll_t; + +typedef struct fingerprint_removed { + fingerprint_finger_id_t finger; +} fingerprint_removed_t; + +typedef struct fingerprint_acquired { + fingerprint_acquired_info_t acquired_info; /* information about the image */ +} fingerprint_acquired_t; + +typedef struct fingerprint_authenticated { + fingerprint_finger_id_t finger; + hw_auth_token_t hat; +} fingerprint_authenticated_t; + +typedef struct fingerprint_msg { + fingerprint_msg_type_t type; + union { + fingerprint_error_t error; + fingerprint_enroll_t enroll; + fingerprint_removed_t removed; + fingerprint_acquired_t acquired; + fingerprint_authenticated_t authenticated; + } data; +} fingerprint_msg_t; + +/* Callback function type */ +typedef void (*fingerprint_notify_t)(const fingerprint_msg_t *msg); + +/* Synchronous operation */ +typedef struct fingerprint_device { + /** + * Common methods of the fingerprint device. This *must* be the first member + * of fingerprint_device as users of this structure will cast a hw_device_t + * to fingerprint_device pointer in contexts where it's known + * the hw_device_t references a fingerprint_device. + */ + struct hw_device_t common; + + /* + * Client provided callback function to receive notifications. + * Do not set by hand, use the function above instead. + */ + fingerprint_notify_t notify; + + /* + * Set notification callback: + * Registers a user function that would receive notifications from the HAL + * The call will block if the HAL state machine is in busy state until HAL + * leaves the busy state. + * + * Function return: 0 if callback function is successfuly registered + * or a negative number in case of error, generally from the errno.h set. + */ + int (*set_notify)(struct fingerprint_device *dev, fingerprint_notify_t notify); + + /* + * Fingerprint pre-enroll enroll request: + * Generates a unique token to upper layers to indicate the start of an enrollment transaction. + * This token will be wrapped by security for verification and passed to enroll() for + * verification before enrollment will be allowed. This is to ensure adding a new fingerprint + * template was preceded by some kind of credential confirmation (e.g. device password). + * + * Function return: 0 if function failed + * otherwise, a uint64_t of token + */ + uint64_t (*pre_enroll)(struct fingerprint_device *dev); + + /* + * Fingerprint enroll request: + * Switches the HAL state machine to collect and store a new fingerprint + * template. Switches back as soon as enroll is complete + * (fingerprint_msg.type == FINGERPRINT_TEMPLATE_ENROLLING && + * fingerprint_msg.data.enroll.samples_remaining == 0) + * or after timeout_sec seconds. + * The fingerprint template will be assigned to the group gid. User has a choice + * to supply the gid or set it to 0 in which case a unique group id will be generated. + * + * Function return: 0 if enrollment process can be successfully started + * or a negative number in case of error, generally from the errno.h set. + * A notify() function may be called indicating the error condition. + */ + int (*enroll)(struct fingerprint_device *dev, const hw_auth_token_t *hat, + uint32_t gid, uint32_t timeout_sec); + + /* + * Finishes the enroll operation and invalidates the pre_enroll() generated challenge. + * This will be called at the end of a multi-finger enrollment session to indicate + * that no more fingers will be added. + * + * Function return: 0 if the request is accepted + * or a negative number in case of error, generally from the errno.h set. + */ + int (*post_enroll)(struct fingerprint_device *dev); + + /* + * get_authenticator_id: + * Returns a token associated with the current fingerprint set. This value will + * change whenever a new fingerprint is enrolled, thus creating a new fingerprint + * set. + * + * Function return: current authenticator id or 0 if function failed. + */ + uint64_t (*get_authenticator_id)(struct fingerprint_device *dev); + + /* + * Cancel pending enroll or authenticate, sending FINGERPRINT_ERROR_CANCELED + * to all running clients. Switches the HAL state machine back to the idle state. + * Unlike enroll_done() doesn't invalidate the pre_enroll() challenge. + * + * Function return: 0 if cancel request is accepted + * or a negative number in case of error, generally from the errno.h set. + */ + int (*cancel)(struct fingerprint_device *dev); + + /* + * Enumerate all the fingerprint templates found in the directory set by + * set_active_group() + * This is a synchronous call. The function takes: + * - A pointer to an array of fingerprint_finger_id_t. + * - The size of the array provided, in fingerprint_finger_id_t elements. + * Max_size is a bi-directional parameter and returns the actual number + * of elements copied to the caller supplied array. + * In the absence of errors the function returns the total number of templates + * in the user directory. + * If the caller has no good guess on the size of the array he should call this + * function witn *max_size == 0 and use the return value for the array allocation. + * The caller of this function has a complete list of the templates when *max_size + * is the same as the function return. + * + * Function return: Total number of fingerprint templates in the current storage directory. + * or a negative number in case of error, generally from the errno.h set. + */ + int (*enumerate)(struct fingerprint_device *dev, fingerprint_finger_id_t *results, + uint32_t *max_size); + + /* + * Fingerprint remove request: + * Deletes a fingerprint template. + * Works only within a path set by set_active_group(). + * notify() will be called with details on the template deleted. + * fingerprint_msg.type == FINGERPRINT_TEMPLATE_REMOVED and + * fingerprint_msg.data.removed.id indicating the template id removed. + * + * Function return: 0 if fingerprint template(s) can be successfully deleted + * or a negative number in case of error, generally from the errno.h set. + */ + int (*remove)(struct fingerprint_device *dev, uint32_t gid, uint32_t fid); + + /* + * Restricts the HAL operation to a set of fingerprints belonging to a + * group provided. + * The caller must provide a path to a storage location within the user's + * data directory. + * + * Function return: 0 on success + * or a negative number in case of error, generally from the errno.h set. + */ + int (*set_active_group)(struct fingerprint_device *dev, uint32_t gid, + const char *store_path); + + /* + * Authenticates an operation identifed by operation_id + * + * Function return: 0 on success + * or a negative number in case of error, generally from the errno.h set. + */ + int (*authenticate)(struct fingerprint_device *dev, uint64_t operation_id, uint32_t gid); + + /* Reserved for backward binary compatibility */ + void *reserved[4]; +} fingerprint_device_t; + +typedef struct fingerprint_module { + /** + * Common methods of the fingerprint module. This *must* be the first member + * of fingerprint_module as users of this structure will cast a hw_module_t + * to fingerprint_module pointer in contexts where it's known + * the hw_module_t references a fingerprint_module. + */ + struct hw_module_t common; +} fingerprint_module_t; + +#endif /* ANDROID_INCLUDE_HARDWARE_FINGERPRINT_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/fused_location.h b/phonelibs/android_hardware_libhardware/include/hardware/fused_location.h new file mode 100644 index 00000000000000..73360a12a1289b --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/fused_location.h @@ -0,0 +1,825 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_HARDWARE_FUSED_LOCATION_H +#define ANDROID_INCLUDE_HARDWARE_FUSED_LOCATION_H + +#include + + +/** + * This header file defines the interface of the Fused Location Provider. + * Fused Location Provider is designed to fuse data from various sources + * like GPS, Wifi, Cell, Sensors, Bluetooth etc to provide a fused location to the + * upper layers. The advantage of doing fusion in hardware is power savings. + * The goal is to do this without waking up the AP to get additional data. + * The software implementation of FLP will decide when to use + * the hardware fused location. Other location features like geofencing will + * also be implemented using fusion in hardware. + */ +__BEGIN_DECLS + +#define FLP_HEADER_VERSION 1 +#define FLP_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1) +#define FLP_DEVICE_API_VERSION_0_1 HARDWARE_DEVICE_API_VERSION_2(0, 1, FLP_HEADER_VERSION) + +/** + * The id of this module + */ +#define FUSED_LOCATION_HARDWARE_MODULE_ID "flp" + +/** + * Name for the FLP location interface + */ +#define FLP_LOCATION_INTERFACE "flp_location" + +/** + * Name for the FLP location interface + */ +#define FLP_DIAGNOSTIC_INTERFACE "flp_diagnostic" + +/** + * Name for the FLP_Geofencing interface. + */ +#define FLP_GEOFENCING_INTERFACE "flp_geofencing" + +/** + * Name for the FLP_device context interface. + */ +#define FLP_DEVICE_CONTEXT_INTERFACE "flp_device_context" + +/** + * Constants to indicate the various subsystems + * that will be used. + */ +#define FLP_TECH_MASK_GNSS (1U<<0) +#define FLP_TECH_MASK_WIFI (1U<<1) +#define FLP_TECH_MASK_SENSORS (1U<<2) +#define FLP_TECH_MASK_CELL (1U<<3) +#define FLP_TECH_MASK_BLUETOOTH (1U<<4) + +/** + * Set when your implementation can produce GNNS-derived locations, + * for use with flp_capabilities_callback. + * + * GNNS is a required capability for a particular feature to be used + * (batching or geofencing). If not supported that particular feature + * won't be used by the upper layer. + */ +#define CAPABILITY_GNSS (1U<<0) +/** + * Set when your implementation can produce WiFi-derived locations, for + * use with flp_capabilities_callback. + */ +#define CAPABILITY_WIFI (1U<<1) +/** + * Set when your implementation can produce cell-derived locations, for + * use with flp_capabilities_callback. + */ +#define CAPABILITY_CELL (1U<<3) + +/** + * Status to return in flp_status_callback when your implementation transitions + * from being unsuccessful in determining location to being successful. + */ +#define FLP_STATUS_LOCATION_AVAILABLE 0 +/** + * Status to return in flp_status_callback when your implementation transitions + * from being successful in determining location to being unsuccessful. + */ +#define FLP_STATUS_LOCATION_UNAVAILABLE 1 + +/** + * This constant is used with the batched locations + * APIs. Batching is mandatory when FLP implementation + * is supported. If the flag is set, the hardware implementation + * will wake up the application processor when the FIFO is full, + * If the flag is not set, the hardware implementation will drop + * the oldest data when the FIFO is full. + */ +#define FLP_BATCH_WAKEUP_ON_FIFO_FULL 0x0000001 + +/** + * While batching, the implementation should not call the + * flp_location_callback on every location fix. However, + * sometimes in high power mode, the system might need + * a location callback every single time the location + * fix has been obtained. This flag controls that option. + * Its the responsibility of the upper layers (caller) to switch + * it off, if it knows that the AP might go to sleep. + * When this bit is on amidst a batching session, batching should + * continue while location fixes are reported in real time. + */ +#define FLP_BATCH_CALLBACK_ON_LOCATION_FIX 0x0000002 + +/** Flags to indicate which values are valid in a FlpLocation. */ +typedef uint16_t FlpLocationFlags; + +// IMPORTANT: Note that the following values must match +// constants in the corresponding java file. + +/** FlpLocation has valid latitude and longitude. */ +#define FLP_LOCATION_HAS_LAT_LONG (1U<<0) +/** FlpLocation has valid altitude. */ +#define FLP_LOCATION_HAS_ALTITUDE (1U<<1) +/** FlpLocation has valid speed. */ +#define FLP_LOCATION_HAS_SPEED (1U<<2) +/** FlpLocation has valid bearing. */ +#define FLP_LOCATION_HAS_BEARING (1U<<4) +/** FlpLocation has valid accuracy. */ +#define FLP_LOCATION_HAS_ACCURACY (1U<<8) + + +typedef int64_t FlpUtcTime; + +/** Represents a location. */ +typedef struct { + /** set to sizeof(FlpLocation) */ + size_t size; + + /** Flags associated with the location object. */ + FlpLocationFlags flags; + + /** Represents latitude in degrees. */ + double latitude; + + /** Represents longitude in degrees. */ + double longitude; + + /** + * Represents altitude in meters above the WGS 84 reference + * ellipsoid. */ + double altitude; + + /** Represents speed in meters per second. */ + float speed; + + /** Represents heading in degrees. */ + float bearing; + + /** Represents expected accuracy in meters. */ + float accuracy; + + /** Timestamp for the location fix. */ + FlpUtcTime timestamp; + + /** Sources used, will be Bitwise OR of the FLP_TECH_MASK bits. */ + uint32_t sources_used; +} FlpLocation; + +typedef enum { + ASSOCIATE_JVM, + DISASSOCIATE_JVM, +} ThreadEvent; + +/** + * Callback with location information. + * Can only be called from a thread associated to JVM using set_thread_event_cb. + * Parameters: + * num_locations is the number of batched locations available. + * location is the pointer to an array of pointers to location objects. + */ +typedef void (*flp_location_callback)(int32_t num_locations, FlpLocation** location); + +/** + * Callback utility for acquiring a wakelock. + * This can be used to prevent the CPU from suspending while handling FLP events. + */ +typedef void (*flp_acquire_wakelock)(); + +/** + * Callback utility for releasing the FLP wakelock. + */ +typedef void (*flp_release_wakelock)(); + +/** + * Callback for associating a thread that can call into the Java framework code. + * This must be used to initialize any threads that report events up to the framework. + * Return value: + * FLP_RESULT_SUCCESS on success. + * FLP_RESULT_ERROR if the association failed in the current thread. + */ +typedef int (*flp_set_thread_event)(ThreadEvent event); + +/** + * Callback for technologies supported by this implementation. + * + * Parameters: capabilities is a bitmask of FLP_CAPABILITY_* values describing + * which features your implementation supports. You should support + * CAPABILITY_GNSS at a minimum for your implementation to be utilized. You can + * return 0 in FlpGeofenceCallbacks to indicate you don't support geofencing, + * or 0 in FlpCallbacks to indicate you don't support location batching. + */ +typedef void (*flp_capabilities_callback)(int capabilities); + +/** + * Callback with status information on the ability to compute location. + * To avoid waking up the application processor you should only send + * changes in status (you shouldn't call this method twice in a row + * with the same status value). As a guideline you should not call this + * more frequently then the requested batch period set with period_ns + * in FlpBatchOptions. For example if period_ns is set to 5 minutes and + * the status changes many times in that interval, you should only report + * one status change every 5 minutes. + * + * Parameters: + * status is one of FLP_STATUS_LOCATION_AVAILABLE + * or FLP_STATUS_LOCATION_UNAVAILABLE. + */ +typedef void (*flp_status_callback)(int32_t status); + +/** FLP callback structure. */ +typedef struct { + /** set to sizeof(FlpCallbacks) */ + size_t size; + flp_location_callback location_cb; + flp_acquire_wakelock acquire_wakelock_cb; + flp_release_wakelock release_wakelock_cb; + flp_set_thread_event set_thread_event_cb; + flp_capabilities_callback flp_capabilities_cb; + flp_status_callback flp_status_cb; +} FlpCallbacks; + + +/** Options with the batching FLP APIs */ +typedef struct { + /** + * Maximum power in mW that the underlying implementation + * can use for this batching call. + * If max_power_allocation_mW is 0, only fixes that are generated + * at no additional cost of power shall be reported. + */ + double max_power_allocation_mW; + + /** Bitwise OR of the FLP_TECH_MASKS to use */ + uint32_t sources_to_use; + + /** + * FLP_BATCH_WAKEUP_ON_FIFO_FULL - If set the hardware + * will wake up the AP when the buffer is full. If not set, the + * hardware will drop the oldest location object. + * + * FLP_BATCH_CALLBACK_ON_LOCATION_FIX - If set the location + * callback will be called every time there is a location fix. + * Its the responsibility of the upper layers (caller) to switch + * it off, if it knows that the AP might go to sleep. When this + * bit is on amidst a batching session, batching should continue + * while location fixes are reported in real time. + * + * Other flags to be bitwised ORed in the future. + */ + uint32_t flags; + + /** + * Frequency with which location needs to be batched in nano + * seconds. + */ + int64_t period_ns; + + /** + * The smallest displacement between reported locations in meters. + * + * If set to 0, then you should report locations at the requested + * interval even if the device is stationary. If positive, you + * can use this parameter as a hint to save power (e.g. throttling + * location period if the user hasn't traveled close to the displacement + * threshold). Even small positive values can be interpreted to mean + * that you don't have to compute location when the device is stationary. + * + * There is no need to filter location delivery based on this parameter. + * Locations can be delivered even if they have a displacement smaller than + * requested. This parameter can safely be ignored at the cost of potential + * power savings. + */ + float smallest_displacement_meters; +} FlpBatchOptions; + +#define FLP_RESULT_SUCCESS 0 +#define FLP_RESULT_ERROR -1 +#define FLP_RESULT_INSUFFICIENT_MEMORY -2 +#define FLP_RESULT_TOO_MANY_GEOFENCES -3 +#define FLP_RESULT_ID_EXISTS -4 +#define FLP_RESULT_ID_UNKNOWN -5 +#define FLP_RESULT_INVALID_GEOFENCE_TRANSITION -6 + +/** + * Represents the standard FLP interface. + */ +typedef struct { + /** + * set to sizeof(FlpLocationInterface) + */ + size_t size; + + /** + * Opens the interface and provides the callback routines + * to the implementation of this interface. Once called you should respond + * by calling the flp_capabilities_callback in FlpCallbacks to + * specify the capabilities that your implementation supports. + */ + int (*init)(FlpCallbacks* callbacks ); + + /** + * Return the batch size (in number of FlpLocation objects) + * available in the hardware. Note, different HW implementations + * may have different sample sizes. This shall return number + * of samples defined in the format of FlpLocation. + * This will be used by the upper layer, to decide on the batching + * interval and whether the AP should be woken up or not. + */ + int (*get_batch_size)(); + + /** + * Start batching locations. This API is primarily used when the AP is + * asleep and the device can batch locations in the hardware. + * flp_location_callback is used to return the locations. When the buffer + * is full and FLP_BATCH_WAKEUP_ON_FIFO_FULL is used, the AP is woken up. + * When the buffer is full and FLP_BATCH_WAKEUP_ON_FIFO_FULL is not set, + * the oldest location object is dropped. In this case the AP will not be + * woken up. The upper layer will use get_batched_location + * API to explicitly ask for the location. + * If FLP_BATCH_CALLBACK_ON_LOCATION_FIX is set, the implementation + * will call the flp_location_callback every single time there is a location + * fix. This overrides FLP_BATCH_WAKEUP_ON_FIFO_FULL flag setting. + * It's the responsibility of the upper layers (caller) to switch + * it off, if it knows that the AP might go to sleep. This is useful + * for nagivational applications when the system is in high power mode. + * Parameters: + * id - Id for the request. + * options - See FlpBatchOptions struct definition. + * Return value: + * FLP_RESULT_SUCCESS on success, FLP_RESULT_INSUFFICIENT_MEMORY, + * FLP_RESULT_ID_EXISTS, FLP_RESULT_ERROR on failure. + */ + int (*start_batching)(int id, FlpBatchOptions* options); + + /** + * Update FlpBatchOptions associated with a batching request. + * When a batching operation is in progress and a batching option + * such as FLP_BATCH_WAKEUP_ON_FIFO_FULL needs to be updated, this API + * will be used. For instance, this can happen when the AP is awake and + * the maps application is being used. + * Parameters: + * id - Id of an existing batch request. + * new_options - Updated FlpBatchOptions + * Return value: + * FLP_RESULT_SUCCESS on success, FLP_RESULT_ID_UNKNOWN, + * FLP_RESULT_ERROR on error. + */ + int (*update_batching_options)(int id, FlpBatchOptions* new_options); + + /** + * Stop batching. + * Parameters: + * id - Id for the request. + * Return Value: + * FLP_RESULT_SUCCESS on success, FLP_RESULT_ID_UNKNOWN or + * FLP_RESULT_ERROR on failure. + */ + int (*stop_batching)(int id); + + /** + * Closes the interface. If any batch operations are in progress, + * they should be stopped. + */ + void (*cleanup)(); + + /** + * Get the fused location that was batched. + * flp_location_callback is used to return the location. The location object + * is dropped from the buffer only when the buffer is full. Do not remove it + * from the buffer just because it has been returned using the callback. + * In other words, when there is no new location object, two calls to + * get_batched_location(1) should return the same location object. + * Parameters: + * last_n_locations - Number of locations to get. This can be one or many. + * If the last_n_locations is 1, you get the latest location known to the + * hardware. + */ + void (*get_batched_location)(int last_n_locations); + + /** + * Injects current location from another location provider + * latitude and longitude are measured in degrees + * expected accuracy is measured in meters + * Parameters: + * location - The location object being injected. + * Return value: FLP_RESULT_SUCCESS or FLP_RESULT_ERROR. + */ + int (*inject_location)(FlpLocation* location); + + /** + * Get a pointer to extension information. + */ + const void* (*get_extension)(const char* name); + + /** + * Retrieve all batched locations currently stored and clear the buffer. + * flp_location_callback MUST be called in response, even if there are + * no locations to flush (in which case num_locations should be 0). + * Subsequent calls to get_batched_location or flush_batched_locations + * should not return any of the locations returned in this call. + */ + void (*flush_batched_locations)(); +} FlpLocationInterface; + +struct flp_device_t { + struct hw_device_t common; + + /** + * Get a handle to the FLP Interface. + */ + const FlpLocationInterface* (*get_flp_interface)(struct flp_device_t* dev); +}; + +/** + * Callback for reports diagnostic data into the Java framework code. +*/ +typedef void (*report_data)(char* data, int length); + +/** + * FLP diagnostic callback structure. + * Currently, not used - but this for future extension. + */ +typedef struct { + /** set to sizeof(FlpDiagnosticCallbacks) */ + size_t size; + + flp_set_thread_event set_thread_event_cb; + + /** reports diagnostic data into the Java framework code */ + report_data data_cb; +} FlpDiagnosticCallbacks; + +/** Extended interface for diagnostic support. */ +typedef struct { + /** set to sizeof(FlpDiagnosticInterface) */ + size_t size; + + /** + * Opens the diagnostic interface and provides the callback routines + * to the implemenation of this interface. + */ + void (*init)(FlpDiagnosticCallbacks* callbacks); + + /** + * Injects diagnostic data into the FLP subsystem. + * Return 0 on success, -1 on error. + **/ + int (*inject_data)(char* data, int length ); +} FlpDiagnosticInterface; + +/** + * Context setting information. + * All these settings shall be injected to FLP HAL at FLP init time. + * Following that, only the changed setting need to be re-injected + * upon changes. + */ + +#define FLP_DEVICE_CONTEXT_GPS_ENABLED (1U<<0) +#define FLP_DEVICE_CONTEXT_AGPS_ENABLED (1U<<1) +#define FLP_DEVICE_CONTEXT_NETWORK_POSITIONING_ENABLED (1U<<2) +#define FLP_DEVICE_CONTEXT_WIFI_CONNECTIVITY_ENABLED (1U<<3) +#define FLP_DEVICE_CONTEXT_WIFI_POSITIONING_ENABLED (1U<<4) +#define FLP_DEVICE_CONTEXT_HW_NETWORK_POSITIONING_ENABLED (1U<<5) +#define FLP_DEVICE_CONTEXT_AIRPLANE_MODE_ON (1U<<6) +#define FLP_DEVICE_CONTEXT_DATA_ENABLED (1U<<7) +#define FLP_DEVICE_CONTEXT_ROAMING_ENABLED (1U<<8) +#define FLP_DEVICE_CONTEXT_CURRENTLY_ROAMING (1U<<9) +#define FLP_DEVICE_CONTEXT_SENSOR_ENABLED (1U<<10) +#define FLP_DEVICE_CONTEXT_BLUETOOTH_ENABLED (1U<<11) +#define FLP_DEVICE_CONTEXT_CHARGER_ON (1U<<12) + +/** Extended interface for device context support. */ +typedef struct { + /** set to sizeof(FlpDeviceContextInterface) */ + size_t size; + + /** + * Injects debug data into the FLP subsystem. + * Return 0 on success, -1 on error. + **/ + int (*inject_device_context)(uint32_t enabledMask); +} FlpDeviceContextInterface; + + +/** + * There are 3 states associated with a Geofence: Inside, Outside, Unknown. + * There are 3 transitions: ENTERED, EXITED, UNCERTAIN. + * + * An example state diagram with confidence level: 95% and Unknown time limit + * set as 30 secs is shown below. (confidence level and Unknown time limit are + * explained latter) + * ____________________________ + * | Unknown (30 secs) | + * """""""""""""""""""""""""""" + * ^ | | ^ + * UNCERTAIN| |ENTERED EXITED| |UNCERTAIN + * | v v | + * ________ EXITED _________ + * | Inside | -----------> | Outside | + * | | <----------- | | + * """""""" ENTERED """"""""" + * + * Inside state: We are 95% confident that the user is inside the geofence. + * Outside state: We are 95% confident that the user is outside the geofence + * Unknown state: Rest of the time. + * + * The Unknown state is better explained with an example: + * + * __________ + * | c| + * | ___ | _______ + * | |a| | | b | + * | """ | """"""" + * | | + * """""""""" + * In the diagram above, "a" and "b" are 2 geofences and "c" is the accuracy + * circle reported by the FLP subsystem. Now with regard to "b", the system is + * confident that the user is outside. But with regard to "a" is not confident + * whether it is inside or outside the geofence. If the accuracy remains the + * same for a sufficient period of time, the UNCERTAIN transition would be + * triggered with the state set to Unknown. If the accuracy improves later, an + * appropriate transition should be triggered. This "sufficient period of time" + * is defined by the parameter in the add_geofence_area API. + * In other words, Unknown state can be interpreted as a state in which the + * FLP subsystem isn't confident enough that the user is either inside or + * outside the Geofence. It moves to Unknown state only after the expiry of the + * timeout. + * + * The geofence callback needs to be triggered for the ENTERED and EXITED + * transitions, when the FLP system is confident that the user has entered + * (Inside state) or exited (Outside state) the Geofence. An implementation + * which uses a value of 95% as the confidence is recommended. The callback + * should be triggered only for the transitions requested by the + * add_geofence_area call. + * + * Even though the diagram and explanation talks about states and transitions, + * the callee is only interested in the transistions. The states are mentioned + * here for illustrative purposes. + * + * Startup Scenario: When the device boots up, if an application adds geofences, + * and then we get an accurate FLP location fix, it needs to trigger the + * appropriate (ENTERED or EXITED) transition for every Geofence it knows about. + * By default, all the Geofences will be in the Unknown state. + * + * When the FLP system is unavailable, flp_geofence_status_callback should be + * called to inform the upper layers of the same. Similarly, when it becomes + * available the callback should be called. This is a global state while the + * UNKNOWN transition described above is per geofence. + * + */ +#define FLP_GEOFENCE_TRANSITION_ENTERED (1L<<0) +#define FLP_GEOFENCE_TRANSITION_EXITED (1L<<1) +#define FLP_GEOFENCE_TRANSITION_UNCERTAIN (1L<<2) + +#define FLP_GEOFENCE_MONITOR_STATUS_UNAVAILABLE (1L<<0) +#define FLP_GEOFENCE_MONITOR_STATUS_AVAILABLE (1L<<1) + +/** + * The callback associated with the geofence. + * Parameters: + * geofence_id - The id associated with the add_geofence_area. + * location - The current location as determined by the FLP subsystem. + * transition - Can be one of FLP_GEOFENCE_TRANSITION_ENTERED, FLP_GEOFENCE_TRANSITION_EXITED, + * FLP_GEOFENCE_TRANSITION_UNCERTAIN. + * timestamp - Timestamp when the transition was detected; -1 if not available. + * sources_used - Bitwise OR of FLP_TECH_MASK flags indicating which + * subsystems were used. + * + * The callback should only be called when the caller is interested in that + * particular transition. For instance, if the caller is interested only in + * ENTERED transition, then the callback should NOT be called with the EXITED + * transition. + * + * IMPORTANT: If a transition is triggered resulting in this callback, the + * subsystem will wake up the application processor, if its in suspend state. + */ +typedef void (*flp_geofence_transition_callback) (int32_t geofence_id, FlpLocation* location, + int32_t transition, FlpUtcTime timestamp, uint32_t sources_used); + +/** + * The callback associated with the availablity of one the sources used for geofence + * monitoring by the FLP sub-system For example, if the GPS system determines that it cannot + * monitor geofences because of lack of reliability or unavailability of the GPS signals, + * it will call this callback with FLP_GEOFENCE_MONITOR_STATUS_UNAVAILABLE parameter and the + * source set to FLP_TECH_MASK_GNSS. + * + * Parameters: + * status - FLP_GEOFENCE_MONITOR_STATUS_UNAVAILABLE or FLP_GEOFENCE_MONITOR_STATUS_AVAILABLE. + * source - One of the FLP_TECH_MASKS + * last_location - Last known location. + */ +typedef void (*flp_geofence_monitor_status_callback) (int32_t status, uint32_t source, + FlpLocation* last_location); + +/** + * The callback associated with the add_geofence call. + * + * Parameter: + * geofence_id - Id of the geofence. + * result - FLP_RESULT_SUCCESS + * FLP_RESULT_ERROR_TOO_MANY_GEOFENCES - geofence limit has been reached. + * FLP_RESULT_ID_EXISTS - geofence with id already exists + * FLP_RESULT_INVALID_GEOFENCE_TRANSITION - the monitorTransition contains an + * invalid transition + * FLP_RESULT_ERROR - for other errors. + */ +typedef void (*flp_geofence_add_callback) (int32_t geofence_id, int32_t result); + +/** + * The callback associated with the remove_geofence call. + * + * Parameter: + * geofence_id - Id of the geofence. + * result - FLP_RESULT_SUCCESS + * FLP_RESULT_ID_UNKNOWN - for invalid id + * FLP_RESULT_ERROR for others. + */ +typedef void (*flp_geofence_remove_callback) (int32_t geofence_id, int32_t result); + + +/** + * The callback associated with the pause_geofence call. + * + * Parameter: + * geofence_id - Id of the geofence. + * result - FLP_RESULT_SUCCESS + * FLP_RESULT__ID_UNKNOWN - for invalid id + * FLP_RESULT_INVALID_TRANSITION - + * when monitor_transitions is invalid + * FLP_RESULT_ERROR for others. + */ +typedef void (*flp_geofence_pause_callback) (int32_t geofence_id, int32_t result); + +/** + * The callback associated with the resume_geofence call. + * + * Parameter: + * geofence_id - Id of the geofence. + * result - FLP_RESULT_SUCCESS + * FLP_RESULT_ID_UNKNOWN - for invalid id + * FLP_RESULT_ERROR for others. + */ +typedef void (*flp_geofence_resume_callback) (int32_t geofence_id, int32_t result); + +typedef struct { + /** set to sizeof(FlpGeofenceCallbacks) */ + size_t size; + flp_geofence_transition_callback geofence_transition_callback; + flp_geofence_monitor_status_callback geofence_status_callback; + flp_geofence_add_callback geofence_add_callback; + flp_geofence_remove_callback geofence_remove_callback; + flp_geofence_pause_callback geofence_pause_callback; + flp_geofence_resume_callback geofence_resume_callback; + flp_set_thread_event set_thread_event_cb; + flp_capabilities_callback flp_capabilities_cb; +} FlpGeofenceCallbacks; + + +/** Type of geofence */ +typedef enum { + TYPE_CIRCLE = 0, +} GeofenceType; + +/** Circular geofence is represented by lat / long / radius */ +typedef struct { + double latitude; + double longitude; + double radius_m; +} GeofenceCircle; + +/** Represents the type of geofence and data */ +typedef struct { + GeofenceType type; + union { + GeofenceCircle circle; + } geofence; +} GeofenceData; + +/** Geofence Options */ +typedef struct { + /** + * The current state of the geofence. For example, if + * the system already knows that the user is inside the geofence, + * this will be set to FLP_GEOFENCE_TRANSITION_ENTERED. In most cases, it + * will be FLP_GEOFENCE_TRANSITION_UNCERTAIN. */ + int last_transition; + + /** + * Transitions to monitor. Bitwise OR of + * FLP_GEOFENCE_TRANSITION_ENTERED, FLP_GEOFENCE_TRANSITION_EXITED and + * FLP_GEOFENCE_TRANSITION_UNCERTAIN. + */ + int monitor_transitions; + + /** + * Defines the best-effort description + * of how soon should the callback be called when the transition + * associated with the Geofence is triggered. For instance, if set + * to 1000 millseconds with FLP_GEOFENCE_TRANSITION_ENTERED, the callback + * should be called 1000 milliseconds within entering the geofence. + * This parameter is defined in milliseconds. + * NOTE: This is not to be confused with the rate that the GPS is + * polled at. It is acceptable to dynamically vary the rate of + * sampling the GPS for power-saving reasons; thus the rate of + * sampling may be faster or slower than this. + */ + int notification_responsivenes_ms; + + /** + * The time limit after which the UNCERTAIN transition + * should be triggered. This paramter is defined in milliseconds. + */ + int unknown_timer_ms; + + /** + * The sources to use for monitoring geofences. Its a BITWISE-OR + * of FLP_TECH_MASK flags. + */ + uint32_t sources_to_use; +} GeofenceOptions; + +/** Geofence struct */ +typedef struct { + int32_t geofence_id; + GeofenceData* data; + GeofenceOptions* options; +} Geofence; + +/** Extended interface for FLP_Geofencing support */ +typedef struct { + /** set to sizeof(FlpGeofencingInterface) */ + size_t size; + + /** + * Opens the geofence interface and provides the callback routines + * to the implemenation of this interface. Once called you should respond + * by calling the flp_capabilities_callback in FlpGeofenceCallbacks to + * specify the capabilities that your implementation supports. + */ + void (*init)( FlpGeofenceCallbacks* callbacks ); + + /** + * Add a list of geofences. + * Parameters: + * number_of_geofences - The number of geofences that needed to be added. + * geofences - Pointer to array of pointers to Geofence structure. + */ + void (*add_geofences) (int32_t number_of_geofences, Geofence** geofences); + + /** + * Pause monitoring a particular geofence. + * Parameters: + * geofence_id - The id for the geofence. + */ + void (*pause_geofence) (int32_t geofence_id); + + /** + * Resume monitoring a particular geofence. + * Parameters: + * geofence_id - The id for the geofence. + * monitor_transitions - Which transitions to monitor. Bitwise OR of + * FLP_GEOFENCE_TRANSITION_ENTERED, FLP_GEOFENCE_TRANSITION_EXITED and + * FLP_GEOFENCE_TRANSITION_UNCERTAIN. + * This supersedes the value associated provided in the + * add_geofence_area call. + */ + void (*resume_geofence) (int32_t geofence_id, int monitor_transitions); + + /** + * Modify a particular geofence option. + * Parameters: + * geofence_id - The id for the geofence. + * options - Various options associated with the geofence. See + * GeofenceOptions structure for details. + */ + void (*modify_geofence_option) (int32_t geofence_id, GeofenceOptions* options); + + /** + * Remove a list of geofences. After the function returns, no notifications + * should be sent. + * Parameter: + * number_of_geofences - The number of geofences that needed to be added. + * geofence_id - Pointer to array of geofence_ids to be removed. + */ + void (*remove_geofences) (int32_t number_of_geofences, int32_t* geofence_id); +} FlpGeofencingInterface; + +__END_DECLS + +#endif /* ANDROID_INCLUDE_HARDWARE_FLP_H */ + diff --git a/phonelibs/android_hardware_libhardware/include/hardware/gatekeeper.h b/phonelibs/android_hardware_libhardware/include/hardware/gatekeeper.h new file mode 100644 index 00000000000000..2bb2b08c39c1b1 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/gatekeeper.h @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_GATEKEEPER_H +#define ANDROID_HARDWARE_GATEKEEPER_H + +#include +#include +#include + +__BEGIN_DECLS + +#define GATEKEEPER_HARDWARE_MODULE_ID "gatekeeper" + +#define GATEKEEPER_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1) + +#define HARDWARE_GATEKEEPER "gatekeeper" + +struct gatekeeper_module { + /** + * Comon methods of the gatekeeper module. This *must* be the first member of + * gatekeeper_module as users of this structure will cast a hw_module_t to + * a gatekeeper_module pointer in the appropriate context. + */ + hw_module_t common; +}; + +struct gatekeeper_device { + /** + * Common methods of the gatekeeper device. As above, this must be the first + * member of keymaster_device. + */ + hw_device_t common; + + /** + * Enrolls desired_password, which should be derived from a user selected pin or password, + * with the authentication factor private key used only for enrolling authentication + * factor data. + * + * If there was already a password enrolled, it should be provided in + * current_password_handle, along with the current password in current_password + * that should validate against current_password_handle. + * + * Parameters: + * - dev: pointer to gatekeeper_device acquired via calls to gatekeeper_open + * - uid: the Android user identifier + * + * - current_password_handle: the currently enrolled password handle the user + * wants to replace. May be null if there's no currently enrolled password. + * - current_password_handle_length: the length in bytes of the buffer pointed + * at by current_password_handle. Must be 0 if current_password_handle is NULL. + * + * - current_password: the user's current password in plain text. If presented, + * it MUST verify against current_password_handle. + * - current_password_length: the size in bytes of the buffer pointed at by + * current_password. Must be 0 if the current_password is NULL. + * + * - desired_password: the new password the user wishes to enroll in plain-text. + * Cannot be NULL. + * - desired_password_length: the length in bytes of the buffer pointed at by + * desired_password. + * + * - enrolled_password_handle: on success, a buffer will be allocated with the + * new password handle referencing the password provided in desired_password. + * This buffer can be used on subsequent calls to enroll or verify. + * The caller is responsible for deallocating this buffer via a call to delete[] + * - enrolled_password_handle_length: pointer to the length in bytes of the buffer allocated + * by this function and pointed to by *enrolled_password_handle_length. + * + * Returns: + * - 0 on success + * - An error code < 0 on failure, or + * - A timeout value T > 0 if the call should not be re-attempted until T milliseconds + * have elapsed. + * + * On error, enrolled_password_handle will not be allocated. + */ + int (*enroll)(const struct gatekeeper_device *dev, uint32_t uid, + const uint8_t *current_password_handle, uint32_t current_password_handle_length, + const uint8_t *current_password, uint32_t current_password_length, + const uint8_t *desired_password, uint32_t desired_password_length, + uint8_t **enrolled_password_handle, uint32_t *enrolled_password_handle_length); + + /** + * Verifies provided_password matches enrolled_password_handle. + * + * Implementations of this module may retain the result of this call + * to attest to the recency of authentication. + * + * On success, writes the address of a verification token to auth_token, + * usable to attest password verification to other trusted services. Clients + * may pass NULL for this value. + * + * Parameters: + * - dev: pointer to gatekeeper_device acquired via calls to gatekeeper_open + * - uid: the Android user identifier + * + * - challenge: An optional challenge to authenticate against, or 0. Used when a separate + * authenticator requests password verification, or for transactional + * password authentication. + * + * - enrolled_password_handle: the currently enrolled password handle that the + * user wishes to verify against. + * - enrolled_password_handle_length: the length in bytes of the buffer pointed + * to by enrolled_password_handle + * + * - provided_password: the plaintext password to be verified against the + * enrolled_password_handle + * - provided_password_length: the length in bytes of the buffer pointed to by + * provided_password + * + * - auth_token: on success, a buffer containing the authentication token + * resulting from this verification is assigned to *auth_token. The caller + * is responsible for deallocating this memory via a call to delete[] + * - auth_token_length: on success, the length in bytes of the authentication + * token assigned to *auth_token will be assigned to *auth_token_length + * + * - request_reenroll: a request to the upper layers to re-enroll the verified + * password due to a version change. Not set if verification fails. + * + * Returns: + * - 0 on success + * - An error code < 0 on failure, or + * - A timeout value T > 0 if the call should not be re-attempted until T milliseconds + * have elapsed. + * On error, auth token will not be allocated + */ + int (*verify)(const struct gatekeeper_device *dev, uint32_t uid, uint64_t challenge, + const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length, + const uint8_t *provided_password, uint32_t provided_password_length, + uint8_t **auth_token, uint32_t *auth_token_length, bool *request_reenroll); + + /* + * Deletes the enrolled_password_handle associated wth the uid. Once deleted + * the user cannot be verified anymore. + * This function is optional and should be set to NULL if it is not implemented. + * + * Parameters + * - dev: pointer to gatekeeper_device acquired via calls to gatekeeper_open + * - uid: the Android user identifier + * + * Returns: + * - 0 on success + * - An error code < 0 on failure + */ + int (*delete_user)(const struct gatekeeper_device *dev, uint32_t uid); + + /* + * Deletes all the enrolled_password_handles for all uid's. Once called, + * no users will be enrolled on the device. + * This function is optional and should be set to NULL if it is not implemented. + * + * Parameters + * - dev: pointer to gatekeeper_device acquired via calls to gatekeeper_open + * + * Returns: + * - 0 on success + * - An error code < 0 on failure + */ + int (*delete_all_users)(const struct gatekeeper_device *dev); +}; + +typedef struct gatekeeper_device gatekeeper_device_t; + +static inline int gatekeeper_open(const struct hw_module_t *module, + gatekeeper_device_t **device) { + return module->methods->open(module, HARDWARE_GATEKEEPER, + (struct hw_device_t **) device); +} + +static inline int gatekeeper_close(gatekeeper_device_t *device) { + return device->common.close(&device->common); +} + +__END_DECLS + +#endif // ANDROID_HARDWARE_GATEKEEPER_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/gps.h b/phonelibs/android_hardware_libhardware/include/hardware/gps.h new file mode 100644 index 00000000000000..76b6cb7aed464b --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/gps.h @@ -0,0 +1,1871 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_HARDWARE_GPS_H +#define ANDROID_INCLUDE_HARDWARE_GPS_H + +#include +#include +#include +#include +#include +#include + +#include + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define GPS_HARDWARE_MODULE_ID "gps" + + +/** Milliseconds since January 1, 1970 */ +typedef int64_t GpsUtcTime; + +/** Maximum number of SVs for gps_sv_status_callback(). */ +#define GPS_MAX_SVS 32 + +/** Maximum number of Measurements in gps_measurement_callback(). */ +#define GPS_MAX_MEASUREMENT 32 + +/** Requested operational mode for GPS operation. */ +typedef uint32_t GpsPositionMode; +// IMPORTANT: Note that the following values must match +// constants in GpsLocationProvider.java. +/** Mode for running GPS standalone (no assistance). */ +#define GPS_POSITION_MODE_STANDALONE 0 +/** AGPS MS-Based mode. */ +#define GPS_POSITION_MODE_MS_BASED 1 +/** + * AGPS MS-Assisted mode. This mode is not maintained by the platform anymore. + * It is strongly recommended to use GPS_POSITION_MODE_MS_BASE instead. + */ +#define GPS_POSITION_MODE_MS_ASSISTED 2 + +/** Requested recurrence mode for GPS operation. */ +typedef uint32_t GpsPositionRecurrence; +// IMPORTANT: Note that the following values must match +// constants in GpsLocationProvider.java. +/** Receive GPS fixes on a recurring basis at a specified period. */ +#define GPS_POSITION_RECURRENCE_PERIODIC 0 +/** Request a single shot GPS fix. */ +#define GPS_POSITION_RECURRENCE_SINGLE 1 + +/** GPS status event values. */ +typedef uint16_t GpsStatusValue; +// IMPORTANT: Note that the following values must match +// constants in GpsLocationProvider.java. +/** GPS status unknown. */ +#define GPS_STATUS_NONE 0 +/** GPS has begun navigating. */ +#define GPS_STATUS_SESSION_BEGIN 1 +/** GPS has stopped navigating. */ +#define GPS_STATUS_SESSION_END 2 +/** GPS has powered on but is not navigating. */ +#define GPS_STATUS_ENGINE_ON 3 +/** GPS is powered off. */ +#define GPS_STATUS_ENGINE_OFF 4 + +/** Flags to indicate which values are valid in a GpsLocation. */ +typedef uint16_t GpsLocationFlags; +// IMPORTANT: Note that the following values must match +// constants in GpsLocationProvider.java. +/** GpsLocation has valid latitude and longitude. */ +#define GPS_LOCATION_HAS_LAT_LONG 0x0001 +/** GpsLocation has valid altitude. */ +#define GPS_LOCATION_HAS_ALTITUDE 0x0002 +/** GpsLocation has valid speed. */ +#define GPS_LOCATION_HAS_SPEED 0x0004 +/** GpsLocation has valid bearing. */ +#define GPS_LOCATION_HAS_BEARING 0x0008 +/** GpsLocation has valid accuracy. */ +#define GPS_LOCATION_HAS_ACCURACY 0x0010 + +/** Flags for the gps_set_capabilities callback. */ + +/** GPS HAL schedules fixes for GPS_POSITION_RECURRENCE_PERIODIC mode. + If this is not set, then the framework will use 1000ms for min_interval + and will start and call start() and stop() to schedule the GPS. + */ +#define GPS_CAPABILITY_SCHEDULING 0x0000001 +/** GPS supports MS-Based AGPS mode */ +#define GPS_CAPABILITY_MSB 0x0000002 +/** GPS supports MS-Assisted AGPS mode */ +#define GPS_CAPABILITY_MSA 0x0000004 +/** GPS supports single-shot fixes */ +#define GPS_CAPABILITY_SINGLE_SHOT 0x0000008 +/** GPS supports on demand time injection */ +#define GPS_CAPABILITY_ON_DEMAND_TIME 0x0000010 +/** GPS supports Geofencing */ +#define GPS_CAPABILITY_GEOFENCING 0x0000020 +/** GPS supports Measurements */ +#define GPS_CAPABILITY_MEASUREMENTS 0x0000040 +/** GPS supports Navigation Messages */ +#define GPS_CAPABILITY_NAV_MESSAGES 0x0000080 + +/** Flags used to specify which aiding data to delete + when calling delete_aiding_data(). */ +typedef uint16_t GpsAidingData; +// IMPORTANT: Note that the following values must match +// constants in GpsLocationProvider.java. +#define GPS_DELETE_EPHEMERIS 0x0001 +#define GPS_DELETE_ALMANAC 0x0002 +#define GPS_DELETE_POSITION 0x0004 +#define GPS_DELETE_TIME 0x0008 +#define GPS_DELETE_IONO 0x0010 +#define GPS_DELETE_UTC 0x0020 +#define GPS_DELETE_HEALTH 0x0040 +#define GPS_DELETE_SVDIR 0x0080 +#define GPS_DELETE_SVSTEER 0x0100 +#define GPS_DELETE_SADATA 0x0200 +#define GPS_DELETE_RTI 0x0400 +#define GPS_DELETE_CELLDB_INFO 0x8000 +#define GPS_DELETE_ALL 0xFFFF + +/** AGPS type */ +typedef uint16_t AGpsType; +#define AGPS_TYPE_SUPL 1 +#define AGPS_TYPE_C2K 2 + +typedef uint16_t AGpsSetIDType; +#define AGPS_SETID_TYPE_NONE 0 +#define AGPS_SETID_TYPE_IMSI 1 +#define AGPS_SETID_TYPE_MSISDN 2 + +typedef uint16_t ApnIpType; +#define APN_IP_INVALID 0 +#define APN_IP_IPV4 1 +#define APN_IP_IPV6 2 +#define APN_IP_IPV4V6 3 + +/** + * String length constants + */ +#define GPS_NI_SHORT_STRING_MAXLEN 256 +#define GPS_NI_LONG_STRING_MAXLEN 2048 + +/** + * GpsNiType constants + */ +typedef uint32_t GpsNiType; +#define GPS_NI_TYPE_VOICE 1 +#define GPS_NI_TYPE_UMTS_SUPL 2 +#define GPS_NI_TYPE_UMTS_CTRL_PLANE 3 + +/** + * GpsNiNotifyFlags constants + */ +typedef uint32_t GpsNiNotifyFlags; +/** NI requires notification */ +#define GPS_NI_NEED_NOTIFY 0x0001 +/** NI requires verification */ +#define GPS_NI_NEED_VERIFY 0x0002 +/** NI requires privacy override, no notification/minimal trace */ +#define GPS_NI_PRIVACY_OVERRIDE 0x0004 + +/** + * GPS NI responses, used to define the response in + * NI structures + */ +typedef int GpsUserResponseType; +#define GPS_NI_RESPONSE_ACCEPT 1 +#define GPS_NI_RESPONSE_DENY 2 +#define GPS_NI_RESPONSE_NORESP 3 + +/** + * NI data encoding scheme + */ +typedef int GpsNiEncodingType; +#define GPS_ENC_NONE 0 +#define GPS_ENC_SUPL_GSM_DEFAULT 1 +#define GPS_ENC_SUPL_UTF8 2 +#define GPS_ENC_SUPL_UCS2 3 +#define GPS_ENC_UNKNOWN -1 + +/** AGPS status event values. */ +typedef uint16_t AGpsStatusValue; +/** GPS requests data connection for AGPS. */ +#define GPS_REQUEST_AGPS_DATA_CONN 1 +/** GPS releases the AGPS data connection. */ +#define GPS_RELEASE_AGPS_DATA_CONN 2 +/** AGPS data connection initiated */ +#define GPS_AGPS_DATA_CONNECTED 3 +/** AGPS data connection completed */ +#define GPS_AGPS_DATA_CONN_DONE 4 +/** AGPS data connection failed */ +#define GPS_AGPS_DATA_CONN_FAILED 5 + +#define AGPS_REF_LOCATION_TYPE_GSM_CELLID 1 +#define AGPS_REF_LOCATION_TYPE_UMTS_CELLID 2 +#define AGPS_REG_LOCATION_TYPE_MAC 3 + +/** Network types for update_network_state "type" parameter */ +#define AGPS_RIL_NETWORK_TYPE_MOBILE 0 +#define AGPS_RIL_NETWORK_TYPE_WIFI 1 +#define AGPS_RIL_NETWORK_TYPE_MOBILE_MMS 2 +#define AGPS_RIL_NETWORK_TYPE_MOBILE_SUPL 3 +#define AGPS_RIL_NETWORK_TTYPE_MOBILE_DUN 4 +#define AGPS_RIL_NETWORK_TTYPE_MOBILE_HIPRI 5 +#define AGPS_RIL_NETWORK_TTYPE_WIMAX 6 + +/** + * Flags to indicate what fields in GpsClock are valid. + */ +typedef uint16_t GpsClockFlags; +/** A valid 'leap second' is stored in the data structure. */ +#define GPS_CLOCK_HAS_LEAP_SECOND (1<<0) +/** A valid 'time uncertainty' is stored in the data structure. */ +#define GPS_CLOCK_HAS_TIME_UNCERTAINTY (1<<1) +/** A valid 'full bias' is stored in the data structure. */ +#define GPS_CLOCK_HAS_FULL_BIAS (1<<2) +/** A valid 'bias' is stored in the data structure. */ +#define GPS_CLOCK_HAS_BIAS (1<<3) +/** A valid 'bias uncertainty' is stored in the data structure. */ +#define GPS_CLOCK_HAS_BIAS_UNCERTAINTY (1<<4) +/** A valid 'drift' is stored in the data structure. */ +#define GPS_CLOCK_HAS_DRIFT (1<<5) +/** A valid 'drift uncertainty' is stored in the data structure. */ +#define GPS_CLOCK_HAS_DRIFT_UNCERTAINTY (1<<6) + +/** + * Enumeration of the available values for the GPS Clock type. + */ +typedef uint8_t GpsClockType; +/** The type is not available ot it is unknown. */ +#define GPS_CLOCK_TYPE_UNKNOWN 0 +/** The source of the time value reported by GPS clock is the local hardware clock. */ +#define GPS_CLOCK_TYPE_LOCAL_HW_TIME 1 +/** + * The source of the time value reported by GPS clock is the GPS time derived from satellites + * (epoch = Jan 6, 1980) + */ +#define GPS_CLOCK_TYPE_GPS_TIME 2 + +/** + * Flags to indicate what fields in GpsMeasurement are valid. + */ +typedef uint32_t GpsMeasurementFlags; +/** A valid 'snr' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_SNR (1<<0) +/** A valid 'elevation' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_ELEVATION (1<<1) +/** A valid 'elevation uncertainty' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY (1<<2) +/** A valid 'azimuth' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_AZIMUTH (1<<3) +/** A valid 'azimuth uncertainty' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY (1<<4) +/** A valid 'pseudorange' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_PSEUDORANGE (1<<5) +/** A valid 'pseudorange uncertainty' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY (1<<6) +/** A valid 'code phase' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_CODE_PHASE (1<<7) +/** A valid 'code phase uncertainty' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY (1<<8) +/** A valid 'carrier frequency' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY (1<<9) +/** A valid 'carrier cycles' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_CARRIER_CYCLES (1<<10) +/** A valid 'carrier phase' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_CARRIER_PHASE (1<<11) +/** A valid 'carrier phase uncertainty' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY (1<<12) +/** A valid 'bit number' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_BIT_NUMBER (1<<13) +/** A valid 'time from last bit' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT (1<<14) +/** A valid 'doppler shift' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_DOPPLER_SHIFT (1<<15) +/** A valid 'doppler shift uncertainty' is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY (1<<16) +/** A valid 'used in fix' flag is stored in the data structure. */ +#define GPS_MEASUREMENT_HAS_USED_IN_FIX (1<<17) +/** The value of 'pseudorange rate' is uncorrected. */ +#define GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE (1<<18) + +/** + * Enumeration of the available values for the GPS Measurement's loss of lock. + */ +typedef uint8_t GpsLossOfLock; +/** The indicator is not available or it is unknown. */ +#define GPS_LOSS_OF_LOCK_UNKNOWN 0 +/** The measurement does not present any indication of loss of lock. */ +#define GPS_LOSS_OF_LOCK_OK 1 +/** Loss of lock between previous and current observation: cycle slip possible. */ +#define GPS_LOSS_OF_LOCK_CYCLE_SLIP 2 + +/** + * Enumeration of available values for the GPS Measurement's multipath indicator. + */ +typedef uint8_t GpsMultipathIndicator; +/** The indicator is not available or unknown. */ +#define GPS_MULTIPATH_INDICATOR_UNKNOWN 0 +/** The measurement has been indicated to use multipath. */ +#define GPS_MULTIPATH_INDICATOR_DETECTED 1 +/** The measurement has been indicated Not to use multipath. */ +#define GPS_MULTIPATH_INDICATOR_NOT_USED 2 + +/** + * Flags indicating the GPS measurement state. + * The expected behavior here is for GPS HAL to set all the flags that applies. For + * example, if the state for a satellite is only C/A code locked and bit synchronized, + * and there is still millisecond ambiguity, the state should be set as: + * GPS_MEASUREMENT_STATE_CODE_LOCK|GPS_MEASUREMENT_STATE_BIT_SYNC|GPS_MEASUREMENT_STATE_MSEC_AMBIGUOUS + * If GPS is still searching for a satellite, the corresponding state should be set to + * GPS_MEASUREMENT_STATE_UNKNOWN(0). + */ +typedef uint16_t GpsMeasurementState; +#define GPS_MEASUREMENT_STATE_UNKNOWN 0 +#define GPS_MEASUREMENT_STATE_CODE_LOCK (1<<0) +#define GPS_MEASUREMENT_STATE_BIT_SYNC (1<<1) +#define GPS_MEASUREMENT_STATE_SUBFRAME_SYNC (1<<2) +#define GPS_MEASUREMENT_STATE_TOW_DECODED (1<<3) +#define GPS_MEASUREMENT_STATE_MSEC_AMBIGUOUS (1<<4) + +/** + * Flags indicating the Accumulated Delta Range's states. + */ +typedef uint16_t GpsAccumulatedDeltaRangeState; +#define GPS_ADR_STATE_UNKNOWN 0 +#define GPS_ADR_STATE_VALID (1<<0) +#define GPS_ADR_STATE_RESET (1<<1) +#define GPS_ADR_STATE_CYCLE_SLIP (1<<2) + +/** + * Enumeration of available values to indicate the available GPS Navigation message types. + */ +typedef uint8_t GpsNavigationMessageType; +/** The message type is unknown. */ +#define GPS_NAVIGATION_MESSAGE_TYPE_UNKNOWN 0 +/** L1 C/A message contained in the structure. */ +#define GPS_NAVIGATION_MESSAGE_TYPE_L1CA 1 +/** L2-CNAV message contained in the structure. */ +#define GPS_NAVIGATION_MESSAGE_TYPE_L2CNAV 2 +/** L5-CNAV message contained in the structure. */ +#define GPS_NAVIGATION_MESSAGE_TYPE_L5CNAV 3 +/** CNAV-2 message contained in the structure. */ +#define GPS_NAVIGATION_MESSAGE_TYPE_CNAV2 4 + +/** + * Status of Navigation Message + * When a message is received properly without any parity error in its navigation words, the + * status should be set to NAV_MESSAGE_STATUS_PARITY_PASSED. But if a message is received + * with words that failed parity check, but GPS is able to correct those words, the status + * should be set to NAV_MESSAGE_STATUS_PARITY_REBUILT. + * No need to send any navigation message that contains words with parity error and cannot be + * corrected. + */ +typedef uint16_t NavigationMessageStatus; +#define NAV_MESSAGE_STATUS_UNKONW 0 +#define NAV_MESSAGE_STATUS_PARITY_PASSED (1<<0) +#define NAV_MESSAGE_STATUS_PARITY_REBUILT (1<<1) + +/** + * Name for the GPS XTRA interface. + */ +#define GPS_XTRA_INTERFACE "gps-xtra" + +/** + * Name for the GPS DEBUG interface. + */ +#define GPS_DEBUG_INTERFACE "gps-debug" + +/** + * Name for the AGPS interface. + */ +#define AGPS_INTERFACE "agps" + +/** + * Name of the Supl Certificate interface. + */ +#define SUPL_CERTIFICATE_INTERFACE "supl-certificate" + +/** + * Name for NI interface + */ +#define GPS_NI_INTERFACE "gps-ni" + +/** + * Name for the AGPS-RIL interface. + */ +#define AGPS_RIL_INTERFACE "agps_ril" + +/** + * Name for the GPS_Geofencing interface. + */ +#define GPS_GEOFENCING_INTERFACE "gps_geofencing" + +/** + * Name of the GPS Measurements interface. + */ +#define GPS_MEASUREMENT_INTERFACE "gps_measurement" + +/** + * Name of the GPS navigation message interface. + */ +#define GPS_NAVIGATION_MESSAGE_INTERFACE "gps_navigation_message" + +/** + * Name of the GNSS/GPS configuration interface. + */ +#define GNSS_CONFIGURATION_INTERFACE "gnss_configuration" + + +/** Represents a location. */ +typedef struct { + /** set to sizeof(GpsLocation) */ + size_t size; + /** Contains GpsLocationFlags bits. */ + uint16_t flags; + /** Represents latitude in degrees. */ + double latitude; + /** Represents longitude in degrees. */ + double longitude; + /** Represents altitude in meters above the WGS 84 reference + * ellipsoid. */ + double altitude; + /** Represents speed in meters per second. */ + float speed; + /** Represents heading in degrees. */ + float bearing; + /** Represents expected accuracy in meters. */ + float accuracy; + /** Timestamp for the location fix. */ + GpsUtcTime timestamp; +} GpsLocation; + +/** Represents the status. */ +typedef struct { + /** set to sizeof(GpsStatus) */ + size_t size; + GpsStatusValue status; +} GpsStatus; + +/** Represents SV information. */ +typedef struct { + /** set to sizeof(GpsSvInfo) */ + size_t size; + /** Pseudo-random number for the SV. */ + int prn; + /** Signal to noise ratio. */ + float snr; + /** Elevation of SV in degrees. */ + float elevation; + /** Azimuth of SV in degrees. */ + float azimuth; +} GpsSvInfo; + +/** Represents SV status. */ +typedef struct { + /** set to sizeof(GpsSvStatus) */ + size_t size; + + /** Number of SVs currently visible. */ + int num_svs; + + /** Contains an array of SV information. */ + GpsSvInfo sv_list[GPS_MAX_SVS]; + + /** Represents a bit mask indicating which SVs + * have ephemeris data. + */ + uint32_t ephemeris_mask; + + /** Represents a bit mask indicating which SVs + * have almanac data. + */ + uint32_t almanac_mask; + + /** + * Represents a bit mask indicating which SVs + * were used for computing the most recent position fix. + */ + uint32_t used_in_fix_mask; +} GpsSvStatus; + + +/* 2G and 3G */ +/* In 3G lac is discarded */ +typedef struct { + uint16_t type; + uint16_t mcc; + uint16_t mnc; + uint16_t lac; + uint32_t cid; +} AGpsRefLocationCellID; + +typedef struct { + uint8_t mac[6]; +} AGpsRefLocationMac; + +/** Represents ref locations */ +typedef struct { + uint16_t type; + union { + AGpsRefLocationCellID cellID; + AGpsRefLocationMac mac; + } u; +} AGpsRefLocation; + +/** Callback with location information. + * Can only be called from a thread created by create_thread_cb. + */ +typedef void (* gps_location_callback)(GpsLocation* location); + +/** Callback with status information. + * Can only be called from a thread created by create_thread_cb. + */ +typedef void (* gps_status_callback)(GpsStatus* status); + +/** + * Callback with SV status information. + * Can only be called from a thread created by create_thread_cb. + */ +typedef void (* gps_sv_status_callback)(GpsSvStatus* sv_info); + +/** Callback for reporting NMEA sentences. + * Can only be called from a thread created by create_thread_cb. + */ +typedef void (* gps_nmea_callback)(GpsUtcTime timestamp, const char* nmea, int length); + +/** Callback to inform framework of the GPS engine's capabilities. + * Capability parameter is a bit field of GPS_CAPABILITY_* flags. + */ +typedef void (* gps_set_capabilities)(uint32_t capabilities); + +/** Callback utility for acquiring the GPS wakelock. + * This can be used to prevent the CPU from suspending while handling GPS events. + */ +typedef void (* gps_acquire_wakelock)(); + +/** Callback utility for releasing the GPS wakelock. */ +typedef void (* gps_release_wakelock)(); + +/** Callback for requesting NTP time */ +typedef void (* gps_request_utc_time)(); + +/** Callback for creating a thread that can call into the Java framework code. + * This must be used to create any threads that report events up to the framework. + */ +typedef pthread_t (* gps_create_thread)(const char* name, void (*start)(void *), void* arg); + +/** GPS callback structure. */ +typedef struct { + /** set to sizeof(GpsCallbacks) */ + size_t size; + gps_location_callback location_cb; + gps_status_callback status_cb; + gps_sv_status_callback sv_status_cb; + gps_nmea_callback nmea_cb; + gps_set_capabilities set_capabilities_cb; + gps_acquire_wakelock acquire_wakelock_cb; + gps_release_wakelock release_wakelock_cb; + gps_create_thread create_thread_cb; + gps_request_utc_time request_utc_time_cb; +} GpsCallbacks; + + +/** Represents the standard GPS interface. */ +typedef struct { + /** set to sizeof(GpsInterface) */ + size_t size; + /** + * Opens the interface and provides the callback routines + * to the implementation of this interface. + */ + int (*init)( GpsCallbacks* callbacks ); + + /** Starts navigating. */ + int (*start)( void ); + + /** Stops navigating. */ + int (*stop)( void ); + + /** Closes the interface. */ + void (*cleanup)( void ); + + /** Injects the current time. */ + int (*inject_time)(GpsUtcTime time, int64_t timeReference, + int uncertainty); + + /** Injects current location from another location provider + * (typically cell ID). + * latitude and longitude are measured in degrees + * expected accuracy is measured in meters + */ + int (*inject_location)(double latitude, double longitude, float accuracy); + + /** + * Specifies that the next call to start will not use the + * information defined in the flags. GPS_DELETE_ALL is passed for + * a cold start. + */ + void (*delete_aiding_data)(GpsAidingData flags); + + /** + * min_interval represents the time between fixes in milliseconds. + * preferred_accuracy represents the requested fix accuracy in meters. + * preferred_time represents the requested time to first fix in milliseconds. + * + * 'mode' parameter should be one of GPS_POSITION_MODE_MS_BASE + * or GPS_POSITION_MODE_STANDALONE. + * It is allowed by the platform (and it is recommended) to fallback to + * GPS_POSITION_MODE_MS_BASE if GPS_POSITION_MODE_MS_ASSISTED is passed in, and + * GPS_POSITION_MODE_MS_BASED is supported. + */ + int (*set_position_mode)(GpsPositionMode mode, GpsPositionRecurrence recurrence, + uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time); + + /** Get a pointer to extension information. */ + const void* (*get_extension)(const char* name); +} GpsInterface; + +/** Callback to request the client to download XTRA data. + * The client should download XTRA data and inject it by calling inject_xtra_data(). + * Can only be called from a thread created by create_thread_cb. + */ +typedef void (* gps_xtra_download_request)(); + +/** Callback structure for the XTRA interface. */ +typedef struct { + gps_xtra_download_request download_request_cb; + gps_create_thread create_thread_cb; +} GpsXtraCallbacks; + +/** Extended interface for XTRA support. */ +typedef struct { + /** set to sizeof(GpsXtraInterface) */ + size_t size; + /** + * Opens the XTRA interface and provides the callback routines + * to the implementation of this interface. + */ + int (*init)( GpsXtraCallbacks* callbacks ); + /** Injects XTRA data into the GPS. */ + int (*inject_xtra_data)( char* data, int length ); +} GpsXtraInterface; + +/** Extended interface for DEBUG support. */ +typedef struct { + /** set to sizeof(GpsDebugInterface) */ + size_t size; + + /** + * This function should return any information that the native + * implementation wishes to include in a bugreport. + */ + size_t (*get_internal_state)(char* buffer, size_t bufferSize); +} GpsDebugInterface; + +#pragma pack(push,4) +// We need to keep the alignment of this data structure to 4-bytes, to ensure that in 64-bit +// environments the size of this legacy definition does not collide with _v2. Implementations should +// be using _v2 and _v3, so it's OK to pay the 'unaligned' penalty in 64-bit if an old +// implementation is still in use. + +/** Represents the status of AGPS. */ +typedef struct { + /** set to sizeof(AGpsStatus_v1) */ + size_t size; + + AGpsType type; + AGpsStatusValue status; +} AGpsStatus_v1; + +#pragma pack(pop) + +/** Represents the status of AGPS augmented with a IPv4 address field. */ +typedef struct { + /** set to sizeof(AGpsStatus_v2) */ + size_t size; + + AGpsType type; + AGpsStatusValue status; + uint32_t ipaddr; +} AGpsStatus_v2; + +/* Represents the status of AGPS augmented to support IPv4 and IPv6. */ +typedef struct { + /** set to sizeof(AGpsStatus_v3) */ + size_t size; + + AGpsType type; + AGpsStatusValue status; + + /** + * Must be set to a valid IPv4 address if the field 'addr' contains an IPv4 + * address, or set to INADDR_NONE otherwise. + */ + uint32_t ipaddr; + + /** + * Must contain the IPv4 (AF_INET) or IPv6 (AF_INET6) address to report. + * Any other value of addr.ss_family will be rejected. + * */ + struct sockaddr_storage addr; +} AGpsStatus_v3; + +typedef AGpsStatus_v3 AGpsStatus; + +/** Callback with AGPS status information. + * Can only be called from a thread created by create_thread_cb. + */ +typedef void (* agps_status_callback)(AGpsStatus* status); + +/** Callback structure for the AGPS interface. */ +typedef struct { + agps_status_callback status_cb; + gps_create_thread create_thread_cb; +} AGpsCallbacks; + + +/** Extended interface for AGPS support. */ +typedef struct { + /** set to sizeof(AGpsInterface_v1) */ + size_t size; + + /** + * Opens the AGPS interface and provides the callback routines + * to the implementation of this interface. + */ + void (*init)( AGpsCallbacks* callbacks ); + /** + * Notifies that a data connection is available and sets + * the name of the APN to be used for SUPL. + */ + int (*data_conn_open)( const char* apn ); + /** + * Notifies that the AGPS data connection has been closed. + */ + int (*data_conn_closed)(); + /** + * Notifies that a data connection is not available for AGPS. + */ + int (*data_conn_failed)(); + /** + * Sets the hostname and port for the AGPS server. + */ + int (*set_server)( AGpsType type, const char* hostname, int port ); +} AGpsInterface_v1; + +/** + * Extended interface for AGPS support, it is augmented to enable to pass + * extra APN data. + */ +typedef struct { + /** set to sizeof(AGpsInterface_v2) */ + size_t size; + + /** + * Opens the AGPS interface and provides the callback routines to the + * implementation of this interface. + */ + void (*init)(AGpsCallbacks* callbacks); + /** + * Deprecated. + * If the HAL supports AGpsInterface_v2 this API will not be used, see + * data_conn_open_with_apn_ip_type for more information. + */ + int (*data_conn_open)(const char* apn); + /** + * Notifies that the AGPS data connection has been closed. + */ + int (*data_conn_closed)(); + /** + * Notifies that a data connection is not available for AGPS. + */ + int (*data_conn_failed)(); + /** + * Sets the hostname and port for the AGPS server. + */ + int (*set_server)(AGpsType type, const char* hostname, int port); + + /** + * Notifies that a data connection is available and sets the name of the + * APN, and its IP type, to be used for SUPL connections. + */ + int (*data_conn_open_with_apn_ip_type)( + const char* apn, + ApnIpType apnIpType); +} AGpsInterface_v2; + +typedef AGpsInterface_v2 AGpsInterface; + +/** Error codes associated with certificate operations */ +#define AGPS_CERTIFICATE_OPERATION_SUCCESS 0 +#define AGPS_CERTIFICATE_ERROR_GENERIC -100 +#define AGPS_CERTIFICATE_ERROR_TOO_MANY_CERTIFICATES -101 + +/** A data structure that represents an X.509 certificate using DER encoding */ +typedef struct { + size_t length; + u_char* data; +} DerEncodedCertificate; + +/** + * A type definition for SHA1 Fingerprints used to identify X.509 Certificates + * The Fingerprint is a digest of the DER Certificate that uniquely identifies it. + */ +typedef struct { + u_char data[20]; +} Sha1CertificateFingerprint; + +/** AGPS Interface to handle SUPL certificate operations */ +typedef struct { + /** set to sizeof(SuplCertificateInterface) */ + size_t size; + + /** + * Installs a set of Certificates used for SUPL connections to the AGPS server. + * If needed the HAL should find out internally any certificates that need to be removed to + * accommodate the certificates to install. + * The certificates installed represent a full set of valid certificates needed to connect to + * AGPS SUPL servers. + * The list of certificates is required, and all must be available at the same time, when trying + * to establish a connection with the AGPS Server. + * + * Parameters: + * certificates - A pointer to an array of DER encoded certificates that are need to be + * installed in the HAL. + * length - The number of certificates to install. + * Returns: + * AGPS_CERTIFICATE_OPERATION_SUCCESS if the operation is completed successfully + * AGPS_CERTIFICATE_ERROR_TOO_MANY_CERTIFICATES if the HAL cannot store the number of + * certificates attempted to be installed, the state of the certificates stored should + * remain the same as before on this error case. + * + * IMPORTANT: + * If needed the HAL should find out internally the set of certificates that need to be + * removed to accommodate the certificates to install. + */ + int (*install_certificates) ( const DerEncodedCertificate* certificates, size_t length ); + + /** + * Notifies the HAL that a list of certificates used for SUPL connections are revoked. It is + * expected that the given set of certificates is removed from the internal store of the HAL. + * + * Parameters: + * fingerprints - A pointer to an array of SHA1 Fingerprints to identify the set of + * certificates to revoke. + * length - The number of fingerprints provided. + * Returns: + * AGPS_CERTIFICATE_OPERATION_SUCCESS if the operation is completed successfully. + * + * IMPORTANT: + * If any of the certificates provided (through its fingerprint) is not known by the HAL, + * it should be ignored and continue revoking/deleting the rest of them. + */ + int (*revoke_certificates) ( const Sha1CertificateFingerprint* fingerprints, size_t length ); +} SuplCertificateInterface; + +/** Represents an NI request */ +typedef struct { + /** set to sizeof(GpsNiNotification) */ + size_t size; + + /** + * An ID generated by HAL to associate NI notifications and UI + * responses + */ + int notification_id; + + /** + * An NI type used to distinguish different categories of NI + * events, such as GPS_NI_TYPE_VOICE, GPS_NI_TYPE_UMTS_SUPL, ... + */ + GpsNiType ni_type; + + /** + * Notification/verification options, combinations of GpsNiNotifyFlags constants + */ + GpsNiNotifyFlags notify_flags; + + /** + * Timeout period to wait for user response. + * Set to 0 for no time out limit. + */ + int timeout; + + /** + * Default response when time out. + */ + GpsUserResponseType default_response; + + /** + * Requestor ID + */ + char requestor_id[GPS_NI_SHORT_STRING_MAXLEN]; + + /** + * Notification message. It can also be used to store client_id in some cases + */ + char text[GPS_NI_LONG_STRING_MAXLEN]; + + /** + * Client name decoding scheme + */ + GpsNiEncodingType requestor_id_encoding; + + /** + * Client name decoding scheme + */ + GpsNiEncodingType text_encoding; + + /** + * A pointer to extra data. Format: + * key_1 = value_1 + * key_2 = value_2 + */ + char extras[GPS_NI_LONG_STRING_MAXLEN]; + +} GpsNiNotification; + +/** Callback with NI notification. + * Can only be called from a thread created by create_thread_cb. + */ +typedef void (*gps_ni_notify_callback)(GpsNiNotification *notification); + +/** GPS NI callback structure. */ +typedef struct +{ + /** + * Sends the notification request from HAL to GPSLocationProvider. + */ + gps_ni_notify_callback notify_cb; + gps_create_thread create_thread_cb; +} GpsNiCallbacks; + +/** + * Extended interface for Network-initiated (NI) support. + */ +typedef struct +{ + /** set to sizeof(GpsNiInterface) */ + size_t size; + + /** Registers the callbacks for HAL to use. */ + void (*init) (GpsNiCallbacks *callbacks); + + /** Sends a response to HAL. */ + void (*respond) (int notif_id, GpsUserResponseType user_response); +} GpsNiInterface; + +struct gps_device_t { + struct hw_device_t common; + + /** + * Set the provided lights to the provided values. + * + * Returns: 0 on succes, error code on failure. + */ + const GpsInterface* (*get_gps_interface)(struct gps_device_t* dev); +}; + +#define AGPS_RIL_REQUEST_SETID_IMSI (1<<0L) +#define AGPS_RIL_REQUEST_SETID_MSISDN (1<<1L) + +#define AGPS_RIL_REQUEST_REFLOC_CELLID (1<<0L) +#define AGPS_RIL_REQUEST_REFLOC_MAC (1<<1L) + +typedef void (*agps_ril_request_set_id)(uint32_t flags); +typedef void (*agps_ril_request_ref_loc)(uint32_t flags); + +typedef struct { + agps_ril_request_set_id request_setid; + agps_ril_request_ref_loc request_refloc; + gps_create_thread create_thread_cb; +} AGpsRilCallbacks; + +/** Extended interface for AGPS_RIL support. */ +typedef struct { + /** set to sizeof(AGpsRilInterface) */ + size_t size; + /** + * Opens the AGPS interface and provides the callback routines + * to the implementation of this interface. + */ + void (*init)( AGpsRilCallbacks* callbacks ); + + /** + * Sets the reference location. + */ + void (*set_ref_location) (const AGpsRefLocation *agps_reflocation, size_t sz_struct); + /** + * Sets the set ID. + */ + void (*set_set_id) (AGpsSetIDType type, const char* setid); + + /** + * Send network initiated message. + */ + void (*ni_message) (uint8_t *msg, size_t len); + + /** + * Notify GPS of network status changes. + * These parameters match values in the android.net.NetworkInfo class. + */ + void (*update_network_state) (int connected, int type, int roaming, const char* extra_info); + + /** + * Notify GPS of network status changes. + * These parameters match values in the android.net.NetworkInfo class. + */ + void (*update_network_availability) (int avaiable, const char* apn); +} AGpsRilInterface; + +/** + * GPS Geofence. + * There are 3 states associated with a Geofence: Inside, Outside, Unknown. + * There are 3 transitions: ENTERED, EXITED, UNCERTAIN. + * + * An example state diagram with confidence level: 95% and Unknown time limit + * set as 30 secs is shown below. (confidence level and Unknown time limit are + * explained latter) + * ____________________________ + * | Unknown (30 secs) | + * """""""""""""""""""""""""""" + * ^ | | ^ + * UNCERTAIN| |ENTERED EXITED| |UNCERTAIN + * | v v | + * ________ EXITED _________ + * | Inside | -----------> | Outside | + * | | <----------- | | + * """""""" ENTERED """"""""" + * + * Inside state: We are 95% confident that the user is inside the geofence. + * Outside state: We are 95% confident that the user is outside the geofence + * Unknown state: Rest of the time. + * + * The Unknown state is better explained with an example: + * + * __________ + * | c| + * | ___ | _______ + * | |a| | | b | + * | """ | """"""" + * | | + * """""""""" + * In the diagram above, "a" and "b" are 2 geofences and "c" is the accuracy + * circle reported by the GPS subsystem. Now with regard to "b", the system is + * confident that the user is outside. But with regard to "a" is not confident + * whether it is inside or outside the geofence. If the accuracy remains the + * same for a sufficient period of time, the UNCERTAIN transition would be + * triggered with the state set to Unknown. If the accuracy improves later, an + * appropriate transition should be triggered. This "sufficient period of time" + * is defined by the parameter in the add_geofence_area API. + * In other words, Unknown state can be interpreted as a state in which the + * GPS subsystem isn't confident enough that the user is either inside or + * outside the Geofence. It moves to Unknown state only after the expiry of the + * timeout. + * + * The geofence callback needs to be triggered for the ENTERED and EXITED + * transitions, when the GPS system is confident that the user has entered + * (Inside state) or exited (Outside state) the Geofence. An implementation + * which uses a value of 95% as the confidence is recommended. The callback + * should be triggered only for the transitions requested by the + * add_geofence_area call. + * + * Even though the diagram and explanation talks about states and transitions, + * the callee is only interested in the transistions. The states are mentioned + * here for illustrative purposes. + * + * Startup Scenario: When the device boots up, if an application adds geofences, + * and then we get an accurate GPS location fix, it needs to trigger the + * appropriate (ENTERED or EXITED) transition for every Geofence it knows about. + * By default, all the Geofences will be in the Unknown state. + * + * When the GPS system is unavailable, gps_geofence_status_callback should be + * called to inform the upper layers of the same. Similarly, when it becomes + * available the callback should be called. This is a global state while the + * UNKNOWN transition described above is per geofence. + * + * An important aspect to note is that users of this API (framework), will use + * other subsystems like wifi, sensors, cell to handle Unknown case and + * hopefully provide a definitive state transition to the third party + * application. GPS Geofence will just be a signal indicating what the GPS + * subsystem knows about the Geofence. + * + */ +#define GPS_GEOFENCE_ENTERED (1<<0L) +#define GPS_GEOFENCE_EXITED (1<<1L) +#define GPS_GEOFENCE_UNCERTAIN (1<<2L) + +#define GPS_GEOFENCE_UNAVAILABLE (1<<0L) +#define GPS_GEOFENCE_AVAILABLE (1<<1L) + +#define GPS_GEOFENCE_OPERATION_SUCCESS 0 +#define GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES -100 +#define GPS_GEOFENCE_ERROR_ID_EXISTS -101 +#define GPS_GEOFENCE_ERROR_ID_UNKNOWN -102 +#define GPS_GEOFENCE_ERROR_INVALID_TRANSITION -103 +#define GPS_GEOFENCE_ERROR_GENERIC -149 + +/** + * The callback associated with the geofence. + * Parameters: + * geofence_id - The id associated with the add_geofence_area. + * location - The current GPS location. + * transition - Can be one of GPS_GEOFENCE_ENTERED, GPS_GEOFENCE_EXITED, + * GPS_GEOFENCE_UNCERTAIN. + * timestamp - Timestamp when the transition was detected. + * + * The callback should only be called when the caller is interested in that + * particular transition. For instance, if the caller is interested only in + * ENTERED transition, then the callback should NOT be called with the EXITED + * transition. + * + * IMPORTANT: If a transition is triggered resulting in this callback, the GPS + * subsystem will wake up the application processor, if its in suspend state. + */ +typedef void (*gps_geofence_transition_callback) (int32_t geofence_id, GpsLocation* location, + int32_t transition, GpsUtcTime timestamp); + +/** + * The callback associated with the availability of the GPS system for geofencing + * monitoring. If the GPS system determines that it cannot monitor geofences + * because of lack of reliability or unavailability of the GPS signals, it will + * call this callback with GPS_GEOFENCE_UNAVAILABLE parameter. + * + * Parameters: + * status - GPS_GEOFENCE_UNAVAILABLE or GPS_GEOFENCE_AVAILABLE. + * last_location - Last known location. + */ +typedef void (*gps_geofence_status_callback) (int32_t status, GpsLocation* last_location); + +/** + * The callback associated with the add_geofence call. + * + * Parameter: + * geofence_id - Id of the geofence. + * status - GPS_GEOFENCE_OPERATION_SUCCESS + * GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES - geofence limit has been reached. + * GPS_GEOFENCE_ERROR_ID_EXISTS - geofence with id already exists + * GPS_GEOFENCE_ERROR_INVALID_TRANSITION - the monitorTransition contains an + * invalid transition + * GPS_GEOFENCE_ERROR_GENERIC - for other errors. + */ +typedef void (*gps_geofence_add_callback) (int32_t geofence_id, int32_t status); + +/** + * The callback associated with the remove_geofence call. + * + * Parameter: + * geofence_id - Id of the geofence. + * status - GPS_GEOFENCE_OPERATION_SUCCESS + * GPS_GEOFENCE_ERROR_ID_UNKNOWN - for invalid id + * GPS_GEOFENCE_ERROR_GENERIC for others. + */ +typedef void (*gps_geofence_remove_callback) (int32_t geofence_id, int32_t status); + + +/** + * The callback associated with the pause_geofence call. + * + * Parameter: + * geofence_id - Id of the geofence. + * status - GPS_GEOFENCE_OPERATION_SUCCESS + * GPS_GEOFENCE_ERROR_ID_UNKNOWN - for invalid id + * GPS_GEOFENCE_ERROR_INVALID_TRANSITION - + * when monitor_transitions is invalid + * GPS_GEOFENCE_ERROR_GENERIC for others. + */ +typedef void (*gps_geofence_pause_callback) (int32_t geofence_id, int32_t status); + +/** + * The callback associated with the resume_geofence call. + * + * Parameter: + * geofence_id - Id of the geofence. + * status - GPS_GEOFENCE_OPERATION_SUCCESS + * GPS_GEOFENCE_ERROR_ID_UNKNOWN - for invalid id + * GPS_GEOFENCE_ERROR_GENERIC for others. + */ +typedef void (*gps_geofence_resume_callback) (int32_t geofence_id, int32_t status); + +typedef struct { + gps_geofence_transition_callback geofence_transition_callback; + gps_geofence_status_callback geofence_status_callback; + gps_geofence_add_callback geofence_add_callback; + gps_geofence_remove_callback geofence_remove_callback; + gps_geofence_pause_callback geofence_pause_callback; + gps_geofence_resume_callback geofence_resume_callback; + gps_create_thread create_thread_cb; +} GpsGeofenceCallbacks; + +/** Extended interface for GPS_Geofencing support */ +typedef struct { + /** set to sizeof(GpsGeofencingInterface) */ + size_t size; + + /** + * Opens the geofence interface and provides the callback routines + * to the implementation of this interface. + */ + void (*init)( GpsGeofenceCallbacks* callbacks ); + + /** + * Add a geofence area. This api currently supports circular geofences. + * Parameters: + * geofence_id - The id for the geofence. If a geofence with this id + * already exists, an error value (GPS_GEOFENCE_ERROR_ID_EXISTS) + * should be returned. + * latitude, longtitude, radius_meters - The lat, long and radius + * (in meters) for the geofence + * last_transition - The current state of the geofence. For example, if + * the system already knows that the user is inside the geofence, + * this will be set to GPS_GEOFENCE_ENTERED. In most cases, it + * will be GPS_GEOFENCE_UNCERTAIN. + * monitor_transition - Which transitions to monitor. Bitwise OR of + * GPS_GEOFENCE_ENTERED, GPS_GEOFENCE_EXITED and + * GPS_GEOFENCE_UNCERTAIN. + * notification_responsiveness_ms - Defines the best-effort description + * of how soon should the callback be called when the transition + * associated with the Geofence is triggered. For instance, if set + * to 1000 millseconds with GPS_GEOFENCE_ENTERED, the callback + * should be called 1000 milliseconds within entering the geofence. + * This parameter is defined in milliseconds. + * NOTE: This is not to be confused with the rate that the GPS is + * polled at. It is acceptable to dynamically vary the rate of + * sampling the GPS for power-saving reasons; thus the rate of + * sampling may be faster or slower than this. + * unknown_timer_ms - The time limit after which the UNCERTAIN transition + * should be triggered. This parameter is defined in milliseconds. + * See above for a detailed explanation. + */ + void (*add_geofence_area) (int32_t geofence_id, double latitude, double longitude, + double radius_meters, int last_transition, int monitor_transitions, + int notification_responsiveness_ms, int unknown_timer_ms); + + /** + * Pause monitoring a particular geofence. + * Parameters: + * geofence_id - The id for the geofence. + */ + void (*pause_geofence) (int32_t geofence_id); + + /** + * Resume monitoring a particular geofence. + * Parameters: + * geofence_id - The id for the geofence. + * monitor_transitions - Which transitions to monitor. Bitwise OR of + * GPS_GEOFENCE_ENTERED, GPS_GEOFENCE_EXITED and + * GPS_GEOFENCE_UNCERTAIN. + * This supersedes the value associated provided in the + * add_geofence_area call. + */ + void (*resume_geofence) (int32_t geofence_id, int monitor_transitions); + + /** + * Remove a geofence area. After the function returns, no notifications + * should be sent. + * Parameter: + * geofence_id - The id for the geofence. + */ + void (*remove_geofence_area) (int32_t geofence_id); +} GpsGeofencingInterface; + + +/** + * Represents an estimate of the GPS clock time. + */ +typedef struct { + /** set to sizeof(GpsClock) */ + size_t size; + + /** A set of flags indicating the validity of the fields in this data structure. */ + GpsClockFlags flags; + + /** + * Leap second data. + * The sign of the value is defined by the following equation: + * utc_time_ns = time_ns + (full_bias_ns + bias_ns) - leap_second * 1,000,000,000 + * + * If the data is available 'flags' must contain GPS_CLOCK_HAS_LEAP_SECOND. + */ + int16_t leap_second; + + /** + * Indicates the type of time reported by the 'time_ns' field. + * This is a Mandatory field. + */ + GpsClockType type; + + /** + * The GPS receiver internal clock value. This can be either the local hardware clock value + * (GPS_CLOCK_TYPE_LOCAL_HW_TIME), or the current GPS time derived inside GPS receiver + * (GPS_CLOCK_TYPE_GPS_TIME). The field 'type' defines the time reported. + * + * For local hardware clock, this value is expected to be monotonically increasing during + * the reporting session. The real GPS time can be derived by compensating the 'full bias' + * (when it is available) from this value. + * + * For GPS time, this value is expected to be the best estimation of current GPS time that GPS + * receiver can achieve. Set the 'time uncertainty' appropriately when GPS time is specified. + * + * Sub-nanosecond accuracy can be provided by means of the 'bias' field. + * The value contains the 'time uncertainty' in it. + * + * This is a Mandatory field. + */ + int64_t time_ns; + + /** + * 1-Sigma uncertainty associated with the clock's time in nanoseconds. + * The uncertainty is represented as an absolute (single sided) value. + * + * This value should be set if GPS_CLOCK_TYPE_GPS_TIME is set. + * If the data is available 'flags' must contain GPS_CLOCK_HAS_TIME_UNCERTAINTY. + */ + double time_uncertainty_ns; + + /** + * The difference between hardware clock ('time' field) inside GPS receiver and the true GPS + * time since 0000Z, January 6, 1980, in nanoseconds. + * This value is used if and only if GPS_CLOCK_TYPE_LOCAL_HW_TIME is set, and GPS receiver + * has solved the clock for GPS time. + * The caller is responsible for using the 'bias uncertainty' field for quality check. + * + * The sign of the value is defined by the following equation: + * true time (GPS time) = time_ns + (full_bias_ns + bias_ns) + * + * This value contains the 'bias uncertainty' in it. + * If the data is available 'flags' must contain GPS_CLOCK_HAS_FULL_BIAS. + + */ + int64_t full_bias_ns; + + /** + * Sub-nanosecond bias. + * The value contains the 'bias uncertainty' in it. + * + * If the data is available 'flags' must contain GPS_CLOCK_HAS_BIAS. + */ + double bias_ns; + + /** + * 1-Sigma uncertainty associated with the clock's bias in nanoseconds. + * The uncertainty is represented as an absolute (single sided) value. + * + * If the data is available 'flags' must contain GPS_CLOCK_HAS_BIAS_UNCERTAINTY. + */ + double bias_uncertainty_ns; + + /** + * The clock's drift in nanoseconds (per second). + * A positive value means that the frequency is higher than the nominal frequency. + * + * The value contains the 'drift uncertainty' in it. + * If the data is available 'flags' must contain GPS_CLOCK_HAS_DRIFT. + * + * If GpsMeasurement's 'flags' field contains GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE, + * it is encouraged that this field is also provided. + */ + double drift_nsps; + + /** + * 1-Sigma uncertainty associated with the clock's drift in nanoseconds (per second). + * The uncertainty is represented as an absolute (single sided) value. + * + * If the data is available 'flags' must contain GPS_CLOCK_HAS_DRIFT_UNCERTAINTY. + */ + double drift_uncertainty_nsps; +} GpsClock; + +/** + * Represents a GPS Measurement, it contains raw and computed information. + */ +typedef struct { + /** set to sizeof(GpsMeasurement) */ + size_t size; + + /** A set of flags indicating the validity of the fields in this data structure. */ + GpsMeasurementFlags flags; + + /** + * Pseudo-random number in the range of [1, 32] + * This is a Mandatory value. + */ + int8_t prn; + + /** + * Time offset at which the measurement was taken in nanoseconds. + * The reference receiver's time is specified by GpsData::clock::time_ns and should be + * interpreted in the same way as indicated by GpsClock::type. + * + * The sign of time_offset_ns is given by the following equation: + * measurement time = GpsClock::time_ns + time_offset_ns + * + * It provides an individual time-stamp for the measurement, and allows sub-nanosecond accuracy. + * This is a Mandatory value. + */ + double time_offset_ns; + + /** + * Per satellite sync state. It represents the current sync state for the associated satellite. + * Based on the sync state, the 'received GPS tow' field should be interpreted accordingly. + * + * This is a Mandatory value. + */ + GpsMeasurementState state; + + /** + * Received GPS Time-of-Week at the measurement time, in nanoseconds. + * The value is relative to the beginning of the current GPS week. + * + * Given the highest sync state that can be achieved, per each satellite, valid range for + * this field can be: + * Searching : [ 0 ] : GPS_MEASUREMENT_STATE_UNKNOWN + * C/A code lock : [ 0 1ms ] : GPS_MEASUREMENT_STATE_CODE_LOCK is set + * Bit sync : [ 0 20ms ] : GPS_MEASUREMENT_STATE_BIT_SYNC is set + * Subframe sync : [ 0 6s ] : GPS_MEASUREMENT_STATE_SUBFRAME_SYNC is set + * TOW decoded : [ 0 1week ] : GPS_MEASUREMENT_STATE_TOW_DECODED is set + * + * However, if there is any ambiguity in integer millisecond, + * GPS_MEASUREMENT_STATE_MSEC_AMBIGUOUS should be set accordingly, in the 'state' field. + * + * This value must be populated if 'state' != GPS_MEASUREMENT_STATE_UNKNOWN. + */ + int64_t received_gps_tow_ns; + + /** + * 1-Sigma uncertainty of the Received GPS Time-of-Week in nanoseconds. + * + * This value must be populated if 'state' != GPS_MEASUREMENT_STATE_UNKNOWN. + */ + int64_t received_gps_tow_uncertainty_ns; + + /** + * Carrier-to-noise density in dB-Hz, in the range [0, 63]. + * It contains the measured C/N0 value for the signal at the antenna input. + * + * This is a Mandatory value. + */ + double c_n0_dbhz; + + /** + * Pseudorange rate at the timestamp in m/s. + * The correction of a given Pseudorange Rate value includes corrections for receiver and + * satellite clock frequency errors. + * + * If GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE is set in 'flags' field, this field must + * be populated with the 'uncorrected' reading. + * If GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE is not set in 'flags' field, this field + * must be populated with the 'corrected' reading. This is the default behavior. + * + * It is encouraged to provide the 'uncorrected' 'pseudorange rate', and provide GpsClock's + * 'drift' field as well. + * + * The value includes the 'pseudorange rate uncertainty' in it. + * A positive 'uncorrected' value indicates that the SV is moving away from the receiver. + * + * The sign of the 'uncorrected' 'pseudorange rate' and its relation to the sign of 'doppler + * shift' is given by the equation: + * pseudorange rate = -k * doppler shift (where k is a constant) + * + * This is a Mandatory value. + */ + double pseudorange_rate_mps; + + /** + * 1-Sigma uncertainty of the pseudurange rate in m/s. + * The uncertainty is represented as an absolute (single sided) value. + * + * This is a Mandatory value. + */ + double pseudorange_rate_uncertainty_mps; + + /** + * Accumulated delta range's state. It indicates whether ADR is reset or there is a cycle slip + * (indicating loss of lock). + * + * This is a Mandatory value. + */ + GpsAccumulatedDeltaRangeState accumulated_delta_range_state; + + /** + * Accumulated delta range since the last channel reset in meters. + * A positive value indicates that the SV is moving away from the receiver. + * + * The sign of the 'accumulated delta range' and its relation to the sign of 'carrier phase' + * is given by the equation: + * accumulated delta range = -k * carrier phase (where k is a constant) + * + * This value must be populated if 'accumulated delta range state' != GPS_ADR_STATE_UNKNOWN. + * However, it is expected that the data is only accurate when: + * 'accumulated delta range state' == GPS_ADR_STATE_VALID. + */ + double accumulated_delta_range_m; + + /** + * 1-Sigma uncertainty of the accumulated delta range in meters. + * This value must be populated if 'accumulated delta range state' != GPS_ADR_STATE_UNKNOWN. + */ + double accumulated_delta_range_uncertainty_m; + + /** + * Best derived Pseudorange by the chip-set, in meters. + * The value contains the 'pseudorange uncertainty' in it. + * + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_PSEUDORANGE. + */ + double pseudorange_m; + + /** + * 1-Sigma uncertainty of the pseudorange in meters. + * The value contains the 'pseudorange' and 'clock' uncertainty in it. + * The uncertainty is represented as an absolute (single sided) value. + * + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY. + */ + double pseudorange_uncertainty_m; + + /** + * A fraction of the current C/A code cycle, in the range [0.0, 1023.0] + * This value contains the time (in Chip units) since the last C/A code cycle (GPS Msec epoch). + * + * The reference frequency is given by the field 'carrier_frequency_hz'. + * The value contains the 'code-phase uncertainty' in it. + * + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CODE_PHASE. + */ + double code_phase_chips; + + /** + * 1-Sigma uncertainty of the code-phase, in a fraction of chips. + * The uncertainty is represented as an absolute (single sided) value. + * + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY. + */ + double code_phase_uncertainty_chips; + + /** + * Carrier frequency at which codes and messages are modulated, it can be L1 or L2. + * If the field is not set, the carrier frequency is assumed to be L1. + * + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY. + */ + float carrier_frequency_hz; + + /** + * The number of full carrier cycles between the satellite and the receiver. + * The reference frequency is given by the field 'carrier_frequency_hz'. + * + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CARRIER_CYCLES. + */ + int64_t carrier_cycles; + + /** + * The RF phase detected by the receiver, in the range [0.0, 1.0]. + * This is usually the fractional part of the complete carrier phase measurement. + * + * The reference frequency is given by the field 'carrier_frequency_hz'. + * The value contains the 'carrier-phase uncertainty' in it. + * + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CARRIER_PHASE. + */ + double carrier_phase; + + /** + * 1-Sigma uncertainty of the carrier-phase. + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY. + */ + double carrier_phase_uncertainty; + + /** + * An enumeration that indicates the 'loss of lock' state of the event. + */ + GpsLossOfLock loss_of_lock; + + /** + * The number of GPS bits transmitted since Sat-Sun midnight (GPS week). + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_BIT_NUMBER. + */ + int32_t bit_number; + + /** + * The elapsed time since the last received bit in milliseconds, in the range [0, 20] + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT. + */ + int16_t time_from_last_bit_ms; + + /** + * Doppler shift in Hz. + * A positive value indicates that the SV is moving toward the receiver. + * + * The reference frequency is given by the field 'carrier_frequency_hz'. + * The value contains the 'doppler shift uncertainty' in it. + * + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_DOPPLER_SHIFT. + */ + double doppler_shift_hz; + + /** + * 1-Sigma uncertainty of the doppler shift in Hz. + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY. + */ + double doppler_shift_uncertainty_hz; + + /** + * An enumeration that indicates the 'multipath' state of the event. + */ + GpsMultipathIndicator multipath_indicator; + + /** + * Signal-to-noise ratio in dB. + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_SNR. + */ + double snr_db; + + /** + * Elevation in degrees, the valid range is [-90, 90]. + * The value contains the 'elevation uncertainty' in it. + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_ELEVATION. + */ + double elevation_deg; + + /** + * 1-Sigma uncertainty of the elevation in degrees, the valid range is [0, 90]. + * The uncertainty is represented as the absolute (single sided) value. + * + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY. + */ + double elevation_uncertainty_deg; + + /** + * Azimuth in degrees, in the range [0, 360). + * The value contains the 'azimuth uncertainty' in it. + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_AZIMUTH. + * */ + double azimuth_deg; + + /** + * 1-Sigma uncertainty of the azimuth in degrees, the valid range is [0, 180]. + * The uncertainty is represented as an absolute (single sided) value. + * + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY. + */ + double azimuth_uncertainty_deg; + + /** + * Whether the GPS represented by the measurement was used for computing the most recent fix. + * If the data is available, 'flags' must contain GPS_MEASUREMENT_HAS_USED_IN_FIX. + */ + bool used_in_fix; +} GpsMeasurement; + +/** Represents a reading of GPS measurements. */ +typedef struct { + /** set to sizeof(GpsData) */ + size_t size; + + /** Number of measurements. */ + size_t measurement_count; + + /** The array of measurements. */ + GpsMeasurement measurements[GPS_MAX_MEASUREMENT]; + + /** The GPS clock time reading. */ + GpsClock clock; +} GpsData; + +/** + * The callback for to report measurements from the HAL. + * + * Parameters: + * data - A data structure containing the measurements. + */ +typedef void (*gps_measurement_callback) (GpsData* data); + +typedef struct { + /** set to sizeof(GpsMeasurementCallbacks) */ + size_t size; + gps_measurement_callback measurement_callback; +} GpsMeasurementCallbacks; + +#define GPS_MEASUREMENT_OPERATION_SUCCESS 0 +#define GPS_MEASUREMENT_ERROR_ALREADY_INIT -100 +#define GPS_MEASUREMENT_ERROR_GENERIC -101 + +/** + * Extended interface for GPS Measurements support. + */ +typedef struct { + /** Set to sizeof(GpsMeasurementInterface) */ + size_t size; + + /** + * Initializes the interface and registers the callback routines with the HAL. + * After a successful call to 'init' the HAL must begin to provide updates at its own phase. + * + * Status: + * GPS_MEASUREMENT_OPERATION_SUCCESS + * GPS_MEASUREMENT_ERROR_ALREADY_INIT - if a callback has already been registered without a + * corresponding call to 'close' + * GPS_MEASUREMENT_ERROR_GENERIC - if any other error occurred, it is expected that the HAL + * will not generate any updates upon returning this error code. + */ + int (*init) (GpsMeasurementCallbacks* callbacks); + + /** + * Stops updates from the HAL, and unregisters the callback routines. + * After a call to stop, the previously registered callbacks must be considered invalid by the + * HAL. + * If stop is invoked without a previous 'init', this function should perform no work. + */ + void (*close) (); + +} GpsMeasurementInterface; + + +/** Represents a GPS navigation message (or a fragment of it). */ +typedef struct { + /** set to sizeof(GpsNavigationMessage) */ + size_t size; + + /** + * Pseudo-random number in the range of [1, 32] + * This is a Mandatory value. + */ + int8_t prn; + + /** + * The type of message contained in the structure. + * This is a Mandatory value. + */ + GpsNavigationMessageType type; + + /** + * The status of the received navigation message. + * No need to send any navigation message that contains words with parity error and cannot be + * corrected. + */ + NavigationMessageStatus status; + + /** + * Message identifier. + * It provides an index so the complete Navigation Message can be assembled. i.e. fo L1 C/A + * subframe 4 and 5, this value corresponds to the 'frame id' of the navigation message. + * Subframe 1, 2, 3 does not contain a 'frame id' and this value can be set to -1. + */ + int16_t message_id; + + /** + * Sub-message identifier. + * If required by the message 'type', this value contains a sub-index within the current + * message (or frame) that is being transmitted. + * i.e. for L1 C/A the submessage id corresponds to the sub-frame id of the navigation message. + */ + int16_t submessage_id; + + /** + * The length of the data (in bytes) contained in the current message. + * If this value is different from zero, 'data' must point to an array of the same size. + * e.g. for L1 C/A the size of the sub-frame will be 40 bytes (10 words, 30 bits/word). + * + * This is a Mandatory value. + */ + size_t data_length; + + /** + * The data of the reported GPS message. + * The bytes (or words) specified using big endian format (MSB first). + * + * For L1 C/A, each subframe contains 10 30-bit GPS words. Each GPS word (30 bits) should be + * fitted into the last 30 bits in a 4-byte word (skip B31 and B32), with MSB first. + */ + uint8_t* data; + +} GpsNavigationMessage; + +/** + * The callback to report an available fragment of a GPS navigation messages from the HAL. + * + * Parameters: + * message - The GPS navigation submessage/subframe representation. + */ +typedef void (*gps_navigation_message_callback) (GpsNavigationMessage* message); + +typedef struct { + /** set to sizeof(GpsNavigationMessageCallbacks) */ + size_t size; + gps_navigation_message_callback navigation_message_callback; +} GpsNavigationMessageCallbacks; + +#define GPS_NAVIGATION_MESSAGE_OPERATION_SUCCESS 0 +#define GPS_NAVIGATION_MESSAGE_ERROR_ALREADY_INIT -100 +#define GPS_NAVIGATION_MESSAGE_ERROR_GENERIC -101 + +/** + * Extended interface for GPS navigation message reporting support. + */ +typedef struct { + /** Set to sizeof(GpsNavigationMessageInterface) */ + size_t size; + + /** + * Initializes the interface and registers the callback routines with the HAL. + * After a successful call to 'init' the HAL must begin to provide updates as they become + * available. + * + * Status: + * GPS_NAVIGATION_MESSAGE_OPERATION_SUCCESS + * GPS_NAVIGATION_MESSAGE_ERROR_ALREADY_INIT - if a callback has already been registered + * without a corresponding call to 'close'. + * GPS_NAVIGATION_MESSAGE_ERROR_GENERIC - if any other error occurred, it is expected that + * the HAL will not generate any updates upon returning this error code. + */ + int (*init) (GpsNavigationMessageCallbacks* callbacks); + + /** + * Stops updates from the HAL, and unregisters the callback routines. + * After a call to stop, the previously registered callbacks must be considered invalid by the + * HAL. + * If stop is invoked without a previous 'init', this function should perform no work. + */ + void (*close) (); + +} GpsNavigationMessageInterface; + +/** + * Interface for passing GNSS configuration contents from platform to HAL. + */ +typedef struct { + /** Set to sizeof(GnssConfigurationInterface) */ + size_t size; + + /** + * Deliver GNSS configuration contents to HAL. + * Parameters: + * config_data - a pointer to a char array which holds what usually is expected from + file(/etc/gps.conf), i.e., a sequence of UTF8 strings separated by '\n'. + * length - total number of UTF8 characters in configuraiton data. + * + * IMPORTANT: + * GPS HAL should expect this function can be called multiple times. And it may be + * called even when GpsLocationProvider is already constructed and enabled. GPS HAL + * should maintain the existing requests for various callback regardless the change + * in configuration data. + */ + void (*configuration_update) (const char* config_data, int32_t length); +} GnssConfigurationInterface; + +__END_DECLS + +#endif /* ANDROID_INCLUDE_HARDWARE_GPS_H */ + diff --git a/phonelibs/android_hardware_libhardware/include/hardware/gralloc.h b/phonelibs/android_hardware_libhardware/include/hardware/gralloc.h new file mode 100644 index 00000000000000..07ac0290b45bdd --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/gralloc.h @@ -0,0 +1,401 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_GRALLOC_INTERFACE_H +#define ANDROID_GRALLOC_INTERFACE_H + +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +__BEGIN_DECLS + +/** + * Module versioning information for the Gralloc hardware module, based on + * gralloc_module_t.common.module_api_version. + * + * Version History: + * + * GRALLOC_MODULE_API_VERSION_0_1: + * Initial Gralloc hardware module API. + * + * GRALLOC_MODULE_API_VERSION_0_2: + * Add support for flexible YCbCr format with (*lock_ycbcr)() method. + * + * GRALLOC_MODULE_API_VERSION_0_3: + * Add support for fence passing to/from lock/unlock. + */ + +#define GRALLOC_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1) +#define GRALLOC_MODULE_API_VERSION_0_2 HARDWARE_MODULE_API_VERSION(0, 2) +#define GRALLOC_MODULE_API_VERSION_0_3 HARDWARE_MODULE_API_VERSION(0, 3) + +#define GRALLOC_DEVICE_API_VERSION_0_1 HARDWARE_DEVICE_API_VERSION(0, 1) + +/** + * The id of this module + */ +#define GRALLOC_HARDWARE_MODULE_ID "gralloc" + +/** + * Name of the graphics device to open + */ + +#define GRALLOC_HARDWARE_GPU0 "gpu0" + +enum { + /* buffer is never read in software */ + GRALLOC_USAGE_SW_READ_NEVER = 0x00000000, + /* buffer is rarely read in software */ + GRALLOC_USAGE_SW_READ_RARELY = 0x00000002, + /* buffer is often read in software */ + GRALLOC_USAGE_SW_READ_OFTEN = 0x00000003, + /* mask for the software read values */ + GRALLOC_USAGE_SW_READ_MASK = 0x0000000F, + + /* buffer is never written in software */ + GRALLOC_USAGE_SW_WRITE_NEVER = 0x00000000, + /* buffer is rarely written in software */ + GRALLOC_USAGE_SW_WRITE_RARELY = 0x00000020, + /* buffer is often written in software */ + GRALLOC_USAGE_SW_WRITE_OFTEN = 0x00000030, + /* mask for the software write values */ + GRALLOC_USAGE_SW_WRITE_MASK = 0x000000F0, + + /* buffer will be used as an OpenGL ES texture */ + GRALLOC_USAGE_HW_TEXTURE = 0x00000100, + /* buffer will be used as an OpenGL ES render target */ + GRALLOC_USAGE_HW_RENDER = 0x00000200, + /* buffer will be used by the 2D hardware blitter */ + GRALLOC_USAGE_HW_2D = 0x00000400, + /* buffer will be used by the HWComposer HAL module */ + GRALLOC_USAGE_HW_COMPOSER = 0x00000800, + /* buffer will be used with the framebuffer device */ + GRALLOC_USAGE_HW_FB = 0x00001000, + + /* buffer should be displayed full-screen on an external display when + * possible */ + GRALLOC_USAGE_EXTERNAL_DISP = 0x00002000, + + /* Must have a hardware-protected path to external display sink for + * this buffer. If a hardware-protected path is not available, then + * either don't composite only this buffer (preferred) to the + * external sink, or (less desirable) do not route the entire + * composition to the external sink. */ + GRALLOC_USAGE_PROTECTED = 0x00004000, + + /* buffer may be used as a cursor */ + GRALLOC_USAGE_CURSOR = 0x00008000, + + /* buffer will be used with the HW video encoder */ + GRALLOC_USAGE_HW_VIDEO_ENCODER = 0x00010000, + /* buffer will be written by the HW camera pipeline */ + GRALLOC_USAGE_HW_CAMERA_WRITE = 0x00020000, + /* buffer will be read by the HW camera pipeline */ + GRALLOC_USAGE_HW_CAMERA_READ = 0x00040000, + /* buffer will be used as part of zero-shutter-lag queue */ + GRALLOC_USAGE_HW_CAMERA_ZSL = 0x00060000, + /* mask for the camera access values */ + GRALLOC_USAGE_HW_CAMERA_MASK = 0x00060000, + /* mask for the software usage bit-mask */ + GRALLOC_USAGE_HW_MASK = 0x00071F00, + + /* buffer will be used as a RenderScript Allocation */ + GRALLOC_USAGE_RENDERSCRIPT = 0x00100000, + + /* Set by the consumer to indicate to the producer that they may attach a + * buffer that they did not detach from the BufferQueue. Will be filtered + * out by GRALLOC_USAGE_ALLOC_MASK, so gralloc modules will not need to + * handle this flag. */ + GRALLOC_USAGE_FOREIGN_BUFFERS = 0x00200000, + + /* Mask of all flags which could be passed to a gralloc module for buffer + * allocation. Any flags not in this mask do not need to be handled by + * gralloc modules. */ + GRALLOC_USAGE_ALLOC_MASK = ~(GRALLOC_USAGE_FOREIGN_BUFFERS), + + /* implementation-specific private usage flags */ + GRALLOC_USAGE_PRIVATE_0 = 0x10000000, + GRALLOC_USAGE_PRIVATE_1 = 0x20000000, + GRALLOC_USAGE_PRIVATE_2 = 0x40000000, + GRALLOC_USAGE_PRIVATE_3 = 0x80000000, + GRALLOC_USAGE_PRIVATE_MASK = 0xF0000000, + +#ifdef EXYNOS4_ENHANCEMENTS + /* SAMSUNG */ + GRALLOC_USAGE_PRIVATE_NONECACHE = 0x00800000, + + GRALLOC_USAGE_HW_FIMC1 = 0x01000000, + GRALLOC_USAGE_HW_ION = 0x02000000, + GRALLOC_USAGE_YUV_ADDR = 0x04000000, + GRALLOC_USAGE_CAMERA = 0x08000000, + + /* SEC Private usage , for Overlay path at HWC */ + GRALLOC_USAGE_HWC_HWOVERLAY = 0x20000000, +#endif +}; + +/*****************************************************************************/ + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +typedef struct gralloc_module_t { + struct hw_module_t common; + + /* + * (*registerBuffer)() must be called before a buffer_handle_t that has not + * been created with (*alloc_device_t::alloc)() can be used. + * + * This is intended to be used with buffer_handle_t's that have been + * received in this process through IPC. + * + * This function checks that the handle is indeed a valid one and prepares + * it for use with (*lock)() and (*unlock)(). + * + * It is not necessary to call (*registerBuffer)() on a handle created + * with (*alloc_device_t::alloc)(). + * + * returns an error if this buffer_handle_t is not valid. + */ + int (*registerBuffer)(struct gralloc_module_t const* module, + buffer_handle_t handle); + + /* + * (*unregisterBuffer)() is called once this handle is no longer needed in + * this process. After this call, it is an error to call (*lock)(), + * (*unlock)(), or (*registerBuffer)(). + * + * This function doesn't close or free the handle itself; this is done + * by other means, usually through libcutils's native_handle_close() and + * native_handle_free(). + * + * It is an error to call (*unregisterBuffer)() on a buffer that wasn't + * explicitly registered first. + */ + int (*unregisterBuffer)(struct gralloc_module_t const* module, + buffer_handle_t handle); + + /* + * The (*lock)() method is called before a buffer is accessed for the + * specified usage. This call may block, for instance if the h/w needs + * to finish rendering or if CPU caches need to be synchronized. + * + * The caller promises to modify only pixels in the area specified + * by (l,t,w,h). + * + * The content of the buffer outside of the specified area is NOT modified + * by this call. + * + * If usage specifies GRALLOC_USAGE_SW_*, vaddr is filled with the address + * of the buffer in virtual memory. + * + * Note calling (*lock)() on HAL_PIXEL_FORMAT_YCbCr_*_888 buffers will fail + * and return -EINVAL. These buffers must be locked with (*lock_ycbcr)() + * instead. + * + * THREADING CONSIDERATIONS: + * + * It is legal for several different threads to lock a buffer from + * read access, none of the threads are blocked. + * + * However, locking a buffer simultaneously for write or read/write is + * undefined, but: + * - shall not result in termination of the process + * - shall not block the caller + * It is acceptable to return an error or to leave the buffer's content + * into an indeterminate state. + * + * If the buffer was created with a usage mask incompatible with the + * requested usage flags here, -EINVAL is returned. + * + */ + + int (*lock)(struct gralloc_module_t const* module, + buffer_handle_t handle, int usage, + int l, int t, int w, int h, + void** vaddr); + + + /* + * The (*unlock)() method must be called after all changes to the buffer + * are completed. + */ + + int (*unlock)(struct gralloc_module_t const* module, + buffer_handle_t handle); + +#ifdef EXYNOS4_ENHANCEMENTS + int (*getphys) (struct gralloc_module_t const* module, + buffer_handle_t handle, void** paddr); +#endif + + /* reserved for future use */ + int (*perform)(struct gralloc_module_t const* module, + int operation, ... ); + + /* + * The (*lock_ycbcr)() method is like the (*lock)() method, with the + * difference that it fills a struct ycbcr with a description of the buffer + * layout, and zeroes out the reserved fields. + * + * If the buffer format is not compatible with a flexible YUV format (e.g. + * the buffer layout cannot be represented with the ycbcr struct), it + * will return -EINVAL. + * + * This method must work on buffers with HAL_PIXEL_FORMAT_YCbCr_*_888 + * if supported by the device, as well as with any other format that is + * requested by the multimedia codecs when they are configured with a + * flexible-YUV-compatible color-format with android native buffers. + * + * Note that this method may also be called on buffers of other formats, + * including non-YUV formats. + * + * Added in GRALLOC_MODULE_API_VERSION_0_2. + */ + + int (*lock_ycbcr)(struct gralloc_module_t const* module, + buffer_handle_t handle, int usage, + int l, int t, int w, int h, + struct android_ycbcr *ycbcr); + + /* + * The (*lockAsync)() method is like the (*lock)() method except + * that the buffer's sync fence object is passed into the lock + * call instead of requiring the caller to wait for completion. + * + * The gralloc implementation takes ownership of the fenceFd and + * is responsible for closing it when no longer needed. + * + * Added in GRALLOC_MODULE_API_VERSION_0_3. + */ + int (*lockAsync)(struct gralloc_module_t const* module, + buffer_handle_t handle, int usage, + int l, int t, int w, int h, + void** vaddr, int fenceFd); + + /* + * The (*unlockAsync)() method is like the (*unlock)() method + * except that a buffer sync fence object is returned from the + * lock call, representing the completion of any pending work + * performed by the gralloc implementation. + * + * The caller takes ownership of the fenceFd and is responsible + * for closing it when no longer needed. + * + * Added in GRALLOC_MODULE_API_VERSION_0_3. + */ + int (*unlockAsync)(struct gralloc_module_t const* module, + buffer_handle_t handle, int* fenceFd); + + /* + * The (*lockAsync_ycbcr)() method is like the (*lock_ycbcr)() + * method except that the buffer's sync fence object is passed + * into the lock call instead of requiring the caller to wait for + * completion. + * + * The gralloc implementation takes ownership of the fenceFd and + * is responsible for closing it when no longer needed. + * + * Added in GRALLOC_MODULE_API_VERSION_0_3. + */ + int (*lockAsync_ycbcr)(struct gralloc_module_t const* module, + buffer_handle_t handle, int usage, + int l, int t, int w, int h, + struct android_ycbcr *ycbcr, int fenceFd); + + /* reserved for future use */ + void* reserved_proc[3]; +} gralloc_module_t; + +/*****************************************************************************/ + +/** + * Every device data structure must begin with hw_device_t + * followed by module specific public methods and attributes. + */ + +typedef struct alloc_device_t { + struct hw_device_t common; + + /* + * (*alloc)() Allocates a buffer in graphic memory with the requested + * parameters and returns a buffer_handle_t and the stride in pixels to + * allow the implementation to satisfy hardware constraints on the width + * of a pixmap (eg: it may have to be multiple of 8 pixels). + * The CALLER TAKES OWNERSHIP of the buffer_handle_t. + * + * If format is HAL_PIXEL_FORMAT_YCbCr_420_888, the returned stride must be + * 0, since the actual strides are available from the android_ycbcr + * structure. + * + * Returns 0 on success or -errno on error. + */ + + int (*alloc)(struct alloc_device_t* dev, + int w, int h, int format, int usage, + buffer_handle_t* handle, int* stride); + + /* + * (*free)() Frees a previously allocated buffer. + * Behavior is undefined if the buffer is still mapped in any process, + * but shall not result in termination of the program or security breaches + * (allowing a process to get access to another process' buffers). + * THIS FUNCTION TAKES OWNERSHIP of the buffer_handle_t which becomes + * invalid after the call. + * + * Returns 0 on success or -errno on error. + */ + int (*free)(struct alloc_device_t* dev, + buffer_handle_t handle); + + /* This hook is OPTIONAL. + * + * If non NULL it will be caused by SurfaceFlinger on dumpsys + */ + void (*dump)(struct alloc_device_t *dev, char *buff, int buff_len); + + void* reserved_proc[7]; +} alloc_device_t; + + +/** convenience API for opening and closing a supported device */ + +static inline int gralloc_open(const struct hw_module_t* module, + struct alloc_device_t** device) { + return module->methods->open(module, + GRALLOC_HARDWARE_GPU0, (struct hw_device_t**)device); +} + +static inline int gralloc_close(struct alloc_device_t* device) { + return device->common.close(&device->common); +} + +__END_DECLS + +#endif // ANDROID_GRALLOC_INTERFACE_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/hardware.h b/phonelibs/android_hardware_libhardware/include/hardware/hardware.h new file mode 100644 index 00000000000000..74f57aa4c28fb3 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/hardware.h @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_HARDWARE_HARDWARE_H +#define ANDROID_INCLUDE_HARDWARE_HARDWARE_H + +#include +#include + +#include +#include + +__BEGIN_DECLS + +/* + * Value for the hw_module_t.tag field + */ + +#define MAKE_TAG_CONSTANT(A,B,C,D) (((A) << 24) | ((B) << 16) | ((C) << 8) | (D)) + +#define HARDWARE_MODULE_TAG MAKE_TAG_CONSTANT('H', 'W', 'M', 'T') +#define HARDWARE_DEVICE_TAG MAKE_TAG_CONSTANT('H', 'W', 'D', 'T') + +#define HARDWARE_MAKE_API_VERSION(maj,min) \ + ((((maj) & 0xff) << 8) | ((min) & 0xff)) + +#define HARDWARE_MAKE_API_VERSION_2(maj,min,hdr) \ + ((((maj) & 0xff) << 24) | (((min) & 0xff) << 16) | ((hdr) & 0xffff)) +#define HARDWARE_API_VERSION_2_MAJ_MIN_MASK 0xffff0000 +#define HARDWARE_API_VERSION_2_HEADER_MASK 0x0000ffff + + +/* + * The current HAL API version. + * + * All module implementations must set the hw_module_t.hal_api_version field + * to this value when declaring the module with HAL_MODULE_INFO_SYM. + * + * Note that previous implementations have always set this field to 0. + * Therefore, libhardware HAL API will always consider versions 0.0 and 1.0 + * to be 100% binary compatible. + * + */ +#define HARDWARE_HAL_API_VERSION HARDWARE_MAKE_API_VERSION(1, 0) + +/* + * Helper macros for module implementors. + * + * The derived modules should provide convenience macros for supported + * versions so that implementations can explicitly specify module/device + * versions at definition time. + * + * Use this macro to set the hw_module_t.module_api_version field. + */ +#define HARDWARE_MODULE_API_VERSION(maj,min) HARDWARE_MAKE_API_VERSION(maj,min) +#define HARDWARE_MODULE_API_VERSION_2(maj,min,hdr) HARDWARE_MAKE_API_VERSION_2(maj,min,hdr) + +/* + * Use this macro to set the hw_device_t.version field + */ +#define HARDWARE_DEVICE_API_VERSION(maj,min) HARDWARE_MAKE_API_VERSION(maj,min) +#define HARDWARE_DEVICE_API_VERSION_2(maj,min,hdr) HARDWARE_MAKE_API_VERSION_2(maj,min,hdr) + +struct hw_module_t; +struct hw_module_methods_t; +struct hw_device_t; + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +typedef struct hw_module_t { + /** tag must be initialized to HARDWARE_MODULE_TAG */ + uint32_t tag; + + /** + * The API version of the implemented module. The module owner is + * responsible for updating the version when a module interface has + * changed. + * + * The derived modules such as gralloc and audio own and manage this field. + * The module user must interpret the version field to decide whether or + * not to inter-operate with the supplied module implementation. + * For example, SurfaceFlinger is responsible for making sure that + * it knows how to manage different versions of the gralloc-module API, + * and AudioFlinger must know how to do the same for audio-module API. + * + * The module API version should include a major and a minor component. + * For example, version 1.0 could be represented as 0x0100. This format + * implies that versions 0x0100-0x01ff are all API-compatible. + * + * In the future, libhardware will expose a hw_get_module_version() + * (or equivalent) function that will take minimum/maximum supported + * versions as arguments and would be able to reject modules with + * versions outside of the supplied range. + */ + uint16_t module_api_version; +#define version_major module_api_version + /** + * version_major/version_minor defines are supplied here for temporary + * source code compatibility. They will be removed in the next version. + * ALL clients must convert to the new version format. + */ + + /** + * The API version of the HAL module interface. This is meant to + * version the hw_module_t, hw_module_methods_t, and hw_device_t + * structures and definitions. + * + * The HAL interface owns this field. Module users/implementations + * must NOT rely on this value for version information. + * + * Presently, 0 is the only valid value. + */ + uint16_t hal_api_version; +#define version_minor hal_api_version + + /** Identifier of module */ + const char *id; + + /** Name of this module */ + const char *name; + + /** Author/owner/implementor of the module */ + const char *author; + + /** Modules methods */ + struct hw_module_methods_t* methods; + + /** module's dso */ + void* dso; + +#ifdef __LP64__ + uint64_t reserved[32-7]; +#else + /** padding to 128 bytes, reserved for future use */ + uint32_t reserved[32-7]; +#endif + +} hw_module_t; + +typedef struct hw_module_methods_t { + /** Open a specific device */ + int (*open)(const struct hw_module_t* module, const char* id, + struct hw_device_t** device); + +} hw_module_methods_t; + +/** + * Every device data structure must begin with hw_device_t + * followed by module specific public methods and attributes. + */ +typedef struct hw_device_t { + /** tag must be initialized to HARDWARE_DEVICE_TAG */ + uint32_t tag; + + /** + * Version of the module-specific device API. This value is used by + * the derived-module user to manage different device implementations. + * + * The module user is responsible for checking the module_api_version + * and device version fields to ensure that the user is capable of + * communicating with the specific module implementation. + * + * One module can support multiple devices with different versions. This + * can be useful when a device interface changes in an incompatible way + * but it is still necessary to support older implementations at the same + * time. One such example is the Camera 2.0 API. + * + * This field is interpreted by the module user and is ignored by the + * HAL interface itself. + */ + uint32_t version; + + /** reference to the module this device belongs to */ + struct hw_module_t* module; + + /** padding reserved for future use */ +#ifdef __LP64__ + uint64_t reserved[12]; +#else + uint32_t reserved[12]; +#endif + + /** Close this device */ + int (*close)(struct hw_device_t* device); + +} hw_device_t; + +/** + * Name of the hal_module_info + */ +#define HAL_MODULE_INFO_SYM HMI + +/** + * Name of the hal_module_info as a string + */ +#define HAL_MODULE_INFO_SYM_AS_STR "HMI" + +/** + * Get the module info associated with a module by id. + * + * @return: 0 == success, <0 == error and *module == NULL + */ +int hw_get_module(const char *id, const struct hw_module_t **module); + +/** + * Get the module info associated with a module instance by class 'class_id' + * and instance 'inst'. + * + * Some modules types necessitate multiple instances. For example audio supports + * multiple concurrent interfaces and thus 'audio' is the module class + * and 'primary' or 'a2dp' are module interfaces. This implies that the files + * providing these modules would be named audio.primary..so and + * audio.a2dp..so + * + * @return: 0 == success, <0 == error and *module == NULL + */ +int hw_get_module_by_class(const char *class_id, const char *inst, + const struct hw_module_t **module); + +__END_DECLS + +#endif /* ANDROID_INCLUDE_HARDWARE_HARDWARE_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/hdmi_cec.h b/phonelibs/android_hardware_libhardware/include/hardware/hdmi_cec.h new file mode 100644 index 00000000000000..ab70f92e2b6c06 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/hdmi_cec.h @@ -0,0 +1,429 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_HARDWARE_HDMI_CEC_H +#define ANDROID_INCLUDE_HARDWARE_HDMI_CEC_H + +#include +#include + +#include + +__BEGIN_DECLS + +#define HDMI_CEC_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0) +#define HDMI_CEC_MODULE_API_VERSION_CURRENT HDMI_MODULE_API_VERSION_1_0 + +#define HDMI_CEC_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0) +#define HDMI_CEC_DEVICE_API_VERSION_CURRENT HDMI_DEVICE_API_VERSION_1_0 + +#define HDMI_CEC_HARDWARE_MODULE_ID "hdmi_cec" +#define HDMI_CEC_HARDWARE_INTERFACE "hdmi_cec_hw_if" + +typedef enum cec_device_type { + CEC_DEVICE_INACTIVE = -1, + CEC_DEVICE_TV = 0, + CEC_DEVICE_RECORDER = 1, + CEC_DEVICE_RESERVED = 2, + CEC_DEVICE_TUNER = 3, + CEC_DEVICE_PLAYBACK = 4, + CEC_DEVICE_AUDIO_SYSTEM = 5, + CEC_DEVICE_MAX = CEC_DEVICE_AUDIO_SYSTEM +} cec_device_type_t; + +typedef enum cec_logical_address { + CEC_ADDR_TV = 0, + CEC_ADDR_RECORDER_1 = 1, + CEC_ADDR_RECORDER_2 = 2, + CEC_ADDR_TUNER_1 = 3, + CEC_ADDR_PLAYBACK_1 = 4, + CEC_ADDR_AUDIO_SYSTEM = 5, + CEC_ADDR_TUNER_2 = 6, + CEC_ADDR_TUNER_3 = 7, + CEC_ADDR_PLAYBACK_2 = 8, + CEC_ADDR_RECORDER_3 = 9, + CEC_ADDR_TUNER_4 = 10, + CEC_ADDR_PLAYBACK_3 = 11, + CEC_ADDR_RESERVED_1 = 12, + CEC_ADDR_RESERVED_2 = 13, + CEC_ADDR_FREE_USE = 14, + CEC_ADDR_UNREGISTERED = 15, + CEC_ADDR_BROADCAST = 15 +} cec_logical_address_t; + +/* + * HDMI CEC messages + */ +enum cec_message_type { + CEC_MESSAGE_FEATURE_ABORT = 0x00, + CEC_MESSAGE_IMAGE_VIEW_ON = 0x04, + CEC_MESSAGE_TUNER_STEP_INCREMENT = 0x05, + CEC_MESSAGE_TUNER_STEP_DECREMENT = 0x06, + CEC_MESSAGE_TUNER_DEVICE_STATUS = 0x07, + CEC_MESSAGE_GIVE_TUNER_DEVICE_STATUS = 0x08, + CEC_MESSAGE_RECORD_ON = 0x09, + CEC_MESSAGE_RECORD_STATUS = 0x0A, + CEC_MESSAGE_RECORD_OFF = 0x0B, + CEC_MESSAGE_TEXT_VIEW_ON = 0x0D, + CEC_MESSAGE_RECORD_TV_SCREEN = 0x0F, + CEC_MESSAGE_GIVE_DECK_STATUS = 0x1A, + CEC_MESSAGE_DECK_STATUS = 0x1B, + CEC_MESSAGE_SET_MENU_LANGUAGE = 0x32, + CEC_MESSAGE_CLEAR_ANALOG_TIMER = 0x33, + CEC_MESSAGE_SET_ANALOG_TIMER = 0x34, + CEC_MESSAGE_TIMER_STATUS = 0x35, + CEC_MESSAGE_STANDBY = 0x36, + CEC_MESSAGE_PLAY = 0x41, + CEC_MESSAGE_DECK_CONTROL = 0x42, + CEC_MESSAGE_TIMER_CLEARED_STATUS = 0x043, + CEC_MESSAGE_USER_CONTROL_PRESSED = 0x44, + CEC_MESSAGE_USER_CONTROL_RELEASED = 0x45, + CEC_MESSAGE_GIVE_OSD_NAME = 0x46, + CEC_MESSAGE_SET_OSD_NAME = 0x47, + CEC_MESSAGE_SET_OSD_STRING = 0x64, + CEC_MESSAGE_SET_TIMER_PROGRAM_TITLE = 0x67, + CEC_MESSAGE_SYSTEM_AUDIO_MODE_REQUEST = 0x70, + CEC_MESSAGE_GIVE_AUDIO_STATUS = 0x71, + CEC_MESSAGE_SET_SYSTEM_AUDIO_MODE = 0x72, + CEC_MESSAGE_REPORT_AUDIO_STATUS = 0x7A, + CEC_MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS = 0x7D, + CEC_MESSAGE_SYSTEM_AUDIO_MODE_STATUS = 0x7E, + CEC_MESSAGE_ROUTING_CHANGE = 0x80, + CEC_MESSAGE_ROUTING_INFORMATION = 0x81, + CEC_MESSAGE_ACTIVE_SOURCE = 0x82, + CEC_MESSAGE_GIVE_PHYSICAL_ADDRESS = 0x83, + CEC_MESSAGE_REPORT_PHYSICAL_ADDRESS = 0x84, + CEC_MESSAGE_REQUEST_ACTIVE_SOURCE = 0x85, + CEC_MESSAGE_SET_STREAM_PATH = 0x86, + CEC_MESSAGE_DEVICE_VENDOR_ID = 0x87, + CEC_MESSAGE_VENDOR_COMMAND = 0x89, + CEC_MESSAGE_VENDOR_REMOTE_BUTTON_DOWN = 0x8A, + CEC_MESSAGE_VENDOR_REMOTE_BUTTON_UP = 0x8B, + CEC_MESSAGE_GIVE_DEVICE_VENDOR_ID = 0x8C, + CEC_MESSAGE_MENU_REQUEST = 0x8D, + CEC_MESSAGE_MENU_STATUS = 0x8E, + CEC_MESSAGE_GIVE_DEVICE_POWER_STATUS = 0x8F, + CEC_MESSAGE_REPORT_POWER_STATUS = 0x90, + CEC_MESSAGE_GET_MENU_LANGUAGE = 0x91, + CEC_MESSAGE_SELECT_ANALOG_SERVICE = 0x92, + CEC_MESSAGE_SELECT_DIGITAL_SERVICE = 0x93, + CEC_MESSAGE_SET_DIGITAL_TIMER = 0x97, + CEC_MESSAGE_CLEAR_DIGITAL_TIMER = 0x99, + CEC_MESSAGE_SET_AUDIO_RATE = 0x9A, + CEC_MESSAGE_INACTIVE_SOURCE = 0x9D, + CEC_MESSAGE_CEC_VERSION = 0x9E, + CEC_MESSAGE_GET_CEC_VERSION = 0x9F, + CEC_MESSAGE_VENDOR_COMMAND_WITH_ID = 0xA0, + CEC_MESSAGE_CLEAR_EXTERNAL_TIMER = 0xA1, + CEC_MESSAGE_SET_EXTERNAL_TIMER = 0xA2, + CEC_MESSAGE_INITIATE_ARC = 0xC0, + CEC_MESSAGE_REPORT_ARC_INITIATED = 0xC1, + CEC_MESSAGE_REPORT_ARC_TERMINATED = 0xC2, + CEC_MESSAGE_REQUEST_ARC_INITIATION = 0xC3, + CEC_MESSAGE_REQUEST_ARC_TERMINATION = 0xC4, + CEC_MESSAGE_TERMINATE_ARC = 0xC5, + CEC_MESSAGE_ABORT = 0xFF +}; + +/* + * Operand description [Abort Reason] + */ +enum abort_reason { + ABORT_UNRECOGNIZED_MODE = 0, + ABORT_NOT_IN_CORRECT_MODE = 1, + ABORT_CANNOT_PROVIDE_SOURCE = 2, + ABORT_INVALID_OPERAND = 3, + ABORT_REFUSED = 4, + ABORT_UNABLE_TO_DETERMINE = 5 +}; + +/* + * HDMI event type. used for hdmi_event_t. + */ +enum { + HDMI_EVENT_CEC_MESSAGE = 1, + HDMI_EVENT_HOT_PLUG = 2, +}; + +/* + * HDMI hotplug event type. Used when the event + * type is HDMI_EVENT_HOT_PLUG. + */ +enum { + HDMI_NOT_CONNECTED = 0, + HDMI_CONNECTED = 1 +}; + +/* + * error code used for send_message. + */ +enum { + HDMI_RESULT_SUCCESS = 0, + HDMI_RESULT_NACK = 1, /* not acknowledged */ + HDMI_RESULT_BUSY = 2, /* bus is busy */ + HDMI_RESULT_FAIL = 3, +}; + +/* + * HDMI port type. + */ +typedef enum hdmi_port_type { + HDMI_INPUT = 0, + HDMI_OUTPUT = 1 +} hdmi_port_type_t; + +/* + * Flags used for set_option() + */ +enum { + /* When set to false, HAL does not wake up the system upon receiving + * or . Used when user changes the TV + * settings to disable the auto TV on functionality. + * True by default. + */ + HDMI_OPTION_WAKEUP = 1, + + /* When set to false, all the CEC commands are discarded. Used when + * user changes the TV settings to disable CEC functionality. + * True by default. + */ + HDMI_OPTION_ENABLE_CEC = 2, + + /* Setting this flag to false means Android system will stop handling + * CEC service and yield the control over to the microprocessor that is + * powered on through the standby mode. When set to true, the system + * will gain the control over, hence telling the microprocessor to stop + * handling the cec commands. This is called when system goes + * in and out of standby mode to notify the microprocessor that it should + * start/stop handling CEC commands on behalf of the system. + * False by default. + */ + HDMI_OPTION_SYSTEM_CEC_CONTROL = 3, + + /* Option 4 not used */ + + /* Passes the updated language information of Android system. + * Contains 3-byte ASCII code as defined in ISO/FDIS 639-2. Can be + * used for HAL to respond to while in standby mode. + * English(eng), for example, is converted to 0x656e67. + */ + HDMI_OPTION_SET_LANG = 5, +}; + +/* + * Maximum length in bytes of cec message body (exclude header block), + * should not exceed 16 (spec CEC 6 Frame Description) + */ +#define CEC_MESSAGE_BODY_MAX_LENGTH 16 + +typedef struct cec_message { + /* logical address of sender */ + cec_logical_address_t initiator; + + /* logical address of receiver */ + cec_logical_address_t destination; + + /* Length in bytes of body, range [0, CEC_MESSAGE_BODY_MAX_LENGTH] */ + size_t length; + unsigned char body[CEC_MESSAGE_BODY_MAX_LENGTH]; +} cec_message_t; + +typedef struct hotplug_event { + /* + * true if the cable is connected; otherwise false. + */ + int connected; + int port_id; +} hotplug_event_t; + +typedef struct tx_status_event { + int status; + int opcode; /* CEC opcode */ +} tx_status_event_t; + +/* + * HDMI event generated from HAL. + */ +typedef struct hdmi_event { + int type; + struct hdmi_cec_device* dev; + union { + cec_message_t cec; + hotplug_event_t hotplug; + }; +} hdmi_event_t; + +/* + * HDMI port descriptor + */ +typedef struct hdmi_port_info { + hdmi_port_type_t type; + // Port ID should start from 1 which corresponds to HDMI "port 1". + int port_id; + int cec_supported; + int arc_supported; + uint16_t physical_address; +} hdmi_port_info_t; + +/* + * Callback function type that will be called by HAL implementation. + * Services can not close/open the device in the callback. + */ +typedef void (*event_callback_t)(const hdmi_event_t* event, void* arg); + +typedef struct hdmi_cec_module { + /** + * Common methods of the HDMI CEC module. This *must* be the first member of + * hdmi_cec_module as users of this structure will cast a hw_module_t to hdmi_cec_module + * pointer in contexts where it's known the hw_module_t references a hdmi_cec_module. + */ + struct hw_module_t common; +} hdmi_module_t; + +/* + * HDMI-CEC HAL interface definition. + */ +typedef struct hdmi_cec_device { + /** + * Common methods of the HDMI CEC device. This *must* be the first member of + * hdmi_cec_device as users of this structure will cast a hw_device_t to hdmi_cec_device + * pointer in contexts where it's known the hw_device_t references a hdmi_cec_device. + */ + struct hw_device_t common; + + /* + * (*add_logical_address)() passes the logical address that will be used + * in this system. + * + * HAL may use it to configure the hardware so that the CEC commands addressed + * the given logical address can be filtered in. This method can be called + * as many times as necessary in order to support multiple logical devices. + * addr should be in the range of valid logical addresses for the call + * to succeed. + * + * Returns 0 on success or -errno on error. + */ + int (*add_logical_address)(const struct hdmi_cec_device* dev, cec_logical_address_t addr); + + /* + * (*clear_logical_address)() tells HAL to reset all the logical addresses. + * + * It is used when the system doesn't need to process CEC command any more, + * hence to tell HAL to stop receiving commands from the CEC bus, and change + * the state back to the beginning. + */ + void (*clear_logical_address)(const struct hdmi_cec_device* dev); + + /* + * (*get_physical_address)() returns the CEC physical address. The + * address is written to addr. + * + * The physical address depends on the topology of the network formed + * by connected HDMI devices. It is therefore likely to change if the cable + * is plugged off and on again. It is advised to call get_physical_address + * to get the updated address when hot plug event takes place. + * + * Returns 0 on success or -errno on error. + */ + int (*get_physical_address)(const struct hdmi_cec_device* dev, uint16_t* addr); + + /* + * (*send_message)() transmits HDMI-CEC message to other HDMI device. + * + * The method should be designed to return in a certain amount of time not + * hanging forever, which can happen if CEC signal line is pulled low for + * some reason. HAL implementation should take the situation into account + * so as not to wait forever for the message to get sent out. + * + * It should try retransmission at least once as specified in the standard. + * + * Returns error code. See HDMI_RESULT_SUCCESS, HDMI_RESULT_NACK, and + * HDMI_RESULT_BUSY. + */ + int (*send_message)(const struct hdmi_cec_device* dev, const cec_message_t*); + + /* + * (*register_event_callback)() registers a callback that HDMI-CEC HAL + * can later use for incoming CEC messages or internal HDMI events. + * When calling from C++, use the argument arg to pass the calling object. + * It will be passed back when the callback is invoked so that the context + * can be retrieved. + */ + void (*register_event_callback)(const struct hdmi_cec_device* dev, + event_callback_t callback, void* arg); + + /* + * (*get_version)() returns the CEC version supported by underlying hardware. + */ + void (*get_version)(const struct hdmi_cec_device* dev, int* version); + + /* + * (*get_vendor_id)() returns the identifier of the vendor. It is + * the 24-bit unique company ID obtained from the IEEE Registration + * Authority Committee (RAC). + */ + void (*get_vendor_id)(const struct hdmi_cec_device* dev, uint32_t* vendor_id); + + /* + * (*get_port_info)() returns the hdmi port information of underlying hardware. + * info is the list of HDMI port information, and 'total' is the number of + * HDMI ports in the system. + */ + void (*get_port_info)(const struct hdmi_cec_device* dev, + struct hdmi_port_info* list[], int* total); + + /* + * (*set_option)() passes flags controlling the way HDMI-CEC service works down + * to HAL implementation. Those flags will be used in case the feature needs + * update in HAL itself, firmware or microcontroller. + */ + void (*set_option)(const struct hdmi_cec_device* dev, int flag, int value); + + /* + * (*set_audio_return_channel)() configures ARC circuit in the hardware logic + * to start or stop the feature. Flag can be either 1 to start the feature + * or 0 to stop it. + * + * Returns 0 on success or -errno on error. + */ + void (*set_audio_return_channel)(const struct hdmi_cec_device* dev, int port_id, int flag); + + /* + * (*is_connected)() returns the connection status of the specified port. + * Returns HDMI_CONNECTED if a device is connected, otherwise HDMI_NOT_CONNECTED. + * The HAL should watch for +5V power signal to determine the status. + */ + int (*is_connected)(const struct hdmi_cec_device* dev, int port_id); + + /* Reserved for future use to maximum 16 functions. Must be NULL. */ + void* reserved[16 - 11]; +} hdmi_cec_device_t; + +/** convenience API for opening and closing a device */ + +static inline int hdmi_cec_open(const struct hw_module_t* module, + struct hdmi_cec_device** device) { + return module->methods->open(module, + HDMI_CEC_HARDWARE_INTERFACE, (struct hw_device_t**)device); +} + +static inline int hdmi_cec_close(struct hdmi_cec_device* device) { + return device->common.close(&device->common); +} + +__END_DECLS + +#endif /* ANDROID_INCLUDE_HARDWARE_HDMI_CEC_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/hw_auth_token.h b/phonelibs/android_hardware_libhardware/include/hardware/hw_auth_token.h new file mode 100644 index 00000000000000..f471d1ab7dfe21 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/hw_auth_token.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#ifndef ANDROID_HARDWARE_HW_AUTH_TOKEN_H +#define ANDROID_HARDWARE_HW_AUTH_TOKEN_H + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +const uint8_t HW_AUTH_TOKEN_VERSION = 0; + +typedef enum { + HW_AUTH_NONE = 0, + HW_AUTH_PASSWORD = 1 << 0, + HW_AUTH_FINGERPRINT = 1 << 1, + // Additional entries should be powers of 2. + HW_AUTH_ANY = UINT32_MAX, +} hw_authenticator_type_t; + +/** + * Data format for an authentication record used to prove successful authentication. + */ +typedef struct __attribute__((__packed__)) { + uint8_t version; // Current version is 0 + uint64_t challenge; + uint64_t user_id; // secure user ID, not Android user ID + uint64_t authenticator_id; // secure authenticator ID + uint32_t authenticator_type; // hw_authenticator_type_t, in network order + uint64_t timestamp; // in network order + uint8_t hmac[32]; +} hw_auth_token_t; + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // ANDROID_HARDWARE_HW_AUTH_TOKEN_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/hwcomposer.h b/phonelibs/android_hardware_libhardware/include/hardware/hwcomposer.h new file mode 100644 index 00000000000000..aa466b300a0b14 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/hwcomposer.h @@ -0,0 +1,833 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_H +#define ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_H + +#include +#include + +#include +#include +#include + +#include + +__BEGIN_DECLS + +/*****************************************************************************/ + +/* for compatibility */ +#define HWC_MODULE_API_VERSION HWC_MODULE_API_VERSION_0_1 +#define HWC_DEVICE_API_VERSION HWC_DEVICE_API_VERSION_0_1 +#define HWC_API_VERSION HWC_DEVICE_API_VERSION + +/*****************************************************************************/ + +/** + * The id of this module + */ +#define HWC_HARDWARE_MODULE_ID "hwcomposer" + +/** + * Name of the sensors device to open + */ +#define HWC_HARDWARE_COMPOSER "composer" + +typedef struct hwc_rect { + int left; + int top; + int right; + int bottom; +} hwc_rect_t; + +typedef struct hwc_frect { + float left; + float top; + float right; + float bottom; +} hwc_frect_t; + +typedef struct hwc_region { + size_t numRects; + hwc_rect_t const* rects; +} hwc_region_t; + +typedef struct hwc_color { + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; +} hwc_color_t; + +typedef struct hwc_layer_1 { + /* + * compositionType is used to specify this layer's type and is set by either + * the hardware composer implementation, or by the caller (see below). + * + * This field is always reset to HWC_BACKGROUND or HWC_FRAMEBUFFER + * before (*prepare)() is called when the HWC_GEOMETRY_CHANGED flag is + * also set, otherwise, this field is preserved between (*prepare)() + * calls. + * + * HWC_BACKGROUND + * Always set by the caller before calling (*prepare)(), this value + * indicates this is a special "background" layer. The only valid field + * is backgroundColor. + * The HWC can toggle this value to HWC_FRAMEBUFFER to indicate it CANNOT + * handle the background color. + * + * + * HWC_FRAMEBUFFER_TARGET + * Always set by the caller before calling (*prepare)(), this value + * indicates this layer is the framebuffer surface used as the target of + * OpenGL ES composition. If the HWC sets all other layers to HWC_OVERLAY + * or HWC_BACKGROUND, then no OpenGL ES composition will be done, and + * this layer should be ignored during set(). + * + * This flag (and the framebuffer surface layer) will only be used if the + * HWC version is HWC_DEVICE_API_VERSION_1_1 or higher. In older versions, + * the OpenGL ES target surface is communicated by the (dpy, sur) fields + * in hwc_compositor_device_1_t. + * + * This value cannot be set by the HWC implementation. + * + * + * HWC_FRAMEBUFFER + * Set by the caller before calling (*prepare)() ONLY when the + * HWC_GEOMETRY_CHANGED flag is also set. + * + * Set by the HWC implementation during (*prepare)(), this indicates + * that the layer will be drawn into the framebuffer using OpenGL ES. + * The HWC can toggle this value to HWC_OVERLAY to indicate it will + * handle the layer. + * + * + * HWC_OVERLAY + * Set by the HWC implementation during (*prepare)(), this indicates + * that the layer will be handled by the HWC (ie: it must not be + * composited with OpenGL ES). + * + * + * HWC_SIDEBAND + * Set by the caller before calling (*prepare)(), this value indicates + * the contents of this layer come from a sideband video stream. + * + * The h/w composer is responsible for receiving new image buffers from + * the stream at the appropriate time (e.g. synchronized to a separate + * audio stream), compositing them with the current contents of other + * layers, and displaying the resulting image. This happens + * independently of the normal prepare/set cycle. The prepare/set calls + * only happen when other layers change, or when properties of the + * sideband layer such as position or size change. + * + * If the h/w composer can't handle the layer as a sideband stream for + * some reason (e.g. unsupported scaling/blending/rotation, or too many + * sideband layers) it can set compositionType to HWC_FRAMEBUFFER in + * (*prepare)(). However, doing so will result in the layer being shown + * as a solid color since the platform is not currently able to composite + * sideband layers with the GPU. This may be improved in future + * versions of the platform. + * + * + * HWC_CURSOR_OVERLAY + * Set by the HWC implementation during (*prepare)(), this value + * indicates the layer's composition will now be handled by the HWC. + * Additionally, the client can now asynchronously update the on-screen + * position of this layer using the setCursorPositionAsync() api. + */ + int32_t compositionType; + + /* + * hints is bit mask set by the HWC implementation during (*prepare)(). + * It is preserved between (*prepare)() calls, unless the + * HWC_GEOMETRY_CHANGED flag is set, in which case it is reset to 0. + * + * see hwc_layer_t::hints + */ + uint32_t hints; + + /* see hwc_layer_t::flags */ + uint32_t flags; + + union { + /* color of the background. hwc_color_t.a is ignored */ + hwc_color_t backgroundColor; + + struct { + union { + /* When compositionType is HWC_FRAMEBUFFER, HWC_OVERLAY, + * HWC_FRAMEBUFFER_TARGET, this is the handle of the buffer to + * compose. This handle is guaranteed to have been allocated + * from gralloc using the GRALLOC_USAGE_HW_COMPOSER usage flag. + * If the layer's handle is unchanged across two consecutive + * prepare calls and the HWC_GEOMETRY_CHANGED flag is not set + * for the second call then the HWComposer implementation may + * assume that the contents of the buffer have not changed. */ + buffer_handle_t handle; + + /* When compositionType is HWC_SIDEBAND, this is the handle + * of the sideband video stream to compose. */ + const native_handle_t* sidebandStream; + }; + + /* transformation to apply to the buffer during composition */ + uint32_t transform; + + /* blending to apply during composition */ + int32_t blending; + + /* area of the source to consider, the origin is the top-left corner of + * the buffer. As of HWC_DEVICE_API_VERSION_1_3, sourceRect uses floats. + * If the h/w can't support a non-integer source crop rectangle, it should + * punt to OpenGL ES composition. + */ + union { + // crop rectangle in integer (pre HWC_DEVICE_API_VERSION_1_3) + hwc_rect_t sourceCropi; + hwc_rect_t sourceCrop; // just for source compatibility + // crop rectangle in floats (as of HWC_DEVICE_API_VERSION_1_3) + hwc_frect_t sourceCropf; + }; + + /* where to composite the sourceCrop onto the display. The sourceCrop + * is scaled using linear filtering to the displayFrame. The origin is the + * top-left corner of the screen. + */ + hwc_rect_t displayFrame; + + /* visible region in screen space. The origin is the + * top-left corner of the screen. + * The visible region INCLUDES areas overlapped by a translucent layer. + */ + hwc_region_t visibleRegionScreen; + + /* Sync fence object that will be signaled when the buffer's + * contents are available. May be -1 if the contents are already + * available. This field is only valid during set(), and should be + * ignored during prepare(). The set() call must not wait for the + * fence to be signaled before returning, but the HWC must wait for + * all buffers to be signaled before reading from them. + * + * HWC_FRAMEBUFFER layers will never have an acquire fence, since + * reads from them are complete before the framebuffer is ready for + * display. + * + * HWC_SIDEBAND layers will never have an acquire fence, since + * synchronization is handled through implementation-defined + * sideband mechanisms. + * + * The HWC takes ownership of the acquireFenceFd and is responsible + * for closing it when no longer needed. + */ + int acquireFenceFd; + + /* During set() the HWC must set this field to a file descriptor for + * a sync fence object that will signal after the HWC has finished + * reading from the buffer. The field is ignored by prepare(). Each + * layer should have a unique file descriptor, even if more than one + * refer to the same underlying fence object; this allows each to be + * closed independently. + * + * If buffer reads can complete at significantly different times, + * then using independent fences is preferred. For example, if the + * HWC handles some layers with a blit engine and others with + * overlays, then the blit layers can be reused immediately after + * the blit completes, but the overlay layers can't be reused until + * a subsequent frame has been displayed. + * + * Since HWC doesn't read from HWC_FRAMEBUFFER layers, it shouldn't + * produce a release fence for them. The releaseFenceFd will be -1 + * for these layers when set() is called. + * + * Since HWC_SIDEBAND buffers don't pass through the HWC client, + * the HWC shouldn't produce a release fence for them. The + * releaseFenceFd will be -1 for these layers when set() is called. + * + * The HWC client taks ownership of the releaseFenceFd and is + * responsible for closing it when no longer needed. + */ + int releaseFenceFd; + + /* + * Availability: HWC_DEVICE_API_VERSION_1_2 + * + * Alpha value applied to the whole layer. The effective + * value of each pixel is computed as: + * + * if (blending == HWC_BLENDING_PREMULT) + * pixel.rgb = pixel.rgb * planeAlpha / 255 + * pixel.a = pixel.a * planeAlpha / 255 + * + * Then blending proceeds as usual according to the "blending" + * field above. + * + * NOTE: planeAlpha applies to YUV layers as well: + * + * pixel.rgb = yuv_to_rgb(pixel.yuv) + * if (blending == HWC_BLENDING_PREMULT) + * pixel.rgb = pixel.rgb * planeAlpha / 255 + * pixel.a = planeAlpha + * + * + * IMPLEMENTATION NOTE: + * + * If the source image doesn't have an alpha channel, then + * the h/w can use the HWC_BLENDING_COVERAGE equations instead of + * HWC_BLENDING_PREMULT and simply set the alpha channel to + * planeAlpha. + * + * e.g.: + * + * if (blending == HWC_BLENDING_PREMULT) + * blending = HWC_BLENDING_COVERAGE; + * pixel.a = planeAlpha; + * + */ + uint8_t planeAlpha; + + /* Pad to 32 bits */ + uint8_t _pad[3]; + + /* + * Availability: HWC_DEVICE_API_VERSION_1_5 + * + * This defines the region of the source buffer that has been + * modified since the last frame. + * + * If surfaceDamage.numRects > 0, then it may be assumed that any + * portion of the source buffer not covered by one of the rects has + * not been modified this frame. If surfaceDamage.numRects == 0, + * then the whole source buffer must be treated as if it had been + * modified. + * + * If the layer's contents are not modified relative to the prior + * prepare/set cycle, surfaceDamage will contain exactly one empty + * rect ([0, 0, 0, 0]). + * + * The damage rects are relative to the pre-transformed buffer, and + * their origin is the top-left corner. + */ + hwc_region_t surfaceDamage; + }; + }; + +#ifdef __LP64__ + /* + * For 64-bit mode, this struct is 120 bytes (and 8-byte aligned), and needs + * to be padded as such to maintain binary compatibility. + */ + uint8_t reserved[120 - 112]; +#else + /* + * For 32-bit mode, this struct is 96 bytes, and needs to be padded as such + * to maintain binary compatibility. + */ + uint8_t reserved[96 - 84]; +#endif + +} hwc_layer_1_t; + +/* This represents a display, typically an EGLDisplay object */ +typedef void* hwc_display_t; + +/* This represents a surface, typically an EGLSurface object */ +typedef void* hwc_surface_t; + +/* + * hwc_display_contents_1_t::flags values + */ +enum { + /* + * HWC_GEOMETRY_CHANGED is set by SurfaceFlinger to indicate that the list + * passed to (*prepare)() has changed by more than just the buffer handles + * and acquire fences. + */ + HWC_GEOMETRY_CHANGED = 0x00000001, +}; + +/* + * Description of the contents to output on a display. + * + * This is the top-level structure passed to the prepare and set calls to + * negotiate and commit the composition of a display image. + */ +typedef struct hwc_display_contents_1 { + /* File descriptor referring to a Sync HAL fence object which will signal + * when this composition is retired. For a physical display, a composition + * is retired when it has been replaced on-screen by a subsequent set. For + * a virtual display, the composition is retired when the writes to + * outputBuffer are complete and can be read. The fence object is created + * and returned by the set call; this field will be -1 on entry to prepare + * and set. SurfaceFlinger will close the returned file descriptor. + */ + int retireFenceFd; + + union { + /* Fields only relevant for HWC_DEVICE_VERSION_1_0. */ + struct { + /* (dpy, sur) is the target of SurfaceFlinger's OpenGL ES + * composition for HWC_DEVICE_VERSION_1_0. They aren't relevant to + * prepare. The set call should commit this surface atomically to + * the display along with any overlay layers. + */ + hwc_display_t dpy; + hwc_surface_t sur; + }; + + /* These fields are used for virtual displays when the h/w composer + * version is at least HWC_DEVICE_VERSION_1_3. */ + struct { + /* outbuf is the buffer that receives the composed image for + * virtual displays. Writes to the outbuf must wait until + * outbufAcquireFenceFd signals. A fence that will signal when + * writes to outbuf are complete should be returned in + * retireFenceFd. + * + * This field is set before prepare(), so properties of the buffer + * can be used to decide which layers can be handled by h/w + * composer. + * + * If prepare() sets all layers to FRAMEBUFFER, then GLES + * composition will happen directly to the output buffer. In this + * case, both outbuf and the FRAMEBUFFER_TARGET layer's buffer will + * be the same, and set() has no work to do besides managing fences. + * + * If the TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS board config + * variable is defined (not the default), then this behavior is + * changed: if all layers are marked for FRAMEBUFFER, GLES + * composition will take place to a scratch framebuffer, and + * h/w composer must copy it to the output buffer. This allows the + * h/w composer to do format conversion if there are cases where + * that is more desirable than doing it in the GLES driver or at the + * virtual display consumer. + * + * If some or all layers are marked OVERLAY, then the framebuffer + * and output buffer will be different. As with physical displays, + * the framebuffer handle will not change between frames if all + * layers are marked for OVERLAY. + */ + buffer_handle_t outbuf; + + /* File descriptor for a fence that will signal when outbuf is + * ready to be written. The h/w composer is responsible for closing + * this when no longer needed. + * + * Will be -1 whenever outbuf is NULL, or when the outbuf can be + * written immediately. + */ + int outbufAcquireFenceFd; + }; + }; + + /* List of layers that will be composed on the display. The buffer handles + * in the list will be unique. If numHwLayers is 0, all composition will be + * performed by SurfaceFlinger. + */ + uint32_t flags; + size_t numHwLayers; + hwc_layer_1_t hwLayers[0]; + +} hwc_display_contents_1_t; + +/* see hwc_composer_device::registerProcs() + * All of the callbacks are required and non-NULL unless otherwise noted. + */ +typedef struct hwc_procs { + /* + * (*invalidate)() triggers a screen refresh, in particular prepare and set + * will be called shortly after this call is made. Note that there is + * NO GUARANTEE that the screen refresh will happen after invalidate() + * returns (in particular, it could happen before). + * invalidate() is GUARANTEED TO NOT CALL BACK into the h/w composer HAL and + * it is safe to call invalidate() from any of hwc_composer_device + * hooks, unless noted otherwise. + */ + void (*invalidate)(const struct hwc_procs* procs); + + /* + * (*vsync)() is called by the h/w composer HAL when a vsync event is + * received and HWC_EVENT_VSYNC is enabled on a display + * (see: hwc_event_control). + * + * the "disp" parameter indicates which display the vsync event is for. + * the "timestamp" parameter is the system monotonic clock timestamp in + * nanosecond of when the vsync event happened. + * + * vsync() is GUARANTEED TO NOT CALL BACK into the h/w composer HAL. + * + * It is expected that vsync() is called from a thread of at least + * HAL_PRIORITY_URGENT_DISPLAY with as little latency as possible, + * typically less than 0.5 ms. + * + * It is a (silent) error to have HWC_EVENT_VSYNC enabled when calling + * hwc_composer_device.set(..., 0, 0, 0) (screen off). The implementation + * can either stop or continue to process VSYNC events, but must not + * crash or cause other problems. + */ + void (*vsync)(const struct hwc_procs* procs, int disp, int64_t timestamp); + + /* + * (*hotplug)() is called by the h/w composer HAL when a display is + * connected or disconnected. The PRIMARY display is always connected and + * the hotplug callback should not be called for it. + * + * The disp parameter indicates which display type this event is for. + * The connected parameter indicates whether the display has just been + * connected (1) or disconnected (0). + * + * The hotplug() callback may call back into the h/w composer on the same + * thread to query refresh rate and dpi for the display. Additionally, + * other threads may be calling into the h/w composer while the callback + * is in progress. + * + * The h/w composer must serialize calls to the hotplug callback; only + * one thread may call it at a time. + * + * This callback will be NULL if the h/w composer is using + * HWC_DEVICE_API_VERSION_1_0. + */ + void (*hotplug)(const struct hwc_procs* procs, int disp, int connected); + +} hwc_procs_t; + + +/*****************************************************************************/ + +typedef struct hwc_module { + /** + * Common methods of the hardware composer module. This *must* be the first member of + * hwc_module as users of this structure will cast a hw_module_t to + * hwc_module pointer in contexts where it's known the hw_module_t references a + * hwc_module. + */ + struct hw_module_t common; +} hwc_module_t; + +typedef struct hwc_composer_device_1 { + /** + * Common methods of the hardware composer device. This *must* be the first member of + * hwc_composer_device_1 as users of this structure will cast a hw_device_t to + * hwc_composer_device_1 pointer in contexts where it's known the hw_device_t references a + * hwc_composer_device_1. + */ + struct hw_device_t common; + + /* + * (*prepare)() is called for each frame before composition and is used by + * SurfaceFlinger to determine what composition steps the HWC can handle. + * + * (*prepare)() can be called more than once, the last call prevails. + * + * The HWC responds by setting the compositionType field in each layer to + * either HWC_FRAMEBUFFER, HWC_OVERLAY, or HWC_CURSOR_OVERLAY. For the + * HWC_FRAMEBUFFER type, composition for the layer is handled by + * SurfaceFlinger with OpenGL ES. For the latter two overlay types, + * the HWC will have to handle the layer's composition. compositionType + * and hints are preserved between (*prepare)() calles unless the + * HWC_GEOMETRY_CHANGED flag is set. + * + * (*prepare)() is called with HWC_GEOMETRY_CHANGED to indicate that the + * list's geometry has changed, that is, when more than just the buffer's + * handles have been updated. Typically this happens (but is not limited to) + * when a window is added, removed, resized or moved. In this case + * compositionType and hints are reset to their default value. + * + * For HWC 1.0, numDisplays will always be one, and displays[0] will be + * non-NULL. + * + * For HWC 1.1, numDisplays will always be HWC_NUM_PHYSICAL_DISPLAY_TYPES. + * Entries for unsupported or disabled/disconnected display types will be + * NULL. + * + * In HWC 1.3, numDisplays may be up to HWC_NUM_DISPLAY_TYPES. The extra + * entries correspond to enabled virtual displays, and will be non-NULL. + * + * returns: 0 on success. An negative error code on error. If an error is + * returned, SurfaceFlinger will assume that none of the layer will be + * handled by the HWC. + */ + int (*prepare)(struct hwc_composer_device_1 *dev, + size_t numDisplays, hwc_display_contents_1_t** displays); + + /* + * (*set)() is used in place of eglSwapBuffers(), and assumes the same + * functionality, except it also commits the work list atomically with + * the actual eglSwapBuffers(). + * + * The layer lists are guaranteed to be the same as the ones returned from + * the last call to (*prepare)(). + * + * When this call returns the caller assumes that the displays will be + * updated in the near future with the content of their work lists, without + * artifacts during the transition from the previous frame. + * + * A display with zero layers indicates that the entire composition has + * been handled by SurfaceFlinger with OpenGL ES. In this case, (*set)() + * behaves just like eglSwapBuffers(). + * + * For HWC 1.0, numDisplays will always be one, and displays[0] will be + * non-NULL. + * + * For HWC 1.1, numDisplays will always be HWC_NUM_PHYSICAL_DISPLAY_TYPES. + * Entries for unsupported or disabled/disconnected display types will be + * NULL. + * + * In HWC 1.3, numDisplays may be up to HWC_NUM_DISPLAY_TYPES. The extra + * entries correspond to enabled virtual displays, and will be non-NULL. + * + * IMPORTANT NOTE: There is an implicit layer containing opaque black + * pixels behind all the layers in the list. It is the responsibility of + * the hwcomposer module to make sure black pixels are output (or blended + * from). + * + * IMPORTANT NOTE: In the event of an error this call *MUST* still cause + * any fences returned in the previous call to set to eventually become + * signaled. The caller may have already issued wait commands on these + * fences, and having set return without causing those fences to signal + * will likely result in a deadlock. + * + * returns: 0 on success. A negative error code on error: + * HWC_EGL_ERROR: eglGetError() will provide the proper error code (only + * allowed prior to HWComposer 1.1) + * Another code for non EGL errors. + */ + int (*set)(struct hwc_composer_device_1 *dev, + size_t numDisplays, hwc_display_contents_1_t** displays); + + /* + * eventControl(..., event, enabled) + * Enables or disables h/w composer events for a display. + * + * eventControl can be called from any thread and takes effect + * immediately. + * + * Supported events are: + * HWC_EVENT_VSYNC + * + * returns -EINVAL if the "event" parameter is not one of the value above + * or if the "enabled" parameter is not 0 or 1. + */ + int (*eventControl)(struct hwc_composer_device_1* dev, int disp, + int event, int enabled); + + union { + /* + * For HWC 1.3 and earlier, the blank() interface is used. + * + * blank(..., blank) + * Blanks or unblanks a display's screen. + * + * Turns the screen off when blank is nonzero, on when blank is zero. + * Multiple sequential calls with the same blank value must be + * supported. + * The screen state transition must be be complete when the function + * returns. + * + * returns 0 on success, negative on error. + */ + int (*blank)(struct hwc_composer_device_1* dev, int disp, int blank); + + /* + * For HWC 1.4 and above, setPowerMode() will be used in place of + * blank(). + * + * setPowerMode(..., mode) + * Sets the display screen's power state. + * + * Refer to the documentation of the HWC_POWER_MODE_* constants + * for information about each power mode. + * + * The functionality is similar to the blank() command in previous + * versions of HWC, but with support for more power states. + * + * The display driver is expected to retain and restore the low power + * state of the display while entering and exiting from suspend. + * + * Multiple sequential calls with the same mode value must be supported. + * + * The screen state transition must be be complete when the function + * returns. + * + * returns 0 on success, negative on error. + */ + int (*setPowerMode)(struct hwc_composer_device_1* dev, int disp, + int mode); + }; + + /* + * Used to retrieve information about the h/w composer + * + * Returns 0 on success or -errno on error. + */ + int (*query)(struct hwc_composer_device_1* dev, int what, int* value); + + /* + * (*registerProcs)() registers callbacks that the h/w composer HAL can + * later use. It will be called immediately after the composer device is + * opened with non-NULL procs. It is FORBIDDEN to call any of the callbacks + * from within registerProcs(). registerProcs() must save the hwc_procs_t + * pointer which is needed when calling a registered callback. + */ + void (*registerProcs)(struct hwc_composer_device_1* dev, + hwc_procs_t const* procs); + + /* + * This field is OPTIONAL and can be NULL. + * + * If non NULL it will be called by SurfaceFlinger on dumpsys + */ + void (*dump)(struct hwc_composer_device_1* dev, char *buff, int buff_len); + + /* + * (*getDisplayConfigs)() returns handles for the configurations available + * on the connected display. These handles must remain valid as long as the + * display is connected. + * + * Configuration handles are written to configs. The number of entries + * allocated by the caller is passed in *numConfigs; getDisplayConfigs must + * not try to write more than this number of config handles. On return, the + * total number of configurations available for the display is returned in + * *numConfigs. If *numConfigs is zero on entry, then configs may be NULL. + * + * Hardware composers implementing HWC_DEVICE_API_VERSION_1_3 or prior + * shall choose one configuration to activate and report it as the first + * entry in the returned list. Reporting the inactive configurations is not + * required. + * + * HWC_DEVICE_API_VERSION_1_4 and later provide configuration management + * through SurfaceFlinger, and hardware composers implementing these APIs + * must also provide getActiveConfig and setActiveConfig. Hardware composers + * implementing these API versions may choose not to activate any + * configuration, leaving configuration selection to higher levels of the + * framework. + * + * Returns 0 on success or a negative error code on error. If disp is a + * hotpluggable display type and no display is connected, an error shall be + * returned. + * + * This field is REQUIRED for HWC_DEVICE_API_VERSION_1_1 and later. + * It shall be NULL for previous versions. + */ + int (*getDisplayConfigs)(struct hwc_composer_device_1* dev, int disp, + uint32_t* configs, size_t* numConfigs); + + /* + * (*getDisplayAttributes)() returns attributes for a specific config of a + * connected display. The config parameter is one of the config handles + * returned by getDisplayConfigs. + * + * The list of attributes to return is provided in the attributes + * parameter, terminated by HWC_DISPLAY_NO_ATTRIBUTE. The value for each + * requested attribute is written in order to the values array. The + * HWC_DISPLAY_NO_ATTRIBUTE attribute does not have a value, so the values + * array will have one less value than the attributes array. + * + * This field is REQUIRED for HWC_DEVICE_API_VERSION_1_1 and later. + * It shall be NULL for previous versions. + * + * If disp is a hotpluggable display type and no display is connected, + * or if config is not a valid configuration for the display, a negative + * error code shall be returned. + */ + int (*getDisplayAttributes)(struct hwc_composer_device_1* dev, int disp, + uint32_t config, const uint32_t* attributes, int32_t* values); + + /* + * (*getActiveConfig)() returns the index of the configuration that is + * currently active on the connected display. The index is relative to + * the list of configuration handles returned by getDisplayConfigs. If there + * is no active configuration, -1 shall be returned. + * + * Returns the configuration index on success or -1 on error. + * + * This field is REQUIRED for HWC_DEVICE_API_VERSION_1_4 and later. + * It shall be NULL for previous versions. + */ + int (*getActiveConfig)(struct hwc_composer_device_1* dev, int disp); + + /* + * (*setActiveConfig)() instructs the hardware composer to switch to the + * display configuration at the given index in the list of configuration + * handles returned by getDisplayConfigs. + * + * If this function returns without error, any subsequent calls to + * getActiveConfig shall return the index set by this function until one + * of the following occurs: + * 1) Another successful call of this function + * 2) The display is disconnected + * + * Returns 0 on success or a negative error code on error. If disp is a + * hotpluggable display type and no display is connected, or if index is + * outside of the range of hardware configurations returned by + * getDisplayConfigs, an error shall be returned. + * + * This field is REQUIRED for HWC_DEVICE_API_VERSION_1_4 and later. + * It shall be NULL for previous versions. + */ + int (*setActiveConfig)(struct hwc_composer_device_1* dev, int disp, + int index); + /* + * Asynchronously update the location of the cursor layer. + * + * Within the standard prepare()/set() composition loop, the client + * (surfaceflinger) can request that a given layer uses dedicated cursor + * composition hardware by specifiying the HWC_IS_CURSOR_LAYER flag. Only + * one layer per display can have this flag set. If the layer is suitable + * for the platform's cursor hardware, hwcomposer will return from prepare() + * a composition type of HWC_CURSOR_OVERLAY for that layer. This indicates + * not only that the client is not responsible for compositing that layer, + * but also that the client can continue to update the position of that layer + * after a call to set(). This can reduce the visible latency of mouse + * movement to visible, on-screen cursor updates. Calls to + * setCursorPositionAsync() may be made from a different thread doing the + * prepare()/set() composition loop, but care must be taken to not interleave + * calls of setCursorPositionAsync() between calls of set()/prepare(). + * + * Notes: + * - Only one layer per display can be specified as a cursor layer with + * HWC_IS_CURSOR_LAYER. + * - hwcomposer will only return one layer per display as HWC_CURSOR_OVERLAY + * - This returns 0 on success or -errno on error. + * - This field is optional for HWC_DEVICE_API_VERSION_1_4 and later. It + * should be null for previous versions. + */ + int (*setCursorPositionAsync)(struct hwc_composer_device_1 *dev, int disp, int x_pos, int y_pos); + + /* + * Reserved for future use. Must be NULL. + */ + void* reserved_proc[1]; + +} hwc_composer_device_1_t; + +/** convenience API for opening and closing a device */ + +static inline int hwc_open_1(const struct hw_module_t* module, + hwc_composer_device_1_t** device) { + return module->methods->open(module, + HWC_HARDWARE_COMPOSER, (struct hw_device_t**)device); +} + +static inline int hwc_close_1(hwc_composer_device_1_t* device) { + return device->common.close(&device->common); +} + +/*****************************************************************************/ + +__END_DECLS + +#endif /* ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/hwcomposer_defs.h b/phonelibs/android_hardware_libhardware/include/hardware/hwcomposer_defs.h new file mode 100644 index 00000000000000..a90822a4b81288 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/hwcomposer_defs.h @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_DEFS_H +#define ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_DEFS_H + +#include +#include + +#include +#include +#include + +__BEGIN_DECLS + +/*****************************************************************************/ + +#define HWC_HEADER_VERSION 1 + +#define HWC_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1) + +#define HWC_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION_2(1, 0, HWC_HEADER_VERSION) +#define HWC_DEVICE_API_VERSION_1_1 HARDWARE_DEVICE_API_VERSION_2(1, 1, HWC_HEADER_VERSION) +#define HWC_DEVICE_API_VERSION_1_2 HARDWARE_DEVICE_API_VERSION_2(1, 2, HWC_HEADER_VERSION) +#define HWC_DEVICE_API_VERSION_1_3 HARDWARE_DEVICE_API_VERSION_2(1, 3, HWC_HEADER_VERSION) +#define HWC_DEVICE_API_VERSION_1_4 HARDWARE_DEVICE_API_VERSION_2(1, 4, HWC_HEADER_VERSION) +#define HWC_DEVICE_API_VERSION_1_5 HARDWARE_DEVICE_API_VERSION_2(1, 5, HWC_HEADER_VERSION) + +enum { + /* hwc_composer_device_t::set failed in EGL */ + HWC_EGL_ERROR = -1 +}; + +/* + * hwc_layer_t::hints values + * Hints are set by the HAL and read by SurfaceFlinger + */ +enum { + /* + * HWC can set the HWC_HINT_TRIPLE_BUFFER hint to indicate to SurfaceFlinger + * that it should triple buffer this layer. Typically HWC does this when + * the layer will be unavailable for use for an extended period of time, + * e.g. if the display will be fetching data directly from the layer and + * the layer can not be modified until after the next set(). + */ + HWC_HINT_TRIPLE_BUFFER = 0x00000001, + + /* + * HWC sets HWC_HINT_CLEAR_FB to tell SurfaceFlinger that it should clear the + * framebuffer with transparent pixels where this layer would be. + * SurfaceFlinger will only honor this flag when the layer has no blending + * + */ + HWC_HINT_CLEAR_FB = 0x00000002 +}; + +/* + * hwc_layer_t::flags values + * Flags are set by SurfaceFlinger and read by the HAL + */ +enum { + /* + * HWC_SKIP_LAYER is set by SurfaceFlnger to indicate that the HAL + * shall not consider this layer for composition as it will be handled + * by SurfaceFlinger (just as if compositionType was set to HWC_OVERLAY). + */ + HWC_SKIP_LAYER = 0x00000001, + + /* + * HWC_IS_CURSOR_LAYER is set by surfaceflinger to indicate that this + * layer is being used as a cursor on this particular display, and that + * surfaceflinger can potentially perform asynchronous position updates for + * this layer. If a call to prepare() returns HWC_CURSOR_OVERLAY for the + * composition type of this layer, then the hwcomposer will allow async + * position updates to this layer via setCursorPositionAsync(). + */ + HWC_IS_CURSOR_LAYER = 0x00000002 +}; + +/* + * hwc_layer_t::compositionType values + */ +enum { + /* this layer is to be drawn into the framebuffer by SurfaceFlinger */ + HWC_FRAMEBUFFER = 0, + + /* this layer will be handled in the HWC */ + HWC_OVERLAY = 1, + + /* this is the background layer. it's used to set the background color. + * there is only a single background layer */ + HWC_BACKGROUND = 2, + + /* this layer holds the result of compositing the HWC_FRAMEBUFFER layers. + * Added in HWC_DEVICE_API_VERSION_1_1. */ + HWC_FRAMEBUFFER_TARGET = 3, + + /* this layer's contents are taken from a sideband buffer stream. + * Added in HWC_DEVICE_API_VERSION_1_4. */ + HWC_SIDEBAND = 4, + + /* this layer's composition will be handled by hwcomposer by dedicated + cursor overlay hardware. hwcomposer will also all async position updates + of this layer outside of the normal prepare()/set() loop. Added in + HWC_DEVICE_API_VERSION_1_4. */ + HWC_CURSOR_OVERLAY = 5 + }; +/* + * hwc_layer_t::blending values + */ +enum { + /* no blending */ + HWC_BLENDING_NONE = 0x0100, + + /* ONE / ONE_MINUS_SRC_ALPHA */ + HWC_BLENDING_PREMULT = 0x0105, + + /* SRC_ALPHA / ONE_MINUS_SRC_ALPHA */ + HWC_BLENDING_COVERAGE = 0x0405 +}; + +/* + * hwc_layer_t::transform values + */ +enum { + /* flip source image horizontally */ + HWC_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H, + /* flip source image vertically */ + HWC_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V, + /* rotate source image 90 degrees clock-wise */ + HWC_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90, + /* rotate source image 180 degrees */ + HWC_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180, + /* rotate source image 270 degrees clock-wise */ + HWC_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270, +}; + +/* attributes queriable with query() */ +enum { + /* + * Must return 1 if the background layer is supported, 0 otherwise. + */ + HWC_BACKGROUND_LAYER_SUPPORTED = 0, + + /* + * Returns the vsync period in nanoseconds. + * + * This query is not used for HWC_DEVICE_API_VERSION_1_1 and later. + * Instead, the per-display attribute HWC_DISPLAY_VSYNC_PERIOD is used. + */ + HWC_VSYNC_PERIOD = 1, + + /* + * Availability: HWC_DEVICE_API_VERSION_1_1 + * Returns a mask of supported display types. + */ + HWC_DISPLAY_TYPES_SUPPORTED = 2, +}; + +/* display attributes returned by getDisplayAttributes() */ +enum { + /* Indicates the end of an attribute list */ + HWC_DISPLAY_NO_ATTRIBUTE = 0, + + /* The vsync period in nanoseconds */ + HWC_DISPLAY_VSYNC_PERIOD = 1, + + /* The number of pixels in the horizontal and vertical directions. */ + HWC_DISPLAY_WIDTH = 2, + HWC_DISPLAY_HEIGHT = 3, + + /* The number of pixels per thousand inches of this configuration. + * + * Scaling DPI by 1000 allows it to be stored in an int without losing + * too much precision. + * + * If the DPI for a configuration is unavailable or the HWC implementation + * considers it unreliable, it should set these attributes to zero. + */ + HWC_DISPLAY_DPI_X = 4, + HWC_DISPLAY_DPI_Y = 5, + + /* Indicates which of the vendor-defined color transforms is provided by + * this configuration. */ + HWC_DISPLAY_COLOR_TRANSFORM = 6, +}; + +/* Allowed events for hwc_methods::eventControl() */ +enum { + HWC_EVENT_VSYNC = 0 +}; + +/* Display types and associated mask bits. */ +enum { + HWC_DISPLAY_PRIMARY = 0, + HWC_DISPLAY_EXTERNAL = 1, // HDMI, DP, etc. +#ifdef QTI_BSP + HWC_DISPLAY_TERTIARY = 2, + HWC_DISPLAY_VIRTUAL = 3, + + HWC_NUM_PHYSICAL_DISPLAY_TYPES = 3, + HWC_NUM_DISPLAY_TYPES = 4, +#else + HWC_DISPLAY_VIRTUAL = 2, + + HWC_NUM_PHYSICAL_DISPLAY_TYPES = 2, + HWC_NUM_DISPLAY_TYPES = 3, +#endif +}; + +enum { + HWC_DISPLAY_PRIMARY_BIT = 1 << HWC_DISPLAY_PRIMARY, + HWC_DISPLAY_EXTERNAL_BIT = 1 << HWC_DISPLAY_EXTERNAL, +#ifdef QTI_BSP + HWC_DISPLAY_TERTIARY_BIT = 1 << HWC_DISPLAY_TERTIARY, +#endif + HWC_DISPLAY_VIRTUAL_BIT = 1 << HWC_DISPLAY_VIRTUAL, +}; + +/* Display power modes */ +enum { + /* The display is turned off (blanked). */ + HWC_POWER_MODE_OFF = 0, + /* The display is turned on and configured in a low power state + * that is suitable for presenting ambient information to the user, + * possibly with lower fidelity than normal but greater efficiency. */ + HWC_POWER_MODE_DOZE = 1, + /* The display is turned on normally. */ + HWC_POWER_MODE_NORMAL = 2, + /* The display is configured as in HWC_POWER_MODE_DOZE but may + * stop applying frame buffer updates from the graphics subsystem. + * This power mode is effectively a hint from the doze dream to + * tell the hardware that it is done drawing to the display for the + * time being and that the display should remain on in a low power + * state and continue showing its current contents indefinitely + * until the mode changes. + * + * This mode may also be used as a signal to enable hardware-based doze + * functionality. In this case, the doze dream is effectively + * indicating that the hardware is free to take over the display + * and manage it autonomously to implement low power always-on display + * functionality. */ + HWC_POWER_MODE_DOZE_SUSPEND = 3, +}; + +/*****************************************************************************/ + +__END_DECLS + +#endif /* ANDROID_INCLUDE_HARDWARE_HWCOMPOSER_DEFS_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/input.h b/phonelibs/android_hardware_libhardware/include/hardware/input.h new file mode 100644 index 00000000000000..969b8ce5701af7 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/input.h @@ -0,0 +1,549 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_HARDWARE_INPUT_H +#define ANDROID_INCLUDE_HARDWARE_INPUT_H + +#include +#include + +__BEGIN_DECLS + +#define INPUT_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0) +#define INPUT_HARDWARE_MODULE_ID "input" + +#define INPUT_INSTANCE_EVDEV "evdev" + +typedef enum input_bus { + INPUT_BUS_BT, + INPUT_BUS_USB, + INPUT_BUS_SERIAL, + INPUT_BUS_BUILTIN +} input_bus_t; + +typedef struct input_host input_host_t; + +typedef struct input_device_handle input_device_handle_t; + +typedef struct input_device_identifier input_device_identifier_t; + +typedef struct input_device_definition input_device_definition_t; + +typedef struct input_report_definition input_report_definition_t; + +typedef struct input_report input_report_t; + +typedef struct input_collection input_collection_t; + +typedef struct input_property_map input_property_map_t; + +typedef struct input_property input_property_t; + +typedef enum { + // keycodes + INPUT_USAGE_KEYCODE_UNKNOWN, + INPUT_USAGE_KEYCODE_SOFT_LEFT, + INPUT_USAGE_KEYCODE_SOFT_RIGHT, + INPUT_USAGE_KEYCODE_HOME, + INPUT_USAGE_KEYCODE_BACK, + INPUT_USAGE_KEYCODE_CALL, + INPUT_USAGE_KEYCODE_ENDCALL, + INPUT_USAGE_KEYCODE_0, + INPUT_USAGE_KEYCODE_1, + INPUT_USAGE_KEYCODE_2, + INPUT_USAGE_KEYCODE_3, + INPUT_USAGE_KEYCODE_4, + INPUT_USAGE_KEYCODE_5, + INPUT_USAGE_KEYCODE_6, + INPUT_USAGE_KEYCODE_7, + INPUT_USAGE_KEYCODE_8, + INPUT_USAGE_KEYCODE_9, + INPUT_USAGE_KEYCODE_STAR, + INPUT_USAGE_KEYCODE_POUND, + INPUT_USAGE_KEYCODE_DPAD_UP, + INPUT_USAGE_KEYCODE_DPAD_DOWN, + INPUT_USAGE_KEYCODE_DPAD_LEFT, + INPUT_USAGE_KEYCODE_DPAD_RIGHT, + INPUT_USAGE_KEYCODE_DPAD_CENTER, + INPUT_USAGE_KEYCODE_VOLUME_UP, + INPUT_USAGE_KEYCODE_VOLUME_DOWN, + INPUT_USAGE_KEYCODE_POWER, + INPUT_USAGE_KEYCODE_CAMERA, + INPUT_USAGE_KEYCODE_CLEAR, + INPUT_USAGE_KEYCODE_A, + INPUT_USAGE_KEYCODE_B, + INPUT_USAGE_KEYCODE_C, + INPUT_USAGE_KEYCODE_D, + INPUT_USAGE_KEYCODE_E, + INPUT_USAGE_KEYCODE_F, + INPUT_USAGE_KEYCODE_G, + INPUT_USAGE_KEYCODE_H, + INPUT_USAGE_KEYCODE_I, + INPUT_USAGE_KEYCODE_J, + INPUT_USAGE_KEYCODE_K, + INPUT_USAGE_KEYCODE_L, + INPUT_USAGE_KEYCODE_M, + INPUT_USAGE_KEYCODE_N, + INPUT_USAGE_KEYCODE_O, + INPUT_USAGE_KEYCODE_P, + INPUT_USAGE_KEYCODE_Q, + INPUT_USAGE_KEYCODE_R, + INPUT_USAGE_KEYCODE_S, + INPUT_USAGE_KEYCODE_T, + INPUT_USAGE_KEYCODE_U, + INPUT_USAGE_KEYCODE_V, + INPUT_USAGE_KEYCODE_W, + INPUT_USAGE_KEYCODE_X, + INPUT_USAGE_KEYCODE_Y, + INPUT_USAGE_KEYCODE_Z, + INPUT_USAGE_KEYCODE_COMMA, + INPUT_USAGE_KEYCODE_PERIOD, + INPUT_USAGE_KEYCODE_ALT_LEFT, + INPUT_USAGE_KEYCODE_ALT_RIGHT, + INPUT_USAGE_KEYCODE_SHIFT_LEFT, + INPUT_USAGE_KEYCODE_SHIFT_RIGHT, + INPUT_USAGE_KEYCODE_TAB, + INPUT_USAGE_KEYCODE_SPACE, + INPUT_USAGE_KEYCODE_SYM, + INPUT_USAGE_KEYCODE_EXPLORER, + INPUT_USAGE_KEYCODE_ENVELOPE, + INPUT_USAGE_KEYCODE_ENTER, + INPUT_USAGE_KEYCODE_DEL, + INPUT_USAGE_KEYCODE_GRAVE, + INPUT_USAGE_KEYCODE_MINUS, + INPUT_USAGE_KEYCODE_EQUALS, + INPUT_USAGE_KEYCODE_LEFT_BRACKET, + INPUT_USAGE_KEYCODE_RIGHT_BRACKET, + INPUT_USAGE_KEYCODE_BACKSLASH, + INPUT_USAGE_KEYCODE_SEMICOLON, + INPUT_USAGE_KEYCODE_APOSTROPHE, + INPUT_USAGE_KEYCODE_SLASH, + INPUT_USAGE_KEYCODE_AT, + INPUT_USAGE_KEYCODE_NUM, + INPUT_USAGE_KEYCODE_HEADSETHOOK, + INPUT_USAGE_KEYCODE_FOCUS, // *Camera* focus + INPUT_USAGE_KEYCODE_PLUS, + INPUT_USAGE_KEYCODE_MENU, + INPUT_USAGE_KEYCODE_NOTIFICATION, + INPUT_USAGE_KEYCODE_SEARCH, + INPUT_USAGE_KEYCODE_MEDIA_PLAY_PAUSE, + INPUT_USAGE_KEYCODE_MEDIA_STOP, + INPUT_USAGE_KEYCODE_MEDIA_NEXT, + INPUT_USAGE_KEYCODE_MEDIA_PREVIOUS, + INPUT_USAGE_KEYCODE_MEDIA_REWIND, + INPUT_USAGE_KEYCODE_MEDIA_FAST_FORWARD, + INPUT_USAGE_KEYCODE_MUTE, + INPUT_USAGE_KEYCODE_PAGE_UP, + INPUT_USAGE_KEYCODE_PAGE_DOWN, + INPUT_USAGE_KEYCODE_PICTSYMBOLS, + INPUT_USAGE_KEYCODE_SWITCH_CHARSET, + INPUT_USAGE_KEYCODE_BUTTON_A, + INPUT_USAGE_KEYCODE_BUTTON_B, + INPUT_USAGE_KEYCODE_BUTTON_C, + INPUT_USAGE_KEYCODE_BUTTON_X, + INPUT_USAGE_KEYCODE_BUTTON_Y, + INPUT_USAGE_KEYCODE_BUTTON_Z, + INPUT_USAGE_KEYCODE_BUTTON_L1, + INPUT_USAGE_KEYCODE_BUTTON_R1, + INPUT_USAGE_KEYCODE_BUTTON_L2, + INPUT_USAGE_KEYCODE_BUTTON_R2, + INPUT_USAGE_KEYCODE_BUTTON_THUMBL, + INPUT_USAGE_KEYCODE_BUTTON_THUMBR, + INPUT_USAGE_KEYCODE_BUTTON_START, + INPUT_USAGE_KEYCODE_BUTTON_SELECT, + INPUT_USAGE_KEYCODE_BUTTON_MODE, + INPUT_USAGE_KEYCODE_ESCAPE, + INPUT_USAGE_KEYCODE_FORWARD_DEL, + INPUT_USAGE_KEYCODE_CTRL_LEFT, + INPUT_USAGE_KEYCODE_CTRL_RIGHT, + INPUT_USAGE_KEYCODE_CAPS_LOCK, + INPUT_USAGE_KEYCODE_SCROLL_LOCK, + INPUT_USAGE_KEYCODE_META_LEFT, + INPUT_USAGE_KEYCODE_META_RIGHT, + INPUT_USAGE_KEYCODE_FUNCTION, + INPUT_USAGE_KEYCODE_SYSRQ, + INPUT_USAGE_KEYCODE_BREAK, + INPUT_USAGE_KEYCODE_MOVE_HOME, + INPUT_USAGE_KEYCODE_MOVE_END, + INPUT_USAGE_KEYCODE_INSERT, + INPUT_USAGE_KEYCODE_FORWARD, + INPUT_USAGE_KEYCODE_MEDIA_PLAY, + INPUT_USAGE_KEYCODE_MEDIA_PAUSE, + INPUT_USAGE_KEYCODE_MEDIA_CLOSE, + INPUT_USAGE_KEYCODE_MEDIA_EJECT, + INPUT_USAGE_KEYCODE_MEDIA_RECORD, + INPUT_USAGE_KEYCODE_F1, + INPUT_USAGE_KEYCODE_F2, + INPUT_USAGE_KEYCODE_F3, + INPUT_USAGE_KEYCODE_F4, + INPUT_USAGE_KEYCODE_F5, + INPUT_USAGE_KEYCODE_F6, + INPUT_USAGE_KEYCODE_F7, + INPUT_USAGE_KEYCODE_F8, + INPUT_USAGE_KEYCODE_F9, + INPUT_USAGE_KEYCODE_F10, + INPUT_USAGE_KEYCODE_F11, + INPUT_USAGE_KEYCODE_F12, + INPUT_USAGE_KEYCODE_NUM_LOCK, + INPUT_USAGE_KEYCODE_NUMPAD_0, + INPUT_USAGE_KEYCODE_NUMPAD_1, + INPUT_USAGE_KEYCODE_NUMPAD_2, + INPUT_USAGE_KEYCODE_NUMPAD_3, + INPUT_USAGE_KEYCODE_NUMPAD_4, + INPUT_USAGE_KEYCODE_NUMPAD_5, + INPUT_USAGE_KEYCODE_NUMPAD_6, + INPUT_USAGE_KEYCODE_NUMPAD_7, + INPUT_USAGE_KEYCODE_NUMPAD_8, + INPUT_USAGE_KEYCODE_NUMPAD_9, + INPUT_USAGE_KEYCODE_NUMPAD_DIVIDE, + INPUT_USAGE_KEYCODE_NUMPAD_MULTIPLY, + INPUT_USAGE_KEYCODE_NUMPAD_SUBTRACT, + INPUT_USAGE_KEYCODE_NUMPAD_ADD, + INPUT_USAGE_KEYCODE_NUMPAD_DOT, + INPUT_USAGE_KEYCODE_NUMPAD_COMMA, + INPUT_USAGE_KEYCODE_NUMPAD_ENTER, + INPUT_USAGE_KEYCODE_NUMPAD_EQUALS, + INPUT_USAGE_KEYCODE_NUMPAD_LEFT_PAREN, + INPUT_USAGE_KEYCODE_NUMPAD_RIGHT_PAREN, + INPUT_USAGE_KEYCODE_VOLUME_MUTE, + INPUT_USAGE_KEYCODE_INFO, + INPUT_USAGE_KEYCODE_CHANNEL_UP, + INPUT_USAGE_KEYCODE_CHANNEL_DOWN, + INPUT_USAGE_KEYCODE_ZOOM_IN, + INPUT_USAGE_KEYCODE_ZOOM_OUT, + INPUT_USAGE_KEYCODE_TV, + INPUT_USAGE_KEYCODE_WINDOW, + INPUT_USAGE_KEYCODE_GUIDE, + INPUT_USAGE_KEYCODE_DVR, + INPUT_USAGE_KEYCODE_BOOKMARK, + INPUT_USAGE_KEYCODE_CAPTIONS, + INPUT_USAGE_KEYCODE_SETTINGS, + INPUT_USAGE_KEYCODE_TV_POWER, + INPUT_USAGE_KEYCODE_TV_INPUT, + INPUT_USAGE_KEYCODE_STB_POWER, + INPUT_USAGE_KEYCODE_STB_INPUT, + INPUT_USAGE_KEYCODE_AVR_POWER, + INPUT_USAGE_KEYCODE_AVR_INPUT, + INPUT_USAGE_KEYCODE_PROG_RED, + INPUT_USAGE_KEYCODE_PROG_GREEN, + INPUT_USAGE_KEYCODE_PROG_YELLOW, + INPUT_USAGE_KEYCODE_PROG_BLUE, + INPUT_USAGE_KEYCODE_APP_SWITCH, + INPUT_USAGE_KEYCODE_BUTTON_1, + INPUT_USAGE_KEYCODE_BUTTON_2, + INPUT_USAGE_KEYCODE_BUTTON_3, + INPUT_USAGE_KEYCODE_BUTTON_4, + INPUT_USAGE_KEYCODE_BUTTON_5, + INPUT_USAGE_KEYCODE_BUTTON_6, + INPUT_USAGE_KEYCODE_BUTTON_7, + INPUT_USAGE_KEYCODE_BUTTON_8, + INPUT_USAGE_KEYCODE_BUTTON_9, + INPUT_USAGE_KEYCODE_BUTTON_10, + INPUT_USAGE_KEYCODE_BUTTON_11, + INPUT_USAGE_KEYCODE_BUTTON_12, + INPUT_USAGE_KEYCODE_BUTTON_13, + INPUT_USAGE_KEYCODE_BUTTON_14, + INPUT_USAGE_KEYCODE_BUTTON_15, + INPUT_USAGE_KEYCODE_BUTTON_16, + INPUT_USAGE_KEYCODE_LANGUAGE_SWITCH, + INPUT_USAGE_KEYCODE_MANNER_MODE, + INPUT_USAGE_KEYCODE_3D_MODE, + INPUT_USAGE_KEYCODE_CONTACTS, + INPUT_USAGE_KEYCODE_CALENDAR, + INPUT_USAGE_KEYCODE_MUSIC, + INPUT_USAGE_KEYCODE_CALCULATOR, + INPUT_USAGE_KEYCODE_ZENKAKU_HANKAKU, + INPUT_USAGE_KEYCODE_EISU, + INPUT_USAGE_KEYCODE_MUHENKAN, + INPUT_USAGE_KEYCODE_HENKAN, + INPUT_USAGE_KEYCODE_KATAKANA_HIRAGANA, + INPUT_USAGE_KEYCODE_YEN, + INPUT_USAGE_KEYCODE_RO, + INPUT_USAGE_KEYCODE_KANA, + INPUT_USAGE_KEYCODE_ASSIST, + INPUT_USAGE_KEYCODE_BRIGHTNESS_DOWN, + INPUT_USAGE_KEYCODE_BRIGHTNESS_UP, + INPUT_USAGE_KEYCODE_MEDIA_AUDIO_TRACK, + INPUT_USAGE_KEYCODE_SLEEP, + INPUT_USAGE_KEYCODE_WAKEUP, + INPUT_USAGE_KEYCODE_PAIRING, + INPUT_USAGE_KEYCODE_MEDIA_TOP_MENU, + INPUT_USAGE_KEYCODE_11, + INPUT_USAGE_KEYCODE_12, + INPUT_USAGE_KEYCODE_LAST_CHANNEL, + INPUT_USAGE_KEYCODE_TV_DATA_SERVICE, + INPUT_USAGE_KEYCODE_VOICE_ASSIST, + INPUT_USAGE_KEYCODE_TV_RADIO_SERVICE, + INPUT_USAGE_KEYCODE_TV_TELETEXT, + INPUT_USAGE_KEYCODE_TV_NUMBER_ENTRY, + INPUT_USAGE_KEYCODE_TV_TERRESTRIAL_ANALOG, + INPUT_USAGE_KEYCODE_TV_TERRESTRIAL_DIGITAL, + INPUT_USAGE_KEYCODE_TV_SATELLITE, + INPUT_USAGE_KEYCODE_TV_SATELLITE_BS, + INPUT_USAGE_KEYCODE_TV_SATELLITE_CS, + INPUT_USAGE_KEYCODE_TV_SATELLITE_SERVICE, + INPUT_USAGE_KEYCODE_TV_NETWORK, + INPUT_USAGE_KEYCODE_TV_ANTENNA_CABLE, + INPUT_USAGE_KEYCODE_TV_INPUT_HDMI_1, + INPUT_USAGE_KEYCODE_TV_INPUT_HDMI_2, + INPUT_USAGE_KEYCODE_TV_INPUT_HDMI_3, + INPUT_USAGE_KEYCODE_TV_INPUT_HDMI_4, + INPUT_USAGE_KEYCODE_TV_INPUT_COMPOSITE_1, + INPUT_USAGE_KEYCODE_TV_INPUT_COMPOSITE_2, + INPUT_USAGE_KEYCODE_TV_INPUT_COMPONENT_1, + INPUT_USAGE_KEYCODE_TV_INPUT_COMPONENT_2, + INPUT_USAGE_KEYCODE_TV_INPUT_VGA_1, + INPUT_USAGE_KEYCODE_TV_AUDIO_DESCRIPTION, + INPUT_USAGE_KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP, + INPUT_USAGE_KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN, + INPUT_USAGE_KEYCODE_TV_ZOOM_MODE, + INPUT_USAGE_KEYCODE_TV_CONTENTS_MENU, + INPUT_USAGE_KEYCODE_TV_MEDIA_CONTEXT_MENU, + INPUT_USAGE_KEYCODE_TV_TIMER_PROGRAMMING, + INPUT_USAGE_KEYCODE_HELP, + + // axes + INPUT_USAGE_AXIS_X, + INPUT_USAGE_AXIS_Y, + INPUT_USAGE_AXIS_PRESSURE, + INPUT_USAGE_AXIS_SIZE, + INPUT_USAGE_AXIS_TOUCH_MAJOR, + INPUT_USAGE_AXIS_TOUCH_MINOR, + INPUT_USAGE_AXIS_TOOL_MAJOR, + INPUT_USAGE_AXIS_TOOL_MINOR, + INPUT_USAGE_AXIS_ORIENTATION, + INPUT_USAGE_AXIS_VSCROLL, + INPUT_USAGE_AXIS_HSCROLL, + INPUT_USAGE_AXIS_Z, + INPUT_USAGE_AXIS_RX, + INPUT_USAGE_AXIS_RY, + INPUT_USAGE_AXIS_RZ, + INPUT_USAGE_AXIS_HAT_X, + INPUT_USAGE_AXIS_HAT_Y, + INPUT_USAGE_AXIS_LTRIGGER, + INPUT_USAGE_AXIS_RTRIGGER, + INPUT_USAGE_AXIS_THROTTLE, + INPUT_USAGE_AXIS_RUDDER, + INPUT_USAGE_AXIS_WHEEL, + INPUT_USAGE_AXIS_GAS, + INPUT_USAGE_AXIS_BRAKE, + INPUT_USAGE_AXIS_DISTANCE, + INPUT_USAGE_AXIS_TILT, + INPUT_USAGE_AXIS_GENERIC_1, + INPUT_USAGE_AXIS_GENERIC_2, + INPUT_USAGE_AXIS_GENERIC_3, + INPUT_USAGE_AXIS_GENERIC_4, + INPUT_USAGE_AXIS_GENERIC_5, + INPUT_USAGE_AXIS_GENERIC_6, + INPUT_USAGE_AXIS_GENERIC_7, + INPUT_USAGE_AXIS_GENERIC_8, + INPUT_USAGE_AXIS_GENERIC_9, + INPUT_USAGE_AXIS_GENERIC_10, + INPUT_USAGE_AXIS_GENERIC_11, + INPUT_USAGE_AXIS_GENERIC_12, + INPUT_USAGE_AXIS_GENERIC_13, + INPUT_USAGE_AXIS_GENERIC_14, + INPUT_USAGE_AXIS_GENERIC_15, + INPUT_USAGE_AXIS_GENERIC_16, + + // leds + INPUT_USAGE_LED_NUM_LOCK, + INPUT_USAGE_LED_CAPS_LOCK, + INPUT_USAGE_LED_SCROLL_LOCK, + INPUT_USAGE_LED_COMPOSE, + INPUT_USAGE_LED_KANA, + INPUT_USAGE_LED_SLEEP, + INPUT_USAGE_LED_SUSPEND, + INPUT_USAGE_LED_MUTE, + INPUT_USAGE_LED_MISC, + INPUT_USAGE_LED_MAIL, + INPUT_USAGE_LED_CHARGING, + INPUT_USAGE_LED_CONTROLLER_1, + INPUT_USAGE_LED_CONTROLLER_2, + INPUT_USAGE_LED_CONTROLLER_3, + INPUT_USAGE_LED_CONTROLLER_4, +} input_usage_t; + +typedef enum { + INPUT_COLLECTION_ID_TOUCH, + INPUT_COLLECTION_ID_KEYBOARD, + INPUT_COLLECTION_ID_MOUSE, + INPUT_COLLECTION_ID_TOUCHPAD, + // etc +} input_collection_id_t; + +typedef struct input_message input_message_t; + +typedef struct input_host_callbacks { + + /** + * Creates a device identifier with the given properties. + * The unique ID should be a string that precisely identifies a given piece of hardware. For + * example, an input device connected via Bluetooth could use its MAC address as its unique ID. + */ + input_device_identifier_t* (*create_device_identifier)(input_host_t* host, + const char* name, int32_t product_id, int32_t vendor_id, + input_bus_t bus, const char* unique_id); + + /** + * Allocates the device definition which will describe the input capabilities of a device. A + * device definition may be used to register as many devices as desired. + */ + input_device_definition_t* (*create_device_definition)(input_host_t* host); + + /** + * Allocate either an input report, which the HAL will use to tell the host of incoming input + * events, or an output report, which the host will use to tell the HAL of desired state + * changes (e.g. setting an LED). + */ + input_report_definition_t* (*create_input_report_definition)(input_host_t* host); + input_report_definition_t* (*create_output_report_definition)(input_host_t* host); + + /** + * Append the report to the given input device. + */ + void (*input_device_definition_add_report)(input_host_t* host, + input_device_definition_t* d, input_report_definition_t* r); + + /** + * Add a collection with the given arity and ID. A collection describes a set + * of logically grouped properties such as the X and Y coordinates of a single finger touch or + * the set of keys on a keyboard. The arity declares how many repeated instances of this + * collection will appear in whatever report it is attached to. The ID describes the type of + * grouping being represented by the collection. For example, a touchscreen capable of + * reporting up to 2 fingers simultaneously might have a collection with the X and Y + * coordinates, an arity of 2, and an ID of INPUT_COLLECTION_USAGE_TOUCHSCREEN. Any given ID + * may only be present once for a given report. + */ + void (*input_report_definition_add_collection)(input_host_t* host, + input_report_definition_t* report, input_collection_id_t id, int32_t arity); + + /** + * Declare an int usage with the given properties. The report and collection defines where the + * usage is being declared. + */ + void (*input_report_definition_declare_usage_int)(input_host_t* host, + input_report_definition_t* report, input_collection_id_t id, + input_usage_t usage, int32_t min, int32_t max, float resolution); + + /** + * Declare a set of boolean usages with the given properties. The report and collection + * defines where the usages are being declared. + */ + void (*input_report_definition_declare_usages_bool)(input_host_t* host, + input_report_definition_t* report, input_collection_id_t id, + input_usage_t* usage, size_t usage_count); + + + /** + * Register a given input device definition. This notifies the host that an input device has + * been connected and gives a description of all its capabilities. + */ + input_device_handle_t* (*register_device)(input_host_t* host, + input_device_identifier_t* id, input_device_definition_t* d); + + /** Unregister the given device */ + void (*unregister_device)(input_host_t* host, input_device_handle_t* handle); + + /** + * Allocate a report that will contain all of the state as described by the given report. + */ + input_report_t* (*input_allocate_report)(input_host_t* host, input_report_definition_t* r); + + /** + * Add an int usage value to a report. + */ + void (*input_report_set_usage_int)(input_host_t* host, input_report_t* r, + input_collection_id_t id, input_usage_t usage, int32_t value, int32_t arity_index); + + /** + * Add a boolean usage value to a report. + */ + void (*input_report_set_usage_bool)(input_host_t* host, input_report_t* r, + input_collection_id_t id, input_usage_t usage, bool value, int32_t arity_index); + + void (*report_event)(input_host_t* host, input_device_handle_t* d, input_report_t* report); + + /** + * Retrieve the set of properties for the device. The returned + * input_property_map_t* may be used to query specific properties via the + * input_get_device_property callback. + */ + input_property_map_t* (*input_get_device_property_map)(input_host_t* host, + input_device_identifier_t* id); + /** + * Retrieve a property for the device with the given key. Returns NULL if + * the key does not exist, or an input_property_t* that must be freed using + * input_free_device_property(). Using an input_property_t after the + * corresponding input_property_map_t is freed is undefined. + */ + input_property_t* (*input_get_device_property)(input_host_t* host, + input_property_map_t* map, const char* key); + + /** + * Get the key for the input property. Returns NULL if the property is NULL. + * The returned const char* is owned by the input_property_t. + */ + const char* (*input_get_property_key)(input_host_t* host, input_property_t* property); + + /** + * Get the value for the input property. Returns NULL if the property is + * NULL. The returned const char* is owned by the input_property_t. + */ + const char* (*input_get_property_value)(input_host_t* host, input_property_t* property); + + /** + * Frees the input_property_t*. + */ + void (*input_free_device_property)(input_host_t* host, input_property_t* property); + + /** + * Frees the input_property_map_t*. + */ + void (*input_free_device_property_map)(input_host_t* host, input_property_map_t* map); +} input_host_callbacks_t; + +typedef struct input_module input_module_t; + +struct input_module { + /** + * Common methods of the input module. This *must* be the first member + * of input_module as users of this structure will cast a hw_module_t + * to input_module pointer in contexts where it's known + * the hw_module_t references a input_module. + */ + struct hw_module_t common; + + /** + * Initialize the module with host callbacks. At this point the HAL should start up whatever + * infrastructure it needs to in order to process input events. + */ + void (*init)(const input_module_t* module, input_host_t* host, input_host_callbacks_t cb); + + /** + * Sends an output report with a new set of state the host would like the given device to + * assume. + */ + void (*notify_report)(const input_module_t* module, input_report_t* report); +}; + +static inline int input_open(const struct hw_module_t** module, const char* type) { + return hw_get_module_by_class(INPUT_HARDWARE_MODULE_ID, type, module); +} + +__END_DECLS + +#endif /* ANDROID_INCLUDE_HARDWARE_INPUT_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/keymaster0.h b/phonelibs/android_hardware_libhardware/include/hardware/keymaster0.h new file mode 100644 index 00000000000000..f020e5b188a838 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/keymaster0.h @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_KEYMASTER_0_H +#define ANDROID_HARDWARE_KEYMASTER_0_H + +#include + +__BEGIN_DECLS + +/** + * Keymaster0 device definition. + */ +struct keymaster0_device { + /** + * Common methods of the keymaster device. This *must* be the first member of + * keymaster0_device as users of this structure will cast a hw_device_t to + * keymaster0_device pointer in contexts where it's known the hw_device_t references a + * keymaster0_device. + */ + struct hw_device_t common; + + /** + * THIS IS DEPRECATED. Use the new "module_api_version" and "hal_api_version" + * fields in the keymaster_module initialization instead. + */ + uint32_t client_version; + + /** + * See flags defined for keymaster0_device::flags in keymaster_common.h + */ + uint32_t flags; + + void* context; + + /** + * Generates a public and private key. The key-blob returned is opaque + * and must subsequently provided for signing and verification. + * + * Returns: 0 on success or an error code less than 0. + */ + int (*generate_keypair)(const struct keymaster0_device* dev, + const keymaster_keypair_t key_type, const void* key_params, + uint8_t** key_blob, size_t* key_blob_length); + + /** + * Imports a public and private key pair. The imported keys will be in + * PKCS#8 format with DER encoding (Java standard). The key-blob + * returned is opaque and will be subsequently provided for signing + * and verification. + * + * Returns: 0 on success or an error code less than 0. + */ + int (*import_keypair)(const struct keymaster0_device* dev, + const uint8_t* key, const size_t key_length, + uint8_t** key_blob, size_t* key_blob_length); + + /** + * Gets the public key part of a key pair. The public key must be in + * X.509 format (Java standard) encoded byte array. + * + * Returns: 0 on success or an error code less than 0. + * On error, x509_data should not be allocated. + */ + int (*get_keypair_public)(const struct keymaster0_device* dev, + const uint8_t* key_blob, const size_t key_blob_length, + uint8_t** x509_data, size_t* x509_data_length); + + /** + * Deletes the key pair associated with the key blob. + * + * This function is optional and should be set to NULL if it is not + * implemented. + * + * Returns 0 on success or an error code less than 0. + */ + int (*delete_keypair)(const struct keymaster0_device* dev, + const uint8_t* key_blob, const size_t key_blob_length); + + /** + * Deletes all keys in the hardware keystore. Used when keystore is + * reset completely. + * + * This function is optional and should be set to NULL if it is not + * implemented. + * + * Returns 0 on success or an error code less than 0. + */ + int (*delete_all)(const struct keymaster0_device* dev); + + /** + * Signs data using a key-blob generated before. This can use either + * an asymmetric key or a secret key. + * + * Returns: 0 on success or an error code less than 0. + */ + int (*sign_data)(const struct keymaster0_device* dev, + const void* signing_params, + const uint8_t* key_blob, const size_t key_blob_length, + const uint8_t* data, const size_t data_length, + uint8_t** signed_data, size_t* signed_data_length); + + /** + * Verifies data signed with a key-blob. This can use either + * an asymmetric key or a secret key. + * + * Returns: 0 on successful verification or an error code less than 0. + */ + int (*verify_data)(const struct keymaster0_device* dev, + const void* signing_params, + const uint8_t* key_blob, const size_t key_blob_length, + const uint8_t* signed_data, const size_t signed_data_length, + const uint8_t* signature, const size_t signature_length); +}; +typedef struct keymaster0_device keymaster0_device_t; + + +/* Convenience API for opening and closing keymaster devices */ + +static inline int keymaster0_open(const struct hw_module_t* module, + keymaster0_device_t** device) +{ + int rc = module->methods->open(module, KEYSTORE_KEYMASTER, + (struct hw_device_t**) device); + + return rc; +} + +static inline int keymaster0_close(keymaster0_device_t* device) +{ + return device->common.close(&device->common); +} + +__END_DECLS + +#endif // ANDROID_HARDWARE_KEYMASTER_0_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/keymaster1.h b/phonelibs/android_hardware_libhardware/include/hardware/keymaster1.h new file mode 100644 index 00000000000000..ac2cc2b4083524 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/keymaster1.h @@ -0,0 +1,597 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_KEYMASTER1_H +#define ANDROID_HARDWARE_KEYMASTER1_H + +#include +#include + +__BEGIN_DECLS + +/** + * Keymaster1 device definition + */ +struct keymaster1_device { + /** + * Common methods of the keymaster device. This *must* be the first member of + * keymaster_device as users of this structure will cast a hw_device_t to + * keymaster_device pointer in contexts where it's known the hw_device_t references a + * keymaster_device. + */ + struct hw_device_t common; + + /** + * THIS IS DEPRECATED. Use the new "module_api_version" and "hal_api_version" + * fields in the keymaster_module initialization instead. + */ + uint32_t client_version; + + /** + * See flags defined for keymaster0_devices::flags in keymaster_common.h + */ + uint32_t flags; + + void* context; + + /** + * \deprecated Generates a public and private key. The key-blob returned is opaque and must + * subsequently provided for signing and verification. + * + * Returns: 0 on success or an error code less than 0. + */ + int (*generate_keypair)(const struct keymaster1_device* dev, const keymaster_keypair_t key_type, + const void* key_params, uint8_t** key_blob, size_t* key_blob_length); + + /** + * \deprecated Imports a public and private key pair. The imported keys will be in PKCS#8 format + * with DER encoding (Java standard). The key-blob returned is opaque and will be subsequently + * provided for signing and verification. + * + * Returns: 0 on success or an error code less than 0. + */ + int (*import_keypair)(const struct keymaster1_device* dev, const uint8_t* key, + const size_t key_length, uint8_t** key_blob, size_t* key_blob_length); + + /** + * \deprecated Gets the public key part of a key pair. The public key must be in X.509 format + * (Java standard) encoded byte array. + * + * Returns: 0 on success or an error code less than 0. On error, x509_data + * should not be allocated. + */ + int (*get_keypair_public)(const struct keymaster1_device* dev, const uint8_t* key_blob, + const size_t key_blob_length, uint8_t** x509_data, + size_t* x509_data_length); + + /** + * \deprecated Deletes the key pair associated with the key blob. + * + * This function is optional and should be set to NULL if it is not + * implemented. + * + * Returns 0 on success or an error code less than 0. + */ + int (*delete_keypair)(const struct keymaster1_device* dev, const uint8_t* key_blob, + const size_t key_blob_length); + + /** + * \deprecated Deletes all keys in the hardware keystore. Used when keystore is reset + * completely. + * + * This function is optional and should be set to NULL if it is not + * implemented. + * + * Returns 0 on success or an error code less than 0. + */ + int (*delete_all)(const struct keymaster1_device* dev); + + /** + * \deprecated Signs data using a key-blob generated before. This can use either an asymmetric + * key or a secret key. + * + * Returns: 0 on success or an error code less than 0. + */ + int (*sign_data)(const struct keymaster1_device* dev, const void* signing_params, + const uint8_t* key_blob, const size_t key_blob_length, const uint8_t* data, + const size_t data_length, uint8_t** signed_data, size_t* signed_data_length); + + /** + * \deprecated Verifies data signed with a key-blob. This can use either an asymmetric key or a + * secret key. + * + * Returns: 0 on successful verification or an error code less than 0. + */ + int (*verify_data)(const struct keymaster1_device* dev, const void* signing_params, + const uint8_t* key_blob, const size_t key_blob_length, + const uint8_t* signed_data, const size_t signed_data_length, + const uint8_t* signature, const size_t signature_length); + + /** + * Gets algorithms supported. + * + * \param[in] dev The keymaster device structure. + * + * \param[out] algorithms Array of algorithms supported. The caller takes ownership of the + * array and must free() it. + * + * \param[out] algorithms_length Length of \p algorithms. + */ + keymaster_error_t (*get_supported_algorithms)(const struct keymaster1_device* dev, + keymaster_algorithm_t** algorithms, + size_t* algorithms_length); + + /** + * Gets the block modes supported for the specified algorithm. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] algorithm The algorithm for which supported modes will be returned. + * + * \param[out] modes Array of modes supported. The caller takes ownership of the array and must + * free() it. + * + * \param[out] modes_length Length of \p modes. + */ + keymaster_error_t (*get_supported_block_modes)(const struct keymaster1_device* dev, + keymaster_algorithm_t algorithm, + keymaster_purpose_t purpose, + keymaster_block_mode_t** modes, + size_t* modes_length); + + /** + * Gets the padding modes supported for the specified algorithm. Caller assumes ownership of + * the allocated array. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] algorithm The algorithm for which supported padding modes will be returned. + * + * \param[out] modes Array of padding modes supported. The caller takes ownership of the array + * and must free() it. + * + * \param[out] modes_length Length of \p modes. + */ + keymaster_error_t (*get_supported_padding_modes)(const struct keymaster1_device* dev, + keymaster_algorithm_t algorithm, + keymaster_purpose_t purpose, + keymaster_padding_t** modes, + size_t* modes_length); + + /** + * Gets the digests supported for the specified algorithm. Caller assumes ownership of the + * allocated array. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] algorithm The algorithm for which supported digests will be returned. + * + * \param[out] digests Array of digests supported. The caller takes ownership of the array and + * must free() it. + * + * \param[out] digests_length Length of \p digests. + */ + keymaster_error_t (*get_supported_digests)(const struct keymaster1_device* dev, + keymaster_algorithm_t algorithm, + keymaster_purpose_t purpose, + keymaster_digest_t** digests, + size_t* digests_length); + + /** + * Gets the key import formats supported for keys of the specified algorithm. Caller assumes + * ownership of the allocated array. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] algorithm The algorithm for which supported formats will be returned. + * + * \param[out] formats Array of formats supported. The caller takes ownership of the array and + * must free() it. + * + * \param[out] formats_length Length of \p formats. + */ + keymaster_error_t (*get_supported_import_formats)(const struct keymaster1_device* dev, + keymaster_algorithm_t algorithm, + keymaster_key_format_t** formats, + size_t* formats_length); + + /** + * Gets the key export formats supported for keys of the specified algorithm. Caller assumes + * ownership of the allocated array. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] algorithm The algorithm for which supported formats will be returned. + * + * \param[out] formats Array of formats supported. The caller takes ownership of the array and + * must free() it. + * + * \param[out] formats_length Length of \p formats. + */ + keymaster_error_t (*get_supported_export_formats)(const struct keymaster1_device* dev, + keymaster_algorithm_t algorithm, + keymaster_key_format_t** formats, + size_t* formats_length); + + /** + * Adds entropy to the RNG used by keymaster. Entropy added through this method is guaranteed + * not to be the only source of entropy used, and the mixing function is required to be secure, + * in the sense that if the RNG is seeded (from any source) with any data the attacker cannot + * predict (or control), then the RNG output is indistinguishable from random. Thus, if the + * entropy from any source is good, the output will be good. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] data Random data to be mixed in. + * + * \param[in] data_length Length of \p data. + */ + keymaster_error_t (*add_rng_entropy)(const struct keymaster1_device* dev, const uint8_t* data, + size_t data_length); + + /** + * Generates a key, or key pair, returning a key blob and/or a description of the key. + * + * Key generation parameters are defined as keymaster tag/value pairs, provided in \p params. + * See keymaster_tag_t for the full list. Some values that are always required for generation + * of useful keys are: + * + * - KM_TAG_ALGORITHM; + * - KM_TAG_PURPOSE; and + * - (KM_TAG_USER_SECURE_ID and KM_TAG_USER_AUTH_TYPE) or KM_TAG_NO_AUTH_REQUIRED. + * + * KM_TAG_AUTH_TIMEOUT should generally be specified unless KM_TAG_NO_AUTH_REQUIRED is present, + * or the user will have to authenticate for every use. + * + * KM_TAG_BLOCK_MODE, KM_TAG_PADDING, KM_TAG_MAC_LENGTH and KM_TAG_DIGEST must be specified for + * algorithms that require them. + * + * The following tags may not be specified; their values will be provided by the implementation. + * + * - KM_TAG_ORIGIN, + * - KM_TAG_ROLLBACK_RESISTANT, + * - KM_TAG_CREATION_DATETIME + * + * \param[in] dev The keymaster device structure. + * + * \param[in] params Array of key generation parameters. + * + * \param[in] params_count Length of \p params. + * + * \param[out] key_blob returns the generated key. \p key_blob must not be NULL. The caller + * assumes ownership key_blob->key_material and must free() it. + * + * \param[out] characteristics returns the characteristics of the key that was, generated, if + * non-NULL. If non-NULL, the caller assumes ownership and must deallocate with + * keymaster_free_characteristics(). Note that KM_TAG_ROOT_OF_TRUST, KM_TAG_APPLICATION_ID and + * KM_TAG_APPLICATION_DATA are never returned. + */ + keymaster_error_t (*generate_key)(const struct keymaster1_device* dev, + const keymaster_key_param_set_t* params, + keymaster_key_blob_t* key_blob, + keymaster_key_characteristics_t** characteristics); + + /** + * Returns the characteristics of the specified key, or KM_ERROR_INVALID_KEY_BLOB if the + * key_blob is invalid (implementations must fully validate the integrity of the key). + * client_id and app_data must be the ID and data provided when the key was generated or + * imported, or empty if KM_TAG_APPLICATION_ID and/or KM_TAG_APPLICATION_DATA were not provided + * during generation. Those values are not included in the returned characteristics. The + * caller assumes ownership of the allocated characteristics object, which must be deallocated + * with keymaster_free_characteristics(). + * + * Note that KM_TAG_ROOT_OF_TRUST, KM_TAG_APPLICATION_ID and KM_TAG_APPLICATION_DATA are never + * returned. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] key_blob The key to retreive characteristics from. + * + * \param[in] client_id The client ID data, or NULL if none associated. + * + * \param[in] app_id The app data, or NULL if none associated. + * + * \param[out] characteristics The key characteristics. + */ + keymaster_error_t (*get_key_characteristics)(const struct keymaster1_device* dev, + const keymaster_key_blob_t* key_blob, + const keymaster_blob_t* client_id, + const keymaster_blob_t* app_data, + keymaster_key_characteristics_t** characteristics); + + /** + * Imports a key, or key pair, returning a key blob and/or a description of the key. + * + * Most key import parameters are defined as keymaster tag/value pairs, provided in "params". + * See keymaster_tag_t for the full list. Values that are always required for import of useful + * keys are: + * + * - KM_TAG_ALGORITHM; + * - KM_TAG_PURPOSE; and + * - (KM_TAG_USER_SECURE_ID and KM_TAG_USER_AUTH_TYPE) or KM_TAG_NO_AUTH_REQUIRED. + * + * KM_TAG_AUTH_TIMEOUT should generally be specified. If unspecified, the user will have to + * authenticate for every use. + * + * The following tags will take default values if unspecified: + * + * - KM_TAG_KEY_SIZE will default to the size of the key provided. + * - KM_TAG_RSA_PUBLIC_EXPONENT will default to the value in the key provided (for RSA keys) + * + * The following tags may not be specified; their values will be provided by the implementation. + * + * - KM_TAG_ORIGIN, + * - KM_TAG_ROLLBACK_RESISTANT, + * - KM_TAG_CREATION_DATETIME + * + * \param[in] dev The keymaster device structure. + * + * \param[in] params Parameters defining the imported key. + * + * \param[in] params_count The number of entries in \p params. + * + * \param[in] key_format specifies the format of the key data in key_data. + * + * \param[out] key_blob Used to return the opaque key blob. Must be non-NULL. The caller + * assumes ownership of the contained key_material. + * + * \param[out] characteristics Used to return the characteristics of the imported key. May be + * NULL, in which case no characteristics will be returned. If non-NULL, the caller assumes + * ownership and must deallocate with keymaster_free_characteristics(). Note that + * KM_TAG_ROOT_OF_TRUST, KM_TAG_APPLICATION_ID and + * KM_TAG_APPLICATION_DATA are never returned. + */ + keymaster_error_t (*import_key)(const struct keymaster1_device* dev, + const keymaster_key_param_set_t* params, + keymaster_key_format_t key_format, + const keymaster_blob_t* key_data, + keymaster_key_blob_t* key_blob, + keymaster_key_characteristics_t** characteristics); + + /** + * Exports a public key, returning a byte array in the specified format. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] export_format The format to be used for exporting the key. + * + * \param[in] key_to_export The key to export. + * + * \param[out] export_data The exported key material. The caller assumes ownership. + * + * \param[out] export_data_length The length of \p export_data. + */ + keymaster_error_t (*export_key)(const struct keymaster1_device* dev, + keymaster_key_format_t export_format, + const keymaster_key_blob_t* key_to_export, + const keymaster_blob_t* client_id, + const keymaster_blob_t* app_data, + keymaster_blob_t* export_data); + + /** + * Deletes the key, or key pair, associated with the key blob. After calling this function it + * will be impossible to use the key for any other operations. May be applied to keys from + * foreign roots of trust (keys not usable under the current root of trust). + * + * This function is optional and should be set to NULL if it is not implemented. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] key The key to be deleted. + */ + keymaster_error_t (*delete_key)(const struct keymaster1_device* dev, + const keymaster_key_blob_t* key); + + /** + * Deletes all keys in the hardware keystore. Used when keystore is reset completely. After + * calling this function it will be impossible to use any previously generated or imported key + * blobs for any operations. + * + * This function is optional and should be set to NULL if it is not implemented. + * + * \param[in] dev The keymaster device structure. + */ + keymaster_error_t (*delete_all_keys)(const struct keymaster1_device* dev); + + /** + * Begins a cryptographic operation using the specified key. If all is well, begin() will + * return KM_ERROR_OK and create an operation handle which must be passed to subsequent calls to + * update(), finish() or abort(). + * + * It is critical that each call to begin() be paired with a subsequent call to finish() or + * abort(), to allow the keymaster implementation to clean up any internal operation state. + * Failure to do this may leak internal state space or other internal resources and may + * eventually cause begin() to return KM_ERROR_TOO_MANY_OPERATIONS when it runs out of space for + * operations. Any result other than KM_ERROR_OK from begin(), update() or finish() implicitly + * aborts the operation, in which case abort() need not be called (and will return + * KM_ERROR_INVALID_OPERATION_HANDLE if called). + * + * \param[in] dev The keymaster device structure. + * + * \param[in] purpose The purpose of the operation, one of KM_PURPOSE_ENCRYPT, + * KM_PURPOSE_DECRYPT, KM_PURPOSE_SIGN or KM_PURPOSE_VERIFY. Note that for AEAD modes, + * encryption and decryption imply signing and verification, respectively, but should be + * specified as KM_PURPOSE_ENCRYPT and KM_PURPOSE_DECRYPT. + * + * \param[in] key The key to be used for the operation. \p key must have a purpose compatible + * with \p purpose and all of its usage requirements must be satisfied, or begin() will return + * an appropriate error code. + * + * \param[in] in_params Additional parameters for the operation. This is typically used to + * provide authentication data, with KM_TAG_AUTH_TOKEN. If KM_TAG_APPLICATION_ID or + * KM_TAG_APPLICATION_DATA were provided during generation, they must be provided here, or the + * operation will fail with KM_ERROR_INVALID_KEY_BLOB. For operations that require a nonce or + * IV, on keys that were generated with KM_TAG_CALLER_NONCE, in_params may contain a tag + * KM_TAG_NONCE. For AEAD operations KM_TAG_CHUNK_SIZE is specified here. + * + * \param[out] out_params Output parameters. Used to return additional data from the operation + * initialization, notably to return the IV or nonce from operations that generate an IV or + * nonce. The caller takes ownership of the output parameters array and must free it with + * keymaster_free_param_set(). out_params may be set to NULL if no output parameters are + * expected. If out_params is NULL, and output paramaters are generated, begin() will return + * KM_ERROR_OUTPUT_PARAMETER_NULL. + * + * \param[out] operation_handle The newly-created operation handle which must be passed to + * update(), finish() or abort(). If operation_handle is NULL, begin() will return + * KM_ERROR_OUTPUT_PARAMETER_NULL. + */ + keymaster_error_t (*begin)(const struct keymaster1_device* dev, keymaster_purpose_t purpose, + const keymaster_key_blob_t* key, + const keymaster_key_param_set_t* in_params, + keymaster_key_param_set_t* out_params, + keymaster_operation_handle_t* operation_handle); + + /** + * Provides data to, and possibly receives output from, an ongoing cryptographic operation begun + * with begin(). + * + * If operation_handle is invalid, update() will return KM_ERROR_INVALID_OPERATION_HANDLE. + * + * update() may not consume all of the data provided in the data buffer. update() will return + * the amount consumed in *data_consumed. The caller should provide the unconsumed data in a + * subsequent call. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] operation_handle The operation handle returned by begin(). + * + * \param[in] in_params Additional parameters for the operation. For AEAD modes, this is used + * to specify KM_TAG_ADDITIONAL_DATA. Note that additional data may be provided in multiple + * calls to update(), but only until input data has been provided. + * + * \param[in] input Data to be processed, per the parameters established in the call to begin(). + * Note that update() may or may not consume all of the data provided. See \p input_consumed. + * + * \param[out] input_consumed Amount of data that was consumed by update(). If this is less + * than the amount provided, the caller should provide the remainder in a subsequent call to + * update(). + * + * \param[out] out_params Output parameters. Used to return additional data from the operation + * The caller takes ownership of the output parameters array and must free it with + * keymaster_free_param_set(). out_params may be set to NULL if no output parameters are + * expected. If out_params is NULL, and output paramaters are generated, begin() will return + * KM_ERROR_OUTPUT_PARAMETER_NULL. + * + * \param[out] output The output data, if any. The caller assumes ownership of the allocated + * buffer. output must not be NULL. + * + * Note that update() may not provide any output, in which case output->data_length will be + * zero, and output->data may be either NULL or zero-length (so the caller should always free() + * it). + */ + keymaster_error_t (*update)(const struct keymaster1_device* dev, + keymaster_operation_handle_t operation_handle, + const keymaster_key_param_set_t* in_params, + const keymaster_blob_t* input, size_t* input_consumed, + keymaster_key_param_set_t* out_params, keymaster_blob_t* output); + + /** + * Finalizes a cryptographic operation begun with begin() and invalidates \p operation_handle. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] operation_handle The operation handle returned by begin(). This handle will be + * invalidated. + * + * \param[in] params Additional parameters for the operation. For AEAD modes, this is used to + * specify KM_TAG_ADDITIONAL_DATA, but only if no input data was provided to update(). + * + * \param[in] signature The signature to be verified if the purpose specified in the begin() + * call was KM_PURPOSE_VERIFY. + * + * \param[out] output The output data, if any. The caller assumes ownership of the allocated + * buffer. + * + * If the operation being finished is a signature verification or an AEAD-mode decryption and + * verification fails then finish() will return KM_ERROR_VERIFICATION_FAILED. + */ + keymaster_error_t (*finish)(const struct keymaster1_device* dev, + keymaster_operation_handle_t operation_handle, + const keymaster_key_param_set_t* in_params, + const keymaster_blob_t* signature, + keymaster_key_param_set_t* out_params, keymaster_blob_t* output); + + /** + * Aborts a cryptographic operation begun with begin(), freeing all internal resources and + * invalidating \p operation_handle. + */ + keymaster_error_t (*abort)(const struct keymaster1_device* dev, + keymaster_operation_handle_t operation_handle); + + /** + * Generates a pair of ATTK defined in SOTER. Save the private key into RPMB. + * Note that the ATTK generated will never be touched outside the keymaster. + * + * \param[in] dev The keymaster device structure. + * + * \param[in] copy_num The number of copies that will be saved in the RPMB. + */ + keymaster_error_t (*generate_attk_key_pair)(const struct keymaster1_device* dev, + const uint8_t copy_num); + + /** + * Verify the existance ATTK defined in SOTER. + * + * \param[in] dev The keymaster device structure. + * + * Returns: 0 if the ATTK exists. + */ + keymaster_error_t (*verify_attk_key_pair)(const struct keymaster1_device* dev); + + /** + * Export the public key of ATTK in PEM format. + * + * \param[in] dev The keymaster device structure. + * + * \param[out] pub_key_data The public key data in X.509v3 format PEM encoded + * + * \param[out] pub_key_data_length The length of the public key data. + */ + keymaster_error_t (*export_attk_public_key)(const struct keymaster1_device* dev, + const uint8_t* pub_key_data, + const size_t pub_key_data_length); + + /** + * Get Unique device ID. + * + * \param[in] dev The keymaster device structure. + * + * \param[out] device_id The unique id for each device, format as below: + * 1.bytes 0-3: Identify each silicon provider id. + * 2.bytes 4-7: SoC model ID, defined by each silicon provider + * 3.bytes 8-15: Public Chip Serial *Number of SoC, defined by each silicon provider + * + * \param[out] device_id_length The length of the device id. + */ + keymaster_error_t (*get_device_id)(const struct keymaster1_device* dev, + const uint8_t* device_id, + const size_t device_id_length); +}; +typedef struct keymaster1_device keymaster1_device_t; + +/* Convenience API for opening and closing keymaster devices */ + +static inline int keymaster1_open(const struct hw_module_t* module, keymaster1_device_t** device) { + return module->methods->open(module, KEYSTORE_KEYMASTER, (struct hw_device_t**)device); +} + +static inline int keymaster1_close(keymaster1_device_t* device) { + return device->common.close(&device->common); +} + +__END_DECLS + +#endif // ANDROID_HARDWARE_KEYMASTER1_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/keymaster_common.h b/phonelibs/android_hardware_libhardware/include/hardware/keymaster_common.h new file mode 100644 index 00000000000000..772d7e4d238680 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/keymaster_common.h @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_KEYMASTER_COMMON_H +#define ANDROID_HARDWARE_KEYMASTER_COMMON_H + +#include +#include +#include + +#include + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define KEYSTORE_HARDWARE_MODULE_ID "keystore" + +#define KEYSTORE_KEYMASTER "keymaster" + + +/** + * Settings for "module_api_version" and "hal_api_version" + * fields in the keymaster_module initialization. + */ + +/** + * Keymaster 0.X module version provide the same APIs, but later versions add more options + * for algorithms and flags. + */ +#define KEYMASTER_MODULE_API_VERSION_0_2 HARDWARE_MODULE_API_VERSION(0, 2) +#define KEYMASTER_DEVICE_API_VERSION_0_2 HARDWARE_DEVICE_API_VERSION(0, 2) + +#define KEYMASTER_MODULE_API_VERSION_0_3 HARDWARE_MODULE_API_VERSION(0, 3) +#define KEYMASTER_DEVICE_API_VERSION_0_3 HARDWARE_DEVICE_API_VERSION(0, 3) + +/** + * Keymaster 1.0 module version provides a completely different API, incompatible with 0.X. + */ +#define KEYMASTER_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0) +#define KEYMASTER_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0) + +struct keystore_module { + /** + * Common methods of the keystore module. This *must* be the first member of keystore_module as + * users of this structure will cast a hw_module_t to keystore_module pointer in contexts where + * it's known the hw_module_t references a keystore_module. + */ + hw_module_t common; + + /* There are no keystore module methods other than the common ones. */ +}; + +/** + * Flags for keymaster0_device::flags + */ +enum { + /* + * Indicates this keymaster implementation does not have hardware that + * keeps private keys out of user space. + * + * This should not be implemented on anything other than the default + * implementation. + */ + KEYMASTER_SOFTWARE_ONLY = 1 << 0, + + /* + * This indicates that the key blobs returned via all the primitives + * are sufficient to operate on their own without the trusted OS + * querying userspace to retrieve some other data. Key blobs of + * this type are normally returned encrypted with a + * Key Encryption Key (KEK). + * + * This is currently used by "vold" to know whether the whole disk + * encryption secret can be unwrapped without having some external + * service started up beforehand since the "/data" partition will + * be unavailable at that point. + */ + KEYMASTER_BLOBS_ARE_STANDALONE = 1 << 1, + + /* + * Indicates that the keymaster module supports DSA keys. + */ + KEYMASTER_SUPPORTS_DSA = 1 << 2, + + /* + * Indicates that the keymaster module supports EC keys. + */ + KEYMASTER_SUPPORTS_EC = 1 << 3, +}; + +/** + * Asymmetric key pair types. + */ +typedef enum { + TYPE_RSA = 1, + TYPE_DSA = 2, + TYPE_EC = 3, +} keymaster_keypair_t; + +/** + * Parameters needed to generate an RSA key. + */ +typedef struct { + uint32_t modulus_size; + uint64_t public_exponent; +} keymaster_rsa_keygen_params_t; + +/** + * Parameters needed to generate a DSA key. + */ +typedef struct { + uint32_t key_size; + uint32_t generator_len; + uint32_t prime_p_len; + uint32_t prime_q_len; + const uint8_t* generator; + const uint8_t* prime_p; + const uint8_t* prime_q; +} keymaster_dsa_keygen_params_t; + +/** + * Parameters needed to generate an EC key. + * + * Field size is the only parameter in version 2. The sizes correspond to these required curves: + * + * 192 = NIST P-192 + * 224 = NIST P-224 + * 256 = NIST P-256 + * 384 = NIST P-384 + * 521 = NIST P-521 + * + * The parameters for these curves are available at: http://www.nsa.gov/ia/_files/nist-routines.pdf + * in Chapter 4. + */ +typedef struct { + uint32_t field_size; +} keymaster_ec_keygen_params_t; + + +/** + * Digest type. + */ +typedef enum { + DIGEST_NONE, +} keymaster_digest_algorithm_t; + +/** + * Type of padding used for RSA operations. + */ +typedef enum { + PADDING_NONE, +} keymaster_rsa_padding_t; + + +typedef struct { + keymaster_digest_algorithm_t digest_type; +} keymaster_dsa_sign_params_t; + +typedef struct { + keymaster_digest_algorithm_t digest_type; +} keymaster_ec_sign_params_t; + +typedef struct { + keymaster_digest_algorithm_t digest_type; + keymaster_rsa_padding_t padding_type; +} keymaster_rsa_sign_params_t; + +__END_DECLS + +#endif // ANDROID_HARDWARE_KEYMASTER_COMMON_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/keymaster_defs.h b/phonelibs/android_hardware_libhardware/include/hardware/keymaster_defs.h new file mode 100644 index 00000000000000..1a723c94a8ce36 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/keymaster_defs.h @@ -0,0 +1,539 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_KEYMASTER_DEFS_H +#define ANDROID_HARDWARE_KEYMASTER_DEFS_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * Authorization tags each have an associated type. This enumeration facilitates tagging each with + * a type, by using the high four bits (of an implied 32-bit unsigned enum value) to specify up to + * 16 data types. These values are ORed with tag IDs to generate the final tag ID values. + */ +typedef enum { + KM_INVALID = 0 << 28, /* Invalid type, used to designate a tag as uninitialized */ + KM_ENUM = 1 << 28, + KM_ENUM_REP = 2 << 28, /* Repeatable enumeration value. */ + KM_UINT = 3 << 28, + KM_UINT_REP = 4 << 28, /* Repeatable integer value */ + KM_ULONG = 5 << 28, + KM_DATE = 6 << 28, + KM_BOOL = 7 << 28, + KM_BIGNUM = 8 << 28, + KM_BYTES = 9 << 28, + KM_ULONG_REP = 10 << 28, /* Repeatable long value */ +} keymaster_tag_type_t; + +typedef enum { + KM_TAG_INVALID = KM_INVALID | 0, + + /* + * Tags that must be semantically enforced by hardware and software implementations. + */ + + /* Crypto parameters */ + KM_TAG_PURPOSE = KM_ENUM_REP | 1, /* keymaster_purpose_t. */ + KM_TAG_ALGORITHM = KM_ENUM | 2, /* keymaster_algorithm_t. */ + KM_TAG_KEY_SIZE = KM_UINT | 3, /* Key size in bits. */ + KM_TAG_BLOCK_MODE = KM_ENUM_REP | 4, /* keymaster_block_mode_t. */ + KM_TAG_DIGEST = KM_ENUM_REP | 5, /* keymaster_digest_t. */ + KM_TAG_PADDING = KM_ENUM_REP | 6, /* keymaster_padding_t. */ + KM_TAG_CALLER_NONCE = KM_BOOL | 7, /* Allow caller to specify nonce or IV. */ + KM_TAG_MIN_MAC_LENGTH = KM_UINT | 8, /* Minimum length of MAC or AEAD authentication tag in + * bits. */ + + /* Algorithm-specific. */ + KM_TAG_RSA_PUBLIC_EXPONENT = KM_ULONG | 200, + + /* Other hardware-enforced. */ + KM_TAG_BLOB_USAGE_REQUIREMENTS = KM_ENUM | 301, /* keymaster_key_blob_usage_requirements_t */ + KM_TAG_BOOTLOADER_ONLY = KM_BOOL | 302, /* Usable only by bootloader */ + + /* + * Tags that should be semantically enforced by hardware if possible and will otherwise be + * enforced by software (keystore). + */ + + /* Key validity period */ + KM_TAG_ACTIVE_DATETIME = KM_DATE | 400, /* Start of validity */ + KM_TAG_ORIGINATION_EXPIRE_DATETIME = KM_DATE | 401, /* Date when new "messages" should no + longer be created. */ + KM_TAG_USAGE_EXPIRE_DATETIME = KM_DATE | 402, /* Date when existing "messages" should no + longer be trusted. */ + KM_TAG_MIN_SECONDS_BETWEEN_OPS = KM_UINT | 403, /* Minimum elapsed time between + cryptographic operations with the key. */ + KM_TAG_MAX_USES_PER_BOOT = KM_UINT | 404, /* Number of times the key can be used per + boot. */ + + /* User authentication */ + KM_TAG_ALL_USERS = KM_BOOL | 500, /* Reserved for future use -- ignore */ + KM_TAG_USER_ID = KM_UINT | 501, /* Reserved for future use -- ignore */ + KM_TAG_USER_SECURE_ID = KM_ULONG_REP | 502, /* Secure ID of authorized user or authenticator(s). + Disallowed if KM_TAG_ALL_USERS or + KM_TAG_NO_AUTH_REQUIRED is present. */ + KM_TAG_NO_AUTH_REQUIRED = KM_BOOL | 503, /* If key is usable without authentication. */ + KM_TAG_USER_AUTH_TYPE = KM_ENUM | 504, /* Bitmask of authenticator types allowed when + * KM_TAG_USER_SECURE_ID contains a secure user ID, + * rather than a secure authenticator ID. Defined in + * hw_authenticator_type_t in hw_auth_token.h. */ + KM_TAG_AUTH_TIMEOUT = KM_UINT | 505, /* Required freshness of user authentication for + private/secret key operations, in seconds. + Public key operations require no authentication. + If absent, authentication is required for every + use. Authentication state is lost when the + device is powered off. */ + + /* Application access control */ + KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600, /* Reserved for future use -- ignore */ + KM_TAG_APPLICATION_ID = KM_BYTES | 601, /* Reserved for fugure use -- ignore */ + + /* + * Semantically unenforceable tags, either because they have no specific meaning or because + * they're informational only. + */ + KM_TAG_APPLICATION_DATA = KM_BYTES | 700, /* Data provided by authorized application. */ + KM_TAG_CREATION_DATETIME = KM_DATE | 701, /* Key creation time */ + KM_TAG_ORIGIN = KM_ENUM | 702, /* keymaster_key_origin_t. */ + KM_TAG_ROLLBACK_RESISTANT = KM_BOOL | 703, /* Whether key is rollback-resistant. */ + KM_TAG_ROOT_OF_TRUST = KM_BYTES | 704, /* Root of trust ID. */ + + /* Tags used only to provide data to or receive data from operations */ + KM_TAG_ASSOCIATED_DATA = KM_BYTES | 1000, /* Used to provide associated data for AEAD modes. */ + KM_TAG_NONCE = KM_BYTES | 1001, /* Nonce or Initialization Vector */ + KM_TAG_AUTH_TOKEN = KM_BYTES | 1002, /* Authentication token that proves secure user + authentication has been performed. Structure + defined in hw_auth_token_t in hw_auth_token.h. */ + KM_TAG_MAC_LENGTH = KM_UINT | 1003, /* MAC or AEAD authentication tag length in bits. */ + + /* Tags used only for SOTER */ + /* Tags used only to check if the key is for SOTER */ + KM_TAG_SOTER_IS_FROM_SOTER = KM_BOOL | 11000, + /* Attach signature signed with ATTK[pri] while exporting public key */ + KM_TAG_SOTER_IS_AUTO_SIGNED_WITH_ATTK_WHEN_GET_PUBLIC_KEY = KM_BOOL | 11001, + /* Attach signature signed with specified private key while exporting public key */ + KM_TAG_SOTER_IS_AUTO_SIGNED_WITH_COMMON_KEY_WHEN_GET_PUBLIC_KEY = KM_BOOL | 11002, + /* keyalias for the keypair of KM_TAG_SOTER_IS_AUTO_SIGNED_WITH_COMMON_KEY_WHEN_GET_PUBLIC_KEY */ + KM_TAG_SOTER_AUTO_SIGNED_COMMON_KEY_WHEN_GET_PUBLIC_KEY = KM_BYTES | 11003, + /* Attach counter while exporting publick key */ + KM_TAG_SOTER_AUTO_ADD_COUNTER_WHEN_GET_PUBLIC_KEY = KM_BOOL | 11004, + /* Attach secmsg(TEE_Name, TEE_Version, Fingerprint_Sensor_Name, Fingerprint_Sensor_Version) + fingerprint_id and counter while signing */ + KM_TAG_SOTER_IS_SECMSG_FID_COUNTER_SIGNED_WHEN_SIGN = KM_BOOL | 11005, + /* use and set ATTK index to next backup ATTK */ + KM_TAG_SOTER_USE_NEXT_ATTK = KM_BOOL | 11006, + /* attach soter uid */ + KM_TAG_SOTER_UID = KM_UINT | 11007, + /* attach key blob of KM_TAG_SOTER_AUTO_SIGNED_COMMON_KEY_WHEN_GET_PUBLIC_KEY if needed */ + KM_TAG_SOTER_AUTO_SIGNED_COMMON_KEY_WHEN_GET_PUBLIC_KEY_BLOB = KM_BYTES | 11008, +} keymaster_tag_t; + +/** + * Algorithms that may be provided by keymaster implementations. Those that must be provided by all + * implementations are tagged as "required". + */ +typedef enum { + /* Asymmetric algorithms. */ + KM_ALGORITHM_RSA = 1, + // KM_ALGORITHM_DSA = 2, -- Removed, do not re-use value 2. + KM_ALGORITHM_EC = 3, + + /* Block ciphers algorithms */ + KM_ALGORITHM_AES = 32, + + /* MAC algorithms */ + KM_ALGORITHM_HMAC = 128, +} keymaster_algorithm_t; + +/** + * Symmetric block cipher modes provided by keymaster implementations. + */ +typedef enum { + /* Unauthenticated modes, usable only for encryption/decryption and not generally recommended + * except for compatibility with existing other protocols. */ + KM_MODE_ECB = 1, + KM_MODE_CBC = 2, + KM_MODE_CTR = 3, + + /* Authenticated modes, usable for encryption/decryption and signing/verification. Recommended + * over unauthenticated modes for all purposes. */ + KM_MODE_GCM = 32, +} keymaster_block_mode_t; + +/** + * Padding modes that may be applied to plaintext for encryption operations. This list includes + * padding modes for both symmetric and asymmetric algorithms. Note that implementations should not + * provide all possible combinations of algorithm and padding, only the + * cryptographically-appropriate pairs. + */ +typedef enum { + KM_PAD_NONE = 1, /* deprecated */ + KM_PAD_RSA_OAEP = 2, + KM_PAD_RSA_PSS = 3, + KM_PAD_RSA_PKCS1_1_5_ENCRYPT = 4, + KM_PAD_RSA_PKCS1_1_5_SIGN = 5, + KM_PAD_PKCS7 = 64, +} keymaster_padding_t; + +/** + * Digests provided by keymaster implementations. + */ +typedef enum { + KM_DIGEST_NONE = 0, + KM_DIGEST_MD5 = 1, /* Optional, may not be implemented in hardware, will be handled in software + * if needed. */ + KM_DIGEST_SHA1 = 2, + KM_DIGEST_SHA_2_224 = 3, + KM_DIGEST_SHA_2_256 = 4, + KM_DIGEST_SHA_2_384 = 5, + KM_DIGEST_SHA_2_512 = 6, +} keymaster_digest_t; + +/** + * The origin of a key (or pair), i.e. where it was generated. Note that KM_TAG_ORIGIN can be found + * in either the hardware-enforced or software-enforced list for a key, indicating whether the key + * is hardware or software-based. Specifically, a key with KM_ORIGIN_GENERATED in the + * hardware-enforced list is guaranteed never to have existed outide the secure hardware. + */ +typedef enum { + KM_ORIGIN_GENERATED = 0, /* Generated in keymaster */ + KM_ORIGIN_IMPORTED = 2, /* Imported, origin unknown */ + KM_ORIGIN_UNKNOWN = 3, /* Keymaster did not record origin. This value can only be seen on + * keys in a keymaster0 implementation. The keymaster0 adapter uses + * this value to document the fact that it is unkown whether the key + * was generated inside or imported into keymaster. */ +} keymaster_key_origin_t; + +/** + * Usability requirements of key blobs. This defines what system functionality must be available + * for the key to function. For example, key "blobs" which are actually handles referencing + * encrypted key material stored in the file system cannot be used until the file system is + * available, and should have BLOB_REQUIRES_FILE_SYSTEM. Other requirements entries will be added + * as needed for implementations. This type is new in 0_4. + */ +typedef enum { + KM_BLOB_STANDALONE = 0, + KM_BLOB_REQUIRES_FILE_SYSTEM = 1, +} keymaster_key_blob_usage_requirements_t; + +/** + * Possible purposes of a key (or pair). This type is new in 0_4. + */ +typedef enum { + KM_PURPOSE_ENCRYPT = 0, + KM_PURPOSE_DECRYPT = 1, + KM_PURPOSE_SIGN = 2, + KM_PURPOSE_VERIFY = 3, +} keymaster_purpose_t; + +typedef struct { + const uint8_t* data; + size_t data_length; +} keymaster_blob_t; + +typedef struct { + keymaster_tag_t tag; + union { + uint32_t enumerated; /* KM_ENUM and KM_ENUM_REP */ + bool boolean; /* KM_BOOL */ + uint32_t integer; /* KM_INT and KM_INT_REP */ + uint64_t long_integer; /* KM_LONG */ + uint64_t date_time; /* KM_DATE */ + keymaster_blob_t blob; /* KM_BIGNUM and KM_BYTES*/ + }; +} keymaster_key_param_t; + +typedef struct { + keymaster_key_param_t* params; /* may be NULL if length == 0 */ + size_t length; +} keymaster_key_param_set_t; + +/** + * Parameters that define a key's characteristics, including authorized modes of usage and access + * control restrictions. The parameters are divided into two categories, those that are enforced by + * secure hardware, and those that are not. For a software-only keymaster implementation the + * enforced array must NULL. Hardware implementations must enforce everything in the enforced + * array. + */ +typedef struct { + keymaster_key_param_set_t hw_enforced; + keymaster_key_param_set_t sw_enforced; +} keymaster_key_characteristics_t; + +typedef struct { + const uint8_t* key_material; + size_t key_material_size; +} keymaster_key_blob_t; + +/** + * Formats for key import and export. At present, only asymmetric key import/export is supported. + * In the future this list will expand greatly to accommodate asymmetric key import/export. + */ +typedef enum { + KM_KEY_FORMAT_X509 = 0, /* for public key export */ + KM_KEY_FORMAT_PKCS8 = 1, /* for asymmetric key pair import */ + KM_KEY_FORMAT_RAW = 3, /* for symmetric key import */ +} keymaster_key_format_t; + +/** + * The keymaster operation API consists of begin, update, finish and abort. This is the type of the + * handle used to tie the sequence of calls together. A 64-bit value is used because it's important + * that handles not be predictable. Implementations must use strong random numbers for handle + * values. + */ +typedef uint64_t keymaster_operation_handle_t; + +typedef enum { + KM_ERROR_OK = 0, + KM_ERROR_ROOT_OF_TRUST_ALREADY_SET = -1, + KM_ERROR_UNSUPPORTED_PURPOSE = -2, + KM_ERROR_INCOMPATIBLE_PURPOSE = -3, + KM_ERROR_UNSUPPORTED_ALGORITHM = -4, + KM_ERROR_INCOMPATIBLE_ALGORITHM = -5, + KM_ERROR_UNSUPPORTED_KEY_SIZE = -6, + KM_ERROR_UNSUPPORTED_BLOCK_MODE = -7, + KM_ERROR_INCOMPATIBLE_BLOCK_MODE = -8, + KM_ERROR_UNSUPPORTED_MAC_LENGTH = -9, + KM_ERROR_UNSUPPORTED_PADDING_MODE = -10, + KM_ERROR_INCOMPATIBLE_PADDING_MODE = -11, + KM_ERROR_UNSUPPORTED_DIGEST = -12, + KM_ERROR_INCOMPATIBLE_DIGEST = -13, + KM_ERROR_INVALID_EXPIRATION_TIME = -14, + KM_ERROR_INVALID_USER_ID = -15, + KM_ERROR_INVALID_AUTHORIZATION_TIMEOUT = -16, + KM_ERROR_UNSUPPORTED_KEY_FORMAT = -17, + KM_ERROR_INCOMPATIBLE_KEY_FORMAT = -18, + KM_ERROR_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = -19, /* For PKCS8 & PKCS12 */ + KM_ERROR_UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = -20, /* For PKCS8 & PKCS12 */ + KM_ERROR_INVALID_INPUT_LENGTH = -21, + KM_ERROR_KEY_EXPORT_OPTIONS_INVALID = -22, + KM_ERROR_DELEGATION_NOT_ALLOWED = -23, + KM_ERROR_KEY_NOT_YET_VALID = -24, + KM_ERROR_KEY_EXPIRED = -25, + KM_ERROR_KEY_USER_NOT_AUTHENTICATED = -26, + KM_ERROR_OUTPUT_PARAMETER_NULL = -27, + KM_ERROR_INVALID_OPERATION_HANDLE = -28, + KM_ERROR_INSUFFICIENT_BUFFER_SPACE = -29, + KM_ERROR_VERIFICATION_FAILED = -30, + KM_ERROR_TOO_MANY_OPERATIONS = -31, + KM_ERROR_UNEXPECTED_NULL_POINTER = -32, + KM_ERROR_INVALID_KEY_BLOB = -33, + KM_ERROR_IMPORTED_KEY_NOT_ENCRYPTED = -34, + KM_ERROR_IMPORTED_KEY_DECRYPTION_FAILED = -35, + KM_ERROR_IMPORTED_KEY_NOT_SIGNED = -36, + KM_ERROR_IMPORTED_KEY_VERIFICATION_FAILED = -37, + KM_ERROR_INVALID_ARGUMENT = -38, + KM_ERROR_UNSUPPORTED_TAG = -39, + KM_ERROR_INVALID_TAG = -40, + KM_ERROR_MEMORY_ALLOCATION_FAILED = -41, + KM_ERROR_IMPORT_PARAMETER_MISMATCH = -44, + KM_ERROR_SECURE_HW_ACCESS_DENIED = -45, + KM_ERROR_OPERATION_CANCELLED = -46, + KM_ERROR_CONCURRENT_ACCESS_CONFLICT = -47, + KM_ERROR_SECURE_HW_BUSY = -48, + KM_ERROR_SECURE_HW_COMMUNICATION_FAILED = -49, + KM_ERROR_UNSUPPORTED_EC_FIELD = -50, + KM_ERROR_MISSING_NONCE = -51, + KM_ERROR_INVALID_NONCE = -52, + KM_ERROR_MISSING_MAC_LENGTH = -53, + KM_ERROR_KEY_RATE_LIMIT_EXCEEDED = -54, + KM_ERROR_CALLER_NONCE_PROHIBITED = -55, + KM_ERROR_KEY_MAX_OPS_EXCEEDED = -56, + KM_ERROR_INVALID_MAC_LENGTH = -57, + KM_ERROR_MISSING_MIN_MAC_LENGTH = -58, + KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH = -59, + + KM_ERROR_UNIMPLEMENTED = -100, + KM_ERROR_VERSION_MISMATCH = -101, + + /* Additional error codes may be added by implementations, but implementers should coordinate + * with Google to avoid code collision. */ + KM_ERROR_UNKNOWN_ERROR = -1000, +} keymaster_error_t; + +/* Convenience functions for manipulating keymaster tag types */ + +static inline keymaster_tag_type_t keymaster_tag_get_type(keymaster_tag_t tag) { + return (keymaster_tag_type_t)(tag & (0xF << 28)); +} + +static inline uint32_t keymaster_tag_mask_type(keymaster_tag_t tag) { + return tag & 0x0FFFFFFF; +} + +static inline bool keymaster_tag_type_repeatable(keymaster_tag_type_t type) { + switch (type) { + case KM_UINT_REP: + case KM_ENUM_REP: + return true; + default: + return false; + } +} + +static inline bool keymaster_tag_repeatable(keymaster_tag_t tag) { + return keymaster_tag_type_repeatable(keymaster_tag_get_type(tag)); +} + +/* Convenience functions for manipulating keymaster_key_param_t structs */ + +inline keymaster_key_param_t keymaster_param_enum(keymaster_tag_t tag, uint32_t value) { + // assert(keymaster_tag_get_type(tag) == KM_ENUM || keymaster_tag_get_type(tag) == KM_ENUM_REP); + keymaster_key_param_t param; + memset(¶m, 0, sizeof(param)); + param.tag = tag; + param.enumerated = value; + return param; +} + +inline keymaster_key_param_t keymaster_param_int(keymaster_tag_t tag, uint32_t value) { + // assert(keymaster_tag_get_type(tag) == KM_INT || keymaster_tag_get_type(tag) == KM_INT_REP); + keymaster_key_param_t param; + memset(¶m, 0, sizeof(param)); + param.tag = tag; + param.integer = value; + return param; +} + +inline keymaster_key_param_t keymaster_param_long(keymaster_tag_t tag, uint64_t value) { + // assert(keymaster_tag_get_type(tag) == KM_LONG); + keymaster_key_param_t param; + memset(¶m, 0, sizeof(param)); + param.tag = tag; + param.long_integer = value; + return param; +} + +inline keymaster_key_param_t keymaster_param_blob(keymaster_tag_t tag, const uint8_t* bytes, + size_t bytes_len) { + // assert(keymaster_tag_get_type(tag) == KM_BYTES || keymaster_tag_get_type(tag) == KM_BIGNUM); + keymaster_key_param_t param; + memset(¶m, 0, sizeof(param)); + param.tag = tag; + param.blob.data = (uint8_t*)bytes; + param.blob.data_length = bytes_len; + return param; +} + +inline keymaster_key_param_t keymaster_param_bool(keymaster_tag_t tag) { + // assert(keymaster_tag_get_type(tag) == KM_BOOL); + keymaster_key_param_t param; + memset(¶m, 0, sizeof(param)); + param.tag = tag; + param.boolean = true; + return param; +} + +inline keymaster_key_param_t keymaster_param_date(keymaster_tag_t tag, uint64_t value) { + // assert(keymaster_tag_get_type(tag) == KM_DATE); + keymaster_key_param_t param; + memset(¶m, 0, sizeof(param)); + param.tag = tag; + param.date_time = value; + return param; +} + +#define KEYMASTER_SIMPLE_COMPARE(a, b) (a < b) ? -1 : ((a > b) ? 1 : 0) +inline int keymaster_param_compare(const keymaster_key_param_t* a, const keymaster_key_param_t* b) { + int retval = KEYMASTER_SIMPLE_COMPARE(a->tag, b->tag); + if (retval != 0) + return retval; + + switch (keymaster_tag_get_type(a->tag)) { + case KM_INVALID: + case KM_BOOL: + return 0; + case KM_ENUM: + case KM_ENUM_REP: + return KEYMASTER_SIMPLE_COMPARE(a->enumerated, b->enumerated); + case KM_UINT: + case KM_UINT_REP: + return KEYMASTER_SIMPLE_COMPARE(a->integer, b->integer); + case KM_ULONG: + case KM_ULONG_REP: + return KEYMASTER_SIMPLE_COMPARE(a->long_integer, b->long_integer); + case KM_DATE: + return KEYMASTER_SIMPLE_COMPARE(a->date_time, b->date_time); + case KM_BIGNUM: + case KM_BYTES: + // Handle the empty cases. + if (a->blob.data_length != 0 && b->blob.data_length == 0) + return -1; + if (a->blob.data_length == 0 && b->blob.data_length == 0) + return 0; + if (a->blob.data_length == 0 && b->blob.data_length > 0) + return 1; + + retval = memcmp(a->blob.data, b->blob.data, a->blob.data_length < b->blob.data_length + ? a->blob.data_length + : b->blob.data_length); + if (retval != 0) + return retval; + else if (a->blob.data_length != b->blob.data_length) { + // Equal up to the common length; longer one is larger. + if (a->blob.data_length < b->blob.data_length) + return -1; + if (a->blob.data_length > b->blob.data_length) + return 1; + }; + } + + return 0; +} +#undef KEYMASTER_SIMPLE_COMPARE + +inline void keymaster_free_param_values(keymaster_key_param_t* param, size_t param_count) { + while (param_count-- > 0) { + switch (keymaster_tag_get_type(param->tag)) { + case KM_BIGNUM: + case KM_BYTES: + free((void*)param->blob.data); + param->blob.data = NULL; + break; + default: + // NOP + break; + } + ++param; + } +} + +inline void keymaster_free_param_set(keymaster_key_param_set_t* set) { + if (set) { + keymaster_free_param_values(set->params, set->length); + free(set->params); + set->params = NULL; + } +} + +inline void keymaster_free_characteristics(keymaster_key_characteristics_t* characteristics) { + if (characteristics) { + keymaster_free_param_set(&characteristics->hw_enforced); + keymaster_free_param_set(&characteristics->sw_enforced); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // ANDROID_HARDWARE_KEYMASTER_DEFS_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/lights.h b/phonelibs/android_hardware_libhardware/include/hardware/lights.h new file mode 100644 index 00000000000000..777c91593f0d09 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/lights.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_LIGHTS_INTERFACE_H +#define ANDROID_LIGHTS_INTERFACE_H + +#include +#include +#include + +#include + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define LIGHTS_HARDWARE_MODULE_ID "lights" + +/* + * These light IDs correspond to logical lights, not physical. + * So for example, if your INDICATOR light is in line with your + * BUTTONS, it might make sense to also light the INDICATOR + * light to a reasonable color when the BUTTONS are lit. + */ +#define LIGHT_ID_BACKLIGHT "backlight" +#define LIGHT_ID_KEYBOARD "keyboard" +#define LIGHT_ID_BUTTONS "buttons" +#define LIGHT_ID_BATTERY "battery" +#define LIGHT_ID_NOTIFICATIONS "notifications" +#define LIGHT_ID_ATTENTION "attention" + +/* + * These lights aren't currently supported by the higher + * layers, but could be someday, so we have the constants + * here now. + */ +#define LIGHT_ID_BLUETOOTH "bluetooth" +#define LIGHT_ID_WIFI "wifi" + +/* + * Additional hardware-specific lights + */ +#define LIGHT_ID_CAPS "caps" +#define LIGHT_ID_FUNC "func" + +/* ************************************************************************ + * Flash modes for the flashMode field of light_state_t. + */ + +#define LIGHT_FLASH_NONE 0 + +/** + * To flash the light at a given rate, set flashMode to LIGHT_FLASH_TIMED, + * and then flashOnMS should be set to the number of milliseconds to turn + * the light on, followed by the number of milliseconds to turn the light + * off. + */ +#define LIGHT_FLASH_TIMED 1 + +/** + * To flash the light using hardware assist, set flashMode to + * the hardware mode. + */ +#define LIGHT_FLASH_HARDWARE 2 + +/** + * Light brightness is managed by a user setting. + */ +#define BRIGHTNESS_MODE_USER 0 + +/** + * Light brightness is managed by a light sensor. + */ +#define BRIGHTNESS_MODE_SENSOR 1 + +/** + * Light mode allows multiple LEDs + */ +#define LIGHT_MODE_MULTIPLE_LEDS 0x01 + +/** + * The parameters that can be set for a given light. + * + * Not all lights must support all parameters. If you + * can do something backward-compatible, you should. + */ +struct light_state_t { + /** + * The color of the LED in ARGB. + * + * Do your best here. + * - If your light can only do red or green, if they ask for blue, + * you should do green. + * - If you can only do a brightness ramp, then use this formula: + * unsigned char brightness = ((77*((color>>16)&0x00ff)) + * + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8; + * - If you can only do on or off, 0 is off, anything else is on. + * + * The high byte should be ignored. Callers will set it to 0xff (which + * would correspond to 255 alpha). + * + * CyanogenMod: The high byte value can be implemented to control the LEDs + * Brightness from the Lights settings. The value goes from 0x01 to 0xFF. + */ + unsigned int color; + + /** + * See the LIGHT_FLASH_* constants + */ + int flashMode; + int flashOnMS; + int flashOffMS; + + /** + * Policy used by the framework to manage the light's brightness. + * Currently the values are BRIGHTNESS_MODE_USER and BRIGHTNESS_MODE_SENSOR. + */ + int brightnessMode; + + /** + * Define the LEDs modes (multiple, ...). + * See the LIGHTS_MODE_* mask constants. + */ + unsigned int ledsModes; +}; + +struct light_device_t { + struct hw_device_t common; + + /** + * Set the provided lights to the provided values. + * + * Returns: 0 on succes, error code on failure. + */ + int (*set_light)(struct light_device_t* dev, + struct light_state_t const* state); +}; + + +__END_DECLS + +#endif // ANDROID_LIGHTS_INTERFACE_H + diff --git a/phonelibs/android_hardware_libhardware/include/hardware/local_time_hal.h b/phonelibs/android_hardware_libhardware/include/hardware/local_time_hal.h new file mode 100644 index 00000000000000..946e799783ce57 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/local_time_hal.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_LOCAL_TIME_HAL_INTERFACE_H +#define ANDROID_LOCAL_TIME_HAL_INTERFACE_H + +#include + +#include + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define LOCAL_TIME_HARDWARE_MODULE_ID "local_time" + +/** + * Name of the local time devices to open + */ +#define LOCAL_TIME_HARDWARE_INTERFACE "local_time_hw_if" + +/**********************************************************************/ + +/** + * A structure used to collect low level sync data in a lab environment. Most + * HAL implementations will never need this structure. + */ +struct local_time_debug_event { + int64_t local_timesync_event_id; + int64_t local_time; +}; + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +struct local_time_module { + struct hw_module_t common; +}; + +struct local_time_hw_device { + /** + * Common methods of the local time hardware device. This *must* be the first member of + * local_time_hw_device as users of this structure will cast a hw_device_t to + * local_time_hw_device pointer in contexts where it's known the hw_device_t references a + * local_time_hw_device. + */ + struct hw_device_t common; + + /** + * + * Returns the current value of the system wide local time counter + */ + int64_t (*get_local_time)(struct local_time_hw_device* dev); + + /** + * + * Returns the nominal frequency (in hertz) of the system wide local time + * counter + */ + uint64_t (*get_local_freq)(struct local_time_hw_device* dev); + + /** + * + * Sets the HW slew rate of oscillator which drives the system wide local + * time counter. On success, platforms should return 0. Platforms which + * do not support HW slew should leave this method set to NULL. + * + * Valid values for rate range from MIN_INT16 to MAX_INT16. Platform + * implementations should attempt map this range linearly to the min/max + * slew rate of their hardware. + */ + int (*set_local_slew)(struct local_time_hw_device* dev, int16_t rate); + + /** + * + * A method used to collect low level sync data in a lab environments. + * Most HAL implementations will simply set this member to NULL, or return + * -EINVAL to indicate that this functionality is not supported. + * Production HALs should never support this method. + */ + int (*get_debug_log)(struct local_time_hw_device* dev, + struct local_time_debug_event* records, + int max_records); +}; + +typedef struct local_time_hw_device local_time_hw_device_t; + +/** convenience API for opening and closing a supported device */ + +static inline int local_time_hw_device_open( + const struct hw_module_t* module, + struct local_time_hw_device** device) +{ + return module->methods->open(module, LOCAL_TIME_HARDWARE_INTERFACE, + (struct hw_device_t**)device); +} + +static inline int local_time_hw_device_close(struct local_time_hw_device* device) +{ + return device->common.close(&device->common); +} + + +__END_DECLS + +#endif // ANDROID_LOCAL_TIME_INTERFACE_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/memtrack.h b/phonelibs/android_hardware_libhardware/include/hardware/memtrack.h new file mode 100644 index 00000000000000..57ba4ad79661d3 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/memtrack.h @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_HARDWARE_MEMTRACK_H +#define ANDROID_INCLUDE_HARDWARE_MEMTRACK_H + +#include +#include +#include + +#include + +__BEGIN_DECLS + +#define MEMTRACK_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1) + +/** + * The id of this module + */ +#define MEMTRACK_HARDWARE_MODULE_ID "memtrack" + +/* + * The Memory Tracker HAL is designed to return information about device-specific + * memory usage. The primary goal is to be able to track memory that is not + * trackable in any other way, for example texture memory that is allocated by + * a process, but not mapped in to that process' address space. + * A secondary goal is to be able to categorize memory used by a process into + * GL, graphics, etc. All memory sizes should be in real memory usage, + * accounting for stride, bit depth, rounding up to page size, etc. + * + * A process collecting memory statistics will call getMemory for each + * combination of pid and memory type. For each memory type that it recognizes + * the HAL should fill out an array of memtrack_record structures breaking + * down the statistics of that memory type as much as possible. For example, + * getMemory(, MEMTRACK_TYPE_GL) might return: + * { { 4096, ACCOUNTED | PRIVATE | SYSTEM }, + * { 40960, UNACCOUNTED | PRIVATE | SYSTEM }, + * { 8192, ACCOUNTED | PRIVATE | DEDICATED }, + * { 8192, UNACCOUNTED | PRIVATE | DEDICATED } } + * If the HAL could not differentiate between SYSTEM and DEDICATED memory, it + * could return: + * { { 12288, ACCOUNTED | PRIVATE }, + * { 49152, UNACCOUNTED | PRIVATE } } + * + * Memory should not overlap between types. For example, a graphics buffer + * that has been mapped into the GPU as a surface should show up when + * MEMTRACK_TYPE_GRAPHICS is requested, and not when MEMTRACK_TYPE_GL + * is requested. + */ + +enum memtrack_type { + MEMTRACK_TYPE_OTHER = 0, + MEMTRACK_TYPE_GL = 1, + MEMTRACK_TYPE_GRAPHICS = 2, + MEMTRACK_TYPE_MULTIMEDIA = 3, + MEMTRACK_TYPE_CAMERA = 4, + MEMTRACK_NUM_TYPES, +}; + +struct memtrack_record { + size_t size_in_bytes; + unsigned int flags; +}; + +/** + * Flags to differentiate memory that can already be accounted for in + * /proc//smaps, + * (Shared_Clean + Shared_Dirty + Private_Clean + Private_Dirty = Size). + * In general, memory mapped in to a userspace process is accounted unless + * it was mapped with remap_pfn_range. + * Exactly one of these should be set. + */ +#define MEMTRACK_FLAG_SMAPS_ACCOUNTED (1 << 1) +#define MEMTRACK_FLAG_SMAPS_UNACCOUNTED (1 << 2) + +/** + * Flags to differentiate memory shared across multiple processes vs. memory + * used by a single process. Only zero or one of these may be set in a record. + * If none are set, record is assumed to count shared + private memory. + */ +#define MEMTRACK_FLAG_SHARED (1 << 3) +#define MEMTRACK_FLAG_SHARED_PSS (1 << 4) /* shared / num_procesess */ +#define MEMTRACK_FLAG_PRIVATE (1 << 5) + +/** + * Flags to differentiate memory taken from the kernel's allocation pool vs. + * memory that is dedicated to non-kernel allocations, for example a carveout + * or separate video memory. Only zero or one of these may be set in a record. + * If none are set, record is assumed to count system + dedicated memory. + */ +#define MEMTRACK_FLAG_SYSTEM (1 << 6) +#define MEMTRACK_FLAG_DEDICATED (1 << 7) + +/** + * Flags to differentiate memory accessible by the CPU in non-secure mode vs. + * memory that is protected. Only zero or one of these may be set in a record. + * If none are set, record is assumed to count secure + nonsecure memory. + */ +#define MEMTRACK_FLAG_NONSECURE (1 << 8) +#define MEMTRACK_FLAG_SECURE (1 << 9) + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +typedef struct memtrack_module { + struct hw_module_t common; + + /** + * (*init)() performs memtrack management setup actions and is called + * once before any calls to getMemory(). + * Returns 0 on success, -errno on error. + */ + int (*init)(const struct memtrack_module *module); + + /** + * (*getMemory)() expects an array of record objects and populates up to + * *num_record structures with the sizes of memory plus associated flags for + * that memory. It also updates *num_records with the total number of + * records it could return if *num_records was large enough when passed in. + * Returning records with size 0 is expected, the number of records should + * not vary between calls to getMemory for the same memory type, even + * for different pids. + * + * The caller will often call getMemory for a type and pid with + * *num_records == 0 to determine how many records to allocate room for, + * this case should be a fast-path in the HAL, returning a constant and + * not querying any kernel files. If *num_records passed in is 0, + * then records may be NULL. + * + * This function must be thread-safe, it may get called from multiple + * threads at the same time. + * + * Returns 0 on success, -ENODEV if the type is not supported, -errno + * on other errors. + */ + int (*getMemory)(const struct memtrack_module *module, + pid_t pid, + int type, + struct memtrack_record *records, + size_t *num_records); +} memtrack_module_t; + +__END_DECLS + +#endif // ANDROID_INCLUDE_HARDWARE_MEMTRACK_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/nfc.h b/phonelibs/android_hardware_libhardware/include/hardware/nfc.h new file mode 100644 index 00000000000000..6002e34e83738f --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/nfc.h @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2011, 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_NFC_HAL_INTERFACE_H +#define ANDROID_NFC_HAL_INTERFACE_H + +#include +#include +#include +#include + +#include + +__BEGIN_DECLS + + +/* NFC device HAL for NCI-based NFC controllers. + * + * This HAL allows NCI silicon vendors to make use + * of the core NCI stack in Android for their own silicon. + * + * The responibilities of the NCI HAL implementation + * are as follows: + * + * - Implement the transport to the NFC controller + * - Implement each of the HAL methods specified below as applicable to their silicon + * - Pass up received NCI messages from the controller to the stack + * + * A simplified timeline of NCI HAL method calls: + * 1) Core NCI stack calls open() + * 2) Core NCI stack executes CORE_RESET and CORE_INIT through calls to write() + * 3) Core NCI stack calls core_initialized() to allow HAL to do post-init configuration + * 4) Core NCI stack calls pre_discover() to allow HAL to prepare for RF discovery + * 5) Core NCI stack starts discovery through calls to write() + * 6) Core NCI stack stops discovery through calls to write() (e.g. screen turns off) + * 7) Core NCI stack calls pre_discover() to prepare for RF discovery (e.g. screen turned back on) + * 8) Core NCI stack starts discovery through calls to write() + * ... + * ... + * 9) Core NCI stack calls close() + */ +#define NFC_NCI_HARDWARE_MODULE_ID "nfc_nci" +#define NFC_NCI_BCM2079X_HARDWARE_MODULE_ID "nfc_nci.bcm2079x" +#define NFC_NCI_NXP_PN54X_HARDWARE_MODULE_ID "nfc_nci.pn54x" +#define NFC_NCI_CONTROLLER "nci" + +/* + * nfc_nci_module_t should contain module-specific parameters + */ +typedef struct nfc_nci_module_t { + /** + * Common methods of the NFC NCI module. This *must* be the first member of + * nfc_nci_module_t as users of this structure will cast a hw_module_t to + * nfc_nci_module_t pointer in contexts where it's known the hw_module_t references a + * nfc_nci_module_t. + */ + struct hw_module_t common; +} nfc_nci_module_t; + +/* + * HAL events that can be passed back to the stack + */ +typedef uint8_t nfc_event_t; + +enum { + HAL_NFC_OPEN_CPLT_EVT = 0x00, + HAL_NFC_CLOSE_CPLT_EVT = 0x01, + HAL_NFC_POST_INIT_CPLT_EVT = 0x02, + HAL_NFC_PRE_DISCOVER_CPLT_EVT = 0x03, + HAL_NFC_REQUEST_CONTROL_EVT = 0x04, + HAL_NFC_RELEASE_CONTROL_EVT = 0x05, + HAL_NFC_ERROR_EVT = 0x06 +}; + +/* + * Allowed status return values for each of the HAL methods + */ +typedef uint8_t nfc_status_t; + +enum { + HAL_NFC_STATUS_OK = 0x00, + HAL_NFC_STATUS_FAILED = 0x01, + HAL_NFC_STATUS_ERR_TRANSPORT = 0x02, + HAL_NFC_STATUS_ERR_CMD_TIMEOUT = 0x03, + HAL_NFC_STATUS_REFUSED = 0x04 +}; + +/* + * The callback passed in from the NFC stack that the HAL + * can use to pass events back to the stack. + */ +typedef void (nfc_stack_callback_t) (nfc_event_t event, nfc_status_t event_status); + +/* + * The callback passed in from the NFC stack that the HAL + * can use to pass incomming data to the stack. + */ +typedef void (nfc_stack_data_callback_t) (uint16_t data_len, uint8_t* p_data); + +/* nfc_nci_device_t starts with a hw_device_t struct, + * followed by device-specific methods and members. + * + * All methods in the NCI HAL are asynchronous. + */ +typedef struct nfc_nci_device { + /** + * Common methods of the NFC NCI device. This *must* be the first member of + * nfc_nci_device_t as users of this structure will cast a hw_device_t to + * nfc_nci_device_t pointer in contexts where it's known the hw_device_t references a + * nfc_nci_device_t. + */ + struct hw_device_t common; + /* + * (*open)() Opens the NFC controller device and performs initialization. + * This may include patch download and other vendor-specific initialization. + * + * If open completes successfully, the controller should be ready to perform + * NCI initialization - ie accept CORE_RESET and subsequent commands through + * the write() call. + * + * If open() returns 0, the NCI stack will wait for a HAL_NFC_OPEN_CPLT_EVT + * before continuing. + * + * If open() returns any other value, the NCI stack will stop. + * + */ + int (*open)(const struct nfc_nci_device *p_dev, nfc_stack_callback_t *p_cback, + nfc_stack_data_callback_t *p_data_cback); + + /* + * (*write)() Performs an NCI write. + * + * This method may queue writes and return immediately. The only + * requirement is that the writes are executed in order. + */ + int (*write)(const struct nfc_nci_device *p_dev, uint16_t data_len, const uint8_t *p_data); + + /* + * (*core_initialized)() is called after the CORE_INIT_RSP is received from the NFCC. + * At this time, the HAL can do any chip-specific configuration. + * + * If core_initialized() returns 0, the NCI stack will wait for a HAL_NFC_POST_INIT_CPLT_EVT + * before continuing. + * + * If core_initialized() returns any other value, the NCI stack will continue + * immediately. + */ + int (*core_initialized)(const struct nfc_nci_device *p_dev, uint8_t* p_core_init_rsp_params); + + /* + * (*pre_discover)() Is called every time before starting RF discovery. + * It is a good place to do vendor-specific configuration that must be + * performed every time RF discovery is about to be started. + * + * If pre_discover() returns 0, the NCI stack will wait for a HAL_NFC_PRE_DISCOVER_CPLT_EVT + * before continuing. + * + * If pre_discover() returns any other value, the NCI stack will start + * RF discovery immediately. + */ + int (*pre_discover)(const struct nfc_nci_device *p_dev); + + /* + * (*close)() Closed the NFC controller. Should free all resources. + */ + int (*close)(const struct nfc_nci_device *p_dev); + + /* + * (*control_granted)() Grant HAL the exclusive control to send NCI commands. + * Called in response to HAL_REQUEST_CONTROL_EVT. + * Must only be called when there are no NCI commands pending. + * HAL_RELEASE_CONTROL_EVT will notify when HAL no longer needs exclusive control. + */ + int (*control_granted)(const struct nfc_nci_device *p_dev); + + /* + * (*power_cycle)() Restart controller by power cyle; + * HAL_OPEN_CPLT_EVT will notify when operation is complete. + */ + int (*power_cycle)(const struct nfc_nci_device *p_dev); +} nfc_nci_device_t; + +/* + * Convenience methods that the NFC stack can use to open + * and close an NCI device + */ +static inline int nfc_nci_open(const struct hw_module_t* module, + nfc_nci_device_t** dev) { + return module->methods->open(module, NFC_NCI_CONTROLLER, + (struct hw_device_t**) dev); +} + +static inline int nfc_nci_close(nfc_nci_device_t* dev) { + return dev->common.close(&dev->common); +} +/* + * End NFC NCI HAL + */ + +/* + * This is a limited NFC HAL for NXP PN544-based devices. + * This HAL as Android is moving to + * an NCI-based NFC stack. + * + * All NCI-based NFC controllers should use the NFC-NCI + * HAL instead. + * Begin PN544 specific HAL + */ +#define NFC_HARDWARE_MODULE_ID "nfc" + +#define NFC_PN544_CONTROLLER "pn544" + +typedef struct nfc_module_t { + /** + * Common methods of the NFC NXP PN544 module. This *must* be the first member of + * nfc_module_t as users of this structure will cast a hw_module_t to + * nfc_module_t pointer in contexts where it's known the hw_module_t references a + * nfc_module_t. + */ + struct hw_module_t common; +} nfc_module_t; + +/* + * PN544 linktypes. + * UART + * I2C + * USB (uses UART DAL) + */ +typedef enum { + PN544_LINK_TYPE_UART, + PN544_LINK_TYPE_I2C, + PN544_LINK_TYPE_USB, + PN544_LINK_TYPE_INVALID, +} nfc_pn544_linktype; + +typedef struct { + /** + * Common methods of the NFC NXP PN544 device. This *must* be the first member of + * nfc_pn544_device_t as users of this structure will cast a hw_device_t to + * nfc_pn544_device_t pointer in contexts where it's known the hw_device_t references a + * nfc_pn544_device_t. + */ + struct hw_device_t common; + + /* The number of EEPROM registers to write */ + uint32_t num_eeprom_settings; + + /* The actual EEPROM settings + * For PN544, each EEPROM setting is a 4-byte entry, + * of the format [0x00, addr_msb, addr_lsb, value]. + */ + uint8_t* eeprom_settings; + + /* The link type to which the PN544 is connected */ + nfc_pn544_linktype linktype; + + /* The device node to which the PN544 is connected */ + const char* device_node; + + /* On Crespo we had an I2C issue that would cause us to sometimes read + * the I2C slave address (0x57) over the bus. libnfc contains + * a hack to ignore this byte and try to read the length byte + * again. + * Set to 0 to disable the workaround, 1 to enable it. + */ + uint8_t enable_i2c_workaround; + /* I2C slave address. Multiple I2C addresses are + * possible for PN544 module. Configure address according to + * board design. + */ + uint8_t i2c_device_address; +} nfc_pn544_device_t; + +static inline int nfc_pn544_open(const struct hw_module_t* module, + nfc_pn544_device_t** dev) { + return module->methods->open(module, NFC_PN544_CONTROLLER, + (struct hw_device_t**) dev); +} + +static inline int nfc_pn544_close(nfc_pn544_device_t* dev) { + return dev->common.close(&dev->common); +} +/* + * End PN544 specific HAL + */ + +__END_DECLS + +#endif // ANDROID_NFC_HAL_INTERFACE_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/nfc_tag.h b/phonelibs/android_hardware_libhardware/include/hardware/nfc_tag.h new file mode 100644 index 00000000000000..040a07d8cb1376 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/nfc_tag.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_NFC_TAG_HAL_INTERFACE_H +#define ANDROID_NFC_TAG_HAL_INTERFACE_H + +#include + +#include + +__BEGIN_DECLS + +/* + * HAL for programmable NFC tags. + * + */ + +#define NFC_TAG_HARDWARE_MODULE_ID "nfc_tag" +#define NFC_TAG_ID "tag" + +typedef struct nfc_tag_module_t { + /** + * Common methods of the NFC tag module. This *must* be the first member of + * nfc_tag_module_t as users of this structure will cast a hw_module_t to + * nfc_tag_module_t pointer in contexts where it's known the hw_module_t references a + * nfc_tag_module_t. + */ + struct hw_module_t common; +} nfc_tag_module_t; + +typedef struct nfc_tag_device { + /** + * Common methods of the NFC tag device. This *must* be the first member of + * nfc_tag_device_t as users of this structure will cast a hw_device_t to + * nfc_tag_device_t pointer in contexts where it's known the hw_device_t references a + * nfc_tag_device_t. + */ + struct hw_device_t common; + + /** + * Initialize the NFC tag. + * + * The driver must: + * * Set the static lock bytes to read only + * * Configure the Capability Container to disable write acess + * eg: 0xE1 0x10 0x0F + * + * This function is called once before any calls to setContent(). + * + * Return 0 on success or -errno on error. + */ + int (*init)(const struct nfc_tag_device *dev); + + /** + * Set the NFC tag content. + * + * The driver must write in the data area of the tag starting at + * byte 0 of block 4 and zero the rest of the data area. + * + * Returns 0 on success or -errno on error. + */ + int (*setContent)(const struct nfc_tag_device *dev, const uint8_t *data, size_t len); + + /** + * Returns the memory size of the data area. + */ + int (*getMemorySize)(const struct nfc_tag_device *dev); +} nfc_tag_device_t; + +static inline int nfc_tag_open(const struct hw_module_t* module, + nfc_tag_device_t** dev) { + return module->methods->open(module, NFC_TAG_ID, + (struct hw_device_t**)dev); +} + +static inline int nfc_tag_close(nfc_tag_device_t* dev) { + return dev->common.close(&dev->common); +} + +__END_DECLS + +#endif // ANDROID_NFC_TAG_HAL_INTERFACE_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/power.h b/phonelibs/android_hardware_libhardware/include/hardware/power.h new file mode 100644 index 00000000000000..2eb98fe96610ba --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/power.h @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_HARDWARE_POWER_H +#define ANDROID_INCLUDE_HARDWARE_POWER_H + +#include +#include +#include + +#include + +__BEGIN_DECLS + +#define POWER_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1) +#define POWER_MODULE_API_VERSION_0_2 HARDWARE_MODULE_API_VERSION(0, 2) +#define POWER_MODULE_API_VERSION_0_3 HARDWARE_MODULE_API_VERSION(0, 3) + +/** + * The id of this module + */ +#define POWER_HARDWARE_MODULE_ID "power" + +/* + * Power hint identifiers passed to (*powerHint) + */ + +typedef enum { + POWER_HINT_VSYNC = 0x00000001, + POWER_HINT_INTERACTION = 0x00000002, + /* DO NOT USE POWER_HINT_VIDEO_ENCODE/_DECODE! They will be removed in + * KLP. + */ + POWER_HINT_VIDEO_ENCODE = 0x00000003, + POWER_HINT_VIDEO_DECODE = 0x00000004, + POWER_HINT_LOW_POWER = 0x00000005, + POWER_HINT_CAM_PREVIEW = 0x00000006, + + POWER_HINT_CPU_BOOST = 0x00000010, + POWER_HINT_LAUNCH_BOOST = 0x00000011, + POWER_HINT_AUDIO = 0x00000020, + POWER_HINT_SET_PROFILE = 0x00000030 + +} power_hint_t; + +typedef enum { + POWER_FEATURE_DOUBLE_TAP_TO_WAKE = 0x00000001, + POWER_FEATURE_SUPPORTED_PROFILES = 0x00001000 +} feature_t; + +/** + * Process info, passed as an opaque handle when + * using POWER_HINT_LAUNCH_BOOST. + */ +typedef struct launch_boost_info { + pid_t pid; + const char* packageName; +} launch_boost_info_t; + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +typedef struct power_module { + struct hw_module_t common; + + /* + * (*init)() performs power management setup actions at runtime + * startup, such as to set default cpufreq parameters. This is + * called only by the Power HAL instance loaded by + * PowerManagerService. + */ + void (*init)(struct power_module *module); + + /* + * (*setInteractive)() performs power management actions upon the + * system entering interactive state (that is, the system is awake + * and ready for interaction, often with UI devices such as + * display and touchscreen enabled) or non-interactive state (the + * system appears asleep, display usually turned off). The + * non-interactive state is usually entered after a period of + * inactivity, in order to conserve battery power during + * such inactive periods. + * + * Typical actions are to turn on or off devices and adjust + * cpufreq parameters. This function may also call the + * appropriate interfaces to allow the kernel to suspend the + * system to low-power sleep state when entering non-interactive + * state, and to disallow low-power suspend when the system is in + * interactive state. When low-power suspend state is allowed, the + * kernel may suspend the system whenever no wakelocks are held. + * + * on is non-zero when the system is transitioning to an + * interactive / awake state, and zero when transitioning to a + * non-interactive / asleep state. + * + * This function is called to enter non-interactive state after + * turning off the screen (if present), and called to enter + * interactive state prior to turning on the screen. + */ + void (*setInteractive)(struct power_module *module, int on); + + /* + * (*powerHint) is called to pass hints on power requirements, which + * may result in adjustment of power/performance parameters of the + * cpufreq governor and other controls. The possible hints are: + * + * POWER_HINT_VSYNC + * + * Foreground app has started or stopped requesting a VSYNC pulse + * from SurfaceFlinger. If the app has started requesting VSYNC + * then CPU and GPU load is expected soon, and it may be appropriate + * to raise speeds of CPU, memory bus, etc. The data parameter is + * non-zero to indicate VSYNC pulse is now requested, or zero for + * VSYNC pulse no longer requested. + * + * POWER_HINT_INTERACTION + * + * User is interacting with the device, for example, touchscreen + * events are incoming. CPU and GPU load may be expected soon, + * and it may be appropriate to raise speeds of CPU, memory bus, + * etc. The data parameter is the estimated length of the interaction + * in milliseconds, or 0 if unknown. + * + * POWER_HINT_LOW_POWER + * + * Low power mode is activated or deactivated. Low power mode + * is intended to save battery at the cost of performance. The data + * parameter is non-zero when low power mode is activated, and zero + * when deactivated. + * + * POWER_HINT_CPU_BOOST + * + * An operation is happening where it would be ideal for the CPU to + * be boosted for a specific duration. The data parameter is an + * integer value of the boost duration in microseconds. + * + * A particular platform may choose to ignore any hint. + * + * availability: version 0.2 + * + */ + void (*powerHint)(struct power_module *module, power_hint_t hint, + void *data); + + /* + * (*setFeature) is called to turn on or off a particular feature + * depending on the state parameter. The possible features are: + * + * FEATURE_DOUBLE_TAP_TO_WAKE + * + * Enabling/Disabling this feature will allow/disallow the system + * to wake up by tapping the screen twice. + * + * availability: version 0.3 + * + */ + void (*setFeature)(struct power_module *module, feature_t feature, int state); + + /* + * (*getFeature) is called to get the current value of a particular + * feature or capability from the hardware or PowerHAL + */ + int (*getFeature)(struct power_module *module, feature_t feature); + +} power_module_t; + +__END_DECLS + +#endif // ANDROID_INCLUDE_HARDWARE_POWER_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/qemu_pipe.h b/phonelibs/android_hardware_libhardware/include/hardware/qemu_pipe.h new file mode 100644 index 00000000000000..53aec97a083dde --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/qemu_pipe.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef ANDROID_INCLUDE_HARDWARE_QEMU_PIPE_H +#define ANDROID_INCLUDE_HARDWARE_QEMU_PIPE_H + +#include +#include +#include +#include +#include /* for pthread_once() */ +#include +#include +#include +#include + +#ifndef D +# define D(...) do{}while(0) +#endif + +/* Try to open a new Qemu fast-pipe. This function returns a file descriptor + * that can be used to communicate with a named service managed by the + * emulator. + * + * This file descriptor can be used as a standard pipe/socket descriptor. + * + * 'pipeName' is the name of the emulator service you want to connect to. + * E.g. 'opengles' or 'camera'. + * + * On success, return a valid file descriptor + * Returns -1 on error, and errno gives the error code, e.g.: + * + * EINVAL -> unknown/unsupported pipeName + * ENOSYS -> fast pipes not available in this system. + * + * ENOSYS should never happen, except if you're trying to run within a + * misconfigured emulator. + * + * You should be able to open several pipes to the same pipe service, + * except for a few special cases (e.g. GSM modem), where EBUSY will be + * returned if more than one client tries to connect to it. + */ +static __inline__ int +qemu_pipe_open(const char* pipeName) +{ + char buff[256]; + int buffLen; + int fd, ret; + + if (pipeName == NULL || pipeName[0] == '\0') { + errno = EINVAL; + return -1; + } + + snprintf(buff, sizeof buff, "pipe:%s", pipeName); + + fd = open("/dev/qemu_pipe", O_RDWR); + if (fd < 0 && errno == ENOENT) + fd = open("/dev/goldfish_pipe", O_RDWR); + if (fd < 0) { + D("%s: Could not open /dev/qemu_pipe: %s", __FUNCTION__, strerror(errno)); + //errno = ENOSYS; + return -1; + } + + buffLen = strlen(buff); + + ret = TEMP_FAILURE_RETRY(write(fd, buff, buffLen+1)); + if (ret != buffLen+1) { + D("%s: Could not connect to %s pipe service: %s", __FUNCTION__, pipeName, strerror(errno)); + if (ret == 0) { + errno = ECONNRESET; + } else if (ret > 0) { + errno = EINVAL; + } + return -1; + } + + return fd; +} + +#endif /* ANDROID_INCLUDE_HARDWARE_QEMUD_PIPE_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/qemud.h b/phonelibs/android_hardware_libhardware/include/hardware/qemud.h new file mode 100644 index 00000000000000..5c39f9c939b00d --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/qemud.h @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_INCLUDE_HARDWARE_QEMUD_H +#define ANDROID_INCLUDE_HARDWARE_QEMUD_H + +#include +#include "qemu_pipe.h" + +/* the following is helper code that is used by the QEMU-specific + * hardware HAL modules to communicate with the emulator program + * through the 'qemud' multiplexing daemon, or through the qemud + * pipe. + * + * see the documentation comments for details in + * development/emulator/qemud/qemud.c + * + * all definitions here are built into the HAL module to avoid + * having to write a tiny shared library for this. + */ + +/* we expect the D macro to be defined to a function macro + * that sends its formatted string argument(s) to the log. + * If not, ignore the traces. + */ +#ifndef D +# define D(...) ((void)0) +#endif + +static __inline__ int +qemud_fd_write(int fd, const void* buff, int len) +{ + int len2; + do { + len2 = write(fd, buff, len); + } while (len2 < 0 && errno == EINTR); + return len2; +} + +static __inline__ int +qemud_fd_read(int fd, void* buff, int len) +{ + int len2; + do { + len2 = read(fd, buff, len); + } while (len2 < 0 && errno == EINTR); + return len2; +} + +static __inline__ int +qemud_channel_open(const char* name) +{ + int fd; + int namelen = strlen(name); + char answer[2]; + char pipe_name[256]; + + /* First, try to connect to the pipe. */ + snprintf(pipe_name, sizeof(pipe_name), "qemud:%s", name); + fd = qemu_pipe_open(pipe_name); + if (fd < 0) { + D("QEMUD pipe is not available for %s: %s", name, strerror(errno)); + /* If pipe is not available, connect to qemud control socket */ + fd = socket_local_client( "qemud", + ANDROID_SOCKET_NAMESPACE_RESERVED, + SOCK_STREAM ); + if (fd < 0) { + D("no qemud control socket: %s", strerror(errno)); + return -1; + } + + /* send service name to connect */ + if (qemud_fd_write(fd, name, namelen) != namelen) { + D("can't send service name to qemud: %s", + strerror(errno)); + close(fd); + return -1; + } + + /* read answer from daemon */ + if (qemud_fd_read(fd, answer, 2) != 2 || + answer[0] != 'O' || answer[1] != 'K') { + D("cant' connect to %s service through qemud", name); + close(fd); + return -1; + } + } + return fd; +} + +static __inline__ int +qemud_channel_send(int fd, const void* msg, int msglen) +{ + char header[5]; + + if (msglen < 0) + msglen = strlen((const char*)msg); + + if (msglen == 0) + return 0; + + snprintf(header, sizeof header, "%04x", msglen); + if (qemud_fd_write(fd, header, 4) != 4) { + D("can't write qemud frame header: %s", strerror(errno)); + return -1; + } + + if (qemud_fd_write(fd, msg, msglen) != msglen) { + D("can4t write qemud frame payload: %s", strerror(errno)); + return -1; + } + return 0; +} + +static __inline__ int +qemud_channel_recv(int fd, void* msg, int msgsize) +{ + char header[5]; + int size, avail; + + if (qemud_fd_read(fd, header, 4) != 4) { + D("can't read qemud frame header: %s", strerror(errno)); + return -1; + } + header[4] = 0; + if (sscanf(header, "%04x", &size) != 1) { + D("malformed qemud frame header: '%.*s'", 4, header); + return -1; + } + if (size > msgsize) + return -1; + + if (qemud_fd_read(fd, msg, size) != size) { + D("can't read qemud frame payload: %s", strerror(errno)); + return -1; + } + return size; +} + +#endif /* ANDROID_INCLUDE_HARDWARE_QEMUD_H */ diff --git a/phonelibs/android_hardware_libhardware/include/hardware/radio.h b/phonelibs/android_hardware_libhardware/include/hardware/radio.h new file mode 100644 index 00000000000000..145deb5737b4ea --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/radio.h @@ -0,0 +1,298 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#ifndef ANDROID_RADIO_HAL_H +#define ANDROID_RADIO_HAL_H + + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define RADIO_HARDWARE_MODULE_ID "radio" + +/** + * Name of the audio devices to open + */ +#define RADIO_HARDWARE_DEVICE "radio_hw_device" + +#define RADIO_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0) +#define RADIO_MODULE_API_VERSION_CURRENT RADIO_MODULE_API_VERSION_1_0 + + +#define RADIO_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0) +#define RADIO_DEVICE_API_VERSION_CURRENT RADIO_DEVICE_API_VERSION_1_0 + +/** + * List of known radio HAL modules. This is the base name of the radio HAL + * library composed of the "radio." prefix, one of the base names below and + * a suffix specific to the device. + * E.g: radio.fm.default.so + */ + +#define RADIO_HARDWARE_MODULE_ID_FM "fm" /* corresponds to RADIO_CLASS_AM_FM */ +#define RADIO_HARDWARE_MODULE_ID_SAT "sat" /* corresponds to RADIO_CLASS_SAT */ +#define RADIO_HARDWARE_MODULE_ID_DT "dt" /* corresponds to RADIO_CLASS_DT */ + + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +struct radio_module { + struct hw_module_t common; +}; + +/* + * Callback function called by the HAL when one of the following occurs: + * - event RADIO_EVENT_HW_FAILURE: radio chip of driver failure requiring + * closing and reopening of the tuner interface. + * - event RADIO_EVENT_CONFIG: new configuration applied in response to open_tuner(), + * or set_configuration(). The event status is 0 (no error) if the configuration has been applied, + * -EINVAL is not or -ETIMEDOUT in case of time out. + * - event RADIO_EVENT_TUNED: tune locked on new station/frequency following scan(), + * step(), tune() or auto AF switching. The event status is 0 (no error) if in tune, + * -EINVAL is not tuned and data in radio_program_info is not valid or -ETIMEDOUT if scan() + * timed out. + * - event RADIO_EVENT_TA: at the beginning and end of traffic announcement if current + * configuration enables TA. + * - event RADIO_EVENT_AF: after automatic switching to alternate frequency if current + * configuration enables AF switching. + * - event RADIO_EVENT_ANTENNA: when the antenna is connected or disconnected. + * - event RADIO_EVENT_METADATA: when new meta data are received from the tuned station. + * The callback MUST NOT be called synchronously while executing a HAL function but from + * a separate thread. + */ +typedef void (*radio_callback_t)(radio_hal_event_t *event, void *cookie); + +/* control interface for a radio tuner */ +struct radio_tuner { + /* + * Apply current radio band configuration (band, range, channel spacing ...). + * + * arguments: + * - config: the band configuration to apply + * + * returns: + * 0 if configuration could be applied + * -EINVAL if configuration requested is invalid + * + * Automatically cancels pending scan, step or tune. + * + * Callback function with event RADIO_EVENT_CONFIG MUST be called once the + * configuration is applied or a failure occurs or after a time out. + */ + int (*set_configuration)(const struct radio_tuner *tuner, + const radio_hal_band_config_t *config); + + /* + * Retrieve current radio band configuration. + * + * arguments: + * - config: where to return the band configuration + * + * returns: + * 0 if valid configuration is returned + * -EINVAL if invalid arguments are passed + */ + int (*get_configuration)(const struct radio_tuner *tuner, + radio_hal_band_config_t *config); + + /* + * Start scanning up to next valid station. + * Must be called when a valid configuration has been applied. + * + * arguments: + * - direction: RADIO_DIRECTION_UP or RADIO_DIRECTION_DOWN + * - skip_sub_channel: valid for HD radio or digital radios only: ignore sub channels + * (e.g SPS for HD radio). + * + * returns: + * 0 if scan successfully started + * -ENOSYS if called out of sequence + * -ENODEV if another error occurs + * + * Automatically cancels pending scan, step or tune. + * + * Callback function with event RADIO_EVENT_TUNED MUST be called once + * locked on a station or after a time out or full frequency scan if + * no station found. The event status should indicate if a valid station + * is tuned or not. + */ + int (*scan)(const struct radio_tuner *tuner, + radio_direction_t direction, bool skip_sub_channel); + + /* + * Move one channel spacing up or down. + * Must be called when a valid configuration has been applied. + * + * arguments: + * - direction: RADIO_DIRECTION_UP or RADIO_DIRECTION_DOWN + * - skip_sub_channel: valid for HD radio or digital radios only: ignore sub channels + * (e.g SPS for HD radio). + * + * returns: + * 0 if step successfully started + * -ENOSYS if called out of sequence + * -ENODEV if another error occurs + * + * Automatically cancels pending scan, step or tune. + * + * Callback function with event RADIO_EVENT_TUNED MUST be called once + * step completed or after a time out. The event status should indicate + * if a valid station is tuned or not. + */ + int (*step)(const struct radio_tuner *tuner, + radio_direction_t direction, bool skip_sub_channel); + + /* + * Tune to specified frequency. + * Must be called when a valid configuration has been applied. + * + * arguments: + * - channel: channel to tune to. A frequency in kHz for AM/FM/HD Radio bands. + * - sub_channel: valid for HD radio or digital radios only: (e.g SPS number for HD radio). + * + * returns: + * 0 if tune successfully started + * -ENOSYS if called out of sequence + * -EINVAL if invalid arguments are passed + * -ENODEV if another error occurs + * + * Automatically cancels pending scan, step or tune. + * + * Callback function with event RADIO_EVENT_TUNED MUST be called once + * tuned or after a time out. The event status should indicate + * if a valid station is tuned or not. + */ + int (*tune)(const struct radio_tuner *tuner, + unsigned int channel, unsigned int sub_channel); + + /* + * Cancel a scan, step or tune operation. + * Must be called while a scan, step or tune operation is pending + * (callback not yet sent). + * + * returns: + * 0 if successful + * -ENOSYS if called out of sequence + * -ENODEV if another error occurs + * + * The callback is not sent. + */ + int (*cancel)(const struct radio_tuner *tuner); + + /* + * Retrieve current station information. + * + * arguments: + * - info: where to return the program info. + * If info->metadata is NULL. no meta data should be returned. + * If meta data must be returned, they should be added to or cloned to + * info->metadata, not passed from a newly created meta data buffer. + * + * returns: + * 0 if tuned and information available + * -EINVAL if invalid arguments are passed + * -ENODEV if another error occurs + */ + int (*get_program_information)(const struct radio_tuner *tuner, + radio_program_info_t *info); +}; + +struct radio_hw_device { + struct hw_device_t common; + + /* + * Retrieve implementation properties. + * + * arguments: + * - properties: where to return the module properties + * + * returns: + * 0 if no error + * -EINVAL if invalid arguments are passed + */ + int (*get_properties)(const struct radio_hw_device *dev, + radio_hal_properties_t *properties); + + /* + * Open a tuner interface for the requested configuration. + * If no other tuner is opened, this will activate the radio module. + * + * arguments: + * - config: the band configuration to apply + * - audio: this tuner will be used for live radio listening and should be connected to + * the radio audio source. + * - callback: the event callback + * - cookie: the cookie to pass when calling the callback + * - tuner: where to return the tuner interface + * + * returns: + * 0 if HW was powered up and configuration could be applied + * -EINVAL if configuration requested is invalid + * -ENOSYS if called out of sequence + * + * Callback function with event RADIO_EVENT_CONFIG MUST be called once the + * configuration is applied or a failure occurs or after a time out. + */ + int (*open_tuner)(const struct radio_hw_device *dev, + const radio_hal_band_config_t *config, + bool audio, + radio_callback_t callback, + void *cookie, + const struct radio_tuner **tuner); + + /* + * Close a tuner interface. + * If the last tuner is closed, the radio module is deactivated. + * + * arguments: + * - tuner: the tuner interface to close + * + * returns: + * 0 if powered down successfully. + * -EINVAL if an invalid argument is passed + * -ENOSYS if called out of sequence + */ + int (*close_tuner)(const struct radio_hw_device *dev, const struct radio_tuner *tuner); + +}; + +typedef struct radio_hw_device radio_hw_device_t; + +/** convenience API for opening and closing a supported device */ + +static inline int radio_hw_device_open(const struct hw_module_t* module, + struct radio_hw_device** device) +{ + return module->methods->open(module, RADIO_HARDWARE_DEVICE, + (struct hw_device_t**)device); +} + +static inline int radio_hw_device_close(const struct radio_hw_device* device) +{ + return device->common.close((struct hw_device_t *)&device->common); +} + +__END_DECLS + +#endif // ANDROID_RADIO_HAL_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/sensors.h b/phonelibs/android_hardware_libhardware/include/hardware/sensors.h new file mode 100644 index 00000000000000..51bffe1196e6d7 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/sensors.h @@ -0,0 +1,1096 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SENSORS_INTERFACE_H +#define ANDROID_SENSORS_INTERFACE_H + +#include +#include +#include + +#include +#include + +__BEGIN_DECLS + +/*****************************************************************************/ + +#define SENSORS_HEADER_VERSION 1 +#define SENSORS_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1) +#define SENSORS_DEVICE_API_VERSION_0_1 HARDWARE_DEVICE_API_VERSION_2(0, 1, SENSORS_HEADER_VERSION) +#define SENSORS_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION_2(1, 0, SENSORS_HEADER_VERSION) +#define SENSORS_DEVICE_API_VERSION_1_1 HARDWARE_DEVICE_API_VERSION_2(1, 1, SENSORS_HEADER_VERSION) +#define SENSORS_DEVICE_API_VERSION_1_2 HARDWARE_DEVICE_API_VERSION_2(1, 2, SENSORS_HEADER_VERSION) +#define SENSORS_DEVICE_API_VERSION_1_3 HARDWARE_DEVICE_API_VERSION_2(1, 3, SENSORS_HEADER_VERSION) +#define SENSORS_DEVICE_API_VERSION_1_4 HARDWARE_DEVICE_API_VERSION_2(1, 4, SENSORS_HEADER_VERSION) + +/** + * Please see the Sensors section of source.android.com for an + * introduction to and detailed descriptions of Android sensor types: + * http://source.android.com/devices/sensors/index.html + */ + +/** + * The id of this module + */ +#define SENSORS_HARDWARE_MODULE_ID "sensors" + +/** + * Name of the sensors device to open + */ +#define SENSORS_HARDWARE_POLL "poll" + +/** + * Handles must be higher than SENSORS_HANDLE_BASE and must be unique. + * A Handle identifies a given sensors. The handle is used to activate + * and/or deactivate sensors. + * In this version of the API there can only be 256 handles. + */ +#define SENSORS_HANDLE_BASE 0 +#define SENSORS_HANDLE_BITS 8 +#define SENSORS_HANDLE_COUNT (1< 35 degrees + * + * Large accelerations without a change in phone orientation should not trigger a tilt event. + * For example, a sharp turn or strong acceleration while driving a car should not trigger a tilt + * event, even though the angle of the average acceleration might vary by more than 35 degrees. + * + * Typically, this sensor is implemented with the help of only an accelerometer. Other sensors can + * be used as well if they do not increase the power consumption significantly. This is a low power + * sensor that should allow the AP to go into suspend mode. Do not emulate this sensor in the HAL. + * Like other wake up sensors, the driver is expected to a hold a wake_lock with a timeout of 200 ms + * while reporting this event. The only allowed return value is 1.0. + * + * Implement only the wake-up version of this sensor. + */ +#define SENSOR_TYPE_TILT_DETECTOR (22) +#define SENSOR_STRING_TYPE_TILT_DETECTOR "android.sensor.tilt_detector" + +/* + * SENSOR_TYPE_WAKE_GESTURE + * reporting-mode: one-shot + * + * A sensor enabling waking up the device based on a device specific motion. + * + * When this sensor triggers, the device behaves as if the power button was + * pressed, turning the screen on. This behavior (turning on the screen when + * this sensor triggers) might be deactivated by the user in the device + * settings. Changes in settings do not impact the behavior of the sensor: + * only whether the framework turns the screen on when it triggers. + * + * The actual gesture to be detected is not specified, and can be chosen by + * the manufacturer of the device. + * This sensor must be low power, as it is likely to be activated 24/7. + * The only allowed value to return is 1.0. + * + * Implement only the wake-up version of this sensor. + */ +#define SENSOR_TYPE_WAKE_GESTURE (23) +#define SENSOR_STRING_TYPE_WAKE_GESTURE "android.sensor.wake_gesture" + +/* + * SENSOR_TYPE_GLANCE_GESTURE + * reporting-mode: one-shot + * + * A sensor enabling briefly turning the screen on to enable the user to + * glance content on screen based on a specific motion. The device should + * turn the screen off after a few moments. + * + * When this sensor triggers, the device turns the screen on momentarily + * to allow the user to glance notifications or other content while the + * device remains locked in a non-interactive state (dozing). This behavior + * (briefly turning on the screen when this sensor triggers) might be deactivated + * by the user in the device settings. Changes in settings do not impact the + * behavior of the sensor: only whether the framework briefly turns the screen on + * when it triggers. + * + * The actual gesture to be detected is not specified, and can be chosen by + * the manufacturer of the device. + * This sensor must be low power, as it is likely to be activated 24/7. + * The only allowed value to return is 1.0. + * + * Implement only the wake-up version of this sensor. + */ +#define SENSOR_TYPE_GLANCE_GESTURE (24) +#define SENSOR_STRING_TYPE_GLANCE_GESTURE "android.sensor.glance_gesture" + +/** + * SENSOR_TYPE_PICK_UP_GESTURE + * reporting-mode: one-shot + * + * A sensor of this type triggers when the device is picked up regardless of wherever is was + * before (desk, pocket, bag). The only allowed return value is 1.0. + * This sensor de-activates itself immediately after it triggers. + * + * Implement only the wake-up version of this sensor. + */ +#define SENSOR_TYPE_PICK_UP_GESTURE (25) +#define SENSOR_STRING_TYPE_PICK_UP_GESTURE "android.sensor.pick_up_gesture" + +/* + * SENSOR_TYPE_WRIST_TILT_GESTURE + * trigger-mode: special + * wake-up sensor: yes + * + * A sensor of this type triggers an event each time a tilt of the wrist-worn + * device is detected. + * + * This sensor must be low power, as it is likely to be activated 24/7. + * The only allowed value to return is 1.0. + * + * Implement only the wake-up version of this sensor. + */ +#define SENSOR_TYPE_WRIST_TILT_GESTURE (26) +#define SENSOR_STRING_TYPE_WRIST_TILT_GESTURE "android.sensor.wrist_tilt_gesture" + +/** + * Values returned by the accelerometer in various locations in the universe. + * all values are in SI units (m/s^2) + */ +#define GRAVITY_SUN (275.0f) +#define GRAVITY_EARTH (9.80665f) + +/** Maximum magnetic field on Earth's surface */ +#define MAGNETIC_FIELD_EARTH_MAX (60.0f) + +/** Minimum magnetic field on Earth's surface */ +#define MAGNETIC_FIELD_EARTH_MIN (30.0f) + +/** + * Possible values of the status field of sensor events. + */ +#define SENSOR_STATUS_NO_CONTACT -1 +#define SENSOR_STATUS_UNRELIABLE 0 +#define SENSOR_STATUS_ACCURACY_LOW 1 +#define SENSOR_STATUS_ACCURACY_MEDIUM 2 +#define SENSOR_STATUS_ACCURACY_HIGH 3 + +/** + * sensor event data + */ +typedef struct { + union { + float v[3]; + struct { + float x; + float y; + float z; + }; + struct { + float azimuth; + float pitch; + float roll; + }; + }; + int8_t status; + uint8_t reserved[3]; +} sensors_vec_t; + +/** + * uncalibrated gyroscope and magnetometer event data + */ +typedef struct { + union { + float uncalib[3]; + struct { + float x_uncalib; + float y_uncalib; + float z_uncalib; + }; + }; + union { + float bias[3]; + struct { + float x_bias; + float y_bias; + float z_bias; + }; + }; +} uncalibrated_event_t; + +/** + * Meta data event data + */ +typedef struct meta_data_event { + int32_t what; + int32_t sensor; +} meta_data_event_t; + +/** + * Heart rate event data + */ +typedef struct { + // Heart rate in beats per minute. + // Set to 0 when status is SENSOR_STATUS_UNRELIABLE or ..._NO_CONTACT + float bpm; + // Status of the sensor for this reading. Set to one SENSOR_STATUS_... + // Note that this value should only be set for sensors that explicitly define + // the meaning of this field. This field is not piped through the framework + // for other sensors. + int8_t status; +} heart_rate_event_t; + +/** + * Union of the various types of sensor data + * that can be returned. + */ +typedef struct sensors_event_t { + /* must be sizeof(struct sensors_event_t) */ + int32_t version; + + /* sensor identifier */ + int32_t sensor; + + /* sensor type */ + int32_t type; + + /* reserved */ + int32_t reserved0; + + /* time is in nanosecond */ + int64_t timestamp; + + union { + union { + float data[16]; + + /* acceleration values are in meter per second per second (m/s^2) */ + sensors_vec_t acceleration; + + /* magnetic vector values are in micro-Tesla (uT) */ + sensors_vec_t magnetic; + + /* orientation values are in degrees */ + sensors_vec_t orientation; + + /* gyroscope values are in rad/s */ + sensors_vec_t gyro; + + /* temperature is in degrees centigrade (Celsius) */ + float temperature; + + /* distance in centimeters */ + float distance; + + /* light in SI lux units */ + float light; + + /* pressure in hectopascal (hPa) */ + float pressure; + + /* relative humidity in percent */ + float relative_humidity; + + /* uncalibrated gyroscope values are in rad/s */ + uncalibrated_event_t uncalibrated_gyro; + + /* uncalibrated magnetometer values are in micro-Teslas */ + uncalibrated_event_t uncalibrated_magnetic; + + /* heart rate data containing value in bpm and status */ + heart_rate_event_t heart_rate; + + /* this is a special event. see SENSOR_TYPE_META_DATA above. + * sensors_meta_data_event_t events are all reported with a type of + * SENSOR_TYPE_META_DATA. The handle is ignored and must be zero. + */ + meta_data_event_t meta_data; + }; + + union { + uint64_t data[8]; + + /* step-counter */ + uint64_t step_counter; + } u64; + }; + + /* Reserved flags for internal use. Set to zero. */ + uint32_t flags; + + uint32_t reserved1[3]; +} sensors_event_t; + + +/* see SENSOR_TYPE_META_DATA */ +typedef sensors_event_t sensors_meta_data_event_t; + + +struct sensor_t; + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +struct sensors_module_t { + struct hw_module_t common; + + /** + * Enumerate all available sensors. The list is returned in "list". + * @return number of sensors in the list + */ + int (*get_sensors_list)(struct sensors_module_t* module, + struct sensor_t const** list); + + /** + * Place the module in a specific mode. The following modes are defined + * + * 0 - Normal operation. Default state of the module. + * 1 - Loopback mode. Data is injected for the the supported + * sensors by the sensor service in this mode. + * @return 0 on success + * -EINVAL if requested mode is not supported + * -EPERM if operation is not allowed + */ + int (*set_operation_mode)(unsigned int mode); +}; + +struct sensor_t { + + /* Name of this sensor. + * All sensors of the same "type" must have a different "name". + */ + const char* name; + + /* vendor of the hardware part */ + const char* vendor; + + /* version of the hardware part + driver. The value of this field + * must increase when the driver is updated in a way that changes the + * output of this sensor. This is important for fused sensors when the + * fusion algorithm is updated. + */ + int version; + + /* handle that identifies this sensors. This handle is used to reference + * this sensor throughout the HAL API. + */ + int handle; + + /* this sensor's type. */ + int type; + + /* maximum range of this sensor's value in SI units */ + float maxRange; + + /* smallest difference between two values reported by this sensor */ + float resolution; + + /* rough estimate of this sensor's power consumption in mA */ + float power; + + /* this value depends on the reporting mode: + * + * continuous: minimum sample period allowed in microseconds + * on-change : 0 + * one-shot :-1 + * special : 0, unless otherwise noted + */ + int32_t minDelay; + + /* number of events reserved for this sensor in the batch mode FIFO. + * If there is a dedicated FIFO for this sensor, then this is the + * size of this FIFO. If the FIFO is shared with other sensors, + * this is the size reserved for that sensor and it can be zero. + */ + uint32_t fifoReservedEventCount; + + /* maximum number of events of this sensor that could be batched. + * This is especially relevant when the FIFO is shared between + * several sensors; this value is then set to the size of that FIFO. + */ + uint32_t fifoMaxEventCount; + + /* type of this sensor as a string. Set to corresponding + * SENSOR_STRING_TYPE_*. + * When defining an OEM specific sensor or sensor manufacturer specific + * sensor, use your reserve domain name as a prefix. + * ex: com.google.glass.onheaddetector + * For sensors of known type, the android framework might overwrite this + * string automatically. + */ + const char* stringType; + + /* permission required to see this sensor, register to it and receive data. + * Set to "" if no permission is required. Some sensor types like the + * heart rate monitor have a mandatory require_permission. + * For sensors that always require a specific permission, like the heart + * rate monitor, the android framework might overwrite this string + * automatically. + */ + const char* requiredPermission; + + /* This value is defined only for continuous mode and on-change sensors. It is the delay between + * two sensor events corresponding to the lowest frequency that this sensor supports. When lower + * frequencies are requested through batch()/setDelay() the events will be generated at this + * frequency instead. It can be used by the framework or applications to estimate when the batch + * FIFO may be full. + * + * NOTE: 1) period_ns is in nanoseconds where as maxDelay/minDelay are in microseconds. + * continuous, on-change: maximum sampling period allowed in microseconds. + * one-shot, special : 0 + * 2) maxDelay should always fit within a 32 bit signed integer. It is declared as 64 bit + * on 64 bit architectures only for binary compatibility reasons. + * Availability: SENSORS_DEVICE_API_VERSION_1_3 + */ + #ifdef __LP64__ + int64_t maxDelay; + #else + int32_t maxDelay; + #endif + + /* Flags for sensor. See SENSOR_FLAG_* above. Only the least significant 32 bits are used here. + * It is declared as 64 bit on 64 bit architectures only for binary compatibility reasons. + * Availability: SENSORS_DEVICE_API_VERSION_1_3 + */ + #ifdef __LP64__ + uint64_t flags; + #else + uint32_t flags; + #endif + + /* reserved fields, must be zero */ + void* reserved[2]; +}; + + +/* + * sensors_poll_device_t is used with SENSORS_DEVICE_API_VERSION_0_1 + * and is present for backward binary and source compatibility. + * See the Sensors HAL interface section for complete descriptions of the + * following functions: + * http://source.android.com/devices/sensors/index.html#hal + */ +struct sensors_poll_device_t { + struct hw_device_t common; + int (*activate)(struct sensors_poll_device_t *dev, + int sensor_handle, int enabled); + int (*setDelay)(struct sensors_poll_device_t *dev, + int sensor_handle, int64_t sampling_period_ns); + int (*poll)(struct sensors_poll_device_t *dev, + sensors_event_t* data, int count); +}; + +/* + * struct sensors_poll_device_1 is used in HAL versions >= SENSORS_DEVICE_API_VERSION_1_0 + */ +typedef struct sensors_poll_device_1 { + union { + /* sensors_poll_device_1 is compatible with sensors_poll_device_t, + * and can be down-cast to it + */ + struct sensors_poll_device_t v0; + + struct { + struct hw_device_t common; + + /* Activate/de-activate one sensor. Return 0 on success, negative + * + * sensor_handle is the handle of the sensor to change. + * enabled set to 1 to enable, or 0 to disable the sensor. + * + * Return 0 on success, negative errno code otherwise. + */ + int (*activate)(struct sensors_poll_device_t *dev, + int sensor_handle, int enabled); + + /** + * Set the events's period in nanoseconds for a given sensor. + * If sampling_period_ns > max_delay it will be truncated to + * max_delay and if sampling_period_ns < min_delay it will be + * replaced by min_delay. + */ + int (*setDelay)(struct sensors_poll_device_t *dev, + int sensor_handle, int64_t sampling_period_ns); + + /** + * Returns an array of sensor data. + */ + int (*poll)(struct sensors_poll_device_t *dev, + sensors_event_t* data, int count); + }; + }; + + + /* + * Sets a sensor’s parameters, including sampling frequency and maximum + * report latency. This function can be called while the sensor is + * activated, in which case it must not cause any sensor measurements to + * be lost: transitioning from one sampling rate to the other cannot cause + * lost events, nor can transitioning from a high maximum report latency to + * a low maximum report latency. + * See the Batching sensor results page for details: + * http://source.android.com/devices/sensors/batching.html + */ + int (*batch)(struct sensors_poll_device_1* dev, + int sensor_handle, int flags, int64_t sampling_period_ns, + int64_t max_report_latency_ns); + + /* + * Flush adds a META_DATA_FLUSH_COMPLETE event (sensors_event_meta_data_t) + * to the end of the "batch mode" FIFO for the specified sensor and flushes + * the FIFO. + * If the FIFO is empty or if the sensor doesn't support batching (FIFO size zero), + * it should return SUCCESS along with a trivial META_DATA_FLUSH_COMPLETE event added to the + * event stream. This applies to all sensors other than one-shot sensors. + * If the sensor is a one-shot sensor, flush must return -EINVAL and not generate + * any flush complete metadata. + * If the sensor is not active at the time flush() is called, flush() should return + * -EINVAL. + */ + int (*flush)(struct sensors_poll_device_1* dev, int sensor_handle); + + /* + * Inject a single sensor sample to be to this device. + * data points to the sensor event to be injected + * @return 0 on success + * -EPERM if operation is not allowed + * -EINVAL if sensor event cannot be injected + */ + int (*inject_sensor_data)(struct sensors_poll_device_1 *dev, const sensors_event_t *data); + + void (*reserved_procs[7])(void); + +} sensors_poll_device_1_t; + + +/** convenience API for opening and closing a device */ + +static inline int sensors_open(const struct hw_module_t* module, + struct sensors_poll_device_t** device) { + return module->methods->open(module, + SENSORS_HARDWARE_POLL, (struct hw_device_t**)device); +} + +static inline int sensors_close(struct sensors_poll_device_t* device) { + return device->common.close(&device->common); +} + +static inline int sensors_open_1(const struct hw_module_t* module, + sensors_poll_device_1_t** device) { + return module->methods->open(module, + SENSORS_HARDWARE_POLL, (struct hw_device_t**)device); +} + +static inline int sensors_close_1(sensors_poll_device_1_t* device) { + return device->common.close(&device->common); +} + +__END_DECLS + +#endif // ANDROID_SENSORS_INTERFACE_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/sound_trigger.h b/phonelibs/android_hardware_libhardware/include/hardware/sound_trigger.h new file mode 100644 index 00000000000000..2a8db87caae265 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/sound_trigger.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#ifndef ANDROID_SOUND_TRIGGER_HAL_H +#define ANDROID_SOUND_TRIGGER_HAL_H + + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define SOUND_TRIGGER_HARDWARE_MODULE_ID "sound_trigger" + +/** + * Name of the audio devices to open + */ +#define SOUND_TRIGGER_HARDWARE_INTERFACE "sound_trigger_hw_if" + +#define SOUND_TRIGGER_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0) +#define SOUND_TRIGGER_MODULE_API_VERSION_CURRENT SOUND_TRIGGER_MODULE_API_VERSION_1_0 + + +#define SOUND_TRIGGER_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0) +#define SOUND_TRIGGER_DEVICE_API_VERSION_CURRENT SOUND_TRIGGER_DEVICE_API_VERSION_1_0 + +/** + * List of known sound trigger HAL modules. This is the base name of the sound_trigger HAL + * library composed of the "sound_trigger." prefix, one of the base names below and + * a suffix specific to the device. + * e.g: sondtrigger.primary.goldfish.so or sound_trigger.primary.default.so + */ + +#define SOUND_TRIGGER_HARDWARE_MODULE_ID_PRIMARY "primary" + + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +struct sound_trigger_module { + struct hw_module_t common; +}; + +typedef void (*recognition_callback_t)(struct sound_trigger_recognition_event *event, void *cookie); +typedef void (*sound_model_callback_t)(struct sound_trigger_model_event *event, void *cookie); + +struct sound_trigger_hw_device { + struct hw_device_t common; + + /* + * Retrieve implementation properties. + */ + int (*get_properties)(const struct sound_trigger_hw_device *dev, + struct sound_trigger_properties *properties); + + /* + * Load a sound model. Once loaded, recognition of this model can be started and stopped. + * Only one active recognition per model at a time. The SoundTrigger service will handle + * concurrent recognition requests by different users/applications on the same model. + * The implementation returns a unique handle used by other functions (unload_sound_model(), + * start_recognition(), etc... + */ + int (*load_sound_model)(const struct sound_trigger_hw_device *dev, + struct sound_trigger_sound_model *sound_model, + sound_model_callback_t callback, + void *cookie, + sound_model_handle_t *handle); + + /* + * Unload a sound model. A sound model can be unloaded to make room for a new one to overcome + * implementation limitations. + */ + int (*unload_sound_model)(const struct sound_trigger_hw_device *dev, + sound_model_handle_t handle); + + /* Start recognition on a given model. Only one recognition active at a time per model. + * Once recognition succeeds of fails, the callback is called. + * TODO: group recognition configuration parameters into one struct and add key phrase options. + */ + int (*start_recognition)(const struct sound_trigger_hw_device *dev, + sound_model_handle_t sound_model_handle, + const struct sound_trigger_recognition_config *config, + recognition_callback_t callback, + void *cookie); + + /* Stop recognition on a given model. + * The implementation does not have to call the callback when stopped via this method. + */ + int (*stop_recognition)(const struct sound_trigger_hw_device *dev, + sound_model_handle_t sound_model_handle); +}; + +typedef struct sound_trigger_hw_device sound_trigger_hw_device_t; + +/** convenience API for opening and closing a supported device */ + +static inline int sound_trigger_hw_device_open(const struct hw_module_t* module, + struct sound_trigger_hw_device** device) +{ + return module->methods->open(module, SOUND_TRIGGER_HARDWARE_INTERFACE, + (struct hw_device_t**)device); +} + +static inline int sound_trigger_hw_device_close(struct sound_trigger_hw_device* device) +{ + return device->common.close(&device->common); +} + +__END_DECLS + +#endif // ANDROID_SOUND_TRIGGER_HAL_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/tv_input.h b/phonelibs/android_hardware_libhardware/include/hardware/tv_input.h new file mode 100644 index 00000000000000..456b06e1fdebc9 --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/tv_input.h @@ -0,0 +1,408 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_TV_INPUT_INTERFACE_H +#define ANDROID_TV_INPUT_INTERFACE_H + +#include +#include +#include + +#include +#include +#include + +__BEGIN_DECLS + +/* + * Module versioning information for the TV input hardware module, based on + * tv_input_module_t.common.module_api_version. + * + * Version History: + * + * TV_INPUT_MODULE_API_VERSION_0_1: + * Initial TV input hardware module API. + * + */ + +#define TV_INPUT_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1) + +#define TV_INPUT_DEVICE_API_VERSION_0_1 HARDWARE_DEVICE_API_VERSION(0, 1) + +/* + * The id of this module + */ +#define TV_INPUT_HARDWARE_MODULE_ID "tv_input" + +#define TV_INPUT_DEFAULT_DEVICE "default" + +/*****************************************************************************/ + +/* + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +typedef struct tv_input_module { + struct hw_module_t common; +} tv_input_module_t; + +/*****************************************************************************/ + +enum { + /* Generic hardware. */ + TV_INPUT_TYPE_OTHER_HARDWARE = 1, + /* Tuner. (e.g. built-in terrestrial tuner) */ + TV_INPUT_TYPE_TUNER = 2, + TV_INPUT_TYPE_COMPOSITE = 3, + TV_INPUT_TYPE_SVIDEO = 4, + TV_INPUT_TYPE_SCART = 5, + TV_INPUT_TYPE_COMPONENT = 6, + TV_INPUT_TYPE_VGA = 7, + TV_INPUT_TYPE_DVI = 8, + /* Physical HDMI port. (e.g. HDMI 1) */ + TV_INPUT_TYPE_HDMI = 9, + TV_INPUT_TYPE_DISPLAY_PORT = 10, +}; +typedef uint32_t tv_input_type_t; + +typedef struct tv_input_device_info { + /* Device ID */ + int device_id; + + /* Type of physical TV input. */ + tv_input_type_t type; + + union { + struct { + /* HDMI port ID number */ + uint32_t port_id; + } hdmi; + + /* TODO: add other type specific information. */ + + int32_t type_info_reserved[16]; + }; + + /* TODO: Add capability if necessary. */ + + /* + * Audio info + * + * audio_type == AUDIO_DEVICE_NONE if this input has no audio. + */ + audio_devices_t audio_type; + const char* audio_address; + + int32_t reserved[16]; +} tv_input_device_info_t; + +/* See tv_input_event_t for more details. */ +enum { + /* + * Hardware notifies the framework that a device is available. + * + * Note that DEVICE_AVAILABLE and DEVICE_UNAVAILABLE events do not represent + * hotplug events (i.e. plugging cable into or out of the physical port). + * These events notify the framework whether the port is available or not. + * For a concrete example, when a user plugs in or pulls out the HDMI cable + * from a HDMI port, it does not generate DEVICE_AVAILABLE and/or + * DEVICE_UNAVAILABLE events. However, if a user inserts a pluggable USB + * tuner into the Android device, it will generate a DEVICE_AVAILABLE event + * and when the port is removed, it should generate a DEVICE_UNAVAILABLE + * event. + * + * For hotplug events, please see STREAM_CONFIGURATION_CHANGED for more + * details. + * + * HAL implementation should register devices by using this event when the + * device boots up. The framework will recognize device reported via this + * event only. In addition, the implementation could use this event to + * notify the framework that a removable TV input device (such as USB tuner + * as stated in the example above) is attached. + */ + TV_INPUT_EVENT_DEVICE_AVAILABLE = 1, + /* + * Hardware notifies the framework that a device is unavailable. + * + * HAL implementation should generate this event when a device registered + * by TV_INPUT_EVENT_DEVICE_AVAILABLE is no longer available. For example, + * the event can indicate that a USB tuner is plugged out from the Android + * device. + * + * Note that this event is not for indicating cable plugged out of the port; + * for that purpose, the implementation should use + * STREAM_CONFIGURATION_CHANGED event. This event represents the port itself + * being no longer available. + */ + TV_INPUT_EVENT_DEVICE_UNAVAILABLE = 2, + /* + * Stream configurations are changed. Client should regard all open streams + * at the specific device are closed, and should call + * get_stream_configurations() again, opening some of them if necessary. + * + * HAL implementation should generate this event when the available stream + * configurations change for any reason. A typical use case of this event + * would be to notify the framework that the input signal has changed + * resolution, or that the cable is plugged out so that the number of + * available streams is 0. + * + * The implementation may use this event to indicate hotplug status of the + * port. the framework regards input devices with no available streams as + * disconnected, so the implementation can generate this event with no + * available streams to indicate that this device is disconnected, and vice + * versa. + */ + TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED = 3, + /* + * Hardware is done with capture request with the buffer. Client can assume + * ownership of the buffer again. + * + * HAL implementation should generate this event after request_capture() if + * it succeeded. The event shall have the buffer with the captured image. + */ + TV_INPUT_EVENT_CAPTURE_SUCCEEDED = 4, + /* + * Hardware met a failure while processing a capture request or client + * canceled the request. Client can assume ownership of the buffer again. + * + * The event is similar to TV_INPUT_EVENT_CAPTURE_SUCCEEDED, but HAL + * implementation generates this event upon a failure to process + * request_capture(), or a request cancellation. + */ + TV_INPUT_EVENT_CAPTURE_FAILED = 5, +}; +typedef uint32_t tv_input_event_type_t; + +typedef struct tv_input_capture_result { + /* Device ID */ + int device_id; + + /* Stream ID */ + int stream_id; + + /* Sequence number of the request */ + uint32_t seq; + + /* + * The buffer passed to hardware in request_capture(). The content of + * buffer is undefined (although buffer itself is valid) for + * TV_INPUT_CAPTURE_FAILED event. + */ + buffer_handle_t buffer; + + /* + * Error code for the request. -ECANCELED if request is cancelled; other + * error codes are unknown errors. + */ + int error_code; +} tv_input_capture_result_t; + +typedef struct tv_input_event { + tv_input_event_type_t type; + + union { + /* + * TV_INPUT_EVENT_DEVICE_AVAILABLE: all fields are relevant + * TV_INPUT_EVENT_DEVICE_UNAVAILABLE: only device_id is relevant + * TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED: only device_id is + * relevant + */ + tv_input_device_info_t device_info; + /* + * TV_INPUT_EVENT_CAPTURE_SUCCEEDED: error_code is not relevant + * TV_INPUT_EVENT_CAPTURE_FAILED: all fields are relevant + */ + tv_input_capture_result_t capture_result; + }; +} tv_input_event_t; + +typedef struct tv_input_callback_ops { + /* + * event contains the type of the event and additional data if necessary. + * The event object is guaranteed to be valid only for the duration of the + * call. + * + * data is an object supplied at device initialization, opaque to the + * hardware. +     */ + void (*notify)(struct tv_input_device* dev, + tv_input_event_t* event, void* data); +} tv_input_callback_ops_t; + +enum { + TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE = 1, + TV_STREAM_TYPE_BUFFER_PRODUCER = 2, +}; +typedef uint32_t tv_stream_type_t; + +typedef struct tv_stream_config { + /* + * ID number of the stream. This value is used to identify the whole stream + * configuration. + */ + int stream_id; + + /* Type of the stream */ + tv_stream_type_t type; + + /* Max width/height of the stream. */ + uint32_t max_video_width; + uint32_t max_video_height; +} tv_stream_config_t; + +typedef struct buffer_producer_stream { + /* + * IN/OUT: Width / height of the stream. Client may request for specific + * size but hardware may change it. Client must allocate buffers with + * specified width and height. + */ + uint32_t width; + uint32_t height; + + /* OUT: Client must set this usage when allocating buffer. */ + uint32_t usage; + + /* OUT: Client must allocate a buffer with this format. */ + uint32_t format; + + /* OUT: Client must allocate buffers based on this count. */ + uint32_t buffer_count; +} buffer_producer_stream_t; + +typedef struct tv_stream { + /* IN: ID in the stream configuration */ + int stream_id; + + /* OUT: Type of the stream (for convenience) */ + tv_stream_type_t type; + + /* Data associated with the stream for client's use */ + union { + /* OUT: A native handle describing the sideband stream source */ + native_handle_t* sideband_stream_source_handle; + + /* IN/OUT: Details are in buffer_producer_stream_t */ + buffer_producer_stream_t buffer_producer; + }; +} tv_stream_t; + +/* + * Every device data structure must begin with hw_device_t + * followed by module specific public methods and attributes. + */ +typedef struct tv_input_device { + struct hw_device_t common; + + /* + * initialize: + * + * Provide callbacks to the device and start operation. At first, no device + * is available and after initialize() completes, currently available + * devices including static devices should notify via callback. + * + * Framework owns callbacks object. + * + * data is a framework-owned object which would be sent back to the + * framework for each callback notifications. + * + * Return 0 on success. + */ + int (*initialize)(struct tv_input_device* dev, + const tv_input_callback_ops_t* callback, void* data); + + /* + * get_stream_configurations: + * + * Get stream configurations for a specific device. An input device may have + * multiple configurations. + * + * The configs object is guaranteed to be valid only until the next call to + * get_stream_configurations() or STREAM_CONFIGURATIONS_CHANGED event. + * + * Return 0 on success. + */ + int (*get_stream_configurations)(const struct tv_input_device* dev, + int device_id, int* num_configurations, + const tv_stream_config_t** configs); + + /* + * open_stream: + * + * Open a stream with given stream ID. Caller owns stream object, and the + * populated data is only valid until the stream is closed. + * + * Return 0 on success; -EBUSY if the client should close other streams to + * open the stream; -EEXIST if the stream with the given ID is already open; + * -EINVAL if device_id and/or stream_id are invalid; other non-zero value + * denotes unknown error. + */ + int (*open_stream)(struct tv_input_device* dev, int device_id, + tv_stream_t* stream); + + /* + * close_stream: + * + * Close a stream to a device. data in tv_stream_t* object associated with + * the stream_id is obsolete once this call finishes. + * + * Return 0 on success; -ENOENT if the stream is not open; -EINVAL if + * device_id and/or stream_id are invalid. + */ + int (*close_stream)(struct tv_input_device* dev, int device_id, + int stream_id); + + /* + * request_capture: + * + * Request buffer capture for a stream. This is only valid for buffer + * producer streams. The buffer should be created with size, format and + * usage specified in the stream. Framework provides seq in an + * increasing sequence per each stream. Hardware should provide the picture + * in a chronological order according to seq. For example, if two + * requests are being processed at the same time, the request with the + * smaller seq should get an earlier frame. + * + * The framework releases the ownership of the buffer upon calling this + * function. When the buffer is filled, hardware notifies the framework + * via TV_INPUT_EVENT_CAPTURE_FINISHED callback, and the ownership is + * transferred back to framework at that time. + * + * Return 0 on success; -ENOENT if the stream is not open; -EINVAL if + * device_id and/or stream_id are invalid; -EWOULDBLOCK if HAL cannot take + * additional requests until it releases a buffer. + */ + int (*request_capture)(struct tv_input_device* dev, int device_id, + int stream_id, buffer_handle_t buffer, uint32_t seq); + + /* + * cancel_capture: + * + * Cancel an ongoing capture. Hardware should release the buffer as soon as + * possible via TV_INPUT_EVENT_CAPTURE_FAILED callback. + * + * Return 0 on success; -ENOENT if the stream is not open; -EINVAL if + * device_id, stream_id, and/or seq are invalid. + */ + int (*cancel_capture)(struct tv_input_device* dev, int device_id, + int stream_id, uint32_t seq); + + void* reserved[16]; +} tv_input_device_t; + +__END_DECLS + +#endif // ANDROID_TV_INPUT_INTERFACE_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/vibrator.h b/phonelibs/android_hardware_libhardware/include/hardware/vibrator.h new file mode 100644 index 00000000000000..92b1fd0051388b --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/vibrator.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _HARDWARE_VIBRATOR_H +#define _HARDWARE_VIBRATOR_H + +#include + +__BEGIN_DECLS + +#define VIBRATOR_API_VERSION HARDWARE_MODULE_API_VERSION(1,0) + +/** + * The id of this module + */ +#define VIBRATOR_HARDWARE_MODULE_ID "vibrator" + +/** + * The id of the main vibrator device + */ +#define VIBRATOR_DEVICE_ID_MAIN "main_vibrator" + +struct vibrator_device; +typedef struct vibrator_device { + /** + * Common methods of the vibrator device. This *must* be the first member of + * vibrator_device as users of this structure will cast a hw_device_t to + * vibrator_device pointer in contexts where it's known the hw_device_t references a + * vibrator_device. + */ + struct hw_device_t common; + + /** Turn on vibrator + * + * What happens when this function is called while the the timeout of a + * previous call has not expired is implementation dependent. + * + * @param timeout_ms number of milliseconds to vibrate + * + * @return 0 in case of success, negative errno code else + */ + int (*vibrator_on)(struct vibrator_device* vibradev, unsigned int timeout_ms); + + /** Turn off vibrator + * + * It is not guaranteed that the vibrator will be immediately stopped: the + * behaviour is implementation dependent. + * + * @return 0 in case of success, negative errno code else + */ + int (*vibrator_off)(struct vibrator_device* vibradev); +} vibrator_device_t; + +static inline int vibrator_open(const struct hw_module_t* module, vibrator_device_t** device) +{ + return module->methods->open(module, VIBRATOR_DEVICE_ID_MAIN, (struct hw_device_t**)device); +} + +__END_DECLS + +#endif // _HARDWARE_VIBRATOR_H diff --git a/phonelibs/android_hardware_libhardware/include/hardware/wipower.h b/phonelibs/android_hardware_libhardware/include/hardware/wipower.h new file mode 100644 index 00000000000000..eb3a0ee0d54f5c --- /dev/null +++ b/phonelibs/android_hardware_libhardware/include/hardware/wipower.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2015, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * 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. + */ + +#ifndef ANDROID_INCLUDE_WIPOWER_H +#define ANDROID_INCLUDE_WIPOWER_H + +#include +#include +#include +#include + +#include +#include + +__BEGIN_DECLS + +typedef enum { + OFF =0, + ON +} wipower_state_t; + + +typedef struct { + +unsigned char optional; +unsigned short rect_voltage; +unsigned short rect_current; +unsigned short out_voltage; +unsigned short out_current; +unsigned char temp; +unsigned short rect_voltage_min; +unsigned short rect_voltage_set; +unsigned short rect_voltage_max; +unsigned char alert; +unsigned short rfu1; +unsigned char rfu2; + +}__attribute__((packed)) wipower_dyn_data_t; + +/** Bluetooth Enable/Disable Callback. */ +typedef void (*wipower_state_changed_callback)(wipower_state_t state); + + +typedef void (*wipower_alerts)(unsigned char alert); + + +typedef void (*wipower_dynamic_data)(wipower_dyn_data_t* alert_data); + + +typedef void (*wipower_power_apply)(unsigned char power_flag); + +typedef void (*callback_thread_event)(bt_cb_thread_evt evt); + +/** Bluetooth DM callback structure. */ +typedef struct { + /** set to sizeof(wipower_callbacks_t) */ + size_t size; + wipower_state_changed_callback wipower_state_changed_cb; + wipower_alerts wipower_alert; + wipower_dynamic_data wipower_data; + wipower_power_apply wipower_power_event; + callback_thread_event callback_thread_event; +} wipower_callbacks_t; + + +/** Represents the standard Wipower interface. */ +typedef struct { + /** set to sizeof(wipower_interface_t) */ + size_t size; + + /** Initialize Wipower modules*/ + int (*init)(wipower_callbacks_t *wp_callbacks); + + /** Enable/Disable Wipower charging */ + int (*enable)(bool enable); + + int (*set_current_limit)(short value); + + unsigned char (*get_current_limit)(void); + + wipower_state_t (*get_state)(void); + + /** Enable/Disable Wipower charging */ + int (*enable_alerts)(bool enable); + + int (*enable_data_notify)(bool enable); + int (*enable_power_apply)(bool enable, bool on, bool time_flag); +} wipower_interface_t; + + +__END_DECLS + +#endif /* ANDROID_INCLUDE_WIPOWER_H */ diff --git a/phonelibs/android_system_core/include/cutils/android_reboot.h b/phonelibs/android_system_core/include/cutils/android_reboot.h new file mode 100644 index 00000000000000..a3861a02dcd9ed --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/android_reboot.h @@ -0,0 +1,39 @@ +/* + * Copyright 2011, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_ANDROID_REBOOT_H__ +#define __CUTILS_ANDROID_REBOOT_H__ + +#include + +__BEGIN_DECLS + +/* Commands */ +#define ANDROID_RB_RESTART 0xDEAD0001 +#define ANDROID_RB_POWEROFF 0xDEAD0002 +#define ANDROID_RB_RESTART2 0xDEAD0003 + +/* Properties */ +#define ANDROID_RB_PROPERTY "sys.powerctl" + +int android_reboot(int cmd, int flags, const char *arg); +int android_reboot_with_callback( + int cmd, int flags, const char *arg, + void (*cb_on_remount)(const struct mntent*)); + +__END_DECLS + +#endif /* __CUTILS_ANDROID_REBOOT_H__ */ diff --git a/phonelibs/android_system_core/include/cutils/aref.h b/phonelibs/android_system_core/include/cutils/aref.h new file mode 100644 index 00000000000000..3bd36ea04c5481 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/aref.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _CUTILS_AREF_H_ +#define _CUTILS_AREF_H_ + +#include +#include + +#include + +__BEGIN_DECLS + +#define AREF_TO_ITEM(aref, container, member) \ + (container *) (((char*) (aref)) - offsetof(container, member)) + +struct aref +{ + volatile int32_t count; +}; + +static inline void aref_init(struct aref *r) +{ + r->count = 1; +} + +static inline int32_t aref_count(struct aref *r) +{ + return r->count; +} + +static inline void aref_get(struct aref *r) +{ + android_atomic_inc(&r->count); +} + +static inline void aref_put(struct aref *r, void (*release)(struct aref *)) +{ + if (android_atomic_dec(&r->count) == 1) + release(r); +} + +__END_DECLS + +#endif // _CUTILS_AREF_H_ diff --git a/phonelibs/android_system_core/include/cutils/ashmem.h b/phonelibs/android_system_core/include/cutils/ashmem.h new file mode 100644 index 00000000000000..25b233e6a1bf67 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/ashmem.h @@ -0,0 +1,45 @@ +/* cutils/ashmem.h + ** + ** Copyright 2008 The Android Open Source Project + ** + ** This file is dual licensed. It may be redistributed and/or modified + ** under the terms of the Apache 2.0 License OR version 2 of the GNU + ** General Public License. + */ + +#ifndef _CUTILS_ASHMEM_H +#define _CUTILS_ASHMEM_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int ashmem_create_region(const char *name, size_t size); +int ashmem_set_prot_region(int fd, int prot); +int ashmem_pin_region(int fd, size_t offset, size_t len); +int ashmem_unpin_region(int fd, size_t offset, size_t len); +int ashmem_get_size_region(int fd); + +#ifdef __cplusplus +} +#endif + +#ifndef __ASHMEMIOC /* in case someone included too */ + +#define ASHMEM_NAME_LEN 256 + +#define ASHMEM_NAME_DEF "dev/ashmem" + +/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */ +#define ASHMEM_NOT_PURGED 0 +#define ASHMEM_WAS_PURGED 1 + +/* Return values from ASHMEM_UNPIN: Is the mapping now pinned or unpinned? */ +#define ASHMEM_IS_UNPINNED 0 +#define ASHMEM_IS_PINNED 1 + +#endif /* ! __ASHMEMIOC */ + +#endif /* _CUTILS_ASHMEM_H */ diff --git a/phonelibs/android_system_core/include/cutils/atomic.h b/phonelibs/android_system_core/include/cutils/atomic.h new file mode 100644 index 00000000000000..ded972acb262aa --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/atomic.h @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_CUTILS_ATOMIC_H +#define ANDROID_CUTILS_ATOMIC_H + +#include +#include +#include + +#ifndef ANDROID_ATOMIC_INLINE +#define ANDROID_ATOMIC_INLINE static inline +#endif + +/* + * A handful of basic atomic operations. + * THESE ARE HERE FOR LEGACY REASONS ONLY. AVOID. + * + * PREFERRED ALTERNATIVES: + * - Use C++/C/pthread locks/mutexes whenever there is not a + * convincing reason to do otherwise. Note that very clever and + * complicated, but correct, lock-free code is often slower than + * using locks, especially where nontrivial data structures + * are involved. + * - C11 stdatomic.h. + * - Where supported, C++11 std::atomic . + * + * PLEASE STOP READING HERE UNLESS YOU ARE TRYING TO UNDERSTAND + * OR UPDATE OLD CODE. + * + * The "acquire" and "release" terms can be defined intuitively in terms + * of the placement of memory barriers in a simple lock implementation: + * - wait until compare-and-swap(lock-is-free --> lock-is-held) succeeds + * - barrier + * - [do work] + * - barrier + * - store(lock-is-free) + * In very crude terms, the initial (acquire) barrier prevents any of the + * "work" from happening before the lock is held, and the later (release) + * barrier ensures that all of the work happens before the lock is released. + * (Think of cached writes, cache read-ahead, and instruction reordering + * around the CAS and store instructions.) + * + * The barriers must apply to both the compiler and the CPU. Note it is + * legal for instructions that occur before an "acquire" barrier to be + * moved down below it, and for instructions that occur after a "release" + * barrier to be moved up above it. + * + * The ARM-driven implementation we use here is short on subtlety, + * and actually requests a full barrier from the compiler and the CPU. + * The only difference between acquire and release is in whether they + * are issued before or after the atomic operation with which they + * are associated. To ease the transition to C/C++ atomic intrinsics, + * you should not rely on this, and instead assume that only the minimal + * acquire/release protection is provided. + * + * NOTE: all int32_t* values are expected to be aligned on 32-bit boundaries. + * If they are not, atomicity is not guaranteed. + */ + +/* + * Basic arithmetic and bitwise operations. These all provide a + * barrier with "release" ordering, and return the previous value. + * + * These have the same characteristics (e.g. what happens on overflow) + * as the equivalent non-atomic C operations. + */ +ANDROID_ATOMIC_INLINE +int32_t android_atomic_inc(volatile int32_t* addr) +{ + volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr; + /* Int32_t, if it exists, is the same as int_least32_t. */ + return atomic_fetch_add_explicit(a, 1, memory_order_release); +} + +ANDROID_ATOMIC_INLINE +int32_t android_atomic_dec(volatile int32_t* addr) +{ + volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr; + return atomic_fetch_sub_explicit(a, 1, memory_order_release); +} + +ANDROID_ATOMIC_INLINE +int32_t android_atomic_add(int32_t value, volatile int32_t* addr) +{ + volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr; + return atomic_fetch_add_explicit(a, value, memory_order_release); +} + +ANDROID_ATOMIC_INLINE +int32_t android_atomic_and(int32_t value, volatile int32_t* addr) +{ + volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr; + return atomic_fetch_and_explicit(a, value, memory_order_release); +} + +ANDROID_ATOMIC_INLINE +int32_t android_atomic_or(int32_t value, volatile int32_t* addr) +{ + volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr; + return atomic_fetch_or_explicit(a, value, memory_order_release); +} + +/* + * Perform an atomic load with "acquire" or "release" ordering. + * + * Note that the notion of a "release" ordering for a load does not + * really fit into the C11 or C++11 memory model. The extra ordering + * is normally observable only by code using memory_order_relaxed + * atomics, or data races. In the rare cases in which such ordering + * is called for, use memory_order_relaxed atomics and a leading + * atomic_thread_fence (typically with memory_order_acquire, + * not memory_order_release!) instead. If you do not understand + * this comment, you are in the vast majority, and should not be + * using release loads or replacing them with anything other than + * locks or default sequentially consistent atomics. + */ +ANDROID_ATOMIC_INLINE +int32_t android_atomic_acquire_load(volatile const int32_t* addr) +{ + volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr; + return atomic_load_explicit(a, memory_order_acquire); +} + +ANDROID_ATOMIC_INLINE +int32_t android_atomic_release_load(volatile const int32_t* addr) +{ + volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr; + atomic_thread_fence(memory_order_seq_cst); + /* Any reasonable clients of this interface would probably prefer */ + /* something weaker. But some remaining clients seem to be */ + /* abusing this API in strange ways, e.g. by using it as a fence. */ + /* Thus we are conservative until we can get rid of remaining */ + /* clients (and this function). */ + return atomic_load_explicit(a, memory_order_relaxed); +} + +/* + * Perform an atomic store with "acquire" or "release" ordering. + * + * Note that the notion of an "acquire" ordering for a store does not + * really fit into the C11 or C++11 memory model. The extra ordering + * is normally observable only by code using memory_order_relaxed + * atomics, or data races. In the rare cases in which such ordering + * is called for, use memory_order_relaxed atomics and a trailing + * atomic_thread_fence (typically with memory_order_release, + * not memory_order_acquire!) instead. + */ +ANDROID_ATOMIC_INLINE +void android_atomic_acquire_store(int32_t value, volatile int32_t* addr) +{ + volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr; + atomic_store_explicit(a, value, memory_order_relaxed); + atomic_thread_fence(memory_order_seq_cst); + /* Again overly conservative to accomodate weird clients. */ +} + +ANDROID_ATOMIC_INLINE +void android_atomic_release_store(int32_t value, volatile int32_t* addr) +{ + volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr; + atomic_store_explicit(a, value, memory_order_release); +} + +/* + * Compare-and-set operation with "acquire" or "release" ordering. + * + * This returns zero if the new value was successfully stored, which will + * only happen when *addr == oldvalue. + * + * (The return value is inverted from implementations on other platforms, + * but matches the ARM ldrex/strex result.) + * + * Implementations that use the release CAS in a loop may be less efficient + * than possible, because we re-issue the memory barrier on each iteration. + */ +ANDROID_ATOMIC_INLINE +int android_atomic_acquire_cas(int32_t oldvalue, int32_t newvalue, + volatile int32_t* addr) +{ + volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr; + return (int)(!atomic_compare_exchange_strong_explicit( + a, &oldvalue, newvalue, + memory_order_acquire, + memory_order_acquire)); +} + +ANDROID_ATOMIC_INLINE +int android_atomic_release_cas(int32_t oldvalue, int32_t newvalue, + volatile int32_t* addr) +{ + volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr; + return (int)(!atomic_compare_exchange_strong_explicit( + a, &oldvalue, newvalue, + memory_order_release, + memory_order_relaxed)); +} + +/* + * Fence primitives. + */ +ANDROID_ATOMIC_INLINE +void android_compiler_barrier(void) +{ + __asm__ __volatile__ ("" : : : "memory"); + /* Could probably also be: */ + /* atomic_signal_fence(memory_order_seq_cst); */ +} + +ANDROID_ATOMIC_INLINE +void android_memory_barrier(void) +{ + atomic_thread_fence(memory_order_seq_cst); +} + +/* + * Aliases for code using an older version of this header. These are now + * deprecated and should not be used. The definitions will be removed + * in a future release. + */ +#define android_atomic_write android_atomic_release_store +#define android_atomic_cmpxchg android_atomic_release_cas + +#endif // ANDROID_CUTILS_ATOMIC_H diff --git a/phonelibs/android_system_core/include/cutils/bitops.h b/phonelibs/android_system_core/include/cutils/bitops.h new file mode 100644 index 00000000000000..045830d90bd6f5 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/bitops.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_BITOPS_H +#define __CUTILS_BITOPS_H + +#include +#include +#include +#include + +__BEGIN_DECLS + +/* + * Bitmask Operations + * + * Note this doesn't provide any locking/exclusion, and isn't atomic. + * Additionally no bounds checking is done on the bitmask array. + * + * Example: + * + * int num_resources; + * unsigned int resource_bits[BITS_TO_WORDS(num_resources)]; + * bitmask_init(resource_bits, num_resources); + * ... + * int bit = bitmask_ffz(resource_bits, num_resources); + * bitmask_set(resource_bits, bit); + * ... + * if (bitmask_test(resource_bits, bit)) { ... } + * ... + * bitmask_clear(resource_bits, bit); + * + */ + +#define BITS_PER_WORD (sizeof(unsigned int) * 8) +#define BITS_TO_WORDS(x) (((x) + BITS_PER_WORD - 1) / BITS_PER_WORD) +#define BIT_IN_WORD(x) ((x) % BITS_PER_WORD) +#define BIT_WORD(x) ((x) / BITS_PER_WORD) +#define BIT_MASK(x) (1 << BIT_IN_WORD(x)) + +static inline void bitmask_init(unsigned int *bitmask, int num_bits) +{ + memset(bitmask, 0, BITS_TO_WORDS(num_bits)*sizeof(unsigned int)); +} + +static inline int bitmask_ffz(unsigned int *bitmask, int num_bits) +{ + int bit, result; + size_t i; + + for (i = 0; i < BITS_TO_WORDS(num_bits); i++) { + bit = ffs(~bitmask[i]); + if (bit) { + // ffs is 1-indexed, return 0-indexed result + bit--; + result = BITS_PER_WORD * i + bit; + if (result >= num_bits) + return -1; + return result; + } + } + return -1; +} + +static inline int bitmask_weight(unsigned int *bitmask, int num_bits) +{ + size_t i; + int weight = 0; + + for (i = 0; i < BITS_TO_WORDS(num_bits); i++) + weight += __builtin_popcount(bitmask[i]); + return weight; +} + +static inline void bitmask_set(unsigned int *bitmask, int bit) +{ + bitmask[BIT_WORD(bit)] |= BIT_MASK(bit); +} + +static inline void bitmask_clear(unsigned int *bitmask, int bit) +{ + bitmask[BIT_WORD(bit)] &= ~BIT_MASK(bit); +} + +static inline bool bitmask_test(unsigned int *bitmask, int bit) +{ + return bitmask[BIT_WORD(bit)] & BIT_MASK(bit); +} + +static inline int popcount(unsigned int x) +{ + return __builtin_popcount(x); +} + +static inline int popcountl(unsigned long x) +{ + return __builtin_popcountl(x); +} + +static inline int popcountll(unsigned long long x) +{ + return __builtin_popcountll(x); +} + +__END_DECLS + +#endif /* __CUTILS_BITOPS_H */ diff --git a/phonelibs/android_system_core/include/cutils/compiler.h b/phonelibs/android_system_core/include/cutils/compiler.h new file mode 100644 index 00000000000000..70f884a1e701f5 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/compiler.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_CUTILS_COMPILER_H +#define ANDROID_CUTILS_COMPILER_H + +/* + * helps the compiler's optimizer predicting branches + */ + +#ifdef __cplusplus +# define CC_LIKELY( exp ) (__builtin_expect( !!(exp), true )) +# define CC_UNLIKELY( exp ) (__builtin_expect( !!(exp), false )) +#else +# define CC_LIKELY( exp ) (__builtin_expect( !!(exp), 1 )) +# define CC_UNLIKELY( exp ) (__builtin_expect( !!(exp), 0 )) +#endif + +/** + * exports marked symbols + * + * if used on a C++ class declaration, this macro must be inserted + * after the "class" keyword. For instance: + * + * template + * class ANDROID_API Singleton { } + */ + +#define ANDROID_API __attribute__((visibility("default"))) + +#endif // ANDROID_CUTILS_COMPILER_H diff --git a/phonelibs/android_system_core/include/cutils/config_utils.h b/phonelibs/android_system_core/include/cutils/config_utils.h new file mode 100644 index 00000000000000..2dea6f19fa1882 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/config_utils.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_CONFIG_UTILS_H +#define __CUTILS_CONFIG_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct cnode cnode; + + +struct cnode +{ + cnode *next; + cnode *first_child; + cnode *last_child; + const char *name; + const char *value; +}; + +/* parse a text string into a config node tree */ +void config_load(cnode *root, char *data); + +/* parse a file into a config node tree */ +void config_load_file(cnode *root, const char *fn); + +/* create a single config node */ +cnode* config_node(const char *name, const char *value); + +/* locate a named child of a config node */ +cnode* config_find(cnode *root, const char *name); + +/* look up a child by name and return the boolean value */ +int config_bool(cnode *root, const char *name, int _default); + +/* look up a child by name and return the string value */ +const char* config_str(cnode *root, const char *name, const char *_default); + +/* add a named child to a config node (or modify it if it already exists) */ +void config_set(cnode *root, const char *name, const char *value); + +/* free a config node tree */ +void config_free(cnode *root); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/phonelibs/android_system_core/include/cutils/debugger.h b/phonelibs/android_system_core/include/cutils/debugger.h new file mode 100644 index 00000000000000..285e1afcd7d28e --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/debugger.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_DEBUGGER_H +#define __CUTILS_DEBUGGER_H + +#include +#include + +__BEGIN_DECLS + +#define DEBUGGER_SOCKET_NAME "android:debuggerd" +#define DEBUGGER32_SOCKET_NAME "android:debuggerd32" +#define DEBUGGER64_SOCKET_NAME DEBUGGER_SOCKET_NAME + +typedef enum { + // dump a crash + DEBUGGER_ACTION_CRASH, + // dump a tombstone file + DEBUGGER_ACTION_DUMP_TOMBSTONE, + // dump a backtrace only back to the socket + DEBUGGER_ACTION_DUMP_BACKTRACE, +} debugger_action_t; + +// Make sure that all values have a fixed size so that this structure +// is the same for 32 bit and 64 bit processes. +// NOTE: Any changes to this structure must also be reflected in +// bionic/linker/debugger.cpp. +typedef struct __attribute__((packed)) { + int32_t action; + pid_t tid; + uint64_t abort_msg_address; + int32_t original_si_code; +} debugger_msg_t; + +/* Dumps a process backtrace, registers, and stack to a tombstone file (requires root). + * Stores the tombstone path in the provided buffer. + * Returns 0 on success, -1 on error. + */ +int dump_tombstone(pid_t tid, char* pathbuf, size_t pathlen); + +/* Dumps a process backtrace, registers, and stack to a tombstone file (requires root). + * Stores the tombstone path in the provided buffer. + * If reading debugger data from debuggerd ever takes longer than timeout_secs + * seconds, then stop and return an error. + * Returns 0 on success, -1 on error. + */ +int dump_tombstone_timeout(pid_t tid, char* pathbuf, size_t pathlen, int timeout_secs); + +/* Dumps a process backtrace only to the specified file (requires root). + * Returns 0 on success, -1 on error. + */ +int dump_backtrace_to_file(pid_t tid, int fd); + +/* Dumps a process backtrace only to the specified file (requires root). + * If reading debugger data from debuggerd ever takes longer than timeout_secs + * seconds, then stop and return an error. + * Returns 0 on success, -1 on error. + */ +int dump_backtrace_to_file_timeout(pid_t tid, int fd, int timeout_secs); + +__END_DECLS + +#endif /* __CUTILS_DEBUGGER_H */ diff --git a/phonelibs/android_system_core/include/cutils/fs.h b/phonelibs/android_system_core/include/cutils/fs.h new file mode 100644 index 00000000000000..70f0b929195f80 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/fs.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_FS_H +#define __CUTILS_FS_H + +#include +#include + +/* + * TEMP_FAILURE_RETRY is defined by some, but not all, versions of + * . (Alas, it is not as standard as we'd hoped!) So, if it's + * not already defined, then define it here. + */ +#ifndef TEMP_FAILURE_RETRY +/* Used to retry syscalls that can return EINTR. */ +#define TEMP_FAILURE_RETRY(exp) ({ \ + typeof (exp) _rc; \ + do { \ + _rc = (exp); \ + } while (_rc == -1 && errno == EINTR); \ + _rc; }) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Ensure that directory exists with given mode and owners. + */ +extern int fs_prepare_dir(const char* path, mode_t mode, uid_t uid, gid_t gid); + +/* + * Read single plaintext integer from given file, correctly handling files + * partially written with fs_write_atomic_int(). + */ +extern int fs_read_atomic_int(const char* path, int* value); + +/* + * Write single plaintext integer to given file, creating backup while + * in progress. + */ +extern int fs_write_atomic_int(const char* path, int value); + +/* + * Ensure that all directories along given path exist, creating parent + * directories as needed. Validates that given path is absolute and that + * it contains no relative "." or ".." paths or symlinks. Last path segment + * is treated as filename and ignored, unless the path ends with "/". + */ +extern int fs_mkdirs(const char* path, mode_t mode); + +#ifdef __cplusplus +} +#endif + +#endif /* __CUTILS_FS_H */ diff --git a/phonelibs/android_system_core/include/cutils/hashmap.h b/phonelibs/android_system_core/include/cutils/hashmap.h new file mode 100644 index 00000000000000..5cb344c152beb3 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/hashmap.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Hash map. + */ + +#ifndef __HASHMAP_H +#define __HASHMAP_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** A hash map. */ +typedef struct Hashmap Hashmap; + +/** + * Creates a new hash map. Returns NULL if memory allocation fails. + * + * @param initialCapacity number of expected entries + * @param hash function which hashes keys + * @param equals function which compares keys for equality + */ +Hashmap* hashmapCreate(size_t initialCapacity, + int (*hash)(void* key), bool (*equals)(void* keyA, void* keyB)); + +/** + * Frees the hash map. Does not free the keys or values themselves. + */ +void hashmapFree(Hashmap* map); + +/** + * Hashes the memory pointed to by key with the given size. Useful for + * implementing hash functions. + */ +int hashmapHash(void* key, size_t keySize); + +/** + * Puts value for the given key in the map. Returns pre-existing value if + * any. + * + * If memory allocation fails, this function returns NULL, the map's size + * does not increase, and errno is set to ENOMEM. + */ +void* hashmapPut(Hashmap* map, void* key, void* value); + +/** + * Gets a value from the map. Returns NULL if no entry for the given key is + * found or if the value itself is NULL. + */ +void* hashmapGet(Hashmap* map, void* key); + +/** + * Returns true if the map contains an entry for the given key. + */ +bool hashmapContainsKey(Hashmap* map, void* key); + +/** + * Gets the value for a key. If a value is not found, this function gets a + * value and creates an entry using the given callback. + * + * If memory allocation fails, the callback is not called, this function + * returns NULL, and errno is set to ENOMEM. + */ +void* hashmapMemoize(Hashmap* map, void* key, + void* (*initialValue)(void* key, void* context), void* context); + +/** + * Removes an entry from the map. Returns the removed value or NULL if no + * entry was present. + */ +void* hashmapRemove(Hashmap* map, void* key); + +/** + * Gets the number of entries in this map. + */ +size_t hashmapSize(Hashmap* map); + +/** + * Invokes the given callback on each entry in the map. Stops iterating if + * the callback returns false. + */ +void hashmapForEach(Hashmap* map, + bool (*callback)(void* key, void* value, void* context), + void* context); + +/** + * Concurrency support. + */ + +/** + * Locks the hash map so only the current thread can access it. + */ +void hashmapLock(Hashmap* map); + +/** + * Unlocks the hash map so other threads can access it. + */ +void hashmapUnlock(Hashmap* map); + +/** + * Key utilities. + */ + +/** + * Hashes int keys. 'key' is a pointer to int. + */ +int hashmapIntHash(void* key); + +/** + * Compares two int keys for equality. + */ +bool hashmapIntEquals(void* keyA, void* keyB); + +/** + * For debugging. + */ + +/** + * Gets current capacity. + */ +size_t hashmapCurrentCapacity(Hashmap* map); + +/** + * Counts the number of entry collisions. + */ +size_t hashmapCountCollisions(Hashmap* map); + +#ifdef __cplusplus +} +#endif + +#endif /* __HASHMAP_H */ diff --git a/phonelibs/android_system_core/include/cutils/iosched_policy.h b/phonelibs/android_system_core/include/cutils/iosched_policy.h new file mode 100644 index 00000000000000..25b87bac0a4a3c --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/iosched_policy.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_IOSCHED_POLICY_H +#define __CUTILS_IOSCHED_POLICY_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + IoSchedClass_NONE, + IoSchedClass_RT, + IoSchedClass_BE, + IoSchedClass_IDLE, +} IoSchedClass; + +extern int android_set_ioprio(int pid, IoSchedClass clazz, int ioprio); +extern int android_get_ioprio(int pid, IoSchedClass *clazz, int *ioprio); + +extern int android_set_rt_ioprio(int pid, int rt); + +#ifdef __cplusplus +} +#endif + +#endif /* __CUTILS_IOSCHED_POLICY_H */ diff --git a/phonelibs/android_system_core/include/cutils/jstring.h b/phonelibs/android_system_core/include/cutils/jstring.h new file mode 100644 index 00000000000000..a3426081a0be04 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/jstring.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_STRING16_H +#define __CUTILS_STRING16_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if __STDC_VERSION__ < 201112L && __cplusplus < 201103L + typedef uint16_t char16_t; +#endif + // otherwise char16_t is a keyword with the right semantics + +extern char * strndup16to8 (const char16_t* s, size_t n); +extern size_t strnlen16to8 (const char16_t* s, size_t n); +extern char * strncpy16to8 (char *dest, const char16_t*s, size_t n); + +extern char16_t * strdup8to16 (const char* s, size_t *out_len); +extern size_t strlen8to16 (const char* utf8Str); +extern char16_t * strcpy8to16 (char16_t *dest, const char*s, size_t *out_len); +extern char16_t * strcpylen8to16 (char16_t *dest, const char*s, int length, + size_t *out_len); + +#ifdef __cplusplus +} +#endif + +#endif /* __CUTILS_STRING16_H */ diff --git a/phonelibs/android_system_core/include/cutils/klog.h b/phonelibs/android_system_core/include/cutils/klog.h new file mode 100644 index 00000000000000..295d62be376795 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/klog.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _CUTILS_KLOG_H_ +#define _CUTILS_KLOG_H_ + +#include +#include +#include + +__BEGIN_DECLS + +void klog_init(void); +int klog_get_level(void); +void klog_set_level(int level); +/* TODO: void klog_close(void); - and make klog_fd users thread safe. */ + +void klog_write(int level, const char *fmt, ...) + __attribute__ ((format(printf, 2, 3))); +void klog_writev(int level, const struct iovec* iov, int iov_count); + +__END_DECLS + +#define KLOG_ERROR_LEVEL 3 +#define KLOG_WARNING_LEVEL 4 +#define KLOG_NOTICE_LEVEL 5 +#define KLOG_INFO_LEVEL 6 +#define KLOG_DEBUG_LEVEL 7 + +#define KLOG_ERROR(tag,x...) klog_write(KLOG_ERROR_LEVEL, "<3>" tag ": " x) +#define KLOG_WARNING(tag,x...) klog_write(KLOG_WARNING_LEVEL, "<4>" tag ": " x) +#define KLOG_NOTICE(tag,x...) klog_write(KLOG_NOTICE_LEVEL, "<5>" tag ": " x) +#define KLOG_INFO(tag,x...) klog_write(KLOG_INFO_LEVEL, "<6>" tag ": " x) +#define KLOG_DEBUG(tag,x...) klog_write(KLOG_DEBUG_LEVEL, "<7>" tag ": " x) + +#define KLOG_DEFAULT_LEVEL 3 /* messages <= this level are logged */ + +#endif diff --git a/phonelibs/android_system_core/include/cutils/list.h b/phonelibs/android_system_core/include/cutils/list.h new file mode 100644 index 00000000000000..4ba2cfd4990062 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/list.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2008-2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _CUTILS_LIST_H_ +#define _CUTILS_LIST_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct listnode +{ + struct listnode *next; + struct listnode *prev; +}; + +#define node_to_item(node, container, member) \ + (container *) (((char*) (node)) - offsetof(container, member)) + +#define list_declare(name) \ + struct listnode name = { \ + .next = &name, \ + .prev = &name, \ + } + +#define list_for_each(node, list) \ + for (node = (list)->next; node != (list); node = node->next) + +#define list_for_each_reverse(node, list) \ + for (node = (list)->prev; node != (list); node = node->prev) + +#define list_for_each_safe(node, n, list) \ + for (node = (list)->next, n = node->next; \ + node != (list); \ + node = n, n = node->next) + +static inline void list_init(struct listnode *node) +{ + node->next = node; + node->prev = node; +} + +static inline void list_add_tail(struct listnode *head, struct listnode *item) +{ + item->next = head; + item->prev = head->prev; + head->prev->next = item; + head->prev = item; +} + +static inline void list_add_head(struct listnode *head, struct listnode *item) +{ + item->next = head->next; + item->prev = head; + head->next->prev = item; + head->next = item; +} + +static inline void list_remove(struct listnode *item) +{ + item->next->prev = item->prev; + item->prev->next = item->next; +} + +#define list_empty(list) ((list) == (list)->next) +#define list_head(list) ((list)->next) +#define list_tail(list) ((list)->prev) + +#ifdef __cplusplus +}; +#endif /* __cplusplus */ + +#endif diff --git a/phonelibs/android_system_core/include/cutils/log.h b/phonelibs/android_system_core/include/cutils/log.h new file mode 100644 index 00000000000000..0e0248e50fa7aa --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/log.h @@ -0,0 +1 @@ +#include diff --git a/phonelibs/android_system_core/include/cutils/memory.h b/phonelibs/android_system_core/include/cutils/memory.h new file mode 100644 index 00000000000000..4d26882556bfc4 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/memory.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_CUTILS_MEMORY_H +#define ANDROID_CUTILS_MEMORY_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* size is given in bytes and must be multiple of 2 */ +void android_memset16(uint16_t* dst, uint16_t value, size_t size); + +/* size is given in bytes and must be multiple of 4 */ +void android_memset32(uint32_t* dst, uint32_t value, size_t size); + +#if defined(__GLIBC__) || defined(_WIN32) +/* Declaration of strlcpy() for platforms that don't already have it. */ +size_t strlcpy(char *dst, const char *src, size_t size); +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // ANDROID_CUTILS_MEMORY_H diff --git a/phonelibs/android_system_core/include/cutils/misc.h b/phonelibs/android_system_core/include/cutils/misc.h new file mode 100644 index 00000000000000..0de505f277c18e --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/misc.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_MISC_H +#define __CUTILS_MISC_H + +#ifdef __cplusplus +extern "C" { +#endif + + /* Load an entire file into a malloc'd chunk of memory + * that is length_of_file + 1 (null terminator). If + * sz is non-zero, return the size of the file via sz. + * Returns 0 on failure. + */ +extern void *load_file(const char *fn, unsigned *sz); + + /* This is the range of UIDs (and GIDs) that are reserved + * for assigning to applications. + */ +#define FIRST_APPLICATION_UID 10000 +#define LAST_APPLICATION_UID 99999 + +#ifdef __cplusplus +} +#endif + +#endif /* __CUTILS_MISC_H */ diff --git a/phonelibs/android_system_core/include/cutils/multiuser.h b/phonelibs/android_system_core/include/cutils/multiuser.h new file mode 100644 index 00000000000000..635ddb13587a95 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/multiuser.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_MULTIUSER_H +#define __CUTILS_MULTIUSER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// NOTE: keep in sync with android.os.UserId + +#define MULTIUSER_APP_PER_USER_RANGE 100000 + +typedef uid_t userid_t; +typedef uid_t appid_t; + +extern userid_t multiuser_get_user_id(uid_t uid); +extern appid_t multiuser_get_app_id(uid_t uid); +extern uid_t multiuser_get_uid(userid_t userId, appid_t appId); + +#ifdef __cplusplus +} +#endif + +#endif /* __CUTILS_MULTIUSER_H */ diff --git a/phonelibs/android_system_core/include/cutils/native_handle.h b/phonelibs/android_system_core/include/cutils/native_handle.h new file mode 100644 index 00000000000000..268c5d3f51b7f2 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/native_handle.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef NATIVE_HANDLE_H_ +#define NATIVE_HANDLE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct native_handle +{ + int version; /* sizeof(native_handle_t) */ + int numFds; /* number of file-descriptors at &data[0] */ + int numInts; /* number of ints at &data[numFds] */ + int data[0]; /* numFds + numInts ints */ +} native_handle_t; + +/* + * native_handle_close + * + * closes the file descriptors contained in this native_handle_t + * + * return 0 on success, or a negative error code on failure + * + */ +int native_handle_close(const native_handle_t* h); + + +/* + * native_handle_create + * + * creates a native_handle_t and initializes it. must be destroyed with + * native_handle_delete(). + * + */ +native_handle_t* native_handle_create(int numFds, int numInts); + +/* + * native_handle_delete + * + * frees a native_handle_t allocated with native_handle_create(). + * This ONLY frees the memory allocated for the native_handle_t, but doesn't + * close the file descriptors; which can be achieved with native_handle_close(). + * + * return 0 on success, or a negative error code on failure + * + */ +int native_handle_delete(native_handle_t* h); + + +#ifdef __cplusplus +} +#endif + +#endif /* NATIVE_HANDLE_H_ */ diff --git a/phonelibs/android_system_core/include/cutils/open_memstream.h b/phonelibs/android_system_core/include/cutils/open_memstream.h new file mode 100644 index 00000000000000..c1a81ebbcbd81e --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/open_memstream.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_OPEN_MEMSTREAM_H__ +#define __CUTILS_OPEN_MEMSTREAM_H__ + +#include + +#if defined(__APPLE__) + +#ifdef __cplusplus +extern "C" { +#endif + +FILE* open_memstream(char** bufp, size_t* sizep); + +#ifdef __cplusplus +} +#endif + +#endif /* __APPLE__ */ + +#endif /*__CUTILS_OPEN_MEMSTREAM_H__*/ diff --git a/phonelibs/android_system_core/include/cutils/partition_utils.h b/phonelibs/android_system_core/include/cutils/partition_utils.h new file mode 100644 index 00000000000000..72ca80d3505c08 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/partition_utils.h @@ -0,0 +1,26 @@ +/* + * Copyright 2011, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_PARTITION_WIPED_H__ +#define __CUTILS_PARTITION_WIPED_H__ + +__BEGIN_DECLS + +int partition_wiped(char *source); + +__END_DECLS + +#endif /* __CUTILS_PARTITION_WIPED_H__ */ diff --git a/phonelibs/android_system_core/include/cutils/process_name.h b/phonelibs/android_system_core/include/cutils/process_name.h new file mode 100644 index 00000000000000..1e72e5c3ad3087 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/process_name.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Gives the current process a name. + */ + +#ifndef __PROCESS_NAME_H +#define __PROCESS_NAME_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Sets the current process name. + * + * Warning: This leaks a string every time you call it. Use judiciously! + */ +void set_process_name(const char* process_name); + +/** Gets the current process name. */ +const char* get_process_name(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __PROCESS_NAME_H */ diff --git a/phonelibs/android_system_core/include/cutils/properties.h b/phonelibs/android_system_core/include/cutils/properties.h new file mode 100644 index 00000000000000..24aa224f64da08 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/properties.h @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_PROPERTIES_H +#define __CUTILS_PROPERTIES_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* System properties are *small* name value pairs managed by the +** property service. If your data doesn't fit in the provided +** space it is not appropriate for a system property. +** +** WARNING: system/bionic/include/sys/system_properties.h also defines +** these, but with different names. (TODO: fix that) +*/ +#define PROPERTY_KEY_MAX PROP_NAME_MAX +#define PROPERTY_VALUE_MAX PROP_VALUE_MAX + +/* property_get: returns the length of the value which will never be +** greater than PROPERTY_VALUE_MAX - 1 and will always be zero terminated. +** (the length does not include the terminating zero). +** +** If the property read fails or returns an empty value, the default +** value is used (if nonnull). +*/ +int property_get(const char *key, char *value, const char *default_value); + +/* property_get_bool: returns the value of key coerced into a +** boolean. If the property is not set, then the default value is returned. +** +* The following is considered to be true (1): +** "1", "true", "y", "yes", "on" +** +** The following is considered to be false (0): +** "0", "false", "n", "no", "off" +** +** The conversion is whitespace-sensitive (e.g. " off" will not be false). +** +** If no property with this key is set (or the key is NULL) or the boolean +** conversion fails, the default value is returned. +**/ +int8_t property_get_bool(const char *key, int8_t default_value); + +/* property_get_int64: returns the value of key truncated and coerced into a +** int64_t. If the property is not set, then the default value is used. +** +** The numeric conversion is identical to strtoimax with the base inferred: +** - All digits up to the first non-digit characters are read +** - The longest consecutive prefix of digits is converted to a long +** +** Valid strings of digits are: +** - An optional sign character + or - +** - An optional prefix indicating the base (otherwise base 10 is assumed) +** -- 0 prefix is octal +** -- 0x / 0X prefix is hex +** +** Leading/trailing whitespace is ignored. Overflow/underflow will cause +** numeric conversion to fail. +** +** If no property with this key is set (or the key is NULL) or the numeric +** conversion fails, the default value is returned. +**/ +int64_t property_get_int64(const char *key, int64_t default_value); + +/* property_get_int32: returns the value of key truncated and coerced into an +** int32_t. If the property is not set, then the default value is used. +** +** The numeric conversion is identical to strtoimax with the base inferred: +** - All digits up to the first non-digit characters are read +** - The longest consecutive prefix of digits is converted to a long +** +** Valid strings of digits are: +** - An optional sign character + or - +** - An optional prefix indicating the base (otherwise base 10 is assumed) +** -- 0 prefix is octal +** -- 0x / 0X prefix is hex +** +** Leading/trailing whitespace is ignored. Overflow/underflow will cause +** numeric conversion to fail. +** +** If no property with this key is set (or the key is NULL) or the numeric +** conversion fails, the default value is returned. +**/ +int32_t property_get_int32(const char *key, int32_t default_value); + +/* property_set: returns 0 on success, < 0 on failure +*/ +int property_set(const char *key, const char *value); + +int property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie); + +#if defined(__BIONIC_FORTIFY) + +extern int __property_get_real(const char *, char *, const char *) + __asm__(__USER_LABEL_PREFIX__ "property_get"); +__errordecl(__property_get_too_small_error, "property_get() called with too small of a buffer"); + +__BIONIC_FORTIFY_INLINE +int property_get(const char *key, char *value, const char *default_value) { + size_t bos = __bos(value); + if (bos < PROPERTY_VALUE_MAX) { + __property_get_too_small_error(); + } + return __property_get_real(key, value, default_value); +} + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/phonelibs/android_system_core/include/cutils/qtaguid.h b/phonelibs/android_system_core/include/cutils/qtaguid.h new file mode 100644 index 00000000000000..f8550fda83b253 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/qtaguid.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_QTAGUID_H +#define __CUTILS_QTAGUID_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Set tags (and owning UIDs) for network sockets. +*/ +extern int qtaguid_tagSocket(int sockfd, int tag, uid_t uid); + +/* + * Untag a network socket before closing. +*/ +extern int qtaguid_untagSocket(int sockfd); + +/* + * For the given uid, switch counter sets. + * The kernel only keeps a limited number of sets. + * 2 for now. + */ +extern int qtaguid_setCounterSet(int counterSetNum, uid_t uid); + +/* + * Delete all tag info that relates to the given tag an uid. + * If the tag is 0, then ALL info about the uid is freeded. + * The delete data also affects active tagged socketd, which are + * then untagged. + * The calling process can only operate on its own tags. + * Unless it is part of the happy AID_NET_BW_ACCT group. + * In which case it can clobber everything. + */ +extern int qtaguid_deleteTagData(int tag, uid_t uid); + +/* + * Enable/disable qtaguid functionnality at a lower level. + * When pacified, the kernel will accept commands but do nothing. + */ +extern int qtaguid_setPacifier(int on); + +#ifdef __cplusplus +} +#endif + +#endif /* __CUTILS_QTAG_UID_H */ diff --git a/phonelibs/android_system_core/include/cutils/record_stream.h b/phonelibs/android_system_core/include/cutils/record_stream.h new file mode 100644 index 00000000000000..bfac87a53cac9f --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/record_stream.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * A simple utility for reading fixed records out of a stream fd + */ + +#ifndef _CUTILS_RECORD_STREAM_H +#define _CUTILS_RECORD_STREAM_H + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct RecordStream RecordStream; + +extern RecordStream *record_stream_new(int fd, size_t maxRecordLen); +extern void record_stream_free(RecordStream *p_rs); + +extern int record_stream_get_next (RecordStream *p_rs, void ** p_outRecord, + size_t *p_outRecordLen); + +#ifdef __cplusplus +} +#endif + + +#endif /*_CUTILS_RECORD_STREAM_H*/ + diff --git a/phonelibs/android_system_core/include/cutils/sched_policy.h b/phonelibs/android_system_core/include/cutils/sched_policy.h new file mode 100644 index 00000000000000..6a8d570b2cb2a1 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/sched_policy.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_SCHED_POLICY_H +#define __CUTILS_SCHED_POLICY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Keep in sync with THREAD_GROUP_* in frameworks/base/core/java/android/os/Process.java */ +typedef enum { + SP_DEFAULT = -1, + SP_BACKGROUND = 0, + SP_FOREGROUND = 1, + SP_SYSTEM = 2, // can't be used with set_sched_policy() + SP_AUDIO_APP = 3, + SP_AUDIO_SYS = 4, + SP_CNT, + SP_MAX = SP_CNT - 1, + SP_SYSTEM_DEFAULT = SP_FOREGROUND, +} SchedPolicy; + +extern int set_cpuset_policy(int tid, SchedPolicy policy); + +/* Assign thread tid to the cgroup associated with the specified policy. + * If the thread is a thread group leader, that is it's gettid() == getpid(), + * then the other threads in the same thread group are _not_ affected. + * On platforms which support gettid(), zero tid means current thread. + * Return value: 0 for success, or -errno for error. + */ +extern int set_sched_policy(int tid, SchedPolicy policy); + +/* Return the policy associated with the cgroup of thread tid via policy pointer. + * On platforms which support gettid(), zero tid means current thread. + * Return value: 0 for success, or -1 for error and set errno. + */ +extern int get_sched_policy(int tid, SchedPolicy *policy); + +/* Return a displayable string corresponding to policy. + * Return value: non-NULL NUL-terminated name of unspecified length; + * the caller is responsible for displaying the useful part of the string. + */ +extern const char *get_sched_policy_name(SchedPolicy policy); + +#ifdef __cplusplus +} +#endif + +#endif /* __CUTILS_SCHED_POLICY_H */ diff --git a/phonelibs/android_system_core/include/cutils/sockets.h b/phonelibs/android_system_core/include/cutils/sockets.h new file mode 100644 index 00000000000000..f8076ca452b86e --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/sockets.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_SOCKETS_H +#define __CUTILS_SOCKETS_H + +#include +#include +#include +#include +#include + +#ifdef HAVE_WINSOCK +#include +typedef int socklen_t; +#else +#include +#endif + +#define ANDROID_SOCKET_ENV_PREFIX "ANDROID_SOCKET_" +#define ANDROID_SOCKET_DIR "/dev/socket" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * android_get_control_socket - simple helper function to get the file + * descriptor of our init-managed Unix domain socket. `name' is the name of the + * socket, as given in init.rc. Returns -1 on error. + * + * This is inline and not in libcutils proper because we want to use this in + * third-party daemons with minimal modification. + */ +static inline int android_get_control_socket(const char *name) +{ + char key[64]; + snprintf(key, sizeof(key), ANDROID_SOCKET_ENV_PREFIX "%s", name); + + const char* val = getenv(key); + if (!val) { + return -1; + } + + errno = 0; + int fd = strtol(val, NULL, 10); + if (errno) { + return -1; + } + + return fd; +} + +/* + * See also android.os.LocalSocketAddress.Namespace + */ +// Linux "abstract" (non-filesystem) namespace +#define ANDROID_SOCKET_NAMESPACE_ABSTRACT 0 +// Android "reserved" (/dev/socket) namespace +#define ANDROID_SOCKET_NAMESPACE_RESERVED 1 +// Normal filesystem namespace +#define ANDROID_SOCKET_NAMESPACE_FILESYSTEM 2 + +extern int socket_loopback_client(int port, int type); +extern int socket_network_client(const char *host, int port, int type); +extern int socket_network_client_timeout(const char *host, int port, int type, + int timeout); +extern int socket_loopback_server(int port, int type); +extern int socket_local_server(const char *name, int namespaceId, int type); +extern int socket_local_server_bind(int s, const char *name, int namespaceId); +extern int socket_local_client_connect(int fd, + const char *name, int namespaceId, int type); +extern int socket_local_client(const char *name, int namespaceId, int type); +extern int socket_inaddr_any_server(int port, int type); + +/* + * socket_peer_is_trusted - Takes a socket which is presumed to be a + * connected local socket (e.g. AF_LOCAL) and returns whether the peer + * (the userid that owns the process on the other end of that socket) + * is one of the two trusted userids, root or shell. + * + * Note: This only works as advertised on the Android OS and always + * just returns true when called on other operating systems. + */ +extern bool socket_peer_is_trusted(int fd); + +#ifdef __cplusplus +} +#endif + +#endif /* __CUTILS_SOCKETS_H */ diff --git a/phonelibs/android_system_core/include/cutils/str_parms.h b/phonelibs/android_system_core/include/cutils/str_parms.h new file mode 100644 index 00000000000000..aa1435a080e2ef --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/str_parms.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_STR_PARMS_H +#define __CUTILS_STR_PARMS_H + +#include +#include + +__BEGIN_DECLS + +struct str_parms; + +struct str_parms *str_parms_create(void); +struct str_parms *str_parms_create_str(const char *_string); +void str_parms_destroy(struct str_parms *str_parms); + +void str_parms_del(struct str_parms *str_parms, const char *key); + +int str_parms_add_str(struct str_parms *str_parms, const char *key, + const char *value); +int str_parms_add_int(struct str_parms *str_parms, const char *key, int value); + +int str_parms_add_float(struct str_parms *str_parms, const char *key, + float value); + +// Returns non-zero if the str_parms contains the specified key. +int str_parms_has_key(struct str_parms *str_parms, const char *key); + +// Gets value associated with the specified key (if present), placing it in the buffer +// pointed to by the out_val parameter. Returns the length of the returned string value. +// If 'key' isn't in the parms, then return -ENOENT (-2) and leave 'out_val' untouched. +int str_parms_get_str(struct str_parms *str_parms, const char *key, + char *out_val, int len); +int str_parms_get_int(struct str_parms *str_parms, const char *key, + int *out_val); +int str_parms_get_float(struct str_parms *str_parms, const char *key, + float *out_val); + +char *str_parms_to_str(struct str_parms *str_parms); + +/* debug */ +void str_parms_dump(struct str_parms *str_parms); + +__END_DECLS + +#endif /* __CUTILS_STR_PARMS_H */ diff --git a/phonelibs/android_system_core/include/cutils/threads.h b/phonelibs/android_system_core/include/cutils/threads.h new file mode 100644 index 00000000000000..5727494079f143 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/threads.h @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_CUTILS_THREADS_H +#define _LIBS_CUTILS_THREADS_H + +#include + +#if !defined(_WIN32) +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/***********************************************************************/ +/***********************************************************************/ +/***** *****/ +/***** local thread storage *****/ +/***** *****/ +/***********************************************************************/ +/***********************************************************************/ + +extern pid_t gettid(); + +#if !defined(_WIN32) + +typedef struct { + pthread_mutex_t lock; + int has_tls; + pthread_key_t tls; +} thread_store_t; + +#define THREAD_STORE_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0 } + +#else // !defined(_WIN32) + +typedef struct { + int lock_init; + int has_tls; + DWORD tls; + CRITICAL_SECTION lock; +} thread_store_t; + +#define THREAD_STORE_INITIALIZER { 0, 0, 0, {0, 0, 0, 0, 0, 0} } + +#endif // !defined(_WIN32) + +typedef void (*thread_store_destruct_t)(void* value); + +extern void* thread_store_get(thread_store_t* store); + +extern void thread_store_set(thread_store_t* store, + void* value, + thread_store_destruct_t destroy); + +/***********************************************************************/ +/***********************************************************************/ +/***** *****/ +/***** mutexes *****/ +/***** *****/ +/***********************************************************************/ +/***********************************************************************/ + +#if !defined(_WIN32) + +typedef pthread_mutex_t mutex_t; + +#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER + +static __inline__ void mutex_lock(mutex_t* lock) +{ + pthread_mutex_lock(lock); +} +static __inline__ void mutex_unlock(mutex_t* lock) +{ + pthread_mutex_unlock(lock); +} +static __inline__ int mutex_init(mutex_t* lock) +{ + return pthread_mutex_init(lock, NULL); +} +static __inline__ void mutex_destroy(mutex_t* lock) +{ + pthread_mutex_destroy(lock); +} + +#else // !defined(_WIN32) + +typedef struct { + int init; + CRITICAL_SECTION lock[1]; +} mutex_t; + +#define MUTEX_INITIALIZER { 0, {{ NULL, 0, 0, NULL, NULL, 0 }} } + +static __inline__ void mutex_lock(mutex_t* lock) +{ + if (!lock->init) { + lock->init = 1; + InitializeCriticalSection( lock->lock ); + lock->init = 2; + } else while (lock->init != 2) + Sleep(10); + + EnterCriticalSection(lock->lock); +} + +static __inline__ void mutex_unlock(mutex_t* lock) +{ + LeaveCriticalSection(lock->lock); +} +static __inline__ int mutex_init(mutex_t* lock) +{ + InitializeCriticalSection(lock->lock); + lock->init = 2; + return 0; +} +static __inline__ void mutex_destroy(mutex_t* lock) +{ + if (lock->init) { + lock->init = 0; + DeleteCriticalSection(lock->lock); + } +} +#endif // !defined(_WIN32) + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBS_CUTILS_THREADS_H */ diff --git a/phonelibs/android_system_core/include/cutils/trace.h b/phonelibs/android_system_core/include/cutils/trace.h new file mode 100644 index 00000000000000..e4ed17983d2dc1 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/trace.h @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_CUTILS_TRACE_H +#define _LIBS_CUTILS_TRACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +__BEGIN_DECLS + +/** + * The ATRACE_TAG macro can be defined before including this header to trace + * using one of the tags defined below. It must be defined to one of the + * following ATRACE_TAG_* macros. The trace tag is used to filter tracing in + * userland to avoid some of the runtime cost of tracing when it is not desired. + * + * Defining ATRACE_TAG to be ATRACE_TAG_ALWAYS will result in the tracing always + * being enabled - this should ONLY be done for debug code, as userland tracing + * has a performance cost even when the trace is not being recorded. Defining + * ATRACE_TAG to be ATRACE_TAG_NEVER or leaving ATRACE_TAG undefined will result + * in the tracing always being disabled. + * + * ATRACE_TAG_HAL should be bitwise ORed with the relevant tags for tracing + * within a hardware module. For example a camera hardware module would set: + * #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL) + * + * Keep these in sync with frameworks/base/core/java/android/os/Trace.java. + */ +#define ATRACE_TAG_NEVER 0 // This tag is never enabled. +#define ATRACE_TAG_ALWAYS (1<<0) // This tag is always enabled. +#define ATRACE_TAG_GRAPHICS (1<<1) +#define ATRACE_TAG_INPUT (1<<2) +#define ATRACE_TAG_VIEW (1<<3) +#define ATRACE_TAG_WEBVIEW (1<<4) +#define ATRACE_TAG_WINDOW_MANAGER (1<<5) +#define ATRACE_TAG_ACTIVITY_MANAGER (1<<6) +#define ATRACE_TAG_SYNC_MANAGER (1<<7) +#define ATRACE_TAG_AUDIO (1<<8) +#define ATRACE_TAG_VIDEO (1<<9) +#define ATRACE_TAG_CAMERA (1<<10) +#define ATRACE_TAG_HAL (1<<11) +#define ATRACE_TAG_APP (1<<12) +#define ATRACE_TAG_RESOURCES (1<<13) +#define ATRACE_TAG_DALVIK (1<<14) +#define ATRACE_TAG_RS (1<<15) +#define ATRACE_TAG_BIONIC (1<<16) +#define ATRACE_TAG_POWER (1<<17) +#define ATRACE_TAG_LAST ATRACE_TAG_POWER + +// Reserved for initialization. +#define ATRACE_TAG_NOT_READY (1LL<<63) + +#define ATRACE_TAG_VALID_MASK ((ATRACE_TAG_LAST - 1) | ATRACE_TAG_LAST) + +#ifndef ATRACE_TAG +#define ATRACE_TAG ATRACE_TAG_NEVER +#elif ATRACE_TAG > ATRACE_TAG_VALID_MASK +#error ATRACE_TAG must be defined to be one of the tags defined in cutils/trace.h +#endif + +/** + * Opens the trace file for writing and reads the property for initial tags. + * The atrace.tags.enableflags property sets the tags to trace. + * This function should not be explicitly called, the first call to any normal + * trace function will cause it to be run safely. + */ +void atrace_setup(); + +/** + * If tracing is ready, set atrace_enabled_tags to the system property + * debug.atrace.tags.enableflags. Can be used as a sysprop change callback. + */ +void atrace_update_tags(); + +/** + * Set whether the process is debuggable. By default the process is not + * considered debuggable. If the process is not debuggable then application- + * level tracing is not allowed unless the ro.debuggable system property is + * set to '1'. + */ +void atrace_set_debuggable(bool debuggable); + +/** + * Set whether tracing is enabled for the current process. This is used to + * prevent tracing within the Zygote process. + */ +void atrace_set_tracing_enabled(bool enabled); + +/** + * Flag indicating whether setup has been completed, initialized to 0. + * Nonzero indicates setup has completed. + * Note: This does NOT indicate whether or not setup was successful. + */ +extern atomic_bool atrace_is_ready; + +/** + * Set of ATRACE_TAG flags to trace for, initialized to ATRACE_TAG_NOT_READY. + * A value of zero indicates setup has failed. + * Any other nonzero value indicates setup has succeeded, and tracing is on. + */ +extern uint64_t atrace_enabled_tags; + +/** + * Handle to the kernel's trace buffer, initialized to -1. + * Any other value indicates setup has succeeded, and is a valid fd for tracing. + */ +extern int atrace_marker_fd; + +/** + * atrace_init readies the process for tracing by opening the trace_marker file. + * Calling any trace function causes this to be run, so calling it is optional. + * This can be explicitly run to avoid setup delay on first trace function. + */ +#define ATRACE_INIT() atrace_init() +static inline void atrace_init() +{ + if (CC_UNLIKELY(!atomic_load_explicit(&atrace_is_ready, memory_order_acquire))) { + atrace_setup(); + } +} + +/** + * Get the mask of all tags currently enabled. + * It can be used as a guard condition around more expensive trace calculations. + * Every trace function calls this, which ensures atrace_init is run. + */ +#define ATRACE_GET_ENABLED_TAGS() atrace_get_enabled_tags() +static inline uint64_t atrace_get_enabled_tags() +{ + atrace_init(); + return atrace_enabled_tags; +} + +/** + * Test if a given tag is currently enabled. + * Returns nonzero if the tag is enabled, otherwise zero. + * It can be used as a guard condition around more expensive trace calculations. + */ +#define ATRACE_ENABLED() atrace_is_tag_enabled(ATRACE_TAG) +static inline uint64_t atrace_is_tag_enabled(uint64_t tag) +{ + return atrace_get_enabled_tags() & tag; +} + +/** + * Trace the beginning of a context. name is used to identify the context. + * This is often used to time function execution. + */ +#define ATRACE_BEGIN(name) atrace_begin(ATRACE_TAG, name) +static inline void atrace_begin(uint64_t tag, const char* name) +{ + if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) { + void atrace_begin_body(const char*); + atrace_begin_body(name); + } +} + +/** + * Trace the end of a context. + * This should match up (and occur after) a corresponding ATRACE_BEGIN. + */ +#define ATRACE_END() atrace_end(ATRACE_TAG) +static inline void atrace_end(uint64_t tag) +{ + if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) { + char c = 'E'; + write(atrace_marker_fd, &c, 1); + } +} + +/** + * Trace the beginning of an asynchronous event. Unlike ATRACE_BEGIN/ATRACE_END + * contexts, asynchronous events do not need to be nested. The name describes + * the event, and the cookie provides a unique identifier for distinguishing + * simultaneous events. The name and cookie used to begin an event must be + * used to end it. + */ +#define ATRACE_ASYNC_BEGIN(name, cookie) \ + atrace_async_begin(ATRACE_TAG, name, cookie) +static inline void atrace_async_begin(uint64_t tag, const char* name, + int32_t cookie) +{ + if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) { + void atrace_async_begin_body(const char*, int32_t); + atrace_async_begin_body(name, cookie); + } +} + +/** + * Trace the end of an asynchronous event. + * This should have a corresponding ATRACE_ASYNC_BEGIN. + */ +#define ATRACE_ASYNC_END(name, cookie) atrace_async_end(ATRACE_TAG, name, cookie) +static inline void atrace_async_end(uint64_t tag, const char* name, int32_t cookie) +{ + if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) { + void atrace_async_end_body(const char*, int32_t); + atrace_async_end_body(name, cookie); + } +} + +/** + * Traces an integer counter value. name is used to identify the counter. + * This can be used to track how a value changes over time. + */ +#define ATRACE_INT(name, value) atrace_int(ATRACE_TAG, name, value) +static inline void atrace_int(uint64_t tag, const char* name, int32_t value) +{ + if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) { + void atrace_int_body(const char*, int32_t); + atrace_int_body(name, value); + } +} + +/** + * Traces a 64-bit integer counter value. name is used to identify the + * counter. This can be used to track how a value changes over time. + */ +#define ATRACE_INT64(name, value) atrace_int64(ATRACE_TAG, name, value) +static inline void atrace_int64(uint64_t tag, const char* name, int64_t value) +{ + if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) { + void atrace_int64_body(const char*, int64_t); + atrace_int64_body(name, value); + } +} + +__END_DECLS + +#endif // _LIBS_CUTILS_TRACE_H diff --git a/phonelibs/android_system_core/include/cutils/uevent.h b/phonelibs/android_system_core/include/cutils/uevent.h new file mode 100644 index 00000000000000..da1c2aae6b37e8 --- /dev/null +++ b/phonelibs/android_system_core/include/cutils/uevent.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CUTILS_UEVENT_H +#define __CUTILS_UEVENT_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int uevent_open_socket(int buf_sz, bool passcred); +ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length); +ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length, uid_t *uid); +ssize_t uevent_kernel_recv(int socket, void *buffer, size_t length, bool require_group, uid_t *uid); + +#ifdef __cplusplus +} +#endif + +#endif /* __CUTILS_UEVENT_H */ diff --git a/phonelibs/android_system_core/include/log/event_tag_map.h b/phonelibs/android_system_core/include/log/event_tag_map.h new file mode 100644 index 00000000000000..1653c61e9a4194 --- /dev/null +++ b/phonelibs/android_system_core/include/log/event_tag_map.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_CUTILS_EVENTTAGMAP_H +#define _LIBS_CUTILS_EVENTTAGMAP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define EVENT_TAG_MAP_FILE "/system/etc/event-log-tags" + +struct EventTagMap; +typedef struct EventTagMap EventTagMap; + +/* + * Open the specified file as an event log tag map. + * + * Returns NULL on failure. + */ +EventTagMap* android_openEventTagMap(const char* fileName); + +/* + * Close the map. + */ +void android_closeEventTagMap(EventTagMap* map); + +/* + * Look up a tag by index. Returns the tag string, or NULL if not found. + */ +const char* android_lookupEventTag(const EventTagMap* map, int tag); + +#ifdef __cplusplus +} +#endif + +#endif /*_LIBS_CUTILS_EVENTTAGMAP_H*/ diff --git a/phonelibs/android_system_core/include/log/log.h b/phonelibs/android_system_core/include/log/log.h new file mode 100644 index 00000000000000..63a441a689e35c --- /dev/null +++ b/phonelibs/android_system_core/include/log/log.h @@ -0,0 +1,642 @@ +/* + * Copyright (C) 2005-2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// C/C++ logging functions. See the logging documentation for API details. +// +// We'd like these to be available from C code (in case we import some from +// somewhere), so this has a C interface. +// +// The output will be correct when the log file is shared between multiple +// threads and/or multiple processes so long as the operating system +// supports O_APPEND. These calls have mutex-protected data structures +// and so are NOT reentrant. Do not use LOG in a signal handler. +// +#ifndef _LIBS_LOG_LOG_H +#define _LIBS_LOG_LOG_H + +#include +#include +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// --------------------------------------------------------------------- + +/* + * Normally we strip ALOGV (VERBOSE messages) from release builds. + * You can modify this (for example with "#define LOG_NDEBUG 0" + * at the top of your source file) to change that behavior. + */ +#ifndef LOG_NDEBUG +#ifdef NDEBUG +#define LOG_NDEBUG 1 +#else +#define LOG_NDEBUG 0 +#endif +#endif + +/* + * This is the local tag used for the following simplified + * logging macros. You can change this preprocessor definition + * before using the other macros to change the tag. + */ +#ifndef LOG_TAG +#define LOG_TAG NULL +#endif + +// --------------------------------------------------------------------- + +#ifndef __predict_false +#define __predict_false(exp) __builtin_expect((exp) != 0, 0) +#endif + +/* + * -DLINT_RLOG in sources that you want to enforce that all logging + * goes to the radio log buffer. If any logging goes to any of the other + * log buffers, there will be a compile or link error to highlight the + * problem. This is not a replacement for a full audit of the code since + * this only catches compiled code, not ifdef'd debug code. Options to + * defining this, either temporarily to do a spot check, or permanently + * to enforce, in all the communications trees; We have hopes to ensure + * that by supplying just the radio log buffer that the communications + * teams will have their one-stop shop for triaging issues. + */ +#ifndef LINT_RLOG + +/* + * Simplified macro to send a verbose log message using the current LOG_TAG. + */ +#ifndef ALOGV +#define __ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) +#if LOG_NDEBUG +#define ALOGV(...) do { if (0) { __ALOGV(__VA_ARGS__); } } while (0) +#else +#define ALOGV(...) __ALOGV(__VA_ARGS__) +#endif +#endif + +#ifndef ALOGV_IF +#if LOG_NDEBUG +#define ALOGV_IF(cond, ...) ((void)0) +#else +#define ALOGV_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \ + : (void)0 ) +#endif +#endif + +/* + * Simplified macro to send a debug log message using the current LOG_TAG. + */ +#ifndef ALOGD +#define ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) +#endif + +#ifndef ALOGD_IF +#define ALOGD_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \ + : (void)0 ) +#endif + +/* + * Simplified macro to send an info log message using the current LOG_TAG. + */ +#ifndef ALOGI +#define ALOGI(...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) +#endif + +#ifndef ALOGI_IF +#define ALOGI_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \ + : (void)0 ) +#endif + +/* + * Simplified macro to send a warning log message using the current LOG_TAG. + */ +#ifndef ALOGW +#define ALOGW(...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) +#endif + +#ifndef ALOGW_IF +#define ALOGW_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \ + : (void)0 ) +#endif + +/* + * Simplified macro to send an error log message using the current LOG_TAG. + */ +#ifndef ALOGE +#define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) +#endif + +#ifndef ALOGE_IF +#define ALOGE_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \ + : (void)0 ) +#endif + +// --------------------------------------------------------------------- + +/* + * Conditional based on whether the current LOG_TAG is enabled at + * verbose priority. + */ +#ifndef IF_ALOGV +#if LOG_NDEBUG +#define IF_ALOGV() if (false) +#else +#define IF_ALOGV() IF_ALOG(LOG_VERBOSE, LOG_TAG) +#endif +#endif + +/* + * Conditional based on whether the current LOG_TAG is enabled at + * debug priority. + */ +#ifndef IF_ALOGD +#define IF_ALOGD() IF_ALOG(LOG_DEBUG, LOG_TAG) +#endif + +/* + * Conditional based on whether the current LOG_TAG is enabled at + * info priority. + */ +#ifndef IF_ALOGI +#define IF_ALOGI() IF_ALOG(LOG_INFO, LOG_TAG) +#endif + +/* + * Conditional based on whether the current LOG_TAG is enabled at + * warn priority. + */ +#ifndef IF_ALOGW +#define IF_ALOGW() IF_ALOG(LOG_WARN, LOG_TAG) +#endif + +/* + * Conditional based on whether the current LOG_TAG is enabled at + * error priority. + */ +#ifndef IF_ALOGE +#define IF_ALOGE() IF_ALOG(LOG_ERROR, LOG_TAG) +#endif + + +// --------------------------------------------------------------------- + +/* + * Simplified macro to send a verbose system log message using the current LOG_TAG. + */ +#ifndef SLOGV +#define __SLOGV(...) \ + ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) +#if LOG_NDEBUG +#define SLOGV(...) do { if (0) { __SLOGV(__VA_ARGS__); } } while (0) +#else +#define SLOGV(...) __SLOGV(__VA_ARGS__) +#endif +#endif + +#ifndef SLOGV_IF +#if LOG_NDEBUG +#define SLOGV_IF(cond, ...) ((void)0) +#else +#define SLOGV_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \ + : (void)0 ) +#endif +#endif + +/* + * Simplified macro to send a debug system log message using the current LOG_TAG. + */ +#ifndef SLOGD +#define SLOGD(...) \ + ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) +#endif + +#ifndef SLOGD_IF +#define SLOGD_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \ + : (void)0 ) +#endif + +/* + * Simplified macro to send an info system log message using the current LOG_TAG. + */ +#ifndef SLOGI +#define SLOGI(...) \ + ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) +#endif + +#ifndef SLOGI_IF +#define SLOGI_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \ + : (void)0 ) +#endif + +/* + * Simplified macro to send a warning system log message using the current LOG_TAG. + */ +#ifndef SLOGW +#define SLOGW(...) \ + ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) +#endif + +#ifndef SLOGW_IF +#define SLOGW_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \ + : (void)0 ) +#endif + +/* + * Simplified macro to send an error system log message using the current LOG_TAG. + */ +#ifndef SLOGE +#define SLOGE(...) \ + ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) +#endif + +#ifndef SLOGE_IF +#define SLOGE_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) \ + : (void)0 ) +#endif + +#endif /* !LINT_RLOG */ + +// --------------------------------------------------------------------- + +/* + * Simplified macro to send a verbose radio log message using the current LOG_TAG. + */ +#ifndef RLOGV +#define __RLOGV(...) \ + ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) +#if LOG_NDEBUG +#define RLOGV(...) do { if (0) { __RLOGV(__VA_ARGS__); } } while (0) +#else +#define RLOGV(...) __RLOGV(__VA_ARGS__) +#endif +#endif + +#ifndef RLOGV_IF +#if LOG_NDEBUG +#define RLOGV_IF(cond, ...) ((void)0) +#else +#define RLOGV_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \ + : (void)0 ) +#endif +#endif + +/* + * Simplified macro to send a debug radio log message using the current LOG_TAG. + */ +#ifndef RLOGD +#define RLOGD(...) \ + ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) +#endif + +#ifndef RLOGD_IF +#define RLOGD_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \ + : (void)0 ) +#endif + +/* + * Simplified macro to send an info radio log message using the current LOG_TAG. + */ +#ifndef RLOGI +#define RLOGI(...) \ + ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) +#endif + +#ifndef RLOGI_IF +#define RLOGI_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \ + : (void)0 ) +#endif + +/* + * Simplified macro to send a warning radio log message using the current LOG_TAG. + */ +#ifndef RLOGW +#define RLOGW(...) \ + ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) +#endif + +#ifndef RLOGW_IF +#define RLOGW_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \ + : (void)0 ) +#endif + +/* + * Simplified macro to send an error radio log message using the current LOG_TAG. + */ +#ifndef RLOGE +#define RLOGE(...) \ + ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) +#endif + +#ifndef RLOGE_IF +#define RLOGE_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) \ + : (void)0 ) +#endif + + +// --------------------------------------------------------------------- + +/* + * Log a fatal error. If the given condition fails, this stops program + * execution like a normal assertion, but also generating the given message. + * It is NOT stripped from release builds. Note that the condition test + * is -inverted- from the normal assert() semantics. + */ +#ifndef LOG_ALWAYS_FATAL_IF +#define LOG_ALWAYS_FATAL_IF(cond, ...) \ + ( (__predict_false(cond)) \ + ? ((void)android_printAssert(#cond, LOG_TAG, ## __VA_ARGS__)) \ + : (void)0 ) +#endif + +#ifndef LOG_ALWAYS_FATAL +#define LOG_ALWAYS_FATAL(...) \ + ( ((void)android_printAssert(NULL, LOG_TAG, ## __VA_ARGS__)) ) +#endif + +/* + * Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that + * are stripped out of release builds. + */ +#if LOG_NDEBUG + +#ifndef LOG_FATAL_IF +#define LOG_FATAL_IF(cond, ...) ((void)0) +#endif +#ifndef LOG_FATAL +#define LOG_FATAL(...) ((void)0) +#endif + +#else + +#ifndef LOG_FATAL_IF +#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ## __VA_ARGS__) +#endif +#ifndef LOG_FATAL +#define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__) +#endif + +#endif + +/* + * Assertion that generates a log message when the assertion fails. + * Stripped out of release builds. Uses the current LOG_TAG. + */ +#ifndef ALOG_ASSERT +#define ALOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ## __VA_ARGS__) +//#define ALOG_ASSERT(cond) LOG_FATAL_IF(!(cond), "Assertion failed: " #cond) +#endif + +// --------------------------------------------------------------------- + +/* + * Basic log message macro. + * + * Example: + * ALOG(LOG_WARN, NULL, "Failed with error %d", errno); + * + * The second argument may be NULL or "" to indicate the "global" tag. + */ +#ifndef ALOG +#define ALOG(priority, tag, ...) \ + LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__) +#endif + +/* + * Log macro that allows you to specify a number for the priority. + */ +#ifndef LOG_PRI +#define LOG_PRI(priority, tag, ...) \ + android_printLog(priority, tag, __VA_ARGS__) +#endif + +/* + * Log macro that allows you to pass in a varargs ("args" is a va_list). + */ +#ifndef LOG_PRI_VA +#define LOG_PRI_VA(priority, tag, fmt, args) \ + android_vprintLog(priority, NULL, tag, fmt, args) +#endif + +/* + * Conditional given a desired logging priority and tag. + */ +#ifndef IF_ALOG +#define IF_ALOG(priority, tag) \ + if (android_testLog(ANDROID_##priority, tag)) +#endif + +// --------------------------------------------------------------------- + +/* + * Event logging. + */ + +/* + * Event log entry types. These must match up with the declarations in + * java/android/android/util/EventLog.java. + */ +typedef enum { + EVENT_TYPE_INT = 0, + EVENT_TYPE_LONG = 1, + EVENT_TYPE_STRING = 2, + EVENT_TYPE_LIST = 3, + EVENT_TYPE_FLOAT = 4, +} AndroidEventLogType; +#define sizeof_AndroidEventLogType sizeof(typeof_AndroidEventLogType) +#define typeof_AndroidEventLogType unsigned char + +#ifndef LOG_EVENT_INT +#define LOG_EVENT_INT(_tag, _value) { \ + int intBuf = _value; \ + (void) android_btWriteLog(_tag, EVENT_TYPE_INT, &intBuf, \ + sizeof(intBuf)); \ + } +#endif +#ifndef LOG_EVENT_LONG +#define LOG_EVENT_LONG(_tag, _value) { \ + long long longBuf = _value; \ + (void) android_btWriteLog(_tag, EVENT_TYPE_LONG, &longBuf, \ + sizeof(longBuf)); \ + } +#endif +#ifndef LOG_EVENT_FLOAT +#define LOG_EVENT_FLOAT(_tag, _value) { \ + float floatBuf = _value; \ + (void) android_btWriteLog(_tag, EVENT_TYPE_FLOAT, &floatBuf, \ + sizeof(floatBuf)); \ + } +#endif +#ifndef LOG_EVENT_STRING +#define LOG_EVENT_STRING(_tag, _value) \ + (void) __android_log_bswrite(_tag, _value); +#endif +/* TODO: something for LIST */ + +/* + * =========================================================================== + * + * The stuff in the rest of this file should not be used directly. + */ + +#define android_printLog(prio, tag, fmt...) \ + __android_log_print(prio, tag, fmt) + +#define android_vprintLog(prio, cond, tag, fmt...) \ + __android_log_vprint(prio, tag, fmt) + +/* XXX Macros to work around syntax errors in places where format string + * arg is not passed to ALOG_ASSERT, LOG_ALWAYS_FATAL or LOG_ALWAYS_FATAL_IF + * (happens only in debug builds). + */ + +/* Returns 2nd arg. Used to substitute default value if caller's vararg list + * is empty. + */ +#define __android_second(dummy, second, ...) second + +/* If passed multiple args, returns ',' followed by all but 1st arg, otherwise + * returns nothing. + */ +#define __android_rest(first, ...) , ## __VA_ARGS__ + +#define android_printAssert(cond, tag, fmt...) \ + __android_log_assert(cond, tag, \ + __android_second(0, ## fmt, NULL) __android_rest(fmt)) + +#define android_writeLog(prio, tag, text) \ + __android_log_write(prio, tag, text) + +#define android_bWriteLog(tag, payload, len) \ + __android_log_bwrite(tag, payload, len) +#define android_btWriteLog(tag, type, payload, len) \ + __android_log_btwrite(tag, type, payload, len) + +#define android_errorWriteLog(tag, subTag) \ + __android_log_error_write(tag, subTag, -1, NULL, 0) + +#define android_errorWriteWithInfoLog(tag, subTag, uid, data, dataLen) \ + __android_log_error_write(tag, subTag, uid, data, dataLen) + +/* + * IF_ALOG uses android_testLog, but IF_ALOG can be overridden. + * android_testLog will remain constant in its purpose as a wrapper + * for Android logging filter policy, and can be subject to + * change. It can be reused by the developers that override + * IF_ALOG as a convenient means to reimplement their policy + * over Android. + */ +#if LOG_NDEBUG /* Production */ +#define android_testLog(prio, tag) \ + (__android_log_is_loggable(prio, tag, ANDROID_LOG_DEBUG) != 0) +#else +#define android_testLog(prio, tag) \ + (__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE) != 0) +#endif + +// TODO: remove these prototypes and their users +#define android_writevLog(vec,num) do{}while(0) +#define android_write1Log(str,len) do{}while (0) +#define android_setMinPriority(tag, prio) do{}while(0) +//#define android_logToCallback(func) do{}while(0) +#define android_logToFile(tag, file) (0) +#define android_logToFd(tag, fd) (0) + +#ifndef log_id_t_defined +#define log_id_t_defined + +typedef enum log_id { + LOG_ID_MIN = 0, + +#ifndef LINT_RLOG + LOG_ID_MAIN = 0, +#endif + LOG_ID_RADIO = 1, +#ifndef LINT_RLOG + LOG_ID_EVENTS = 2, + LOG_ID_SYSTEM = 3, + LOG_ID_CRASH = 4, + LOG_ID_KERNEL = 5, +#endif + + LOG_ID_MAX +} log_id_t; +#endif +#define sizeof_log_id_t sizeof(typeof_log_id_t) +#define typeof_log_id_t unsigned char + +/* + * Use the per-tag properties "log.tag." to generate a runtime + * result of non-zero to expose a log. + */ +int __android_log_is_loggable(int prio, const char *tag, int def); + +int __android_log_error_write(int tag, const char *subTag, int32_t uid, const char *data, + uint32_t dataLen); + +/* + * Send a simple string to the log. + */ +int __android_log_buf_write(int bufID, int prio, const char *tag, const char *text); +int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...) +#if defined(__GNUC__) + __attribute__((__format__(printf, 4, 5))) +#endif + ; + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBS_LOG_LOG_H */ diff --git a/phonelibs/android_system_core/include/log/log_read.h b/phonelibs/android_system_core/include/log/log_read.h new file mode 100644 index 00000000000000..1b70affc3540c1 --- /dev/null +++ b/phonelibs/android_system_core/include/log/log_read.h @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2013-2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_LOG_LOG_READ_H +#define _LIBS_LOG_LOG_READ_H + +#include +#include + +/* struct log_time is a wire-format variant of struct timespec */ +#define NS_PER_SEC 1000000000ULL + +#ifdef __cplusplus + +// NB: do NOT define a copy constructor. This will result in structure +// no longer being compatible with pass-by-value which is desired +// efficient behavior. Also, pass-by-reference breaks C/C++ ABI. +struct log_time { +public: + uint32_t tv_sec; // good to Feb 5 2106 + uint32_t tv_nsec; + + static const uint32_t tv_sec_max = 0xFFFFFFFFUL; + static const uint32_t tv_nsec_max = 999999999UL; + + log_time(const timespec &T) + { + tv_sec = T.tv_sec; + tv_nsec = T.tv_nsec; + } + log_time(uint32_t sec, uint32_t nsec) + { + tv_sec = sec; + tv_nsec = nsec; + } + static const timespec EPOCH; + log_time() + { + } + log_time(clockid_t id) + { + timespec T; + clock_gettime(id, &T); + tv_sec = T.tv_sec; + tv_nsec = T.tv_nsec; + } + log_time(const char *T) + { + const uint8_t *c = (const uint8_t *) T; + tv_sec = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); + tv_nsec = c[4] | (c[5] << 8) | (c[6] << 16) | (c[7] << 24); + } + + // timespec + bool operator== (const timespec &T) const + { + return (tv_sec == static_cast(T.tv_sec)) + && (tv_nsec == static_cast(T.tv_nsec)); + } + bool operator!= (const timespec &T) const + { + return !(*this == T); + } + bool operator< (const timespec &T) const + { + return (tv_sec < static_cast(T.tv_sec)) + || ((tv_sec == static_cast(T.tv_sec)) + && (tv_nsec < static_cast(T.tv_nsec))); + } + bool operator>= (const timespec &T) const + { + return !(*this < T); + } + bool operator> (const timespec &T) const + { + return (tv_sec > static_cast(T.tv_sec)) + || ((tv_sec == static_cast(T.tv_sec)) + && (tv_nsec > static_cast(T.tv_nsec))); + } + bool operator<= (const timespec &T) const + { + return !(*this > T); + } + log_time operator-= (const timespec &T); + log_time operator- (const timespec &T) const + { + log_time local(*this); + return local -= T; + } + log_time operator+= (const timespec &T); + log_time operator+ (const timespec &T) const + { + log_time local(*this); + return local += T; + } + + // log_time + bool operator== (const log_time &T) const + { + return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec); + } + bool operator!= (const log_time &T) const + { + return !(*this == T); + } + bool operator< (const log_time &T) const + { + return (tv_sec < T.tv_sec) + || ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec)); + } + bool operator>= (const log_time &T) const + { + return !(*this < T); + } + bool operator> (const log_time &T) const + { + return (tv_sec > T.tv_sec) + || ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec)); + } + bool operator<= (const log_time &T) const + { + return !(*this > T); + } + log_time operator-= (const log_time &T); + log_time operator- (const log_time &T) const + { + log_time local(*this); + return local -= T; + } + log_time operator+= (const log_time &T); + log_time operator+ (const log_time &T) const + { + log_time local(*this); + return local += T; + } + + uint64_t nsec() const + { + return static_cast(tv_sec) * NS_PER_SEC + tv_nsec; + } + + static const char default_format[]; + + // Add %#q for the fraction of a second to the standard library functions + char *strptime(const char *s, const char *format = default_format); +} __attribute__((__packed__)); + +#else + +typedef struct log_time { + uint32_t tv_sec; + uint32_t tv_nsec; +} __attribute__((__packed__)) log_time; + +#endif + +#endif /* define _LIBS_LOG_LOG_READ_H */ diff --git a/phonelibs/android_system_core/include/log/logd.h b/phonelibs/android_system_core/include/log/logd.h new file mode 100644 index 00000000000000..0fe515f2abad39 --- /dev/null +++ b/phonelibs/android_system_core/include/log/logd.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_CUTILS_LOGD_H +#define _ANDROID_CUTILS_LOGD_H + +/* the stable/frozen log-related definitions have been + * moved to this header, which is exposed by the NDK + */ +#include + +/* the rest is only used internally by the system */ +#if !defined(_WIN32) +#include +#endif +#include +#include +#include +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int __android_log_bwrite(int32_t tag, const void *payload, size_t len); +int __android_log_btwrite(int32_t tag, char type, const void *payload, + size_t len); +int __android_log_bswrite(int32_t tag, const char *payload); + +#ifdef __cplusplus +} +#endif + +#endif /* _LOGD_H */ diff --git a/phonelibs/android_system_core/include/log/logger.h b/phonelibs/android_system_core/include/log/logger.h new file mode 100644 index 00000000000000..f030dab5a97d55 --- /dev/null +++ b/phonelibs/android_system_core/include/log/logger.h @@ -0,0 +1,196 @@ +/* +** +** Copyright 2007-2014, The Android Open Source Project +** +** This file is dual licensed. It may be redistributed and/or modified +** under the terms of the Apache 2.0 License OR version 2 of the GNU +** General Public License. +*/ + +#ifndef _LIBS_LOG_LOGGER_H +#define _LIBS_LOG_LOGGER_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The userspace structure for version 1 of the logger_entry ABI. + * This structure is returned to userspace by the kernel logger + * driver unless an upgrade to a newer ABI version is requested. + */ +struct logger_entry { + uint16_t len; /* length of the payload */ + uint16_t __pad; /* no matter what, we get 2 bytes of padding */ + int32_t pid; /* generating process's pid */ + int32_t tid; /* generating process's tid */ + int32_t sec; /* seconds since Epoch */ + int32_t nsec; /* nanoseconds */ + char msg[0]; /* the entry's payload */ +} __attribute__((__packed__)); + +/* + * The userspace structure for version 2 of the logger_entry ABI. + * This structure is returned to userspace if ioctl(LOGGER_SET_VERSION) + * is called with version==2; or used with the user space log daemon. + */ +struct logger_entry_v2 { + uint16_t len; /* length of the payload */ + uint16_t hdr_size; /* sizeof(struct logger_entry_v2) */ + int32_t pid; /* generating process's pid */ + int32_t tid; /* generating process's tid */ + int32_t sec; /* seconds since Epoch */ + int32_t nsec; /* nanoseconds */ + uint32_t euid; /* effective UID of logger */ + char msg[0]; /* the entry's payload */ +} __attribute__((__packed__)); + +struct logger_entry_v3 { + uint16_t len; /* length of the payload */ + uint16_t hdr_size; /* sizeof(struct logger_entry_v3) */ + int32_t pid; /* generating process's pid */ + int32_t tid; /* generating process's tid */ + int32_t sec; /* seconds since Epoch */ + int32_t nsec; /* nanoseconds */ + uint32_t lid; /* log id of the payload */ + char msg[0]; /* the entry's payload */ +} __attribute__((__packed__)); + +/* + * The maximum size of the log entry payload that can be + * written to the logger. An attempt to write more than + * this amount will result in a truncated log entry. + */ +#define LOGGER_ENTRY_MAX_PAYLOAD 4076 + +/* + * The maximum size of a log entry which can be read from the + * kernel logger driver. An attempt to read less than this amount + * may result in read() returning EINVAL. + */ +#define LOGGER_ENTRY_MAX_LEN (5*1024) + +#define NS_PER_SEC 1000000000ULL + +struct log_msg { + union { + unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1]; + struct logger_entry_v3 entry; + struct logger_entry_v3 entry_v3; + struct logger_entry_v2 entry_v2; + struct logger_entry entry_v1; + } __attribute__((aligned(4))); +#ifdef __cplusplus + /* Matching log_time operators */ + bool operator== (const log_msg &T) const + { + return (entry.sec == T.entry.sec) && (entry.nsec == T.entry.nsec); + } + bool operator!= (const log_msg &T) const + { + return !(*this == T); + } + bool operator< (const log_msg &T) const + { + return (entry.sec < T.entry.sec) + || ((entry.sec == T.entry.sec) + && (entry.nsec < T.entry.nsec)); + } + bool operator>= (const log_msg &T) const + { + return !(*this < T); + } + bool operator> (const log_msg &T) const + { + return (entry.sec > T.entry.sec) + || ((entry.sec == T.entry.sec) + && (entry.nsec > T.entry.nsec)); + } + bool operator<= (const log_msg &T) const + { + return !(*this > T); + } + uint64_t nsec() const + { + return static_cast(entry.sec) * NS_PER_SEC + entry.nsec; + } + + /* packet methods */ + log_id_t id() + { + return (log_id_t) entry.lid; + } + char *msg() + { + return entry.hdr_size ? (char *) buf + entry.hdr_size : entry_v1.msg; + } + unsigned int len() + { + return (entry.hdr_size ? entry.hdr_size : sizeof(entry_v1)) + entry.len; + } +#endif +}; + +struct logger; + +log_id_t android_logger_get_id(struct logger *logger); + +int android_logger_clear(struct logger *logger); +long android_logger_get_log_size(struct logger *logger); +int android_logger_set_log_size(struct logger *logger, unsigned long size); +long android_logger_get_log_readable_size(struct logger *logger); +int android_logger_get_log_version(struct logger *logger); + +struct logger_list; + +ssize_t android_logger_get_statistics(struct logger_list *logger_list, + char *buf, size_t len); +ssize_t android_logger_get_prune_list(struct logger_list *logger_list, + char *buf, size_t len); +int android_logger_set_prune_list(struct logger_list *logger_list, + char *buf, size_t len); + +#define ANDROID_LOG_RDONLY O_RDONLY +#define ANDROID_LOG_WRONLY O_WRONLY +#define ANDROID_LOG_RDWR O_RDWR +#define ANDROID_LOG_ACCMODE O_ACCMODE +#define ANDROID_LOG_NONBLOCK O_NONBLOCK +#define ANDROID_LOG_PSTORE 0x80000000 + +struct logger_list *android_logger_list_alloc(int mode, + unsigned int tail, + pid_t pid); +struct logger_list *android_logger_list_alloc_time(int mode, + log_time start, + pid_t pid); +void android_logger_list_free(struct logger_list *logger_list); +/* In the purest sense, the following two are orthogonal interfaces */ +int android_logger_list_read(struct logger_list *logger_list, + struct log_msg *log_msg); + +/* Multiple log_id_t opens */ +struct logger *android_logger_open(struct logger_list *logger_list, + log_id_t id); +#define android_logger_close android_logger_free +/* Single log_id_t open */ +struct logger_list *android_logger_list_open(log_id_t id, + int mode, + unsigned int tail, + pid_t pid); +#define android_logger_list_close android_logger_list_free + +/* + * log_id_t helpers + */ +log_id_t android_name_to_log_id(const char *logName); +const char *android_log_id_to_name(log_id_t log_id); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBS_LOG_LOGGER_H */ diff --git a/phonelibs/android_system_core/include/log/logprint.h b/phonelibs/android_system_core/include/log/logprint.h new file mode 100644 index 00000000000000..4b812cc9411d59 --- /dev/null +++ b/phonelibs/android_system_core/include/log/logprint.h @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LOGPRINT_H +#define _LOGPRINT_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + FORMAT_OFF = 0, + FORMAT_BRIEF, + FORMAT_PROCESS, + FORMAT_TAG, + FORMAT_THREAD, + FORMAT_RAW, + FORMAT_TIME, + FORMAT_THREADTIME, + FORMAT_LONG, + /* The following three are modifiers to above formats */ + FORMAT_MODIFIER_COLOR, /* converts priority to color */ + FORMAT_MODIFIER_TIME_USEC, /* switches from msec to usec time precision */ + FORMAT_MODIFIER_PRINTABLE, /* converts non-printable to printable escapes */ +} AndroidLogPrintFormat; + +typedef struct AndroidLogFormat_t AndroidLogFormat; + +typedef struct AndroidLogEntry_t { + time_t tv_sec; + long tv_nsec; + android_LogPriority priority; + int32_t pid; + int32_t tid; + const char * tag; + size_t messageLen; + const char * message; +} AndroidLogEntry; + +AndroidLogFormat *android_log_format_new(); + +void android_log_format_free(AndroidLogFormat *p_format); + +/* currently returns 0 if format is a modifier, 1 if not */ +int android_log_setPrintFormat(AndroidLogFormat *p_format, + AndroidLogPrintFormat format); + +/** + * Returns FORMAT_OFF on invalid string + */ +AndroidLogPrintFormat android_log_formatFromString(const char *s); + +/** + * filterExpression: a single filter expression + * eg "AT:d" + * + * returns 0 on success and -1 on invalid expression + * + * Assumes single threaded execution + * + */ + +int android_log_addFilterRule(AndroidLogFormat *p_format, + const char *filterExpression); + + +/** + * filterString: a whitespace-separated set of filter expressions + * eg "AT:d *:i" + * + * returns 0 on success and -1 on invalid expression + * + * Assumes single threaded execution + * + */ + +int android_log_addFilterString(AndroidLogFormat *p_format, + const char *filterString); + + +/** + * returns 1 if this log line should be printed based on its priority + * and tag, and 0 if it should not + */ +int android_log_shouldPrintLine ( + AndroidLogFormat *p_format, const char *tag, android_LogPriority pri); + + +/** + * Splits a wire-format buffer into an AndroidLogEntry + * entry allocated by caller. Pointers will point directly into buf + * + * Returns 0 on success and -1 on invalid wire format (entry will be + * in unspecified state) + */ +int android_log_processLogBuffer(struct logger_entry *buf, + AndroidLogEntry *entry); + +/** + * Like android_log_processLogBuffer, but for binary logs. + * + * If "map" is non-NULL, it will be used to convert the log tag number + * into a string. + */ +int android_log_processBinaryLogBuffer(struct logger_entry *buf, + AndroidLogEntry *entry, const EventTagMap* map, char* messageBuf, + int messageBufLen); + + +/** + * Formats a log message into a buffer + * + * Uses defaultBuffer if it can, otherwise malloc()'s a new buffer + * If return value != defaultBuffer, caller must call free() + * Returns NULL on malloc error + */ + +char *android_log_formatLogLine ( + AndroidLogFormat *p_format, + char *defaultBuffer, + size_t defaultBufferSize, + const AndroidLogEntry *p_line, + size_t *p_outLength); + + +/** + * Either print or do not print log line, based on filter + * + * Assumes single threaded execution + * + */ +int android_log_printLogLine( + AndroidLogFormat *p_format, + int fd, + const AndroidLogEntry *entry); + + +#ifdef __cplusplus +} +#endif + + +#endif /*_LOGPRINT_H*/ diff --git a/phonelibs/android_system_core/include/log/uio.h b/phonelibs/android_system_core/include/log/uio.h new file mode 100644 index 00000000000000..7059da5f76942e --- /dev/null +++ b/phonelibs/android_system_core/include/log/uio.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2007-2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_CUTILS_UIO_H +#define _LIBS_CUTILS_UIO_H + +#if !defined(_WIN32) + +#include + +#else + +#ifdef __cplusplus +extern "C" { +#endif + +// +// Implementation of sys/uio.h for Win32. +// + +#include + +struct iovec { + void* iov_base; + size_t iov_len; +}; + +extern int readv( int fd, struct iovec* vecs, int count ); +extern int writev( int fd, const struct iovec* vecs, int count ); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif /* _LIBS_UTILS_UIO_H */ + diff --git a/phonelibs/android_system_core/include/system/camera.h b/phonelibs/android_system_core/include/system/camera.h new file mode 100644 index 00000000000000..0570ca04c6ebe7 --- /dev/null +++ b/phonelibs/android_system_core/include/system/camera.h @@ -0,0 +1,365 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_CORE_INCLUDE_ANDROID_CAMERA_H +#define SYSTEM_CORE_INCLUDE_ANDROID_CAMERA_H + +#include +#include +#include +#include +#include +#include + +__BEGIN_DECLS + +/** + * A set of bit masks for specifying how the received preview frames are + * handled before the previewCallback() call. + * + * The least significant 3 bits of an "int" value are used for this purpose: + * + * ..... 0 0 0 + * ^ ^ ^ + * | | |---------> determine whether the callback is enabled or not + * | |-----------> determine whether the callback is one-shot or not + * |-------------> determine whether the frame is copied out or not + * + * WARNING: When a frame is sent directly without copying, it is the frame + * receiver's responsiblity to make sure that the frame data won't get + * corrupted by subsequent preview frames filled by the camera. This flag is + * recommended only when copying out data brings significant performance price + * and the handling/processing of the received frame data is always faster than + * the preview frame rate so that data corruption won't occur. + * + * For instance, + * 1. 0x00 disables the callback. In this case, copy out and one shot bits + * are ignored. + * 2. 0x01 enables a callback without copying out the received frames. A + * typical use case is the Camcorder application to avoid making costly + * frame copies. + * 3. 0x05 is enabling a callback with frame copied out repeatedly. A typical + * use case is the Camera application. + * 4. 0x07 is enabling a callback with frame copied out only once. A typical + * use case is the Barcode scanner application. + */ + +enum { + CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK = 0x01, + CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK = 0x02, + CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK = 0x04, + /** Typical use cases */ + CAMERA_FRAME_CALLBACK_FLAG_NOOP = 0x00, + CAMERA_FRAME_CALLBACK_FLAG_CAMCORDER = 0x01, + CAMERA_FRAME_CALLBACK_FLAG_CAMERA = 0x05, + CAMERA_FRAME_CALLBACK_FLAG_BARCODE_SCANNER = 0x07 +}; + +/** msgType in notifyCallback and dataCallback functions */ +enum { + CAMERA_MSG_ERROR = 0x0001, // notifyCallback + CAMERA_MSG_SHUTTER = 0x0002, // notifyCallback + CAMERA_MSG_FOCUS = 0x0004, // notifyCallback + CAMERA_MSG_ZOOM = 0x0008, // notifyCallback + CAMERA_MSG_PREVIEW_FRAME = 0x0010, // dataCallback + CAMERA_MSG_VIDEO_FRAME = 0x0020, // data_timestamp_callback + CAMERA_MSG_POSTVIEW_FRAME = 0x0040, // dataCallback + CAMERA_MSG_RAW_IMAGE = 0x0080, // dataCallback + CAMERA_MSG_COMPRESSED_IMAGE = 0x0100, // dataCallback + CAMERA_MSG_RAW_IMAGE_NOTIFY = 0x0200, // dataCallback + // Preview frame metadata. This can be combined with + // CAMERA_MSG_PREVIEW_FRAME in dataCallback. For example, the apps can + // request FRAME and METADATA. Or the apps can request only FRAME or only + // METADATA. + CAMERA_MSG_PREVIEW_METADATA = 0x0400, // dataCallback + // Notify on autofocus start and stop. This is useful in continuous + // autofocus - FOCUS_MODE_CONTINUOUS_VIDEO and FOCUS_MODE_CONTINUOUS_PICTURE. + CAMERA_MSG_FOCUS_MOVE = 0x0800, // notifyCallback + CAMERA_MSG_VENDOR_START = 0x1000, + CAMERA_MSG_STATS_DATA = CAMERA_MSG_VENDOR_START, + CAMERA_MSG_META_DATA = 0x2000, + CAMERA_MSG_VENDOR_END = 0x8000, + CAMERA_MSG_ALL_MSGS = 0xFFFF +}; + +/** meta data type in CameraMetaDataCallback */ +enum { + CAMERA_META_DATA_ASD = 0x001, //ASD data + CAMERA_META_DATA_FD = 0x002, //FD/FP data + CAMERA_META_DATA_HDR = 0x003, //Auto HDR data +}; + +/** cmdType in sendCommand functions */ +enum { + CAMERA_CMD_START_SMOOTH_ZOOM = 1, + CAMERA_CMD_STOP_SMOOTH_ZOOM = 2, + + /** + * Set the clockwise rotation of preview display (setPreviewDisplay) in + * degrees. This affects the preview frames and the picture displayed after + * snapshot. This method is useful for portrait mode applications. Note + * that preview display of front-facing cameras is flipped horizontally + * before the rotation, that is, the image is reflected along the central + * vertical axis of the camera sensor. So the users can see themselves as + * looking into a mirror. + * + * This does not affect the order of byte array of + * CAMERA_MSG_PREVIEW_FRAME, CAMERA_MSG_VIDEO_FRAME, + * CAMERA_MSG_POSTVIEW_FRAME, CAMERA_MSG_RAW_IMAGE, or + * CAMERA_MSG_COMPRESSED_IMAGE. This is allowed to be set during preview + * since API level 14. + */ + CAMERA_CMD_SET_DISPLAY_ORIENTATION = 3, + + /** + * cmdType to disable/enable shutter sound. In sendCommand passing arg1 = + * 0 will disable, while passing arg1 = 1 will enable the shutter sound. + */ + CAMERA_CMD_ENABLE_SHUTTER_SOUND = 4, + + /* cmdType to play recording sound */ + CAMERA_CMD_PLAY_RECORDING_SOUND = 5, + + /** + * Start the face detection. This should be called after preview is started. + * The camera will notify the listener of CAMERA_MSG_FACE and the detected + * faces in the preview frame. The detected faces may be the same as the + * previous ones. Apps should call CAMERA_CMD_STOP_FACE_DETECTION to stop + * the face detection. This method is supported if CameraParameters + * KEY_MAX_NUM_HW_DETECTED_FACES or KEY_MAX_NUM_SW_DETECTED_FACES is + * bigger than 0. Hardware and software face detection should not be running + * at the same time. If the face detection has started, apps should not send + * this again. + * + * In hardware face detection mode, CameraParameters KEY_WHITE_BALANCE, + * KEY_FOCUS_AREAS and KEY_METERING_AREAS have no effect. + * + * arg1 is the face detection type. It can be CAMERA_FACE_DETECTION_HW or + * CAMERA_FACE_DETECTION_SW. If the type of face detection requested is not + * supported, the HAL must return BAD_VALUE. + */ + CAMERA_CMD_START_FACE_DETECTION = 6, + + /** + * Stop the face detection. + */ + CAMERA_CMD_STOP_FACE_DETECTION = 7, + + /** + * Enable/disable focus move callback (CAMERA_MSG_FOCUS_MOVE). Passing + * arg1 = 0 will disable, while passing arg1 = 1 will enable the callback. + */ + CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG = 8, + + /** + * Ping camera service to see if camera hardware is released. + * + * When any camera method returns error, the client can use ping command + * to see if the camera has been taken away by other clients. If the result + * is NO_ERROR, it means the camera hardware is not released. If the result + * is not NO_ERROR, the camera has been released and the existing client + * can silently finish itself or show a dialog. + */ + CAMERA_CMD_PING = 9, + + /** + * Configure the number of video buffers used for recording. The intended + * video buffer count for recording is passed as arg1, which must be + * greater than 0. This command must be sent before recording is started. + * This command returns INVALID_OPERATION error if it is sent after video + * recording is started, or the command is not supported at all. This + * command also returns a BAD_VALUE error if the intended video buffer + * count is non-positive or too big to be realized. + */ + CAMERA_CMD_SET_VIDEO_BUFFER_COUNT = 10, + + /** + * Configure an explicit format to use for video recording metadata mode. + * This can be used to switch the format from the + * default IMPLEMENTATION_DEFINED gralloc format to some other + * device-supported format, and the default dataspace from the BT_709 color + * space to some other device-supported dataspace. arg1 is the HAL pixel + * format, and arg2 is the HAL dataSpace. This command returns + * INVALID_OPERATION error if it is sent after video recording is started, + * or the command is not supported at all. + * + * If the gralloc format is set to a format other than + * IMPLEMENTATION_DEFINED, then HALv3 devices will use gralloc usage flags + * of SW_READ_OFTEN. + */ +#ifndef CAMERA_VENDOR_L_COMPAT + CAMERA_CMD_SET_VIDEO_FORMAT = 11, + + CAMERA_CMD_VENDOR_START = 20, + /** + * Commands to enable/disable preview histogram + * + * Based on user's input to enable/disable histogram from the camera + * UI, send the appropriate command to the HAL to turn on/off the histogram + * stats and start sending the data to the application. + */ + CAMERA_CMD_HISTOGRAM_ON = CAMERA_CMD_VENDOR_START, + CAMERA_CMD_HISTOGRAM_OFF = CAMERA_CMD_VENDOR_START + 1, + CAMERA_CMD_HISTOGRAM_SEND_DATA = CAMERA_CMD_VENDOR_START + 2, + CAMERA_CMD_LONGSHOT_ON = CAMERA_CMD_VENDOR_START + 3, + CAMERA_CMD_LONGSHOT_OFF = CAMERA_CMD_VENDOR_START + 4, + CAMERA_CMD_STOP_LONGSHOT = CAMERA_CMD_VENDOR_START + 5, + CAMERA_CMD_METADATA_ON = CAMERA_CMD_VENDOR_START + 6, + CAMERA_CMD_METADATA_OFF = CAMERA_CMD_VENDOR_START + 7, + CAMERA_CMD_VENDOR_END = 200, +#else + + /** + * Values used by older HALs, provided as an option for compatibility + */ + CAMERA_CMD_HISTOGRAM_ON = 11, + CAMERA_CMD_HISTOGRAM_OFF = 12, + CAMERA_CMD_HISTOGRAM_SEND_DATA = 13, + CAMERA_CMD_LONGSHOT_ON = 14, + CAMERA_CMD_LONGSHOT_OFF = 15, + CAMERA_CMD_STOP_LONGSHOT = 16, + CAMERA_CMD_METADATA_ON = 100, + CAMERA_CMD_METADATA_OFF = 101, + CAMERA_CMD_SET_VIDEO_FORMAT = 102, +#endif +}; + +/** camera fatal errors */ +enum { + CAMERA_ERROR_UNKNOWN = 1, + /** + * Camera was released because another client has connected to the camera. + * The original client should call Camera::disconnect immediately after + * getting this notification. Otherwise, the camera will be released by + * camera service in a short time. The client should not call any method + * (except disconnect and sending CAMERA_CMD_PING) after getting this. + */ + CAMERA_ERROR_RELEASED = 2, + CAMERA_ERROR_SERVER_DIED = 100 +}; + +enum { + /** The facing of the camera is opposite to that of the screen. */ + CAMERA_FACING_BACK = 0, + /** The facing of the camera is the same as that of the screen. */ + CAMERA_FACING_FRONT = 1, + /** + * The facing of the camera is not fixed relative to the screen. + * The cameras with this facing are external cameras, e.g. USB cameras. + */ + CAMERA_FACING_EXTERNAL = 2 +}; + +enum { + /** Hardware face detection. It does not use much CPU. */ + CAMERA_FACE_DETECTION_HW = 0, + /** + * Software face detection. It uses some CPU. Applications must use + * Camera.setPreviewTexture for preview in this mode. + */ + CAMERA_FACE_DETECTION_SW = 1 +}; + +/** + * The information of a face from camera face detection. + */ +typedef struct camera_face { + /** + * Bounds of the face [left, top, right, bottom]. (-1000, -1000) represents + * the top-left of the camera field of view, and (1000, 1000) represents the + * bottom-right of the field of view. The width and height cannot be 0 or + * negative. This is supported by both hardware and software face detection. + * + * The direction is relative to the sensor orientation, that is, what the + * sensor sees. The direction is not affected by the rotation or mirroring + * of CAMERA_CMD_SET_DISPLAY_ORIENTATION. + */ + int32_t rect[4]; + + /** + * The confidence level of the face. The range is 1 to 100. 100 is the + * highest confidence. This is supported by both hardware and software + * face detection. + */ + int32_t score; + + /** + * An unique id per face while the face is visible to the tracker. If + * the face leaves the field-of-view and comes back, it will get a new + * id. If the value is 0, id is not supported. + */ + int32_t id; + + /** + * The coordinates of the center of the left eye. The range is -1000 to + * 1000. -2000, -2000 if this is not supported. + */ + int32_t left_eye[2]; + + /** + * The coordinates of the center of the right eye. The range is -1000 to + * 1000. -2000, -2000 if this is not supported. + */ + int32_t right_eye[2]; + + /** + * The coordinates of the center of the mouth. The range is -1000 to 1000. + * -2000, -2000 if this is not supported. + */ + int32_t mouth[2]; + int32_t smile_degree; + int32_t smile_score; + int32_t blink_detected; + int32_t face_recognised; + int32_t gaze_angle; + int32_t updown_dir; + int32_t leftright_dir; + int32_t roll_dir; + int32_t left_right_gaze; + int32_t top_bottom_gaze; + int32_t leye_blink; + int32_t reye_blink; + +} camera_face_t; + +/** + * The information of a data type received in a camera frame. + */ +typedef enum { + /** Data buffer */ + CAMERA_FRAME_DATA_BUF = 0x000, + /** File descriptor */ + CAMERA_FRAME_DATA_FD = 0x100 +} camera_frame_data_type_t; + +/** + * The metadata of the frame data. + */ +typedef struct camera_frame_metadata { + /** + * The number of detected faces in the frame. + */ + int32_t number_of_faces; + + /** + * An array of the detected faces. The length is number_of_faces. + */ + camera_face_t *faces; +} camera_frame_metadata_t; + +__END_DECLS + +#endif /* SYSTEM_CORE_INCLUDE_ANDROID_CAMERA_H */ diff --git a/phonelibs/android_system_core/include/system/graphics.h b/phonelibs/android_system_core/include/system/graphics.h new file mode 100644 index 00000000000000..afd9f7bdb32f7f --- /dev/null +++ b/phonelibs/android_system_core/include/system/graphics.h @@ -0,0 +1,763 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_CORE_INCLUDE_ANDROID_GRAPHICS_H +#define SYSTEM_CORE_INCLUDE_ANDROID_GRAPHICS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * If the HAL needs to create service threads to handle graphics related + * tasks, these threads need to run at HAL_PRIORITY_URGENT_DISPLAY priority + * if they can block the main rendering thread in any way. + * + * the priority of the current thread can be set with: + * + * #include + * setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); + * + */ + +#define HAL_PRIORITY_URGENT_DISPLAY (-8) + +/** + * pixel format definitions + */ + +enum { + /* + * "linear" color pixel formats: + * + * When used with ANativeWindow, the dataSpace field describes the color + * space of the buffer. + * + * The color space determines, for example, if the formats are linear or + * gamma-corrected; or whether any special operations are performed when + * reading or writing into a buffer in one of these formats. + */ + HAL_PIXEL_FORMAT_RGBA_8888 = 1, + HAL_PIXEL_FORMAT_RGBX_8888 = 2, + HAL_PIXEL_FORMAT_RGB_888 = 3, + HAL_PIXEL_FORMAT_RGB_565 = 4, + HAL_PIXEL_FORMAT_BGRA_8888 = 5, + + /* + * 0x100 - 0x1FF + * + * This range is reserved for pixel formats that are specific to the HAL + * implementation. Implementations can use any value in this range to + * communicate video pixel formats between their HAL modules. These formats + * must not have an alpha channel. Additionally, an EGLimage created from a + * gralloc buffer of one of these formats must be supported for use with the + * GL_OES_EGL_image_external OpenGL ES extension. + */ + + /* + * Android YUV format: + * + * This format is exposed outside of the HAL to software decoders and + * applications. EGLImageKHR must support it in conjunction with the + * OES_EGL_image_external extension. + * + * YV12 is a 4:2:0 YCrCb planar format comprised of a WxH Y plane followed + * by (W/2) x (H/2) Cr and Cb planes. + * + * This format assumes + * - an even width + * - an even height + * - a horizontal stride multiple of 16 pixels + * - a vertical stride equal to the height + * + * y_size = stride * height + * c_stride = ALIGN(stride/2, 16) + * c_size = c_stride * height/2 + * size = y_size + c_size * 2 + * cr_offset = y_size + * cb_offset = y_size + c_size + * + * When used with ANativeWindow, the dataSpace field describes the color + * space of the buffer. + */ + HAL_PIXEL_FORMAT_YV12 = 0x32315659, // YCrCb 4:2:0 Planar + + + /* + * Android Y8 format: + * + * This format is exposed outside of the HAL to the framework. + * The expected gralloc usage flags are SW_* and HW_CAMERA_*, + * and no other HW_ flags will be used. + * + * Y8 is a YUV planar format comprised of a WxH Y plane, + * with each pixel being represented by 8 bits. + * + * It is equivalent to just the Y plane from YV12. + * + * This format assumes + * - an even width + * - an even height + * - a horizontal stride multiple of 16 pixels + * - a vertical stride equal to the height + * + * size = stride * height + * + * When used with ANativeWindow, the dataSpace field describes the color + * space of the buffer. + */ + HAL_PIXEL_FORMAT_Y8 = 0x20203859, + + /* + * Android Y16 format: + * + * This format is exposed outside of the HAL to the framework. + * The expected gralloc usage flags are SW_* and HW_CAMERA_*, + * and no other HW_ flags will be used. + * + * Y16 is a YUV planar format comprised of a WxH Y plane, + * with each pixel being represented by 16 bits. + * + * It is just like Y8, but has double the bits per pixel (little endian). + * + * This format assumes + * - an even width + * - an even height + * - a horizontal stride multiple of 16 pixels + * - a vertical stride equal to the height + * - strides are specified in pixels, not in bytes + * + * size = stride * height * 2 + * + * When used with ANativeWindow, the dataSpace field describes the color + * space of the buffer, except that dataSpace field + * HAL_DATASPACE_DEPTH indicates that this buffer contains a depth + * image where each sample is a distance value measured by a depth camera, + * plus an associated confidence value. + */ + HAL_PIXEL_FORMAT_Y16 = 0x20363159, + + /* + * Android RAW sensor format: + * + * This format is exposed outside of the camera HAL to applications. + * + * RAW16 is a single-channel, 16-bit, little endian format, typically + * representing raw Bayer-pattern images from an image sensor, with minimal + * processing. + * + * The exact pixel layout of the data in the buffer is sensor-dependent, and + * needs to be queried from the camera device. + * + * Generally, not all 16 bits are used; more common values are 10 or 12 + * bits. If not all bits are used, the lower-order bits are filled first. + * All parameters to interpret the raw data (black and white points, + * color space, etc) must be queried from the camera device. + * + * This format assumes + * - an even width + * - an even height + * - a horizontal stride multiple of 16 pixels + * - a vertical stride equal to the height + * - strides are specified in pixels, not in bytes + * + * size = stride * height * 2 + * + * This format must be accepted by the gralloc module when used with the + * following usage flags: + * - GRALLOC_USAGE_HW_CAMERA_* + * - GRALLOC_USAGE_SW_* + * - GRALLOC_USAGE_RENDERSCRIPT + * + * When used with ANativeWindow, the dataSpace should be + * HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial + * extra metadata to define. + */ + HAL_PIXEL_FORMAT_RAW16 = 0x20, + + /* + * Android RAW10 format: + * + * This format is exposed outside of the camera HAL to applications. + * + * RAW10 is a single-channel, 10-bit per pixel, densely packed in each row, + * unprocessed format, usually representing raw Bayer-pattern images coming from + * an image sensor. + * + * In an image buffer with this format, starting from the first pixel of each + * row, each 4 consecutive pixels are packed into 5 bytes (40 bits). Each one + * of the first 4 bytes contains the top 8 bits of each pixel, The fifth byte + * contains the 2 least significant bits of the 4 pixels, the exact layout data + * for each 4 consecutive pixels is illustrated below (Pi[j] stands for the jth + * bit of the ith pixel): + * + * bit 7 bit 0 + * =====|=====|=====|=====|=====|=====|=====|=====| + * Byte 0: |P0[9]|P0[8]|P0[7]|P0[6]|P0[5]|P0[4]|P0[3]|P0[2]| + * |-----|-----|-----|-----|-----|-----|-----|-----| + * Byte 1: |P1[9]|P1[8]|P1[7]|P1[6]|P1[5]|P1[4]|P1[3]|P1[2]| + * |-----|-----|-----|-----|-----|-----|-----|-----| + * Byte 2: |P2[9]|P2[8]|P2[7]|P2[6]|P2[5]|P2[4]|P2[3]|P2[2]| + * |-----|-----|-----|-----|-----|-----|-----|-----| + * Byte 3: |P3[9]|P3[8]|P3[7]|P3[6]|P3[5]|P3[4]|P3[3]|P3[2]| + * |-----|-----|-----|-----|-----|-----|-----|-----| + * Byte 4: |P3[1]|P3[0]|P2[1]|P2[0]|P1[1]|P1[0]|P0[1]|P0[0]| + * =============================================== + * + * This format assumes + * - a width multiple of 4 pixels + * - an even height + * - a vertical stride equal to the height + * - strides are specified in bytes, not in pixels + * + * size = stride * height + * + * When stride is equal to width * (10 / 8), there will be no padding bytes at + * the end of each row, the entire image data is densely packed. When stride is + * larger than width * (10 / 8), padding bytes will be present at the end of each + * row (including the last row). + * + * This format must be accepted by the gralloc module when used with the + * following usage flags: + * - GRALLOC_USAGE_HW_CAMERA_* + * - GRALLOC_USAGE_SW_* + * - GRALLOC_USAGE_RENDERSCRIPT + * + * When used with ANativeWindow, the dataSpace field should be + * HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial + * extra metadata to define. + */ + HAL_PIXEL_FORMAT_RAW10 = 0x25, + + /* + * Android RAW12 format: + * + * This format is exposed outside of camera HAL to applications. + * + * RAW12 is a single-channel, 12-bit per pixel, densely packed in each row, + * unprocessed format, usually representing raw Bayer-pattern images coming from + * an image sensor. + * + * In an image buffer with this format, starting from the first pixel of each + * row, each two consecutive pixels are packed into 3 bytes (24 bits). The first + * and second byte contains the top 8 bits of first and second pixel. The third + * byte contains the 4 least significant bits of the two pixels, the exact layout + * data for each two consecutive pixels is illustrated below (Pi[j] stands for + * the jth bit of the ith pixel): + * + * bit 7 bit 0 + * ======|======|======|======|======|======|======|======| + * Byte 0: |P0[11]|P0[10]|P0[ 9]|P0[ 8]|P0[ 7]|P0[ 6]|P0[ 5]|P0[ 4]| + * |------|------|------|------|------|------|------|------| + * Byte 1: |P1[11]|P1[10]|P1[ 9]|P1[ 8]|P1[ 7]|P1[ 6]|P1[ 5]|P1[ 4]| + * |------|------|------|------|------|------|------|------| + * Byte 2: |P1[ 3]|P1[ 2]|P1[ 1]|P1[ 0]|P0[ 3]|P0[ 2]|P0[ 1]|P0[ 0]| + * ======================================================= + * + * This format assumes: + * - a width multiple of 4 pixels + * - an even height + * - a vertical stride equal to the height + * - strides are specified in bytes, not in pixels + * + * size = stride * height + * + * When stride is equal to width * (12 / 8), there will be no padding bytes at + * the end of each row, the entire image data is densely packed. When stride is + * larger than width * (12 / 8), padding bytes will be present at the end of + * each row (including the last row). + * + * This format must be accepted by the gralloc module when used with the + * following usage flags: + * - GRALLOC_USAGE_HW_CAMERA_* + * - GRALLOC_USAGE_SW_* + * - GRALLOC_USAGE_RENDERSCRIPT + * + * When used with ANativeWindow, the dataSpace field should be + * HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial + * extra metadata to define. + */ + HAL_PIXEL_FORMAT_RAW12 = 0x26, + + /* + * Android opaque RAW format: + * + * This format is exposed outside of the camera HAL to applications. + * + * RAW_OPAQUE is a format for unprocessed raw image buffers coming from an + * image sensor. The actual structure of buffers of this format is + * implementation-dependent. + * + * This format must be accepted by the gralloc module when used with the + * following usage flags: + * - GRALLOC_USAGE_HW_CAMERA_* + * - GRALLOC_USAGE_SW_* + * - GRALLOC_USAGE_RENDERSCRIPT + * + * When used with ANativeWindow, the dataSpace field should be + * HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial + * extra metadata to define. + */ + HAL_PIXEL_FORMAT_RAW_OPAQUE = 0x24, + + /* + * Android binary blob graphics buffer format: + * + * This format is used to carry task-specific data which does not have a + * standard image structure. The details of the format are left to the two + * endpoints. + * + * A typical use case is for transporting JPEG-compressed images from the + * Camera HAL to the framework or to applications. + * + * Buffers of this format must have a height of 1, and width equal to their + * size in bytes. + * + * When used with ANativeWindow, the mapping of the dataSpace field to + * buffer contents for BLOB is as follows: + * + * dataSpace value | Buffer contents + * -------------------------------+----------------------------------------- + * HAL_DATASPACE_JFIF | An encoded JPEG image + * HAL_DATASPACE_DEPTH | An android_depth_points buffer + * Other | Unsupported + * + */ + HAL_PIXEL_FORMAT_BLOB = 0x21, + + /* + * Android format indicating that the choice of format is entirely up to the + * device-specific Gralloc implementation. + * + * The Gralloc implementation should examine the usage bits passed in when + * allocating a buffer with this format, and it should derive the pixel + * format from those usage flags. This format will never be used with any + * of the GRALLOC_USAGE_SW_* usage flags. + * + * If a buffer of this format is to be used as an OpenGL ES texture, the + * framework will assume that sampling the texture will always return an + * alpha value of 1.0 (i.e. the buffer contains only opaque pixel values). + * + * When used with ANativeWindow, the dataSpace field describes the color + * space of the buffer. + */ + HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 0x22, + + /* + * Android flexible YCbCr 4:2:0 formats + * + * This format allows platforms to use an efficient YCbCr/YCrCb 4:2:0 + * buffer layout, while still describing the general format in a + * layout-independent manner. While called YCbCr, it can be + * used to describe formats with either chromatic ordering, as well as + * whole planar or semiplanar layouts. + * + * struct android_ycbcr (below) is the the struct used to describe it. + * + * This format must be accepted by the gralloc module when + * USAGE_SW_WRITE_* or USAGE_SW_READ_* are set. + * + * This format is locked for use by gralloc's (*lock_ycbcr) method, and + * locking with the (*lock) method will return an error. + * + * When used with ANativeWindow, the dataSpace field describes the color + * space of the buffer. + */ + HAL_PIXEL_FORMAT_YCbCr_420_888 = 0x23, + + /* + * Android flexible YCbCr 4:2:2 formats + * + * This format allows platforms to use an efficient YCbCr/YCrCb 4:2:2 + * buffer layout, while still describing the general format in a + * layout-independent manner. While called YCbCr, it can be + * used to describe formats with either chromatic ordering, as well as + * whole planar or semiplanar layouts. + * + * This format is currently only used by SW readable buffers + * produced by MediaCodecs, so the gralloc module can ignore this format. + */ + HAL_PIXEL_FORMAT_YCbCr_422_888 = 0x27, + + /* + * Android flexible YCbCr 4:4:4 formats + * + * This format allows platforms to use an efficient YCbCr/YCrCb 4:4:4 + * buffer layout, while still describing the general format in a + * layout-independent manner. While called YCbCr, it can be + * used to describe formats with either chromatic ordering, as well as + * whole planar or semiplanar layouts. + * + * This format is currently only used by SW readable buffers + * produced by MediaCodecs, so the gralloc module can ignore this format. + */ + HAL_PIXEL_FORMAT_YCbCr_444_888 = 0x28, + + /* + * Android flexible RGB 888 formats + * + * This format allows platforms to use an efficient RGB/BGR/RGBX/BGRX + * buffer layout, while still describing the general format in a + * layout-independent manner. While called RGB, it can be + * used to describe formats with either color ordering and optional + * padding, as well as whole planar layout. + * + * This format is currently only used by SW readable buffers + * produced by MediaCodecs, so the gralloc module can ignore this format. + */ + HAL_PIXEL_FORMAT_FLEX_RGB_888 = 0x29, + + /* + * Android flexible RGBA 8888 formats + * + * This format allows platforms to use an efficient RGBA/BGRA/ARGB/ABGR + * buffer layout, while still describing the general format in a + * layout-independent manner. While called RGBA, it can be + * used to describe formats with any of the component orderings, as + * well as whole planar layout. + * + * This format is currently only used by SW readable buffers + * produced by MediaCodecs, so the gralloc module can ignore this format. + */ + HAL_PIXEL_FORMAT_FLEX_RGBA_8888 = 0x2A, + + /* Legacy formats (deprecated), used by ImageFormat.java */ + HAL_PIXEL_FORMAT_YCbCr_422_SP = 0x10, // NV16 + HAL_PIXEL_FORMAT_YCrCb_420_SP = 0x11, // NV21 + HAL_PIXEL_FORMAT_YCbCr_422_I = 0x14, // YUY2 +}; + +/* + * Structure for describing YCbCr formats for consumption by applications. + * This is used with HAL_PIXEL_FORMAT_YCbCr_*_888. + * + * Buffer chroma subsampling is defined in the format. + * e.g. HAL_PIXEL_FORMAT_YCbCr_420_888 has subsampling 4:2:0. + * + * Buffers must have a 8 bit depth. + * + * @y, @cb, and @cr point to the first byte of their respective planes. + * + * Stride describes the distance in bytes from the first value of one row of + * the image to the first value of the next row. It includes the width of the + * image plus padding. + * @ystride is the stride of the luma plane. + * @cstride is the stride of the chroma planes. + * + * @chroma_step is the distance in bytes from one chroma pixel value to the + * next. This is 2 bytes for semiplanar (because chroma values are interleaved + * and each chroma value is one byte) and 1 for planar. + */ + +struct android_ycbcr { + void *y; + void *cb; + void *cr; + size_t ystride; + size_t cstride; + size_t chroma_step; + + /** reserved for future use, set to 0 by gralloc's (*lock_ycbcr)() */ + uint32_t reserved[8]; +}; + +/** + * Structure used to define depth point clouds for format HAL_PIXEL_FORMAT_BLOB + * with dataSpace value of HAL_DATASPACE_DEPTH. + * When locking a native buffer of the above format and dataSpace value, + * the vaddr pointer can be cast to this structure. + * + * A variable-length list of (x,y,z, confidence) 3D points, as floats. (x, y, + * z) represents a measured point's position, with the coordinate system defined + * by the data source. Confidence represents the estimated likelihood that this + * measurement is correct. It is between 0.f and 1.f, inclusive, with 1.f == + * 100% confidence. + * + * @num_points is the number of points in the list + * + * @xyz_points is the flexible array of floating-point values. + * It contains (num_points) * 4 floats. + * + * For example: + * android_depth_points d = get_depth_buffer(); + * struct { + * float x; float y; float z; float confidence; + * } firstPoint, lastPoint; + * + * firstPoint.x = d.xyzc_points[0]; + * firstPoint.y = d.xyzc_points[1]; + * firstPoint.z = d.xyzc_points[2]; + * firstPoint.confidence = d.xyzc_points[3]; + * lastPoint.x = d.xyzc_points[(d.num_points - 1) * 4 + 0]; + * lastPoint.y = d.xyzc_points[(d.num_points - 1) * 4 + 1]; + * lastPoint.z = d.xyzc_points[(d.num_points - 1) * 4 + 2]; + * lastPoint.confidence = d.xyzc_points[(d.num_points - 1) * 4 + 3]; + */ + +struct android_depth_points { + uint32_t num_points; + + /** reserved for future use, set to 0 by gralloc's (*lock)() */ + uint32_t reserved[8]; + + float xyzc_points[]; +}; + +/** + * Transformation definitions + * + * IMPORTANT NOTE: + * HAL_TRANSFORM_ROT_90 is applied CLOCKWISE and AFTER HAL_TRANSFORM_FLIP_{H|V}. + * + */ + +enum { + /* flip source image horizontally (around the vertical axis) */ + HAL_TRANSFORM_FLIP_H = 0x01, + /* flip source image vertically (around the horizontal axis)*/ + HAL_TRANSFORM_FLIP_V = 0x02, + /* rotate source image 90 degrees clockwise */ + HAL_TRANSFORM_ROT_90 = 0x04, + /* rotate source image 180 degrees */ + HAL_TRANSFORM_ROT_180 = 0x03, + /* rotate source image 270 degrees clockwise */ + HAL_TRANSFORM_ROT_270 = 0x07, + /* don't use. see system/window.h */ + HAL_TRANSFORM_RESERVED = 0x08, +}; + +/** + * Dataspace Definitions + * ====================== + * + * Dataspace is the definition of how pixel values should be interpreted. + * + * For many formats, this is the colorspace of the image data, which includes + * primaries (including white point) and the transfer characteristic function, + * which describes both gamma curve and numeric range (within the bit depth). + * + * Other dataspaces include depth measurement data from a depth camera. + */ + +typedef enum android_dataspace { + /* + * Default-assumption data space, when not explicitly specified. + * + * It is safest to assume the buffer is an image with sRGB primaries and + * encoding ranges, but the consumer and/or the producer of the data may + * simply be using defaults. No automatic gamma transform should be + * expected, except for a possible display gamma transform when drawn to a + * screen. + */ + HAL_DATASPACE_UNKNOWN = 0x0, + + /* + * Arbitrary dataspace with manually defined characteristics. Definition + * for colorspaces or other meaning must be communicated separately. + * + * This is used when specifying primaries, transfer characteristics, + * etc. separately. + * + * A typical use case is in video encoding parameters (e.g. for H.264), + * where a colorspace can have separately defined primaries, transfer + * characteristics, etc. + */ + HAL_DATASPACE_ARBITRARY = 0x1, + + /* + * RGB Colorspaces + * ----------------- + * + * Primaries are given using (x,y) coordinates in the CIE 1931 definition + * of x and y specified by ISO 11664-1. + * + * Transfer characteristics are the opto-electronic transfer characteristic + * at the source as a function of linear optical intensity (luminance). + */ + + /* + * sRGB linear encoding: + * + * The red, green, and blue components are stored in sRGB space, but + * are linear, not gamma-encoded. + * The RGB primaries and the white point are the same as BT.709. + * + * The values are encoded using the full range ([0,255] for 8-bit) for all + * components. + */ + HAL_DATASPACE_SRGB_LINEAR = 0x200, + + /* + * sRGB gamma encoding: + * + * The red, green and blue components are stored in sRGB space, and + * converted to linear space when read, using the standard sRGB to linear + * equation: + * + * Clinear = Csrgb / 12.92 for Csrgb <= 0.04045 + * = (Csrgb + 0.055 / 1.055)^2.4 for Csrgb > 0.04045 + * + * When written the inverse transformation is performed: + * + * Csrgb = 12.92 * Clinear for Clinear <= 0.0031308 + * = 1.055 * Clinear^(1/2.4) - 0.055 for Clinear > 0.0031308 + * + * + * The alpha component, if present, is always stored in linear space and + * is left unmodified when read or written. + * + * The RGB primaries and the white point are the same as BT.709. + * + * The values are encoded using the full range ([0,255] for 8-bit) for all + * components. + * + */ + HAL_DATASPACE_SRGB = 0x201, + + /* + * YCbCr Colorspaces + * ----------------- + * + * Primaries are given using (x,y) coordinates in the CIE 1931 definition + * of x and y specified by ISO 11664-1. + * + * Transfer characteristics are the opto-electronic transfer characteristic + * at the source as a function of linear optical intensity (luminance). + */ + + /* + * JPEG File Interchange Format (JFIF) + * + * Same model as BT.601-625, but all values (Y, Cb, Cr) range from 0 to 255 + * + * Transfer characteristic curve: + * E = 1.099 * L ^ 0.45 - 0.099, 1.00 >= L >= 0.018 + * E = 4.500 L, 0.018 > L >= 0 + * L - luminance of image 0 <= L <= 1 for conventional colorimetry + * E - corresponding electrical signal + * + * Primaries: x y + * green 0.290 0.600 + * blue 0.150 0.060 + * red 0.640 0.330 + * white (D65) 0.3127 0.3290 + */ + HAL_DATASPACE_JFIF = 0x101, + + /* + * ITU-R Recommendation 601 (BT.601) - 625-line + * + * Standard-definition television, 625 Lines (PAL) + * + * For 8-bit-depth formats: + * Luma (Y) samples should range from 16 to 235, inclusive + * Chroma (Cb, Cr) samples should range from 16 to 240, inclusive + * + * For 10-bit-depth formats: + * Luma (Y) samples should range from 64 to 940, inclusive + * Chroma (Cb, Cr) samples should range from 64 to 960, inclusive + * + * Transfer characteristic curve: + * E = 1.099 * L ^ 0.45 - 0.099, 1.00 >= L >= 0.018 + * E = 4.500 L, 0.018 > L >= 0 + * L - luminance of image 0 <= L <= 1 for conventional colorimetry + * E - corresponding electrical signal + * + * Primaries: x y + * green 0.290 0.600 + * blue 0.150 0.060 + * red 0.640 0.330 + * white (D65) 0.3127 0.3290 + */ + HAL_DATASPACE_BT601_625 = 0x102, + + /* + * ITU-R Recommendation 601 (BT.601) - 525-line + * + * Standard-definition television, 525 Lines (NTSC) + * + * For 8-bit-depth formats: + * Luma (Y) samples should range from 16 to 235, inclusive + * Chroma (Cb, Cr) samples should range from 16 to 240, inclusive + * + * For 10-bit-depth formats: + * Luma (Y) samples should range from 64 to 940, inclusive + * Chroma (Cb, Cr) samples should range from 64 to 960, inclusive + * + * Transfer characteristic curve: + * E = 1.099 * L ^ 0.45 - 0.099, 1.00 >= L >= 0.018 + * E = 4.500 L, 0.018 > L >= 0 + * L - luminance of image 0 <= L <= 1 for conventional colorimetry + * E - corresponding electrical signal + * + * Primaries: x y + * green 0.310 0.595 + * blue 0.155 0.070 + * red 0.630 0.340 + * white (D65) 0.3127 0.3290 + */ + HAL_DATASPACE_BT601_525 = 0x103, + + /* + * ITU-R Recommendation 709 (BT.709) + * + * High-definition television + * + * For 8-bit-depth formats: + * Luma (Y) samples should range from 16 to 235, inclusive + * Chroma (Cb, Cr) samples should range from 16 to 240, inclusive + * + * For 10-bit-depth formats: + * Luma (Y) samples should range from 64 to 940, inclusive + * Chroma (Cb, Cr) samples should range from 64 to 960, inclusive + * + * Primaries: x y + * green 0.300 0.600 + * blue 0.150 0.060 + * red 0.640 0.330 + * white (D65) 0.3127 0.3290 + */ + HAL_DATASPACE_BT709 = 0x104, + + /* + * The buffer contains depth ranging measurements from a depth camera. + * This value is valid with formats: + * HAL_PIXEL_FORMAT_Y16: 16-bit samples, consisting of a depth measurement + * and an associated confidence value. The 3 MSBs of the sample make + * up the confidence value, and the low 13 LSBs of the sample make up + * the depth measurement. + * For the confidence section, 0 means 100% confidence, 1 means 0% + * confidence. The mapping to a linear float confidence value between + * 0.f and 1.f can be obtained with + * float confidence = (((depthSample >> 13) - 1) & 0x7) / 7.0f; + * The depth measurement can be extracted simply with + * uint16_t range = (depthSample & 0x1FFF); + * HAL_PIXEL_FORMAT_BLOB: A depth point cloud, as + * a variable-length float (x,y,z, confidence) coordinate point list. + * The point cloud will be represented with the android_depth_points + * structure. + */ + HAL_DATASPACE_DEPTH = 0x1000 + +} android_dataspace_t; + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_CORE_INCLUDE_ANDROID_GRAPHICS_H */ diff --git a/phonelibs/android_system_core/include/system/radio.h b/phonelibs/android_system_core/include/system/radio.h new file mode 100644 index 00000000000000..a088526046ed1c --- /dev/null +++ b/phonelibs/android_system_core/include/system/radio.h @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_RADIO_H +#define ANDROID_RADIO_H + +#include +#include +#include +#include +#include + + +#define RADIO_NUM_BANDS_MAX 16 +#define RADIO_NUM_SPACINGS_MAX 16 +#define RADIO_STRING_LEN_MAX 128 + +/* + * Radio hardware module class. A given radio hardware module HAL is of one class + * only. The platform can not have more than one hardware module of each class. + * Current version of the framework only supports RADIO_CLASS_AM_FM. + */ +typedef enum { + RADIO_CLASS_AM_FM = 0, /* FM (including HD radio) and AM */ + RADIO_CLASS_SAT = 1, /* Satellite Radio */ + RADIO_CLASS_DT = 2, /* Digital Radio (DAB) */ +} radio_class_t; + +/* value for field "type" of radio band described in struct radio_hal_band_config */ +typedef enum { + RADIO_BAND_AM = 0, /* Amplitude Modulation band: LW, MW, SW */ + RADIO_BAND_FM = 1, /* Frequency Modulation band: FM */ + RADIO_BAND_FM_HD = 2, /* FM HD Radio / DRM (IBOC) */ + RADIO_BAND_AM_HD = 3, /* AM HD Radio / DRM (IBOC) */ +} radio_band_t; + +/* RDS variant implemented. A struct radio_hal_fm_band_config can list none or several. */ +enum { + RADIO_RDS_NONE = 0x0, + RADIO_RDS_WORLD = 0x01, + RADIO_RDS_US = 0x02, +}; +typedef unsigned int radio_rds_t; + +/* FM deemphasis variant implemented. A struct radio_hal_fm_band_config can list one or more. */ +enum { + RADIO_DEEMPHASIS_50 = 0x1, + RADIO_DEEMPHASIS_75 = 0x2, +}; +typedef unsigned int radio_deemphasis_t; + +/* Region a particular radio band configuration corresponds to. Not used at the HAL. + * Derived by the framework when converting the band descriptors retrieved from the HAL to + * individual band descriptors for each supported region. */ +typedef enum { + RADIO_REGION_NONE = -1, + RADIO_REGION_ITU_1 = 0, + RADIO_REGION_ITU_2 = 1, + RADIO_REGION_OIRT = 2, + RADIO_REGION_JAPAN = 3, + RADIO_REGION_KOREA = 4, +} radio_region_t; + +/* scanning direction for scan() and step() tuner APIs */ +typedef enum { + RADIO_DIRECTION_UP, + RADIO_DIRECTION_DOWN +} radio_direction_t; + +/* unique handle allocated to a radio module */ +typedef unsigned int radio_handle_t; + +/* Opaque meta data structure used by radio meta data API (see system/radio_metadata.h) */ +typedef struct radio_medtadata radio_metadata_t; + + +/* Additional attributes for an FM band configuration */ +typedef struct radio_hal_fm_band_config { + radio_deemphasis_t deemphasis; /* deemphasis variant */ + bool stereo; /* stereo supported */ + radio_rds_t rds; /* RDS variants supported */ + bool ta; /* Traffic Announcement supported */ + bool af; /* Alternate Frequency supported */ +} radio_hal_fm_band_config_t; + +/* Additional attributes for an AM band configuration */ +typedef struct radio_hal_am_band_config { + bool stereo; /* stereo supported */ +} radio_hal_am_band_config_t; + +/* Radio band configuration. Describes a given band supported by the radio module. + * The HAL can expose only one band per type with the the maximum range supported and all options. + * THe framework will derive the actual regions were this module can operate and expose separate + * band configurations for applications to chose from. */ +typedef struct radio_hal_band_config { + radio_band_t type; + bool antenna_connected; + unsigned int lower_limit; + unsigned int upper_limit; + unsigned int num_spacings; + unsigned int spacings[RADIO_NUM_SPACINGS_MAX]; + union { + radio_hal_fm_band_config_t fm; + radio_hal_am_band_config_t am; + }; +} radio_hal_band_config_t; + +/* Used internally by the framework to represent a band for s specific region */ +typedef struct radio_band_config { + radio_region_t region; + radio_hal_band_config_t band; +} radio_band_config_t; + + +/* Exposes properties of a given hardware radio module. + * NOTE: current framework implementation supports only one audio source (num_audio_sources = 1). + * The source corresponds to AUDIO_DEVICE_IN_FM_TUNER. + * If more than one tuner is supported (num_tuners > 1), only one can be connected to the audio + * source. */ +typedef struct radio_hal_properties { + radio_class_t class_id; /* Class of this module. E.g RADIO_CLASS_AM_FM */ + char implementor[RADIO_STRING_LEN_MAX]; /* implementor name */ + char product[RADIO_STRING_LEN_MAX]; /* product name */ + char version[RADIO_STRING_LEN_MAX]; /* product version */ + char serial[RADIO_STRING_LEN_MAX]; /* serial number (for subscription services) */ + unsigned int num_tuners; /* number of tuners controllable independently */ + unsigned int num_audio_sources; /* number of audio sources driven simultaneously */ + bool supports_capture; /* the hardware supports capture of audio source audio HAL */ + unsigned int num_bands; /* number of band descriptors */ + radio_hal_band_config_t bands[RADIO_NUM_BANDS_MAX]; /* band descriptors */ +} radio_hal_properties_t; + +/* Used internally by the framework. Same information as in struct radio_hal_properties plus a + * unique handle and one band configuration per region. */ +typedef struct radio_properties { + radio_handle_t handle; + radio_class_t class_id; + char implementor[RADIO_STRING_LEN_MAX]; + char product[RADIO_STRING_LEN_MAX]; + char version[RADIO_STRING_LEN_MAX]; + char serial[RADIO_STRING_LEN_MAX]; + unsigned int num_tuners; + unsigned int num_audio_sources; + bool supports_capture; + unsigned int num_bands; + radio_band_config_t bands[RADIO_NUM_BANDS_MAX]; +} radio_properties_t; + +/* Radio program information. Returned by the HAL with event RADIO_EVENT_TUNED. + * Contains information on currently tuned channel. + */ +typedef struct radio_program_info { + unsigned int channel; /* current channel. (e.g kHz for band type RADIO_BAND_FM) */ + unsigned int sub_channel; /* current sub channel. (used for RADIO_BAND_FM_HD) */ + bool tuned; /* tuned to a program or not */ + bool stereo; /* program is stereo or not */ + bool digital; /* digital program or not (e.g HD Radio program) */ + unsigned int signal_strength; /* signal strength from 0 to 100 */ + radio_metadata_t *metadata; /* non null if meta data are present (e.g PTY, song title ...) */ +} radio_program_info_t; + + +/* Events sent to the framework via the HAL callback. An event can notify the completion of an + * asynchronous command (configuration, tune, scan ...) or a spontaneous change (antenna connection, + * failure, AF switching, meta data reception... */ +enum { + RADIO_EVENT_HW_FAILURE = 0, /* hardware module failure. Requires reopening the tuner */ + RADIO_EVENT_CONFIG = 1, /* configuration change completed */ + RADIO_EVENT_ANTENNA = 2, /* Antenna connected, disconnected */ + RADIO_EVENT_TUNED = 3, /* tune, step, scan completed */ + RADIO_EVENT_METADATA = 4, /* New meta data received */ + RADIO_EVENT_TA = 5, /* Traffic announcement start or stop */ + RADIO_EVENT_AF_SWITCH = 6, /* Switch to Alternate Frequency */ + // begin framework only events + RADIO_EVENT_CONTROL = 100, /* loss/gain of tuner control */ + RADIO_EVENT_SERVER_DIED = 101, /* radio service died */ +}; +typedef unsigned int radio_event_type_t; + +/* Event passed to the framework by the HAL callback */ +typedef struct radio_hal_event { + radio_event_type_t type; /* event type */ + int status; /* used by RADIO_EVENT_CONFIG, RADIO_EVENT_TUNED */ + union { + bool on; /* RADIO_EVENT_ANTENNA, RADIO_EVENT_TA */ + radio_hal_band_config_t config; /* RADIO_EVENT_CONFIG */ + radio_program_info_t info; /* RADIO_EVENT_TUNED, RADIO_EVENT_AF_SWITCH */ + radio_metadata_t *metadata; /* RADIO_EVENT_METADATA */ + }; +} radio_hal_event_t; + +/* Used internally by the framework. Same information as in struct radio_hal_event */ +typedef struct radio_event { + radio_event_type_t type; + int status; + union { + bool on; + radio_band_config_t config; + radio_program_info_t info; + radio_metadata_t *metadata; /* offset from start of struct when in shared memory */ + }; +} radio_event_t; + + +static radio_rds_t radio_rds_for_region(bool rds, radio_region_t region) { + if (!rds) + return RADIO_RDS_NONE; + switch(region) { + case RADIO_REGION_ITU_1: + case RADIO_REGION_OIRT: + case RADIO_REGION_JAPAN: + case RADIO_REGION_KOREA: + return RADIO_RDS_WORLD; + case RADIO_REGION_ITU_2: + return RADIO_RDS_US; + default: + return RADIO_REGION_NONE; + } +} + +static radio_deemphasis_t radio_demephasis_for_region(radio_region_t region) { + switch(region) { + case RADIO_REGION_KOREA: + case RADIO_REGION_ITU_2: + return RADIO_DEEMPHASIS_75; + case RADIO_REGION_ITU_1: + case RADIO_REGION_OIRT: + case RADIO_REGION_JAPAN: + default: + return RADIO_DEEMPHASIS_50; + } +} + +#endif // ANDROID_RADIO_H diff --git a/phonelibs/android_system_core/include/system/thread_defs.h b/phonelibs/android_system_core/include/system/thread_defs.h new file mode 100644 index 00000000000000..377a48ce922f93 --- /dev/null +++ b/phonelibs/android_system_core/include/system/thread_defs.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_THREAD_DEFS_H +#define ANDROID_THREAD_DEFS_H + +#include "graphics.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +enum { + /* + * *********************************************** + * ** Keep in sync with android.os.Process.java ** + * *********************************************** + * + * This maps directly to the "nice" priorities we use in Android. + * A thread priority should be chosen inverse-proportionally to + * the amount of work the thread is expected to do. The more work + * a thread will do, the less favorable priority it should get so that + * it doesn't starve the system. Threads not behaving properly might + * be "punished" by the kernel. + * Use the levels below when appropriate. Intermediate values are + * acceptable, preferably use the {MORE|LESS}_FAVORABLE constants below. + */ + ANDROID_PRIORITY_LOWEST = 19, + + /* use for background tasks */ + ANDROID_PRIORITY_BACKGROUND = 10, + + /* most threads run at normal priority */ + ANDROID_PRIORITY_NORMAL = 0, + + /* threads currently running a UI that the user is interacting with */ + ANDROID_PRIORITY_FOREGROUND = -2, + + /* the main UI thread has a slightly more favorable priority */ + ANDROID_PRIORITY_DISPLAY = -4, + + /* ui service treads might want to run at a urgent display (uncommon) */ + ANDROID_PRIORITY_URGENT_DISPLAY = HAL_PRIORITY_URGENT_DISPLAY, + + /* all normal audio threads */ + ANDROID_PRIORITY_AUDIO = -16, + + /* service audio threads (uncommon) */ + ANDROID_PRIORITY_URGENT_AUDIO = -19, + + /* should never be used in practice. regular process might not + * be allowed to use this level */ + ANDROID_PRIORITY_HIGHEST = -20, + + ANDROID_PRIORITY_DEFAULT = ANDROID_PRIORITY_NORMAL, + ANDROID_PRIORITY_MORE_FAVORABLE = -1, + ANDROID_PRIORITY_LESS_FAVORABLE = +1, +}; + +#if defined(__cplusplus) +} +#endif + +#endif /* ANDROID_THREAD_DEFS_H */ diff --git a/phonelibs/android_system_core/include/system/window.h b/phonelibs/android_system_core/include/system/window.h new file mode 100644 index 00000000000000..508ce00bacecfb --- /dev/null +++ b/phonelibs/android_system_core/include/system/window.h @@ -0,0 +1,954 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H +#define SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __UNUSED +#define __UNUSED __attribute__((__unused__)) +#endif +#ifndef __deprecated +#define __deprecated __attribute__((__deprecated__)) +#endif + +__BEGIN_DECLS + +/*****************************************************************************/ + +#define ANDROID_NATIVE_MAKE_CONSTANT(a,b,c,d) \ + (((unsigned)(a)<<24)|((unsigned)(b)<<16)|((unsigned)(c)<<8)|(unsigned)(d)) + +#define ANDROID_NATIVE_WINDOW_MAGIC \ + ANDROID_NATIVE_MAKE_CONSTANT('_','w','n','d') + +#define ANDROID_NATIVE_BUFFER_MAGIC \ + ANDROID_NATIVE_MAKE_CONSTANT('_','b','f','r') + +// --------------------------------------------------------------------------- + +// This #define may be used to conditionally compile device-specific code to +// support either the prior ANativeWindow interface, which did not pass libsync +// fences around, or the new interface that does. This #define is only present +// when the ANativeWindow interface does include libsync support. +#define ANDROID_NATIVE_WINDOW_HAS_SYNC 1 + +// --------------------------------------------------------------------------- + +typedef const native_handle_t* buffer_handle_t; + +// --------------------------------------------------------------------------- + +typedef struct android_native_rect_t +{ + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; +} android_native_rect_t; + +// --------------------------------------------------------------------------- + +typedef struct android_native_base_t +{ + /* a magic value defined by the actual EGL native type */ + int magic; + + /* the sizeof() of the actual EGL native type */ + int version; + + void* reserved[4]; + + /* reference-counting interface */ + void (*incRef)(struct android_native_base_t* base); + void (*decRef)(struct android_native_base_t* base); +} android_native_base_t; + +typedef struct ANativeWindowBuffer +{ +#ifdef __cplusplus + ANativeWindowBuffer() { + common.magic = ANDROID_NATIVE_BUFFER_MAGIC; + common.version = sizeof(ANativeWindowBuffer); + memset(common.reserved, 0, sizeof(common.reserved)); + } + + // Implement the methods that sp expects so that it + // can be used to automatically refcount ANativeWindowBuffer's. + void incStrong(const void* /*id*/) const { + common.incRef(const_cast(&common)); + } + void decStrong(const void* /*id*/) const { + common.decRef(const_cast(&common)); + } +#endif + + struct android_native_base_t common; + + int width; + int height; + int stride; + int format; + int usage; + + void* reserved[2]; + + buffer_handle_t handle; + + void* reserved_proc[8]; +} ANativeWindowBuffer_t; + +// Old typedef for backwards compatibility. +typedef ANativeWindowBuffer_t android_native_buffer_t; + +// --------------------------------------------------------------------------- + +/* attributes queriable with query() */ +enum { + NATIVE_WINDOW_WIDTH = 0, + NATIVE_WINDOW_HEIGHT = 1, + NATIVE_WINDOW_FORMAT = 2, + + /* The minimum number of buffers that must remain un-dequeued after a buffer + * has been queued. This value applies only if set_buffer_count was used to + * override the number of buffers and if a buffer has since been queued. + * Users of the set_buffer_count ANativeWindow method should query this + * value before calling set_buffer_count. If it is necessary to have N + * buffers simultaneously dequeued as part of the steady-state operation, + * and this query returns M then N+M buffers should be requested via + * native_window_set_buffer_count. + * + * Note that this value does NOT apply until a single buffer has been + * queued. In particular this means that it is possible to: + * + * 1. Query M = min undequeued buffers + * 2. Set the buffer count to N + M + * 3. Dequeue all N + M buffers + * 4. Cancel M buffers + * 5. Queue, dequeue, queue, dequeue, ad infinitum + */ + NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS = 3, + + /* Check whether queueBuffer operations on the ANativeWindow send the buffer + * to the window compositor. The query sets the returned 'value' argument + * to 1 if the ANativeWindow DOES send queued buffers directly to the window + * compositor and 0 if the buffers do not go directly to the window + * compositor. + * + * This can be used to determine whether protected buffer content should be + * sent to the ANativeWindow. Note, however, that a result of 1 does NOT + * indicate that queued buffers will be protected from applications or users + * capturing their contents. If that behavior is desired then some other + * mechanism (e.g. the GRALLOC_USAGE_PROTECTED flag) should be used in + * conjunction with this query. + */ + NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER = 4, + + /* Get the concrete type of a ANativeWindow. See below for the list of + * possible return values. + * + * This query should not be used outside the Android framework and will + * likely be removed in the near future. + */ + NATIVE_WINDOW_CONCRETE_TYPE = 5, + + + /* + * Default width and height of ANativeWindow buffers, these are the + * dimensions of the window buffers irrespective of the + * NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS call and match the native window + * size unless overridden by NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS. + */ + NATIVE_WINDOW_DEFAULT_WIDTH = 6, + NATIVE_WINDOW_DEFAULT_HEIGHT = 7, + + /* + * transformation that will most-likely be applied to buffers. This is only + * a hint, the actual transformation applied might be different. + * + * INTENDED USE: + * + * The transform hint can be used by a producer, for instance the GLES + * driver, to pre-rotate the rendering such that the final transformation + * in the composer is identity. This can be very useful when used in + * conjunction with the h/w composer HAL, in situations where it + * cannot handle arbitrary rotations. + * + * 1. Before dequeuing a buffer, the GL driver (or any other ANW client) + * queries the ANW for NATIVE_WINDOW_TRANSFORM_HINT. + * + * 2. The GL driver overrides the width and height of the ANW to + * account for NATIVE_WINDOW_TRANSFORM_HINT. This is done by querying + * NATIVE_WINDOW_DEFAULT_{WIDTH | HEIGHT}, swapping the dimensions + * according to NATIVE_WINDOW_TRANSFORM_HINT and calling + * native_window_set_buffers_dimensions(). + * + * 3. The GL driver dequeues a buffer of the new pre-rotated size. + * + * 4. The GL driver renders to the buffer such that the image is + * already transformed, that is applying NATIVE_WINDOW_TRANSFORM_HINT + * to the rendering. + * + * 5. The GL driver calls native_window_set_transform to apply + * inverse transformation to the buffer it just rendered. + * In order to do this, the GL driver needs + * to calculate the inverse of NATIVE_WINDOW_TRANSFORM_HINT, this is + * done easily: + * + * int hintTransform, inverseTransform; + * query(..., NATIVE_WINDOW_TRANSFORM_HINT, &hintTransform); + * inverseTransform = hintTransform; + * if (hintTransform & HAL_TRANSFORM_ROT_90) + * inverseTransform ^= HAL_TRANSFORM_ROT_180; + * + * + * 6. The GL driver queues the pre-transformed buffer. + * + * 7. The composer combines the buffer transform with the display + * transform. If the buffer transform happens to cancel out the + * display transform then no rotation is needed. + * + */ + NATIVE_WINDOW_TRANSFORM_HINT = 8, + + /* + * Boolean that indicates whether the consumer is running more than + * one buffer behind the producer. + */ + NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND = 9, + + /* + * The consumer gralloc usage bits currently set by the consumer. + * The values are defined in hardware/libhardware/include/gralloc.h. + */ + NATIVE_WINDOW_CONSUMER_USAGE_BITS = 10, + + /** + * Transformation that will by applied to buffers by the hwcomposer. + * This must not be set or checked by producer endpoints, and will + * disable the transform hint set in SurfaceFlinger (see + * NATIVE_WINDOW_TRANSFORM_HINT). + * + * INTENDED USE: + * Temporary - Please do not use this. This is intended only to be used + * by the camera's LEGACY mode. + * + * In situations where a SurfaceFlinger client wishes to set a transform + * that is not visible to the producer, and will always be applied in the + * hardware composer, the client can set this flag with + * native_window_set_buffers_sticky_transform. This can be used to rotate + * and flip buffers consumed by hardware composer without actually changing + * the aspect ratio of the buffers produced. + */ + NATIVE_WINDOW_STICKY_TRANSFORM = 11, + + /** + * The default data space for the buffers as set by the consumer. + * The values are defined in graphics.h. + */ + NATIVE_WINDOW_DEFAULT_DATASPACE = 12, + + /* + * Returns the age of the contents of the most recently dequeued buffer as + * the number of frames that have elapsed since it was last queued. For + * example, if the window is double-buffered, the age of any given buffer in + * steady state will be 2. If the dequeued buffer has never been queued, its + * age will be 0. + */ + NATIVE_WINDOW_BUFFER_AGE = 13, +}; + +/* Valid operations for the (*perform)() hook. + * + * Values marked as 'deprecated' are supported, but have been superceded by + * other functionality. + * + * Values marked as 'private' should be considered private to the framework. + * HAL implementation code with access to an ANativeWindow should not use these, + * as it may not interact properly with the framework's use of the + * ANativeWindow. + */ +enum { + NATIVE_WINDOW_SET_USAGE = 0, + NATIVE_WINDOW_CONNECT = 1, /* deprecated */ + NATIVE_WINDOW_DISCONNECT = 2, /* deprecated */ + NATIVE_WINDOW_SET_CROP = 3, /* private */ + NATIVE_WINDOW_SET_BUFFER_COUNT = 4, + NATIVE_WINDOW_SET_BUFFERS_GEOMETRY = 5, /* deprecated */ + NATIVE_WINDOW_SET_BUFFERS_TRANSFORM = 6, + NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP = 7, + NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS = 8, + NATIVE_WINDOW_SET_BUFFERS_FORMAT = 9, + NATIVE_WINDOW_SET_SCALING_MODE = 10, /* private */ + NATIVE_WINDOW_LOCK = 11, /* private */ + NATIVE_WINDOW_UNLOCK_AND_POST = 12, /* private */ + NATIVE_WINDOW_API_CONNECT = 13, /* private */ + NATIVE_WINDOW_API_DISCONNECT = 14, /* private */ + NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS = 15, /* private */ + NATIVE_WINDOW_SET_POST_TRANSFORM_CROP = 16, /* private */ + NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM = 17,/* private */ + NATIVE_WINDOW_SET_SIDEBAND_STREAM = 18, + NATIVE_WINDOW_SET_BUFFERS_DATASPACE = 19, + NATIVE_WINDOW_SET_SURFACE_DAMAGE = 20, /* private */ +}; + +/* parameter for NATIVE_WINDOW_[API_][DIS]CONNECT */ +enum { + /* Buffers will be queued by EGL via eglSwapBuffers after being filled using + * OpenGL ES. + */ + NATIVE_WINDOW_API_EGL = 1, + + /* Buffers will be queued after being filled using the CPU + */ + NATIVE_WINDOW_API_CPU = 2, + + /* Buffers will be queued by Stagefright after being filled by a video + * decoder. The video decoder can either be a software or hardware decoder. + */ + NATIVE_WINDOW_API_MEDIA = 3, + + /* Buffers will be queued by the the camera HAL. + */ + NATIVE_WINDOW_API_CAMERA = 4, +}; + +/* parameter for NATIVE_WINDOW_SET_BUFFERS_TRANSFORM */ +enum { + /* flip source image horizontally */ + NATIVE_WINDOW_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H , + /* flip source image vertically */ + NATIVE_WINDOW_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V, + /* rotate source image 90 degrees clock-wise, and is applied after TRANSFORM_FLIP_{H|V} */ + NATIVE_WINDOW_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90, + /* rotate source image 180 degrees */ + NATIVE_WINDOW_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180, + /* rotate source image 270 degrees clock-wise */ + NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270, + /* transforms source by the inverse transform of the screen it is displayed onto. This + * transform is applied last */ + NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY = 0x08 +}; + +/* parameter for NATIVE_WINDOW_SET_SCALING_MODE */ +enum { + /* the window content is not updated (frozen) until a buffer of + * the window size is received (enqueued) + */ + NATIVE_WINDOW_SCALING_MODE_FREEZE = 0, + /* the buffer is scaled in both dimensions to match the window size */ + NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW = 1, + /* the buffer is scaled uniformly such that the smaller dimension + * of the buffer matches the window size (cropping in the process) + */ + NATIVE_WINDOW_SCALING_MODE_SCALE_CROP = 2, + /* the window is clipped to the size of the buffer's crop rectangle; pixels + * outside the crop rectangle are treated as if they are completely + * transparent. + */ + NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP = 3, +}; + +/* values returned by the NATIVE_WINDOW_CONCRETE_TYPE query */ +enum { + NATIVE_WINDOW_FRAMEBUFFER = 0, /* FramebufferNativeWindow */ + NATIVE_WINDOW_SURFACE = 1, /* Surface */ +}; + +/* parameter for NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP + * + * Special timestamp value to indicate that timestamps should be auto-generated + * by the native window when queueBuffer is called. This is equal to INT64_MIN, + * defined directly to avoid problems with C99/C++ inclusion of stdint.h. + */ +static const int64_t NATIVE_WINDOW_TIMESTAMP_AUTO = (-9223372036854775807LL-1); + +struct ANativeWindow +{ +#ifdef __cplusplus + ANativeWindow() + : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0) + { + common.magic = ANDROID_NATIVE_WINDOW_MAGIC; + common.version = sizeof(ANativeWindow); + memset(common.reserved, 0, sizeof(common.reserved)); + } + + /* Implement the methods that sp expects so that it + can be used to automatically refcount ANativeWindow's. */ + void incStrong(const void* /*id*/) const { + common.incRef(const_cast(&common)); + } + void decStrong(const void* /*id*/) const { + common.decRef(const_cast(&common)); + } +#endif + + struct android_native_base_t common; + + /* flags describing some attributes of this surface or its updater */ + const uint32_t flags; + + /* min swap interval supported by this updated */ + const int minSwapInterval; + + /* max swap interval supported by this updated */ + const int maxSwapInterval; + + /* horizontal and vertical resolution in DPI */ + const float xdpi; + const float ydpi; + + /* Some storage reserved for the OEM's driver. */ + intptr_t oem[4]; + + /* + * Set the swap interval for this surface. + * + * Returns 0 on success or -errno on error. + */ + int (*setSwapInterval)(struct ANativeWindow* window, + int interval); + + /* + * Hook called by EGL to acquire a buffer. After this call, the buffer + * is not locked, so its content cannot be modified. This call may block if + * no buffers are available. + * + * The window holds a reference to the buffer between dequeueBuffer and + * either queueBuffer or cancelBuffer, so clients only need their own + * reference if they might use the buffer after queueing or canceling it. + * Holding a reference to a buffer after queueing or canceling it is only + * allowed if a specific buffer count has been set. + * + * Returns 0 on success or -errno on error. + * + * XXX: This function is deprecated. It will continue to work for some + * time for binary compatibility, but the new dequeueBuffer function that + * outputs a fence file descriptor should be used in its place. + */ + int (*dequeueBuffer_DEPRECATED)(struct ANativeWindow* window, + struct ANativeWindowBuffer** buffer); + + /* + * hook called by EGL to lock a buffer. This MUST be called before modifying + * the content of a buffer. The buffer must have been acquired with + * dequeueBuffer first. + * + * Returns 0 on success or -errno on error. + * + * XXX: This function is deprecated. It will continue to work for some + * time for binary compatibility, but it is essentially a no-op, and calls + * to it should be removed. + */ + int (*lockBuffer_DEPRECATED)(struct ANativeWindow* window, + struct ANativeWindowBuffer* buffer); + + /* + * Hook called by EGL when modifications to the render buffer are done. + * This unlocks and post the buffer. + * + * The window holds a reference to the buffer between dequeueBuffer and + * either queueBuffer or cancelBuffer, so clients only need their own + * reference if they might use the buffer after queueing or canceling it. + * Holding a reference to a buffer after queueing or canceling it is only + * allowed if a specific buffer count has been set. + * + * Buffers MUST be queued in the same order than they were dequeued. + * + * Returns 0 on success or -errno on error. + * + * XXX: This function is deprecated. It will continue to work for some + * time for binary compatibility, but the new queueBuffer function that + * takes a fence file descriptor should be used in its place (pass a value + * of -1 for the fence file descriptor if there is no valid one to pass). + */ + int (*queueBuffer_DEPRECATED)(struct ANativeWindow* window, + struct ANativeWindowBuffer* buffer); + + /* + * hook used to retrieve information about the native window. + * + * Returns 0 on success or -errno on error. + */ + int (*query)(const struct ANativeWindow* window, + int what, int* value); + + /* + * hook used to perform various operations on the surface. + * (*perform)() is a generic mechanism to add functionality to + * ANativeWindow while keeping backward binary compatibility. + * + * DO NOT CALL THIS HOOK DIRECTLY. Instead, use the helper functions + * defined below. + * + * (*perform)() returns -ENOENT if the 'what' parameter is not supported + * by the surface's implementation. + * + * See above for a list of valid operations, such as + * NATIVE_WINDOW_SET_USAGE or NATIVE_WINDOW_CONNECT + */ + int (*perform)(struct ANativeWindow* window, + int operation, ... ); + + /* + * Hook used to cancel a buffer that has been dequeued. + * No synchronization is performed between dequeue() and cancel(), so + * either external synchronization is needed, or these functions must be + * called from the same thread. + * + * The window holds a reference to the buffer between dequeueBuffer and + * either queueBuffer or cancelBuffer, so clients only need their own + * reference if they might use the buffer after queueing or canceling it. + * Holding a reference to a buffer after queueing or canceling it is only + * allowed if a specific buffer count has been set. + * + * XXX: This function is deprecated. It will continue to work for some + * time for binary compatibility, but the new cancelBuffer function that + * takes a fence file descriptor should be used in its place (pass a value + * of -1 for the fence file descriptor if there is no valid one to pass). + */ + int (*cancelBuffer_DEPRECATED)(struct ANativeWindow* window, + struct ANativeWindowBuffer* buffer); + + /* + * Hook called by EGL to acquire a buffer. This call may block if no + * buffers are available. + * + * The window holds a reference to the buffer between dequeueBuffer and + * either queueBuffer or cancelBuffer, so clients only need their own + * reference if they might use the buffer after queueing or canceling it. + * Holding a reference to a buffer after queueing or canceling it is only + * allowed if a specific buffer count has been set. + * + * The libsync fence file descriptor returned in the int pointed to by the + * fenceFd argument will refer to the fence that must signal before the + * dequeued buffer may be written to. A value of -1 indicates that the + * caller may access the buffer immediately without waiting on a fence. If + * a valid file descriptor is returned (i.e. any value except -1) then the + * caller is responsible for closing the file descriptor. + * + * Returns 0 on success or -errno on error. + */ + int (*dequeueBuffer)(struct ANativeWindow* window, + struct ANativeWindowBuffer** buffer, int* fenceFd); + + /* + * Hook called by EGL when modifications to the render buffer are done. + * This unlocks and post the buffer. + * + * The window holds a reference to the buffer between dequeueBuffer and + * either queueBuffer or cancelBuffer, so clients only need their own + * reference if they might use the buffer after queueing or canceling it. + * Holding a reference to a buffer after queueing or canceling it is only + * allowed if a specific buffer count has been set. + * + * The fenceFd argument specifies a libsync fence file descriptor for a + * fence that must signal before the buffer can be accessed. If the buffer + * can be accessed immediately then a value of -1 should be used. The + * caller must not use the file descriptor after it is passed to + * queueBuffer, and the ANativeWindow implementation is responsible for + * closing it. + * + * Returns 0 on success or -errno on error. + */ + int (*queueBuffer)(struct ANativeWindow* window, + struct ANativeWindowBuffer* buffer, int fenceFd); + + /* + * Hook used to cancel a buffer that has been dequeued. + * No synchronization is performed between dequeue() and cancel(), so + * either external synchronization is needed, or these functions must be + * called from the same thread. + * + * The window holds a reference to the buffer between dequeueBuffer and + * either queueBuffer or cancelBuffer, so clients only need their own + * reference if they might use the buffer after queueing or canceling it. + * Holding a reference to a buffer after queueing or canceling it is only + * allowed if a specific buffer count has been set. + * + * The fenceFd argument specifies a libsync fence file decsriptor for a + * fence that must signal before the buffer can be accessed. If the buffer + * can be accessed immediately then a value of -1 should be used. + * + * Note that if the client has not waited on the fence that was returned + * from dequeueBuffer, that same fence should be passed to cancelBuffer to + * ensure that future uses of the buffer are preceded by a wait on that + * fence. The caller must not use the file descriptor after it is passed + * to cancelBuffer, and the ANativeWindow implementation is responsible for + * closing it. + * + * Returns 0 on success or -errno on error. + */ + int (*cancelBuffer)(struct ANativeWindow* window, + struct ANativeWindowBuffer* buffer, int fenceFd); +}; + + /* Backwards compatibility: use ANativeWindow (struct ANativeWindow in C). + * android_native_window_t is deprecated. + */ +typedef struct ANativeWindow ANativeWindow; +typedef struct ANativeWindow android_native_window_t __deprecated; + +/* + * native_window_set_usage(..., usage) + * Sets the intended usage flags for the next buffers + * acquired with (*lockBuffer)() and on. + * By default (if this function is never called), a usage of + * GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE + * is assumed. + * Calling this function will usually cause following buffers to be + * reallocated. + */ + +static inline int native_window_set_usage( + struct ANativeWindow* window, int usage) +{ + return window->perform(window, NATIVE_WINDOW_SET_USAGE, usage); +} + +/* deprecated. Always returns 0. Don't call. */ +static inline int native_window_connect( + struct ANativeWindow* window __UNUSED, int api __UNUSED) __deprecated; + +static inline int native_window_connect( + struct ANativeWindow* window __UNUSED, int api __UNUSED) { + return 0; +} + +/* deprecated. Always returns 0. Don't call. */ +static inline int native_window_disconnect( + struct ANativeWindow* window __UNUSED, int api __UNUSED) __deprecated; + +static inline int native_window_disconnect( + struct ANativeWindow* window __UNUSED, int api __UNUSED) { + return 0; +} + +/* + * native_window_set_crop(..., crop) + * Sets which region of the next queued buffers needs to be considered. + * Depending on the scaling mode, a buffer's crop region is scaled and/or + * cropped to match the surface's size. This function sets the crop in + * pre-transformed buffer pixel coordinates. + * + * The specified crop region applies to all buffers queued after it is called. + * + * If 'crop' is NULL, subsequently queued buffers won't be cropped. + * + * An error is returned if for instance the crop region is invalid, out of the + * buffer's bound or if the window is invalid. + */ +static inline int native_window_set_crop( + struct ANativeWindow* window, + android_native_rect_t const * crop) +{ + return window->perform(window, NATIVE_WINDOW_SET_CROP, crop); +} + +/* + * native_window_set_post_transform_crop(..., crop) + * Sets which region of the next queued buffers needs to be considered. + * Depending on the scaling mode, a buffer's crop region is scaled and/or + * cropped to match the surface's size. This function sets the crop in + * post-transformed pixel coordinates. + * + * The specified crop region applies to all buffers queued after it is called. + * + * If 'crop' is NULL, subsequently queued buffers won't be cropped. + * + * An error is returned if for instance the crop region is invalid, out of the + * buffer's bound or if the window is invalid. + */ +static inline int native_window_set_post_transform_crop( + struct ANativeWindow* window, + android_native_rect_t const * crop) +{ + return window->perform(window, NATIVE_WINDOW_SET_POST_TRANSFORM_CROP, crop); +} + +/* + * native_window_set_active_rect(..., active_rect) + * + * This function is deprecated and will be removed soon. For now it simply + * sets the post-transform crop for compatibility while multi-project commits + * get checked. + */ +static inline int native_window_set_active_rect( + struct ANativeWindow* window, + android_native_rect_t const * active_rect) __deprecated; + +static inline int native_window_set_active_rect( + struct ANativeWindow* window, + android_native_rect_t const * active_rect) +{ + return native_window_set_post_transform_crop(window, active_rect); +} + +/* + * native_window_set_buffer_count(..., count) + * Sets the number of buffers associated with this native window. + */ +static inline int native_window_set_buffer_count( + struct ANativeWindow* window, + size_t bufferCount) +{ + return window->perform(window, NATIVE_WINDOW_SET_BUFFER_COUNT, bufferCount); +} + +/* + * native_window_set_buffers_geometry(..., int w, int h, int format) + * All buffers dequeued after this call will have the dimensions and format + * specified. A successful call to this function has the same effect as calling + * native_window_set_buffers_size and native_window_set_buffers_format. + * + * XXX: This function is deprecated. The native_window_set_buffers_dimensions + * and native_window_set_buffers_format functions should be used instead. + */ +static inline int native_window_set_buffers_geometry( + struct ANativeWindow* window, + int w, int h, int format) __deprecated; + +static inline int native_window_set_buffers_geometry( + struct ANativeWindow* window, + int w, int h, int format) +{ + return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY, + w, h, format); +} + +/* + * native_window_set_buffers_dimensions(..., int w, int h) + * All buffers dequeued after this call will have the dimensions specified. + * In particular, all buffers will have a fixed-size, independent from the + * native-window size. They will be scaled according to the scaling mode + * (see native_window_set_scaling_mode) upon window composition. + * + * If w and h are 0, the normal behavior is restored. That is, dequeued buffers + * following this call will be sized to match the window's size. + * + * Calling this function will reset the window crop to a NULL value, which + * disables cropping of the buffers. + */ +static inline int native_window_set_buffers_dimensions( + struct ANativeWindow* window, + int w, int h) +{ + return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS, + w, h); +} + +/* + * native_window_set_buffers_user_dimensions(..., int w, int h) + * + * Sets the user buffer size for the window, which overrides the + * window's size. All buffers dequeued after this call will have the + * dimensions specified unless overridden by + * native_window_set_buffers_dimensions. All buffers will have a + * fixed-size, independent from the native-window size. They will be + * scaled according to the scaling mode (see + * native_window_set_scaling_mode) upon window composition. + * + * If w and h are 0, the normal behavior is restored. That is, the + * default buffer size will match the windows's size. + * + * Calling this function will reset the window crop to a NULL value, which + * disables cropping of the buffers. + */ +static inline int native_window_set_buffers_user_dimensions( + struct ANativeWindow* window, + int w, int h) +{ + return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS, + w, h); +} + +/* + * native_window_set_buffers_format(..., int format) + * All buffers dequeued after this call will have the format specified. + * + * If the specified format is 0, the default buffer format will be used. + */ +static inline int native_window_set_buffers_format( + struct ANativeWindow* window, + int format) +{ + return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_FORMAT, format); +} + +/* + * native_window_set_buffers_data_space(..., int dataSpace) + * All buffers queued after this call will be associated with the dataSpace + * parameter specified. + * + * dataSpace specifies additional information about the buffer that's dependent + * on the buffer format and the endpoints. For example, it can be used to convey + * the color space of the image data in the buffer, or it can be used to + * indicate that the buffers contain depth measurement data instead of color + * images. The default dataSpace is 0, HAL_DATASPACE_UNKNOWN, unless it has been + * overridden by the consumer. + */ +static inline int native_window_set_buffers_data_space( + struct ANativeWindow* window, + android_dataspace_t dataSpace) +{ + return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_DATASPACE, + dataSpace); +} + +/* + * native_window_set_buffers_transform(..., int transform) + * All buffers queued after this call will be displayed transformed according + * to the transform parameter specified. + */ +static inline int native_window_set_buffers_transform( + struct ANativeWindow* window, + int transform) +{ + return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TRANSFORM, + transform); +} + +/* + * native_window_set_buffers_sticky_transform(..., int transform) + * All buffers queued after this call will be displayed transformed according + * to the transform parameter specified applied on top of the regular buffer + * transform. Setting this transform will disable the transform hint. + * + * Temporary - This is only intended to be used by the LEGACY camera mode, do + * not use this for anything else. + */ +static inline int native_window_set_buffers_sticky_transform( + struct ANativeWindow* window, + int transform) +{ + return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM, + transform); +} + +/* + * native_window_set_buffers_timestamp(..., int64_t timestamp) + * All buffers queued after this call will be associated with the timestamp + * parameter specified. If the timestamp is set to NATIVE_WINDOW_TIMESTAMP_AUTO + * (the default), timestamps will be generated automatically when queueBuffer is + * called. The timestamp is measured in nanoseconds, and is normally monotonically + * increasing. The timestamp should be unaffected by time-of-day adjustments, + * and for a camera should be strictly monotonic but for a media player may be + * reset when the position is set. + */ +static inline int native_window_set_buffers_timestamp( + struct ANativeWindow* window, + int64_t timestamp) +{ + return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP, + timestamp); +} + +/* + * native_window_set_scaling_mode(..., int mode) + * All buffers queued after this call will be associated with the scaling mode + * specified. + */ +static inline int native_window_set_scaling_mode( + struct ANativeWindow* window, + int mode) +{ + return window->perform(window, NATIVE_WINDOW_SET_SCALING_MODE, + mode); +} + +/* + * native_window_api_connect(..., int api) + * connects an API to this window. only one API can be connected at a time. + * Returns -EINVAL if for some reason the window cannot be connected, which + * can happen if it's connected to some other API. + */ +static inline int native_window_api_connect( + struct ANativeWindow* window, int api) +{ + return window->perform(window, NATIVE_WINDOW_API_CONNECT, api); +} + +/* + * native_window_api_disconnect(..., int api) + * disconnect the API from this window. + * An error is returned if for instance the window wasn't connected in the + * first place. + */ +static inline int native_window_api_disconnect( + struct ANativeWindow* window, int api) +{ + return window->perform(window, NATIVE_WINDOW_API_DISCONNECT, api); +} + +/* + * native_window_dequeue_buffer_and_wait(...) + * Dequeue a buffer and wait on the fence associated with that buffer. The + * buffer may safely be accessed immediately upon this function returning. An + * error is returned if either of the dequeue or the wait operations fail. + */ +static inline int native_window_dequeue_buffer_and_wait(ANativeWindow *anw, + struct ANativeWindowBuffer** anb) { + return anw->dequeueBuffer_DEPRECATED(anw, anb); +} + +/* + * native_window_set_sideband_stream(..., native_handle_t*) + * Attach a sideband buffer stream to a native window. + */ +static inline int native_window_set_sideband_stream( + struct ANativeWindow* window, + native_handle_t* sidebandHandle) +{ + return window->perform(window, NATIVE_WINDOW_SET_SIDEBAND_STREAM, + sidebandHandle); +} + +/* + * native_window_set_surface_damage(..., android_native_rect_t* rects, int numRects) + * Set the surface damage (i.e., the region of the surface that has changed + * since the previous frame). The damage set by this call will be reset (to the + * default of full-surface damage) after calling queue, so this must be called + * prior to every frame with damage that does not cover the whole surface if the + * caller desires downstream consumers to use this optimization. + * + * The damage region is specified as an array of rectangles, with the important + * caveat that the origin of the surface is considered to be the bottom-left + * corner, as in OpenGL ES. + * + * If numRects is set to 0, rects may be NULL, and the surface damage will be + * set to the full surface (the same as if this function had not been called for + * this frame). + */ +static inline int native_window_set_surface_damage( + struct ANativeWindow* window, + const android_native_rect_t* rects, size_t numRects) +{ + return window->perform(window, NATIVE_WINDOW_SET_SURFACE_DAMAGE, + rects, numRects); +} + +__END_DECLS + +#endif /* SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H */ diff --git a/phonelibs/android_system_core/include/utils/AndroidThreads.h b/phonelibs/android_system_core/include/utils/AndroidThreads.h new file mode 100644 index 00000000000000..aad1e82cb7e439 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/AndroidThreads.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_UTILS_ANDROID_THREADS_H +#define _LIBS_UTILS_ANDROID_THREADS_H + +#include +#include + +#if !defined(_WIN32) +# include +#endif + +#include + +// --------------------------------------------------------------------------- +// C API + +#ifdef __cplusplus +extern "C" { +#endif + +// Create and run a new thread. +extern int androidCreateThread(android_thread_func_t, void *); + +// Create thread with lots of parameters +extern int androidCreateThreadEtc(android_thread_func_t entryFunction, + void *userData, + const char* threadName, + int32_t threadPriority, + size_t threadStackSize, + android_thread_id_t *threadId); + +// Get some sort of unique identifier for the current thread. +extern android_thread_id_t androidGetThreadId(); + +// Low-level thread creation -- never creates threads that can +// interact with the Java VM. +extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction, + void *userData, + const char* threadName, + int32_t threadPriority, + size_t threadStackSize, + android_thread_id_t *threadId); + +// set the same of the running thread +extern void androidSetThreadName(const char* name); + +// Used by the Java Runtime to control how threads are created, so that +// they can be proper and lovely Java threads. +typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction, + void *userData, + const char* threadName, + int32_t threadPriority, + size_t threadStackSize, + android_thread_id_t *threadId); + +extern void androidSetCreateThreadFunc(android_create_thread_fn func); + +// ------------------------------------------------------------------ +// Extra functions working with raw pids. + +#ifdef HAVE_ANDROID_OS +// Change the priority AND scheduling group of a particular thread. The priority +// should be one of the ANDROID_PRIORITY constants. Returns INVALID_OPERATION +// if the priority set failed, else another value if just the group set failed; +// in either case errno is set. Thread ID zero means current thread. +extern int androidSetThreadPriority(pid_t tid, int prio); + +// Get the current priority of a particular thread. Returns one of the +// ANDROID_PRIORITY constants or a negative result in case of error. +extern int androidGetThreadPriority(pid_t tid); +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +// ---------------------------------------------------------------------------- +// C++ API +#ifdef __cplusplus +namespace android { +// ---------------------------------------------------------------------------- + +// Create and run a new thread. +inline bool createThread(thread_func_t f, void *a) { + return androidCreateThread(f, a) ? true : false; +} + +// Create thread with lots of parameters +inline bool createThreadEtc(thread_func_t entryFunction, + void *userData, + const char* threadName = "android:unnamed_thread", + int32_t threadPriority = PRIORITY_DEFAULT, + size_t threadStackSize = 0, + thread_id_t *threadId = 0) +{ + return androidCreateThreadEtc(entryFunction, userData, threadName, + threadPriority, threadStackSize, threadId) ? true : false; +} + +// Get some sort of unique identifier for the current thread. +inline thread_id_t getThreadId() { + return androidGetThreadId(); +} + +// ---------------------------------------------------------------------------- +}; // namespace android +#endif // __cplusplus +// ---------------------------------------------------------------------------- + +#endif // _LIBS_UTILS_ANDROID_THREADS_H diff --git a/phonelibs/android_system_core/include/utils/Atomic.h b/phonelibs/android_system_core/include/utils/Atomic.h new file mode 100644 index 00000000000000..7eb476c94e106f --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Atomic.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UTILS_ATOMIC_H +#define ANDROID_UTILS_ATOMIC_H + +#include + +#endif // ANDROID_UTILS_ATOMIC_H diff --git a/phonelibs/android_system_core/include/utils/BasicHashtable.h b/phonelibs/android_system_core/include/utils/BasicHashtable.h new file mode 100644 index 00000000000000..c235d625262651 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/BasicHashtable.h @@ -0,0 +1,402 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_BASIC_HASHTABLE_H +#define ANDROID_BASIC_HASHTABLE_H + +#include +#include +#include +#include + +namespace android { + +/* Implementation type. Nothing to see here. */ +class BasicHashtableImpl { +protected: + struct Bucket { + // The collision flag indicates that the bucket is part of a collision chain + // such that at least two entries both hash to this bucket. When true, we + // may need to seek further along the chain to find the entry. + static const uint32_t COLLISION = 0x80000000UL; + + // The present flag indicates that the bucket contains an initialized entry value. + static const uint32_t PRESENT = 0x40000000UL; + + // Mask for 30 bits worth of the hash code that are stored within the bucket to + // speed up lookups and rehashing by eliminating the need to recalculate the + // hash code of the entry's key. + static const uint32_t HASH_MASK = 0x3fffffffUL; + + // Combined value that stores the collision and present flags as well as + // a 30 bit hash code. + uint32_t cookie; + + // Storage for the entry begins here. + char entry[0]; + }; + + BasicHashtableImpl(size_t entrySize, bool hasTrivialDestructor, + size_t minimumInitialCapacity, float loadFactor); + BasicHashtableImpl(const BasicHashtableImpl& other); + virtual ~BasicHashtableImpl(); + + void dispose(); + + inline void edit() { + if (mBuckets && !SharedBuffer::bufferFromData(mBuckets)->onlyOwner()) { + clone(); + } + } + + void setTo(const BasicHashtableImpl& other); + void clear(); + + ssize_t next(ssize_t index) const; + ssize_t find(ssize_t index, hash_t hash, const void* __restrict__ key) const; + size_t add(hash_t hash, const void* __restrict__ entry); + void removeAt(size_t index); + void rehash(size_t minimumCapacity, float loadFactor); + + const size_t mBucketSize; // number of bytes per bucket including the entry + const bool mHasTrivialDestructor; // true if the entry type does not require destruction + size_t mCapacity; // number of buckets that can be filled before exceeding load factor + float mLoadFactor; // load factor + size_t mSize; // number of elements actually in the table + size_t mFilledBuckets; // number of buckets for which collision or present is true + size_t mBucketCount; // number of slots in the mBuckets array + void* mBuckets; // array of buckets, as a SharedBuffer + + inline const Bucket& bucketAt(const void* __restrict__ buckets, size_t index) const { + return *reinterpret_cast( + static_cast(buckets) + index * mBucketSize); + } + + inline Bucket& bucketAt(void* __restrict__ buckets, size_t index) const { + return *reinterpret_cast(static_cast(buckets) + index * mBucketSize); + } + + virtual bool compareBucketKey(const Bucket& bucket, const void* __restrict__ key) const = 0; + virtual void initializeBucketEntry(Bucket& bucket, const void* __restrict__ entry) const = 0; + virtual void destroyBucketEntry(Bucket& bucket) const = 0; + +private: + void clone(); + + // Allocates a bucket array as a SharedBuffer. + void* allocateBuckets(size_t count) const; + + // Releases a bucket array's associated SharedBuffer. + void releaseBuckets(void* __restrict__ buckets, size_t count) const; + + // Destroys the contents of buckets (invokes destroyBucketEntry for each + // populated bucket if needed). + void destroyBuckets(void* __restrict__ buckets, size_t count) const; + + // Copies the content of buckets (copies the cookie and invokes copyBucketEntry + // for each populated bucket if needed). + void copyBuckets(const void* __restrict__ fromBuckets, + void* __restrict__ toBuckets, size_t count) const; + + // Determines the appropriate size of a bucket array to store a certain minimum + // number of entries and returns its effective capacity. + static void determineCapacity(size_t minimumCapacity, float loadFactor, + size_t* __restrict__ outBucketCount, size_t* __restrict__ outCapacity); + + // Trim a hash code to 30 bits to match what we store in the bucket's cookie. + inline static hash_t trimHash(hash_t hash) { + return (hash & Bucket::HASH_MASK) ^ (hash >> 30); + } + + // Returns the index of the first bucket that is in the collision chain + // for the specified hash code, given the total number of buckets. + // (Primary hash) + inline static size_t chainStart(hash_t hash, size_t count) { + return hash % count; + } + + // Returns the increment to add to a bucket index to seek to the next bucket + // in the collision chain for the specified hash code, given the total number of buckets. + // (Secondary hash) + inline static size_t chainIncrement(hash_t hash, size_t count) { + return ((hash >> 7) | (hash << 25)) % (count - 1) + 1; + } + + // Returns the index of the next bucket that is in the collision chain + // that is defined by the specified increment, given the total number of buckets. + inline static size_t chainSeek(size_t index, size_t increment, size_t count) { + return (index + increment) % count; + } +}; + +/* + * A BasicHashtable stores entries that are indexed by hash code in place + * within an array. The basic operations are finding entries by key, + * adding new entries and removing existing entries. + * + * This class provides a very limited set of operations with simple semantics. + * It is intended to be used as a building block to construct more complex + * and interesting data structures such as HashMap. Think very hard before + * adding anything extra to BasicHashtable, it probably belongs at a + * higher level of abstraction. + * + * TKey: The key type. + * TEntry: The entry type which is what is actually stored in the array. + * + * TKey must support the following contract: + * bool operator==(const TKey& other) const; // return true if equal + * bool operator!=(const TKey& other) const; // return true if unequal + * + * TEntry must support the following contract: + * const TKey& getKey() const; // get the key from the entry + * + * This class supports storing entries with duplicate keys. Of course, it can't + * tell them apart during removal so only the first entry will be removed. + * We do this because it means that operations like add() can't fail. + */ +template +class BasicHashtable : private BasicHashtableImpl { +public: + /* Creates a hashtable with the specified minimum initial capacity. + * The underlying array will be created when the first entry is added. + * + * minimumInitialCapacity: The minimum initial capacity for the hashtable. + * Default is 0. + * loadFactor: The desired load factor for the hashtable, between 0 and 1. + * Default is 0.75. + */ + BasicHashtable(size_t minimumInitialCapacity = 0, float loadFactor = 0.75f); + + /* Copies a hashtable. + * The underlying storage is shared copy-on-write. + */ + BasicHashtable(const BasicHashtable& other); + + /* Clears and destroys the hashtable. + */ + virtual ~BasicHashtable(); + + /* Making this hashtable a copy of the other hashtable. + * The underlying storage is shared copy-on-write. + * + * other: The hashtable to copy. + */ + inline BasicHashtable& operator =(const BasicHashtable & other) { + setTo(other); + return *this; + } + + /* Returns the number of entries in the hashtable. + */ + inline size_t size() const { + return mSize; + } + + /* Returns the capacity of the hashtable, which is the number of elements that can + * added to the hashtable without requiring it to be grown. + */ + inline size_t capacity() const { + return mCapacity; + } + + /* Returns the number of buckets that the hashtable has, which is the size of its + * underlying array. + */ + inline size_t bucketCount() const { + return mBucketCount; + } + + /* Returns the load factor of the hashtable. */ + inline float loadFactor() const { + return mLoadFactor; + }; + + /* Returns a const reference to the entry at the specified index. + * + * index: The index of the entry to retrieve. Must be a valid index within + * the bounds of the hashtable. + */ + inline const TEntry& entryAt(size_t index) const { + return entryFor(bucketAt(mBuckets, index)); + } + + /* Returns a non-const reference to the entry at the specified index. + * + * index: The index of the entry to edit. Must be a valid index within + * the bounds of the hashtable. + */ + inline TEntry& editEntryAt(size_t index) { + edit(); + return entryFor(bucketAt(mBuckets, index)); + } + + /* Clears the hashtable. + * All entries in the hashtable are destroyed immediately. + * If you need to do something special with the entries in the hashtable then iterate + * over them and do what you need before clearing the hashtable. + */ + inline void clear() { + BasicHashtableImpl::clear(); + } + + /* Returns the index of the next entry in the hashtable given the index of a previous entry. + * If the given index is -1, then returns the index of the first entry in the hashtable, + * if there is one, or -1 otherwise. + * If the given index is not -1, then returns the index of the next entry in the hashtable, + * in strictly increasing order, or -1 if there are none left. + * + * index: The index of the previous entry that was iterated, or -1 to begin + * iteration at the beginning of the hashtable. + */ + inline ssize_t next(ssize_t index) const { + return BasicHashtableImpl::next(index); + } + + /* Finds the index of an entry with the specified key. + * If the given index is -1, then returns the index of the first matching entry, + * otherwise returns the index of the next matching entry. + * If the hashtable contains multiple entries with keys that match the requested + * key, then the sequence of entries returned is arbitrary. + * Returns -1 if no entry was found. + * + * index: The index of the previous entry with the specified key, or -1 to + * find the first matching entry. + * hash: The hashcode of the key. + * key: The key. + */ + inline ssize_t find(ssize_t index, hash_t hash, const TKey& key) const { + return BasicHashtableImpl::find(index, hash, &key); + } + + /* Adds the entry to the hashtable. + * Returns the index of the newly added entry. + * If an entry with the same key already exists, then a duplicate entry is added. + * If the entry will not fit, then the hashtable's capacity is increased and + * its contents are rehashed. See rehash(). + * + * hash: The hashcode of the key. + * entry: The entry to add. + */ + inline size_t add(hash_t hash, const TEntry& entry) { + return BasicHashtableImpl::add(hash, &entry); + } + + /* Removes the entry with the specified index from the hashtable. + * The entry is destroyed immediately. + * The index must be valid. + * + * The hashtable is not compacted after an item is removed, so it is legal + * to continue iterating over the hashtable using next() or find(). + * + * index: The index of the entry to remove. Must be a valid index within the + * bounds of the hashtable, and it must refer to an existing entry. + */ + inline void removeAt(size_t index) { + BasicHashtableImpl::removeAt(index); + } + + /* Rehashes the contents of the hashtable. + * Grows the hashtable to at least the specified minimum capacity or the + * current number of elements, whichever is larger. + * + * Rehashing causes all entries to be copied and the entry indices may change. + * Although the hash codes are cached by the hashtable, rehashing can be an + * expensive operation and should be avoided unless the hashtable's size + * needs to be changed. + * + * Rehashing is the only way to change the capacity or load factor of the + * hashtable once it has been created. It can be used to compact the + * hashtable by choosing a minimum capacity that is smaller than the current + * capacity (such as 0). + * + * minimumCapacity: The desired minimum capacity after rehashing. + * loadFactor: The desired load factor after rehashing. + */ + inline void rehash(size_t minimumCapacity, float loadFactor) { + BasicHashtableImpl::rehash(minimumCapacity, loadFactor); + } + + /* Determines whether there is room to add another entry without rehashing. + * When this returns true, a subsequent add() operation is guaranteed to + * complete without performing a rehash. + */ + inline bool hasMoreRoom() const { + return mCapacity > mFilledBuckets; + } + +protected: + static inline const TEntry& entryFor(const Bucket& bucket) { + return reinterpret_cast(bucket.entry); + } + + static inline TEntry& entryFor(Bucket& bucket) { + return reinterpret_cast(bucket.entry); + } + + virtual bool compareBucketKey(const Bucket& bucket, const void* __restrict__ key) const; + virtual void initializeBucketEntry(Bucket& bucket, const void* __restrict__ entry) const; + virtual void destroyBucketEntry(Bucket& bucket) const; + +private: + // For dumping the raw contents of a hashtable during testing. + friend class BasicHashtableTest; + inline uint32_t cookieAt(size_t index) const { + return bucketAt(mBuckets, index).cookie; + } +}; + +template +BasicHashtable::BasicHashtable(size_t minimumInitialCapacity, float loadFactor) : + BasicHashtableImpl(sizeof(TEntry), traits::has_trivial_dtor, + minimumInitialCapacity, loadFactor) { +} + +template +BasicHashtable::BasicHashtable(const BasicHashtable& other) : + BasicHashtableImpl(other) { +} + +template +BasicHashtable::~BasicHashtable() { + dispose(); +} + +template +bool BasicHashtable::compareBucketKey(const Bucket& bucket, + const void* __restrict__ key) const { + return entryFor(bucket).getKey() == *static_cast(key); +} + +template +void BasicHashtable::initializeBucketEntry(Bucket& bucket, + const void* __restrict__ entry) const { + if (!traits::has_trivial_copy) { + new (&entryFor(bucket)) TEntry(*(static_cast(entry))); + } else { + memcpy(&entryFor(bucket), entry, sizeof(TEntry)); + } +} + +template +void BasicHashtable::destroyBucketEntry(Bucket& bucket) const { + if (!traits::has_trivial_dtor) { + entryFor(bucket).~TEntry(); + } +} + +}; // namespace android + +#endif // ANDROID_BASIC_HASHTABLE_H diff --git a/phonelibs/android_system_core/include/utils/BitSet.h b/phonelibs/android_system_core/include/utils/BitSet.h new file mode 100644 index 00000000000000..8c612931de6b65 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/BitSet.h @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTILS_BITSET_H +#define UTILS_BITSET_H + +#include +#include + +/* + * Contains some bit manipulation helpers. + */ + +namespace android { + +// A simple set of 32 bits that can be individually marked or cleared. +struct BitSet32 { + uint32_t value; + + inline BitSet32() : value(0UL) { } + explicit inline BitSet32(uint32_t value) : value(value) { } + + // Gets the value associated with a particular bit index. + static inline uint32_t valueForBit(uint32_t n) { return 0x80000000UL >> n; } + + // Clears the bit set. + inline void clear() { clear(value); } + + static inline void clear(uint32_t& value) { value = 0UL; } + + // Returns the number of marked bits in the set. + inline uint32_t count() const { return count(value); } + + static inline uint32_t count(uint32_t value) { return __builtin_popcountl(value); } + + // Returns true if the bit set does not contain any marked bits. + inline bool isEmpty() const { return isEmpty(value); } + + static inline bool isEmpty(uint32_t value) { return ! value; } + + // Returns true if the bit set does not contain any unmarked bits. + inline bool isFull() const { return isFull(value); } + + static inline bool isFull(uint32_t value) { return value == 0xffffffffUL; } + + // Returns true if the specified bit is marked. + inline bool hasBit(uint32_t n) const { return hasBit(value, n); } + + static inline bool hasBit(uint32_t value, uint32_t n) { return value & valueForBit(n); } + + // Marks the specified bit. + inline void markBit(uint32_t n) { markBit(value, n); } + + static inline void markBit (uint32_t& value, uint32_t n) { value |= valueForBit(n); } + + // Clears the specified bit. + inline void clearBit(uint32_t n) { clearBit(value, n); } + + static inline void clearBit(uint32_t& value, uint32_t n) { value &= ~ valueForBit(n); } + + // Finds the first marked bit in the set. + // Result is undefined if all bits are unmarked. + inline uint32_t firstMarkedBit() const { return firstMarkedBit(value); } + + static uint32_t firstMarkedBit(uint32_t value) { return clz_checked(value); } + + // Finds the first unmarked bit in the set. + // Result is undefined if all bits are marked. + inline uint32_t firstUnmarkedBit() const { return firstUnmarkedBit(value); } + + static inline uint32_t firstUnmarkedBit(uint32_t value) { return clz_checked(~ value); } + + // Finds the last marked bit in the set. + // Result is undefined if all bits are unmarked. + inline uint32_t lastMarkedBit() const { return lastMarkedBit(value); } + + static inline uint32_t lastMarkedBit(uint32_t value) { return 31 - ctz_checked(value); } + + // Finds the first marked bit in the set and clears it. Returns the bit index. + // Result is undefined if all bits are unmarked. + inline uint32_t clearFirstMarkedBit() { return clearFirstMarkedBit(value); } + + static inline uint32_t clearFirstMarkedBit(uint32_t& value) { + uint32_t n = firstMarkedBit(value); + clearBit(value, n); + return n; + } + + // Finds the first unmarked bit in the set and marks it. Returns the bit index. + // Result is undefined if all bits are marked. + inline uint32_t markFirstUnmarkedBit() { return markFirstUnmarkedBit(value); } + + static inline uint32_t markFirstUnmarkedBit(uint32_t& value) { + uint32_t n = firstUnmarkedBit(value); + markBit(value, n); + return n; + } + + // Finds the last marked bit in the set and clears it. Returns the bit index. + // Result is undefined if all bits are unmarked. + inline uint32_t clearLastMarkedBit() { return clearLastMarkedBit(value); } + + static inline uint32_t clearLastMarkedBit(uint32_t& value) { + uint32_t n = lastMarkedBit(value); + clearBit(value, n); + return n; + } + + // Gets the index of the specified bit in the set, which is the number of + // marked bits that appear before the specified bit. + inline uint32_t getIndexOfBit(uint32_t n) const { + return getIndexOfBit(value, n); + } + + static inline uint32_t getIndexOfBit(uint32_t value, uint32_t n) { + return __builtin_popcountl(value & ~(0xffffffffUL >> n)); + } + + inline bool operator== (const BitSet32& other) const { return value == other.value; } + inline bool operator!= (const BitSet32& other) const { return value != other.value; } + inline BitSet32 operator& (const BitSet32& other) const { + return BitSet32(value & other.value); + } + inline BitSet32& operator&= (const BitSet32& other) { + value &= other.value; + return *this; + } + inline BitSet32 operator| (const BitSet32& other) const { + return BitSet32(value | other.value); + } + inline BitSet32& operator|= (const BitSet32& other) { + value |= other.value; + return *this; + } + +private: + // We use these helpers as the signature of __builtin_c{l,t}z has "unsigned int" for the + // input, which is only guaranteed to be 16b, not 32. The compiler should optimize this away. + static inline uint32_t clz_checked(uint32_t value) { + if (sizeof(unsigned int) == sizeof(uint32_t)) { + return __builtin_clz(value); + } else { + return __builtin_clzl(value); + } + } + + static inline uint32_t ctz_checked(uint32_t value) { + if (sizeof(unsigned int) == sizeof(uint32_t)) { + return __builtin_ctz(value); + } else { + return __builtin_ctzl(value); + } + } +}; + +ANDROID_BASIC_TYPES_TRAITS(BitSet32) + +// A simple set of 64 bits that can be individually marked or cleared. +struct BitSet64 { + uint64_t value; + + inline BitSet64() : value(0ULL) { } + explicit inline BitSet64(uint64_t value) : value(value) { } + + // Gets the value associated with a particular bit index. + static inline uint64_t valueForBit(uint32_t n) { return 0x8000000000000000ULL >> n; } + + // Clears the bit set. + inline void clear() { clear(value); } + + static inline void clear(uint64_t& value) { value = 0ULL; } + + // Returns the number of marked bits in the set. + inline uint32_t count() const { return count(value); } + + static inline uint32_t count(uint64_t value) { return __builtin_popcountll(value); } + + // Returns true if the bit set does not contain any marked bits. + inline bool isEmpty() const { return isEmpty(value); } + + static inline bool isEmpty(uint64_t value) { return ! value; } + + // Returns true if the bit set does not contain any unmarked bits. + inline bool isFull() const { return isFull(value); } + + static inline bool isFull(uint64_t value) { return value == 0xffffffffffffffffULL; } + + // Returns true if the specified bit is marked. + inline bool hasBit(uint32_t n) const { return hasBit(value, n); } + + static inline bool hasBit(uint64_t value, uint32_t n) { return value & valueForBit(n); } + + // Marks the specified bit. + inline void markBit(uint32_t n) { markBit(value, n); } + + static inline void markBit(uint64_t& value, uint32_t n) { value |= valueForBit(n); } + + // Clears the specified bit. + inline void clearBit(uint32_t n) { clearBit(value, n); } + + static inline void clearBit(uint64_t& value, uint32_t n) { value &= ~ valueForBit(n); } + + // Finds the first marked bit in the set. + // Result is undefined if all bits are unmarked. + inline uint32_t firstMarkedBit() const { return firstMarkedBit(value); } + + static inline uint32_t firstMarkedBit(uint64_t value) { return __builtin_clzll(value); } + + // Finds the first unmarked bit in the set. + // Result is undefined if all bits are marked. + inline uint32_t firstUnmarkedBit() const { return firstUnmarkedBit(value); } + + static inline uint32_t firstUnmarkedBit(uint64_t value) { return __builtin_clzll(~ value); } + + // Finds the last marked bit in the set. + // Result is undefined if all bits are unmarked. + inline uint32_t lastMarkedBit() const { return lastMarkedBit(value); } + + static inline uint32_t lastMarkedBit(uint64_t value) { return 63 - __builtin_ctzll(value); } + + // Finds the first marked bit in the set and clears it. Returns the bit index. + // Result is undefined if all bits are unmarked. + inline uint32_t clearFirstMarkedBit() { return clearFirstMarkedBit(value); } + + static inline uint32_t clearFirstMarkedBit(uint64_t& value) { + uint64_t n = firstMarkedBit(value); + clearBit(value, n); + return n; + } + + // Finds the first unmarked bit in the set and marks it. Returns the bit index. + // Result is undefined if all bits are marked. + inline uint32_t markFirstUnmarkedBit() { return markFirstUnmarkedBit(value); } + + static inline uint32_t markFirstUnmarkedBit(uint64_t& value) { + uint64_t n = firstUnmarkedBit(value); + markBit(value, n); + return n; + } + + // Finds the last marked bit in the set and clears it. Returns the bit index. + // Result is undefined if all bits are unmarked. + inline uint32_t clearLastMarkedBit() { return clearLastMarkedBit(value); } + + static inline uint32_t clearLastMarkedBit(uint64_t& value) { + uint64_t n = lastMarkedBit(value); + clearBit(value, n); + return n; + } + + // Gets the index of the specified bit in the set, which is the number of + // marked bits that appear before the specified bit. + inline uint32_t getIndexOfBit(uint32_t n) const { return getIndexOfBit(value, n); } + + static inline uint32_t getIndexOfBit(uint64_t value, uint32_t n) { + return __builtin_popcountll(value & ~(0xffffffffffffffffULL >> n)); + } + + inline bool operator== (const BitSet64& other) const { return value == other.value; } + inline bool operator!= (const BitSet64& other) const { return value != other.value; } + inline BitSet64 operator& (const BitSet64& other) const { + return BitSet64(value & other.value); + } + inline BitSet64& operator&= (const BitSet64& other) { + value &= other.value; + return *this; + } + inline BitSet64 operator| (const BitSet64& other) const { + return BitSet64(value | other.value); + } + inline BitSet64& operator|= (const BitSet64& other) { + value |= other.value; + return *this; + } +}; + +ANDROID_BASIC_TYPES_TRAITS(BitSet64) + +} // namespace android + +#endif // UTILS_BITSET_H diff --git a/phonelibs/android_system_core/include/utils/BlobCache.h b/phonelibs/android_system_core/include/utils/BlobCache.h new file mode 100644 index 00000000000000..65dca9fb4583fa --- /dev/null +++ b/phonelibs/android_system_core/include/utils/BlobCache.h @@ -0,0 +1,249 @@ +/* + ** Copyright 2011, The Android Open Source Project + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License. + */ + +#ifndef ANDROID_BLOB_CACHE_H +#define ANDROID_BLOB_CACHE_H + +#include + +#include +#include +#include +#include + +namespace android { + +// A BlobCache is an in-memory cache for binary key/value pairs. A BlobCache +// does NOT provide any thread-safety guarantees. +// +// The cache contents can be serialized to an in-memory buffer or mmap'd file +// and then reloaded in a subsequent execution of the program. This +// serialization is non-portable and the data should only be used by the device +// that generated it. +class BlobCache : public RefBase { + +public: + + // Create an empty blob cache. The blob cache will cache key/value pairs + // with key and value sizes less than or equal to maxKeySize and + // maxValueSize, respectively. The total combined size of ALL cache entries + // (key sizes plus value sizes) will not exceed maxTotalSize. + BlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize); + + // set inserts a new binary value into the cache and associates it with the + // given binary key. If the key or value are too large for the cache then + // the cache remains unchanged. This includes the case where a different + // value was previously associated with the given key - the old value will + // remain in the cache. If the given key and value are small enough to be + // put in the cache (based on the maxKeySize, maxValueSize, and maxTotalSize + // values specified to the BlobCache constructor), then the key/value pair + // will be in the cache after set returns. Note, however, that a subsequent + // call to set may evict old key/value pairs from the cache. + // + // Preconditions: + // key != NULL + // 0 < keySize + // value != NULL + // 0 < valueSize + void set(const void* key, size_t keySize, const void* value, + size_t valueSize); + + // get retrieves from the cache the binary value associated with a given + // binary key. If the key is present in the cache then the length of the + // binary value associated with that key is returned. If the value argument + // is non-NULL and the size of the cached value is less than valueSize bytes + // then the cached value is copied into the buffer pointed to by the value + // argument. If the key is not present in the cache then 0 is returned and + // the buffer pointed to by the value argument is not modified. + // + // Note that when calling get multiple times with the same key, the later + // calls may fail, returning 0, even if earlier calls succeeded. The return + // value must be checked for each call. + // + // Preconditions: + // key != NULL + // 0 < keySize + // 0 <= valueSize + size_t get(const void* key, size_t keySize, void* value, size_t valueSize); + + + // getFlattenedSize returns the number of bytes needed to store the entire + // serialized cache. + size_t getFlattenedSize() const; + + // flatten serializes the current contents of the cache into the memory + // pointed to by 'buffer'. The serialized cache contents can later be + // loaded into a BlobCache object using the unflatten method. The contents + // of the BlobCache object will not be modified. + // + // Preconditions: + // size >= this.getFlattenedSize() + status_t flatten(void* buffer, size_t size) const; + + // unflatten replaces the contents of the cache with the serialized cache + // contents in the memory pointed to by 'buffer'. The previous contents of + // the BlobCache will be evicted from the cache. If an error occurs while + // unflattening the serialized cache contents then the BlobCache will be + // left in an empty state. + // + status_t unflatten(void const* buffer, size_t size); + +private: + // Copying is disallowed. + BlobCache(const BlobCache&); + void operator=(const BlobCache&); + + // A random function helper to get around MinGW not having nrand48() + long int blob_random(); + + // clean evicts a randomly chosen set of entries from the cache such that + // the total size of all remaining entries is less than mMaxTotalSize/2. + void clean(); + + // isCleanable returns true if the cache is full enough for the clean method + // to have some effect, and false otherwise. + bool isCleanable() const; + + // A Blob is an immutable sized unstructured data blob. + class Blob : public RefBase { + public: + Blob(const void* data, size_t size, bool copyData); + ~Blob(); + + bool operator<(const Blob& rhs) const; + + const void* getData() const; + size_t getSize() const; + + private: + // Copying is not allowed. + Blob(const Blob&); + void operator=(const Blob&); + + // mData points to the buffer containing the blob data. + const void* mData; + + // mSize is the size of the blob data in bytes. + size_t mSize; + + // mOwnsData indicates whether or not this Blob object should free the + // memory pointed to by mData when the Blob gets destructed. + bool mOwnsData; + }; + + // A CacheEntry is a single key/value pair in the cache. + class CacheEntry { + public: + CacheEntry(); + CacheEntry(const sp& key, const sp& value); + CacheEntry(const CacheEntry& ce); + + bool operator<(const CacheEntry& rhs) const; + const CacheEntry& operator=(const CacheEntry&); + + sp getKey() const; + sp getValue() const; + + void setValue(const sp& value); + + private: + + // mKey is the key that identifies the cache entry. + sp mKey; + + // mValue is the cached data associated with the key. + sp mValue; + }; + + // A Header is the header for the entire BlobCache serialization format. No + // need to make this portable, so we simply write the struct out. + struct Header { + // mMagicNumber is the magic number that identifies the data as + // serialized BlobCache contents. It must always contain 'Blb$'. + uint32_t mMagicNumber; + + // mBlobCacheVersion is the serialization format version. + uint32_t mBlobCacheVersion; + + // mDeviceVersion is the device-specific version of the cache. This can + // be used to invalidate the cache. + uint32_t mDeviceVersion; + + // mNumEntries is number of cache entries following the header in the + // data. + size_t mNumEntries; + + // mBuildId is the build id of the device when the cache was created. + // When an update to the build happens (via an OTA or other update) this + // is used to invalidate the cache. + int mBuildIdLength; + char mBuildId[]; + }; + + // An EntryHeader is the header for a serialized cache entry. No need to + // make this portable, so we simply write the struct out. Each EntryHeader + // is followed imediately by the key data and then the value data. + // + // The beginning of each serialized EntryHeader is 4-byte aligned, so the + // number of bytes that a serialized cache entry will occupy is: + // + // ((sizeof(EntryHeader) + keySize + valueSize) + 3) & ~3 + // + struct EntryHeader { + // mKeySize is the size of the entry key in bytes. + size_t mKeySize; + + // mValueSize is the size of the entry value in bytes. + size_t mValueSize; + + // mData contains both the key and value data for the cache entry. The + // key comes first followed immediately by the value. + uint8_t mData[]; + }; + + // mMaxKeySize is the maximum key size that will be cached. Calls to + // BlobCache::set with a keySize parameter larger than mMaxKeySize will + // simply not add the key/value pair to the cache. + const size_t mMaxKeySize; + + // mMaxValueSize is the maximum value size that will be cached. Calls to + // BlobCache::set with a valueSize parameter larger than mMaxValueSize will + // simply not add the key/value pair to the cache. + const size_t mMaxValueSize; + + // mMaxTotalSize is the maximum size that all cache entries can occupy. This + // includes space for both keys and values. When a call to BlobCache::set + // would otherwise cause this limit to be exceeded, either the key/value + // pair passed to BlobCache::set will not be cached or other cache entries + // will be evicted from the cache to make room for the new entry. + const size_t mMaxTotalSize; + + // mTotalSize is the total combined size of all keys and values currently in + // the cache. + size_t mTotalSize; + + // mRandState is the pseudo-random number generator state. It is passed to + // nrand48 to generate random numbers when needed. + unsigned short mRandState[3]; + + // mCacheEntries stores all the cache entries that are resident in memory. + // Cache entries are added to it by the 'set' method. + SortedVector mCacheEntries; +}; + +} + +#endif // ANDROID_BLOB_CACHE_H diff --git a/phonelibs/android_system_core/include/utils/ByteOrder.h b/phonelibs/android_system_core/include/utils/ByteOrder.h new file mode 100644 index 00000000000000..baa3a83dddfc47 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/ByteOrder.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// + +#ifndef _LIBS_UTILS_BYTE_ORDER_H +#define _LIBS_UTILS_BYTE_ORDER_H + +#include +#include +#ifdef HAVE_WINSOCK +#include +#else +#include +#endif + +/* + * These macros are like the hton/ntoh byte swapping macros, + * except they allow you to swap to and from the "device" byte + * order. The device byte order is the endianness of the target + * device -- for the ARM CPUs we use today, this is little endian. + * + * Note that the byte swapping functions have not been optimized + * much; performance is currently not an issue for them since the + * intent is to allow us to avoid byte swapping on the device. + */ + +static inline uint32_t android_swap_long(uint32_t v) +{ + return (v<<24) | ((v<<8)&0x00FF0000) | ((v>>8)&0x0000FF00) | (v>>24); +} + +static inline uint16_t android_swap_short(uint16_t v) +{ + return (v<<8) | (v>>8); +} + +#define DEVICE_BYTE_ORDER LITTLE_ENDIAN + +#if BYTE_ORDER == DEVICE_BYTE_ORDER + +#define dtohl(x) (x) +#define dtohs(x) (x) +#define htodl(x) (x) +#define htods(x) (x) + +#else + +#define dtohl(x) (android_swap_long(x)) +#define dtohs(x) (android_swap_short(x)) +#define htodl(x) (android_swap_long(x)) +#define htods(x) (android_swap_short(x)) + +#endif + +#if BYTE_ORDER == LITTLE_ENDIAN +#define fromlel(x) (x) +#define fromles(x) (x) +#define tolel(x) (x) +#define toles(x) (x) +#else +#define fromlel(x) (android_swap_long(x)) +#define fromles(x) (android_swap_short(x)) +#define tolel(x) (android_swap_long(x)) +#define toles(x) (android_swap_short(x)) +#endif + +#endif // _LIBS_UTILS_BYTE_ORDER_H diff --git a/phonelibs/android_system_core/include/utils/CallStack.h b/phonelibs/android_system_core/include/utils/CallStack.h new file mode 100644 index 00000000000000..27e89f4622c8dc --- /dev/null +++ b/phonelibs/android_system_core/include/utils/CallStack.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_CALLSTACK_H +#define ANDROID_CALLSTACK_H + +#include +#include +#include +#include + +#include +#include + +namespace android { + +class Printer; + +// Collect/print the call stack (function, file, line) traces for a single thread. +class CallStack { +public: + // Create an empty call stack. No-op. + CallStack(); + // Create a callstack with the current thread's stack trace. + // Immediately dump it to logcat using the given logtag. + CallStack(const char* logtag, int32_t ignoreDepth=1); + ~CallStack(); + + // Reset the stack frames (same as creating an empty call stack). + void clear() { mFrameLines.clear(); } + + // Immediately collect the stack traces for the specified thread. + // The default is to dump the stack of the current call. + void update(int32_t ignoreDepth=1, pid_t tid=BACKTRACE_CURRENT_THREAD); + + // Dump a stack trace to the log using the supplied logtag. + void log(const char* logtag, + android_LogPriority priority = ANDROID_LOG_DEBUG, + const char* prefix = 0) const; + + // Dump a stack trace to the specified file descriptor. + void dump(int fd, int indent = 0, const char* prefix = 0) const; + + // Return a string (possibly very long) containing the complete stack trace. + String8 toString(const char* prefix = 0) const; + + // Dump a serialized representation of the stack trace to the specified printer. + void print(Printer& printer) const; + + // Get the count of stack frames that are in this call stack. + size_t size() const { return mFrameLines.size(); } + +private: + Vector mFrameLines; +}; + +}; // namespace android + +#endif // ANDROID_CALLSTACK_H diff --git a/phonelibs/android_system_core/include/utils/Compat.h b/phonelibs/android_system_core/include/utils/Compat.h new file mode 100644 index 00000000000000..7d96310272e117 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Compat.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LIB_UTILS_COMPAT_H +#define __LIB_UTILS_COMPAT_H + +#include + +#if defined(__APPLE__) + +/* Mac OS has always had a 64-bit off_t, so it doesn't have off64_t. */ + +typedef off_t off64_t; + +static inline off64_t lseek64(int fd, off64_t offset, int whence) { + return lseek(fd, offset, whence); +} + +static inline ssize_t pread64(int fd, void* buf, size_t nbytes, off64_t offset) { + return pread(fd, buf, nbytes, offset); +} + +#endif /* __APPLE__ */ + +#if defined(_WIN32) +#define O_CLOEXEC O_NOINHERIT +#define O_NOFOLLOW 0 +#define DEFFILEMODE 0666 +#endif /* _WIN32 */ + +#if defined(_WIN32) +#define ZD "%ld" +#define ZD_TYPE long +#else +#define ZD "%zd" +#define ZD_TYPE ssize_t +#endif + +/* + * Needed for cases where something should be constexpr if possible, but not + * being constexpr is fine if in pre-C++11 code (such as a const static float + * member variable). + */ +#if __cplusplus >= 201103L +#define CONSTEXPR constexpr +#else +#define CONSTEXPR +#endif + +/* + * TEMP_FAILURE_RETRY is defined by some, but not all, versions of + * . (Alas, it is not as standard as we'd hoped!) So, if it's + * not already defined, then define it here. + */ +#ifndef TEMP_FAILURE_RETRY +/* Used to retry syscalls that can return EINTR. */ +#define TEMP_FAILURE_RETRY(exp) ({ \ + typeof (exp) _rc; \ + do { \ + _rc = (exp); \ + } while (_rc == -1 && errno == EINTR); \ + _rc; }) +#endif + +#endif /* __LIB_UTILS_COMPAT_H */ diff --git a/phonelibs/android_system_core/include/utils/Condition.h b/phonelibs/android_system_core/include/utils/Condition.h new file mode 100644 index 00000000000000..5a7251982a65e4 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Condition.h @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_UTILS_CONDITION_H +#define _LIBS_UTILS_CONDITION_H + +#include +#include +#include + +#if !defined(_WIN32) +# include +#endif + +#include +#include +#include + +// --------------------------------------------------------------------------- +namespace android { +// --------------------------------------------------------------------------- + +/* + * Condition variable class. The implementation is system-dependent. + * + * Condition variables are paired up with mutexes. Lock the mutex, + * call wait(), then either re-wait() if things aren't quite what you want, + * or unlock the mutex and continue. All threads calling wait() must + * use the same mutex for a given Condition. + */ +class Condition { +public: + enum { + PRIVATE = 0, + SHARED = 1 + }; + + enum WakeUpType { + WAKE_UP_ONE = 0, + WAKE_UP_ALL = 1 + }; + + Condition(); + Condition(int type); + ~Condition(); + // Wait on the condition variable. Lock the mutex before calling. + status_t wait(Mutex& mutex); + // same with relative timeout + status_t waitRelative(Mutex& mutex, nsecs_t reltime); + // Signal the condition variable, allowing exactly one thread to continue. + void signal(); + // Signal the condition variable, allowing one or all threads to continue. + void signal(WakeUpType type) { + if (type == WAKE_UP_ONE) { + signal(); + } else { + broadcast(); + } + } + // Signal the condition variable, allowing all threads to continue. + void broadcast(); + +private: +#if !defined(_WIN32) + pthread_cond_t mCond; +#else + void* mState; +#endif +}; + +// --------------------------------------------------------------------------- + +#if !defined(_WIN32) + +inline Condition::Condition() { + pthread_cond_init(&mCond, NULL); +} +inline Condition::Condition(int type) { + if (type == SHARED) { + pthread_condattr_t attr; + pthread_condattr_init(&attr); + pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + pthread_cond_init(&mCond, &attr); + pthread_condattr_destroy(&attr); + } else { + pthread_cond_init(&mCond, NULL); + } +} +inline Condition::~Condition() { + pthread_cond_destroy(&mCond); +} +inline status_t Condition::wait(Mutex& mutex) { + return -pthread_cond_wait(&mCond, &mutex.mMutex); +} +inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) { +#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE) + struct timespec ts; + ts.tv_sec = reltime/1000000000; + ts.tv_nsec = reltime%1000000000; + return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts); +#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE + struct timespec ts; +#if defined(__linux__) + clock_gettime(CLOCK_REALTIME, &ts); +#else // __APPLE__ + // we don't support the clocks here. + struct timeval t; + gettimeofday(&t, NULL); + ts.tv_sec = t.tv_sec; + ts.tv_nsec= t.tv_usec*1000; +#endif + ts.tv_sec += reltime/1000000000; + ts.tv_nsec+= reltime%1000000000; + if (ts.tv_nsec >= 1000000000) { + ts.tv_nsec -= 1000000000; + ts.tv_sec += 1; + } + return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts); +#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE +} +inline void Condition::signal() { + /* + * POSIX says pthread_cond_signal wakes up "one or more" waiting threads. + * However bionic follows the glibc guarantee which wakes up "exactly one" + * waiting thread. + * + * man 3 pthread_cond_signal + * pthread_cond_signal restarts one of the threads that are waiting on + * the condition variable cond. If no threads are waiting on cond, + * nothing happens. If several threads are waiting on cond, exactly one + * is restarted, but it is not specified which. + */ + pthread_cond_signal(&mCond); +} +inline void Condition::broadcast() { + pthread_cond_broadcast(&mCond); +} + +#endif // !defined(_WIN32) + +// --------------------------------------------------------------------------- +}; // namespace android +// --------------------------------------------------------------------------- + +#endif // _LIBS_UTILS_CONDITON_H diff --git a/phonelibs/android_system_core/include/utils/Debug.h b/phonelibs/android_system_core/include/utils/Debug.h new file mode 100644 index 00000000000000..08893bdaaf324f --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Debug.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UTILS_DEBUG_H +#define ANDROID_UTILS_DEBUG_H + +#include +#include + +namespace android { +// --------------------------------------------------------------------------- + +#ifdef __cplusplus +template struct CompileTimeAssert; +template<> struct CompileTimeAssert {}; +#define COMPILE_TIME_ASSERT(_exp) \ + template class CompileTimeAssert< (_exp) >; +#endif +#define COMPILE_TIME_ASSERT_FUNCTION_SCOPE(_exp) \ + CompileTimeAssert<( _exp )>(); + +// --------------------------------------------------------------------------- + +#ifdef __cplusplus +template struct CompileTimeIfElse; +template +struct CompileTimeIfElse { typedef LHS TYPE; }; +template +struct CompileTimeIfElse { typedef RHS TYPE; }; +#endif + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_UTILS_DEBUG_H diff --git a/phonelibs/android_system_core/include/utils/Endian.h b/phonelibs/android_system_core/include/utils/Endian.h new file mode 100644 index 00000000000000..591cae0d3461d2 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Endian.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Android endian-ness defines. +// +#ifndef _LIBS_UTILS_ENDIAN_H +#define _LIBS_UTILS_ENDIAN_H + +#if defined(__APPLE__) || defined(_WIN32) + +#define __BIG_ENDIAN 0x1000 +#define __LITTLE_ENDIAN 0x0001 +#define __BYTE_ORDER __LITTLE_ENDIAN + +#else + +#include + +#endif + +#endif /*_LIBS_UTILS_ENDIAN_H*/ diff --git a/phonelibs/android_system_core/include/utils/Errors.h b/phonelibs/android_system_core/include/utils/Errors.h new file mode 100644 index 00000000000000..46173db4a3de82 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Errors.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_ERRORS_H +#define ANDROID_ERRORS_H + +#include +#include + +namespace android { + +// use this type to return error codes +#ifdef HAVE_MS_C_RUNTIME +typedef int status_t; +#else +typedef int32_t status_t; +#endif + +/* the MS C runtime lacks a few error codes */ + +/* + * Error codes. + * All error codes are negative values. + */ + +// Win32 #defines NO_ERROR as well. It has the same value, so there's no +// real conflict, though it's a bit awkward. +#ifdef _WIN32 +# undef NO_ERROR +#endif + +enum { + OK = 0, // Everything's swell. + NO_ERROR = 0, // No errors. + + UNKNOWN_ERROR = (-2147483647-1), // INT32_MIN value + + NO_MEMORY = -ENOMEM, + INVALID_OPERATION = -ENOSYS, + BAD_VALUE = -EINVAL, + BAD_TYPE = (UNKNOWN_ERROR + 1), + NAME_NOT_FOUND = -ENOENT, + PERMISSION_DENIED = -EPERM, + NO_INIT = -ENODEV, + ALREADY_EXISTS = -EEXIST, + DEAD_OBJECT = -EPIPE, + FAILED_TRANSACTION = (UNKNOWN_ERROR + 2), + JPARKS_BROKE_IT = -EPIPE, +#if !defined(HAVE_MS_C_RUNTIME) + BAD_INDEX = -EOVERFLOW, + NOT_ENOUGH_DATA = -ENODATA, + WOULD_BLOCK = -EWOULDBLOCK, + TIMED_OUT = -ETIMEDOUT, + UNKNOWN_TRANSACTION = -EBADMSG, +#else + BAD_INDEX = -E2BIG, + NOT_ENOUGH_DATA = (UNKNOWN_ERROR + 3), + WOULD_BLOCK = (UNKNOWN_ERROR + 4), + TIMED_OUT = (UNKNOWN_ERROR + 5), + UNKNOWN_TRANSACTION = (UNKNOWN_ERROR + 6), +#endif + FDS_NOT_ALLOWED = (UNKNOWN_ERROR + 7), +}; + +// Restore define; enumeration is in "android" namespace, so the value defined +// there won't work for Win32 code in a different namespace. +#ifdef _WIN32 +# define NO_ERROR 0L +#endif + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_ERRORS_H diff --git a/phonelibs/android_system_core/include/utils/FileMap.h b/phonelibs/android_system_core/include/utils/FileMap.h new file mode 100644 index 00000000000000..f70fc927e4ca36 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/FileMap.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Encapsulate a shared file mapping. +// +#ifndef __LIBS_FILE_MAP_H +#define __LIBS_FILE_MAP_H + +#include + +#include + +#if defined(__MINGW32__) +// Ensure that we always pull in winsock2.h before windows.h +#ifdef HAVE_WINSOCK +#include +#endif +#include +#endif + +namespace android { + +/* + * This represents a memory-mapped file. It might be the entire file or + * only part of it. This requires a little bookkeeping because the mapping + * needs to be aligned on page boundaries, and in some cases we'd like to + * have multiple references to the mapped area without creating additional + * maps. + * + * This always uses MAP_SHARED. + * + * TODO: we should be able to create a new FileMap that is a subset of + * an existing FileMap and shares the underlying mapped pages. Requires + * completing the refcounting stuff and possibly introducing the notion + * of a FileMap hierarchy. + */ +class FileMap { +public: + FileMap(void); + + /* + * Create a new mapping on an open file. + * + * Closing the file descriptor does not unmap the pages, so we don't + * claim ownership of the fd. + * + * Returns "false" on failure. + */ + bool create(const char* origFileName, int fd, + off64_t offset, size_t length, bool readOnly); + + ~FileMap(void); + + /* + * Return the name of the file this map came from, if known. + */ + const char* getFileName(void) const { return mFileName; } + + /* + * Get a pointer to the piece of the file we requested. + */ + void* getDataPtr(void) const { return mDataPtr; } + + /* + * Get the length we requested. + */ + size_t getDataLength(void) const { return mDataLength; } + + /* + * Get the data offset used to create this map. + */ + off64_t getDataOffset(void) const { return mDataOffset; } + + /* + * This maps directly to madvise() values, but allows us to avoid + * including everywhere. + */ + enum MapAdvice { + NORMAL, RANDOM, SEQUENTIAL, WILLNEED, DONTNEED + }; + + /* + * Apply an madvise() call to the entire file. + * + * Returns 0 on success, -1 on failure. + */ + int advise(MapAdvice advice); + +protected: + +private: + // these are not implemented + FileMap(const FileMap& src); + const FileMap& operator=(const FileMap& src); + + char* mFileName; // original file name, if known + void* mBasePtr; // base of mmap area; page aligned + size_t mBaseLength; // length, measured from "mBasePtr" + off64_t mDataOffset; // offset used when map was created + void* mDataPtr; // start of requested data, offset from base + size_t mDataLength; // length, measured from "mDataPtr" +#if defined(__MINGW32__) + HANDLE mFileHandle; // Win32 file handle + HANDLE mFileMapping; // Win32 file mapping handle +#endif + + static long mPageSize; +}; + +}; // namespace android + +#endif // __LIBS_FILE_MAP_H diff --git a/phonelibs/android_system_core/include/utils/Flattenable.h b/phonelibs/android_system_core/include/utils/Flattenable.h new file mode 100644 index 00000000000000..882a8b2499a1c9 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Flattenable.h @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UTILS_FLATTENABLE_H +#define ANDROID_UTILS_FLATTENABLE_H + + +#include +#include +#include +#include + +namespace android { + + +class FlattenableUtils { +public: + template + static size_t align(size_t size) { + COMPILE_TIME_ASSERT_FUNCTION_SCOPE( !(N & (N-1)) ); + return (size + (N-1)) & ~(N-1); + } + + template + static size_t align(void const*& buffer) { + COMPILE_TIME_ASSERT_FUNCTION_SCOPE( !(N & (N-1)) ); + intptr_t b = intptr_t(buffer); + buffer = (void*)((intptr_t(buffer) + (N-1)) & ~(N-1)); + return size_t(intptr_t(buffer) - b); + } + + template + static size_t align(void*& buffer) { + return align( const_cast(buffer) ); + } + + static void advance(void*& buffer, size_t& size, size_t offset) { + buffer = reinterpret_cast( intptr_t(buffer) + offset ); + size -= offset; + } + + static void advance(void const*& buffer, size_t& size, size_t offset) { + buffer = reinterpret_cast( intptr_t(buffer) + offset ); + size -= offset; + } + + // write a POD structure + template + static void write(void*& buffer, size_t& size, const T& value) { + *static_cast(buffer) = value; + advance(buffer, size, sizeof(T)); + } + + // read a POD structure + template + static void read(void const*& buffer, size_t& size, T& value) { + value = *static_cast(buffer); + advance(buffer, size, sizeof(T)); + } +}; + + +/* + * The Flattenable protocol allows an object to serialize itself out + * to a byte-buffer and an array of file descriptors. + * Flattenable objects must implement this protocol. + */ + +template +class Flattenable { +public: + // size in bytes of the flattened object + inline size_t getFlattenedSize() const; + + // number of file descriptors to flatten + inline size_t getFdCount() const; + + // flattens the object into buffer. + // size should be at least of getFlattenedSize() + // file descriptors are written in the fds[] array but ownership is + // not transfered (ie: they must be dupped by the caller of + // flatten() if needed). + inline status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const; + + // unflattens the object from buffer. + // size should be equal to the value of getFlattenedSize() when the + // object was flattened. + // unflattened file descriptors are found in the fds[] array and + // don't need to be dupped(). ie: the caller of unflatten doesn't + // keep ownership. If a fd is not retained by unflatten() it must be + // explicitly closed. + inline status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count); +}; + +template +inline size_t Flattenable::getFlattenedSize() const { + return static_cast(this)->T::getFlattenedSize(); +} +template +inline size_t Flattenable::getFdCount() const { + return static_cast(this)->T::getFdCount(); +} +template +inline status_t Flattenable::flatten( + void*& buffer, size_t& size, int*& fds, size_t& count) const { + return static_cast(this)->T::flatten(buffer, size, fds, count); +} +template +inline status_t Flattenable::unflatten( + void const*& buffer, size_t& size, int const*& fds, size_t& count) { + return static_cast(this)->T::unflatten(buffer, size, fds, count); +} + +/* + * LightFlattenable is a protocol allowing object to serialize themselves out + * to a byte-buffer. Because it doesn't handle file-descriptors, + * LightFlattenable is usually more size efficient than Flattenable. + * LightFlattenable objects must implement this protocol. + */ +template +class LightFlattenable { +public: + // returns whether this object always flatten into the same size. + // for efficiency, this should always be inline. + inline bool isFixedSize() const; + + // returns size in bytes of the flattened object. must be a constant. + inline size_t getFlattenedSize() const; + + // flattens the object into buffer. + inline status_t flatten(void* buffer, size_t size) const; + + // unflattens the object from buffer of given size. + inline status_t unflatten(void const* buffer, size_t size); +}; + +template +inline bool LightFlattenable::isFixedSize() const { + return static_cast(this)->T::isFixedSize(); +} +template +inline size_t LightFlattenable::getFlattenedSize() const { + return static_cast(this)->T::getFlattenedSize(); +} +template +inline status_t LightFlattenable::flatten(void* buffer, size_t size) const { + return static_cast(this)->T::flatten(buffer, size); +} +template +inline status_t LightFlattenable::unflatten(void const* buffer, size_t size) { + return static_cast(this)->T::unflatten(buffer, size); +} + +/* + * LightFlattenablePod is an implementation of the LightFlattenable protocol + * for POD (plain-old-data) objects. + * Simply derive from LightFlattenablePod to make Foo flattenable; no + * need to implement any methods; obviously Foo must be a POD structure. + */ +template +class LightFlattenablePod : public LightFlattenable { +public: + inline bool isFixedSize() const { + return true; + } + + inline size_t getFlattenedSize() const { + return sizeof(T); + } + inline status_t flatten(void* buffer, size_t size) const { + if (size < sizeof(T)) return NO_MEMORY; + *reinterpret_cast(buffer) = *static_cast(this); + return NO_ERROR; + } + inline status_t unflatten(void const* buffer, size_t) { + *static_cast(this) = *reinterpret_cast(buffer); + return NO_ERROR; + } +}; + + +}; // namespace android + + +#endif /* ANDROID_UTILS_FLATTENABLE_H */ diff --git a/phonelibs/android_system_core/include/utils/Functor.h b/phonelibs/android_system_core/include/utils/Functor.h new file mode 100644 index 00000000000000..09ea614b614f29 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Functor.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_FUNCTOR_H +#define ANDROID_FUNCTOR_H + +#include + +namespace android { + +class Functor { +public: + Functor() {} + virtual ~Functor() {} + virtual status_t operator ()(int /*what*/, void* /*data*/) { return NO_ERROR; } +}; + +}; // namespace android + +#endif // ANDROID_FUNCTOR_H diff --git a/phonelibs/android_system_core/include/utils/JenkinsHash.h b/phonelibs/android_system_core/include/utils/JenkinsHash.h new file mode 100644 index 00000000000000..7da5dbd6a91321 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/JenkinsHash.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Implementation of Jenkins one-at-a-time hash function. These choices are + * optimized for code size and portability, rather than raw speed. But speed + * should still be quite good. + **/ + +#ifndef ANDROID_JENKINS_HASH_H +#define ANDROID_JENKINS_HASH_H + +#include + +namespace android { + +/* The Jenkins hash of a sequence of 32 bit words A, B, C is: + * Whiten(Mix(Mix(Mix(0, A), B), C)) */ + +inline uint32_t JenkinsHashMix(uint32_t hash, uint32_t data) { + hash += data; + hash += (hash << 10); + hash ^= (hash >> 6); + return hash; +} + +hash_t JenkinsHashWhiten(uint32_t hash); + +/* Helpful utility functions for hashing data in 32 bit chunks */ +uint32_t JenkinsHashMixBytes(uint32_t hash, const uint8_t* bytes, size_t size); + +uint32_t JenkinsHashMixShorts(uint32_t hash, const uint16_t* shorts, size_t size); + +} + +#endif // ANDROID_JENKINS_HASH_H diff --git a/phonelibs/android_system_core/include/utils/KeyedVector.h b/phonelibs/android_system_core/include/utils/KeyedVector.h new file mode 100644 index 00000000000000..c4faae0b76ae79 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/KeyedVector.h @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_KEYED_VECTOR_H +#define ANDROID_KEYED_VECTOR_H + +#include +#include +#include + +#include + +#include +#include +#include + +// --------------------------------------------------------------------------- + +namespace android { + +template +class KeyedVector +{ +public: + typedef KEY key_type; + typedef VALUE value_type; + + inline KeyedVector(); + + /* + * empty the vector + */ + + inline void clear() { mVector.clear(); } + + /*! + * vector stats + */ + + //! returns number of items in the vector + inline size_t size() const { return mVector.size(); } + //! returns whether or not the vector is empty + inline bool isEmpty() const { return mVector.isEmpty(); } + //! returns how many items can be stored without reallocating the backing store + inline size_t capacity() const { return mVector.capacity(); } + //! sets the capacity. capacity can never be reduced less than size() + inline ssize_t setCapacity(size_t size) { return mVector.setCapacity(size); } + + // returns true if the arguments is known to be identical to this vector + inline bool isIdenticalTo(const KeyedVector& rhs) const; + + /*! + * accessors + */ + const VALUE& valueFor(const KEY& key) const; + const VALUE& valueAt(size_t index) const; + const KEY& keyAt(size_t index) const; + ssize_t indexOfKey(const KEY& key) const; + const VALUE& operator[] (size_t index) const; + + /*! + * modifying the array + */ + + VALUE& editValueFor(const KEY& key); + VALUE& editValueAt(size_t index); + + /*! + * add/insert/replace items + */ + + ssize_t add(const KEY& key, const VALUE& item); + ssize_t replaceValueFor(const KEY& key, const VALUE& item); + ssize_t replaceValueAt(size_t index, const VALUE& item); + + /*! + * remove items + */ + + ssize_t removeItem(const KEY& key); + ssize_t removeItemsAt(size_t index, size_t count = 1); + +private: + SortedVector< key_value_pair_t > mVector; +}; + +// KeyedVector can be trivially moved using memcpy() because its +// underlying SortedVector can be trivially moved. +template struct trait_trivial_move > { + enum { value = trait_trivial_move > >::value }; +}; + + +// --------------------------------------------------------------------------- + +/** + * Variation of KeyedVector that holds a default value to return when + * valueFor() is called with a key that doesn't exist. + */ +template +class DefaultKeyedVector : public KeyedVector +{ +public: + inline DefaultKeyedVector(const VALUE& defValue = VALUE()); + const VALUE& valueFor(const KEY& key) const; + +private: + VALUE mDefault; +}; + +// --------------------------------------------------------------------------- + +template inline +KeyedVector::KeyedVector() +{ +} + +template inline +bool KeyedVector::isIdenticalTo(const KeyedVector& rhs) const { + return mVector.array() == rhs.mVector.array(); +} + +template inline +ssize_t KeyedVector::indexOfKey(const KEY& key) const { + return mVector.indexOf( key_value_pair_t(key) ); +} + +template inline +const VALUE& KeyedVector::valueFor(const KEY& key) const { + ssize_t i = this->indexOfKey(key); + LOG_ALWAYS_FATAL_IF(i<0, "%s: key not found", __PRETTY_FUNCTION__); + return mVector.itemAt(i).value; +} + +template inline +const VALUE& KeyedVector::valueAt(size_t index) const { + return mVector.itemAt(index).value; +} + +template inline +const VALUE& KeyedVector::operator[] (size_t index) const { + return valueAt(index); +} + +template inline +const KEY& KeyedVector::keyAt(size_t index) const { + return mVector.itemAt(index).key; +} + +template inline +VALUE& KeyedVector::editValueFor(const KEY& key) { + ssize_t i = this->indexOfKey(key); + LOG_ALWAYS_FATAL_IF(i<0, "%s: key not found", __PRETTY_FUNCTION__); + return mVector.editItemAt(i).value; +} + +template inline +VALUE& KeyedVector::editValueAt(size_t index) { + return mVector.editItemAt(index).value; +} + +template inline +ssize_t KeyedVector::add(const KEY& key, const VALUE& value) { + return mVector.add( key_value_pair_t(key, value) ); +} + +template inline +ssize_t KeyedVector::replaceValueFor(const KEY& key, const VALUE& value) { + key_value_pair_t pair(key, value); + mVector.remove(pair); + return mVector.add(pair); +} + +template inline +ssize_t KeyedVector::replaceValueAt(size_t index, const VALUE& item) { + if (index inline +ssize_t KeyedVector::removeItem(const KEY& key) { + return mVector.remove(key_value_pair_t(key)); +} + +template inline +ssize_t KeyedVector::removeItemsAt(size_t index, size_t count) { + return mVector.removeItemsAt(index, count); +} + +// --------------------------------------------------------------------------- + +template inline +DefaultKeyedVector::DefaultKeyedVector(const VALUE& defValue) + : mDefault(defValue) +{ +} + +template inline +const VALUE& DefaultKeyedVector::valueFor(const KEY& key) const { + ssize_t i = this->indexOfKey(key); + return i >= 0 ? KeyedVector::valueAt(i) : mDefault; +} + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_KEYED_VECTOR_H diff --git a/phonelibs/android_system_core/include/utils/LinearTransform.h b/phonelibs/android_system_core/include/utils/LinearTransform.h new file mode 100644 index 00000000000000..04cb355c7ff77c --- /dev/null +++ b/phonelibs/android_system_core/include/utils/LinearTransform.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_UTILS_LINEAR_TRANSFORM_H +#define _LIBS_UTILS_LINEAR_TRANSFORM_H + +#include + +namespace android { + +// LinearTransform defines a structure which hold the definition of a +// transformation from single dimensional coordinate system A into coordinate +// system B (and back again). Values in A and in B are 64 bit, the linear +// scale factor is expressed as a rational number using two 32 bit values. +// +// Specifically, let +// f(a) = b +// F(b) = f^-1(b) = a +// then +// +// f(a) = (((a - a_zero) * a_to_b_numer) / a_to_b_denom) + b_zero; +// +// and +// +// F(b) = (((b - b_zero) * a_to_b_denom) / a_to_b_numer) + a_zero; +// +struct LinearTransform { + int64_t a_zero; + int64_t b_zero; + int32_t a_to_b_numer; + uint32_t a_to_b_denom; + + // Transform from A->B + // Returns true on success, or false in the case of a singularity or an + // overflow. + bool doForwardTransform(int64_t a_in, int64_t* b_out) const; + + // Transform from B->A + // Returns true on success, or false in the case of a singularity or an + // overflow. + bool doReverseTransform(int64_t b_in, int64_t* a_out) const; + + // Helpers which will reduce the fraction N/D using Euclid's method. + template static void reduce(T* N, T* D); + static void reduce(int32_t* N, uint32_t* D); +}; + + +} + +#endif // _LIBS_UTILS_LINEAR_TRANSFORM_H diff --git a/phonelibs/android_system_core/include/utils/List.h b/phonelibs/android_system_core/include/utils/List.h new file mode 100644 index 00000000000000..403cd7f1e54021 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/List.h @@ -0,0 +1,332 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Templated list class. Normally we'd use STL, but we don't have that. +// This class mimics STL's interfaces. +// +// Objects are copied into the list with the '=' operator or with copy- +// construction, so if the compiler's auto-generated versions won't work for +// you, define your own. +// +// The only class you want to use from here is "List". +// +#ifndef _LIBS_UTILS_LIST_H +#define _LIBS_UTILS_LIST_H + +#include +#include + +namespace android { + +/* + * Doubly-linked list. Instantiate with "List myList". + * + * Objects added to the list are copied using the assignment operator, + * so this must be defined. + */ +template +class List +{ +protected: + /* + * One element in the list. + */ + class _Node { + public: + explicit _Node(const T& val) : mVal(val) {} + ~_Node() {} + inline T& getRef() { return mVal; } + inline const T& getRef() const { return mVal; } + inline _Node* getPrev() const { return mpPrev; } + inline _Node* getNext() const { return mpNext; } + inline void setVal(const T& val) { mVal = val; } + inline void setPrev(_Node* ptr) { mpPrev = ptr; } + inline void setNext(_Node* ptr) { mpNext = ptr; } + private: + friend class List; + friend class _ListIterator; + T mVal; + _Node* mpPrev; + _Node* mpNext; + }; + + /* + * Iterator for walking through the list. + */ + + template + struct CONST_ITERATOR { + typedef _Node const * NodePtr; + typedef const TYPE Type; + }; + + template + struct NON_CONST_ITERATOR { + typedef _Node* NodePtr; + typedef TYPE Type; + }; + + template< + typename U, + template class Constness + > + class _ListIterator { + typedef _ListIterator _Iter; + typedef typename Constness::NodePtr _NodePtr; + typedef typename Constness::Type _Type; + + explicit _ListIterator(_NodePtr ptr) : mpNode(ptr) {} + + public: + _ListIterator() {} + _ListIterator(const _Iter& rhs) : mpNode(rhs.mpNode) {} + ~_ListIterator() {} + + // this will handle conversions from iterator to const_iterator + // (and also all convertible iterators) + // Here, in this implementation, the iterators can be converted + // if the nodes can be converted + template explicit + _ListIterator(const V& rhs) : mpNode(rhs.mpNode) {} + + + /* + * Dereference operator. Used to get at the juicy insides. + */ + _Type& operator*() const { return mpNode->getRef(); } + _Type* operator->() const { return &(mpNode->getRef()); } + + /* + * Iterator comparison. + */ + inline bool operator==(const _Iter& right) const { + return mpNode == right.mpNode; } + + inline bool operator!=(const _Iter& right) const { + return mpNode != right.mpNode; } + + /* + * handle comparisons between iterator and const_iterator + */ + template + inline bool operator==(const OTHER& right) const { + return mpNode == right.mpNode; } + + template + inline bool operator!=(const OTHER& right) const { + return mpNode != right.mpNode; } + + /* + * Incr/decr, used to move through the list. + */ + inline _Iter& operator++() { // pre-increment + mpNode = mpNode->getNext(); + return *this; + } + const _Iter operator++(int) { // post-increment + _Iter tmp(*this); + mpNode = mpNode->getNext(); + return tmp; + } + inline _Iter& operator--() { // pre-increment + mpNode = mpNode->getPrev(); + return *this; + } + const _Iter operator--(int) { // post-increment + _Iter tmp(*this); + mpNode = mpNode->getPrev(); + return tmp; + } + + inline _NodePtr getNode() const { return mpNode; } + + _NodePtr mpNode; /* should be private, but older gcc fails */ + private: + friend class List; + }; + +public: + List() { + prep(); + } + List(const List& src) { // copy-constructor + prep(); + insert(begin(), src.begin(), src.end()); + } + virtual ~List() { + clear(); + delete[] (unsigned char*) mpMiddle; + } + + typedef _ListIterator iterator; + typedef _ListIterator const_iterator; + + List& operator=(const List& right); + + /* returns true if the list is empty */ + inline bool empty() const { return mpMiddle->getNext() == mpMiddle; } + + /* return #of elements in list */ + size_t size() const { + return size_t(distance(begin(), end())); + } + + /* + * Return the first element or one past the last element. The + * _Node* we're returning is converted to an "iterator" by a + * constructor in _ListIterator. + */ + inline iterator begin() { + return iterator(mpMiddle->getNext()); + } + inline const_iterator begin() const { + return const_iterator(const_cast<_Node const*>(mpMiddle->getNext())); + } + inline iterator end() { + return iterator(mpMiddle); + } + inline const_iterator end() const { + return const_iterator(const_cast<_Node const*>(mpMiddle)); + } + + /* add the object to the head or tail of the list */ + void push_front(const T& val) { insert(begin(), val); } + void push_back(const T& val) { insert(end(), val); } + + /* insert before the current node; returns iterator at new node */ + iterator insert(iterator posn, const T& val) + { + _Node* newNode = new _Node(val); // alloc & copy-construct + newNode->setNext(posn.getNode()); + newNode->setPrev(posn.getNode()->getPrev()); + posn.getNode()->getPrev()->setNext(newNode); + posn.getNode()->setPrev(newNode); + return iterator(newNode); + } + + /* insert a range of elements before the current node */ + void insert(iterator posn, const_iterator first, const_iterator last) { + for ( ; first != last; ++first) + insert(posn, *first); + } + + /* remove one entry; returns iterator at next node */ + iterator erase(iterator posn) { + _Node* pNext = posn.getNode()->getNext(); + _Node* pPrev = posn.getNode()->getPrev(); + pPrev->setNext(pNext); + pNext->setPrev(pPrev); + delete posn.getNode(); + return iterator(pNext); + } + + /* remove a range of elements */ + iterator erase(iterator first, iterator last) { + while (first != last) + erase(first++); // don't erase than incr later! + return iterator(last); + } + + /* remove all contents of the list */ + void clear() { + _Node* pCurrent = mpMiddle->getNext(); + _Node* pNext; + + while (pCurrent != mpMiddle) { + pNext = pCurrent->getNext(); + delete pCurrent; + pCurrent = pNext; + } + mpMiddle->setPrev(mpMiddle); + mpMiddle->setNext(mpMiddle); + } + + /* + * Measure the distance between two iterators. On exist, "first" + * will be equal to "last". The iterators must refer to the same + * list. + * + * FIXME: This is actually a generic iterator function. It should be a + * template function at the top-level with specializations for things like + * vector<>, which can just do pointer math). Here we limit it to + * _ListIterator of the same type but different constness. + */ + template< + typename U, + template class CL, + template class CR + > + ptrdiff_t distance( + _ListIterator first, _ListIterator last) const + { + ptrdiff_t count = 0; + while (first != last) { + ++first; + ++count; + } + return count; + } + +private: + /* + * I want a _Node but don't need it to hold valid data. More + * to the point, I don't want T's constructor to fire, since it + * might have side-effects or require arguments. So, we do this + * slightly uncouth storage alloc. + */ + void prep() { + mpMiddle = (_Node*) new unsigned char[sizeof(_Node)]; + mpMiddle->setPrev(mpMiddle); + mpMiddle->setNext(mpMiddle); + } + + /* + * This node plays the role of "pointer to head" and "pointer to tail". + * It sits in the middle of a circular list of nodes. The iterator + * runs around the circle until it encounters this one. + */ + _Node* mpMiddle; +}; + +/* + * Assignment operator. + * + * The simplest way to do this would be to clear out the target list and + * fill it with the source. However, we can speed things along by + * re-using existing elements. + */ +template +List& List::operator=(const List& right) +{ + if (this == &right) + return *this; // self-assignment + iterator firstDst = begin(); + iterator lastDst = end(); + const_iterator firstSrc = right.begin(); + const_iterator lastSrc = right.end(); + while (firstSrc != lastSrc && firstDst != lastDst) + *firstDst++ = *firstSrc++; + if (firstSrc == lastSrc) // ran out of elements in source? + erase(firstDst, lastDst); // yes, erase any extras + else + insert(lastDst, firstSrc, lastSrc); // copy remaining over + return *this; +} + +}; // namespace android + +#endif // _LIBS_UTILS_LIST_H diff --git a/phonelibs/android_system_core/include/utils/Log.h b/phonelibs/android_system_core/include/utils/Log.h new file mode 100644 index 00000000000000..4259c86d1ac486 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Log.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// C/C++ logging functions. See the logging documentation for API details. +// +// We'd like these to be available from C code (in case we import some from +// somewhere), so this has a C interface. +// +// The output will be correct when the log file is shared between multiple +// threads and/or multiple processes so long as the operating system +// supports O_APPEND. These calls have mutex-protected data structures +// and so are NOT reentrant. Do not use LOG in a signal handler. +// +#ifndef _LIBS_UTILS_LOG_H +#define _LIBS_UTILS_LOG_H + +#include +#include + +#ifdef __cplusplus + +namespace android { + +/* + * A very simple utility that yells in the log when an operation takes too long. + */ +class LogIfSlow { +public: + LogIfSlow(const char* tag, android_LogPriority priority, + int timeoutMillis, const char* message); + ~LogIfSlow(); + +private: + const char* const mTag; + const android_LogPriority mPriority; + const int mTimeoutMillis; + const char* const mMessage; + const int64_t mStart; +}; + +/* + * Writes the specified debug log message if this block takes longer than the + * specified number of milliseconds to run. Includes the time actually taken. + * + * { + * ALOGD_IF_SLOW(50, "Excessive delay doing something."); + * doSomething(); + * } + */ +#define ALOGD_IF_SLOW(timeoutMillis, message) \ + android::LogIfSlow _logIfSlow(LOG_TAG, ANDROID_LOG_DEBUG, timeoutMillis, message); + +} // namespace android + +#endif // __cplusplus + +#endif // _LIBS_UTILS_LOG_H diff --git a/phonelibs/android_system_core/include/utils/Looper.h b/phonelibs/android_system_core/include/utils/Looper.h new file mode 100644 index 00000000000000..da2d5f2b5bdba7 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Looper.h @@ -0,0 +1,487 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTILS_LOOPER_H +#define UTILS_LOOPER_H + +#include +#include +#include +#include + +#include + +namespace android { + +/* + * NOTE: Since Looper is used to implement the NDK ALooper, the Looper + * enums and the signature of Looper_callbackFunc need to align with + * that implementation. + */ + +/** + * For callback-based event loops, this is the prototype of the function + * that is called when a file descriptor event occurs. + * It is given the file descriptor it is associated with, + * a bitmask of the poll events that were triggered (typically EVENT_INPUT), + * and the data pointer that was originally supplied. + * + * Implementations should return 1 to continue receiving callbacks, or 0 + * to have this file descriptor and callback unregistered from the looper. + */ +typedef int (*Looper_callbackFunc)(int fd, int events, void* data); + +/** + * A message that can be posted to a Looper. + */ +struct Message { + Message() : what(0) { } + Message(int what) : what(what) { } + + /* The message type. (interpretation is left up to the handler) */ + int what; +}; + + +/** + * Interface for a Looper message handler. + * + * The Looper holds a strong reference to the message handler whenever it has + * a message to deliver to it. Make sure to call Looper::removeMessages + * to remove any pending messages destined for the handler so that the handler + * can be destroyed. + */ +class MessageHandler : public virtual RefBase { +protected: + virtual ~MessageHandler() { } + +public: + /** + * Handles a message. + */ + virtual void handleMessage(const Message& message) = 0; +}; + + +/** + * A simple proxy that holds a weak reference to a message handler. + */ +class WeakMessageHandler : public MessageHandler { +protected: + virtual ~WeakMessageHandler(); + +public: + WeakMessageHandler(const wp& handler); + virtual void handleMessage(const Message& message); + +private: + wp mHandler; +}; + + +/** + * A looper callback. + */ +class LooperCallback : public virtual RefBase { +protected: + virtual ~LooperCallback() { } + +public: + /** + * Handles a poll event for the given file descriptor. + * It is given the file descriptor it is associated with, + * a bitmask of the poll events that were triggered (typically EVENT_INPUT), + * and the data pointer that was originally supplied. + * + * Implementations should return 1 to continue receiving callbacks, or 0 + * to have this file descriptor and callback unregistered from the looper. + */ + virtual int handleEvent(int fd, int events, void* data) = 0; +}; + +/** + * Wraps a Looper_callbackFunc function pointer. + */ +class SimpleLooperCallback : public LooperCallback { +protected: + virtual ~SimpleLooperCallback(); + +public: + SimpleLooperCallback(Looper_callbackFunc callback); + virtual int handleEvent(int fd, int events, void* data); + +private: + Looper_callbackFunc mCallback; +}; + +/** + * A polling loop that supports monitoring file descriptor events, optionally + * using callbacks. The implementation uses epoll() internally. + * + * A looper can be associated with a thread although there is no requirement that it must be. + */ +class Looper : public RefBase { +protected: + virtual ~Looper(); + +public: + enum { + /** + * Result from Looper_pollOnce() and Looper_pollAll(): + * The poll was awoken using wake() before the timeout expired + * and no callbacks were executed and no other file descriptors were ready. + */ + POLL_WAKE = -1, + + /** + * Result from Looper_pollOnce() and Looper_pollAll(): + * One or more callbacks were executed. + */ + POLL_CALLBACK = -2, + + /** + * Result from Looper_pollOnce() and Looper_pollAll(): + * The timeout expired. + */ + POLL_TIMEOUT = -3, + + /** + * Result from Looper_pollOnce() and Looper_pollAll(): + * An error occurred. + */ + POLL_ERROR = -4, + }; + + /** + * Flags for file descriptor events that a looper can monitor. + * + * These flag bits can be combined to monitor multiple events at once. + */ + enum { + /** + * The file descriptor is available for read operations. + */ + EVENT_INPUT = 1 << 0, + + /** + * The file descriptor is available for write operations. + */ + EVENT_OUTPUT = 1 << 1, + + /** + * The file descriptor has encountered an error condition. + * + * The looper always sends notifications about errors; it is not necessary + * to specify this event flag in the requested event set. + */ + EVENT_ERROR = 1 << 2, + + /** + * The file descriptor was hung up. + * For example, indicates that the remote end of a pipe or socket was closed. + * + * The looper always sends notifications about hangups; it is not necessary + * to specify this event flag in the requested event set. + */ + EVENT_HANGUP = 1 << 3, + + /** + * The file descriptor is invalid. + * For example, the file descriptor was closed prematurely. + * + * The looper always sends notifications about invalid file descriptors; it is not necessary + * to specify this event flag in the requested event set. + */ + EVENT_INVALID = 1 << 4, + }; + + enum { + /** + * Option for Looper_prepare: this looper will accept calls to + * Looper_addFd() that do not have a callback (that is provide NULL + * for the callback). In this case the caller of Looper_pollOnce() + * or Looper_pollAll() MUST check the return from these functions to + * discover when data is available on such fds and process it. + */ + PREPARE_ALLOW_NON_CALLBACKS = 1<<0 + }; + + /** + * Creates a looper. + * + * If allowNonCallbaks is true, the looper will allow file descriptors to be + * registered without associated callbacks. This assumes that the caller of + * pollOnce() is prepared to handle callback-less events itself. + */ + Looper(bool allowNonCallbacks); + + /** + * Returns whether this looper instance allows the registration of file descriptors + * using identifiers instead of callbacks. + */ + bool getAllowNonCallbacks() const; + + /** + * Waits for events to be available, with optional timeout in milliseconds. + * Invokes callbacks for all file descriptors on which an event occurred. + * + * If the timeout is zero, returns immediately without blocking. + * If the timeout is negative, waits indefinitely until an event appears. + * + * Returns POLL_WAKE if the poll was awoken using wake() before + * the timeout expired and no callbacks were invoked and no other file + * descriptors were ready. + * + * Returns POLL_CALLBACK if one or more callbacks were invoked. + * + * Returns POLL_TIMEOUT if there was no data before the given + * timeout expired. + * + * Returns POLL_ERROR if an error occurred. + * + * Returns a value >= 0 containing an identifier if its file descriptor has data + * and it has no callback function (requiring the caller here to handle it). + * In this (and only this) case outFd, outEvents and outData will contain the poll + * events and data associated with the fd, otherwise they will be set to NULL. + * + * This method does not return until it has finished invoking the appropriate callbacks + * for all file descriptors that were signalled. + */ + int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData); + inline int pollOnce(int timeoutMillis) { + return pollOnce(timeoutMillis, NULL, NULL, NULL); + } + + /** + * Like pollOnce(), but performs all pending callbacks until all + * data has been consumed or a file descriptor is available with no callback. + * This function will never return POLL_CALLBACK. + */ + int pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData); + inline int pollAll(int timeoutMillis) { + return pollAll(timeoutMillis, NULL, NULL, NULL); + } + + /** + * Wakes the poll asynchronously. + * + * This method can be called on any thread. + * This method returns immediately. + */ + void wake(); + + /** + * Adds a new file descriptor to be polled by the looper. + * If the same file descriptor was previously added, it is replaced. + * + * "fd" is the file descriptor to be added. + * "ident" is an identifier for this event, which is returned from pollOnce(). + * The identifier must be >= 0, or POLL_CALLBACK if providing a non-NULL callback. + * "events" are the poll events to wake up on. Typically this is EVENT_INPUT. + * "callback" is the function to call when there is an event on the file descriptor. + * "data" is a private data pointer to supply to the callback. + * + * There are two main uses of this function: + * + * (1) If "callback" is non-NULL, then this function will be called when there is + * data on the file descriptor. It should execute any events it has pending, + * appropriately reading from the file descriptor. The 'ident' is ignored in this case. + * + * (2) If "callback" is NULL, the 'ident' will be returned by Looper_pollOnce + * when its file descriptor has data available, requiring the caller to take + * care of processing it. + * + * Returns 1 if the file descriptor was added, 0 if the arguments were invalid. + * + * This method can be called on any thread. + * This method may block briefly if it needs to wake the poll. + * + * The callback may either be specified as a bare function pointer or as a smart + * pointer callback object. The smart pointer should be preferred because it is + * easier to avoid races when the callback is removed from a different thread. + * See removeFd() for details. + */ + int addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data); + int addFd(int fd, int ident, int events, const sp& callback, void* data); + + /** + * Removes a previously added file descriptor from the looper. + * + * When this method returns, it is safe to close the file descriptor since the looper + * will no longer have a reference to it. However, it is possible for the callback to + * already be running or for it to run one last time if the file descriptor was already + * signalled. Calling code is responsible for ensuring that this case is safely handled. + * For example, if the callback takes care of removing itself during its own execution either + * by returning 0 or by calling this method, then it can be guaranteed to not be invoked + * again at any later time unless registered anew. + * + * A simple way to avoid this problem is to use the version of addFd() that takes + * a sp instead of a bare function pointer. The LooperCallback will + * be released at the appropriate time by the Looper. + * + * Returns 1 if the file descriptor was removed, 0 if none was previously registered. + * + * This method can be called on any thread. + * This method may block briefly if it needs to wake the poll. + */ + int removeFd(int fd); + + /** + * Enqueues a message to be processed by the specified handler. + * + * The handler must not be null. + * This method can be called on any thread. + */ + void sendMessage(const sp& handler, const Message& message); + + /** + * Enqueues a message to be processed by the specified handler after all pending messages + * after the specified delay. + * + * The time delay is specified in uptime nanoseconds. + * The handler must not be null. + * This method can be called on any thread. + */ + void sendMessageDelayed(nsecs_t uptimeDelay, const sp& handler, + const Message& message); + + /** + * Enqueues a message to be processed by the specified handler after all pending messages + * at the specified time. + * + * The time is specified in uptime nanoseconds. + * The handler must not be null. + * This method can be called on any thread. + */ + void sendMessageAtTime(nsecs_t uptime, const sp& handler, + const Message& message); + + /** + * Removes all messages for the specified handler from the queue. + * + * The handler must not be null. + * This method can be called on any thread. + */ + void removeMessages(const sp& handler); + + /** + * Removes all messages of a particular type for the specified handler from the queue. + * + * The handler must not be null. + * This method can be called on any thread. + */ + void removeMessages(const sp& handler, int what); + + /** + * Returns whether this looper's thread is currently polling for more work to do. + * This is a good signal that the loop is still alive rather than being stuck + * handling a callback. Note that this method is intrinsically racy, since the + * state of the loop can change before you get the result back. + */ + bool isPolling() const; + + /** + * Prepares a looper associated with the calling thread, and returns it. + * If the thread already has a looper, it is returned. Otherwise, a new + * one is created, associated with the thread, and returned. + * + * The opts may be PREPARE_ALLOW_NON_CALLBACKS or 0. + */ + static sp prepare(int opts); + + /** + * Sets the given looper to be associated with the calling thread. + * If another looper is already associated with the thread, it is replaced. + * + * If "looper" is NULL, removes the currently associated looper. + */ + static void setForThread(const sp& looper); + + /** + * Returns the looper associated with the calling thread, or NULL if + * there is not one. + */ + static sp getForThread(); + +private: + struct Request { + int fd; + int ident; + int events; + int seq; + sp callback; + void* data; + + void initEventItem(struct epoll_event* eventItem) const; + }; + + struct Response { + int events; + Request request; + }; + + struct MessageEnvelope { + MessageEnvelope() : uptime(0) { } + + MessageEnvelope(nsecs_t uptime, const sp handler, + const Message& message) : uptime(uptime), handler(handler), message(message) { + } + + nsecs_t uptime; + sp handler; + Message message; + }; + + const bool mAllowNonCallbacks; // immutable + + int mWakeEventFd; // immutable + Mutex mLock; + + Vector mMessageEnvelopes; // guarded by mLock + bool mSendingMessage; // guarded by mLock + + // Whether we are currently waiting for work. Not protected by a lock, + // any use of it is racy anyway. + volatile bool mPolling; + + int mEpollFd; // guarded by mLock but only modified on the looper thread + bool mEpollRebuildRequired; // guarded by mLock + + // Locked list of file descriptor monitoring requests. + KeyedVector mRequests; // guarded by mLock + int mNextRequestSeq; + + // This state is only used privately by pollOnce and does not require a lock since + // it runs on a single thread. + Vector mResponses; + size_t mResponseIndex; + nsecs_t mNextMessageUptime; // set to LLONG_MAX when none + + int pollInner(int timeoutMillis); + int removeFd(int fd, int seq); + void awoken(); + void pushResponse(int events, const Request& request); + void rebuildEpollLocked(); + void scheduleEpollRebuildLocked(); + + static void initTLSKey(); + static void threadDestructor(void *st); + static void initEpollEvent(struct epoll_event* eventItem); +}; + +} // namespace android + +#endif // UTILS_LOOPER_H diff --git a/phonelibs/android_system_core/include/utils/LruCache.h b/phonelibs/android_system_core/include/utils/LruCache.h new file mode 100644 index 00000000000000..cd9d7f94a024c0 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/LruCache.h @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UTILS_LRU_CACHE_H +#define ANDROID_UTILS_LRU_CACHE_H + +#include +#include + +namespace android { + +/** + * GenerationCache callback used when an item is removed + */ +template +class OnEntryRemoved { +public: + virtual ~OnEntryRemoved() { }; + virtual void operator()(EntryKey& key, EntryValue& value) = 0; +}; // class OnEntryRemoved + +template +class LruCache { +public: + explicit LruCache(uint32_t maxCapacity); + + enum Capacity { + kUnlimitedCapacity, + }; + + void setOnEntryRemovedListener(OnEntryRemoved* listener); + size_t size() const; + const TValue& get(const TKey& key); + bool put(const TKey& key, const TValue& value); + bool remove(const TKey& key); + bool removeOldest(); + void clear(); + const TValue& peekOldestValue(); + + class Iterator { + public: + Iterator(const LruCache& cache): mCache(cache), mIndex(-1) { + } + + bool next() { + mIndex = mCache.mTable->next(mIndex); + return (ssize_t)mIndex != -1; + } + + size_t index() const { + return mIndex; + } + + const TValue& value() const { + return mCache.mTable->entryAt(mIndex).value; + } + + const TKey& key() const { + return mCache.mTable->entryAt(mIndex).key; + } + private: + const LruCache& mCache; + size_t mIndex; + }; + +private: + LruCache(const LruCache& that); // disallow copy constructor + + struct Entry { + TKey key; + TValue value; + Entry* parent; + Entry* child; + + Entry(TKey key_, TValue value_) : key(key_), value(value_), parent(NULL), child(NULL) { + } + const TKey& getKey() const { return key; } + }; + + void attachToCache(Entry& entry); + void detachFromCache(Entry& entry); + void rehash(size_t newCapacity); + + UniquePtr > mTable; + OnEntryRemoved* mListener; + Entry* mOldest; + Entry* mYoungest; + uint32_t mMaxCapacity; + TValue mNullValue; +}; + +// Implementation is here, because it's fully templated +template +LruCache::LruCache(uint32_t maxCapacity) + : mTable(new BasicHashtable) + , mListener(NULL) + , mOldest(NULL) + , mYoungest(NULL) + , mMaxCapacity(maxCapacity) + , mNullValue(NULL) { +}; + +template +void LruCache::setOnEntryRemovedListener(OnEntryRemoved* listener) { + mListener = listener; +} + +template +size_t LruCache::size() const { + return mTable->size(); +} + +template +const TValue& LruCache::get(const TKey& key) { + hash_t hash = hash_type(key); + ssize_t index = mTable->find(-1, hash, key); + if (index == -1) { + return mNullValue; + } + Entry& entry = mTable->editEntryAt(index); + detachFromCache(entry); + attachToCache(entry); + return entry.value; +} + +template +bool LruCache::put(const TKey& key, const TValue& value) { + if (mMaxCapacity != kUnlimitedCapacity && size() >= mMaxCapacity) { + removeOldest(); + } + + hash_t hash = hash_type(key); + ssize_t index = mTable->find(-1, hash, key); + if (index >= 0) { + return false; + } + if (!mTable->hasMoreRoom()) { + rehash(mTable->capacity() * 2); + } + + // Would it be better to initialize a blank entry and assign key, value? + Entry initEntry(key, value); + index = mTable->add(hash, initEntry); + Entry& entry = mTable->editEntryAt(index); + attachToCache(entry); + return true; +} + +template +bool LruCache::remove(const TKey& key) { + hash_t hash = hash_type(key); + ssize_t index = mTable->find(-1, hash, key); + if (index < 0) { + return false; + } + Entry& entry = mTable->editEntryAt(index); + if (mListener) { + (*mListener)(entry.key, entry.value); + } + detachFromCache(entry); + mTable->removeAt(index); + return true; +} + +template +bool LruCache::removeOldest() { + if (mOldest != NULL) { + return remove(mOldest->key); + // TODO: should probably abort if false + } + return false; +} + +template +const TValue& LruCache::peekOldestValue() { + if (mOldest) { + return mOldest->value; + } + return mNullValue; +} + +template +void LruCache::clear() { + if (mListener) { + for (Entry* p = mOldest; p != NULL; p = p->child) { + (*mListener)(p->key, p->value); + } + } + mYoungest = NULL; + mOldest = NULL; + mTable->clear(); +} + +template +void LruCache::attachToCache(Entry& entry) { + if (mYoungest == NULL) { + mYoungest = mOldest = &entry; + } else { + entry.parent = mYoungest; + mYoungest->child = &entry; + mYoungest = &entry; + } +} + +template +void LruCache::detachFromCache(Entry& entry) { + if (entry.parent != NULL) { + entry.parent->child = entry.child; + } else { + mOldest = entry.child; + } + if (entry.child != NULL) { + entry.child->parent = entry.parent; + } else { + mYoungest = entry.parent; + } + + entry.parent = NULL; + entry.child = NULL; +} + +template +void LruCache::rehash(size_t newCapacity) { + UniquePtr > oldTable(mTable.release()); + Entry* oldest = mOldest; + + mOldest = NULL; + mYoungest = NULL; + mTable.reset(new BasicHashtable(newCapacity)); + for (Entry* p = oldest; p != NULL; p = p->child) { + put(p->key, p->value); + } +} + +} + +#endif // ANDROID_UTILS_LRU_CACHE_H diff --git a/phonelibs/android_system_core/include/utils/Mutex.h b/phonelibs/android_system_core/include/utils/Mutex.h new file mode 100644 index 00000000000000..757519b0860c23 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Mutex.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_UTILS_MUTEX_H +#define _LIBS_UTILS_MUTEX_H + +#include +#include +#include + +#if !defined(_WIN32) +# include +#endif + +#include +#include + +// --------------------------------------------------------------------------- +namespace android { +// --------------------------------------------------------------------------- + +class Condition; + +/* + * Simple mutex class. The implementation is system-dependent. + * + * The mutex must be unlocked by the thread that locked it. They are not + * recursive, i.e. the same thread can't lock it multiple times. + */ +class Mutex { +public: + enum { + PRIVATE = 0, + SHARED = 1 + }; + + Mutex(); + Mutex(const char* name); + Mutex(int type, const char* name = NULL); + ~Mutex(); + + // lock or unlock the mutex + status_t lock(); + void unlock(); + + // lock if possible; returns 0 on success, error otherwise + status_t tryLock(); + +#if HAVE_ANDROID_OS + // lock the mutex, but don't wait longer than timeoutMilliseconds. + // Returns 0 on success, TIMED_OUT for failure due to timeout expiration. + // + // OSX doesn't have pthread_mutex_timedlock() or equivalent. To keep + // capabilities consistent across host OSes, this method is only available + // when building Android binaries. + status_t timedLock(nsecs_t timeoutMilliseconds); +#endif + + // Manages the mutex automatically. It'll be locked when Autolock is + // constructed and released when Autolock goes out of scope. + class Autolock { + public: + inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); } + inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); } + inline ~Autolock() { mLock.unlock(); } + private: + Mutex& mLock; + }; + +private: + friend class Condition; + + // A mutex cannot be copied + Mutex(const Mutex&); + Mutex& operator = (const Mutex&); + +#if !defined(_WIN32) + pthread_mutex_t mMutex; +#else + void _init(); + void* mState; +#endif +}; + +// --------------------------------------------------------------------------- + +#if !defined(_WIN32) + +inline Mutex::Mutex() { + pthread_mutex_init(&mMutex, NULL); +} +inline Mutex::Mutex(__attribute__((unused)) const char* name) { + pthread_mutex_init(&mMutex, NULL); +} +inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) { + if (type == SHARED) { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + pthread_mutex_init(&mMutex, &attr); + pthread_mutexattr_destroy(&attr); + } else { + pthread_mutex_init(&mMutex, NULL); + } +} +inline Mutex::~Mutex() { + pthread_mutex_destroy(&mMutex); +} +inline status_t Mutex::lock() { + return -pthread_mutex_lock(&mMutex); +} +inline void Mutex::unlock() { + pthread_mutex_unlock(&mMutex); +} +inline status_t Mutex::tryLock() { + return -pthread_mutex_trylock(&mMutex); +} +#if HAVE_ANDROID_OS +inline status_t Mutex::timedLock(nsecs_t timeoutNs) { + const struct timespec ts = { + /* .tv_sec = */ static_cast(timeoutNs / 1000000000), + /* .tv_nsec = */ static_cast(timeoutNs % 1000000000), + }; + return -pthread_mutex_timedlock(&mMutex, &ts); +} +#endif + +#endif // !defined(_WIN32) + +// --------------------------------------------------------------------------- + +/* + * Automatic mutex. Declare one of these at the top of a function. + * When the function returns, it will go out of scope, and release the + * mutex. + */ + +typedef Mutex::Autolock AutoMutex; + +// --------------------------------------------------------------------------- +}; // namespace android +// --------------------------------------------------------------------------- + +#endif // _LIBS_UTILS_MUTEX_H diff --git a/phonelibs/android_system_core/include/utils/NativeHandle.h b/phonelibs/android_system_core/include/utils/NativeHandle.h new file mode 100644 index 00000000000000..b82516879ad474 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/NativeHandle.h @@ -0,0 +1,56 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_NATIVE_HANDLE_H +#define ANDROID_NATIVE_HANDLE_H + +#include +#include + +typedef struct native_handle native_handle_t; + +namespace android { + +class NativeHandle: public LightRefBase { +public: + // Create a refcounted wrapper around a native_handle_t, and declare + // whether the wrapper owns the handle (so that it should clean up the + // handle upon destruction) or not. + // If handle is NULL, no NativeHandle will be created. + static sp create(native_handle_t* handle, bool ownsHandle); + + const native_handle_t* handle() const { + return mHandle; + } + +private: + // for access to the destructor + friend class LightRefBase; + + NativeHandle(native_handle_t* handle, bool ownsHandle); + virtual ~NativeHandle(); + + native_handle_t* mHandle; + bool mOwnsHandle; + + // non-copyable + NativeHandle(const NativeHandle&); + NativeHandle& operator=(const NativeHandle&); +}; + +} // namespace android + +#endif // ANDROID_NATIVE_HANDLE_H diff --git a/phonelibs/android_system_core/include/utils/Printer.h b/phonelibs/android_system_core/include/utils/Printer.h new file mode 100644 index 00000000000000..bb6628767ca893 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Printer.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_PRINTER_H +#define ANDROID_PRINTER_H + +#include + +namespace android { + +// Interface for printing to an arbitrary data stream +class Printer { +public: + // Print a new line specified by 'string'. \n is appended automatically. + // -- Assumes that the string has no new line in it. + virtual void printLine(const char* string = "") = 0; + + // Print a new line specified by the format string. \n is appended automatically. + // -- Assumes that the resulting string has no new line in it. + virtual void printFormatLine(const char* format, ...) __attribute__((format (printf, 2, 3))); + +protected: + Printer(); + virtual ~Printer(); +}; // class Printer + +// Print to logcat +class LogPrinter : public Printer { +public: + // Create a printer using the specified logcat and log priority + // - Unless ignoreBlankLines is false, print blank lines to logcat + // (Note that the default ALOG behavior is to ignore blank lines) + LogPrinter(const char* logtag, + android_LogPriority priority = ANDROID_LOG_DEBUG, + const char* prefix = 0, + bool ignoreBlankLines = false); + + // Print the specified line to logcat. No \n at the end is necessary. + virtual void printLine(const char* string); + +private: + void printRaw(const char* string); + + const char* mLogTag; + android_LogPriority mPriority; + const char* mPrefix; + bool mIgnoreBlankLines; +}; // class LogPrinter + +// Print to a file descriptor +class FdPrinter : public Printer { +public: + // Create a printer using the specified file descriptor. + // - Each line will be prefixed with 'indent' number of blank spaces. + // - In addition, each line will be prefixed with the 'prefix' string. + FdPrinter(int fd, unsigned int indent = 0, const char* prefix = 0); + + // Print the specified line to the file descriptor. \n is appended automatically. + virtual void printLine(const char* string); + +private: + enum { + MAX_FORMAT_STRING = 20, + }; + + int mFd; + unsigned int mIndent; + const char* mPrefix; + char mFormatString[MAX_FORMAT_STRING]; +}; // class FdPrinter + +class String8; + +// Print to a String8 +class String8Printer : public Printer { +public: + // Create a printer using the specified String8 as the target. + // - In addition, each line will be prefixed with the 'prefix' string. + // - target's memory lifetime must be a superset of this String8Printer. + String8Printer(String8* target, const char* prefix = 0); + + // Append the specified line to the String8. \n is appended automatically. + virtual void printLine(const char* string); + +private: + String8* mTarget; + const char* mPrefix; +}; // class String8Printer + +// Print to an existing Printer by adding a prefix to each line +class PrefixPrinter : public Printer { +public: + // Create a printer using the specified printer as the target. + PrefixPrinter(Printer& printer, const char* prefix); + + // Print the line (prefixed with prefix) using the printer. + virtual void printLine(const char* string); + +private: + Printer& mPrinter; + const char* mPrefix; +}; + +}; // namespace android + +#endif // ANDROID_PRINTER_H diff --git a/phonelibs/android_system_core/include/utils/ProcessCallStack.h b/phonelibs/android_system_core/include/utils/ProcessCallStack.h new file mode 100644 index 00000000000000..32458b8b14979a --- /dev/null +++ b/phonelibs/android_system_core/include/utils/ProcessCallStack.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_PROCESS_CALLSTACK_H +#define ANDROID_PROCESS_CALLSTACK_H + +#include +#include +#include +#include + +#include +#include + +namespace android { + +class Printer; + +// Collect/print the call stack (function, file, line) traces for all threads in a process. +class ProcessCallStack { +public: + // Create an empty call stack. No-op. + ProcessCallStack(); + // Copy the existing process callstack (no other side effects). + ProcessCallStack(const ProcessCallStack& rhs); + ~ProcessCallStack(); + + // Immediately collect the stack traces for all threads. + void update(); + + // Print all stack traces to the log using the supplied logtag. + void log(const char* logtag, android_LogPriority priority = ANDROID_LOG_DEBUG, + const char* prefix = 0) const; + + // Dump all stack traces to the specified file descriptor. + void dump(int fd, int indent = 0, const char* prefix = 0) const; + + // Return a string (possibly very long) containing all the stack traces. + String8 toString(const char* prefix = 0) const; + + // Dump a serialized representation of all the stack traces to the specified printer. + void print(Printer& printer) const; + + // Get the number of threads whose stack traces were collected. + size_t size() const; + +private: + void printInternal(Printer& printer, Printer& csPrinter) const; + + // Reset the process's stack frames and metadata. + void clear(); + + struct ThreadInfo { + CallStack callStack; + String8 threadName; + }; + + // tid -> ThreadInfo + KeyedVector mThreadMap; + // Time that update() was last called + struct tm mTimeUpdated; +}; + +}; // namespace android + +#endif // ANDROID_PROCESS_CALLSTACK_H diff --git a/phonelibs/android_system_core/include/utils/PropertyMap.h b/phonelibs/android_system_core/include/utils/PropertyMap.h new file mode 100644 index 00000000000000..a9e674f9afb1f1 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/PropertyMap.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _UTILS_PROPERTY_MAP_H +#define _UTILS_PROPERTY_MAP_H + +#include +#include +#include +#include + +namespace android { + +/* + * Provides a mechanism for passing around string-based property key / value pairs + * and loading them from property files. + * + * The property files have the following simple structure: + * + * # Comment + * key = value + * + * Keys and values are any sequence of printable ASCII characters. + * The '=' separates the key from the value. + * The key and value may not contain whitespace. + * + * The '\' character is reserved for escape sequences and is not currently supported. + * The '"" character is reserved for quoting and is not currently supported. + * Files that contain the '\' or '"' character will fail to parse. + * + * The file must not contain duplicate keys. + * + * TODO Support escape sequences and quoted values when needed. + */ +class PropertyMap { +public: + /* Creates an empty property map. */ + PropertyMap(); + ~PropertyMap(); + + /* Clears the property map. */ + void clear(); + + /* Adds a property. + * Replaces the property with the same key if it is already present. + */ + void addProperty(const String8& key, const String8& value); + + /* Returns true if the property map contains the specified key. */ + bool hasProperty(const String8& key) const; + + /* Gets the value of a property and parses it. + * Returns true and sets outValue if the key was found and its value was parsed successfully. + * Otherwise returns false and does not modify outValue. (Also logs a warning.) + */ + bool tryGetProperty(const String8& key, String8& outValue) const; + bool tryGetProperty(const String8& key, bool& outValue) const; + bool tryGetProperty(const String8& key, int32_t& outValue) const; + bool tryGetProperty(const String8& key, float& outValue) const; + + /* Adds all values from the specified property map. */ + void addAll(const PropertyMap* map); + + /* Gets the underlying property map. */ + inline const KeyedVector& getProperties() const { return mProperties; } + + /* Loads a property map from a file. */ + static status_t load(const String8& filename, PropertyMap** outMap); + +private: + class Parser { + PropertyMap* mMap; + Tokenizer* mTokenizer; + + public: + Parser(PropertyMap* map, Tokenizer* tokenizer); + ~Parser(); + status_t parse(); + + private: + status_t parseType(); + status_t parseKey(); + status_t parseKeyProperty(); + status_t parseModifier(const String8& token, int32_t* outMetaState); + status_t parseCharacterLiteral(char16_t* outCharacter); + }; + + KeyedVector mProperties; +}; + +} // namespace android + +#endif // _UTILS_PROPERTY_MAP_H diff --git a/phonelibs/android_system_core/include/utils/RWLock.h b/phonelibs/android_system_core/include/utils/RWLock.h new file mode 100644 index 00000000000000..e743b1c8ced05a --- /dev/null +++ b/phonelibs/android_system_core/include/utils/RWLock.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_UTILS_RWLOCK_H +#define _LIBS_UTILS_RWLOCK_H + +#include +#include + +#if !defined(_WIN32) +# include +#endif + +#include +#include + +// --------------------------------------------------------------------------- +namespace android { +// --------------------------------------------------------------------------- + +#if !defined(_WIN32) + +/* + * Simple mutex class. The implementation is system-dependent. + * + * The mutex must be unlocked by the thread that locked it. They are not + * recursive, i.e. the same thread can't lock it multiple times. + */ +class RWLock { +public: + enum { + PRIVATE = 0, + SHARED = 1 + }; + + RWLock(); + RWLock(const char* name); + RWLock(int type, const char* name = NULL); + ~RWLock(); + + status_t readLock(); + status_t tryReadLock(); + status_t writeLock(); + status_t tryWriteLock(); + void unlock(); + + class AutoRLock { + public: + inline AutoRLock(RWLock& rwlock) : mLock(rwlock) { mLock.readLock(); } + inline ~AutoRLock() { mLock.unlock(); } + private: + RWLock& mLock; + }; + + class AutoWLock { + public: + inline AutoWLock(RWLock& rwlock) : mLock(rwlock) { mLock.writeLock(); } + inline ~AutoWLock() { mLock.unlock(); } + private: + RWLock& mLock; + }; + +private: + // A RWLock cannot be copied + RWLock(const RWLock&); + RWLock& operator = (const RWLock&); + + pthread_rwlock_t mRWLock; +}; + +inline RWLock::RWLock() { + pthread_rwlock_init(&mRWLock, NULL); +} +inline RWLock::RWLock(__attribute__((unused)) const char* name) { + pthread_rwlock_init(&mRWLock, NULL); +} +inline RWLock::RWLock(int type, __attribute__((unused)) const char* name) { + if (type == SHARED) { + pthread_rwlockattr_t attr; + pthread_rwlockattr_init(&attr); + pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + pthread_rwlock_init(&mRWLock, &attr); + pthread_rwlockattr_destroy(&attr); + } else { + pthread_rwlock_init(&mRWLock, NULL); + } +} +inline RWLock::~RWLock() { + pthread_rwlock_destroy(&mRWLock); +} +inline status_t RWLock::readLock() { + return -pthread_rwlock_rdlock(&mRWLock); +} +inline status_t RWLock::tryReadLock() { + return -pthread_rwlock_tryrdlock(&mRWLock); +} +inline status_t RWLock::writeLock() { + return -pthread_rwlock_wrlock(&mRWLock); +} +inline status_t RWLock::tryWriteLock() { + return -pthread_rwlock_trywrlock(&mRWLock); +} +inline void RWLock::unlock() { + pthread_rwlock_unlock(&mRWLock); +} + +#endif // !defined(_WIN32) + +// --------------------------------------------------------------------------- +}; // namespace android +// --------------------------------------------------------------------------- + +#endif // _LIBS_UTILS_RWLOCK_H diff --git a/phonelibs/android_system_core/include/utils/RefBase.h b/phonelibs/android_system_core/include/utils/RefBase.h new file mode 100644 index 00000000000000..eac6a78402378a --- /dev/null +++ b/phonelibs/android_system_core/include/utils/RefBase.h @@ -0,0 +1,555 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_REF_BASE_H +#define ANDROID_REF_BASE_H + +#include + +#include +#include +#include +#include + +#include +#include + +// --------------------------------------------------------------------------- +namespace android { + +class TextOutput; +TextOutput& printWeakPointer(TextOutput& to, const void* val); + +// --------------------------------------------------------------------------- + +#define COMPARE_WEAK(_op_) \ +inline bool operator _op_ (const sp& o) const { \ + return m_ptr _op_ o.m_ptr; \ +} \ +inline bool operator _op_ (const T* o) const { \ + return m_ptr _op_ o; \ +} \ +template \ +inline bool operator _op_ (const sp& o) const { \ + return m_ptr _op_ o.m_ptr; \ +} \ +template \ +inline bool operator _op_ (const U* o) const { \ + return m_ptr _op_ o; \ +} + +// --------------------------------------------------------------------------- + +class ReferenceRenamer { +protected: + // destructor is purposedly not virtual so we avoid code overhead from + // subclasses; we have to make it protected to guarantee that it + // cannot be called from this base class (and to make strict compilers + // happy). + ~ReferenceRenamer() { } +public: + virtual void operator()(size_t i) const = 0; +}; + +// --------------------------------------------------------------------------- + +class RefBase +{ +public: + void incStrong(const void* id) const; + void decStrong(const void* id) const; + + void forceIncStrong(const void* id) const; + + //! DEBUGGING ONLY: Get current strong ref count. + int32_t getStrongCount() const; + + class weakref_type + { + public: + RefBase* refBase() const; + + void incWeak(const void* id); + void decWeak(const void* id); + + // acquires a strong reference if there is already one. + bool attemptIncStrong(const void* id); + + // acquires a weak reference if there is already one. + // This is not always safe. see ProcessState.cpp and BpBinder.cpp + // for proper use. + bool attemptIncWeak(const void* id); + + //! DEBUGGING ONLY: Get current weak ref count. + int32_t getWeakCount() const; + + //! DEBUGGING ONLY: Print references held on object. + void printRefs() const; + + //! DEBUGGING ONLY: Enable tracking for this object. + // enable -- enable/disable tracking + // retain -- when tracking is enable, if true, then we save a stack trace + // for each reference and dereference; when retain == false, we + // match up references and dereferences and keep only the + // outstanding ones. + + void trackMe(bool enable, bool retain); + }; + + weakref_type* createWeak(const void* id) const; + + weakref_type* getWeakRefs() const; + + //! DEBUGGING ONLY: Print references held on object. + inline void printRefs() const { getWeakRefs()->printRefs(); } + + //! DEBUGGING ONLY: Enable tracking of object. + inline void trackMe(bool enable, bool retain) + { + getWeakRefs()->trackMe(enable, retain); + } + + typedef RefBase basetype; + +protected: + RefBase(); + virtual ~RefBase(); + + //! Flags for extendObjectLifetime() + enum { + OBJECT_LIFETIME_STRONG = 0x0000, + OBJECT_LIFETIME_WEAK = 0x0001, + OBJECT_LIFETIME_MASK = 0x0001 + }; + + void extendObjectLifetime(int32_t mode); + + //! Flags for onIncStrongAttempted() + enum { + FIRST_INC_STRONG = 0x0001 + }; + + virtual void onFirstRef(); + virtual void onLastStrongRef(const void* id); + virtual bool onIncStrongAttempted(uint32_t flags, const void* id); + virtual void onLastWeakRef(const void* id); + +private: + friend class weakref_type; + class weakref_impl; + + RefBase(const RefBase& o); + RefBase& operator=(const RefBase& o); + +private: + friend class ReferenceMover; + + static void renameRefs(size_t n, const ReferenceRenamer& renamer); + + static void renameRefId(weakref_type* ref, + const void* old_id, const void* new_id); + + static void renameRefId(RefBase* ref, + const void* old_id, const void* new_id); + + weakref_impl* const mRefs; +}; + +// --------------------------------------------------------------------------- + +template +class LightRefBase +{ +public: + inline LightRefBase() : mCount(0) { } + inline void incStrong(__attribute__((unused)) const void* id) const { + android_atomic_inc(&mCount); + } + inline void decStrong(__attribute__((unused)) const void* id) const { + if (android_atomic_dec(&mCount) == 1) { + delete static_cast(this); + } + } + //! DEBUGGING ONLY: Get current strong ref count. + inline int32_t getStrongCount() const { + return mCount; + } + + typedef LightRefBase basetype; + +protected: + inline ~LightRefBase() { } + +private: + friend class ReferenceMover; + inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { } + inline static void renameRefId(T* ref, + const void* old_id, const void* new_id) { } + +private: + mutable volatile int32_t mCount; +}; + +// This is a wrapper around LightRefBase that simply enforces a virtual +// destructor to eliminate the template requirement of LightRefBase +class VirtualLightRefBase : public LightRefBase { +public: + virtual ~VirtualLightRefBase() {} +}; + +// --------------------------------------------------------------------------- + +template +class wp +{ +public: + typedef typename RefBase::weakref_type weakref_type; + + inline wp() : m_ptr(0) { } + + wp(T* other); + wp(const wp& other); + wp(const sp& other); + template wp(U* other); + template wp(const sp& other); + template wp(const wp& other); + + ~wp(); + + // Assignment + + wp& operator = (T* other); + wp& operator = (const wp& other); + wp& operator = (const sp& other); + + template wp& operator = (U* other); + template wp& operator = (const wp& other); + template wp& operator = (const sp& other); + + void set_object_and_refs(T* other, weakref_type* refs); + + // promotion to sp + + sp promote() const; + + // Reset + + void clear(); + + // Accessors + + inline weakref_type* get_refs() const { return m_refs; } + + inline T* unsafe_get() const { return m_ptr; } + + // Operators + + COMPARE_WEAK(==) + COMPARE_WEAK(!=) + COMPARE_WEAK(>) + COMPARE_WEAK(<) + COMPARE_WEAK(<=) + COMPARE_WEAK(>=) + + inline bool operator == (const wp& o) const { + return (m_ptr == o.m_ptr) && (m_refs == o.m_refs); + } + template + inline bool operator == (const wp& o) const { + return m_ptr == o.m_ptr; + } + + inline bool operator > (const wp& o) const { + return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); + } + template + inline bool operator > (const wp& o) const { + return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); + } + + inline bool operator < (const wp& o) const { + return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); + } + template + inline bool operator < (const wp& o) const { + return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); + } + inline bool operator != (const wp& o) const { return m_refs != o.m_refs; } + template inline bool operator != (const wp& o) const { return !operator == (o); } + inline bool operator <= (const wp& o) const { return !operator > (o); } + template inline bool operator <= (const wp& o) const { return !operator > (o); } + inline bool operator >= (const wp& o) const { return !operator < (o); } + template inline bool operator >= (const wp& o) const { return !operator < (o); } + +private: + template friend class sp; + template friend class wp; + + T* m_ptr; + weakref_type* m_refs; +}; + +template +TextOutput& operator<<(TextOutput& to, const wp& val); + +#undef COMPARE_WEAK + +// --------------------------------------------------------------------------- +// No user serviceable parts below here. + +template +wp::wp(T* other) + : m_ptr(other) +{ + if (other) m_refs = other->createWeak(this); +} + +template +wp::wp(const wp& other) + : m_ptr(other.m_ptr), m_refs(other.m_refs) +{ + if (m_ptr) m_refs->incWeak(this); +} + +template +wp::wp(const sp& other) + : m_ptr(other.m_ptr) +{ + if (m_ptr) { + m_refs = m_ptr->createWeak(this); + } +} + +template template +wp::wp(U* other) + : m_ptr(other) +{ + if (other) m_refs = other->createWeak(this); +} + +template template +wp::wp(const wp& other) + : m_ptr(other.m_ptr) +{ + if (m_ptr) { + m_refs = other.m_refs; + m_refs->incWeak(this); + } +} + +template template +wp::wp(const sp& other) + : m_ptr(other.m_ptr) +{ + if (m_ptr) { + m_refs = m_ptr->createWeak(this); + } +} + +template +wp::~wp() +{ + if (m_ptr) m_refs->decWeak(this); +} + +template +wp& wp::operator = (T* other) +{ + weakref_type* newRefs = + other ? other->createWeak(this) : 0; + if (m_ptr) m_refs->decWeak(this); + m_ptr = other; + m_refs = newRefs; + return *this; +} + +template +wp& wp::operator = (const wp& other) +{ + weakref_type* otherRefs(other.m_refs); + T* otherPtr(other.m_ptr); + if (otherPtr) otherRefs->incWeak(this); + if (m_ptr) m_refs->decWeak(this); + m_ptr = otherPtr; + m_refs = otherRefs; + return *this; +} + +template +wp& wp::operator = (const sp& other) +{ + weakref_type* newRefs = + other != NULL ? other->createWeak(this) : 0; + T* otherPtr(other.m_ptr); + if (m_ptr) m_refs->decWeak(this); + m_ptr = otherPtr; + m_refs = newRefs; + return *this; +} + +template template +wp& wp::operator = (U* other) +{ + weakref_type* newRefs = + other ? other->createWeak(this) : 0; + if (m_ptr) m_refs->decWeak(this); + m_ptr = other; + m_refs = newRefs; + return *this; +} + +template template +wp& wp::operator = (const wp& other) +{ + weakref_type* otherRefs(other.m_refs); + U* otherPtr(other.m_ptr); + if (otherPtr) otherRefs->incWeak(this); + if (m_ptr) m_refs->decWeak(this); + m_ptr = otherPtr; + m_refs = otherRefs; + return *this; +} + +template template +wp& wp::operator = (const sp& other) +{ + weakref_type* newRefs = + other != NULL ? other->createWeak(this) : 0; + U* otherPtr(other.m_ptr); + if (m_ptr) m_refs->decWeak(this); + m_ptr = otherPtr; + m_refs = newRefs; + return *this; +} + +template +void wp::set_object_and_refs(T* other, weakref_type* refs) +{ + if (other) refs->incWeak(this); + if (m_ptr) m_refs->decWeak(this); + m_ptr = other; + m_refs = refs; +} + +template +sp wp::promote() const +{ + sp result; + if (m_ptr && m_refs->attemptIncStrong(&result)) { + result.set_pointer(m_ptr); + } + return result; +} + +template +void wp::clear() +{ + if (m_ptr) { + m_refs->decWeak(this); + m_ptr = 0; + } +} + +template +inline TextOutput& operator<<(TextOutput& to, const wp& val) +{ + return printWeakPointer(to, val.unsafe_get()); +} + +// --------------------------------------------------------------------------- + +// this class just serves as a namespace so TYPE::moveReferences can stay +// private. +class ReferenceMover { +public: + // it would be nice if we could make sure no extra code is generated + // for sp or wp when TYPE is a descendant of RefBase: + // Using a sp override doesn't work; it's a bit like we wanted + // a template template... + + template static inline + void move_references(sp* d, sp const* s, size_t n) { + + class Renamer : public ReferenceRenamer { + sp* d; + sp const* s; + virtual void operator()(size_t i) const { + // The id are known to be the sp<>'s this pointer + TYPE::renameRefId(d[i].get(), &s[i], &d[i]); + } + public: + Renamer(sp* d, sp const* s) : d(d), s(s) { } + virtual ~Renamer() { } + }; + + memmove(d, s, n*sizeof(sp)); + TYPE::renameRefs(n, Renamer(d, s)); + } + + + template static inline + void move_references(wp* d, wp const* s, size_t n) { + + class Renamer : public ReferenceRenamer { + wp* d; + wp const* s; + virtual void operator()(size_t i) const { + // The id are known to be the wp<>'s this pointer + TYPE::renameRefId(d[i].get_refs(), &s[i], &d[i]); + } + public: + Renamer(wp* d, wp const* s) : d(d), s(s) { } + virtual ~Renamer() { } + }; + + memmove(d, s, n*sizeof(wp)); + TYPE::renameRefs(n, Renamer(d, s)); + } +}; + +// specialization for moving sp<> and wp<> types. +// these are used by the [Sorted|Keyed]Vector<> implementations +// sp<> and wp<> need to be handled specially, because they do not +// have trivial copy operation in the general case (see RefBase.cpp +// when DEBUG ops are enabled), but can be implemented very +// efficiently in most cases. + +template inline +void move_forward_type(sp* d, sp const* s, size_t n) { + ReferenceMover::move_references(d, s, n); +} + +template inline +void move_backward_type(sp* d, sp const* s, size_t n) { + ReferenceMover::move_references(d, s, n); +} + +template inline +void move_forward_type(wp* d, wp const* s, size_t n) { + ReferenceMover::move_references(d, s, n); +} + +template inline +void move_backward_type(wp* d, wp const* s, size_t n) { + ReferenceMover::move_references(d, s, n); +} + + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_REF_BASE_H diff --git a/phonelibs/android_system_core/include/utils/SharedBuffer.h b/phonelibs/android_system_core/include/utils/SharedBuffer.h new file mode 100644 index 00000000000000..b6709537e69358 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/SharedBuffer.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SHARED_BUFFER_H +#define ANDROID_SHARED_BUFFER_H + +#include +#include + +// --------------------------------------------------------------------------- + +namespace android { + +class SharedBuffer +{ +public: + + /* flags to use with release() */ + enum { + eKeepStorage = 0x00000001 + }; + + /*! allocate a buffer of size 'size' and acquire() it. + * call release() to free it. + */ + static SharedBuffer* alloc(size_t size); + + /*! free the memory associated with the SharedBuffer. + * Fails if there are any users associated with this SharedBuffer. + * In other words, the buffer must have been release by all its + * users. + */ + static ssize_t dealloc(const SharedBuffer* released); + + //! access the data for read + inline const void* data() const; + + //! access the data for read/write + inline void* data(); + + //! get size of the buffer + inline size_t size() const; + + //! get back a SharedBuffer object from its data + static inline SharedBuffer* bufferFromData(void* data); + + //! get back a SharedBuffer object from its data + static inline const SharedBuffer* bufferFromData(const void* data); + + //! get the size of a SharedBuffer object from its data + static inline size_t sizeFromData(const void* data); + + //! edit the buffer (get a writtable, or non-const, version of it) + SharedBuffer* edit() const; + + //! edit the buffer, resizing if needed + SharedBuffer* editResize(size_t size) const; + + //! like edit() but fails if a copy is required + SharedBuffer* attemptEdit() const; + + //! resize and edit the buffer, loose it's content. + SharedBuffer* reset(size_t size) const; + + //! acquire/release a reference on this buffer + void acquire() const; + + /*! release a reference on this buffer, with the option of not + * freeing the memory associated with it if it was the last reference + * returns the previous reference count + */ + int32_t release(uint32_t flags = 0) const; + + //! returns wether or not we're the only owner + inline bool onlyOwner() const; + + +private: + inline SharedBuffer() { } + inline ~SharedBuffer() { } + SharedBuffer(const SharedBuffer&); + SharedBuffer& operator = (const SharedBuffer&); + + // 16 bytes. must be sized to preserve correct alignment. + mutable int32_t mRefs; + size_t mSize; + uint32_t mReserved[2]; +}; + +// --------------------------------------------------------------------------- + +const void* SharedBuffer::data() const { + return this + 1; +} + +void* SharedBuffer::data() { + return this + 1; +} + +size_t SharedBuffer::size() const { + return mSize; +} + +SharedBuffer* SharedBuffer::bufferFromData(void* data) { + return data ? static_cast(data)-1 : 0; +} + +const SharedBuffer* SharedBuffer::bufferFromData(const void* data) { + return data ? static_cast(data)-1 : 0; +} + +size_t SharedBuffer::sizeFromData(const void* data) { + return data ? bufferFromData(data)->mSize : 0; +} + +bool SharedBuffer::onlyOwner() const { + return (mRefs == 1); +} + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_VECTOR_H diff --git a/phonelibs/android_system_core/include/utils/Singleton.h b/phonelibs/android_system_core/include/utils/Singleton.h new file mode 100644 index 00000000000000..ffc03cb5d641a4 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Singleton.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UTILS_SINGLETON_H +#define ANDROID_UTILS_SINGLETON_H + +#include +#include +#include +#include + +namespace android { +// --------------------------------------------------------------------------- + +template +class ANDROID_API Singleton +{ +public: + static TYPE& getInstance() { + Mutex::Autolock _l(sLock); + TYPE* instance = sInstance; + if (instance == 0) { + instance = new TYPE(); + sInstance = instance; + } + return *instance; + } + + static bool hasInstance() { + Mutex::Autolock _l(sLock); + return sInstance != 0; + } + +protected: + ~Singleton() { }; + Singleton() { }; + +private: + Singleton(const Singleton&); + Singleton& operator = (const Singleton&); + static Mutex sLock; + static TYPE* sInstance; +}; + +/* + * use ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) in your implementation file + * (eg: .cpp) to create the static instance of Singleton<>'s attributes, + * and avoid to have a copy of them in each compilation units Singleton + * is used. + * NOTE: we use a version of Mutex ctor that takes a parameter, because + * for some unknown reason using the default ctor doesn't emit the variable! + */ + +#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \ + template<> ::android::Mutex \ + (::android::Singleton< TYPE >::sLock)(::android::Mutex::PRIVATE); \ + template<> TYPE* ::android::Singleton< TYPE >::sInstance(0); \ + template class ::android::Singleton< TYPE >; + + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_UTILS_SINGLETON_H + diff --git a/phonelibs/android_system_core/include/utils/SortedVector.h b/phonelibs/android_system_core/include/utils/SortedVector.h new file mode 100644 index 00000000000000..2d3e82a7c0140f --- /dev/null +++ b/phonelibs/android_system_core/include/utils/SortedVector.h @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SORTED_VECTOR_H +#define ANDROID_SORTED_VECTOR_H + +#include +#include +#include + +#include + +#include +#include +#include + +// --------------------------------------------------------------------------- + +namespace android { + +template +class SortedVector : private SortedVectorImpl +{ + friend class Vector; + +public: + typedef TYPE value_type; + + /*! + * Constructors and destructors + */ + + SortedVector(); + SortedVector(const SortedVector& rhs); + virtual ~SortedVector(); + + /*! copy operator */ + const SortedVector& operator = (const SortedVector& rhs) const; + SortedVector& operator = (const SortedVector& rhs); + + /* + * empty the vector + */ + + inline void clear() { VectorImpl::clear(); } + + /*! + * vector stats + */ + + //! returns number of items in the vector + inline size_t size() const { return VectorImpl::size(); } + //! returns whether or not the vector is empty + inline bool isEmpty() const { return VectorImpl::isEmpty(); } + //! returns how many items can be stored without reallocating the backing store + inline size_t capacity() const { return VectorImpl::capacity(); } + //! sets the capacity. capacity can never be reduced less than size() + inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); } + + /*! + * C-style array access + */ + + //! read-only C-style access + inline const TYPE* array() const; + + //! read-write C-style access. BE VERY CAREFUL when modifying the array + //! you must keep it sorted! You usually don't use this function. + TYPE* editArray(); + + //! finds the index of an item + ssize_t indexOf(const TYPE& item) const; + + //! finds where this item should be inserted + size_t orderOf(const TYPE& item) const; + + + /*! + * accessors + */ + + //! read-only access to an item at a given index + inline const TYPE& operator [] (size_t index) const; + //! alternate name for operator [] + inline const TYPE& itemAt(size_t index) const; + //! stack-usage of the vector. returns the top of the stack (last element) + const TYPE& top() const; + + /*! + * modifying the array + */ + + //! add an item in the right place (and replace the one that is there) + ssize_t add(const TYPE& item); + + //! editItemAt() MUST NOT change the order of this item + TYPE& editItemAt(size_t index) { + return *( static_cast(VectorImpl::editItemLocation(index)) ); + } + + //! merges a vector into this one + ssize_t merge(const Vector& vector); + ssize_t merge(const SortedVector& vector); + + //! removes an item + ssize_t remove(const TYPE&); + + //! remove several items + inline ssize_t removeItemsAt(size_t index, size_t count = 1); + //! remove one item + inline ssize_t removeAt(size_t index) { return removeItemsAt(index); } + +protected: + virtual void do_construct(void* storage, size_t num) const; + virtual void do_destroy(void* storage, size_t num) const; + virtual void do_copy(void* dest, const void* from, size_t num) const; + virtual void do_splat(void* dest, const void* item, size_t num) const; + virtual void do_move_forward(void* dest, const void* from, size_t num) const; + virtual void do_move_backward(void* dest, const void* from, size_t num) const; + virtual int do_compare(const void* lhs, const void* rhs) const; +}; + +// SortedVector can be trivially moved using memcpy() because moving does not +// require any change to the underlying SharedBuffer contents or reference count. +template struct trait_trivial_move > { enum { value = true }; }; + +// --------------------------------------------------------------------------- +// No user serviceable parts from here... +// --------------------------------------------------------------------------- + +template inline +SortedVector::SortedVector() + : SortedVectorImpl(sizeof(TYPE), + ((traits::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0) + |(traits::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0) + |(traits::has_trivial_copy ? HAS_TRIVIAL_COPY : 0)) + ) +{ +} + +template inline +SortedVector::SortedVector(const SortedVector& rhs) + : SortedVectorImpl(rhs) { +} + +template inline +SortedVector::~SortedVector() { + finish_vector(); +} + +template inline +SortedVector& SortedVector::operator = (const SortedVector& rhs) { + SortedVectorImpl::operator = (rhs); + return *this; +} + +template inline +const SortedVector& SortedVector::operator = (const SortedVector& rhs) const { + SortedVectorImpl::operator = (rhs); + return *this; +} + +template inline +const TYPE* SortedVector::array() const { + return static_cast(arrayImpl()); +} + +template inline +TYPE* SortedVector::editArray() { + return static_cast(editArrayImpl()); +} + + +template inline +const TYPE& SortedVector::operator[](size_t index) const { + LOG_FATAL_IF(index>=size(), + "%s: index=%u out of range (%u)", __PRETTY_FUNCTION__, + int(index), int(size())); + return *(array() + index); +} + +template inline +const TYPE& SortedVector::itemAt(size_t index) const { + return operator[](index); +} + +template inline +const TYPE& SortedVector::top() const { + return *(array() + size() - 1); +} + +template inline +ssize_t SortedVector::add(const TYPE& item) { + return SortedVectorImpl::add(&item); +} + +template inline +ssize_t SortedVector::indexOf(const TYPE& item) const { + return SortedVectorImpl::indexOf(&item); +} + +template inline +size_t SortedVector::orderOf(const TYPE& item) const { + return SortedVectorImpl::orderOf(&item); +} + +template inline +ssize_t SortedVector::merge(const Vector& vector) { + return SortedVectorImpl::merge(reinterpret_cast(vector)); +} + +template inline +ssize_t SortedVector::merge(const SortedVector& vector) { + return SortedVectorImpl::merge(reinterpret_cast(vector)); +} + +template inline +ssize_t SortedVector::remove(const TYPE& item) { + return SortedVectorImpl::remove(&item); +} + +template inline +ssize_t SortedVector::removeItemsAt(size_t index, size_t count) { + return VectorImpl::removeItemsAt(index, count); +} + +// --------------------------------------------------------------------------- + +template +void SortedVector::do_construct(void* storage, size_t num) const { + construct_type( reinterpret_cast(storage), num ); +} + +template +void SortedVector::do_destroy(void* storage, size_t num) const { + destroy_type( reinterpret_cast(storage), num ); +} + +template +void SortedVector::do_copy(void* dest, const void* from, size_t num) const { + copy_type( reinterpret_cast(dest), reinterpret_cast(from), num ); +} + +template +void SortedVector::do_splat(void* dest, const void* item, size_t num) const { + splat_type( reinterpret_cast(dest), reinterpret_cast(item), num ); +} + +template +void SortedVector::do_move_forward(void* dest, const void* from, size_t num) const { + move_forward_type( reinterpret_cast(dest), reinterpret_cast(from), num ); +} + +template +void SortedVector::do_move_backward(void* dest, const void* from, size_t num) const { + move_backward_type( reinterpret_cast(dest), reinterpret_cast(from), num ); +} + +template +int SortedVector::do_compare(const void* lhs, const void* rhs) const { + return compare_type( *reinterpret_cast(lhs), *reinterpret_cast(rhs) ); +} + +}; // namespace android + + +// --------------------------------------------------------------------------- + +#endif // ANDROID_SORTED_VECTOR_H diff --git a/phonelibs/android_system_core/include/utils/StopWatch.h b/phonelibs/android_system_core/include/utils/StopWatch.h new file mode 100644 index 00000000000000..693dd3ccfce40f --- /dev/null +++ b/phonelibs/android_system_core/include/utils/StopWatch.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_STOPWATCH_H +#define ANDROID_STOPWATCH_H + +#include +#include + +#include + +// --------------------------------------------------------------------------- + +namespace android { + +class StopWatch +{ +public: + StopWatch( const char *name, + int clock = SYSTEM_TIME_MONOTONIC, + uint32_t flags = 0); + ~StopWatch(); + + const char* name() const; + nsecs_t lap(); + nsecs_t elapsedTime() const; + + void reset(); + +private: + const char* mName; + int mClock; + uint32_t mFlags; + + struct lap_t { + nsecs_t soFar; + nsecs_t thisLap; + }; + + nsecs_t mStartTime; + lap_t mLaps[8]; + int mNumLaps; +}; + + +}; // namespace android + + +// --------------------------------------------------------------------------- + +#endif // ANDROID_STOPWATCH_H diff --git a/phonelibs/android_system_core/include/utils/String16.h b/phonelibs/android_system_core/include/utils/String16.h new file mode 100644 index 00000000000000..d131bfc6a72dff --- /dev/null +++ b/phonelibs/android_system_core/include/utils/String16.h @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_STRING16_H +#define ANDROID_STRING16_H + +#include +#include +#include +#include + +// --------------------------------------------------------------------------- + +extern "C" { + +} + +// --------------------------------------------------------------------------- + +namespace android { + +// --------------------------------------------------------------------------- + +class String8; +class TextOutput; + +//! This is a string holding UTF-16 characters. +class String16 +{ +public: + /* use String16(StaticLinkage) if you're statically linking against + * libutils and declaring an empty static String16, e.g.: + * + * static String16 sAStaticEmptyString(String16::kEmptyString); + * static String16 sAnotherStaticEmptyString(sAStaticEmptyString); + */ + enum StaticLinkage { kEmptyString }; + + String16(); + explicit String16(StaticLinkage); + String16(const String16& o); + String16(const String16& o, + size_t len, + size_t begin=0); + explicit String16(const char16_t* o); + explicit String16(const char16_t* o, size_t len); + explicit String16(const String8& o); + explicit String16(const char* o); + explicit String16(const char* o, size_t len); + + ~String16(); + + inline const char16_t* string() const; + inline size_t size() const; + + inline const SharedBuffer* sharedBuffer() const; + + void setTo(const String16& other); + status_t setTo(const char16_t* other); + status_t setTo(const char16_t* other, size_t len); + status_t setTo(const String16& other, + size_t len, + size_t begin=0); + + status_t append(const String16& other); + status_t append(const char16_t* other, size_t len); + + inline String16& operator=(const String16& other); + + inline String16& operator+=(const String16& other); + inline String16 operator+(const String16& other) const; + + status_t insert(size_t pos, const char16_t* chrs); + status_t insert(size_t pos, + const char16_t* chrs, size_t len); + + ssize_t findFirst(char16_t c) const; + ssize_t findLast(char16_t c) const; + + bool startsWith(const String16& prefix) const; + bool startsWith(const char16_t* prefix) const; + + status_t makeLower(); + + status_t replaceAll(char16_t replaceThis, + char16_t withThis); + + status_t remove(size_t len, size_t begin=0); + + inline int compare(const String16& other) const; + + inline bool operator<(const String16& other) const; + inline bool operator<=(const String16& other) const; + inline bool operator==(const String16& other) const; + inline bool operator!=(const String16& other) const; + inline bool operator>=(const String16& other) const; + inline bool operator>(const String16& other) const; + + inline bool operator<(const char16_t* other) const; + inline bool operator<=(const char16_t* other) const; + inline bool operator==(const char16_t* other) const; + inline bool operator!=(const char16_t* other) const; + inline bool operator>=(const char16_t* other) const; + inline bool operator>(const char16_t* other) const; + + inline operator const char16_t*() const; + +private: + const char16_t* mString; +}; + +// String16 can be trivially moved using memcpy() because moving does not +// require any change to the underlying SharedBuffer contents or reference count. +ANDROID_TRIVIAL_MOVE_TRAIT(String16) + +// --------------------------------------------------------------------------- +// No user servicable parts below. + +inline int compare_type(const String16& lhs, const String16& rhs) +{ + return lhs.compare(rhs); +} + +inline int strictly_order_type(const String16& lhs, const String16& rhs) +{ + return compare_type(lhs, rhs) < 0; +} + +inline const char16_t* String16::string() const +{ + return mString; +} + +inline size_t String16::size() const +{ + return SharedBuffer::sizeFromData(mString)/sizeof(char16_t)-1; +} + +inline const SharedBuffer* String16::sharedBuffer() const +{ + return SharedBuffer::bufferFromData(mString); +} + +inline String16& String16::operator=(const String16& other) +{ + setTo(other); + return *this; +} + +inline String16& String16::operator+=(const String16& other) +{ + append(other); + return *this; +} + +inline String16 String16::operator+(const String16& other) const +{ + String16 tmp(*this); + tmp += other; + return tmp; +} + +inline int String16::compare(const String16& other) const +{ + return strzcmp16(mString, size(), other.mString, other.size()); +} + +inline bool String16::operator<(const String16& other) const +{ + return strzcmp16(mString, size(), other.mString, other.size()) < 0; +} + +inline bool String16::operator<=(const String16& other) const +{ + return strzcmp16(mString, size(), other.mString, other.size()) <= 0; +} + +inline bool String16::operator==(const String16& other) const +{ + return strzcmp16(mString, size(), other.mString, other.size()) == 0; +} + +inline bool String16::operator!=(const String16& other) const +{ + return strzcmp16(mString, size(), other.mString, other.size()) != 0; +} + +inline bool String16::operator>=(const String16& other) const +{ + return strzcmp16(mString, size(), other.mString, other.size()) >= 0; +} + +inline bool String16::operator>(const String16& other) const +{ + return strzcmp16(mString, size(), other.mString, other.size()) > 0; +} + +inline bool String16::operator<(const char16_t* other) const +{ + return strcmp16(mString, other) < 0; +} + +inline bool String16::operator<=(const char16_t* other) const +{ + return strcmp16(mString, other) <= 0; +} + +inline bool String16::operator==(const char16_t* other) const +{ + return strcmp16(mString, other) == 0; +} + +inline bool String16::operator!=(const char16_t* other) const +{ + return strcmp16(mString, other) != 0; +} + +inline bool String16::operator>=(const char16_t* other) const +{ + return strcmp16(mString, other) >= 0; +} + +inline bool String16::operator>(const char16_t* other) const +{ + return strcmp16(mString, other) > 0; +} + +inline String16::operator const char16_t*() const +{ + return mString; +} + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_STRING16_H diff --git a/phonelibs/android_system_core/include/utils/String8.h b/phonelibs/android_system_core/include/utils/String8.h new file mode 100644 index 00000000000000..ecfcf10be772b2 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/String8.h @@ -0,0 +1,408 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_STRING8_H +#define ANDROID_STRING8_H + +#include +#include +#include +#include + +#include // for strcmp +#include + +// --------------------------------------------------------------------------- + +namespace android { + +class String16; +class TextOutput; + +//! This is a string holding UTF-8 characters. Does not allow the value more +// than 0x10FFFF, which is not valid unicode codepoint. +class String8 +{ +public: + /* use String8(StaticLinkage) if you're statically linking against + * libutils and declaring an empty static String8, e.g.: + * + * static String8 sAStaticEmptyString(String8::kEmptyString); + * static String8 sAnotherStaticEmptyString(sAStaticEmptyString); + */ + enum StaticLinkage { kEmptyString }; + + String8(); + explicit String8(StaticLinkage); + String8(const String8& o); + explicit String8(const char* o); + explicit String8(const char* o, size_t numChars); + + explicit String8(const String16& o); + explicit String8(const char16_t* o); + explicit String8(const char16_t* o, size_t numChars); + explicit String8(const char32_t* o); + explicit String8(const char32_t* o, size_t numChars); + ~String8(); + + static inline const String8 empty(); + + static String8 format(const char* fmt, ...) __attribute__((format (printf, 1, 2))); + static String8 formatV(const char* fmt, va_list args); + + inline const char* string() const; + inline size_t size() const; + inline size_t length() const; + inline size_t bytes() const; + inline bool isEmpty() const; + + inline const SharedBuffer* sharedBuffer() const; + + void clear(); + + void setTo(const String8& other); + status_t setTo(const char* other); + status_t setTo(const char* other, size_t numChars); + status_t setTo(const char16_t* other, size_t numChars); + status_t setTo(const char32_t* other, + size_t length); + + status_t append(const String8& other); + status_t append(const char* other); + status_t append(const char* other, size_t numChars); + + status_t appendFormat(const char* fmt, ...) + __attribute__((format (printf, 2, 3))); + status_t appendFormatV(const char* fmt, va_list args); + + // Note that this function takes O(N) time to calculate the value. + // No cache value is stored. + size_t getUtf32Length() const; + int32_t getUtf32At(size_t index, + size_t *next_index) const; + void getUtf32(char32_t* dst) const; + + inline String8& operator=(const String8& other); + inline String8& operator=(const char* other); + + inline String8& operator+=(const String8& other); + inline String8 operator+(const String8& other) const; + + inline String8& operator+=(const char* other); + inline String8 operator+(const char* other) const; + + inline int compare(const String8& other) const; + + inline bool operator<(const String8& other) const; + inline bool operator<=(const String8& other) const; + inline bool operator==(const String8& other) const; + inline bool operator!=(const String8& other) const; + inline bool operator>=(const String8& other) const; + inline bool operator>(const String8& other) const; + + inline bool operator<(const char* other) const; + inline bool operator<=(const char* other) const; + inline bool operator==(const char* other) const; + inline bool operator!=(const char* other) const; + inline bool operator>=(const char* other) const; + inline bool operator>(const char* other) const; + + inline operator const char*() const; + + char* lockBuffer(size_t size); + void unlockBuffer(); + status_t unlockBuffer(size_t size); + + // return the index of the first byte of other in this at or after + // start, or -1 if not found + ssize_t find(const char* other, size_t start = 0) const; + + // return true if this string contains the specified substring + inline bool contains(const char* other) const; + + // removes all occurrence of the specified substring + // returns true if any were found and removed + bool removeAll(const char* other); + + void toLower(); + void toLower(size_t start, size_t numChars); + void toUpper(); + void toUpper(size_t start, size_t numChars); + + + /* + * These methods operate on the string as if it were a path name. + */ + + /* + * Set the filename field to a specific value. + * + * Normalizes the filename, removing a trailing '/' if present. + */ + void setPathName(const char* name); + void setPathName(const char* name, size_t numChars); + + /* + * Get just the filename component. + * + * "/tmp/foo/bar.c" --> "bar.c" + */ + String8 getPathLeaf(void) const; + + /* + * Remove the last (file name) component, leaving just the directory + * name. + * + * "/tmp/foo/bar.c" --> "/tmp/foo" + * "/tmp" --> "" // ????? shouldn't this be "/" ???? XXX + * "bar.c" --> "" + */ + String8 getPathDir(void) const; + + /* + * Retrieve the front (root dir) component. Optionally also return the + * remaining components. + * + * "/tmp/foo/bar.c" --> "tmp" (remain = "foo/bar.c") + * "/tmp" --> "tmp" (remain = "") + * "bar.c" --> "bar.c" (remain = "") + */ + String8 walkPath(String8* outRemains = NULL) const; + + /* + * Return the filename extension. This is the last '.' and any number + * of characters that follow it. The '.' is included in case we + * decide to expand our definition of what constitutes an extension. + * + * "/tmp/foo/bar.c" --> ".c" + * "/tmp" --> "" + * "/tmp/foo.bar/baz" --> "" + * "foo.jpeg" --> ".jpeg" + * "foo." --> "" + */ + String8 getPathExtension(void) const; + + /* + * Return the path without the extension. Rules for what constitutes + * an extension are described in the comment for getPathExtension(). + * + * "/tmp/foo/bar.c" --> "/tmp/foo/bar" + */ + String8 getBasePath(void) const; + + /* + * Add a component to the pathname. We guarantee that there is + * exactly one path separator between the old path and the new. + * If there is no existing name, we just copy the new name in. + * + * If leaf is a fully qualified path (i.e. starts with '/', it + * replaces whatever was there before. + */ + String8& appendPath(const char* leaf); + String8& appendPath(const String8& leaf) { return appendPath(leaf.string()); } + + /* + * Like appendPath(), but does not affect this string. Returns a new one instead. + */ + String8 appendPathCopy(const char* leaf) const + { String8 p(*this); p.appendPath(leaf); return p; } + String8 appendPathCopy(const String8& leaf) const { return appendPathCopy(leaf.string()); } + + /* + * Converts all separators in this string to /, the default path separator. + * + * If the default OS separator is backslash, this converts all + * backslashes to slashes, in-place. Otherwise it does nothing. + * Returns self. + */ + String8& convertToResPath(); + +private: + status_t real_append(const char* other, size_t numChars); + char* find_extension(void) const; + + const char* mString; +}; + +// String8 can be trivially moved using memcpy() because moving does not +// require any change to the underlying SharedBuffer contents or reference count. +ANDROID_TRIVIAL_MOVE_TRAIT(String8) + +// --------------------------------------------------------------------------- +// No user servicable parts below. + +inline int compare_type(const String8& lhs, const String8& rhs) +{ + return lhs.compare(rhs); +} + +inline int strictly_order_type(const String8& lhs, const String8& rhs) +{ + return compare_type(lhs, rhs) < 0; +} + +inline const String8 String8::empty() { + return String8(); +} + +inline const char* String8::string() const +{ + return mString; +} + +inline size_t String8::length() const +{ + return SharedBuffer::sizeFromData(mString)-1; +} + +inline size_t String8::size() const +{ + return length(); +} + +inline bool String8::isEmpty() const +{ + return length() == 0; +} + +inline size_t String8::bytes() const +{ + return SharedBuffer::sizeFromData(mString)-1; +} + +inline const SharedBuffer* String8::sharedBuffer() const +{ + return SharedBuffer::bufferFromData(mString); +} + +inline bool String8::contains(const char* other) const +{ + return find(other) >= 0; +} + +inline String8& String8::operator=(const String8& other) +{ + setTo(other); + return *this; +} + +inline String8& String8::operator=(const char* other) +{ + setTo(other); + return *this; +} + +inline String8& String8::operator+=(const String8& other) +{ + append(other); + return *this; +} + +inline String8 String8::operator+(const String8& other) const +{ + String8 tmp(*this); + tmp += other; + return tmp; +} + +inline String8& String8::operator+=(const char* other) +{ + append(other); + return *this; +} + +inline String8 String8::operator+(const char* other) const +{ + String8 tmp(*this); + tmp += other; + return tmp; +} + +inline int String8::compare(const String8& other) const +{ + return strcmp(mString, other.mString); +} + +inline bool String8::operator<(const String8& other) const +{ + return strcmp(mString, other.mString) < 0; +} + +inline bool String8::operator<=(const String8& other) const +{ + return strcmp(mString, other.mString) <= 0; +} + +inline bool String8::operator==(const String8& other) const +{ + return strcmp(mString, other.mString) == 0; +} + +inline bool String8::operator!=(const String8& other) const +{ + return strcmp(mString, other.mString) != 0; +} + +inline bool String8::operator>=(const String8& other) const +{ + return strcmp(mString, other.mString) >= 0; +} + +inline bool String8::operator>(const String8& other) const +{ + return strcmp(mString, other.mString) > 0; +} + +inline bool String8::operator<(const char* other) const +{ + return strcmp(mString, other) < 0; +} + +inline bool String8::operator<=(const char* other) const +{ + return strcmp(mString, other) <= 0; +} + +inline bool String8::operator==(const char* other) const +{ + return strcmp(mString, other) == 0; +} + +inline bool String8::operator!=(const char* other) const +{ + return strcmp(mString, other) != 0; +} + +inline bool String8::operator>=(const char* other) const +{ + return strcmp(mString, other) >= 0; +} + +inline bool String8::operator>(const char* other) const +{ + return strcmp(mString, other) > 0; +} + +inline String8::operator const char*() const +{ + return mString; +} + +} // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_STRING8_H diff --git a/phonelibs/android_system_core/include/utils/StrongPointer.h b/phonelibs/android_system_core/include/utils/StrongPointer.h new file mode 100644 index 00000000000000..aba9577da4fc5d --- /dev/null +++ b/phonelibs/android_system_core/include/utils/StrongPointer.h @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_STRONG_POINTER_H +#define ANDROID_STRONG_POINTER_H + +#include + +#include +#include +#include + +// --------------------------------------------------------------------------- +namespace android { + +template class wp; + +// --------------------------------------------------------------------------- + +#define COMPARE(_op_) \ +inline bool operator _op_ (const sp& o) const { \ + return m_ptr _op_ o.m_ptr; \ +} \ +inline bool operator _op_ (const T* o) const { \ + return m_ptr _op_ o; \ +} \ +template \ +inline bool operator _op_ (const sp& o) const { \ + return m_ptr _op_ o.m_ptr; \ +} \ +template \ +inline bool operator _op_ (const U* o) const { \ + return m_ptr _op_ o; \ +} \ +inline bool operator _op_ (const wp& o) const { \ + return m_ptr _op_ o.m_ptr; \ +} \ +template \ +inline bool operator _op_ (const wp& o) const { \ + return m_ptr _op_ o.m_ptr; \ +} + +// --------------------------------------------------------------------------- + +template +class sp { +public: + inline sp() : m_ptr(0) { } + + sp(T* other); + sp(const sp& other); + template sp(U* other); + template sp(const sp& other); + + ~sp(); + + // Assignment + + sp& operator = (T* other); + sp& operator = (const sp& other); + + template sp& operator = (const sp& other); + template sp& operator = (U* other); + + //! Special optimization for use by ProcessState (and nobody else). + void force_set(T* other); + + // Reset + + void clear(); + + // Accessors + + inline T& operator* () const { return *m_ptr; } + inline T* operator-> () const { return m_ptr; } + inline T* get() const { return m_ptr; } + + // Operators + + COMPARE(==) + COMPARE(!=) + COMPARE(>) + COMPARE(<) + COMPARE(<=) + COMPARE(>=) + +private: + template friend class sp; + template friend class wp; + void set_pointer(T* ptr); + T* m_ptr; +}; + +#undef COMPARE + +// --------------------------------------------------------------------------- +// No user serviceable parts below here. + +template +sp::sp(T* other) + : m_ptr(other) { + if (other) + other->incStrong(this); +} + +template +sp::sp(const sp& other) + : m_ptr(other.m_ptr) { + if (m_ptr) + m_ptr->incStrong(this); +} + +template template +sp::sp(U* other) + : m_ptr(other) { + if (other) + ((T*) other)->incStrong(this); +} + +template template +sp::sp(const sp& other) + : m_ptr(other.m_ptr) { + if (m_ptr) + m_ptr->incStrong(this); +} + +template +sp::~sp() { + if (m_ptr) + m_ptr->decStrong(this); +} + +template +sp& sp::operator =(const sp& other) { + T* otherPtr(other.m_ptr); + if (otherPtr) + otherPtr->incStrong(this); + if (m_ptr) + m_ptr->decStrong(this); + m_ptr = otherPtr; + return *this; +} + +template +sp& sp::operator =(T* other) { + if (other) + other->incStrong(this); + if (m_ptr) + m_ptr->decStrong(this); + m_ptr = other; + return *this; +} + +template template +sp& sp::operator =(const sp& other) { + T* otherPtr(other.m_ptr); + if (otherPtr) + otherPtr->incStrong(this); + if (m_ptr) + m_ptr->decStrong(this); + m_ptr = otherPtr; + return *this; +} + +template template +sp& sp::operator =(U* other) { + if (other) + ((T*) other)->incStrong(this); + if (m_ptr) + m_ptr->decStrong(this); + m_ptr = other; + return *this; +} + +template +void sp::force_set(T* other) { + other->forceIncStrong(this); + m_ptr = other; +} + +template +void sp::clear() { + if (m_ptr) { + m_ptr->decStrong(this); + m_ptr = 0; + } +} + +template +void sp::set_pointer(T* ptr) { + m_ptr = ptr; +} + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_STRONG_POINTER_H diff --git a/phonelibs/android_system_core/include/utils/SystemClock.h b/phonelibs/android_system_core/include/utils/SystemClock.h new file mode 100644 index 00000000000000..01db340780032b --- /dev/null +++ b/phonelibs/android_system_core/include/utils/SystemClock.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UTILS_SYSTEMCLOCK_H +#define ANDROID_UTILS_SYSTEMCLOCK_H + +#include +#include + +namespace android { + +int64_t uptimeMillis(); +int64_t elapsedRealtime(); +int64_t elapsedRealtimeNano(); + +}; // namespace android + +#endif // ANDROID_UTILS_SYSTEMCLOCK_H + diff --git a/phonelibs/android_system_core/include/utils/Thread.h b/phonelibs/android_system_core/include/utils/Thread.h new file mode 100644 index 00000000000000..28839fdedc1c06 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Thread.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_UTILS_THREAD_H +#define _LIBS_UTILS_THREAD_H + +#include +#include +#include + +#if !defined(_WIN32) +# include +#endif + +#include +#include +#include +#include +#include +#include + +// --------------------------------------------------------------------------- +namespace android { +// --------------------------------------------------------------------------- + +class Thread : virtual public RefBase +{ +public: + // Create a Thread object, but doesn't create or start the associated + // thread. See the run() method. + Thread(bool canCallJava = true); + virtual ~Thread(); + + // Start the thread in threadLoop() which needs to be implemented. + virtual status_t run( const char* name = 0, + int32_t priority = PRIORITY_DEFAULT, + size_t stack = 0); + + // Ask this object's thread to exit. This function is asynchronous, when the + // function returns the thread might still be running. Of course, this + // function can be called from a different thread. + virtual void requestExit(); + + // Good place to do one-time initializations + virtual status_t readyToRun(); + + // Call requestExit() and wait until this object's thread exits. + // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call + // this function from this object's thread. Will return WOULD_BLOCK in + // that case. + status_t requestExitAndWait(); + + // Wait until this object's thread exits. Returns immediately if not yet running. + // Do not call from this object's thread; will return WOULD_BLOCK in that case. + status_t join(); + + // Indicates whether this thread is running or not. + bool isRunning() const; + +#ifdef HAVE_ANDROID_OS + // Return the thread's kernel ID, same as the thread itself calling gettid(), + // or -1 if the thread is not running. + pid_t getTid() const; +#endif + +protected: + // exitPending() returns true if requestExit() has been called. + bool exitPending() const; + +private: + // Derived class must implement threadLoop(). The thread starts its life + // here. There are two ways of using the Thread object: + // 1) loop: if threadLoop() returns true, it will be called again if + // requestExit() wasn't called. + // 2) once: if threadLoop() returns false, the thread will exit upon return. + virtual bool threadLoop() = 0; + +private: + Thread& operator=(const Thread&); + static int _threadLoop(void* user); + const bool mCanCallJava; + // always hold mLock when reading or writing + thread_id_t mThread; + mutable Mutex mLock; + Condition mThreadExitedCondition; + status_t mStatus; + // note that all accesses of mExitPending and mRunning need to hold mLock + volatile bool mExitPending; + volatile bool mRunning; + sp mHoldSelf; +#ifdef HAVE_ANDROID_OS + // legacy for debugging, not used by getTid() as it is set by the child thread + // and so is not initialized until the child reaches that point + pid_t mTid; +#endif +}; + + +}; // namespace android + +// --------------------------------------------------------------------------- +#endif // _LIBS_UTILS_THREAD_H +// --------------------------------------------------------------------------- diff --git a/phonelibs/android_system_core/include/utils/ThreadDefs.h b/phonelibs/android_system_core/include/utils/ThreadDefs.h new file mode 100644 index 00000000000000..9711c137925e96 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/ThreadDefs.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_UTILS_THREAD_DEFS_H +#define _LIBS_UTILS_THREAD_DEFS_H + +#include +#include +#include +#include + +// --------------------------------------------------------------------------- +// C API + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* android_thread_id_t; + +typedef int (*android_thread_func_t)(void*); + +#ifdef __cplusplus +} // extern "C" +#endif + +// --------------------------------------------------------------------------- +// C++ API +#ifdef __cplusplus +namespace android { +// --------------------------------------------------------------------------- + +typedef android_thread_id_t thread_id_t; +typedef android_thread_func_t thread_func_t; + +enum { + PRIORITY_LOWEST = ANDROID_PRIORITY_LOWEST, + PRIORITY_BACKGROUND = ANDROID_PRIORITY_BACKGROUND, + PRIORITY_NORMAL = ANDROID_PRIORITY_NORMAL, + PRIORITY_FOREGROUND = ANDROID_PRIORITY_FOREGROUND, + PRIORITY_DISPLAY = ANDROID_PRIORITY_DISPLAY, + PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY, + PRIORITY_AUDIO = ANDROID_PRIORITY_AUDIO, + PRIORITY_URGENT_AUDIO = ANDROID_PRIORITY_URGENT_AUDIO, + PRIORITY_HIGHEST = ANDROID_PRIORITY_HIGHEST, + PRIORITY_DEFAULT = ANDROID_PRIORITY_DEFAULT, + PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE, + PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE, +}; + +// --------------------------------------------------------------------------- +}; // namespace android +#endif // __cplusplus +// --------------------------------------------------------------------------- + + +#endif // _LIBS_UTILS_THREAD_DEFS_H diff --git a/phonelibs/android_system_core/include/utils/Timers.h b/phonelibs/android_system_core/include/utils/Timers.h new file mode 100644 index 00000000000000..54ec47489fcb3c --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Timers.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Timer functions. +// +#ifndef _LIBS_UTILS_TIMERS_H +#define _LIBS_UTILS_TIMERS_H + +#include +#include +#include + +#include + +// ------------------------------------------------------------------ +// C API + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int64_t nsecs_t; // nano-seconds + +static CONSTEXPR inline nsecs_t seconds_to_nanoseconds(nsecs_t secs) +{ + return secs*1000000000; +} + +static CONSTEXPR inline nsecs_t milliseconds_to_nanoseconds(nsecs_t secs) +{ + return secs*1000000; +} + +static CONSTEXPR inline nsecs_t microseconds_to_nanoseconds(nsecs_t secs) +{ + return secs*1000; +} + +static CONSTEXPR inline nsecs_t nanoseconds_to_seconds(nsecs_t secs) +{ + return secs/1000000000; +} + +static CONSTEXPR inline nsecs_t nanoseconds_to_milliseconds(nsecs_t secs) +{ + return secs/1000000; +} + +static CONSTEXPR inline nsecs_t nanoseconds_to_microseconds(nsecs_t secs) +{ + return secs/1000; +} + +static CONSTEXPR inline nsecs_t s2ns(nsecs_t v) {return seconds_to_nanoseconds(v);} +static CONSTEXPR inline nsecs_t ms2ns(nsecs_t v) {return milliseconds_to_nanoseconds(v);} +static CONSTEXPR inline nsecs_t us2ns(nsecs_t v) {return microseconds_to_nanoseconds(v);} +static CONSTEXPR inline nsecs_t ns2s(nsecs_t v) {return nanoseconds_to_seconds(v);} +static CONSTEXPR inline nsecs_t ns2ms(nsecs_t v) {return nanoseconds_to_milliseconds(v);} +static CONSTEXPR inline nsecs_t ns2us(nsecs_t v) {return nanoseconds_to_microseconds(v);} + +static CONSTEXPR inline nsecs_t seconds(nsecs_t v) { return s2ns(v); } +static CONSTEXPR inline nsecs_t milliseconds(nsecs_t v) { return ms2ns(v); } +static CONSTEXPR inline nsecs_t microseconds(nsecs_t v) { return us2ns(v); } + +enum { + SYSTEM_TIME_REALTIME = 0, // system-wide realtime clock + SYSTEM_TIME_MONOTONIC = 1, // monotonic time since unspecified starting point + SYSTEM_TIME_PROCESS = 2, // high-resolution per-process clock + SYSTEM_TIME_THREAD = 3, // high-resolution per-thread clock + SYSTEM_TIME_BOOTTIME = 4 // same as SYSTEM_TIME_MONOTONIC, but including CPU suspend time +}; + +// return the system-time according to the specified clock +#ifdef __cplusplus +nsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC); +#else +nsecs_t systemTime(int clock); +#endif // def __cplusplus + +/** + * Returns the number of milliseconds to wait between the reference time and the timeout time. + * If the timeout is in the past relative to the reference time, returns 0. + * If the timeout is more than INT_MAX milliseconds in the future relative to the reference time, + * such as when timeoutTime == LLONG_MAX, returns -1 to indicate an infinite timeout delay. + * Otherwise, returns the difference between the reference time and timeout time + * rounded up to the next millisecond. + */ +int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _LIBS_UTILS_TIMERS_H diff --git a/phonelibs/android_system_core/include/utils/Tokenizer.h b/phonelibs/android_system_core/include/utils/Tokenizer.h new file mode 100644 index 00000000000000..bb25f374cb343c --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Tokenizer.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _UTILS_TOKENIZER_H +#define _UTILS_TOKENIZER_H + +#include +#include +#include +#include + +namespace android { + +/** + * A simple tokenizer for loading and parsing ASCII text files line by line. + */ +class Tokenizer { + Tokenizer(const String8& filename, FileMap* fileMap, char* buffer, + bool ownBuffer, size_t length); + +public: + ~Tokenizer(); + + /** + * Opens a file and maps it into memory. + * + * Returns NO_ERROR and a tokenizer for the file, if successful. + * Otherwise returns an error and sets outTokenizer to NULL. + */ + static status_t open(const String8& filename, Tokenizer** outTokenizer); + + /** + * Prepares to tokenize the contents of a string. + * + * Returns NO_ERROR and a tokenizer for the string, if successful. + * Otherwise returns an error and sets outTokenizer to NULL. + */ + static status_t fromContents(const String8& filename, + const char* contents, Tokenizer** outTokenizer); + + /** + * Returns true if at the end of the file. + */ + inline bool isEof() const { return mCurrent == getEnd(); } + + /** + * Returns true if at the end of the line or end of the file. + */ + inline bool isEol() const { return isEof() || *mCurrent == '\n'; } + + /** + * Gets the name of the file. + */ + inline String8 getFilename() const { return mFilename; } + + /** + * Gets a 1-based line number index for the current position. + */ + inline int32_t getLineNumber() const { return mLineNumber; } + + /** + * Formats a location string consisting of the filename and current line number. + * Returns a string like "MyFile.txt:33". + */ + String8 getLocation() const; + + /** + * Gets the character at the current position. + * Returns null at end of file. + */ + inline char peekChar() const { return isEof() ? '\0' : *mCurrent; } + + /** + * Gets the remainder of the current line as a string, excluding the newline character. + */ + String8 peekRemainderOfLine() const; + + /** + * Gets the character at the current position and advances past it. + * Returns null at end of file. + */ + inline char nextChar() { return isEof() ? '\0' : *(mCurrent++); } + + /** + * Gets the next token on this line stopping at the specified delimiters + * or the end of the line whichever comes first and advances past it. + * Also stops at embedded nulls. + * Returns the token or an empty string if the current character is a delimiter + * or is at the end of the line. + */ + String8 nextToken(const char* delimiters); + + /** + * Advances to the next line. + * Does nothing if already at the end of the file. + */ + void nextLine(); + + /** + * Skips over the specified delimiters in the line. + * Also skips embedded nulls. + */ + void skipDelimiters(const char* delimiters); + +private: + Tokenizer(const Tokenizer& other); // not copyable + + String8 mFilename; + FileMap* mFileMap; + char* mBuffer; + bool mOwnBuffer; + size_t mLength; + + const char* mCurrent; + int32_t mLineNumber; + + inline const char* getEnd() const { return mBuffer + mLength; } + +}; + +} // namespace android + +#endif // _UTILS_TOKENIZER_H diff --git a/phonelibs/android_system_core/include/utils/Trace.h b/phonelibs/android_system_core/include/utils/Trace.h new file mode 100644 index 00000000000000..6ee343d79ad039 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Trace.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_TRACE_H +#define ANDROID_TRACE_H + +#ifdef HAVE_ANDROID_OS + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// See for more ATRACE_* macros. + +// ATRACE_NAME traces the beginning and end of the current scope. To trace +// the correct start and end times this macro should be declared first in the +// scope body. +#define ATRACE_NAME(name) android::ScopedTrace ___tracer(ATRACE_TAG, name) +// ATRACE_CALL is an ATRACE_NAME that uses the current function name. +#define ATRACE_CALL() ATRACE_NAME(__FUNCTION__) + +namespace android { + +class ScopedTrace { +public: +inline ScopedTrace(uint64_t tag, const char* name) + : mTag(tag) { + atrace_begin(mTag,name); +} + +inline ~ScopedTrace() { + atrace_end(mTag); +} + +private: + uint64_t mTag; +}; + +}; // namespace android + +#else // HAVE_ANDROID_OS + +#define ATRACE_NAME(...) +#define ATRACE_CALL() + +#endif // HAVE_ANDROID_OS + +#endif // ANDROID_TRACE_H diff --git a/phonelibs/android_system_core/include/utils/TypeHelpers.h b/phonelibs/android_system_core/include/utils/TypeHelpers.h new file mode 100644 index 00000000000000..13c90815994736 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/TypeHelpers.h @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_TYPE_HELPERS_H +#define ANDROID_TYPE_HELPERS_H + +#include +#include +#include +#include + +// --------------------------------------------------------------------------- + +namespace android { + +/* + * Types traits + */ + +template struct trait_trivial_ctor { enum { value = false }; }; +template struct trait_trivial_dtor { enum { value = false }; }; +template struct trait_trivial_copy { enum { value = false }; }; +template struct trait_trivial_move { enum { value = false }; }; +template struct trait_pointer { enum { value = false }; }; +template struct trait_pointer { enum { value = true }; }; + +template +struct traits { + enum { + // whether this type is a pointer + is_pointer = trait_pointer::value, + // whether this type's constructor is a no-op + has_trivial_ctor = is_pointer || trait_trivial_ctor::value, + // whether this type's destructor is a no-op + has_trivial_dtor = is_pointer || trait_trivial_dtor::value, + // whether this type type can be copy-constructed with memcpy + has_trivial_copy = is_pointer || trait_trivial_copy::value, + // whether this type can be moved with memmove + has_trivial_move = is_pointer || trait_trivial_move::value + }; +}; + +template +struct aggregate_traits { + enum { + is_pointer = false, + has_trivial_ctor = + traits::has_trivial_ctor && traits::has_trivial_ctor, + has_trivial_dtor = + traits::has_trivial_dtor && traits::has_trivial_dtor, + has_trivial_copy = + traits::has_trivial_copy && traits::has_trivial_copy, + has_trivial_move = + traits::has_trivial_move && traits::has_trivial_move + }; +}; + +#define ANDROID_TRIVIAL_CTOR_TRAIT( T ) \ + template<> struct trait_trivial_ctor< T > { enum { value = true }; }; + +#define ANDROID_TRIVIAL_DTOR_TRAIT( T ) \ + template<> struct trait_trivial_dtor< T > { enum { value = true }; }; + +#define ANDROID_TRIVIAL_COPY_TRAIT( T ) \ + template<> struct trait_trivial_copy< T > { enum { value = true }; }; + +#define ANDROID_TRIVIAL_MOVE_TRAIT( T ) \ + template<> struct trait_trivial_move< T > { enum { value = true }; }; + +#define ANDROID_BASIC_TYPES_TRAITS( T ) \ + ANDROID_TRIVIAL_CTOR_TRAIT( T ) \ + ANDROID_TRIVIAL_DTOR_TRAIT( T ) \ + ANDROID_TRIVIAL_COPY_TRAIT( T ) \ + ANDROID_TRIVIAL_MOVE_TRAIT( T ) + +// --------------------------------------------------------------------------- + +/* + * basic types traits + */ + +ANDROID_BASIC_TYPES_TRAITS( void ) +ANDROID_BASIC_TYPES_TRAITS( bool ) +ANDROID_BASIC_TYPES_TRAITS( char ) +ANDROID_BASIC_TYPES_TRAITS( unsigned char ) +ANDROID_BASIC_TYPES_TRAITS( short ) +ANDROID_BASIC_TYPES_TRAITS( unsigned short ) +ANDROID_BASIC_TYPES_TRAITS( int ) +ANDROID_BASIC_TYPES_TRAITS( unsigned int ) +ANDROID_BASIC_TYPES_TRAITS( long ) +ANDROID_BASIC_TYPES_TRAITS( unsigned long ) +ANDROID_BASIC_TYPES_TRAITS( long long ) +ANDROID_BASIC_TYPES_TRAITS( unsigned long long ) +ANDROID_BASIC_TYPES_TRAITS( float ) +ANDROID_BASIC_TYPES_TRAITS( double ) + +// --------------------------------------------------------------------------- + + +/* + * compare and order types + */ + +template inline +int strictly_order_type(const TYPE& lhs, const TYPE& rhs) { + return (lhs < rhs) ? 1 : 0; +} + +template inline +int compare_type(const TYPE& lhs, const TYPE& rhs) { + return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs); +} + +/* + * create, destroy, copy and move types... + */ + +template inline +void construct_type(TYPE* p, size_t n) { + if (!traits::has_trivial_ctor) { + while (n--) { + new(p++) TYPE; + } + } +} + +template inline +void destroy_type(TYPE* p, size_t n) { + if (!traits::has_trivial_dtor) { + while (n--) { + p->~TYPE(); + p++; + } + } +} + +template inline +void copy_type(TYPE* d, const TYPE* s, size_t n) { + if (!traits::has_trivial_copy) { + while (n--) { + new(d) TYPE(*s); + d++, s++; + } + } else { + memcpy(d,s,n*sizeof(TYPE)); + } +} + +template inline +void splat_type(TYPE* where, const TYPE* what, size_t n) { + if (!traits::has_trivial_copy) { + while (n--) { + new(where) TYPE(*what); + where++; + } + } else { + while (n--) { + *where++ = *what; + } + } +} + +template inline +void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) { + if ((traits::has_trivial_dtor && traits::has_trivial_copy) + || traits::has_trivial_move) + { + memmove(d,s,n*sizeof(TYPE)); + } else { + d += n; + s += n; + while (n--) { + --d, --s; + if (!traits::has_trivial_copy) { + new(d) TYPE(*s); + } else { + *d = *s; + } + if (!traits::has_trivial_dtor) { + s->~TYPE(); + } + } + } +} + +template inline +void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) { + if ((traits::has_trivial_dtor && traits::has_trivial_copy) + || traits::has_trivial_move) + { + memmove(d,s,n*sizeof(TYPE)); + } else { + while (n--) { + if (!traits::has_trivial_copy) { + new(d) TYPE(*s); + } else { + *d = *s; + } + if (!traits::has_trivial_dtor) { + s->~TYPE(); + } + d++, s++; + } + } +} + +// --------------------------------------------------------------------------- + +/* + * a key/value pair + */ + +template +struct key_value_pair_t { + typedef KEY key_t; + typedef VALUE value_t; + + KEY key; + VALUE value; + key_value_pair_t() { } + key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { } + key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v) { } + key_value_pair_t(const KEY& k) : key(k) { } + inline bool operator < (const key_value_pair_t& o) const { + return strictly_order_type(key, o.key); + } + inline const KEY& getKey() const { + return key; + } + inline const VALUE& getValue() const { + return value; + } +}; + +template +struct trait_trivial_ctor< key_value_pair_t > +{ enum { value = aggregate_traits::has_trivial_ctor }; }; +template +struct trait_trivial_dtor< key_value_pair_t > +{ enum { value = aggregate_traits::has_trivial_dtor }; }; +template +struct trait_trivial_copy< key_value_pair_t > +{ enum { value = aggregate_traits::has_trivial_copy }; }; +template +struct trait_trivial_move< key_value_pair_t > +{ enum { value = aggregate_traits::has_trivial_move }; }; + +// --------------------------------------------------------------------------- + +/* + * Hash codes. + */ +typedef uint32_t hash_t; + +template +hash_t hash_type(const TKey& key); + +/* Built-in hash code specializations. + * Assumes pointers are 32bit. */ +#define ANDROID_INT32_HASH(T) \ + template <> inline hash_t hash_type(const T& value) { return hash_t(value); } +#define ANDROID_INT64_HASH(T) \ + template <> inline hash_t hash_type(const T& value) { \ + return hash_t((value >> 32) ^ value); } +#define ANDROID_REINTERPRET_HASH(T, R) \ + template <> inline hash_t hash_type(const T& value) { \ + return hash_type(*reinterpret_cast(&value)); } + +ANDROID_INT32_HASH(bool) +ANDROID_INT32_HASH(int8_t) +ANDROID_INT32_HASH(uint8_t) +ANDROID_INT32_HASH(int16_t) +ANDROID_INT32_HASH(uint16_t) +ANDROID_INT32_HASH(int32_t) +ANDROID_INT32_HASH(uint32_t) +ANDROID_INT64_HASH(int64_t) +ANDROID_INT64_HASH(uint64_t) +ANDROID_REINTERPRET_HASH(float, uint32_t) +ANDROID_REINTERPRET_HASH(double, uint64_t) + +template inline hash_t hash_type(T* const & value) { + return hash_type(uintptr_t(value)); +} + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_TYPE_HELPERS_H diff --git a/phonelibs/android_system_core/include/utils/Unicode.h b/phonelibs/android_system_core/include/utils/Unicode.h new file mode 100644 index 00000000000000..4e17cc3d9c5a46 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Unicode.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UNICODE_H +#define ANDROID_UNICODE_H + +#include +#include + +extern "C" { + +// Standard string functions on char16_t strings. +int strcmp16(const char16_t *, const char16_t *); +int strncmp16(const char16_t *s1, const char16_t *s2, size_t n); +size_t strlen16(const char16_t *); +size_t strnlen16(const char16_t *, size_t); +char16_t *strcpy16(char16_t *, const char16_t *); +char16_t *strncpy16(char16_t *, const char16_t *, size_t); + +// Version of comparison that supports embedded nulls. +// This is different than strncmp() because we don't stop +// at a nul character and consider the strings to be different +// if the lengths are different (thus we need to supply the +// lengths of both strings). This can also be used when +// your string is not nul-terminated as it will have the +// equivalent result as strcmp16 (unlike strncmp16). +int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2); + +// Version of strzcmp16 for comparing strings in different endianness. +int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2); + +// Standard string functions on char32_t strings. +size_t strlen32(const char32_t *); +size_t strnlen32(const char32_t *, size_t); + +/** + * Measure the length of a UTF-32 string in UTF-8. If the string is invalid + * such as containing a surrogate character, -1 will be returned. + */ +ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len); + +/** + * Stores a UTF-8 string converted from "src" in "dst", if "dst_length" is not + * large enough to store the string, the part of the "src" string is stored + * into "dst" as much as possible. See the examples for more detail. + * Returns the size actually used for storing the string. + * dst" is not null-terminated when dst_len is fully used (like strncpy). + * + * Example 1 + * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84) + * "src_len" == 2 + * "dst_len" >= 7 + * -> + * Returned value == 6 + * "dst" becomes \xE3\x81\x82\xE3\x81\x84\0 + * (note that "dst" is null-terminated) + * + * Example 2 + * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84) + * "src_len" == 2 + * "dst_len" == 5 + * -> + * Returned value == 3 + * "dst" becomes \xE3\x81\x82\0 + * (note that "dst" is null-terminated, but \u3044 is not stored in "dst" + * since "dst" does not have enough size to store the character) + * + * Example 3 + * "src" == \u3042\u3044 (\xE3\x81\x82\xE3\x81\x84) + * "src_len" == 2 + * "dst_len" == 6 + * -> + * Returned value == 6 + * "dst" becomes \xE3\x81\x82\xE3\x81\x84 + * (note that "dst" is NOT null-terminated, like strncpy) + */ +void utf32_to_utf8(const char32_t* src, size_t src_len, char* dst, size_t dst_len); + +/** + * Returns the unicode value at "index". + * Returns -1 when the index is invalid (equals to or more than "src_len"). + * If returned value is positive, it is able to be converted to char32_t, which + * is unsigned. Then, if "next_index" is not NULL, the next index to be used is + * stored in "next_index". "next_index" can be NULL. + */ +int32_t utf32_from_utf8_at(const char *src, size_t src_len, size_t index, size_t *next_index); + + +/** + * Returns the UTF-8 length of UTF-16 string "src". + */ +ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len); + +/** + * Converts a UTF-16 string to UTF-8. The destination buffer must be large + * enough to fit the UTF-16 as measured by utf16_to_utf8_length with an added + * NULL terminator. + */ +void utf16_to_utf8(const char16_t* src, size_t src_len, char* dst, size_t dst_len); + +/** + * Returns the length of "src" when "src" is valid UTF-8 string. + * Returns 0 if src is NULL or 0-length string. Returns -1 when the source + * is an invalid string. + * + * This function should be used to determine whether "src" is valid UTF-8 + * characters with valid unicode codepoints. "src" must be null-terminated. + * + * If you are going to use other utf8_to_... functions defined in this header + * with string which may not be valid UTF-8 with valid codepoint (form 0 to + * 0x10FFFF), you should use this function before calling others, since the + * other functions do not check whether the string is valid UTF-8 or not. + * + * If you do not care whether "src" is valid UTF-8 or not, you should use + * strlen() as usual, which should be much faster. + */ +ssize_t utf8_length(const char *src); + +/** + * Measure the length of a UTF-32 string. + */ +size_t utf8_to_utf32_length(const char *src, size_t src_len); + +/** + * Stores a UTF-32 string converted from "src" in "dst". "dst" must be large + * enough to store the entire converted string as measured by + * utf8_to_utf32_length plus space for a NULL terminator. + */ +void utf8_to_utf32(const char* src, size_t src_len, char32_t* dst); + +/** + * Returns the UTF-16 length of UTF-8 string "src". + */ +ssize_t utf8_to_utf16_length(const uint8_t* src, size_t srcLen); + +/** + * Convert UTF-8 to UTF-16 including surrogate pairs. + * Returns a pointer to the end of the string (where a null terminator might go + * if you wanted to add one). + */ +char16_t* utf8_to_utf16_no_null_terminator(const uint8_t* src, size_t srcLen, char16_t* dst); + +/** + * Convert UTF-8 to UTF-16 including surrogate pairs. The destination buffer + * must be large enough to hold the result as measured by utf8_to_utf16_length + * plus an added NULL terminator. + */ +void utf8_to_utf16(const uint8_t* src, size_t srcLen, char16_t* dst); + +/** + * Like utf8_to_utf16_no_null_terminator, but you can supply a maximum length of the + * decoded string. The decoded string will fill up to that length; if it is longer + * the returned pointer will be to the character after dstLen. + */ +char16_t* utf8_to_utf16_n(const uint8_t* src, size_t srcLen, char16_t* dst, size_t dstLen); + +} + +#endif diff --git a/phonelibs/android_system_core/include/utils/Vector.h b/phonelibs/android_system_core/include/utils/Vector.h new file mode 100644 index 00000000000000..ed7b725213150a --- /dev/null +++ b/phonelibs/android_system_core/include/utils/Vector.h @@ -0,0 +1,423 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_VECTOR_H +#define ANDROID_VECTOR_H + +#include +#include +#include + +#include + +#include +#include + +// --------------------------------------------------------------------------- + +namespace android { + +template +class SortedVector; + +/*! + * The main templated vector class ensuring type safety + * while making use of VectorImpl. + * This is the class users want to use. + */ + +template +class Vector : private VectorImpl +{ +public: + typedef TYPE value_type; + + /*! + * Constructors and destructors + */ + + Vector(); + Vector(const Vector& rhs); + explicit Vector(const SortedVector& rhs); + virtual ~Vector(); + + /*! copy operator */ + const Vector& operator = (const Vector& rhs) const; + Vector& operator = (const Vector& rhs); + + const Vector& operator = (const SortedVector& rhs) const; + Vector& operator = (const SortedVector& rhs); + + /* + * empty the vector + */ + + inline void clear() { VectorImpl::clear(); } + + /*! + * vector stats + */ + + //! returns number of items in the vector + inline size_t size() const { return VectorImpl::size(); } + //! returns whether or not the vector is empty + inline bool isEmpty() const { return VectorImpl::isEmpty(); } + //! returns how many items can be stored without reallocating the backing store + inline size_t capacity() const { return VectorImpl::capacity(); } + //! sets the capacity. capacity can never be reduced less than size() + inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); } + + /*! + * set the size of the vector. items are appended with the default + * constructor, or removed from the end as needed. + */ + inline ssize_t resize(size_t size) { return VectorImpl::resize(size); } + + /*! + * C-style array access + */ + + //! read-only C-style access + inline const TYPE* array() const; + //! read-write C-style access + TYPE* editArray(); + + /*! + * accessors + */ + + //! read-only access to an item at a given index + inline const TYPE& operator [] (size_t index) const; + //! alternate name for operator [] + inline const TYPE& itemAt(size_t index) const; + //! stack-usage of the vector. returns the top of the stack (last element) + const TYPE& top() const; + + /*! + * modifying the array + */ + + //! copy-on write support, grants write access to an item + TYPE& editItemAt(size_t index); + //! grants right access to the top of the stack (last element) + TYPE& editTop(); + + /*! + * append/insert another vector + */ + + //! insert another vector at a given index + ssize_t insertVectorAt(const Vector& vector, size_t index); + + //! append another vector at the end of this one + ssize_t appendVector(const Vector& vector); + + + //! insert an array at a given index + ssize_t insertArrayAt(const TYPE* array, size_t index, size_t length); + + //! append an array at the end of this vector + ssize_t appendArray(const TYPE* array, size_t length); + + /*! + * add/insert/replace items + */ + + //! insert one or several items initialized with their default constructor + inline ssize_t insertAt(size_t index, size_t numItems = 1); + //! insert one or several items initialized from a prototype item + ssize_t insertAt(const TYPE& prototype_item, size_t index, size_t numItems = 1); + //! pop the top of the stack (removes the last element). No-op if the stack's empty + inline void pop(); + //! pushes an item initialized with its default constructor + inline void push(); + //! pushes an item on the top of the stack + void push(const TYPE& item); + //! same as push() but returns the index the item was added at (or an error) + inline ssize_t add(); + //! same as push() but returns the index the item was added at (or an error) + ssize_t add(const TYPE& item); + //! replace an item with a new one initialized with its default constructor + inline ssize_t replaceAt(size_t index); + //! replace an item with a new one + ssize_t replaceAt(const TYPE& item, size_t index); + + /*! + * remove items + */ + + //! remove several items + inline ssize_t removeItemsAt(size_t index, size_t count = 1); + //! remove one item + inline ssize_t removeAt(size_t index) { return removeItemsAt(index); } + + /*! + * sort (stable) the array + */ + + typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs); + typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state); + + inline status_t sort(compar_t cmp); + inline status_t sort(compar_r_t cmp, void* state); + + // for debugging only + inline size_t getItemSize() const { return itemSize(); } + + + /* + * these inlines add some level of compatibility with STL. eventually + * we should probably turn things around. + */ + typedef TYPE* iterator; + typedef TYPE const* const_iterator; + + inline iterator begin() { return editArray(); } + inline iterator end() { return editArray() + size(); } + inline const_iterator begin() const { return array(); } + inline const_iterator end() const { return array() + size(); } + inline void reserve(size_t n) { setCapacity(n); } + inline bool empty() const{ return isEmpty(); } + inline void push_back(const TYPE& item) { insertAt(item, size(), 1); } + inline void push_front(const TYPE& item) { insertAt(item, 0, 1); } + inline iterator erase(iterator pos) { + ssize_t index = removeItemsAt(pos-array()); + return begin() + index; + } + +protected: + virtual void do_construct(void* storage, size_t num) const; + virtual void do_destroy(void* storage, size_t num) const; + virtual void do_copy(void* dest, const void* from, size_t num) const; + virtual void do_splat(void* dest, const void* item, size_t num) const; + virtual void do_move_forward(void* dest, const void* from, size_t num) const; + virtual void do_move_backward(void* dest, const void* from, size_t num) const; +}; + +// Vector can be trivially moved using memcpy() because moving does not +// require any change to the underlying SharedBuffer contents or reference count. +template struct trait_trivial_move > { enum { value = true }; }; + +// --------------------------------------------------------------------------- +// No user serviceable parts from here... +// --------------------------------------------------------------------------- + +template inline +Vector::Vector() + : VectorImpl(sizeof(TYPE), + ((traits::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0) + |(traits::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0) + |(traits::has_trivial_copy ? HAS_TRIVIAL_COPY : 0)) + ) +{ +} + +template inline +Vector::Vector(const Vector& rhs) + : VectorImpl(rhs) { +} + +template inline +Vector::Vector(const SortedVector& rhs) + : VectorImpl(static_cast(rhs)) { +} + +template inline +Vector::~Vector() { + finish_vector(); +} + +template inline +Vector& Vector::operator = (const Vector& rhs) { + VectorImpl::operator = (rhs); + return *this; +} + +template inline +const Vector& Vector::operator = (const Vector& rhs) const { + VectorImpl::operator = (static_cast(rhs)); + return *this; +} + +template inline +Vector& Vector::operator = (const SortedVector& rhs) { + VectorImpl::operator = (static_cast(rhs)); + return *this; +} + +template inline +const Vector& Vector::operator = (const SortedVector& rhs) const { + VectorImpl::operator = (rhs); + return *this; +} + +template inline +const TYPE* Vector::array() const { + return static_cast(arrayImpl()); +} + +template inline +TYPE* Vector::editArray() { + return static_cast(editArrayImpl()); +} + + +template inline +const TYPE& Vector::operator[](size_t index) const { + LOG_FATAL_IF(index>=size(), + "%s: index=%u out of range (%u)", __PRETTY_FUNCTION__, + int(index), int(size())); + return *(array() + index); +} + +template inline +const TYPE& Vector::itemAt(size_t index) const { + return operator[](index); +} + +template inline +const TYPE& Vector::top() const { + return *(array() + size() - 1); +} + +template inline +TYPE& Vector::editItemAt(size_t index) { + return *( static_cast(editItemLocation(index)) ); +} + +template inline +TYPE& Vector::editTop() { + return *( static_cast(editItemLocation(size()-1)) ); +} + +template inline +ssize_t Vector::insertVectorAt(const Vector& vector, size_t index) { + return VectorImpl::insertVectorAt(reinterpret_cast(vector), index); +} + +template inline +ssize_t Vector::appendVector(const Vector& vector) { + return VectorImpl::appendVector(reinterpret_cast(vector)); +} + +template inline +ssize_t Vector::insertArrayAt(const TYPE* array, size_t index, size_t length) { + return VectorImpl::insertArrayAt(array, index, length); +} + +template inline +ssize_t Vector::appendArray(const TYPE* array, size_t length) { + return VectorImpl::appendArray(array, length); +} + +template inline +ssize_t Vector::insertAt(const TYPE& item, size_t index, size_t numItems) { + return VectorImpl::insertAt(&item, index, numItems); +} + +template inline +void Vector::push(const TYPE& item) { + return VectorImpl::push(&item); +} + +template inline +ssize_t Vector::add(const TYPE& item) { + return VectorImpl::add(&item); +} + +template inline +ssize_t Vector::replaceAt(const TYPE& item, size_t index) { + return VectorImpl::replaceAt(&item, index); +} + +template inline +ssize_t Vector::insertAt(size_t index, size_t numItems) { + return VectorImpl::insertAt(index, numItems); +} + +template inline +void Vector::pop() { + VectorImpl::pop(); +} + +template inline +void Vector::push() { + VectorImpl::push(); +} + +template inline +ssize_t Vector::add() { + return VectorImpl::add(); +} + +template inline +ssize_t Vector::replaceAt(size_t index) { + return VectorImpl::replaceAt(index); +} + +template inline +ssize_t Vector::removeItemsAt(size_t index, size_t count) { + return VectorImpl::removeItemsAt(index, count); +} + +template inline +status_t Vector::sort(Vector::compar_t cmp) { + return VectorImpl::sort((VectorImpl::compar_t)cmp); +} + +template inline +status_t Vector::sort(Vector::compar_r_t cmp, void* state) { + return VectorImpl::sort((VectorImpl::compar_r_t)cmp, state); +} + +// --------------------------------------------------------------------------- + +template +void Vector::do_construct(void* storage, size_t num) const { + construct_type( reinterpret_cast(storage), num ); +} + +template +void Vector::do_destroy(void* storage, size_t num) const { + destroy_type( reinterpret_cast(storage), num ); +} + +template +void Vector::do_copy(void* dest, const void* from, size_t num) const { + copy_type( reinterpret_cast(dest), reinterpret_cast(from), num ); +} + +template +void Vector::do_splat(void* dest, const void* item, size_t num) const { + splat_type( reinterpret_cast(dest), reinterpret_cast(item), num ); +} + +template +void Vector::do_move_forward(void* dest, const void* from, size_t num) const { + move_forward_type( reinterpret_cast(dest), reinterpret_cast(from), num ); +} + +template +void Vector::do_move_backward(void* dest, const void* from, size_t num) const { + move_backward_type( reinterpret_cast(dest), reinterpret_cast(from), num ); +} + +}; // namespace android + + +// --------------------------------------------------------------------------- + +#endif // ANDROID_VECTOR_H diff --git a/phonelibs/android_system_core/include/utils/VectorImpl.h b/phonelibs/android_system_core/include/utils/VectorImpl.h new file mode 100644 index 00000000000000..21ad71ce607534 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/VectorImpl.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_VECTOR_IMPL_H +#define ANDROID_VECTOR_IMPL_H + +#include +#include +#include +#include + +// --------------------------------------------------------------------------- +// No user serviceable parts in here... +// --------------------------------------------------------------------------- + +namespace android { + +/*! + * Implementation of the guts of the vector<> class + * this ensures backward binary compatibility and + * reduces code size. + * For performance reasons, we expose mStorage and mCount + * so these fields are set in stone. + * + */ + +class VectorImpl +{ +public: + enum { // flags passed to the ctor + HAS_TRIVIAL_CTOR = 0x00000001, + HAS_TRIVIAL_DTOR = 0x00000002, + HAS_TRIVIAL_COPY = 0x00000004, + }; + + VectorImpl(size_t itemSize, uint32_t flags); + VectorImpl(const VectorImpl& rhs); + virtual ~VectorImpl(); + + /*! must be called from subclasses destructor */ + void finish_vector(); + + VectorImpl& operator = (const VectorImpl& rhs); + + /*! C-style array access */ + inline const void* arrayImpl() const { return mStorage; } + void* editArrayImpl(); + + /*! vector stats */ + inline size_t size() const { return mCount; } + inline bool isEmpty() const { return mCount == 0; } + size_t capacity() const; + ssize_t setCapacity(size_t size); + ssize_t resize(size_t size); + + /*! append/insert another vector or array */ + ssize_t insertVectorAt(const VectorImpl& vector, size_t index); + ssize_t appendVector(const VectorImpl& vector); + ssize_t insertArrayAt(const void* array, size_t index, size_t length); + ssize_t appendArray(const void* array, size_t length); + + /*! add/insert/replace items */ + ssize_t insertAt(size_t where, size_t numItems = 1); + ssize_t insertAt(const void* item, size_t where, size_t numItems = 1); + void pop(); + void push(); + void push(const void* item); + ssize_t add(); + ssize_t add(const void* item); + ssize_t replaceAt(size_t index); + ssize_t replaceAt(const void* item, size_t index); + + /*! remove items */ + ssize_t removeItemsAt(size_t index, size_t count = 1); + void clear(); + + const void* itemLocation(size_t index) const; + void* editItemLocation(size_t index); + + typedef int (*compar_t)(const void* lhs, const void* rhs); + typedef int (*compar_r_t)(const void* lhs, const void* rhs, void* state); + status_t sort(compar_t cmp); + status_t sort(compar_r_t cmp, void* state); + +protected: + size_t itemSize() const; + void release_storage(); + + virtual void do_construct(void* storage, size_t num) const = 0; + virtual void do_destroy(void* storage, size_t num) const = 0; + virtual void do_copy(void* dest, const void* from, size_t num) const = 0; + virtual void do_splat(void* dest, const void* item, size_t num) const = 0; + virtual void do_move_forward(void* dest, const void* from, size_t num) const = 0; + virtual void do_move_backward(void* dest, const void* from, size_t num) const = 0; + +private: + void* _grow(size_t where, size_t amount); + void _shrink(size_t where, size_t amount); + + inline void _do_construct(void* storage, size_t num) const; + inline void _do_destroy(void* storage, size_t num) const; + inline void _do_copy(void* dest, const void* from, size_t num) const; + inline void _do_splat(void* dest, const void* item, size_t num) const; + inline void _do_move_forward(void* dest, const void* from, size_t num) const; + inline void _do_move_backward(void* dest, const void* from, size_t num) const; + + // These 2 fields are exposed in the inlines below, + // so they're set in stone. + void * mStorage; // base address of the vector + size_t mCount; // number of items + + const uint32_t mFlags; + const size_t mItemSize; +}; + + + +class SortedVectorImpl : public VectorImpl +{ +public: + SortedVectorImpl(size_t itemSize, uint32_t flags); + SortedVectorImpl(const VectorImpl& rhs); + virtual ~SortedVectorImpl(); + + SortedVectorImpl& operator = (const SortedVectorImpl& rhs); + + //! finds the index of an item + ssize_t indexOf(const void* item) const; + + //! finds where this item should be inserted + size_t orderOf(const void* item) const; + + //! add an item in the right place (or replaces it if there is one) + ssize_t add(const void* item); + + //! merges a vector into this one + ssize_t merge(const VectorImpl& vector); + ssize_t merge(const SortedVectorImpl& vector); + + //! removes an item + ssize_t remove(const void* item); + +protected: + virtual int do_compare(const void* lhs, const void* rhs) const = 0; + +private: + ssize_t _indexOrderOf(const void* item, size_t* order = 0) const; + + // these are made private, because they can't be used on a SortedVector + // (they don't have an implementation either) + ssize_t add(); + void pop(); + void push(); + void push(const void* item); + ssize_t insertVectorAt(const VectorImpl& vector, size_t index); + ssize_t appendVector(const VectorImpl& vector); + ssize_t insertArrayAt(const void* array, size_t index, size_t length); + ssize_t appendArray(const void* array, size_t length); + ssize_t insertAt(size_t where, size_t numItems = 1); + ssize_t insertAt(const void* item, size_t where, size_t numItems = 1); + ssize_t replaceAt(size_t index); + ssize_t replaceAt(const void* item, size_t index); +}; + +}; // namespace android + + +// --------------------------------------------------------------------------- + +#endif // ANDROID_VECTOR_IMPL_H diff --git a/phonelibs/android_system_core/include/utils/ashmem.h b/phonelibs/android_system_core/include/utils/ashmem.h new file mode 100644 index 00000000000000..0854775780f9e9 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/ashmem.h @@ -0,0 +1,41 @@ +/* utils/ashmem.h + ** + ** Copyright 2008 The Android Open Source Project + ** + ** This file is dual licensed. It may be redistributed and/or modified + ** under the terms of the Apache 2.0 License OR version 2 of the GNU + ** General Public License. + */ + +#ifndef _UTILS_ASHMEM_H +#define _UTILS_ASHMEM_H + +#include +#include + +#define ASHMEM_NAME_LEN 256 + +#define ASHMEM_NAME_DEF "dev/ashmem" + +/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */ +#define ASHMEM_NOT_REAPED 0 +#define ASHMEM_WAS_REAPED 1 + +/* Return values from ASHMEM_UNPIN: Is the mapping now pinned or unpinned? */ +#define ASHMEM_NOW_UNPINNED 0 +#define ASHMEM_NOW_PINNED 1 + +#define __ASHMEMIOC 0x77 + +#define ASHMEM_SET_NAME _IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN]) +#define ASHMEM_GET_NAME _IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN]) +#define ASHMEM_SET_SIZE _IOW(__ASHMEMIOC, 3, size_t) +#define ASHMEM_GET_SIZE _IO(__ASHMEMIOC, 4) +#define ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned long) +#define ASHMEM_GET_PROT_MASK _IO(__ASHMEMIOC, 6) +#define ASHMEM_PIN _IO(__ASHMEMIOC, 7) +#define ASHMEM_UNPIN _IO(__ASHMEMIOC, 8) +#define ASHMEM_ISPINNED _IO(__ASHMEMIOC, 9) +#define ASHMEM_PURGE_ALL_CACHES _IO(__ASHMEMIOC, 10) + +#endif /* _UTILS_ASHMEM_H */ diff --git a/phonelibs/android_system_core/include/utils/misc.h b/phonelibs/android_system_core/include/utils/misc.h new file mode 100644 index 00000000000000..6cccec387d1102 --- /dev/null +++ b/phonelibs/android_system_core/include/utils/misc.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2005 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Handy utility functions and portability code. +// +#ifndef _LIBS_UTILS_MISC_H +#define _LIBS_UTILS_MISC_H + +#include + +/* get #of elements in a static array */ +#ifndef NELEM +# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) +#endif + +namespace android { + +typedef void (*sysprop_change_callback)(void); +void add_sysprop_change_callback(sysprop_change_callback cb, int priority); +void report_sysprop_change(); + +}; // namespace android + +#endif // _LIBS_UTILS_MISC_H diff --git a/phonelibs/android_system_core/include/utils/threads.h b/phonelibs/android_system_core/include/utils/threads.h new file mode 100644 index 00000000000000..9de3382118697f --- /dev/null +++ b/phonelibs/android_system_core/include/utils/threads.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_UTILS_THREADS_H +#define _LIBS_UTILS_THREADS_H + +/* + * Please, DO NOT USE! + * + * This file is here only for legacy reasons. Instead, include directly + * the headers you need below. + * + */ + +#include + +#ifdef __cplusplus +#include +#include +#include +#include +#include +#endif + +#endif // _LIBS_UTILS_THREADS_H diff --git a/phonelibs/boringssl/LICENSE b/phonelibs/boringssl/LICENSE new file mode 100644 index 00000000000000..2f4dfcdb04c830 --- /dev/null +++ b/phonelibs/boringssl/LICENSE @@ -0,0 +1,274 @@ +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. diff --git a/phonelibs/bzip2/LICENSE b/phonelibs/bzip2/LICENSE new file mode 100644 index 00000000000000..cc614178cf7958 --- /dev/null +++ b/phonelibs/bzip2/LICENSE @@ -0,0 +1,42 @@ + +-------------------------------------------------------------------------- + +This program, "bzip2", the associated library "libbzip2", and all +documentation, are copyright (C) 1996-2010 Julian R Seward. 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. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + +3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + +4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. + +Julian Seward, jseward@bzip.org +bzip2/libbzip2 version 1.0.6 of 6 September 2010 + +-------------------------------------------------------------------------- diff --git a/phonelibs/bzip2/build.txt b/phonelibs/bzip2/build.txt new file mode 100644 index 00000000000000..ceb3226210027a --- /dev/null +++ b/phonelibs/bzip2/build.txt @@ -0,0 +1,6 @@ +git clone https://github.com/enthought/bzip2-1.0.6.git +cd bzip2-1.0.6 +git reset --hard 288acf97a15d558f96c24c89f578b724d6e06b0c + +make libbz2.a +cp libbz2.a ../ diff --git a/phonelibs/bzip2/bzlib.h b/phonelibs/bzip2/bzlib.h new file mode 100644 index 00000000000000..8277123da8cf70 --- /dev/null +++ b/phonelibs/bzip2/bzlib.h @@ -0,0 +1,282 @@ + +/*-------------------------------------------------------------*/ +/*--- Public header file for the library. ---*/ +/*--- bzlib.h ---*/ +/*-------------------------------------------------------------*/ + +/* ------------------------------------------------------------------ + This file is part of bzip2/libbzip2, a program and library for + lossless, block-sorting data compression. + + bzip2/libbzip2 version 1.0.6 of 6 September 2010 + Copyright (C) 1996-2010 Julian Seward + + Please read the WARNING, DISCLAIMER and PATENTS sections in the + README file. + + This program is released under the terms of the license contained + in the file LICENSE. + ------------------------------------------------------------------ */ + + +#ifndef _BZLIB_H +#define _BZLIB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define BZ_RUN 0 +#define BZ_FLUSH 1 +#define BZ_FINISH 2 + +#define BZ_OK 0 +#define BZ_RUN_OK 1 +#define BZ_FLUSH_OK 2 +#define BZ_FINISH_OK 3 +#define BZ_STREAM_END 4 +#define BZ_SEQUENCE_ERROR (-1) +#define BZ_PARAM_ERROR (-2) +#define BZ_MEM_ERROR (-3) +#define BZ_DATA_ERROR (-4) +#define BZ_DATA_ERROR_MAGIC (-5) +#define BZ_IO_ERROR (-6) +#define BZ_UNEXPECTED_EOF (-7) +#define BZ_OUTBUFF_FULL (-8) +#define BZ_CONFIG_ERROR (-9) + +typedef + struct { + char *next_in; + unsigned int avail_in; + unsigned int total_in_lo32; + unsigned int total_in_hi32; + + char *next_out; + unsigned int avail_out; + unsigned int total_out_lo32; + unsigned int total_out_hi32; + + void *state; + + void *(*bzalloc)(void *,int,int); + void (*bzfree)(void *,void *); + void *opaque; + } + bz_stream; + + +#ifndef BZ_IMPORT +#define BZ_EXPORT +#endif + +#ifndef BZ_NO_STDIO +/* Need a definitition for FILE */ +#include +#endif + +#ifdef _WIN32 +# include +# ifdef small + /* windows.h define small to char */ +# undef small +# endif +# ifdef BZ_EXPORT +# define BZ_API(func) WINAPI func +# define BZ_EXTERN extern +# else + /* import windows dll dynamically */ +# define BZ_API(func) (WINAPI * func) +# define BZ_EXTERN +# endif +#else +# define BZ_API(func) func +# define BZ_EXTERN extern +#endif + + +/*-- Core (low-level) library functions --*/ + +BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( + bz_stream* strm, + int blockSize100k, + int verbosity, + int workFactor + ); + +BZ_EXTERN int BZ_API(BZ2_bzCompress) ( + bz_stream* strm, + int action + ); + +BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( + bz_stream* strm + ); + +BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( + bz_stream *strm, + int verbosity, + int small + ); + +BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( + bz_stream* strm + ); + +BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( + bz_stream *strm + ); + + + +/*-- High(er) level library functions --*/ + +#ifndef BZ_NO_STDIO +#define BZ_MAX_UNUSED 5000 + +typedef void BZFILE; + +BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( + int* bzerror, + FILE* f, + int verbosity, + int small, + void* unused, + int nUnused + ); + +BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( + int* bzerror, + BZFILE* b + ); + +BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( + int* bzerror, + BZFILE* b, + void** unused, + int* nUnused + ); + +BZ_EXTERN int BZ_API(BZ2_bzRead) ( + int* bzerror, + BZFILE* b, + void* buf, + int len + ); + +BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( + int* bzerror, + FILE* f, + int blockSize100k, + int verbosity, + int workFactor + ); + +BZ_EXTERN void BZ_API(BZ2_bzWrite) ( + int* bzerror, + BZFILE* b, + void* buf, + int len + ); + +BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( + int* bzerror, + BZFILE* b, + int abandon, + unsigned int* nbytes_in, + unsigned int* nbytes_out + ); + +BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( + int* bzerror, + BZFILE* b, + int abandon, + unsigned int* nbytes_in_lo32, + unsigned int* nbytes_in_hi32, + unsigned int* nbytes_out_lo32, + unsigned int* nbytes_out_hi32 + ); +#endif + + +/*-- Utility functions --*/ + +BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( + char* dest, + unsigned int* destLen, + char* source, + unsigned int sourceLen, + int blockSize100k, + int verbosity, + int workFactor + ); + +BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( + char* dest, + unsigned int* destLen, + char* source, + unsigned int sourceLen, + int small, + int verbosity + ); + + +/*-- + Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp) + to support better zlib compatibility. + This code is not _officially_ part of libbzip2 (yet); + I haven't tested it, documented it, or considered the + threading-safeness of it. + If this code breaks, please contact both Yoshioka and me. +--*/ + +BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) ( + void + ); + +#ifndef BZ_NO_STDIO +BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) ( + const char *path, + const char *mode + ); + +BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) ( + int fd, + const char *mode + ); + +BZ_EXTERN int BZ_API(BZ2_bzread) ( + BZFILE* b, + void* buf, + int len + ); + +BZ_EXTERN int BZ_API(BZ2_bzwrite) ( + BZFILE* b, + void* buf, + int len + ); + +BZ_EXTERN int BZ_API(BZ2_bzflush) ( + BZFILE* b + ); + +BZ_EXTERN void BZ_API(BZ2_bzclose) ( + BZFILE* b + ); + +BZ_EXTERN const char * BZ_API(BZ2_bzerror) ( + BZFILE *b, + int *errnum + ); +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/*-------------------------------------------------------------*/ +/*--- end bzlib.h ---*/ +/*-------------------------------------------------------------*/ diff --git a/phonelibs/bzip2/libbz2.a b/phonelibs/bzip2/libbz2.a new file mode 100644 index 00000000000000..0efccceb17bba5 Binary files /dev/null and b/phonelibs/bzip2/libbz2.a differ diff --git a/phonelibs/capnp-c/include/capnp_c.h b/phonelibs/capnp-c/include/capnp_c.h deleted file mode 100644 index 9fa2718f7f0cf1..00000000000000 --- a/phonelibs/capnp-c/include/capnp_c.h +++ /dev/null @@ -1,426 +0,0 @@ -/* vim: set sw=8 ts=8 sts=8 noet: */ -/* capnp_c.h - * - * Copyright (C) 2013 James McKaskill - * Copyright (C) 2014 Steve Dee - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ - -#ifndef CAPNP_C_H -#define CAPNP_C_H - -#include -#include -#if defined(unix) && !defined(__APPLE__) -#include -#endif - -// ssize_t is not defined in stdint.h in MSVC. -#ifdef _MSC_VER -typedef intmax_t ssize_t; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__cplusplus) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) -#define CAPN_INLINE static inline -#else -#define CAPN_INLINE static -#endif - -#define CAPN_VERSION 1 - -/* struct capn is a common structure shared between segments in the same - * session/context so that far pointers between segments will be created. - * - * lookup is used to lookup segments by id when derefencing a far pointer - * - * create is used to create or lookup an alternate segment that has at least - * sz available (ie returned seg->len + sz <= seg->cap) - * - * create_local is used to create a segment for the copy tree and should be - * allocated in the local memory space. - * - * Allocated segments must be zero initialized. - * - * create and lookup can be NULL if you don't need multiple segments and don't - * want to support copying - * - * seglist and copylist are linked lists which can be used to free up segments - * on cleanup, but should not be modified by the user. - * - * lookup, create, create_local, and user can be set by the user. Other values - * should be zero initialized. - */ -struct capn { - /* user settable */ - struct capn_segment *(*lookup)(void* /*user*/, uint32_t /*id */); - struct capn_segment *(*create)(void* /*user*/, uint32_t /*id */, int /*sz*/); - struct capn_segment *(*create_local)(void* /*user*/, int /*sz*/); - void *user; - /* zero initialized, user should not modify */ - uint32_t segnum; - struct capn_tree *copy; - struct capn_tree *segtree; - struct capn_segment *seglist, *lastseg; - struct capn_segment *copylist; -}; - -/* struct capn_tree is a rb tree header used internally for the segment id - * lookup and copy tree */ -struct capn_tree { - struct capn_tree *parent, *link[2]; - unsigned int red : 1; -}; - -struct capn_tree *capn_tree_insert(struct capn_tree *root, struct capn_tree *n); - -/* struct capn_segment contains the information about a single segment. - * - * capn points to a struct capn that is shared between segments in the - * same session - * - * id specifies the segment id, used for far pointers - * - * data specifies the segment data. This should not move after creation. - * - * len specifies the current segment length. This is 0 for a blank - * segment. - * - * cap specifies the segment capacity. - * - * When creating new structures len will be incremented until it reaces cap, - * at which point a new segment will be requested via capn->create. The - * create callback can either create a new segment or expand an existing - * one by incrementing cap and returning the expanded segment. - * - * data, len, and cap must all by 8 byte aligned - * - * data, len, cap, and user should all set by the user. Other values - * should be zero initialized. - */ -#ifdef _MSC_VER -__declspec(align(64)) -#endif -struct capn_segment { - struct capn_tree hdr; - struct capn_segment *next; - struct capn *capn; - uint32_t id; - /* user settable */ - char *data; - size_t len, cap; - void *user; -}; - -enum CAPN_TYPE { - CAPN_NULL = 0, - CAPN_STRUCT = 1, - CAPN_LIST = 2, - CAPN_PTR_LIST = 3, - CAPN_BIT_LIST = 4, - CAPN_FAR_POINTER = 5, -}; - -struct capn_ptr { - unsigned int type : 4; - unsigned int has_ptr_tag : 1; - unsigned int is_list_member : 1; - unsigned int is_composite_list : 1; - unsigned int datasz : 19; - unsigned int ptrs : 16; - int len; - char *data; - struct capn_segment *seg; -}; - -struct capn_text { - int len; - const char *str; - struct capn_segment *seg; -}; - -typedef struct capn_ptr capn_ptr; -typedef struct capn_text capn_text; -typedef struct {capn_ptr p;} capn_data; -typedef struct {capn_ptr p;} capn_list1; -typedef struct {capn_ptr p;} capn_list8; -typedef struct {capn_ptr p;} capn_list16; -typedef struct {capn_ptr p;} capn_list32; -typedef struct {capn_ptr p;} capn_list64; - -struct capn_msg { - struct capn_segment *seg; - uint64_t iface; - uint16_t method; - capn_ptr args; -}; - -/* capn_append_segment appends a segment to a session */ -void capn_append_segment(struct capn*, struct capn_segment*); - -capn_ptr capn_root(struct capn *c); -void capn_resolve(capn_ptr *p); - -#define capn_len(list) ((list).p.type == CAPN_FAR_POINTER ? (capn_resolve(&(list).p), (list).p.len) : (list).p.len) - -/* capn_getp|setp functions get/set ptrs in list/structs - * off is the list index or pointer index in a struct - * capn_setp will copy the data, create far pointers, etc if the target - * is in a different segment/context. - * Both of these will use/return inner pointers for composite lists. - */ -capn_ptr capn_getp(capn_ptr p, int off, int resolve); -int capn_setp(capn_ptr p, int off, capn_ptr tgt); - -capn_text capn_get_text(capn_ptr p, int off, capn_text def); -capn_data capn_get_data(capn_ptr p, int off); -int capn_set_text(capn_ptr p, int off, capn_text tgt); - -/* capn_get* functions get data from a list - * The length of the list is given by p->size - * off specifies how far into the list to start - * sz indicates the number of elements to get - * The function returns the number of elements read or -1 on an error. - * off must be byte aligned for capn_getv1 - */ -int capn_get1(capn_list1 p, int off); -uint8_t capn_get8(capn_list8 p, int off); -uint16_t capn_get16(capn_list16 p, int off); -uint32_t capn_get32(capn_list32 p, int off); -uint64_t capn_get64(capn_list64 p, int off); -int capn_getv1(capn_list1 p, int off, uint8_t *data, int sz); -int capn_getv8(capn_list8 p, int off, uint8_t *data, int sz); -int capn_getv16(capn_list16 p, int off, uint16_t *data, int sz); -int capn_getv32(capn_list32 p, int off, uint32_t *data, int sz); -int capn_getv64(capn_list64 p, int off, uint64_t *data, int sz); - -/* capn_set* functions set data in a list - * off specifies how far into the list to start - * sz indicates the number of elements to write - * The function returns the number of elemnts written or -1 on an error. - * off must be byte aligned for capn_setv1 - */ -int capn_set1(capn_list1 p, int off, int v); -int capn_set8(capn_list8 p, int off, uint8_t v); -int capn_set16(capn_list16 p, int off, uint16_t v); -int capn_set32(capn_list32 p, int off, uint32_t v); -int capn_set64(capn_list64 p, int off, uint64_t v); -int capn_setv1(capn_list1 p, int off, const uint8_t *data, int sz); -int capn_setv8(capn_list8 p, int off, const uint8_t *data, int sz); -int capn_setv16(capn_list16 p, int off, const uint16_t *data, int sz); -int capn_setv32(capn_list32 p, int off, const uint32_t *data, int sz); -int capn_setv64(capn_list64 p, int off, const uint64_t *data, int sz); - -/* capn_new_* functions create a new object - * datasz is in bytes, ptrs is # of pointers, sz is # of elements in the list - * On an error a CAPN_NULL pointer is returned - */ -capn_ptr capn_new_string(struct capn_segment *seg, const char *str, ssize_t sz); -capn_ptr capn_new_struct(struct capn_segment *seg, int datasz, int ptrs); -capn_ptr capn_new_interface(struct capn_segment *seg, int datasz, int ptrs); -capn_ptr capn_new_ptr_list(struct capn_segment *seg, int sz); -capn_ptr capn_new_list(struct capn_segment *seg, int sz, int datasz, int ptrs); -capn_list1 capn_new_list1(struct capn_segment *seg, int sz); -capn_list8 capn_new_list8(struct capn_segment *seg, int sz); -capn_list16 capn_new_list16(struct capn_segment *seg, int sz); -capn_list32 capn_new_list32(struct capn_segment *seg, int sz); -capn_list64 capn_new_list64(struct capn_segment *seg, int sz); - -/* capn_read|write* functions read/write struct values - * off is the offset into the structure in bytes - * Rarely should these be called directly, instead use the generated code. - * Data must be xored with the default value - * These are inlined - */ -CAPN_INLINE uint8_t capn_read8(capn_ptr p, int off); -CAPN_INLINE uint16_t capn_read16(capn_ptr p, int off); -CAPN_INLINE uint32_t capn_read32(capn_ptr p, int off); -CAPN_INLINE uint64_t capn_read64(capn_ptr p, int off); -CAPN_INLINE int capn_write1(capn_ptr p, int off, int val); -CAPN_INLINE int capn_write8(capn_ptr p, int off, uint8_t val); -CAPN_INLINE int capn_write16(capn_ptr p, int off, uint16_t val); -CAPN_INLINE int capn_write32(capn_ptr p, int off, uint32_t val); -CAPN_INLINE int capn_write64(capn_ptr p, int off, uint64_t val); - -/* capn_init_malloc inits the capn struct with a create function which - * allocates segments on the heap using malloc - * - * capn_init_(fp|mem) inits by reading segments in from the file/memory buffer - * in serialized form (optionally packed). It will then setup the create - * function ala capn_init_malloc so that further segments can be created. - * - * capn_free frees all the segment headers and data created by the create - * function setup by capn_init_* - */ -void capn_init_malloc(struct capn *c); -int capn_init_fp(struct capn *c, FILE *f, int packed); -int capn_init_mem(struct capn *c, const uint8_t *p, size_t sz, int packed); - -/* capn_write_(fp|mem) writes segments to the file/memory buffer in - * serialized form and returns the number of bytes written. - */ -/* TODO */ -/*int capn_write_fp(struct capn *c, FILE *f, int packed);*/ -int capn_write_fd(struct capn *c, ssize_t (*write_fd)(int fd, void *p, size_t count), int fd, int packed); -int capn_write_mem(struct capn *c, uint8_t *p, size_t sz, int packed); - -void capn_free(struct capn *c); -void capn_reset_copy(struct capn *c); - -/* Inline functions */ - - -CAPN_INLINE uint8_t capn_flip8(uint8_t v) { - return v; -} -CAPN_INLINE uint16_t capn_flip16(uint16_t v) { -#if defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN) - return v; -#elif defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN) && \ - defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 - return __builtin_bswap16(v); -#else - union { uint16_t u; uint8_t v[2]; } s; - s.v[0] = (uint8_t)v; - s.v[1] = (uint8_t)(v>>8); - return s.u; -#endif -} -CAPN_INLINE uint32_t capn_flip32(uint32_t v) { -#if defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN) - return v; -#elif defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN) && \ - defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 - return __builtin_bswap32(v); -#else - union { uint32_t u; uint8_t v[4]; } s; - s.v[0] = (uint8_t)v; - s.v[1] = (uint8_t)(v>>8); - s.v[2] = (uint8_t)(v>>16); - s.v[3] = (uint8_t)(v>>24); - return s.u; -#endif -} -CAPN_INLINE uint64_t capn_flip64(uint64_t v) { -#if defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN) - return v; -#elif defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN) && \ - defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 - return __builtin_bswap64(v); -#else - union { uint64_t u; uint8_t v[8]; } s; - s.v[0] = (uint8_t)v; - s.v[1] = (uint8_t)(v>>8); - s.v[2] = (uint8_t)(v>>16); - s.v[3] = (uint8_t)(v>>24); - s.v[4] = (uint8_t)(v>>32); - s.v[5] = (uint8_t)(v>>40); - s.v[6] = (uint8_t)(v>>48); - s.v[7] = (uint8_t)(v>>56); - return s.u; -#endif -} - -CAPN_INLINE int capn_write1(capn_ptr p, int off, int val) { - if (off >= p.datasz*8) { - return -1; - } else if (val) { - uint8_t tmp = (uint8_t)(1 << (off & 7)); - ((uint8_t*) p.data)[off >> 3] |= tmp; - return 0; - } else { - uint8_t tmp = (uint8_t)(~(1 << (off & 7))); - ((uint8_t*) p.data)[off >> 3] &= tmp; - return 0; - } -} - -CAPN_INLINE uint8_t capn_read8(capn_ptr p, int off) { - return off+1 <= p.datasz ? capn_flip8(*(uint8_t*) (p.data+off)) : 0; -} -CAPN_INLINE int capn_write8(capn_ptr p, int off, uint8_t val) { - if (off+1 <= p.datasz) { - *(uint8_t*) (p.data+off) = capn_flip8(val); - return 0; - } else { - return -1; - } -} - -CAPN_INLINE uint16_t capn_read16(capn_ptr p, int off) { - return off+2 <= p.datasz ? capn_flip16(*(uint16_t*) (p.data+off)) : 0; -} -CAPN_INLINE int capn_write16(capn_ptr p, int off, uint16_t val) { - if (off+2 <= p.datasz) { - *(uint16_t*) (p.data+off) = capn_flip16(val); - return 0; - } else { - return -1; - } -} - -CAPN_INLINE uint32_t capn_read32(capn_ptr p, int off) { - return off+4 <= p.datasz ? capn_flip32(*(uint32_t*) (p.data+off)) : 0; -} -CAPN_INLINE int capn_write32(capn_ptr p, int off, uint32_t val) { - if (off+4 <= p.datasz) { - *(uint32_t*) (p.data+off) = capn_flip32(val); - return 0; - } else { - return -1; - } -} - -CAPN_INLINE uint64_t capn_read64(capn_ptr p, int off) { - return off+8 <= p.datasz ? capn_flip64(*(uint64_t*) (p.data+off)) : 0; -} -CAPN_INLINE int capn_write64(capn_ptr p, int off, uint64_t val) { - if (off+8 <= p.datasz) { - *(uint64_t*) (p.data+off) = capn_flip64(val); - return 0; - } else { - return -1; - } -} - -union capn_conv_f32 { - uint32_t u; - float f; -}; - -union capn_conv_f64 { - uint64_t u; - double f; -}; - -CAPN_INLINE float capn_to_f32(uint32_t v) { - union capn_conv_f32 u; - u.u = v; - return u.f; -} -CAPN_INLINE double capn_to_f64(uint64_t v) { - union capn_conv_f64 u; - u.u = v; - return u.f; -} -CAPN_INLINE uint32_t capn_from_f32(float v) { - union capn_conv_f32 u; - u.f = v; - return u.u; -} -CAPN_INLINE uint64_t capn_from_f64(double v) { - union capn_conv_f64 u; - u.f = v; - return u.u; -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/capnp-cpp/aarch64/bin/capnp b/phonelibs/capnp-cpp/aarch64/bin/capnp deleted file mode 100755 index e60fe7fe3c1ba0..00000000000000 Binary files a/phonelibs/capnp-cpp/aarch64/bin/capnp and /dev/null differ diff --git a/phonelibs/capnp-cpp/aarch64/bin/capnpc b/phonelibs/capnp-cpp/aarch64/bin/capnpc deleted file mode 120000 index 5668473f09dafe..00000000000000 --- a/phonelibs/capnp-cpp/aarch64/bin/capnpc +++ /dev/null @@ -1 +0,0 @@ -capnp \ No newline at end of file diff --git a/phonelibs/capnp-cpp/aarch64/bin/capnpc-c++ b/phonelibs/capnp-cpp/aarch64/bin/capnpc-c++ deleted file mode 100755 index d3090911446257..00000000000000 Binary files a/phonelibs/capnp-cpp/aarch64/bin/capnpc-c++ and /dev/null differ diff --git a/phonelibs/capnp-cpp/aarch64/bin/capnpc-capnp b/phonelibs/capnp-cpp/aarch64/bin/capnpc-capnp deleted file mode 100755 index b1c7a9a9b818b6..00000000000000 Binary files a/phonelibs/capnp-cpp/aarch64/bin/capnpc-capnp and /dev/null differ diff --git a/phonelibs/capnp-cpp/aarch64/lib/libcapnp.a b/phonelibs/capnp-cpp/aarch64/lib/libcapnp.a deleted file mode 100644 index a997023caa4e1b..00000000000000 Binary files a/phonelibs/capnp-cpp/aarch64/lib/libcapnp.a and /dev/null differ diff --git a/phonelibs/capnp-cpp/aarch64/lib/libcapnpc.a b/phonelibs/capnp-cpp/aarch64/lib/libcapnpc.a deleted file mode 100644 index 2ede39fb910a33..00000000000000 Binary files a/phonelibs/capnp-cpp/aarch64/lib/libcapnpc.a and /dev/null differ diff --git a/phonelibs/capnp-cpp/aarch64/lib/libkj.a b/phonelibs/capnp-cpp/aarch64/lib/libkj.a deleted file mode 100644 index 58cf096637f027..00000000000000 Binary files a/phonelibs/capnp-cpp/aarch64/lib/libkj.a and /dev/null differ diff --git a/phonelibs/capnp-cpp/include/capnp/any.h b/phonelibs/capnp-cpp/include/capnp/any.h deleted file mode 100644 index 6df9dc8dc2dcea..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/any.h +++ /dev/null @@ -1,1073 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_ANY_H_ -#define CAPNP_ANY_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "layout.h" -#include "pointer-helpers.h" -#include "orphan.h" -#include "list.h" - -namespace capnp { - -class StructSchema; -class ListSchema; -class InterfaceSchema; -class Orphanage; -class ClientHook; -class PipelineHook; -struct PipelineOp; -struct AnyPointer; - -struct AnyList { - AnyList() = delete; - - class Reader; - class Builder; -}; - -struct AnyStruct { - AnyStruct() = delete; - - class Reader; - class Builder; - class Pipeline; -}; - -template<> -struct List { - List() = delete; - - class Reader; - class Builder; -}; - -namespace _ { // private -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; -} // namespace _ (private) - -// ======================================================================================= -// AnyPointer! - -enum class Equality { - NOT_EQUAL, - EQUAL, - UNKNOWN_CONTAINS_CAPS -}; - -kj::StringPtr KJ_STRINGIFY(Equality res); - -struct AnyPointer { - // Reader/Builder for the `AnyPointer` field type, i.e. a pointer that can point to an arbitrary - // object. - - AnyPointer() = delete; - - class Reader { - public: - typedef AnyPointer Reads; - - Reader() = default; - inline Reader(_::PointerReader reader): reader(reader) {} - - inline MessageSize targetSize() const; - // Get the total size of the target object and all its children. - - inline PointerType getPointerType() const; - - inline bool isNull() const { return getPointerType() == PointerType::NULL_; } - inline bool isStruct() const { return getPointerType() == PointerType::STRUCT; } - inline bool isList() const { return getPointerType() == PointerType::LIST; } - inline bool isCapability() const { return getPointerType() == PointerType::CAPABILITY; } - - Equality equals(AnyPointer::Reader right); - bool operator==(AnyPointer::Reader right); - inline bool operator!=(AnyPointer::Reader right) { - return !(*this == right); - } - - template - inline ReaderFor getAs() const; - // Valid for T = any generated struct type, interface type, List, Text, or Data. - - template - inline ReaderFor getAs(StructSchema schema) const; - // Only valid for T = DynamicStruct. Requires `#include `. - - template - inline ReaderFor getAs(ListSchema schema) const; - // Only valid for T = DynamicList. Requires `#include `. - - template - inline ReaderFor getAs(InterfaceSchema schema) const; - // Only valid for T = DynamicCapability. Requires `#include `. - -#if !CAPNP_LITE - kj::Own getPipelinedCap(kj::ArrayPtr ops) const; - // Used by RPC system to implement pipelining. Applications generally shouldn't use this - // directly. -#endif // !CAPNP_LITE - - private: - _::PointerReader reader; - friend struct AnyPointer; - friend class Orphanage; - friend class CapReaderContext; - friend struct _::PointerHelpers; - }; - - class Builder { - public: - typedef AnyPointer Builds; - - Builder() = delete; - inline Builder(decltype(nullptr)) {} - inline Builder(_::PointerBuilder builder): builder(builder) {} - - inline MessageSize targetSize() const; - // Get the total size of the target object and all its children. - - inline PointerType getPointerType(); - - inline bool isNull() { return getPointerType() == PointerType::NULL_; } - inline bool isStruct() { return getPointerType() == PointerType::STRUCT; } - inline bool isList() { return getPointerType() == PointerType::LIST; } - inline bool isCapability() { return getPointerType() == PointerType::CAPABILITY; } - - inline Equality equals(AnyPointer::Reader right) { - return asReader().equals(right); - } - inline bool operator==(AnyPointer::Reader right) { - return asReader() == right; - } - inline bool operator!=(AnyPointer::Reader right) { - return !(*this == right); - } - - inline void clear(); - // Set to null. - - template - inline BuilderFor getAs(); - // Valid for T = any generated struct type, List, Text, or Data. - - template - inline BuilderFor getAs(StructSchema schema); - // Only valid for T = DynamicStruct. Requires `#include `. - - template - inline BuilderFor getAs(ListSchema schema); - // Only valid for T = DynamicList. Requires `#include `. - - template - inline BuilderFor getAs(InterfaceSchema schema); - // Only valid for T = DynamicCapability. Requires `#include `. - - template - inline BuilderFor initAs(); - // Valid for T = any generated struct type. - - template - inline BuilderFor initAs(uint elementCount); - // Valid for T = List, Text, or Data. - - template - inline BuilderFor initAs(StructSchema schema); - // Only valid for T = DynamicStruct. Requires `#include `. - - template - inline BuilderFor initAs(ListSchema schema, uint elementCount); - // Only valid for T = DynamicList. Requires `#include `. - - inline AnyList::Builder initAsAnyList(ElementSize elementSize, uint elementCount); - // Note: Does not accept INLINE_COMPOSITE for elementSize. - - inline List::Builder initAsListOfAnyStruct( - uint16_t dataWordCount, uint16_t pointerCount, uint elementCount); - - inline AnyStruct::Builder initAsAnyStruct(uint16_t dataWordCount, uint16_t pointerCount); - - template - inline void setAs(ReaderFor value); - // Valid for ReaderType = T::Reader for T = any generated struct type, List, Text, Data, - // DynamicStruct, or DynamicList (the dynamic types require `#include `). - - template - inline void setAs(std::initializer_list>> list); - // Valid for T = List. - - template - inline void setCanonicalAs(ReaderFor value); - - inline void set(Reader value) { builder.copyFrom(value.reader); } - // Set to a copy of another AnyPointer. - - inline void setCanonical(Reader value) { builder.copyFrom(value.reader, true); } - - template - inline void adopt(Orphan&& orphan); - // Valid for T = any generated struct type, List, Text, Data, DynamicList, DynamicStruct, - // or DynamicValue (the dynamic types require `#include `). - - template - inline Orphan disownAs(); - // Valid for T = any generated struct type, List, Text, Data. - - template - inline Orphan disownAs(StructSchema schema); - // Only valid for T = DynamicStruct. Requires `#include `. - - template - inline Orphan disownAs(ListSchema schema); - // Only valid for T = DynamicList. Requires `#include `. - - template - inline Orphan disownAs(InterfaceSchema schema); - // Only valid for T = DynamicCapability. Requires `#include `. - - inline Orphan disown(); - // Disown without a type. - - inline Reader asReader() const { return Reader(builder.asReader()); } - inline operator Reader() const { return Reader(builder.asReader()); } - - private: - _::PointerBuilder builder; - friend class Orphanage; - friend class CapBuilderContext; - friend struct _::PointerHelpers; - }; - -#if !CAPNP_LITE - class Pipeline { - public: - typedef AnyPointer Pipelines; - - inline Pipeline(decltype(nullptr)) {} - inline explicit Pipeline(kj::Own&& hook): hook(kj::mv(hook)) {} - - Pipeline noop(); - // Just make a copy. - - Pipeline getPointerField(uint16_t pointerIndex); - // Deprecated. In the future, we should use .asAnyStruct.getPointerField. - - inline AnyStruct::Pipeline asAnyStruct(); - - kj::Own asCap(); - // Expect that the result is a capability and construct a pipelined version of it now. - - inline kj::Own releasePipelineHook() { return kj::mv(hook); } - // For use by RPC implementations. - - template ) == Kind::INTERFACE>> - inline operator T() { return T(asCap()); } - - private: - kj::Own hook; - kj::Array ops; - - inline Pipeline(kj::Own&& hook, kj::Array&& ops) - : hook(kj::mv(hook)), ops(kj::mv(ops)) {} - - friend class LocalClient; - friend class PipelineHook; - friend class AnyStruct::Pipeline; - }; -#endif // !CAPNP_LITE -}; - -template <> -class Orphan { - // An orphaned object of unknown type. - -public: - Orphan() = default; - KJ_DISALLOW_COPY(Orphan); - Orphan(Orphan&&) = default; - inline Orphan(_::OrphanBuilder&& builder) - : builder(kj::mv(builder)) {} - - Orphan& operator=(Orphan&&) = default; - - template - inline Orphan(Orphan&& other): builder(kj::mv(other.builder)) {} - template - inline Orphan& operator=(Orphan&& other) { builder = kj::mv(other.builder); return *this; } - // Cast from typed orphan. - - // It's not possible to get an AnyPointer::{Reader,Builder} directly since there is no - // underlying pointer (the pointer would normally live in the parent, but this object is - // orphaned). It is possible, however, to request typed readers/builders. - - template - inline BuilderFor getAs(); - template - inline BuilderFor getAs(StructSchema schema); - template - inline BuilderFor getAs(ListSchema schema); - template - inline typename T::Client getAs(InterfaceSchema schema); - template - inline ReaderFor getAsReader() const; - template - inline ReaderFor getAsReader(StructSchema schema) const; - template - inline ReaderFor getAsReader(ListSchema schema) const; - template - inline typename T::Client getAsReader(InterfaceSchema schema) const; - - template - inline Orphan releaseAs(); - template - inline Orphan releaseAs(StructSchema schema); - template - inline Orphan releaseAs(ListSchema schema); - template - inline Orphan releaseAs(InterfaceSchema schema); - // Down-cast the orphan to a specific type. - - inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } - -private: - _::OrphanBuilder builder; - - template - friend struct _::PointerHelpers; - friend class Orphanage; - template - friend class Orphan; - friend class AnyPointer::Builder; -}; - -template struct AnyTypeFor_; -template <> struct AnyTypeFor_ { typedef AnyStruct Type; }; -template <> struct AnyTypeFor_ { typedef AnyList Type; }; - -template -using AnyTypeFor = typename AnyTypeFor_::Type; - -template -inline ReaderFor>> toAny(T&& value) { - return ReaderFor>>( - _::PointerHelpers>::getInternalReader(value)); -} -template -inline BuilderFor>> toAny(T&& value) { - return BuilderFor>>( - _::PointerHelpers>::getInternalBuilder(kj::mv(value))); -} - -template <> -struct List { - // Note: This cannot be used for a list of structs, since such lists are not encoded as pointer - // lists! Use List. - - List() = delete; - - class Reader { - public: - typedef List Reads; - - inline Reader(): reader(ElementSize::POINTER) {} - inline explicit Reader(_::ListReader reader): reader(reader) {} - - inline uint size() const { return unbound(reader.size() / ELEMENTS); } - inline AnyPointer::Reader operator[](uint index) const { - KJ_IREQUIRE(index < size()); - return AnyPointer::Reader(reader.getPointerElement(bounded(index) * ELEMENTS)); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - - private: - _::ListReader reader; - template - friend struct _::PointerHelpers; - template - friend struct List; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Builder { - public: - typedef List Builds; - - Builder() = delete; - inline Builder(decltype(nullptr)): builder(ElementSize::POINTER) {} - inline explicit Builder(_::ListBuilder builder): builder(builder) {} - - inline operator Reader() const { return Reader(builder.asReader()); } - inline Reader asReader() const { return Reader(builder.asReader()); } - - inline uint size() const { return unbound(builder.size() / ELEMENTS); } - inline AnyPointer::Builder operator[](uint index) { - KJ_IREQUIRE(index < size()); - return AnyPointer::Builder(builder.getPointerElement(bounded(index) * ELEMENTS)); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - - private: - _::ListBuilder builder; - template - friend struct _::PointerHelpers; - friend class Orphanage; - template - friend struct ToDynamic_; - }; -}; - -class AnyStruct::Reader { -public: - typedef AnyStruct Reads; - - Reader() = default; - inline Reader(_::StructReader reader): _reader(reader) {} - - template ) == Kind::STRUCT>> - inline Reader(T&& value) - : _reader(_::PointerHelpers>::getInternalReader(kj::fwd(value))) {} - - kj::ArrayPtr getDataSection() { - return _reader.getDataSectionAsBlob(); - } - List::Reader getPointerSection() { - return List::Reader(_reader.getPointerSectionAsList()); - } - - kj::Array canonicalize() { - return _reader.canonicalize(); - } - - Equality equals(AnyStruct::Reader right); - bool operator==(AnyStruct::Reader right); - inline bool operator!=(AnyStruct::Reader right) { - return !(*this == right); - } - - template - ReaderFor as() const { - // T must be a struct type. - return typename T::Reader(_reader); - } -private: - _::StructReader _reader; - - template - friend struct _::PointerHelpers; - friend class Orphanage; -}; - -class AnyStruct::Builder { -public: - typedef AnyStruct Builds; - - inline Builder(decltype(nullptr)) {} - inline Builder(_::StructBuilder builder): _builder(builder) {} - -#if !_MSC_VER // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves. - template ) == Kind::STRUCT>> - inline Builder(T&& value) - : _builder(_::PointerHelpers>::getInternalBuilder(kj::fwd(value))) {} -#endif - - inline kj::ArrayPtr getDataSection() { - return _builder.getDataSectionAsBlob(); - } - List::Builder getPointerSection() { - return List::Builder(_builder.getPointerSectionAsList()); - } - - inline Equality equals(AnyStruct::Reader right) { - return asReader().equals(right); - } - inline bool operator==(AnyStruct::Reader right) { - return asReader() == right; - } - inline bool operator!=(AnyStruct::Reader right) { - return !(*this == right); - } - - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return Reader(_builder.asReader()); } - - template - BuilderFor as() { - // T must be a struct type. - return typename T::Builder(_builder); - } -private: - _::StructBuilder _builder; - friend class Orphanage; - friend class CapBuilderContext; -}; - -#if !CAPNP_LITE -class AnyStruct::Pipeline { -public: - inline Pipeline(decltype(nullptr)): typeless(nullptr) {} - inline explicit Pipeline(AnyPointer::Pipeline&& typeless) - : typeless(kj::mv(typeless)) {} - - inline AnyPointer::Pipeline getPointerField(uint16_t pointerIndex) { - // Return a new Promise representing a sub-object of the result. `pointerIndex` is the index - // of the sub-object within the pointer section of the result (the result must be a struct). - // - // TODO(perf): On GCC 4.8 / Clang 3.3, use rvalue qualifiers to avoid the need for copies. - // Also make `ops` into a Vector to optimize this. - return typeless.getPointerField(pointerIndex); - } - -private: - AnyPointer::Pipeline typeless; -}; -#endif // !CAPNP_LITE - -class List::Reader { -public: - typedef List Reads; - - inline Reader(): reader(ElementSize::INLINE_COMPOSITE) {} - inline explicit Reader(_::ListReader reader): reader(reader) {} - - inline uint size() const { return unbound(reader.size() / ELEMENTS); } - inline AnyStruct::Reader operator[](uint index) const { - KJ_IREQUIRE(index < size()); - return AnyStruct::Reader(reader.getStructElement(bounded(index) * ELEMENTS)); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - _::ListReader reader; - template - friend struct _::PointerHelpers; - template - friend struct List; - friend class Orphanage; - template - friend struct ToDynamic_; -}; - -class List::Builder { -public: - typedef List Builds; - - Builder() = delete; - inline Builder(decltype(nullptr)): builder(ElementSize::INLINE_COMPOSITE) {} - inline explicit Builder(_::ListBuilder builder): builder(builder) {} - - inline operator Reader() const { return Reader(builder.asReader()); } - inline Reader asReader() const { return Reader(builder.asReader()); } - - inline uint size() const { return unbound(builder.size() / ELEMENTS); } - inline AnyStruct::Builder operator[](uint index) { - KJ_IREQUIRE(index < size()); - return AnyStruct::Builder(builder.getStructElement(bounded(index) * ELEMENTS)); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - -private: - _::ListBuilder builder; - template - friend struct _::PointerHelpers; - friend class Orphanage; - template - friend struct ToDynamic_; -}; - -class AnyList::Reader { -public: - typedef AnyList Reads; - - inline Reader(): _reader(ElementSize::VOID) {} - inline Reader(_::ListReader reader): _reader(reader) {} - -#if !_MSC_VER // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves. - template ) == Kind::LIST>> - inline Reader(T&& value) - : _reader(_::PointerHelpers>::getInternalReader(kj::fwd(value))) {} -#endif - - inline ElementSize getElementSize() { return _reader.getElementSize(); } - inline uint size() { return unbound(_reader.size() / ELEMENTS); } - - inline kj::ArrayPtr getRawBytes() { return _reader.asRawBytes(); } - - Equality equals(AnyList::Reader right); - bool operator==(AnyList::Reader right); - inline bool operator!=(AnyList::Reader right) { - return !(*this == right); - } - - template ReaderFor as() { - // T must be List. - return ReaderFor(_reader); - } -private: - _::ListReader _reader; - - template - friend struct _::PointerHelpers; - friend class Orphanage; -}; - -class AnyList::Builder { -public: - typedef AnyList Builds; - - inline Builder(decltype(nullptr)): _builder(ElementSize::VOID) {} - inline Builder(_::ListBuilder builder): _builder(builder) {} - -#if !_MSC_VER // TODO(msvc): MSVC ICEs on this. Try restoring when compiler improves. - template ) == Kind::LIST>> - inline Builder(T&& value) - : _builder(_::PointerHelpers>::getInternalBuilder(kj::fwd(value))) {} -#endif - - inline ElementSize getElementSize() { return _builder.getElementSize(); } - inline uint size() { return unbound(_builder.size() / ELEMENTS); } - - Equality equals(AnyList::Reader right); - inline bool operator==(AnyList::Reader right) { - return asReader() == right; - } - inline bool operator!=(AnyList::Reader right) { - return !(*this == right); - } - - template BuilderFor as() { - // T must be List. - return BuilderFor(_builder); - } - - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return Reader(_builder.asReader()); } - -private: - _::ListBuilder _builder; - - friend class Orphanage; -}; - -// ======================================================================================= -// Pipeline helpers -// -// These relate to capabilities, but we don't declare them in capability.h because generated code -// for structs needs to know about these, even in files that contain no interfaces. - -#if !CAPNP_LITE - -struct PipelineOp { - // Corresponds to rpc.capnp's PromisedAnswer.Op. - - enum Type { - NOOP, // for convenience - - GET_POINTER_FIELD - - // There may be other types in the future... - }; - - Type type; - union { - uint16_t pointerIndex; // for GET_POINTER_FIELD - }; -}; - -class PipelineHook { - // Represents a currently-running call, and implements pipelined requests on its result. - -public: - virtual kj::Own addRef() = 0; - // Increment this object's reference count. - - virtual kj::Own getPipelinedCap(kj::ArrayPtr ops) = 0; - // Extract a promised Capability from the results. - - virtual kj::Own getPipelinedCap(kj::Array&& ops); - // Version of getPipelinedCap() passing the array by move. May avoid a copy in some cases. - // Default implementation just calls the other version. - - template > - static inline kj::Own from(Pipeline&& pipeline); - -private: - template struct FromImpl; -}; - -#endif // !CAPNP_LITE - -// ======================================================================================= -// Inline implementation details - -inline MessageSize AnyPointer::Reader::targetSize() const { - return reader.targetSize().asPublic(); -} - -inline PointerType AnyPointer::Reader::getPointerType() const { - return reader.getPointerType(); -} - -template -inline ReaderFor AnyPointer::Reader::getAs() const { - return _::PointerHelpers::get(reader); -} - -inline MessageSize AnyPointer::Builder::targetSize() const { - return asReader().targetSize(); -} - -inline PointerType AnyPointer::Builder::getPointerType() { - return builder.getPointerType(); -} - -inline void AnyPointer::Builder::clear() { - return builder.clear(); -} - -template -inline BuilderFor AnyPointer::Builder::getAs() { - return _::PointerHelpers::get(builder); -} - -template -inline BuilderFor AnyPointer::Builder::initAs() { - return _::PointerHelpers::init(builder); -} - -template -inline BuilderFor AnyPointer::Builder::initAs(uint elementCount) { - return _::PointerHelpers::init(builder, elementCount); -} - -inline AnyList::Builder AnyPointer::Builder::initAsAnyList( - ElementSize elementSize, uint elementCount) { - return AnyList::Builder(builder.initList(elementSize, bounded(elementCount) * ELEMENTS)); -} - -inline List::Builder AnyPointer::Builder::initAsListOfAnyStruct( - uint16_t dataWordCount, uint16_t pointerCount, uint elementCount) { - return List::Builder(builder.initStructList(bounded(elementCount) * ELEMENTS, - _::StructSize(bounded(dataWordCount) * WORDS, - bounded(pointerCount) * POINTERS))); -} - -inline AnyStruct::Builder AnyPointer::Builder::initAsAnyStruct( - uint16_t dataWordCount, uint16_t pointerCount) { - return AnyStruct::Builder(builder.initStruct( - _::StructSize(bounded(dataWordCount) * WORDS, - bounded(pointerCount) * POINTERS))); -} - -template -inline void AnyPointer::Builder::setAs(ReaderFor value) { - return _::PointerHelpers::set(builder, value); -} - -template -inline void AnyPointer::Builder::setCanonicalAs(ReaderFor value) { - return _::PointerHelpers::setCanonical(builder, value); -} - -template -inline void AnyPointer::Builder::setAs( - std::initializer_list>> list) { - return _::PointerHelpers::set(builder, list); -} - -template -inline void AnyPointer::Builder::adopt(Orphan&& orphan) { - _::PointerHelpers::adopt(builder, kj::mv(orphan)); -} - -template -inline Orphan AnyPointer::Builder::disownAs() { - return _::PointerHelpers::disown(builder); -} - -inline Orphan AnyPointer::Builder::disown() { - return Orphan(builder.disown()); -} - -template <> struct ReaderFor_ { typedef AnyPointer::Reader Type; }; -template <> struct BuilderFor_ { typedef AnyPointer::Builder Type; }; -template <> struct ReaderFor_ { typedef AnyStruct::Reader Type; }; -template <> struct BuilderFor_ { typedef AnyStruct::Builder Type; }; - -template <> -struct Orphanage::GetInnerReader { - static inline _::PointerReader apply(const AnyPointer::Reader& t) { - return t.reader; - } -}; - -template <> -struct Orphanage::GetInnerBuilder { - static inline _::PointerBuilder apply(AnyPointer::Builder& t) { - return t.builder; - } -}; - -template <> -struct Orphanage::GetInnerReader { - static inline _::StructReader apply(const AnyStruct::Reader& t) { - return t._reader; - } -}; - -template <> -struct Orphanage::GetInnerBuilder { - static inline _::StructBuilder apply(AnyStruct::Builder& t) { - return t._builder; - } -}; - -template <> -struct Orphanage::GetInnerReader { - static inline _::ListReader apply(const AnyList::Reader& t) { - return t._reader; - } -}; - -template <> -struct Orphanage::GetInnerBuilder { - static inline _::ListBuilder apply(AnyList::Builder& t) { - return t._builder; - } -}; - -template -inline BuilderFor Orphan::getAs() { - return _::OrphanGetImpl::apply(builder); -} -template -inline ReaderFor Orphan::getAsReader() const { - return _::OrphanGetImpl::applyReader(builder); -} -template -inline Orphan Orphan::releaseAs() { - return Orphan(kj::mv(builder)); -} - -// Using AnyPointer as the template type should work... - -template <> -inline typename AnyPointer::Reader AnyPointer::Reader::getAs() const { - return *this; -} -template <> -inline typename AnyPointer::Builder AnyPointer::Builder::getAs() { - return *this; -} -template <> -inline typename AnyPointer::Builder AnyPointer::Builder::initAs() { - clear(); - return *this; -} -template <> -inline void AnyPointer::Builder::setAs(AnyPointer::Reader value) { - return builder.copyFrom(value.reader); -} -template <> -inline void AnyPointer::Builder::adopt(Orphan&& orphan) { - builder.adopt(kj::mv(orphan.builder)); -} -template <> -inline Orphan AnyPointer::Builder::disownAs() { - return Orphan(builder.disown()); -} -template <> -inline Orphan Orphan::releaseAs() { - return kj::mv(*this); -} - -namespace _ { // private - -// Specialize PointerHelpers for AnyPointer. - -template <> -struct PointerHelpers { - static inline AnyPointer::Reader get(PointerReader reader, - const void* defaultValue = nullptr, - uint defaultBytes = 0) { - return AnyPointer::Reader(reader); - } - static inline AnyPointer::Builder get(PointerBuilder builder, - const void* defaultValue = nullptr, - uint defaultBytes = 0) { - return AnyPointer::Builder(builder); - } - static inline void set(PointerBuilder builder, AnyPointer::Reader value) { - AnyPointer::Builder(builder).set(value); - } - static inline void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan disown(PointerBuilder builder) { - return Orphan(builder.disown()); - } - static inline _::PointerReader getInternalReader(const AnyPointer::Reader& reader) { - return reader.reader; - } - static inline _::PointerBuilder getInternalBuilder(AnyPointer::Builder&& builder) { - return builder.builder; - } -}; - -template <> -struct PointerHelpers { - static inline AnyStruct::Reader get( - PointerReader reader, const word* defaultValue = nullptr) { - return AnyStruct::Reader(reader.getStruct(defaultValue)); - } - static inline AnyStruct::Builder get( - PointerBuilder builder, const word* defaultValue = nullptr) { - // TODO(someday): Allow specifying the size somehow? - return AnyStruct::Builder(builder.getStruct( - _::StructSize(ZERO * WORDS, ZERO * POINTERS), defaultValue)); - } - static inline void set(PointerBuilder builder, AnyStruct::Reader value) { - builder.setStruct(value._reader); - } - static inline AnyStruct::Builder init( - PointerBuilder builder, uint16_t dataWordCount, uint16_t pointerCount) { - return AnyStruct::Builder(builder.initStruct( - StructSize(bounded(dataWordCount) * WORDS, - bounded(pointerCount) * POINTERS))); - } - - static void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static Orphan disown(PointerBuilder builder) { - return Orphan(builder.disown()); - } -}; - -template <> -struct PointerHelpers { - static inline AnyList::Reader get( - PointerReader reader, const word* defaultValue = nullptr) { - return AnyList::Reader(reader.getListAnySize(defaultValue)); - } - static inline AnyList::Builder get( - PointerBuilder builder, const word* defaultValue = nullptr) { - return AnyList::Builder(builder.getListAnySize(defaultValue)); - } - static inline void set(PointerBuilder builder, AnyList::Reader value) { - builder.setList(value._reader); - } - static inline AnyList::Builder init( - PointerBuilder builder, ElementSize elementSize, uint elementCount) { - return AnyList::Builder(builder.initList( - elementSize, bounded(elementCount) * ELEMENTS)); - } - static inline AnyList::Builder init( - PointerBuilder builder, uint16_t dataWordCount, uint16_t pointerCount, uint elementCount) { - return AnyList::Builder(builder.initStructList( - bounded(elementCount) * ELEMENTS, - StructSize(bounded(dataWordCount) * WORDS, - bounded(pointerCount) * POINTERS))); - } - - static void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static Orphan disown(PointerBuilder builder) { - return Orphan(builder.disown()); - } -}; - -template <> -struct OrphanGetImpl { - static inline AnyStruct::Builder apply(_::OrphanBuilder& builder) { - return AnyStruct::Builder(builder.asStruct(_::StructSize(ZERO * WORDS, ZERO * POINTERS))); - } - static inline AnyStruct::Reader applyReader(const _::OrphanBuilder& builder) { - return AnyStruct::Reader(builder.asStructReader(_::StructSize(ZERO * WORDS, ZERO * POINTERS))); - } - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, _::StructSize(ZERO * WORDS, ZERO * POINTERS)); - } -}; - -template <> -struct OrphanGetImpl { - static inline AnyList::Builder apply(_::OrphanBuilder& builder) { - return AnyList::Builder(builder.asListAnySize()); - } - static inline AnyList::Reader applyReader(const _::OrphanBuilder& builder) { - return AnyList::Reader(builder.asListReaderAnySize()); - } - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, ElementSize::POINTER); - } -}; - -} // namespace _ (private) - -#if !CAPNP_LITE - -template -struct PipelineHook::FromImpl { - static inline kj::Own apply(typename T::Pipeline&& pipeline) { - return from(kj::mv(pipeline._typeless)); - } -}; - -template <> -struct PipelineHook::FromImpl { - static inline kj::Own apply(AnyPointer::Pipeline&& pipeline) { - return kj::mv(pipeline.hook); - } -}; - -template -inline kj::Own PipelineHook::from(Pipeline&& pipeline) { - return FromImpl::apply(kj::fwd(pipeline)); -} - -#endif // !CAPNP_LITE - -} // namespace capnp - -#endif // CAPNP_ANY_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/blob.h b/phonelibs/capnp-cpp/include/capnp/blob.h deleted file mode 100644 index d11f101a5ad378..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/blob.h +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_BLOB_H_ -#define CAPNP_BLOB_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include -#include -#include "common.h" -#include - -namespace capnp { - -struct Data { - Data() = delete; - class Reader; - class Builder; - class Pipeline {}; -}; - -struct Text { - Text() = delete; - class Reader; - class Builder; - class Pipeline {}; -}; - -class Data::Reader: public kj::ArrayPtr { - // Points to a blob of bytes. The usual Reader rules apply -- Data::Reader behaves like a simple - // pointer which does not own its target, can be passed by value, etc. - -public: - typedef Data Reads; - - Reader() = default; - inline Reader(decltype(nullptr)): ArrayPtr(nullptr) {} - inline Reader(const byte* value, size_t size): ArrayPtr(value, size) {} - inline Reader(const kj::Array& value): ArrayPtr(value) {} - inline Reader(const ArrayPtr& value): ArrayPtr(value) {} - inline Reader(const kj::Array& value): ArrayPtr(value) {} - inline Reader(const ArrayPtr& value): ArrayPtr(value) {} -}; - -class Text::Reader: public kj::StringPtr { - // Like Data::Reader, but points at NUL-terminated UTF-8 text. The NUL terminator is not counted - // in the size but must be present immediately after the last byte. - // - // Text::Reader's interface contract is that its data MUST be NUL-terminated. The producer of - // the Text::Reader must guarantee this, so that the consumer need not check. The data SHOULD - // also be valid UTF-8, but this is NOT guaranteed -- the consumer must verify if it cares. - -public: - typedef Text Reads; - - Reader() = default; - inline Reader(decltype(nullptr)): StringPtr(nullptr) {} - inline Reader(const char* value): StringPtr(value) {} - inline Reader(const char* value, size_t size): StringPtr(value, size) {} - inline Reader(const kj::String& value): StringPtr(value) {} - inline Reader(const StringPtr& value): StringPtr(value) {} - -#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP - template ().c_str())> - inline Reader(const T& t): StringPtr(t) {} - // Allow implicit conversion from any class that has a c_str() method (namely, std::string). - // We use a template trick to detect std::string in order to avoid including the header for - // those who don't want it. -#endif -}; - -class Data::Builder: public kj::ArrayPtr { - // Like Data::Reader except the pointers aren't const. - -public: - typedef Data Builds; - - Builder() = default; - inline Builder(decltype(nullptr)): ArrayPtr(nullptr) {} - inline Builder(byte* value, size_t size): ArrayPtr(value, size) {} - inline Builder(kj::Array& value): ArrayPtr(value) {} - inline Builder(ArrayPtr value): ArrayPtr(value) {} - - inline Data::Reader asReader() const { return Data::Reader(*this); } - inline operator Reader() const { return asReader(); } -}; - -class Text::Builder: public kj::DisallowConstCopy { - // Basically identical to kj::StringPtr, except that the contents are non-const. - -public: - inline Builder(): content(nulstr, 1) {} - inline Builder(decltype(nullptr)): content(nulstr, 1) {} - inline Builder(char* value): content(value, strlen(value) + 1) {} - inline Builder(char* value, size_t size): content(value, size + 1) { - KJ_IREQUIRE(value[size] == '\0', "StringPtr must be NUL-terminated."); - } - - inline Reader asReader() const { return Reader(content.begin(), content.size() - 1); } - inline operator Reader() const { return asReader(); } - - inline operator kj::ArrayPtr(); - inline kj::ArrayPtr asArray(); - inline operator kj::ArrayPtr() const; - inline kj::ArrayPtr asArray() const; - inline kj::ArrayPtr asBytes() { return asArray().asBytes(); } - inline kj::ArrayPtr asBytes() const { return asArray().asBytes(); } - // Result does not include NUL terminator. - - inline operator kj::StringPtr() const; - inline kj::StringPtr asString() const; - - inline const char* cStr() const { return content.begin(); } - // Returns NUL-terminated string. - - inline size_t size() const { return content.size() - 1; } - // Result does not include NUL terminator. - - inline char operator[](size_t index) const { return content[index]; } - inline char& operator[](size_t index) { return content[index]; } - - inline char* begin() { return content.begin(); } - inline char* end() { return content.end() - 1; } - inline const char* begin() const { return content.begin(); } - inline const char* end() const { return content.end() - 1; } - - inline bool operator==(decltype(nullptr)) const { return content.size() <= 1; } - inline bool operator!=(decltype(nullptr)) const { return content.size() > 1; } - - inline bool operator==(Builder other) const { return asString() == other.asString(); } - inline bool operator!=(Builder other) const { return asString() != other.asString(); } - inline bool operator< (Builder other) const { return asString() < other.asString(); } - inline bool operator> (Builder other) const { return asString() > other.asString(); } - inline bool operator<=(Builder other) const { return asString() <= other.asString(); } - inline bool operator>=(Builder other) const { return asString() >= other.asString(); } - - inline kj::StringPtr slice(size_t start) const; - inline kj::ArrayPtr slice(size_t start, size_t end) const; - inline Builder slice(size_t start); - inline kj::ArrayPtr slice(size_t start, size_t end); - // A string slice is only NUL-terminated if it is a suffix, so slice() has a one-parameter - // version that assumes end = size(). - -private: - inline explicit Builder(kj::ArrayPtr content): content(content) {} - - kj::ArrayPtr content; - - static char nulstr[1]; -}; - -inline kj::StringPtr KJ_STRINGIFY(Text::Builder builder) { - return builder.asString(); -} - -inline bool operator==(const char* a, const Text::Builder& b) { return a == b.asString(); } -inline bool operator!=(const char* a, const Text::Builder& b) { return a != b.asString(); } - -inline Text::Builder::operator kj::StringPtr() const { - return kj::StringPtr(content.begin(), content.size() - 1); -} - -inline kj::StringPtr Text::Builder::asString() const { - return kj::StringPtr(content.begin(), content.size() - 1); -} - -inline Text::Builder::operator kj::ArrayPtr() { - return content.slice(0, content.size() - 1); -} - -inline kj::ArrayPtr Text::Builder::asArray() { - return content.slice(0, content.size() - 1); -} - -inline Text::Builder::operator kj::ArrayPtr() const { - return content.slice(0, content.size() - 1); -} - -inline kj::ArrayPtr Text::Builder::asArray() const { - return content.slice(0, content.size() - 1); -} - -inline kj::StringPtr Text::Builder::slice(size_t start) const { - return asReader().slice(start); -} -inline kj::ArrayPtr Text::Builder::slice(size_t start, size_t end) const { - return content.slice(start, end); -} - -inline Text::Builder Text::Builder::slice(size_t start) { - return Text::Builder(content.slice(start, content.size())); -} -inline kj::ArrayPtr Text::Builder::slice(size_t start, size_t end) { - return content.slice(start, end); -} - -} // namespace capnp - -#endif // CAPNP_BLOB_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/c++.capnp b/phonelibs/capnp-cpp/include/capnp/c++.capnp deleted file mode 100644 index 2bda54717920ab..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/c++.capnp +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -# Licensed under the MIT License: -# -# 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. - -@0xbdf87d7bb8304e81; -$namespace("capnp::annotations"); - -annotation namespace(file): Text; -annotation name(field, enumerant, struct, enum, interface, method, param, group, union): Text; diff --git a/phonelibs/capnp-cpp/include/capnp/c++.capnp.h b/phonelibs/capnp-cpp/include/capnp/c++.capnp.h deleted file mode 100644 index 6d9817fbded116..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/c++.capnp.h +++ /dev/null @@ -1,33 +0,0 @@ -// Generated by Cap'n Proto compiler, DO NOT EDIT -// source: c++.capnp - -#ifndef CAPNP_INCLUDED_bdf87d7bb8304e81_ -#define CAPNP_INCLUDED_bdf87d7bb8304e81_ - -#include - -#if CAPNP_VERSION != 6001 -#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." -#endif - - -namespace capnp { -namespace schemas { - -CAPNP_DECLARE_SCHEMA(b9c6f99ebf805f2c); -CAPNP_DECLARE_SCHEMA(f264a779fef191ce); - -} // namespace schemas -} // namespace capnp - -namespace capnp { -namespace annotations { - -// ======================================================================================= - -// ======================================================================================= - -} // namespace -} // namespace - -#endif // CAPNP_INCLUDED_bdf87d7bb8304e81_ diff --git a/phonelibs/capnp-cpp/include/capnp/c.capnp b/phonelibs/capnp-cpp/include/capnp/c.capnp deleted file mode 100644 index 5de7e7363afcc0..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/c.capnp +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (c) 2016 NetDEF, Inc. and contributors -# Licensed under the MIT License: -# -# 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. - -@0xc0183dd65ffef0f3; - -annotation nameinfix @0x85a8d86d736ba637 (file): Text; -# add an infix (middle insert) for output file names -# -# "make" generally has implicit rules for compiling "foo.c" => "foo". This -# is very annoying with capnp since the rule will be "foo" => "foo.c", leading -# to a loop. $nameinfix (recommended parameter: "-gen") inserts its parameter -# before the ".c", so the filename becomes "foo-gen.c" -# -# ("foo" is really "foo.capnp", so it's foo.capnp-gen.c) - -annotation fieldgetset @0xf72bc690355d66de (file): Void; -# generate getter & setter functions for accessing fields -# -# allows grabbing/putting values without de-/encoding the entire struct. diff --git a/phonelibs/capnp-cpp/include/capnp/capability.h b/phonelibs/capnp-cpp/include/capnp/capability.h deleted file mode 100644 index 56a5e6f6de2d38..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/capability.h +++ /dev/null @@ -1,884 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_CAPABILITY_H_ -#define CAPNP_CAPABILITY_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#if CAPNP_LITE -#error "RPC APIs, including this header, are not available in lite mode." -#endif - -#include -#include -#include "raw-schema.h" -#include "any.h" -#include "pointer-helpers.h" - -namespace capnp { - -template -class Response; - -template -class RemotePromise: public kj::Promise>, public T::Pipeline { - // A Promise which supports pipelined calls. T is typically a struct type. T must declare - // an inner "mix-in" type "Pipeline" which implements pipelining; RemotePromise simply - // multiply-inherits that type along with Promise>. T::Pipeline must be movable, - // but does not need to be copyable (i.e. just like Promise). - // - // The promise is for an owned pointer so that the RPC system can allocate the MessageReader - // itself. - -public: - inline RemotePromise(kj::Promise>&& promise, typename T::Pipeline&& pipeline) - : kj::Promise>(kj::mv(promise)), - T::Pipeline(kj::mv(pipeline)) {} - inline RemotePromise(decltype(nullptr)) - : kj::Promise>(nullptr), - T::Pipeline(nullptr) {} - KJ_DISALLOW_COPY(RemotePromise); - RemotePromise(RemotePromise&& other) = default; - RemotePromise& operator=(RemotePromise&& other) = default; -}; - -class LocalClient; -namespace _ { // private -extern const RawSchema NULL_INTERFACE_SCHEMA; // defined in schema.c++ -class CapabilityServerSetBase; -} // namespace _ (private) - -struct Capability { - // A capability without type-safe methods. Typed capability clients wrap `Client` and typed - // capability servers subclass `Server` to dispatch to the regular, typed methods. - - class Client; - class Server; - - struct _capnpPrivate { - struct IsInterface; - static constexpr uint64_t typeId = 0x3; - static constexpr Kind kind = Kind::INTERFACE; - static constexpr _::RawSchema const* schema = &_::NULL_INTERFACE_SCHEMA; - - static const _::RawBrandedSchema* brand() { - return &_::NULL_INTERFACE_SCHEMA.defaultBrand; - } - }; -}; - -// ======================================================================================= -// Capability clients - -class RequestHook; -class ResponseHook; -class PipelineHook; -class ClientHook; - -template -class Request: public Params::Builder { - // A call that hasn't been sent yet. This class extends a Builder for the call's "Params" - // structure with a method send() that actually sends it. - // - // Given a Cap'n Proto method `foo(a :A, b :B): C`, the generated client interface will have - // a method `Request fooRequest()` (as well as a convenience method - // `RemotePromise foo(A::Reader a, B::Reader b)`). - -public: - inline Request(typename Params::Builder builder, kj::Own&& hook) - : Params::Builder(builder), hook(kj::mv(hook)) {} - inline Request(decltype(nullptr)): Params::Builder(nullptr) {} - - RemotePromise send() KJ_WARN_UNUSED_RESULT; - // Send the call and return a promise for the results. - -private: - kj::Own hook; - - friend class Capability::Client; - friend struct DynamicCapability; - template - friend class CallContext; - friend class RequestHook; -}; - -template -class Response: public Results::Reader { - // A completed call. This class extends a Reader for the call's answer structure. The Response - // is move-only -- once it goes out-of-scope, the underlying message will be freed. - -public: - inline Response(typename Results::Reader reader, kj::Own&& hook) - : Results::Reader(reader), hook(kj::mv(hook)) {} - -private: - kj::Own hook; - - template - friend class Request; - friend class ResponseHook; -}; - -class Capability::Client { - // Base type for capability clients. - -public: - typedef Capability Reads; - typedef Capability Calls; - - Client(decltype(nullptr)); - // If you need to declare a Client before you have anything to assign to it (perhaps because - // the assignment is going to occur in an if/else scope), you can start by initializing it to - // `nullptr`. The resulting client is not meant to be called and throws exceptions from all - // methods. - - template ()>> - Client(kj::Own&& server); - // Make a client capability that wraps the given server capability. The server's methods will - // only be executed in the given EventLoop, regardless of what thread calls the client's methods. - - template ()>> - Client(kj::Promise&& promise); - // Make a client from a promise for a future client. The resulting client queues calls until the - // promise resolves. - - Client(kj::Exception&& exception); - // Make a broken client that throws the given exception from all calls. - - Client(Client& other); - Client& operator=(Client& other); - // Copies by reference counting. Warning: This refcounting is not thread-safe. All copies of - // the client must remain in one thread. - - Client(Client&&) = default; - Client& operator=(Client&&) = default; - // Move constructor avoids reference counting. - - explicit Client(kj::Own&& hook); - // For use by the RPC implementation: Wrap a ClientHook. - - template - typename T::Client castAs(); - // Reinterpret the capability as implementing the given interface. Note that no error will occur - // here if the capability does not actually implement this interface, but later method calls will - // fail. It's up to the application to decide how indicate that additional interfaces are - // supported. - // - // TODO(perf): GCC 4.8 / Clang 3.3: rvalue-qualified version for better performance. - - template - typename T::Client castAs(InterfaceSchema schema); - // Dynamic version. `T` must be `DynamicCapability`, and you must `#include `. - - kj::Promise whenResolved(); - // If the capability is actually only a promise, the returned promise resolves once the - // capability itself has resolved to its final destination (or propagates the exception if - // the capability promise is rejected). This is mainly useful for error-checking in the case - // where no calls are being made. There is no reason to wait for this before making calls; if - // the capability does not resolve, the call results will propagate the error. - - Request typelessRequest( - uint64_t interfaceId, uint16_t methodId, - kj::Maybe sizeHint); - // Make a request without knowing the types of the params or results. You specify the type ID - // and method number manually. - - // TODO(someday): method(s) for Join - -protected: - Client() = default; - - template - Request newCall(uint64_t interfaceId, uint16_t methodId, - kj::Maybe sizeHint); - -private: - kj::Own hook; - - static kj::Own makeLocalClient(kj::Own&& server); - - template - friend struct _::PointerHelpers; - friend struct DynamicCapability; - friend class Orphanage; - friend struct DynamicStruct; - friend struct DynamicList; - template - friend struct List; - friend class _::CapabilityServerSetBase; - friend class ClientHook; -}; - -// ======================================================================================= -// Capability servers - -class CallContextHook; - -template -class CallContext: public kj::DisallowConstCopy { - // Wrapper around CallContextHook with a specific return type. - // - // Methods of this class may only be called from within the server's event loop, not from other - // threads. - // - // The CallContext becomes invalid as soon as the call reports completion. - -public: - explicit CallContext(CallContextHook& hook); - - typename Params::Reader getParams(); - // Get the params payload. - - void releaseParams(); - // Release the params payload. getParams() will throw an exception after this is called. - // Releasing the params may allow the RPC system to free up buffer space to handle other - // requests. Long-running asynchronous methods should try to call this as early as is - // convenient. - - typename Results::Builder getResults(kj::Maybe sizeHint = nullptr); - typename Results::Builder initResults(kj::Maybe sizeHint = nullptr); - void setResults(typename Results::Reader value); - void adoptResults(Orphan&& value); - Orphanage getResultsOrphanage(kj::Maybe sizeHint = nullptr); - // Manipulate the results payload. The "Return" message (part of the RPC protocol) will - // typically be allocated the first time one of these is called. Some RPC systems may - // allocate these messages in a limited space (such as a shared memory segment), therefore the - // application should delay calling these as long as is convenient to do so (but don't delay - // if doing so would require extra copies later). - // - // `sizeHint` indicates a guess at the message size. This will usually be used to decide how - // much space to allocate for the first message segment (don't worry: only space that is actually - // used will be sent on the wire). If omitted, the system decides. The message root pointer - // should not be included in the size. So, if you are simply going to copy some existing message - // directly into the results, just call `.totalSize()` and pass that in. - - template - kj::Promise tailCall(Request&& tailRequest); - // Resolve the call by making a tail call. `tailRequest` is a request that has been filled in - // but not yet sent. The context will send the call, then fill in the results with the result - // of the call. If tailCall() is used, {get,init,set,adopt}Results (above) *must not* be called. - // - // The RPC implementation may be able to optimize a tail call to another machine such that the - // results never actually pass through this machine. Even if no such optimization is possible, - // `tailCall()` may allow pipelined calls to be forwarded optimistically to the new call site. - // - // In general, this should be the last thing a method implementation calls, and the promise - // returned from `tailCall()` should then be returned by the method implementation. - - void allowCancellation(); - // Indicate that it is OK for the RPC system to discard its Promise for this call's result if - // the caller cancels the call, thereby transitively canceling any asynchronous operations the - // call implementation was performing. This is not done by default because it could represent a - // security risk: applications must be carefully written to ensure that they do not end up in - // a bad state if an operation is canceled at an arbitrary point. However, for long-running - // method calls that hold significant resources, prompt cancellation is often useful. - // - // Keep in mind that asynchronous cancellation cannot occur while the method is synchronously - // executing on a local thread. The method must perform an asynchronous operation or call - // `EventLoop::current().evalLater()` to yield control. - // - // Note: You might think that we should offer `onCancel()` and/or `isCanceled()` methods that - // provide notification when the caller cancels the request without forcefully killing off the - // promise chain. Unfortunately, this composes poorly with promise forking: the canceled - // path may be just one branch of a fork of the result promise. The other branches still want - // the call to continue. Promise forking is used within the Cap'n Proto implementation -- in - // particular each pipelined call forks the result promise. So, if a caller made a pipelined - // call and then dropped the original object, the call should not be canceled, but it would be - // excessively complicated for the framework to avoid notififying of cancellation as long as - // pipelined calls still exist. - -private: - CallContextHook* hook; - - friend class Capability::Server; - friend struct DynamicCapability; -}; - -class Capability::Server { - // Objects implementing a Cap'n Proto interface must subclass this. Typically, such objects - // will instead subclass a typed Server interface which will take care of implementing - // dispatchCall(). - -public: - typedef Capability Serves; - - virtual kj::Promise dispatchCall(uint64_t interfaceId, uint16_t methodId, - CallContext context) = 0; - // Call the given method. `params` is the input struct, and should be released as soon as it - // is no longer needed. `context` may be used to allocate the output struct and deal with - // cancellation. - - // TODO(someday): Method which can optionally be overridden to implement Join when the object is - // a proxy. - -protected: - inline Capability::Client thisCap(); - // Get a capability pointing to this object, much like the `this` keyword. - // - // The effect of this method is undefined if: - // - No capability client has been created pointing to this object. (This is always the case in - // the server's constructor.) - // - The capability client pointing at this object has been destroyed. (This is always the case - // in the server's destructor.) - // - Multiple capability clients have been created around the same server (possible if the server - // is refcounted, which is not recommended since the client itself provides refcounting). - - template - CallContext internalGetTypedContext( - CallContext typeless); - kj::Promise internalUnimplemented(const char* actualInterfaceName, - uint64_t requestedTypeId); - kj::Promise internalUnimplemented(const char* interfaceName, - uint64_t typeId, uint16_t methodId); - kj::Promise internalUnimplemented(const char* interfaceName, const char* methodName, - uint64_t typeId, uint16_t methodId); - -private: - ClientHook* thisHook = nullptr; - friend class LocalClient; -}; - -// ======================================================================================= - -class ReaderCapabilityTable: private _::CapTableReader { - // Class which imbues Readers with the ability to read capabilities. - // - // In Cap'n Proto format, the encoding of a capability pointer is simply an integer index into - // an external table. Since these pointers fundamentally point outside the message, a - // MessageReader by default has no idea what they point at, and therefore reading capabilities - // from such a reader will throw exceptions. - // - // In order to be able to read capabilities, you must first attach a capability table, using - // this class. By "imbuing" a Reader, you get a new Reader which will interpret capability - // pointers by treating them as indexes into the ReaderCapabilityTable. - // - // Note that when using Cap'n Proto's RPC system, this is handled automatically. - -public: - explicit ReaderCapabilityTable(kj::Array>> table); - KJ_DISALLOW_COPY(ReaderCapabilityTable); - - template - T imbue(T reader); - // Return a reader equivalent to `reader` except that when reading capability-valued fields, - // the capabilities are looked up in this table. - -private: - kj::Array>> table; - - kj::Maybe> extractCap(uint index) override; -}; - -class BuilderCapabilityTable: private _::CapTableBuilder { - // Class which imbues Builders with the ability to read and write capabilities. - // - // This is much like ReaderCapabilityTable, except for builders. The table starts out empty, - // but capabilities can be added to it over time. - -public: - BuilderCapabilityTable(); - KJ_DISALLOW_COPY(BuilderCapabilityTable); - - inline kj::ArrayPtr>> getTable() { return table; } - - template - T imbue(T builder); - // Return a builder equivalent to `builder` except that when reading capability-valued fields, - // the capabilities are looked up in this table. - -private: - kj::Vector>> table; - - kj::Maybe> extractCap(uint index) override; - uint injectCap(kj::Own&& cap) override; - void dropCap(uint index) override; -}; - -// ======================================================================================= - -namespace _ { // private - -class CapabilityServerSetBase { -public: - Capability::Client addInternal(kj::Own&& server, void* ptr); - kj::Promise getLocalServerInternal(Capability::Client& client); -}; - -} // namespace _ (private) - -template -class CapabilityServerSet: private _::CapabilityServerSetBase { - // Allows a server to recognize its own capabilities when passed back to it, and obtain the - // underlying Server objects associated with them. - // - // All objects in the set must have the same interface type T. The objects may implement various - // interfaces derived from T (and in fact T can be `capnp::Capability` to accept all objects), - // but note that if you compile with RTTI disabled then you will not be able to down-cast through - // virtual inheritance, and all inheritance between server interfaces is virtual. So, with RTTI - // disabled, you will likely need to set T to be the most-derived Cap'n Proto interface type, - // and you server class will need to be directly derived from that, so that you can use - // static_cast (or kj::downcast) to cast to it after calling getLocalServer(). (If you compile - // with RTTI, then you can freely dynamic_cast and ignore this issue!) - -public: - CapabilityServerSet() = default; - KJ_DISALLOW_COPY(CapabilityServerSet); - - typename T::Client add(kj::Own&& server); - // Create a new capability Client for the given Server and also add this server to the set. - - kj::Promise> getLocalServer(typename T::Client& client); - // Given a Client pointing to a server previously passed to add(), return the corresponding - // Server. This returns a promise because if the input client is itself a promise, this must - // wait for it to resolve. Keep in mind that the server will be deleted when all clients are - // gone, so the caller should make sure to keep the client alive (hence why this method only - // accepts an lvalue input). -}; - -// ======================================================================================= -// Hook interfaces which must be implemented by the RPC system. Applications never call these -// directly; the RPC system implements them and the types defined earlier in this file wrap them. - -class RequestHook { - // Hook interface implemented by RPC system representing a request being built. - -public: - virtual RemotePromise send() = 0; - // Send the call and return a promise for the result. - - virtual const void* getBrand() = 0; - // Returns a void* that identifies who made this request. This can be used by an RPC adapter to - // discover when tail call is going to be sent over its own connection and therefore can be - // optimized into a remote tail call. - - template - inline static kj::Own from(Request&& request) { - return kj::mv(request.hook); - } -}; - -class ResponseHook { - // Hook interface implemented by RPC system representing a response. - // - // At present this class has no methods. It exists only for garbage collection -- when the - // ResponseHook is destroyed, the results can be freed. - -public: - virtual ~ResponseHook() noexcept(false); - // Just here to make sure the type is dynamic. - - template - inline static kj::Own from(Response&& response) { - return kj::mv(response.hook); - } -}; - -// class PipelineHook is declared in any.h because it is needed there. - -class ClientHook { -public: - ClientHook(); - - virtual Request newCall( - uint64_t interfaceId, uint16_t methodId, kj::Maybe sizeHint) = 0; - // Start a new call, allowing the client to allocate request/response objects as it sees fit. - // This version is used when calls are made from application code in the local process. - - struct VoidPromiseAndPipeline { - kj::Promise promise; - kj::Own pipeline; - }; - - virtual VoidPromiseAndPipeline call(uint64_t interfaceId, uint16_t methodId, - kj::Own&& context) = 0; - // Call the object, but the caller controls allocation of the request/response objects. If the - // callee insists on allocating these objects itself, it must make a copy. This version is used - // when calls come in over the network via an RPC system. Note that even if the returned - // `Promise` is discarded, the call may continue executing if any pipelined calls are - // waiting for it. - // - // Since the caller of this method chooses the CallContext implementation, it is the caller's - // responsibility to ensure that the returned promise is not canceled unless allowed via - // the context's `allowCancellation()`. - // - // The call must not begin synchronously; the callee must arrange for the call to begin in a - // later turn of the event loop. Otherwise, application code may call back and affect the - // callee's state in an unexpected way. - - virtual kj::Maybe getResolved() = 0; - // If this ClientHook is a promise that has already resolved, returns the inner, resolved version - // of the capability. The caller may permanently replace this client with the resolved one if - // desired. Returns null if the client isn't a promise or hasn't resolved yet -- use - // `whenMoreResolved()` to distinguish between them. - - virtual kj::Maybe>> whenMoreResolved() = 0; - // If this client is a settled reference (not a promise), return nullptr. Otherwise, return a - // promise that eventually resolves to a new client that is closer to being the final, settled - // client (i.e. the value eventually returned by `getResolved()`). Calling this repeatedly - // should eventually produce a settled client. - - kj::Promise whenResolved(); - // Repeatedly calls whenMoreResolved() until it returns nullptr. - - virtual kj::Own addRef() = 0; - // Return a new reference to the same capability. - - virtual const void* getBrand() = 0; - // Returns a void* that identifies who made this client. This can be used by an RPC adapter to - // discover when a capability it needs to marshal is one that it created in the first place, and - // therefore it can transfer the capability without proxying. - - static const uint NULL_CAPABILITY_BRAND; - // Value is irrelevant; used for pointer. - - inline bool isNull() { return getBrand() == &NULL_CAPABILITY_BRAND; } - // Returns true if the capability was created as a result of assigning a Client to null or by - // reading a null pointer out of a Cap'n Proto message. - - virtual void* getLocalServer(_::CapabilityServerSetBase& capServerSet); - // If this is a local capability created through `capServerSet`, return the underlying Server. - // Otherwise, return nullptr. Default implementation (which everyone except LocalClient should - // use) always returns nullptr. - - static kj::Own from(Capability::Client client) { return kj::mv(client.hook); } -}; - -class CallContextHook { - // Hook interface implemented by RPC system to manage a call on the server side. See - // CallContext. - -public: - virtual AnyPointer::Reader getParams() = 0; - virtual void releaseParams() = 0; - virtual AnyPointer::Builder getResults(kj::Maybe sizeHint) = 0; - virtual kj::Promise tailCall(kj::Own&& request) = 0; - virtual void allowCancellation() = 0; - - virtual kj::Promise onTailCall() = 0; - // If `tailCall()` is called, resolves to the PipelineHook from the tail call. An - // implementation of `ClientHook::call()` is allowed to call this at most once. - - virtual ClientHook::VoidPromiseAndPipeline directTailCall(kj::Own&& request) = 0; - // Call this when you would otherwise call onTailCall() immediately followed by tailCall(). - // Implementations of tailCall() should typically call directTailCall() and then fulfill the - // promise fulfiller for onTailCall() with the returned pipeline. - - virtual kj::Own addRef() = 0; -}; - -kj::Own newLocalPromiseClient(kj::Promise>&& promise); -// Returns a ClientHook that queues up calls until `promise` resolves, then forwards them to -// the new client. This hook's `getResolved()` and `whenMoreResolved()` methods will reflect the -// redirection to the eventual replacement client. - -kj::Own newLocalPromisePipeline(kj::Promise>&& promise); -// Returns a PipelineHook that queues up calls until `promise` resolves, then forwards them to -// the new pipeline. - -kj::Own newBrokenCap(kj::StringPtr reason); -kj::Own newBrokenCap(kj::Exception&& reason); -// Helper function that creates a capability which simply throws exceptions when called. - -kj::Own newBrokenPipeline(kj::Exception&& reason); -// Helper function that creates a pipeline which simply throws exceptions when called. - -Request newBrokenRequest( - kj::Exception&& reason, kj::Maybe sizeHint); -// Helper function that creates a Request object that simply throws exceptions when sent. - -// ======================================================================================= -// Extend PointerHelpers for interfaces - -namespace _ { // private - -template -struct PointerHelpers { - static inline typename T::Client get(PointerReader reader) { - return typename T::Client(reader.getCapability()); - } - static inline typename T::Client get(PointerBuilder builder) { - return typename T::Client(builder.getCapability()); - } - static inline void set(PointerBuilder builder, typename T::Client&& value) { - builder.setCapability(kj::mv(value.Capability::Client::hook)); - } - static inline void set(PointerBuilder builder, typename T::Client& value) { - builder.setCapability(value.Capability::Client::hook->addRef()); - } - static inline void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan disown(PointerBuilder builder) { - return Orphan(builder.disown()); - } -}; - -} // namespace _ (private) - -// ======================================================================================= -// Extend List for interfaces - -template -struct List { - List() = delete; - - class Reader { - public: - typedef List Reads; - - Reader() = default; - inline explicit Reader(_::ListReader reader): reader(reader) {} - - inline uint size() const { return unbound(reader.size() / ELEMENTS); } - inline typename T::Client operator[](uint index) const { - KJ_IREQUIRE(index < size()); - return typename T::Client(reader.getPointerElement( - bounded(index) * ELEMENTS).getCapability()); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - - private: - _::ListReader reader; - template - friend struct _::PointerHelpers; - template - friend struct List; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Builder { - public: - typedef List Builds; - - Builder() = delete; - inline Builder(decltype(nullptr)) {} - inline explicit Builder(_::ListBuilder builder): builder(builder) {} - - inline operator Reader() const { return Reader(builder.asReader()); } - inline Reader asReader() const { return Reader(builder.asReader()); } - - inline uint size() const { return unbound(builder.size() / ELEMENTS); } - inline typename T::Client operator[](uint index) { - KJ_IREQUIRE(index < size()); - return typename T::Client(builder.getPointerElement( - bounded(index) * ELEMENTS).getCapability()); - } - inline void set(uint index, typename T::Client value) { - KJ_IREQUIRE(index < size()); - builder.getPointerElement(bounded(index) * ELEMENTS).setCapability(kj::mv(value.hook)); - } - inline void adopt(uint index, Orphan&& value) { - KJ_IREQUIRE(index < size()); - builder.getPointerElement(bounded(index) * ELEMENTS).adopt(kj::mv(value)); - } - inline Orphan disown(uint index) { - KJ_IREQUIRE(index < size()); - return Orphan(builder.getPointerElement(bounded(index) * ELEMENTS).disown()); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - - private: - _::ListBuilder builder; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - -private: - inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { - return builder.initList(ElementSize::POINTER, bounded(size) * ELEMENTS); - } - inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { - return builder.getList(ElementSize::POINTER, defaultValue); - } - inline static _::ListReader getFromPointer( - const _::PointerReader& reader, const word* defaultValue) { - return reader.getList(ElementSize::POINTER, defaultValue); - } - - template - friend struct List; - template - friend struct _::PointerHelpers; -}; - -// ======================================================================================= -// Inline implementation details - -template -RemotePromise Request::send() { - auto typelessPromise = hook->send(); - hook = nullptr; // prevent reuse - - // Convert the Promise to return the correct response type. - // Explicitly upcast to kj::Promise to make clear that calling .then() doesn't invalidate the - // Pipeline part of the RemotePromise. - auto typedPromise = kj::implicitCast>&>(typelessPromise) - .then([](Response&& response) -> Response { - return Response(response.getAs(), kj::mv(response.hook)); - }); - - // Wrap the typeless pipeline in a typed wrapper. - typename Results::Pipeline typedPipeline( - kj::mv(kj::implicitCast(typelessPromise))); - - return RemotePromise(kj::mv(typedPromise), kj::mv(typedPipeline)); -} - -inline Capability::Client::Client(kj::Own&& hook): hook(kj::mv(hook)) {} -template -inline Capability::Client::Client(kj::Own&& server) - : hook(makeLocalClient(kj::mv(server))) {} -template -inline Capability::Client::Client(kj::Promise&& promise) - : hook(newLocalPromiseClient(promise.then([](T&& t) { return kj::mv(t.hook); }))) {} -inline Capability::Client::Client(Client& other): hook(other.hook->addRef()) {} -inline Capability::Client& Capability::Client::operator=(Client& other) { - hook = other.hook->addRef(); - return *this; -} -template -inline typename T::Client Capability::Client::castAs() { - return typename T::Client(hook->addRef()); -} -inline kj::Promise Capability::Client::whenResolved() { - return hook->whenResolved(); -} -inline Request Capability::Client::typelessRequest( - uint64_t interfaceId, uint16_t methodId, - kj::Maybe sizeHint) { - return newCall(interfaceId, methodId, sizeHint); -} -template -inline Request Capability::Client::newCall( - uint64_t interfaceId, uint16_t methodId, kj::Maybe sizeHint) { - auto typeless = hook->newCall(interfaceId, methodId, sizeHint); - return Request(typeless.template getAs(), kj::mv(typeless.hook)); -} - -template -inline CallContext::CallContext(CallContextHook& hook): hook(&hook) {} -template -inline typename Params::Reader CallContext::getParams() { - return hook->getParams().template getAs(); -} -template -inline void CallContext::releaseParams() { - hook->releaseParams(); -} -template -inline typename Results::Builder CallContext::getResults( - kj::Maybe sizeHint) { - // `template` keyword needed due to: http://llvm.org/bugs/show_bug.cgi?id=17401 - return hook->getResults(sizeHint).template getAs(); -} -template -inline typename Results::Builder CallContext::initResults( - kj::Maybe sizeHint) { - // `template` keyword needed due to: http://llvm.org/bugs/show_bug.cgi?id=17401 - return hook->getResults(sizeHint).template initAs(); -} -template -inline void CallContext::setResults(typename Results::Reader value) { - hook->getResults(value.totalSize()).template setAs(value); -} -template -inline void CallContext::adoptResults(Orphan&& value) { - hook->getResults(nullptr).adopt(kj::mv(value)); -} -template -inline Orphanage CallContext::getResultsOrphanage( - kj::Maybe sizeHint) { - return Orphanage::getForMessageContaining(hook->getResults(sizeHint)); -} -template -template -inline kj::Promise CallContext::tailCall( - Request&& tailRequest) { - return hook->tailCall(kj::mv(tailRequest.hook)); -} -template -inline void CallContext::allowCancellation() { - hook->allowCancellation(); -} - -template -CallContext Capability::Server::internalGetTypedContext( - CallContext typeless) { - return CallContext(*typeless.hook); -} - -Capability::Client Capability::Server::thisCap() { - return Client(thisHook->addRef()); -} - -template -T ReaderCapabilityTable::imbue(T reader) { - return T(_::PointerHelpers>::getInternalReader(reader).imbue(this)); -} - -template -T BuilderCapabilityTable::imbue(T builder) { - return T(_::PointerHelpers>::getInternalBuilder(kj::mv(builder)).imbue(this)); -} - -template -typename T::Client CapabilityServerSet::add(kj::Own&& server) { - void* ptr = reinterpret_cast(server.get()); - // Clang insists that `castAs` is a template-dependent member and therefore we need the - // `template` keyword here, but AFAICT this is wrong: addImpl() is not a template. - return addInternal(kj::mv(server), ptr).template castAs(); -} - -template -kj::Promise> CapabilityServerSet::getLocalServer( - typename T::Client& client) { - return getLocalServerInternal(client) - .then([](void* server) -> kj::Maybe { - if (server == nullptr) { - return nullptr; - } else { - return *reinterpret_cast(server); - } - }); -} - -template -struct Orphanage::GetInnerReader { - static inline kj::Own apply(typename T::Client t) { - return ClientHook::from(kj::mv(t)); - } -}; - -} // namespace capnp - -#endif // CAPNP_CAPABILITY_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/common.h b/phonelibs/capnp-cpp/include/capnp/common.h deleted file mode 100644 index 3fc7a421124026..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/common.h +++ /dev/null @@ -1,723 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -// This file contains types which are intended to help detect incorrect usage at compile -// time, but should then be optimized down to basic primitives (usually, integers) by the -// compiler. - -#ifndef CAPNP_COMMON_H_ -#define CAPNP_COMMON_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include -#include -#include - -#if CAPNP_DEBUG_TYPES -#include -#endif - -namespace capnp { - -#define CAPNP_VERSION_MAJOR 0 -#define CAPNP_VERSION_MINOR 6 -#define CAPNP_VERSION_MICRO 1 - -#define CAPNP_VERSION \ - (CAPNP_VERSION_MAJOR * 1000000 + CAPNP_VERSION_MINOR * 1000 + CAPNP_VERSION_MICRO) - -#ifndef CAPNP_LITE -#define CAPNP_LITE 0 -#endif - -typedef unsigned int uint; - -struct Void { - // Type used for Void fields. Using C++'s "void" type creates a bunch of issues since it behaves - // differently from other types. - - inline constexpr bool operator==(Void other) const { return true; } - inline constexpr bool operator!=(Void other) const { return false; } -}; - -static constexpr Void VOID = Void(); -// Constant value for `Void`, which is an empty struct. - -inline kj::StringPtr KJ_STRINGIFY(Void) { return "void"; } - -struct Text; -struct Data; - -enum class Kind: uint8_t { - PRIMITIVE, - BLOB, - ENUM, - STRUCT, - UNION, - INTERFACE, - LIST, - - OTHER - // Some other type which is often a type parameter to Cap'n Proto templates, but which needs - // special handling. This includes types like AnyPointer, Dynamic*, etc. -}; - -enum class Style: uint8_t { - PRIMITIVE, - POINTER, // other than struct - STRUCT, - CAPABILITY -}; - -enum class ElementSize: uint8_t { - // Size of a list element. - - VOID = 0, - BIT = 1, - BYTE = 2, - TWO_BYTES = 3, - FOUR_BYTES = 4, - EIGHT_BYTES = 5, - - POINTER = 6, - - INLINE_COMPOSITE = 7 -}; - -enum class PointerType { - // Various wire types a pointer field can take - - NULL_, - // Should be NULL, but that's #defined in stddef.h - - STRUCT, - LIST, - CAPABILITY -}; - -namespace schemas { - -template -struct EnumInfo; - -} // namespace schemas - -namespace _ { // private - -template struct Kind_; - -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::PRIMITIVE; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::BLOB; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::BLOB; }; - -template struct Kind_> { - static constexpr Kind kind = Kind::STRUCT; -}; -template struct Kind_> { - static constexpr Kind kind = Kind::INTERFACE; -}; -template struct Kind_::IsEnum>> { - static constexpr Kind kind = Kind::ENUM; -}; - -} // namespace _ (private) - -template ::kind> -inline constexpr Kind kind() { - // This overload of kind() matches types which have a Kind_ specialization. - - return k; -} - -#if _MSC_VER - -#define CAPNP_KIND(T) ::capnp::_::Kind_::kind -// Avoid constexpr methods in MSVC (it remains buggy in many situations). - -#else // _MSC_VER - -#define CAPNP_KIND(T) ::capnp::kind() -// Use this macro rather than kind() in any code which must work in MSVC. - -#endif // _MSC_VER, else - -#if !CAPNP_LITE - -template ()> -inline constexpr Style style() { - return k == Kind::PRIMITIVE || k == Kind::ENUM ? Style::PRIMITIVE - : k == Kind::STRUCT ? Style::STRUCT - : k == Kind::INTERFACE ? Style::CAPABILITY : Style::POINTER; -} - -#endif // !CAPNP_LITE - -template -struct List; - -#if _MSC_VER - -template -struct List {}; -// For some reason, without this declaration, MSVC will error out on some uses of List -// claiming that "T" -- as used in the default initializer for the second template param, "k" -- -// is not defined. I do not understand this error, but adding this empty default declaration fixes -// it. - -#endif - -template struct ListElementType_; -template struct ListElementType_> { typedef T Type; }; -template using ListElementType = typename ListElementType_::Type; - -namespace _ { // private -template struct Kind_> { - static constexpr Kind kind = Kind::LIST; -}; -} // namespace _ (private) - -template struct ReaderFor_ { typedef typename T::Reader Type; }; -template struct ReaderFor_ { typedef T Type; }; -template struct ReaderFor_ { typedef T Type; }; -template struct ReaderFor_ { typedef typename T::Client Type; }; -template using ReaderFor = typename ReaderFor_::Type; -// The type returned by List::Reader::operator[]. - -template struct BuilderFor_ { typedef typename T::Builder Type; }; -template struct BuilderFor_ { typedef T Type; }; -template struct BuilderFor_ { typedef T Type; }; -template struct BuilderFor_ { typedef typename T::Client Type; }; -template using BuilderFor = typename BuilderFor_::Type; -// The type returned by List::Builder::operator[]. - -template struct PipelineFor_ { typedef typename T::Pipeline Type;}; -template struct PipelineFor_ { typedef typename T::Client Type; }; -template using PipelineFor = typename PipelineFor_::Type; - -template struct TypeIfEnum_; -template struct TypeIfEnum_ { typedef T Type; }; - -template -using TypeIfEnum = typename TypeIfEnum_>::Type; - -template -using FromReader = typename kj::Decay::Reads; -// FromReader = MyType (for any Cap'n Proto type). - -template -using FromBuilder = typename kj::Decay::Builds; -// FromBuilder = MyType (for any Cap'n Proto type). - -template -using FromPipeline = typename kj::Decay::Pipelines; -// FromBuilder = MyType (for any Cap'n Proto type). - -template -using FromClient = typename kj::Decay::Calls; -// FromReader = MyType (for any Cap'n Proto interface type). - -template -using FromServer = typename kj::Decay::Serves; -// FromBuilder = MyType (for any Cap'n Proto interface type). - -template -struct FromAny_; - -template -struct FromAny_>> { - using Type = FromReader; -}; - -template -struct FromAny_>> { - using Type = FromBuilder; -}; - -template -struct FromAny_>> { - using Type = FromPipeline; -}; - -// Note that T::Client is covered by FromReader - -template -struct FromAny_, kj::VoidSfinae>> { - using Type = FromServer; -}; - -template -struct FromAny_::kind == Kind::PRIMITIVE || _::Kind_::kind == Kind::ENUM>> { - // TODO(msvc): Ideally the EnableIf condition would be `style() == Style::PRIMITIVE`, but MSVC - // cannot yet use style() in this constexpr context. - - using Type = kj::Decay; -}; - -template -using FromAny = typename FromAny_::Type; -// Given any Cap'n Proto value type as an input, return the Cap'n Proto base type. That is: -// -// Foo::Reader -> Foo -// Foo::Builder -> Foo -// Foo::Pipeline -> Foo -// Foo::Client -> Foo -// Own -> Foo -// uint32_t -> uint32_t - -namespace _ { // private - -template -struct PointerHelpers; - -#if _MSC_VER - -template -struct PointerHelpers {}; -// For some reason, without this declaration, MSVC will error out on some uses of PointerHelpers -// claiming that "T" -- as used in the default initializer for the second template param, "k" -- -// is not defined. I do not understand this error, but adding this empty default declaration fixes -// it. - -#endif - -} // namespace _ (private) - -struct MessageSize { - // Size of a message. Every struct type has a method `.totalSize()` that returns this. - uint64_t wordCount; - uint capCount; -}; - -// ======================================================================================= -// Raw memory types and measures - -using kj::byte; - -class word { uint64_t content KJ_UNUSED_MEMBER; KJ_DISALLOW_COPY(word); public: word() = default; }; -// word is an opaque type with size of 64 bits. This type is useful only to make pointer -// arithmetic clearer. Since the contents are private, the only way to access them is to first -// reinterpret_cast to some other pointer type. -// -// Copying is disallowed because you should always use memcpy(). Otherwise, you may run afoul of -// aliasing rules. -// -// A pointer of type word* should always be word-aligned even if won't actually be dereferenced as -// that type. - -static_assert(sizeof(byte) == 1, "uint8_t is not one byte?"); -static_assert(sizeof(word) == 8, "uint64_t is not 8 bytes?"); - -#if CAPNP_DEBUG_TYPES -// Set CAPNP_DEBUG_TYPES to 1 to use kj::Quantity for "count" types. Otherwise, plain integers are -// used. All the code should still operate exactly the same, we just lose compile-time checking. -// Note that this will also change symbol names, so it's important that the library and any clients -// be compiled with the same setting here. -// -// We disable this by default to reduce symbol name size and avoid any possibility of the compiler -// failing to fully-optimize the types, but anyone modifying Cap'n Proto itself should enable this -// during development and testing. - -namespace _ { class BitLabel; class ElementLabel; struct WirePointer; } - -template -using BitCountN = kj::Quantity(), T>, _::BitLabel>; -template -using ByteCountN = kj::Quantity(), T>, byte>; -template -using WordCountN = kj::Quantity(), T>, word>; -template -using ElementCountN = kj::Quantity(), T>, _::ElementLabel>; -template -using WirePointerCountN = kj::Quantity(), T>, _::WirePointer>; - -typedef BitCountN<8, uint8_t> BitCount8; -typedef BitCountN<16, uint16_t> BitCount16; -typedef BitCountN<32, uint32_t> BitCount32; -typedef BitCountN<64, uint64_t> BitCount64; -typedef BitCountN BitCount; - -typedef ByteCountN<8, uint8_t> ByteCount8; -typedef ByteCountN<16, uint16_t> ByteCount16; -typedef ByteCountN<32, uint32_t> ByteCount32; -typedef ByteCountN<64, uint64_t> ByteCount64; -typedef ByteCountN ByteCount; - -typedef WordCountN<8, uint8_t> WordCount8; -typedef WordCountN<16, uint16_t> WordCount16; -typedef WordCountN<32, uint32_t> WordCount32; -typedef WordCountN<64, uint64_t> WordCount64; -typedef WordCountN WordCount; - -typedef ElementCountN<8, uint8_t> ElementCount8; -typedef ElementCountN<16, uint16_t> ElementCount16; -typedef ElementCountN<32, uint32_t> ElementCount32; -typedef ElementCountN<64, uint64_t> ElementCount64; -typedef ElementCountN ElementCount; - -typedef WirePointerCountN<8, uint8_t> WirePointerCount8; -typedef WirePointerCountN<16, uint16_t> WirePointerCount16; -typedef WirePointerCountN<32, uint32_t> WirePointerCount32; -typedef WirePointerCountN<64, uint64_t> WirePointerCount64; -typedef WirePointerCountN WirePointerCount; - -template -using BitsPerElementN = decltype(BitCountN() / ElementCountN()); -template -using BytesPerElementN = decltype(ByteCountN() / ElementCountN()); -template -using WordsPerElementN = decltype(WordCountN() / ElementCountN()); -template -using PointersPerElementN = decltype(WirePointerCountN() / ElementCountN()); - -using kj::bounded; -using kj::unbound; -using kj::unboundAs; -using kj::unboundMax; -using kj::unboundMaxBits; -using kj::assertMax; -using kj::assertMaxBits; -using kj::upgradeBound; -using kj::ThrowOverflow; -using kj::assumeBits; -using kj::assumeMax; -using kj::subtractChecked; -using kj::trySubtract; - -template -inline constexpr U* operator+(U* ptr, kj::Quantity offset) { - return ptr + unbound(offset / kj::unit>()); -} -template -inline constexpr const U* operator+(const U* ptr, kj::Quantity offset) { - return ptr + unbound(offset / kj::unit>()); -} -template -inline constexpr U* operator+=(U*& ptr, kj::Quantity offset) { - return ptr = ptr + unbound(offset / kj::unit>()); -} -template -inline constexpr const U* operator+=(const U*& ptr, kj::Quantity offset) { - return ptr = ptr + unbound(offset / kj::unit>()); -} - -template -inline constexpr U* operator-(U* ptr, kj::Quantity offset) { - return ptr - unbound(offset / kj::unit>()); -} -template -inline constexpr const U* operator-(const U* ptr, kj::Quantity offset) { - return ptr - unbound(offset / kj::unit>()); -} -template -inline constexpr U* operator-=(U*& ptr, kj::Quantity offset) { - return ptr = ptr - unbound(offset / kj::unit>()); -} -template -inline constexpr const U* operator-=(const U*& ptr, kj::Quantity offset) { - return ptr = ptr - unbound(offset / kj::unit>()); -} - -constexpr auto BITS = kj::unit>(); -constexpr auto BYTES = kj::unit>(); -constexpr auto WORDS = kj::unit>(); -constexpr auto ELEMENTS = kj::unit>(); -constexpr auto POINTERS = kj::unit>(); - -constexpr auto ZERO = kj::bounded<0>(); -constexpr auto ONE = kj::bounded<1>(); - -// GCC 4.7 actually gives unused warnings on these constants in opt mode... -constexpr auto BITS_PER_BYTE KJ_UNUSED = bounded<8>() * BITS / BYTES; -constexpr auto BITS_PER_WORD KJ_UNUSED = bounded<64>() * BITS / WORDS; -constexpr auto BYTES_PER_WORD KJ_UNUSED = bounded<8>() * BYTES / WORDS; - -constexpr auto BITS_PER_POINTER KJ_UNUSED = bounded<64>() * BITS / POINTERS; -constexpr auto BYTES_PER_POINTER KJ_UNUSED = bounded<8>() * BYTES / POINTERS; -constexpr auto WORDS_PER_POINTER KJ_UNUSED = ONE * WORDS / POINTERS; - -constexpr auto POINTER_SIZE_IN_WORDS = ONE * POINTERS * WORDS_PER_POINTER; - -constexpr uint SEGMENT_WORD_COUNT_BITS = 29; // Number of words in a segment. -constexpr uint LIST_ELEMENT_COUNT_BITS = 29; // Number of elements in a list. -constexpr uint STRUCT_DATA_WORD_COUNT_BITS = 16; // Number of words in a Struct data section. -constexpr uint STRUCT_POINTER_COUNT_BITS = 16; // Number of pointers in a Struct pointer section. -constexpr uint BLOB_SIZE_BITS = 29; // Number of bytes in a blob. - -typedef WordCountN SegmentWordCount; -typedef ElementCountN ListElementCount; -typedef WordCountN StructDataWordCount; -typedef WirePointerCountN StructPointerCount; -typedef ByteCountN BlobSize; - -constexpr auto MAX_SEGMENT_WORDS = - bounded()>() * WORDS; -constexpr auto MAX_LIST_ELEMENTS = - bounded()>() * ELEMENTS; -constexpr auto MAX_STUCT_DATA_WORDS = - bounded()>() * WORDS; -constexpr auto MAX_STRUCT_POINTER_COUNT = - bounded()>() * POINTERS; - -using StructDataBitCount = decltype(WordCountN() * BITS_PER_WORD); -// Number of bits in a Struct data segment (should come out to BitCountN<22>). - -using StructDataOffset = decltype(StructDataBitCount() * (ONE * ELEMENTS / BITS)); -using StructPointerOffset = StructPointerCount; -// Type of a field offset. - -inline StructDataOffset assumeDataOffset(uint32_t offset) { - return assumeMax(MAX_STUCT_DATA_WORDS * BITS_PER_WORD * (ONE * ELEMENTS / BITS), - bounded(offset) * ELEMENTS); -} - -inline StructPointerOffset assumePointerOffset(uint32_t offset) { - return assumeMax(MAX_STRUCT_POINTER_COUNT, bounded(offset) * POINTERS); -} - -constexpr uint MAX_TEXT_SIZE = kj::maxValueForBits() - 1; -typedef kj::Quantity, byte> TextSize; -// Not including NUL terminator. - -template -inline KJ_CONSTEXPR() decltype(bounded() * BYTES / ELEMENTS) bytesPerElement() { - return bounded() * BYTES / ELEMENTS; -} - -template -inline KJ_CONSTEXPR() decltype(bounded() * BITS / ELEMENTS) bitsPerElement() { - return bounded() * BITS / ELEMENTS; -} - -template -inline constexpr kj::Quantity, T> -intervalLength(const T* a, const T* b, kj::Quantity, T>) { - return kj::assumeMax(b - a) * kj::unit, T>>(); -} - -template -inline constexpr kj::ArrayPtr arrayPtr(const U* ptr, kj::Quantity size) { - return kj::ArrayPtr(ptr, unbound(size / kj::unit>())); -} -template -inline constexpr kj::ArrayPtr arrayPtr(U* ptr, kj::Quantity size) { - return kj::ArrayPtr(ptr, unbound(size / kj::unit>())); -} - -#else - -template -using BitCountN = T; -template -using ByteCountN = T; -template -using WordCountN = T; -template -using ElementCountN = T; -template -using WirePointerCountN = T; - - -// XXX -typedef BitCountN<8, uint8_t> BitCount8; -typedef BitCountN<16, uint16_t> BitCount16; -typedef BitCountN<32, uint32_t> BitCount32; -typedef BitCountN<64, uint64_t> BitCount64; -typedef BitCountN BitCount; - -typedef ByteCountN<8, uint8_t> ByteCount8; -typedef ByteCountN<16, uint16_t> ByteCount16; -typedef ByteCountN<32, uint32_t> ByteCount32; -typedef ByteCountN<64, uint64_t> ByteCount64; -typedef ByteCountN ByteCount; - -typedef WordCountN<8, uint8_t> WordCount8; -typedef WordCountN<16, uint16_t> WordCount16; -typedef WordCountN<32, uint32_t> WordCount32; -typedef WordCountN<64, uint64_t> WordCount64; -typedef WordCountN WordCount; - -typedef ElementCountN<8, uint8_t> ElementCount8; -typedef ElementCountN<16, uint16_t> ElementCount16; -typedef ElementCountN<32, uint32_t> ElementCount32; -typedef ElementCountN<64, uint64_t> ElementCount64; -typedef ElementCountN ElementCount; - -typedef WirePointerCountN<8, uint8_t> WirePointerCount8; -typedef WirePointerCountN<16, uint16_t> WirePointerCount16; -typedef WirePointerCountN<32, uint32_t> WirePointerCount32; -typedef WirePointerCountN<64, uint64_t> WirePointerCount64; -typedef WirePointerCountN WirePointerCount; - -template -using BitsPerElementN = decltype(BitCountN() / ElementCountN()); -template -using BytesPerElementN = decltype(ByteCountN() / ElementCountN()); -template -using WordsPerElementN = decltype(WordCountN() / ElementCountN()); -template -using PointersPerElementN = decltype(WirePointerCountN() / ElementCountN()); - -using kj::ThrowOverflow; -// YYY - -template inline constexpr uint bounded() { return i; } -template inline constexpr T bounded(T i) { return i; } -template inline constexpr T unbound(T i) { return i; } - -template inline constexpr T unboundAs(U i) { return i; } - -template inline constexpr uint unboundMax(T i) { return i; } -template inline constexpr uint unboundMaxBits(T i) { return i; } - -template -inline T assertMax(T value, ErrorFunc&& func) { - if (KJ_UNLIKELY(value > newMax)) func(); - return value; -} - -template -inline T assertMax(uint newMax, T value, ErrorFunc&& func) { - if (KJ_UNLIKELY(value > newMax)) func(); - return value; -} - -template -inline T assertMaxBits(T value, ErrorFunc&& func = ErrorFunc()) { - if (KJ_UNLIKELY(value > kj::maxValueForBits())) func(); - return value; -} - -template -inline T assertMaxBits(uint bits, T value, ErrorFunc&& func = ErrorFunc()) { - if (KJ_UNLIKELY(value > (1ull << bits) - 1)) func(); - return value; -} - -template inline constexpr T upgradeBound(U i) { return i; } - -template inline constexpr T assumeBits(T i) { return i; } -template inline constexpr T assumeMax(T i) { return i; } - -template -inline auto subtractChecked(T a, U b, ErrorFunc&& errorFunc = ErrorFunc()) - -> decltype(a - b) { - if (b > a) errorFunc(); - return a - b; -} - -template -inline auto trySubtract(T a, U b) -> kj::Maybe { - if (b > a) { - return nullptr; - } else { - return a - b; - } -} - -constexpr uint BITS = 1; -constexpr uint BYTES = 1; -constexpr uint WORDS = 1; -constexpr uint ELEMENTS = 1; -constexpr uint POINTERS = 1; - -constexpr uint ZERO = 0; -constexpr uint ONE = 1; - -// GCC 4.7 actually gives unused warnings on these constants in opt mode... -constexpr uint BITS_PER_BYTE KJ_UNUSED = 8; -constexpr uint BITS_PER_WORD KJ_UNUSED = 64; -constexpr uint BYTES_PER_WORD KJ_UNUSED = 8; - -constexpr uint BITS_PER_POINTER KJ_UNUSED = 64; -constexpr uint BYTES_PER_POINTER KJ_UNUSED = 8; -constexpr uint WORDS_PER_POINTER KJ_UNUSED = 1; - -// XXX -constexpr uint POINTER_SIZE_IN_WORDS = ONE * POINTERS * WORDS_PER_POINTER; - -constexpr uint SEGMENT_WORD_COUNT_BITS = 29; // Number of words in a segment. -constexpr uint LIST_ELEMENT_COUNT_BITS = 29; // Number of elements in a list. -constexpr uint STRUCT_DATA_WORD_COUNT_BITS = 16; // Number of words in a Struct data section. -constexpr uint STRUCT_POINTER_COUNT_BITS = 16; // Number of pointers in a Struct pointer section. -constexpr uint BLOB_SIZE_BITS = 29; // Number of bytes in a blob. - -typedef WordCountN SegmentWordCount; -typedef ElementCountN ListElementCount; -typedef WordCountN StructDataWordCount; -typedef WirePointerCountN StructPointerCount; -typedef ByteCountN BlobSize; -// YYY - -constexpr auto MAX_SEGMENT_WORDS = kj::maxValueForBits(); -constexpr auto MAX_LIST_ELEMENTS = kj::maxValueForBits(); -constexpr auto MAX_STUCT_DATA_WORDS = kj::maxValueForBits(); -constexpr auto MAX_STRUCT_POINTER_COUNT = kj::maxValueForBits(); - -typedef uint StructDataBitCount; -typedef uint StructDataOffset; -typedef uint StructPointerOffset; - -inline StructDataOffset assumeDataOffset(uint32_t offset) { return offset; } -inline StructPointerOffset assumePointerOffset(uint32_t offset) { return offset; } - -constexpr uint MAX_TEXT_SIZE = kj::maxValueForBits() - 1; -typedef uint TextSize; - -template -inline KJ_CONSTEXPR() size_t bytesPerElement() { return sizeof(T); } - -template -inline KJ_CONSTEXPR() size_t bitsPerElement() { return sizeof(T) * 8; } - -template -inline constexpr ptrdiff_t intervalLength(const T* a, const T* b, uint) { - return b - a; -} - -template -inline constexpr kj::ArrayPtr arrayPtr(const U* ptr, T size) { - return kj::arrayPtr(ptr, size); -} -template -inline constexpr kj::ArrayPtr arrayPtr(U* ptr, T size) { - return kj::arrayPtr(ptr, size); -} - -#endif - -} // namespace capnp - -#endif // CAPNP_COMMON_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/compat/json.capnp.h b/phonelibs/capnp-cpp/include/capnp/compat/json.capnp.h deleted file mode 100644 index a8877e540b9f2a..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/compat/json.capnp.h +++ /dev/null @@ -1,860 +0,0 @@ -// Generated by Cap'n Proto compiler, DO NOT EDIT -// source: json.capnp - -#ifndef CAPNP_INCLUDED_8ef99297a43a5e34_ -#define CAPNP_INCLUDED_8ef99297a43a5e34_ - -#include -#if !CAPNP_LITE -#include -#endif // !CAPNP_LITE - -#if CAPNP_VERSION != 6001 -#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." -#endif - - -namespace capnp { -namespace schemas { - -CAPNP_DECLARE_SCHEMA(8825ffaa852cda72); -CAPNP_DECLARE_SCHEMA(c27855d853a937cc); -CAPNP_DECLARE_SCHEMA(9bbf84153dd4bb60); - -} // namespace schemas -} // namespace capnp - -namespace capnp { - -struct JsonValue { - JsonValue() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - NULL_, - BOOLEAN, - NUMBER, - STRING, - ARRAY, - OBJECT, - CALL, - }; - struct Field; - struct Call; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(8825ffaa852cda72, 2, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct JsonValue::Field { - Field() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(c27855d853a937cc, 0, 2) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct JsonValue::Call { - Call() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9bbf84153dd4bb60, 0, 2) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -// ======================================================================================= - -class JsonValue::Reader { -public: - typedef JsonValue Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isNull() const; - inline ::capnp::Void getNull() const; - - inline bool isBoolean() const; - inline bool getBoolean() const; - - inline bool isNumber() const; - inline double getNumber() const; - - inline bool isString() const; - inline bool hasString() const; - inline ::capnp::Text::Reader getString() const; - - inline bool isArray() const; - inline bool hasArray() const; - inline ::capnp::List< ::capnp::JsonValue>::Reader getArray() const; - - inline bool isObject() const; - inline bool hasObject() const; - inline ::capnp::List< ::capnp::JsonValue::Field>::Reader getObject() const; - - inline bool isCall() const; - inline bool hasCall() const; - inline ::capnp::JsonValue::Call::Reader getCall() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class JsonValue::Builder { -public: - typedef JsonValue Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isNull(); - inline ::capnp::Void getNull(); - inline void setNull( ::capnp::Void value = ::capnp::VOID); - - inline bool isBoolean(); - inline bool getBoolean(); - inline void setBoolean(bool value); - - inline bool isNumber(); - inline double getNumber(); - inline void setNumber(double value); - - inline bool isString(); - inline bool hasString(); - inline ::capnp::Text::Builder getString(); - inline void setString( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initString(unsigned int size); - inline void adoptString(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownString(); - - inline bool isArray(); - inline bool hasArray(); - inline ::capnp::List< ::capnp::JsonValue>::Builder getArray(); - inline void setArray( ::capnp::List< ::capnp::JsonValue>::Reader value); - inline ::capnp::List< ::capnp::JsonValue>::Builder initArray(unsigned int size); - inline void adoptArray(::capnp::Orphan< ::capnp::List< ::capnp::JsonValue>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::JsonValue>> disownArray(); - - inline bool isObject(); - inline bool hasObject(); - inline ::capnp::List< ::capnp::JsonValue::Field>::Builder getObject(); - inline void setObject( ::capnp::List< ::capnp::JsonValue::Field>::Reader value); - inline ::capnp::List< ::capnp::JsonValue::Field>::Builder initObject(unsigned int size); - inline void adoptObject(::capnp::Orphan< ::capnp::List< ::capnp::JsonValue::Field>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::JsonValue::Field>> disownObject(); - - inline bool isCall(); - inline bool hasCall(); - inline ::capnp::JsonValue::Call::Builder getCall(); - inline void setCall( ::capnp::JsonValue::Call::Reader value); - inline ::capnp::JsonValue::Call::Builder initCall(); - inline void adoptCall(::capnp::Orphan< ::capnp::JsonValue::Call>&& value); - inline ::capnp::Orphan< ::capnp::JsonValue::Call> disownCall(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class JsonValue::Pipeline { -public: - typedef JsonValue Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class JsonValue::Field::Reader { -public: - typedef Field Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasName() const; - inline ::capnp::Text::Reader getName() const; - - inline bool hasValue() const; - inline ::capnp::JsonValue::Reader getValue() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class JsonValue::Field::Builder { -public: - typedef Field Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasName(); - inline ::capnp::Text::Builder getName(); - inline void setName( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initName(unsigned int size); - inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownName(); - - inline bool hasValue(); - inline ::capnp::JsonValue::Builder getValue(); - inline void setValue( ::capnp::JsonValue::Reader value); - inline ::capnp::JsonValue::Builder initValue(); - inline void adoptValue(::capnp::Orphan< ::capnp::JsonValue>&& value); - inline ::capnp::Orphan< ::capnp::JsonValue> disownValue(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class JsonValue::Field::Pipeline { -public: - typedef Field Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::JsonValue::Pipeline getValue(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class JsonValue::Call::Reader { -public: - typedef Call Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasFunction() const; - inline ::capnp::Text::Reader getFunction() const; - - inline bool hasParams() const; - inline ::capnp::List< ::capnp::JsonValue>::Reader getParams() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class JsonValue::Call::Builder { -public: - typedef Call Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasFunction(); - inline ::capnp::Text::Builder getFunction(); - inline void setFunction( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initFunction(unsigned int size); - inline void adoptFunction(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownFunction(); - - inline bool hasParams(); - inline ::capnp::List< ::capnp::JsonValue>::Builder getParams(); - inline void setParams( ::capnp::List< ::capnp::JsonValue>::Reader value); - inline ::capnp::List< ::capnp::JsonValue>::Builder initParams(unsigned int size); - inline void adoptParams(::capnp::Orphan< ::capnp::List< ::capnp::JsonValue>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::JsonValue>> disownParams(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class JsonValue::Call::Pipeline { -public: - typedef Call Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -// ======================================================================================= - -inline ::capnp::JsonValue::Which JsonValue::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline ::capnp::JsonValue::Which JsonValue::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline bool JsonValue::Reader::isNull() const { - return which() == JsonValue::NULL_; -} -inline bool JsonValue::Builder::isNull() { - return which() == JsonValue::NULL_; -} -inline ::capnp::Void JsonValue::Reader::getNull() const { - KJ_IREQUIRE((which() == JsonValue::NULL_), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void JsonValue::Builder::getNull() { - KJ_IREQUIRE((which() == JsonValue::NULL_), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void JsonValue::Builder::setNull( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, JsonValue::NULL_); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool JsonValue::Reader::isBoolean() const { - return which() == JsonValue::BOOLEAN; -} -inline bool JsonValue::Builder::isBoolean() { - return which() == JsonValue::BOOLEAN; -} -inline bool JsonValue::Reader::getBoolean() const { - KJ_IREQUIRE((which() == JsonValue::BOOLEAN), - "Must check which() before get()ing a union member."); - return _reader.getDataField( - ::capnp::bounded<16>() * ::capnp::ELEMENTS); -} - -inline bool JsonValue::Builder::getBoolean() { - KJ_IREQUIRE((which() == JsonValue::BOOLEAN), - "Must check which() before get()ing a union member."); - return _builder.getDataField( - ::capnp::bounded<16>() * ::capnp::ELEMENTS); -} -inline void JsonValue::Builder::setBoolean(bool value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, JsonValue::BOOLEAN); - _builder.setDataField( - ::capnp::bounded<16>() * ::capnp::ELEMENTS, value); -} - -inline bool JsonValue::Reader::isNumber() const { - return which() == JsonValue::NUMBER; -} -inline bool JsonValue::Builder::isNumber() { - return which() == JsonValue::NUMBER; -} -inline double JsonValue::Reader::getNumber() const { - KJ_IREQUIRE((which() == JsonValue::NUMBER), - "Must check which() before get()ing a union member."); - return _reader.getDataField( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline double JsonValue::Builder::getNumber() { - KJ_IREQUIRE((which() == JsonValue::NUMBER), - "Must check which() before get()ing a union member."); - return _builder.getDataField( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void JsonValue::Builder::setNumber(double value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, JsonValue::NUMBER); - _builder.setDataField( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool JsonValue::Reader::isString() const { - return which() == JsonValue::STRING; -} -inline bool JsonValue::Builder::isString() { - return which() == JsonValue::STRING; -} -inline bool JsonValue::Reader::hasString() const { - if (which() != JsonValue::STRING) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool JsonValue::Builder::hasString() { - if (which() != JsonValue::STRING) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader JsonValue::Reader::getString() const { - KJ_IREQUIRE((which() == JsonValue::STRING), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder JsonValue::Builder::getString() { - KJ_IREQUIRE((which() == JsonValue::STRING), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void JsonValue::Builder::setString( ::capnp::Text::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, JsonValue::STRING); - ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder JsonValue::Builder::initString(unsigned int size) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, JsonValue::STRING); - return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void JsonValue::Builder::adoptString( - ::capnp::Orphan< ::capnp::Text>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, JsonValue::STRING); - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> JsonValue::Builder::disownString() { - KJ_IREQUIRE((which() == JsonValue::STRING), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool JsonValue::Reader::isArray() const { - return which() == JsonValue::ARRAY; -} -inline bool JsonValue::Builder::isArray() { - return which() == JsonValue::ARRAY; -} -inline bool JsonValue::Reader::hasArray() const { - if (which() != JsonValue::ARRAY) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool JsonValue::Builder::hasArray() { - if (which() != JsonValue::ARRAY) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::JsonValue>::Reader JsonValue::Reader::getArray() const { - KJ_IREQUIRE((which() == JsonValue::ARRAY), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue>>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::JsonValue>::Builder JsonValue::Builder::getArray() { - KJ_IREQUIRE((which() == JsonValue::ARRAY), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue>>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void JsonValue::Builder::setArray( ::capnp::List< ::capnp::JsonValue>::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, JsonValue::ARRAY); - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue>>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::JsonValue>::Builder JsonValue::Builder::initArray(unsigned int size) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, JsonValue::ARRAY); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue>>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void JsonValue::Builder::adoptArray( - ::capnp::Orphan< ::capnp::List< ::capnp::JsonValue>>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, JsonValue::ARRAY); - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue>>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::JsonValue>> JsonValue::Builder::disownArray() { - KJ_IREQUIRE((which() == JsonValue::ARRAY), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue>>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool JsonValue::Reader::isObject() const { - return which() == JsonValue::OBJECT; -} -inline bool JsonValue::Builder::isObject() { - return which() == JsonValue::OBJECT; -} -inline bool JsonValue::Reader::hasObject() const { - if (which() != JsonValue::OBJECT) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool JsonValue::Builder::hasObject() { - if (which() != JsonValue::OBJECT) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::JsonValue::Field>::Reader JsonValue::Reader::getObject() const { - KJ_IREQUIRE((which() == JsonValue::OBJECT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue::Field>>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::JsonValue::Field>::Builder JsonValue::Builder::getObject() { - KJ_IREQUIRE((which() == JsonValue::OBJECT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue::Field>>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void JsonValue::Builder::setObject( ::capnp::List< ::capnp::JsonValue::Field>::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, JsonValue::OBJECT); - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue::Field>>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::JsonValue::Field>::Builder JsonValue::Builder::initObject(unsigned int size) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, JsonValue::OBJECT); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue::Field>>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void JsonValue::Builder::adoptObject( - ::capnp::Orphan< ::capnp::List< ::capnp::JsonValue::Field>>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, JsonValue::OBJECT); - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue::Field>>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::JsonValue::Field>> JsonValue::Builder::disownObject() { - KJ_IREQUIRE((which() == JsonValue::OBJECT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue::Field>>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool JsonValue::Reader::isCall() const { - return which() == JsonValue::CALL; -} -inline bool JsonValue::Builder::isCall() { - return which() == JsonValue::CALL; -} -inline bool JsonValue::Reader::hasCall() const { - if (which() != JsonValue::CALL) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool JsonValue::Builder::hasCall() { - if (which() != JsonValue::CALL) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::JsonValue::Call::Reader JsonValue::Reader::getCall() const { - KJ_IREQUIRE((which() == JsonValue::CALL), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::JsonValue::Call>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::JsonValue::Call::Builder JsonValue::Builder::getCall() { - KJ_IREQUIRE((which() == JsonValue::CALL), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::JsonValue::Call>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void JsonValue::Builder::setCall( ::capnp::JsonValue::Call::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, JsonValue::CALL); - ::capnp::_::PointerHelpers< ::capnp::JsonValue::Call>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::JsonValue::Call::Builder JsonValue::Builder::initCall() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, JsonValue::CALL); - return ::capnp::_::PointerHelpers< ::capnp::JsonValue::Call>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void JsonValue::Builder::adoptCall( - ::capnp::Orphan< ::capnp::JsonValue::Call>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, JsonValue::CALL); - ::capnp::_::PointerHelpers< ::capnp::JsonValue::Call>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::JsonValue::Call> JsonValue::Builder::disownCall() { - KJ_IREQUIRE((which() == JsonValue::CALL), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::JsonValue::Call>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool JsonValue::Field::Reader::hasName() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool JsonValue::Field::Builder::hasName() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader JsonValue::Field::Reader::getName() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder JsonValue::Field::Builder::getName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void JsonValue::Field::Builder::setName( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder JsonValue::Field::Builder::initName(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void JsonValue::Field::Builder::adoptName( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> JsonValue::Field::Builder::disownName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool JsonValue::Field::Reader::hasValue() const { - return !_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline bool JsonValue::Field::Builder::hasValue() { - return !_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::JsonValue::Reader JsonValue::Field::Reader::getValue() const { - return ::capnp::_::PointerHelpers< ::capnp::JsonValue>::get(_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline ::capnp::JsonValue::Builder JsonValue::Field::Builder::getValue() { - return ::capnp::_::PointerHelpers< ::capnp::JsonValue>::get(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::JsonValue::Pipeline JsonValue::Field::Pipeline::getValue() { - return ::capnp::JsonValue::Pipeline(_typeless.getPointerField(1)); -} -#endif // !CAPNP_LITE -inline void JsonValue::Field::Builder::setValue( ::capnp::JsonValue::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::JsonValue>::set(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), value); -} -inline ::capnp::JsonValue::Builder JsonValue::Field::Builder::initValue() { - return ::capnp::_::PointerHelpers< ::capnp::JsonValue>::init(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline void JsonValue::Field::Builder::adoptValue( - ::capnp::Orphan< ::capnp::JsonValue>&& value) { - ::capnp::_::PointerHelpers< ::capnp::JsonValue>::adopt(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::JsonValue> JsonValue::Field::Builder::disownValue() { - return ::capnp::_::PointerHelpers< ::capnp::JsonValue>::disown(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} - -inline bool JsonValue::Call::Reader::hasFunction() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool JsonValue::Call::Builder::hasFunction() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader JsonValue::Call::Reader::getFunction() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder JsonValue::Call::Builder::getFunction() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void JsonValue::Call::Builder::setFunction( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder JsonValue::Call::Builder::initFunction(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void JsonValue::Call::Builder::adoptFunction( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> JsonValue::Call::Builder::disownFunction() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool JsonValue::Call::Reader::hasParams() const { - return !_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline bool JsonValue::Call::Builder::hasParams() { - return !_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::JsonValue>::Reader JsonValue::Call::Reader::getParams() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue>>::get(_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::JsonValue>::Builder JsonValue::Call::Builder::getParams() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue>>::get(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline void JsonValue::Call::Builder::setParams( ::capnp::List< ::capnp::JsonValue>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue>>::set(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::JsonValue>::Builder JsonValue::Call::Builder::initParams(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue>>::init(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), size); -} -inline void JsonValue::Call::Builder::adoptParams( - ::capnp::Orphan< ::capnp::List< ::capnp::JsonValue>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue>>::adopt(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::JsonValue>> JsonValue::Call::Builder::disownParams() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::JsonValue>>::disown(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} - -} // namespace - -#endif // CAPNP_INCLUDED_8ef99297a43a5e34_ diff --git a/phonelibs/capnp-cpp/include/capnp/compat/json.h b/phonelibs/capnp-cpp/include/capnp/compat/json.h deleted file mode 100644 index 7fa815e0998e9e..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/compat/json.h +++ /dev/null @@ -1,462 +0,0 @@ -// Copyright (c) 2015 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_COMPAT_JSON_H_ -#define CAPNP_COMPAT_JSON_H_ - -#include -#include -#include - -namespace capnp { - -class JsonCodec { - // Flexible class for encoding Cap'n Proto types as JSON, and decoding JSON back to Cap'n Proto. - // - // Typical usage: - // - // JsonCodec json; - // - // // encode - // kj::String encoded = json.encode(someStructReader); - // - // // decode - // json.decode(encoded, someStructBuilder); - // - // Advanced users can do fancy things like override the way certain types or fields are - // represented in JSON by registering handlers. See the unit test for an example. - // - // Notes: - // - When encoding, all primitive fields are always encoded, even if default-valued. Pointer - // fields are only encoded if they are non-null. - // - 64-bit integers are encoded as strings, since JSON "numbers" are double-precision floating - // points which cannot store a 64-bit integer without losing data. - // - NaNs and infinite floating point numbers are not allowed by the JSON spec, and so are encoded - // as null. This matches the behavior of `JSON.stringify` in at least Firefox and Chrome. - // - Data is encoded as an array of numbers in the range [0,255]. You probably want to register - // a handler that does something better, like maybe base64 encoding, but there are a zillion - // different ways people do this. - // - Encoding/decoding capabilities and AnyPointers requires registering a Handler, since there's - // no obvious default behavior. - // - When decoding, unrecognized field names are ignored. Note: This means that JSON is NOT a - // good format for receiving input from a human. Consider `capnp eval` or the SchemaParser - // library for human input. - -public: - JsonCodec(); - ~JsonCodec() noexcept(false); - - // --------------------------------------------------------------------------- - // standard API - - void setPrettyPrint(bool enabled); - // Enable to insert newlines, indentation, and other extra spacing into the output. The default - // is to use minimal whitespace. - - void setMaxNestingDepth(size_t maxNestingDepth); - // Set maximum nesting depth when decoding JSON to prevent highly nested input from overflowing - // the call stack. The default is 64. - - template - kj::String encode(T&& value); - // Encode any Cap'n Proto value to JSON, including primitives and - // Dynamic{Enum,Struct,List,Capability}, but not DynamicValue (see below). - - kj::String encode(DynamicValue::Reader value, Type type) const; - // Encode a DynamicValue to JSON. `type` is needed because `DynamicValue` itself does - // not distinguish between e.g. int32 and int64, which in JSON are handled differently. Most - // of the time, though, you can use the single-argument templated version of `encode()` instead. - - void decode(kj::ArrayPtr input, DynamicStruct::Builder output) const; - // Decode JSON text directly into a struct builder. This only works for structs since lists - // need to be allocated with the correct size in advance. - // - // (Remember that any Cap'n Proto struct reader type can be implicitly cast to - // DynamicStruct::Reader.) - - template - Orphan decode(kj::ArrayPtr input, Orphanage orphanage) const; - // Decode JSON text to any Cap'n Proto object (pointer value), allocated using the given - // orphanage. T must be specified explicitly and cannot be dynamic, e.g.: - // - // Orphan orphan = json.decode(text, orphanage); - - template - ReaderFor decode(kj::ArrayPtr input) const; - // Decode JSON text into a primitive or capability value. T must be specified explicitly and - // cannot be dynamic, e.g.: - // - // uint32_t n = json.decode(text); - - Orphan decode(kj::ArrayPtr input, Type type, Orphanage orphanage) const; - Orphan decode( - kj::ArrayPtr input, ListSchema type, Orphanage orphanage) const; - Orphan decode( - kj::ArrayPtr input, StructSchema type, Orphanage orphanage) const; - DynamicCapability::Client decode(kj::ArrayPtr input, InterfaceSchema type) const; - DynamicEnum decode(kj::ArrayPtr input, EnumSchema type) const; - // Decode to a dynamic value, specifying the type schema. - - // --------------------------------------------------------------------------- - // layered API - // - // You can separate text <-> JsonValue from JsonValue <-> T. These are particularly useful - // for calling from Handler implementations. - - kj::String encodeRaw(JsonValue::Reader value) const; - void decodeRaw(kj::ArrayPtr input, JsonValue::Builder output) const; - // Translate JsonValue <-> text. - - template - void encode(T&& value, JsonValue::Builder output); - void encode(DynamicValue::Reader input, Type type, JsonValue::Builder output) const; - void decode(JsonValue::Reader input, DynamicStruct::Builder output) const; - template - Orphan decode(JsonValue::Reader input, Orphanage orphanage) const; - template - ReaderFor decode(JsonValue::Reader input) const; - - Orphan decode(JsonValue::Reader input, Type type, Orphanage orphanage) const; - Orphan decode(JsonValue::Reader input, ListSchema type, Orphanage orphanage) const; - Orphan decode( - JsonValue::Reader input, StructSchema type, Orphanage orphanage) const; - DynamicCapability::Client decode(JsonValue::Reader input, InterfaceSchema type) const; - DynamicEnum decode(JsonValue::Reader input, EnumSchema type) const; - - // --------------------------------------------------------------------------- - // specializing particular types - - template ()> - class Handler; - // Implement this interface to specify a special encoding for a particular type or field. - // - // The templates are a bit ugly, but subclasses of this type essentially implement two methods, - // one to encode values of this type and one to decode values of this type. `encode()` is simple: - // - // void encode(const JsonCodec& codec, ReaderFor input, JsonValue::Builder output) const; - // - // `decode()` is a bit trickier. When T is a struct (including DynamicStruct), it is: - // - // void decode(const JsonCodec& codec, JsonValue::Reader input, BuilderFor output) const; - // - // However, when T is a primitive, decode() is: - // - // T decode(const JsonCodec& codec, JsonValue::Reader input) const; - // - // Or when T is any non-struct object (list, blob), decode() is: - // - // Orphan decode(const JsonCodec& codec, JsonValue::Reader input, Orphanage orphanage) const; - // - // Or when T is an interface: - // - // T::Client decode(const JsonCodec& codec, JsonValue::Reader input) const; - // - // Additionally, when T is a struct you can *optionally* also implement the orphan-returning form - // of decode(), but it will only be called when the struct would be allocated as an individual - // object, not as part of a list. This allows you to return "nullptr" in these cases to say that - // the pointer value should be null. This does not apply to list elements because struct list - // elements cannot ever be null (since Cap'n Proto encodes struct lists as a flat list rather - // than list-of-pointers). - - template - void addTypeHandler(Handler& handler); - void addTypeHandler(Type type, Handler& handler); - void addTypeHandler(EnumSchema type, Handler& handler); - void addTypeHandler(StructSchema type, Handler& handler); - void addTypeHandler(ListSchema type, Handler& handler); - void addTypeHandler(InterfaceSchema type, Handler& handler); - // Arrange that whenever the type T appears in the message, your handler will be used to - // encode/decode it. - // - // Note that if you register a handler for a capability type, it will also apply to subtypes. - // Thus Handler handles all capabilities. - - template - void addFieldHandler(StructSchema::Field field, Handler& handler); - // Matches only the specific field. T can be a dynamic type. T must match the field's type. - -private: - class HandlerBase; - struct Impl; - - kj::Own impl; - - void encodeField(StructSchema::Field field, DynamicValue::Reader input, - JsonValue::Builder output) const; - void decodeArray(List::Reader input, DynamicList::Builder output) const; - void decodeObject(List::Reader input, DynamicStruct::Builder output) const; - void addTypeHandlerImpl(Type type, HandlerBase& handler); - void addFieldHandlerImpl(StructSchema::Field field, Type type, HandlerBase& handler); -}; - -// ======================================================================================= -// inline implementation details - -template -kj::String JsonCodec::encode(T&& value) { - typedef FromAny> Base; - return encode(DynamicValue::Reader(ReaderFor(kj::fwd(value))), Type::from()); -} - -template -inline Orphan JsonCodec::decode(kj::ArrayPtr input, Orphanage orphanage) const { - return decode(input, Type::from(), orphanage).template releaseAs(); -} - -template -inline ReaderFor JsonCodec::decode(kj::ArrayPtr input) const { - static_assert(style() == Style::PRIMITIVE || style() == Style::CAPABILITY, - "must specify an orphanage to decode an object type"); - return decode(input, Type::from(), Orphanage()).getReader().template as(); -} - -inline Orphan JsonCodec::decode( - kj::ArrayPtr input, ListSchema type, Orphanage orphanage) const { - return decode(input, Type(type), orphanage).releaseAs(); -} -inline Orphan JsonCodec::decode( - kj::ArrayPtr input, StructSchema type, Orphanage orphanage) const { - return decode(input, Type(type), orphanage).releaseAs(); -} -inline DynamicCapability::Client JsonCodec::decode( - kj::ArrayPtr input, InterfaceSchema type) const { - return decode(input, Type(type), Orphanage()).getReader().as(); -} -inline DynamicEnum JsonCodec::decode(kj::ArrayPtr input, EnumSchema type) const { - return decode(input, Type(type), Orphanage()).getReader().as(); -} - -// ----------------------------------------------------------------------------- - -template -void JsonCodec::encode(T&& value, JsonValue::Builder output) { - typedef FromAny> Base; - encode(DynamicValue::Reader(ReaderFor(kj::fwd(value))), Type::from(), output); -} - -template -inline Orphan JsonCodec::decode(JsonValue::Reader input, Orphanage orphanage) const { - return decode(input, Type::from(), orphanage).template releaseAs(); -} - -template -inline ReaderFor JsonCodec::decode(JsonValue::Reader input) const { - static_assert(style() == Style::PRIMITIVE || style() == Style::CAPABILITY, - "must specify an orphanage to decode an object type"); - return decode(input, Type::from(), Orphanage()).getReader().template as(); -} - -inline Orphan JsonCodec::decode( - JsonValue::Reader input, ListSchema type, Orphanage orphanage) const { - return decode(input, Type(type), orphanage).releaseAs(); -} -inline Orphan JsonCodec::decode( - JsonValue::Reader input, StructSchema type, Orphanage orphanage) const { - return decode(input, Type(type), orphanage).releaseAs(); -} -inline DynamicCapability::Client JsonCodec::decode( - JsonValue::Reader input, InterfaceSchema type) const { - return decode(input, Type(type), Orphanage()).getReader().as(); -} -inline DynamicEnum JsonCodec::decode(JsonValue::Reader input, EnumSchema type) const { - return decode(input, Type(type), Orphanage()).getReader().as(); -} - -// ----------------------------------------------------------------------------- - -class JsonCodec::HandlerBase { - // Internal helper; ignore. -public: - virtual void encodeBase(const JsonCodec& codec, DynamicValue::Reader input, - JsonValue::Builder output) const = 0; - virtual Orphan decodeBase(const JsonCodec& codec, JsonValue::Reader input, - Type type, Orphanage orphanage) const; - virtual void decodeStructBase(const JsonCodec& codec, JsonValue::Reader input, - DynamicStruct::Builder output) const; -}; - -template -class JsonCodec::Handler: private JsonCodec::HandlerBase { -public: - virtual void encode(const JsonCodec& codec, ReaderFor input, - JsonValue::Builder output) const = 0; - virtual Orphan decode(const JsonCodec& codec, JsonValue::Reader input, - Orphanage orphanage) const = 0; - -private: - void encodeBase(const JsonCodec& codec, DynamicValue::Reader input, - JsonValue::Builder output) const override final { - encode(codec, input.as(), output); - } - Orphan decodeBase(const JsonCodec& codec, JsonValue::Reader input, - Type type, Orphanage orphanage) const override final { - return decode(codec, input, orphanage); - } - friend class JsonCodec; -}; - -template -class JsonCodec::Handler: private JsonCodec::HandlerBase { -public: - virtual void encode(const JsonCodec& codec, ReaderFor input, - JsonValue::Builder output) const = 0; - virtual void decode(const JsonCodec& codec, JsonValue::Reader input, - BuilderFor output) const = 0; - virtual Orphan decode(const JsonCodec& codec, JsonValue::Reader input, - Orphanage orphanage) const { - // If subclass does not override, fall back to regular version. - auto result = orphanage.newOrphan(); - decode(codec, input, result.get()); - return result; - } - -private: - void encodeBase(const JsonCodec& codec, DynamicValue::Reader input, - JsonValue::Builder output) const override final { - encode(codec, input.as(), output); - } - Orphan decodeBase(const JsonCodec& codec, JsonValue::Reader input, - Type type, Orphanage orphanage) const override final { - return decode(codec, input, orphanage); - } - void decodeStructBase(const JsonCodec& codec, JsonValue::Reader input, - DynamicStruct::Builder output) const override final { - decode(codec, input, output.as()); - } - friend class JsonCodec; -}; - -template <> -class JsonCodec::Handler: private JsonCodec::HandlerBase { - // Almost identical to Style::STRUCT except that we pass the struct type to decode(). - -public: - virtual void encode(const JsonCodec& codec, DynamicStruct::Reader input, - JsonValue::Builder output) const = 0; - virtual void decode(const JsonCodec& codec, JsonValue::Reader input, - DynamicStruct::Builder output) const = 0; - virtual Orphan decode(const JsonCodec& codec, JsonValue::Reader input, - StructSchema type, Orphanage orphanage) const { - // If subclass does not override, fall back to regular version. - auto result = orphanage.newOrphan(type); - decode(codec, input, result.get()); - return result; - } - -private: - void encodeBase(const JsonCodec& codec, DynamicValue::Reader input, - JsonValue::Builder output) const override final { - encode(codec, input.as(), output); - } - Orphan decodeBase(const JsonCodec& codec, JsonValue::Reader input, - Type type, Orphanage orphanage) const override final { - return decode(codec, input, type.asStruct(), orphanage); - } - void decodeStructBase(const JsonCodec& codec, JsonValue::Reader input, - DynamicStruct::Builder output) const override final { - decode(codec, input, output.as()); - } - friend class JsonCodec; -}; - -template -class JsonCodec::Handler: private JsonCodec::HandlerBase { -public: - virtual void encode(const JsonCodec& codec, T input, JsonValue::Builder output) const = 0; - virtual T decode(const JsonCodec& codec, JsonValue::Reader input) const = 0; - -private: - void encodeBase(const JsonCodec& codec, DynamicValue::Reader input, - JsonValue::Builder output) const override final { - encode(codec, input.as(), output); - } - Orphan decodeBase(const JsonCodec& codec, JsonValue::Reader input, - Type type, Orphanage orphanage) const override final { - return decode(codec, input); - } - friend class JsonCodec; -}; - -template -class JsonCodec::Handler: private JsonCodec::HandlerBase { -public: - virtual void encode(const JsonCodec& codec, typename T::Client input, - JsonValue::Builder output) const = 0; - virtual typename T::Client decode(const JsonCodec& codec, JsonValue::Reader input) const = 0; - -private: - void encodeBase(const JsonCodec& codec, DynamicValue::Reader input, - JsonValue::Builder output) const override final { - encode(codec, input.as(), output); - } - Orphan decodeBase(const JsonCodec& codec, JsonValue::Reader input, - Type type, Orphanage orphanage) const override final { - return orphanage.newOrphanCopy(decode(codec, input)); - } - friend class JsonCodec; -}; - -template -inline void JsonCodec::addTypeHandler(Handler& handler) { - addTypeHandlerImpl(Type::from(), handler); -} -inline void JsonCodec::addTypeHandler(Type type, Handler& handler) { - addTypeHandlerImpl(type, handler); -} -inline void JsonCodec::addTypeHandler(EnumSchema type, Handler& handler) { - addTypeHandlerImpl(type, handler); -} -inline void JsonCodec::addTypeHandler(StructSchema type, Handler& handler) { - addTypeHandlerImpl(type, handler); -} -inline void JsonCodec::addTypeHandler(ListSchema type, Handler& handler) { - addTypeHandlerImpl(type, handler); -} -inline void JsonCodec::addTypeHandler(InterfaceSchema type, Handler& handler) { - addTypeHandlerImpl(type, handler); -} - -template -inline void JsonCodec::addFieldHandler(StructSchema::Field field, Handler& handler) { - addFieldHandlerImpl(field, Type::from(), handler); -} - -template <> void JsonCodec::addTypeHandler(Handler& handler) - KJ_UNAVAILABLE("JSON handlers for type sets (e.g. all structs, all lists) not implemented; " - "try specifying a specific type schema as the first parameter"); -template <> void JsonCodec::addTypeHandler(Handler& handler) - KJ_UNAVAILABLE("JSON handlers for type sets (e.g. all structs, all lists) not implemented; " - "try specifying a specific type schema as the first parameter"); -template <> void JsonCodec::addTypeHandler(Handler& handler) - KJ_UNAVAILABLE("JSON handlers for type sets (e.g. all structs, all lists) not implemented; " - "try specifying a specific type schema as the first parameter"); -template <> void JsonCodec::addTypeHandler(Handler& handler) - KJ_UNAVAILABLE("JSON handlers for type sets (e.g. all structs, all lists) not implemented; " - "try specifying a specific type schema as the first parameter"); -template <> void JsonCodec::addTypeHandler(Handler& handler) - KJ_UNAVAILABLE("JSON handlers for type sets (e.g. all structs, all lists) not implemented; " - "try specifying a specific type schema as the first parameter"); -// TODO(someday): Implement support for registering handlers that cover thinsg like "all structs" -// or "all lists". Currently you can only target a specific struct or list type. - -} // namespace capnp - -#endif // CAPNP_COMPAT_JSON_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/dynamic.h b/phonelibs/capnp-cpp/include/capnp/dynamic.h deleted file mode 100644 index fcefcc3bf2fee9..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/dynamic.h +++ /dev/null @@ -1,1643 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -// This file defines classes that can be used to manipulate messages based on schemas that are not -// known until runtime. This is also useful for writing generic code that uses schemas to handle -// arbitrary types in a generic way. -// -// Each of the classes defined here has a to() template method which converts an instance back to a -// native type. This method will throw an exception if the requested type does not match the -// schema. To convert native types to dynamic, use DynamicFactory. -// -// As always, underlying data is validated lazily, so you have to actually traverse the whole -// message if you want to validate all content. - -#ifndef CAPNP_DYNAMIC_H_ -#define CAPNP_DYNAMIC_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "schema.h" -#include "layout.h" -#include "message.h" -#include "any.h" -#include "capability.h" - -namespace capnp { - -class MessageReader; -class MessageBuilder; - -struct DynamicValue { - DynamicValue() = delete; - - enum Type { - UNKNOWN, - // Means that the value has unknown type and content because it comes from a newer version of - // the schema, or from a newer version of Cap'n Proto that has new features that this version - // doesn't understand. - - VOID, - BOOL, - INT, - UINT, - FLOAT, - TEXT, - DATA, - LIST, - ENUM, - STRUCT, - CAPABILITY, - ANY_POINTER - }; - - class Reader; - class Builder; - class Pipeline; -}; -class DynamicEnum; -struct DynamicStruct { - DynamicStruct() = delete; - class Reader; - class Builder; - class Pipeline; -}; -struct DynamicList { - DynamicList() = delete; - class Reader; - class Builder; -}; -struct DynamicCapability { - DynamicCapability() = delete; - class Client; - class Server; -}; -template <> class Orphan; - -template struct DynamicTypeFor_; -template <> struct DynamicTypeFor_ { typedef DynamicEnum Type; }; -template <> struct DynamicTypeFor_ { typedef DynamicStruct Type; }; -template <> struct DynamicTypeFor_ { typedef DynamicList Type; }; -template <> struct DynamicTypeFor_ { typedef DynamicCapability Type; }; - -template -using DynamicTypeFor = typename DynamicTypeFor_()>::Type; - -template -ReaderFor>> toDynamic(T&& value); -template -BuilderFor>> toDynamic(T&& value); -template -DynamicTypeFor> toDynamic(T&& value); -template -typename DynamicTypeFor>::Client toDynamic(kj::Own&& value); - -namespace _ { // private - -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; - -} // namespace _ (private) - -template <> inline constexpr Style style() { return Style::POINTER; } -template <> inline constexpr Style style() { return Style::PRIMITIVE; } -template <> inline constexpr Style style() { return Style::STRUCT; } -template <> inline constexpr Style style() { return Style::POINTER; } -template <> inline constexpr Style style() { return Style::CAPABILITY; } - -// ------------------------------------------------------------------- - -class DynamicEnum { -public: - DynamicEnum() = default; - inline DynamicEnum(EnumSchema::Enumerant enumerant) - : schema(enumerant.getContainingEnum()), value(enumerant.getOrdinal()) {} - inline DynamicEnum(EnumSchema schema, uint16_t value) - : schema(schema), value(value) {} - - template () == Kind::ENUM>> - inline DynamicEnum(T&& value): DynamicEnum(toDynamic(value)) {} - - template - inline T as() const { return static_cast(asImpl(typeId())); } - // Cast to a native enum type. - - inline EnumSchema getSchema() const { return schema; } - - kj::Maybe getEnumerant() const; - // Get which enumerant this enum value represents. Returns nullptr if the numeric value does not - // correspond to any enumerant in the schema -- this can happen if the data was built using a - // newer schema that has more values defined. - - inline uint16_t getRaw() const { return value; } - // Returns the raw underlying enum value. - -private: - EnumSchema schema; - uint16_t value; - - uint16_t asImpl(uint64_t requestedTypeId) const; - - friend struct DynamicStruct; - friend struct DynamicList; - friend struct DynamicValue; - template - friend DynamicTypeFor> toDynamic(T&& value); -}; - -// ------------------------------------------------------------------- - -class DynamicStruct::Reader { -public: - typedef DynamicStruct Reads; - - Reader() = default; - - template >() == Kind::STRUCT>> - inline Reader(T&& value): Reader(toDynamic(value)) {} - - inline MessageSize totalSize() const { return reader.totalSize().asPublic(); } - - template - typename T::Reader as() const; - // Convert the dynamic struct to its compiled-in type. - - inline StructSchema getSchema() const { return schema; } - - DynamicValue::Reader get(StructSchema::Field field) const; - // Read the given field value. - - bool has(StructSchema::Field field) const; - // Tests whether the given field is set to its default value. For pointer values, this does - // not actually traverse the value comparing it with the default, but simply returns true if the - // pointer is non-null. For members of unions, has() returns false if the union member is not - // active, but does not necessarily return true if the member is active (depends on the field's - // value). - - kj::Maybe which() const; - // If the struct contains an (unnamed) union, and the currently-active field within that union - // is known, this returns that field. Otherwise, it returns null. In other words, this returns - // null if there is no union present _or_ if the union's discriminant is set to an unrecognized - // value. This could happen in particular when receiving a message from a sender who has a - // newer version of the protocol and is using a field of the union that you don't know about yet. - - DynamicValue::Reader get(kj::StringPtr name) const; - bool has(kj::StringPtr name) const; - // Shortcuts to access fields by name. These throw exceptions if no such field exists. - -private: - StructSchema schema; - _::StructReader reader; - - inline Reader(StructSchema schema, _::StructReader reader) - : schema(schema), reader(reader) {} - Reader(StructSchema schema, const _::OrphanBuilder& orphan); - - bool isSetInUnion(StructSchema::Field field) const; - void verifySetInUnion(StructSchema::Field field) const; - static DynamicValue::Reader getImpl(_::StructReader reader, StructSchema::Field field); - - template - friend struct _::PointerHelpers; - friend class DynamicStruct::Builder; - friend struct DynamicList; - friend class MessageReader; - friend class MessageBuilder; - template - friend struct ::capnp::ToDynamic_; - friend kj::StringTree _::structString( - _::StructReader reader, const _::RawBrandedSchema& schema); - friend class Orphanage; - friend class Orphan; - friend class Orphan; - friend class Orphan; -}; - -class DynamicStruct::Builder { -public: - typedef DynamicStruct Builds; - - Builder() = default; - inline Builder(decltype(nullptr)) {} - - template >() == Kind::STRUCT>> - inline Builder(T&& value): Builder(toDynamic(value)) {} - - inline MessageSize totalSize() const { return asReader().totalSize(); } - - template - typename T::Builder as(); - // Cast to a particular struct type. - - inline StructSchema getSchema() const { return schema; } - - DynamicValue::Builder get(StructSchema::Field field); - // Read the given field value. - - inline bool has(StructSchema::Field field) { return asReader().has(field); } - // Tests whether the given field is set to its default value. For pointer values, this does - // not actually traverse the value comparing it with the default, but simply returns true if the - // pointer is non-null. For members of unions, has() returns whether the field is currently - // active and the union as a whole is non-default -- so, the only time has() will return false - // for an active union field is if it is the default active field and it has its default value. - - kj::Maybe which(); - // If the struct contains an (unnamed) union, and the currently-active field within that union - // is known, this returns that field. Otherwise, it returns null. In other words, this returns - // null if there is no union present _or_ if the union's discriminant is set to an unrecognized - // value. This could happen in particular when receiving a message from a sender who has a - // newer version of the protocol and is using a field of the union that you don't know about yet. - - void set(StructSchema::Field field, const DynamicValue::Reader& value); - // Set the given field value. - - DynamicValue::Builder init(StructSchema::Field field); - DynamicValue::Builder init(StructSchema::Field field, uint size); - // Init a struct, list, or blob field. - - void adopt(StructSchema::Field field, Orphan&& orphan); - Orphan disown(StructSchema::Field field); - // Adopt/disown. This works even for non-pointer fields: adopt() becomes equivalent to set() - // and disown() becomes like get() followed by clear(). - - void clear(StructSchema::Field field); - // Clear a field, setting it to its default value. For pointer fields, this actually makes the - // field null. - - DynamicValue::Builder get(kj::StringPtr name); - bool has(kj::StringPtr name); - void set(kj::StringPtr name, const DynamicValue::Reader& value); - void set(kj::StringPtr name, std::initializer_list value); - DynamicValue::Builder init(kj::StringPtr name); - DynamicValue::Builder init(kj::StringPtr name, uint size); - void adopt(kj::StringPtr name, Orphan&& orphan); - Orphan disown(kj::StringPtr name); - void clear(kj::StringPtr name); - // Shortcuts to access fields by name. These throw exceptions if no such field exists. - - Reader asReader() const; - -private: - StructSchema schema; - _::StructBuilder builder; - - inline Builder(StructSchema schema, _::StructBuilder builder) - : schema(schema), builder(builder) {} - Builder(StructSchema schema, _::OrphanBuilder& orphan); - - bool isSetInUnion(StructSchema::Field field); - void verifySetInUnion(StructSchema::Field field); - void setInUnion(StructSchema::Field field); - - template - friend struct _::PointerHelpers; - friend struct DynamicList; - friend class MessageReader; - friend class MessageBuilder; - template - friend struct ::capnp::ToDynamic_; - friend class Orphanage; - friend class Orphan; - friend class Orphan; - friend class Orphan; -}; - -class DynamicStruct::Pipeline { -public: - typedef DynamicStruct Pipelines; - - inline Pipeline(decltype(nullptr)): typeless(nullptr) {} - - template - typename T::Pipeline releaseAs(); - // Convert the dynamic pipeline to its compiled-in type. - - inline StructSchema getSchema() { return schema; } - - DynamicValue::Pipeline get(StructSchema::Field field); - // Read the given field value. - - DynamicValue::Pipeline get(kj::StringPtr name); - // Get by string name. - -private: - StructSchema schema; - AnyPointer::Pipeline typeless; - - inline explicit Pipeline(StructSchema schema, AnyPointer::Pipeline&& typeless) - : schema(schema), typeless(kj::mv(typeless)) {} - - friend class Request; -}; - -// ------------------------------------------------------------------- - -class DynamicList::Reader { -public: - typedef DynamicList Reads; - - inline Reader(): reader(ElementSize::VOID) {} - - template >() == Kind::LIST>> - inline Reader(T&& value): Reader(toDynamic(value)) {} - - template - typename T::Reader as() const; - // Try to convert to any List, Data, or Text. Throws an exception if the underlying data - // can't possibly represent the requested type. - - inline ListSchema getSchema() const { return schema; } - - inline uint size() const { return unbound(reader.size() / ELEMENTS); } - DynamicValue::Reader operator[](uint index) const; - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - ListSchema schema; - _::ListReader reader; - - Reader(ListSchema schema, _::ListReader reader): schema(schema), reader(reader) {} - Reader(ListSchema schema, const _::OrphanBuilder& orphan); - - template - friend struct _::PointerHelpers; - friend struct DynamicStruct; - friend class DynamicList::Builder; - template - friend struct ::capnp::ToDynamic_; - friend class Orphanage; - friend class Orphan; - friend class Orphan; - friend class Orphan; -}; - -class DynamicList::Builder { -public: - typedef DynamicList Builds; - - inline Builder(): builder(ElementSize::VOID) {} - inline Builder(decltype(nullptr)): builder(ElementSize::VOID) {} - - template >() == Kind::LIST>> - inline Builder(T&& value): Builder(toDynamic(value)) {} - - template - typename T::Builder as(); - // Try to convert to any List, Data, or Text. Throws an exception if the underlying data - // can't possibly represent the requested type. - - inline ListSchema getSchema() const { return schema; } - - inline uint size() const { return unbound(builder.size() / ELEMENTS); } - DynamicValue::Builder operator[](uint index); - void set(uint index, const DynamicValue::Reader& value); - DynamicValue::Builder init(uint index, uint size); - void adopt(uint index, Orphan&& orphan); - Orphan disown(uint index); - - typedef _::IndexingIterator Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - - void copyFrom(std::initializer_list value); - - Reader asReader() const; - -private: - ListSchema schema; - _::ListBuilder builder; - - Builder(ListSchema schema, _::ListBuilder builder): schema(schema), builder(builder) {} - Builder(ListSchema schema, _::OrphanBuilder& orphan); - - template - friend struct _::PointerHelpers; - friend struct DynamicStruct; - template - friend struct ::capnp::ToDynamic_; - friend class Orphanage; - template - friend struct _::OrphanGetImpl; - friend class Orphan; - friend class Orphan; - friend class Orphan; -}; - -// ------------------------------------------------------------------- - -class DynamicCapability::Client: public Capability::Client { -public: - typedef DynamicCapability Calls; - typedef DynamicCapability Reads; - - Client() = default; - - template >() == Kind::INTERFACE>> - inline Client(T&& client); - - template ()>> - inline Client(kj::Own&& server); - - template () == Kind::INTERFACE>> - typename T::Client as(); - template () == Kind::INTERFACE>> - typename T::Client releaseAs(); - // Convert to any client type. - - Client upcast(InterfaceSchema requestedSchema); - // Upcast to a superclass. Throws an exception if `schema` is not a superclass. - - inline InterfaceSchema getSchema() { return schema; } - - Request newRequest( - InterfaceSchema::Method method, kj::Maybe sizeHint = nullptr); - Request newRequest( - kj::StringPtr methodName, kj::Maybe sizeHint = nullptr); - -private: - InterfaceSchema schema; - - Client(InterfaceSchema schema, kj::Own&& hook) - : Capability::Client(kj::mv(hook)), schema(schema) {} - - template - inline Client(InterfaceSchema schema, kj::Own&& server); - - friend struct Capability; - friend struct DynamicStruct; - friend struct DynamicList; - friend struct DynamicValue; - friend class Orphan; - friend class Orphan; - friend class Orphan; - template - friend struct _::PointerHelpers; -}; - -class DynamicCapability::Server: public Capability::Server { -public: - typedef DynamicCapability Serves; - - Server(InterfaceSchema schema): schema(schema) {} - - virtual kj::Promise call(InterfaceSchema::Method method, - CallContext context) = 0; - - kj::Promise dispatchCall(uint64_t interfaceId, uint16_t methodId, - CallContext context) override final; - - inline InterfaceSchema getSchema() const { return schema; } - -private: - InterfaceSchema schema; -}; - -template <> -class Request: public DynamicStruct::Builder { - // Specialization of `Request` for DynamicStruct. - -public: - inline Request(DynamicStruct::Builder builder, kj::Own&& hook, - StructSchema resultSchema) - : DynamicStruct::Builder(builder), hook(kj::mv(hook)), resultSchema(resultSchema) {} - - RemotePromise send(); - // Send the call and return a promise for the results. - -private: - kj::Own hook; - StructSchema resultSchema; - - friend class Capability::Client; - friend struct DynamicCapability; - template - friend class CallContext; - friend class RequestHook; -}; - -template <> -class CallContext: public kj::DisallowConstCopy { - // Wrapper around CallContextHook with a specific return type. - // - // Methods of this class may only be called from within the server's event loop, not from other - // threads. - -public: - explicit CallContext(CallContextHook& hook, StructSchema paramType, StructSchema resultType); - - DynamicStruct::Reader getParams(); - void releaseParams(); - DynamicStruct::Builder getResults(kj::Maybe sizeHint = nullptr); - DynamicStruct::Builder initResults(kj::Maybe sizeHint = nullptr); - void setResults(DynamicStruct::Reader value); - void adoptResults(Orphan&& value); - Orphanage getResultsOrphanage(kj::Maybe sizeHint = nullptr); - template - kj::Promise tailCall(Request&& tailRequest); - void allowCancellation(); - -private: - CallContextHook* hook; - StructSchema paramType; - StructSchema resultType; - - friend class DynamicCapability::Server; -}; - -// ------------------------------------------------------------------- - -// Make sure ReaderFor and BuilderFor work for DynamicEnum, DynamicStruct, and -// DynamicList, so that we can define DynamicValue::as(). - -template <> struct ReaderFor_ { typedef DynamicEnum Type; }; -template <> struct BuilderFor_ { typedef DynamicEnum Type; }; -template <> struct ReaderFor_ { typedef DynamicStruct::Reader Type; }; -template <> struct BuilderFor_ { typedef DynamicStruct::Builder Type; }; -template <> struct ReaderFor_ { typedef DynamicList::Reader Type; }; -template <> struct BuilderFor_ { typedef DynamicList::Builder Type; }; -template <> struct ReaderFor_ { typedef DynamicCapability::Client Type; }; -template <> struct BuilderFor_ { typedef DynamicCapability::Client Type; }; -template <> struct PipelineFor_ { typedef DynamicCapability::Client Type; }; - -class DynamicValue::Reader { -public: - typedef DynamicValue Reads; - - inline Reader(decltype(nullptr) n = nullptr); // UNKNOWN - inline Reader(Void value); - inline Reader(bool value); - inline Reader(char value); - inline Reader(signed char value); - inline Reader(short value); - inline Reader(int value); - inline Reader(long value); - inline Reader(long long value); - inline Reader(unsigned char value); - inline Reader(unsigned short value); - inline Reader(unsigned int value); - inline Reader(unsigned long value); - inline Reader(unsigned long long value); - inline Reader(float value); - inline Reader(double value); - inline Reader(const char* value); // Text - inline Reader(const Text::Reader& value); - inline Reader(const Data::Reader& value); - inline Reader(const DynamicList::Reader& value); - inline Reader(DynamicEnum value); - inline Reader(const DynamicStruct::Reader& value); - inline Reader(const AnyPointer::Reader& value); - inline Reader(DynamicCapability::Client& value); - inline Reader(DynamicCapability::Client&& value); - template ()>> - inline Reader(kj::Own&& value); - Reader(ConstSchema constant); - - template ()))> - inline Reader(T&& value): Reader(toDynamic(kj::mv(value))) {} - - Reader(const Reader& other); - Reader(Reader&& other) noexcept; - ~Reader() noexcept(false); - Reader& operator=(const Reader& other); - Reader& operator=(Reader&& other); - // Unfortunately, we cannot use the implicit definitions of these since DynamicCapability is not - // trivially copyable. - - template - inline ReaderFor as() const { return AsImpl::apply(*this); } - // Use to interpret the value as some Cap'n Proto type. Allowed types are: - // - Void, bool, [u]int{8,16,32,64}_t, float, double, any enum: Returns the raw value. - // - Text, Data, AnyPointer, any struct type: Returns the corresponding Reader. - // - List for any T listed above: Returns List::Reader. - // - DynamicEnum: Returns the corresponding type. - // - DynamicStruct, DynamicList: Returns the corresponding Reader. - // - Any capability type, including DynamicCapability: Returns the corresponding Client. - // - DynamicValue: Returns an identical Reader. Useful to avoid special-casing in generic code. - // (TODO(perf): On GCC 4.8 / Clang 3.3, provide rvalue-qualified version that avoids - // refcounting.) - // - // DynamicValue allows various implicit conversions, mostly just to make the interface friendlier. - // - Any integer can be converted to any other integer type so long as the actual value is within - // the new type's range. - // - Floating-point types can be converted to integers as long as no information would be lost - // in the conversion. - // - Integers can be converted to floating points. This may lose information, but won't throw. - // - Float32/Float64 can be converted between each other. Converting Float64 -> Float32 may lose - // information, but won't throw. - // - Text can be converted to an enum, if the Text matches one of the enumerant names (but not - // vice-versa). - // - Capabilities can be upcast (cast to a supertype), but not downcast. - // - // Any other conversion attempt will throw an exception. - - inline Type getType() const { return type; } - // Get the type of this value. - -private: - Type type; - - union { - Void voidValue; - bool boolValue; - int64_t intValue; - uint64_t uintValue; - double floatValue; - Text::Reader textValue; - Data::Reader dataValue; - DynamicList::Reader listValue; - DynamicEnum enumValue; - DynamicStruct::Reader structValue; - AnyPointer::Reader anyPointerValue; - - mutable DynamicCapability::Client capabilityValue; - // Declared mutable because `Client`s normally cannot be const. - - // Warning: Copy/move constructors assume all these types are trivially copyable except - // Capability. - }; - - template ()> struct AsImpl; - // Implementation backing the as() method. Needs to be a struct to allow partial - // specialization. Has a method apply() which does the work. - - friend class Orphanage; // to speed up newOrphanCopy(DynamicValue::Reader) -}; - -class DynamicValue::Builder { -public: - typedef DynamicValue Builds; - - inline Builder(decltype(nullptr) n = nullptr); // UNKNOWN - inline Builder(Void value); - inline Builder(bool value); - inline Builder(char value); - inline Builder(signed char value); - inline Builder(short value); - inline Builder(int value); - inline Builder(long value); - inline Builder(long long value); - inline Builder(unsigned char value); - inline Builder(unsigned short value); - inline Builder(unsigned int value); - inline Builder(unsigned long value); - inline Builder(unsigned long long value); - inline Builder(float value); - inline Builder(double value); - inline Builder(Text::Builder value); - inline Builder(Data::Builder value); - inline Builder(DynamicList::Builder value); - inline Builder(DynamicEnum value); - inline Builder(DynamicStruct::Builder value); - inline Builder(AnyPointer::Builder value); - inline Builder(DynamicCapability::Client& value); - inline Builder(DynamicCapability::Client&& value); - - template ()))> - inline Builder(T value): Builder(toDynamic(value)) {} - - Builder(Builder& other); - Builder(Builder&& other) noexcept; - ~Builder() noexcept(false); - Builder& operator=(Builder& other); - Builder& operator=(Builder&& other); - // Unfortunately, we cannot use the implicit definitions of these since DynamicCapability is not - // trivially copyable. - - template - inline BuilderFor as() { return AsImpl::apply(*this); } - // See DynamicValue::Reader::as(). - - inline Type getType() { return type; } - // Get the type of this value. - - Reader asReader() const; - -private: - Type type; - - union { - Void voidValue; - bool boolValue; - int64_t intValue; - uint64_t uintValue; - double floatValue; - Text::Builder textValue; - Data::Builder dataValue; - DynamicList::Builder listValue; - DynamicEnum enumValue; - DynamicStruct::Builder structValue; - AnyPointer::Builder anyPointerValue; - - mutable DynamicCapability::Client capabilityValue; - // Declared mutable because `Client`s normally cannot be const. - }; - - template ()> struct AsImpl; - // Implementation backing the as() method. Needs to be a struct to allow partial - // specialization. Has a method apply() which does the work. - - friend class Orphan; -}; - -class DynamicValue::Pipeline { -public: - typedef DynamicValue Pipelines; - - inline Pipeline(decltype(nullptr) n = nullptr); - inline Pipeline(DynamicStruct::Pipeline&& value); - inline Pipeline(DynamicCapability::Client&& value); - - Pipeline(Pipeline&& other) noexcept; - Pipeline& operator=(Pipeline&& other); - ~Pipeline() noexcept(false); - - template - inline PipelineFor releaseAs() { return AsImpl::apply(*this); } - - inline Type getType() { return type; } - // Get the type of this value. - -private: - Type type; - union { - DynamicStruct::Pipeline structValue; - DynamicCapability::Client capabilityValue; - }; - - template ()> struct AsImpl; - // Implementation backing the releaseAs() method. Needs to be a struct to allow partial - // specialization. Has a method apply() which does the work. -}; - -kj::StringTree KJ_STRINGIFY(const DynamicValue::Reader& value); -kj::StringTree KJ_STRINGIFY(const DynamicValue::Builder& value); -kj::StringTree KJ_STRINGIFY(DynamicEnum value); -kj::StringTree KJ_STRINGIFY(const DynamicStruct::Reader& value); -kj::StringTree KJ_STRINGIFY(const DynamicStruct::Builder& value); -kj::StringTree KJ_STRINGIFY(const DynamicList::Reader& value); -kj::StringTree KJ_STRINGIFY(const DynamicList::Builder& value); - -// ------------------------------------------------------------------- -// Orphan <-> Dynamic glue - -template <> -class Orphan { -public: - Orphan() = default; - KJ_DISALLOW_COPY(Orphan); - Orphan(Orphan&&) = default; - Orphan& operator=(Orphan&&) = default; - - template () == Kind::STRUCT>> - inline Orphan(Orphan&& other): schema(Schema::from()), builder(kj::mv(other.builder)) {} - - DynamicStruct::Builder get(); - DynamicStruct::Reader getReader() const; - - template - Orphan releaseAs(); - // Like DynamicStruct::Builder::as(), but coerces the Orphan type. Since Orphans are move-only, - // the original Orphan is no longer valid after this call; ownership is - // transferred to the returned Orphan. - - inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } - -private: - StructSchema schema; - _::OrphanBuilder builder; - - inline Orphan(StructSchema schema, _::OrphanBuilder&& builder) - : schema(schema), builder(kj::mv(builder)) {} - - template - friend struct _::PointerHelpers; - friend struct DynamicList; - friend class Orphanage; - friend class Orphan; - friend class Orphan; - friend class MessageBuilder; -}; - -template <> -class Orphan { -public: - Orphan() = default; - KJ_DISALLOW_COPY(Orphan); - Orphan(Orphan&&) = default; - Orphan& operator=(Orphan&&) = default; - - template () == Kind::LIST>> - inline Orphan(Orphan&& other): schema(Schema::from()), builder(kj::mv(other.builder)) {} - - DynamicList::Builder get(); - DynamicList::Reader getReader() const; - - template - Orphan releaseAs(); - // Like DynamicList::Builder::as(), but coerces the Orphan type. Since Orphans are move-only, - // the original Orphan is no longer valid after this call; ownership is - // transferred to the returned Orphan. - - // TODO(someday): Support truncate(). - - inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } - -private: - ListSchema schema; - _::OrphanBuilder builder; - - inline Orphan(ListSchema schema, _::OrphanBuilder&& builder) - : schema(schema), builder(kj::mv(builder)) {} - - template - friend struct _::PointerHelpers; - friend struct DynamicList; - friend class Orphanage; - friend class Orphan; - friend class Orphan; -}; - -template <> -class Orphan { -public: - Orphan() = default; - KJ_DISALLOW_COPY(Orphan); - Orphan(Orphan&&) = default; - Orphan& operator=(Orphan&&) = default; - - template () == Kind::INTERFACE>> - inline Orphan(Orphan&& other): schema(Schema::from()), builder(kj::mv(other.builder)) {} - - DynamicCapability::Client get(); - DynamicCapability::Client getReader() const; - - template - Orphan releaseAs(); - // Like DynamicCapability::Client::as(), but coerces the Orphan type. Since Orphans are move-only, - // the original Orphan is no longer valid after this call; ownership is - // transferred to the returned Orphan. - - inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } - -private: - InterfaceSchema schema; - _::OrphanBuilder builder; - - inline Orphan(InterfaceSchema schema, _::OrphanBuilder&& builder) - : schema(schema), builder(kj::mv(builder)) {} - - template - friend struct _::PointerHelpers; - friend struct DynamicList; - friend class Orphanage; - friend class Orphan; - friend class Orphan; -}; - -template <> -class Orphan { -public: - inline Orphan(decltype(nullptr) n = nullptr): type(DynamicValue::UNKNOWN) {} - inline Orphan(Void value); - inline Orphan(bool value); - inline Orphan(char value); - inline Orphan(signed char value); - inline Orphan(short value); - inline Orphan(int value); - inline Orphan(long value); - inline Orphan(long long value); - inline Orphan(unsigned char value); - inline Orphan(unsigned short value); - inline Orphan(unsigned int value); - inline Orphan(unsigned long value); - inline Orphan(unsigned long long value); - inline Orphan(float value); - inline Orphan(double value); - inline Orphan(DynamicEnum value); - Orphan(Orphan&&) = default; - template - Orphan(Orphan&&); - Orphan(Orphan&&); - Orphan(void*) = delete; // So Orphan(bool) doesn't accept pointers. - KJ_DISALLOW_COPY(Orphan); - - Orphan& operator=(Orphan&&) = default; - - inline DynamicValue::Type getType() { return type; } - - DynamicValue::Builder get(); - DynamicValue::Reader getReader() const; - - template - Orphan releaseAs(); - // Like DynamicValue::Builder::as(), but coerces the Orphan type. Since Orphans are move-only, - // the original Orphan is no longer valid after this call; ownership is - // transferred to the returned Orphan. - -private: - DynamicValue::Type type; - union { - Void voidValue; - bool boolValue; - int64_t intValue; - uint64_t uintValue; - double floatValue; - DynamicEnum enumValue; - StructSchema structSchema; - ListSchema listSchema; - InterfaceSchema interfaceSchema; - }; - - _::OrphanBuilder builder; - // Only used if `type` is a pointer type. - - Orphan(DynamicValue::Builder value, _::OrphanBuilder&& builder); - Orphan(DynamicValue::Type type, _::OrphanBuilder&& builder) - : type(type), builder(kj::mv(builder)) {} - Orphan(StructSchema structSchema, _::OrphanBuilder&& builder) - : type(DynamicValue::STRUCT), structSchema(structSchema), builder(kj::mv(builder)) {} - Orphan(ListSchema listSchema, _::OrphanBuilder&& builder) - : type(DynamicValue::LIST), listSchema(listSchema), builder(kj::mv(builder)) {} - - template - friend struct _::PointerHelpers; - friend struct DynamicStruct; - friend struct DynamicList; - friend struct AnyPointer; - friend class Orphanage; -}; - -template -inline Orphan::Orphan(Orphan&& other) - : Orphan(other.get(), kj::mv(other.builder)) {} - -inline Orphan::Orphan(Orphan&& other) - : type(DynamicValue::ANY_POINTER), builder(kj::mv(other.builder)) {} - -template -Orphan Orphan::releaseAs() { - get().as(); // type check - return Orphan(kj::mv(builder)); -} - -template -Orphan Orphan::releaseAs() { - get().as(); // type check - return Orphan(kj::mv(builder)); -} - -template -Orphan Orphan::releaseAs() { - get().as(); // type check - return Orphan(kj::mv(builder)); -} - -template -Orphan Orphan::releaseAs() { - get().as(); // type check - type = DynamicValue::UNKNOWN; - return Orphan(kj::mv(builder)); -} - -template <> -Orphan Orphan::releaseAs(); -template <> -Orphan Orphan::releaseAs(); -template <> -Orphan Orphan::releaseAs(); -template <> -Orphan Orphan::releaseAs(); - -template <> -struct Orphanage::GetInnerBuilder { - static inline _::StructBuilder apply(DynamicStruct::Builder& t) { - return t.builder; - } -}; - -template <> -struct Orphanage::GetInnerBuilder { - static inline _::ListBuilder apply(DynamicList::Builder& t) { - return t.builder; - } -}; - -template <> -inline Orphan Orphanage::newOrphanCopy( - DynamicStruct::Reader copyFrom) const { - return Orphan( - copyFrom.getSchema(), _::OrphanBuilder::copy(arena, capTable, copyFrom.reader)); -} - -template <> -inline Orphan Orphanage::newOrphanCopy( - DynamicList::Reader copyFrom) const { - return Orphan(copyFrom.getSchema(), - _::OrphanBuilder::copy(arena, capTable, copyFrom.reader)); -} - -template <> -inline Orphan Orphanage::newOrphanCopy( - DynamicCapability::Client copyFrom) const { - return Orphan( - copyFrom.getSchema(), _::OrphanBuilder::copy(arena, capTable, copyFrom.hook->addRef())); -} - -template <> -Orphan Orphanage::newOrphanCopy( - DynamicValue::Reader copyFrom) const; - -namespace _ { // private - -template <> -struct PointerHelpers { - // getDynamic() is used when an AnyPointer's get() accessor is passed arguments, because for - // non-dynamic types PointerHelpers::get() takes a default value as the third argument, and we - // don't want people to accidentally be able to provide their own default value. - static DynamicStruct::Reader getDynamic(PointerReader reader, StructSchema schema); - static DynamicStruct::Builder getDynamic(PointerBuilder builder, StructSchema schema); - static void set(PointerBuilder builder, const DynamicStruct::Reader& value); - static DynamicStruct::Builder init(PointerBuilder builder, StructSchema schema); - static inline void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan disown(PointerBuilder builder, StructSchema schema) { - return Orphan(schema, builder.disown()); - } -}; - -template <> -struct PointerHelpers { - // getDynamic() is used when an AnyPointer's get() accessor is passed arguments, because for - // non-dynamic types PointerHelpers::get() takes a default value as the third argument, and we - // don't want people to accidentally be able to provide their own default value. - static DynamicList::Reader getDynamic(PointerReader reader, ListSchema schema); - static DynamicList::Builder getDynamic(PointerBuilder builder, ListSchema schema); - static void set(PointerBuilder builder, const DynamicList::Reader& value); - static DynamicList::Builder init(PointerBuilder builder, ListSchema schema, uint size); - static inline void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan disown(PointerBuilder builder, ListSchema schema) { - return Orphan(schema, builder.disown()); - } -}; - -template <> -struct PointerHelpers { - // getDynamic() is used when an AnyPointer's get() accessor is passed arguments, because for - // non-dynamic types PointerHelpers::get() takes a default value as the third argument, and we - // don't want people to accidentally be able to provide their own default value. - static DynamicCapability::Client getDynamic(PointerReader reader, InterfaceSchema schema); - static DynamicCapability::Client getDynamic(PointerBuilder builder, InterfaceSchema schema); - static void set(PointerBuilder builder, DynamicCapability::Client& value); - static void set(PointerBuilder builder, DynamicCapability::Client&& value); - static inline void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan disown(PointerBuilder builder, InterfaceSchema schema) { - return Orphan(schema, builder.disown()); - } -}; - -} // namespace _ (private) - -template -inline ReaderFor AnyPointer::Reader::getAs(StructSchema schema) const { - return _::PointerHelpers::getDynamic(reader, schema); -} -template -inline ReaderFor AnyPointer::Reader::getAs(ListSchema schema) const { - return _::PointerHelpers::getDynamic(reader, schema); -} -template -inline ReaderFor AnyPointer::Reader::getAs(InterfaceSchema schema) const { - return _::PointerHelpers::getDynamic(reader, schema); -} -template -inline BuilderFor AnyPointer::Builder::getAs(StructSchema schema) { - return _::PointerHelpers::getDynamic(builder, schema); -} -template -inline BuilderFor AnyPointer::Builder::getAs(ListSchema schema) { - return _::PointerHelpers::getDynamic(builder, schema); -} -template -inline BuilderFor AnyPointer::Builder::getAs(InterfaceSchema schema) { - return _::PointerHelpers::getDynamic(builder, schema); -} -template -inline BuilderFor AnyPointer::Builder::initAs(StructSchema schema) { - return _::PointerHelpers::init(builder, schema); -} -template -inline BuilderFor AnyPointer::Builder::initAs(ListSchema schema, uint elementCount) { - return _::PointerHelpers::init(builder, schema, elementCount); -} -template <> -inline void AnyPointer::Builder::setAs(DynamicStruct::Reader value) { - return _::PointerHelpers::set(builder, value); -} -template <> -inline void AnyPointer::Builder::setAs(DynamicList::Reader value) { - return _::PointerHelpers::set(builder, value); -} -template <> -inline void AnyPointer::Builder::setAs(DynamicCapability::Client value) { - return _::PointerHelpers::set(builder, kj::mv(value)); -} -template <> -void AnyPointer::Builder::adopt(Orphan&& orphan); -template -inline Orphan AnyPointer::Builder::disownAs(StructSchema schema) { - return _::PointerHelpers::disown(builder, schema); -} -template -inline Orphan AnyPointer::Builder::disownAs(ListSchema schema) { - return _::PointerHelpers::disown(builder, schema); -} -template -inline Orphan AnyPointer::Builder::disownAs(InterfaceSchema schema) { - return _::PointerHelpers::disown(builder, schema); -} - -// We have to declare the methods below inline because Clang and GCC disagree about how to mangle -// their symbol names. -template <> -inline DynamicStruct::Builder Orphan::getAs(StructSchema schema) { - return DynamicStruct::Builder(schema, builder); -} -template <> -inline DynamicStruct::Reader Orphan::getAsReader( - StructSchema schema) const { - return DynamicStruct::Reader(schema, builder); -} -template <> -inline Orphan Orphan::releaseAs(StructSchema schema) { - return Orphan(schema, kj::mv(builder)); -} -template <> -inline DynamicList::Builder Orphan::getAs(ListSchema schema) { - return DynamicList::Builder(schema, builder); -} -template <> -inline DynamicList::Reader Orphan::getAsReader(ListSchema schema) const { - return DynamicList::Reader(schema, builder); -} -template <> -inline Orphan Orphan::releaseAs(ListSchema schema) { - return Orphan(schema, kj::mv(builder)); -} -template <> -inline DynamicCapability::Client Orphan::getAs( - InterfaceSchema schema) { - return DynamicCapability::Client(schema, builder.asCapability()); -} -template <> -inline DynamicCapability::Client Orphan::getAsReader( - InterfaceSchema schema) const { - return DynamicCapability::Client(schema, builder.asCapability()); -} -template <> -inline Orphan Orphan::releaseAs( - InterfaceSchema schema) { - return Orphan(schema, kj::mv(builder)); -} - -// ======================================================================================= -// Inline implementation details. - -template -struct ToDynamic_ { - static inline DynamicStruct::Reader apply(const typename T::Reader& value) { - return DynamicStruct::Reader(Schema::from(), value._reader); - } - static inline DynamicStruct::Builder apply(typename T::Builder& value) { - return DynamicStruct::Builder(Schema::from(), value._builder); - } -}; - -template -struct ToDynamic_ { - static inline DynamicList::Reader apply(const typename T::Reader& value) { - return DynamicList::Reader(Schema::from(), value.reader); - } - static inline DynamicList::Builder apply(typename T::Builder& value) { - return DynamicList::Builder(Schema::from(), value.builder); - } -}; - -template -struct ToDynamic_ { - static inline DynamicCapability::Client apply(typename T::Client value) { - return DynamicCapability::Client(kj::mv(value)); - } - static inline DynamicCapability::Client apply(typename T::Client&& value) { - return DynamicCapability::Client(kj::mv(value)); - } -}; - -template -ReaderFor>> toDynamic(T&& value) { - return ToDynamic_>::apply(value); -} -template -BuilderFor>> toDynamic(T&& value) { - return ToDynamic_>::apply(value); -} -template -DynamicTypeFor> toDynamic(T&& value) { - return DynamicEnum(Schema::from>(), static_cast(value)); -} -template -typename DynamicTypeFor>::Client toDynamic(kj::Own&& value) { - return typename FromServer::Client(kj::mv(value)); -} - -inline DynamicValue::Reader::Reader(std::nullptr_t n): type(UNKNOWN) {} -inline DynamicValue::Builder::Builder(std::nullptr_t n): type(UNKNOWN) {} - -#define CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(cppType, typeTag, fieldName) \ -inline DynamicValue::Reader::Reader(cppType value) \ - : type(typeTag), fieldName##Value(value) {} \ -inline DynamicValue::Builder::Builder(cppType value) \ - : type(typeTag), fieldName##Value(value) {} \ -inline Orphan::Orphan(cppType value) \ - : type(DynamicValue::typeTag), fieldName##Value(value) {} - -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Void, VOID, void); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(bool, BOOL, bool); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(char, INT, int); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(signed char, INT, int); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(short, INT, int); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(int, INT, int); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(long, INT, int); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(long long, INT, int); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned char, UINT, uint); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned short, UINT, uint); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned int, UINT, uint); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned long, UINT, uint); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(unsigned long long, UINT, uint); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(float, FLOAT, float); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(double, FLOAT, float); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(DynamicEnum, ENUM, enum); -#undef CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR - -#define CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(cppType, typeTag, fieldName) \ -inline DynamicValue::Reader::Reader(const cppType::Reader& value) \ - : type(typeTag), fieldName##Value(value) {} \ -inline DynamicValue::Builder::Builder(cppType::Builder value) \ - : type(typeTag), fieldName##Value(value) {} - -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Text, TEXT, text); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(Data, DATA, data); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(DynamicList, LIST, list); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(DynamicStruct, STRUCT, struct); -CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(AnyPointer, ANY_POINTER, anyPointer); - -#undef CAPNP_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR - -inline DynamicValue::Reader::Reader(DynamicCapability::Client& value) - : type(CAPABILITY), capabilityValue(value) {} -inline DynamicValue::Reader::Reader(DynamicCapability::Client&& value) - : type(CAPABILITY), capabilityValue(kj::mv(value)) {} -template -inline DynamicValue::Reader::Reader(kj::Own&& value) - : type(CAPABILITY), capabilityValue(kj::mv(value)) {} -inline DynamicValue::Builder::Builder(DynamicCapability::Client& value) - : type(CAPABILITY), capabilityValue(value) {} -inline DynamicValue::Builder::Builder(DynamicCapability::Client&& value) - : type(CAPABILITY), capabilityValue(kj::mv(value)) {} - -inline DynamicValue::Reader::Reader(const char* value): Reader(Text::Reader(value)) {} - -#define CAPNP_DECLARE_TYPE(discrim, typeName) \ -template <> \ -struct DynamicValue::Reader::AsImpl { \ - static ReaderFor apply(const Reader& reader); \ -}; \ -template <> \ -struct DynamicValue::Builder::AsImpl { \ - static BuilderFor apply(Builder& builder); \ -}; - -//CAPNP_DECLARE_TYPE(VOID, Void) -CAPNP_DECLARE_TYPE(BOOL, bool) -CAPNP_DECLARE_TYPE(INT8, int8_t) -CAPNP_DECLARE_TYPE(INT16, int16_t) -CAPNP_DECLARE_TYPE(INT32, int32_t) -CAPNP_DECLARE_TYPE(INT64, int64_t) -CAPNP_DECLARE_TYPE(UINT8, uint8_t) -CAPNP_DECLARE_TYPE(UINT16, uint16_t) -CAPNP_DECLARE_TYPE(UINT32, uint32_t) -CAPNP_DECLARE_TYPE(UINT64, uint64_t) -CAPNP_DECLARE_TYPE(FLOAT32, float) -CAPNP_DECLARE_TYPE(FLOAT64, double) - -CAPNP_DECLARE_TYPE(TEXT, Text) -CAPNP_DECLARE_TYPE(DATA, Data) -CAPNP_DECLARE_TYPE(LIST, DynamicList) -CAPNP_DECLARE_TYPE(STRUCT, DynamicStruct) -CAPNP_DECLARE_TYPE(INTERFACE, DynamicCapability) -CAPNP_DECLARE_TYPE(ENUM, DynamicEnum) -CAPNP_DECLARE_TYPE(ANY_POINTER, AnyPointer) -#undef CAPNP_DECLARE_TYPE - -// CAPNP_DECLARE_TYPE(Void) causes gcc 4.7 to segfault. If I do it manually and remove the -// ReaderFor<> and BuilderFor<> wrappers, it works. -template <> -struct DynamicValue::Reader::AsImpl { - static Void apply(const Reader& reader); -}; -template <> -struct DynamicValue::Builder::AsImpl { - static Void apply(Builder& builder); -}; - -template -struct DynamicValue::Reader::AsImpl { - static T apply(const Reader& reader) { - return reader.as().as(); - } -}; -template -struct DynamicValue::Builder::AsImpl { - static T apply(Builder& builder) { - return builder.as().as(); - } -}; - -template -struct DynamicValue::Reader::AsImpl { - static typename T::Reader apply(const Reader& reader) { - return reader.as().as(); - } -}; -template -struct DynamicValue::Builder::AsImpl { - static typename T::Builder apply(Builder& builder) { - return builder.as().as(); - } -}; - -template -struct DynamicValue::Reader::AsImpl { - static typename T::Reader apply(const Reader& reader) { - return reader.as().as(); - } -}; -template -struct DynamicValue::Builder::AsImpl { - static typename T::Builder apply(Builder& builder) { - return builder.as().as(); - } -}; - -template -struct DynamicValue::Reader::AsImpl { - static typename T::Client apply(const Reader& reader) { - return reader.as().as(); - } -}; -template -struct DynamicValue::Builder::AsImpl { - static typename T::Client apply(Builder& builder) { - return builder.as().as(); - } -}; - -template <> -struct DynamicValue::Reader::AsImpl { - static DynamicValue::Reader apply(const Reader& reader) { - return reader; - } -}; -template <> -struct DynamicValue::Builder::AsImpl { - static DynamicValue::Builder apply(Builder& builder) { - return builder; - } -}; - -inline DynamicValue::Pipeline::Pipeline(std::nullptr_t n): type(UNKNOWN) {} -inline DynamicValue::Pipeline::Pipeline(DynamicStruct::Pipeline&& value) - : type(STRUCT), structValue(kj::mv(value)) {} -inline DynamicValue::Pipeline::Pipeline(DynamicCapability::Client&& value) - : type(CAPABILITY), capabilityValue(kj::mv(value)) {} - -template -struct DynamicValue::Pipeline::AsImpl { - static typename T::Pipeline apply(Pipeline& pipeline) { - return pipeline.releaseAs().releaseAs(); - } -}; -template -struct DynamicValue::Pipeline::AsImpl { - static typename T::Client apply(Pipeline& pipeline) { - return pipeline.releaseAs().releaseAs(); - } -}; -template <> -struct DynamicValue::Pipeline::AsImpl { - static PipelineFor apply(Pipeline& pipeline); -}; -template <> -struct DynamicValue::Pipeline::AsImpl { - static PipelineFor apply(Pipeline& pipeline); -}; - -// ------------------------------------------------------------------- - -template -typename T::Reader DynamicStruct::Reader::as() const { - static_assert(kind() == Kind::STRUCT, - "DynamicStruct::Reader::as() can only convert to struct types."); - schema.requireUsableAs(); - return typename T::Reader(reader); -} - -template -typename T::Builder DynamicStruct::Builder::as() { - static_assert(kind() == Kind::STRUCT, - "DynamicStruct::Builder::as() can only convert to struct types."); - schema.requireUsableAs(); - return typename T::Builder(builder); -} - -template <> -inline DynamicStruct::Reader DynamicStruct::Reader::as() const { - return *this; -} -template <> -inline DynamicStruct::Builder DynamicStruct::Builder::as() { - return *this; -} - -inline DynamicStruct::Reader DynamicStruct::Builder::asReader() const { - return DynamicStruct::Reader(schema, builder.asReader()); -} - -template <> -inline AnyStruct::Reader DynamicStruct::Reader::as() const { - return AnyStruct::Reader(reader); -} - -template <> -inline AnyStruct::Builder DynamicStruct::Builder::as() { - return AnyStruct::Builder(builder); -} - -template -typename T::Pipeline DynamicStruct::Pipeline::releaseAs() { - static_assert(kind() == Kind::STRUCT, - "DynamicStruct::Pipeline::releaseAs() can only convert to struct types."); - schema.requireUsableAs(); - return typename T::Pipeline(kj::mv(typeless)); -} - -// ------------------------------------------------------------------- - -template -typename T::Reader DynamicList::Reader::as() const { - static_assert(kind() == Kind::LIST, - "DynamicStruct::Reader::as() can only convert to list types."); - schema.requireUsableAs(); - return typename T::Reader(reader); -} -template -typename T::Builder DynamicList::Builder::as() { - static_assert(kind() == Kind::LIST, - "DynamicStruct::Builder::as() can only convert to list types."); - schema.requireUsableAs(); - return typename T::Builder(builder); -} - -template <> -inline DynamicList::Reader DynamicList::Reader::as() const { - return *this; -} -template <> -inline DynamicList::Builder DynamicList::Builder::as() { - return *this; -} - -template <> -inline AnyList::Reader DynamicList::Reader::as() const { - return AnyList::Reader(reader); -} - -template <> -inline AnyList::Builder DynamicList::Builder::as() { - return AnyList::Builder(builder); -} - -// ------------------------------------------------------------------- - -template -inline DynamicCapability::Client::Client(T&& client) - : Capability::Client(kj::mv(client)), schema(Schema::from>()) {} - -template -inline DynamicCapability::Client::Client(kj::Own&& server) - : Client(server->getSchema(), kj::mv(server)) {} -template -inline DynamicCapability::Client::Client(InterfaceSchema schema, kj::Own&& server) - : Capability::Client(kj::mv(server)), schema(schema) {} - -template -typename T::Client DynamicCapability::Client::as() { - static_assert(kind() == Kind::INTERFACE, - "DynamicCapability::Client::as() can only convert to interface types."); - schema.requireUsableAs(); - return typename T::Client(hook->addRef()); -} - -template -typename T::Client DynamicCapability::Client::releaseAs() { - static_assert(kind() == Kind::INTERFACE, - "DynamicCapability::Client::as() can only convert to interface types."); - schema.requireUsableAs(); - return typename T::Client(kj::mv(hook)); -} - -inline CallContext::CallContext( - CallContextHook& hook, StructSchema paramType, StructSchema resultType) - : hook(&hook), paramType(paramType), resultType(resultType) {} -inline DynamicStruct::Reader CallContext::getParams() { - return hook->getParams().getAs(paramType); -} -inline void CallContext::releaseParams() { - hook->releaseParams(); -} -inline DynamicStruct::Builder CallContext::getResults( - kj::Maybe sizeHint) { - return hook->getResults(sizeHint).getAs(resultType); -} -inline DynamicStruct::Builder CallContext::initResults( - kj::Maybe sizeHint) { - return hook->getResults(sizeHint).initAs(resultType); -} -inline void CallContext::setResults(DynamicStruct::Reader value) { - hook->getResults(value.totalSize()).setAs(value); -} -inline void CallContext::adoptResults(Orphan&& value) { - hook->getResults(MessageSize { 0, 0 }).adopt(kj::mv(value)); -} -inline Orphanage CallContext::getResultsOrphanage( - kj::Maybe sizeHint) { - return Orphanage::getForMessageContaining(hook->getResults(sizeHint)); -} -template -inline kj::Promise CallContext::tailCall( - Request&& tailRequest) { - return hook->tailCall(kj::mv(tailRequest.hook)); -} -inline void CallContext::allowCancellation() { - hook->allowCancellation(); -} - -template <> -inline DynamicCapability::Client Capability::Client::castAs( - InterfaceSchema schema) { - return DynamicCapability::Client(schema, hook->addRef()); -} - -// ------------------------------------------------------------------- - -template -ReaderFor ConstSchema::as() const { - return DynamicValue::Reader(*this).as(); -} - -} // namespace capnp - -#endif // CAPNP_DYNAMIC_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/endian.h b/phonelibs/capnp-cpp/include/capnp/endian.h deleted file mode 100644 index c5a6e63c5a9584..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/endian.h +++ /dev/null @@ -1,309 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_ENDIAN_H_ -#define CAPNP_ENDIAN_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "common.h" -#include -#include // memcpy - -namespace capnp { -namespace _ { // private - -// WireValue -// -// Wraps a primitive value as it appears on the wire. Namely, values are little-endian on the -// wire, because little-endian is the most common endianness in modern CPUs. -// -// Note: In general, code that depends cares about byte ordering is bad. See: -// http://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html -// Cap'n Proto is special because it is essentially doing compiler-like things, fussing over -// allocation and layout of memory, in order to squeeze out every last drop of performance. - -#if _MSC_VER -// Assume Windows is little-endian. -// -// TODO(msvc): This is ugly. Maybe refactor later checks to be based on CAPNP_BYTE_ORDER or -// CAPNP_SWAP_BYTES or something, and define that in turn based on _MSC_VER or the GCC -// intrinsics. - -#ifndef __ORDER_BIG_ENDIAN__ -#define __ORDER_BIG_ENDIAN__ 4321 -#endif -#ifndef __ORDER_LITTLE_ENDIAN__ -#define __ORDER_LITTLE_ENDIAN__ 1234 -#endif -#ifndef __BYTE_ORDER__ -#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ -#endif -#endif - -#if CAPNP_REVERSE_ENDIAN -#define CAPNP_WIRE_BYTE_ORDER __ORDER_BIG_ENDIAN__ -#define CAPNP_OPPOSITE_OF_WIRE_BYTE_ORDER __ORDER_LITTLE_ENDIAN__ -#else -#define CAPNP_WIRE_BYTE_ORDER __ORDER_LITTLE_ENDIAN__ -#define CAPNP_OPPOSITE_OF_WIRE_BYTE_ORDER __ORDER_BIG_ENDIAN__ -#endif - -#if defined(__BYTE_ORDER__) && \ - __BYTE_ORDER__ == CAPNP_WIRE_BYTE_ORDER && \ - !CAPNP_DISABLE_ENDIAN_DETECTION -// CPU is little-endian. We can just read/write the memory directly. - -template -class DirectWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { return value; } - KJ_ALWAYS_INLINE(void set(T newValue)) { value = newValue; } - -private: - T value; -}; - -template -using WireValue = DirectWireValue; -// To prevent ODR problems when endian-test, endian-reverse-test, and endian-fallback-test are -// linked together, we define each implementation with a different name and define an alias to the -// one we want to use. - -#elif defined(__BYTE_ORDER__) && \ - __BYTE_ORDER__ == CAPNP_OPPOSITE_OF_WIRE_BYTE_ORDER && \ - defined(__GNUC__) && !CAPNP_DISABLE_ENDIAN_DETECTION -// Big-endian, but GCC's __builtin_bswap() is available. - -// TODO(perf): Use dedicated instructions to read little-endian data on big-endian CPUs that have -// them. - -// TODO(perf): Verify that this code optimizes reasonably. In particular, ensure that the -// compiler optimizes away the memcpy()s and keeps everything in registers. - -template -class SwappingWireValue; - -template -class SwappingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { return value; } - KJ_ALWAYS_INLINE(void set(T newValue)) { value = newValue; } - -private: - T value; -}; - -template -class SwappingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { - // Not all platforms have __builtin_bswap16() for some reason. In particular, it is missing - // on gcc-4.7.3-cygwin32 (but present on gcc-4.8.1-cygwin64). - uint16_t swapped = (value << 8) | (value >> 8); - T result; - memcpy(&result, &swapped, sizeof(T)); - return result; - } - KJ_ALWAYS_INLINE(void set(T newValue)) { - uint16_t raw; - memcpy(&raw, &newValue, sizeof(T)); - // Not all platforms have __builtin_bswap16() for some reason. In particular, it is missing - // on gcc-4.7.3-cygwin32 (but present on gcc-4.8.1-cygwin64). - value = (raw << 8) | (raw >> 8); - } - -private: - uint16_t value; -}; - -template -class SwappingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { - uint32_t swapped = __builtin_bswap32(value); - T result; - memcpy(&result, &swapped, sizeof(T)); - return result; - } - KJ_ALWAYS_INLINE(void set(T newValue)) { - uint32_t raw; - memcpy(&raw, &newValue, sizeof(T)); - value = __builtin_bswap32(raw); - } - -private: - uint32_t value; -}; - -template -class SwappingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { - uint64_t swapped = __builtin_bswap64(value); - T result; - memcpy(&result, &swapped, sizeof(T)); - return result; - } - KJ_ALWAYS_INLINE(void set(T newValue)) { - uint64_t raw; - memcpy(&raw, &newValue, sizeof(T)); - value = __builtin_bswap64(raw); - } - -private: - uint64_t value; -}; - -template -using WireValue = SwappingWireValue; -// To prevent ODR problems when endian-test, endian-reverse-test, and endian-fallback-test are -// linked together, we define each implementation with a different name and define an alias to the -// one we want to use. - -#else -// Unknown endianness. Fall back to bit shifts. - -#if !CAPNP_DISABLE_ENDIAN_DETECTION -#if _MSC_VER -#pragma message("Couldn't detect endianness of your platform. Using unoptimized fallback implementation.") -#pragma message("Consider changing this code to detect your platform and send us a patch!") -#else -#warning "Couldn't detect endianness of your platform. Using unoptimized fallback implementation." -#warning "Consider changing this code to detect your platform and send us a patch!" -#endif -#endif // !CAPNP_DISABLE_ENDIAN_DETECTION - -template -class ShiftingWireValue; - -template -class ShiftingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { return value; } - KJ_ALWAYS_INLINE(void set(T newValue)) { value = newValue; } - -private: - T value; -}; - -template -class ShiftingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { - uint16_t raw = (static_cast(bytes[0]) ) | - (static_cast(bytes[1]) << 8); - T result; - memcpy(&result, &raw, sizeof(T)); - return result; - } - KJ_ALWAYS_INLINE(void set(T newValue)) { - uint16_t raw; - memcpy(&raw, &newValue, sizeof(T)); - bytes[0] = raw; - bytes[1] = raw >> 8; - } - -private: - union { - byte bytes[2]; - uint16_t align; - }; -}; - -template -class ShiftingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { - uint32_t raw = (static_cast(bytes[0]) ) | - (static_cast(bytes[1]) << 8) | - (static_cast(bytes[2]) << 16) | - (static_cast(bytes[3]) << 24); - T result; - memcpy(&result, &raw, sizeof(T)); - return result; - } - KJ_ALWAYS_INLINE(void set(T newValue)) { - uint32_t raw; - memcpy(&raw, &newValue, sizeof(T)); - bytes[0] = raw; - bytes[1] = raw >> 8; - bytes[2] = raw >> 16; - bytes[3] = raw >> 24; - } - -private: - union { - byte bytes[4]; - uint32_t align; - }; -}; - -template -class ShiftingWireValue { -public: - KJ_ALWAYS_INLINE(T get() const) { - uint64_t raw = (static_cast(bytes[0]) ) | - (static_cast(bytes[1]) << 8) | - (static_cast(bytes[2]) << 16) | - (static_cast(bytes[3]) << 24) | - (static_cast(bytes[4]) << 32) | - (static_cast(bytes[5]) << 40) | - (static_cast(bytes[6]) << 48) | - (static_cast(bytes[7]) << 56); - T result; - memcpy(&result, &raw, sizeof(T)); - return result; - } - KJ_ALWAYS_INLINE(void set(T newValue)) { - uint64_t raw; - memcpy(&raw, &newValue, sizeof(T)); - bytes[0] = raw; - bytes[1] = raw >> 8; - bytes[2] = raw >> 16; - bytes[3] = raw >> 24; - bytes[4] = raw >> 32; - bytes[5] = raw >> 40; - bytes[6] = raw >> 48; - bytes[7] = raw >> 56; - } - -private: - union { - byte bytes[8]; - uint64_t align; - }; -}; - -template -using WireValue = ShiftingWireValue; -// To prevent ODR problems when endian-test, endian-reverse-test, and endian-fallback-test are -// linked together, we define each implementation with a different name and define an alias to the -// one we want to use. - -#endif - -} // namespace _ (private) -} // namespace capnp - -#endif // CAPNP_ENDIAN_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/ez-rpc.h b/phonelibs/capnp-cpp/include/capnp/ez-rpc.h deleted file mode 100644 index fba5ace5820255..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/ez-rpc.h +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_EZ_RPC_H_ -#define CAPNP_EZ_RPC_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "rpc.h" -#include "message.h" - -struct sockaddr; - -namespace kj { class AsyncIoProvider; class LowLevelAsyncIoProvider; } - -namespace capnp { - -class EzRpcContext; - -class EzRpcClient { - // Super-simple interface for setting up a Cap'n Proto RPC client. Example: - // - // # Cap'n Proto schema - // interface Adder { - // add @0 (left :Int32, right :Int32) -> (value :Int32); - // } - // - // // C++ client - // int main() { - // capnp::EzRpcClient client("localhost:3456"); - // Adder::Client adder = client.getMain(); - // auto request = adder.addRequest(); - // request.setLeft(12); - // request.setRight(34); - // auto response = request.send().wait(client.getWaitScope()); - // assert(response.getValue() == 46); - // return 0; - // } - // - // // C++ server - // class AdderImpl final: public Adder::Server { - // public: - // kj::Promise add(AddContext context) override { - // auto params = context.getParams(); - // context.getResults().setValue(params.getLeft() + params.getRight()); - // return kj::READY_NOW; - // } - // }; - // - // int main() { - // capnp::EzRpcServer server(kj::heap(), "*:3456"); - // kj::NEVER_DONE.wait(server.getWaitScope()); - // } - // - // This interface is easy, but it hides a lot of useful features available from the lower-level - // classes: - // - The server can only export a small set of public, singleton capabilities under well-known - // string names. This is fine for transient services where no state needs to be kept between - // connections, but hides the power of Cap'n Proto when it comes to long-lived resources. - // - EzRpcClient/EzRpcServer automatically set up a `kj::EventLoop` and make it current for the - // thread. Only one `kj::EventLoop` can exist per thread, so you cannot use these interfaces - // if you wish to set up your own event loop. (However, you can safely create multiple - // EzRpcClient / EzRpcServer objects in a single thread; they will make sure to make no more - // than one EventLoop.) - // - These classes only support simple two-party connections, not multilateral VatNetworks. - // - These classes only support communication over a raw, unencrypted socket. If you want to - // build on an abstract stream (perhaps one which supports encryption), you must use the - // lower-level interfaces. - // - // Some of these restrictions will probably be lifted in future versions, but some things will - // always require using the low-level interfaces directly. If you are interested in working - // at a lower level, start by looking at these interfaces: - // - `kj::setupAsyncIo()` in `kj/async-io.h`. - // - `RpcSystem` in `capnp/rpc.h`. - // - `TwoPartyVatNetwork` in `capnp/rpc-twoparty.h`. - -public: - explicit EzRpcClient(kj::StringPtr serverAddress, uint defaultPort = 0, - ReaderOptions readerOpts = ReaderOptions()); - // Construct a new EzRpcClient and connect to the given address. The connection is formed in - // the background -- if it fails, calls to capabilities returned by importCap() will fail with an - // appropriate exception. - // - // `defaultPort` is the IP port number to use if `serverAddress` does not include it explicitly. - // If unspecified, the port is required in `serverAddress`. - // - // The address is parsed by `kj::Network` in `kj/async-io.h`. See that interface for more info - // on the address format, but basically it's what you'd expect. - // - // `readerOpts` is the ReaderOptions structure used to read each incoming message on the - // connection. Setting this may be necessary if you need to receive very large individual - // messages or messages. However, it is recommended that you instead think about how to change - // your protocol to send large data blobs in multiple small chunks -- this is much better for - // both security and performance. See `ReaderOptions` in `message.h` for more details. - - EzRpcClient(const struct sockaddr* serverAddress, uint addrSize, - ReaderOptions readerOpts = ReaderOptions()); - // Like the above constructor, but connects to an already-resolved socket address. Any address - // format supported by `kj::Network` in `kj/async-io.h` is accepted. - - explicit EzRpcClient(int socketFd, ReaderOptions readerOpts = ReaderOptions()); - // Create a client on top of an already-connected socket. - // `readerOpts` acts as in the first constructor. - - ~EzRpcClient() noexcept(false); - - template - typename Type::Client getMain(); - Capability::Client getMain(); - // Get the server's main (aka "bootstrap") interface. - - template - typename Type::Client importCap(kj::StringPtr name) - KJ_DEPRECATED("Change your server to export a main interface, then use getMain() instead."); - Capability::Client importCap(kj::StringPtr name) - KJ_DEPRECATED("Change your server to export a main interface, then use getMain() instead."); - // ** DEPRECATED ** - // - // Ask the sever for the capability with the given name. You may specify a type to automatically - // down-cast to that type. It is up to you to specify the correct expected type. - // - // Named interfaces are deprecated. The new preferred usage pattern is for the server to export - // a "main" interface which itself has methods for getting any other interfaces. - - kj::WaitScope& getWaitScope(); - // Get the `WaitScope` for the client's `EventLoop`, which allows you to synchronously wait on - // promises. - - kj::AsyncIoProvider& getIoProvider(); - // Get the underlying AsyncIoProvider set up by the RPC system. This is useful if you want - // to do some non-RPC I/O in asynchronous fashion. - - kj::LowLevelAsyncIoProvider& getLowLevelIoProvider(); - // Get the underlying LowLevelAsyncIoProvider set up by the RPC system. This is useful if you - // want to do some non-RPC I/O in asynchronous fashion. - -private: - struct Impl; - kj::Own impl; -}; - -class EzRpcServer { - // The server counterpart to `EzRpcClient`. See `EzRpcClient` for an example. - -public: - explicit EzRpcServer(Capability::Client mainInterface, kj::StringPtr bindAddress, - uint defaultPort = 0, ReaderOptions readerOpts = ReaderOptions()); - // Construct a new `EzRpcServer` that binds to the given address. An address of "*" means to - // bind to all local addresses. - // - // `defaultPort` is the IP port number to use if `serverAddress` does not include it explicitly. - // If unspecified, a port is chosen automatically, and you must call getPort() to find out what - // it is. - // - // The address is parsed by `kj::Network` in `kj/async-io.h`. See that interface for more info - // on the address format, but basically it's what you'd expect. - // - // The server might not begin listening immediately, especially if `bindAddress` needs to be - // resolved. If you need to wait until the server is definitely up, wait on the promise returned - // by `getPort()`. - // - // `readerOpts` is the ReaderOptions structure used to read each incoming message on the - // connection. Setting this may be necessary if you need to receive very large individual - // messages or messages. However, it is recommended that you instead think about how to change - // your protocol to send large data blobs in multiple small chunks -- this is much better for - // both security and performance. See `ReaderOptions` in `message.h` for more details. - - EzRpcServer(Capability::Client mainInterface, struct sockaddr* bindAddress, uint addrSize, - ReaderOptions readerOpts = ReaderOptions()); - // Like the above constructor, but binds to an already-resolved socket address. Any address - // format supported by `kj::Network` in `kj/async-io.h` is accepted. - - EzRpcServer(Capability::Client mainInterface, int socketFd, uint port, - ReaderOptions readerOpts = ReaderOptions()); - // Create a server on top of an already-listening socket (i.e. one on which accept() may be - // called). `port` is returned by `getPort()` -- it serves no other purpose. - // `readerOpts` acts as in the other two above constructors. - - explicit EzRpcServer(kj::StringPtr bindAddress, uint defaultPort = 0, - ReaderOptions readerOpts = ReaderOptions()) - KJ_DEPRECATED("Please specify a main interface for your server."); - EzRpcServer(struct sockaddr* bindAddress, uint addrSize, - ReaderOptions readerOpts = ReaderOptions()) - KJ_DEPRECATED("Please specify a main interface for your server."); - EzRpcServer(int socketFd, uint port, ReaderOptions readerOpts = ReaderOptions()) - KJ_DEPRECATED("Please specify a main interface for your server."); - - ~EzRpcServer() noexcept(false); - - void exportCap(kj::StringPtr name, Capability::Client cap); - // Export a capability publicly under the given name, so that clients can import it. - // - // Keep in mind that you can implicitly convert `kj::Own&&` to - // `Capability::Client`, so it's typical to pass something like - // `kj::heap()` as the second parameter. - - kj::Promise getPort(); - // Get the IP port number on which this server is listening. This promise won't resolve until - // the server is actually listening. If the address was not an IP address (e.g. it was a Unix - // domain socket) then getPort() resolves to zero. - - kj::WaitScope& getWaitScope(); - // Get the `WaitScope` for the client's `EventLoop`, which allows you to synchronously wait on - // promises. - - kj::AsyncIoProvider& getIoProvider(); - // Get the underlying AsyncIoProvider set up by the RPC system. This is useful if you want - // to do some non-RPC I/O in asynchronous fashion. - - kj::LowLevelAsyncIoProvider& getLowLevelIoProvider(); - // Get the underlying LowLevelAsyncIoProvider set up by the RPC system. This is useful if you - // want to do some non-RPC I/O in asynchronous fashion. - -private: - struct Impl; - kj::Own impl; -}; - -// ======================================================================================= -// inline implementation details - -template -inline typename Type::Client EzRpcClient::getMain() { - return getMain().castAs(); -} - -template -inline typename Type::Client EzRpcClient::importCap(kj::StringPtr name) { - return importCap(name).castAs(); -} - -} // namespace capnp - -#endif // CAPNP_EZ_RPC_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/generated-header-support.h b/phonelibs/capnp-cpp/include/capnp/generated-header-support.h deleted file mode 100644 index 51b6dd7c113c63..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/generated-header-support.h +++ /dev/null @@ -1,407 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -// This file is included from all generated headers. - -#ifndef CAPNP_GENERATED_HEADER_SUPPORT_H_ -#define CAPNP_GENERATED_HEADER_SUPPORT_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "raw-schema.h" -#include "layout.h" -#include "list.h" -#include "orphan.h" -#include "pointer-helpers.h" -#include "any.h" -#include -#include - -namespace capnp { - -class MessageBuilder; // So that it can be declared a friend. - -template -struct ToDynamic_; // Defined in dynamic.h, needs to be declared as everyone's friend. - -struct DynamicStruct; // So that it can be declared a friend. - -struct Capability; // To declare brandBindingFor() - -namespace _ { // private - -#if !CAPNP_LITE - -template -inline const RawSchema& rawSchema() { - return *CapnpPrivate::schema; -} -template ::typeId> -inline const RawSchema& rawSchema() { - return *schemas::EnumInfo::schema; -} - -template -inline const RawBrandedSchema& rawBrandedSchema() { - return *CapnpPrivate::brand(); -} -template ::typeId> -inline const RawBrandedSchema& rawBrandedSchema() { - return schemas::EnumInfo::schema->defaultBrand; -} - -template -struct ChooseBrand; -// If all of `Params` are `AnyPointer`, return the type's default brand. Otherwise, return a -// specific brand instance. TypeTag is the _capnpPrivate struct for the type in question. - -template -struct ChooseBrand { - // All params were AnyPointer. No specific brand needed. - static constexpr _::RawBrandedSchema const* brand() { return &TypeTag::schema->defaultBrand; } -}; - -template -struct ChooseBrand: public ChooseBrand {}; -// The first parameter is AnyPointer, so recurse to check the rest. - -template -struct ChooseBrand { - // At least one parameter is not AnyPointer, so use the specificBrand constant. - static constexpr _::RawBrandedSchema const* brand() { return &TypeTag::specificBrand; } -}; - -template ()> -struct BrandBindingFor_; - -#define HANDLE_TYPE(Type, which) \ - template <> \ - struct BrandBindingFor_ { \ - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { \ - return { which, listDepth, nullptr }; \ - } \ - } -HANDLE_TYPE(Void, 0); -HANDLE_TYPE(bool, 1); -HANDLE_TYPE(int8_t, 2); -HANDLE_TYPE(int16_t, 3); -HANDLE_TYPE(int32_t, 4); -HANDLE_TYPE(int64_t, 5); -HANDLE_TYPE(uint8_t, 6); -HANDLE_TYPE(uint16_t, 7); -HANDLE_TYPE(uint32_t, 8); -HANDLE_TYPE(uint64_t, 9); -HANDLE_TYPE(float, 10); -HANDLE_TYPE(double, 11); -#undef HANDLE_TYPE - -template <> -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 12, listDepth, nullptr }; - } -}; - -template <> -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 13, listDepth, nullptr }; - } -}; - -template -struct BrandBindingFor_, Kind::LIST> { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return BrandBindingFor_::get(listDepth + 1); - } -}; - -template -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 15, listDepth, nullptr }; - } -}; - -template -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 16, listDepth, T::_capnpPrivate::brand() }; - } -}; - -template -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 17, listDepth, T::_capnpPrivate::brand() }; - } -}; - -template <> -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 18, listDepth, 0, 0 }; - } -}; - -template <> -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 18, listDepth, 0, 1 }; - } -}; - -template <> -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 18, listDepth, 0, 2 }; - } -}; - -template <> -struct BrandBindingFor_ { - static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { - return { 18, listDepth, 0, 3 }; - } -}; - -template -constexpr RawBrandedSchema::Binding brandBindingFor() { - return BrandBindingFor_::get(0); -} - -kj::StringTree structString(StructReader reader, const RawBrandedSchema& schema); -kj::String enumString(uint16_t value, const RawBrandedSchema& schema); -// Declared here so that we can declare inline stringify methods on generated types. -// Defined in stringify.c++, which depends on dynamic.c++, which is allowed not to be linked in. - -template -inline kj::StringTree structString(StructReader reader) { - return structString(reader, rawBrandedSchema()); -} -template -inline kj::String enumString(T value) { - return enumString(static_cast(value), rawBrandedSchema()); -} - -#endif // !CAPNP_LITE - -// TODO(cleanup): Unify ConstStruct and ConstList. -template -class ConstStruct { -public: - ConstStruct() = delete; - KJ_DISALLOW_COPY(ConstStruct); - inline explicit constexpr ConstStruct(const word* ptr): ptr(ptr) {} - - inline typename T::Reader get() const { - return AnyPointer::Reader(PointerReader::getRootUnchecked(ptr)).getAs(); - } - - inline operator typename T::Reader() const { return get(); } - inline typename T::Reader operator*() const { return get(); } - inline TemporaryPointer operator->() const { return get(); } - -private: - const word* ptr; -}; - -template -class ConstList { -public: - ConstList() = delete; - KJ_DISALLOW_COPY(ConstList); - inline explicit constexpr ConstList(const word* ptr): ptr(ptr) {} - - inline typename List::Reader get() const { - return AnyPointer::Reader(PointerReader::getRootUnchecked(ptr)).getAs>(); - } - - inline operator typename List::Reader() const { return get(); } - inline typename List::Reader operator*() const { return get(); } - inline TemporaryPointer::Reader> operator->() const { return get(); } - -private: - const word* ptr; -}; - -template -class ConstText { -public: - ConstText() = delete; - KJ_DISALLOW_COPY(ConstText); - inline explicit constexpr ConstText(const word* ptr): ptr(ptr) {} - - inline Text::Reader get() const { - return Text::Reader(reinterpret_cast(ptr), size); - } - - inline operator Text::Reader() const { return get(); } - inline Text::Reader operator*() const { return get(); } - inline TemporaryPointer operator->() const { return get(); } - - inline kj::StringPtr toString() const { - return get(); - } - -private: - const word* ptr; -}; - -template -inline kj::StringPtr KJ_STRINGIFY(const ConstText& s) { - return s.get(); -} - -template -class ConstData { -public: - ConstData() = delete; - KJ_DISALLOW_COPY(ConstData); - inline explicit constexpr ConstData(const word* ptr): ptr(ptr) {} - - inline Data::Reader get() const { - return Data::Reader(reinterpret_cast(ptr), size); - } - - inline operator Data::Reader() const { return get(); } - inline Data::Reader operator*() const { return get(); } - inline TemporaryPointer operator->() const { return get(); } - -private: - const word* ptr; -}; - -template -inline auto KJ_STRINGIFY(const ConstData& s) -> decltype(kj::toCharSequence(s.get())) { - return kj::toCharSequence(s.get()); -} - -} // namespace _ (private) - -template -inline constexpr uint64_t typeId() { return CapnpPrivate::typeId; } -template ::typeId> -inline constexpr uint64_t typeId() { return id; } -// typeId() returns the type ID as defined in the schema. Works with structs, enums, and -// interfaces. - -template -inline constexpr uint sizeInWords() { - // Return the size, in words, of a Struct type, if allocated free-standing (not in a list). - // May be useful for pre-computing space needed in order to precisely allocate messages. - - return unbound((upgradeBound(_::structSize().data) + - _::structSize().pointers * WORDS_PER_POINTER) / WORDS); -} - -} // namespace capnp - -#if _MSC_VER -// MSVC doesn't understand floating-point constexpr yet. -// -// TODO(msvc): Remove this hack when MSVC is fixed. -#define CAPNP_NON_INT_CONSTEXPR_DECL_INIT(value) -#define CAPNP_NON_INT_CONSTEXPR_DEF_INIT(value) = value -#else -#define CAPNP_NON_INT_CONSTEXPR_DECL_INIT(value) = value -#define CAPNP_NON_INT_CONSTEXPR_DEF_INIT(value) -#endif - -#if _MSC_VER -// TODO(msvc): A little hack to allow MSVC to use C++14 return type deduction in cases where the -// explicit type exposes bugs in the compiler. -#define CAPNP_AUTO_IF_MSVC(...) auto -#else -#define CAPNP_AUTO_IF_MSVC(...) __VA_ARGS__ -#endif - -#if CAPNP_LITE - -#define CAPNP_DECLARE_SCHEMA(id) \ - extern ::capnp::word const* const bp_##id - -#define CAPNP_DECLARE_ENUM(type, id) \ - inline ::kj::String KJ_STRINGIFY(type##_##id value) { \ - return ::kj::str(static_cast(value)); \ - } \ - template <> struct EnumInfo { \ - struct IsEnum; \ - static constexpr uint64_t typeId = 0x##id; \ - static inline ::capnp::word const* encodedSchema() { return bp_##id; } \ - } - -#if _MSC_VER -// TODO(msvc): MSVC dosen't expect constexprs to have definitions. -#define CAPNP_DEFINE_ENUM(type, id) -#else -#define CAPNP_DEFINE_ENUM(type, id) \ - constexpr uint64_t EnumInfo::typeId -#endif - -#define CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize_, pointerCount_) \ - struct IsStruct; \ - static constexpr uint64_t typeId = 0x##id; \ - static constexpr uint16_t dataWordSize = dataWordSize_; \ - static constexpr uint16_t pointerCount = pointerCount_; \ - static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } - -#else // CAPNP_LITE - -#define CAPNP_DECLARE_SCHEMA(id) \ - extern ::capnp::word const* const bp_##id; \ - extern const ::capnp::_::RawSchema s_##id - -#define CAPNP_DECLARE_ENUM(type, id) \ - inline ::kj::String KJ_STRINGIFY(type##_##id value) { \ - return ::capnp::_::enumString(value); \ - } \ - template <> struct EnumInfo { \ - struct IsEnum; \ - static constexpr uint64_t typeId = 0x##id; \ - static inline ::capnp::word const* encodedSchema() { return bp_##id; } \ - static constexpr ::capnp::_::RawSchema const* schema = &s_##id; \ - } -#define CAPNP_DEFINE_ENUM(type, id) \ - constexpr uint64_t EnumInfo::typeId; \ - constexpr ::capnp::_::RawSchema const* EnumInfo::schema - -#define CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize_, pointerCount_) \ - struct IsStruct; \ - static constexpr uint64_t typeId = 0x##id; \ - static constexpr ::capnp::Kind kind = ::capnp::Kind::STRUCT; \ - static constexpr uint16_t dataWordSize = dataWordSize_; \ - static constexpr uint16_t pointerCount = pointerCount_; \ - static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } \ - static constexpr ::capnp::_::RawSchema const* schema = &::capnp::schemas::s_##id; - -#define CAPNP_DECLARE_INTERFACE_HEADER(id) \ - struct IsInterface; \ - static constexpr uint64_t typeId = 0x##id; \ - static constexpr ::capnp::Kind kind = ::capnp::Kind::INTERFACE; \ - static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } \ - static constexpr ::capnp::_::RawSchema const* schema = &::capnp::schemas::s_##id; - -#endif // CAPNP_LITE, else - -#endif // CAPNP_GENERATED_HEADER_SUPPORT_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/json.capnp b/phonelibs/capnp-cpp/include/capnp/json.capnp deleted file mode 100644 index 55188736f8bdb2..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/json.capnp +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2015 Sandstorm Development Group, Inc. and contributors -# Licensed under the MIT License: -# -# 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. - -@0x8ef99297a43a5e34; - -$import "/capnp/c++.capnp".namespace("capnp"); - -struct JsonValue { - union { - null @0 :Void; - boolean @1 :Bool; - number @2 :Float64; - string @3 :Text; - array @4 :List(JsonValue); - object @5 :List(Field); - # Standard JSON values. - - call @6 :Call; - # Non-standard: A "function call", applying a named function (named by a single identifier) - # to a parameter list. Examples: - # - # BinData(0, "Zm9vCg==") - # ISODate("2015-04-15T08:44:50.218Z") - # - # Mongo DB users will recognize the above as exactly the syntax Mongo uses to represent BSON - # "binary" and "date" types in text, since JSON has no analog of these. This is basically the - # reason this extension exists. We do NOT recommend using `call` unless you specifically need - # to be compatible with some silly format that uses this syntax. - } - - struct Field { - name @0 :Text; - value @1 :JsonValue; - } - - struct Call { - function @0 :Text; - params @1 :List(JsonValue); - } -} diff --git a/phonelibs/capnp-cpp/include/capnp/layout.h b/phonelibs/capnp-cpp/include/capnp/layout.h deleted file mode 100644 index 99dc533b2bf157..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/layout.h +++ /dev/null @@ -1,1274 +0,0 @@ -// Copyright (c) 2013-2016 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -// This file is NOT intended for use by clients, except in generated code. -// -// This file defines low-level, non-type-safe classes for traversing the Cap'n Proto memory layout -// (which is also its wire format). Code generated by the Cap'n Proto compiler uses these classes, -// as does other parts of the Cap'n proto library which provide a higher-level interface for -// dynamic introspection. - -#ifndef CAPNP_LAYOUT_H_ -#define CAPNP_LAYOUT_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include -#include -#include "common.h" -#include "blob.h" -#include "endian.h" - -#if (defined(__mips__) || defined(__hppa__)) && !defined(CAPNP_CANONICALIZE_NAN) -#define CAPNP_CANONICALIZE_NAN 1 -// Explicitly detect NaNs and canonicalize them to the quiet NaN value as would be returned by -// __builtin_nan("") on systems implementing the IEEE-754 recommended (but not required) NaN -// signalling/quiet differentiation (such as x86). Unfortunately, some architectures -- in -// particular, MIPS -- represent quiet vs. signalling nans differently than the rest of the world. -// Canonicalizing them makes output consistent (which is important!), but hurts performance -// slightly. -// -// Note that trying to convert MIPS NaNs to standard NaNs without losing data doesn't work. -// Signaling vs. quiet is indicated by a bit, with the meaning being the opposite on MIPS vs. -// everyone else. It would be great if we could just flip that bit, but we can't, because if the -// significand is all-zero, then the value is infinity rather than NaN. This means that on most -// machines, where the bit indicates quietness, there is one more quiet NaN value than signalling -// NaN value, whereas on MIPS there is one more sNaN than qNaN, and thus there is no isomorphic -// mapping that properly preserves quietness. Instead of doing something hacky, we just give up -// and blow away NaN payloads, because no one uses them anyway. -#endif - -namespace capnp { - -#if !CAPNP_LITE -class ClientHook; -#endif // !CAPNP_LITE - -namespace _ { // private - -class PointerBuilder; -class PointerReader; -class StructBuilder; -class StructReader; -class ListBuilder; -class ListReader; -class OrphanBuilder; -struct WirePointer; -struct WireHelpers; -class SegmentReader; -class SegmentBuilder; -class Arena; -class BuilderArena; - -// ============================================================================= - -#if CAPNP_DEBUG_TYPES -typedef kj::UnitRatio, BitLabel, ElementLabel> BitsPerElementTableType; -#else -typedef uint BitsPerElementTableType; -#endif - -static constexpr BitsPerElementTableType BITS_PER_ELEMENT_TABLE[8] = { - bounded< 0>() * BITS / ELEMENTS, - bounded< 1>() * BITS / ELEMENTS, - bounded< 8>() * BITS / ELEMENTS, - bounded<16>() * BITS / ELEMENTS, - bounded<32>() * BITS / ELEMENTS, - bounded<64>() * BITS / ELEMENTS, - bounded< 0>() * BITS / ELEMENTS, - bounded< 0>() * BITS / ELEMENTS -}; - -inline KJ_CONSTEXPR() BitsPerElementTableType dataBitsPerElement(ElementSize size) { - return _::BITS_PER_ELEMENT_TABLE[static_cast(size)]; -} - -inline constexpr PointersPerElementN<1> pointersPerElement(ElementSize size) { - return size == ElementSize::POINTER - ? PointersPerElementN<1>(ONE * POINTERS / ELEMENTS) - : PointersPerElementN<1>(ZERO * POINTERS / ELEMENTS); -} - -static constexpr BitsPerElementTableType BITS_PER_ELEMENT_INCLUDING_PONITERS_TABLE[8] = { - bounded< 0>() * BITS / ELEMENTS, - bounded< 1>() * BITS / ELEMENTS, - bounded< 8>() * BITS / ELEMENTS, - bounded<16>() * BITS / ELEMENTS, - bounded<32>() * BITS / ELEMENTS, - bounded<64>() * BITS / ELEMENTS, - bounded<64>() * BITS / ELEMENTS, - bounded< 0>() * BITS / ELEMENTS -}; - -inline KJ_CONSTEXPR() BitsPerElementTableType bitsPerElementIncludingPointers(ElementSize size) { - return _::BITS_PER_ELEMENT_INCLUDING_PONITERS_TABLE[static_cast(size)]; -} - -template struct ElementSizeForByteSize; -template <> struct ElementSizeForByteSize<1> { static constexpr ElementSize value = ElementSize::BYTE; }; -template <> struct ElementSizeForByteSize<2> { static constexpr ElementSize value = ElementSize::TWO_BYTES; }; -template <> struct ElementSizeForByteSize<4> { static constexpr ElementSize value = ElementSize::FOUR_BYTES; }; -template <> struct ElementSizeForByteSize<8> { static constexpr ElementSize value = ElementSize::EIGHT_BYTES; }; - -template struct ElementSizeForType { - static constexpr ElementSize value = - // Primitive types that aren't special-cased below can be determined from sizeof(). - CAPNP_KIND(T) == Kind::PRIMITIVE ? ElementSizeForByteSize::value : - CAPNP_KIND(T) == Kind::ENUM ? ElementSize::TWO_BYTES : - CAPNP_KIND(T) == Kind::STRUCT ? ElementSize::INLINE_COMPOSITE : - - // Everything else is a pointer. - ElementSize::POINTER; -}; - -// Void and bool are special. -template <> struct ElementSizeForType { static constexpr ElementSize value = ElementSize::VOID; }; -template <> struct ElementSizeForType { static constexpr ElementSize value = ElementSize::BIT; }; - -// Lists and blobs are pointers, not structs. -template struct ElementSizeForType> { - static constexpr ElementSize value = ElementSize::POINTER; -}; -template <> struct ElementSizeForType { - static constexpr ElementSize value = ElementSize::POINTER; -}; -template <> struct ElementSizeForType { - static constexpr ElementSize value = ElementSize::POINTER; -}; - -template -inline constexpr ElementSize elementSizeForType() { - return ElementSizeForType::value; -} - -struct MessageSizeCounts { - WordCountN<61, uint64_t> wordCount; // 2^64 bytes - uint capCount; - - MessageSizeCounts& operator+=(const MessageSizeCounts& other) { - // OK to truncate unchecked because this class is used to count actual stuff in memory, and - // we couldn't possibly have anywhere near 2^61 words. - wordCount = assumeBits<61>(wordCount + other.wordCount); - capCount += other.capCount; - return *this; - } - - void addWords(WordCountN<61, uint64_t> other) { - wordCount = assumeBits<61>(wordCount + other); - } - - MessageSize asPublic() { - return MessageSize { unbound(wordCount / WORDS), capCount }; - } -}; - -// ============================================================================= - -template -union AlignedData { - // Useful for declaring static constant data blobs as an array of bytes, but forcing those - // bytes to be word-aligned. - - uint8_t bytes[wordCount * sizeof(word)]; - word words[wordCount]; -}; - -struct StructSize { - StructDataWordCount data; - StructPointerCount pointers; - - inline constexpr WordCountN<17> total() const { return data + pointers * WORDS_PER_POINTER; } - - StructSize() = default; - inline constexpr StructSize(StructDataWordCount data, StructPointerCount pointers) - : data(data), pointers(pointers) {} -}; - -template -inline constexpr StructSize structSize() { - return StructSize(bounded(CapnpPrivate::dataWordSize) * WORDS, - bounded(CapnpPrivate::pointerCount) * POINTERS); -} - -template > -inline constexpr StructSize minStructSizeForElement() { - // If T is a struct, return its struct size. Otherwise return the minimum struct size big enough - // to hold a T. - - return StructSize(bounded(CapnpPrivate::dataWordSize) * WORDS, - bounded(CapnpPrivate::pointerCount) * POINTERS); -} - -template > -inline constexpr StructSize minStructSizeForElement() { - // If T is a struct, return its struct size. Otherwise return the minimum struct size big enough - // to hold a T. - - return StructSize( - dataBitsPerElement(elementSizeForType()) * ELEMENTS > ZERO * BITS - ? StructDataWordCount(ONE * WORDS) : StructDataWordCount(ZERO * WORDS), - pointersPerElement(elementSizeForType()) * ELEMENTS); -} - -// ------------------------------------------------------------------- -// Masking of default values - -template struct Mask_; -template struct Mask_ { typedef T Type; }; -template struct Mask_ { typedef uint16_t Type; }; -template <> struct Mask_ { typedef uint32_t Type; }; -template <> struct Mask_ { typedef uint64_t Type; }; - -template struct Mask_ { - // Union discriminants end up here. - static_assert(sizeof(T) == 2, "Don't know how to mask this type."); - typedef uint16_t Type; -}; - -template -using Mask = typename Mask_::Type; - -template -KJ_ALWAYS_INLINE(Mask mask(T value, Mask mask)); -template -KJ_ALWAYS_INLINE(T unmask(Mask value, Mask mask)); - -template -inline Mask mask(T value, Mask mask) { - return static_cast >(value) ^ mask; -} - -template <> -inline uint32_t mask(float value, uint32_t mask) { -#if CAPNP_CANONICALIZE_NAN - if (value != value) { - return 0x7fc00000u ^ mask; - } -#endif - - uint32_t i; - static_assert(sizeof(i) == sizeof(value), "float is not 32 bits?"); - memcpy(&i, &value, sizeof(value)); - return i ^ mask; -} - -template <> -inline uint64_t mask(double value, uint64_t mask) { -#if CAPNP_CANONICALIZE_NAN - if (value != value) { - return 0x7ff8000000000000ull ^ mask; - } -#endif - - uint64_t i; - static_assert(sizeof(i) == sizeof(value), "double is not 64 bits?"); - memcpy(&i, &value, sizeof(value)); - return i ^ mask; -} - -template -inline T unmask(Mask value, Mask mask) { - return static_cast(value ^ mask); -} - -template <> -inline float unmask(uint32_t value, uint32_t mask) { - value ^= mask; - float result; - static_assert(sizeof(result) == sizeof(value), "float is not 32 bits?"); - memcpy(&result, &value, sizeof(value)); - return result; -} - -template <> -inline double unmask(uint64_t value, uint64_t mask) { - value ^= mask; - double result; - static_assert(sizeof(result) == sizeof(value), "double is not 64 bits?"); - memcpy(&result, &value, sizeof(value)); - return result; -} - -// ------------------------------------------------------------------- - -class CapTableReader { -public: -#if !CAPNP_LITE - virtual kj::Maybe> extractCap(uint index) = 0; - // Extract the capability at the given index. If the index is invalid, returns null. -#endif // !CAPNP_LITE -}; - -class CapTableBuilder: public CapTableReader { -public: -#if !CAPNP_LITE - virtual uint injectCap(kj::Own&& cap) = 0; - // Add the capability to the message and return its index. If the same ClientHook is injected - // twice, this may return the same index both times, but in this case dropCap() needs to be - // called an equal number of times to actually remove the cap. - - virtual void dropCap(uint index) = 0; - // Remove a capability injected earlier. Called when the pointer is overwritten or zero'd out. -#endif // !CAPNP_LITE -}; - -// ------------------------------------------------------------------- - -class PointerBuilder: public kj::DisallowConstCopy { - // Represents a single pointer, usually embedded in a struct or a list. - -public: - inline PointerBuilder(): segment(nullptr), capTable(nullptr), pointer(nullptr) {} - - static inline PointerBuilder getRoot( - SegmentBuilder* segment, CapTableBuilder* capTable, word* location); - // Get a PointerBuilder representing a message root located in the given segment at the given - // location. - - inline bool isNull() { return getPointerType() == PointerType::NULL_; } - PointerType getPointerType() const; - - StructBuilder getStruct(StructSize size, const word* defaultValue); - ListBuilder getList(ElementSize elementSize, const word* defaultValue); - ListBuilder getStructList(StructSize elementSize, const word* defaultValue); - ListBuilder getListAnySize(const word* defaultValue); - template typename T::Builder getBlob( - const void* defaultValue, ByteCount defaultSize); -#if !CAPNP_LITE - kj::Own getCapability(); -#endif // !CAPNP_LITE - // Get methods: Get the value. If it is null, initialize it to a copy of the default value. - // The default value is encoded as an "unchecked message" for structs, lists, and objects, or a - // simple byte array for blobs. - - StructBuilder initStruct(StructSize size); - ListBuilder initList(ElementSize elementSize, ElementCount elementCount); - ListBuilder initStructList(ElementCount elementCount, StructSize size); - template typename T::Builder initBlob(ByteCount size); - // Init methods: Initialize the pointer to a newly-allocated object, discarding the existing - // object. - - void setStruct(const StructReader& value, bool canonical = false); - void setList(const ListReader& value, bool canonical = false); - template void setBlob(typename T::Reader value); -#if !CAPNP_LITE - void setCapability(kj::Own&& cap); -#endif // !CAPNP_LITE - // Set methods: Initialize the pointer to a newly-allocated copy of the given value, discarding - // the existing object. - - void adopt(OrphanBuilder&& orphan); - // Set the pointer to point at the given orphaned value. - - OrphanBuilder disown(); - // Set the pointer to null and return its previous value as an orphan. - - void clear(); - // Clear the pointer to null, discarding its previous value. - - void transferFrom(PointerBuilder other); - // Equivalent to `adopt(other.disown())`. - - void copyFrom(PointerReader other, bool canonical = false); - // Equivalent to `set(other.get())`. - // If you set the canonical flag, it will attempt to lay the target out - // canonically, provided enough space is available. - - PointerReader asReader() const; - - BuilderArena* getArena() const; - // Get the arena containing this pointer. - - CapTableBuilder* getCapTable(); - // Gets the capability context in which this object is operating. - - PointerBuilder imbue(CapTableBuilder* capTable); - // Return a copy of this builder except using the given capability context. - -private: - SegmentBuilder* segment; // Memory segment in which the pointer resides. - CapTableBuilder* capTable; // Table of capability indexes. - WirePointer* pointer; // Pointer to the pointer. - - inline PointerBuilder(SegmentBuilder* segment, CapTableBuilder* capTable, WirePointer* pointer) - : segment(segment), capTable(capTable), pointer(pointer) {} - - friend class StructBuilder; - friend class ListBuilder; - friend class OrphanBuilder; -}; - -class PointerReader { -public: - inline PointerReader() - : segment(nullptr), capTable(nullptr), pointer(nullptr), nestingLimit(0x7fffffff) {} - - static PointerReader getRoot(SegmentReader* segment, CapTableReader* capTable, - const word* location, int nestingLimit); - // Get a PointerReader representing a message root located in the given segment at the given - // location. - - static inline PointerReader getRootUnchecked(const word* location); - // Get a PointerReader for an unchecked message. - - MessageSizeCounts targetSize() const; - // Return the total size of the target object and everything to which it points. Does not count - // far pointer overhead. This is useful for deciding how much space is needed to copy the object - // into a flat array. However, the caller is advised NOT to treat this value as secure. Instead, - // use the result as a hint for allocating the first segment, do the copy, and then throw an - // exception if it overruns. - - inline bool isNull() const { return getPointerType() == PointerType::NULL_; } - PointerType getPointerType() const; - - StructReader getStruct(const word* defaultValue) const; - ListReader getList(ElementSize expectedElementSize, const word* defaultValue) const; - ListReader getListAnySize(const word* defaultValue) const; - template - typename T::Reader getBlob(const void* defaultValue, ByteCount defaultSize) const; -#if !CAPNP_LITE - kj::Own getCapability() const; -#endif // !CAPNP_LITE - // Get methods: Get the value. If it is null, return the default value instead. - // The default value is encoded as an "unchecked message" for structs, lists, and objects, or a - // simple byte array for blobs. - - const word* getUnchecked() const; - // If this is an unchecked message, get a word* pointing at the location of the pointer. This - // word* can actually be passed to readUnchecked() to read the designated sub-object later. If - // this isn't an unchecked message, throws an exception. - - kj::Maybe getArena() const; - // Get the arena containing this pointer. - - CapTableReader* getCapTable(); - // Gets the capability context in which this object is operating. - - PointerReader imbue(CapTableReader* capTable) const; - // Return a copy of this reader except using the given capability context. - - bool isCanonical(const word **readHead); - // Validate this pointer's canonicity, subject to the conditions: - // * All data to the left of readHead has been read thus far (for pointer - // ordering) - // * All pointers in preorder have already been checked - // * This pointer is in the first and only segment of the message - -private: - SegmentReader* segment; // Memory segment in which the pointer resides. - CapTableReader* capTable; // Table of capability indexes. - const WirePointer* pointer; // Pointer to the pointer. null = treat as null pointer. - - int nestingLimit; - // Limits the depth of message structures to guard against stack-overflow-based DoS attacks. - // Once this reaches zero, further pointers will be pruned. - - inline PointerReader(SegmentReader* segment, CapTableReader* capTable, - const WirePointer* pointer, int nestingLimit) - : segment(segment), capTable(capTable), pointer(pointer), nestingLimit(nestingLimit) {} - - friend class StructReader; - friend class ListReader; - friend class PointerBuilder; - friend class OrphanBuilder; -}; - -// ------------------------------------------------------------------- - -class StructBuilder: public kj::DisallowConstCopy { -public: - inline StructBuilder(): segment(nullptr), capTable(nullptr), data(nullptr), pointers(nullptr) {} - - inline word* getLocation() { return reinterpret_cast(data); } - // Get the object's location. Only valid for independently-allocated objects (i.e. not list - // elements). - - inline StructDataBitCount getDataSectionSize() const { return dataSize; } - inline StructPointerCount getPointerSectionSize() const { return pointerCount; } - inline kj::ArrayPtr getDataSectionAsBlob(); - inline _::ListBuilder getPointerSectionAsList(); - - template - KJ_ALWAYS_INLINE(bool hasDataField(StructDataOffset offset)); - // Return true if the field is set to something other than its default value. - - template - KJ_ALWAYS_INLINE(T getDataField(StructDataOffset offset)); - // Gets the data field value of the given type at the given offset. The offset is measured in - // multiples of the field size, determined by the type. - - template - KJ_ALWAYS_INLINE(T getDataField(StructDataOffset offset, Mask mask)); - // Like getDataField() but applies the given XOR mask to the data on load. Used for reading - // fields with non-zero default values. - - template - KJ_ALWAYS_INLINE(void setDataField(StructDataOffset offset, kj::NoInfer value)); - // Sets the data field value at the given offset. - - template - KJ_ALWAYS_INLINE(void setDataField(StructDataOffset offset, - kj::NoInfer value, Mask mask)); - // Like setDataField() but applies the given XOR mask before storing. Used for writing fields - // with non-zero default values. - - KJ_ALWAYS_INLINE(PointerBuilder getPointerField(StructPointerOffset ptrIndex)); - // Get a builder for a pointer field given the index within the pointer section. - - void clearAll(); - // Clear all pointers and data. - - void transferContentFrom(StructBuilder other); - // Adopt all pointers from `other`, and also copy all data. If `other`'s sections are larger - // than this, the extra data is not transferred, meaning there is a risk of data loss when - // transferring from messages built with future versions of the protocol. - - void copyContentFrom(StructReader other); - // Copy content from `other`. If `other`'s sections are larger than this, the extra data is not - // copied, meaning there is a risk of data loss when copying from messages built with future - // versions of the protocol. - - StructReader asReader() const; - // Gets a StructReader pointing at the same memory. - - BuilderArena* getArena(); - // Gets the arena in which this object is allocated. - - CapTableBuilder* getCapTable(); - // Gets the capability context in which this object is operating. - - StructBuilder imbue(CapTableBuilder* capTable); - // Return a copy of this builder except using the given capability context. - -private: - SegmentBuilder* segment; // Memory segment in which the struct resides. - CapTableBuilder* capTable; // Table of capability indexes. - void* data; // Pointer to the encoded data. - WirePointer* pointers; // Pointer to the encoded pointers. - - StructDataBitCount dataSize; - // Size of data section. We use a bit count rather than a word count to more easily handle the - // case of struct lists encoded with less than a word per element. - - StructPointerCount pointerCount; // Size of the pointer section. - - inline StructBuilder(SegmentBuilder* segment, CapTableBuilder* capTable, - void* data, WirePointer* pointers, - StructDataBitCount dataSize, StructPointerCount pointerCount) - : segment(segment), capTable(capTable), data(data), pointers(pointers), - dataSize(dataSize), pointerCount(pointerCount) {} - - friend class ListBuilder; - friend struct WireHelpers; - friend class OrphanBuilder; -}; - -class StructReader { -public: - inline StructReader() - : segment(nullptr), capTable(nullptr), data(nullptr), pointers(nullptr), - dataSize(ZERO * BITS), pointerCount(ZERO * POINTERS), nestingLimit(0x7fffffff) {} - inline StructReader(kj::ArrayPtr data) - : segment(nullptr), capTable(nullptr), data(data.begin()), pointers(nullptr), - dataSize(assumeBits(data.size()) * WORDS * BITS_PER_WORD), - pointerCount(ZERO * POINTERS), nestingLimit(0x7fffffff) {} - - const void* getLocation() const { return data; } - - inline StructDataBitCount getDataSectionSize() const { return dataSize; } - inline StructPointerCount getPointerSectionSize() const { return pointerCount; } - inline kj::ArrayPtr getDataSectionAsBlob(); - inline _::ListReader getPointerSectionAsList(); - - kj::Array canonicalize(); - - template - KJ_ALWAYS_INLINE(bool hasDataField(StructDataOffset offset) const); - // Return true if the field is set to something other than its default value. - - template - KJ_ALWAYS_INLINE(T getDataField(StructDataOffset offset) const); - // Get the data field value of the given type at the given offset. The offset is measured in - // multiples of the field size, determined by the type. Returns zero if the offset is past the - // end of the struct's data section. - - template - KJ_ALWAYS_INLINE(T getDataField(StructDataOffset offset, Mask mask) const); - // Like getDataField(offset), but applies the given XOR mask to the result. Used for reading - // fields with non-zero default values. - - KJ_ALWAYS_INLINE(PointerReader getPointerField(StructPointerOffset ptrIndex) const); - // Get a reader for a pointer field given the index within the pointer section. If the index - // is out-of-bounds, returns a null pointer. - - MessageSizeCounts totalSize() const; - // Return the total size of the struct and everything to which it points. Does not count far - // pointer overhead. This is useful for deciding how much space is needed to copy the struct - // into a flat array. However, the caller is advised NOT to treat this value as secure. Instead, - // use the result as a hint for allocating the first segment, do the copy, and then throw an - // exception if it overruns. - - CapTableReader* getCapTable(); - // Gets the capability context in which this object is operating. - - StructReader imbue(CapTableReader* capTable) const; - // Return a copy of this reader except using the given capability context. - - bool isCanonical(const word **readHead, const word **ptrHead, - bool *dataTrunc, bool *ptrTrunc); - // Validate this pointer's canonicity, subject to the conditions: - // * All data to the left of readHead has been read thus far (for pointer - // ordering) - // * All pointers in preorder have already been checked - // * This pointer is in the first and only segment of the message - // - // If this function returns false, the struct is non-canonical. If it - // returns true, then: - // * If it is a composite in a list, it is canonical if at least one struct - // in the list outputs dataTrunc = 1, and at least one outputs ptrTrunc = 1 - // * If it is derived from a struct pointer, it is canonical if - // dataTrunc = 1 AND ptrTrunc = 1 - -private: - SegmentReader* segment; // Memory segment in which the struct resides. - CapTableReader* capTable; // Table of capability indexes. - - const void* data; - const WirePointer* pointers; - - StructDataBitCount dataSize; - // Size of data section. We use a bit count rather than a word count to more easily handle the - // case of struct lists encoded with less than a word per element. - - StructPointerCount pointerCount; // Size of the pointer section. - - int nestingLimit; - // Limits the depth of message structures to guard against stack-overflow-based DoS attacks. - // Once this reaches zero, further pointers will be pruned. - // TODO(perf): Limit to 16 bits for better packing? - - inline StructReader(SegmentReader* segment, CapTableReader* capTable, - const void* data, const WirePointer* pointers, - StructDataBitCount dataSize, StructPointerCount pointerCount, - int nestingLimit) - : segment(segment), capTable(capTable), data(data), pointers(pointers), - dataSize(dataSize), pointerCount(pointerCount), - nestingLimit(nestingLimit) {} - - friend class ListReader; - friend class StructBuilder; - friend struct WireHelpers; -}; - -// ------------------------------------------------------------------- - -class ListBuilder: public kj::DisallowConstCopy { -public: - inline explicit ListBuilder(ElementSize elementSize) - : segment(nullptr), capTable(nullptr), ptr(nullptr), elementCount(ZERO * ELEMENTS), - step(ZERO * BITS / ELEMENTS), structDataSize(ZERO * BITS), - structPointerCount(ZERO * POINTERS), elementSize(elementSize) {} - - inline word* getLocation() { - // Get the object's location. - - if (elementSize == ElementSize::INLINE_COMPOSITE && ptr != nullptr) { - return reinterpret_cast(ptr) - POINTER_SIZE_IN_WORDS; - } else { - return reinterpret_cast(ptr); - } - } - - inline ElementSize getElementSize() const { return elementSize; } - - inline ListElementCount size() const; - // The number of elements in the list. - - Text::Builder asText(); - Data::Builder asData(); - // Reinterpret the list as a blob. Throws an exception if the elements are not byte-sized. - - template - KJ_ALWAYS_INLINE(T getDataElement(ElementCount index)); - // Get the element of the given type at the given index. - - template - KJ_ALWAYS_INLINE(void setDataElement(ElementCount index, kj::NoInfer value)); - // Set the element at the given index. - - KJ_ALWAYS_INLINE(PointerBuilder getPointerElement(ElementCount index)); - - StructBuilder getStructElement(ElementCount index); - - ListReader asReader() const; - // Get a ListReader pointing at the same memory. - - BuilderArena* getArena(); - // Gets the arena in which this object is allocated. - - CapTableBuilder* getCapTable(); - // Gets the capability context in which this object is operating. - - ListBuilder imbue(CapTableBuilder* capTable); - // Return a copy of this builder except using the given capability context. - -private: - SegmentBuilder* segment; // Memory segment in which the list resides. - CapTableBuilder* capTable; // Table of capability indexes. - - byte* ptr; // Pointer to list content. - - ListElementCount elementCount; // Number of elements in the list. - - BitsPerElementN<23> step; - // The distance between elements. The maximum value occurs when a struct contains 2^16-1 data - // words and 2^16-1 pointers, i.e. 2^17 - 2 words, or 2^23 - 128 bits. - - StructDataBitCount structDataSize; - StructPointerCount structPointerCount; - // The struct properties to use when interpreting the elements as structs. All lists can be - // interpreted as struct lists, so these are always filled in. - - ElementSize elementSize; - // The element size as a ElementSize. This is only really needed to disambiguate INLINE_COMPOSITE - // from other types when the overall size is exactly zero or one words. - - inline ListBuilder(SegmentBuilder* segment, CapTableBuilder* capTable, void* ptr, - BitsPerElementN<23> step, ListElementCount size, - StructDataBitCount structDataSize, StructPointerCount structPointerCount, - ElementSize elementSize) - : segment(segment), capTable(capTable), ptr(reinterpret_cast(ptr)), - elementCount(size), step(step), structDataSize(structDataSize), - structPointerCount(structPointerCount), elementSize(elementSize) {} - - friend class StructBuilder; - friend struct WireHelpers; - friend class OrphanBuilder; -}; - -class ListReader { -public: - inline explicit ListReader(ElementSize elementSize) - : segment(nullptr), capTable(nullptr), ptr(nullptr), elementCount(ZERO * ELEMENTS), - step(ZERO * BITS / ELEMENTS), structDataSize(ZERO * BITS), - structPointerCount(ZERO * POINTERS), elementSize(elementSize), nestingLimit(0x7fffffff) {} - - inline ListElementCount size() const; - // The number of elements in the list. - - inline ElementSize getElementSize() const { return elementSize; } - - Text::Reader asText(); - Data::Reader asData(); - // Reinterpret the list as a blob. Throws an exception if the elements are not byte-sized. - - kj::ArrayPtr asRawBytes(); - - template - KJ_ALWAYS_INLINE(T getDataElement(ElementCount index) const); - // Get the element of the given type at the given index. - - KJ_ALWAYS_INLINE(PointerReader getPointerElement(ElementCount index) const); - - StructReader getStructElement(ElementCount index) const; - - CapTableReader* getCapTable(); - // Gets the capability context in which this object is operating. - - ListReader imbue(CapTableReader* capTable) const; - // Return a copy of this reader except using the given capability context. - - bool isCanonical(const word **readHead, const WirePointer* ref); - // Validate this pointer's canonicity, subject to the conditions: - // * All data to the left of readHead has been read thus far (for pointer - // ordering) - // * All pointers in preorder have already been checked - // * This pointer is in the first and only segment of the message - -private: - SegmentReader* segment; // Memory segment in which the list resides. - CapTableReader* capTable; // Table of capability indexes. - - const byte* ptr; // Pointer to list content. - - ListElementCount elementCount; // Number of elements in the list. - - BitsPerElementN<23> step; - // The distance between elements. The maximum value occurs when a struct contains 2^16-1 data - // words and 2^16-1 pointers, i.e. 2^17 - 2 words, or 2^23 - 2 bits. - - StructDataBitCount structDataSize; - StructPointerCount structPointerCount; - // The struct properties to use when interpreting the elements as structs. All lists can be - // interpreted as struct lists, so these are always filled in. - - ElementSize elementSize; - // The element size as a ElementSize. This is only really needed to disambiguate INLINE_COMPOSITE - // from other types when the overall size is exactly zero or one words. - - int nestingLimit; - // Limits the depth of message structures to guard against stack-overflow-based DoS attacks. - // Once this reaches zero, further pointers will be pruned. - - inline ListReader(SegmentReader* segment, CapTableReader* capTable, const void* ptr, - ListElementCount elementCount, BitsPerElementN<23> step, - StructDataBitCount structDataSize, StructPointerCount structPointerCount, - ElementSize elementSize, int nestingLimit) - : segment(segment), capTable(capTable), ptr(reinterpret_cast(ptr)), - elementCount(elementCount), step(step), structDataSize(structDataSize), - structPointerCount(structPointerCount), elementSize(elementSize), - nestingLimit(nestingLimit) {} - - friend class StructReader; - friend class ListBuilder; - friend struct WireHelpers; - friend class OrphanBuilder; -}; - -// ------------------------------------------------------------------- - -class OrphanBuilder { -public: - inline OrphanBuilder(): segment(nullptr), capTable(nullptr), location(nullptr) { - memset(&tag, 0, sizeof(tag)); - } - OrphanBuilder(const OrphanBuilder& other) = delete; - inline OrphanBuilder(OrphanBuilder&& other) noexcept; - inline ~OrphanBuilder() noexcept(false); - - static OrphanBuilder initStruct(BuilderArena* arena, CapTableBuilder* capTable, StructSize size); - static OrphanBuilder initList(BuilderArena* arena, CapTableBuilder* capTable, - ElementCount elementCount, ElementSize elementSize); - static OrphanBuilder initStructList(BuilderArena* arena, CapTableBuilder* capTable, - ElementCount elementCount, StructSize elementSize); - static OrphanBuilder initText(BuilderArena* arena, CapTableBuilder* capTable, ByteCount size); - static OrphanBuilder initData(BuilderArena* arena, CapTableBuilder* capTable, ByteCount size); - - static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, StructReader copyFrom); - static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, ListReader copyFrom); - static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, PointerReader copyFrom); - static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, Text::Reader copyFrom); - static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, Data::Reader copyFrom); -#if !CAPNP_LITE - static OrphanBuilder copy(BuilderArena* arena, CapTableBuilder* capTable, - kj::Own copyFrom); -#endif // !CAPNP_LITE - - static OrphanBuilder concat(BuilderArena* arena, CapTableBuilder* capTable, - ElementSize expectedElementSize, StructSize expectedStructSize, - kj::ArrayPtr lists); - - static OrphanBuilder referenceExternalData(BuilderArena* arena, Data::Reader data); - - OrphanBuilder& operator=(const OrphanBuilder& other) = delete; - inline OrphanBuilder& operator=(OrphanBuilder&& other); - - inline bool operator==(decltype(nullptr)) const { return location == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return location != nullptr; } - - StructBuilder asStruct(StructSize size); - // Interpret as a struct, or throw an exception if not a struct. - - ListBuilder asList(ElementSize elementSize); - // Interpret as a list, or throw an exception if not a list. elementSize cannot be - // INLINE_COMPOSITE -- use asStructList() instead. - - ListBuilder asStructList(StructSize elementSize); - // Interpret as a struct list, or throw an exception if not a list. - - ListBuilder asListAnySize(); - // For AnyList. - - Text::Builder asText(); - Data::Builder asData(); - // Interpret as a blob, or throw an exception if not a blob. - - StructReader asStructReader(StructSize size) const; - ListReader asListReader(ElementSize elementSize) const; - ListReader asListReaderAnySize() const; -#if !CAPNP_LITE - kj::Own asCapability() const; -#endif // !CAPNP_LITE - Text::Reader asTextReader() const; - Data::Reader asDataReader() const; - - bool truncate(ElementCount size, bool isText) KJ_WARN_UNUSED_RESULT; - // Resize the orphan list to the given size. Returns false if the list is currently empty but - // the requested size is non-zero, in which case the caller will need to allocate a new list. - - void truncate(ElementCount size, ElementSize elementSize); - void truncate(ElementCount size, StructSize elementSize); - void truncateText(ElementCount size); - // Versions of truncate() that know how to allocate a new list if needed. - -private: - static_assert(ONE * POINTERS * WORDS_PER_POINTER == ONE * WORDS, - "This struct assumes a pointer is one word."); - word tag; - // Contains an encoded WirePointer representing this object. WirePointer is defined in - // layout.c++, but fits in a word. - // - // This may be a FAR pointer. Even in that case, `location` points to the eventual destination - // of that far pointer. The reason we keep the far pointer around rather than just making `tag` - // represent the final destination is because if the eventual adopter of the pointer is not in - // the target's segment then it may be useful to reuse the far pointer landing pad. - // - // If `tag` is not a far pointer, its offset is garbage; only `location` points to the actual - // target. - - SegmentBuilder* segment; - // Segment in which the object resides. - - CapTableBuilder* capTable; - // Table of capability indexes. - - word* location; - // Pointer to the object, or nullptr if the pointer is null. For capabilities, we make this - // 0x1 just so that it is non-null for operator==, but it is never used. - - inline OrphanBuilder(const void* tagPtr, SegmentBuilder* segment, - CapTableBuilder* capTable, word* location) - : segment(segment), capTable(capTable), location(location) { - memcpy(&tag, tagPtr, sizeof(tag)); - } - - inline WirePointer* tagAsPtr() { return reinterpret_cast(&tag); } - inline const WirePointer* tagAsPtr() const { return reinterpret_cast(&tag); } - - void euthanize(); - // Erase the target object, zeroing it out and possibly reclaiming the memory. Called when - // the OrphanBuilder is being destroyed or overwritten and it is non-null. - - friend struct WireHelpers; -}; - -// ======================================================================================= -// Internal implementation details... - -// These are defined in the source file. -template <> typename Text::Builder PointerBuilder::initBlob(ByteCount size); -template <> void PointerBuilder::setBlob(typename Text::Reader value); -template <> typename Text::Builder PointerBuilder::getBlob( - const void* defaultValue, ByteCount defaultSize); -template <> typename Text::Reader PointerReader::getBlob( - const void* defaultValue, ByteCount defaultSize) const; - -template <> typename Data::Builder PointerBuilder::initBlob(ByteCount size); -template <> void PointerBuilder::setBlob(typename Data::Reader value); -template <> typename Data::Builder PointerBuilder::getBlob( - const void* defaultValue, ByteCount defaultSize); -template <> typename Data::Reader PointerReader::getBlob( - const void* defaultValue, ByteCount defaultSize) const; - -inline PointerBuilder PointerBuilder::getRoot( - SegmentBuilder* segment, CapTableBuilder* capTable, word* location) { - return PointerBuilder(segment, capTable, reinterpret_cast(location)); -} - -inline PointerReader PointerReader::getRootUnchecked(const word* location) { - return PointerReader(nullptr, nullptr, - reinterpret_cast(location), 0x7fffffff); -} - -// ------------------------------------------------------------------- - -inline kj::ArrayPtr StructBuilder::getDataSectionAsBlob() { - return kj::ArrayPtr(reinterpret_cast(data), - unbound(dataSize / BITS_PER_BYTE / BYTES)); -} - -inline _::ListBuilder StructBuilder::getPointerSectionAsList() { - return _::ListBuilder(segment, capTable, pointers, ONE * POINTERS * BITS_PER_POINTER / ELEMENTS, - pointerCount * (ONE * ELEMENTS / POINTERS), - ZERO * BITS, ONE * POINTERS, ElementSize::POINTER); -} - -template -inline bool StructBuilder::hasDataField(StructDataOffset offset) { - return getDataField>(offset) != 0; -} - -template <> -inline bool StructBuilder::hasDataField(StructDataOffset offset) { - return false; -} - -template -inline T StructBuilder::getDataField(StructDataOffset offset) { - return reinterpret_cast*>(data)[unbound(offset / ELEMENTS)].get(); -} - -template <> -inline bool StructBuilder::getDataField(StructDataOffset offset) { - BitCount32 boffset = offset * (ONE * BITS / ELEMENTS); - byte* b = reinterpret_cast(data) + boffset / BITS_PER_BYTE; - return (*reinterpret_cast(b) & - unbound(ONE << (boffset % BITS_PER_BYTE / BITS))) != 0; -} - -template <> -inline Void StructBuilder::getDataField(StructDataOffset offset) { - return VOID; -} - -template -inline T StructBuilder::getDataField(StructDataOffset offset, Mask mask) { - return unmask(getDataField >(offset), mask); -} - -template -inline void StructBuilder::setDataField(StructDataOffset offset, kj::NoInfer value) { - reinterpret_cast*>(data)[unbound(offset / ELEMENTS)].set(value); -} - -#if CAPNP_CANONICALIZE_NAN -// Use mask() on floats and doubles to make sure we canonicalize NaNs. -template <> -inline void StructBuilder::setDataField(StructDataOffset offset, float value) { - setDataField(offset, mask(value, 0)); -} -template <> -inline void StructBuilder::setDataField(StructDataOffset offset, double value) { - setDataField(offset, mask(value, 0)); -} -#endif - -template <> -inline void StructBuilder::setDataField(StructDataOffset offset, bool value) { - auto boffset = offset * (ONE * BITS / ELEMENTS); - byte* b = reinterpret_cast(data) + boffset / BITS_PER_BYTE; - uint bitnum = unboundMaxBits<3>(boffset % BITS_PER_BYTE / BITS); - *reinterpret_cast(b) = (*reinterpret_cast(b) & ~(1 << bitnum)) - | (static_cast(value) << bitnum); -} - -template <> -inline void StructBuilder::setDataField(StructDataOffset offset, Void value) {} - -template -inline void StructBuilder::setDataField(StructDataOffset offset, - kj::NoInfer value, Mask m) { - setDataField >(offset, mask(value, m)); -} - -inline PointerBuilder StructBuilder::getPointerField(StructPointerOffset ptrIndex) { - // Hacky because WirePointer is defined in the .c++ file (so is incomplete here). - return PointerBuilder(segment, capTable, reinterpret_cast( - reinterpret_cast(pointers) + ptrIndex * WORDS_PER_POINTER)); -} - -// ------------------------------------------------------------------- - -inline kj::ArrayPtr StructReader::getDataSectionAsBlob() { - return kj::ArrayPtr(reinterpret_cast(data), - unbound(dataSize / BITS_PER_BYTE / BYTES)); -} - -inline _::ListReader StructReader::getPointerSectionAsList() { - return _::ListReader(segment, capTable, pointers, pointerCount * (ONE * ELEMENTS / POINTERS), - ONE * POINTERS * BITS_PER_POINTER / ELEMENTS, ZERO * BITS, ONE * POINTERS, - ElementSize::POINTER, nestingLimit); -} - -template -inline bool StructReader::hasDataField(StructDataOffset offset) const { - return getDataField>(offset) != 0; -} - -template <> -inline bool StructReader::hasDataField(StructDataOffset offset) const { - return false; -} - -template -inline T StructReader::getDataField(StructDataOffset offset) const { - if ((offset + ONE * ELEMENTS) * capnp::bitsPerElement() <= dataSize) { - return reinterpret_cast*>(data)[unbound(offset / ELEMENTS)].get(); - } else { - return static_cast(0); - } -} - -template <> -inline bool StructReader::getDataField(StructDataOffset offset) const { - auto boffset = offset * (ONE * BITS / ELEMENTS); - if (boffset < dataSize) { - const byte* b = reinterpret_cast(data) + boffset / BITS_PER_BYTE; - return (*reinterpret_cast(b) & - unbound(ONE << (boffset % BITS_PER_BYTE / BITS))) != 0; - } else { - return false; - } -} - -template <> -inline Void StructReader::getDataField(StructDataOffset offset) const { - return VOID; -} - -template -T StructReader::getDataField(StructDataOffset offset, Mask mask) const { - return unmask(getDataField >(offset), mask); -} - -inline PointerReader StructReader::getPointerField(StructPointerOffset ptrIndex) const { - if (ptrIndex < pointerCount) { - // Hacky because WirePointer is defined in the .c++ file (so is incomplete here). - return PointerReader(segment, capTable, reinterpret_cast( - reinterpret_cast(pointers) + ptrIndex * WORDS_PER_POINTER), nestingLimit); - } else{ - return PointerReader(); - } -} - -// ------------------------------------------------------------------- - -inline ListElementCount ListBuilder::size() const { return elementCount; } - -template -inline T ListBuilder::getDataElement(ElementCount index) { - return reinterpret_cast*>( - ptr + upgradeBound(index) * step / BITS_PER_BYTE)->get(); - - // TODO(perf): Benchmark this alternate implementation, which I suspect may make better use of - // the x86 SIB byte. Also use it for all the other getData/setData implementations below, and - // the various non-inline methods that look up pointers. - // Also if using this, consider changing ptr back to void* instead of byte*. -// return reinterpret_cast*>(ptr)[ -// index / ELEMENTS * (step / capnp::bitsPerElement())].get(); -} - -template <> -inline bool ListBuilder::getDataElement(ElementCount index) { - // Ignore step for bit lists because bit lists cannot be upgraded to struct lists. - auto bindex = index * (ONE * BITS / ELEMENTS); - byte* b = ptr + bindex / BITS_PER_BYTE; - return (*reinterpret_cast(b) & - unbound(ONE << (bindex % BITS_PER_BYTE / BITS))) != 0; -} - -template <> -inline Void ListBuilder::getDataElement(ElementCount index) { - return VOID; -} - -template -inline void ListBuilder::setDataElement(ElementCount index, kj::NoInfer value) { - reinterpret_cast*>( - ptr + upgradeBound(index) * step / BITS_PER_BYTE)->set(value); -} - -#if CAPNP_CANONICALIZE_NAN -// Use mask() on floats and doubles to make sure we canonicalize NaNs. -template <> -inline void ListBuilder::setDataElement(ElementCount index, float value) { - setDataElement(index, mask(value, 0)); -} -template <> -inline void ListBuilder::setDataElement(ElementCount index, double value) { - setDataElement(index, mask(value, 0)); -} -#endif - -template <> -inline void ListBuilder::setDataElement(ElementCount index, bool value) { - // Ignore stepBytes for bit lists because bit lists cannot be upgraded to struct lists. - auto bindex = index * (ONE * BITS / ELEMENTS); - byte* b = ptr + bindex / BITS_PER_BYTE; - auto bitnum = bindex % BITS_PER_BYTE / BITS; - *reinterpret_cast(b) = (*reinterpret_cast(b) & ~(1 << unbound(bitnum))) - | (static_cast(value) << unbound(bitnum)); -} - -template <> -inline void ListBuilder::setDataElement(ElementCount index, Void value) {} - -inline PointerBuilder ListBuilder::getPointerElement(ElementCount index) { - return PointerBuilder(segment, capTable, reinterpret_cast(ptr + - upgradeBound(index) * step / BITS_PER_BYTE)); -} - -// ------------------------------------------------------------------- - -inline ListElementCount ListReader::size() const { return elementCount; } - -template -inline T ListReader::getDataElement(ElementCount index) const { - return reinterpret_cast*>( - ptr + upgradeBound(index) * step / BITS_PER_BYTE)->get(); -} - -template <> -inline bool ListReader::getDataElement(ElementCount index) const { - // Ignore step for bit lists because bit lists cannot be upgraded to struct lists. - auto bindex = index * (ONE * BITS / ELEMENTS); - const byte* b = ptr + bindex / BITS_PER_BYTE; - return (*reinterpret_cast(b) & - unbound(ONE << (bindex % BITS_PER_BYTE / BITS))) != 0; -} - -template <> -inline Void ListReader::getDataElement(ElementCount index) const { - return VOID; -} - -inline PointerReader ListReader::getPointerElement(ElementCount index) const { - return PointerReader(segment, capTable, reinterpret_cast( - ptr + upgradeBound(index) * step / BITS_PER_BYTE), nestingLimit); -} - -// ------------------------------------------------------------------- - -inline OrphanBuilder::OrphanBuilder(OrphanBuilder&& other) noexcept - : segment(other.segment), capTable(other.capTable), location(other.location) { - memcpy(&tag, &other.tag, sizeof(tag)); // Needs memcpy to comply with aliasing rules. - other.segment = nullptr; - other.location = nullptr; -} - -inline OrphanBuilder::~OrphanBuilder() noexcept(false) { - if (segment != nullptr) euthanize(); -} - -inline OrphanBuilder& OrphanBuilder::operator=(OrphanBuilder&& other) { - // With normal smart pointers, it's important to handle the case where the incoming pointer - // is actually transitively owned by this one. In this case, euthanize() would destroy `other` - // before we copied it. This isn't possible in the case of `OrphanBuilder` because it only - // owns message objects, and `other` is not itself a message object, therefore cannot possibly - // be transitively owned by `this`. - - if (segment != nullptr) euthanize(); - segment = other.segment; - capTable = other.capTable; - location = other.location; - memcpy(&tag, &other.tag, sizeof(tag)); // Needs memcpy to comply with aliasing rules. - other.segment = nullptr; - other.location = nullptr; - return *this; -} - -} // namespace _ (private) -} // namespace capnp - -#endif // CAPNP_LAYOUT_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/list.h b/phonelibs/capnp-cpp/include/capnp/list.h deleted file mode 100644 index 23e5e6c10e661f..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/list.h +++ /dev/null @@ -1,546 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_LIST_H_ -#define CAPNP_LIST_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "layout.h" -#include "orphan.h" -#include -#ifdef KJ_STD_COMPAT -#include -#endif // KJ_STD_COMPAT - -namespace capnp { -namespace _ { // private - -template -class TemporaryPointer { - // This class is a little hack which lets us define operator->() in cases where it needs to - // return a pointer to a temporary value. We instead construct a TemporaryPointer and return that - // (by value). The compiler then invokes operator->() on the TemporaryPointer, which itself is - // able to return a real pointer to its member. - -public: - TemporaryPointer(T&& value): value(kj::mv(value)) {} - TemporaryPointer(const T& value): value(value) {} - - inline T* operator->() { return &value; } -private: - T value; -}; - -template -class IndexingIterator { -public: - IndexingIterator() = default; - - inline Element operator*() const { return (*container)[index]; } - inline TemporaryPointer operator->() const { - return TemporaryPointer((*container)[index]); - } - inline Element operator[]( int off) const { return (*container)[index]; } - inline Element operator[](uint off) const { return (*container)[index]; } - - inline IndexingIterator& operator++() { ++index; return *this; } - inline IndexingIterator operator++(int) { IndexingIterator other = *this; ++index; return other; } - inline IndexingIterator& operator--() { --index; return *this; } - inline IndexingIterator operator--(int) { IndexingIterator other = *this; --index; return other; } - - inline IndexingIterator operator+(uint amount) const { return IndexingIterator(container, index + amount); } - inline IndexingIterator operator-(uint amount) const { return IndexingIterator(container, index - amount); } - inline IndexingIterator operator+( int amount) const { return IndexingIterator(container, index + amount); } - inline IndexingIterator operator-( int amount) const { return IndexingIterator(container, index - amount); } - - inline int operator-(const IndexingIterator& other) const { return index - other.index; } - - inline IndexingIterator& operator+=(uint amount) { index += amount; return *this; } - inline IndexingIterator& operator-=(uint amount) { index -= amount; return *this; } - inline IndexingIterator& operator+=( int amount) { index += amount; return *this; } - inline IndexingIterator& operator-=( int amount) { index -= amount; return *this; } - - // STL says comparing iterators of different containers is not allowed, so we only compare - // indices here. - inline bool operator==(const IndexingIterator& other) const { return index == other.index; } - inline bool operator!=(const IndexingIterator& other) const { return index != other.index; } - inline bool operator<=(const IndexingIterator& other) const { return index <= other.index; } - inline bool operator>=(const IndexingIterator& other) const { return index >= other.index; } - inline bool operator< (const IndexingIterator& other) const { return index < other.index; } - inline bool operator> (const IndexingIterator& other) const { return index > other.index; } - -private: - Container* container; - uint index; - - friend Container; - inline IndexingIterator(Container* container, uint index) - : container(container), index(index) {} -}; - -} // namespace _ (private) - -template -struct List { - // List of primitives. - - List() = delete; - - class Reader { - public: - typedef List Reads; - - inline Reader(): reader(_::elementSizeForType()) {} - inline explicit Reader(_::ListReader reader): reader(reader) {} - - inline uint size() const { return unbound(reader.size() / ELEMENTS); } - inline T operator[](uint index) const { - KJ_IREQUIRE(index < size()); - return reader.template getDataElement(bounded(index) * ELEMENTS); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - - private: - _::ListReader reader; - template - friend struct _::PointerHelpers; - template - friend struct List; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Builder { - public: - typedef List Builds; - - inline Builder(): builder(_::elementSizeForType()) {} - inline Builder(decltype(nullptr)): Builder() {} - inline explicit Builder(_::ListBuilder builder): builder(builder) {} - - inline operator Reader() const { return Reader(builder.asReader()); } - inline Reader asReader() const { return Reader(builder.asReader()); } - - inline uint size() const { return unbound(builder.size() / ELEMENTS); } - inline T operator[](uint index) { - KJ_IREQUIRE(index < size()); - return builder.template getDataElement(bounded(index) * ELEMENTS); - } - inline void set(uint index, T value) { - // Alas, it is not possible to make operator[] return a reference to which you can assign, - // since the encoded representation does not necessarily match the compiler's representation - // of the type. We can't even return a clever class that implements operator T() and - // operator=() because it will lead to surprising behavior when using type inference (e.g. - // calling a template function with inferred argument types, or using "auto" or "decltype"). - - builder.template setDataElement(bounded(index) * ELEMENTS, value); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - - private: - _::ListBuilder builder; - template - friend struct _::PointerHelpers; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Pipeline {}; - -private: - inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { - return builder.initList(_::elementSizeForType(), bounded(size) * ELEMENTS); - } - inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { - return builder.getList(_::elementSizeForType(), defaultValue); - } - inline static _::ListReader getFromPointer( - const _::PointerReader& reader, const word* defaultValue) { - return reader.getList(_::elementSizeForType(), defaultValue); - } - - template - friend struct List; - template - friend struct _::PointerHelpers; -}; - -template -struct List: public List {}; - -template -struct List { - // List of structs. - - List() = delete; - - class Reader { - public: - typedef List Reads; - - inline Reader(): reader(ElementSize::INLINE_COMPOSITE) {} - inline explicit Reader(_::ListReader reader): reader(reader) {} - - inline uint size() const { return unbound(reader.size() / ELEMENTS); } - inline typename T::Reader operator[](uint index) const { - KJ_IREQUIRE(index < size()); - return typename T::Reader(reader.getStructElement(bounded(index) * ELEMENTS)); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - - private: - _::ListReader reader; - template - friend struct _::PointerHelpers; - template - friend struct List; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Builder { - public: - typedef List Builds; - - inline Builder(): builder(ElementSize::INLINE_COMPOSITE) {} - inline Builder(decltype(nullptr)): Builder() {} - inline explicit Builder(_::ListBuilder builder): builder(builder) {} - - inline operator Reader() const { return Reader(builder.asReader()); } - inline Reader asReader() const { return Reader(builder.asReader()); } - - inline uint size() const { return unbound(builder.size() / ELEMENTS); } - inline typename T::Builder operator[](uint index) { - KJ_IREQUIRE(index < size()); - return typename T::Builder(builder.getStructElement(bounded(index) * ELEMENTS)); - } - - inline void adoptWithCaveats(uint index, Orphan&& orphan) { - // Mostly behaves like you'd expect `adopt` to behave, but with two caveats originating from - // the fact that structs in a struct list are allocated inline rather than by pointer: - // * This actually performs a shallow copy, effectively adopting each of the orphan's - // children rather than adopting the orphan itself. The orphan ends up being discarded, - // possibly wasting space in the message object. - // * If the orphan is larger than the target struct -- say, because the orphan was built - // using a newer version of the schema that has additional fields -- it will be truncated, - // losing data. - - KJ_IREQUIRE(index < size()); - - // We pass a zero-valued StructSize to asStruct() because we do not want the struct to be - // expanded under any circumstances. We're just going to throw it away anyway, and - // transferContentFrom() already carefully compares the struct sizes before transferring. - builder.getStructElement(bounded(index) * ELEMENTS).transferContentFrom( - orphan.builder.asStruct(_::StructSize(ZERO * WORDS, ZERO * POINTERS))); - } - inline void setWithCaveats(uint index, const typename T::Reader& reader) { - // Mostly behaves like you'd expect `set` to behave, but with a caveat originating from - // the fact that structs in a struct list are allocated inline rather than by pointer: - // If the source struct is larger than the target struct -- say, because the source was built - // using a newer version of the schema that has additional fields -- it will be truncated, - // losing data. - // - // Note: If you are trying to concatenate some lists, use Orphanage::newOrphanConcat() to - // do it without losing any data in case the source lists come from a newer version of the - // protocol. (Plus, it's easier to use anyhow.) - - KJ_IREQUIRE(index < size()); - builder.getStructElement(bounded(index) * ELEMENTS).copyContentFrom(reader._reader); - } - - // There are no init(), set(), adopt(), or disown() methods for lists of structs because the - // elements of the list are inlined and are initialized when the list is initialized. This - // means that init() would be redundant, and set() would risk data loss if the input struct - // were from a newer version of the protocol. - - typedef _::IndexingIterator Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - - private: - _::ListBuilder builder; - template - friend struct _::PointerHelpers; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Pipeline {}; - -private: - inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { - return builder.initStructList(bounded(size) * ELEMENTS, _::structSize()); - } - inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { - return builder.getStructList(_::structSize(), defaultValue); - } - inline static _::ListReader getFromPointer( - const _::PointerReader& reader, const word* defaultValue) { - return reader.getList(ElementSize::INLINE_COMPOSITE, defaultValue); - } - - template - friend struct List; - template - friend struct _::PointerHelpers; -}; - -template -struct List, Kind::LIST> { - // List of lists. - - List() = delete; - - class Reader { - public: - typedef List> Reads; - - inline Reader(): reader(ElementSize::POINTER) {} - inline explicit Reader(_::ListReader reader): reader(reader) {} - - inline uint size() const { return unbound(reader.size() / ELEMENTS); } - inline typename List::Reader operator[](uint index) const { - KJ_IREQUIRE(index < size()); - return typename List::Reader(_::PointerHelpers>::get( - reader.getPointerElement(bounded(index) * ELEMENTS))); - } - - typedef _::IndexingIterator::Reader> Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - - private: - _::ListReader reader; - template - friend struct _::PointerHelpers; - template - friend struct List; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Builder { - public: - typedef List> Builds; - - inline Builder(): builder(ElementSize::POINTER) {} - inline Builder(decltype(nullptr)): Builder() {} - inline explicit Builder(_::ListBuilder builder): builder(builder) {} - - inline operator Reader() const { return Reader(builder.asReader()); } - inline Reader asReader() const { return Reader(builder.asReader()); } - - inline uint size() const { return unbound(builder.size() / ELEMENTS); } - inline typename List::Builder operator[](uint index) { - KJ_IREQUIRE(index < size()); - return typename List::Builder(_::PointerHelpers>::get( - builder.getPointerElement(bounded(index) * ELEMENTS))); - } - inline typename List::Builder init(uint index, uint size) { - KJ_IREQUIRE(index < this->size()); - return typename List::Builder(_::PointerHelpers>::init( - builder.getPointerElement(bounded(index) * ELEMENTS), size)); - } - inline void set(uint index, typename List::Reader value) { - KJ_IREQUIRE(index < size()); - builder.getPointerElement(bounded(index) * ELEMENTS).setList(value.reader); - } - void set(uint index, std::initializer_list> value) { - KJ_IREQUIRE(index < size()); - auto l = init(index, value.size()); - uint i = 0; - for (auto& element: value) { - l.set(i++, element); - } - } - inline void adopt(uint index, Orphan&& value) { - KJ_IREQUIRE(index < size()); - builder.getPointerElement(bounded(index) * ELEMENTS).adopt(kj::mv(value.builder)); - } - inline Orphan disown(uint index) { - KJ_IREQUIRE(index < size()); - return Orphan(builder.getPointerElement(bounded(index) * ELEMENTS).disown()); - } - - typedef _::IndexingIterator::Builder> Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - - private: - _::ListBuilder builder; - template - friend struct _::PointerHelpers; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Pipeline {}; - -private: - inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { - return builder.initList(ElementSize::POINTER, bounded(size) * ELEMENTS); - } - inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { - return builder.getList(ElementSize::POINTER, defaultValue); - } - inline static _::ListReader getFromPointer( - const _::PointerReader& reader, const word* defaultValue) { - return reader.getList(ElementSize::POINTER, defaultValue); - } - - template - friend struct List; - template - friend struct _::PointerHelpers; -}; - -template -struct List { - List() = delete; - - class Reader { - public: - typedef List Reads; - - inline Reader(): reader(ElementSize::POINTER) {} - inline explicit Reader(_::ListReader reader): reader(reader) {} - - inline uint size() const { return unbound(reader.size() / ELEMENTS); } - inline typename T::Reader operator[](uint index) const { - KJ_IREQUIRE(index < size()); - return reader.getPointerElement(bounded(index) * ELEMENTS) - .template getBlob(nullptr, ZERO * BYTES); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - - private: - _::ListReader reader; - template - friend struct _::PointerHelpers; - template - friend struct List; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Builder { - public: - typedef List Builds; - - inline Builder(): builder(ElementSize::POINTER) {} - inline Builder(decltype(nullptr)): Builder() {} - inline explicit Builder(_::ListBuilder builder): builder(builder) {} - - inline operator Reader() const { return Reader(builder.asReader()); } - inline Reader asReader() const { return Reader(builder.asReader()); } - - inline uint size() const { return unbound(builder.size() / ELEMENTS); } - inline typename T::Builder operator[](uint index) { - KJ_IREQUIRE(index < size()); - return builder.getPointerElement(bounded(index) * ELEMENTS) - .template getBlob(nullptr, ZERO * BYTES); - } - inline void set(uint index, typename T::Reader value) { - KJ_IREQUIRE(index < size()); - builder.getPointerElement(bounded(index) * ELEMENTS).template setBlob(value); - } - inline typename T::Builder init(uint index, uint size) { - KJ_IREQUIRE(index < this->size()); - return builder.getPointerElement(bounded(index) * ELEMENTS) - .template initBlob(bounded(size) * BYTES); - } - inline void adopt(uint index, Orphan&& value) { - KJ_IREQUIRE(index < size()); - builder.getPointerElement(bounded(index) * ELEMENTS).adopt(kj::mv(value.builder)); - } - inline Orphan disown(uint index) { - KJ_IREQUIRE(index < size()); - return Orphan(builder.getPointerElement(bounded(index) * ELEMENTS).disown()); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() { return Iterator(this, 0); } - inline Iterator end() { return Iterator(this, size()); } - - private: - _::ListBuilder builder; - template - friend struct _::PointerHelpers; - friend class Orphanage; - template - friend struct ToDynamic_; - }; - - class Pipeline {}; - -private: - inline static _::ListBuilder initPointer(_::PointerBuilder builder, uint size) { - return builder.initList(ElementSize::POINTER, bounded(size) * ELEMENTS); - } - inline static _::ListBuilder getFromPointer(_::PointerBuilder builder, const word* defaultValue) { - return builder.getList(ElementSize::POINTER, defaultValue); - } - inline static _::ListReader getFromPointer( - const _::PointerReader& reader, const word* defaultValue) { - return reader.getList(ElementSize::POINTER, defaultValue); - } - - template - friend struct List; - template - friend struct _::PointerHelpers; -}; - -} // namespace capnp - -#ifdef KJ_STD_COMPAT -namespace std { - -template -struct iterator_traits> - : public std::iterator {}; - -} // namespace std -#endif // KJ_STD_COMPAT - -#endif // CAPNP_LIST_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/membrane.h b/phonelibs/capnp-cpp/include/capnp/membrane.h deleted file mode 100644 index 6fa8a1335d9418..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/membrane.h +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 2015 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_MEMBRANE_H_ -#define CAPNP_MEMBRANE_H_ -// In capability theory, a "membrane" is a wrapper around a capability which (usually) forwards -// calls but recursively wraps capabilities in those calls in the same membrane. The purpose of a -// membrane is to enforce a barrier between two capabilities that cannot be bypassed by merely -// introducing new objects. -// -// The most common use case for a membrane is revocation: Say Alice wants to give Bob a capability -// to access Carol, but wants to be able to revoke this capability later. Alice can accomplish this -// by wrapping Carol in a revokable wrapper which passes through calls until such a time as Alice -// indicates it should be revoked, after which all calls through the wrapper will throw exceptions. -// However, a naive wrapper approach has a problem: if Bob makes a call to Carol and sends a new -// capability in that call, or if Carol returns a capability to Bob in the response to a call, then -// the two are now able to communicate using this new capability, which Alice cannot revoke. In -// order to avoid this problem, Alice must use not just a wrapper but a "membrane", which -// recursively wraps all objects that pass through it in either direction. Thus, all connections -// formed between Bob and Carol (originating from Alice's original introduction) can be revoked -// together by revoking the membrane. -// -// Note that when a capability is passed into a membrane and then passed back out, the result is -// the original capability, not a double-membraned capability. This means that in our revocation -// example, if Bob uses his capability to Carol to obtain another capability from her, then send -// it back to her, the capability Carol receives back will NOT be revoked when Bob's access to -// Carol is revoked. Thus Bob can create long-term irrevocable connections. In most practical use -// cases, this is what you want. APIs commonly rely on the fact that a capability obtained and then -// passed back can be recognized as the original capability. -// -// Mark Miller on membranes: http://www.eros-os.org/pipermail/e-lang/2003-January/008434.html - -#include "capability.h" - -namespace capnp { - -class MembranePolicy { - // Applications may implement this interface to define a membrane policy, which allows some - // calls crossing the membrane to be blocked or redirected. - -public: - virtual kj::Maybe inboundCall( - uint64_t interfaceId, uint16_t methodId, Capability::Client target) = 0; - // Given an inbound call (a call originating "outside" the membrane destined for an object - // "inside" the membrane), decides what to do with it. The policy may: - // - // - Return null to indicate that the call should proceed to the destination. All capabilities - // in the parameters or result will be properly wrapped in the same membrane. - // - Return a capability to have the call redirected to that capability. Note that the redirect - // capability will be treated as outside the membrane, so the params and results will not be - // auto-wrapped; however, the callee can easily wrap the returned capability in the membrane - // itself before returning to achieve this effect. - // - Throw an exception to cause the call to fail with that exception. - // - // `target` is the underlying capability (*inside* the membrane) for which the call is destined. - // Generally, the only way you should use `target` is to wrap it in some capability which you - // return as a redirect. The redirect capability may modify the call in some way and send it to - // `target`. Be careful to use `copyIntoMembrane()` and `copyOutOfMembrane()` as appropriate when - // copying parameters or results across the membrane. - // - // Note that since `target` is inside the capability, if you were to directly return it (rather - // than return null), the effect would be that the membrane would be broken: the call would - // proceed directly and any new capabilities introduced through it would not be membraned. You - // generally should not do that. - - virtual kj::Maybe outboundCall( - uint64_t interfaceId, uint16_t methodId, Capability::Client target) = 0; - // Like `inboundCall()`, but applies to calls originating *inside* the membrane and terminating - // outside. - // - // Note: It is strongly recommended that `outboundCall()` returns null in exactly the same cases - // that `inboundCall()` return null. Conversely, for any case where `inboundCall()` would - // redirect or throw, `outboundCall()` should also redirect or throw. Otherwise, you can run - // into inconsistent behavion when a promise is returned across a membrane, and that promise - // later resolves to a capability on the other side of the membrane: calls on the promise - // will enter and then exit the membrane, but calls on the eventual resolution will not cross - // the membrane at all, so it is important that these two cases behave the same. - - virtual kj::Own addRef() = 0; - // Return a new owned pointer to the same policy. - // - // Typically an implementation of MembranePolicy should also inherit kj::Refcounted and implement - // `addRef()` as `return kj::addRef(*this);`. - // - // Note that the membraning system considers two membranes created with the same MembranePolicy - // object actually to be the *same* membrane. This is relevant when an object passes into the - // membrane and then back out (or out and then back in): instead of double-wrapping the object, - // the wrapping will be removed. -}; - -Capability::Client membrane(Capability::Client inner, kj::Own policy); -// Wrap `inner` in a membrane specified by `policy`. `inner` is considered "inside" the membrane, -// while the returned capability should only be called from outside the membrane. - -Capability::Client reverseMembrane(Capability::Client outer, kj::Own policy); -// Like `membrane` but treat the input capability as "outside" the membrane, and return a -// capability appropriate for use inside. -// -// Applications typically won't use this directly; the membraning code automatically sets up -// reverse membranes where needed. - -template -ClientType membrane(ClientType inner, kj::Own policy); -template -ClientType reverseMembrane(ClientType inner, kj::Own policy); -// Convenience templates which return the same interface type as the input. - -template -typename ServerType::Serves::Client membrane( - kj::Own inner, kj::Own policy); -template -typename ServerType::Serves::Client reverseMembrane( - kj::Own inner, kj::Own policy); -// Convenience templates which input a capability server type and return the appropriate client -// type. - -template -Orphan::Reads> copyIntoMembrane( - Reader&& from, Orphanage to, kj::Own policy); -// Copy a Cap'n Proto object (e.g. struct or list), adding the given membrane to any capabilities -// found within it. `from` is interpreted as "outside" the membrane while `to` is "inside". - -template -Orphan::Reads> copyOutOfMembrane( - Reader&& from, Orphanage to, kj::Own policy); -// Like copyIntoMembrane() except that `from` is "inside" the membrane and `to` is "outside". - -// ======================================================================================= -// inline implementation details - -template -ClientType membrane(ClientType inner, kj::Own policy) { - return membrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) - .castAs(); -} -template -ClientType reverseMembrane(ClientType inner, kj::Own policy) { - return reverseMembrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) - .castAs(); -} - -template -typename ServerType::Serves::Client membrane( - kj::Own inner, kj::Own policy) { - return membrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) - .castAs(); -} -template -typename ServerType::Serves::Client reverseMembrane( - kj::Own inner, kj::Own policy) { - return reverseMembrane(Capability::Client(kj::mv(inner)), kj::mv(policy)) - .castAs(); -} - -namespace _ { // private - -OrphanBuilder copyOutOfMembrane(PointerReader from, Orphanage to, - kj::Own policy, bool reverse); -OrphanBuilder copyOutOfMembrane(StructReader from, Orphanage to, - kj::Own policy, bool reverse); -OrphanBuilder copyOutOfMembrane(ListReader from, Orphanage to, - kj::Own policy, bool reverse); - -} // namespace _ (private) - -template -Orphan::Reads> copyIntoMembrane( - Reader&& from, Orphanage to, kj::Own policy) { - return _::copyOutOfMembrane( - _::PointerHelpers::Reads>::getInternalReader(from), - to, kj::mv(policy), true); -} - -template -Orphan::Reads> copyOutOfMembrane( - Reader&& from, Orphanage to, kj::Own policy) { - return _::copyOutOfMembrane( - _::PointerHelpers::Reads>::getInternalReader(from), - to, kj::mv(policy), false); -} - -} // namespace capnp - -#endif // CAPNP_MEMBRANE_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/message.h b/phonelibs/capnp-cpp/include/capnp/message.h deleted file mode 100644 index b4d5e9fc82230d..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/message.h +++ /dev/null @@ -1,508 +0,0 @@ -// Copyright (c) 2013-2016 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#include -#include -#include -#include -#include "common.h" -#include "layout.h" -#include "any.h" - -#ifndef CAPNP_MESSAGE_H_ -#define CAPNP_MESSAGE_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -namespace capnp { - -namespace _ { // private - class ReaderArena; - class BuilderArena; -} - -class StructSchema; -class Orphanage; -template -class Orphan; - -// ======================================================================================= - -struct ReaderOptions { - // Options controlling how data is read. - - uint64_t traversalLimitInWords = 8 * 1024 * 1024; - // Limits how many total words of data are allowed to be traversed. Traversal is counted when - // a new struct or list builder is obtained, e.g. from a get() accessor. This means that calling - // the getter for the same sub-struct multiple times will cause it to be double-counted. Once - // the traversal limit is reached, an error will be reported. - // - // This limit exists for security reasons. It is possible for an attacker to construct a message - // in which multiple pointers point at the same location. This is technically invalid, but hard - // to detect. Using such a message, an attacker could cause a message which is small on the wire - // to appear much larger when actually traversed, possibly exhausting server resources leading to - // denial-of-service. - // - // It makes sense to set a traversal limit that is much larger than the underlying message. - // Together with sensible coding practices (e.g. trying to avoid calling sub-object getters - // multiple times, which is expensive anyway), this should provide adequate protection without - // inconvenience. - // - // The default limit is 64 MiB. This may or may not be a sensible number for any given use case, - // but probably at least prevents easy exploitation while also avoiding causing problems in most - // typical cases. - - int nestingLimit = 64; - // Limits how deeply-nested a message structure can be, e.g. structs containing other structs or - // lists of structs. - // - // Like the traversal limit, this limit exists for security reasons. Since it is common to use - // recursive code to traverse recursive data structures, an attacker could easily cause a stack - // overflow by sending a very-deeply-nested (or even cyclic) message, without the message even - // being very large. The default limit of 64 is probably low enough to prevent any chance of - // stack overflow, yet high enough that it is never a problem in practice. -}; - -class MessageReader { - // Abstract interface for an object used to read a Cap'n Proto message. Subclasses of - // MessageReader are responsible for reading the raw, flat message content. Callers should - // usually call `messageReader.getRoot()` to get a `MyStructType::Reader` - // representing the root of the message, then use that to traverse the message content. - // - // Some common subclasses of `MessageReader` include `SegmentArrayMessageReader`, whose - // constructor accepts pointers to the raw data, and `StreamFdMessageReader` (from - // `serialize.h`), which reads the message from a file descriptor. One might implement other - // subclasses to handle things like reading from shared memory segments, mmap()ed files, etc. - -public: - MessageReader(ReaderOptions options); - // It is suggested that subclasses take ReaderOptions as a constructor parameter, but give it a - // default value of "ReaderOptions()". The base class constructor doesn't have a default value - // in order to remind subclasses that they really need to give the user a way to provide this. - - virtual ~MessageReader() noexcept(false); - - virtual kj::ArrayPtr getSegment(uint id) = 0; - // Gets the segment with the given ID, or returns null if no such segment exists. This method - // will be called at most once for each segment ID. - - inline const ReaderOptions& getOptions(); - // Get the options passed to the constructor. - - template - typename RootType::Reader getRoot(); - // Get the root struct of the message, interpreting it as the given struct type. - - template - typename RootType::Reader getRoot(SchemaType schema); - // Dynamically interpret the root struct of the message using the given schema (a StructSchema). - // RootType in this case must be DynamicStruct, and you must #include to - // use this. - - bool isCanonical(); - // Returns whether the message encoded in the reader is in canonical form. - -private: - ReaderOptions options; - - // Space in which we can construct a ReaderArena. We don't use ReaderArena directly here - // because we don't want clients to have to #include arena.h, which itself includes a bunch of - // big STL headers. We don't use a pointer to a ReaderArena because that would require an - // extra malloc on every message which could be expensive when processing small messages. - void* arenaSpace[15 + sizeof(kj::MutexGuarded) / sizeof(void*)]; - bool allocatedArena; - - _::ReaderArena* arena() { return reinterpret_cast<_::ReaderArena*>(arenaSpace); } - AnyPointer::Reader getRootInternal(); -}; - -class MessageBuilder { - // Abstract interface for an object used to allocate and build a message. Subclasses of - // MessageBuilder are responsible for allocating the space in which the message will be written. - // The most common subclass is `MallocMessageBuilder`, but other subclasses may be used to do - // tricky things like allocate messages in shared memory or mmap()ed files. - // - // Creating a new message ususually means allocating a new MessageBuilder (ideally on the stack) - // and then calling `messageBuilder.initRoot()` to get a `MyStructType::Builder`. - // That, in turn, can be used to fill in the message content. When done, you can call - // `messageBuilder.getSegmentsForOutput()` to get a list of flat data arrays containing the - // message. - -public: - MessageBuilder(); - virtual ~MessageBuilder() noexcept(false); - KJ_DISALLOW_COPY(MessageBuilder); - - struct SegmentInit { - kj::ArrayPtr space; - - size_t wordsUsed; - // Number of words in `space` which are used; the rest are free space in which additional - // objects may be allocated. - }; - - explicit MessageBuilder(kj::ArrayPtr segments); - // Create a MessageBuilder backed by existing memory. This is an advanced interface that most - // people should not use. THIS METHOD IS INSECURE; see below. - // - // This allows a MessageBuilder to be constructed to modify an in-memory message without first - // making a copy of the content. This is especially useful in conjunction with mmap(). - // - // The contents of each segment must outlive the MessageBuilder, but the SegmentInit array itself - // only need outlive the constructor. - // - // SECURITY: Do not use this in conjunction with untrusted data. This constructor assumes that - // the input message is valid. This constructor is designed to be used with data you control, - // e.g. an mmap'd file which is owned and accessed by only one program. When reading data you - // do not trust, you *must* load it into a Reader and then copy into a Builder as a means of - // validating the content. - // - // WARNING: It is NOT safe to initialize a MessageBuilder in this way from memory that is - // currently in use by another MessageBuilder or MessageReader. Other readers/builders will - // not observe changes to the segment sizes nor newly-allocated segments caused by allocating - // new objects in this message. - - virtual kj::ArrayPtr allocateSegment(uint minimumSize) = 0; - // Allocates an array of at least the given number of words, throwing an exception or crashing if - // this is not possible. It is expected that this method will usually return more space than - // requested, and the caller should use that extra space as much as possible before allocating - // more. The returned space remains valid at least until the MessageBuilder is destroyed. - // - // Cap'n Proto will only call this once at a time, so the subclass need not worry about - // thread-safety. - - template - typename RootType::Builder initRoot(); - // Initialize the root struct of the message as the given struct type. - - template - void setRoot(Reader&& value); - // Set the root struct to a deep copy of the given struct. - - template - typename RootType::Builder getRoot(); - // Get the root struct of the message, interpreting it as the given struct type. - - template - typename RootType::Builder getRoot(SchemaType schema); - // Dynamically interpret the root struct of the message using the given schema (a StructSchema). - // RootType in this case must be DynamicStruct, and you must #include to - // use this. - - template - typename RootType::Builder initRoot(SchemaType schema); - // Dynamically init the root struct of the message using the given schema (a StructSchema). - // RootType in this case must be DynamicStruct, and you must #include to - // use this. - - template - void adoptRoot(Orphan&& orphan); - // Like setRoot() but adopts the orphan without copying. - - kj::ArrayPtr> getSegmentsForOutput(); - // Get the raw data that makes up the message. - - Orphanage getOrphanage(); - - bool isCanonical(); - // Check whether the message builder is in canonical form - -private: - void* arenaSpace[22]; - // Space in which we can construct a BuilderArena. We don't use BuilderArena directly here - // because we don't want clients to have to #include arena.h, which itself includes a bunch of - // big STL headers. We don't use a pointer to a BuilderArena because that would require an - // extra malloc on every message which could be expensive when processing small messages. - - bool allocatedArena = false; - // We have to initialize the arena lazily because when we do so we want to allocate the root - // pointer immediately, and this will allocate a segment, which requires a virtual function - // call on the MessageBuilder. We can't do such a call in the constructor since the subclass - // isn't constructed yet. This is kind of annoying because it means that getOrphanage() is - // not thread-safe, but that shouldn't be a huge deal... - - _::BuilderArena* arena() { return reinterpret_cast<_::BuilderArena*>(arenaSpace); } - _::SegmentBuilder* getRootSegment(); - AnyPointer::Builder getRootInternal(); -}; - -template -typename RootType::Reader readMessageUnchecked(const word* data); -// IF THE INPUT IS INVALID, THIS MAY CRASH, CORRUPT MEMORY, CREATE A SECURITY HOLE IN YOUR APP, -// MURDER YOUR FIRST-BORN CHILD, AND/OR BRING ABOUT ETERNAL DAMNATION ON ALL OF HUMANITY. DO NOT -// USE UNLESS YOU UNDERSTAND THE CONSEQUENCES. -// -// Given a pointer to a known-valid message located in a single contiguous memory segment, -// returns a reader for that message. No bounds-checking will be done while traversing this -// message. Use this only if you have already verified that all pointers are valid and in-bounds, -// and there are no far pointers in the message. -// -// To create a message that can be passed to this function, build a message using a MallocAllocator -// whose preferred segment size is larger than the message size. This guarantees that the message -// will be allocated as a single segment, meaning getSegmentsForOutput() returns a single word -// array. That word array is your message; you may pass a pointer to its first word into -// readMessageUnchecked() to read the message. -// -// This can be particularly handy for embedding messages in generated code: you can -// embed the raw bytes (using AlignedData) then make a Reader for it using this. This is the way -// default values are embedded in code generated by the Cap'n Proto compiler. E.g., if you have -// a message MyMessage, you can read its default value like so: -// MyMessage::Reader reader = Message::readMessageUnchecked(MyMessage::DEFAULT.words); -// -// To sanitize a message from an untrusted source such that it can be safely passed to -// readMessageUnchecked(), use copyToUnchecked(). - -template -void copyToUnchecked(Reader&& reader, kj::ArrayPtr uncheckedBuffer); -// Copy the content of the given reader into the given buffer, such that it can safely be passed to -// readMessageUnchecked(). The buffer's size must be exactly reader.totalSizeInWords() + 1, -// otherwise an exception will be thrown. The buffer must be zero'd before calling. - -template -typename RootType::Reader readDataStruct(kj::ArrayPtr data); -// Interprets the given data as a single, data-only struct. Only primitive fields (booleans, -// numbers, and enums) will be readable; all pointers will be null. This is useful if you want -// to use Cap'n Proto as a language/platform-neutral way to pack some bits. -// -// The input is a word array rather than a byte array to enforce alignment. If you have a byte -// array which you know is word-aligned (or if your platform supports unaligned reads and you don't -// mind the performance penalty), then you can use `reinterpret_cast` to convert a byte array into -// a word array: -// -// kj::arrayPtr(reinterpret_cast(bytes.begin()), -// reinterpret_cast(bytes.end())) - -template -typename kj::ArrayPtr writeDataStruct(BuilderType builder); -// Given a struct builder, get the underlying data section as a word array, suitable for passing -// to `readDataStruct()`. -// -// Note that you may call `.toBytes()` on the returned value to convert to `ArrayPtr`. - -template -static typename Type::Reader defaultValue(); -// Get a default instance of the given struct or list type. -// -// TODO(cleanup): Find a better home for this function? - -// ======================================================================================= - -class SegmentArrayMessageReader: public MessageReader { - // A simple MessageReader that reads from an array of word arrays representing all segments. - // In particular you can read directly from the output of MessageBuilder::getSegmentsForOutput() - // (although it would probably make more sense to call builder.getRoot().asReader() in that case). - -public: - SegmentArrayMessageReader(kj::ArrayPtr> segments, - ReaderOptions options = ReaderOptions()); - // Creates a message pointing at the given segment array, without taking ownership of the - // segments. All arrays passed in must remain valid until the MessageReader is destroyed. - - KJ_DISALLOW_COPY(SegmentArrayMessageReader); - ~SegmentArrayMessageReader() noexcept(false); - - virtual kj::ArrayPtr getSegment(uint id) override; - -private: - kj::ArrayPtr> segments; -}; - -enum class AllocationStrategy: uint8_t { - FIXED_SIZE, - // The builder will prefer to allocate the same amount of space for each segment with no - // heuristic growth. It will still allocate larger segments when the preferred size is too small - // for some single object. This mode is generally not recommended, but can be particularly useful - // for testing in order to force a message to allocate a predictable number of segments. Note - // that you can force every single object in the message to be located in a separate segment by - // using this mode with firstSegmentWords = 0. - - GROW_HEURISTICALLY - // The builder will heuristically decide how much space to allocate for each segment. Each - // allocated segment will be progressively larger than the previous segments on the assumption - // that message sizes are exponentially distributed. The total number of segments that will be - // allocated for a message of size n is O(log n). -}; - -constexpr uint SUGGESTED_FIRST_SEGMENT_WORDS = 1024; -constexpr AllocationStrategy SUGGESTED_ALLOCATION_STRATEGY = AllocationStrategy::GROW_HEURISTICALLY; - -class MallocMessageBuilder: public MessageBuilder { - // A simple MessageBuilder that uses malloc() (actually, calloc()) to allocate segments. This - // implementation should be reasonable for any case that doesn't require writing the message to - // a specific location in memory. - -public: - explicit MallocMessageBuilder(uint firstSegmentWords = SUGGESTED_FIRST_SEGMENT_WORDS, - AllocationStrategy allocationStrategy = SUGGESTED_ALLOCATION_STRATEGY); - // Creates a BuilderContext which allocates at least the given number of words for the first - // segment, and then uses the given strategy to decide how much to allocate for subsequent - // segments. When choosing a value for firstSegmentWords, consider that: - // 1) Reading and writing messages gets slower when multiple segments are involved, so it's good - // if most messages fit in a single segment. - // 2) Unused bytes will not be written to the wire, so generally it is not a big deal to allocate - // more space than you need. It only becomes problematic if you are allocating many messages - // in parallel and thus use lots of memory, or if you allocate so much extra space that just - // zeroing it out becomes a bottleneck. - // The defaults have been chosen to be reasonable for most people, so don't change them unless you - // have reason to believe you need to. - - explicit MallocMessageBuilder(kj::ArrayPtr firstSegment, - AllocationStrategy allocationStrategy = SUGGESTED_ALLOCATION_STRATEGY); - // This version always returns the given array for the first segment, and then proceeds with the - // allocation strategy. This is useful for optimization when building lots of small messages in - // a tight loop: you can reuse the space for the first segment. - // - // firstSegment MUST be zero-initialized. MallocMessageBuilder's destructor will write new zeros - // over any space that was used so that it can be reused. - - KJ_DISALLOW_COPY(MallocMessageBuilder); - virtual ~MallocMessageBuilder() noexcept(false); - - virtual kj::ArrayPtr allocateSegment(uint minimumSize) override; - -private: - uint nextSize; - AllocationStrategy allocationStrategy; - - bool ownFirstSegment; - bool returnedFirstSegment; - - void* firstSegment; - - struct MoreSegments; - kj::Maybe> moreSegments; -}; - -class FlatMessageBuilder: public MessageBuilder { - // THIS IS NOT THE CLASS YOU'RE LOOKING FOR. - // - // If you want to write a message into already-existing scratch space, use `MallocMessageBuilder` - // and pass the scratch space to its constructor. It will then only fall back to malloc() if - // the scratch space is not large enough. - // - // Do NOT use this class unless you really know what you're doing. This class is problematic - // because it requires advance knowledge of the size of your message, which is usually impossible - // to determine without actually building the message. The class was created primarily to - // implement `copyToUnchecked()`, which itself exists only to support other internal parts of - // the Cap'n Proto implementation. - -public: - explicit FlatMessageBuilder(kj::ArrayPtr array); - KJ_DISALLOW_COPY(FlatMessageBuilder); - virtual ~FlatMessageBuilder() noexcept(false); - - void requireFilled(); - // Throws an exception if the flat array is not exactly full. - - virtual kj::ArrayPtr allocateSegment(uint minimumSize) override; - -private: - kj::ArrayPtr array; - bool allocated; -}; - -// ======================================================================================= -// implementation details - -inline const ReaderOptions& MessageReader::getOptions() { - return options; -} - -template -inline typename RootType::Reader MessageReader::getRoot() { - return getRootInternal().getAs(); -} - -template -inline typename RootType::Builder MessageBuilder::initRoot() { - return getRootInternal().initAs(); -} - -template -inline void MessageBuilder::setRoot(Reader&& value) { - getRootInternal().setAs>(value); -} - -template -inline typename RootType::Builder MessageBuilder::getRoot() { - return getRootInternal().getAs(); -} - -template -void MessageBuilder::adoptRoot(Orphan&& orphan) { - return getRootInternal().adopt(kj::mv(orphan)); -} - -template -typename RootType::Reader MessageReader::getRoot(SchemaType schema) { - return getRootInternal().getAs(schema); -} - -template -typename RootType::Builder MessageBuilder::getRoot(SchemaType schema) { - return getRootInternal().getAs(schema); -} - -template -typename RootType::Builder MessageBuilder::initRoot(SchemaType schema) { - return getRootInternal().initAs(schema); -} - -template -typename RootType::Reader readMessageUnchecked(const word* data) { - return AnyPointer::Reader(_::PointerReader::getRootUnchecked(data)).getAs(); -} - -template -void copyToUnchecked(Reader&& reader, kj::ArrayPtr uncheckedBuffer) { - FlatMessageBuilder builder(uncheckedBuffer); - builder.setRoot(kj::fwd(reader)); - builder.requireFilled(); -} - -template -typename RootType::Reader readDataStruct(kj::ArrayPtr data) { - return typename RootType::Reader(_::StructReader(data)); -} - -template -typename kj::ArrayPtr writeDataStruct(BuilderType builder) { - auto bytes = _::PointerHelpers>::getInternalBuilder(kj::mv(builder)) - .getDataSectionAsBlob(); - return kj::arrayPtr(reinterpret_cast(bytes.begin()), - reinterpret_cast(bytes.end())); -} - -template -static typename Type::Reader defaultValue() { - return typename Type::Reader(_::StructReader()); -} - -template -kj::Array canonicalize(T&& reader) { - return _::PointerHelpers>::getInternalReader(reader).canonicalize(); -} - -} // namespace capnp - -#endif // CAPNP_MESSAGE_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/orphan.h b/phonelibs/capnp-cpp/include/capnp/orphan.h deleted file mode 100644 index 8c8b9a6054c885..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/orphan.h +++ /dev/null @@ -1,440 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_ORPHAN_H_ -#define CAPNP_ORPHAN_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "layout.h" - -namespace capnp { - -class StructSchema; -class ListSchema; -struct DynamicStruct; -struct DynamicList; -namespace _ { struct OrphanageInternal; } - -template -class Orphan { - // Represents an object which is allocated within some message builder but has no pointers - // pointing at it. An Orphan can later be "adopted" by some other object as one of that object's - // fields, without having to copy the orphan. For a field `foo` of pointer type, the generated - // code will define builder methods `void adoptFoo(Orphan)` and `Orphan disownFoo()`. - // Orphans can also be created independently of any parent using an Orphanage. - // - // `Orphan` can be moved but not copied, like `Own`, so that it is impossible for one - // orphan to be adopted multiple times. If an orphan is destroyed without being adopted, its - // contents are zero'd out (and possibly reused, if we ever implement the ability to reuse space - // in a message arena). - -public: - Orphan() = default; - KJ_DISALLOW_COPY(Orphan); - Orphan(Orphan&&) = default; - Orphan& operator=(Orphan&&) = default; - inline Orphan(_::OrphanBuilder&& builder): builder(kj::mv(builder)) {} - - inline BuilderFor get(); - // Get the underlying builder. If the orphan is null, this will allocate and return a default - // object rather than crash. This is done for security -- otherwise, you might enable a DoS - // attack any time you disown a field and fail to check if it is null. In the case of structs, - // this means that the orphan is no longer null after get() returns. In the case of lists, - // no actual object is allocated since a simple empty ListBuilder can be returned. - - inline ReaderFor getReader() const; - - inline bool operator==(decltype(nullptr)) const { return builder == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return builder != nullptr; } - - inline void truncate(uint size); - // Resize an object (which must be a list or a blob) to the given size. - // - // If the new size is less than the original, the remaining elements will be discarded. The - // list is never moved in this case. If the list happens to be located at the end of its segment - // (which is always true if the list was the last thing allocated), the removed memory will be - // reclaimed (reducing the messag size), otherwise it is simply zeroed. The reclaiming behavior - // is particularly useful for allocating buffer space when you aren't sure how much space you - // actually need: you can pre-allocate, say, a 4k byte array, read() from a file into it, and - // then truncate it back to the amount of space actually used. - // - // If the new size is greater than the original, the list is extended with default values. If - // the list is the last object in its segment *and* there is enough space left in the segment to - // extend it to cover the new values, then the list is extended in-place. Otherwise, it must be - // moved to a new location, leaving a zero'd hole in the previous space that won't be filled. - // This copy is shallow; sub-objects will simply be reparented, not copied. - // - // Any existing readers or builders pointing at the object are invalidated by this call (even if - // it doesn't move). You must call `get()` or `getReader()` again to get the new, valid pointer. - -private: - _::OrphanBuilder builder; - - template - friend struct _::PointerHelpers; - template - friend struct List; - template - friend class Orphan; - friend class Orphanage; - friend class MessageBuilder; -}; - -class Orphanage: private kj::DisallowConstCopy { - // Use to directly allocate Orphan objects, without having a parent object allocate and then - // disown the object. - -public: - inline Orphanage(): arena(nullptr) {} - - template - static Orphanage getForMessageContaining(BuilderType builder); - // Construct an Orphanage that allocates within the message containing the given Builder. This - // allows the constructed Orphans to be adopted by objects within said message. - // - // This constructor takes the builder rather than having the builder have a getOrphanage() method - // because this is an advanced feature and we don't want to pollute the builder APIs with it. - // - // Note that if you have a direct pointer to the `MessageBuilder`, you can simply call its - // `getOrphanage()` method. - - template - Orphan newOrphan() const; - // Allocate a new orphaned struct. - - template - Orphan newOrphan(uint size) const; - // Allocate a new orphaned list or blob. - - Orphan newOrphan(StructSchema schema) const; - // Dynamically create an orphan struct with the given schema. You must - // #include to use this. - - Orphan newOrphan(ListSchema schema, uint size) const; - // Dynamically create an orphan list with the given schema. You must #include - // to use this. - - template - Orphan> newOrphanCopy(Reader copyFrom) const; - // Allocate a new orphaned object (struct, list, or blob) and initialize it as a copy of the - // given object. - - template - Orphan>>> newOrphanConcat(kj::ArrayPtr lists) const; - template - Orphan>>> newOrphanConcat(kj::ArrayPtr lists) const; - // Given an array of List readers, copy and concatenate the lists, creating a new Orphan. - // - // Note that compared to allocating the list yourself and using `setWithCaveats()` to set each - // item, this method avoids the "caveats": the new list will be allocated with the element size - // being the maximum of that from all the input lists. This is particularly important when - // concatenating struct lists: if the lists were created using a newer version of the protocol - // in which some new fields had been added to the struct, using `setWithCaveats()` would - // truncate off those new fields. - - Orphan referenceExternalData(Data::Reader data) const; - // Creates an Orphan that points at an existing region of memory (e.g. from another message) - // without copying it. There are some SEVERE restrictions on how this can be used: - // - The memory must remain valid until the `MessageBuilder` is destroyed (even if the orphan is - // abandoned). - // - Because the data is const, you will not be allowed to obtain a `Data::Builder` - // for this blob. Any call which would return such a builder will throw an exception. You - // can, however, obtain a Reader, e.g. via orphan.getReader() or from a parent Reader (once - // the orphan is adopted). It is your responsibility to make sure your code can deal with - // these problems when using this optimization; if you can't, allocate a copy instead. - // - `data.begin()` must be aligned to a machine word boundary (32-bit or 64-bit depending on - // the CPU). Any pointer returned by malloc() as well as any data blob obtained from another - // Cap'n Proto message satisfies this. - // - If `data.size()` is not a multiple of 8, extra bytes past data.end() up until the next 8-byte - // boundary will be visible in the raw message when it is written out. Thus, there must be no - // secrets in these bytes. Data blobs obtained from other Cap'n Proto messages should be safe - // as these bytes should be zero (unless the sender had the same problem). - // - // The array will actually become one of the message's segments. The data can thus be adopted - // into the message tree without copying it. This is particularly useful when referencing very - // large blobs, such as whole mmap'd files. - -private: - _::BuilderArena* arena; - _::CapTableBuilder* capTable; - - inline explicit Orphanage(_::BuilderArena* arena, _::CapTableBuilder* capTable) - : arena(arena), capTable(capTable) {} - - template - struct GetInnerBuilder; - template - struct GetInnerReader; - template - struct NewOrphanListImpl; - - friend class MessageBuilder; - friend struct _::OrphanageInternal; -}; - -// ======================================================================================= -// Inline implementation details. - -namespace _ { // private - -template -struct OrphanGetImpl; - -template -struct OrphanGetImpl { - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, _::elementSizeForType()); - } -}; - -template -struct OrphanGetImpl { - static inline typename T::Builder apply(_::OrphanBuilder& builder) { - return typename T::Builder(builder.asStruct(_::structSize())); - } - static inline typename T::Reader applyReader(const _::OrphanBuilder& builder) { - return typename T::Reader(builder.asStructReader(_::structSize())); - } - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, _::structSize()); - } -}; - -#if !CAPNP_LITE -template -struct OrphanGetImpl { - static inline typename T::Client apply(_::OrphanBuilder& builder) { - return typename T::Client(builder.asCapability()); - } - static inline typename T::Client applyReader(const _::OrphanBuilder& builder) { - return typename T::Client(builder.asCapability()); - } - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, ElementSize::POINTER); - } -}; -#endif // !CAPNP_LITE - -template -struct OrphanGetImpl, Kind::LIST> { - static inline typename List::Builder apply(_::OrphanBuilder& builder) { - return typename List::Builder(builder.asList(_::ElementSizeForType::value)); - } - static inline typename List::Reader applyReader(const _::OrphanBuilder& builder) { - return typename List::Reader(builder.asListReader(_::ElementSizeForType::value)); - } - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, ElementSize::POINTER); - } -}; - -template -struct OrphanGetImpl, Kind::LIST> { - static inline typename List::Builder apply(_::OrphanBuilder& builder) { - return typename List::Builder(builder.asStructList(_::structSize())); - } - static inline typename List::Reader applyReader(const _::OrphanBuilder& builder) { - return typename List::Reader(builder.asListReader(_::ElementSizeForType::value)); - } - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, ElementSize::POINTER); - } -}; - -template <> -struct OrphanGetImpl { - static inline Text::Builder apply(_::OrphanBuilder& builder) { - return Text::Builder(builder.asText()); - } - static inline Text::Reader applyReader(const _::OrphanBuilder& builder) { - return Text::Reader(builder.asTextReader()); - } - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, ElementSize::POINTER); - } -}; - -template <> -struct OrphanGetImpl { - static inline Data::Builder apply(_::OrphanBuilder& builder) { - return Data::Builder(builder.asData()); - } - static inline Data::Reader applyReader(const _::OrphanBuilder& builder) { - return Data::Reader(builder.asDataReader()); - } - static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) { - builder.truncate(size, ElementSize::POINTER); - } -}; - -struct OrphanageInternal { - static inline _::BuilderArena* getArena(Orphanage orphanage) { return orphanage.arena; } - static inline _::CapTableBuilder* getCapTable(Orphanage orphanage) { return orphanage.capTable; } -}; - -} // namespace _ (private) - -template -inline BuilderFor Orphan::get() { - return _::OrphanGetImpl::apply(builder); -} - -template -inline ReaderFor Orphan::getReader() const { - return _::OrphanGetImpl::applyReader(builder); -} - -template -inline void Orphan::truncate(uint size) { - _::OrphanGetImpl>::truncateListOf(builder, bounded(size) * ELEMENTS); -} - -template <> -inline void Orphan::truncate(uint size) { - builder.truncateText(bounded(size) * ELEMENTS); -} - -template <> -inline void Orphan::truncate(uint size) { - builder.truncate(bounded(size) * ELEMENTS, ElementSize::BYTE); -} - -template -struct Orphanage::GetInnerBuilder { - static inline _::StructBuilder apply(typename T::Builder& t) { - return t._builder; - } -}; - -template -struct Orphanage::GetInnerBuilder { - static inline _::ListBuilder apply(typename T::Builder& t) { - return t.builder; - } -}; - -template -Orphanage Orphanage::getForMessageContaining(BuilderType builder) { - auto inner = GetInnerBuilder>::apply(builder); - return Orphanage(inner.getArena(), inner.getCapTable()); -} - -template -Orphan Orphanage::newOrphan() const { - return Orphan(_::OrphanBuilder::initStruct(arena, capTable, _::structSize())); -} - -template -struct Orphanage::NewOrphanListImpl> { - static inline _::OrphanBuilder apply( - _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { - return _::OrphanBuilder::initList( - arena, capTable, bounded(size) * ELEMENTS, _::ElementSizeForType::value); - } -}; - -template -struct Orphanage::NewOrphanListImpl> { - static inline _::OrphanBuilder apply( - _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { - return _::OrphanBuilder::initStructList( - arena, capTable, bounded(size) * ELEMENTS, _::structSize()); - } -}; - -template <> -struct Orphanage::NewOrphanListImpl { - static inline _::OrphanBuilder apply( - _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { - return _::OrphanBuilder::initText(arena, capTable, bounded(size) * BYTES); - } -}; - -template <> -struct Orphanage::NewOrphanListImpl { - static inline _::OrphanBuilder apply( - _::BuilderArena* arena, _::CapTableBuilder* capTable, uint size) { - return _::OrphanBuilder::initData(arena, capTable, bounded(size) * BYTES); - } -}; - -template -Orphan Orphanage::newOrphan(uint size) const { - return Orphan(NewOrphanListImpl::apply(arena, capTable, size)); -} - -template -struct Orphanage::GetInnerReader { - static inline _::StructReader apply(const typename T::Reader& t) { - return t._reader; - } -}; - -template -struct Orphanage::GetInnerReader { - static inline _::ListReader apply(const typename T::Reader& t) { - return t.reader; - } -}; - -template -struct Orphanage::GetInnerReader { - static inline const typename T::Reader& apply(const typename T::Reader& t) { - return t; - } -}; - -template -inline Orphan> Orphanage::newOrphanCopy(Reader copyFrom) const { - return Orphan>(_::OrphanBuilder::copy( - arena, capTable, GetInnerReader>::apply(copyFrom))); -} - -template -inline Orphan>>> -Orphanage::newOrphanConcat(kj::ArrayPtr lists) const { - return newOrphanConcat(kj::implicitCast>(lists)); -} -template -inline Orphan>>> -Orphanage::newOrphanConcat(kj::ArrayPtr lists) const { - // Optimization / simplification: Rely on List::Reader containing nothing except a - // _::ListReader. - static_assert(sizeof(T) == sizeof(_::ListReader), "lists are not bare readers?"); - kj::ArrayPtr raw( - reinterpret_cast(lists.begin()), lists.size()); - typedef ListElementType> Element; - return Orphan>( - _::OrphanBuilder::concat(arena, capTable, - _::elementSizeForType(), - _::minStructSizeForElement(), raw)); -} - -inline Orphan Orphanage::referenceExternalData(Data::Reader data) const { - return Orphan(_::OrphanBuilder::referenceExternalData(arena, data)); -} - -} // namespace capnp - -#endif // CAPNP_ORPHAN_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/persistent.capnp b/phonelibs/capnp-cpp/include/capnp/persistent.capnp deleted file mode 100644 index a13b47168a4cc8..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/persistent.capnp +++ /dev/null @@ -1,139 +0,0 @@ -# Copyright (c) 2014 Sandstorm Development Group, Inc. and contributors -# Licensed under the MIT License: -# -# 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. - -@0xb8630836983feed7; - -$import "/capnp/c++.capnp".namespace("capnp"); - -interface Persistent@0xc8cb212fcd9f5691(SturdyRef, Owner) { - # Interface implemented by capabilities that outlive a single connection. A client may save() - # the capability, producing a SturdyRef. The SturdyRef can be stored to disk, then later used to - # obtain a new reference to the capability on a future connection. - # - # The exact format of SturdyRef depends on the "realm" in which the SturdyRef appears. A "realm" - # is an abstract space in which all SturdyRefs have the same format and refer to the same set of - # resources. Every vat is in exactly one realm. All capability clients within that vat must - # produce SturdyRefs of the format appropriate for the realm. - # - # Similarly, every VatNetwork also resides in a particular realm. Usually, a vat's "realm" - # corresponds to the realm of its main VatNetwork. However, a Vat can in fact communicate over - # a VatNetwork in a different realm -- in this case, all SturdyRefs need to be transformed when - # coming or going through said VatNetwork. The RPC system has hooks for registering - # transformation callbacks for this purpose. - # - # Since the format of SturdyRef is realm-dependent, it is not defined here. An application should - # choose an appropriate realm for itself as part of its design. Note that under Sandstorm, every - # application exists in its own realm and is therefore free to define its own SturdyRef format; - # the Sandstorm platform handles translating between realms. - # - # Note that whether a capability is persistent is often orthogonal to its type. In these cases, - # the capability's interface should NOT inherit `Persistent`; instead, just perform a cast at - # runtime. It's not type-safe, but trying to be type-safe in these cases will likely lead to - # tears. In cases where a particular interface only makes sense on persistent capabilities, it - # still should not explicitly inherit Persistent because the `SturdyRef` and `Owner` types will - # vary between realms (they may even be different at the call site than they are on the - # implementation). Instead, mark persistent interfaces with the $persistent annotation (defined - # below). - # - # Sealing - # ------- - # - # As an added security measure, SturdyRefs may be "sealed" to a particular owner, such that - # if the SturdyRef itself leaks to a third party, that party cannot actually restore it because - # they are not the owner. To restore a sealed capability, you must first prove to its host that - # you are the rightful owner. The precise mechanism for this authentication is defined by the - # realm. - # - # Sealing is a defense-in-depth mechanism meant to mitigate damage in the case of catastrophic - # attacks. For example, say an attacker temporarily gains read access to a database full of - # SturdyRefs: it would be unfortunate if it were then necessary to revoke every single reference - # in the database to prevent the attacker from using them. - # - # In general, an "owner" is a course-grained identity. Because capability-based security is still - # the primary mechanism of security, it is not necessary nor desirable to have a separate "owner" - # identity for every single process or object; that is exactly what capabilities are supposed to - # avoid! Instead, it makes sense for an "owner" to literally identify the owner of the machines - # where the capability is stored. If untrusted third parties are able to run arbitrary code on - # said machines, then the sandbox for that code should be designed using Distributed Confinement - # such that the third-party code never sees the bits of the SturdyRefs and cannot directly - # exercise the owner's power to restore refs. See: - # - # http://www.erights.org/elib/capability/dist-confine.html - # - # Resist the urge to represent an Owner as a simple public key. The whole point of sealing is to - # defend against leaked-storage attacks. Such attacks can easily result in the owner's private - # key being stolen as well. A better solution is for `Owner` to contain a simple globally unique - # identifier for the owner, and for everyone to separately maintain a mapping of owner IDs to - # public keys. If an owner's private key is compromised, then humans will need to communicate - # and agree on a replacement public key, then update the mapping. - # - # As a concrete example, an `Owner` could simply contain a domain name, and restoring a SturdyRef - # would require signing a request using the domain's private key. Authenticating this key could - # be accomplished through certificate authorities or web-of-trust techniques. - - save @0 SaveParams -> SaveResults; - # Save a capability persistently so that it can be restored by a future connection. Not all - # capabilities can be saved -- application interfaces should define which capabilities support - # this and which do not. - - struct SaveParams { - sealFor @0 :Owner; - # Seal the SturdyRef so that it can only be restored by the specified Owner. This is meant - # to mitigate damage when a SturdyRef is leaked. See comments above. - # - # Leaving this value null may or may not be allowed; it is up to the realm to decide. If a - # realm does allow a null owner, this should indicate that anyone is allowed to restore the - # ref. - } - struct SaveResults { - sturdyRef @0 :SturdyRef; - } -} - -interface RealmGateway(InternalRef, ExternalRef, InternalOwner, ExternalOwner) { - # Interface invoked when a SturdyRef is about to cross realms. The RPC system supports providing - # a RealmGateway as a callback hook when setting up RPC over some VatNetwork. - - import @0 (cap :Persistent(ExternalRef, ExternalOwner), - params :Persistent(InternalRef, InternalOwner).SaveParams) - -> Persistent(InternalRef, InternalOwner).SaveResults; - # Given an external capability, save it and return an internal reference. Used when someone - # inside the realm tries to save a capability from outside the realm. - - export @1 (cap :Persistent(InternalRef, InternalOwner), - params :Persistent(ExternalRef, ExternalOwner).SaveParams) - -> Persistent(ExternalRef, ExternalOwner).SaveResults; - # Given an internal capability, save it and return an external reference. Used when someone - # outside the realm tries to save a capability from inside the realm. -} - -annotation persistent(interface, field) :Void; -# Apply this annotation to interfaces for objects that will always be persistent, instead of -# extending the Persistent capability, since the correct type parameters to Persistent depend on -# the realm, which is orthogonal to the interface type and therefore should not be defined -# along-side it. -# -# You may also apply this annotation to a capability-typed field which will always contain a -# persistent capability, but where the capability's interface itself is not already marked -# persistent. -# -# Note that absence of the $persistent annotation doesn't mean a capability of that type isn't -# persistent; it just means not *all* such capabilities are persistent. diff --git a/phonelibs/capnp-cpp/include/capnp/persistent.capnp.h b/phonelibs/capnp-cpp/include/capnp/persistent.capnp.h deleted file mode 100644 index f9b443220a9584..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/persistent.capnp.h +++ /dev/null @@ -1,1328 +0,0 @@ -// Generated by Cap'n Proto compiler, DO NOT EDIT -// source: persistent.capnp - -#ifndef CAPNP_INCLUDED_b8630836983feed7_ -#define CAPNP_INCLUDED_b8630836983feed7_ - -#include -#if !CAPNP_LITE -#include -#endif // !CAPNP_LITE - -#if CAPNP_VERSION != 6001 -#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." -#endif - - -namespace capnp { -namespace schemas { - -CAPNP_DECLARE_SCHEMA(c8cb212fcd9f5691); -CAPNP_DECLARE_SCHEMA(f76fba59183073a5); -CAPNP_DECLARE_SCHEMA(b76848c18c40efbf); -CAPNP_DECLARE_SCHEMA(84ff286cd00a3ed4); -CAPNP_DECLARE_SCHEMA(f0c2cc1d3909574d); -CAPNP_DECLARE_SCHEMA(ecafa18b482da3aa); -CAPNP_DECLARE_SCHEMA(f622595091cafb67); - -} // namespace schemas -} // namespace capnp - -namespace capnp { - -template -struct Persistent { - Persistent() = delete; - -#if !CAPNP_LITE - class Client; - class Server; -#endif // !CAPNP_LITE - - struct SaveParams; - struct SaveResults; - - #if !CAPNP_LITE - struct _capnpPrivate { - CAPNP_DECLARE_INTERFACE_HEADER(c8cb212fcd9f5691) - static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; - static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; - static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; - static const ::capnp::_::RawBrandedSchema specificBrand; - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, SturdyRef, Owner>::brand(); } - }; - #endif // !CAPNP_LITE -}; - -template -struct Persistent::SaveParams { - SaveParams() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(f76fba59183073a5, 0, 1) - #if !CAPNP_LITE - static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; - static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; - static const ::capnp::_::RawBrandedSchema specificBrand; - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, SturdyRef, Owner>::brand(); } - #endif // !CAPNP_LITE - }; -}; - -template -struct Persistent::SaveResults { - SaveResults() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(b76848c18c40efbf, 0, 1) - #if !CAPNP_LITE - static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; - static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; - static const ::capnp::_::RawBrandedSchema specificBrand; - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, SturdyRef, Owner>::brand(); } - #endif // !CAPNP_LITE - }; -}; - -template -struct RealmGateway { - RealmGateway() = delete; - -#if !CAPNP_LITE - class Client; - class Server; -#endif // !CAPNP_LITE - - struct ImportParams; - struct ExportParams; - - #if !CAPNP_LITE - struct _capnpPrivate { - CAPNP_DECLARE_INTERFACE_HEADER(84ff286cd00a3ed4) - static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; - static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; - static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; - static const ::capnp::_::RawBrandedSchema specificBrand; - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, InternalRef, ExternalRef, InternalOwner, ExternalOwner>::brand(); } - }; - #endif // !CAPNP_LITE -}; - -template -struct RealmGateway::ImportParams { - ImportParams() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(f0c2cc1d3909574d, 0, 2) - #if !CAPNP_LITE - static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; - static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; - static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; - static const ::capnp::_::RawBrandedSchema specificBrand; - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, InternalRef, ExternalRef, InternalOwner, ExternalOwner>::brand(); } - #endif // !CAPNP_LITE - }; -}; - -template -struct RealmGateway::ExportParams { - ExportParams() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(ecafa18b482da3aa, 0, 2) - #if !CAPNP_LITE - static const ::capnp::_::RawBrandedSchema::Scope brandScopes[]; - static const ::capnp::_::RawBrandedSchema::Binding brandBindings[]; - static const ::capnp::_::RawBrandedSchema::Dependency brandDependencies[]; - static const ::capnp::_::RawBrandedSchema specificBrand; - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return ::capnp::_::ChooseBrand<_capnpPrivate, InternalRef, ExternalRef, InternalOwner, ExternalOwner>::brand(); } - #endif // !CAPNP_LITE - }; -}; - -// ======================================================================================= - -#if !CAPNP_LITE -template -class Persistent::Client - : public virtual ::capnp::Capability::Client { -public: - typedef Persistent Calls; - typedef Persistent Reads; - - Client(decltype(nullptr)); - explicit Client(::kj::Own< ::capnp::ClientHook>&& hook); - template ()>> - Client(::kj::Own<_t>&& server); - template ()>> - Client(::kj::Promise<_t>&& promise); - Client(::kj::Exception&& exception); - Client(Client&) = default; - Client(Client&&) = default; - Client& operator=(Client& other); - Client& operator=(Client&& other); - - template - typename Persistent::Client asGeneric() { - return castAs>(); - } - - CAPNP_AUTO_IF_MSVC(::capnp::Request::SaveParams, typename ::capnp::Persistent::SaveResults>) saveRequest( - ::kj::Maybe< ::capnp::MessageSize> sizeHint = nullptr); - -protected: - Client() = default; -}; - -template -class Persistent::Server - : public virtual ::capnp::Capability::Server { -public: - typedef Persistent Serves; - - ::kj::Promise dispatchCall(uint64_t interfaceId, uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) - override; - -protected: - typedef ::capnp::CallContext::SaveParams, typename ::capnp::Persistent::SaveResults> SaveContext; - virtual ::kj::Promise save(SaveContext context); - - inline typename ::capnp::Persistent::Client thisCap() { - return ::capnp::Capability::Server::thisCap() - .template castAs< ::capnp::Persistent>(); - } - - ::kj::Promise dispatchCallInternal(uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context); -}; -#endif // !CAPNP_LITE - -template -class Persistent::SaveParams::Reader { -public: - typedef SaveParams Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - template - typename Persistent::SaveParams::Reader asPersistentGeneric() { - return typename Persistent::SaveParams::Reader(_reader); - } - - inline bool hasSealFor() const; - inline ::capnp::ReaderFor getSealFor() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -template -class Persistent::SaveParams::Builder { -public: - typedef SaveParams Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - template - typename Persistent::SaveParams::Builder asPersistentGeneric() { - return typename Persistent::SaveParams::Builder(_builder); - } - - inline bool hasSealFor(); - inline ::capnp::BuilderFor getSealFor(); - inline void setSealFor( ::capnp::ReaderFor value); - inline ::capnp::BuilderFor initSealFor(); - inline ::capnp::BuilderFor initSealFor(unsigned int size); - inline void adoptSealFor(::capnp::Orphan&& value); - inline ::capnp::Orphan disownSealFor(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -template -class Persistent::SaveParams::Pipeline { -public: - typedef SaveParams Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::PipelineFor getSealFor(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -template -class Persistent::SaveResults::Reader { -public: - typedef SaveResults Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - template - typename Persistent::SaveResults::Reader asPersistentGeneric() { - return typename Persistent::SaveResults::Reader(_reader); - } - - inline bool hasSturdyRef() const; - inline ::capnp::ReaderFor getSturdyRef() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -template -class Persistent::SaveResults::Builder { -public: - typedef SaveResults Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - template - typename Persistent::SaveResults::Builder asPersistentGeneric() { - return typename Persistent::SaveResults::Builder(_builder); - } - - inline bool hasSturdyRef(); - inline ::capnp::BuilderFor getSturdyRef(); - inline void setSturdyRef( ::capnp::ReaderFor value); - inline ::capnp::BuilderFor initSturdyRef(); - inline ::capnp::BuilderFor initSturdyRef(unsigned int size); - inline void adoptSturdyRef(::capnp::Orphan&& value); - inline ::capnp::Orphan disownSturdyRef(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -template -class Persistent::SaveResults::Pipeline { -public: - typedef SaveResults Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::PipelineFor getSturdyRef(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -#if !CAPNP_LITE -template -class RealmGateway::Client - : public virtual ::capnp::Capability::Client { -public: - typedef RealmGateway Calls; - typedef RealmGateway Reads; - - Client(decltype(nullptr)); - explicit Client(::kj::Own< ::capnp::ClientHook>&& hook); - template ()>> - Client(::kj::Own<_t>&& server); - template ()>> - Client(::kj::Promise<_t>&& promise); - Client(::kj::Exception&& exception); - Client(Client&) = default; - Client(Client&&) = default; - Client& operator=(Client& other); - Client& operator=(Client&& other); - - template - typename RealmGateway::Client asGeneric() { - return castAs>(); - } - - CAPNP_AUTO_IF_MSVC(::capnp::Request::ImportParams, typename ::capnp::Persistent::SaveResults>) importRequest( - ::kj::Maybe< ::capnp::MessageSize> sizeHint = nullptr); - CAPNP_AUTO_IF_MSVC(::capnp::Request::ExportParams, typename ::capnp::Persistent::SaveResults>) exportRequest( - ::kj::Maybe< ::capnp::MessageSize> sizeHint = nullptr); - -protected: - Client() = default; -}; - -template -class RealmGateway::Server - : public virtual ::capnp::Capability::Server { -public: - typedef RealmGateway Serves; - - ::kj::Promise dispatchCall(uint64_t interfaceId, uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) - override; - -protected: - typedef typename ::capnp::RealmGateway::ImportParams ImportParams; - typedef ::capnp::CallContext::SaveResults> ImportContext; - virtual ::kj::Promise import(ImportContext context); - typedef typename ::capnp::RealmGateway::ExportParams ExportParams; - typedef ::capnp::CallContext::SaveResults> ExportContext; - virtual ::kj::Promise export_(ExportContext context); - - inline typename ::capnp::RealmGateway::Client thisCap() { - return ::capnp::Capability::Server::thisCap() - .template castAs< ::capnp::RealmGateway>(); - } - - ::kj::Promise dispatchCallInternal(uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context); -}; -#endif // !CAPNP_LITE - -template -class RealmGateway::ImportParams::Reader { -public: - typedef ImportParams Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - template - typename RealmGateway::ImportParams::Reader asRealmGatewayGeneric() { - return typename RealmGateway::ImportParams::Reader(_reader); - } - - inline bool hasCap() const; -#if !CAPNP_LITE - inline typename ::capnp::Persistent::Client getCap() const; -#endif // !CAPNP_LITE - - inline bool hasParams() const; - inline typename ::capnp::Persistent::SaveParams::Reader getParams() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -template -class RealmGateway::ImportParams::Builder { -public: - typedef ImportParams Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - template - typename RealmGateway::ImportParams::Builder asRealmGatewayGeneric() { - return typename RealmGateway::ImportParams::Builder(_builder); - } - - inline bool hasCap(); -#if !CAPNP_LITE - inline typename ::capnp::Persistent::Client getCap(); - inline void setCap(typename ::capnp::Persistent::Client&& value); - inline void setCap(typename ::capnp::Persistent::Client& value); - inline void adoptCap(::capnp::Orphan< ::capnp::Persistent>&& value); - inline ::capnp::Orphan< ::capnp::Persistent> disownCap(); -#endif // !CAPNP_LITE - - inline bool hasParams(); - inline typename ::capnp::Persistent::SaveParams::Builder getParams(); - inline void setParams(typename ::capnp::Persistent::SaveParams::Reader value); - inline typename ::capnp::Persistent::SaveParams::Builder initParams(); - inline void adoptParams(::capnp::Orphan::SaveParams>&& value); - inline ::capnp::Orphan::SaveParams> disownParams(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -template -class RealmGateway::ImportParams::Pipeline { -public: - typedef ImportParams Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline typename ::capnp::Persistent::Client getCap(); - inline typename ::capnp::Persistent::SaveParams::Pipeline getParams(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -template -class RealmGateway::ExportParams::Reader { -public: - typedef ExportParams Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - template - typename RealmGateway::ExportParams::Reader asRealmGatewayGeneric() { - return typename RealmGateway::ExportParams::Reader(_reader); - } - - inline bool hasCap() const; -#if !CAPNP_LITE - inline typename ::capnp::Persistent::Client getCap() const; -#endif // !CAPNP_LITE - - inline bool hasParams() const; - inline typename ::capnp::Persistent::SaveParams::Reader getParams() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -template -class RealmGateway::ExportParams::Builder { -public: - typedef ExportParams Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - template - typename RealmGateway::ExportParams::Builder asRealmGatewayGeneric() { - return typename RealmGateway::ExportParams::Builder(_builder); - } - - inline bool hasCap(); -#if !CAPNP_LITE - inline typename ::capnp::Persistent::Client getCap(); - inline void setCap(typename ::capnp::Persistent::Client&& value); - inline void setCap(typename ::capnp::Persistent::Client& value); - inline void adoptCap(::capnp::Orphan< ::capnp::Persistent>&& value); - inline ::capnp::Orphan< ::capnp::Persistent> disownCap(); -#endif // !CAPNP_LITE - - inline bool hasParams(); - inline typename ::capnp::Persistent::SaveParams::Builder getParams(); - inline void setParams(typename ::capnp::Persistent::SaveParams::Reader value); - inline typename ::capnp::Persistent::SaveParams::Builder initParams(); - inline void adoptParams(::capnp::Orphan::SaveParams>&& value); - inline ::capnp::Orphan::SaveParams> disownParams(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -template -class RealmGateway::ExportParams::Pipeline { -public: - typedef ExportParams Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline typename ::capnp::Persistent::Client getCap(); - inline typename ::capnp::Persistent::SaveParams::Pipeline getParams(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -// ======================================================================================= - -#if !CAPNP_LITE -template -inline Persistent::Client::Client(decltype(nullptr)) - : ::capnp::Capability::Client(nullptr) {} -template -inline Persistent::Client::Client( - ::kj::Own< ::capnp::ClientHook>&& hook) - : ::capnp::Capability::Client(::kj::mv(hook)) {} -template -template -inline Persistent::Client::Client(::kj::Own<_t>&& server) - : ::capnp::Capability::Client(::kj::mv(server)) {} -template -template -inline Persistent::Client::Client(::kj::Promise<_t>&& promise) - : ::capnp::Capability::Client(::kj::mv(promise)) {} -template -inline Persistent::Client::Client(::kj::Exception&& exception) - : ::capnp::Capability::Client(::kj::mv(exception)) {} -template -inline typename ::capnp::Persistent::Client& Persistent::Client::operator=(Client& other) { - ::capnp::Capability::Client::operator=(other); - return *this; -} -template -inline typename ::capnp::Persistent::Client& Persistent::Client::operator=(Client&& other) { - ::capnp::Capability::Client::operator=(kj::mv(other)); - return *this; -} - -#endif // !CAPNP_LITE -template -inline bool Persistent::SaveParams::Reader::hasSealFor() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -template -inline bool Persistent::SaveParams::Builder::hasSealFor() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -template -inline ::capnp::ReaderFor Persistent::SaveParams::Reader::getSealFor() const { - return ::capnp::_::PointerHelpers::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -template -inline ::capnp::BuilderFor Persistent::SaveParams::Builder::getSealFor() { - return ::capnp::_::PointerHelpers::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -template -inline ::capnp::PipelineFor Persistent::SaveParams::Pipeline::getSealFor() { - return ::capnp::PipelineFor(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -template -inline void Persistent::SaveParams::Builder::setSealFor( ::capnp::ReaderFor value) { - ::capnp::_::PointerHelpers::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -template -inline ::capnp::BuilderFor Persistent::SaveParams::Builder::initSealFor() { - return ::capnp::_::PointerHelpers::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -template -inline ::capnp::BuilderFor Persistent::SaveParams::Builder::initSealFor(unsigned int size) { - return ::capnp::_::PointerHelpers::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -template -inline void Persistent::SaveParams::Builder::adoptSealFor( - ::capnp::Orphan&& value) { - ::capnp::_::PointerHelpers::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -template -inline ::capnp::Orphan Persistent::SaveParams::Builder::disownSealFor() { - return ::capnp::_::PointerHelpers::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -// Persistent::SaveParams -template -constexpr uint16_t Persistent::SaveParams::_capnpPrivate::dataWordSize; -template -constexpr uint16_t Persistent::SaveParams::_capnpPrivate::pointerCount; -#if !CAPNP_LITE -template -constexpr ::capnp::Kind Persistent::SaveParams::_capnpPrivate::kind; -template -constexpr ::capnp::_::RawSchema const* Persistent::SaveParams::_capnpPrivate::schema; -template -const ::capnp::_::RawBrandedSchema::Scope Persistent::SaveParams::_capnpPrivate::brandScopes[] = { - { 0xc8cb212fcd9f5691, brandBindings + 0, 2, false}, -}; -template -const ::capnp::_::RawBrandedSchema::Binding Persistent::SaveParams::_capnpPrivate::brandBindings[] = { - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), -}; -template -const ::capnp::_::RawBrandedSchema Persistent::SaveParams::_capnpPrivate::specificBrand = { - &::capnp::schemas::s_f76fba59183073a5, brandScopes, nullptr, - 1, 0, nullptr -}; -#endif // !CAPNP_LITE - -template -inline bool Persistent::SaveResults::Reader::hasSturdyRef() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -template -inline bool Persistent::SaveResults::Builder::hasSturdyRef() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -template -inline ::capnp::ReaderFor Persistent::SaveResults::Reader::getSturdyRef() const { - return ::capnp::_::PointerHelpers::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -template -inline ::capnp::BuilderFor Persistent::SaveResults::Builder::getSturdyRef() { - return ::capnp::_::PointerHelpers::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -template -inline ::capnp::PipelineFor Persistent::SaveResults::Pipeline::getSturdyRef() { - return ::capnp::PipelineFor(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -template -inline void Persistent::SaveResults::Builder::setSturdyRef( ::capnp::ReaderFor value) { - ::capnp::_::PointerHelpers::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -template -inline ::capnp::BuilderFor Persistent::SaveResults::Builder::initSturdyRef() { - return ::capnp::_::PointerHelpers::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -template -inline ::capnp::BuilderFor Persistent::SaveResults::Builder::initSturdyRef(unsigned int size) { - return ::capnp::_::PointerHelpers::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -template -inline void Persistent::SaveResults::Builder::adoptSturdyRef( - ::capnp::Orphan&& value) { - ::capnp::_::PointerHelpers::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -template -inline ::capnp::Orphan Persistent::SaveResults::Builder::disownSturdyRef() { - return ::capnp::_::PointerHelpers::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -// Persistent::SaveResults -template -constexpr uint16_t Persistent::SaveResults::_capnpPrivate::dataWordSize; -template -constexpr uint16_t Persistent::SaveResults::_capnpPrivate::pointerCount; -#if !CAPNP_LITE -template -constexpr ::capnp::Kind Persistent::SaveResults::_capnpPrivate::kind; -template -constexpr ::capnp::_::RawSchema const* Persistent::SaveResults::_capnpPrivate::schema; -template -const ::capnp::_::RawBrandedSchema::Scope Persistent::SaveResults::_capnpPrivate::brandScopes[] = { - { 0xc8cb212fcd9f5691, brandBindings + 0, 2, false}, -}; -template -const ::capnp::_::RawBrandedSchema::Binding Persistent::SaveResults::_capnpPrivate::brandBindings[] = { - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), -}; -template -const ::capnp::_::RawBrandedSchema Persistent::SaveResults::_capnpPrivate::specificBrand = { - &::capnp::schemas::s_b76848c18c40efbf, brandScopes, nullptr, - 1, 0, nullptr -}; -#endif // !CAPNP_LITE - -#if !CAPNP_LITE -template -CAPNP_AUTO_IF_MSVC(::capnp::Request::SaveParams, typename ::capnp::Persistent::SaveResults>) -Persistent::Client::saveRequest(::kj::Maybe< ::capnp::MessageSize> sizeHint) { - return newCall::SaveParams, typename ::capnp::Persistent::SaveResults>( - 0xc8cb212fcd9f5691ull, 0, sizeHint); -} -template -::kj::Promise Persistent::Server::save(SaveContext) { - return ::capnp::Capability::Server::internalUnimplemented( - "capnp/persistent.capnp:Persistent", "save", - 0xc8cb212fcd9f5691ull, 0); -} -template -::kj::Promise Persistent::Server::dispatchCall( - uint64_t interfaceId, uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { - switch (interfaceId) { - case 0xc8cb212fcd9f5691ull: - return dispatchCallInternal(methodId, context); - default: - return internalUnimplemented("capnp/persistent.capnp:Persistent", interfaceId); - } -} -template -::kj::Promise Persistent::Server::dispatchCallInternal( - uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { - switch (methodId) { - case 0: - return save(::capnp::Capability::Server::internalGetTypedContext< - typename ::capnp::Persistent::SaveParams, typename ::capnp::Persistent::SaveResults>(context)); - default: - (void)context; - return ::capnp::Capability::Server::internalUnimplemented( - "capnp/persistent.capnp:Persistent", - 0xc8cb212fcd9f5691ull, methodId); - } -} -#endif // !CAPNP_LITE - -// Persistent -#if !CAPNP_LITE -template -constexpr ::capnp::Kind Persistent::_capnpPrivate::kind; -template -constexpr ::capnp::_::RawSchema const* Persistent::_capnpPrivate::schema; -template -const ::capnp::_::RawBrandedSchema::Scope Persistent::_capnpPrivate::brandScopes[] = { - { 0xc8cb212fcd9f5691, brandBindings + 0, 2, false}, -}; -template -const ::capnp::_::RawBrandedSchema::Binding Persistent::_capnpPrivate::brandBindings[] = { - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), -}; -template -const ::capnp::_::RawBrandedSchema::Dependency Persistent::_capnpPrivate::brandDependencies[] = { - { 33554432, ::capnp::Persistent::SaveParams::_capnpPrivate::brand() }, - { 50331648, ::capnp::Persistent::SaveResults::_capnpPrivate::brand() }, -}; -template -const ::capnp::_::RawBrandedSchema Persistent::_capnpPrivate::specificBrand = { - &::capnp::schemas::s_c8cb212fcd9f5691, brandScopes, brandDependencies, - 1, 2, nullptr -}; -#endif // !CAPNP_LITE - -#if !CAPNP_LITE -template -inline RealmGateway::Client::Client(decltype(nullptr)) - : ::capnp::Capability::Client(nullptr) {} -template -inline RealmGateway::Client::Client( - ::kj::Own< ::capnp::ClientHook>&& hook) - : ::capnp::Capability::Client(::kj::mv(hook)) {} -template -template -inline RealmGateway::Client::Client(::kj::Own<_t>&& server) - : ::capnp::Capability::Client(::kj::mv(server)) {} -template -template -inline RealmGateway::Client::Client(::kj::Promise<_t>&& promise) - : ::capnp::Capability::Client(::kj::mv(promise)) {} -template -inline RealmGateway::Client::Client(::kj::Exception&& exception) - : ::capnp::Capability::Client(::kj::mv(exception)) {} -template -inline typename ::capnp::RealmGateway::Client& RealmGateway::Client::operator=(Client& other) { - ::capnp::Capability::Client::operator=(other); - return *this; -} -template -inline typename ::capnp::RealmGateway::Client& RealmGateway::Client::operator=(Client&& other) { - ::capnp::Capability::Client::operator=(kj::mv(other)); - return *this; -} - -#endif // !CAPNP_LITE -template -inline bool RealmGateway::ImportParams::Reader::hasCap() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -template -inline bool RealmGateway::ImportParams::Builder::hasCap() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -#if !CAPNP_LITE -template -inline typename ::capnp::Persistent::Client RealmGateway::ImportParams::Reader::getCap() const { - return ::capnp::_::PointerHelpers< ::capnp::Persistent>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -template -inline typename ::capnp::Persistent::Client RealmGateway::ImportParams::Builder::getCap() { - return ::capnp::_::PointerHelpers< ::capnp::Persistent>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -template -inline typename ::capnp::Persistent::Client RealmGateway::ImportParams::Pipeline::getCap() { - return typename ::capnp::Persistent::Client(_typeless.getPointerField(0).asCap()); -} -template -inline void RealmGateway::ImportParams::Builder::setCap(typename ::capnp::Persistent::Client&& cap) { - ::capnp::_::PointerHelpers< ::capnp::Persistent>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(cap)); -} -template -inline void RealmGateway::ImportParams::Builder::setCap(typename ::capnp::Persistent::Client& cap) { - ::capnp::_::PointerHelpers< ::capnp::Persistent>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), cap); -} -template -inline void RealmGateway::ImportParams::Builder::adoptCap( - ::capnp::Orphan< ::capnp::Persistent>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Persistent>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -template -inline ::capnp::Orphan< ::capnp::Persistent> RealmGateway::ImportParams::Builder::disownCap() { - return ::capnp::_::PointerHelpers< ::capnp::Persistent>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -#endif // !CAPNP_LITE - -template -inline bool RealmGateway::ImportParams::Reader::hasParams() const { - return !_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -template -inline bool RealmGateway::ImportParams::Builder::hasParams() { - return !_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -template -inline typename ::capnp::Persistent::SaveParams::Reader RealmGateway::ImportParams::Reader::getParams() const { - return ::capnp::_::PointerHelpers::SaveParams>::get(_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -template -inline typename ::capnp::Persistent::SaveParams::Builder RealmGateway::ImportParams::Builder::getParams() { - return ::capnp::_::PointerHelpers::SaveParams>::get(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -template -inline typename ::capnp::Persistent::SaveParams::Pipeline RealmGateway::ImportParams::Pipeline::getParams() { - return typename ::capnp::Persistent::SaveParams::Pipeline(_typeless.getPointerField(1)); -} -#endif // !CAPNP_LITE -template -inline void RealmGateway::ImportParams::Builder::setParams(typename ::capnp::Persistent::SaveParams::Reader value) { - ::capnp::_::PointerHelpers::SaveParams>::set(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), value); -} -template -inline typename ::capnp::Persistent::SaveParams::Builder RealmGateway::ImportParams::Builder::initParams() { - return ::capnp::_::PointerHelpers::SaveParams>::init(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -template -inline void RealmGateway::ImportParams::Builder::adoptParams( - ::capnp::Orphan::SaveParams>&& value) { - ::capnp::_::PointerHelpers::SaveParams>::adopt(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); -} -template -inline ::capnp::Orphan::SaveParams> RealmGateway::ImportParams::Builder::disownParams() { - return ::capnp::_::PointerHelpers::SaveParams>::disown(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} - -// RealmGateway::ImportParams -template -constexpr uint16_t RealmGateway::ImportParams::_capnpPrivate::dataWordSize; -template -constexpr uint16_t RealmGateway::ImportParams::_capnpPrivate::pointerCount; -#if !CAPNP_LITE -template -constexpr ::capnp::Kind RealmGateway::ImportParams::_capnpPrivate::kind; -template -constexpr ::capnp::_::RawSchema const* RealmGateway::ImportParams::_capnpPrivate::schema; -template -const ::capnp::_::RawBrandedSchema::Scope RealmGateway::ImportParams::_capnpPrivate::brandScopes[] = { - { 0x84ff286cd00a3ed4, brandBindings + 0, 4, false}, -}; -template -const ::capnp::_::RawBrandedSchema::Binding RealmGateway::ImportParams::_capnpPrivate::brandBindings[] = { - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), -}; -template -const ::capnp::_::RawBrandedSchema::Dependency RealmGateway::ImportParams::_capnpPrivate::brandDependencies[] = { - { 16777216, ::capnp::Persistent::_capnpPrivate::brand() }, - { 16777217, ::capnp::Persistent::SaveParams::_capnpPrivate::brand() }, -}; -template -const ::capnp::_::RawBrandedSchema RealmGateway::ImportParams::_capnpPrivate::specificBrand = { - &::capnp::schemas::s_f0c2cc1d3909574d, brandScopes, brandDependencies, - 1, 2, nullptr -}; -#endif // !CAPNP_LITE - -template -inline bool RealmGateway::ExportParams::Reader::hasCap() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -template -inline bool RealmGateway::ExportParams::Builder::hasCap() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -#if !CAPNP_LITE -template -inline typename ::capnp::Persistent::Client RealmGateway::ExportParams::Reader::getCap() const { - return ::capnp::_::PointerHelpers< ::capnp::Persistent>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -template -inline typename ::capnp::Persistent::Client RealmGateway::ExportParams::Builder::getCap() { - return ::capnp::_::PointerHelpers< ::capnp::Persistent>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -template -inline typename ::capnp::Persistent::Client RealmGateway::ExportParams::Pipeline::getCap() { - return typename ::capnp::Persistent::Client(_typeless.getPointerField(0).asCap()); -} -template -inline void RealmGateway::ExportParams::Builder::setCap(typename ::capnp::Persistent::Client&& cap) { - ::capnp::_::PointerHelpers< ::capnp::Persistent>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(cap)); -} -template -inline void RealmGateway::ExportParams::Builder::setCap(typename ::capnp::Persistent::Client& cap) { - ::capnp::_::PointerHelpers< ::capnp::Persistent>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), cap); -} -template -inline void RealmGateway::ExportParams::Builder::adoptCap( - ::capnp::Orphan< ::capnp::Persistent>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Persistent>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -template -inline ::capnp::Orphan< ::capnp::Persistent> RealmGateway::ExportParams::Builder::disownCap() { - return ::capnp::_::PointerHelpers< ::capnp::Persistent>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -#endif // !CAPNP_LITE - -template -inline bool RealmGateway::ExportParams::Reader::hasParams() const { - return !_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -template -inline bool RealmGateway::ExportParams::Builder::hasParams() { - return !_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -template -inline typename ::capnp::Persistent::SaveParams::Reader RealmGateway::ExportParams::Reader::getParams() const { - return ::capnp::_::PointerHelpers::SaveParams>::get(_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -template -inline typename ::capnp::Persistent::SaveParams::Builder RealmGateway::ExportParams::Builder::getParams() { - return ::capnp::_::PointerHelpers::SaveParams>::get(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -template -inline typename ::capnp::Persistent::SaveParams::Pipeline RealmGateway::ExportParams::Pipeline::getParams() { - return typename ::capnp::Persistent::SaveParams::Pipeline(_typeless.getPointerField(1)); -} -#endif // !CAPNP_LITE -template -inline void RealmGateway::ExportParams::Builder::setParams(typename ::capnp::Persistent::SaveParams::Reader value) { - ::capnp::_::PointerHelpers::SaveParams>::set(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), value); -} -template -inline typename ::capnp::Persistent::SaveParams::Builder RealmGateway::ExportParams::Builder::initParams() { - return ::capnp::_::PointerHelpers::SaveParams>::init(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -template -inline void RealmGateway::ExportParams::Builder::adoptParams( - ::capnp::Orphan::SaveParams>&& value) { - ::capnp::_::PointerHelpers::SaveParams>::adopt(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); -} -template -inline ::capnp::Orphan::SaveParams> RealmGateway::ExportParams::Builder::disownParams() { - return ::capnp::_::PointerHelpers::SaveParams>::disown(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} - -// RealmGateway::ExportParams -template -constexpr uint16_t RealmGateway::ExportParams::_capnpPrivate::dataWordSize; -template -constexpr uint16_t RealmGateway::ExportParams::_capnpPrivate::pointerCount; -#if !CAPNP_LITE -template -constexpr ::capnp::Kind RealmGateway::ExportParams::_capnpPrivate::kind; -template -constexpr ::capnp::_::RawSchema const* RealmGateway::ExportParams::_capnpPrivate::schema; -template -const ::capnp::_::RawBrandedSchema::Scope RealmGateway::ExportParams::_capnpPrivate::brandScopes[] = { - { 0x84ff286cd00a3ed4, brandBindings + 0, 4, false}, -}; -template -const ::capnp::_::RawBrandedSchema::Binding RealmGateway::ExportParams::_capnpPrivate::brandBindings[] = { - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), -}; -template -const ::capnp::_::RawBrandedSchema::Dependency RealmGateway::ExportParams::_capnpPrivate::brandDependencies[] = { - { 16777216, ::capnp::Persistent::_capnpPrivate::brand() }, - { 16777217, ::capnp::Persistent::SaveParams::_capnpPrivate::brand() }, -}; -template -const ::capnp::_::RawBrandedSchema RealmGateway::ExportParams::_capnpPrivate::specificBrand = { - &::capnp::schemas::s_ecafa18b482da3aa, brandScopes, brandDependencies, - 1, 2, nullptr -}; -#endif // !CAPNP_LITE - -#if !CAPNP_LITE -template -CAPNP_AUTO_IF_MSVC(::capnp::Request::ImportParams, typename ::capnp::Persistent::SaveResults>) -RealmGateway::Client::importRequest(::kj::Maybe< ::capnp::MessageSize> sizeHint) { - return newCall::ImportParams, typename ::capnp::Persistent::SaveResults>( - 0x84ff286cd00a3ed4ull, 0, sizeHint); -} -template -::kj::Promise RealmGateway::Server::import(ImportContext) { - return ::capnp::Capability::Server::internalUnimplemented( - "capnp/persistent.capnp:RealmGateway", "import", - 0x84ff286cd00a3ed4ull, 0); -} -template -CAPNP_AUTO_IF_MSVC(::capnp::Request::ExportParams, typename ::capnp::Persistent::SaveResults>) -RealmGateway::Client::exportRequest(::kj::Maybe< ::capnp::MessageSize> sizeHint) { - return newCall::ExportParams, typename ::capnp::Persistent::SaveResults>( - 0x84ff286cd00a3ed4ull, 1, sizeHint); -} -template -::kj::Promise RealmGateway::Server::export_(ExportContext) { - return ::capnp::Capability::Server::internalUnimplemented( - "capnp/persistent.capnp:RealmGateway", "export", - 0x84ff286cd00a3ed4ull, 1); -} -template -::kj::Promise RealmGateway::Server::dispatchCall( - uint64_t interfaceId, uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { - switch (interfaceId) { - case 0x84ff286cd00a3ed4ull: - return dispatchCallInternal(methodId, context); - default: - return internalUnimplemented("capnp/persistent.capnp:RealmGateway", interfaceId); - } -} -template -::kj::Promise RealmGateway::Server::dispatchCallInternal( - uint16_t methodId, - ::capnp::CallContext< ::capnp::AnyPointer, ::capnp::AnyPointer> context) { - switch (methodId) { - case 0: - return import(::capnp::Capability::Server::internalGetTypedContext< - typename ::capnp::RealmGateway::ImportParams, typename ::capnp::Persistent::SaveResults>(context)); - case 1: - return export_(::capnp::Capability::Server::internalGetTypedContext< - typename ::capnp::RealmGateway::ExportParams, typename ::capnp::Persistent::SaveResults>(context)); - default: - (void)context; - return ::capnp::Capability::Server::internalUnimplemented( - "capnp/persistent.capnp:RealmGateway", - 0x84ff286cd00a3ed4ull, methodId); - } -} -#endif // !CAPNP_LITE - -// RealmGateway -#if !CAPNP_LITE -template -constexpr ::capnp::Kind RealmGateway::_capnpPrivate::kind; -template -constexpr ::capnp::_::RawSchema const* RealmGateway::_capnpPrivate::schema; -template -const ::capnp::_::RawBrandedSchema::Scope RealmGateway::_capnpPrivate::brandScopes[] = { - { 0x84ff286cd00a3ed4, brandBindings + 0, 4, false}, -}; -template -const ::capnp::_::RawBrandedSchema::Binding RealmGateway::_capnpPrivate::brandBindings[] = { - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), - ::capnp::_::brandBindingFor(), -}; -template -const ::capnp::_::RawBrandedSchema::Dependency RealmGateway::_capnpPrivate::brandDependencies[] = { - { 33554432, ::capnp::RealmGateway::ImportParams::_capnpPrivate::brand() }, - { 33554433, ::capnp::RealmGateway::ExportParams::_capnpPrivate::brand() }, - { 50331648, ::capnp::Persistent::SaveResults::_capnpPrivate::brand() }, - { 50331649, ::capnp::Persistent::SaveResults::_capnpPrivate::brand() }, -}; -template -const ::capnp::_::RawBrandedSchema RealmGateway::_capnpPrivate::specificBrand = { - &::capnp::schemas::s_84ff286cd00a3ed4, brandScopes, brandDependencies, - 1, 4, nullptr -}; -#endif // !CAPNP_LITE - -} // namespace - -#endif // CAPNP_INCLUDED_b8630836983feed7_ diff --git a/phonelibs/capnp-cpp/include/capnp/pointer-helpers.h b/phonelibs/capnp-cpp/include/capnp/pointer-helpers.h deleted file mode 100644 index fe70e5036ff221..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/pointer-helpers.h +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_POINTER_HELPERS_H_ -#define CAPNP_POINTER_HELPERS_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "layout.h" -#include "list.h" - -namespace capnp { -namespace _ { // private - -// PointerHelpers is a template class that assists in wrapping/unwrapping the low-level types in -// layout.h with the high-level public API and generated types. This way, the code generator -// and other templates do not have to specialize on each kind of pointer. - -template -struct PointerHelpers { - static inline typename T::Reader get(PointerReader reader, const word* defaultValue = nullptr) { - return typename T::Reader(reader.getStruct(defaultValue)); - } - static inline typename T::Builder get(PointerBuilder builder, - const word* defaultValue = nullptr) { - return typename T::Builder(builder.getStruct(structSize(), defaultValue)); - } - static inline void set(PointerBuilder builder, typename T::Reader value) { - builder.setStruct(value._reader); - } - static inline void setCanonical(PointerBuilder builder, typename T::Reader value) { - builder.setStruct(value._reader, true); - } - static inline typename T::Builder init(PointerBuilder builder) { - return typename T::Builder(builder.initStruct(structSize())); - } - static inline void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan disown(PointerBuilder builder) { - return Orphan(builder.disown()); - } - static inline _::StructReader getInternalReader(const typename T::Reader& reader) { - return reader._reader; - } - static inline _::StructBuilder getInternalBuilder(typename T::Builder&& builder) { - return builder._builder; - } -}; - -template -struct PointerHelpers, Kind::LIST> { - static inline typename List::Reader get(PointerReader reader, - const word* defaultValue = nullptr) { - return typename List::Reader(List::getFromPointer(reader, defaultValue)); - } - static inline typename List::Builder get(PointerBuilder builder, - const word* defaultValue = nullptr) { - return typename List::Builder(List::getFromPointer(builder, defaultValue)); - } - static inline void set(PointerBuilder builder, typename List::Reader value) { - builder.setList(value.reader); - } - static inline void setCanonical(PointerBuilder builder, typename List::Reader value) { - builder.setList(value.reader, true); - } - static void set(PointerBuilder builder, kj::ArrayPtr> value) { - auto l = init(builder, value.size()); - uint i = 0; - for (auto& element: value) { - l.set(i++, element); - } - } - static inline typename List::Builder init(PointerBuilder builder, uint size) { - return typename List::Builder(List::initPointer(builder, size)); - } - static inline void adopt(PointerBuilder builder, Orphan>&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan> disown(PointerBuilder builder) { - return Orphan>(builder.disown()); - } - static inline _::ListReader getInternalReader(const typename List::Reader& reader) { - return reader.reader; - } - static inline _::ListBuilder getInternalBuilder(typename List::Builder&& builder) { - return builder.builder; - } -}; - -template -struct PointerHelpers { - static inline typename T::Reader get(PointerReader reader, - const void* defaultValue = nullptr, - uint defaultBytes = 0) { - return reader.getBlob(defaultValue, bounded(defaultBytes) * BYTES); - } - static inline typename T::Builder get(PointerBuilder builder, - const void* defaultValue = nullptr, - uint defaultBytes = 0) { - return builder.getBlob(defaultValue, bounded(defaultBytes) * BYTES); - } - static inline void set(PointerBuilder builder, typename T::Reader value) { - builder.setBlob(value); - } - static inline void setCanonical(PointerBuilder builder, typename T::Reader value) { - builder.setBlob(value); - } - static inline typename T::Builder init(PointerBuilder builder, uint size) { - return builder.initBlob(bounded(size) * BYTES); - } - static inline void adopt(PointerBuilder builder, Orphan&& value) { - builder.adopt(kj::mv(value.builder)); - } - static inline Orphan disown(PointerBuilder builder) { - return Orphan(builder.disown()); - } -}; - -struct UncheckedMessage { - typedef const word* Reader; -}; - -template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; - -template <> -struct PointerHelpers { - // Reads an AnyPointer field as an unchecked message pointer. Requires that the containing - // message is itself unchecked. This hack is currently private. It is used to locate default - // values within encoded schemas. - - static inline const word* get(PointerReader reader) { - return reader.getUnchecked(); - } -}; - -} // namespace _ (private) -} // namespace capnp - -#endif // CAPNP_POINTER_HELPERS_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/pretty-print.h b/phonelibs/capnp-cpp/include/capnp/pretty-print.h deleted file mode 100644 index e6458bca496b5e..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/pretty-print.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_PRETTY_PRINT_H_ -#define CAPNP_PRETTY_PRINT_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "dynamic.h" -#include - -namespace capnp { - -kj::StringTree prettyPrint(DynamicStruct::Reader value); -kj::StringTree prettyPrint(DynamicStruct::Builder value); -kj::StringTree prettyPrint(DynamicList::Reader value); -kj::StringTree prettyPrint(DynamicList::Builder value); -// Print the given Cap'n Proto struct or list with nice indentation. Note that you can pass any -// struct or list reader or builder type to this method, since they can be implicitly converted -// to one of the dynamic types. -// -// If you don't want indentation, just use the value's KJ stringifier (e.g. pass it to kj::str(), -// any of the KJ debug macros, etc.). - -} // namespace capnp - -#endif // PRETTY_PRINT_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/raw-schema.h b/phonelibs/capnp-cpp/include/capnp/raw-schema.h deleted file mode 100644 index ed9425a6241b19..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/raw-schema.h +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_RAW_SCHEMA_H_ -#define CAPNP_RAW_SCHEMA_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "common.h" // for uint and friends - -#if _MSC_VER -#include -#endif - -namespace capnp { -namespace _ { // private - -struct RawSchema; - -struct RawBrandedSchema { - // Represents a combination of a schema and bindings for its generic parameters. - // - // Note that while we generate one `RawSchema` per type, we generate a `RawBrandedSchema` for - // every _instance_ of a generic type -- or, at least, every instance that is actually used. For - // generated-code types, we use template magic to initialize these. - - const RawSchema* generic; - // Generic type which we're branding. - - struct Binding { - uint8_t which; // Numeric value of one of schema::Type::Which. - - bool isImplicitParameter; - // For AnyPointer, true if it's an implicit method parameter. - - uint16_t listDepth; // Number of times to wrap the base type in List(). - - uint16_t paramIndex; - // For AnyPointer. If it's a type parameter (scopeId is non-zero) or it's an implicit parameter - // (isImplicitParameter is true), then this is the parameter index. Otherwise this is a numeric - // value of one of schema::Type::AnyPointer::Unconstrained::Which. - - union { - const RawBrandedSchema* schema; // for struct, enum, interface - uint64_t scopeId; // for AnyPointer, if it's a type parameter - }; - - Binding() = default; - inline constexpr Binding(uint8_t which, uint16_t listDepth, const RawBrandedSchema* schema) - : which(which), isImplicitParameter(false), listDepth(listDepth), paramIndex(0), - schema(schema) {} - inline constexpr Binding(uint8_t which, uint16_t listDepth, - uint64_t scopeId, uint16_t paramIndex) - : which(which), isImplicitParameter(false), listDepth(listDepth), paramIndex(paramIndex), - scopeId(scopeId) {} - inline constexpr Binding(uint8_t which, uint16_t listDepth, uint16_t implicitParamIndex) - : which(which), isImplicitParameter(true), listDepth(listDepth), - paramIndex(implicitParamIndex), scopeId(0) {} - }; - - struct Scope { - uint64_t typeId; - // Type ID whose parameters are being bound. - - const Binding* bindings; - uint bindingCount; - // Bindings for those parameters. - - bool isUnbound; - // This scope is unbound, in the sense of SchemaLoader::getUnbound(). - }; - - const Scope* scopes; - // Array of enclosing scopes for which generic variables have been bound, sorted by type ID. - - struct Dependency { - uint location; - const RawBrandedSchema* schema; - }; - - const Dependency* dependencies; - // Map of branded schemas for dependencies of this type, given our brand. Only dependencies that - // are branded are included in this map; if a dependency is missing, use its `defaultBrand`. - - uint32_t scopeCount; - uint32_t dependencyCount; - - enum class DepKind { - // Component of a Dependency::location. Specifies what sort of dependency this is. - - INVALID, - // Mostly defined to ensure that zero is not a valid location. - - FIELD, - // Binding needed for a field's type. The index is the field index (NOT ordinal!). - - METHOD_PARAMS, - // Bindings needed for a method's params type. The index is the method number. - - METHOD_RESULTS, - // Bindings needed for a method's results type. The index is the method ordinal. - - SUPERCLASS, - // Bindings needed for a superclass type. The index is the superclass's index in the - // "extends" list. - - CONST_TYPE - // Bindings needed for the type of a constant. The index is zero. - }; - - static inline uint makeDepLocation(DepKind kind, uint index) { - // Make a number representing the location of a particular dependency within its parent - // schema. - - return (static_cast(kind) << 24) | index; - } - - class Initializer { - public: - virtual void init(const RawBrandedSchema* generic) const = 0; - }; - - const Initializer* lazyInitializer; - // Lazy initializer, invoked by ensureInitialized(). - - inline void ensureInitialized() const { - // Lazy initialization support. Invoke to ensure that initialization has taken place. This - // is required in particular when traversing the dependency list. RawSchemas for compiled-in - // types are always initialized; only dynamically-loaded schemas may be lazy. - -#if __GNUC__ - const Initializer* i = __atomic_load_n(&lazyInitializer, __ATOMIC_ACQUIRE); -#elif _MSC_VER - const Initializer* i = *static_cast(&lazyInitializer); - std::atomic_thread_fence(std::memory_order_acquire); -#else -#error "Platform not supported" -#endif - if (i != nullptr) i->init(this); - } - - inline bool isUnbound() const; - // Checks if this schema is the result of calling SchemaLoader::getUnbound(), in which case - // binding lookups need to be handled specially. -}; - -struct RawSchema { - // The generated code defines a constant RawSchema for every compiled declaration. - // - // This is an internal structure which could change in the future. - - uint64_t id; - - const word* encodedNode; - // Encoded SchemaNode, readable via readMessageUnchecked(encodedNode). - - uint32_t encodedSize; - // Size of encodedNode, in words. - - const RawSchema* const* dependencies; - // Pointers to other types on which this one depends, sorted by ID. The schemas in this table - // may be uninitialized -- you must call ensureInitialized() on the one you wish to use before - // using it. - // - // TODO(someday): Make this a hashtable. - - const uint16_t* membersByName; - // Indexes of members sorted by name. Used to implement name lookup. - // TODO(someday): Make this a hashtable. - - uint32_t dependencyCount; - uint32_t memberCount; - // Sizes of above tables. - - const uint16_t* membersByDiscriminant; - // List of all member indexes ordered by discriminant value. Those which don't have a - // discriminant value are listed at the end, in order by ordinal. - - const RawSchema* canCastTo; - // Points to the RawSchema of a compiled-in type to which it is safe to cast any DynamicValue - // with this schema. This is null for all compiled-in types; it is only set by SchemaLoader on - // dynamically-loaded types. - - class Initializer { - public: - virtual void init(const RawSchema* schema) const = 0; - }; - - const Initializer* lazyInitializer; - // Lazy initializer, invoked by ensureInitialized(). - - inline void ensureInitialized() const { - // Lazy initialization support. Invoke to ensure that initialization has taken place. This - // is required in particular when traversing the dependency list. RawSchemas for compiled-in - // types are always initialized; only dynamically-loaded schemas may be lazy. - -#if __GNUC__ - const Initializer* i = __atomic_load_n(&lazyInitializer, __ATOMIC_ACQUIRE); -#elif _MSC_VER - const Initializer* i = *static_cast(&lazyInitializer); - std::atomic_thread_fence(std::memory_order_acquire); -#else -#error "Platform not supported" -#endif - if (i != nullptr) i->init(this); - } - - RawBrandedSchema defaultBrand; - // Specifies the brand to use for this schema if no generic parameters have been bound to - // anything. Generally, in the default brand, all generic parameters are treated as if they were - // bound to `AnyPointer`. -}; - -inline bool RawBrandedSchema::isUnbound() const { - // The unbound schema is the only one that has no scopes but is not the default schema. - return scopeCount == 0 && this != &generic->defaultBrand; -} - -} // namespace _ (private) -} // namespace capnp - -#endif // CAPNP_RAW_SCHEMA_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/rpc-prelude.h b/phonelibs/capnp-cpp/include/capnp/rpc-prelude.h deleted file mode 100644 index 7d26e39de8a68e..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/rpc-prelude.h +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -// This file contains a bunch of internal declarations that must appear before rpc.h can start. -// We don't define these directly in rpc.h because it makes the file hard to read. - -#ifndef CAPNP_RPC_PRELUDE_H_ -#define CAPNP_RPC_PRELUDE_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "capability.h" -#include "persistent.capnp.h" - -namespace capnp { - -class OutgoingRpcMessage; -class IncomingRpcMessage; - -template -class RpcSystem; - -namespace _ { // private - -class VatNetworkBase { - // Non-template version of VatNetwork. Ignore this class; see VatNetwork in rpc.h. - -public: - class Connection; - - struct ConnectionAndProvisionId { - kj::Own connection; - kj::Own firstMessage; - Orphan provisionId; - }; - - class Connection { - public: - virtual kj::Own newOutgoingMessage(uint firstSegmentWordSize) = 0; - virtual kj::Promise>> receiveIncomingMessage() = 0; - virtual kj::Promise shutdown() = 0; - virtual AnyStruct::Reader baseGetPeerVatId() = 0; - }; - virtual kj::Maybe> baseConnect(AnyStruct::Reader vatId) = 0; - virtual kj::Promise> baseAccept() = 0; -}; - -class SturdyRefRestorerBase { -public: - virtual Capability::Client baseRestore(AnyPointer::Reader ref) = 0; -}; - -class BootstrapFactoryBase { - // Non-template version of BootstrapFactory. Ignore this class; see BootstrapFactory in rpc.h. -public: - virtual Capability::Client baseCreateFor(AnyStruct::Reader clientId) = 0; -}; - -class RpcSystemBase { - // Non-template version of RpcSystem. Ignore this class; see RpcSystem in rpc.h. - -public: - RpcSystemBase(VatNetworkBase& network, kj::Maybe bootstrapInterface, - kj::Maybe::Client> gateway); - RpcSystemBase(VatNetworkBase& network, BootstrapFactoryBase& bootstrapFactory, - kj::Maybe::Client> gateway); - RpcSystemBase(VatNetworkBase& network, SturdyRefRestorerBase& restorer); - RpcSystemBase(RpcSystemBase&& other) noexcept; - ~RpcSystemBase() noexcept(false); - -private: - class Impl; - kj::Own impl; - - Capability::Client baseBootstrap(AnyStruct::Reader vatId); - Capability::Client baseRestore(AnyStruct::Reader vatId, AnyPointer::Reader objectId); - void baseSetFlowLimit(size_t words); - - template - friend class capnp::RpcSystem; -}; - -template struct InternalRefFromRealmGateway_; -template -struct InternalRefFromRealmGateway_> { - typedef InternalRef Type; -}; -template -using InternalRefFromRealmGateway = typename InternalRefFromRealmGateway_::Type; -template -using InternalRefFromRealmGatewayClient = InternalRefFromRealmGateway; - -template struct ExternalRefFromRealmGateway_; -template -struct ExternalRefFromRealmGateway_> { - typedef ExternalRef Type; -}; -template -using ExternalRefFromRealmGateway = typename ExternalRefFromRealmGateway_::Type; -template -using ExternalRefFromRealmGatewayClient = ExternalRefFromRealmGateway; - -} // namespace _ (private) -} // namespace capnp - -#endif // CAPNP_RPC_PRELUDE_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/rpc-twoparty.capnp b/phonelibs/capnp-cpp/include/capnp/rpc-twoparty.capnp deleted file mode 100644 index 0b670e8ac3fc24..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/rpc-twoparty.capnp +++ /dev/null @@ -1,169 +0,0 @@ -# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -# Licensed under the MIT License: -# -# 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. - -@0xa184c7885cdaf2a1; -# This file defines the "network-specific parameters" in rpc.capnp to support a network consisting -# of two vats. Each of these vats may in fact be in communication with other vats, but any -# capabilities they forward must be proxied. Thus, to each end of the connection, all capabilities -# received from the other end appear to live in a single vat. -# -# Two notable use cases for this model include: -# - Regular client-server communications, where a remote client machine (perhaps living on an end -# user's personal device) connects to a server. The server may be part of a cluster, and may -# call on other servers in the cluster to help service the user's request. It may even obtain -# capabilities from these other servers which it passes on to the user. To simplify network -# common traversal problems (e.g. if the user is behind a firewall), it is probably desirable to -# multiplex all communications between the server cluster and the client over the original -# connection rather than form new ones. This connection should use the two-party protocol, as -# the client has no interest in knowing about additional servers. -# - Applications running in a sandbox. A supervisor process may execute a confined application -# such that all of the confined app's communications with the outside world must pass through -# the supervisor. In this case, the connection between the confined app and the supervisor might -# as well use the two-party protocol, because the confined app is intentionally prevented from -# talking to any other vat anyway. Any external resources will be proxied through the supervisor, -# and so to the contained app will appear as if they were hosted by the supervisor itself. -# -# Since there are only two vats in this network, there is never a need for three-way introductions, -# so level 3 is free. Moreover, because it is never necessary to form new connections, the -# two-party protocol can be used easily anywhere where a two-way byte stream exists, without regard -# to where that byte stream goes or how it was initiated. This makes the two-party runtime library -# highly reusable. -# -# Joins (level 4) _could_ be needed in cases where one or both vats are participating in other -# networks that use joins. For instance, if Alice and Bob are speaking through the two-party -# protocol, and Bob is also participating on another network, Bob may send Alice two or more -# proxied capabilities which, unbeknownst to Bob at the time, are in fact pointing at the same -# remote object. Alice may then request to join these capabilities, at which point Bob will have -# to forward the join to the other network. Note, however, that if Alice is _not_ participating on -# any other network, then Alice will never need to _receive_ a Join, because Alice would always -# know when two locally-hosted capabilities are the same and would never export a redundant alias -# to Bob. So, Alice can respond to all incoming joins with an error, and only needs to implement -# outgoing joins if she herself desires to use this feature. Also, outgoing joins are relatively -# easy to implement in this scenario. -# -# What all this means is that a level 4 implementation of the confined network is barely more -# complicated than a level 2 implementation. However, such an implementation allows the "client" -# or "confined" app to access the server's/supervisor's network with equal functionality to any -# native participant. In other words, an application which implements only the two-party protocol -# can be paired with a proxy app in order to participate in any network. -# -# So, when implementing Cap'n Proto in a new language, it makes sense to implement only the -# two-party protocol initially, and then pair applications with an appropriate proxy written in -# C++, rather than implement other parameterizations of the RPC protocol directly. - -using Cxx = import "/capnp/c++.capnp"; -$Cxx.namespace("capnp::rpc::twoparty"); - -# Note: SturdyRef is not specified here. It is up to the application to define semantics of -# SturdyRefs if desired. - -enum Side { - server @0; - # The object lives on the "server" or "supervisor" end of the connection. Only the - # server/supervisor knows how to interpret the ref; to the client, it is opaque. - # - # Note that containers intending to implement strong confinement should rewrite SturdyRefs - # received from the external network before passing them on to the confined app. The confined - # app thus does not ever receive the raw bits of the SturdyRef (which it could perhaps - # maliciously leak), but instead receives only a thing that it can pass back to the container - # later to restore the ref. See: - # http://www.erights.org/elib/capability/dist-confine.html - - client @1; - # The object lives on the "client" or "confined app" end of the connection. Only the client - # knows how to interpret the ref; to the server/supervisor, it is opaque. Most clients do not - # actually know how to persist capabilities at all, so use of this is unusual. -} - -struct VatId { - side @0 :Side; -} - -struct ProvisionId { - # Only used for joins, since three-way introductions never happen on a two-party network. - - joinId @0 :UInt32; - # The ID from `JoinKeyPart`. -} - -struct RecipientId {} -# Never used, because there are only two parties. - -struct ThirdPartyCapId {} -# Never used, because there is no third party. - -struct JoinKeyPart { - # Joins in the two-party case are simplified by a few observations. - # - # First, on a two-party network, a Join only ever makes sense if the receiving end is also - # connected to other networks. A vat which is not connected to any other network can safely - # reject all joins. - # - # Second, since a two-party connection bisects the network -- there can be no other connections - # between the networks at either end of the connection -- if one part of a join crosses the - # connection, then _all_ parts must cross it. Therefore, a vat which is receiving a Join request - # off some other network which needs to be forwarded across the two-party connection can - # collect all the parts on its end and only forward them across the two-party connection when all - # have been received. - # - # For example, imagine that Alice and Bob are vats connected over a two-party connection, and - # each is also connected to other networks. At some point, Alice receives one part of a Join - # request off her network. The request is addressed to a capability that Alice received from - # Bob and is proxying to her other network. Alice goes ahead and responds to the Join part as - # if she hosted the capability locally (this is important so that if not all the Join parts end - # up at Alice, the original sender can detect the failed Join without hanging). As other parts - # trickle in, Alice verifies that each part is addressed to a capability from Bob and continues - # to respond to each one. Once the complete set of join parts is received, Alice checks if they - # were all for the exact same capability. If so, she doesn't need to send anything to Bob at - # all. Otherwise, she collects the set of capabilities (from Bob) to which the join parts were - # addressed and essentially initiates a _new_ Join request on those capabilities to Bob. Alice - # does not forward the Join parts she received herself, but essentially forwards the Join as a - # whole. - # - # On Bob's end, since he knows that Alice will always send all parts of a Join together, he - # simply waits until he's received them all, then performs a join on the respective capabilities - # as if it had been requested locally. - - joinId @0 :UInt32; - # A number identifying this join, chosen by the sender. May be reused once `Finish` messages are - # sent corresponding to all of the `Join` messages. - - partCount @1 :UInt16; - # The number of capabilities to be joined. - - partNum @2 :UInt16; - # Which part this request targets -- a number in the range [0, partCount). -} - -struct JoinResult { - joinId @0 :UInt32; - # Matches `JoinKeyPart`. - - succeeded @1 :Bool; - # All JoinResults in the set will have the same value for `succeeded`. The receiver actually - # implements the join by waiting for all the `JoinKeyParts` and then performing its own join on - # them, then going back and answering all the join requests afterwards. - - cap @2 :AnyPointer; - # One of the JoinResults will have a non-null `cap` which is the joined capability. - # - # TODO(cleanup): Change `AnyPointer` to `Capability` when that is supported. -} diff --git a/phonelibs/capnp-cpp/include/capnp/rpc-twoparty.capnp.h b/phonelibs/capnp-cpp/include/capnp/rpc-twoparty.capnp.h deleted file mode 100644 index 9d7820646a75ec..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/rpc-twoparty.capnp.h +++ /dev/null @@ -1,726 +0,0 @@ -// Generated by Cap'n Proto compiler, DO NOT EDIT -// source: rpc-twoparty.capnp - -#ifndef CAPNP_INCLUDED_a184c7885cdaf2a1_ -#define CAPNP_INCLUDED_a184c7885cdaf2a1_ - -#include - -#if CAPNP_VERSION != 6001 -#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." -#endif - - -namespace capnp { -namespace schemas { - -CAPNP_DECLARE_SCHEMA(9fd69ebc87b9719c); -enum class Side_9fd69ebc87b9719c: uint16_t { - SERVER, - CLIENT, -}; -CAPNP_DECLARE_ENUM(Side, 9fd69ebc87b9719c); -CAPNP_DECLARE_SCHEMA(d20b909fee733a8e); -CAPNP_DECLARE_SCHEMA(b88d09a9c5f39817); -CAPNP_DECLARE_SCHEMA(89f389b6fd4082c1); -CAPNP_DECLARE_SCHEMA(b47f4979672cb59d); -CAPNP_DECLARE_SCHEMA(95b29059097fca83); -CAPNP_DECLARE_SCHEMA(9d263a3630b7ebee); - -} // namespace schemas -} // namespace capnp - -namespace capnp { -namespace rpc { -namespace twoparty { - -typedef ::capnp::schemas::Side_9fd69ebc87b9719c Side; - -struct VatId { - VatId() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d20b909fee733a8e, 1, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct ProvisionId { - ProvisionId() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(b88d09a9c5f39817, 1, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct RecipientId { - RecipientId() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(89f389b6fd4082c1, 0, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct ThirdPartyCapId { - ThirdPartyCapId() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(b47f4979672cb59d, 0, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct JoinKeyPart { - JoinKeyPart() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(95b29059097fca83, 1, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct JoinResult { - JoinResult() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9d263a3630b7ebee, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -// ======================================================================================= - -class VatId::Reader { -public: - typedef VatId Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::capnp::rpc::twoparty::Side getSide() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class VatId::Builder { -public: - typedef VatId Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::capnp::rpc::twoparty::Side getSide(); - inline void setSide( ::capnp::rpc::twoparty::Side value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class VatId::Pipeline { -public: - typedef VatId Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class ProvisionId::Reader { -public: - typedef ProvisionId Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getJoinId() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class ProvisionId::Builder { -public: - typedef ProvisionId Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getJoinId(); - inline void setJoinId( ::uint32_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class ProvisionId::Pipeline { -public: - typedef ProvisionId Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class RecipientId::Reader { -public: - typedef RecipientId Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class RecipientId::Builder { -public: - typedef RecipientId Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class RecipientId::Pipeline { -public: - typedef RecipientId Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class ThirdPartyCapId::Reader { -public: - typedef ThirdPartyCapId Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class ThirdPartyCapId::Builder { -public: - typedef ThirdPartyCapId Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class ThirdPartyCapId::Pipeline { -public: - typedef ThirdPartyCapId Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class JoinKeyPart::Reader { -public: - typedef JoinKeyPart Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getJoinId() const; - - inline ::uint16_t getPartCount() const; - - inline ::uint16_t getPartNum() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class JoinKeyPart::Builder { -public: - typedef JoinKeyPart Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getJoinId(); - inline void setJoinId( ::uint32_t value); - - inline ::uint16_t getPartCount(); - inline void setPartCount( ::uint16_t value); - - inline ::uint16_t getPartNum(); - inline void setPartNum( ::uint16_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class JoinKeyPart::Pipeline { -public: - typedef JoinKeyPart Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class JoinResult::Reader { -public: - typedef JoinResult Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getJoinId() const; - - inline bool getSucceeded() const; - - inline bool hasCap() const; - inline ::capnp::AnyPointer::Reader getCap() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class JoinResult::Builder { -public: - typedef JoinResult Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getJoinId(); - inline void setJoinId( ::uint32_t value); - - inline bool getSucceeded(); - inline void setSucceeded(bool value); - - inline bool hasCap(); - inline ::capnp::AnyPointer::Builder getCap(); - inline ::capnp::AnyPointer::Builder initCap(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class JoinResult::Pipeline { -public: - typedef JoinResult Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -// ======================================================================================= - -inline ::capnp::rpc::twoparty::Side VatId::Reader::getSide() const { - return _reader.getDataField< ::capnp::rpc::twoparty::Side>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::rpc::twoparty::Side VatId::Builder::getSide() { - return _builder.getDataField< ::capnp::rpc::twoparty::Side>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void VatId::Builder::setSide( ::capnp::rpc::twoparty::Side value) { - _builder.setDataField< ::capnp::rpc::twoparty::Side>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline ::uint32_t ProvisionId::Reader::getJoinId() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t ProvisionId::Builder::getJoinId() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void ProvisionId::Builder::setJoinId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline ::uint32_t JoinKeyPart::Reader::getJoinId() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t JoinKeyPart::Builder::getJoinId() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void JoinKeyPart::Builder::setJoinId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t JoinKeyPart::Reader::getPartCount() const { - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t JoinKeyPart::Builder::getPartCount() { - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} -inline void JoinKeyPart::Builder::setPartCount( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t JoinKeyPart::Reader::getPartNum() const { - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<3>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t JoinKeyPart::Builder::getPartNum() { - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<3>() * ::capnp::ELEMENTS); -} -inline void JoinKeyPart::Builder::setPartNum( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<3>() * ::capnp::ELEMENTS, value); -} - -inline ::uint32_t JoinResult::Reader::getJoinId() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t JoinResult::Builder::getJoinId() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void JoinResult::Builder::setJoinId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool JoinResult::Reader::getSucceeded() const { - return _reader.getDataField( - ::capnp::bounded<32>() * ::capnp::ELEMENTS); -} - -inline bool JoinResult::Builder::getSucceeded() { - return _builder.getDataField( - ::capnp::bounded<32>() * ::capnp::ELEMENTS); -} -inline void JoinResult::Builder::setSucceeded(bool value) { - _builder.setDataField( - ::capnp::bounded<32>() * ::capnp::ELEMENTS, value); -} - -inline bool JoinResult::Reader::hasCap() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool JoinResult::Builder::hasCap() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader JoinResult::Reader::getCap() const { - return ::capnp::AnyPointer::Reader(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder JoinResult::Builder::getCap() { - return ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder JoinResult::Builder::initCap() { - auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); - result.clear(); - return result; -} - -} // namespace -} // namespace -} // namespace - -#endif // CAPNP_INCLUDED_a184c7885cdaf2a1_ diff --git a/phonelibs/capnp-cpp/include/capnp/rpc-twoparty.h b/phonelibs/capnp-cpp/include/capnp/rpc-twoparty.h deleted file mode 100644 index 093c1fecdf9f35..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/rpc-twoparty.h +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_RPC_TWOPARTY_H_ -#define CAPNP_RPC_TWOPARTY_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "rpc.h" -#include "message.h" -#include -#include - -namespace capnp { - -namespace rpc { - namespace twoparty { - typedef VatId SturdyRefHostId; // For backwards-compatibility with version 0.4. - } -} - -typedef VatNetwork - TwoPartyVatNetworkBase; - -class TwoPartyVatNetwork: public TwoPartyVatNetworkBase, - private TwoPartyVatNetworkBase::Connection { - // A `VatNetwork` that consists of exactly two parties communicating over an arbitrary byte - // stream. This is used to implement the common case of a client/server network. - // - // See `ez-rpc.h` for a simple interface for setting up two-party clients and servers. - // Use `TwoPartyVatNetwork` only if you need the advanced features. - -public: - TwoPartyVatNetwork(kj::AsyncIoStream& stream, rpc::twoparty::Side side, - ReaderOptions receiveOptions = ReaderOptions()); - KJ_DISALLOW_COPY(TwoPartyVatNetwork); - - kj::Promise onDisconnect() { return disconnectPromise.addBranch(); } - // Returns a promise that resolves when the peer disconnects. - - rpc::twoparty::Side getSide() { return side; } - - // implements VatNetwork ----------------------------------------------------- - - kj::Maybe> connect( - rpc::twoparty::VatId::Reader ref) override; - kj::Promise> accept() override; - -private: - class OutgoingMessageImpl; - class IncomingMessageImpl; - - kj::AsyncIoStream& stream; - rpc::twoparty::Side side; - MallocMessageBuilder peerVatId; - ReaderOptions receiveOptions; - bool accepted = false; - - kj::Maybe> previousWrite; - // Resolves when the previous write completes. This effectively serves as the write queue. - // Becomes null when shutdown() is called. - - kj::Own>> acceptFulfiller; - // Fulfiller for the promise returned by acceptConnectionAsRefHost() on the client side, or the - // second call on the server side. Never fulfilled, because there is only one connection. - - kj::ForkedPromise disconnectPromise = nullptr; - - class FulfillerDisposer: public kj::Disposer { - // Hack: TwoPartyVatNetwork is both a VatNetwork and a VatNetwork::Connection. When the RPC - // system detects (or initiates) a disconnection, it drops its reference to the Connection. - // When all references have been dropped, then we want disconnectPromise to be fulfilled. - // So we hand out Owns with this disposer attached, so that we can detect when - // they are dropped. - - public: - mutable kj::Own> fulfiller; - mutable uint refcount = 0; - - void disposeImpl(void* pointer) const override; - }; - FulfillerDisposer disconnectFulfiller; - - kj::Own asConnection(); - // Returns a pointer to this with the disposer set to disconnectFulfiller. - - // implements Connection ----------------------------------------------------- - - rpc::twoparty::VatId::Reader getPeerVatId() override; - kj::Own newOutgoingMessage(uint firstSegmentWordSize) override; - kj::Promise>> receiveIncomingMessage() override; - kj::Promise shutdown() override; -}; - -class TwoPartyServer: private kj::TaskSet::ErrorHandler { - // Convenience class which implements a simple server which accepts connections on a listener - // socket and serices them as two-party connections. - -public: - explicit TwoPartyServer(Capability::Client bootstrapInterface); - - void accept(kj::Own&& connection); - // Accepts the connection for servicing. - - kj::Promise listen(kj::ConnectionReceiver& listener); - // Listens for connections on the given listener. The returned promise never resolves unless an - // exception is thrown while trying to accept. You may discard the returned promise to cancel - // listening. - -private: - Capability::Client bootstrapInterface; - kj::TaskSet tasks; - - struct AcceptedConnection; - - void taskFailed(kj::Exception&& exception) override; -}; - -class TwoPartyClient { - // Convenience class which implements a simple client. - -public: - explicit TwoPartyClient(kj::AsyncIoStream& connection); - TwoPartyClient(kj::AsyncIoStream& connection, Capability::Client bootstrapInterface, - rpc::twoparty::Side side = rpc::twoparty::Side::CLIENT); - - Capability::Client bootstrap(); - // Get the server's bootstrap interface. - - inline kj::Promise onDisconnect() { return network.onDisconnect(); } - -private: - TwoPartyVatNetwork network; - RpcSystem rpcSystem; -}; - -} // namespace capnp - -#endif // CAPNP_RPC_TWOPARTY_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/rpc.capnp b/phonelibs/capnp-cpp/include/capnp/rpc.capnp deleted file mode 100644 index cd808b39f70466..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/rpc.capnp +++ /dev/null @@ -1,1399 +0,0 @@ -# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -# Licensed under the MIT License: -# -# 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. - -@0xb312981b2552a250; -# Recall that Cap'n Proto RPC allows messages to contain references to remote objects that -# implement interfaces. These references are called "capabilities", because they both designate -# the remote object to use and confer permission to use it. -# -# Recall also that Cap'n Proto RPC has the feature that when a method call itself returns a -# capability, the caller can begin calling methods on that capability _before the first call has -# returned_. The caller essentially sends a message saying "Hey server, as soon as you finish -# that previous call, do this with the result!". Cap'n Proto's RPC protocol makes this possible. -# -# The protocol is significantly more complicated than most RPC protocols. However, this is -# implementation complexity that underlies an easy-to-grasp higher-level model of object oriented -# programming. That is, just like TCP is a surprisingly complicated protocol that implements a -# conceptually-simple byte stream abstraction, Cap'n Proto is a surprisingly complicated protocol -# that implements a conceptually-simple object abstraction. -# -# Cap'n Proto RPC is based heavily on CapTP, the object-capability protocol used by the E -# programming language: -# http://www.erights.org/elib/distrib/captp/index.html -# -# Cap'n Proto RPC takes place between "vats". A vat hosts some set of objects and talks to other -# vats through direct bilateral connections. Typically, there is a 1:1 correspondence between vats -# and processes (in the unix sense of the word), although this is not strictly always true (one -# process could run multiple vats, or a distributed virtual vat might live across many processes). -# -# Cap'n Proto does not distinguish between "clients" and "servers" -- this is up to the application. -# Either end of any connection can potentially hold capabilities pointing to the other end, and -# can call methods on those capabilities. In the doc comments below, we use the words "sender" -# and "receiver". These refer to the sender and receiver of an instance of the struct or field -# being documented. Sometimes we refer to a "third-party" that is neither the sender nor the -# receiver. Documentation is generally written from the point of view of the sender. -# -# It is generally up to the vat network implementation to securely verify that connections are made -# to the intended vat as well as to encrypt transmitted data for privacy and integrity. See the -# `VatNetwork` example interface near the end of this file. -# -# When a new connection is formed, the only interesting things that can be done are to send a -# `Bootstrap` (level 0) or `Accept` (level 3) message. -# -# Unless otherwise specified, messages must be delivered to the receiving application in the same -# order in which they were initiated by the sending application. The goal is to support "E-Order", -# which states that two calls made on the same reference must be delivered in the order which they -# were made: -# http://erights.org/elib/concurrency/partial-order.html -# -# Since the full protocol is complicated, we define multiple levels of support that an -# implementation may target. For many applications, level 1 support will be sufficient. -# Comments in this file indicate which level requires the corresponding feature to be -# implemented. -# -# * **Level 0:** The implementation does not support object references. Only the bootstrap interface -# can be called. At this level, the implementation does not support object-oriented protocols and -# is similar in complexity to JSON-RPC or Protobuf services. This level should be considered only -# a temporary stepping-stone toward level 1 as the lack of object references drastically changes -# how protocols are designed. Applications _should not_ attempt to design their protocols around -# the limitations of level 0 implementations. -# -# * **Level 1:** The implementation supports simple bilateral interaction with object references -# and promise pipelining, but interactions between three or more parties are supported only via -# proxying of objects. E.g. if Alice (in Vat A) wants to send Bob (in Vat B) a capability -# pointing to Carol (in Vat C), Alice must create a proxy of Carol within Vat A and send Bob a -# reference to that; Bob cannot form a direct connection to Carol. Level 1 implementations do -# not support checking if two capabilities received from different vats actually point to the -# same object ("join"), although they should be able to do this check on capabilities received -# from the same vat. -# -# * **Level 2:** The implementation supports saving persistent capabilities -- i.e. capabilities -# that remain valid even after disconnect, and can be restored on a future connection. When a -# capability is saved, the requester receives a `SturdyRef`, which is a token that can be used -# to restore the capability later. -# -# * **Level 3:** The implementation supports three-way interactions. That is, if Alice (in Vat A) -# sends Bob (in Vat B) a capability pointing to Carol (in Vat C), then Vat B will automatically -# form a direct connection to Vat C rather than have requests be proxied through Vat A. -# -# * **Level 4:** The entire protocol is implemented, including joins (checking if two capabilities -# are equivalent). -# -# Note that an implementation must also support specific networks (transports), as described in -# the "Network-specific Parameters" section below. An implementation might have different levels -# depending on the network used. -# -# New implementations of Cap'n Proto should start out targeting the simplistic two-party network -# type as defined in `rpc-twoparty.capnp`. With this network type, level 3 is irrelevant and -# levels 2 and 4 are much easier than usual to implement. When such an implementation is paired -# with a container proxy, the contained app effectively gets to make full use of the proxy's -# network at level 4. And since Cap'n Proto IPC is extremely fast, it may never make sense to -# bother implementing any other vat network protocol -- just use the correct container type and get -# it for free. - -using Cxx = import "/capnp/c++.capnp"; -$Cxx.namespace("capnp::rpc"); - -# ======================================================================================== -# The Four Tables -# -# Cap'n Proto RPC connections are stateful (although an application built on Cap'n Proto could -# export a stateless interface). As in CapTP, for each open connection, a vat maintains four state -# tables: questions, answers, imports, and exports. See the diagram at: -# http://www.erights.org/elib/distrib/captp/4tables.html -# -# The question table corresponds to the other end's answer table, and the imports table corresponds -# to the other end's exports table. -# -# The entries in each table are identified by ID numbers (defined below as 32-bit integers). These -# numbers are always specific to the connection; a newly-established connection starts with no -# valid IDs. Since low-numbered IDs will pack better, it is suggested that IDs be assigned like -# Unix file descriptors -- prefer the lowest-number ID that is currently available. -# -# IDs in the questions/answers tables are chosen by the questioner and generally represent method -# calls that are in progress. -# -# IDs in the imports/exports tables are chosen by the exporter and generally represent objects on -# which methods may be called. Exports may be "settled", meaning the exported object is an actual -# object living in the exporter's vat, or they may be "promises", meaning the exported object is -# the as-yet-unknown result of an ongoing operation and will eventually be resolved to some other -# object once that operation completes. Calls made to a promise will be forwarded to the eventual -# target once it is known. The eventual replacement object does *not* get the same ID as the -# promise, as it may turn out to be an object that is already exported (so already has an ID) or -# may even live in a completely different vat (and so won't get an ID on the same export table -# at all). -# -# IDs can be reused over time. To make this safe, we carefully define the lifetime of IDs. Since -# messages using the ID could be traveling in both directions simultaneously, we must define the -# end of life of each ID _in each direction_. The ID is only safe to reuse once it has been -# released by both sides. -# -# When a Cap'n Proto connection is lost, everything on the four tables is lost. All questions are -# canceled and throw exceptions. All imports become broken (all future calls to them throw -# exceptions). All exports and answers are implicitly released. The only things not lost are -# persistent capabilities (`SturdyRef`s). The application must plan for this and should respond by -# establishing a new connection and restoring from these persistent capabilities. - -using QuestionId = UInt32; -# **(level 0)** -# -# Identifies a question in the sender's question table (which corresponds to the receiver's answer -# table). The questioner (caller) chooses an ID when making a call. The ID remains valid in -# caller -> callee messages until a Finish message is sent, and remains valid in callee -> caller -# messages until a Return message is sent. - -using AnswerId = QuestionId; -# **(level 0)** -# -# Identifies an answer in the sender's answer table (which corresponds to the receiver's question -# table). -# -# AnswerId is physically equivalent to QuestionId, since the question and answer tables correspond, -# but we define a separate type for documentation purposes: we always use the type representing -# the sender's point of view. - -using ExportId = UInt32; -# **(level 1)** -# -# Identifies an exported capability or promise in the sender's export table (which corresponds -# to the receiver's import table). The exporter chooses an ID before sending a capability over the -# wire. If the capability is already in the table, the exporter should reuse the same ID. If the -# ID is a promise (as opposed to a settled capability), this must be indicated at the time the ID -# is introduced (e.g. by using `senderPromise` instead of `senderHosted` in `CapDescriptor`); in -# this case, the importer shall expect a later `Resolve` message that replaces the promise. -# -# ExportId/ImportIds are subject to reference counting. Whenever an `ExportId` is sent over the -# wire (from the exporter to the importer), the export's reference count is incremented (unless -# otherwise specified). The reference count is later decremented by a `Release` message. Since -# the `Release` message can specify an arbitrary number by which to reduce the reference count, the -# importer should usually batch reference decrements and only send a `Release` when it believes the -# reference count has hit zero. Of course, it is possible that a new reference to the export is -# in-flight at the time that the `Release` message is sent, so it is necessary for the exporter to -# keep track of the reference count on its end as well to avoid race conditions. -# -# When a connection is lost, all exports are implicitly released. It is not possible to restore -# a connection state after disconnect (although a transport layer could implement a concept of -# persistent connections if it is transparent to the RPC layer). - -using ImportId = ExportId; -# **(level 1)** -# -# Identifies an imported capability or promise in the sender's import table (which corresponds to -# the receiver's export table). -# -# ImportId is physically equivalent to ExportId, since the export and import tables correspond, -# but we define a separate type for documentation purposes: we always use the type representing -# the sender's point of view. -# -# An `ImportId` remains valid in importer -> exporter messages until the importer has sent -# `Release` messages that (it believes) have reduced the reference count to zero. - -# ======================================================================================== -# Messages - -struct Message { - # An RPC connection is a bi-directional stream of Messages. - - union { - unimplemented @0 :Message; - # The sender previously received this message from the peer but didn't understand it or doesn't - # yet implement the functionality that was requested. So, the sender is echoing the message - # back. In some cases, the receiver may be able to recover from this by pretending the sender - # had taken some appropriate "null" action. - # - # For example, say `resolve` is received by a level 0 implementation (because a previous call - # or return happened to contain a promise). The level 0 implementation will echo it back as - # `unimplemented`. The original sender can then simply release the cap to which the promise - # had resolved, thus avoiding a leak. - # - # For any message type that introduces a question, if the message comes back unimplemented, - # the original sender may simply treat it as if the question failed with an exception. - # - # In cases where there is no sensible way to react to an `unimplemented` message (without - # resource leaks or other serious problems), the connection may need to be aborted. This is - # a gray area; different implementations may take different approaches. - - abort @1 :Exception; - # Sent when a connection is being aborted due to an unrecoverable error. This could be e.g. - # because the sender received an invalid or nonsensical message (`isCallersFault` is true) or - # because the sender had an internal error (`isCallersFault` is false). The sender will shut - # down the outgoing half of the connection after `abort` and will completely close the - # connection shortly thereafter (it's up to the sender how much of a time buffer they want to - # offer for the client to receive the `abort` before the connection is reset). - - # Level 0 features ----------------------------------------------- - - bootstrap @8 :Bootstrap; # Request the peer's bootstrap interface. - call @2 :Call; # Begin a method call. - return @3 :Return; # Complete a method call. - finish @4 :Finish; # Release a returned answer / cancel a call. - - # Level 1 features ----------------------------------------------- - - resolve @5 :Resolve; # Resolve a previously-sent promise. - release @6 :Release; # Release a capability so that the remote object can be deallocated. - disembargo @13 :Disembargo; # Lift an embargo used to enforce E-order over promise resolution. - - # Level 2 features ----------------------------------------------- - - obsoleteSave @7 :AnyPointer; - # Obsolete request to save a capability, resulting in a SturdyRef. This has been replaced - # by the `Persistent` interface defined in `persistent.capnp`. This operation was never - # implemented. - - obsoleteDelete @9 :AnyPointer; - # Obsolete way to delete a SturdyRef. This operation was never implemented. - - # Level 3 features ----------------------------------------------- - - provide @10 :Provide; # Provide a capability to a third party. - accept @11 :Accept; # Accept a capability provided by a third party. - - # Level 4 features ----------------------------------------------- - - join @12 :Join; # Directly connect to the common root of two or more proxied caps. - } -} - -# Level 0 message types ---------------------------------------------- - -struct Bootstrap { - # **(level 0)** - # - # Get the "bootstrap" interface exported by the remote vat. - # - # For level 0, 1, and 2 implementations, the "bootstrap" interface is simply the main interface - # exported by a vat. If the vat acts as a server fielding connections from clients, then the - # bootstrap interface defines the basic functionality available to a client when it connects. - # The exact interface definition obviously depends on the application. - # - # We call this a "bootstrap" because in an ideal Cap'n Proto world, bootstrap interfaces would - # never be used. In such a world, any time you connect to a new vat, you do so because you - # received an introduction from some other vat (see `ThirdPartyCapId`). Thus, the first message - # you send is `Accept`, and further communications derive from there. `Bootstrap` is not used. - # - # In such an ideal world, DNS itself would support Cap'n Proto -- performing a DNS lookup would - # actually return a new Cap'n Proto capability, thus introducing you to the target system via - # level 3 RPC. Applications would receive the capability to talk to DNS in the first place as - # an initial endowment or part of a Powerbox interaction. Therefore, an app can form arbitrary - # connections without ever using `Bootstrap`. - # - # Of course, in the real world, DNS is not Cap'n-Proto-based, and we don't want Cap'n Proto to - # require a whole new internet infrastructure to be useful. Therefore, we offer bootstrap - # interfaces as a way to get up and running without a level 3 introduction. Thus, bootstrap - # interfaces are used to "bootstrap" from other, non-Cap'n-Proto-based means of service discovery, - # such as legacy DNS. - # - # Note that a vat need not provide a bootstrap interface, and in fact many vats (especially those - # acting as clients) do not. In this case, the vat should either reply to `Bootstrap` with a - # `Return` indicating an exception, or should return a dummy capability with no methods. - - questionId @0 :QuestionId; - # A new question ID identifying this request, which will eventually receive a Return message - # containing the restored capability. - - deprecatedObjectId @1 :AnyPointer; - # ** DEPRECATED ** - # - # A Vat may export multiple bootstrap interfaces. In this case, `deprecatedObjectId` specifies - # which one to return. If this pointer is null, then the default bootstrap interface is returned. - # - # As of verison 0.5, use of this field is deprecated. If a service wants to export multiple - # bootstrap interfaces, it should instead define a single bootstarp interface that has methods - # that return each of the other interfaces. - # - # **History** - # - # In the first version of Cap'n Proto RPC (0.4.x) the `Bootstrap` message was called `Restore`. - # At the time, it was thought that this would eventually serve as the way to restore SturdyRefs - # (level 2). Meanwhile, an application could offer its "main" interface on a well-known - # (non-secret) SturdyRef. - # - # Since level 2 RPC was not implemented at the time, the `Restore` message was in practice only - # used to obtain the main interface. Since most applications had only one main interface that - # they wanted to restore, they tended to designate this with a null `objectId`. - # - # Unfortunately, the earliest version of the EZ RPC interfaces set a precedent of exporting - # multiple main interfaces by allowing them to be exported under string names. In this case, - # `objectId` was a Text value specifying the name. - # - # All of this proved problematic for several reasons: - # - # - The arrangement assumed that a client wishing to restore a SturdyRef would know exactly what - # machine to connect to and would be able to immediately restore a SturdyRef on connection. - # However, in practice, the ability to restore SturdyRefs is itself a capability that may - # require going through an authentication process to obtain. Thus, it makes more sense to - # define a "restorer service" as a full Cap'n Proto interface. If this restorer interface is - # offered as the vat's bootstrap interface, then this is equivalent to the old arrangement. - # - # - Overloading "Restore" for the purpose of obtaining well-known capabilities encouraged the - # practice of exporting singleton services with string names. If singleton services are desired, - # it is better to have one main interface that has methods that can be used to obtain each - # service, in order to get all the usual benefits of schemas and type checking. - # - # - Overloading "Restore" also had a security problem: Often, "main" or "well-known" - # capabilities exported by a vat are in fact not public: they are intended to be accessed only - # by clients who are capable of forming a connection to the vat. This can lead to trouble if - # the client itself has other clients and wishes to foward some `Restore` requests from those - # external clients -- it has to be very careful not to allow through `Restore` requests - # addressing the default capability. - # - # For example, consider the case of a sandboxed Sandstorm application and its supervisor. The - # application exports a default capability to its supervisor that provides access to - # functionality that only the supervisor is supposed to access. Meanwhile, though, applications - # may publish other capabilities that may be persistent, in which case the application needs - # to field `Restore` requests that could come from anywhere. These requests of course have to - # pass through the supervisor, as all communications with the outside world must. But, the - # supervisor has to be careful not to honor an external request addressing the application's - # default capability, since this capability is privileged. Unfortunately, the default - # capability cannot be given an unguessable name, because then the supervisor itself would not - # be able to address it! - # - # As of Cap'n Proto 0.5, `Restore` has been renamed to `Bootstrap` and is no longer planned for - # use in restoring SturdyRefs. - # - # Note that 0.4 also defined a message type called `Delete` that, like `Restore`, addressed a - # SturdyRef, but indicated that the client would not restore the ref again in the future. This - # operation was never implemented, so it was removed entirely. If a "delete" operation is desired, - # it should exist as a method on the same interface that handles restoring SturdyRefs. However, - # the utility of such an operation is questionable. You wouldn't be able to rely on it for - # garbage collection since a client could always disappear permanently without remembering to - # delete all its SturdyRefs, thus leaving them dangling forever. Therefore, it is advisable to - # design systems such that SturdyRefs never represent "owned" pointers. - # - # For example, say a SturdyRef points to an image file hosted on some server. That image file - # should also live inside a collection (a gallery, perhaps) hosted on the same server, owned by - # a user who can delete the image at any time. If the user deletes the image, the SturdyRef - # stops working. On the other hand, if the SturdyRef is discarded, this has no effect on the - # existence of the image in its collection. -} - -struct Call { - # **(level 0)** - # - # Message type initiating a method call on a capability. - - questionId @0 :QuestionId; - # A number, chosen by the caller, that identifies this call in future messages. This number - # must be different from all other calls originating from the same end of the connection (but - # may overlap with question IDs originating from the opposite end). A fine strategy is to use - # sequential question IDs, but the recipient should not assume this. - # - # A question ID can be reused once both: - # - A matching Return has been received from the callee. - # - A matching Finish has been sent from the caller. - - target @1 :MessageTarget; - # The object that should receive this call. - - interfaceId @2 :UInt64; - # The type ID of the interface being called. Each capability may implement multiple interfaces. - - methodId @3 :UInt16; - # The ordinal number of the method to call within the requested interface. - - allowThirdPartyTailCall @8 :Bool = false; - # Indicates whether or not the receiver is allowed to send a `Return` containing - # `acceptFromThirdParty`. Level 3 implementations should set this true. Otherwise, the callee - # will have to proxy the return in the case of a tail call to a third-party vat. - - params @4 :Payload; - # The call parameters. `params.content` is a struct whose fields correspond to the parameters of - # the method. - - sendResultsTo :union { - # Where should the return message be sent? - - caller @5 :Void; - # Send the return message back to the caller (the usual). - - yourself @6 :Void; - # **(level 1)** - # - # Don't actually return the results to the sender. Instead, hold on to them and await - # instructions from the sender regarding what to do with them. In particular, the sender - # may subsequently send a `Return` for some other call (which the receiver had previously made - # to the sender) with `takeFromOtherQuestion` set. The results from this call are then used - # as the results of the other call. - # - # When `yourself` is used, the receiver must still send a `Return` for the call, but sets the - # field `resultsSentElsewhere` in that `Return` rather than including the results. - # - # This feature can be used to implement tail calls in which a call from Vat A to Vat B ends up - # returning the result of a call from Vat B back to Vat A. - # - # In particular, the most common use case for this feature is when Vat A makes a call to a - # promise in Vat B, and then that promise ends up resolving to a capability back in Vat A. - # Vat B must forward all the queued calls on that promise back to Vat A, but can set `yourself` - # in the calls so that the results need not pass back through Vat B. - # - # For example: - # - Alice, in Vat A, call foo() on Bob in Vat B. - # - Alice makes a pipelined call bar() on the promise returned by foo(). - # - Later on, Bob resolves the promise from foo() to point at Carol, who lives in Vat A (next - # to Alice). - # - Vat B dutifully forwards the bar() call to Carol. Let us call this forwarded call bar'(). - # Notice that bar() and bar'() are travelling in opposite directions on the same network - # link. - # - The `Call` for bar'() has `sendResultsTo` set to `yourself`, with the value being the - # question ID originally assigned to the bar() call. - # - Vat A receives bar'() and delivers it to Carol. - # - When bar'() returns, Vat A immediately takes the results and returns them from bar(). - # - Meanwhile, Vat A sends a `Return` for bar'() to Vat B, with `resultsSentElsewhere` set in - # place of results. - # - Vat A sends a `Finish` for that call to Vat B. - # - Vat B receives the `Return` for bar'() and sends a `Return` for bar(), with - # `receivedFromYourself` set in place of the results. - # - Vat B receives the `Finish` for bar() and sends a `Finish` to bar'(). - - thirdParty @7 :RecipientId; - # **(level 3)** - # - # The call's result should be returned to a different vat. The receiver (the callee) expects - # to receive an `Accept` message from the indicated vat, and should return the call's result - # to it, rather than to the sender of the `Call`. - # - # This operates much like `yourself`, above, except that Carol is in a separate Vat C. `Call` - # messages are sent from Vat A -> Vat B and Vat B -> Vat C. A `Return` message is sent from - # Vat B -> Vat A that contains `acceptFromThirdParty` in place of results. When Vat A sends - # an `Accept` to Vat C, it receives back a `Return` containing the call's actual result. Vat C - # also sends a `Return` to Vat B with `resultsSentElsewhere`. - } -} - -struct Return { - # **(level 0)** - # - # Message type sent from callee to caller indicating that the call has completed. - - answerId @0 :AnswerId; - # Equal to the QuestionId of the corresponding `Call` message. - - releaseParamCaps @1 :Bool = true; - # If true, all capabilities that were in the params should be considered released. The sender - # must not send separate `Release` messages for them. Level 0 implementations in particular - # should always set this true. This defaults true because if level 0 implementations forget to - # set it they'll never notice (just silently leak caps), but if level >=1 implementations forget - # to set it to false they'll quickly get errors. - - union { - results @2 :Payload; - # The result. - # - # For regular method calls, `results.content` points to the result struct. - # - # For a `Return` in response to an `Accept`, `results` contains a single capability (rather - # than a struct), and `results.content` is just a capability pointer with index 0. A `Finish` - # is still required in this case. - - exception @3 :Exception; - # Indicates that the call failed and explains why. - - canceled @4 :Void; - # Indicates that the call was canceled due to the caller sending a Finish message - # before the call had completed. - - resultsSentElsewhere @5 :Void; - # This is set when returning from a `Call` that had `sendResultsTo` set to something other - # than `caller`. - - takeFromOtherQuestion @6 :QuestionId; - # The sender has also sent (before this message) a `Call` with the given question ID and with - # `sendResultsTo.yourself` set, and the results of that other call should be used as the - # results here. - - acceptFromThirdParty @7 :ThirdPartyCapId; - # **(level 3)** - # - # The caller should contact a third-party vat to pick up the results. An `Accept` message - # sent to the vat will return the result. This pairs with `Call.sendResultsTo.thirdParty`. - # It should only be used if the corresponding `Call` had `allowThirdPartyTailCall` set. - } -} - -struct Finish { - # **(level 0)** - # - # Message type sent from the caller to the callee to indicate: - # 1) The questionId will no longer be used in any messages sent by the callee (no further - # pipelined requests). - # 2) If the call has not returned yet, the caller no longer cares about the result. If nothing - # else cares about the result either (e.g. there are no other outstanding calls pipelined on - # the result of this one) then the callee may wish to immediately cancel the operation and - # send back a Return message with "canceled" set. However, implementations are not required - # to support premature cancellation -- instead, the implementation may wait until the call - # actually completes and send a normal `Return` message. - # - # TODO(someday): Should we separate (1) and implicitly releasing result capabilities? It would be - # possible and useful to notify the server that it doesn't need to keep around the response to - # service pipeline requests even though the caller still wants to receive it / hasn't yet - # finished processing it. It could also be useful to notify the server that it need not marshal - # the results because the caller doesn't want them anyway, even if the caller is still sending - # pipelined calls, although this seems less useful (just saving some bytes on the wire). - - questionId @0 :QuestionId; - # ID of the call whose result is to be released. - - releaseResultCaps @1 :Bool = true; - # If true, all capabilities that were in the results should be considered released. The sender - # must not send separate `Release` messages for them. Level 0 implementations in particular - # should always set this true. This defaults true because if level 0 implementations forget to - # set it they'll never notice (just silently leak caps), but if level >=1 implementations forget - # set it false they'll quickly get errors. -} - -# Level 1 message types ---------------------------------------------- - -struct Resolve { - # **(level 1)** - # - # Message type sent to indicate that a previously-sent promise has now been resolved to some other - # object (possibly another promise) -- or broken, or canceled. - # - # Keep in mind that it's possible for a `Resolve` to be sent to a level 0 implementation that - # doesn't implement it. For example, a method call or return might contain a capability in the - # payload. Normally this is fine even if the receiver is level 0, because they will implicitly - # release all such capabilities on return / finish. But if the cap happens to be a promise, then - # a follow-up `Resolve` may be sent regardless of this release. The level 0 receiver will reply - # with an `unimplemented` message, and the sender (of the `Resolve`) can respond to this as if the - # receiver had immediately released any capability to which the promise resolved. - # - # When implementing promise resolution, it's important to understand how embargos work and the - # tricky case of the Tribble 4-way race condition. See the comments for the Disembargo message, - # below. - - promiseId @0 :ExportId; - # The ID of the promise to be resolved. - # - # Unlike all other instances of `ExportId` sent from the exporter, the `Resolve` message does - # _not_ increase the reference count of `promiseId`. In fact, it is expected that the receiver - # will release the export soon after receiving `Resolve`, and the sender will not send this - # `ExportId` again until it has been released and recycled. - # - # When an export ID sent over the wire (e.g. in a `CapDescriptor`) is indicated to be a promise, - # this indicates that the sender will follow up at some point with a `Resolve` message. If the - # same `promiseId` is sent again before `Resolve`, still only one `Resolve` is sent. If the - # same ID is sent again later _after_ a `Resolve`, it can only be because the export's - # reference count hit zero in the meantime and the ID was re-assigned to a new export, therefore - # this later promise does _not_ correspond to the earlier `Resolve`. - # - # If a promise ID's reference count reaches zero before a `Resolve` is sent, the `Resolve` - # message may or may not still be sent (the `Resolve` may have already been in-flight when - # `Release` was sent, but if the `Release` is received before `Resolve` then there is no longer - # any reason to send a `Resolve`). Thus a `Resolve` may be received for a promise of which - # the receiver has no knowledge, because it already released it earlier. In this case, the - # receiver should simply release the capability to which the promise resolved. - - union { - cap @1 :CapDescriptor; - # The object to which the promise resolved. - # - # The sender promises that from this point forth, until `promiseId` is released, it shall - # simply forward all messages to the capability designated by `cap`. This is true even if - # `cap` itself happens to desigate another promise, and that other promise later resolves -- - # messages sent to `promiseId` shall still go to that other promise, not to its resolution. - # This is important in the case that the receiver of the `Resolve` ends up sending a - # `Disembargo` message towards `promiseId` in order to control message ordering -- that - # `Disembargo` really needs to reflect back to exactly the object designated by `cap` even - # if that object is itself a promise. - - exception @2 :Exception; - # Indicates that the promise was broken. - } -} - -struct Release { - # **(level 1)** - # - # Message type sent to indicate that the sender is done with the given capability and the receiver - # can free resources allocated to it. - - id @0 :ImportId; - # What to release. - - referenceCount @1 :UInt32; - # The amount by which to decrement the reference count. The export is only actually released - # when the reference count reaches zero. -} - -struct Disembargo { - # **(level 1)** - # - # Message sent to indicate that an embargo on a recently-resolved promise may now be lifted. - # - # Embargos are used to enforce E-order in the presence of promise resolution. That is, if an - # application makes two calls foo() and bar() on the same capability reference, in that order, - # the calls should be delivered in the order in which they were made. But if foo() is called - # on a promise, and that promise happens to resolve before bar() is called, then the two calls - # may travel different paths over the network, and thus could arrive in the wrong order. In - # this case, the call to `bar()` must be embargoed, and a `Disembargo` message must be sent along - # the same path as `foo()` to ensure that the `Disembargo` arrives after `foo()`. Once the - # `Disembargo` arrives, `bar()` can then be delivered. - # - # There are two particular cases where embargos are important. Consider object Alice, in Vat A, - # who holds a promise P, pointing towards Vat B, that eventually resolves to Carol. The two - # cases are: - # - Carol lives in Vat A, i.e. next to Alice. In this case, Vat A needs to send a `Disembargo` - # message that echos through Vat B and back, to ensure that all pipelined calls on the promise - # have been delivered. - # - Carol lives in a different Vat C. When the promise resolves, a three-party handoff occurs - # (see `Provide` and `Accept`, which constitute level 3 of the protocol). In this case, we - # piggyback on the state that has already been set up to handle the handoff: the `Accept` - # message (from Vat A to Vat C) is embargoed, as are all pipelined messages sent to it, while - # a `Disembargo` message is sent from Vat A through Vat B to Vat C. See `Accept.embargo` for - # an example. - # - # Note that in the case where Carol actually lives in Vat B (i.e., the same vat that the promise - # already pointed at), no embargo is needed, because the pipelined calls are delivered over the - # same path as the later direct calls. - # - # Keep in mind that promise resolution happens both in the form of Resolve messages as well as - # Return messages (which resolve PromisedAnswers). Embargos apply in both cases. - # - # An alternative strategy for enforcing E-order over promise resolution could be for Vat A to - # implement the embargo internally. When Vat A is notified of promise resolution, it could - # send a dummy no-op call to promise P and wait for it to complete. Until that call completes, - # all calls to the capability are queued locally. This strategy works, but is pessimistic: - # in the three-party case, it requires an A -> B -> C -> B -> A round trip before calls can start - # being delivered directly to from Vat A to Vat C. The `Disembargo` message allows latency to be - # reduced. (In the two-party loopback case, the `Disembargo` message is just a more explicit way - # of accomplishing the same thing as a no-op call, but isn't any faster.) - # - # *The Tribble 4-way Race Condition* - # - # Any implementation of promise resolution and embargos must be aware of what we call the - # "Tribble 4-way race condition", after Dean Tribble, who explained the problem in a lively - # Friam meeting. - # - # Embargos are designed to work in the case where a two-hop path is being shortened to one hop. - # But sometimes there are more hops. Imagine that Alice has a reference to a remote promise P1 - # that eventually resolves to _another_ remote promise P2 (in a third vat), which _at the same - # time_ happens to resolve to Bob (in a fourth vat). In this case, we're shortening from a 3-hop - # path (with four parties) to a 1-hop path (Alice -> Bob). - # - # Extending the embargo/disembargo protocol to be able to shorted multiple hops at once seems - # difficult. Instead, we make a rule that prevents this case from coming up: - # - # One a promise P has been resolved to a remove object reference R, then all further messages - # received addressed to P will be forwarded strictly to R. Even if it turns out later that R is - # itself a promise, and has resolved to some other object Q, messages sent to P will still be - # forwarded to R, not directly to Q (R will of course further forward the messages to Q). - # - # This rule does not cause a significant performance burden because once P has resolved to R, it - # is expected that people sending messages to P will shortly start sending them to R instead and - # drop P. P is at end-of-life anyway, so it doesn't matter if it ignores chances to further - # optimize its path. - - target @0 :MessageTarget; - # What is to be disembargoed. - - using EmbargoId = UInt32; - # Used in `senderLoopback` and `receiverLoopback`, below. - - context :union { - senderLoopback @1 :EmbargoId; - # The sender is requesting a disembargo on a promise that is known to resolve back to a - # capability hosted by the sender. As soon as the receiver has echoed back all pipelined calls - # on this promise, it will deliver the Disembargo back to the sender with `receiverLoopback` - # set to the same value as `senderLoopback`. This value is chosen by the sender, and since - # it is also consumed be the sender, the sender can use whatever strategy it wants to make sure - # the value is unambiguous. - # - # The receiver must verify that the target capability actually resolves back to the sender's - # vat. Otherwise, the sender has committed a protocol error and should be disconnected. - - receiverLoopback @2 :EmbargoId; - # The receiver previously sent a `senderLoopback` Disembargo towards a promise resolving to - # this capability, and that Disembargo is now being echoed back. - - accept @3 :Void; - # **(level 3)** - # - # The sender is requesting a disembargo on a promise that is known to resolve to a third-party - # capability that the sender is currently in the process of accepting (using `Accept`). - # The receiver of this `Disembargo` has an outstanding `Provide` on said capability. The - # receiver should now send a `Disembargo` with `provide` set to the question ID of that - # `Provide` message. - # - # See `Accept.embargo` for an example. - - provide @4 :QuestionId; - # **(level 3)** - # - # The sender is requesting a disembargo on a capability currently being provided to a third - # party. The question ID identifies the `Provide` message previously sent by the sender to - # this capability. On receipt, the receiver (the capability host) shall release the embargo - # on the `Accept` message that it has received from the third party. See `Accept.embargo` for - # an example. - } -} - -# Level 2 message types ---------------------------------------------- - -# See persistent.capnp. - -# Level 3 message types ---------------------------------------------- - -struct Provide { - # **(level 3)** - # - # Message type sent to indicate that the sender wishes to make a particular capability implemented - # by the receiver available to a third party for direct access (without the need for the third - # party to proxy through the sender). - # - # (In CapTP, `Provide` and `Accept` are methods of the global `NonceLocator` object exported by - # every vat. In Cap'n Proto, we bake this into the core protocol.) - - questionId @0 :QuestionId; - # Question ID to be held open until the recipient has received the capability. A result will be - # returned once the third party has successfully received the capability. The sender must at some - # point send a `Finish` message as with any other call, and that message can be used to cancel the - # whole operation. - - target @1 :MessageTarget; - # What is to be provided to the third party. - - recipient @2 :RecipientId; - # Identity of the third party that is expected to pick up the capability. -} - -struct Accept { - # **(level 3)** - # - # Message type sent to pick up a capability hosted by the receiving vat and provided by a third - # party. The third party previously designated the capability using `Provide`. - # - # This message is also used to pick up a redirected return -- see `Return.redirect`. - - questionId @0 :QuestionId; - # A new question ID identifying this accept message, which will eventually receive a Return - # message containing the provided capability (or the call result in the case of a redirected - # return). - - provision @1 :ProvisionId; - # Identifies the provided object to be picked up. - - embargo @2 :Bool; - # If true, this accept shall be temporarily embargoed. The resulting `Return` will not be sent, - # and any pipelined calls will not be delivered, until the embargo is released. The receiver - # (the capability host) will expect the provider (the vat that sent the `Provide` message) to - # eventually send a `Disembargo` message with the field `context.provide` set to the question ID - # of the original `Provide` message. At that point, the embargo is released and the queued - # messages are delivered. - # - # For example: - # - Alice, in Vat A, holds a promise P, which currently points toward Vat B. - # - Alice calls foo() on P. The `Call` message is sent to Vat B. - # - The promise P in Vat B ends up resolving to Carol, in Vat C. - # - Vat B sends a `Provide` message to Vat C, identifying Vat A as the recipient. - # - Vat B sends a `Resolve` message to Vat A, indicating that the promise has resolved to a - # `ThirdPartyCapId` identifying Carol in Vat C. - # - Vat A sends an `Accept` message to Vat C to pick up the capability. Since Vat A knows that - # it has an outstanding call to the promise, it sets `embargo` to `true` in the `Accept` - # message. - # - Vat A sends a `Disembargo` message to Vat B on promise P, with `context.accept` set. - # - Alice makes a call bar() to promise P, which is now pointing towards Vat C. Alice doesn't - # know anything about the mechanics of promise resolution happening under the hood, but she - # expects that bar() will be delivered after foo() because that is the order in which she - # initiated the calls. - # - Vat A sends the bar() call to Vat C, as a pipelined call on the result of the `Accept` (which - # hasn't returned yet, due to the embargo). Since calls to the newly-accepted capability - # are embargoed, Vat C does not deliver the call yet. - # - At some point, Vat B forwards the foo() call from the beginning of this example on to Vat C. - # - Vat B forwards the `Disembargo` from Vat A on to vat C. It sets `context.provide` to the - # question ID of the `Provide` message it had sent previously. - # - Vat C receives foo() before `Disembargo`, thus allowing it to correctly deliver foo() - # before delivering bar(). - # - Vat C receives `Disembargo` from Vat B. It can now send a `Return` for the `Accept` from - # Vat A, as well as deliver bar(). -} - -# Level 4 message types ---------------------------------------------- - -struct Join { - # **(level 4)** - # - # Message type sent to implement E.join(), which, given a number of capabilities that are - # expected to be equivalent, finds the underlying object upon which they all agree and forms a - # direct connection to it, skipping any proxies that may have been constructed by other vats - # while transmitting the capability. See: - # http://erights.org/elib/equality/index.html - # - # Note that this should only serve to bypass fully-transparent proxies -- proxies that were - # created merely for convenience, without any intention of hiding the underlying object. - # - # For example, say Bob holds two capabilities hosted by Alice and Carol, but he expects that both - # are simply proxies for a capability hosted elsewhere. He then issues a join request, which - # operates as follows: - # - Bob issues Join requests on both Alice and Carol. Each request contains a different piece - # of the JoinKey. - # - Alice is proxying a capability hosted by Dana, so forwards the request to Dana's cap. - # - Dana receives the first request and sees that the JoinKeyPart is one of two. She notes that - # she doesn't have the other part yet, so she records the request and responds with a - # JoinResult. - # - Alice relays the JoinAswer back to Bob. - # - Carol is also proxying a capability from Dana, and so forwards her Join request to Dana as - # well. - # - Dana receives Carol's request and notes that she now has both parts of a JoinKey. She - # combines them in order to form information needed to form a secure connection to Bob. She - # also responds with another JoinResult. - # - Bob receives the responses from Alice and Carol. He uses the returned JoinResults to - # determine how to connect to Dana and attempts to form the connection. Since Bob and Dana now - # agree on a secret key that neither Alice nor Carol ever saw, this connection can be made - # securely even if Alice or Carol is conspiring against the other. (If Alice and Carol are - # conspiring _together_, they can obviously reproduce the key, but this doesn't matter because - # the whole point of the join is to verify that Alice and Carol agree on what capability they - # are proxying.) - # - # If the two capabilities aren't actually proxies of the same object, then the join requests - # will come back with conflicting `hostId`s and the join will fail before attempting to form any - # connection. - - questionId @0 :QuestionId; - # Question ID used to respond to this Join. (Note that this ID only identifies one part of the - # request for one hop; each part has a different ID and relayed copies of the request have - # (probably) different IDs still.) - # - # The receiver will reply with a `Return` whose `results` is a JoinResult. This `JoinResult` - # is relayed from the joined object's host, possibly with transformation applied as needed - # by the network. - # - # Like any return, the result must be released using a `Finish`. However, this release - # should not occur until the joiner has either successfully connected to the joined object. - # Vats relaying a `Join` message similarly must not release the result they receive until the - # return they relayed back towards the joiner has itself been released. This allows the - # joined object's host to detect when the Join operation is canceled before completing -- if - # it receives a `Finish` for one of the join results before the joiner successfully - # connects. It can then free any resources it had allocated as part of the join. - - target @1 :MessageTarget; - # The capability to join. - - keyPart @2 :JoinKeyPart; - # A part of the join key. These combine to form the complete join key, which is used to establish - # a direct connection. - - # TODO(before implementing): Change this so that multiple parts can be sent in a single Join - # message, so that if multiple join parts are going to cross the same connection they can be sent - # together, so that the receive can potentially optimize its handling of them. In the case where - # all parts are bundled together, should the recipient be expected to simply return a cap, so - # that the caller can immediately start pipelining to it? -} - -# ======================================================================================== -# Common structures used in messages - -struct MessageTarget { - # The target of a `Call` or other messages that target a capability. - - union { - importedCap @0 :ImportId; - # This message is to a capability or promise previously imported by the caller (exported by - # the receiver). - - promisedAnswer @1 :PromisedAnswer; - # This message is to a capability that is expected to be returned by another call that has not - # yet been completed. - # - # At level 0, this is supported only for addressing the result of a previous `Bootstrap`, so - # that initial startup doesn't require a round trip. - } -} - -struct Payload { - # Represents some data structure that might contain capabilities. - - content @0 :AnyPointer; - # Some Cap'n Proto data structure. Capability pointers embedded in this structure index into - # `capTable`. - - capTable @1 :List(CapDescriptor); - # Descriptors corresponding to the cap pointers in `content`. -} - -struct CapDescriptor { - # **(level 1)** - # - # When an application-defined type contains an interface pointer, that pointer contains an index - # into the message's capability table -- i.e. the `capTable` part of the `Payload`. Each - # capability in the table is represented as a `CapDescriptor`. The runtime API should not reveal - # the CapDescriptor directly to the application, but should instead wrap it in some kind of - # callable object with methods corresponding to the interface that the capability implements. - # - # Keep in mind that `ExportIds` in a `CapDescriptor` are subject to reference counting. See the - # description of `ExportId`. - - union { - none @0 :Void; - # There is no capability here. This `CapDescriptor` should not appear in the payload content. - # A `none` CapDescriptor can be generated when an application inserts a capability into a - # message and then later changes its mind and removes it -- rewriting all of the other - # capability pointers may be hard, so instead a tombstone is left, similar to the way a removed - # struct or list instance is zeroed out of the message but the space is not reclaimed. - # Hopefully this is unusual. - - senderHosted @1 :ExportId; - # A capability newly exported by the sender. This is the ID of the new capability in the - # sender's export table (receiver's import table). - - senderPromise @2 :ExportId; - # A promise that the sender will resolve later. The sender will send exactly one Resolve - # message at a future point in time to replace this promise. Note that even if the same - # `senderPromise` is received multiple times, only one `Resolve` is sent to cover all of - # them. If `senderPromise` is released before the `Resolve` is sent, the sender (of this - # `CapDescriptor`) may choose not to send the `Resolve` at all. - - receiverHosted @3 :ImportId; - # A capability (or promise) previously exported by the receiver (imported by the sender). - - receiverAnswer @4 :PromisedAnswer; - # A capability expected to be returned in the results of a currently-outstanding call posed - # by the sender. - - thirdPartyHosted @5 :ThirdPartyCapDescriptor; - # **(level 3)** - # - # A capability that lives in neither the sender's nor the receiver's vat. The sender needs - # to form a direct connection to a third party to pick up the capability. - # - # Level 1 and 2 implementations that receive a `thirdPartyHosted` may simply send calls to its - # `vine` instead. - } -} - -struct PromisedAnswer { - # **(mostly level 1)** - # - # Specifies how to derive a promise from an unanswered question, by specifying the path of fields - # to follow from the root of the eventual result struct to get to the desired capability. Used - # to address method calls to a not-yet-returned capability or to pass such a capability as an - # input to some other method call. - # - # Level 0 implementations must support `PromisedAnswer` only for the case where the answer is - # to a `Bootstrap` message. In this case, `path` is always empty since `Bootstrap` always returns - # a raw capability. - - questionId @0 :QuestionId; - # ID of the question (in the sender's question table / receiver's answer table) whose answer is - # expected to contain the capability. - - transform @1 :List(Op); - # Operations / transformations to apply to the result in order to get the capability actually - # being addressed. E.g. if the result is a struct and you want to call a method on a capability - # pointed to by a field of the struct, you need a `getPointerField` op. - - struct Op { - union { - noop @0 :Void; - # Does nothing. This member is mostly defined so that we can make `Op` a union even - # though (as of this writing) only one real operation is defined. - - getPointerField @1 :UInt16; - # Get a pointer field within a struct. The number is an index into the pointer section, NOT - # a field ordinal, so that the receiver does not need to understand the schema. - - # TODO(someday): We could add: - # - For lists, the ability to address every member of the list, or a slice of the list, the - # result of which would be another list. This is useful for implementing the equivalent of - # a SQL table join (not to be confused with the `Join` message type). - # - Maybe some ability to test a union. - # - Probably not a good idea: the ability to specify an arbitrary script to run on the - # result. We could define a little stack-based language where `Op` specifies one - # "instruction" or transformation to apply. Although this is not a good idea - # (over-engineered), any narrower additions to `Op` should be designed as if this - # were the eventual goal. - } - } -} - -struct ThirdPartyCapDescriptor { - # **(level 3)** - # - # Identifies a capability in a third-party vat that the sender wants the receiver to pick up. - - id @0 :ThirdPartyCapId; - # Identifies the third-party host and the specific capability to accept from it. - - vineId @1 :ExportId; - # A proxy for the third-party object exported by the sender. In CapTP terminology this is called - # a "vine", because it is an indirect reference to the third-party object that snakes through the - # sender vat. This serves two purposes: - # - # * Level 1 and 2 implementations that don't understand how to connect to a third party may - # simply send calls to the vine. Such calls will be forwarded to the third-party by the - # sender. - # - # * Level 3 implementations must release the vine once they have successfully picked up the - # object from the third party. This ensures that the capability is not released by the sender - # prematurely. - # - # The sender will close the `Provide` request that it has sent to the third party as soon as - # it receives either a `Call` or a `Release` message directed at the vine. -} - -struct Exception { - # **(level 0)** - # - # Describes an arbitrary error that prevented an operation (e.g. a call) from completing. - # - # Cap'n Proto exceptions always indicate that something went wrong. In other words, in a fantasy - # world where everything always works as expected, no exceptions would ever be thrown. Clients - # should only ever catch exceptions as a means to implement fault-tolerance, where "fault" can - # mean: - # - Bugs. - # - Invalid input. - # - Configuration errors. - # - Network problems. - # - Insufficient resources. - # - Version skew (unimplemented functionality). - # - Other logistical problems. - # - # Exceptions should NOT be used to flag application-specific conditions that a client is expected - # to handle in an application-specific way. Put another way, in the Cap'n Proto world, - # "checked exceptions" (where an interface explicitly defines the exceptions it throws and - # clients are forced by the type system to handle those exceptions) do NOT make sense. - - reason @0 :Text; - # Human-readable failure description. - - type @3 :Type; - # The type of the error. The purpose of this enum is not to describe the error itself, but - # rather to describe how the client might want to respond to the error. - - enum Type { - failed @0; - # A generic problem occurred, and it is believed that if the operation were repeated without - # any change in the state of the world, the problem would occur again. - # - # A client might respond to this error by logging it for investigation by the developer and/or - # displaying it to the user. - - overloaded @1; - # The request was rejected due to a temporary lack of resources. - # - # Examples include: - # - There's not enough CPU time to keep up with incoming requests, so some are rejected. - # - The server ran out of RAM or disk space during the request. - # - The operation timed out (took significantly longer than it should have). - # - # A client might respond to this error by scheduling to retry the operation much later. The - # client should NOT retry again immediately since this would likely exacerbate the problem. - - disconnected @2; - # The method failed because a connection to some necessary capability was lost. - # - # Examples include: - # - The client introduced the server to a third-party capability, the connection to that third - # party was subsequently lost, and then the client requested that the server use the dead - # capability for something. - # - The client previously requested that the server obtain a capability from some third party. - # The server returned a capability to an object wrapping the third-party capability. Later, - # the server's connection to the third party was lost. - # - The capability has been revoked. Revocation does not necessarily mean that the client is - # no longer authorized to use the capability; it is often used simply as a way to force the - # client to repeat the setup process, perhaps to efficiently move them to a new back-end or - # get them to recognize some other change that has occurred. - # - # A client should normally respond to this error by releasing all capabilities it is currently - # holding related to the one it called and then re-creating them by restoring SturdyRefs and/or - # repeating the method calls used to create them originally. In other words, disconnect and - # start over. This should in turn cause the server to obtain a new copy of the capability that - # it lost, thus making everything work. - # - # If the client receives another `disconnencted` error in the process of rebuilding the - # capability and retrying the call, it should treat this as an `overloaded` error: the network - # is currently unreliable, possibly due to load or other temporary issues. - - unimplemented @3; - # The server doesn't implement the requested method. If there is some other method that the - # client could call (perhaps an older and/or slower interface), it should try that instead. - # Otherwise, this should be treated like `failed`. - } - - obsoleteIsCallersFault @1 :Bool; - # OBSOLETE. Ignore. - - obsoleteDurability @2 :UInt16; - # OBSOLETE. See `type` instead. -} - -# ======================================================================================== -# Network-specific Parameters -# -# Some parts of the Cap'n Proto RPC protocol are not specified here because different vat networks -# may wish to use different approaches to solving them. For example, on the public internet, you -# may want to authenticate vats using public-key cryptography, but on a local intranet with trusted -# infrastructure, you may be happy to authenticate based on network address only, or some other -# lightweight mechanism. -# -# To accommodate this, we specify several "parameter" types. Each type is defined here as an -# alias for `AnyPointer`, but a specific network will want to define a specific set of types to use. -# All vats in a vat network must agree on these parameters in order to be able to communicate. -# Inter-network communication can be accomplished through "gateways" that perform translation -# between the primitives used on each network; these gateways may need to be deeply stateful, -# depending on the translations they perform. -# -# For interaction over the global internet between parties with no other prior arrangement, a -# particular set of bindings for these types is defined elsewhere. (TODO(someday): Specify where -# these common definitions live.) -# -# Another common network type is the two-party network, in which one of the parties typically -# interacts with the outside world entirely through the other party. In such a connection between -# Alice and Bob, all objects that exist on Bob's other networks appear to Alice as if they were -# hosted by Bob himself, and similarly all objects on Alice's network (if she even has one) appear -# to Bob as if they were hosted by Alice. This network type is interesting because from the point -# of view of a simple application that communicates with only one other party via the two-party -# protocol, there are no three-party interactions at all, and joins are unusually simple to -# implement, so implementing at level 4 is barely more complicated than implementing at level 1. -# Moreover, if you pair an app implementing the two-party network with a container that implements -# some other network, the app can then participate on the container's network just as if it -# implemented that network directly. The types used by the two-party network are defined in -# `rpc-twoparty.capnp`. -# -# The things that we need to parameterize are: -# - How to store capabilities long-term without holding a connection open (mostly level 2). -# - How to authenticate vats in three-party introductions (level 3). -# - How to implement `Join` (level 4). -# -# Persistent references -# --------------------- -# -# **(mostly level 2)** -# -# We want to allow some capabilities to be stored long-term, even if a connection is lost and later -# recreated. ExportId is a short-term identifier that is specific to a connection, so it doesn't -# help here. We need a way to specify long-term identifiers, as well as a strategy for -# reconnecting to a referenced capability later. -# -# Three-party interactions -# ------------------------ -# -# **(level 3)** -# -# In cases where more than two vats are interacting, we have situations where VatA holds a -# capability hosted by VatB and wants to send that capability to VatC. This can be accomplished -# by VatA proxying requests on the new capability, but doing so has two big problems: -# - It's inefficient, requiring an extra network hop. -# - If VatC receives another capability to the same object from VatD, it is difficult for VatC to -# detect that the two capabilities are really the same and to implement the E "join" operation, -# which is necessary for certain four-or-more-party interactions, such as the escrow pattern. -# See: http://www.erights.org/elib/equality/grant-matcher/index.html -# -# Instead, we want a way for VatC to form a direct, authenticated connection to VatB. -# -# Join -# ---- -# -# **(level 4)** -# -# The `Join` message type and corresponding operation arranges for a direct connection to be formed -# between the joiner and the host of the joined object, and this connection must be authenticated. -# Thus, the details are network-dependent. - -using SturdyRef = AnyPointer; -# **(level 2)** -# -# Identifies a persisted capability that can be restored in the future. How exactly a SturdyRef -# is restored to a live object is specified along with the SturdyRef definition (i.e. not by -# rpc.capnp). -# -# Generally a SturdyRef needs to specify three things: -# - How to reach the vat that can restore the ref (e.g. a hostname or IP address). -# - How to authenticate the vat after connecting (e.g. a public key fingerprint). -# - The identity of a specific object hosted by the vat. Generally, this is an opaque pointer whose -# format is defined by the specific vat -- the client has no need to inspect the object ID. -# It is important that the objec ID be unguessable if the object is not public (and objects -# should almost never be public). -# -# The above are only suggestions. Some networks might work differently. For example, a private -# network might employ a special restorer service whose sole purpose is to restore SturdyRefs. -# In this case, the entire contents of SturdyRef might be opaque, because they are intended only -# to be forwarded to the restorer service. - -using ProvisionId = AnyPointer; -# **(level 3)** -# -# The information that must be sent in an `Accept` message to identify the object being accepted. -# -# In a network where each vat has a public/private key pair, this could simply be the public key -# fingerprint of the provider vat along with the question ID used in the `Provide` message sent from -# that provider. - -using RecipientId = AnyPointer; -# **(level 3)** -# -# The information that must be sent in a `Provide` message to identify the recipient of the -# capability. -# -# In a network where each vat has a public/private key pair, this could simply be the public key -# fingerprint of the recipient. (CapTP also calls for a nonce to identify the object. In our -# case, the `Provide` message's `questionId` can serve as the nonce.) - -using ThirdPartyCapId = AnyPointer; -# **(level 3)** -# -# The information needed to connect to a third party and accept a capability from it. -# -# In a network where each vat has a public/private key pair, this could be a combination of the -# third party's public key fingerprint, hints on how to connect to the third party (e.g. an IP -# address), and the question ID used in the corresponding `Provide` message sent to that third party -# (used to identify which capability to pick up). - -using JoinKeyPart = AnyPointer; -# **(level 4)** -# -# A piece of a secret key. One piece is sent along each path that is expected to lead to the same -# place. Once the pieces are combined, a direct connection may be formed between the sender and -# the receiver, bypassing any men-in-the-middle along the paths. See the `Join` message type. -# -# The motivation for Joins is discussed under "Supporting Equality" in the "Unibus" protocol -# sketch: http://www.erights.org/elib/distrib/captp/unibus.html -# -# In a network where each vat has a public/private key pair and each vat forms no more than one -# connection to each other vat, Joins will rarely -- perhaps never -- be needed, as objects never -# need to be transparently proxied and references to the same object sent over the same connection -# have the same export ID. Thus, a successful join requires only checking that the two objects -# come from the same connection and have the same ID, and then completes immediately. -# -# However, in networks where two vats may form more than one connection between each other, or -# where proxying of objects occurs, joins are necessary. -# -# Typically, each JoinKeyPart would include a fixed-length data value such that all value parts -# XOR'd together forms a shared secret that can be used to form an encrypted connection between -# the joiner and the joined object's host. Each JoinKeyPart should also include an indication of -# how many parts to expect and a hash of the shared secret (used to match up parts). - -using JoinResult = AnyPointer; -# **(level 4)** -# -# Information returned as the result to a `Join` message, needed by the joiner in order to form a -# direct connection to a joined object. This might simply be the address of the joined object's -# host vat, since the `JoinKey` has already been communicated so the two vats already have a shared -# secret to use to authenticate each other. -# -# The `JoinResult` should also contain information that can be used to detect when the Join -# requests ended up reaching different objects, so that this situation can be detected easily. -# This could be a simple matter of including a sequence number -- if the joiner receives two -# `JoinResult`s with sequence number 0, then they must have come from different objects and the -# whole join is a failure. - -# ======================================================================================== -# Network interface sketch -# -# The interfaces below are meant to be pseudo-code to illustrate how the details of a particular -# vat network might be abstracted away. They are written like Cap'n Proto interfaces, but in -# practice you'd probably define these interfaces manually in the target programming language. A -# Cap'n Proto RPC implementation should be able to use these interfaces without knowing the -# definitions of the various network-specific parameters defined above. - -# interface VatNetwork { -# # Represents a vat network, with the ability to connect to particular vats and receive -# # connections from vats. -# # -# # Note that methods returning a `Connection` may return a pre-existing `Connection`, and the -# # caller is expected to find and share state with existing users of the connection. -# -# # Level 0 features ----------------------------------------------- -# -# connect(vatId :VatId) :Connection; -# # Connect to the given vat. The transport should return a promise that does not -# # resolve until authentication has completed, but allows messages to be pipelined in before -# # that; the transport either queues these messages until authenticated, or sends them encrypted -# # such that only the authentic vat would be able to decrypt them. The latter approach avoids a -# # round trip for authentication. -# -# accept() :Connection; -# # Wait for the next incoming connection and return it. Only connections formed by -# # connect() are returned by this method. -# -# # Level 4 features ----------------------------------------------- -# -# newJoiner(count :UInt32) :NewJoinerResponse; -# # Prepare a new Join operation, which will eventually lead to forming a new direct connection -# # to the host of the joined capability. `count` is the number of capabilities to join. -# -# struct NewJoinerResponse { -# joinKeyParts :List(JoinKeyPart); -# # Key parts to send in Join messages to each capability. -# -# joiner :Joiner; -# # Used to establish the final connection. -# } -# -# interface Joiner { -# addJoinResult(result :JoinResult) :Void; -# # Add a JoinResult received in response to one of the `Join` messages. All `JoinResult`s -# # returned from all paths must be added before trying to connect. -# -# connect() :ConnectionAndProvisionId; -# # Try to form a connection to the joined capability's host, verifying that it has received -# # all of the JoinKeyParts. Once the connection is formed, the caller should send an `Accept` -# # message on it with the specified `ProvisionId` in order to receive the final capability. -# } -# -# acceptConnectionFromJoiner(parts :List(JoinKeyPart), paths :List(VatPath)) -# :ConnectionAndProvisionId; -# # Called on a joined capability's host to receive the connection from the joiner, once all -# # key parts have arrived. The caller should expect to receive an `Accept` message over the -# # connection with the given ProvisionId. -# } -# -# interface Connection { -# # Level 0 features ----------------------------------------------- -# -# send(message :Message) :Void; -# # Send the message. Returns successfully when the message (and all preceding messages) has -# # been acknowledged by the recipient. -# -# receive() :Message; -# # Receive the next message, and acknowledges receipt to the sender. Messages are received in -# # the order in which they are sent. -# -# # Level 3 features ----------------------------------------------- -# -# introduceTo(recipient :Connection) :IntroductionInfo; -# # Call before starting a three-way introduction, assuming a `Provide` message is to be sent on -# # this connection and a `ThirdPartyCapId` is to be sent to `recipient`. -# -# struct IntroductionInfo { -# sendToRecipient :ThirdPartyCapId; -# sendToTarget :RecipientId; -# } -# -# connectToIntroduced(capId :ThirdPartyCapId) :ConnectionAndProvisionId; -# # Given a ThirdPartyCapId received over this connection, connect to the third party. The -# # caller should then send an `Accept` message over the new connection. -# -# acceptIntroducedConnection(recipientId :RecipientId) :Connection; -# # Given a RecipientId received in a `Provide` message on this `Connection`, wait for the -# # recipient to connect, and return the connection formed. Usually, the first message received -# # on the new connection will be an `Accept` message. -# } -# -# struct ConnectionAndProvisionId { -# # **(level 3)** -# -# connection :Connection; -# # Connection on which to issue `Accept` message. -# -# provision :ProvisionId; -# # `ProvisionId` to send in the `Accept` message. -# } diff --git a/phonelibs/capnp-cpp/include/capnp/rpc.capnp.h b/phonelibs/capnp-cpp/include/capnp/rpc.capnp.h deleted file mode 100644 index 0a440397fc3b51..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/rpc.capnp.h +++ /dev/null @@ -1,4898 +0,0 @@ -// Generated by Cap'n Proto compiler, DO NOT EDIT -// source: rpc.capnp - -#ifndef CAPNP_INCLUDED_b312981b2552a250_ -#define CAPNP_INCLUDED_b312981b2552a250_ - -#include - -#if CAPNP_VERSION != 6001 -#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." -#endif - - -namespace capnp { -namespace schemas { - -CAPNP_DECLARE_SCHEMA(91b79f1f808db032); -CAPNP_DECLARE_SCHEMA(e94ccf8031176ec4); -CAPNP_DECLARE_SCHEMA(836a53ce789d4cd4); -CAPNP_DECLARE_SCHEMA(dae8b0f61aab5f99); -CAPNP_DECLARE_SCHEMA(9e19b28d3db3573a); -CAPNP_DECLARE_SCHEMA(d37d2eb2c2f80e63); -CAPNP_DECLARE_SCHEMA(bbc29655fa89086e); -CAPNP_DECLARE_SCHEMA(ad1a6c0d7dd07497); -CAPNP_DECLARE_SCHEMA(f964368b0fbd3711); -CAPNP_DECLARE_SCHEMA(d562b4df655bdd4d); -CAPNP_DECLARE_SCHEMA(9c6a046bfbc1ac5a); -CAPNP_DECLARE_SCHEMA(d4c9b56290554016); -CAPNP_DECLARE_SCHEMA(fbe1980490e001af); -CAPNP_DECLARE_SCHEMA(95bc14545813fbc1); -CAPNP_DECLARE_SCHEMA(9a0e61223d96743b); -CAPNP_DECLARE_SCHEMA(8523ddc40b86b8b0); -CAPNP_DECLARE_SCHEMA(d800b1d6cd6f1ca0); -CAPNP_DECLARE_SCHEMA(f316944415569081); -CAPNP_DECLARE_SCHEMA(d37007fde1f0027d); -CAPNP_DECLARE_SCHEMA(d625b7063acf691a); -CAPNP_DECLARE_SCHEMA(b28c96e23f4cbd58); -enum class Type_b28c96e23f4cbd58: uint16_t { - FAILED, - OVERLOADED, - DISCONNECTED, - UNIMPLEMENTED, -}; -CAPNP_DECLARE_ENUM(Type, b28c96e23f4cbd58); - -} // namespace schemas -} // namespace capnp - -namespace capnp { -namespace rpc { - -struct Message { - Message() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - UNIMPLEMENTED, - ABORT, - CALL, - RETURN, - FINISH, - RESOLVE, - RELEASE, - OBSOLETE_SAVE, - BOOTSTRAP, - OBSOLETE_DELETE, - PROVIDE, - ACCEPT, - JOIN, - DISEMBARGO, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(91b79f1f808db032, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Bootstrap { - Bootstrap() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(e94ccf8031176ec4, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Call { - Call() = delete; - - class Reader; - class Builder; - class Pipeline; - struct SendResultsTo; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(836a53ce789d4cd4, 3, 3) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Call::SendResultsTo { - SendResultsTo() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - CALLER, - YOURSELF, - THIRD_PARTY, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(dae8b0f61aab5f99, 3, 3) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Return { - Return() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - RESULTS, - EXCEPTION, - CANCELED, - RESULTS_SENT_ELSEWHERE, - TAKE_FROM_OTHER_QUESTION, - ACCEPT_FROM_THIRD_PARTY, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9e19b28d3db3573a, 2, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Finish { - Finish() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d37d2eb2c2f80e63, 1, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Resolve { - Resolve() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - CAP, - EXCEPTION, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(bbc29655fa89086e, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Release { - Release() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(ad1a6c0d7dd07497, 1, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Disembargo { - Disembargo() = delete; - - class Reader; - class Builder; - class Pipeline; - struct Context; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(f964368b0fbd3711, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Disembargo::Context { - Context() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - SENDER_LOOPBACK, - RECEIVER_LOOPBACK, - ACCEPT, - PROVIDE, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d562b4df655bdd4d, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Provide { - Provide() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9c6a046bfbc1ac5a, 1, 2) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Accept { - Accept() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d4c9b56290554016, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Join { - Join() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(fbe1980490e001af, 1, 2) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct MessageTarget { - MessageTarget() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - IMPORTED_CAP, - PROMISED_ANSWER, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(95bc14545813fbc1, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Payload { - Payload() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9a0e61223d96743b, 0, 2) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct CapDescriptor { - CapDescriptor() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - NONE, - SENDER_HOSTED, - SENDER_PROMISE, - RECEIVER_HOSTED, - RECEIVER_ANSWER, - THIRD_PARTY_HOSTED, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(8523ddc40b86b8b0, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct PromisedAnswer { - PromisedAnswer() = delete; - - class Reader; - class Builder; - class Pipeline; - struct Op; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d800b1d6cd6f1ca0, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct PromisedAnswer::Op { - Op() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - NOOP, - GET_POINTER_FIELD, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(f316944415569081, 1, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct ThirdPartyCapDescriptor { - ThirdPartyCapDescriptor() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d37007fde1f0027d, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Exception { - Exception() = delete; - - class Reader; - class Builder; - class Pipeline; - typedef ::capnp::schemas::Type_b28c96e23f4cbd58 Type; - - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d625b7063acf691a, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -// ======================================================================================= - -class Message::Reader { -public: - typedef Message Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isUnimplemented() const; - inline bool hasUnimplemented() const; - inline ::capnp::rpc::Message::Reader getUnimplemented() const; - - inline bool isAbort() const; - inline bool hasAbort() const; - inline ::capnp::rpc::Exception::Reader getAbort() const; - - inline bool isCall() const; - inline bool hasCall() const; - inline ::capnp::rpc::Call::Reader getCall() const; - - inline bool isReturn() const; - inline bool hasReturn() const; - inline ::capnp::rpc::Return::Reader getReturn() const; - - inline bool isFinish() const; - inline bool hasFinish() const; - inline ::capnp::rpc::Finish::Reader getFinish() const; - - inline bool isResolve() const; - inline bool hasResolve() const; - inline ::capnp::rpc::Resolve::Reader getResolve() const; - - inline bool isRelease() const; - inline bool hasRelease() const; - inline ::capnp::rpc::Release::Reader getRelease() const; - - inline bool isObsoleteSave() const; - inline bool hasObsoleteSave() const; - inline ::capnp::AnyPointer::Reader getObsoleteSave() const; - - inline bool isBootstrap() const; - inline bool hasBootstrap() const; - inline ::capnp::rpc::Bootstrap::Reader getBootstrap() const; - - inline bool isObsoleteDelete() const; - inline bool hasObsoleteDelete() const; - inline ::capnp::AnyPointer::Reader getObsoleteDelete() const; - - inline bool isProvide() const; - inline bool hasProvide() const; - inline ::capnp::rpc::Provide::Reader getProvide() const; - - inline bool isAccept() const; - inline bool hasAccept() const; - inline ::capnp::rpc::Accept::Reader getAccept() const; - - inline bool isJoin() const; - inline bool hasJoin() const; - inline ::capnp::rpc::Join::Reader getJoin() const; - - inline bool isDisembargo() const; - inline bool hasDisembargo() const; - inline ::capnp::rpc::Disembargo::Reader getDisembargo() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Message::Builder { -public: - typedef Message Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isUnimplemented(); - inline bool hasUnimplemented(); - inline ::capnp::rpc::Message::Builder getUnimplemented(); - inline void setUnimplemented( ::capnp::rpc::Message::Reader value); - inline ::capnp::rpc::Message::Builder initUnimplemented(); - inline void adoptUnimplemented(::capnp::Orphan< ::capnp::rpc::Message>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Message> disownUnimplemented(); - - inline bool isAbort(); - inline bool hasAbort(); - inline ::capnp::rpc::Exception::Builder getAbort(); - inline void setAbort( ::capnp::rpc::Exception::Reader value); - inline ::capnp::rpc::Exception::Builder initAbort(); - inline void adoptAbort(::capnp::Orphan< ::capnp::rpc::Exception>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Exception> disownAbort(); - - inline bool isCall(); - inline bool hasCall(); - inline ::capnp::rpc::Call::Builder getCall(); - inline void setCall( ::capnp::rpc::Call::Reader value); - inline ::capnp::rpc::Call::Builder initCall(); - inline void adoptCall(::capnp::Orphan< ::capnp::rpc::Call>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Call> disownCall(); - - inline bool isReturn(); - inline bool hasReturn(); - inline ::capnp::rpc::Return::Builder getReturn(); - inline void setReturn( ::capnp::rpc::Return::Reader value); - inline ::capnp::rpc::Return::Builder initReturn(); - inline void adoptReturn(::capnp::Orphan< ::capnp::rpc::Return>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Return> disownReturn(); - - inline bool isFinish(); - inline bool hasFinish(); - inline ::capnp::rpc::Finish::Builder getFinish(); - inline void setFinish( ::capnp::rpc::Finish::Reader value); - inline ::capnp::rpc::Finish::Builder initFinish(); - inline void adoptFinish(::capnp::Orphan< ::capnp::rpc::Finish>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Finish> disownFinish(); - - inline bool isResolve(); - inline bool hasResolve(); - inline ::capnp::rpc::Resolve::Builder getResolve(); - inline void setResolve( ::capnp::rpc::Resolve::Reader value); - inline ::capnp::rpc::Resolve::Builder initResolve(); - inline void adoptResolve(::capnp::Orphan< ::capnp::rpc::Resolve>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Resolve> disownResolve(); - - inline bool isRelease(); - inline bool hasRelease(); - inline ::capnp::rpc::Release::Builder getRelease(); - inline void setRelease( ::capnp::rpc::Release::Reader value); - inline ::capnp::rpc::Release::Builder initRelease(); - inline void adoptRelease(::capnp::Orphan< ::capnp::rpc::Release>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Release> disownRelease(); - - inline bool isObsoleteSave(); - inline bool hasObsoleteSave(); - inline ::capnp::AnyPointer::Builder getObsoleteSave(); - inline ::capnp::AnyPointer::Builder initObsoleteSave(); - - inline bool isBootstrap(); - inline bool hasBootstrap(); - inline ::capnp::rpc::Bootstrap::Builder getBootstrap(); - inline void setBootstrap( ::capnp::rpc::Bootstrap::Reader value); - inline ::capnp::rpc::Bootstrap::Builder initBootstrap(); - inline void adoptBootstrap(::capnp::Orphan< ::capnp::rpc::Bootstrap>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Bootstrap> disownBootstrap(); - - inline bool isObsoleteDelete(); - inline bool hasObsoleteDelete(); - inline ::capnp::AnyPointer::Builder getObsoleteDelete(); - inline ::capnp::AnyPointer::Builder initObsoleteDelete(); - - inline bool isProvide(); - inline bool hasProvide(); - inline ::capnp::rpc::Provide::Builder getProvide(); - inline void setProvide( ::capnp::rpc::Provide::Reader value); - inline ::capnp::rpc::Provide::Builder initProvide(); - inline void adoptProvide(::capnp::Orphan< ::capnp::rpc::Provide>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Provide> disownProvide(); - - inline bool isAccept(); - inline bool hasAccept(); - inline ::capnp::rpc::Accept::Builder getAccept(); - inline void setAccept( ::capnp::rpc::Accept::Reader value); - inline ::capnp::rpc::Accept::Builder initAccept(); - inline void adoptAccept(::capnp::Orphan< ::capnp::rpc::Accept>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Accept> disownAccept(); - - inline bool isJoin(); - inline bool hasJoin(); - inline ::capnp::rpc::Join::Builder getJoin(); - inline void setJoin( ::capnp::rpc::Join::Reader value); - inline ::capnp::rpc::Join::Builder initJoin(); - inline void adoptJoin(::capnp::Orphan< ::capnp::rpc::Join>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Join> disownJoin(); - - inline bool isDisembargo(); - inline bool hasDisembargo(); - inline ::capnp::rpc::Disembargo::Builder getDisembargo(); - inline void setDisembargo( ::capnp::rpc::Disembargo::Reader value); - inline ::capnp::rpc::Disembargo::Builder initDisembargo(); - inline void adoptDisembargo(::capnp::Orphan< ::capnp::rpc::Disembargo>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Disembargo> disownDisembargo(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Message::Pipeline { -public: - typedef Message Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Bootstrap::Reader { -public: - typedef Bootstrap Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId() const; - - inline bool hasDeprecatedObjectId() const; - inline ::capnp::AnyPointer::Reader getDeprecatedObjectId() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Bootstrap::Builder { -public: - typedef Bootstrap Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId(); - inline void setQuestionId( ::uint32_t value); - - inline bool hasDeprecatedObjectId(); - inline ::capnp::AnyPointer::Builder getDeprecatedObjectId(); - inline ::capnp::AnyPointer::Builder initDeprecatedObjectId(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Bootstrap::Pipeline { -public: - typedef Bootstrap Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Call::Reader { -public: - typedef Call Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId() const; - - inline bool hasTarget() const; - inline ::capnp::rpc::MessageTarget::Reader getTarget() const; - - inline ::uint64_t getInterfaceId() const; - - inline ::uint16_t getMethodId() const; - - inline bool hasParams() const; - inline ::capnp::rpc::Payload::Reader getParams() const; - - inline typename SendResultsTo::Reader getSendResultsTo() const; - - inline bool getAllowThirdPartyTailCall() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Call::Builder { -public: - typedef Call Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId(); - inline void setQuestionId( ::uint32_t value); - - inline bool hasTarget(); - inline ::capnp::rpc::MessageTarget::Builder getTarget(); - inline void setTarget( ::capnp::rpc::MessageTarget::Reader value); - inline ::capnp::rpc::MessageTarget::Builder initTarget(); - inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value); - inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget(); - - inline ::uint64_t getInterfaceId(); - inline void setInterfaceId( ::uint64_t value); - - inline ::uint16_t getMethodId(); - inline void setMethodId( ::uint16_t value); - - inline bool hasParams(); - inline ::capnp::rpc::Payload::Builder getParams(); - inline void setParams( ::capnp::rpc::Payload::Reader value); - inline ::capnp::rpc::Payload::Builder initParams(); - inline void adoptParams(::capnp::Orphan< ::capnp::rpc::Payload>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Payload> disownParams(); - - inline typename SendResultsTo::Builder getSendResultsTo(); - inline typename SendResultsTo::Builder initSendResultsTo(); - - inline bool getAllowThirdPartyTailCall(); - inline void setAllowThirdPartyTailCall(bool value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Call::Pipeline { -public: - typedef Call Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::rpc::MessageTarget::Pipeline getTarget(); - inline ::capnp::rpc::Payload::Pipeline getParams(); - inline typename SendResultsTo::Pipeline getSendResultsTo(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Call::SendResultsTo::Reader { -public: - typedef SendResultsTo Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isCaller() const; - inline ::capnp::Void getCaller() const; - - inline bool isYourself() const; - inline ::capnp::Void getYourself() const; - - inline bool isThirdParty() const; - inline bool hasThirdParty() const; - inline ::capnp::AnyPointer::Reader getThirdParty() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Call::SendResultsTo::Builder { -public: - typedef SendResultsTo Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isCaller(); - inline ::capnp::Void getCaller(); - inline void setCaller( ::capnp::Void value = ::capnp::VOID); - - inline bool isYourself(); - inline ::capnp::Void getYourself(); - inline void setYourself( ::capnp::Void value = ::capnp::VOID); - - inline bool isThirdParty(); - inline bool hasThirdParty(); - inline ::capnp::AnyPointer::Builder getThirdParty(); - inline ::capnp::AnyPointer::Builder initThirdParty(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Call::SendResultsTo::Pipeline { -public: - typedef SendResultsTo Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Return::Reader { -public: - typedef Return Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline ::uint32_t getAnswerId() const; - - inline bool getReleaseParamCaps() const; - - inline bool isResults() const; - inline bool hasResults() const; - inline ::capnp::rpc::Payload::Reader getResults() const; - - inline bool isException() const; - inline bool hasException() const; - inline ::capnp::rpc::Exception::Reader getException() const; - - inline bool isCanceled() const; - inline ::capnp::Void getCanceled() const; - - inline bool isResultsSentElsewhere() const; - inline ::capnp::Void getResultsSentElsewhere() const; - - inline bool isTakeFromOtherQuestion() const; - inline ::uint32_t getTakeFromOtherQuestion() const; - - inline bool isAcceptFromThirdParty() const; - inline bool hasAcceptFromThirdParty() const; - inline ::capnp::AnyPointer::Reader getAcceptFromThirdParty() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Return::Builder { -public: - typedef Return Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline ::uint32_t getAnswerId(); - inline void setAnswerId( ::uint32_t value); - - inline bool getReleaseParamCaps(); - inline void setReleaseParamCaps(bool value); - - inline bool isResults(); - inline bool hasResults(); - inline ::capnp::rpc::Payload::Builder getResults(); - inline void setResults( ::capnp::rpc::Payload::Reader value); - inline ::capnp::rpc::Payload::Builder initResults(); - inline void adoptResults(::capnp::Orphan< ::capnp::rpc::Payload>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Payload> disownResults(); - - inline bool isException(); - inline bool hasException(); - inline ::capnp::rpc::Exception::Builder getException(); - inline void setException( ::capnp::rpc::Exception::Reader value); - inline ::capnp::rpc::Exception::Builder initException(); - inline void adoptException(::capnp::Orphan< ::capnp::rpc::Exception>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Exception> disownException(); - - inline bool isCanceled(); - inline ::capnp::Void getCanceled(); - inline void setCanceled( ::capnp::Void value = ::capnp::VOID); - - inline bool isResultsSentElsewhere(); - inline ::capnp::Void getResultsSentElsewhere(); - inline void setResultsSentElsewhere( ::capnp::Void value = ::capnp::VOID); - - inline bool isTakeFromOtherQuestion(); - inline ::uint32_t getTakeFromOtherQuestion(); - inline void setTakeFromOtherQuestion( ::uint32_t value); - - inline bool isAcceptFromThirdParty(); - inline bool hasAcceptFromThirdParty(); - inline ::capnp::AnyPointer::Builder getAcceptFromThirdParty(); - inline ::capnp::AnyPointer::Builder initAcceptFromThirdParty(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Return::Pipeline { -public: - typedef Return Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Finish::Reader { -public: - typedef Finish Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId() const; - - inline bool getReleaseResultCaps() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Finish::Builder { -public: - typedef Finish Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId(); - inline void setQuestionId( ::uint32_t value); - - inline bool getReleaseResultCaps(); - inline void setReleaseResultCaps(bool value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Finish::Pipeline { -public: - typedef Finish Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Resolve::Reader { -public: - typedef Resolve Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline ::uint32_t getPromiseId() const; - - inline bool isCap() const; - inline bool hasCap() const; - inline ::capnp::rpc::CapDescriptor::Reader getCap() const; - - inline bool isException() const; - inline bool hasException() const; - inline ::capnp::rpc::Exception::Reader getException() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Resolve::Builder { -public: - typedef Resolve Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline ::uint32_t getPromiseId(); - inline void setPromiseId( ::uint32_t value); - - inline bool isCap(); - inline bool hasCap(); - inline ::capnp::rpc::CapDescriptor::Builder getCap(); - inline void setCap( ::capnp::rpc::CapDescriptor::Reader value); - inline ::capnp::rpc::CapDescriptor::Builder initCap(); - inline void adoptCap(::capnp::Orphan< ::capnp::rpc::CapDescriptor>&& value); - inline ::capnp::Orphan< ::capnp::rpc::CapDescriptor> disownCap(); - - inline bool isException(); - inline bool hasException(); - inline ::capnp::rpc::Exception::Builder getException(); - inline void setException( ::capnp::rpc::Exception::Reader value); - inline ::capnp::rpc::Exception::Builder initException(); - inline void adoptException(::capnp::Orphan< ::capnp::rpc::Exception>&& value); - inline ::capnp::Orphan< ::capnp::rpc::Exception> disownException(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Resolve::Pipeline { -public: - typedef Resolve Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Release::Reader { -public: - typedef Release Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getId() const; - - inline ::uint32_t getReferenceCount() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Release::Builder { -public: - typedef Release Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getId(); - inline void setId( ::uint32_t value); - - inline ::uint32_t getReferenceCount(); - inline void setReferenceCount( ::uint32_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Release::Pipeline { -public: - typedef Release Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Disembargo::Reader { -public: - typedef Disembargo Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasTarget() const; - inline ::capnp::rpc::MessageTarget::Reader getTarget() const; - - inline typename Context::Reader getContext() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Disembargo::Builder { -public: - typedef Disembargo Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasTarget(); - inline ::capnp::rpc::MessageTarget::Builder getTarget(); - inline void setTarget( ::capnp::rpc::MessageTarget::Reader value); - inline ::capnp::rpc::MessageTarget::Builder initTarget(); - inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value); - inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget(); - - inline typename Context::Builder getContext(); - inline typename Context::Builder initContext(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Disembargo::Pipeline { -public: - typedef Disembargo Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::rpc::MessageTarget::Pipeline getTarget(); - inline typename Context::Pipeline getContext(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Disembargo::Context::Reader { -public: - typedef Context Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isSenderLoopback() const; - inline ::uint32_t getSenderLoopback() const; - - inline bool isReceiverLoopback() const; - inline ::uint32_t getReceiverLoopback() const; - - inline bool isAccept() const; - inline ::capnp::Void getAccept() const; - - inline bool isProvide() const; - inline ::uint32_t getProvide() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Disembargo::Context::Builder { -public: - typedef Context Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isSenderLoopback(); - inline ::uint32_t getSenderLoopback(); - inline void setSenderLoopback( ::uint32_t value); - - inline bool isReceiverLoopback(); - inline ::uint32_t getReceiverLoopback(); - inline void setReceiverLoopback( ::uint32_t value); - - inline bool isAccept(); - inline ::capnp::Void getAccept(); - inline void setAccept( ::capnp::Void value = ::capnp::VOID); - - inline bool isProvide(); - inline ::uint32_t getProvide(); - inline void setProvide( ::uint32_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Disembargo::Context::Pipeline { -public: - typedef Context Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Provide::Reader { -public: - typedef Provide Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId() const; - - inline bool hasTarget() const; - inline ::capnp::rpc::MessageTarget::Reader getTarget() const; - - inline bool hasRecipient() const; - inline ::capnp::AnyPointer::Reader getRecipient() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Provide::Builder { -public: - typedef Provide Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId(); - inline void setQuestionId( ::uint32_t value); - - inline bool hasTarget(); - inline ::capnp::rpc::MessageTarget::Builder getTarget(); - inline void setTarget( ::capnp::rpc::MessageTarget::Reader value); - inline ::capnp::rpc::MessageTarget::Builder initTarget(); - inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value); - inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget(); - - inline bool hasRecipient(); - inline ::capnp::AnyPointer::Builder getRecipient(); - inline ::capnp::AnyPointer::Builder initRecipient(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Provide::Pipeline { -public: - typedef Provide Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::rpc::MessageTarget::Pipeline getTarget(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Accept::Reader { -public: - typedef Accept Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId() const; - - inline bool hasProvision() const; - inline ::capnp::AnyPointer::Reader getProvision() const; - - inline bool getEmbargo() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Accept::Builder { -public: - typedef Accept Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId(); - inline void setQuestionId( ::uint32_t value); - - inline bool hasProvision(); - inline ::capnp::AnyPointer::Builder getProvision(); - inline ::capnp::AnyPointer::Builder initProvision(); - - inline bool getEmbargo(); - inline void setEmbargo(bool value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Accept::Pipeline { -public: - typedef Accept Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Join::Reader { -public: - typedef Join Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId() const; - - inline bool hasTarget() const; - inline ::capnp::rpc::MessageTarget::Reader getTarget() const; - - inline bool hasKeyPart() const; - inline ::capnp::AnyPointer::Reader getKeyPart() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Join::Builder { -public: - typedef Join Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId(); - inline void setQuestionId( ::uint32_t value); - - inline bool hasTarget(); - inline ::capnp::rpc::MessageTarget::Builder getTarget(); - inline void setTarget( ::capnp::rpc::MessageTarget::Reader value); - inline ::capnp::rpc::MessageTarget::Builder initTarget(); - inline void adoptTarget(::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value); - inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> disownTarget(); - - inline bool hasKeyPart(); - inline ::capnp::AnyPointer::Builder getKeyPart(); - inline ::capnp::AnyPointer::Builder initKeyPart(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Join::Pipeline { -public: - typedef Join Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::rpc::MessageTarget::Pipeline getTarget(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class MessageTarget::Reader { -public: - typedef MessageTarget Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isImportedCap() const; - inline ::uint32_t getImportedCap() const; - - inline bool isPromisedAnswer() const; - inline bool hasPromisedAnswer() const; - inline ::capnp::rpc::PromisedAnswer::Reader getPromisedAnswer() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class MessageTarget::Builder { -public: - typedef MessageTarget Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isImportedCap(); - inline ::uint32_t getImportedCap(); - inline void setImportedCap( ::uint32_t value); - - inline bool isPromisedAnswer(); - inline bool hasPromisedAnswer(); - inline ::capnp::rpc::PromisedAnswer::Builder getPromisedAnswer(); - inline void setPromisedAnswer( ::capnp::rpc::PromisedAnswer::Reader value); - inline ::capnp::rpc::PromisedAnswer::Builder initPromisedAnswer(); - inline void adoptPromisedAnswer(::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value); - inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> disownPromisedAnswer(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class MessageTarget::Pipeline { -public: - typedef MessageTarget Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Payload::Reader { -public: - typedef Payload Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasContent() const; - inline ::capnp::AnyPointer::Reader getContent() const; - - inline bool hasCapTable() const; - inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Reader getCapTable() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Payload::Builder { -public: - typedef Payload Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasContent(); - inline ::capnp::AnyPointer::Builder getContent(); - inline ::capnp::AnyPointer::Builder initContent(); - - inline bool hasCapTable(); - inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Builder getCapTable(); - inline void setCapTable( ::capnp::List< ::capnp::rpc::CapDescriptor>::Reader value); - inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Builder initCapTable(unsigned int size); - inline void adoptCapTable(::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>> disownCapTable(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Payload::Pipeline { -public: - typedef Payload Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class CapDescriptor::Reader { -public: - typedef CapDescriptor Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isNone() const; - inline ::capnp::Void getNone() const; - - inline bool isSenderHosted() const; - inline ::uint32_t getSenderHosted() const; - - inline bool isSenderPromise() const; - inline ::uint32_t getSenderPromise() const; - - inline bool isReceiverHosted() const; - inline ::uint32_t getReceiverHosted() const; - - inline bool isReceiverAnswer() const; - inline bool hasReceiverAnswer() const; - inline ::capnp::rpc::PromisedAnswer::Reader getReceiverAnswer() const; - - inline bool isThirdPartyHosted() const; - inline bool hasThirdPartyHosted() const; - inline ::capnp::rpc::ThirdPartyCapDescriptor::Reader getThirdPartyHosted() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class CapDescriptor::Builder { -public: - typedef CapDescriptor Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isNone(); - inline ::capnp::Void getNone(); - inline void setNone( ::capnp::Void value = ::capnp::VOID); - - inline bool isSenderHosted(); - inline ::uint32_t getSenderHosted(); - inline void setSenderHosted( ::uint32_t value); - - inline bool isSenderPromise(); - inline ::uint32_t getSenderPromise(); - inline void setSenderPromise( ::uint32_t value); - - inline bool isReceiverHosted(); - inline ::uint32_t getReceiverHosted(); - inline void setReceiverHosted( ::uint32_t value); - - inline bool isReceiverAnswer(); - inline bool hasReceiverAnswer(); - inline ::capnp::rpc::PromisedAnswer::Builder getReceiverAnswer(); - inline void setReceiverAnswer( ::capnp::rpc::PromisedAnswer::Reader value); - inline ::capnp::rpc::PromisedAnswer::Builder initReceiverAnswer(); - inline void adoptReceiverAnswer(::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value); - inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> disownReceiverAnswer(); - - inline bool isThirdPartyHosted(); - inline bool hasThirdPartyHosted(); - inline ::capnp::rpc::ThirdPartyCapDescriptor::Builder getThirdPartyHosted(); - inline void setThirdPartyHosted( ::capnp::rpc::ThirdPartyCapDescriptor::Reader value); - inline ::capnp::rpc::ThirdPartyCapDescriptor::Builder initThirdPartyHosted(); - inline void adoptThirdPartyHosted(::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor>&& value); - inline ::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor> disownThirdPartyHosted(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class CapDescriptor::Pipeline { -public: - typedef CapDescriptor Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class PromisedAnswer::Reader { -public: - typedef PromisedAnswer Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId() const; - - inline bool hasTransform() const; - inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Reader getTransform() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class PromisedAnswer::Builder { -public: - typedef PromisedAnswer Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getQuestionId(); - inline void setQuestionId( ::uint32_t value); - - inline bool hasTransform(); - inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Builder getTransform(); - inline void setTransform( ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Reader value); - inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Builder initTransform(unsigned int size); - inline void adoptTransform(::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>> disownTransform(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class PromisedAnswer::Pipeline { -public: - typedef PromisedAnswer Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class PromisedAnswer::Op::Reader { -public: - typedef Op Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isNoop() const; - inline ::capnp::Void getNoop() const; - - inline bool isGetPointerField() const; - inline ::uint16_t getGetPointerField() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class PromisedAnswer::Op::Builder { -public: - typedef Op Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isNoop(); - inline ::capnp::Void getNoop(); - inline void setNoop( ::capnp::Void value = ::capnp::VOID); - - inline bool isGetPointerField(); - inline ::uint16_t getGetPointerField(); - inline void setGetPointerField( ::uint16_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class PromisedAnswer::Op::Pipeline { -public: - typedef Op Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class ThirdPartyCapDescriptor::Reader { -public: - typedef ThirdPartyCapDescriptor Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasId() const; - inline ::capnp::AnyPointer::Reader getId() const; - - inline ::uint32_t getVineId() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class ThirdPartyCapDescriptor::Builder { -public: - typedef ThirdPartyCapDescriptor Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasId(); - inline ::capnp::AnyPointer::Builder getId(); - inline ::capnp::AnyPointer::Builder initId(); - - inline ::uint32_t getVineId(); - inline void setVineId( ::uint32_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class ThirdPartyCapDescriptor::Pipeline { -public: - typedef ThirdPartyCapDescriptor Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Exception::Reader { -public: - typedef Exception Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasReason() const; - inline ::capnp::Text::Reader getReason() const; - - inline bool getObsoleteIsCallersFault() const; - - inline ::uint16_t getObsoleteDurability() const; - - inline ::capnp::rpc::Exception::Type getType() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Exception::Builder { -public: - typedef Exception Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasReason(); - inline ::capnp::Text::Builder getReason(); - inline void setReason( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initReason(unsigned int size); - inline void adoptReason(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownReason(); - - inline bool getObsoleteIsCallersFault(); - inline void setObsoleteIsCallersFault(bool value); - - inline ::uint16_t getObsoleteDurability(); - inline void setObsoleteDurability( ::uint16_t value); - - inline ::capnp::rpc::Exception::Type getType(); - inline void setType( ::capnp::rpc::Exception::Type value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Exception::Pipeline { -public: - typedef Exception Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -// ======================================================================================= - -inline ::capnp::rpc::Message::Which Message::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::Message::Which Message::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline bool Message::Reader::isUnimplemented() const { - return which() == Message::UNIMPLEMENTED; -} -inline bool Message::Builder::isUnimplemented() { - return which() == Message::UNIMPLEMENTED; -} -inline bool Message::Reader::hasUnimplemented() const { - if (which() != Message::UNIMPLEMENTED) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasUnimplemented() { - if (which() != Message::UNIMPLEMENTED) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Message::Reader Message::Reader::getUnimplemented() const { - KJ_IREQUIRE((which() == Message::UNIMPLEMENTED), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Message::Builder Message::Builder::getUnimplemented() { - KJ_IREQUIRE((which() == Message::UNIMPLEMENTED), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::setUnimplemented( ::capnp::rpc::Message::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::UNIMPLEMENTED); - ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Message::Builder Message::Builder::initUnimplemented() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::UNIMPLEMENTED); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptUnimplemented( - ::capnp::Orphan< ::capnp::rpc::Message>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::UNIMPLEMENTED); - ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Message> Message::Builder::disownUnimplemented() { - KJ_IREQUIRE((which() == Message::UNIMPLEMENTED), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Message>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isAbort() const { - return which() == Message::ABORT; -} -inline bool Message::Builder::isAbort() { - return which() == Message::ABORT; -} -inline bool Message::Reader::hasAbort() const { - if (which() != Message::ABORT) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasAbort() { - if (which() != Message::ABORT) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Exception::Reader Message::Reader::getAbort() const { - KJ_IREQUIRE((which() == Message::ABORT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Exception::Builder Message::Builder::getAbort() { - KJ_IREQUIRE((which() == Message::ABORT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::setAbort( ::capnp::rpc::Exception::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ABORT); - ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Exception::Builder Message::Builder::initAbort() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ABORT); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptAbort( - ::capnp::Orphan< ::capnp::rpc::Exception>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ABORT); - ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Exception> Message::Builder::disownAbort() { - KJ_IREQUIRE((which() == Message::ABORT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isCall() const { - return which() == Message::CALL; -} -inline bool Message::Builder::isCall() { - return which() == Message::CALL; -} -inline bool Message::Reader::hasCall() const { - if (which() != Message::CALL) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasCall() { - if (which() != Message::CALL) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Call::Reader Message::Reader::getCall() const { - KJ_IREQUIRE((which() == Message::CALL), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Call::Builder Message::Builder::getCall() { - KJ_IREQUIRE((which() == Message::CALL), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::setCall( ::capnp::rpc::Call::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::CALL); - ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Call::Builder Message::Builder::initCall() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::CALL); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptCall( - ::capnp::Orphan< ::capnp::rpc::Call>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::CALL); - ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Call> Message::Builder::disownCall() { - KJ_IREQUIRE((which() == Message::CALL), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Call>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isReturn() const { - return which() == Message::RETURN; -} -inline bool Message::Builder::isReturn() { - return which() == Message::RETURN; -} -inline bool Message::Reader::hasReturn() const { - if (which() != Message::RETURN) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasReturn() { - if (which() != Message::RETURN) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Return::Reader Message::Reader::getReturn() const { - KJ_IREQUIRE((which() == Message::RETURN), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Return::Builder Message::Builder::getReturn() { - KJ_IREQUIRE((which() == Message::RETURN), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::setReturn( ::capnp::rpc::Return::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RETURN); - ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Return::Builder Message::Builder::initReturn() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RETURN); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptReturn( - ::capnp::Orphan< ::capnp::rpc::Return>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RETURN); - ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Return> Message::Builder::disownReturn() { - KJ_IREQUIRE((which() == Message::RETURN), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Return>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isFinish() const { - return which() == Message::FINISH; -} -inline bool Message::Builder::isFinish() { - return which() == Message::FINISH; -} -inline bool Message::Reader::hasFinish() const { - if (which() != Message::FINISH) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasFinish() { - if (which() != Message::FINISH) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Finish::Reader Message::Reader::getFinish() const { - KJ_IREQUIRE((which() == Message::FINISH), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Finish::Builder Message::Builder::getFinish() { - KJ_IREQUIRE((which() == Message::FINISH), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::setFinish( ::capnp::rpc::Finish::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::FINISH); - ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Finish::Builder Message::Builder::initFinish() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::FINISH); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptFinish( - ::capnp::Orphan< ::capnp::rpc::Finish>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::FINISH); - ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Finish> Message::Builder::disownFinish() { - KJ_IREQUIRE((which() == Message::FINISH), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Finish>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isResolve() const { - return which() == Message::RESOLVE; -} -inline bool Message::Builder::isResolve() { - return which() == Message::RESOLVE; -} -inline bool Message::Reader::hasResolve() const { - if (which() != Message::RESOLVE) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasResolve() { - if (which() != Message::RESOLVE) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Resolve::Reader Message::Reader::getResolve() const { - KJ_IREQUIRE((which() == Message::RESOLVE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Resolve::Builder Message::Builder::getResolve() { - KJ_IREQUIRE((which() == Message::RESOLVE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::setResolve( ::capnp::rpc::Resolve::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RESOLVE); - ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Resolve::Builder Message::Builder::initResolve() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RESOLVE); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptResolve( - ::capnp::Orphan< ::capnp::rpc::Resolve>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RESOLVE); - ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Resolve> Message::Builder::disownResolve() { - KJ_IREQUIRE((which() == Message::RESOLVE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Resolve>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isRelease() const { - return which() == Message::RELEASE; -} -inline bool Message::Builder::isRelease() { - return which() == Message::RELEASE; -} -inline bool Message::Reader::hasRelease() const { - if (which() != Message::RELEASE) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasRelease() { - if (which() != Message::RELEASE) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Release::Reader Message::Reader::getRelease() const { - KJ_IREQUIRE((which() == Message::RELEASE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Release::Builder Message::Builder::getRelease() { - KJ_IREQUIRE((which() == Message::RELEASE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::setRelease( ::capnp::rpc::Release::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RELEASE); - ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Release::Builder Message::Builder::initRelease() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RELEASE); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptRelease( - ::capnp::Orphan< ::capnp::rpc::Release>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::RELEASE); - ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Release> Message::Builder::disownRelease() { - KJ_IREQUIRE((which() == Message::RELEASE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Release>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isObsoleteSave() const { - return which() == Message::OBSOLETE_SAVE; -} -inline bool Message::Builder::isObsoleteSave() { - return which() == Message::OBSOLETE_SAVE; -} -inline bool Message::Reader::hasObsoleteSave() const { - if (which() != Message::OBSOLETE_SAVE) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasObsoleteSave() { - if (which() != Message::OBSOLETE_SAVE) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Message::Reader::getObsoleteSave() const { - KJ_IREQUIRE((which() == Message::OBSOLETE_SAVE), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Reader(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Message::Builder::getObsoleteSave() { - KJ_IREQUIRE((which() == Message::OBSOLETE_SAVE), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Message::Builder::initObsoleteSave() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::OBSOLETE_SAVE); - auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline bool Message::Reader::isBootstrap() const { - return which() == Message::BOOTSTRAP; -} -inline bool Message::Builder::isBootstrap() { - return which() == Message::BOOTSTRAP; -} -inline bool Message::Reader::hasBootstrap() const { - if (which() != Message::BOOTSTRAP) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasBootstrap() { - if (which() != Message::BOOTSTRAP) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Bootstrap::Reader Message::Reader::getBootstrap() const { - KJ_IREQUIRE((which() == Message::BOOTSTRAP), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Bootstrap::Builder Message::Builder::getBootstrap() { - KJ_IREQUIRE((which() == Message::BOOTSTRAP), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::setBootstrap( ::capnp::rpc::Bootstrap::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::BOOTSTRAP); - ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Bootstrap::Builder Message::Builder::initBootstrap() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::BOOTSTRAP); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptBootstrap( - ::capnp::Orphan< ::capnp::rpc::Bootstrap>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::BOOTSTRAP); - ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Bootstrap> Message::Builder::disownBootstrap() { - KJ_IREQUIRE((which() == Message::BOOTSTRAP), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Bootstrap>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isObsoleteDelete() const { - return which() == Message::OBSOLETE_DELETE; -} -inline bool Message::Builder::isObsoleteDelete() { - return which() == Message::OBSOLETE_DELETE; -} -inline bool Message::Reader::hasObsoleteDelete() const { - if (which() != Message::OBSOLETE_DELETE) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasObsoleteDelete() { - if (which() != Message::OBSOLETE_DELETE) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Message::Reader::getObsoleteDelete() const { - KJ_IREQUIRE((which() == Message::OBSOLETE_DELETE), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Reader(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Message::Builder::getObsoleteDelete() { - KJ_IREQUIRE((which() == Message::OBSOLETE_DELETE), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Message::Builder::initObsoleteDelete() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::OBSOLETE_DELETE); - auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline bool Message::Reader::isProvide() const { - return which() == Message::PROVIDE; -} -inline bool Message::Builder::isProvide() { - return which() == Message::PROVIDE; -} -inline bool Message::Reader::hasProvide() const { - if (which() != Message::PROVIDE) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasProvide() { - if (which() != Message::PROVIDE) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Provide::Reader Message::Reader::getProvide() const { - KJ_IREQUIRE((which() == Message::PROVIDE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Provide::Builder Message::Builder::getProvide() { - KJ_IREQUIRE((which() == Message::PROVIDE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::setProvide( ::capnp::rpc::Provide::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::PROVIDE); - ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Provide::Builder Message::Builder::initProvide() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::PROVIDE); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptProvide( - ::capnp::Orphan< ::capnp::rpc::Provide>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::PROVIDE); - ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Provide> Message::Builder::disownProvide() { - KJ_IREQUIRE((which() == Message::PROVIDE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Provide>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isAccept() const { - return which() == Message::ACCEPT; -} -inline bool Message::Builder::isAccept() { - return which() == Message::ACCEPT; -} -inline bool Message::Reader::hasAccept() const { - if (which() != Message::ACCEPT) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasAccept() { - if (which() != Message::ACCEPT) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Accept::Reader Message::Reader::getAccept() const { - KJ_IREQUIRE((which() == Message::ACCEPT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Accept::Builder Message::Builder::getAccept() { - KJ_IREQUIRE((which() == Message::ACCEPT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::setAccept( ::capnp::rpc::Accept::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ACCEPT); - ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Accept::Builder Message::Builder::initAccept() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ACCEPT); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptAccept( - ::capnp::Orphan< ::capnp::rpc::Accept>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::ACCEPT); - ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Accept> Message::Builder::disownAccept() { - KJ_IREQUIRE((which() == Message::ACCEPT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Accept>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isJoin() const { - return which() == Message::JOIN; -} -inline bool Message::Builder::isJoin() { - return which() == Message::JOIN; -} -inline bool Message::Reader::hasJoin() const { - if (which() != Message::JOIN) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasJoin() { - if (which() != Message::JOIN) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Join::Reader Message::Reader::getJoin() const { - KJ_IREQUIRE((which() == Message::JOIN), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Join::Builder Message::Builder::getJoin() { - KJ_IREQUIRE((which() == Message::JOIN), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::setJoin( ::capnp::rpc::Join::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::JOIN); - ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Join::Builder Message::Builder::initJoin() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::JOIN); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptJoin( - ::capnp::Orphan< ::capnp::rpc::Join>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::JOIN); - ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Join> Message::Builder::disownJoin() { - KJ_IREQUIRE((which() == Message::JOIN), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Join>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Message::Reader::isDisembargo() const { - return which() == Message::DISEMBARGO; -} -inline bool Message::Builder::isDisembargo() { - return which() == Message::DISEMBARGO; -} -inline bool Message::Reader::hasDisembargo() const { - if (which() != Message::DISEMBARGO) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Message::Builder::hasDisembargo() { - if (which() != Message::DISEMBARGO) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Disembargo::Reader Message::Reader::getDisembargo() const { - KJ_IREQUIRE((which() == Message::DISEMBARGO), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Disembargo::Builder Message::Builder::getDisembargo() { - KJ_IREQUIRE((which() == Message::DISEMBARGO), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::setDisembargo( ::capnp::rpc::Disembargo::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::DISEMBARGO); - ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Disembargo::Builder Message::Builder::initDisembargo() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::DISEMBARGO); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Message::Builder::adoptDisembargo( - ::capnp::Orphan< ::capnp::rpc::Disembargo>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Message::DISEMBARGO); - ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Disembargo> Message::Builder::disownDisembargo() { - KJ_IREQUIRE((which() == Message::DISEMBARGO), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Disembargo>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::uint32_t Bootstrap::Reader::getQuestionId() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Bootstrap::Builder::getQuestionId() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Bootstrap::Builder::setQuestionId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Bootstrap::Reader::hasDeprecatedObjectId() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Bootstrap::Builder::hasDeprecatedObjectId() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Bootstrap::Reader::getDeprecatedObjectId() const { - return ::capnp::AnyPointer::Reader(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Bootstrap::Builder::getDeprecatedObjectId() { - return ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Bootstrap::Builder::initDeprecatedObjectId() { - auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline ::uint32_t Call::Reader::getQuestionId() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Call::Builder::getQuestionId() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Call::Builder::setQuestionId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Call::Reader::hasTarget() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Call::Builder::hasTarget() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::MessageTarget::Reader Call::Reader::getTarget() const { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::MessageTarget::Builder Call::Builder::getTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::rpc::MessageTarget::Pipeline Call::Pipeline::getTarget() { - return ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Call::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::MessageTarget::Builder Call::Builder::initTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Call::Builder::adoptTarget( - ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Call::Builder::disownTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::uint64_t Call::Reader::getInterfaceId() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Call::Builder::getInterfaceId() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Call::Builder::setInterfaceId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t Call::Reader::getMethodId() const { - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t Call::Builder::getMethodId() { - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} -inline void Call::Builder::setMethodId( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); -} - -inline bool Call::Reader::hasParams() const { - return !_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline bool Call::Builder::hasParams() { - return !_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Payload::Reader Call::Reader::getParams() const { - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get(_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Payload::Builder Call::Builder::getParams() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::rpc::Payload::Pipeline Call::Pipeline::getParams() { - return ::capnp::rpc::Payload::Pipeline(_typeless.getPointerField(1)); -} -#endif // !CAPNP_LITE -inline void Call::Builder::setParams( ::capnp::rpc::Payload::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::set(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Payload::Builder Call::Builder::initParams() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::init(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline void Call::Builder::adoptParams( - ::capnp::Orphan< ::capnp::rpc::Payload>&& value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::adopt(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Payload> Call::Builder::disownParams() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::disown(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} - -inline typename Call::SendResultsTo::Reader Call::Reader::getSendResultsTo() const { - return typename Call::SendResultsTo::Reader(_reader); -} -inline typename Call::SendResultsTo::Builder Call::Builder::getSendResultsTo() { - return typename Call::SendResultsTo::Builder(_builder); -} -#if !CAPNP_LITE -inline typename Call::SendResultsTo::Pipeline Call::Pipeline::getSendResultsTo() { - return typename Call::SendResultsTo::Pipeline(_typeless.noop()); -} -#endif // !CAPNP_LITE -inline typename Call::SendResultsTo::Builder Call::Builder::initSendResultsTo() { - _builder.setDataField< ::uint16_t>(::capnp::bounded<3>() * ::capnp::ELEMENTS, 0); - _builder.getPointerField(::capnp::bounded<2>() * ::capnp::POINTERS).clear(); - return typename Call::SendResultsTo::Builder(_builder); -} -inline bool Call::Reader::getAllowThirdPartyTailCall() const { - return _reader.getDataField( - ::capnp::bounded<128>() * ::capnp::ELEMENTS); -} - -inline bool Call::Builder::getAllowThirdPartyTailCall() { - return _builder.getDataField( - ::capnp::bounded<128>() * ::capnp::ELEMENTS); -} -inline void Call::Builder::setAllowThirdPartyTailCall(bool value) { - _builder.setDataField( - ::capnp::bounded<128>() * ::capnp::ELEMENTS, value); -} - -inline ::capnp::rpc::Call::SendResultsTo::Which Call::SendResultsTo::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::Call::SendResultsTo::Which Call::SendResultsTo::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS); -} - -inline bool Call::SendResultsTo::Reader::isCaller() const { - return which() == Call::SendResultsTo::CALLER; -} -inline bool Call::SendResultsTo::Builder::isCaller() { - return which() == Call::SendResultsTo::CALLER; -} -inline ::capnp::Void Call::SendResultsTo::Reader::getCaller() const { - KJ_IREQUIRE((which() == Call::SendResultsTo::CALLER), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Call::SendResultsTo::Builder::getCaller() { - KJ_IREQUIRE((which() == Call::SendResultsTo::CALLER), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Call::SendResultsTo::Builder::setCaller( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS, Call::SendResultsTo::CALLER); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Call::SendResultsTo::Reader::isYourself() const { - return which() == Call::SendResultsTo::YOURSELF; -} -inline bool Call::SendResultsTo::Builder::isYourself() { - return which() == Call::SendResultsTo::YOURSELF; -} -inline ::capnp::Void Call::SendResultsTo::Reader::getYourself() const { - KJ_IREQUIRE((which() == Call::SendResultsTo::YOURSELF), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Call::SendResultsTo::Builder::getYourself() { - KJ_IREQUIRE((which() == Call::SendResultsTo::YOURSELF), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Call::SendResultsTo::Builder::setYourself( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS, Call::SendResultsTo::YOURSELF); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Call::SendResultsTo::Reader::isThirdParty() const { - return which() == Call::SendResultsTo::THIRD_PARTY; -} -inline bool Call::SendResultsTo::Builder::isThirdParty() { - return which() == Call::SendResultsTo::THIRD_PARTY; -} -inline bool Call::SendResultsTo::Reader::hasThirdParty() const { - if (which() != Call::SendResultsTo::THIRD_PARTY) return false; - return !_reader.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); -} -inline bool Call::SendResultsTo::Builder::hasThirdParty() { - if (which() != Call::SendResultsTo::THIRD_PARTY) return false; - return !_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Call::SendResultsTo::Reader::getThirdParty() const { - KJ_IREQUIRE((which() == Call::SendResultsTo::THIRD_PARTY), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Reader(_reader.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Call::SendResultsTo::Builder::getThirdParty() { - KJ_IREQUIRE((which() == Call::SendResultsTo::THIRD_PARTY), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Call::SendResultsTo::Builder::initThirdParty() { - _builder.setDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS, Call::SendResultsTo::THIRD_PARTY); - auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline ::capnp::rpc::Return::Which Return::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::Return::Which Return::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Return::Reader::getAnswerId() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Return::Builder::getAnswerId() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Return::Builder::setAnswerId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Return::Reader::getReleaseParamCaps() const { - return _reader.getDataField( - ::capnp::bounded<32>() * ::capnp::ELEMENTS, true); -} - -inline bool Return::Builder::getReleaseParamCaps() { - return _builder.getDataField( - ::capnp::bounded<32>() * ::capnp::ELEMENTS, true); -} -inline void Return::Builder::setReleaseParamCaps(bool value) { - _builder.setDataField( - ::capnp::bounded<32>() * ::capnp::ELEMENTS, value, true); -} - -inline bool Return::Reader::isResults() const { - return which() == Return::RESULTS; -} -inline bool Return::Builder::isResults() { - return which() == Return::RESULTS; -} -inline bool Return::Reader::hasResults() const { - if (which() != Return::RESULTS) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Return::Builder::hasResults() { - if (which() != Return::RESULTS) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Payload::Reader Return::Reader::getResults() const { - KJ_IREQUIRE((which() == Return::RESULTS), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Payload::Builder Return::Builder::getResults() { - KJ_IREQUIRE((which() == Return::RESULTS), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Return::Builder::setResults( ::capnp::rpc::Payload::Reader value) { - _builder.setDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::RESULTS); - ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Payload::Builder Return::Builder::initResults() { - _builder.setDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::RESULTS); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Return::Builder::adoptResults( - ::capnp::Orphan< ::capnp::rpc::Payload>&& value) { - _builder.setDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::RESULTS); - ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Payload> Return::Builder::disownResults() { - KJ_IREQUIRE((which() == Return::RESULTS), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Payload>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Return::Reader::isException() const { - return which() == Return::EXCEPTION; -} -inline bool Return::Builder::isException() { - return which() == Return::EXCEPTION; -} -inline bool Return::Reader::hasException() const { - if (which() != Return::EXCEPTION) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Return::Builder::hasException() { - if (which() != Return::EXCEPTION) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Exception::Reader Return::Reader::getException() const { - KJ_IREQUIRE((which() == Return::EXCEPTION), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Exception::Builder Return::Builder::getException() { - KJ_IREQUIRE((which() == Return::EXCEPTION), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Return::Builder::setException( ::capnp::rpc::Exception::Reader value) { - _builder.setDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::EXCEPTION); - ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Exception::Builder Return::Builder::initException() { - _builder.setDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::EXCEPTION); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Return::Builder::adoptException( - ::capnp::Orphan< ::capnp::rpc::Exception>&& value) { - _builder.setDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::EXCEPTION); - ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Exception> Return::Builder::disownException() { - KJ_IREQUIRE((which() == Return::EXCEPTION), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Return::Reader::isCanceled() const { - return which() == Return::CANCELED; -} -inline bool Return::Builder::isCanceled() { - return which() == Return::CANCELED; -} -inline ::capnp::Void Return::Reader::getCanceled() const { - KJ_IREQUIRE((which() == Return::CANCELED), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Return::Builder::getCanceled() { - KJ_IREQUIRE((which() == Return::CANCELED), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Return::Builder::setCanceled( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::CANCELED); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Return::Reader::isResultsSentElsewhere() const { - return which() == Return::RESULTS_SENT_ELSEWHERE; -} -inline bool Return::Builder::isResultsSentElsewhere() { - return which() == Return::RESULTS_SENT_ELSEWHERE; -} -inline ::capnp::Void Return::Reader::getResultsSentElsewhere() const { - KJ_IREQUIRE((which() == Return::RESULTS_SENT_ELSEWHERE), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Return::Builder::getResultsSentElsewhere() { - KJ_IREQUIRE((which() == Return::RESULTS_SENT_ELSEWHERE), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Return::Builder::setResultsSentElsewhere( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::RESULTS_SENT_ELSEWHERE); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Return::Reader::isTakeFromOtherQuestion() const { - return which() == Return::TAKE_FROM_OTHER_QUESTION; -} -inline bool Return::Builder::isTakeFromOtherQuestion() { - return which() == Return::TAKE_FROM_OTHER_QUESTION; -} -inline ::uint32_t Return::Reader::getTakeFromOtherQuestion() const { - KJ_IREQUIRE((which() == Return::TAKE_FROM_OTHER_QUESTION), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Return::Builder::getTakeFromOtherQuestion() { - KJ_IREQUIRE((which() == Return::TAKE_FROM_OTHER_QUESTION), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} -inline void Return::Builder::setTakeFromOtherQuestion( ::uint32_t value) { - _builder.setDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::TAKE_FROM_OTHER_QUESTION); - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); -} - -inline bool Return::Reader::isAcceptFromThirdParty() const { - return which() == Return::ACCEPT_FROM_THIRD_PARTY; -} -inline bool Return::Builder::isAcceptFromThirdParty() { - return which() == Return::ACCEPT_FROM_THIRD_PARTY; -} -inline bool Return::Reader::hasAcceptFromThirdParty() const { - if (which() != Return::ACCEPT_FROM_THIRD_PARTY) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Return::Builder::hasAcceptFromThirdParty() { - if (which() != Return::ACCEPT_FROM_THIRD_PARTY) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Return::Reader::getAcceptFromThirdParty() const { - KJ_IREQUIRE((which() == Return::ACCEPT_FROM_THIRD_PARTY), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Reader(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Return::Builder::getAcceptFromThirdParty() { - KJ_IREQUIRE((which() == Return::ACCEPT_FROM_THIRD_PARTY), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Return::Builder::initAcceptFromThirdParty() { - _builder.setDataField( - ::capnp::bounded<3>() * ::capnp::ELEMENTS, Return::ACCEPT_FROM_THIRD_PARTY); - auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline ::uint32_t Finish::Reader::getQuestionId() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Finish::Builder::getQuestionId() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Finish::Builder::setQuestionId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Finish::Reader::getReleaseResultCaps() const { - return _reader.getDataField( - ::capnp::bounded<32>() * ::capnp::ELEMENTS, true); -} - -inline bool Finish::Builder::getReleaseResultCaps() { - return _builder.getDataField( - ::capnp::bounded<32>() * ::capnp::ELEMENTS, true); -} -inline void Finish::Builder::setReleaseResultCaps(bool value) { - _builder.setDataField( - ::capnp::bounded<32>() * ::capnp::ELEMENTS, value, true); -} - -inline ::capnp::rpc::Resolve::Which Resolve::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::Resolve::Which Resolve::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Resolve::Reader::getPromiseId() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Resolve::Builder::getPromiseId() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Resolve::Builder::setPromiseId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Resolve::Reader::isCap() const { - return which() == Resolve::CAP; -} -inline bool Resolve::Builder::isCap() { - return which() == Resolve::CAP; -} -inline bool Resolve::Reader::hasCap() const { - if (which() != Resolve::CAP) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Resolve::Builder::hasCap() { - if (which() != Resolve::CAP) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::CapDescriptor::Reader Resolve::Reader::getCap() const { - KJ_IREQUIRE((which() == Resolve::CAP), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::CapDescriptor::Builder Resolve::Builder::getCap() { - KJ_IREQUIRE((which() == Resolve::CAP), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Resolve::Builder::setCap( ::capnp::rpc::CapDescriptor::Reader value) { - _builder.setDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::CAP); - ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::CapDescriptor::Builder Resolve::Builder::initCap() { - _builder.setDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::CAP); - return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Resolve::Builder::adoptCap( - ::capnp::Orphan< ::capnp::rpc::CapDescriptor>&& value) { - _builder.setDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::CAP); - ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::CapDescriptor> Resolve::Builder::disownCap() { - KJ_IREQUIRE((which() == Resolve::CAP), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::CapDescriptor>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Resolve::Reader::isException() const { - return which() == Resolve::EXCEPTION; -} -inline bool Resolve::Builder::isException() { - return which() == Resolve::EXCEPTION; -} -inline bool Resolve::Reader::hasException() const { - if (which() != Resolve::EXCEPTION) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Resolve::Builder::hasException() { - if (which() != Resolve::EXCEPTION) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::Exception::Reader Resolve::Reader::getException() const { - KJ_IREQUIRE((which() == Resolve::EXCEPTION), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::Exception::Builder Resolve::Builder::getException() { - KJ_IREQUIRE((which() == Resolve::EXCEPTION), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Resolve::Builder::setException( ::capnp::rpc::Exception::Reader value) { - _builder.setDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::EXCEPTION); - ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::Exception::Builder Resolve::Builder::initException() { - _builder.setDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::EXCEPTION); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Resolve::Builder::adoptException( - ::capnp::Orphan< ::capnp::rpc::Exception>&& value) { - _builder.setDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, Resolve::EXCEPTION); - ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::Exception> Resolve::Builder::disownException() { - KJ_IREQUIRE((which() == Resolve::EXCEPTION), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::Exception>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::uint32_t Release::Reader::getId() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Release::Builder::getId() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Release::Builder::setId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline ::uint32_t Release::Reader::getReferenceCount() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Release::Builder::getReferenceCount() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Release::Builder::setReferenceCount( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool Disembargo::Reader::hasTarget() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Disembargo::Builder::hasTarget() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::MessageTarget::Reader Disembargo::Reader::getTarget() const { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::MessageTarget::Builder Disembargo::Builder::getTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::rpc::MessageTarget::Pipeline Disembargo::Pipeline::getTarget() { - return ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Disembargo::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::MessageTarget::Builder Disembargo::Builder::initTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Disembargo::Builder::adoptTarget( - ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Disembargo::Builder::disownTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline typename Disembargo::Context::Reader Disembargo::Reader::getContext() const { - return typename Disembargo::Context::Reader(_reader); -} -inline typename Disembargo::Context::Builder Disembargo::Builder::getContext() { - return typename Disembargo::Context::Builder(_builder); -} -#if !CAPNP_LITE -inline typename Disembargo::Context::Pipeline Disembargo::Pipeline::getContext() { - return typename Disembargo::Context::Pipeline(_typeless.noop()); -} -#endif // !CAPNP_LITE -inline typename Disembargo::Context::Builder Disembargo::Builder::initContext() { - _builder.setDataField< ::uint32_t>(::capnp::bounded<0>() * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint16_t>(::capnp::bounded<2>() * ::capnp::ELEMENTS, 0); - return typename Disembargo::Context::Builder(_builder); -} -inline ::capnp::rpc::Disembargo::Context::Which Disembargo::Context::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::Disembargo::Context::Which Disembargo::Context::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} - -inline bool Disembargo::Context::Reader::isSenderLoopback() const { - return which() == Disembargo::Context::SENDER_LOOPBACK; -} -inline bool Disembargo::Context::Builder::isSenderLoopback() { - return which() == Disembargo::Context::SENDER_LOOPBACK; -} -inline ::uint32_t Disembargo::Context::Reader::getSenderLoopback() const { - KJ_IREQUIRE((which() == Disembargo::Context::SENDER_LOOPBACK), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Disembargo::Context::Builder::getSenderLoopback() { - KJ_IREQUIRE((which() == Disembargo::Context::SENDER_LOOPBACK), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Disembargo::Context::Builder::setSenderLoopback( ::uint32_t value) { - _builder.setDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, Disembargo::Context::SENDER_LOOPBACK); - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Disembargo::Context::Reader::isReceiverLoopback() const { - return which() == Disembargo::Context::RECEIVER_LOOPBACK; -} -inline bool Disembargo::Context::Builder::isReceiverLoopback() { - return which() == Disembargo::Context::RECEIVER_LOOPBACK; -} -inline ::uint32_t Disembargo::Context::Reader::getReceiverLoopback() const { - KJ_IREQUIRE((which() == Disembargo::Context::RECEIVER_LOOPBACK), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Disembargo::Context::Builder::getReceiverLoopback() { - KJ_IREQUIRE((which() == Disembargo::Context::RECEIVER_LOOPBACK), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Disembargo::Context::Builder::setReceiverLoopback( ::uint32_t value) { - _builder.setDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, Disembargo::Context::RECEIVER_LOOPBACK); - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Disembargo::Context::Reader::isAccept() const { - return which() == Disembargo::Context::ACCEPT; -} -inline bool Disembargo::Context::Builder::isAccept() { - return which() == Disembargo::Context::ACCEPT; -} -inline ::capnp::Void Disembargo::Context::Reader::getAccept() const { - KJ_IREQUIRE((which() == Disembargo::Context::ACCEPT), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Disembargo::Context::Builder::getAccept() { - KJ_IREQUIRE((which() == Disembargo::Context::ACCEPT), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Disembargo::Context::Builder::setAccept( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, Disembargo::Context::ACCEPT); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Disembargo::Context::Reader::isProvide() const { - return which() == Disembargo::Context::PROVIDE; -} -inline bool Disembargo::Context::Builder::isProvide() { - return which() == Disembargo::Context::PROVIDE; -} -inline ::uint32_t Disembargo::Context::Reader::getProvide() const { - KJ_IREQUIRE((which() == Disembargo::Context::PROVIDE), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Disembargo::Context::Builder::getProvide() { - KJ_IREQUIRE((which() == Disembargo::Context::PROVIDE), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Disembargo::Context::Builder::setProvide( ::uint32_t value) { - _builder.setDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, Disembargo::Context::PROVIDE); - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline ::uint32_t Provide::Reader::getQuestionId() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Provide::Builder::getQuestionId() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Provide::Builder::setQuestionId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Provide::Reader::hasTarget() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Provide::Builder::hasTarget() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::MessageTarget::Reader Provide::Reader::getTarget() const { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::MessageTarget::Builder Provide::Builder::getTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::rpc::MessageTarget::Pipeline Provide::Pipeline::getTarget() { - return ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Provide::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::MessageTarget::Builder Provide::Builder::initTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Provide::Builder::adoptTarget( - ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Provide::Builder::disownTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Provide::Reader::hasRecipient() const { - return !_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline bool Provide::Builder::hasRecipient() { - return !_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Provide::Reader::getRecipient() const { - return ::capnp::AnyPointer::Reader(_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Provide::Builder::getRecipient() { - return ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Provide::Builder::initRecipient() { - auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline ::uint32_t Accept::Reader::getQuestionId() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Accept::Builder::getQuestionId() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Accept::Builder::setQuestionId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Accept::Reader::hasProvision() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Accept::Builder::hasProvision() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Accept::Reader::getProvision() const { - return ::capnp::AnyPointer::Reader(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Accept::Builder::getProvision() { - return ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Accept::Builder::initProvision() { - auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline bool Accept::Reader::getEmbargo() const { - return _reader.getDataField( - ::capnp::bounded<32>() * ::capnp::ELEMENTS); -} - -inline bool Accept::Builder::getEmbargo() { - return _builder.getDataField( - ::capnp::bounded<32>() * ::capnp::ELEMENTS); -} -inline void Accept::Builder::setEmbargo(bool value) { - _builder.setDataField( - ::capnp::bounded<32>() * ::capnp::ELEMENTS, value); -} - -inline ::uint32_t Join::Reader::getQuestionId() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Join::Builder::getQuestionId() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Join::Builder::setQuestionId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Join::Reader::hasTarget() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Join::Builder::hasTarget() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::MessageTarget::Reader Join::Reader::getTarget() const { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::MessageTarget::Builder Join::Builder::getTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::rpc::MessageTarget::Pipeline Join::Pipeline::getTarget() { - return ::capnp::rpc::MessageTarget::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Join::Builder::setTarget( ::capnp::rpc::MessageTarget::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::MessageTarget::Builder Join::Builder::initTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Join::Builder::adoptTarget( - ::capnp::Orphan< ::capnp::rpc::MessageTarget>&& value) { - ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::MessageTarget> Join::Builder::disownTarget() { - return ::capnp::_::PointerHelpers< ::capnp::rpc::MessageTarget>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Join::Reader::hasKeyPart() const { - return !_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline bool Join::Builder::hasKeyPart() { - return !_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Join::Reader::getKeyPart() const { - return ::capnp::AnyPointer::Reader(_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Join::Builder::getKeyPart() { - return ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Join::Builder::initKeyPart() { - auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline ::capnp::rpc::MessageTarget::Which MessageTarget::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::MessageTarget::Which MessageTarget::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} - -inline bool MessageTarget::Reader::isImportedCap() const { - return which() == MessageTarget::IMPORTED_CAP; -} -inline bool MessageTarget::Builder::isImportedCap() { - return which() == MessageTarget::IMPORTED_CAP; -} -inline ::uint32_t MessageTarget::Reader::getImportedCap() const { - KJ_IREQUIRE((which() == MessageTarget::IMPORTED_CAP), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t MessageTarget::Builder::getImportedCap() { - KJ_IREQUIRE((which() == MessageTarget::IMPORTED_CAP), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void MessageTarget::Builder::setImportedCap( ::uint32_t value) { - _builder.setDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, MessageTarget::IMPORTED_CAP); - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool MessageTarget::Reader::isPromisedAnswer() const { - return which() == MessageTarget::PROMISED_ANSWER; -} -inline bool MessageTarget::Builder::isPromisedAnswer() { - return which() == MessageTarget::PROMISED_ANSWER; -} -inline bool MessageTarget::Reader::hasPromisedAnswer() const { - if (which() != MessageTarget::PROMISED_ANSWER) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool MessageTarget::Builder::hasPromisedAnswer() { - if (which() != MessageTarget::PROMISED_ANSWER) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::PromisedAnswer::Reader MessageTarget::Reader::getPromisedAnswer() const { - KJ_IREQUIRE((which() == MessageTarget::PROMISED_ANSWER), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::PromisedAnswer::Builder MessageTarget::Builder::getPromisedAnswer() { - KJ_IREQUIRE((which() == MessageTarget::PROMISED_ANSWER), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void MessageTarget::Builder::setPromisedAnswer( ::capnp::rpc::PromisedAnswer::Reader value) { - _builder.setDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, MessageTarget::PROMISED_ANSWER); - ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::PromisedAnswer::Builder MessageTarget::Builder::initPromisedAnswer() { - _builder.setDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, MessageTarget::PROMISED_ANSWER); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void MessageTarget::Builder::adoptPromisedAnswer( - ::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value) { - _builder.setDataField( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, MessageTarget::PROMISED_ANSWER); - ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> MessageTarget::Builder::disownPromisedAnswer() { - KJ_IREQUIRE((which() == MessageTarget::PROMISED_ANSWER), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Payload::Reader::hasContent() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Payload::Builder::hasContent() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Payload::Reader::getContent() const { - return ::capnp::AnyPointer::Reader(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Payload::Builder::getContent() { - return ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Payload::Builder::initContent() { - auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline bool Payload::Reader::hasCapTable() const { - return !_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline bool Payload::Builder::hasCapTable() { - return !_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Reader Payload::Reader::getCapTable() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::get(_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Builder Payload::Builder::getCapTable() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::get(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline void Payload::Builder::setCapTable( ::capnp::List< ::capnp::rpc::CapDescriptor>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::set(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::rpc::CapDescriptor>::Builder Payload::Builder::initCapTable(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::init(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), size); -} -inline void Payload::Builder::adoptCapTable( - ::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::adopt(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::CapDescriptor>> Payload::Builder::disownCapTable() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::CapDescriptor>>::disown(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} - -inline ::capnp::rpc::CapDescriptor::Which CapDescriptor::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::CapDescriptor::Which CapDescriptor::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline bool CapDescriptor::Reader::isNone() const { - return which() == CapDescriptor::NONE; -} -inline bool CapDescriptor::Builder::isNone() { - return which() == CapDescriptor::NONE; -} -inline ::capnp::Void CapDescriptor::Reader::getNone() const { - KJ_IREQUIRE((which() == CapDescriptor::NONE), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void CapDescriptor::Builder::getNone() { - KJ_IREQUIRE((which() == CapDescriptor::NONE), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void CapDescriptor::Builder::setNone( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::NONE); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool CapDescriptor::Reader::isSenderHosted() const { - return which() == CapDescriptor::SENDER_HOSTED; -} -inline bool CapDescriptor::Builder::isSenderHosted() { - return which() == CapDescriptor::SENDER_HOSTED; -} -inline ::uint32_t CapDescriptor::Reader::getSenderHosted() const { - KJ_IREQUIRE((which() == CapDescriptor::SENDER_HOSTED), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t CapDescriptor::Builder::getSenderHosted() { - KJ_IREQUIRE((which() == CapDescriptor::SENDER_HOSTED), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void CapDescriptor::Builder::setSenderHosted( ::uint32_t value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::SENDER_HOSTED); - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool CapDescriptor::Reader::isSenderPromise() const { - return which() == CapDescriptor::SENDER_PROMISE; -} -inline bool CapDescriptor::Builder::isSenderPromise() { - return which() == CapDescriptor::SENDER_PROMISE; -} -inline ::uint32_t CapDescriptor::Reader::getSenderPromise() const { - KJ_IREQUIRE((which() == CapDescriptor::SENDER_PROMISE), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t CapDescriptor::Builder::getSenderPromise() { - KJ_IREQUIRE((which() == CapDescriptor::SENDER_PROMISE), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void CapDescriptor::Builder::setSenderPromise( ::uint32_t value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::SENDER_PROMISE); - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool CapDescriptor::Reader::isReceiverHosted() const { - return which() == CapDescriptor::RECEIVER_HOSTED; -} -inline bool CapDescriptor::Builder::isReceiverHosted() { - return which() == CapDescriptor::RECEIVER_HOSTED; -} -inline ::uint32_t CapDescriptor::Reader::getReceiverHosted() const { - KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_HOSTED), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t CapDescriptor::Builder::getReceiverHosted() { - KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_HOSTED), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void CapDescriptor::Builder::setReceiverHosted( ::uint32_t value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_HOSTED); - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool CapDescriptor::Reader::isReceiverAnswer() const { - return which() == CapDescriptor::RECEIVER_ANSWER; -} -inline bool CapDescriptor::Builder::isReceiverAnswer() { - return which() == CapDescriptor::RECEIVER_ANSWER; -} -inline bool CapDescriptor::Reader::hasReceiverAnswer() const { - if (which() != CapDescriptor::RECEIVER_ANSWER) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool CapDescriptor::Builder::hasReceiverAnswer() { - if (which() != CapDescriptor::RECEIVER_ANSWER) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::PromisedAnswer::Reader CapDescriptor::Reader::getReceiverAnswer() const { - KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_ANSWER), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::PromisedAnswer::Builder CapDescriptor::Builder::getReceiverAnswer() { - KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_ANSWER), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void CapDescriptor::Builder::setReceiverAnswer( ::capnp::rpc::PromisedAnswer::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_ANSWER); - ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::PromisedAnswer::Builder CapDescriptor::Builder::initReceiverAnswer() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_ANSWER); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void CapDescriptor::Builder::adoptReceiverAnswer( - ::capnp::Orphan< ::capnp::rpc::PromisedAnswer>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::RECEIVER_ANSWER); - ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::PromisedAnswer> CapDescriptor::Builder::disownReceiverAnswer() { - KJ_IREQUIRE((which() == CapDescriptor::RECEIVER_ANSWER), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::PromisedAnswer>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool CapDescriptor::Reader::isThirdPartyHosted() const { - return which() == CapDescriptor::THIRD_PARTY_HOSTED; -} -inline bool CapDescriptor::Builder::isThirdPartyHosted() { - return which() == CapDescriptor::THIRD_PARTY_HOSTED; -} -inline bool CapDescriptor::Reader::hasThirdPartyHosted() const { - if (which() != CapDescriptor::THIRD_PARTY_HOSTED) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool CapDescriptor::Builder::hasThirdPartyHosted() { - if (which() != CapDescriptor::THIRD_PARTY_HOSTED) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::rpc::ThirdPartyCapDescriptor::Reader CapDescriptor::Reader::getThirdPartyHosted() const { - KJ_IREQUIRE((which() == CapDescriptor::THIRD_PARTY_HOSTED), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::rpc::ThirdPartyCapDescriptor::Builder CapDescriptor::Builder::getThirdPartyHosted() { - KJ_IREQUIRE((which() == CapDescriptor::THIRD_PARTY_HOSTED), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void CapDescriptor::Builder::setThirdPartyHosted( ::capnp::rpc::ThirdPartyCapDescriptor::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::THIRD_PARTY_HOSTED); - ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::rpc::ThirdPartyCapDescriptor::Builder CapDescriptor::Builder::initThirdPartyHosted() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::THIRD_PARTY_HOSTED); - return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void CapDescriptor::Builder::adoptThirdPartyHosted( - ::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, CapDescriptor::THIRD_PARTY_HOSTED); - ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::rpc::ThirdPartyCapDescriptor> CapDescriptor::Builder::disownThirdPartyHosted() { - KJ_IREQUIRE((which() == CapDescriptor::THIRD_PARTY_HOSTED), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::rpc::ThirdPartyCapDescriptor>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::uint32_t PromisedAnswer::Reader::getQuestionId() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t PromisedAnswer::Builder::getQuestionId() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void PromisedAnswer::Builder::setQuestionId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool PromisedAnswer::Reader::hasTransform() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool PromisedAnswer::Builder::hasTransform() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Reader PromisedAnswer::Reader::getTransform() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Builder PromisedAnswer::Builder::getTransform() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void PromisedAnswer::Builder::setTransform( ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>::Builder PromisedAnswer::Builder::initTransform(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void PromisedAnswer::Builder::adoptTransform( - ::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>> PromisedAnswer::Builder::disownTransform() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::rpc::PromisedAnswer::Op>>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::capnp::rpc::PromisedAnswer::Op::Which PromisedAnswer::Op::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline ::capnp::rpc::PromisedAnswer::Op::Which PromisedAnswer::Op::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline bool PromisedAnswer::Op::Reader::isNoop() const { - return which() == PromisedAnswer::Op::NOOP; -} -inline bool PromisedAnswer::Op::Builder::isNoop() { - return which() == PromisedAnswer::Op::NOOP; -} -inline ::capnp::Void PromisedAnswer::Op::Reader::getNoop() const { - KJ_IREQUIRE((which() == PromisedAnswer::Op::NOOP), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void PromisedAnswer::Op::Builder::getNoop() { - KJ_IREQUIRE((which() == PromisedAnswer::Op::NOOP), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void PromisedAnswer::Op::Builder::setNoop( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, PromisedAnswer::Op::NOOP); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool PromisedAnswer::Op::Reader::isGetPointerField() const { - return which() == PromisedAnswer::Op::GET_POINTER_FIELD; -} -inline bool PromisedAnswer::Op::Builder::isGetPointerField() { - return which() == PromisedAnswer::Op::GET_POINTER_FIELD; -} -inline ::uint16_t PromisedAnswer::Op::Reader::getGetPointerField() const { - KJ_IREQUIRE((which() == PromisedAnswer::Op::GET_POINTER_FIELD), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t PromisedAnswer::Op::Builder::getGetPointerField() { - KJ_IREQUIRE((which() == PromisedAnswer::Op::GET_POINTER_FIELD), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void PromisedAnswer::Op::Builder::setGetPointerField( ::uint16_t value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, PromisedAnswer::Op::GET_POINTER_FIELD); - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool ThirdPartyCapDescriptor::Reader::hasId() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool ThirdPartyCapDescriptor::Builder::hasId() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader ThirdPartyCapDescriptor::Reader::getId() const { - return ::capnp::AnyPointer::Reader(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder ThirdPartyCapDescriptor::Builder::getId() { - return ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder ThirdPartyCapDescriptor::Builder::initId() { - auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline ::uint32_t ThirdPartyCapDescriptor::Reader::getVineId() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t ThirdPartyCapDescriptor::Builder::getVineId() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void ThirdPartyCapDescriptor::Builder::setVineId( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Exception::Reader::hasReason() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Exception::Builder::hasReason() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Exception::Reader::getReason() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Exception::Builder::getReason() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Exception::Builder::setReason( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Exception::Builder::initReason(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void Exception::Builder::adoptReason( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Exception::Builder::disownReason() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Exception::Reader::getObsoleteIsCallersFault() const { - return _reader.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline bool Exception::Builder::getObsoleteIsCallersFault() { - return _builder.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Exception::Builder::setObsoleteIsCallersFault(bool value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t Exception::Reader::getObsoleteDurability() const { - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t Exception::Builder::getObsoleteDurability() { - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Exception::Builder::setObsoleteDurability( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline ::capnp::rpc::Exception::Type Exception::Reader::getType() const { - return _reader.getDataField< ::capnp::rpc::Exception::Type>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} - -inline ::capnp::rpc::Exception::Type Exception::Builder::getType() { - return _builder.getDataField< ::capnp::rpc::Exception::Type>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} -inline void Exception::Builder::setType( ::capnp::rpc::Exception::Type value) { - _builder.setDataField< ::capnp::rpc::Exception::Type>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); -} - -} // namespace -} // namespace - -#endif // CAPNP_INCLUDED_b312981b2552a250_ diff --git a/phonelibs/capnp-cpp/include/capnp/rpc.h b/phonelibs/capnp-cpp/include/capnp/rpc.h deleted file mode 100644 index d84ed982e78314..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/rpc.h +++ /dev/null @@ -1,537 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_RPC_H_ -#define CAPNP_RPC_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "capability.h" -#include "rpc-prelude.h" - -namespace capnp { - -template -class VatNetwork; -template -class SturdyRefRestorer; - -template -class BootstrapFactory: public _::BootstrapFactoryBase { - // Interface that constructs per-client bootstrap interfaces. Use this if you want each client - // who connects to see a different bootstrap interface based on their (authenticated) VatId. - // This allows an application to bootstrap off of the authentication performed at the VatNetwork - // level. (Typically VatId is some sort of public key.) - // - // This is only useful for multi-party networks. For TwoPartyVatNetwork, there's no reason to - // use a BootstrapFactory; just specify a single bootstrap capability in this case. - -public: - virtual Capability::Client createFor(typename VatId::Reader clientId) = 0; - // Create a bootstrap capability appropriate for exposing to the given client. VatNetwork will - // have authenticated the client VatId before this is called. - -private: - Capability::Client baseCreateFor(AnyStruct::Reader clientId) override; -}; - -template -class RpcSystem: public _::RpcSystemBase { - // Represents the RPC system, which is the portal to objects available on the network. - // - // The RPC implementation sits on top of an implementation of `VatNetwork`. The `VatNetwork` - // determines how to form connections between vats -- specifically, two-way, private, reliable, - // sequenced datagram connections. The RPC implementation determines how to use such connections - // to manage object references and make method calls. - // - // See `makeRpcServer()` and `makeRpcClient()` below for convenient syntax for setting up an - // `RpcSystem` given a `VatNetwork`. - // - // See `ez-rpc.h` for an even simpler interface for setting up RPC in a typical two-party - // client/server scenario. - -public: - template - RpcSystem( - VatNetwork& network, - kj::Maybe bootstrapInterface, - kj::Maybe::Client> gateway = nullptr); - - template - RpcSystem( - VatNetwork& network, - BootstrapFactory& bootstrapFactory, - kj::Maybe::Client> gateway = nullptr); - - template - RpcSystem( - VatNetwork& network, - SturdyRefRestorer& restorer); - - RpcSystem(RpcSystem&& other) = default; - - Capability::Client bootstrap(typename VatId::Reader vatId); - // Connect to the given vat and return its bootstrap interface. - - Capability::Client restore(typename VatId::Reader hostId, AnyPointer::Reader objectId) - KJ_DEPRECATED("Please transition to using a bootstrap interface instead."); - // ** DEPRECATED ** - // - // Restores the given SturdyRef from the network and return the capability representing it. - // - // `hostId` identifies the host from which to request the ref, in the format specified by the - // `VatNetwork` in use. `objectId` is the object ID in whatever format is expected by said host. - // - // This method will be removed in a future version of Cap'n Proto. Instead, please transition - // to using bootstrap(), which is equivalent to calling restore() with a null `objectId`. - // You may emulate the old concept of object IDs by exporting a bootstrap interface which has - // methods that can be used to obtain other capabilities by ID. - - void setFlowLimit(size_t words); - // Sets the incoming call flow limit. If more than `words` worth of call messages have not yet - // received responses, the RpcSystem will not read further messages from the stream. This can be - // used as a crude way to prevent a resource exhaustion attack (or bug) in which a peer makes an - // excessive number of simultaneous calls that consume the receiver's RAM. - // - // There are some caveats. When over the flow limit, all messages are blocked, including returns. - // If the outstanding calls are themselves waiting on calls going in the opposite direction, the - // flow limit may prevent those calls from completing, leading to deadlock. However, a - // sufficiently high limit should make this unlikely. - // - // Note that a call's parameter size counts against the flow limit until the call returns, even - // if the recipient calls releaseParams() to free the parameter memory early. This is because - // releaseParams() may simply indicate that the parameters have been forwarded to another - // machine, but are still in-memory there. For illustration, say that Alice made a call to Bob - // who forwarded the call to Carol. Bob has imposed a flow limit on Alice. Alice's calls are - // being forwarded to Carol, so Bob never keeps the parameters in-memory for more than a brief - // period. However, the flow limit counts all calls that haven't returned, even if Bob has - // already freed the memory they consumed. You might argue that the right solution here is - // instead for Carol to impose her own flow limit on Bob. This has a serious problem, though: - // Bob might be forwarding requests to Carol on behalf of many different parties, not just Alice. - // If Alice can pump enough data to hit the Bob -> Carol flow limit, then those other parties - // will be disrupted. Thus, we can only really impose the limit on the Alice -> Bob link, which - // only affects Alice. We need that one flow limit to limit Alice's impact on the whole system, - // so it has to count all in-flight calls. - // - // In Sandstorm, flow limits are imposed by the supervisor on calls coming out of a grain, in - // order to prevent a grain from inundating the system with in-flight calls. In practice, the - // main time this happens is when a grain is pushing a large file download and doesn't implement - // proper cooperative flow control. -}; - -template -RpcSystem makeRpcServer( - VatNetwork& network, - Capability::Client bootstrapInterface); -// Make an RPC server. Typical usage (e.g. in a main() function): -// -// MyEventLoop eventLoop; -// kj::WaitScope waitScope(eventLoop); -// MyNetwork network; -// MyMainInterface::Client bootstrap = makeMain(); -// auto server = makeRpcServer(network, bootstrap); -// kj::NEVER_DONE.wait(waitScope); // run forever -// -// See also ez-rpc.h, which has simpler instructions for the common case of a two-party -// client-server RPC connection. - -template , - typename ExternalRef = _::ExternalRefFromRealmGatewayClient> -RpcSystem makeRpcServer( - VatNetwork& network, - Capability::Client bootstrapInterface, RealmGatewayClient gateway); -// Make an RPC server for a VatNetwork that resides in a different realm from the application. -// The given RealmGateway is used to translate SturdyRefs between the app's ("internal") format -// and the network's ("external") format. - -template -RpcSystem makeRpcServer( - VatNetwork& network, - BootstrapFactory& bootstrapFactory); -// Make an RPC server that can serve different bootstrap interfaces to different clients via a -// BootstrapInterface. - -template , - typename ExternalRef = _::ExternalRefFromRealmGatewayClient> -RpcSystem makeRpcServer( - VatNetwork& network, - BootstrapFactory& bootstrapFactory, RealmGatewayClient gateway); -// Make an RPC server that can serve different bootstrap interfaces to different clients via a -// BootstrapInterface and communicates with a different realm than the application is in via a -// RealmGateway. - -template -RpcSystem makeRpcServer( - VatNetwork& network, - SturdyRefRestorer& restorer) - KJ_DEPRECATED("Please transition to using a bootstrap interface instead."); -// ** DEPRECATED ** -// -// Create an RPC server which exports multiple main interfaces by object ID. The `restorer` object -// can be used to look up objects by ID. -// -// Please transition to exporting only one interface, which is known as the "bootstrap" interface. -// For backwards-compatibility with old clients, continue to implement SturdyRefRestorer, but -// return the new bootstrap interface when the request object ID is null. When new clients connect -// and request the bootstrap interface, they will get that interface. Eventually, once all clients -// are updated to request only the bootstrap interface, stop implementing SturdyRefRestorer and -// switch to passing the bootstrap capability itself as the second parameter to `makeRpcServer()`. - -template -RpcSystem makeRpcClient( - VatNetwork& network); -// Make an RPC client. Typical usage (e.g. in a main() function): -// -// MyEventLoop eventLoop; -// kj::WaitScope waitScope(eventLoop); -// MyNetwork network; -// auto client = makeRpcClient(network); -// MyCapability::Client cap = client.restore(hostId, objId).castAs(); -// auto response = cap.fooRequest().send().wait(waitScope); -// handleMyResponse(response); -// -// See also ez-rpc.h, which has simpler instructions for the common case of a two-party -// client-server RPC connection. - -template , - typename ExternalRef = _::ExternalRefFromRealmGatewayClient> -RpcSystem makeRpcClient( - VatNetwork& network, - RealmGatewayClient gateway); -// Make an RPC client for a VatNetwork that resides in a different realm from the application. -// The given RealmGateway is used to translate SturdyRefs between the app's ("internal") format -// and the network's ("external") format. - -template -class SturdyRefRestorer: public _::SturdyRefRestorerBase { - // ** DEPRECATED ** - // - // In Cap'n Proto 0.4.x, applications could export multiple main interfaces identified by - // object IDs. The callback used to map object IDs to objects was `SturdyRefRestorer`, as we - // imagined this would eventually be used for restoring SturdyRefs as well. In practice, it was - // never used for real SturdyRefs, only for exporting singleton objects under well-known names. - // - // The new preferred strategy is to export only a _single_ such interface, called the - // "bootstrap interface". That interface can itself have methods for obtaining other objects, of - // course, but that is up to the app. `SturdyRefRestorer` exists for backwards-compatibility. - // - // Hint: Use SturdyRefRestorer to define a server that exports services under - // string names. - -public: - virtual Capability::Client restore(typename SturdyRefObjectId::Reader ref) - KJ_DEPRECATED( - "Please transition to using bootstrap interfaces instead of SturdyRefRestorer.") = 0; - // Restore the given object, returning a capability representing it. - -private: - Capability::Client baseRestore(AnyPointer::Reader ref) override final; -}; - -// ======================================================================================= -// VatNetwork - -class OutgoingRpcMessage { - // A message to be sent by a `VatNetwork`. - -public: - virtual AnyPointer::Builder getBody() = 0; - // Get the message body, which the caller may fill in any way it wants. (The standard RPC - // implementation initializes it as a Message as defined in rpc.capnp.) - - virtual void send() = 0; - // Send the message, or at least put it in a queue to be sent later. Note that the builder - // returned by `getBody()` remains valid at least until the `OutgoingRpcMessage` is destroyed. -}; - -class IncomingRpcMessage { - // A message received from a `VatNetwork`. - -public: - virtual AnyPointer::Reader getBody() = 0; - // Get the message body, to be interpreted by the caller. (The standard RPC implementation - // interprets it as a Message as defined in rpc.capnp.) -}; - -template -class VatNetwork: public _::VatNetworkBase { - // Cap'n Proto RPC operates between vats, where a "vat" is some sort of host of objects. - // Typically one Cap'n Proto process (in the Unix sense) is one vat. The RPC system is what - // allows calls between objects hosted in different vats. - // - // The RPC implementation sits on top of an implementation of `VatNetwork`. The `VatNetwork` - // determines how to form connections between vats -- specifically, two-way, private, reliable, - // sequenced datagram connections. The RPC implementation determines how to use such connections - // to manage object references and make method calls. - // - // The most common implementation of VatNetwork is TwoPartyVatNetwork (rpc-twoparty.h). Most - // simple client-server apps will want to use it. (You may even want to use the EZ RPC - // interfaces in `ez-rpc.h` and avoid all of this.) - // - // TODO(someday): Provide a standard implementation for the public internet. - -public: - class Connection; - - struct ConnectionAndProvisionId { - // Result of connecting to a vat introduced by another vat. - - kj::Own connection; - // Connection to the new vat. - - kj::Own firstMessage; - // An already-allocated `OutgoingRpcMessage` associated with `connection`. The RPC system will - // construct this as an `Accept` message and send it. - - Orphan provisionId; - // A `ProvisionId` already allocated inside `firstMessage`, which the RPC system will use to - // build the `Accept` message. - }; - - class Connection: public _::VatNetworkBase::Connection { - // A two-way RPC connection. - // - // This object may represent a connection that doesn't exist yet, but is expected to exist - // in the future. In this case, sent messages will automatically be queued and sent once the - // connection is ready, so that the caller doesn't need to know the difference. - - public: - // Level 0 features ---------------------------------------------- - - virtual typename VatId::Reader getPeerVatId() = 0; - // Returns the connected vat's authenticated VatId. It is the VatNetwork's responsibility to - // authenticate this, so that the caller can be assured that they are really talking to the - // identified vat and not an imposter. - - virtual kj::Own newOutgoingMessage(uint firstSegmentWordSize) override = 0; - // Allocate a new message to be sent on this connection. - // - // If `firstSegmentWordSize` is non-zero, it should be treated as a hint suggesting how large - // to make the first segment. This is entirely a hint and the connection may adjust it up or - // down. If it is zero, the connection should choose the size itself. - - virtual kj::Promise>> receiveIncomingMessage() override = 0; - // Wait for a message to be received and return it. If the read stream cleanly terminates, - // return null. If any other problem occurs, throw an exception. - - virtual kj::Promise shutdown() override KJ_WARN_UNUSED_RESULT = 0; - // Waits until all outgoing messages have been sent, then shuts down the outgoing stream. The - // returned promise resolves after shutdown is complete. - - private: - AnyStruct::Reader baseGetPeerVatId() override; - }; - - // Level 0 features ------------------------------------------------ - - virtual kj::Maybe> connect(typename VatId::Reader hostId) = 0; - // Connect to a VatId. Note that this method immediately returns a `Connection`, even - // if the network connection has not yet been established. Messages can be queued to this - // connection and will be delivered once it is open. The caller must attempt to read from the - // connection to verify that it actually succeeded; the read will fail if the connection - // couldn't be opened. Some network implementations may actually start sending messages before - // hearing back from the server at all, to avoid a round trip. - // - // Returns nullptr if `hostId` refers to the local host. - - virtual kj::Promise> accept() = 0; - // Wait for the next incoming connection and return it. - - // Level 4 features ------------------------------------------------ - // TODO(someday) - -private: - kj::Maybe> - baseConnect(AnyStruct::Reader hostId) override final; - kj::Promise> baseAccept() override final; -}; - -// ======================================================================================= -// *************************************************************************************** -// Inline implementation details start here -// *************************************************************************************** -// ======================================================================================= - -template -Capability::Client BootstrapFactory::baseCreateFor(AnyStruct::Reader clientId) { - return createFor(clientId.as()); -} - -template -kj::Maybe> - VatNetwork:: - baseConnect(AnyStruct::Reader ref) { - auto maybe = connect(ref.as()); - return maybe.map([](kj::Own& conn) -> kj::Own<_::VatNetworkBase::Connection> { - return kj::mv(conn); - }); -} - -template -kj::Promise> - VatNetwork::baseAccept() { - return accept().then( - [](kj::Own&& connection) -> kj::Own<_::VatNetworkBase::Connection> { - return kj::mv(connection); - }); -} - -template -AnyStruct::Reader VatNetwork< - SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>:: - Connection::baseGetPeerVatId() { - return getPeerVatId(); -} - -template -Capability::Client SturdyRefRestorer::baseRestore(AnyPointer::Reader ref) { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - return restore(ref.getAs()); -#pragma GCC diagnostic pop -} - -template -template -RpcSystem::RpcSystem( - VatNetwork& network, - kj::Maybe bootstrap, - kj::Maybe::Client> gateway) - : _::RpcSystemBase(network, kj::mv(bootstrap), kj::mv(gateway)) {} - -template -template -RpcSystem::RpcSystem( - VatNetwork& network, - BootstrapFactory& bootstrapFactory, - kj::Maybe::Client> gateway) - : _::RpcSystemBase(network, bootstrapFactory, kj::mv(gateway)) {} - -template -template -RpcSystem::RpcSystem( - VatNetwork& network, - SturdyRefRestorer& restorer) - : _::RpcSystemBase(network, restorer) {} - -template -Capability::Client RpcSystem::bootstrap(typename VatId::Reader vatId) { - return baseBootstrap(_::PointerHelpers::getInternalReader(vatId)); -} - -template -Capability::Client RpcSystem::restore( - typename VatId::Reader hostId, AnyPointer::Reader objectId) { - return baseRestore(_::PointerHelpers::getInternalReader(hostId), objectId); -} - -template -inline void RpcSystem::setFlowLimit(size_t words) { - baseSetFlowLimit(words); -} - -template -RpcSystem makeRpcServer( - VatNetwork& network, - Capability::Client bootstrapInterface) { - return RpcSystem(network, kj::mv(bootstrapInterface)); -} - -template -RpcSystem makeRpcServer( - VatNetwork& network, - Capability::Client bootstrapInterface, RealmGatewayClient gateway) { - return RpcSystem(network, kj::mv(bootstrapInterface), - gateway.template castAs>()); -} - -template -RpcSystem makeRpcServer( - VatNetwork& network, - BootstrapFactory& bootstrapFactory) { - return RpcSystem(network, bootstrapFactory); -} - -template -RpcSystem makeRpcServer( - VatNetwork& network, - BootstrapFactory& bootstrapFactory, RealmGatewayClient gateway) { - return RpcSystem(network, bootstrapFactory, gateway.template castAs>()); -} - -template -RpcSystem makeRpcServer( - VatNetwork& network, - SturdyRefRestorer& restorer) { - return RpcSystem(network, restorer); -} - -template -RpcSystem makeRpcClient( - VatNetwork& network) { - return RpcSystem(network, nullptr); -} - -template -RpcSystem makeRpcClient( - VatNetwork& network, - RealmGatewayClient gateway) { - return RpcSystem(network, nullptr, gateway.template castAs>()); -} - -} // namespace capnp - -#endif // CAPNP_RPC_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/schema-lite.h b/phonelibs/capnp-cpp/include/capnp/schema-lite.h deleted file mode 100644 index 58a8c14c05b73e..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/schema-lite.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_SCHEMA_LITE_H_ -#define CAPNP_SCHEMA_LITE_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include -#include "message.h" - -namespace capnp { - -template -inline schema::Node::Reader schemaProto() { - // Get the schema::Node for this type's schema. This function works even in lite mode. - return readMessageUnchecked(CapnpPrivate::encodedSchema()); -} - -template ::typeId> -inline schema::Node::Reader schemaProto() { - // Get the schema::Node for this type's schema. This function works even in lite mode. - return readMessageUnchecked(schemas::EnumInfo::encodedSchema()); -} - -} // namespace capnp - -#endif // CAPNP_SCHEMA_LITE_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/schema-loader.h b/phonelibs/capnp-cpp/include/capnp/schema-loader.h deleted file mode 100644 index 0e34cba77fdbb8..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/schema-loader.h +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_SCHEMA_LOADER_H_ -#define CAPNP_SCHEMA_LOADER_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "schema.h" -#include -#include - -namespace capnp { - -class SchemaLoader { - // Class which can be used to construct Schema objects from schema::Nodes as defined in - // schema.capnp. - // - // It is a bad idea to use this class on untrusted input with exceptions disabled -- you may - // be exposing yourself to denial-of-service attacks, as attackers can easily construct schemas - // that are subtly inconsistent in a way that causes exceptions to be thrown either by - // SchemaLoader or by the dynamic API when the schemas are subsequently used. If you enable and - // properly catch exceptions, you should be OK -- assuming no bugs in the Cap'n Proto - // implementation, of course. - -public: - class LazyLoadCallback { - public: - virtual void load(const SchemaLoader& loader, uint64_t id) const = 0; - // Request that the schema node with the given ID be loaded into the given SchemaLoader. If - // the callback is able to find a schema for this ID, it should invoke `loadOnce()` on - // `loader` to load it. If no such node exists, it should simply do nothing and return. - // - // The callback is allowed to load schema nodes other than the one requested, e.g. because it - // expects they will be needed soon. - // - // If the `SchemaLoader` is used from multiple threads, the callback must be thread-safe. - // In particular, it's possible for multiple threads to invoke `load()` with the same ID. - // If the callback performs a large amount of work to look up IDs, it should be sure to - // de-dup these requests. - }; - - SchemaLoader(); - - SchemaLoader(const LazyLoadCallback& callback); - // Construct a SchemaLoader which will invoke the given callback when a schema node is requested - // that isn't already loaded. - - ~SchemaLoader() noexcept(false); - KJ_DISALLOW_COPY(SchemaLoader); - - Schema get(uint64_t id, schema::Brand::Reader brand = schema::Brand::Reader(), - Schema scope = Schema()) const; - // Gets the schema for the given ID, throwing an exception if it isn't present. - // - // The returned schema may be invalidated if load() is called with a new schema for the same ID. - // In general, you should not call load() while a schema from this loader is in-use. - // - // `brand` and `scope` are used to determine brand bindings where relevant. `brand` gives - // parameter bindings for the target type's brand parameters that were specified at the reference - // site. `scope` specifies the scope in which the type ID appeared -- if `brand` itself contains - // parameter references or indicates that some parameters will be inherited, these will be - // interpreted within / inherited from `scope`. - - kj::Maybe tryGet(uint64_t id, schema::Brand::Reader bindings = schema::Brand::Reader(), - Schema scope = Schema()) const; - // Like get() but doesn't throw. - - Schema getUnbound(uint64_t id) const; - // Gets a special version of the schema in which all brand parameters are "unbound". This means - // that if you look up a type via the Schema API, and it resolves to a brand parameter, the - // returned Type's getBrandParameter() method will return info about that parameter. Otherwise, - // normally, all brand parameters that aren't otherwise bound are assumed to simply be - // "AnyPointer". - - Type getType(schema::Type::Reader type, Schema scope = Schema()) const; - // Convenience method which interprets a schema::Type to produce a Type object. Implemented in - // terms of get(). - - Schema load(const schema::Node::Reader& reader); - // Loads the given schema node. Validates the node and throws an exception if invalid. This - // makes a copy of the schema, so the object passed in can be destroyed after this returns. - // - // If the node has any dependencies which are not already loaded, they will be initialized as - // stubs -- empty schemas of whichever kind is expected. - // - // If another schema for the given reader has already been seen, the loader will inspect both - // schemas to determine which one is newer, and use that that one. If the two versions are - // found to be incompatible, an exception is thrown. If the two versions differ but are - // compatible and the loader cannot determine which is newer (e.g., the only changes are renames), - // the existing schema will be preferred. Note that in any case, the loader will end up keeping - // around copies of both schemas, so you shouldn't repeatedly reload schemas into the same loader. - // - // The following properties of the schema node are validated: - // - Struct size and preferred list encoding are valid and consistent. - // - Struct members are fields or unions. - // - Union members are fields. - // - Field offsets are in-bounds. - // - Ordinals and codeOrders are sequential starting from zero. - // - Values are of the right union case to match their types. - // - // You should assume anything not listed above is NOT validated. In particular, things that are - // not validated now, but could be in the future, include but are not limited to: - // - Names. - // - Annotation values. (This is hard because the annotation declaration is not always - // available.) - // - Content of default/constant values of pointer type. (Validating these would require knowing - // their schema, but even if the schemas are available at validation time, they could be - // updated by a subsequent load(), invalidating existing values. Instead, these values are - // validated at the time they are used, as usual for Cap'n Proto objects.) - // - // Also note that unknown types are not considered invalid. Instead, the dynamic API returns - // a DynamicValue with type UNKNOWN for these. - - Schema loadOnce(const schema::Node::Reader& reader) const; - // Like `load()` but does nothing if a schema with the same ID is already loaded. In contrast, - // `load()` would attempt to compare the schemas and take the newer one. `loadOnce()` is safe - // to call even while concurrently using schemas from this loader. It should be considered an - // error to call `loadOnce()` with two non-identical schemas that share the same ID, although - // this error may or may not actually be detected by the implementation. - - template - void loadCompiledTypeAndDependencies(); - // Load the schema for the given compiled-in type and all of its dependencies. - // - // If you want to be able to cast a DynamicValue built from this SchemaLoader to the compiled-in - // type using as(), you must call this method before constructing the DynamicValue. Otherwise, - // as() will throw an exception complaining about type mismatch. - - kj::Array getAllLoaded() const; - // Get a complete list of all loaded schema nodes. It is particularly useful to call this after - // loadCompiledTypeAndDependencies() in order to get a flat list of all of T's transitive - // dependencies. - -private: - class Validator; - class CompatibilityChecker; - class Impl; - class InitializerImpl; - class BrandedInitializerImpl; - kj::MutexGuarded> impl; - - void loadNative(const _::RawSchema* nativeSchema); -}; - -template -inline void SchemaLoader::loadCompiledTypeAndDependencies() { - loadNative(&_::rawSchema()); -} - -} // namespace capnp - -#endif // CAPNP_SCHEMA_LOADER_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/schema-parser.h b/phonelibs/capnp-cpp/include/capnp/schema-parser.h deleted file mode 100644 index 3322bbfbfbc77a..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/schema-parser.h +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_SCHEMA_PARSER_H_ -#define CAPNP_SCHEMA_PARSER_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "schema-loader.h" -#include - -namespace capnp { - -class ParsedSchema; -class SchemaFile; - -class SchemaParser { - // Parses `.capnp` files to produce `Schema` objects. - // - // This class is thread-safe, hence all its methods are const. - -public: - SchemaParser(); - ~SchemaParser() noexcept(false); - - ParsedSchema parseDiskFile(kj::StringPtr displayName, kj::StringPtr diskPath, - kj::ArrayPtr importPath) const; - // Parse a file located on disk. Throws an exception if the file dosen't exist. - // - // Parameters: - // * `displayName`: The name that will appear in the file's schema node. (If the file has - // already been parsed, this will be ignored and the display name from the first time it was - // parsed will be kept.) - // * `diskPath`: The path to the file on disk. - // * `importPath`: Directories to search when resolving absolute imports within this file - // (imports that start with a `/`). Must remain valid until the SchemaParser is destroyed. - // (If the file has already been parsed, this will be ignored and the import path from the - // first time it was parsed will be kept.) - // - // This method is a shortcut, equivalent to: - // parser.parseFile(SchemaFile::newDiskFile(displayName, diskPath, importPath))`; - // - // This method throws an exception if any errors are encountered in the file or in anything the - // file depends on. Note that merely importing another file does not count as a dependency on - // anything in the imported file -- only the imported types which are actually used are - // "dependencies". - - ParsedSchema parseFile(kj::Own&& file) const; - // Advanced interface for parsing a file that may or may not be located in any global namespace. - // Most users will prefer `parseDiskFile()`. - // - // If the file has already been parsed (that is, a SchemaFile that compares equal to this one - // was parsed previously), the existing schema will be returned again. - // - // This method reports errors by calling SchemaFile::reportError() on the file where the error - // is located. If that call does not throw an exception, `parseFile()` may in fact return - // normally. In this case, the result is a best-effort attempt to compile the schema, but it - // may be invalid or corrupt, and using it for anything may cause exceptions to be thrown. - - template - inline void loadCompiledTypeAndDependencies() { - // See SchemaLoader::loadCompiledTypeAndDependencies(). - getLoader().loadCompiledTypeAndDependencies(); - } - -private: - struct Impl; - class ModuleImpl; - kj::Own impl; - mutable bool hadErrors = false; - - ModuleImpl& getModuleImpl(kj::Own&& file) const; - SchemaLoader& getLoader(); - - friend class ParsedSchema; -}; - -class ParsedSchema: public Schema { - // ParsedSchema is an extension of Schema which also has the ability to look up nested nodes - // by name. See `SchemaParser`. - -public: - inline ParsedSchema(): parser(nullptr) {} - - kj::Maybe findNested(kj::StringPtr name) const; - // Gets the nested node with the given name, or returns null if there is no such nested - // declaration. - - ParsedSchema getNested(kj::StringPtr name) const; - // Gets the nested node with the given name, or throws an exception if there is no such nested - // declaration. - -private: - inline ParsedSchema(Schema inner, const SchemaParser& parser): Schema(inner), parser(&parser) {} - - const SchemaParser* parser; - friend class SchemaParser; -}; - -// ======================================================================================= -// Advanced API - -class SchemaFile { - // Abstract interface representing a schema file. You can implement this yourself in order to - // gain more control over how the compiler resolves imports and reads files. For the - // common case of files on disk or other global filesystem-like namespaces, use - // `SchemaFile::newDiskFile()`. - -public: - class FileReader { - public: - virtual bool exists(kj::StringPtr path) const = 0; - virtual kj::Array read(kj::StringPtr path) const = 0; - }; - - class DiskFileReader final: public FileReader { - // Implementation of FileReader that uses the local disk. Files are read using mmap() if - // possible. - - public: - static const DiskFileReader instance; - - bool exists(kj::StringPtr path) const override; - kj::Array read(kj::StringPtr path) const override; - }; - - static kj::Own newDiskFile( - kj::StringPtr displayName, kj::StringPtr diskPath, - kj::ArrayPtr importPath, - const FileReader& fileReader = DiskFileReader::instance); - // Construct a SchemaFile representing a file on disk (or located in the filesystem-like - // namespace represented by `fileReader`). - // - // Parameters: - // * `displayName`: The name that will appear in the file's schema node. - // * `diskPath`: The path to the file on disk. - // * `importPath`: Directories to search when resolving absolute imports within this file - // (imports that start with a `/`). The array content must remain valid as long as the - // SchemaFile exists (which is at least as long as the SchemaParser that parses it exists). - // * `fileReader`: Allows you to use a filesystem other than the actual local disk. Although, - // if you find yourself using this, it may make more sense for you to implement SchemaFile - // yourself. - // - // The SchemaFile compares equal to any other SchemaFile that has exactly the same disk path, - // after canonicalization. - // - // The SchemaFile will throw an exception if any errors are reported. - - // ----------------------------------------------------------------- - // For more control, you can implement this interface. - - virtual kj::StringPtr getDisplayName() const = 0; - // Get the file's name, as it should appear in the schema. - - virtual kj::Array readContent() const = 0; - // Read the file's entire content and return it as a byte array. - - virtual kj::Maybe> import(kj::StringPtr path) const = 0; - // Resolve an import, relative to this file. - // - // `path` is exactly what appears between quotes after the `import` keyword in the source code. - // It is entirely up to the `SchemaFile` to decide how to map this to another file. Typically, - // a leading '/' means that the file is an "absolute" path and is searched for in some list of - // schema file repositories. On the other hand, a path that doesn't start with '/' is relative - // to the importing file. - - virtual bool operator==(const SchemaFile& other) const = 0; - virtual bool operator!=(const SchemaFile& other) const = 0; - virtual size_t hashCode() const = 0; - // Compare two SchemaFiles to see if they refer to the same underlying file. This is an - // optimization used to avoid the need to re-parse a file to check its ID. - - struct SourcePos { - uint byte; - uint line; - uint column; - }; - virtual void reportError(SourcePos start, SourcePos end, kj::StringPtr message) const = 0; - // Report that the file contains an error at the given interval. - -private: - class DiskSchemaFile; -}; - -} // namespace capnp - -#endif // CAPNP_SCHEMA_PARSER_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/schema.capnp b/phonelibs/capnp-cpp/include/capnp/schema.capnp deleted file mode 100644 index 4bef693f6cfd3e..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/schema.capnp +++ /dev/null @@ -1,498 +0,0 @@ -# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -# Licensed under the MIT License: -# -# 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. - -using Cxx = import "/capnp/c++.capnp"; - -@0xa93fc509624c72d9; -$Cxx.namespace("capnp::schema"); - -using Id = UInt64; -# The globally-unique ID of a file, type, or annotation. - -struct Node { - id @0 :Id; - - displayName @1 :Text; - # Name to present to humans to identify this Node. You should not attempt to parse this. Its - # format could change. It is not guaranteed to be unique. - # - # (On Zooko's triangle, this is the node's nickname.) - - displayNamePrefixLength @2 :UInt32; - # If you want a shorter version of `displayName` (just naming this node, without its surrounding - # scope), chop off this many characters from the beginning of `displayName`. - - scopeId @3 :Id; - # ID of the lexical parent node. Typically, the scope node will have a NestedNode pointing back - # at this node, but robust code should avoid relying on this (and, in fact, group nodes are not - # listed in the outer struct's nestedNodes, since they are listed in the fields). `scopeId` is - # zero if the node has no parent, which is normally only the case with files, but should be - # allowed for any kind of node (in order to make runtime type generation easier). - - parameters @32 :List(Parameter); - # If this node is parameterized (generic), the list of parameters. Empty for non-generic types. - - isGeneric @33 :Bool; - # True if this node is generic, meaning that it or one of its parent scopes has a non-empty - # `parameters`. - - struct Parameter { - # Information about one of the node's parameters. - - name @0 :Text; - } - - nestedNodes @4 :List(NestedNode); - # List of nodes nested within this node, along with the names under which they were declared. - - struct NestedNode { - name @0 :Text; - # Unqualified symbol name. Unlike Node.displayName, this *can* be used programmatically. - # - # (On Zooko's triangle, this is the node's petname according to its parent scope.) - - id @1 :Id; - # ID of the nested node. Typically, the target node's scopeId points back to this node, but - # robust code should avoid relying on this. - } - - annotations @5 :List(Annotation); - # Annotations applied to this node. - - union { - # Info specific to each kind of node. - - file @6 :Void; - - struct :group { - dataWordCount @7 :UInt16; - # Size of the data section, in words. - - pointerCount @8 :UInt16; - # Size of the pointer section, in pointers (which are one word each). - - preferredListEncoding @9 :ElementSize; - # The preferred element size to use when encoding a list of this struct. If this is anything - # other than `inlineComposite` then the struct is one word or less in size and is a candidate - # for list packing optimization. - - isGroup @10 :Bool; - # If true, then this "struct" node is actually not an independent node, but merely represents - # some named union or group within a particular parent struct. This node's scopeId refers - # to the parent struct, which may itself be a union/group in yet another struct. - # - # All group nodes share the same dataWordCount and pointerCount as the top-level - # struct, and their fields live in the same ordinal and offset spaces as all other fields in - # the struct. - # - # Note that a named union is considered a special kind of group -- in fact, a named union - # is exactly equivalent to a group that contains nothing but an unnamed union. - - discriminantCount @11 :UInt16; - # Number of fields in this struct which are members of an anonymous union, and thus may - # overlap. If this is non-zero, then a 16-bit discriminant is present indicating which - # of the overlapping fields is active. This can never be 1 -- if it is non-zero, it must be - # two or more. - # - # Note that the fields of an unnamed union are considered fields of the scope containing the - # union -- an unnamed union is not its own group. So, a top-level struct may contain a - # non-zero discriminant count. Named unions, on the other hand, are equivalent to groups - # containing unnamed unions. So, a named union has its own independent schema node, with - # `isGroup` = true. - - discriminantOffset @12 :UInt32; - # If `discriminantCount` is non-zero, this is the offset of the union discriminant, in - # multiples of 16 bits. - - fields @13 :List(Field); - # Fields defined within this scope (either the struct's top-level fields, or the fields of - # a particular group; see `isGroup`). - # - # The fields are sorted by ordinal number, but note that because groups share the same - # ordinal space, the field's index in this list is not necessarily exactly its ordinal. - # On the other hand, the field's position in this list does remain the same even as the - # protocol evolves, since it is not possible to insert or remove an earlier ordinal. - # Therefore, for most use cases, if you want to identify a field by number, it may make the - # most sense to use the field's index in this list rather than its ordinal. - } - - enum :group { - enumerants@14 :List(Enumerant); - # Enumerants ordered by numeric value (ordinal). - } - - interface :group { - methods @15 :List(Method); - # Methods ordered by ordinal. - - superclasses @31 :List(Superclass); - # Superclasses of this interface. - } - - const :group { - type @16 :Type; - value @17 :Value; - } - - annotation :group { - type @18 :Type; - - targetsFile @19 :Bool; - targetsConst @20 :Bool; - targetsEnum @21 :Bool; - targetsEnumerant @22 :Bool; - targetsStruct @23 :Bool; - targetsField @24 :Bool; - targetsUnion @25 :Bool; - targetsGroup @26 :Bool; - targetsInterface @27 :Bool; - targetsMethod @28 :Bool; - targetsParam @29 :Bool; - targetsAnnotation @30 :Bool; - } - } -} - -struct Field { - # Schema for a field of a struct. - - name @0 :Text; - - codeOrder @1 :UInt16; - # Indicates where this member appeared in the code, relative to other members. - # Code ordering may have semantic relevance -- programmers tend to place related fields - # together. So, using code ordering makes sense in human-readable formats where ordering is - # otherwise irrelevant, like JSON. The values of codeOrder are tightly-packed, so the maximum - # value is count(members) - 1. Fields that are members of a union are only ordered relative to - # the other members of that union, so the maximum value there is count(union.members). - - annotations @2 :List(Annotation); - - const noDiscriminant :UInt16 = 0xffff; - - discriminantValue @3 :UInt16 = Field.noDiscriminant; - # If the field is in a union, this is the value which the union's discriminant should take when - # the field is active. If the field is not in a union, this is 0xffff. - - union { - slot :group { - # A regular, non-group, non-fixed-list field. - - offset @4 :UInt32; - # Offset, in units of the field's size, from the beginning of the section in which the field - # resides. E.g. for a UInt32 field, multiply this by 4 to get the byte offset from the - # beginning of the data section. - - type @5 :Type; - defaultValue @6 :Value; - - hadExplicitDefault @10 :Bool; - # Whether the default value was specified explicitly. Non-explicit default values are always - # zero or empty values. Usually, whether the default value was explicit shouldn't matter. - # The main use case for this flag is for structs representing method parameters: - # explicitly-defaulted parameters may be allowed to be omitted when calling the method. - } - - group :group { - # A group. - - typeId @7 :Id; - # The ID of the group's node. - } - } - - ordinal :union { - implicit @8 :Void; - explicit @9 :UInt16; - # The original ordinal number given to the field. You probably should NOT use this; if you need - # a numeric identifier for a field, use its position within the field array for its scope. - # The ordinal is given here mainly just so that the original schema text can be reproduced given - # the compiled version -- i.e. so that `capnp compile -ocapnp` can do its job. - } -} - -struct Enumerant { - # Schema for member of an enum. - - name @0 :Text; - - codeOrder @1 :UInt16; - # Specifies order in which the enumerants were declared in the code. - # Like Struct.Field.codeOrder. - - annotations @2 :List(Annotation); -} - -struct Superclass { - id @0 :Id; - brand @1 :Brand; -} - -struct Method { - # Schema for method of an interface. - - name @0 :Text; - - codeOrder @1 :UInt16; - # Specifies order in which the methods were declared in the code. - # Like Struct.Field.codeOrder. - - implicitParameters @7 :List(Node.Parameter); - # The parameters listed in [] (typically, type / generic parameters), whose bindings are intended - # to be inferred rather than specified explicitly, although not all languages support this. - - paramStructType @2 :Id; - # ID of the parameter struct type. If a named parameter list was specified in the method - # declaration (rather than a single struct parameter type) then a corresponding struct type is - # auto-generated. Such an auto-generated type will not be listed in the interface's - # `nestedNodes` and its `scopeId` will be zero -- it is completely detached from the namespace. - # (Awkwardly, it does of course inherit generic parameters from the method's scope, which makes - # this a situation where you can't just climb the scope chain to find where a particular - # generic parameter was introduced. Making the `scopeId` zero was a mistake.) - - paramBrand @5 :Brand; - # Brand of param struct type. - - resultStructType @3 :Id; - # ID of the return struct type; similar to `paramStructType`. - - resultBrand @6 :Brand; - # Brand of result struct type. - - annotations @4 :List(Annotation); -} - -struct Type { - # Represents a type expression. - - union { - # The ordinals intentionally match those of Value. - - void @0 :Void; - bool @1 :Void; - int8 @2 :Void; - int16 @3 :Void; - int32 @4 :Void; - int64 @5 :Void; - uint8 @6 :Void; - uint16 @7 :Void; - uint32 @8 :Void; - uint64 @9 :Void; - float32 @10 :Void; - float64 @11 :Void; - text @12 :Void; - data @13 :Void; - - list :group { - elementType @14 :Type; - } - - enum :group { - typeId @15 :Id; - brand @21 :Brand; - } - struct :group { - typeId @16 :Id; - brand @22 :Brand; - } - interface :group { - typeId @17 :Id; - brand @23 :Brand; - } - - anyPointer :union { - unconstrained :union { - # A regular AnyPointer. - # - # The name "unconstrained" means as opposed to constraining it to match a type parameter. - # In retrospect this name is probably a poor choice given that it may still be constrained - # to be a struct, list, or capability. - - anyKind @18 :Void; # truly AnyPointer - struct @25 :Void; # AnyStruct - list @26 :Void; # AnyList - capability @27 :Void; # Capability - } - - parameter :group { - # This is actually a reference to a type parameter defined within this scope. - - scopeId @19 :Id; - # ID of the generic type whose parameter we're referencing. This should be a parent of the - # current scope. - - parameterIndex @20 :UInt16; - # Index of the parameter within the generic type's parameter list. - } - - implicitMethodParameter :group { - # This is actually a reference to an implicit (generic) parameter of a method. The only - # legal context for this type to appear is inside Method.paramBrand or Method.resultBrand. - - parameterIndex @24 :UInt16; - } - } - } -} - -struct Brand { - # Specifies bindings for parameters of generics. Since these bindings turn a generic into a - # non-generic, we call it the "brand". - - scopes @0 :List(Scope); - # For each of the target type and each of its parent scopes, a parameterization may be included - # in this list. If no parameterization is included for a particular relevant scope, then either - # that scope has no parameters or all parameters should be considered to be `AnyPointer`. - - struct Scope { - scopeId @0 :Id; - # ID of the scope to which these params apply. - - union { - bind @1 :List(Binding); - # List of parameter bindings. - - inherit @2 :Void; - # The place where this Brand appears is actually within this scope or a sub-scope, - # and the bindings for this scope should be inherited from the reference point. - } - } - - struct Binding { - union { - unbound @0 :Void; - type @1 :Type; - - # TODO(someday): Allow non-type parameters? Unsure if useful. - } - } -} - -struct Value { - # Represents a value, e.g. a field default value, constant value, or annotation value. - - union { - # The ordinals intentionally match those of Type. - - void @0 :Void; - bool @1 :Bool; - int8 @2 :Int8; - int16 @3 :Int16; - int32 @4 :Int32; - int64 @5 :Int64; - uint8 @6 :UInt8; - uint16 @7 :UInt16; - uint32 @8 :UInt32; - uint64 @9 :UInt64; - float32 @10 :Float32; - float64 @11 :Float64; - text @12 :Text; - data @13 :Data; - - list @14 :AnyPointer; - - enum @15 :UInt16; - struct @16 :AnyPointer; - - interface @17 :Void; - # The only interface value that can be represented statically is "null", whose methods always - # throw exceptions. - - anyPointer @18 :AnyPointer; - } -} - -struct Annotation { - # Describes an annotation applied to a declaration. Note AnnotationNode describes the - # annotation's declaration, while this describes a use of the annotation. - - id @0 :Id; - # ID of the annotation node. - - brand @2 :Brand; - # Brand of the annotation. - # - # Note that the annotation itself is not allowed to be parameterized, but its scope might be. - - value @1 :Value; -} - -enum ElementSize { - # Possible element sizes for encoded lists. These correspond exactly to the possible values of - # the 3-bit element size component of a list pointer. - - empty @0; # aka "void", but that's a keyword. - bit @1; - byte @2; - twoBytes @3; - fourBytes @4; - eightBytes @5; - pointer @6; - inlineComposite @7; -} - -struct CapnpVersion { - major @0 :UInt16; - minor @1 :UInt8; - micro @2 :UInt8; -} - -struct CodeGeneratorRequest { - capnpVersion @2 :CapnpVersion; - # Version of the `capnp` executable. Generally, code generators should ignore this, but the code - # generators that ship with `capnp` itself will print a warning if this mismatches since that - # probably indicates something is misconfigured. - # - # The first version of 'capnp' to set this was 0.6.0. So, if it's missing, the compiler version - # is older than that. - - nodes @0 :List(Node); - # All nodes parsed by the compiler, including for the files on the command line and their - # imports. - - requestedFiles @1 :List(RequestedFile); - # Files which were listed on the command line. - - struct RequestedFile { - id @0 :Id; - # ID of the file. - - filename @1 :Text; - # Name of the file as it appeared on the command-line (minus the src-prefix). You may use - # this to decide where to write the output. - - imports @2 :List(Import); - # List of all imported paths seen in this file. - - struct Import { - id @0 :Id; - # ID of the imported file. - - name @1 :Text; - # Name which *this* file used to refer to the foreign file. This may be a relative name. - # This information is provided because it might be useful for code generation, e.g. to - # generate #include directives in C++. We don't put this in Node.file because this - # information is only meaningful at compile time anyway. - # - # (On Zooko's triangle, this is the import's petname according to the importing file.) - } - } -} diff --git a/phonelibs/capnp-cpp/include/capnp/schema.capnp.h b/phonelibs/capnp-cpp/include/capnp/schema.capnp.h deleted file mode 100644 index 1f116c9f8fe7af..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/schema.capnp.h +++ /dev/null @@ -1,7861 +0,0 @@ -// Generated by Cap'n Proto compiler, DO NOT EDIT -// source: schema.capnp - -#ifndef CAPNP_INCLUDED_a93fc509624c72d9_ -#define CAPNP_INCLUDED_a93fc509624c72d9_ - -#include - -#if CAPNP_VERSION != 6001 -#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." -#endif - - -namespace capnp { -namespace schemas { - -CAPNP_DECLARE_SCHEMA(e682ab4cf923a417); -CAPNP_DECLARE_SCHEMA(b9521bccf10fa3b1); -CAPNP_DECLARE_SCHEMA(debf55bbfa0fc242); -CAPNP_DECLARE_SCHEMA(9ea0b19b37fb4435); -CAPNP_DECLARE_SCHEMA(b54ab3364333f598); -CAPNP_DECLARE_SCHEMA(e82753cff0c2218f); -CAPNP_DECLARE_SCHEMA(b18aa5ac7a0d9420); -CAPNP_DECLARE_SCHEMA(ec1619d4400a0290); -CAPNP_DECLARE_SCHEMA(9aad50a41f4af45f); -CAPNP_DECLARE_SCHEMA(97b14cbe7cfec712); -CAPNP_DECLARE_SCHEMA(c42305476bb4746f); -CAPNP_DECLARE_SCHEMA(cafccddb68db1d11); -CAPNP_DECLARE_SCHEMA(bb90d5c287870be6); -CAPNP_DECLARE_SCHEMA(978a7cebdc549a4d); -CAPNP_DECLARE_SCHEMA(a9962a9ed0a4d7f8); -CAPNP_DECLARE_SCHEMA(9500cce23b334d80); -CAPNP_DECLARE_SCHEMA(d07378ede1f9cc60); -CAPNP_DECLARE_SCHEMA(87e739250a60ea97); -CAPNP_DECLARE_SCHEMA(9e0e78711a7f87a9); -CAPNP_DECLARE_SCHEMA(ac3a6f60ef4cc6d3); -CAPNP_DECLARE_SCHEMA(ed8bca69f7fb0cbf); -CAPNP_DECLARE_SCHEMA(c2573fe8a23e49f1); -CAPNP_DECLARE_SCHEMA(8e3b5f79fe593656); -CAPNP_DECLARE_SCHEMA(9dd1f724f4614a85); -CAPNP_DECLARE_SCHEMA(baefc9120c56e274); -CAPNP_DECLARE_SCHEMA(903455f06065422b); -CAPNP_DECLARE_SCHEMA(abd73485a9636bc9); -CAPNP_DECLARE_SCHEMA(c863cd16969ee7fc); -CAPNP_DECLARE_SCHEMA(ce23dcd2d7b00c9b); -CAPNP_DECLARE_SCHEMA(f1c8950dab257542); -CAPNP_DECLARE_SCHEMA(d1958f7dba521926); -enum class ElementSize_d1958f7dba521926: uint16_t { - EMPTY, - BIT, - BYTE, - TWO_BYTES, - FOUR_BYTES, - EIGHT_BYTES, - POINTER, - INLINE_COMPOSITE, -}; -CAPNP_DECLARE_ENUM(ElementSize, d1958f7dba521926); -CAPNP_DECLARE_SCHEMA(d85d305b7d839963); -CAPNP_DECLARE_SCHEMA(bfc546f6210ad7ce); -CAPNP_DECLARE_SCHEMA(cfea0eb02e810062); -CAPNP_DECLARE_SCHEMA(ae504193122357e5); - -} // namespace schemas -} // namespace capnp - -namespace capnp { -namespace schema { - -struct Node { - Node() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - FILE, - STRUCT, - ENUM, - INTERFACE, - CONST, - ANNOTATION, - }; - struct Parameter; - struct NestedNode; - struct Struct; - struct Enum; - struct Interface; - struct Const; - struct Annotation; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(e682ab4cf923a417, 5, 6) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Node::Parameter { - Parameter() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(b9521bccf10fa3b1, 0, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Node::NestedNode { - NestedNode() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(debf55bbfa0fc242, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Node::Struct { - Struct() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9ea0b19b37fb4435, 5, 6) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Node::Enum { - Enum() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(b54ab3364333f598, 5, 6) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Node::Interface { - Interface() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(e82753cff0c2218f, 5, 6) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Node::Const { - Const() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(b18aa5ac7a0d9420, 5, 6) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Node::Annotation { - Annotation() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(ec1619d4400a0290, 5, 6) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Field { - Field() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - SLOT, - GROUP, - }; - static constexpr ::uint16_t NO_DISCRIMINANT = 65535u; - struct Slot; - struct Group; - struct Ordinal; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9aad50a41f4af45f, 3, 4) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Field::Slot { - Slot() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(c42305476bb4746f, 3, 4) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Field::Group { - Group() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(cafccddb68db1d11, 3, 4) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Field::Ordinal { - Ordinal() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - IMPLICIT, - EXPLICIT, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(bb90d5c287870be6, 3, 4) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Enumerant { - Enumerant() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(978a7cebdc549a4d, 1, 2) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Superclass { - Superclass() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(a9962a9ed0a4d7f8, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Method { - Method() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9500cce23b334d80, 3, 5) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Type { - Type() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - VOID, - BOOL, - INT8, - INT16, - INT32, - INT64, - UINT8, - UINT16, - UINT32, - UINT64, - FLOAT32, - FLOAT64, - TEXT, - DATA, - LIST, - ENUM, - STRUCT, - INTERFACE, - ANY_POINTER, - }; - struct List; - struct Enum; - struct Struct; - struct Interface; - struct AnyPointer; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d07378ede1f9cc60, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Type::List { - List() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(87e739250a60ea97, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Type::Enum { - Enum() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9e0e78711a7f87a9, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Type::Struct { - Struct() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(ac3a6f60ef4cc6d3, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Type::Interface { - Interface() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(ed8bca69f7fb0cbf, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Type::AnyPointer { - AnyPointer() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - UNCONSTRAINED, - PARAMETER, - IMPLICIT_METHOD_PARAMETER, - }; - struct Unconstrained; - struct Parameter; - struct ImplicitMethodParameter; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(c2573fe8a23e49f1, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Type::AnyPointer::Unconstrained { - Unconstrained() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - ANY_KIND, - STRUCT, - LIST, - CAPABILITY, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(8e3b5f79fe593656, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Type::AnyPointer::Parameter { - Parameter() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(9dd1f724f4614a85, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Type::AnyPointer::ImplicitMethodParameter { - ImplicitMethodParameter() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(baefc9120c56e274, 3, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Brand { - Brand() = delete; - - class Reader; - class Builder; - class Pipeline; - struct Scope; - struct Binding; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(903455f06065422b, 0, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Brand::Scope { - Scope() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - BIND, - INHERIT, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(abd73485a9636bc9, 2, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Brand::Binding { - Binding() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - UNBOUND, - TYPE, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(c863cd16969ee7fc, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Value { - Value() = delete; - - class Reader; - class Builder; - class Pipeline; - enum Which: uint16_t { - VOID, - BOOL, - INT8, - INT16, - INT32, - INT64, - UINT8, - UINT16, - UINT32, - UINT64, - FLOAT32, - FLOAT64, - TEXT, - DATA, - LIST, - ENUM, - STRUCT, - INTERFACE, - ANY_POINTER, - }; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(ce23dcd2d7b00c9b, 2, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct Annotation { - Annotation() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(f1c8950dab257542, 1, 2) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -typedef ::capnp::schemas::ElementSize_d1958f7dba521926 ElementSize; - -struct CapnpVersion { - CapnpVersion() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(d85d305b7d839963, 1, 0) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct CodeGeneratorRequest { - CodeGeneratorRequest() = delete; - - class Reader; - class Builder; - class Pipeline; - struct RequestedFile; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(bfc546f6210ad7ce, 0, 3) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct CodeGeneratorRequest::RequestedFile { - RequestedFile() = delete; - - class Reader; - class Builder; - class Pipeline; - struct Import; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(cfea0eb02e810062, 1, 2) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -struct CodeGeneratorRequest::RequestedFile::Import { - Import() = delete; - - class Reader; - class Builder; - class Pipeline; - - struct _capnpPrivate { - CAPNP_DECLARE_STRUCT_HEADER(ae504193122357e5, 1, 1) - #if !CAPNP_LITE - static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; } - #endif // !CAPNP_LITE - }; -}; - -// ======================================================================================= - -class Node::Reader { -public: - typedef Node Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline ::uint64_t getId() const; - - inline bool hasDisplayName() const; - inline ::capnp::Text::Reader getDisplayName() const; - - inline ::uint32_t getDisplayNamePrefixLength() const; - - inline ::uint64_t getScopeId() const; - - inline bool hasNestedNodes() const; - inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader getNestedNodes() const; - - inline bool hasAnnotations() const; - inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() const; - - inline bool isFile() const; - inline ::capnp::Void getFile() const; - - inline bool isStruct() const; - inline typename Struct::Reader getStruct() const; - - inline bool isEnum() const; - inline typename Enum::Reader getEnum() const; - - inline bool isInterface() const; - inline typename Interface::Reader getInterface() const; - - inline bool isConst() const; - inline typename Const::Reader getConst() const; - - inline bool isAnnotation() const; - inline typename Annotation::Reader getAnnotation() const; - - inline bool hasParameters() const; - inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader getParameters() const; - - inline bool getIsGeneric() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::Builder { -public: - typedef Node Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline ::uint64_t getId(); - inline void setId( ::uint64_t value); - - inline bool hasDisplayName(); - inline ::capnp::Text::Builder getDisplayName(); - inline void setDisplayName( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initDisplayName(unsigned int size); - inline void adoptDisplayName(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownDisplayName(); - - inline ::uint32_t getDisplayNamePrefixLength(); - inline void setDisplayNamePrefixLength( ::uint32_t value); - - inline ::uint64_t getScopeId(); - inline void setScopeId( ::uint64_t value); - - inline bool hasNestedNodes(); - inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder getNestedNodes(); - inline void setNestedNodes( ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader value); - inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder initNestedNodes(unsigned int size); - inline void adoptNestedNodes(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>> disownNestedNodes(); - - inline bool hasAnnotations(); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); - inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); - inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); - - inline bool isFile(); - inline ::capnp::Void getFile(); - inline void setFile( ::capnp::Void value = ::capnp::VOID); - - inline bool isStruct(); - inline typename Struct::Builder getStruct(); - inline typename Struct::Builder initStruct(); - - inline bool isEnum(); - inline typename Enum::Builder getEnum(); - inline typename Enum::Builder initEnum(); - - inline bool isInterface(); - inline typename Interface::Builder getInterface(); - inline typename Interface::Builder initInterface(); - - inline bool isConst(); - inline typename Const::Builder getConst(); - inline typename Const::Builder initConst(); - - inline bool isAnnotation(); - inline typename Annotation::Builder getAnnotation(); - inline typename Annotation::Builder initAnnotation(); - - inline bool hasParameters(); - inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder getParameters(); - inline void setParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value); - inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder initParameters(unsigned int size); - inline void adoptParameters(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> disownParameters(); - - inline bool getIsGeneric(); - inline void setIsGeneric(bool value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::Pipeline { -public: - typedef Node Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Node::Parameter::Reader { -public: - typedef Parameter Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasName() const; - inline ::capnp::Text::Reader getName() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::Parameter::Builder { -public: - typedef Parameter Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasName(); - inline ::capnp::Text::Builder getName(); - inline void setName( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initName(unsigned int size); - inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownName(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::Parameter::Pipeline { -public: - typedef Parameter Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Node::NestedNode::Reader { -public: - typedef NestedNode Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasName() const; - inline ::capnp::Text::Reader getName() const; - - inline ::uint64_t getId() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::NestedNode::Builder { -public: - typedef NestedNode Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasName(); - inline ::capnp::Text::Builder getName(); - inline void setName( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initName(unsigned int size); - inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownName(); - - inline ::uint64_t getId(); - inline void setId( ::uint64_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::NestedNode::Pipeline { -public: - typedef NestedNode Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Node::Struct::Reader { -public: - typedef Struct Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint16_t getDataWordCount() const; - - inline ::uint16_t getPointerCount() const; - - inline ::capnp::schema::ElementSize getPreferredListEncoding() const; - - inline bool getIsGroup() const; - - inline ::uint16_t getDiscriminantCount() const; - - inline ::uint32_t getDiscriminantOffset() const; - - inline bool hasFields() const; - inline ::capnp::List< ::capnp::schema::Field>::Reader getFields() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::Struct::Builder { -public: - typedef Struct Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint16_t getDataWordCount(); - inline void setDataWordCount( ::uint16_t value); - - inline ::uint16_t getPointerCount(); - inline void setPointerCount( ::uint16_t value); - - inline ::capnp::schema::ElementSize getPreferredListEncoding(); - inline void setPreferredListEncoding( ::capnp::schema::ElementSize value); - - inline bool getIsGroup(); - inline void setIsGroup(bool value); - - inline ::uint16_t getDiscriminantCount(); - inline void setDiscriminantCount( ::uint16_t value); - - inline ::uint32_t getDiscriminantOffset(); - inline void setDiscriminantOffset( ::uint32_t value); - - inline bool hasFields(); - inline ::capnp::List< ::capnp::schema::Field>::Builder getFields(); - inline void setFields( ::capnp::List< ::capnp::schema::Field>::Reader value); - inline ::capnp::List< ::capnp::schema::Field>::Builder initFields(unsigned int size); - inline void adoptFields(::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>> disownFields(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::Struct::Pipeline { -public: - typedef Struct Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Node::Enum::Reader { -public: - typedef Enum Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasEnumerants() const; - inline ::capnp::List< ::capnp::schema::Enumerant>::Reader getEnumerants() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::Enum::Builder { -public: - typedef Enum Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasEnumerants(); - inline ::capnp::List< ::capnp::schema::Enumerant>::Builder getEnumerants(); - inline void setEnumerants( ::capnp::List< ::capnp::schema::Enumerant>::Reader value); - inline ::capnp::List< ::capnp::schema::Enumerant>::Builder initEnumerants(unsigned int size); - inline void adoptEnumerants(::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>> disownEnumerants(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::Enum::Pipeline { -public: - typedef Enum Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Node::Interface::Reader { -public: - typedef Interface Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasMethods() const; - inline ::capnp::List< ::capnp::schema::Method>::Reader getMethods() const; - - inline bool hasSuperclasses() const; - inline ::capnp::List< ::capnp::schema::Superclass>::Reader getSuperclasses() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::Interface::Builder { -public: - typedef Interface Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasMethods(); - inline ::capnp::List< ::capnp::schema::Method>::Builder getMethods(); - inline void setMethods( ::capnp::List< ::capnp::schema::Method>::Reader value); - inline ::capnp::List< ::capnp::schema::Method>::Builder initMethods(unsigned int size); - inline void adoptMethods(::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>> disownMethods(); - - inline bool hasSuperclasses(); - inline ::capnp::List< ::capnp::schema::Superclass>::Builder getSuperclasses(); - inline void setSuperclasses( ::capnp::List< ::capnp::schema::Superclass>::Reader value); - inline ::capnp::List< ::capnp::schema::Superclass>::Builder initSuperclasses(unsigned int size); - inline void adoptSuperclasses(::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>> disownSuperclasses(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::Interface::Pipeline { -public: - typedef Interface Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Node::Const::Reader { -public: - typedef Const Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasType() const; - inline ::capnp::schema::Type::Reader getType() const; - - inline bool hasValue() const; - inline ::capnp::schema::Value::Reader getValue() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::Const::Builder { -public: - typedef Const Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasType(); - inline ::capnp::schema::Type::Builder getType(); - inline void setType( ::capnp::schema::Type::Reader value); - inline ::capnp::schema::Type::Builder initType(); - inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); - inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); - - inline bool hasValue(); - inline ::capnp::schema::Value::Builder getValue(); - inline void setValue( ::capnp::schema::Value::Reader value); - inline ::capnp::schema::Value::Builder initValue(); - inline void adoptValue(::capnp::Orphan< ::capnp::schema::Value>&& value); - inline ::capnp::Orphan< ::capnp::schema::Value> disownValue(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::Const::Pipeline { -public: - typedef Const Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Type::Pipeline getType(); - inline ::capnp::schema::Value::Pipeline getValue(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Node::Annotation::Reader { -public: - typedef Annotation Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasType() const; - inline ::capnp::schema::Type::Reader getType() const; - - inline bool getTargetsFile() const; - - inline bool getTargetsConst() const; - - inline bool getTargetsEnum() const; - - inline bool getTargetsEnumerant() const; - - inline bool getTargetsStruct() const; - - inline bool getTargetsField() const; - - inline bool getTargetsUnion() const; - - inline bool getTargetsGroup() const; - - inline bool getTargetsInterface() const; - - inline bool getTargetsMethod() const; - - inline bool getTargetsParam() const; - - inline bool getTargetsAnnotation() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Node::Annotation::Builder { -public: - typedef Annotation Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasType(); - inline ::capnp::schema::Type::Builder getType(); - inline void setType( ::capnp::schema::Type::Reader value); - inline ::capnp::schema::Type::Builder initType(); - inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); - inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); - - inline bool getTargetsFile(); - inline void setTargetsFile(bool value); - - inline bool getTargetsConst(); - inline void setTargetsConst(bool value); - - inline bool getTargetsEnum(); - inline void setTargetsEnum(bool value); - - inline bool getTargetsEnumerant(); - inline void setTargetsEnumerant(bool value); - - inline bool getTargetsStruct(); - inline void setTargetsStruct(bool value); - - inline bool getTargetsField(); - inline void setTargetsField(bool value); - - inline bool getTargetsUnion(); - inline void setTargetsUnion(bool value); - - inline bool getTargetsGroup(); - inline void setTargetsGroup(bool value); - - inline bool getTargetsInterface(); - inline void setTargetsInterface(bool value); - - inline bool getTargetsMethod(); - inline void setTargetsMethod(bool value); - - inline bool getTargetsParam(); - inline void setTargetsParam(bool value); - - inline bool getTargetsAnnotation(); - inline void setTargetsAnnotation(bool value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Node::Annotation::Pipeline { -public: - typedef Annotation Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Type::Pipeline getType(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Field::Reader { -public: - typedef Field Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool hasName() const; - inline ::capnp::Text::Reader getName() const; - - inline ::uint16_t getCodeOrder() const; - - inline bool hasAnnotations() const; - inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() const; - - inline ::uint16_t getDiscriminantValue() const; - - inline bool isSlot() const; - inline typename Slot::Reader getSlot() const; - - inline bool isGroup() const; - inline typename Group::Reader getGroup() const; - - inline typename Ordinal::Reader getOrdinal() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Field::Builder { -public: - typedef Field Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool hasName(); - inline ::capnp::Text::Builder getName(); - inline void setName( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initName(unsigned int size); - inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownName(); - - inline ::uint16_t getCodeOrder(); - inline void setCodeOrder( ::uint16_t value); - - inline bool hasAnnotations(); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); - inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); - inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); - - inline ::uint16_t getDiscriminantValue(); - inline void setDiscriminantValue( ::uint16_t value); - - inline bool isSlot(); - inline typename Slot::Builder getSlot(); - inline typename Slot::Builder initSlot(); - - inline bool isGroup(); - inline typename Group::Builder getGroup(); - inline typename Group::Builder initGroup(); - - inline typename Ordinal::Builder getOrdinal(); - inline typename Ordinal::Builder initOrdinal(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Field::Pipeline { -public: - typedef Field Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline typename Ordinal::Pipeline getOrdinal(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Field::Slot::Reader { -public: - typedef Slot Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint32_t getOffset() const; - - inline bool hasType() const; - inline ::capnp::schema::Type::Reader getType() const; - - inline bool hasDefaultValue() const; - inline ::capnp::schema::Value::Reader getDefaultValue() const; - - inline bool getHadExplicitDefault() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Field::Slot::Builder { -public: - typedef Slot Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint32_t getOffset(); - inline void setOffset( ::uint32_t value); - - inline bool hasType(); - inline ::capnp::schema::Type::Builder getType(); - inline void setType( ::capnp::schema::Type::Reader value); - inline ::capnp::schema::Type::Builder initType(); - inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); - inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); - - inline bool hasDefaultValue(); - inline ::capnp::schema::Value::Builder getDefaultValue(); - inline void setDefaultValue( ::capnp::schema::Value::Reader value); - inline ::capnp::schema::Value::Builder initDefaultValue(); - inline void adoptDefaultValue(::capnp::Orphan< ::capnp::schema::Value>&& value); - inline ::capnp::Orphan< ::capnp::schema::Value> disownDefaultValue(); - - inline bool getHadExplicitDefault(); - inline void setHadExplicitDefault(bool value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Field::Slot::Pipeline { -public: - typedef Slot Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Type::Pipeline getType(); - inline ::capnp::schema::Value::Pipeline getDefaultValue(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Field::Group::Reader { -public: - typedef Group Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Field::Group::Builder { -public: - typedef Group Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId(); - inline void setTypeId( ::uint64_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Field::Group::Pipeline { -public: - typedef Group Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Field::Ordinal::Reader { -public: - typedef Ordinal Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isImplicit() const; - inline ::capnp::Void getImplicit() const; - - inline bool isExplicit() const; - inline ::uint16_t getExplicit() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Field::Ordinal::Builder { -public: - typedef Ordinal Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isImplicit(); - inline ::capnp::Void getImplicit(); - inline void setImplicit( ::capnp::Void value = ::capnp::VOID); - - inline bool isExplicit(); - inline ::uint16_t getExplicit(); - inline void setExplicit( ::uint16_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Field::Ordinal::Pipeline { -public: - typedef Ordinal Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Enumerant::Reader { -public: - typedef Enumerant Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasName() const; - inline ::capnp::Text::Reader getName() const; - - inline ::uint16_t getCodeOrder() const; - - inline bool hasAnnotations() const; - inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Enumerant::Builder { -public: - typedef Enumerant Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasName(); - inline ::capnp::Text::Builder getName(); - inline void setName( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initName(unsigned int size); - inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownName(); - - inline ::uint16_t getCodeOrder(); - inline void setCodeOrder( ::uint16_t value); - - inline bool hasAnnotations(); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); - inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); - inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Enumerant::Pipeline { -public: - typedef Enumerant Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Superclass::Reader { -public: - typedef Superclass Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getId() const; - - inline bool hasBrand() const; - inline ::capnp::schema::Brand::Reader getBrand() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Superclass::Builder { -public: - typedef Superclass Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getId(); - inline void setId( ::uint64_t value); - - inline bool hasBrand(); - inline ::capnp::schema::Brand::Builder getBrand(); - inline void setBrand( ::capnp::schema::Brand::Reader value); - inline ::capnp::schema::Brand::Builder initBrand(); - inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); - inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Superclass::Pipeline { -public: - typedef Superclass Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Brand::Pipeline getBrand(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Method::Reader { -public: - typedef Method Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasName() const; - inline ::capnp::Text::Reader getName() const; - - inline ::uint16_t getCodeOrder() const; - - inline ::uint64_t getParamStructType() const; - - inline ::uint64_t getResultStructType() const; - - inline bool hasAnnotations() const; - inline ::capnp::List< ::capnp::schema::Annotation>::Reader getAnnotations() const; - - inline bool hasParamBrand() const; - inline ::capnp::schema::Brand::Reader getParamBrand() const; - - inline bool hasResultBrand() const; - inline ::capnp::schema::Brand::Reader getResultBrand() const; - - inline bool hasImplicitParameters() const; - inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader getImplicitParameters() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Method::Builder { -public: - typedef Method Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasName(); - inline ::capnp::Text::Builder getName(); - inline void setName( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initName(unsigned int size); - inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownName(); - - inline ::uint16_t getCodeOrder(); - inline void setCodeOrder( ::uint16_t value); - - inline ::uint64_t getParamStructType(); - inline void setParamStructType( ::uint64_t value); - - inline ::uint64_t getResultStructType(); - inline void setResultStructType( ::uint64_t value); - - inline bool hasAnnotations(); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder getAnnotations(); - inline void setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value); - inline ::capnp::List< ::capnp::schema::Annotation>::Builder initAnnotations(unsigned int size); - inline void adoptAnnotations(::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> disownAnnotations(); - - inline bool hasParamBrand(); - inline ::capnp::schema::Brand::Builder getParamBrand(); - inline void setParamBrand( ::capnp::schema::Brand::Reader value); - inline ::capnp::schema::Brand::Builder initParamBrand(); - inline void adoptParamBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); - inline ::capnp::Orphan< ::capnp::schema::Brand> disownParamBrand(); - - inline bool hasResultBrand(); - inline ::capnp::schema::Brand::Builder getResultBrand(); - inline void setResultBrand( ::capnp::schema::Brand::Reader value); - inline ::capnp::schema::Brand::Builder initResultBrand(); - inline void adoptResultBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); - inline ::capnp::Orphan< ::capnp::schema::Brand> disownResultBrand(); - - inline bool hasImplicitParameters(); - inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder getImplicitParameters(); - inline void setImplicitParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value); - inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder initImplicitParameters(unsigned int size); - inline void adoptImplicitParameters(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> disownImplicitParameters(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Method::Pipeline { -public: - typedef Method Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Brand::Pipeline getParamBrand(); - inline ::capnp::schema::Brand::Pipeline getResultBrand(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::Reader { -public: - typedef Type Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isVoid() const; - inline ::capnp::Void getVoid() const; - - inline bool isBool() const; - inline ::capnp::Void getBool() const; - - inline bool isInt8() const; - inline ::capnp::Void getInt8() const; - - inline bool isInt16() const; - inline ::capnp::Void getInt16() const; - - inline bool isInt32() const; - inline ::capnp::Void getInt32() const; - - inline bool isInt64() const; - inline ::capnp::Void getInt64() const; - - inline bool isUint8() const; - inline ::capnp::Void getUint8() const; - - inline bool isUint16() const; - inline ::capnp::Void getUint16() const; - - inline bool isUint32() const; - inline ::capnp::Void getUint32() const; - - inline bool isUint64() const; - inline ::capnp::Void getUint64() const; - - inline bool isFloat32() const; - inline ::capnp::Void getFloat32() const; - - inline bool isFloat64() const; - inline ::capnp::Void getFloat64() const; - - inline bool isText() const; - inline ::capnp::Void getText() const; - - inline bool isData() const; - inline ::capnp::Void getData() const; - - inline bool isList() const; - inline typename List::Reader getList() const; - - inline bool isEnum() const; - inline typename Enum::Reader getEnum() const; - - inline bool isStruct() const; - inline typename Struct::Reader getStruct() const; - - inline bool isInterface() const; - inline typename Interface::Reader getInterface() const; - - inline bool isAnyPointer() const; - inline typename AnyPointer::Reader getAnyPointer() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::Builder { -public: - typedef Type Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isVoid(); - inline ::capnp::Void getVoid(); - inline void setVoid( ::capnp::Void value = ::capnp::VOID); - - inline bool isBool(); - inline ::capnp::Void getBool(); - inline void setBool( ::capnp::Void value = ::capnp::VOID); - - inline bool isInt8(); - inline ::capnp::Void getInt8(); - inline void setInt8( ::capnp::Void value = ::capnp::VOID); - - inline bool isInt16(); - inline ::capnp::Void getInt16(); - inline void setInt16( ::capnp::Void value = ::capnp::VOID); - - inline bool isInt32(); - inline ::capnp::Void getInt32(); - inline void setInt32( ::capnp::Void value = ::capnp::VOID); - - inline bool isInt64(); - inline ::capnp::Void getInt64(); - inline void setInt64( ::capnp::Void value = ::capnp::VOID); - - inline bool isUint8(); - inline ::capnp::Void getUint8(); - inline void setUint8( ::capnp::Void value = ::capnp::VOID); - - inline bool isUint16(); - inline ::capnp::Void getUint16(); - inline void setUint16( ::capnp::Void value = ::capnp::VOID); - - inline bool isUint32(); - inline ::capnp::Void getUint32(); - inline void setUint32( ::capnp::Void value = ::capnp::VOID); - - inline bool isUint64(); - inline ::capnp::Void getUint64(); - inline void setUint64( ::capnp::Void value = ::capnp::VOID); - - inline bool isFloat32(); - inline ::capnp::Void getFloat32(); - inline void setFloat32( ::capnp::Void value = ::capnp::VOID); - - inline bool isFloat64(); - inline ::capnp::Void getFloat64(); - inline void setFloat64( ::capnp::Void value = ::capnp::VOID); - - inline bool isText(); - inline ::capnp::Void getText(); - inline void setText( ::capnp::Void value = ::capnp::VOID); - - inline bool isData(); - inline ::capnp::Void getData(); - inline void setData( ::capnp::Void value = ::capnp::VOID); - - inline bool isList(); - inline typename List::Builder getList(); - inline typename List::Builder initList(); - - inline bool isEnum(); - inline typename Enum::Builder getEnum(); - inline typename Enum::Builder initEnum(); - - inline bool isStruct(); - inline typename Struct::Builder getStruct(); - inline typename Struct::Builder initStruct(); - - inline bool isInterface(); - inline typename Interface::Builder getInterface(); - inline typename Interface::Builder initInterface(); - - inline bool isAnyPointer(); - inline typename AnyPointer::Builder getAnyPointer(); - inline typename AnyPointer::Builder initAnyPointer(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::Pipeline { -public: - typedef Type Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::List::Reader { -public: - typedef List Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasElementType() const; - inline ::capnp::schema::Type::Reader getElementType() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::List::Builder { -public: - typedef List Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasElementType(); - inline ::capnp::schema::Type::Builder getElementType(); - inline void setElementType( ::capnp::schema::Type::Reader value); - inline ::capnp::schema::Type::Builder initElementType(); - inline void adoptElementType(::capnp::Orphan< ::capnp::schema::Type>&& value); - inline ::capnp::Orphan< ::capnp::schema::Type> disownElementType(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::List::Pipeline { -public: - typedef List Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Type::Pipeline getElementType(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::Enum::Reader { -public: - typedef Enum Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId() const; - - inline bool hasBrand() const; - inline ::capnp::schema::Brand::Reader getBrand() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::Enum::Builder { -public: - typedef Enum Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId(); - inline void setTypeId( ::uint64_t value); - - inline bool hasBrand(); - inline ::capnp::schema::Brand::Builder getBrand(); - inline void setBrand( ::capnp::schema::Brand::Reader value); - inline ::capnp::schema::Brand::Builder initBrand(); - inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); - inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::Enum::Pipeline { -public: - typedef Enum Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Brand::Pipeline getBrand(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::Struct::Reader { -public: - typedef Struct Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId() const; - - inline bool hasBrand() const; - inline ::capnp::schema::Brand::Reader getBrand() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::Struct::Builder { -public: - typedef Struct Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId(); - inline void setTypeId( ::uint64_t value); - - inline bool hasBrand(); - inline ::capnp::schema::Brand::Builder getBrand(); - inline void setBrand( ::capnp::schema::Brand::Reader value); - inline ::capnp::schema::Brand::Builder initBrand(); - inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); - inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::Struct::Pipeline { -public: - typedef Struct Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Brand::Pipeline getBrand(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::Interface::Reader { -public: - typedef Interface Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId() const; - - inline bool hasBrand() const; - inline ::capnp::schema::Brand::Reader getBrand() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::Interface::Builder { -public: - typedef Interface Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getTypeId(); - inline void setTypeId( ::uint64_t value); - - inline bool hasBrand(); - inline ::capnp::schema::Brand::Builder getBrand(); - inline void setBrand( ::capnp::schema::Brand::Reader value); - inline ::capnp::schema::Brand::Builder initBrand(); - inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); - inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::Interface::Pipeline { -public: - typedef Interface Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Brand::Pipeline getBrand(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::AnyPointer::Reader { -public: - typedef AnyPointer Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isUnconstrained() const; - inline typename Unconstrained::Reader getUnconstrained() const; - - inline bool isParameter() const; - inline typename Parameter::Reader getParameter() const; - - inline bool isImplicitMethodParameter() const; - inline typename ImplicitMethodParameter::Reader getImplicitMethodParameter() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::AnyPointer::Builder { -public: - typedef AnyPointer Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isUnconstrained(); - inline typename Unconstrained::Builder getUnconstrained(); - inline typename Unconstrained::Builder initUnconstrained(); - - inline bool isParameter(); - inline typename Parameter::Builder getParameter(); - inline typename Parameter::Builder initParameter(); - - inline bool isImplicitMethodParameter(); - inline typename ImplicitMethodParameter::Builder getImplicitMethodParameter(); - inline typename ImplicitMethodParameter::Builder initImplicitMethodParameter(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::AnyPointer::Pipeline { -public: - typedef AnyPointer Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::AnyPointer::Unconstrained::Reader { -public: - typedef Unconstrained Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isAnyKind() const; - inline ::capnp::Void getAnyKind() const; - - inline bool isStruct() const; - inline ::capnp::Void getStruct() const; - - inline bool isList() const; - inline ::capnp::Void getList() const; - - inline bool isCapability() const; - inline ::capnp::Void getCapability() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::AnyPointer::Unconstrained::Builder { -public: - typedef Unconstrained Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isAnyKind(); - inline ::capnp::Void getAnyKind(); - inline void setAnyKind( ::capnp::Void value = ::capnp::VOID); - - inline bool isStruct(); - inline ::capnp::Void getStruct(); - inline void setStruct( ::capnp::Void value = ::capnp::VOID); - - inline bool isList(); - inline ::capnp::Void getList(); - inline void setList( ::capnp::Void value = ::capnp::VOID); - - inline bool isCapability(); - inline ::capnp::Void getCapability(); - inline void setCapability( ::capnp::Void value = ::capnp::VOID); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::AnyPointer::Unconstrained::Pipeline { -public: - typedef Unconstrained Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::AnyPointer::Parameter::Reader { -public: - typedef Parameter Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getScopeId() const; - - inline ::uint16_t getParameterIndex() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::AnyPointer::Parameter::Builder { -public: - typedef Parameter Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getScopeId(); - inline void setScopeId( ::uint64_t value); - - inline ::uint16_t getParameterIndex(); - inline void setParameterIndex( ::uint16_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::AnyPointer::Parameter::Pipeline { -public: - typedef Parameter Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Type::AnyPointer::ImplicitMethodParameter::Reader { -public: - typedef ImplicitMethodParameter Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint16_t getParameterIndex() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Type::AnyPointer::ImplicitMethodParameter::Builder { -public: - typedef ImplicitMethodParameter Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint16_t getParameterIndex(); - inline void setParameterIndex( ::uint16_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Type::AnyPointer::ImplicitMethodParameter::Pipeline { -public: - typedef ImplicitMethodParameter Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Brand::Reader { -public: - typedef Brand Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasScopes() const; - inline ::capnp::List< ::capnp::schema::Brand::Scope>::Reader getScopes() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Brand::Builder { -public: - typedef Brand Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasScopes(); - inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder getScopes(); - inline void setScopes( ::capnp::List< ::capnp::schema::Brand::Scope>::Reader value); - inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder initScopes(unsigned int size); - inline void adoptScopes(::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>> disownScopes(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Brand::Pipeline { -public: - typedef Brand Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Brand::Scope::Reader { -public: - typedef Scope Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline ::uint64_t getScopeId() const; - - inline bool isBind() const; - inline bool hasBind() const; - inline ::capnp::List< ::capnp::schema::Brand::Binding>::Reader getBind() const; - - inline bool isInherit() const; - inline ::capnp::Void getInherit() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Brand::Scope::Builder { -public: - typedef Scope Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline ::uint64_t getScopeId(); - inline void setScopeId( ::uint64_t value); - - inline bool isBind(); - inline bool hasBind(); - inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder getBind(); - inline void setBind( ::capnp::List< ::capnp::schema::Brand::Binding>::Reader value); - inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder initBind(unsigned int size); - inline void adoptBind(::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>> disownBind(); - - inline bool isInherit(); - inline ::capnp::Void getInherit(); - inline void setInherit( ::capnp::Void value = ::capnp::VOID); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Brand::Scope::Pipeline { -public: - typedef Scope Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Brand::Binding::Reader { -public: - typedef Binding Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isUnbound() const; - inline ::capnp::Void getUnbound() const; - - inline bool isType() const; - inline bool hasType() const; - inline ::capnp::schema::Type::Reader getType() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Brand::Binding::Builder { -public: - typedef Binding Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isUnbound(); - inline ::capnp::Void getUnbound(); - inline void setUnbound( ::capnp::Void value = ::capnp::VOID); - - inline bool isType(); - inline bool hasType(); - inline ::capnp::schema::Type::Builder getType(); - inline void setType( ::capnp::schema::Type::Reader value); - inline ::capnp::schema::Type::Builder initType(); - inline void adoptType(::capnp::Orphan< ::capnp::schema::Type>&& value); - inline ::capnp::Orphan< ::capnp::schema::Type> disownType(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Brand::Binding::Pipeline { -public: - typedef Binding Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Value::Reader { -public: - typedef Value Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline Which which() const; - inline bool isVoid() const; - inline ::capnp::Void getVoid() const; - - inline bool isBool() const; - inline bool getBool() const; - - inline bool isInt8() const; - inline ::int8_t getInt8() const; - - inline bool isInt16() const; - inline ::int16_t getInt16() const; - - inline bool isInt32() const; - inline ::int32_t getInt32() const; - - inline bool isInt64() const; - inline ::int64_t getInt64() const; - - inline bool isUint8() const; - inline ::uint8_t getUint8() const; - - inline bool isUint16() const; - inline ::uint16_t getUint16() const; - - inline bool isUint32() const; - inline ::uint32_t getUint32() const; - - inline bool isUint64() const; - inline ::uint64_t getUint64() const; - - inline bool isFloat32() const; - inline float getFloat32() const; - - inline bool isFloat64() const; - inline double getFloat64() const; - - inline bool isText() const; - inline bool hasText() const; - inline ::capnp::Text::Reader getText() const; - - inline bool isData() const; - inline bool hasData() const; - inline ::capnp::Data::Reader getData() const; - - inline bool isList() const; - inline bool hasList() const; - inline ::capnp::AnyPointer::Reader getList() const; - - inline bool isEnum() const; - inline ::uint16_t getEnum() const; - - inline bool isStruct() const; - inline bool hasStruct() const; - inline ::capnp::AnyPointer::Reader getStruct() const; - - inline bool isInterface() const; - inline ::capnp::Void getInterface() const; - - inline bool isAnyPointer() const; - inline bool hasAnyPointer() const; - inline ::capnp::AnyPointer::Reader getAnyPointer() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Value::Builder { -public: - typedef Value Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline Which which(); - inline bool isVoid(); - inline ::capnp::Void getVoid(); - inline void setVoid( ::capnp::Void value = ::capnp::VOID); - - inline bool isBool(); - inline bool getBool(); - inline void setBool(bool value); - - inline bool isInt8(); - inline ::int8_t getInt8(); - inline void setInt8( ::int8_t value); - - inline bool isInt16(); - inline ::int16_t getInt16(); - inline void setInt16( ::int16_t value); - - inline bool isInt32(); - inline ::int32_t getInt32(); - inline void setInt32( ::int32_t value); - - inline bool isInt64(); - inline ::int64_t getInt64(); - inline void setInt64( ::int64_t value); - - inline bool isUint8(); - inline ::uint8_t getUint8(); - inline void setUint8( ::uint8_t value); - - inline bool isUint16(); - inline ::uint16_t getUint16(); - inline void setUint16( ::uint16_t value); - - inline bool isUint32(); - inline ::uint32_t getUint32(); - inline void setUint32( ::uint32_t value); - - inline bool isUint64(); - inline ::uint64_t getUint64(); - inline void setUint64( ::uint64_t value); - - inline bool isFloat32(); - inline float getFloat32(); - inline void setFloat32(float value); - - inline bool isFloat64(); - inline double getFloat64(); - inline void setFloat64(double value); - - inline bool isText(); - inline bool hasText(); - inline ::capnp::Text::Builder getText(); - inline void setText( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initText(unsigned int size); - inline void adoptText(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownText(); - - inline bool isData(); - inline bool hasData(); - inline ::capnp::Data::Builder getData(); - inline void setData( ::capnp::Data::Reader value); - inline ::capnp::Data::Builder initData(unsigned int size); - inline void adoptData(::capnp::Orphan< ::capnp::Data>&& value); - inline ::capnp::Orphan< ::capnp::Data> disownData(); - - inline bool isList(); - inline bool hasList(); - inline ::capnp::AnyPointer::Builder getList(); - inline ::capnp::AnyPointer::Builder initList(); - - inline bool isEnum(); - inline ::uint16_t getEnum(); - inline void setEnum( ::uint16_t value); - - inline bool isStruct(); - inline bool hasStruct(); - inline ::capnp::AnyPointer::Builder getStruct(); - inline ::capnp::AnyPointer::Builder initStruct(); - - inline bool isInterface(); - inline ::capnp::Void getInterface(); - inline void setInterface( ::capnp::Void value = ::capnp::VOID); - - inline bool isAnyPointer(); - inline bool hasAnyPointer(); - inline ::capnp::AnyPointer::Builder getAnyPointer(); - inline ::capnp::AnyPointer::Builder initAnyPointer(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Value::Pipeline { -public: - typedef Value Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class Annotation::Reader { -public: - typedef Annotation Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getId() const; - - inline bool hasValue() const; - inline ::capnp::schema::Value::Reader getValue() const; - - inline bool hasBrand() const; - inline ::capnp::schema::Brand::Reader getBrand() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class Annotation::Builder { -public: - typedef Annotation Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getId(); - inline void setId( ::uint64_t value); - - inline bool hasValue(); - inline ::capnp::schema::Value::Builder getValue(); - inline void setValue( ::capnp::schema::Value::Reader value); - inline ::capnp::schema::Value::Builder initValue(); - inline void adoptValue(::capnp::Orphan< ::capnp::schema::Value>&& value); - inline ::capnp::Orphan< ::capnp::schema::Value> disownValue(); - - inline bool hasBrand(); - inline ::capnp::schema::Brand::Builder getBrand(); - inline void setBrand( ::capnp::schema::Brand::Reader value); - inline ::capnp::schema::Brand::Builder initBrand(); - inline void adoptBrand(::capnp::Orphan< ::capnp::schema::Brand>&& value); - inline ::capnp::Orphan< ::capnp::schema::Brand> disownBrand(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class Annotation::Pipeline { -public: - typedef Annotation Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::Value::Pipeline getValue(); - inline ::capnp::schema::Brand::Pipeline getBrand(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class CapnpVersion::Reader { -public: - typedef CapnpVersion Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint16_t getMajor() const; - - inline ::uint8_t getMinor() const; - - inline ::uint8_t getMicro() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class CapnpVersion::Builder { -public: - typedef CapnpVersion Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint16_t getMajor(); - inline void setMajor( ::uint16_t value); - - inline ::uint8_t getMinor(); - inline void setMinor( ::uint8_t value); - - inline ::uint8_t getMicro(); - inline void setMicro( ::uint8_t value); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class CapnpVersion::Pipeline { -public: - typedef CapnpVersion Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class CodeGeneratorRequest::Reader { -public: - typedef CodeGeneratorRequest Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline bool hasNodes() const; - inline ::capnp::List< ::capnp::schema::Node>::Reader getNodes() const; - - inline bool hasRequestedFiles() const; - inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader getRequestedFiles() const; - - inline bool hasCapnpVersion() const; - inline ::capnp::schema::CapnpVersion::Reader getCapnpVersion() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class CodeGeneratorRequest::Builder { -public: - typedef CodeGeneratorRequest Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline bool hasNodes(); - inline ::capnp::List< ::capnp::schema::Node>::Builder getNodes(); - inline void setNodes( ::capnp::List< ::capnp::schema::Node>::Reader value); - inline ::capnp::List< ::capnp::schema::Node>::Builder initNodes(unsigned int size); - inline void adoptNodes(::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>> disownNodes(); - - inline bool hasRequestedFiles(); - inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder getRequestedFiles(); - inline void setRequestedFiles( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader value); - inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder initRequestedFiles(unsigned int size); - inline void adoptRequestedFiles(::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>> disownRequestedFiles(); - - inline bool hasCapnpVersion(); - inline ::capnp::schema::CapnpVersion::Builder getCapnpVersion(); - inline void setCapnpVersion( ::capnp::schema::CapnpVersion::Reader value); - inline ::capnp::schema::CapnpVersion::Builder initCapnpVersion(); - inline void adoptCapnpVersion(::capnp::Orphan< ::capnp::schema::CapnpVersion>&& value); - inline ::capnp::Orphan< ::capnp::schema::CapnpVersion> disownCapnpVersion(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class CodeGeneratorRequest::Pipeline { -public: - typedef CodeGeneratorRequest Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - - inline ::capnp::schema::CapnpVersion::Pipeline getCapnpVersion(); -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class CodeGeneratorRequest::RequestedFile::Reader { -public: - typedef RequestedFile Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getId() const; - - inline bool hasFilename() const; - inline ::capnp::Text::Reader getFilename() const; - - inline bool hasImports() const; - inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader getImports() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class CodeGeneratorRequest::RequestedFile::Builder { -public: - typedef RequestedFile Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getId(); - inline void setId( ::uint64_t value); - - inline bool hasFilename(); - inline ::capnp::Text::Builder getFilename(); - inline void setFilename( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initFilename(unsigned int size); - inline void adoptFilename(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownFilename(); - - inline bool hasImports(); - inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder getImports(); - inline void setImports( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader value); - inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder initImports(unsigned int size); - inline void adoptImports(::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>&& value); - inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>> disownImports(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class CodeGeneratorRequest::RequestedFile::Pipeline { -public: - typedef RequestedFile Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -class CodeGeneratorRequest::RequestedFile::Import::Reader { -public: - typedef Import Reads; - - Reader() = default; - inline explicit Reader(::capnp::_::StructReader base): _reader(base) {} - - inline ::capnp::MessageSize totalSize() const { - return _reader.totalSize().asPublic(); - } - -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { - return ::capnp::_::structString(_reader, *_capnpPrivate::brand()); - } -#endif // !CAPNP_LITE - - inline ::uint64_t getId() const; - - inline bool hasName() const; - inline ::capnp::Text::Reader getName() const; - -private: - ::capnp::_::StructReader _reader; - template - friend struct ::capnp::ToDynamic_; - template - friend struct ::capnp::_::PointerHelpers; - template - friend struct ::capnp::List; - friend class ::capnp::MessageBuilder; - friend class ::capnp::Orphanage; -}; - -class CodeGeneratorRequest::RequestedFile::Import::Builder { -public: - typedef Import Builds; - - Builder() = delete; // Deleted to discourage incorrect usage. - // You can explicitly initialize to nullptr instead. - inline Builder(decltype(nullptr)) {} - inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {} - inline operator Reader() const { return Reader(_builder.asReader()); } - inline Reader asReader() const { return *this; } - - inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); } -#if !CAPNP_LITE - inline ::kj::StringTree toString() const { return asReader().toString(); } -#endif // !CAPNP_LITE - - inline ::uint64_t getId(); - inline void setId( ::uint64_t value); - - inline bool hasName(); - inline ::capnp::Text::Builder getName(); - inline void setName( ::capnp::Text::Reader value); - inline ::capnp::Text::Builder initName(unsigned int size); - inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value); - inline ::capnp::Orphan< ::capnp::Text> disownName(); - -private: - ::capnp::_::StructBuilder _builder; - template - friend struct ::capnp::ToDynamic_; - friend class ::capnp::Orphanage; - template - friend struct ::capnp::_::PointerHelpers; -}; - -#if !CAPNP_LITE -class CodeGeneratorRequest::RequestedFile::Import::Pipeline { -public: - typedef Import Pipelines; - - inline Pipeline(decltype(nullptr)): _typeless(nullptr) {} - inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless) - : _typeless(kj::mv(typeless)) {} - -private: - ::capnp::AnyPointer::Pipeline _typeless; - friend class ::capnp::PipelineHook; - template - friend struct ::capnp::ToDynamic_; -}; -#endif // !CAPNP_LITE - -// ======================================================================================= - -inline ::capnp::schema::Node::Which Node::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<6>() * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Node::Which Node::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<6>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Node::Reader::getId() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Node::Builder::getId() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Node::Builder::setId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Reader::hasDisplayName() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Node::Builder::hasDisplayName() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Node::Reader::getDisplayName() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Node::Builder::getDisplayName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Node::Builder::setDisplayName( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Node::Builder::initDisplayName(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void Node::Builder::adoptDisplayName( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Node::Builder::disownDisplayName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::uint32_t Node::Reader::getDisplayNamePrefixLength() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Node::Builder::getDisplayNamePrefixLength() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} -inline void Node::Builder::setDisplayNamePrefixLength( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); -} - -inline ::uint64_t Node::Reader::getScopeId() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Node::Builder::getScopeId() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} -inline void Node::Builder::setScopeId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Reader::hasNestedNodes() const { - return !_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline bool Node::Builder::hasNestedNodes() { - return !_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader Node::Reader::getNestedNodes() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::get(_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder Node::Builder::getNestedNodes() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::get(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline void Node::Builder::setNestedNodes( ::capnp::List< ::capnp::schema::Node::NestedNode>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::set(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Node::NestedNode>::Builder Node::Builder::initNestedNodes(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::init(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), size); -} -inline void Node::Builder::adoptNestedNodes( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::adopt(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::NestedNode>> Node::Builder::disownNestedNodes() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::NestedNode>>::disown(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} - -inline bool Node::Reader::hasAnnotations() const { - return !_reader.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); -} -inline bool Node::Builder::hasAnnotations() { - return !_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Reader Node::Reader::getAnnotations() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_reader.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Node::Builder::getAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} -inline void Node::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Node::Builder::initAnnotations(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS), size); -} -inline void Node::Builder::adoptAnnotations( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Node::Builder::disownAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} - -inline bool Node::Reader::isFile() const { - return which() == Node::FILE; -} -inline bool Node::Builder::isFile() { - return which() == Node::FILE; -} -inline ::capnp::Void Node::Reader::getFile() const { - KJ_IREQUIRE((which() == Node::FILE), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Node::Builder::getFile() { - KJ_IREQUIRE((which() == Node::FILE), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Node::Builder::setFile( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::FILE); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Reader::isStruct() const { - return which() == Node::STRUCT; -} -inline bool Node::Builder::isStruct() { - return which() == Node::STRUCT; -} -inline typename Node::Struct::Reader Node::Reader::getStruct() const { - KJ_IREQUIRE((which() == Node::STRUCT), - "Must check which() before get()ing a union member."); - return typename Node::Struct::Reader(_reader); -} -inline typename Node::Struct::Builder Node::Builder::getStruct() { - KJ_IREQUIRE((which() == Node::STRUCT), - "Must check which() before get()ing a union member."); - return typename Node::Struct::Builder(_builder); -} -inline typename Node::Struct::Builder Node::Builder::initStruct() { - _builder.setDataField( - ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::STRUCT); - _builder.setDataField< ::uint16_t>(::capnp::bounded<7>() * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint16_t>(::capnp::bounded<12>() * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint16_t>(::capnp::bounded<13>() * ::capnp::ELEMENTS, 0); - _builder.setDataField(::capnp::bounded<224>() * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint16_t>(::capnp::bounded<15>() * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint32_t>(::capnp::bounded<8>() * ::capnp::ELEMENTS, 0); - _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); - return typename Node::Struct::Builder(_builder); -} -inline bool Node::Reader::isEnum() const { - return which() == Node::ENUM; -} -inline bool Node::Builder::isEnum() { - return which() == Node::ENUM; -} -inline typename Node::Enum::Reader Node::Reader::getEnum() const { - KJ_IREQUIRE((which() == Node::ENUM), - "Must check which() before get()ing a union member."); - return typename Node::Enum::Reader(_reader); -} -inline typename Node::Enum::Builder Node::Builder::getEnum() { - KJ_IREQUIRE((which() == Node::ENUM), - "Must check which() before get()ing a union member."); - return typename Node::Enum::Builder(_builder); -} -inline typename Node::Enum::Builder Node::Builder::initEnum() { - _builder.setDataField( - ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::ENUM); - _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); - return typename Node::Enum::Builder(_builder); -} -inline bool Node::Reader::isInterface() const { - return which() == Node::INTERFACE; -} -inline bool Node::Builder::isInterface() { - return which() == Node::INTERFACE; -} -inline typename Node::Interface::Reader Node::Reader::getInterface() const { - KJ_IREQUIRE((which() == Node::INTERFACE), - "Must check which() before get()ing a union member."); - return typename Node::Interface::Reader(_reader); -} -inline typename Node::Interface::Builder Node::Builder::getInterface() { - KJ_IREQUIRE((which() == Node::INTERFACE), - "Must check which() before get()ing a union member."); - return typename Node::Interface::Builder(_builder); -} -inline typename Node::Interface::Builder Node::Builder::initInterface() { - _builder.setDataField( - ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::INTERFACE); - _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); - _builder.getPointerField(::capnp::bounded<4>() * ::capnp::POINTERS).clear(); - return typename Node::Interface::Builder(_builder); -} -inline bool Node::Reader::isConst() const { - return which() == Node::CONST; -} -inline bool Node::Builder::isConst() { - return which() == Node::CONST; -} -inline typename Node::Const::Reader Node::Reader::getConst() const { - KJ_IREQUIRE((which() == Node::CONST), - "Must check which() before get()ing a union member."); - return typename Node::Const::Reader(_reader); -} -inline typename Node::Const::Builder Node::Builder::getConst() { - KJ_IREQUIRE((which() == Node::CONST), - "Must check which() before get()ing a union member."); - return typename Node::Const::Builder(_builder); -} -inline typename Node::Const::Builder Node::Builder::initConst() { - _builder.setDataField( - ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::CONST); - _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); - _builder.getPointerField(::capnp::bounded<4>() * ::capnp::POINTERS).clear(); - return typename Node::Const::Builder(_builder); -} -inline bool Node::Reader::isAnnotation() const { - return which() == Node::ANNOTATION; -} -inline bool Node::Builder::isAnnotation() { - return which() == Node::ANNOTATION; -} -inline typename Node::Annotation::Reader Node::Reader::getAnnotation() const { - KJ_IREQUIRE((which() == Node::ANNOTATION), - "Must check which() before get()ing a union member."); - return typename Node::Annotation::Reader(_reader); -} -inline typename Node::Annotation::Builder Node::Builder::getAnnotation() { - KJ_IREQUIRE((which() == Node::ANNOTATION), - "Must check which() before get()ing a union member."); - return typename Node::Annotation::Builder(_builder); -} -inline typename Node::Annotation::Builder Node::Builder::initAnnotation() { - _builder.setDataField( - ::capnp::bounded<6>() * ::capnp::ELEMENTS, Node::ANNOTATION); - _builder.setDataField(::capnp::bounded<112>() * ::capnp::ELEMENTS, 0); - _builder.setDataField(::capnp::bounded<113>() * ::capnp::ELEMENTS, 0); - _builder.setDataField(::capnp::bounded<114>() * ::capnp::ELEMENTS, 0); - _builder.setDataField(::capnp::bounded<115>() * ::capnp::ELEMENTS, 0); - _builder.setDataField(::capnp::bounded<116>() * ::capnp::ELEMENTS, 0); - _builder.setDataField(::capnp::bounded<117>() * ::capnp::ELEMENTS, 0); - _builder.setDataField(::capnp::bounded<118>() * ::capnp::ELEMENTS, 0); - _builder.setDataField(::capnp::bounded<119>() * ::capnp::ELEMENTS, 0); - _builder.setDataField(::capnp::bounded<120>() * ::capnp::ELEMENTS, 0); - _builder.setDataField(::capnp::bounded<121>() * ::capnp::ELEMENTS, 0); - _builder.setDataField(::capnp::bounded<122>() * ::capnp::ELEMENTS, 0); - _builder.setDataField(::capnp::bounded<123>() * ::capnp::ELEMENTS, 0); - _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); - return typename Node::Annotation::Builder(_builder); -} -inline bool Node::Reader::hasParameters() const { - return !_reader.getPointerField( - ::capnp::bounded<5>() * ::capnp::POINTERS).isNull(); -} -inline bool Node::Builder::hasParameters() { - return !_builder.getPointerField( - ::capnp::bounded<5>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader Node::Reader::getParameters() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get(_reader.getPointerField( - ::capnp::bounded<5>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Node::Builder::getParameters() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get(_builder.getPointerField( - ::capnp::bounded<5>() * ::capnp::POINTERS)); -} -inline void Node::Builder::setParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::set(_builder.getPointerField( - ::capnp::bounded<5>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Node::Builder::initParameters(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::init(_builder.getPointerField( - ::capnp::bounded<5>() * ::capnp::POINTERS), size); -} -inline void Node::Builder::adoptParameters( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::adopt(_builder.getPointerField( - ::capnp::bounded<5>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> Node::Builder::disownParameters() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::disown(_builder.getPointerField( - ::capnp::bounded<5>() * ::capnp::POINTERS)); -} - -inline bool Node::Reader::getIsGeneric() const { - return _reader.getDataField( - ::capnp::bounded<288>() * ::capnp::ELEMENTS); -} - -inline bool Node::Builder::getIsGeneric() { - return _builder.getDataField( - ::capnp::bounded<288>() * ::capnp::ELEMENTS); -} -inline void Node::Builder::setIsGeneric(bool value) { - _builder.setDataField( - ::capnp::bounded<288>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Parameter::Reader::hasName() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Node::Parameter::Builder::hasName() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Node::Parameter::Reader::getName() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Node::Parameter::Builder::getName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Node::Parameter::Builder::setName( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Node::Parameter::Builder::initName(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void Node::Parameter::Builder::adoptName( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Node::Parameter::Builder::disownName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Node::NestedNode::Reader::hasName() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Node::NestedNode::Builder::hasName() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Node::NestedNode::Reader::getName() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Node::NestedNode::Builder::getName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Node::NestedNode::Builder::setName( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Node::NestedNode::Builder::initName(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void Node::NestedNode::Builder::adoptName( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Node::NestedNode::Builder::disownName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::uint64_t Node::NestedNode::Reader::getId() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Node::NestedNode::Builder::getId() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Node::NestedNode::Builder::setId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t Node::Struct::Reader::getDataWordCount() const { - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<7>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t Node::Struct::Builder::getDataWordCount() { - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<7>() * ::capnp::ELEMENTS); -} -inline void Node::Struct::Builder::setDataWordCount( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<7>() * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t Node::Struct::Reader::getPointerCount() const { - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<12>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t Node::Struct::Builder::getPointerCount() { - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<12>() * ::capnp::ELEMENTS); -} -inline void Node::Struct::Builder::setPointerCount( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<12>() * ::capnp::ELEMENTS, value); -} - -inline ::capnp::schema::ElementSize Node::Struct::Reader::getPreferredListEncoding() const { - return _reader.getDataField< ::capnp::schema::ElementSize>( - ::capnp::bounded<13>() * ::capnp::ELEMENTS); -} - -inline ::capnp::schema::ElementSize Node::Struct::Builder::getPreferredListEncoding() { - return _builder.getDataField< ::capnp::schema::ElementSize>( - ::capnp::bounded<13>() * ::capnp::ELEMENTS); -} -inline void Node::Struct::Builder::setPreferredListEncoding( ::capnp::schema::ElementSize value) { - _builder.setDataField< ::capnp::schema::ElementSize>( - ::capnp::bounded<13>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Struct::Reader::getIsGroup() const { - return _reader.getDataField( - ::capnp::bounded<224>() * ::capnp::ELEMENTS); -} - -inline bool Node::Struct::Builder::getIsGroup() { - return _builder.getDataField( - ::capnp::bounded<224>() * ::capnp::ELEMENTS); -} -inline void Node::Struct::Builder::setIsGroup(bool value) { - _builder.setDataField( - ::capnp::bounded<224>() * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t Node::Struct::Reader::getDiscriminantCount() const { - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<15>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t Node::Struct::Builder::getDiscriminantCount() { - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<15>() * ::capnp::ELEMENTS); -} -inline void Node::Struct::Builder::setDiscriminantCount( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<15>() * ::capnp::ELEMENTS, value); -} - -inline ::uint32_t Node::Struct::Reader::getDiscriminantOffset() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<8>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Node::Struct::Builder::getDiscriminantOffset() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<8>() * ::capnp::ELEMENTS); -} -inline void Node::Struct::Builder::setDiscriminantOffset( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<8>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Struct::Reader::hasFields() const { - return !_reader.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); -} -inline bool Node::Struct::Builder::hasFields() { - return !_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Field>::Reader Node::Struct::Reader::getFields() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::get(_reader.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Field>::Builder Node::Struct::Builder::getFields() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::get(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -inline void Node::Struct::Builder::setFields( ::capnp::List< ::capnp::schema::Field>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::set(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Field>::Builder Node::Struct::Builder::initFields(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::init(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), size); -} -inline void Node::Struct::Builder::adoptFields( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::adopt(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Field>> Node::Struct::Builder::disownFields() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Field>>::disown(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} - -inline bool Node::Enum::Reader::hasEnumerants() const { - return !_reader.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); -} -inline bool Node::Enum::Builder::hasEnumerants() { - return !_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Enumerant>::Reader Node::Enum::Reader::getEnumerants() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::get(_reader.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Enumerant>::Builder Node::Enum::Builder::getEnumerants() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::get(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -inline void Node::Enum::Builder::setEnumerants( ::capnp::List< ::capnp::schema::Enumerant>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::set(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Enumerant>::Builder Node::Enum::Builder::initEnumerants(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::init(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), size); -} -inline void Node::Enum::Builder::adoptEnumerants( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::adopt(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Enumerant>> Node::Enum::Builder::disownEnumerants() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Enumerant>>::disown(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} - -inline bool Node::Interface::Reader::hasMethods() const { - return !_reader.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); -} -inline bool Node::Interface::Builder::hasMethods() { - return !_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Method>::Reader Node::Interface::Reader::getMethods() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::get(_reader.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Method>::Builder Node::Interface::Builder::getMethods() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::get(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -inline void Node::Interface::Builder::setMethods( ::capnp::List< ::capnp::schema::Method>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::set(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Method>::Builder Node::Interface::Builder::initMethods(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::init(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), size); -} -inline void Node::Interface::Builder::adoptMethods( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::adopt(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Method>> Node::Interface::Builder::disownMethods() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Method>>::disown(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} - -inline bool Node::Interface::Reader::hasSuperclasses() const { - return !_reader.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); -} -inline bool Node::Interface::Builder::hasSuperclasses() { - return !_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Superclass>::Reader Node::Interface::Reader::getSuperclasses() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::get(_reader.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Superclass>::Builder Node::Interface::Builder::getSuperclasses() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::get(_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS)); -} -inline void Node::Interface::Builder::setSuperclasses( ::capnp::List< ::capnp::schema::Superclass>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::set(_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Superclass>::Builder Node::Interface::Builder::initSuperclasses(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::init(_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS), size); -} -inline void Node::Interface::Builder::adoptSuperclasses( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::adopt(_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Superclass>> Node::Interface::Builder::disownSuperclasses() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Superclass>>::disown(_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS)); -} - -inline bool Node::Const::Reader::hasType() const { - return !_reader.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); -} -inline bool Node::Const::Builder::hasType() { - return !_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Type::Reader Node::Const::Reader::getType() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_reader.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::Type::Builder Node::Const::Builder::getType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Type::Pipeline Node::Const::Pipeline::getType() { - return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(3)); -} -#endif // !CAPNP_LITE -inline void Node::Const::Builder::setType( ::capnp::schema::Type::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Type::Builder Node::Const::Builder::initType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -inline void Node::Const::Builder::adoptType( - ::capnp::Orphan< ::capnp::schema::Type>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Type> Node::Const::Builder::disownType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} - -inline bool Node::Const::Reader::hasValue() const { - return !_reader.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); -} -inline bool Node::Const::Builder::hasValue() { - return !_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Value::Reader Node::Const::Reader::getValue() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_reader.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::Value::Builder Node::Const::Builder::getValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Value::Pipeline Node::Const::Pipeline::getValue() { - return ::capnp::schema::Value::Pipeline(_typeless.getPointerField(4)); -} -#endif // !CAPNP_LITE -inline void Node::Const::Builder::setValue( ::capnp::schema::Value::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Value>::set(_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Value::Builder Node::Const::Builder::initValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::init(_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS)); -} -inline void Node::Const::Builder::adoptValue( - ::capnp::Orphan< ::capnp::schema::Value>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Value>::adopt(_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Value> Node::Const::Builder::disownValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::disown(_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS)); -} - -inline bool Node::Annotation::Reader::hasType() const { - return !_reader.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); -} -inline bool Node::Annotation::Builder::hasType() { - return !_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Type::Reader Node::Annotation::Reader::getType() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_reader.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::Type::Builder Node::Annotation::Builder::getType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Type::Pipeline Node::Annotation::Pipeline::getType() { - return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(3)); -} -#endif // !CAPNP_LITE -inline void Node::Annotation::Builder::setType( ::capnp::schema::Type::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Type::Builder Node::Annotation::Builder::initType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -inline void Node::Annotation::Builder::adoptType( - ::capnp::Orphan< ::capnp::schema::Type>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Type> Node::Annotation::Builder::disownType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} - -inline bool Node::Annotation::Reader::getTargetsFile() const { - return _reader.getDataField( - ::capnp::bounded<112>() * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsFile() { - return _builder.getDataField( - ::capnp::bounded<112>() * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsFile(bool value) { - _builder.setDataField( - ::capnp::bounded<112>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsConst() const { - return _reader.getDataField( - ::capnp::bounded<113>() * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsConst() { - return _builder.getDataField( - ::capnp::bounded<113>() * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsConst(bool value) { - _builder.setDataField( - ::capnp::bounded<113>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsEnum() const { - return _reader.getDataField( - ::capnp::bounded<114>() * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsEnum() { - return _builder.getDataField( - ::capnp::bounded<114>() * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsEnum(bool value) { - _builder.setDataField( - ::capnp::bounded<114>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsEnumerant() const { - return _reader.getDataField( - ::capnp::bounded<115>() * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsEnumerant() { - return _builder.getDataField( - ::capnp::bounded<115>() * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsEnumerant(bool value) { - _builder.setDataField( - ::capnp::bounded<115>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsStruct() const { - return _reader.getDataField( - ::capnp::bounded<116>() * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsStruct() { - return _builder.getDataField( - ::capnp::bounded<116>() * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsStruct(bool value) { - _builder.setDataField( - ::capnp::bounded<116>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsField() const { - return _reader.getDataField( - ::capnp::bounded<117>() * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsField() { - return _builder.getDataField( - ::capnp::bounded<117>() * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsField(bool value) { - _builder.setDataField( - ::capnp::bounded<117>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsUnion() const { - return _reader.getDataField( - ::capnp::bounded<118>() * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsUnion() { - return _builder.getDataField( - ::capnp::bounded<118>() * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsUnion(bool value) { - _builder.setDataField( - ::capnp::bounded<118>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsGroup() const { - return _reader.getDataField( - ::capnp::bounded<119>() * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsGroup() { - return _builder.getDataField( - ::capnp::bounded<119>() * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsGroup(bool value) { - _builder.setDataField( - ::capnp::bounded<119>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsInterface() const { - return _reader.getDataField( - ::capnp::bounded<120>() * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsInterface() { - return _builder.getDataField( - ::capnp::bounded<120>() * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsInterface(bool value) { - _builder.setDataField( - ::capnp::bounded<120>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsMethod() const { - return _reader.getDataField( - ::capnp::bounded<121>() * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsMethod() { - return _builder.getDataField( - ::capnp::bounded<121>() * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsMethod(bool value) { - _builder.setDataField( - ::capnp::bounded<121>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsParam() const { - return _reader.getDataField( - ::capnp::bounded<122>() * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsParam() { - return _builder.getDataField( - ::capnp::bounded<122>() * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsParam(bool value) { - _builder.setDataField( - ::capnp::bounded<122>() * ::capnp::ELEMENTS, value); -} - -inline bool Node::Annotation::Reader::getTargetsAnnotation() const { - return _reader.getDataField( - ::capnp::bounded<123>() * ::capnp::ELEMENTS); -} - -inline bool Node::Annotation::Builder::getTargetsAnnotation() { - return _builder.getDataField( - ::capnp::bounded<123>() * ::capnp::ELEMENTS); -} -inline void Node::Annotation::Builder::setTargetsAnnotation(bool value) { - _builder.setDataField( - ::capnp::bounded<123>() * ::capnp::ELEMENTS, value); -} - -inline ::capnp::schema::Field::Which Field::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<4>() * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Field::Which Field::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<4>() * ::capnp::ELEMENTS); -} - -inline bool Field::Reader::hasName() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Field::Builder::hasName() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Field::Reader::getName() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Field::Builder::getName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Field::Builder::setName( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Field::Builder::initName(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void Field::Builder::adoptName( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Field::Builder::disownName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::uint16_t Field::Reader::getCodeOrder() const { - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t Field::Builder::getCodeOrder() { - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Field::Builder::setCodeOrder( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Field::Reader::hasAnnotations() const { - return !_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline bool Field::Builder::hasAnnotations() { - return !_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Reader Field::Reader::getAnnotations() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Field::Builder::getAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline void Field::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Field::Builder::initAnnotations(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), size); -} -inline void Field::Builder::adoptAnnotations( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Field::Builder::disownAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} - -inline ::uint16_t Field::Reader::getDiscriminantValue() const { - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, 65535u); -} - -inline ::uint16_t Field::Builder::getDiscriminantValue() { - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, 65535u); -} -inline void Field::Builder::setDiscriminantValue( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value, 65535u); -} - -inline bool Field::Reader::isSlot() const { - return which() == Field::SLOT; -} -inline bool Field::Builder::isSlot() { - return which() == Field::SLOT; -} -inline typename Field::Slot::Reader Field::Reader::getSlot() const { - KJ_IREQUIRE((which() == Field::SLOT), - "Must check which() before get()ing a union member."); - return typename Field::Slot::Reader(_reader); -} -inline typename Field::Slot::Builder Field::Builder::getSlot() { - KJ_IREQUIRE((which() == Field::SLOT), - "Must check which() before get()ing a union member."); - return typename Field::Slot::Builder(_builder); -} -inline typename Field::Slot::Builder Field::Builder::initSlot() { - _builder.setDataField( - ::capnp::bounded<4>() * ::capnp::ELEMENTS, Field::SLOT); - _builder.setDataField< ::uint32_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); - _builder.setDataField(::capnp::bounded<128>() * ::capnp::ELEMENTS, 0); - _builder.getPointerField(::capnp::bounded<2>() * ::capnp::POINTERS).clear(); - _builder.getPointerField(::capnp::bounded<3>() * ::capnp::POINTERS).clear(); - return typename Field::Slot::Builder(_builder); -} -inline bool Field::Reader::isGroup() const { - return which() == Field::GROUP; -} -inline bool Field::Builder::isGroup() { - return which() == Field::GROUP; -} -inline typename Field::Group::Reader Field::Reader::getGroup() const { - KJ_IREQUIRE((which() == Field::GROUP), - "Must check which() before get()ing a union member."); - return typename Field::Group::Reader(_reader); -} -inline typename Field::Group::Builder Field::Builder::getGroup() { - KJ_IREQUIRE((which() == Field::GROUP), - "Must check which() before get()ing a union member."); - return typename Field::Group::Builder(_builder); -} -inline typename Field::Group::Builder Field::Builder::initGroup() { - _builder.setDataField( - ::capnp::bounded<4>() * ::capnp::ELEMENTS, Field::GROUP); - _builder.setDataField< ::uint64_t>(::capnp::bounded<2>() * ::capnp::ELEMENTS, 0); - return typename Field::Group::Builder(_builder); -} -inline typename Field::Ordinal::Reader Field::Reader::getOrdinal() const { - return typename Field::Ordinal::Reader(_reader); -} -inline typename Field::Ordinal::Builder Field::Builder::getOrdinal() { - return typename Field::Ordinal::Builder(_builder); -} -#if !CAPNP_LITE -inline typename Field::Ordinal::Pipeline Field::Pipeline::getOrdinal() { - return typename Field::Ordinal::Pipeline(_typeless.noop()); -} -#endif // !CAPNP_LITE -inline typename Field::Ordinal::Builder Field::Builder::initOrdinal() { - _builder.setDataField< ::uint16_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint16_t>(::capnp::bounded<6>() * ::capnp::ELEMENTS, 0); - return typename Field::Ordinal::Builder(_builder); -} -inline ::uint32_t Field::Slot::Reader::getOffset() const { - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Field::Slot::Builder::getOffset() { - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Field::Slot::Builder::setOffset( ::uint32_t value) { - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool Field::Slot::Reader::hasType() const { - return !_reader.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); -} -inline bool Field::Slot::Builder::hasType() { - return !_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Type::Reader Field::Slot::Reader::getType() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_reader.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::Type::Builder Field::Slot::Builder::getType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Type::Pipeline Field::Slot::Pipeline::getType() { - return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(2)); -} -#endif // !CAPNP_LITE -inline void Field::Slot::Builder::setType( ::capnp::schema::Type::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Type::Builder Field::Slot::Builder::initType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} -inline void Field::Slot::Builder::adoptType( - ::capnp::Orphan< ::capnp::schema::Type>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Type> Field::Slot::Builder::disownType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} - -inline bool Field::Slot::Reader::hasDefaultValue() const { - return !_reader.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); -} -inline bool Field::Slot::Builder::hasDefaultValue() { - return !_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Value::Reader Field::Slot::Reader::getDefaultValue() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_reader.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::Value::Builder Field::Slot::Builder::getDefaultValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Value::Pipeline Field::Slot::Pipeline::getDefaultValue() { - return ::capnp::schema::Value::Pipeline(_typeless.getPointerField(3)); -} -#endif // !CAPNP_LITE -inline void Field::Slot::Builder::setDefaultValue( ::capnp::schema::Value::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Value>::set(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Value::Builder Field::Slot::Builder::initDefaultValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::init(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -inline void Field::Slot::Builder::adoptDefaultValue( - ::capnp::Orphan< ::capnp::schema::Value>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Value>::adopt(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Value> Field::Slot::Builder::disownDefaultValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::disown(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} - -inline bool Field::Slot::Reader::getHadExplicitDefault() const { - return _reader.getDataField( - ::capnp::bounded<128>() * ::capnp::ELEMENTS); -} - -inline bool Field::Slot::Builder::getHadExplicitDefault() { - return _builder.getDataField( - ::capnp::bounded<128>() * ::capnp::ELEMENTS); -} -inline void Field::Slot::Builder::setHadExplicitDefault(bool value) { - _builder.setDataField( - ::capnp::bounded<128>() * ::capnp::ELEMENTS, value); -} - -inline ::uint64_t Field::Group::Reader::getTypeId() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Field::Group::Builder::getTypeId() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} -inline void Field::Group::Builder::setTypeId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); -} - -inline ::capnp::schema::Field::Ordinal::Which Field::Ordinal::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<5>() * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Field::Ordinal::Which Field::Ordinal::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<5>() * ::capnp::ELEMENTS); -} - -inline bool Field::Ordinal::Reader::isImplicit() const { - return which() == Field::Ordinal::IMPLICIT; -} -inline bool Field::Ordinal::Builder::isImplicit() { - return which() == Field::Ordinal::IMPLICIT; -} -inline ::capnp::Void Field::Ordinal::Reader::getImplicit() const { - KJ_IREQUIRE((which() == Field::Ordinal::IMPLICIT), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Field::Ordinal::Builder::getImplicit() { - KJ_IREQUIRE((which() == Field::Ordinal::IMPLICIT), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Field::Ordinal::Builder::setImplicit( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<5>() * ::capnp::ELEMENTS, Field::Ordinal::IMPLICIT); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Field::Ordinal::Reader::isExplicit() const { - return which() == Field::Ordinal::EXPLICIT; -} -inline bool Field::Ordinal::Builder::isExplicit() { - return which() == Field::Ordinal::EXPLICIT; -} -inline ::uint16_t Field::Ordinal::Reader::getExplicit() const { - KJ_IREQUIRE((which() == Field::Ordinal::EXPLICIT), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<6>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t Field::Ordinal::Builder::getExplicit() { - KJ_IREQUIRE((which() == Field::Ordinal::EXPLICIT), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<6>() * ::capnp::ELEMENTS); -} -inline void Field::Ordinal::Builder::setExplicit( ::uint16_t value) { - _builder.setDataField( - ::capnp::bounded<5>() * ::capnp::ELEMENTS, Field::Ordinal::EXPLICIT); - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<6>() * ::capnp::ELEMENTS, value); -} - -inline bool Enumerant::Reader::hasName() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Enumerant::Builder::hasName() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Enumerant::Reader::getName() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Enumerant::Builder::getName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Enumerant::Builder::setName( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Enumerant::Builder::initName(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void Enumerant::Builder::adoptName( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Enumerant::Builder::disownName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::uint16_t Enumerant::Reader::getCodeOrder() const { - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t Enumerant::Builder::getCodeOrder() { - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Enumerant::Builder::setCodeOrder( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Enumerant::Reader::hasAnnotations() const { - return !_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline bool Enumerant::Builder::hasAnnotations() { - return !_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Reader Enumerant::Reader::getAnnotations() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Enumerant::Builder::getAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline void Enumerant::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Enumerant::Builder::initAnnotations(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), size); -} -inline void Enumerant::Builder::adoptAnnotations( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Enumerant::Builder::disownAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} - -inline ::uint64_t Superclass::Reader::getId() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Superclass::Builder::getId() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Superclass::Builder::setId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Superclass::Reader::hasBrand() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Superclass::Builder::hasBrand() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Brand::Reader Superclass::Reader::getBrand() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::Brand::Builder Superclass::Builder::getBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Brand::Pipeline Superclass::Pipeline::getBrand() { - return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Superclass::Builder::setBrand( ::capnp::schema::Brand::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Brand::Builder Superclass::Builder::initBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Superclass::Builder::adoptBrand( - ::capnp::Orphan< ::capnp::schema::Brand>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Brand> Superclass::Builder::disownBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Method::Reader::hasName() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Method::Builder::hasName() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Method::Reader::getName() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Method::Builder::getName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Method::Builder::setName( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Method::Builder::initName(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void Method::Builder::adoptName( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Method::Builder::disownName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::uint16_t Method::Reader::getCodeOrder() const { - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t Method::Builder::getCodeOrder() { - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Method::Builder::setCodeOrder( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline ::uint64_t Method::Reader::getParamStructType() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Method::Builder::getParamStructType() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Method::Builder::setParamStructType( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline ::uint64_t Method::Reader::getResultStructType() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Method::Builder::getResultStructType() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} -inline void Method::Builder::setResultStructType( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); -} - -inline bool Method::Reader::hasAnnotations() const { - return !_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline bool Method::Builder::hasAnnotations() { - return !_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Reader Method::Reader::getAnnotations() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Method::Builder::getAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::get(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline void Method::Builder::setAnnotations( ::capnp::List< ::capnp::schema::Annotation>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::set(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Annotation>::Builder Method::Builder::initAnnotations(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::init(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), size); -} -inline void Method::Builder::adoptAnnotations( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::adopt(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Annotation>> Method::Builder::disownAnnotations() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Annotation>>::disown(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} - -inline bool Method::Reader::hasParamBrand() const { - return !_reader.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); -} -inline bool Method::Builder::hasParamBrand() { - return !_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Brand::Reader Method::Reader::getParamBrand() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::Brand::Builder Method::Builder::getParamBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Brand::Pipeline Method::Pipeline::getParamBrand() { - return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(2)); -} -#endif // !CAPNP_LITE -inline void Method::Builder::setParamBrand( ::capnp::schema::Brand::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Brand::Builder Method::Builder::initParamBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} -inline void Method::Builder::adoptParamBrand( - ::capnp::Orphan< ::capnp::schema::Brand>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Brand> Method::Builder::disownParamBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} - -inline bool Method::Reader::hasResultBrand() const { - return !_reader.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); -} -inline bool Method::Builder::hasResultBrand() { - return !_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Brand::Reader Method::Reader::getResultBrand() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::Brand::Builder Method::Builder::getResultBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Brand::Pipeline Method::Pipeline::getResultBrand() { - return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(3)); -} -#endif // !CAPNP_LITE -inline void Method::Builder::setResultBrand( ::capnp::schema::Brand::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Brand::Builder Method::Builder::initResultBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} -inline void Method::Builder::adoptResultBrand( - ::capnp::Orphan< ::capnp::schema::Brand>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Brand> Method::Builder::disownResultBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( - ::capnp::bounded<3>() * ::capnp::POINTERS)); -} - -inline bool Method::Reader::hasImplicitParameters() const { - return !_reader.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); -} -inline bool Method::Builder::hasImplicitParameters() { - return !_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Node::Parameter>::Reader Method::Reader::getImplicitParameters() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get(_reader.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Method::Builder::getImplicitParameters() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::get(_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS)); -} -inline void Method::Builder::setImplicitParameters( ::capnp::List< ::capnp::schema::Node::Parameter>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::set(_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Node::Parameter>::Builder Method::Builder::initImplicitParameters(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::init(_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS), size); -} -inline void Method::Builder::adoptImplicitParameters( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::adopt(_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node::Parameter>> Method::Builder::disownImplicitParameters() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node::Parameter>>::disown(_builder.getPointerField( - ::capnp::bounded<4>() * ::capnp::POINTERS)); -} - -inline ::capnp::schema::Type::Which Type::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Type::Which Type::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline bool Type::Reader::isVoid() const { - return which() == Type::VOID; -} -inline bool Type::Builder::isVoid() { - return which() == Type::VOID; -} -inline ::capnp::Void Type::Reader::getVoid() const { - KJ_IREQUIRE((which() == Type::VOID), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getVoid() { - KJ_IREQUIRE((which() == Type::VOID), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::Builder::setVoid( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::VOID); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isBool() const { - return which() == Type::BOOL; -} -inline bool Type::Builder::isBool() { - return which() == Type::BOOL; -} -inline ::capnp::Void Type::Reader::getBool() const { - KJ_IREQUIRE((which() == Type::BOOL), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getBool() { - KJ_IREQUIRE((which() == Type::BOOL), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::Builder::setBool( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::BOOL); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isInt8() const { - return which() == Type::INT8; -} -inline bool Type::Builder::isInt8() { - return which() == Type::INT8; -} -inline ::capnp::Void Type::Reader::getInt8() const { - KJ_IREQUIRE((which() == Type::INT8), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getInt8() { - KJ_IREQUIRE((which() == Type::INT8), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::Builder::setInt8( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::INT8); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isInt16() const { - return which() == Type::INT16; -} -inline bool Type::Builder::isInt16() { - return which() == Type::INT16; -} -inline ::capnp::Void Type::Reader::getInt16() const { - KJ_IREQUIRE((which() == Type::INT16), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getInt16() { - KJ_IREQUIRE((which() == Type::INT16), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::Builder::setInt16( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::INT16); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isInt32() const { - return which() == Type::INT32; -} -inline bool Type::Builder::isInt32() { - return which() == Type::INT32; -} -inline ::capnp::Void Type::Reader::getInt32() const { - KJ_IREQUIRE((which() == Type::INT32), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getInt32() { - KJ_IREQUIRE((which() == Type::INT32), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::Builder::setInt32( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::INT32); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isInt64() const { - return which() == Type::INT64; -} -inline bool Type::Builder::isInt64() { - return which() == Type::INT64; -} -inline ::capnp::Void Type::Reader::getInt64() const { - KJ_IREQUIRE((which() == Type::INT64), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getInt64() { - KJ_IREQUIRE((which() == Type::INT64), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::Builder::setInt64( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::INT64); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isUint8() const { - return which() == Type::UINT8; -} -inline bool Type::Builder::isUint8() { - return which() == Type::UINT8; -} -inline ::capnp::Void Type::Reader::getUint8() const { - KJ_IREQUIRE((which() == Type::UINT8), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getUint8() { - KJ_IREQUIRE((which() == Type::UINT8), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::Builder::setUint8( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::UINT8); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isUint16() const { - return which() == Type::UINT16; -} -inline bool Type::Builder::isUint16() { - return which() == Type::UINT16; -} -inline ::capnp::Void Type::Reader::getUint16() const { - KJ_IREQUIRE((which() == Type::UINT16), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getUint16() { - KJ_IREQUIRE((which() == Type::UINT16), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::Builder::setUint16( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::UINT16); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isUint32() const { - return which() == Type::UINT32; -} -inline bool Type::Builder::isUint32() { - return which() == Type::UINT32; -} -inline ::capnp::Void Type::Reader::getUint32() const { - KJ_IREQUIRE((which() == Type::UINT32), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getUint32() { - KJ_IREQUIRE((which() == Type::UINT32), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::Builder::setUint32( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::UINT32); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isUint64() const { - return which() == Type::UINT64; -} -inline bool Type::Builder::isUint64() { - return which() == Type::UINT64; -} -inline ::capnp::Void Type::Reader::getUint64() const { - KJ_IREQUIRE((which() == Type::UINT64), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getUint64() { - KJ_IREQUIRE((which() == Type::UINT64), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::Builder::setUint64( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::UINT64); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isFloat32() const { - return which() == Type::FLOAT32; -} -inline bool Type::Builder::isFloat32() { - return which() == Type::FLOAT32; -} -inline ::capnp::Void Type::Reader::getFloat32() const { - KJ_IREQUIRE((which() == Type::FLOAT32), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getFloat32() { - KJ_IREQUIRE((which() == Type::FLOAT32), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::Builder::setFloat32( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::FLOAT32); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isFloat64() const { - return which() == Type::FLOAT64; -} -inline bool Type::Builder::isFloat64() { - return which() == Type::FLOAT64; -} -inline ::capnp::Void Type::Reader::getFloat64() const { - KJ_IREQUIRE((which() == Type::FLOAT64), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getFloat64() { - KJ_IREQUIRE((which() == Type::FLOAT64), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::Builder::setFloat64( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::FLOAT64); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isText() const { - return which() == Type::TEXT; -} -inline bool Type::Builder::isText() { - return which() == Type::TEXT; -} -inline ::capnp::Void Type::Reader::getText() const { - KJ_IREQUIRE((which() == Type::TEXT), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getText() { - KJ_IREQUIRE((which() == Type::TEXT), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::Builder::setText( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::TEXT); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isData() const { - return which() == Type::DATA; -} -inline bool Type::Builder::isData() { - return which() == Type::DATA; -} -inline ::capnp::Void Type::Reader::getData() const { - KJ_IREQUIRE((which() == Type::DATA), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::Builder::getData() { - KJ_IREQUIRE((which() == Type::DATA), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::Builder::setData( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::DATA); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Reader::isList() const { - return which() == Type::LIST; -} -inline bool Type::Builder::isList() { - return which() == Type::LIST; -} -inline typename Type::List::Reader Type::Reader::getList() const { - KJ_IREQUIRE((which() == Type::LIST), - "Must check which() before get()ing a union member."); - return typename Type::List::Reader(_reader); -} -inline typename Type::List::Builder Type::Builder::getList() { - KJ_IREQUIRE((which() == Type::LIST), - "Must check which() before get()ing a union member."); - return typename Type::List::Builder(_builder); -} -inline typename Type::List::Builder Type::Builder::initList() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::LIST); - _builder.getPointerField(::capnp::bounded<0>() * ::capnp::POINTERS).clear(); - return typename Type::List::Builder(_builder); -} -inline bool Type::Reader::isEnum() const { - return which() == Type::ENUM; -} -inline bool Type::Builder::isEnum() { - return which() == Type::ENUM; -} -inline typename Type::Enum::Reader Type::Reader::getEnum() const { - KJ_IREQUIRE((which() == Type::ENUM), - "Must check which() before get()ing a union member."); - return typename Type::Enum::Reader(_reader); -} -inline typename Type::Enum::Builder Type::Builder::getEnum() { - KJ_IREQUIRE((which() == Type::ENUM), - "Must check which() before get()ing a union member."); - return typename Type::Enum::Builder(_builder); -} -inline typename Type::Enum::Builder Type::Builder::initEnum() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::ENUM); - _builder.setDataField< ::uint64_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); - _builder.getPointerField(::capnp::bounded<0>() * ::capnp::POINTERS).clear(); - return typename Type::Enum::Builder(_builder); -} -inline bool Type::Reader::isStruct() const { - return which() == Type::STRUCT; -} -inline bool Type::Builder::isStruct() { - return which() == Type::STRUCT; -} -inline typename Type::Struct::Reader Type::Reader::getStruct() const { - KJ_IREQUIRE((which() == Type::STRUCT), - "Must check which() before get()ing a union member."); - return typename Type::Struct::Reader(_reader); -} -inline typename Type::Struct::Builder Type::Builder::getStruct() { - KJ_IREQUIRE((which() == Type::STRUCT), - "Must check which() before get()ing a union member."); - return typename Type::Struct::Builder(_builder); -} -inline typename Type::Struct::Builder Type::Builder::initStruct() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::STRUCT); - _builder.setDataField< ::uint64_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); - _builder.getPointerField(::capnp::bounded<0>() * ::capnp::POINTERS).clear(); - return typename Type::Struct::Builder(_builder); -} -inline bool Type::Reader::isInterface() const { - return which() == Type::INTERFACE; -} -inline bool Type::Builder::isInterface() { - return which() == Type::INTERFACE; -} -inline typename Type::Interface::Reader Type::Reader::getInterface() const { - KJ_IREQUIRE((which() == Type::INTERFACE), - "Must check which() before get()ing a union member."); - return typename Type::Interface::Reader(_reader); -} -inline typename Type::Interface::Builder Type::Builder::getInterface() { - KJ_IREQUIRE((which() == Type::INTERFACE), - "Must check which() before get()ing a union member."); - return typename Type::Interface::Builder(_builder); -} -inline typename Type::Interface::Builder Type::Builder::initInterface() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::INTERFACE); - _builder.setDataField< ::uint64_t>(::capnp::bounded<1>() * ::capnp::ELEMENTS, 0); - _builder.getPointerField(::capnp::bounded<0>() * ::capnp::POINTERS).clear(); - return typename Type::Interface::Builder(_builder); -} -inline bool Type::Reader::isAnyPointer() const { - return which() == Type::ANY_POINTER; -} -inline bool Type::Builder::isAnyPointer() { - return which() == Type::ANY_POINTER; -} -inline typename Type::AnyPointer::Reader Type::Reader::getAnyPointer() const { - KJ_IREQUIRE((which() == Type::ANY_POINTER), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::Reader(_reader); -} -inline typename Type::AnyPointer::Builder Type::Builder::getAnyPointer() { - KJ_IREQUIRE((which() == Type::ANY_POINTER), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::Builder(_builder); -} -inline typename Type::AnyPointer::Builder Type::Builder::initAnyPointer() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Type::ANY_POINTER); - _builder.setDataField< ::uint16_t>(::capnp::bounded<4>() * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint16_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint64_t>(::capnp::bounded<2>() * ::capnp::ELEMENTS, 0); - return typename Type::AnyPointer::Builder(_builder); -} -inline bool Type::List::Reader::hasElementType() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Type::List::Builder::hasElementType() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Type::Reader Type::List::Reader::getElementType() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::Type::Builder Type::List::Builder::getElementType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Type::Pipeline Type::List::Pipeline::getElementType() { - return ::capnp::schema::Type::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Type::List::Builder::setElementType( ::capnp::schema::Type::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Type::Builder Type::List::Builder::initElementType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Type::List::Builder::adoptElementType( - ::capnp::Orphan< ::capnp::schema::Type>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Type> Type::List::Builder::disownElementType() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::uint64_t Type::Enum::Reader::getTypeId() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Type::Enum::Builder::getTypeId() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Type::Enum::Builder::setTypeId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Enum::Reader::hasBrand() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Type::Enum::Builder::hasBrand() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Brand::Reader Type::Enum::Reader::getBrand() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::Brand::Builder Type::Enum::Builder::getBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Brand::Pipeline Type::Enum::Pipeline::getBrand() { - return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Type::Enum::Builder::setBrand( ::capnp::schema::Brand::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Brand::Builder Type::Enum::Builder::initBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Type::Enum::Builder::adoptBrand( - ::capnp::Orphan< ::capnp::schema::Brand>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Brand> Type::Enum::Builder::disownBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::uint64_t Type::Struct::Reader::getTypeId() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Type::Struct::Builder::getTypeId() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Type::Struct::Builder::setTypeId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Struct::Reader::hasBrand() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Type::Struct::Builder::hasBrand() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Brand::Reader Type::Struct::Reader::getBrand() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::Brand::Builder Type::Struct::Builder::getBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Brand::Pipeline Type::Struct::Pipeline::getBrand() { - return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Type::Struct::Builder::setBrand( ::capnp::schema::Brand::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Brand::Builder Type::Struct::Builder::initBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Type::Struct::Builder::adoptBrand( - ::capnp::Orphan< ::capnp::schema::Brand>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Brand> Type::Struct::Builder::disownBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::uint64_t Type::Interface::Reader::getTypeId() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Type::Interface::Builder::getTypeId() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Type::Interface::Builder::setTypeId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::Interface::Reader::hasBrand() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Type::Interface::Builder::hasBrand() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Brand::Reader Type::Interface::Reader::getBrand() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::Brand::Builder Type::Interface::Builder::getBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Brand::Pipeline Type::Interface::Pipeline::getBrand() { - return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Type::Interface::Builder::setBrand( ::capnp::schema::Brand::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Brand::Builder Type::Interface::Builder::initBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Type::Interface::Builder::adoptBrand( - ::capnp::Orphan< ::capnp::schema::Brand>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Brand> Type::Interface::Builder::disownBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::capnp::schema::Type::AnyPointer::Which Type::AnyPointer::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<4>() * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Type::AnyPointer::Which Type::AnyPointer::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<4>() * ::capnp::ELEMENTS); -} - -inline bool Type::AnyPointer::Reader::isUnconstrained() const { - return which() == Type::AnyPointer::UNCONSTRAINED; -} -inline bool Type::AnyPointer::Builder::isUnconstrained() { - return which() == Type::AnyPointer::UNCONSTRAINED; -} -inline typename Type::AnyPointer::Unconstrained::Reader Type::AnyPointer::Reader::getUnconstrained() const { - KJ_IREQUIRE((which() == Type::AnyPointer::UNCONSTRAINED), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::Unconstrained::Reader(_reader); -} -inline typename Type::AnyPointer::Unconstrained::Builder Type::AnyPointer::Builder::getUnconstrained() { - KJ_IREQUIRE((which() == Type::AnyPointer::UNCONSTRAINED), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::Unconstrained::Builder(_builder); -} -inline typename Type::AnyPointer::Unconstrained::Builder Type::AnyPointer::Builder::initUnconstrained() { - _builder.setDataField( - ::capnp::bounded<4>() * ::capnp::ELEMENTS, Type::AnyPointer::UNCONSTRAINED); - _builder.setDataField< ::uint16_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0); - return typename Type::AnyPointer::Unconstrained::Builder(_builder); -} -inline bool Type::AnyPointer::Reader::isParameter() const { - return which() == Type::AnyPointer::PARAMETER; -} -inline bool Type::AnyPointer::Builder::isParameter() { - return which() == Type::AnyPointer::PARAMETER; -} -inline typename Type::AnyPointer::Parameter::Reader Type::AnyPointer::Reader::getParameter() const { - KJ_IREQUIRE((which() == Type::AnyPointer::PARAMETER), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::Parameter::Reader(_reader); -} -inline typename Type::AnyPointer::Parameter::Builder Type::AnyPointer::Builder::getParameter() { - KJ_IREQUIRE((which() == Type::AnyPointer::PARAMETER), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::Parameter::Builder(_builder); -} -inline typename Type::AnyPointer::Parameter::Builder Type::AnyPointer::Builder::initParameter() { - _builder.setDataField( - ::capnp::bounded<4>() * ::capnp::ELEMENTS, Type::AnyPointer::PARAMETER); - _builder.setDataField< ::uint16_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0); - _builder.setDataField< ::uint64_t>(::capnp::bounded<2>() * ::capnp::ELEMENTS, 0); - return typename Type::AnyPointer::Parameter::Builder(_builder); -} -inline bool Type::AnyPointer::Reader::isImplicitMethodParameter() const { - return which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER; -} -inline bool Type::AnyPointer::Builder::isImplicitMethodParameter() { - return which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER; -} -inline typename Type::AnyPointer::ImplicitMethodParameter::Reader Type::AnyPointer::Reader::getImplicitMethodParameter() const { - KJ_IREQUIRE((which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::ImplicitMethodParameter::Reader(_reader); -} -inline typename Type::AnyPointer::ImplicitMethodParameter::Builder Type::AnyPointer::Builder::getImplicitMethodParameter() { - KJ_IREQUIRE((which() == Type::AnyPointer::IMPLICIT_METHOD_PARAMETER), - "Must check which() before get()ing a union member."); - return typename Type::AnyPointer::ImplicitMethodParameter::Builder(_builder); -} -inline typename Type::AnyPointer::ImplicitMethodParameter::Builder Type::AnyPointer::Builder::initImplicitMethodParameter() { - _builder.setDataField( - ::capnp::bounded<4>() * ::capnp::ELEMENTS, Type::AnyPointer::IMPLICIT_METHOD_PARAMETER); - _builder.setDataField< ::uint16_t>(::capnp::bounded<5>() * ::capnp::ELEMENTS, 0); - return typename Type::AnyPointer::ImplicitMethodParameter::Builder(_builder); -} -inline ::capnp::schema::Type::AnyPointer::Unconstrained::Which Type::AnyPointer::Unconstrained::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<5>() * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Type::AnyPointer::Unconstrained::Which Type::AnyPointer::Unconstrained::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<5>() * ::capnp::ELEMENTS); -} - -inline bool Type::AnyPointer::Unconstrained::Reader::isAnyKind() const { - return which() == Type::AnyPointer::Unconstrained::ANY_KIND; -} -inline bool Type::AnyPointer::Unconstrained::Builder::isAnyKind() { - return which() == Type::AnyPointer::Unconstrained::ANY_KIND; -} -inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getAnyKind() const { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::ANY_KIND), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getAnyKind() { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::ANY_KIND), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::AnyPointer::Unconstrained::Builder::setAnyKind( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<5>() * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::ANY_KIND); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::AnyPointer::Unconstrained::Reader::isStruct() const { - return which() == Type::AnyPointer::Unconstrained::STRUCT; -} -inline bool Type::AnyPointer::Unconstrained::Builder::isStruct() { - return which() == Type::AnyPointer::Unconstrained::STRUCT; -} -inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getStruct() const { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::STRUCT), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getStruct() { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::STRUCT), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::AnyPointer::Unconstrained::Builder::setStruct( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<5>() * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::STRUCT); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::AnyPointer::Unconstrained::Reader::isList() const { - return which() == Type::AnyPointer::Unconstrained::LIST; -} -inline bool Type::AnyPointer::Unconstrained::Builder::isList() { - return which() == Type::AnyPointer::Unconstrained::LIST; -} -inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getList() const { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::LIST), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getList() { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::LIST), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::AnyPointer::Unconstrained::Builder::setList( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<5>() * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::LIST); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Type::AnyPointer::Unconstrained::Reader::isCapability() const { - return which() == Type::AnyPointer::Unconstrained::CAPABILITY; -} -inline bool Type::AnyPointer::Unconstrained::Builder::isCapability() { - return which() == Type::AnyPointer::Unconstrained::CAPABILITY; -} -inline ::capnp::Void Type::AnyPointer::Unconstrained::Reader::getCapability() const { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::CAPABILITY), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Type::AnyPointer::Unconstrained::Builder::getCapability() { - KJ_IREQUIRE((which() == Type::AnyPointer::Unconstrained::CAPABILITY), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Type::AnyPointer::Unconstrained::Builder::setCapability( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<5>() * ::capnp::ELEMENTS, Type::AnyPointer::Unconstrained::CAPABILITY); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline ::uint64_t Type::AnyPointer::Parameter::Reader::getScopeId() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Type::AnyPointer::Parameter::Builder::getScopeId() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} -inline void Type::AnyPointer::Parameter::Builder::setScopeId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t Type::AnyPointer::Parameter::Reader::getParameterIndex() const { - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<5>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t Type::AnyPointer::Parameter::Builder::getParameterIndex() { - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<5>() * ::capnp::ELEMENTS); -} -inline void Type::AnyPointer::Parameter::Builder::setParameterIndex( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<5>() * ::capnp::ELEMENTS, value); -} - -inline ::uint16_t Type::AnyPointer::ImplicitMethodParameter::Reader::getParameterIndex() const { - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<5>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t Type::AnyPointer::ImplicitMethodParameter::Builder::getParameterIndex() { - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<5>() * ::capnp::ELEMENTS); -} -inline void Type::AnyPointer::ImplicitMethodParameter::Builder::setParameterIndex( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<5>() * ::capnp::ELEMENTS, value); -} - -inline bool Brand::Reader::hasScopes() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Brand::Builder::hasScopes() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Brand::Scope>::Reader Brand::Reader::getScopes() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder Brand::Builder::getScopes() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Brand::Builder::setScopes( ::capnp::List< ::capnp::schema::Brand::Scope>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Brand::Scope>::Builder Brand::Builder::initScopes(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void Brand::Builder::adoptScopes( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Scope>> Brand::Builder::disownScopes() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Scope>>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::capnp::schema::Brand::Scope::Which Brand::Scope::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<4>() * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Brand::Scope::Which Brand::Scope::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<4>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Brand::Scope::Reader::getScopeId() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Brand::Scope::Builder::getScopeId() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Brand::Scope::Builder::setScopeId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Brand::Scope::Reader::isBind() const { - return which() == Brand::Scope::BIND; -} -inline bool Brand::Scope::Builder::isBind() { - return which() == Brand::Scope::BIND; -} -inline bool Brand::Scope::Reader::hasBind() const { - if (which() != Brand::Scope::BIND) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Brand::Scope::Builder::hasBind() { - if (which() != Brand::Scope::BIND) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Brand::Binding>::Reader Brand::Scope::Reader::getBind() const { - KJ_IREQUIRE((which() == Brand::Scope::BIND), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder Brand::Scope::Builder::getBind() { - KJ_IREQUIRE((which() == Brand::Scope::BIND), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Brand::Scope::Builder::setBind( ::capnp::List< ::capnp::schema::Brand::Binding>::Reader value) { - _builder.setDataField( - ::capnp::bounded<4>() * ::capnp::ELEMENTS, Brand::Scope::BIND); - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Brand::Binding>::Builder Brand::Scope::Builder::initBind(unsigned int size) { - _builder.setDataField( - ::capnp::bounded<4>() * ::capnp::ELEMENTS, Brand::Scope::BIND); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void Brand::Scope::Builder::adoptBind( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>>&& value) { - _builder.setDataField( - ::capnp::bounded<4>() * ::capnp::ELEMENTS, Brand::Scope::BIND); - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Brand::Binding>> Brand::Scope::Builder::disownBind() { - KJ_IREQUIRE((which() == Brand::Scope::BIND), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Brand::Binding>>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Brand::Scope::Reader::isInherit() const { - return which() == Brand::Scope::INHERIT; -} -inline bool Brand::Scope::Builder::isInherit() { - return which() == Brand::Scope::INHERIT; -} -inline ::capnp::Void Brand::Scope::Reader::getInherit() const { - KJ_IREQUIRE((which() == Brand::Scope::INHERIT), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Brand::Scope::Builder::getInherit() { - KJ_IREQUIRE((which() == Brand::Scope::INHERIT), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Brand::Scope::Builder::setInherit( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<4>() * ::capnp::ELEMENTS, Brand::Scope::INHERIT); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline ::capnp::schema::Brand::Binding::Which Brand::Binding::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Brand::Binding::Which Brand::Binding::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline bool Brand::Binding::Reader::isUnbound() const { - return which() == Brand::Binding::UNBOUND; -} -inline bool Brand::Binding::Builder::isUnbound() { - return which() == Brand::Binding::UNBOUND; -} -inline ::capnp::Void Brand::Binding::Reader::getUnbound() const { - KJ_IREQUIRE((which() == Brand::Binding::UNBOUND), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Brand::Binding::Builder::getUnbound() { - KJ_IREQUIRE((which() == Brand::Binding::UNBOUND), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Brand::Binding::Builder::setUnbound( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Brand::Binding::UNBOUND); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Brand::Binding::Reader::isType() const { - return which() == Brand::Binding::TYPE; -} -inline bool Brand::Binding::Builder::isType() { - return which() == Brand::Binding::TYPE; -} -inline bool Brand::Binding::Reader::hasType() const { - if (which() != Brand::Binding::TYPE) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Brand::Binding::Builder::hasType() { - if (which() != Brand::Binding::TYPE) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Type::Reader Brand::Binding::Reader::getType() const { - KJ_IREQUIRE((which() == Brand::Binding::TYPE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::Type::Builder Brand::Binding::Builder::getType() { - KJ_IREQUIRE((which() == Brand::Binding::TYPE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Brand::Binding::Builder::setType( ::capnp::schema::Type::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Brand::Binding::TYPE); - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Type::Builder Brand::Binding::Builder::initType() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Brand::Binding::TYPE); - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Brand::Binding::Builder::adoptType( - ::capnp::Orphan< ::capnp::schema::Type>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Brand::Binding::TYPE); - ::capnp::_::PointerHelpers< ::capnp::schema::Type>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Type> Brand::Binding::Builder::disownType() { - KJ_IREQUIRE((which() == Brand::Binding::TYPE), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::schema::Type>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline ::capnp::schema::Value::Which Value::Reader::which() const { - return _reader.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline ::capnp::schema::Value::Which Value::Builder::which() { - return _builder.getDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline bool Value::Reader::isVoid() const { - return which() == Value::VOID; -} -inline bool Value::Builder::isVoid() { - return which() == Value::VOID; -} -inline ::capnp::Void Value::Reader::getVoid() const { - KJ_IREQUIRE((which() == Value::VOID), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Value::Builder::getVoid() { - KJ_IREQUIRE((which() == Value::VOID), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Value::Builder::setVoid( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::VOID); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isBool() const { - return which() == Value::BOOL; -} -inline bool Value::Builder::isBool() { - return which() == Value::BOOL; -} -inline bool Value::Reader::getBool() const { - KJ_IREQUIRE((which() == Value::BOOL), - "Must check which() before get()ing a union member."); - return _reader.getDataField( - ::capnp::bounded<16>() * ::capnp::ELEMENTS); -} - -inline bool Value::Builder::getBool() { - KJ_IREQUIRE((which() == Value::BOOL), - "Must check which() before get()ing a union member."); - return _builder.getDataField( - ::capnp::bounded<16>() * ::capnp::ELEMENTS); -} -inline void Value::Builder::setBool(bool value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::BOOL); - _builder.setDataField( - ::capnp::bounded<16>() * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isInt8() const { - return which() == Value::INT8; -} -inline bool Value::Builder::isInt8() { - return which() == Value::INT8; -} -inline ::int8_t Value::Reader::getInt8() const { - KJ_IREQUIRE((which() == Value::INT8), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::int8_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} - -inline ::int8_t Value::Builder::getInt8() { - KJ_IREQUIRE((which() == Value::INT8), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::int8_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} -inline void Value::Builder::setInt8( ::int8_t value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::INT8); - _builder.setDataField< ::int8_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isInt16() const { - return which() == Value::INT16; -} -inline bool Value::Builder::isInt16() { - return which() == Value::INT16; -} -inline ::int16_t Value::Reader::getInt16() const { - KJ_IREQUIRE((which() == Value::INT16), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::int16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::int16_t Value::Builder::getInt16() { - KJ_IREQUIRE((which() == Value::INT16), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::int16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Value::Builder::setInt16( ::int16_t value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::INT16); - _builder.setDataField< ::int16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isInt32() const { - return which() == Value::INT32; -} -inline bool Value::Builder::isInt32() { - return which() == Value::INT32; -} -inline ::int32_t Value::Reader::getInt32() const { - KJ_IREQUIRE((which() == Value::INT32), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::int32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::int32_t Value::Builder::getInt32() { - KJ_IREQUIRE((which() == Value::INT32), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::int32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Value::Builder::setInt32( ::int32_t value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::INT32); - _builder.setDataField< ::int32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isInt64() const { - return which() == Value::INT64; -} -inline bool Value::Builder::isInt64() { - return which() == Value::INT64; -} -inline ::int64_t Value::Reader::getInt64() const { - KJ_IREQUIRE((which() == Value::INT64), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::int64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::int64_t Value::Builder::getInt64() { - KJ_IREQUIRE((which() == Value::INT64), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::int64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Value::Builder::setInt64( ::int64_t value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::INT64); - _builder.setDataField< ::int64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isUint8() const { - return which() == Value::UINT8; -} -inline bool Value::Builder::isUint8() { - return which() == Value::UINT8; -} -inline ::uint8_t Value::Reader::getUint8() const { - KJ_IREQUIRE((which() == Value::UINT8), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint8_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} - -inline ::uint8_t Value::Builder::getUint8() { - KJ_IREQUIRE((which() == Value::UINT8), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint8_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} -inline void Value::Builder::setUint8( ::uint8_t value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::UINT8); - _builder.setDataField< ::uint8_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isUint16() const { - return which() == Value::UINT16; -} -inline bool Value::Builder::isUint16() { - return which() == Value::UINT16; -} -inline ::uint16_t Value::Reader::getUint16() const { - KJ_IREQUIRE((which() == Value::UINT16), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t Value::Builder::getUint16() { - KJ_IREQUIRE((which() == Value::UINT16), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Value::Builder::setUint16( ::uint16_t value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::UINT16); - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isUint32() const { - return which() == Value::UINT32; -} -inline bool Value::Builder::isUint32() { - return which() == Value::UINT32; -} -inline ::uint32_t Value::Reader::getUint32() const { - KJ_IREQUIRE((which() == Value::UINT32), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint32_t Value::Builder::getUint32() { - KJ_IREQUIRE((which() == Value::UINT32), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Value::Builder::setUint32( ::uint32_t value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::UINT32); - _builder.setDataField< ::uint32_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isUint64() const { - return which() == Value::UINT64; -} -inline bool Value::Builder::isUint64() { - return which() == Value::UINT64; -} -inline ::uint64_t Value::Reader::getUint64() const { - KJ_IREQUIRE((which() == Value::UINT64), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Value::Builder::getUint64() { - KJ_IREQUIRE((which() == Value::UINT64), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Value::Builder::setUint64( ::uint64_t value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::UINT64); - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isFloat32() const { - return which() == Value::FLOAT32; -} -inline bool Value::Builder::isFloat32() { - return which() == Value::FLOAT32; -} -inline float Value::Reader::getFloat32() const { - KJ_IREQUIRE((which() == Value::FLOAT32), - "Must check which() before get()ing a union member."); - return _reader.getDataField( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline float Value::Builder::getFloat32() { - KJ_IREQUIRE((which() == Value::FLOAT32), - "Must check which() before get()ing a union member."); - return _builder.getDataField( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Value::Builder::setFloat32(float value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::FLOAT32); - _builder.setDataField( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isFloat64() const { - return which() == Value::FLOAT64; -} -inline bool Value::Builder::isFloat64() { - return which() == Value::FLOAT64; -} -inline double Value::Reader::getFloat64() const { - KJ_IREQUIRE((which() == Value::FLOAT64), - "Must check which() before get()ing a union member."); - return _reader.getDataField( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline double Value::Builder::getFloat64() { - KJ_IREQUIRE((which() == Value::FLOAT64), - "Must check which() before get()ing a union member."); - return _builder.getDataField( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Value::Builder::setFloat64(double value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::FLOAT64); - _builder.setDataField( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isText() const { - return which() == Value::TEXT; -} -inline bool Value::Builder::isText() { - return which() == Value::TEXT; -} -inline bool Value::Reader::hasText() const { - if (which() != Value::TEXT) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Value::Builder::hasText() { - if (which() != Value::TEXT) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader Value::Reader::getText() const { - KJ_IREQUIRE((which() == Value::TEXT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder Value::Builder::getText() { - KJ_IREQUIRE((which() == Value::TEXT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Value::Builder::setText( ::capnp::Text::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::TEXT); - ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder Value::Builder::initText(unsigned int size) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::TEXT); - return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void Value::Builder::adoptText( - ::capnp::Orphan< ::capnp::Text>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::TEXT); - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> Value::Builder::disownText() { - KJ_IREQUIRE((which() == Value::TEXT), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Value::Reader::isData() const { - return which() == Value::DATA; -} -inline bool Value::Builder::isData() { - return which() == Value::DATA; -} -inline bool Value::Reader::hasData() const { - if (which() != Value::DATA) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Value::Builder::hasData() { - if (which() != Value::DATA) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Data::Reader Value::Reader::getData() const { - KJ_IREQUIRE((which() == Value::DATA), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::Data>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::Data::Builder Value::Builder::getData() { - KJ_IREQUIRE((which() == Value::DATA), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::Data>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Value::Builder::setData( ::capnp::Data::Reader value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::DATA); - ::capnp::_::PointerHelpers< ::capnp::Data>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::Data::Builder Value::Builder::initData(unsigned int size) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::DATA); - return ::capnp::_::PointerHelpers< ::capnp::Data>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void Value::Builder::adoptData( - ::capnp::Orphan< ::capnp::Data>&& value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::DATA); - ::capnp::_::PointerHelpers< ::capnp::Data>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Data> Value::Builder::disownData() { - KJ_IREQUIRE((which() == Value::DATA), - "Must check which() before get()ing a union member."); - return ::capnp::_::PointerHelpers< ::capnp::Data>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Value::Reader::isList() const { - return which() == Value::LIST; -} -inline bool Value::Builder::isList() { - return which() == Value::LIST; -} -inline bool Value::Reader::hasList() const { - if (which() != Value::LIST) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Value::Builder::hasList() { - if (which() != Value::LIST) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Value::Reader::getList() const { - KJ_IREQUIRE((which() == Value::LIST), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Reader(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Value::Builder::getList() { - KJ_IREQUIRE((which() == Value::LIST), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Value::Builder::initList() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::LIST); - auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline bool Value::Reader::isEnum() const { - return which() == Value::ENUM; -} -inline bool Value::Builder::isEnum() { - return which() == Value::ENUM; -} -inline ::uint16_t Value::Reader::getEnum() const { - KJ_IREQUIRE((which() == Value::ENUM), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t Value::Builder::getEnum() { - KJ_IREQUIRE((which() == Value::ENUM), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS); -} -inline void Value::Builder::setEnum( ::uint16_t value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::ENUM); - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<1>() * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isStruct() const { - return which() == Value::STRUCT; -} -inline bool Value::Builder::isStruct() { - return which() == Value::STRUCT; -} -inline bool Value::Reader::hasStruct() const { - if (which() != Value::STRUCT) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Value::Builder::hasStruct() { - if (which() != Value::STRUCT) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Value::Reader::getStruct() const { - KJ_IREQUIRE((which() == Value::STRUCT), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Reader(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Value::Builder::getStruct() { - KJ_IREQUIRE((which() == Value::STRUCT), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Value::Builder::initStruct() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::STRUCT); - auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline bool Value::Reader::isInterface() const { - return which() == Value::INTERFACE; -} -inline bool Value::Builder::isInterface() { - return which() == Value::INTERFACE; -} -inline ::capnp::Void Value::Reader::getInterface() const { - KJ_IREQUIRE((which() == Value::INTERFACE), - "Must check which() before get()ing a union member."); - return _reader.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::capnp::Void Value::Builder::getInterface() { - KJ_IREQUIRE((which() == Value::INTERFACE), - "Must check which() before get()ing a union member."); - return _builder.getDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Value::Builder::setInterface( ::capnp::Void value) { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::INTERFACE); - _builder.setDataField< ::capnp::Void>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Value::Reader::isAnyPointer() const { - return which() == Value::ANY_POINTER; -} -inline bool Value::Builder::isAnyPointer() { - return which() == Value::ANY_POINTER; -} -inline bool Value::Reader::hasAnyPointer() const { - if (which() != Value::ANY_POINTER) return false; - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Value::Builder::hasAnyPointer() { - if (which() != Value::ANY_POINTER) return false; - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::AnyPointer::Reader Value::Reader::getAnyPointer() const { - KJ_IREQUIRE((which() == Value::ANY_POINTER), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Reader(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Value::Builder::getAnyPointer() { - KJ_IREQUIRE((which() == Value::ANY_POINTER), - "Must check which() before get()ing a union member."); - return ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::AnyPointer::Builder Value::Builder::initAnyPointer() { - _builder.setDataField( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::ANY_POINTER); - auto result = ::capnp::AnyPointer::Builder(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); - result.clear(); - return result; -} - -inline ::uint64_t Annotation::Reader::getId() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t Annotation::Builder::getId() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void Annotation::Builder::setId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool Annotation::Reader::hasValue() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool Annotation::Builder::hasValue() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Value::Reader Annotation::Reader::getValue() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::Value::Builder Annotation::Builder::getValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Value::Pipeline Annotation::Pipeline::getValue() { - return ::capnp::schema::Value::Pipeline(_typeless.getPointerField(0)); -} -#endif // !CAPNP_LITE -inline void Annotation::Builder::setValue( ::capnp::schema::Value::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Value>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Value::Builder Annotation::Builder::initValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void Annotation::Builder::adoptValue( - ::capnp::Orphan< ::capnp::schema::Value>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Value>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Value> Annotation::Builder::disownValue() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Value>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool Annotation::Reader::hasBrand() const { - return !_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline bool Annotation::Builder::hasBrand() { - return !_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::Brand::Reader Annotation::Reader::getBrand() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::Brand::Builder Annotation::Builder::getBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::get(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::Brand::Pipeline Annotation::Pipeline::getBrand() { - return ::capnp::schema::Brand::Pipeline(_typeless.getPointerField(1)); -} -#endif // !CAPNP_LITE -inline void Annotation::Builder::setBrand( ::capnp::schema::Brand::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::set(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::Brand::Builder Annotation::Builder::initBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::init(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline void Annotation::Builder::adoptBrand( - ::capnp::Orphan< ::capnp::schema::Brand>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::adopt(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::Brand> Annotation::Builder::disownBrand() { - return ::capnp::_::PointerHelpers< ::capnp::schema::Brand>::disown(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} - -inline ::uint16_t CapnpVersion::Reader::getMajor() const { - return _reader.getDataField< ::uint16_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint16_t CapnpVersion::Builder::getMajor() { - return _builder.getDataField< ::uint16_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void CapnpVersion::Builder::setMajor( ::uint16_t value) { - _builder.setDataField< ::uint16_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline ::uint8_t CapnpVersion::Reader::getMinor() const { - return _reader.getDataField< ::uint8_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} - -inline ::uint8_t CapnpVersion::Builder::getMinor() { - return _builder.getDataField< ::uint8_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS); -} -inline void CapnpVersion::Builder::setMinor( ::uint8_t value) { - _builder.setDataField< ::uint8_t>( - ::capnp::bounded<2>() * ::capnp::ELEMENTS, value); -} - -inline ::uint8_t CapnpVersion::Reader::getMicro() const { - return _reader.getDataField< ::uint8_t>( - ::capnp::bounded<3>() * ::capnp::ELEMENTS); -} - -inline ::uint8_t CapnpVersion::Builder::getMicro() { - return _builder.getDataField< ::uint8_t>( - ::capnp::bounded<3>() * ::capnp::ELEMENTS); -} -inline void CapnpVersion::Builder::setMicro( ::uint8_t value) { - _builder.setDataField< ::uint8_t>( - ::capnp::bounded<3>() * ::capnp::ELEMENTS, value); -} - -inline bool CodeGeneratorRequest::Reader::hasNodes() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool CodeGeneratorRequest::Builder::hasNodes() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::Node>::Reader CodeGeneratorRequest::Reader::getNodes() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::Node>::Builder CodeGeneratorRequest::Builder::getNodes() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void CodeGeneratorRequest::Builder::setNodes( ::capnp::List< ::capnp::schema::Node>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::Node>::Builder CodeGeneratorRequest::Builder::initNodes(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void CodeGeneratorRequest::Builder::adoptNodes( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::Node>> CodeGeneratorRequest::Builder::disownNodes() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::Node>>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool CodeGeneratorRequest::Reader::hasRequestedFiles() const { - return !_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline bool CodeGeneratorRequest::Builder::hasRequestedFiles() { - return !_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader CodeGeneratorRequest::Reader::getRequestedFiles() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::get(_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder CodeGeneratorRequest::Builder::getRequestedFiles() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::get(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline void CodeGeneratorRequest::Builder::setRequestedFiles( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::set(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>::Builder CodeGeneratorRequest::Builder::initRequestedFiles(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::init(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), size); -} -inline void CodeGeneratorRequest::Builder::adoptRequestedFiles( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::adopt(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>> CodeGeneratorRequest::Builder::disownRequestedFiles() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile>>::disown(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} - -inline bool CodeGeneratorRequest::Reader::hasCapnpVersion() const { - return !_reader.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); -} -inline bool CodeGeneratorRequest::Builder::hasCapnpVersion() { - return !_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::schema::CapnpVersion::Reader CodeGeneratorRequest::Reader::getCapnpVersion() const { - return ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::get(_reader.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} -inline ::capnp::schema::CapnpVersion::Builder CodeGeneratorRequest::Builder::getCapnpVersion() { - return ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::get(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} -#if !CAPNP_LITE -inline ::capnp::schema::CapnpVersion::Pipeline CodeGeneratorRequest::Pipeline::getCapnpVersion() { - return ::capnp::schema::CapnpVersion::Pipeline(_typeless.getPointerField(2)); -} -#endif // !CAPNP_LITE -inline void CodeGeneratorRequest::Builder::setCapnpVersion( ::capnp::schema::CapnpVersion::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::set(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS), value); -} -inline ::capnp::schema::CapnpVersion::Builder CodeGeneratorRequest::Builder::initCapnpVersion() { - return ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::init(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} -inline void CodeGeneratorRequest::Builder::adoptCapnpVersion( - ::capnp::Orphan< ::capnp::schema::CapnpVersion>&& value) { - ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::adopt(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::schema::CapnpVersion> CodeGeneratorRequest::Builder::disownCapnpVersion() { - return ::capnp::_::PointerHelpers< ::capnp::schema::CapnpVersion>::disown(_builder.getPointerField( - ::capnp::bounded<2>() * ::capnp::POINTERS)); -} - -inline ::uint64_t CodeGeneratorRequest::RequestedFile::Reader::getId() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t CodeGeneratorRequest::RequestedFile::Builder::getId() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void CodeGeneratorRequest::RequestedFile::Builder::setId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool CodeGeneratorRequest::RequestedFile::Reader::hasFilename() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool CodeGeneratorRequest::RequestedFile::Builder::hasFilename() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader CodeGeneratorRequest::RequestedFile::Reader::getFilename() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Builder::getFilename() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void CodeGeneratorRequest::RequestedFile::Builder::setFilename( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Builder::initFilename(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void CodeGeneratorRequest::RequestedFile::Builder::adoptFilename( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> CodeGeneratorRequest::RequestedFile::Builder::disownFilename() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -inline bool CodeGeneratorRequest::RequestedFile::Reader::hasImports() const { - return !_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline bool CodeGeneratorRequest::RequestedFile::Builder::hasImports() { - return !_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader CodeGeneratorRequest::RequestedFile::Reader::getImports() const { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::get(_reader.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder CodeGeneratorRequest::RequestedFile::Builder::getImports() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::get(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} -inline void CodeGeneratorRequest::RequestedFile::Builder::setImports( ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::set(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), value); -} -inline ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>::Builder CodeGeneratorRequest::RequestedFile::Builder::initImports(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::init(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), size); -} -inline void CodeGeneratorRequest::RequestedFile::Builder::adoptImports( - ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>&& value) { - ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::adopt(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>> CodeGeneratorRequest::RequestedFile::Builder::disownImports() { - return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::schema::CodeGeneratorRequest::RequestedFile::Import>>::disown(_builder.getPointerField( - ::capnp::bounded<1>() * ::capnp::POINTERS)); -} - -inline ::uint64_t CodeGeneratorRequest::RequestedFile::Import::Reader::getId() const { - return _reader.getDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} - -inline ::uint64_t CodeGeneratorRequest::RequestedFile::Import::Builder::getId() { - return _builder.getDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS); -} -inline void CodeGeneratorRequest::RequestedFile::Import::Builder::setId( ::uint64_t value) { - _builder.setDataField< ::uint64_t>( - ::capnp::bounded<0>() * ::capnp::ELEMENTS, value); -} - -inline bool CodeGeneratorRequest::RequestedFile::Import::Reader::hasName() const { - return !_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline bool CodeGeneratorRequest::RequestedFile::Import::Builder::hasName() { - return !_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS).isNull(); -} -inline ::capnp::Text::Reader CodeGeneratorRequest::RequestedFile::Import::Reader::getName() const { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Import::Builder::getName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} -inline void CodeGeneratorRequest::RequestedFile::Import::Builder::setName( ::capnp::Text::Reader value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), value); -} -inline ::capnp::Text::Builder CodeGeneratorRequest::RequestedFile::Import::Builder::initName(unsigned int size) { - return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), size); -} -inline void CodeGeneratorRequest::RequestedFile::Import::Builder::adoptName( - ::capnp::Orphan< ::capnp::Text>&& value) { - ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value)); -} -inline ::capnp::Orphan< ::capnp::Text> CodeGeneratorRequest::RequestedFile::Import::Builder::disownName() { - return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField( - ::capnp::bounded<0>() * ::capnp::POINTERS)); -} - -} // namespace -} // namespace - -#endif // CAPNP_INCLUDED_a93fc509624c72d9_ diff --git a/phonelibs/capnp-cpp/include/capnp/schema.h b/phonelibs/capnp-cpp/include/capnp/schema.h deleted file mode 100644 index d59fa7523668d3..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/schema.h +++ /dev/null @@ -1,934 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_SCHEMA_H_ -#define CAPNP_SCHEMA_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#if CAPNP_LITE -#error "Reflection APIs, including this header, are not available in lite mode." -#endif - -#include - -namespace capnp { - -class Schema; -class StructSchema; -class EnumSchema; -class InterfaceSchema; -class ConstSchema; -class ListSchema; -class Type; - -template ()> struct SchemaType_ { typedef Schema Type; }; -template struct SchemaType_ { typedef schema::Type::Which Type; }; -template struct SchemaType_ { typedef schema::Type::Which Type; }; -template struct SchemaType_ { typedef EnumSchema Type; }; -template struct SchemaType_ { typedef StructSchema Type; }; -template struct SchemaType_ { typedef InterfaceSchema Type; }; -template struct SchemaType_ { typedef ListSchema Type; }; - -template -using SchemaType = typename SchemaType_::Type; -// SchemaType is the type of T's schema, e.g. StructSchema if T is a struct. - -namespace _ { // private -extern const RawSchema NULL_SCHEMA; -extern const RawSchema NULL_STRUCT_SCHEMA; -extern const RawSchema NULL_ENUM_SCHEMA; -extern const RawSchema NULL_INTERFACE_SCHEMA; -extern const RawSchema NULL_CONST_SCHEMA; -// The schema types default to these null (empty) schemas in case of error, especially when -// exceptions are disabled. -} // namespace _ (private) - -class Schema { - // Convenience wrapper around capnp::schema::Node. - -public: - inline Schema(): raw(&_::NULL_SCHEMA.defaultBrand) {} - - template - static inline SchemaType from() { return SchemaType::template fromImpl(); } - // Get the Schema for a particular compiled-in type. - - schema::Node::Reader getProto() const; - // Get the underlying Cap'n Proto representation of the schema node. (Note that this accessor - // has performance comparable to accessors of struct-typed fields on Reader classes.) - - kj::ArrayPtr asUncheckedMessage() const; - // Get the encoded schema node content as a single message segment. It is safe to read as an - // unchecked message. - - Schema getDependency(uint64_t id) const KJ_DEPRECATED("Does not handle generics correctly."); - // DEPRECATED: This method cannot correctly account for generic type parameter bindings that - // may apply to the dependency. Instead of using this method, use a method of the Schema API - // that corresponds to the exact kind of dependency. For example, to get a field type, use - // StructSchema::Field::getType(). - // - // Gets the Schema for one of this Schema's dependencies. For example, if this Schema is for a - // struct, you could look up the schema for one of its fields' types. Throws an exception if this - // schema doesn't actually depend on the given id. - // - // Note that not all type IDs found in the schema node are considered "dependencies" -- only the - // ones that are needed to implement the dynamic API are. That includes: - // - Field types. - // - Group types. - // - scopeId for group nodes, but NOT otherwise. - // - Method parameter and return types. - // - // The following are NOT considered dependencies: - // - Nested nodes. - // - scopeId for a non-group node. - // - Annotations. - // - // To obtain schemas for those, you would need a SchemaLoader. - - bool isBranded() const; - // Returns true if this schema represents a non-default parameterization of this type. - - Schema getGeneric() const; - // Get the version of this schema with any brands removed. - - class BrandArgumentList; - BrandArgumentList getBrandArgumentsAtScope(uint64_t scopeId) const; - // Gets the values bound to the brand parameters at the given scope. - - StructSchema asStruct() const; - EnumSchema asEnum() const; - InterfaceSchema asInterface() const; - ConstSchema asConst() const; - // Cast the Schema to a specific type. Throws an exception if the type doesn't match. Use - // getProto() to determine type, e.g. getProto().isStruct(). - - inline bool operator==(const Schema& other) const { return raw == other.raw; } - inline bool operator!=(const Schema& other) const { return raw != other.raw; } - // Determine whether two Schemas are wrapping the exact same underlying data, by identity. If - // you want to check if two Schemas represent the same type (but possibly different versions of - // it), compare their IDs instead. - - template - void requireUsableAs() const; - // Throws an exception if a value with this Schema cannot safely be cast to a native value of - // the given type. This passes if either: - // - *this == from() - // - This schema was loaded with SchemaLoader, the type ID matches typeId(), and - // loadCompiledTypeAndDependencies() was called on the SchemaLoader. - - kj::StringPtr getShortDisplayName() const; - // Get the short version of the node's display name. - -private: - const _::RawBrandedSchema* raw; - - inline explicit Schema(const _::RawBrandedSchema* raw): raw(raw) { - KJ_IREQUIRE(raw->lazyInitializer == nullptr, - "Must call ensureInitialized() on RawSchema before constructing Schema."); - } - - template static inline Schema fromImpl() { - return Schema(&_::rawSchema()); - } - - void requireUsableAs(const _::RawSchema* expected) const; - - uint32_t getSchemaOffset(const schema::Value::Reader& value) const; - - Type getBrandBinding(uint64_t scopeId, uint index) const; - // Look up the binding for a brand parameter used by this Schema. Returns `AnyPointer` if the - // parameter is not bound. - // - // TODO(someday): Public interface for iterating over all bindings? - - Schema getDependency(uint64_t id, uint location) const; - // Look up schema for a particular dependency of this schema. `location` is the dependency - // location number as defined in _::RawBrandedSchema. - - Type interpretType(schema::Type::Reader proto, uint location) const; - // Interpret a schema::Type in the given location within the schema, compiling it into a - // Type object. - - friend class StructSchema; - friend class EnumSchema; - friend class InterfaceSchema; - friend class ConstSchema; - friend class ListSchema; - friend class SchemaLoader; - friend class Type; - friend kj::StringTree _::structString( - _::StructReader reader, const _::RawBrandedSchema& schema); - friend kj::String _::enumString(uint16_t value, const _::RawBrandedSchema& schema); -}; - -kj::StringPtr KJ_STRINGIFY(const Schema& schema); - -class Schema::BrandArgumentList { - // A list of generic parameter bindings for parameters of some particular type. Note that since - // parameters on an outer type apply to all inner types as well, a deeply-nested type can have - // multiple BrandArgumentLists that apply to it. - // - // A BrandArgumentList only represents the arguments that the client of the type specified. Since - // new parameters can be added over time, this list may not cover all defined parameters for the - // type. Missing parameters should be treated as AnyPointer. This class's implementation of - // operator[] already does this for you; out-of-bounds access will safely return AnyPointer. - -public: - inline BrandArgumentList(): scopeId(0), size_(0), bindings(nullptr) {} - - inline uint size() const { return size_; } - Type operator[](uint index) const; - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - uint64_t scopeId; - uint size_; - bool isUnbound; - const _::RawBrandedSchema::Binding* bindings; - - inline BrandArgumentList(uint64_t scopeId, bool isUnbound) - : scopeId(scopeId), size_(0), isUnbound(isUnbound), bindings(nullptr) {} - inline BrandArgumentList(uint64_t scopeId, uint size, - const _::RawBrandedSchema::Binding* bindings) - : scopeId(scopeId), size_(size), isUnbound(false), bindings(bindings) {} - - friend class Schema; -}; - -// ------------------------------------------------------------------- - -class StructSchema: public Schema { -public: - inline StructSchema(): Schema(&_::NULL_STRUCT_SCHEMA.defaultBrand) {} - - class Field; - class FieldList; - class FieldSubset; - - FieldList getFields() const; - // List top-level fields of this struct. This list will contain top-level groups (including - // named unions) but not the members of those groups. The list does, however, contain the - // members of the unnamed union, if there is one. - - FieldSubset getUnionFields() const; - // If the field contains an unnamed union, get a list of fields in the union, ordered by - // ordinal. Since discriminant values are assigned sequentially by ordinal, you may index this - // list by discriminant value. - - FieldSubset getNonUnionFields() const; - // Get the fields of this struct which are not in an unnamed union, ordered by ordinal. - - kj::Maybe findFieldByName(kj::StringPtr name) const; - // Find the field with the given name, or return null if there is no such field. If the struct - // contains an unnamed union, then this will find fields of that union in addition to fields - // of the outer struct, since they exist in the same namespace. It will not, however, find - // members of groups (including named unions) -- you must first look up the group itself, - // then dig into its type. - - Field getFieldByName(kj::StringPtr name) const; - // Like findFieldByName() but throws an exception on failure. - - kj::Maybe getFieldByDiscriminant(uint16_t discriminant) const; - // Finds the field whose `discriminantValue` is equal to the given value, or returns null if - // there is no such field. (If the schema does not represent a union or a struct containing - // an unnamed union, then this always returns null.) - -private: - StructSchema(Schema base): Schema(base) {} - template static inline StructSchema fromImpl() { - return StructSchema(Schema(&_::rawBrandedSchema())); - } - friend class Schema; - friend class Type; -}; - -class StructSchema::Field { -public: - Field() = default; - - inline schema::Field::Reader getProto() const { return proto; } - inline StructSchema getContainingStruct() const { return parent; } - - inline uint getIndex() const { return index; } - // Get the index of this field within the containing struct or union. - - Type getType() const; - // Get the type of this field. Note that this is preferred over getProto().getType() as this - // method will apply generics. - - uint32_t getDefaultValueSchemaOffset() const; - // For struct, list, and object fields, returns the offset, in words, within the first segment of - // the struct's schema, where this field's default value pointer is located. The schema is - // always stored as a single-segment unchecked message, which in turn means that the default - // value pointer itself can be treated as the root of an unchecked message -- if you know where - // to find it, which is what this method helps you with. - // - // For blobs, returns the offset of the beginning of the blob's content within the first segment - // of the struct's schema. - // - // This is primarily useful for code generators. The C++ code generator, for example, embeds - // the entire schema as a raw word array within the generated code. Of course, to implement - // field accessors, it needs access to those fields' default values. Embedding separate copies - // of those default values would be redundant since they are already included in the schema, but - // seeking through the schema at runtime to find the default values would be ugly. Instead, - // the code generator can use getDefaultValueSchemaOffset() to find the offset of the default - // value within the schema, and can simply apply that offset at runtime. - // - // If the above does not make sense, you probably don't need this method. - - inline bool operator==(const Field& other) const; - inline bool operator!=(const Field& other) const { return !(*this == other); } - -private: - StructSchema parent; - uint index; - schema::Field::Reader proto; - - inline Field(StructSchema parent, uint index, schema::Field::Reader proto) - : parent(parent), index(index), proto(proto) {} - - friend class StructSchema; -}; - -kj::StringPtr KJ_STRINGIFY(const StructSchema::Field& field); - -class StructSchema::FieldList { -public: - FieldList() = default; // empty list - - inline uint size() const { return list.size(); } - inline Field operator[](uint index) const { return Field(parent, index, list[index]); } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - StructSchema parent; - List::Reader list; - - inline FieldList(StructSchema parent, List::Reader list) - : parent(parent), list(list) {} - - friend class StructSchema; -}; - -class StructSchema::FieldSubset { -public: - FieldSubset() = default; // empty list - - inline uint size() const { return size_; } - inline Field operator[](uint index) const { - return Field(parent, indices[index], list[indices[index]]); - } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - StructSchema parent; - List::Reader list; - const uint16_t* indices; - uint size_; - - inline FieldSubset(StructSchema parent, List::Reader list, - const uint16_t* indices, uint size) - : parent(parent), list(list), indices(indices), size_(size) {} - - friend class StructSchema; -}; - -// ------------------------------------------------------------------- - -class EnumSchema: public Schema { -public: - inline EnumSchema(): Schema(&_::NULL_ENUM_SCHEMA.defaultBrand) {} - - class Enumerant; - class EnumerantList; - - EnumerantList getEnumerants() const; - - kj::Maybe findEnumerantByName(kj::StringPtr name) const; - - Enumerant getEnumerantByName(kj::StringPtr name) const; - // Like findEnumerantByName() but throws an exception on failure. - -private: - EnumSchema(Schema base): Schema(base) {} - template static inline EnumSchema fromImpl() { - return EnumSchema(Schema(&_::rawBrandedSchema())); - } - friend class Schema; - friend class Type; -}; - -class EnumSchema::Enumerant { -public: - Enumerant() = default; - - inline schema::Enumerant::Reader getProto() const { return proto; } - inline EnumSchema getContainingEnum() const { return parent; } - - inline uint16_t getOrdinal() const { return ordinal; } - inline uint getIndex() const { return ordinal; } - - inline bool operator==(const Enumerant& other) const; - inline bool operator!=(const Enumerant& other) const { return !(*this == other); } - -private: - EnumSchema parent; - uint16_t ordinal; - schema::Enumerant::Reader proto; - - inline Enumerant(EnumSchema parent, uint16_t ordinal, schema::Enumerant::Reader proto) - : parent(parent), ordinal(ordinal), proto(proto) {} - - friend class EnumSchema; -}; - -class EnumSchema::EnumerantList { -public: - EnumerantList() = default; // empty list - - inline uint size() const { return list.size(); } - inline Enumerant operator[](uint index) const { return Enumerant(parent, index, list[index]); } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - EnumSchema parent; - List::Reader list; - - inline EnumerantList(EnumSchema parent, List::Reader list) - : parent(parent), list(list) {} - - friend class EnumSchema; -}; - -// ------------------------------------------------------------------- - -class InterfaceSchema: public Schema { -public: - inline InterfaceSchema(): Schema(&_::NULL_INTERFACE_SCHEMA.defaultBrand) {} - - class Method; - class MethodList; - - MethodList getMethods() const; - - kj::Maybe findMethodByName(kj::StringPtr name) const; - - Method getMethodByName(kj::StringPtr name) const; - // Like findMethodByName() but throws an exception on failure. - - class SuperclassList; - - SuperclassList getSuperclasses() const; - // Get the immediate superclasses of this type, after applying generics. - - bool extends(InterfaceSchema other) const; - // Returns true if `other` is a superclass of this interface (including if `other == *this`). - - kj::Maybe findSuperclass(uint64_t typeId) const; - // Find the superclass of this interface with the given type ID. Returns null if the interface - // extends no such type. - -private: - InterfaceSchema(Schema base): Schema(base) {} - template static inline InterfaceSchema fromImpl() { - return InterfaceSchema(Schema(&_::rawBrandedSchema())); - } - friend class Schema; - friend class Type; - - kj::Maybe findMethodByName(kj::StringPtr name, uint& counter) const; - bool extends(InterfaceSchema other, uint& counter) const; - kj::Maybe findSuperclass(uint64_t typeId, uint& counter) const; - // We protect against malicious schemas with large or cyclic hierarchies by cutting off the - // search when the counter reaches a threshold. -}; - -class InterfaceSchema::Method { -public: - Method() = default; - - inline schema::Method::Reader getProto() const { return proto; } - inline InterfaceSchema getContainingInterface() const { return parent; } - - inline uint16_t getOrdinal() const { return ordinal; } - inline uint getIndex() const { return ordinal; } - - StructSchema getParamType() const; - StructSchema getResultType() const; - // Get the parameter and result types, including substituting generic parameters. - - inline bool operator==(const Method& other) const; - inline bool operator!=(const Method& other) const { return !(*this == other); } - -private: - InterfaceSchema parent; - uint16_t ordinal; - schema::Method::Reader proto; - - inline Method(InterfaceSchema parent, uint16_t ordinal, - schema::Method::Reader proto) - : parent(parent), ordinal(ordinal), proto(proto) {} - - friend class InterfaceSchema; -}; - -class InterfaceSchema::MethodList { -public: - MethodList() = default; // empty list - - inline uint size() const { return list.size(); } - inline Method operator[](uint index) const { return Method(parent, index, list[index]); } - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - InterfaceSchema parent; - List::Reader list; - - inline MethodList(InterfaceSchema parent, List::Reader list) - : parent(parent), list(list) {} - - friend class InterfaceSchema; -}; - -class InterfaceSchema::SuperclassList { -public: - SuperclassList() = default; // empty list - - inline uint size() const { return list.size(); } - InterfaceSchema operator[](uint index) const; - - typedef _::IndexingIterator Iterator; - inline Iterator begin() const { return Iterator(this, 0); } - inline Iterator end() const { return Iterator(this, size()); } - -private: - InterfaceSchema parent; - List::Reader list; - - inline SuperclassList(InterfaceSchema parent, List::Reader list) - : parent(parent), list(list) {} - - friend class InterfaceSchema; -}; - -// ------------------------------------------------------------------- - -class ConstSchema: public Schema { - // Represents a constant declaration. - // - // `ConstSchema` can be implicitly cast to DynamicValue to read its value. - -public: - inline ConstSchema(): Schema(&_::NULL_CONST_SCHEMA.defaultBrand) {} - - template - ReaderFor as() const; - // Read the constant's value. This is a convenience method equivalent to casting the ConstSchema - // to a DynamicValue and then calling its `as()` method. For dependency reasons, this method - // is defined in , which you must #include explicitly. - - uint32_t getValueSchemaOffset() const; - // Much like StructSchema::Field::getDefaultValueSchemaOffset(), if the constant has pointer - // type, this gets the offset from the beginning of the constant's schema node to a pointer - // representing the constant value. - - Type getType() const; - -private: - ConstSchema(Schema base): Schema(base) {} - friend class Schema; -}; - -// ------------------------------------------------------------------- - -class Type { -public: - struct BrandParameter { - uint64_t scopeId; - uint index; - }; - struct ImplicitParameter { - uint index; - }; - - inline Type(); - inline Type(schema::Type::Which primitive); - inline Type(StructSchema schema); - inline Type(EnumSchema schema); - inline Type(InterfaceSchema schema); - inline Type(ListSchema schema); - inline Type(schema::Type::AnyPointer::Unconstrained::Which anyPointerKind); - inline Type(BrandParameter param); - inline Type(ImplicitParameter param); - - template - inline static Type from(); - - inline schema::Type::Which which() const; - - StructSchema asStruct() const; - EnumSchema asEnum() const; - InterfaceSchema asInterface() const; - ListSchema asList() const; - // Each of these methods may only be called if which() returns the corresponding type. - - kj::Maybe getBrandParameter() const; - // Only callable if which() returns ANY_POINTER. Returns null if the type is just a regular - // AnyPointer and not a parameter. - - kj::Maybe getImplicitParameter() const; - // Only callable if which() returns ANY_POINTER. Returns null if the type is just a regular - // AnyPointer and not a parameter. "Implicit parameters" refer to type parameters on methods. - - inline schema::Type::AnyPointer::Unconstrained::Which whichAnyPointerKind() const; - // Only callable if which() returns ANY_POINTER. - - inline bool isVoid() const; - inline bool isBool() const; - inline bool isInt8() const; - inline bool isInt16() const; - inline bool isInt32() const; - inline bool isInt64() const; - inline bool isUInt8() const; - inline bool isUInt16() const; - inline bool isUInt32() const; - inline bool isUInt64() const; - inline bool isFloat32() const; - inline bool isFloat64() const; - inline bool isText() const; - inline bool isData() const; - inline bool isList() const; - inline bool isEnum() const; - inline bool isStruct() const; - inline bool isInterface() const; - inline bool isAnyPointer() const; - - bool operator==(const Type& other) const; - inline bool operator!=(const Type& other) const { return !(*this == other); } - - size_t hashCode() const; - - inline Type wrapInList(uint depth = 1) const; - // Return the Type formed by wrapping this type in List() `depth` times. - - inline Type(schema::Type::Which derived, const _::RawBrandedSchema* schema); - // For internal use. - -private: - schema::Type::Which baseType; // type not including applications of List() - uint8_t listDepth; // 0 for T, 1 for List(T), 2 for List(List(T)), ... - - bool isImplicitParam; - // If true, this refers to an implicit method parameter. baseType must be ANY_POINTER, scopeId - // must be zero, and paramIndex indicates the parameter index. - - union { - uint16_t paramIndex; - // If baseType is ANY_POINTER but this Type actually refers to a type parameter, this is the - // index of the parameter among the parameters at its scope, and `scopeId` below is the type ID - // of the scope where the parameter was defined. - - schema::Type::AnyPointer::Unconstrained::Which anyPointerKind; - // If scopeId is zero and isImplicitParam is false. - }; - - union { - const _::RawBrandedSchema* schema; // if type is struct, enum, interface... - uint64_t scopeId; // if type is AnyPointer but it's actually a type parameter... - }; - - Type(schema::Type::Which baseType, uint8_t listDepth, const _::RawBrandedSchema* schema) - : baseType(baseType), listDepth(listDepth), schema(schema) { - KJ_IREQUIRE(baseType != schema::Type::ANY_POINTER); - } - - void requireUsableAs(Type expected) const; - - friend class ListSchema; // only for requireUsableAs() -}; - -// ------------------------------------------------------------------- - -class ListSchema { - // ListSchema is a little different because list types are not described by schema nodes. So, - // ListSchema doesn't subclass Schema. - -public: - ListSchema() = default; - - static ListSchema of(schema::Type::Which primitiveType); - static ListSchema of(StructSchema elementType); - static ListSchema of(EnumSchema elementType); - static ListSchema of(InterfaceSchema elementType); - static ListSchema of(ListSchema elementType); - static ListSchema of(Type elementType); - // Construct the schema for a list of the given type. - - static ListSchema of(schema::Type::Reader elementType, Schema context) - KJ_DEPRECATED("Does not handle generics correctly."); - // DEPRECATED: This method cannot correctly account for generic type parameter bindings that - // may apply to the input type. Instead of using this method, use a method of the Schema API - // that corresponds to the exact kind of dependency. For example, to get a field type, use - // StructSchema::Field::getType(). - // - // Construct from an element type schema. Requires a context which can handle getDependency() - // requests for any type ID found in the schema. - - Type getElementType() const; - - inline schema::Type::Which whichElementType() const; - // Get the element type's "which()". ListSchema does not actually store a schema::Type::Reader - // describing the element type, but if it did, this would be equivalent to calling - // .getBody().which() on that type. - - StructSchema getStructElementType() const; - EnumSchema getEnumElementType() const; - InterfaceSchema getInterfaceElementType() const; - ListSchema getListElementType() const; - // Get the schema for complex element types. Each of these throws an exception if the element - // type is not of the requested kind. - - inline bool operator==(const ListSchema& other) const { return elementType == other.elementType; } - inline bool operator!=(const ListSchema& other) const { return elementType != other.elementType; } - - template - void requireUsableAs() const; - -private: - Type elementType; - - inline explicit ListSchema(Type elementType): elementType(elementType) {} - - template - struct FromImpl; - template static inline ListSchema fromImpl() { - return FromImpl::get(); - } - - void requireUsableAs(ListSchema expected) const; - - friend class Schema; -}; - -// ======================================================================================= -// inline implementation - -template <> inline schema::Type::Which Schema::from() { return schema::Type::VOID; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::BOOL; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::INT8; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::INT16; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::INT32; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::INT64; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT8; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT16; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT32; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::UINT64; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::FLOAT32; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::FLOAT64; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::TEXT; } -template <> inline schema::Type::Which Schema::from() { return schema::Type::DATA; } - -inline Schema Schema::getDependency(uint64_t id) const { - return getDependency(id, 0); -} - -inline bool Schema::isBranded() const { - return raw != &raw->generic->defaultBrand; -} - -inline Schema Schema::getGeneric() const { - return Schema(&raw->generic->defaultBrand); -} - -template -inline void Schema::requireUsableAs() const { - requireUsableAs(&_::rawSchema()); -} - -inline bool StructSchema::Field::operator==(const Field& other) const { - return parent == other.parent && index == other.index; -} -inline bool EnumSchema::Enumerant::operator==(const Enumerant& other) const { - return parent == other.parent && ordinal == other.ordinal; -} -inline bool InterfaceSchema::Method::operator==(const Method& other) const { - return parent == other.parent && ordinal == other.ordinal; -} - -inline ListSchema ListSchema::of(StructSchema elementType) { - return ListSchema(Type(elementType)); -} -inline ListSchema ListSchema::of(EnumSchema elementType) { - return ListSchema(Type(elementType)); -} -inline ListSchema ListSchema::of(InterfaceSchema elementType) { - return ListSchema(Type(elementType)); -} -inline ListSchema ListSchema::of(ListSchema elementType) { - return ListSchema(Type(elementType)); -} -inline ListSchema ListSchema::of(Type elementType) { - return ListSchema(elementType); -} - -inline Type ListSchema::getElementType() const { - return elementType; -} - -inline schema::Type::Which ListSchema::whichElementType() const { - return elementType.which(); -} - -inline StructSchema ListSchema::getStructElementType() const { - return elementType.asStruct(); -} - -inline EnumSchema ListSchema::getEnumElementType() const { - return elementType.asEnum(); -} - -inline InterfaceSchema ListSchema::getInterfaceElementType() const { - return elementType.asInterface(); -} - -inline ListSchema ListSchema::getListElementType() const { - return elementType.asList(); -} - -template -inline void ListSchema::requireUsableAs() const { - static_assert(kind() == Kind::LIST, - "ListSchema::requireUsableAs() requires T is a list type."); - requireUsableAs(Schema::from()); -} - -inline void ListSchema::requireUsableAs(ListSchema expected) const { - elementType.requireUsableAs(expected.elementType); -} - -template -struct ListSchema::FromImpl> { - static inline ListSchema get() { return of(Schema::from()); } -}; - -inline Type::Type(): baseType(schema::Type::VOID), listDepth(0), schema(nullptr) {} -inline Type::Type(schema::Type::Which primitive) - : baseType(primitive), listDepth(0), isImplicitParam(false) { - KJ_IREQUIRE(primitive != schema::Type::STRUCT && - primitive != schema::Type::ENUM && - primitive != schema::Type::INTERFACE && - primitive != schema::Type::LIST); - if (primitive == schema::Type::ANY_POINTER) { - scopeId = 0; - anyPointerKind = schema::Type::AnyPointer::Unconstrained::ANY_KIND; - } else { - schema = nullptr; - } -} -inline Type::Type(schema::Type::Which derived, const _::RawBrandedSchema* schema) - : baseType(derived), listDepth(0), isImplicitParam(false), schema(schema) { - KJ_IREQUIRE(derived == schema::Type::STRUCT || - derived == schema::Type::ENUM || - derived == schema::Type::INTERFACE); -} - -inline Type::Type(StructSchema schema) - : baseType(schema::Type::STRUCT), listDepth(0), schema(schema.raw) {} -inline Type::Type(EnumSchema schema) - : baseType(schema::Type::ENUM), listDepth(0), schema(schema.raw) {} -inline Type::Type(InterfaceSchema schema) - : baseType(schema::Type::INTERFACE), listDepth(0), schema(schema.raw) {} -inline Type::Type(ListSchema schema) - : Type(schema.getElementType()) { ++listDepth; } -inline Type::Type(schema::Type::AnyPointer::Unconstrained::Which anyPointerKind) - : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(false), - anyPointerKind(anyPointerKind), scopeId(0) {} -inline Type::Type(BrandParameter param) - : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(false), - paramIndex(param.index), scopeId(param.scopeId) {} -inline Type::Type(ImplicitParameter param) - : baseType(schema::Type::ANY_POINTER), listDepth(0), isImplicitParam(true), - paramIndex(param.index), scopeId(0) {} - -inline schema::Type::Which Type::which() const { - return listDepth > 0 ? schema::Type::LIST : baseType; -} - -inline schema::Type::AnyPointer::Unconstrained::Which Type::whichAnyPointerKind() const { - KJ_IREQUIRE(baseType == schema::Type::ANY_POINTER); - return !isImplicitParam && scopeId == 0 ? anyPointerKind - : schema::Type::AnyPointer::Unconstrained::ANY_KIND; -} - -template -inline Type Type::from() { return Type(Schema::from()); } - -inline bool Type::isVoid () const { return baseType == schema::Type::VOID && listDepth == 0; } -inline bool Type::isBool () const { return baseType == schema::Type::BOOL && listDepth == 0; } -inline bool Type::isInt8 () const { return baseType == schema::Type::INT8 && listDepth == 0; } -inline bool Type::isInt16 () const { return baseType == schema::Type::INT16 && listDepth == 0; } -inline bool Type::isInt32 () const { return baseType == schema::Type::INT32 && listDepth == 0; } -inline bool Type::isInt64 () const { return baseType == schema::Type::INT64 && listDepth == 0; } -inline bool Type::isUInt8 () const { return baseType == schema::Type::UINT8 && listDepth == 0; } -inline bool Type::isUInt16 () const { return baseType == schema::Type::UINT16 && listDepth == 0; } -inline bool Type::isUInt32 () const { return baseType == schema::Type::UINT32 && listDepth == 0; } -inline bool Type::isUInt64 () const { return baseType == schema::Type::UINT64 && listDepth == 0; } -inline bool Type::isFloat32() const { return baseType == schema::Type::FLOAT32 && listDepth == 0; } -inline bool Type::isFloat64() const { return baseType == schema::Type::FLOAT64 && listDepth == 0; } -inline bool Type::isText () const { return baseType == schema::Type::TEXT && listDepth == 0; } -inline bool Type::isData () const { return baseType == schema::Type::DATA && listDepth == 0; } -inline bool Type::isList () const { return listDepth > 0; } -inline bool Type::isEnum () const { return baseType == schema::Type::ENUM && listDepth == 0; } -inline bool Type::isStruct () const { return baseType == schema::Type::STRUCT && listDepth == 0; } -inline bool Type::isInterface() const { - return baseType == schema::Type::INTERFACE && listDepth == 0; -} -inline bool Type::isAnyPointer() const { - return baseType == schema::Type::ANY_POINTER && listDepth == 0; -} - -inline Type Type::wrapInList(uint depth) const { - Type result = *this; - result.listDepth += depth; - return result; -} - -} // namespace capnp - -#endif // CAPNP_SCHEMA_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/serialize-async.h b/phonelibs/capnp-cpp/include/capnp/serialize-async.h deleted file mode 100644 index a16bfd8975a6c7..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/serialize-async.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_SERIALIZE_ASYNC_H_ -#define CAPNP_SERIALIZE_ASYNC_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include -#include "message.h" - -namespace capnp { - -kj::Promise> readMessage( - kj::AsyncInputStream& input, ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); -// Read a message asynchronously. -// -// `input` must remain valid until the returned promise resolves (or is canceled). -// -// `scratchSpace`, if provided, must remain valid until the returned MessageReader is destroyed. - -kj::Promise>> tryReadMessage( - kj::AsyncInputStream& input, ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); -// Like `readMessage` but returns null on EOF. - -kj::Promise writeMessage(kj::AsyncOutputStream& output, - kj::ArrayPtr> segments) - KJ_WARN_UNUSED_RESULT; -kj::Promise writeMessage(kj::AsyncOutputStream& output, MessageBuilder& builder) - KJ_WARN_UNUSED_RESULT; -// Write asynchronously. The parameters must remain valid until the returned promise resolves. - -// ======================================================================================= -// inline implementation details - -inline kj::Promise writeMessage(kj::AsyncOutputStream& output, MessageBuilder& builder) { - return writeMessage(output, builder.getSegmentsForOutput()); -} - -} // namespace capnp - -#endif // CAPNP_SERIALIZE_ASYNC_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/serialize-packed.h b/phonelibs/capnp-cpp/include/capnp/serialize-packed.h deleted file mode 100644 index a71260ce1dd4c1..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/serialize-packed.h +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_SERIALIZE_PACKED_H_ -#define CAPNP_SERIALIZE_PACKED_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "serialize.h" - -namespace capnp { - -namespace _ { // private - -class PackedInputStream: public kj::InputStream { - // An input stream that unpacks packed data with a picky constraint: The caller must read data - // in the exact same size and sequence as the data was written to PackedOutputStream. - -public: - explicit PackedInputStream(kj::BufferedInputStream& inner); - KJ_DISALLOW_COPY(PackedInputStream); - ~PackedInputStream() noexcept(false); - - // implements InputStream ------------------------------------------ - size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; - void skip(size_t bytes) override; - -private: - kj::BufferedInputStream& inner; -}; - -class PackedOutputStream: public kj::OutputStream { -public: - explicit PackedOutputStream(kj::BufferedOutputStream& inner); - KJ_DISALLOW_COPY(PackedOutputStream); - ~PackedOutputStream() noexcept(false); - - // implements OutputStream ----------------------------------------- - void write(const void* buffer, size_t bytes) override; - -private: - kj::BufferedOutputStream& inner; -}; - -} // namespace _ (private) - -class PackedMessageReader: private _::PackedInputStream, public InputStreamMessageReader { -public: - PackedMessageReader(kj::BufferedInputStream& inputStream, ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); - KJ_DISALLOW_COPY(PackedMessageReader); - ~PackedMessageReader() noexcept(false); -}; - -class PackedFdMessageReader: private kj::FdInputStream, private kj::BufferedInputStreamWrapper, - public PackedMessageReader { -public: - PackedFdMessageReader(int fd, ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); - // Read message from a file descriptor, without taking ownership of the descriptor. - // Note that if you want to reuse the descriptor after the reader is destroyed, you'll need to - // seek it, since otherwise the position is unspecified. - - PackedFdMessageReader(kj::AutoCloseFd fd, ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); - // Read a message from a file descriptor, taking ownership of the descriptor. - - KJ_DISALLOW_COPY(PackedFdMessageReader); - - ~PackedFdMessageReader() noexcept(false); -}; - -void writePackedMessage(kj::BufferedOutputStream& output, MessageBuilder& builder); -void writePackedMessage(kj::BufferedOutputStream& output, - kj::ArrayPtr> segments); -// Write a packed message to a buffered output stream. - -void writePackedMessage(kj::OutputStream& output, MessageBuilder& builder); -void writePackedMessage(kj::OutputStream& output, - kj::ArrayPtr> segments); -// Write a packed message to an unbuffered output stream. If you intend to write multiple messages -// in succession, consider wrapping your output in a buffered stream in order to reduce system -// call overhead. - -void writePackedMessageToFd(int fd, MessageBuilder& builder); -void writePackedMessageToFd(int fd, kj::ArrayPtr> segments); -// Write a single packed message to the file descriptor. - -size_t computeUnpackedSizeInWords(kj::ArrayPtr packedBytes); -// Computes the number of words to which the given packed bytes will unpack. Not intended for use -// in performance-sensitive situations. - -// ======================================================================================= -// inline stuff - -inline void writePackedMessage(kj::BufferedOutputStream& output, MessageBuilder& builder) { - writePackedMessage(output, builder.getSegmentsForOutput()); -} - -inline void writePackedMessage(kj::OutputStream& output, MessageBuilder& builder) { - writePackedMessage(output, builder.getSegmentsForOutput()); -} - -inline void writePackedMessageToFd(int fd, MessageBuilder& builder) { - writePackedMessageToFd(fd, builder.getSegmentsForOutput()); -} - -} // namespace capnp - -#endif // CAPNP_SERIALIZE_PACKED_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/serialize-text.h b/phonelibs/capnp-cpp/include/capnp/serialize-text.h deleted file mode 100644 index d86fc2c00ec8a5..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/serialize-text.h +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2015 Philip Quinn. -// Licensed under the MIT License: -// -// 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. - -#ifndef CAPNP_SERIALIZE_TEXT_H_ -#define CAPNP_SERIALIZE_TEXT_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include -#include "dynamic.h" -#include "orphan.h" -#include "schema.h" - -namespace capnp { - -class TextCodec { - // Reads and writes Cap'n Proto objects in a plain text format (as used in the schema - // language for constants, and read/written by the 'decode' and 'encode' commands of - // the capnp tool). - // - // This format is useful for debugging or human input, but it is not a robust alternative - // to the binary format. Changes to a schema's types or names that are permitted in a - // schema's binary evolution will likely break messages stored in this format. - // - // Note that definitions or references (to constants, other fields, or files) are not - // permitted in this format. To evaluate declarations with the full expressiveness of the - // schema language, see `capnp::SchemaParser`. - // - // Requires linking with the capnpc library. - -public: - TextCodec(); - ~TextCodec() noexcept(true); - - void setPrettyPrint(bool enabled); - // If enabled, pads the output of `encode()` with spaces and newlines to make it more - // human-readable. - - template - kj::String encode(T&& value) const; - kj::String encode(DynamicValue::Reader value) const; - // Encode any Cap'n Proto value. - - template - Orphan decode(kj::StringPtr input, Orphanage orphanage) const; - // Decode a text message into a Cap'n Proto object of type T, allocated in the given - // orphanage. Any errors parsing the input or assigning the fields of T are thrown as - // exceptions. - - void decode(kj::StringPtr input, DynamicStruct::Builder output) const; - // Decode a text message for a struct into the given builder. Any errors parsing the - // input or assigning the fields of the output are thrown as exceptions. - - // TODO(someday): expose some control over the error handling? -private: - Orphan decode(kj::StringPtr input, Type type, Orphanage orphanage) const; - - bool prettyPrint; -}; - -// ======================================================================================= -// inline stuff - -template -inline kj::String TextCodec::encode(T&& value) const { - return encode(DynamicValue::Reader(ReaderFor>(kj::fwd(value)))); -} - -template -inline Orphan TextCodec::decode(kj::StringPtr input, Orphanage orphanage) const { - return decode(input, Type::from(), orphanage).template releaseAs(); -} - -} // namespace capnp - -#endif // CAPNP_SERIALIZE_TEXT_H_ diff --git a/phonelibs/capnp-cpp/include/capnp/serialize.h b/phonelibs/capnp-cpp/include/capnp/serialize.h deleted file mode 100644 index 797db517662abd..00000000000000 --- a/phonelibs/capnp-cpp/include/capnp/serialize.h +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -// This file implements a simple serialization format for Cap'n Proto messages. The format -// is as follows: -// -// * 32-bit little-endian segment count (4 bytes). -// * 32-bit little-endian size of each segment (4*(segment count) bytes). -// * Padding so that subsequent data is 64-bit-aligned (0 or 4 bytes). (I.e., if there are an even -// number of segments, there are 4 bytes of zeros here, otherwise there is no padding.) -// * Data from each segment, in order (8*sum(segment sizes) bytes) -// -// This format has some important properties: -// - It is self-delimiting, so multiple messages may be written to a stream without any external -// delimiter. -// - The total size and position of each segment can be determined by reading only the first part -// of the message, allowing lazy and random-access reading of the segment data. -// - A message is always at least 8 bytes. -// - A single-segment message can be read entirely in two system calls with no buffering. -// - A multi-segment message can be read entirely in three system calls with no buffering. -// - The format is appropriate for mmap()ing since all data is aligned. - -#ifndef CAPNP_SERIALIZE_H_ -#define CAPNP_SERIALIZE_H_ - -#if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) -#pragma GCC system_header -#endif - -#include "message.h" -#include - -namespace capnp { - -class FlatArrayMessageReader: public MessageReader { - // Parses a message from a flat array. Note that it makes sense to use this together with mmap() - // for extremely fast parsing. - -public: - FlatArrayMessageReader(kj::ArrayPtr array, ReaderOptions options = ReaderOptions()); - // The array must remain valid until the MessageReader is destroyed. - - kj::ArrayPtr getSegment(uint id) override; - - const word* getEnd() const { return end; } - // Get a pointer just past the end of the message as determined by reading the message header. - // This could actually be before the end of the input array. This pointer is useful e.g. if - // you know that the input array has extra stuff appended after the message and you want to - // get at it. - -private: - // Optimize for single-segment case. - kj::ArrayPtr segment0; - kj::Array> moreSegments; - const word* end; -}; - -kj::ArrayPtr initMessageBuilderFromFlatArrayCopy( - kj::ArrayPtr array, MessageBuilder& target, - ReaderOptions options = ReaderOptions()); -// Convenience function which reads a message using `FlatArrayMessageReader` then copies the -// content into the target `MessageBuilder`, verifying that the message structure is valid -// (although not necessarily that it matches the desired schema). -// -// Returns an ArrayPtr containing any words left over in the array after consuming the whole -// message. This is useful when reading multiple messages that have been concatenated. See also -// FlatArrayMessageReader::getEnd(). -// -// (Note that it's also possible to initialize a `MessageBuilder` directly without a copy using one -// of `MessageBuilder`'s constructors. However, this approach skips the validation step and is not -// safe to use on untrusted input. Therefore, we do not provide a convenience method for it.) - -kj::Array messageToFlatArray(MessageBuilder& builder); -// Constructs a flat array containing the entire content of the given message. -// -// To output the message as bytes, use `.asBytes()` on the returned word array. Keep in mind that -// `asBytes()` returns an ArrayPtr, so you have to save the Array as well to prevent it from being -// deleted. For example: -// -// kj::Array words = messageToFlatArray(myMessage); -// kj::ArrayPtr bytes = words.asBytes(); -// write(fd, bytes.begin(), bytes.size()); - -kj::Array messageToFlatArray(kj::ArrayPtr> segments); -// Version of messageToFlatArray that takes a raw segment array. - -size_t computeSerializedSizeInWords(MessageBuilder& builder); -// Returns the size, in words, that will be needed to serialize the message, including the header. - -size_t computeSerializedSizeInWords(kj::ArrayPtr> segments); -// Version of computeSerializedSizeInWords that takes a raw segment array. - -size_t expectedSizeInWordsFromPrefix(kj::ArrayPtr messagePrefix); -// Given a prefix of a serialized message, try to determine the expected total size of the message, -// in words. The returned size is based on the information known so far; it may be an underestimate -// if the prefix doesn't contain the full segment table. -// -// If the returned value is greater than `messagePrefix.size()`, then the message is not yet -// complete and the app cannot parse it yet. If the returned value is less than or equal to -// `messagePrefix.size()`, then the returned value is the exact total size of the message; any -// remaining bytes are part of the next message. -// -// This function is useful when reading messages from a stream in an asynchronous way, but when -// using the full KJ async infrastructure would be too difficult. Each time bytes are received, -// use this function to determine if an entire message is ready to be parsed. - -// ======================================================================================= - -class InputStreamMessageReader: public MessageReader { - // A MessageReader that reads from an abstract kj::InputStream. See also StreamFdMessageReader - // for a subclass specific to file descriptors. - -public: - InputStreamMessageReader(kj::InputStream& inputStream, - ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); - ~InputStreamMessageReader() noexcept(false); - - // implements MessageReader ---------------------------------------- - kj::ArrayPtr getSegment(uint id) override; - -private: - kj::InputStream& inputStream; - byte* readPos; - - // Optimize for single-segment case. - kj::ArrayPtr segment0; - kj::Array> moreSegments; - - kj::Array ownedSpace; - // Only if scratchSpace wasn't big enough. - - kj::UnwindDetector unwindDetector; -}; - -void readMessageCopy(kj::InputStream& input, MessageBuilder& target, - ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); -// Convenience function which reads a message using `InputStreamMessageReader` then copies the -// content into the target `MessageBuilder`, verifying that the message structure is valid -// (although not necessarily that it matches the desired schema). -// -// (Note that it's also possible to initialize a `MessageBuilder` directly without a copy using one -// of `MessageBuilder`'s constructors. However, this approach skips the validation step and is not -// safe to use on untrusted input. Therefore, we do not provide a convenience method for it.) - -void writeMessage(kj::OutputStream& output, MessageBuilder& builder); -// Write the message to the given output stream. - -void writeMessage(kj::OutputStream& output, kj::ArrayPtr> segments); -// Write the segment array to the given output stream. - -// ======================================================================================= -// Specializations for reading from / writing to file descriptors. - -class StreamFdMessageReader: private kj::FdInputStream, public InputStreamMessageReader { - // A MessageReader that reads from a steam-based file descriptor. - -public: - StreamFdMessageReader(int fd, ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr) - : FdInputStream(fd), InputStreamMessageReader(*this, options, scratchSpace) {} - // Read message from a file descriptor, without taking ownership of the descriptor. - - StreamFdMessageReader(kj::AutoCloseFd fd, ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr) - : FdInputStream(kj::mv(fd)), InputStreamMessageReader(*this, options, scratchSpace) {} - // Read a message from a file descriptor, taking ownership of the descriptor. - - ~StreamFdMessageReader() noexcept(false); -}; - -void readMessageCopyFromFd(int fd, MessageBuilder& target, - ReaderOptions options = ReaderOptions(), - kj::ArrayPtr scratchSpace = nullptr); -// Convenience function which reads a message using `StreamFdMessageReader` then copies the -// content into the target `MessageBuilder`, verifying that the message structure is valid -// (although not necessarily that it matches the desired schema). -// -// (Note that it's also possible to initialize a `MessageBuilder` directly without a copy using one -// of `MessageBuilder`'s constructors. However, this approach skips the validation step and is not -// safe to use on untrusted input. Therefore, we do not provide a convenience method for it.) - -void writeMessageToFd(int fd, MessageBuilder& builder); -// Write the message to the given file descriptor. -// -// This function throws an exception on any I/O error. If your code is not exception-safe, be sure -// you catch this exception at the call site. If throwing an exception is not acceptable, you -// can implement your own OutputStream with arbitrary error handling and then use writeMessage(). - -void writeMessageToFd(int fd, kj::ArrayPtr> segments); -// Write the segment array to the given file descriptor. -// -// This function throws an exception on any I/O error. If your code is not exception-safe, be sure -// you catch this exception at the call site. If throwing an exception is not acceptable, you -// can implement your own OutputStream with arbitrary error handling and then use writeMessage(). - -// ======================================================================================= -// inline stuff - -inline kj::Array messageToFlatArray(MessageBuilder& builder) { - return messageToFlatArray(builder.getSegmentsForOutput()); -} - -inline size_t computeSerializedSizeInWords(MessageBuilder& builder) { - return computeSerializedSizeInWords(builder.getSegmentsForOutput()); -} - -inline void writeMessage(kj::OutputStream& output, MessageBuilder& builder) { - writeMessage(output, builder.getSegmentsForOutput()); -} - -inline void writeMessageToFd(int fd, MessageBuilder& builder) { - writeMessageToFd(fd, builder.getSegmentsForOutput()); -} - -} // namespace capnp - -#endif // SERIALIZE_H_ diff --git a/phonelibs/capnp-cpp/include/kj/arena.h b/phonelibs/capnp-cpp/include/kj/arena.h deleted file mode 100644 index 32c1f61c51626f..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/arena.h +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_ARENA_H_ -#define KJ_ARENA_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "memory.h" -#include "array.h" -#include "string.h" - -namespace kj { - -class Arena { - // A class which allows several objects to be allocated in contiguous chunks of memory, then - // frees them all at once. - // - // Allocating from the same Arena in multiple threads concurrently is NOT safe, because making - // it safe would require atomic operations that would slow down allocation even when - // single-threaded. If you need to use arena allocation in a multithreaded context, consider - // allocating thread-local arenas. - -public: - explicit Arena(size_t chunkSizeHint = 1024); - // Create an Arena. `chunkSizeHint` hints at where to start when allocating chunks, but is only - // a hint -- the Arena will, for example, allocate progressively larger chunks as time goes on, - // in order to reduce overall allocation overhead. - - explicit Arena(ArrayPtr scratch); - // Allocates from the given scratch space first, only resorting to the heap when it runs out. - - KJ_DISALLOW_COPY(Arena); - ~Arena() noexcept(false); - - template - T& allocate(Params&&... params); - template - ArrayPtr allocateArray(size_t size); - // Allocate an object or array of type T. If T has a non-trivial destructor, that destructor - // will be run during the Arena's destructor. Such destructors are run in opposite order of - // allocation. Note that these methods must maintain a list of destructors to call, which has - // overhead, but this overhead only applies if T has a non-trivial destructor. - - template - Own allocateOwn(Params&&... params); - template - Array allocateOwnArray(size_t size); - template - ArrayBuilder allocateOwnArrayBuilder(size_t capacity); - // Allocate an object or array of type T. Destructors are executed when the returned Own - // or Array goes out-of-scope, which must happen before the Arena is destroyed. This variant - // is useful when you need to control when the destructor is called. This variant also avoids - // the need for the Arena itself to keep track of destructors to call later, which may make it - // slightly more efficient. - - template - inline T& copy(T&& value) { return allocate>(kj::fwd(value)); } - // Allocate a copy of the given value in the arena. This is just a shortcut for calling the - // type's copy (or move) constructor. - - StringPtr copyString(StringPtr content); - // Make a copy of the given string inside the arena, and return a pointer to the copy. - -private: - struct ChunkHeader { - ChunkHeader* next; - byte* pos; // first unallocated byte in this chunk - byte* end; // end of this chunk - }; - struct ObjectHeader { - void (*destructor)(void*); - ObjectHeader* next; - }; - - size_t nextChunkSize; - ChunkHeader* chunkList = nullptr; - ObjectHeader* objectList = nullptr; - - ChunkHeader* currentChunk = nullptr; - - void cleanup(); - // Run all destructors, leaving the above pointers null. If a destructor throws, the State is - // left in a consistent state, such that if cleanup() is called again, it will pick up where - // it left off. - - void* allocateBytes(size_t amount, uint alignment, bool hasDisposer); - // Allocate the given number of bytes. `hasDisposer` must be true if `setDisposer()` may be - // called on this pointer later. - - void* allocateBytesInternal(size_t amount, uint alignment); - // Try to allocate the given number of bytes without taking a lock. Fails if and only if there - // is no space left in the current chunk. - - void setDestructor(void* ptr, void (*destructor)(void*)); - // Schedule the given destructor to be executed when the Arena is destroyed. `ptr` must be a - // pointer previously returned by an `allocateBytes()` call for which `hasDisposer` was true. - - template - static void destroyArray(void* pointer) { - size_t elementCount = *reinterpret_cast(pointer); - constexpr size_t prefixSize = kj::max(alignof(T), sizeof(size_t)); - DestructorOnlyArrayDisposer::instance.disposeImpl( - reinterpret_cast(pointer) + prefixSize, - sizeof(T), elementCount, elementCount, &destroyObject); - } - - template - static void destroyObject(void* pointer) { - dtor(*reinterpret_cast(pointer)); - } -}; - -// ======================================================================================= -// Inline implementation details - -template -T& Arena::allocate(Params&&... params) { - T& result = *reinterpret_cast(allocateBytes( - sizeof(T), alignof(T), !__has_trivial_destructor(T))); - if (!__has_trivial_constructor(T) || sizeof...(Params) > 0) { - ctor(result, kj::fwd(params)...); - } - if (!__has_trivial_destructor(T)) { - setDestructor(&result, &destroyObject); - } - return result; -} - -template -ArrayPtr Arena::allocateArray(size_t size) { - if (__has_trivial_destructor(T)) { - ArrayPtr result = - arrayPtr(reinterpret_cast(allocateBytes( - sizeof(T) * size, alignof(T), false)), size); - if (!__has_trivial_constructor(T)) { - for (size_t i = 0; i < size; i++) { - ctor(result[i]); - } - } - return result; - } else { - // Allocate with a 64-bit prefix in which we store the array size. - constexpr size_t prefixSize = kj::max(alignof(T), sizeof(size_t)); - void* base = allocateBytes(sizeof(T) * size + prefixSize, alignof(T), true); - size_t& tag = *reinterpret_cast(base); - ArrayPtr result = - arrayPtr(reinterpret_cast(reinterpret_cast(base) + prefixSize), size); - setDestructor(base, &destroyArray); - - if (__has_trivial_constructor(T)) { - tag = size; - } else { - // In case of constructor exceptions, we need the tag to end up storing the number of objects - // that were successfully constructed, so that they'll be properly destroyed. - tag = 0; - for (size_t i = 0; i < size; i++) { - ctor(result[i]); - tag = i + 1; - } - } - return result; - } -} - -template -Own Arena::allocateOwn(Params&&... params) { - T& result = *reinterpret_cast(allocateBytes(sizeof(T), alignof(T), false)); - if (!__has_trivial_constructor(T) || sizeof...(Params) > 0) { - ctor(result, kj::fwd(params)...); - } - return Own(&result, DestructorOnlyDisposer::instance); -} - -template -Array Arena::allocateOwnArray(size_t size) { - ArrayBuilder result = allocateOwnArrayBuilder(size); - for (size_t i = 0; i < size; i++) { - result.add(); - } - return result.finish(); -} - -template -ArrayBuilder Arena::allocateOwnArrayBuilder(size_t capacity) { - return ArrayBuilder( - reinterpret_cast(allocateBytes(sizeof(T) * capacity, alignof(T), false)), - capacity, DestructorOnlyArrayDisposer::instance); -} - -} // namespace kj - -#endif // KJ_ARENA_H_ diff --git a/phonelibs/capnp-cpp/include/kj/array.h b/phonelibs/capnp-cpp/include/kj/array.h deleted file mode 100644 index 51b5dcf31949ab..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/array.h +++ /dev/null @@ -1,813 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_ARRAY_H_ -#define KJ_ARRAY_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "common.h" -#include -#include - -namespace kj { - -// ======================================================================================= -// ArrayDisposer -- Implementation details. - -class ArrayDisposer { - // Much like Disposer from memory.h. - -protected: - // Do not declare a destructor, as doing so will force a global initializer for - // HeapArrayDisposer::instance. - - virtual void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, - size_t capacity, void (*destroyElement)(void*)) const = 0; - // Disposes of the array. `destroyElement` invokes the destructor of each element, or is nullptr - // if the elements have trivial destructors. `capacity` is the amount of space that was - // allocated while `elementCount` is the number of elements that were actually constructed; - // these are always the same number for Array but may be different when using ArrayBuilder. - -public: - - template - void dispose(T* firstElement, size_t elementCount, size_t capacity) const; - // Helper wrapper around disposeImpl(). - // - // Callers must not call dispose() on the same array twice, even if the first call throws - // an exception. - -private: - template - struct Dispose_; -}; - -class ExceptionSafeArrayUtil { - // Utility class that assists in constructing or destroying elements of an array, where the - // constructor or destructor could throw exceptions. In case of an exception, - // ExceptionSafeArrayUtil's destructor will call destructors on all elements that have been - // constructed but not destroyed. Remember that destructors that throw exceptions are required - // to use UnwindDetector to detect unwind and avoid exceptions in this case. Therefore, no more - // than one exception will be thrown (and the program will not terminate). - -public: - inline ExceptionSafeArrayUtil(void* ptr, size_t elementSize, size_t constructedElementCount, - void (*destroyElement)(void*)) - : pos(reinterpret_cast(ptr) + elementSize * constructedElementCount), - elementSize(elementSize), constructedElementCount(constructedElementCount), - destroyElement(destroyElement) {} - KJ_DISALLOW_COPY(ExceptionSafeArrayUtil); - - inline ~ExceptionSafeArrayUtil() noexcept(false) { - if (constructedElementCount > 0) destroyAll(); - } - - void construct(size_t count, void (*constructElement)(void*)); - // Construct the given number of elements. - - void destroyAll(); - // Destroy all elements. Call this immediately before ExceptionSafeArrayUtil goes out-of-scope - // to ensure that one element throwing an exception does not prevent the others from being - // destroyed. - - void release() { constructedElementCount = 0; } - // Prevent ExceptionSafeArrayUtil's destructor from destroying the constructed elements. - // Call this after you've successfully finished constructing. - -private: - byte* pos; - size_t elementSize; - size_t constructedElementCount; - void (*destroyElement)(void*); -}; - -class DestructorOnlyArrayDisposer: public ArrayDisposer { -public: - static const DestructorOnlyArrayDisposer instance; - - void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, - size_t capacity, void (*destroyElement)(void*)) const override; -}; - -class NullArrayDisposer: public ArrayDisposer { - // An ArrayDisposer that does nothing. Can be used to construct a fake Arrays that doesn't - // actually own its content. - -public: - static const NullArrayDisposer instance; - - void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, - size_t capacity, void (*destroyElement)(void*)) const override; -}; - -// ======================================================================================= -// Array - -template -class Array { - // An owned array which will automatically be disposed of (using an ArrayDisposer) in the - // destructor. Can be moved, but not copied. Much like Own, but for arrays rather than - // single objects. - -public: - inline Array(): ptr(nullptr), size_(0), disposer(nullptr) {} - inline Array(decltype(nullptr)): ptr(nullptr), size_(0), disposer(nullptr) {} - inline Array(Array&& other) noexcept - : ptr(other.ptr), size_(other.size_), disposer(other.disposer) { - other.ptr = nullptr; - other.size_ = 0; - } - inline Array(Array>&& other) noexcept - : ptr(other.ptr), size_(other.size_), disposer(other.disposer) { - other.ptr = nullptr; - other.size_ = 0; - } - inline Array(T* firstElement, size_t size, const ArrayDisposer& disposer) - : ptr(firstElement), size_(size), disposer(&disposer) {} - - KJ_DISALLOW_COPY(Array); - inline ~Array() noexcept { dispose(); } - - inline operator ArrayPtr() { - return ArrayPtr(ptr, size_); - } - inline operator ArrayPtr() const { - return ArrayPtr(ptr, size_); - } - inline ArrayPtr asPtr() { - return ArrayPtr(ptr, size_); - } - inline ArrayPtr asPtr() const { - return ArrayPtr(ptr, size_); - } - - inline size_t size() const { return size_; } - inline T& operator[](size_t index) const { - KJ_IREQUIRE(index < size_, "Out-of-bounds Array access."); - return ptr[index]; - } - - inline const T* begin() const { return ptr; } - inline const T* end() const { return ptr + size_; } - inline const T& front() const { return *ptr; } - inline const T& back() const { return *(ptr + size_ - 1); } - inline T* begin() { return ptr; } - inline T* end() { return ptr + size_; } - inline T& front() { return *ptr; } - inline T& back() { return *(ptr + size_ - 1); } - - inline ArrayPtr slice(size_t start, size_t end) { - KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds Array::slice()."); - return ArrayPtr(ptr + start, end - start); - } - inline ArrayPtr slice(size_t start, size_t end) const { - KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds Array::slice()."); - return ArrayPtr(ptr + start, end - start); - } - - inline ArrayPtr asBytes() const { return asPtr().asBytes(); } - inline ArrayPtr> asBytes() { return asPtr().asBytes(); } - inline ArrayPtr asChars() const { return asPtr().asChars(); } - inline ArrayPtr> asChars() { return asPtr().asChars(); } - - inline Array> releaseAsBytes() { - // Like asBytes() but transfers ownership. - static_assert(sizeof(T) == sizeof(byte), - "releaseAsBytes() only possible on arrays with byte-size elements (e.g. chars)."); - Array> result( - reinterpret_cast*>(ptr), size_, *disposer); - ptr = nullptr; - size_ = 0; - return result; - } - inline Array> releaseAsChars() { - // Like asChars() but transfers ownership. - static_assert(sizeof(T) == sizeof(PropagateConst), - "releaseAsChars() only possible on arrays with char-size elements (e.g. bytes)."); - Array> result( - reinterpret_cast*>(ptr), size_, *disposer); - ptr = nullptr; - size_ = 0; - return result; - } - - inline bool operator==(decltype(nullptr)) const { return size_ == 0; } - inline bool operator!=(decltype(nullptr)) const { return size_ != 0; } - - inline Array& operator=(decltype(nullptr)) { - dispose(); - return *this; - } - - inline Array& operator=(Array&& other) { - dispose(); - ptr = other.ptr; - size_ = other.size_; - disposer = other.disposer; - other.ptr = nullptr; - other.size_ = 0; - return *this; - } - -private: - T* ptr; - size_t size_; - const ArrayDisposer* disposer; - - inline void dispose() { - // Make sure that if an exception is thrown, we are left with a null ptr, so we won't possibly - // dispose again. - T* ptrCopy = ptr; - size_t sizeCopy = size_; - if (ptrCopy != nullptr) { - ptr = nullptr; - size_ = 0; - disposer->dispose(ptrCopy, sizeCopy, sizeCopy); - } - } - - template - friend class Array; -}; - -static_assert(!canMemcpy>(), "canMemcpy<>() is broken"); - -namespace _ { // private - -class HeapArrayDisposer final: public ArrayDisposer { -public: - template - static T* allocate(size_t count); - template - static T* allocateUninitialized(size_t count); - - static const HeapArrayDisposer instance; - -private: - static void* allocateImpl(size_t elementSize, size_t elementCount, size_t capacity, - void (*constructElement)(void*), void (*destroyElement)(void*)); - // Allocates and constructs the array. Both function pointers are null if the constructor is - // trivial, otherwise destroyElement is null if the constructor doesn't throw. - - virtual void disposeImpl(void* firstElement, size_t elementSize, size_t elementCount, - size_t capacity, void (*destroyElement)(void*)) const override; - - template - struct Allocate_; -}; - -} // namespace _ (private) - -template -inline Array heapArray(size_t size) { - // Much like `heap()` from memory.h, allocates a new array on the heap. - - return Array(_::HeapArrayDisposer::allocate(size), size, - _::HeapArrayDisposer::instance); -} - -template Array heapArray(const T* content, size_t size); -template Array heapArray(ArrayPtr content); -template Array heapArray(ArrayPtr content); -template Array heapArray(Iterator begin, Iterator end); -template Array heapArray(std::initializer_list init); -// Allocate a heap array containing a copy of the given content. - -template -Array heapArrayFromIterable(Container&& a) { return heapArray(a.begin(), a.end()); } -template -Array heapArrayFromIterable(Array&& a) { return mv(a); } - -// ======================================================================================= -// ArrayBuilder - -template -class ArrayBuilder { - // Class which lets you build an Array specifying the exact constructor arguments for each - // element, rather than starting by default-constructing them. - -public: - ArrayBuilder(): ptr(nullptr), pos(nullptr), endPtr(nullptr) {} - ArrayBuilder(decltype(nullptr)): ptr(nullptr), pos(nullptr), endPtr(nullptr) {} - explicit ArrayBuilder(RemoveConst* firstElement, size_t capacity, - const ArrayDisposer& disposer) - : ptr(firstElement), pos(firstElement), endPtr(firstElement + capacity), - disposer(&disposer) {} - ArrayBuilder(ArrayBuilder&& other) - : ptr(other.ptr), pos(other.pos), endPtr(other.endPtr), disposer(other.disposer) { - other.ptr = nullptr; - other.pos = nullptr; - other.endPtr = nullptr; - } - KJ_DISALLOW_COPY(ArrayBuilder); - inline ~ArrayBuilder() noexcept(false) { dispose(); } - - inline operator ArrayPtr() { - return arrayPtr(ptr, pos); - } - inline operator ArrayPtr() const { - return arrayPtr(ptr, pos); - } - inline ArrayPtr asPtr() { - return arrayPtr(ptr, pos); - } - inline ArrayPtr asPtr() const { - return arrayPtr(ptr, pos); - } - - inline size_t size() const { return pos - ptr; } - inline size_t capacity() const { return endPtr - ptr; } - inline T& operator[](size_t index) const { - KJ_IREQUIRE(index < implicitCast(pos - ptr), "Out-of-bounds Array access."); - return ptr[index]; - } - - inline const T* begin() const { return ptr; } - inline const T* end() const { return pos; } - inline const T& front() const { return *ptr; } - inline const T& back() const { return *(pos - 1); } - inline T* begin() { return ptr; } - inline T* end() { return pos; } - inline T& front() { return *ptr; } - inline T& back() { return *(pos - 1); } - - ArrayBuilder& operator=(ArrayBuilder&& other) { - dispose(); - ptr = other.ptr; - pos = other.pos; - endPtr = other.endPtr; - disposer = other.disposer; - other.ptr = nullptr; - other.pos = nullptr; - other.endPtr = nullptr; - return *this; - } - ArrayBuilder& operator=(decltype(nullptr)) { - dispose(); - return *this; - } - - template - T& add(Params&&... params) { - KJ_IREQUIRE(pos < endPtr, "Added too many elements to ArrayBuilder."); - ctor(*pos, kj::fwd(params)...); - return *pos++; - } - - template - void addAll(Container&& container) { - addAll()>( - container.begin(), container.end()); - } - - template - void addAll(Iterator start, Iterator end); - - void removeLast() { - KJ_IREQUIRE(pos > ptr, "No elements present to remove."); - kj::dtor(*--pos); - } - - void truncate(size_t size) { - KJ_IREQUIRE(size <= this->size(), "can't use truncate() to expand"); - - T* target = ptr + size; - if (__has_trivial_destructor(T)) { - pos = target; - } else { - while (pos > target) { - kj::dtor(*--pos); - } - } - } - - void resize(size_t size) { - KJ_IREQUIRE(size <= capacity(), "can't resize past capacity"); - - T* target = ptr + size; - if (target > pos) { - // expand - if (__has_trivial_constructor(T)) { - pos = target; - } else { - while (pos < target) { - kj::ctor(*pos++); - } - } - } else { - // truncate - if (__has_trivial_destructor(T)) { - pos = target; - } else { - while (pos > target) { - kj::dtor(*--pos); - } - } - } - } - - Array finish() { - // We could safely remove this check if we assume that the disposer implementation doesn't - // need to know the original capacity, as is thes case with HeapArrayDisposer since it uses - // operator new() or if we created a custom disposer for ArrayBuilder which stores the capacity - // in a prefix. But that would make it hard to write cleverer heap allocators, and anyway this - // check might catch bugs. Probably people should use Vector if they want to build arrays - // without knowing the final size in advance. - KJ_IREQUIRE(pos == endPtr, "ArrayBuilder::finish() called prematurely."); - Array result(reinterpret_cast(ptr), pos - ptr, *disposer); - ptr = nullptr; - pos = nullptr; - endPtr = nullptr; - return result; - } - - inline bool isFull() const { - return pos == endPtr; - } - -private: - T* ptr; - RemoveConst* pos; - T* endPtr; - const ArrayDisposer* disposer; - - inline void dispose() { - // Make sure that if an exception is thrown, we are left with a null ptr, so we won't possibly - // dispose again. - T* ptrCopy = ptr; - T* posCopy = pos; - T* endCopy = endPtr; - if (ptrCopy != nullptr) { - ptr = nullptr; - pos = nullptr; - endPtr = nullptr; - disposer->dispose(ptrCopy, posCopy - ptrCopy, endCopy - ptrCopy); - } - } -}; - -template -inline ArrayBuilder heapArrayBuilder(size_t size) { - // Like `heapArray()` but does not default-construct the elements. You must construct them - // manually by calling `add()`. - - return ArrayBuilder(_::HeapArrayDisposer::allocateUninitialized>(size), - size, _::HeapArrayDisposer::instance); -} - -// ======================================================================================= -// Inline Arrays - -template -class FixedArray { - // A fixed-width array whose storage is allocated inline rather than on the heap. - -public: - inline size_t size() const { return fixedSize; } - inline T* begin() { return content; } - inline T* end() { return content + fixedSize; } - inline const T* begin() const { return content; } - inline const T* end() const { return content + fixedSize; } - - inline operator ArrayPtr() { - return arrayPtr(content, fixedSize); - } - inline operator ArrayPtr() const { - return arrayPtr(content, fixedSize); - } - - inline T& operator[](size_t index) { return content[index]; } - inline const T& operator[](size_t index) const { return content[index]; } - -private: - T content[fixedSize]; -}; - -template -class CappedArray { - // Like `FixedArray` but can be dynamically resized as long as the size does not exceed the limit - // specified by the template parameter. - // - // TODO(someday): Don't construct elements past currentSize? - -public: - inline KJ_CONSTEXPR() CappedArray(): currentSize(fixedSize) {} - inline explicit constexpr CappedArray(size_t s): currentSize(s) {} - - inline size_t size() const { return currentSize; } - inline void setSize(size_t s) { KJ_IREQUIRE(s <= fixedSize); currentSize = s; } - inline T* begin() { return content; } - inline T* end() { return content + currentSize; } - inline const T* begin() const { return content; } - inline const T* end() const { return content + currentSize; } - - inline operator ArrayPtr() { - return arrayPtr(content, currentSize); - } - inline operator ArrayPtr() const { - return arrayPtr(content, currentSize); - } - - inline T& operator[](size_t index) { return content[index]; } - inline const T& operator[](size_t index) const { return content[index]; } - -private: - size_t currentSize; - T content[fixedSize]; -}; - -// ======================================================================================= -// KJ_MAP - -#define KJ_MAP(elementName, array) \ - ::kj::_::Mapper(array) * \ - [&](typename ::kj::_::Mapper::Element elementName) -// Applies some function to every element of an array, returning an Array of the results, with -// nice syntax. Example: -// -// StringPtr foo = "abcd"; -// Array bar = KJ_MAP(c, foo) -> char { return c + 1; }; -// KJ_ASSERT(str(bar) == "bcde"); - -namespace _ { // private - -template -struct Mapper { - T array; - Mapper(T&& array): array(kj::fwd(array)) {} - template - auto operator*(Func&& func) -> Array { - auto builder = heapArrayBuilder(array.size()); - for (auto iter = array.begin(); iter != array.end(); ++iter) { - builder.add(func(*iter)); - } - return builder.finish(); - } - typedef decltype(*kj::instance().begin()) Element; -}; - -template -struct Mapper { - T* array; - Mapper(T* array): array(array) {} - template - auto operator*(Func&& func) -> Array { - auto builder = heapArrayBuilder(s); - for (size_t i = 0; i < s; i++) { - builder.add(func(array[i])); - } - return builder.finish(); - } - typedef decltype(*array)& Element; -}; - -} // namespace _ (private) - -// ======================================================================================= -// Inline implementation details - -template -struct ArrayDisposer::Dispose_ { - static void dispose(T* firstElement, size_t elementCount, size_t capacity, - const ArrayDisposer& disposer) { - disposer.disposeImpl(const_cast*>(firstElement), - sizeof(T), elementCount, capacity, nullptr); - } -}; -template -struct ArrayDisposer::Dispose_ { - static void destruct(void* ptr) { - kj::dtor(*reinterpret_cast(ptr)); - } - - static void dispose(T* firstElement, size_t elementCount, size_t capacity, - const ArrayDisposer& disposer) { - disposer.disposeImpl(firstElement, sizeof(T), elementCount, capacity, &destruct); - } -}; - -template -void ArrayDisposer::dispose(T* firstElement, size_t elementCount, size_t capacity) const { - Dispose_::dispose(firstElement, elementCount, capacity, *this); -} - -namespace _ { // private - -template -struct HeapArrayDisposer::Allocate_ { - static T* allocate(size_t elementCount, size_t capacity) { - return reinterpret_cast(allocateImpl( - sizeof(T), elementCount, capacity, nullptr, nullptr)); - } -}; -template -struct HeapArrayDisposer::Allocate_ { - static void construct(void* ptr) { - kj::ctor(*reinterpret_cast(ptr)); - } - static T* allocate(size_t elementCount, size_t capacity) { - return reinterpret_cast(allocateImpl( - sizeof(T), elementCount, capacity, &construct, nullptr)); - } -}; -template -struct HeapArrayDisposer::Allocate_ { - static void construct(void* ptr) { - kj::ctor(*reinterpret_cast(ptr)); - } - static void destruct(void* ptr) { - kj::dtor(*reinterpret_cast(ptr)); - } - static T* allocate(size_t elementCount, size_t capacity) { - return reinterpret_cast(allocateImpl( - sizeof(T), elementCount, capacity, &construct, &destruct)); - } -}; - -template -T* HeapArrayDisposer::allocate(size_t count) { - return Allocate_::allocate(count, count); -} - -template -T* HeapArrayDisposer::allocateUninitialized(size_t count) { - return Allocate_::allocate(0, count); -} - -template ()> -struct CopyConstructArray_; - -template -struct CopyConstructArray_ { - static inline T* apply(T* __restrict__ pos, T* start, T* end) { - memcpy(pos, start, reinterpret_cast(end) - reinterpret_cast(start)); - return pos + (end - start); - } -}; - -template -struct CopyConstructArray_ { - static inline T* apply(T* __restrict__ pos, const T* start, const T* end) { - memcpy(pos, start, reinterpret_cast(end) - reinterpret_cast(start)); - return pos + (end - start); - } -}; - -template -struct CopyConstructArray_ { - static inline T* apply(T* __restrict__ pos, Iterator start, Iterator end) { - // Since both the copy constructor and assignment operator are trivial, we know that assignment - // is equivalent to copy-constructing. So we can make this case somewhat easier for the - // compiler to optimize. - while (start != end) { - *pos++ = *start++; - } - return pos; - } -}; - -template -struct CopyConstructArray_ { - struct ExceptionGuard { - T* start; - T* pos; - inline explicit ExceptionGuard(T* pos): start(pos), pos(pos) {} - ~ExceptionGuard() noexcept(false) { - while (pos > start) { - dtor(*--pos); - } - } - }; - - static T* apply(T* __restrict__ pos, Iterator start, Iterator end) { - // Verify that T can be *implicitly* constructed from the source values. - if (false) implicitCast(*start); - - if (noexcept(T(*start))) { - while (start != end) { - ctor(*pos++, *start++); - } - return pos; - } else { - // Crap. This is complicated. - ExceptionGuard guard(pos); - while (start != end) { - ctor(*guard.pos, *start++); - ++guard.pos; - } - guard.start = guard.pos; - return guard.pos; - } - } -}; - -template -struct CopyConstructArray_ { - // Actually move-construct. - - struct ExceptionGuard { - T* start; - T* pos; - inline explicit ExceptionGuard(T* pos): start(pos), pos(pos) {} - ~ExceptionGuard() noexcept(false) { - while (pos > start) { - dtor(*--pos); - } - } - }; - - static T* apply(T* __restrict__ pos, Iterator start, Iterator end) { - // Verify that T can be *implicitly* constructed from the source values. - if (false) implicitCast(kj::mv(*start)); - - if (noexcept(T(kj::mv(*start)))) { - while (start != end) { - ctor(*pos++, kj::mv(*start++)); - } - return pos; - } else { - // Crap. This is complicated. - ExceptionGuard guard(pos); - while (start != end) { - ctor(*guard.pos, kj::mv(*start++)); - ++guard.pos; - } - guard.start = guard.pos; - return guard.pos; - } - } -}; - -} // namespace _ (private) - -template -template -void ArrayBuilder::addAll(Iterator start, Iterator end) { - pos = _::CopyConstructArray_, Decay, move>::apply(pos, start, end); -} - -template -Array heapArray(const T* content, size_t size) { - ArrayBuilder builder = heapArrayBuilder(size); - builder.addAll(content, content + size); - return builder.finish(); -} - -template -Array heapArray(T* content, size_t size) { - ArrayBuilder builder = heapArrayBuilder(size); - builder.addAll(content, content + size); - return builder.finish(); -} - -template -Array heapArray(ArrayPtr content) { - ArrayBuilder builder = heapArrayBuilder(content.size()); - builder.addAll(content); - return builder.finish(); -} - -template -Array heapArray(ArrayPtr content) { - ArrayBuilder builder = heapArrayBuilder(content.size()); - builder.addAll(content); - return builder.finish(); -} - -template Array -heapArray(Iterator begin, Iterator end) { - ArrayBuilder builder = heapArrayBuilder(end - begin); - builder.addAll(begin, end); - return builder.finish(); -} - -template -inline Array heapArray(std::initializer_list init) { - return heapArray(init.begin(), init.end()); -} - -} // namespace kj - -#endif // KJ_ARRAY_H_ diff --git a/phonelibs/capnp-cpp/include/kj/async-inl.h b/phonelibs/capnp-cpp/include/kj/async-inl.h deleted file mode 100644 index f11e4fcd5b9f74..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/async-inl.h +++ /dev/null @@ -1,1112 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -// This file contains extended inline implementation details that are required along with async.h. -// We move this all into a separate file to make async.h more readable. -// -// Non-inline declarations here are defined in async.c++. - -#ifndef KJ_ASYNC_H_ -#error "Do not include this directly; include kj/async.h." -#include "async.h" // help IDE parse this file -#endif - -#ifndef KJ_ASYNC_INL_H_ -#define KJ_ASYNC_INL_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -namespace kj { -namespace _ { // private - -template -class ExceptionOr; - -class ExceptionOrValue { -public: - ExceptionOrValue(bool, Exception&& exception): exception(kj::mv(exception)) {} - KJ_DISALLOW_COPY(ExceptionOrValue); - - void addException(Exception&& exception) { - if (this->exception == nullptr) { - this->exception = kj::mv(exception); - } - } - - template - ExceptionOr& as() { return *static_cast*>(this); } - template - const ExceptionOr& as() const { return *static_cast*>(this); } - - Maybe exception; - -protected: - // Allow subclasses to have move constructor / assignment. - ExceptionOrValue() = default; - ExceptionOrValue(ExceptionOrValue&& other) = default; - ExceptionOrValue& operator=(ExceptionOrValue&& other) = default; -}; - -template -class ExceptionOr: public ExceptionOrValue { -public: - ExceptionOr() = default; - ExceptionOr(T&& value): value(kj::mv(value)) {} - ExceptionOr(bool, Exception&& exception): ExceptionOrValue(false, kj::mv(exception)) {} - ExceptionOr(ExceptionOr&&) = default; - ExceptionOr& operator=(ExceptionOr&&) = default; - - Maybe value; -}; - -class Event { - // An event waiting to be executed. Not for direct use by applications -- promises use this - // internally. - -public: - Event(); - ~Event() noexcept(false); - KJ_DISALLOW_COPY(Event); - - void armDepthFirst(); - // Enqueue this event so that `fire()` will be called from the event loop soon. - // - // Events scheduled in this way are executed in depth-first order: if an event callback arms - // more events, those events are placed at the front of the queue (in the order in which they - // were armed), so that they run immediately after the first event's callback returns. - // - // Depth-first event scheduling is appropriate for events that represent simple continuations - // of a previous event that should be globbed together for performance. Depth-first scheduling - // can lead to starvation, so any long-running task must occasionally yield with - // `armBreadthFirst()`. (Promise::then() uses depth-first whereas evalLater() uses - // breadth-first.) - // - // To use breadth-first scheduling instead, use `armBreadthFirst()`. - - void armBreadthFirst(); - // Like `armDepthFirst()` except that the event is placed at the end of the queue. - - kj::String trace(); - // Dump debug info about this event. - - virtual _::PromiseNode* getInnerForTrace(); - // If this event wraps a PromiseNode, get that node. Used for debug tracing. - // Default implementation returns nullptr. - -protected: - virtual Maybe> fire() = 0; - // Fire the event. Possibly returns a pointer to itself, which will be discarded by the - // caller. This is the only way that an event can delete itself as a result of firing, as - // doing so from within fire() will throw an exception. - -private: - friend class kj::EventLoop; - EventLoop& loop; - Event* next; - Event** prev; - bool firing = false; -}; - -class PromiseNode { - // A Promise contains a chain of PromiseNodes tracking the pending transformations. - // - // To reduce generated code bloat, PromiseNode is not a template. Instead, it makes very hacky - // use of pointers to ExceptionOrValue which actually point to ExceptionOr, but are only - // so down-cast in the few places that really need to be templated. Luckily this is all - // internal implementation details. - -public: - virtual void onReady(Event& event) noexcept = 0; - // Arms the given event when ready. - - virtual void setSelfPointer(Own* selfPtr) noexcept; - // Tells the node that `selfPtr` is the pointer that owns this node, and will continue to own - // this node until it is destroyed or setSelfPointer() is called again. ChainPromiseNode uses - // this to shorten redundant chains. The default implementation does nothing; only - // ChainPromiseNode should implement this. - - virtual void get(ExceptionOrValue& output) noexcept = 0; - // Get the result. `output` points to an ExceptionOr into which the result will be written. - // Can only be called once, and only after the node is ready. Must be called directly from the - // event loop, with no application code on the stack. - - virtual PromiseNode* getInnerForTrace(); - // If this node wraps some other PromiseNode, get the wrapped node. Used for debug tracing. - // Default implementation returns nullptr. - -protected: - class OnReadyEvent { - // Helper class for implementing onReady(). - - public: - void init(Event& newEvent); - // Returns true if arm() was already called. - - void arm(); - // Arms the event if init() has already been called and makes future calls to init() return - // true. - - private: - Event* event = nullptr; - }; -}; - -// ------------------------------------------------------------------- - -class ImmediatePromiseNodeBase: public PromiseNode { -public: - ImmediatePromiseNodeBase(); - ~ImmediatePromiseNodeBase() noexcept(false); - - void onReady(Event& event) noexcept override; -}; - -template -class ImmediatePromiseNode final: public ImmediatePromiseNodeBase { - // A promise that has already been resolved to an immediate value or exception. - -public: - ImmediatePromiseNode(ExceptionOr&& result): result(kj::mv(result)) {} - - void get(ExceptionOrValue& output) noexcept override { - output.as() = kj::mv(result); - } - -private: - ExceptionOr result; -}; - -class ImmediateBrokenPromiseNode final: public ImmediatePromiseNodeBase { -public: - ImmediateBrokenPromiseNode(Exception&& exception); - - void get(ExceptionOrValue& output) noexcept override; - -private: - Exception exception; -}; - -// ------------------------------------------------------------------- - -class AttachmentPromiseNodeBase: public PromiseNode { -public: - AttachmentPromiseNodeBase(Own&& dependency); - - void onReady(Event& event) noexcept override; - void get(ExceptionOrValue& output) noexcept override; - PromiseNode* getInnerForTrace() override; - -private: - Own dependency; - - void dropDependency(); - - template - friend class AttachmentPromiseNode; -}; - -template -class AttachmentPromiseNode final: public AttachmentPromiseNodeBase { - // A PromiseNode that holds on to some object (usually, an Own, but could be any movable - // object) until the promise resolves. - -public: - AttachmentPromiseNode(Own&& dependency, Attachment&& attachment) - : AttachmentPromiseNodeBase(kj::mv(dependency)), - attachment(kj::mv(attachment)) {} - - ~AttachmentPromiseNode() noexcept(false) { - // We need to make sure the dependency is deleted before we delete the attachment because the - // dependency may be using the attachment. - dropDependency(); - } - -private: - Attachment attachment; -}; - -// ------------------------------------------------------------------- - -class PtmfHelper { - // This class is a private helper for GetFunctorStartAddress. The class represents the internal - // representation of a pointer-to-member-function. - - template - friend struct GetFunctorStartAddress; - -#if __GNUG__ - - void* ptr; - ptrdiff_t adj; - // Layout of a pointer-to-member-function used by GCC and compatible compilers. - - void* apply(void* obj) { -#if defined(__arm__) || defined(__mips__) || defined(__aarch64__) - if (adj & 1) { - ptrdiff_t voff = (ptrdiff_t)ptr; -#else - ptrdiff_t voff = (ptrdiff_t)ptr; - if (voff & 1) { - voff &= ~1; -#endif - return *(void**)(*(char**)obj + voff); - } else { - return ptr; - } - } - -#define BODY \ - PtmfHelper result; \ - static_assert(sizeof(p) == sizeof(result), "unknown ptmf layout"); \ - memcpy(&result, &p, sizeof(result)); \ - return result - -#else // __GNUG__ - - void* apply(void* obj) { return nullptr; } - // TODO(port): PTMF instruction address extraction - -#define BODY return PtmfHelper{} - -#endif // __GNUG__, else - - template - static PtmfHelper from(F p) { BODY; } - // Create a PtmfHelper from some arbitrary pointer-to-member-function which is not - // overloaded nor a template. In this case the compiler is able to deduce the full function - // signature directly given the name since there is only one function with that name. - - template - static PtmfHelper from(R (C::*p)(NoInfer

...)) { BODY; } - template - static PtmfHelper from(R (C::*p)(NoInfer

...) const) { BODY; } - // Create a PtmfHelper from some poniter-to-member-function which is a template. In this case - // the function must match exactly the containing type C, return type R, and parameter types P... - // GetFunctorStartAddress normally specifies exactly the correct C and R, but can only make a - // guess at P. Luckily, if the function parameters are template parameters then it's not - // necessary to be precise about P. -#undef BODY -}; - -template -struct GetFunctorStartAddress { - // Given a functor (any object defining operator()), return the start address of the function, - // suitable for passing to addr2line to obtain a source file/line for debugging purposes. - // - // This turns out to be incredibly hard to implement in the presence of overloaded or templated - // functors. Therefore, we impose these specific restrictions, specific to our use case: - // - Overloading is not allowed, but templating is. (Generally we only intend to support lambdas - // anyway.) - // - The template parameters to GetFunctorStartAddress specify a hint as to the expected - // parameter types. If the functor is templated, its parameters must match exactly these types. - // (If it's not templated, ParamTypes are ignored.) - - template - static void* apply(Func&& func) { - typedef decltype(func(instance()...)) ReturnType; - return PtmfHelper::from, ParamTypes...>( - &Decay::operator()).apply(&func); - } -}; - -template <> -struct GetFunctorStartAddress: public GetFunctorStartAddress<> {}; -// Hack for TransformPromiseNode use case: an input type of `Void` indicates that the function -// actually has no parameters. - -class TransformPromiseNodeBase: public PromiseNode { -public: - TransformPromiseNodeBase(Own&& dependency, void* continuationTracePtr); - - void onReady(Event& event) noexcept override; - void get(ExceptionOrValue& output) noexcept override; - PromiseNode* getInnerForTrace() override; - -private: - Own dependency; - void* continuationTracePtr; - - void dropDependency(); - void getDepResult(ExceptionOrValue& output); - - virtual void getImpl(ExceptionOrValue& output) = 0; - - template - friend class TransformPromiseNode; -}; - -template -class TransformPromiseNode final: public TransformPromiseNodeBase { - // A PromiseNode that transforms the result of another PromiseNode through an application-provided - // function (implements `then()`). - -public: - TransformPromiseNode(Own&& dependency, Func&& func, ErrorFunc&& errorHandler) - : TransformPromiseNodeBase(kj::mv(dependency), - GetFunctorStartAddress::apply(func)), - func(kj::fwd(func)), errorHandler(kj::fwd(errorHandler)) {} - - ~TransformPromiseNode() noexcept(false) { - // We need to make sure the dependency is deleted before we delete the continuations because it - // is a common pattern for the continuations to hold ownership of objects that might be in-use - // by the dependency. - dropDependency(); - } - -private: - Func func; - ErrorFunc errorHandler; - - void getImpl(ExceptionOrValue& output) override { - ExceptionOr depResult; - getDepResult(depResult); - KJ_IF_MAYBE(depException, depResult.exception) { - output.as() = handle( - MaybeVoidCaller>>::apply( - errorHandler, kj::mv(*depException))); - } else KJ_IF_MAYBE(depValue, depResult.value) { - output.as() = handle(MaybeVoidCaller::apply(func, kj::mv(*depValue))); - } - } - - ExceptionOr handle(T&& value) { - return kj::mv(value); - } - ExceptionOr handle(PropagateException::Bottom&& value) { - return ExceptionOr(false, value.asException()); - } -}; - -// ------------------------------------------------------------------- - -class ForkHubBase; - -class ForkBranchBase: public PromiseNode { -public: - ForkBranchBase(Own&& hub); - ~ForkBranchBase() noexcept(false); - - void hubReady() noexcept; - // Called by the hub to indicate that it is ready. - - // implements PromiseNode ------------------------------------------ - void onReady(Event& event) noexcept override; - PromiseNode* getInnerForTrace() override; - -protected: - inline ExceptionOrValue& getHubResultRef(); - - void releaseHub(ExceptionOrValue& output); - // Release the hub. If an exception is thrown, add it to `output`. - -private: - OnReadyEvent onReadyEvent; - - Own hub; - ForkBranchBase* next = nullptr; - ForkBranchBase** prevPtr = nullptr; - - friend class ForkHubBase; -}; - -template T copyOrAddRef(T& t) { return t; } -template Own copyOrAddRef(Own& t) { return t->addRef(); } - -template -class ForkBranch final: public ForkBranchBase { - // A PromiseNode that implements one branch of a fork -- i.e. one of the branches that receives - // a const reference. - -public: - ForkBranch(Own&& hub): ForkBranchBase(kj::mv(hub)) {} - - void get(ExceptionOrValue& output) noexcept override { - ExceptionOr& hubResult = getHubResultRef().template as(); - KJ_IF_MAYBE(value, hubResult.value) { - output.as().value = copyOrAddRef(*value); - } else { - output.as().value = nullptr; - } - output.exception = hubResult.exception; - releaseHub(output); - } -}; - -template -class SplitBranch final: public ForkBranchBase { - // A PromiseNode that implements one branch of a fork -- i.e. one of the branches that receives - // a const reference. - -public: - SplitBranch(Own&& hub): ForkBranchBase(kj::mv(hub)) {} - - typedef kj::Decay(kj::instance()))> Element; - - void get(ExceptionOrValue& output) noexcept override { - ExceptionOr& hubResult = getHubResultRef().template as(); - KJ_IF_MAYBE(value, hubResult.value) { - output.as().value = kj::mv(kj::get(*value)); - } else { - output.as().value = nullptr; - } - output.exception = hubResult.exception; - releaseHub(output); - } -}; - -// ------------------------------------------------------------------- - -class ForkHubBase: public Refcounted, protected Event { -public: - ForkHubBase(Own&& inner, ExceptionOrValue& resultRef); - - inline ExceptionOrValue& getResultRef() { return resultRef; } - -private: - Own inner; - ExceptionOrValue& resultRef; - - ForkBranchBase* headBranch = nullptr; - ForkBranchBase** tailBranch = &headBranch; - // Tail becomes null once the inner promise is ready and all branches have been notified. - - Maybe> fire() override; - _::PromiseNode* getInnerForTrace() override; - - friend class ForkBranchBase; -}; - -template -class ForkHub final: public ForkHubBase { - // A PromiseNode that implements the hub of a fork. The first call to Promise::fork() replaces - // the promise's outer node with a ForkHub, and subsequent calls add branches to that hub (if - // possible). - -public: - ForkHub(Own&& inner): ForkHubBase(kj::mv(inner), result) {} - - Promise<_::UnfixVoid> addBranch() { - return Promise<_::UnfixVoid>(false, kj::heap>(addRef(*this))); - } - - _::SplitTuplePromise split() { - return splitImpl(MakeIndexes()>()); - } - -private: - ExceptionOr result; - - template - _::SplitTuplePromise splitImpl(Indexes) { - return kj::tuple(addSplit()...); - } - - template - Promise::Element>> addSplit() { - return Promise::Element>>( - false, maybeChain(kj::heap>(addRef(*this)), - implicitCast::Element*>(nullptr))); - } -}; - -inline ExceptionOrValue& ForkBranchBase::getHubResultRef() { - return hub->getResultRef(); -} - -// ------------------------------------------------------------------- - -class ChainPromiseNode final: public PromiseNode, public Event { - // Promise node which reduces Promise> to Promise. - // - // `Event` is only a public base class because otherwise we can't cast Own to - // Own. Ugh, templates and private... - -public: - explicit ChainPromiseNode(Own inner); - ~ChainPromiseNode() noexcept(false); - - void onReady(Event& event) noexcept override; - void setSelfPointer(Own* selfPtr) noexcept override; - void get(ExceptionOrValue& output) noexcept override; - PromiseNode* getInnerForTrace() override; - -private: - enum State { - STEP1, - STEP2 - }; - - State state; - - Own inner; - // In STEP1, a PromiseNode for a Promise. - // In STEP2, a PromiseNode for a T. - - Event* onReadyEvent = nullptr; - Own* selfPtr = nullptr; - - Maybe> fire() override; -}; - -template -Own maybeChain(Own&& node, Promise*) { - return heap(kj::mv(node)); -} - -template -Own&& maybeChain(Own&& node, T*) { - return kj::mv(node); -} - -// ------------------------------------------------------------------- - -class ExclusiveJoinPromiseNode final: public PromiseNode { -public: - ExclusiveJoinPromiseNode(Own left, Own right); - ~ExclusiveJoinPromiseNode() noexcept(false); - - void onReady(Event& event) noexcept override; - void get(ExceptionOrValue& output) noexcept override; - PromiseNode* getInnerForTrace() override; - -private: - class Branch: public Event { - public: - Branch(ExclusiveJoinPromiseNode& joinNode, Own dependency); - ~Branch() noexcept(false); - - bool get(ExceptionOrValue& output); - // Returns true if this is the side that finished. - - Maybe> fire() override; - _::PromiseNode* getInnerForTrace() override; - - private: - ExclusiveJoinPromiseNode& joinNode; - Own dependency; - }; - - Branch left; - Branch right; - OnReadyEvent onReadyEvent; -}; - -// ------------------------------------------------------------------- - -class ArrayJoinPromiseNodeBase: public PromiseNode { -public: - ArrayJoinPromiseNodeBase(Array> promises, - ExceptionOrValue* resultParts, size_t partSize); - ~ArrayJoinPromiseNodeBase() noexcept(false); - - void onReady(Event& event) noexcept override final; - void get(ExceptionOrValue& output) noexcept override final; - PromiseNode* getInnerForTrace() override final; - -protected: - virtual void getNoError(ExceptionOrValue& output) noexcept = 0; - // Called to compile the result only in the case where there were no errors. - -private: - uint countLeft; - OnReadyEvent onReadyEvent; - - class Branch final: public Event { - public: - Branch(ArrayJoinPromiseNodeBase& joinNode, Own dependency, - ExceptionOrValue& output); - ~Branch() noexcept(false); - - Maybe> fire() override; - _::PromiseNode* getInnerForTrace() override; - - Maybe getPart(); - // Calls dependency->get(output). If there was an exception, return it. - - private: - ArrayJoinPromiseNodeBase& joinNode; - Own dependency; - ExceptionOrValue& output; - }; - - Array branches; -}; - -template -class ArrayJoinPromiseNode final: public ArrayJoinPromiseNodeBase { -public: - ArrayJoinPromiseNode(Array> promises, - Array> resultParts) - : ArrayJoinPromiseNodeBase(kj::mv(promises), resultParts.begin(), sizeof(ExceptionOr)), - resultParts(kj::mv(resultParts)) {} - -protected: - void getNoError(ExceptionOrValue& output) noexcept override { - auto builder = heapArrayBuilder(resultParts.size()); - for (auto& part: resultParts) { - KJ_IASSERT(part.value != nullptr, - "Bug in KJ promise framework: Promise result had neither value no exception."); - builder.add(kj::mv(*_::readMaybe(part.value))); - } - output.as>() = builder.finish(); - } - -private: - Array> resultParts; -}; - -template <> -class ArrayJoinPromiseNode final: public ArrayJoinPromiseNodeBase { -public: - ArrayJoinPromiseNode(Array> promises, - Array> resultParts); - ~ArrayJoinPromiseNode(); - -protected: - void getNoError(ExceptionOrValue& output) noexcept override; - -private: - Array> resultParts; -}; - -// ------------------------------------------------------------------- - -class EagerPromiseNodeBase: public PromiseNode, protected Event { - // A PromiseNode that eagerly evaluates its dependency even if its dependent does not eagerly - // evaluate it. - -public: - EagerPromiseNodeBase(Own&& dependency, ExceptionOrValue& resultRef); - - void onReady(Event& event) noexcept override; - PromiseNode* getInnerForTrace() override; - -private: - Own dependency; - OnReadyEvent onReadyEvent; - - ExceptionOrValue& resultRef; - - Maybe> fire() override; -}; - -template -class EagerPromiseNode final: public EagerPromiseNodeBase { -public: - EagerPromiseNode(Own&& dependency) - : EagerPromiseNodeBase(kj::mv(dependency), result) {} - - void get(ExceptionOrValue& output) noexcept override { - output.as() = kj::mv(result); - } - -private: - ExceptionOr result; -}; - -template -Own spark(Own&& node) { - // Forces evaluation of the given node to begin as soon as possible, even if no one is waiting - // on it. - return heap>(kj::mv(node)); -} - -// ------------------------------------------------------------------- - -class AdapterPromiseNodeBase: public PromiseNode { -public: - void onReady(Event& event) noexcept override; - -protected: - inline void setReady() { - onReadyEvent.arm(); - } - -private: - OnReadyEvent onReadyEvent; -}; - -template -class AdapterPromiseNode final: public AdapterPromiseNodeBase, - private PromiseFulfiller> { - // A PromiseNode that wraps a PromiseAdapter. - -public: - template - AdapterPromiseNode(Params&&... params) - : adapter(static_cast>&>(*this), kj::fwd(params)...) {} - - void get(ExceptionOrValue& output) noexcept override { - KJ_IREQUIRE(!isWaiting()); - output.as() = kj::mv(result); - } - -private: - ExceptionOr result; - bool waiting = true; - Adapter adapter; - - void fulfill(T&& value) override { - if (waiting) { - waiting = false; - result = ExceptionOr(kj::mv(value)); - setReady(); - } - } - - void reject(Exception&& exception) override { - if (waiting) { - waiting = false; - result = ExceptionOr(false, kj::mv(exception)); - setReady(); - } - } - - bool isWaiting() override { - return waiting; - } -}; - -} // namespace _ (private) - -// ======================================================================================= - -template -Promise::Promise(_::FixVoid value) - : PromiseBase(heap<_::ImmediatePromiseNode<_::FixVoid>>(kj::mv(value))) {} - -template -Promise::Promise(kj::Exception&& exception) - : PromiseBase(heap<_::ImmediateBrokenPromiseNode>(kj::mv(exception))) {} - -template -template -PromiseForResult Promise::then(Func&& func, ErrorFunc&& errorHandler) { - typedef _::FixVoid<_::ReturnType> ResultT; - - Own<_::PromiseNode> intermediate = - heap<_::TransformPromiseNode, Func, ErrorFunc>>( - kj::mv(node), kj::fwd(func), kj::fwd(errorHandler)); - return PromiseForResult(false, - _::maybeChain(kj::mv(intermediate), implicitCast(nullptr))); -} - -namespace _ { // private - -template -struct IdentityFunc { - inline T operator()(T&& value) const { - return kj::mv(value); - } -}; -template -struct IdentityFunc> { - inline Promise operator()(T&& value) const { - return kj::mv(value); - } -}; -template <> -struct IdentityFunc { - inline void operator()() const {} -}; -template <> -struct IdentityFunc> { - Promise operator()() const; - // This can't be inline because it will make the translation unit depend on kj-async. Awkwardly, - // Cap'n Proto relies on being able to include this header without creating such a link-time - // dependency. -}; - -} // namespace _ (private) - -template -template -Promise Promise::catch_(ErrorFunc&& errorHandler) { - // then()'s ErrorFunc can only return a Promise if Func also returns a Promise. In this case, - // Func is being filled in automatically. We want to make sure ErrorFunc can return a Promise, - // but we don't want the extra overhead of promise chaining if ErrorFunc doesn't actually - // return a promise. So we make our Func return match ErrorFunc. - return then(_::IdentityFunc()))>(), - kj::fwd(errorHandler)); -} - -template -T Promise::wait(WaitScope& waitScope) { - _::ExceptionOr<_::FixVoid> result; - - waitImpl(kj::mv(node), result, waitScope); - - KJ_IF_MAYBE(value, result.value) { - KJ_IF_MAYBE(exception, result.exception) { - throwRecoverableException(kj::mv(*exception)); - } - return _::returnMaybeVoid(kj::mv(*value)); - } else KJ_IF_MAYBE(exception, result.exception) { - throwFatalException(kj::mv(*exception)); - } else { - // Result contained neither a value nor an exception? - KJ_UNREACHABLE; - } -} - -template <> -inline void Promise::wait(WaitScope& waitScope) { - // Override case to use throwRecoverableException(). - - _::ExceptionOr<_::Void> result; - - waitImpl(kj::mv(node), result, waitScope); - - if (result.value != nullptr) { - KJ_IF_MAYBE(exception, result.exception) { - throwRecoverableException(kj::mv(*exception)); - } - } else KJ_IF_MAYBE(exception, result.exception) { - throwRecoverableException(kj::mv(*exception)); - } else { - // Result contained neither a value nor an exception? - KJ_UNREACHABLE; - } -} - -template -ForkedPromise Promise::fork() { - return ForkedPromise(false, refcounted<_::ForkHub<_::FixVoid>>(kj::mv(node))); -} - -template -Promise ForkedPromise::addBranch() { - return hub->addBranch(); -} - -template -_::SplitTuplePromise Promise::split() { - return refcounted<_::ForkHub<_::FixVoid>>(kj::mv(node))->split(); -} - -template -Promise Promise::exclusiveJoin(Promise&& other) { - return Promise(false, heap<_::ExclusiveJoinPromiseNode>(kj::mv(node), kj::mv(other.node))); -} - -template -template -Promise Promise::attach(Attachments&&... attachments) { - return Promise(false, kj::heap<_::AttachmentPromiseNode>>( - kj::mv(node), kj::tuple(kj::fwd(attachments)...))); -} - -template -template -Promise Promise::eagerlyEvaluate(ErrorFunc&& errorHandler) { - // See catch_() for commentary. - return Promise(false, _::spark<_::FixVoid>(then( - _::IdentityFunc()))>(), - kj::fwd(errorHandler)).node)); -} - -template -Promise Promise::eagerlyEvaluate(decltype(nullptr)) { - return Promise(false, _::spark<_::FixVoid>(kj::mv(node))); -} - -template -kj::String Promise::trace() { - return PromiseBase::trace(); -} - -template -inline PromiseForResult evalLater(Func&& func) { - return _::yield().then(kj::fwd(func), _::PropagateException()); -} - -template -inline PromiseForResult evalNow(Func&& func) { - PromiseForResult result = nullptr; - KJ_IF_MAYBE(e, kj::runCatchingExceptions([&]() { - result = func(); - })) { - result = kj::mv(*e); - } - return result; -} - -template -template -void Promise::detach(ErrorFunc&& errorHandler) { - return _::detach(then([](T&&) {}, kj::fwd(errorHandler))); -} - -template <> -template -void Promise::detach(ErrorFunc&& errorHandler) { - return _::detach(then([]() {}, kj::fwd(errorHandler))); -} - -template -Promise> joinPromises(Array>&& promises) { - return Promise>(false, kj::heap<_::ArrayJoinPromiseNode>( - KJ_MAP(p, promises) { return kj::mv(p.node); }, - heapArray<_::ExceptionOr>(promises.size()))); -} - -// ======================================================================================= - -namespace _ { // private - -template -class WeakFulfiller final: public PromiseFulfiller, private kj::Disposer { - // A wrapper around PromiseFulfiller which can be detached. - // - // There are a couple non-trivialities here: - // - If the WeakFulfiller is discarded, we want the promise it fulfills to be implicitly - // rejected. - // - We cannot destroy the WeakFulfiller until the application has discarded it *and* it has been - // detached from the underlying fulfiller, because otherwise the later detach() call will go - // to a dangling pointer. Essentially, WeakFulfiller is reference counted, although the - // refcount never goes over 2 and we manually implement the refcounting because we need to do - // other special things when each side detaches anyway. To this end, WeakFulfiller is its own - // Disposer -- dispose() is called when the application discards its owned pointer to the - // fulfiller and detach() is called when the promise is destroyed. - -public: - KJ_DISALLOW_COPY(WeakFulfiller); - - static kj::Own make() { - WeakFulfiller* ptr = new WeakFulfiller; - return Own(ptr, *ptr); - } - - void fulfill(FixVoid&& value) override { - if (inner != nullptr) { - inner->fulfill(kj::mv(value)); - } - } - - void reject(Exception&& exception) override { - if (inner != nullptr) { - inner->reject(kj::mv(exception)); - } - } - - bool isWaiting() override { - return inner != nullptr && inner->isWaiting(); - } - - void attach(PromiseFulfiller& newInner) { - inner = &newInner; - } - - void detach(PromiseFulfiller& from) { - if (inner == nullptr) { - // Already disposed. - delete this; - } else { - KJ_IREQUIRE(inner == &from); - inner = nullptr; - } - } - -private: - mutable PromiseFulfiller* inner; - - WeakFulfiller(): inner(nullptr) {} - - void disposeImpl(void* pointer) const override { - // TODO(perf): Factor some of this out so it isn't regenerated for every fulfiller type? - - if (inner == nullptr) { - // Already detached. - delete this; - } else { - if (inner->isWaiting()) { - inner->reject(kj::Exception(kj::Exception::Type::FAILED, __FILE__, __LINE__, - kj::heapString("PromiseFulfiller was destroyed without fulfilling the promise."))); - } - inner = nullptr; - } - } -}; - -template -class PromiseAndFulfillerAdapter { -public: - PromiseAndFulfillerAdapter(PromiseFulfiller& fulfiller, - WeakFulfiller& wrapper) - : fulfiller(fulfiller), wrapper(wrapper) { - wrapper.attach(fulfiller); - } - - ~PromiseAndFulfillerAdapter() noexcept(false) { - wrapper.detach(fulfiller); - } - -private: - PromiseFulfiller& fulfiller; - WeakFulfiller& wrapper; -}; - -} // namespace _ (private) - -template -template -bool PromiseFulfiller::rejectIfThrows(Func&& func) { - KJ_IF_MAYBE(exception, kj::runCatchingExceptions(kj::mv(func))) { - reject(kj::mv(*exception)); - return false; - } else { - return true; - } -} - -template -bool PromiseFulfiller::rejectIfThrows(Func&& func) { - KJ_IF_MAYBE(exception, kj::runCatchingExceptions(kj::mv(func))) { - reject(kj::mv(*exception)); - return false; - } else { - return true; - } -} - -template -Promise newAdaptedPromise(Params&&... adapterConstructorParams) { - return Promise(false, heap<_::AdapterPromiseNode<_::FixVoid, Adapter>>( - kj::fwd(adapterConstructorParams)...)); -} - -template -PromiseFulfillerPair newPromiseAndFulfiller() { - auto wrapper = _::WeakFulfiller::make(); - - Own<_::PromiseNode> intermediate( - heap<_::AdapterPromiseNode<_::FixVoid, _::PromiseAndFulfillerAdapter>>(*wrapper)); - Promise<_::JoinPromises> promise(false, - _::maybeChain(kj::mv(intermediate), implicitCast(nullptr))); - - return PromiseFulfillerPair { kj::mv(promise), kj::mv(wrapper) }; -} - -} // namespace kj - -#endif // KJ_ASYNC_INL_H_ diff --git a/phonelibs/capnp-cpp/include/kj/async-io.h b/phonelibs/capnp-cpp/include/kj/async-io.h deleted file mode 100644 index 2804ed7289603d..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/async-io.h +++ /dev/null @@ -1,561 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_ASYNC_IO_H_ -#define KJ_ASYNC_IO_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "async.h" -#include "function.h" -#include "thread.h" -#include "time.h" - -struct sockaddr; - -namespace kj { - -#if _WIN32 -class Win32EventPort; -#else -class UnixEventPort; -#endif - -class NetworkAddress; -class AsyncOutputStream; - -// ======================================================================================= -// Streaming I/O - -class AsyncInputStream { - // Asynchronous equivalent of InputStream (from io.h). - -public: - virtual Promise read(void* buffer, size_t minBytes, size_t maxBytes); - virtual Promise tryRead(void* buffer, size_t minBytes, size_t maxBytes) = 0; - - Promise read(void* buffer, size_t bytes); - - virtual Maybe tryGetLength(); - // Get the remaining number of bytes that will be produced by this stream, if known. - // - // This is used e.g. to fill in the Content-Length header of an HTTP message. If unknown, the - // HTTP implementation may need to fall back to Transfer-Encoding: chunked. - // - // The default implementation always returns null. - - virtual Promise pumpTo( - AsyncOutputStream& output, uint64_t amount = kj::maxValue); - // Read `amount` bytes from this stream (or to EOF) and write them to `output`, returning the - // total bytes actually pumped (which is only less than `amount` if EOF was reached). - // - // Override this if your stream type knows how to pump itself to certain kinds of output - // streams more efficiently than via the naive approach. You can use - // kj::dynamicDowncastIfAvailable() to test for stream types you recognize, and if none match, - // delegate to the default implementation. - // - // The default implementation first tries calling output.tryPumpFrom(), but if that fails, it - // performs a naive pump by allocating a buffer and reading to it / writing from it in a loop. - - Promise> readAllBytes(); - Promise readAllText(); - // Read until EOF and return as one big byte array or string. -}; - -class AsyncOutputStream { - // Asynchronous equivalent of OutputStream (from io.h). - -public: - virtual Promise write(const void* buffer, size_t size) KJ_WARN_UNUSED_RESULT = 0; - virtual Promise write(ArrayPtr> pieces) - KJ_WARN_UNUSED_RESULT = 0; - - virtual Maybe> tryPumpFrom( - AsyncInputStream& input, uint64_t amount = kj::maxValue); - // Implements double-dispatch for AsyncInputStream::pumpTo(). - // - // This method should only be called from within an implementation of pumpTo(). - // - // This method examines the type of `input` to find optimized ways to pump data from it to this - // output stream. If it finds one, it performs the pump. Otherwise, it returns null. - // - // The default implementation always returns null. -}; - -class AsyncIoStream: public AsyncInputStream, public AsyncOutputStream { - // A combination input and output stream. - -public: - virtual void shutdownWrite() = 0; - // Cleanly shut down just the write end of the stream, while keeping the read end open. - - virtual void abortRead() {} - // Similar to shutdownWrite, but this will shut down the read end of the stream, and should only - // be called when an error has occurred. - - virtual void getsockopt(int level, int option, void* value, uint* length); - virtual void setsockopt(int level, int option, const void* value, uint length); - // Corresponds to getsockopt() and setsockopt() syscalls. Will throw an "unimplemented" exception - // if the stream is not a socket or the option is not appropriate for the socket type. The - // default implementations always throw "unimplemented". - - virtual void getsockname(struct sockaddr* addr, uint* length); - virtual void getpeername(struct sockaddr* addr, uint* length); - // Corresponds to getsockname() and getpeername() syscalls. Will throw an "unimplemented" - // exception if the stream is not a socket. The default implementations always throw - // "unimplemented". - // - // Note that we don't provide methods that return NetworkAddress because it usually wouldn't - // be useful. You can't connect() to or listen() on these addresses, obviously, because they are - // ephemeral addresses for a single connection. -}; - -struct OneWayPipe { - // A data pipe with an input end and an output end. (Typically backed by pipe() system call.) - - Own in; - Own out; -}; - -struct TwoWayPipe { - // A data pipe that supports sending in both directions. Each end's output sends data to the - // other end's input. (Typically backed by socketpair() system call.) - - Own ends[2]; -}; - -class ConnectionReceiver { - // Represents a server socket listening on a port. - -public: - virtual Promise> accept() = 0; - // Accept the next incoming connection. - - virtual uint getPort() = 0; - // Gets the port number, if applicable (i.e. if listening on IP). This is useful if you didn't - // specify a port when constructing the NetworkAddress -- one will have been assigned - // automatically. - - virtual void getsockopt(int level, int option, void* value, uint* length); - virtual void setsockopt(int level, int option, const void* value, uint length); - // Same as the methods of AsyncIoStream. -}; - -// ======================================================================================= -// Datagram I/O - -class AncillaryMessage { - // Represents an ancillary message (aka control message) received using the recvmsg() system - // call (or equivalent). Most apps will not use this. - -public: - inline AncillaryMessage(int level, int type, ArrayPtr data); - AncillaryMessage() = default; - - inline int getLevel() const; - // Originating protocol / socket level. - - inline int getType() const; - // Protocol-specific message type. - - template - inline Maybe as(); - // Interpret the ancillary message as the given struct type. Most ancillary messages are some - // sort of struct, so this is a convenient way to access it. Returns nullptr if the message - // is smaller than the struct -- this can happen if the message was truncated due to - // insufficient ancillary buffer space. - - template - inline ArrayPtr asArray(); - // Interpret the ancillary message as an array of items. If the message size does not evenly - // divide into elements of type T, the remainder is discarded -- this can happen if the message - // was truncated due to insufficient ancillary buffer space. - -private: - int level; - int type; - ArrayPtr data; - // Message data. In most cases you should use `as()` or `asArray()`. -}; - -class DatagramReceiver { - // Class encapsulating the recvmsg() system call. You must specify the DatagramReceiver's - // capacity in advance; if a received packet is larger than the capacity, it will be truncated. - -public: - virtual Promise receive() = 0; - // Receive a new message, overwriting this object's content. - // - // receive() may reuse the same buffers for content and ancillary data with each call. - - template - struct MaybeTruncated { - T value; - - bool isTruncated; - // True if the Receiver's capacity was insufficient to receive the value and therefore the - // value is truncated. - }; - - virtual MaybeTruncated> getContent() = 0; - // Get the content of the datagram. - - virtual MaybeTruncated> getAncillary() = 0; - // Ancilarry messages received with the datagram. See the recvmsg() system call and the cmsghdr - // struct. Most apps don't need this. - // - // If the returned value is truncated, then the last message in the array may itself be - // truncated, meaning its as() method will return nullptr or its asArray() method will - // return fewer elements than expected. Truncation can also mean that additional messages were - // available but discarded. - - virtual NetworkAddress& getSource() = 0; - // Get the datagram sender's address. - - struct Capacity { - size_t content = 8192; - // How much space to allocate for the datagram content. If a datagram is received that is - // larger than this, it will be truncated, with no way to recover the tail. - - size_t ancillary = 0; - // How much space to allocate for ancillary messages. As with content, if the ancillary data - // is larger than this, it will be truncated. - }; -}; - -class DatagramPort { -public: - virtual Promise send(const void* buffer, size_t size, NetworkAddress& destination) = 0; - virtual Promise send(ArrayPtr> pieces, - NetworkAddress& destination) = 0; - - virtual Own makeReceiver( - DatagramReceiver::Capacity capacity = DatagramReceiver::Capacity()) = 0; - // Create a new `Receiver` that can be used to receive datagrams. `capacity` specifies how much - // space to allocate for the received message. The `DatagramPort` must outlive the `Receiver`. - - virtual uint getPort() = 0; - // Gets the port number, if applicable (i.e. if listening on IP). This is useful if you didn't - // specify a port when constructing the NetworkAddress -- one will have been assigned - // automatically. - - virtual void getsockopt(int level, int option, void* value, uint* length); - virtual void setsockopt(int level, int option, const void* value, uint length); - // Same as the methods of AsyncIoStream. -}; - -// ======================================================================================= -// Networks - -class NetworkAddress { - // Represents a remote address to which the application can connect. - -public: - virtual Promise> connect() = 0; - // Make a new connection to this address. - // - // The address must not be a wildcard ("*"). If it is an IP address, it must have a port number. - - virtual Own listen() = 0; - // Listen for incoming connections on this address. - // - // The address must be local. - - virtual Own bindDatagramPort(); - // Open this address as a datagram (e.g. UDP) port. - // - // The address must be local. - - virtual Own clone() = 0; - // Returns an equivalent copy of this NetworkAddress. - - virtual String toString() = 0; - // Produce a human-readable string which hopefully can be passed to Network::parseAddress() - // to reproduce this address, although whether or not that works of course depends on the Network - // implementation. This should be called only to display the address to human users, who will - // hopefully know what they are able to do with it. -}; - -class Network { - // Factory for NetworkAddress instances, representing the network services offered by the - // operating system. - // - // This interface typically represents broad authority, and well-designed code should limit its - // use to high-level startup code and user interaction. Low-level APIs should accept - // NetworkAddress instances directly and work from there, if at all possible. - -public: - virtual Promise> parseAddress(StringPtr addr, uint portHint = 0) = 0; - // Construct a network address from a user-provided string. The format of the address - // strings is not specified at the API level, and application code should make no assumptions - // about them. These strings should always be provided by humans, and said humans will know - // what format to use in their particular context. - // - // `portHint`, if provided, specifies the "standard" IP port number for the application-level - // service in play. If the address turns out to be an IP address (v4 or v6), and it lacks a - // port number, this port will be used. If `addr` lacks a port number *and* `portHint` is - // omitted, then the returned address will only support listen() and bindDatagramPort() - // (not connect()), and an unused port will be chosen each time one of those methods is called. - - virtual Own getSockaddr(const void* sockaddr, uint len) = 0; - // Construct a network address from a legacy struct sockaddr. -}; - -// ======================================================================================= -// I/O Provider - -class AsyncIoProvider { - // Class which constructs asynchronous wrappers around the operating system's I/O facilities. - // - // Generally, the implementation of this interface must integrate closely with a particular - // `EventLoop` implementation. Typically, the EventLoop implementation itself will provide - // an AsyncIoProvider. - -public: - virtual OneWayPipe newOneWayPipe() = 0; - // Creates an input/output stream pair representing the ends of a one-way pipe (e.g. created with - // the pipe(2) system call). - - virtual TwoWayPipe newTwoWayPipe() = 0; - // Creates two AsyncIoStreams representing the two ends of a two-way pipe (e.g. created with - // socketpair(2) system call). Data written to one end can be read from the other. - - virtual Network& getNetwork() = 0; - // Creates a new `Network` instance representing the networks exposed by the operating system. - // - // DO NOT CALL THIS except at the highest levels of your code, ideally in the main() function. If - // you call this from low-level code, then you are preventing higher-level code from injecting an - // alternative implementation. Instead, if your code needs to use network functionality, it - // should ask for a `Network` as a constructor or method parameter, so that higher-level code can - // chose what implementation to use. The system network is essentially a singleton. See: - // http://www.object-oriented-security.org/lets-argue/singletons - // - // Code that uses the system network should not make any assumptions about what kinds of - // addresses it will parse, as this could differ across platforms. String addresses should come - // strictly from the user, who will know how to write them correctly for their system. - // - // With that said, KJ currently supports the following string address formats: - // - IPv4: "1.2.3.4", "1.2.3.4:80" - // - IPv6: "1234:5678::abcd", "[1234:5678::abcd]:80" - // - Local IP wildcard (covers both v4 and v6): "*", "*:80" - // - Symbolic names: "example.com", "example.com:80", "example.com:http", "1.2.3.4:http" - // - Unix domain: "unix:/path/to/socket" - - struct PipeThread { - // A combination of a thread and a two-way pipe that communicates with that thread. - // - // The fields are intentionally ordered so that the pipe will be destroyed (and therefore - // disconnected) before the thread is destroyed (and therefore joined). Thus if the thread - // arranges to exit when it detects disconnect, destruction should be clean. - - Own thread; - Own pipe; - }; - - virtual PipeThread newPipeThread( - Function startFunc) = 0; - // Create a new thread and set up a two-way pipe (socketpair) which can be used to communicate - // with it. One end of the pipe is passed to the thread's start function and the other end of - // the pipe is returned. The new thread also gets its own `AsyncIoProvider` instance and will - // already have an active `EventLoop` when `startFunc` is called. - // - // TODO(someday): I'm not entirely comfortable with this interface. It seems to be doing too - // much at once but I'm not sure how to cleanly break it down. - - virtual Timer& getTimer() = 0; - // Returns a `Timer` based on real time. Time does not pass while event handlers are running -- - // it only updates when the event loop polls for system events. This means that calling `now()` - // on this timer does not require a system call. - // - // This timer is not affected by changes to the system date. It is unspecified whether the timer - // continues to count while the system is suspended. -}; - -class LowLevelAsyncIoProvider { - // Similar to `AsyncIoProvider`, but represents a lower-level interface that may differ on - // different operating systems. You should prefer to use `AsyncIoProvider` over this interface - // whenever possible, as `AsyncIoProvider` is portable and friendlier to dependency-injection. - // - // On Unix, this interface can be used to import native file descriptors into the async framework. - // Different implementations of this interface might work on top of different event handling - // primitives, such as poll vs. epoll vs. kqueue vs. some higher-level event library. - // - // On Windows, this interface can be used to import native HANDLEs into the async framework. - // Different implementations of this interface might work on top of different event handling - // primitives, such as I/O completion ports vs. completion routines. - // - // TODO(port): Actually implement Windows support. - -public: - // --------------------------------------------------------------------------- - // Unix-specific stuff - - enum Flags { - // Flags controlling how to wrap a file descriptor. - - TAKE_OWNERSHIP = 1 << 0, - // The returned object should own the file descriptor, automatically closing it when destroyed. - // The close-on-exec flag will be set on the descriptor if it is not already. - // - // If this flag is not used, then the file descriptor is not automatically closed and the - // close-on-exec flag is not modified. - -#if !_WIN32 - ALREADY_CLOEXEC = 1 << 1, - // Indicates that the close-on-exec flag is known already to be set, so need not be set again. - // Only relevant when combined with TAKE_OWNERSHIP. - // - // On Linux, all system calls which yield new file descriptors have flags or variants which - // set the close-on-exec flag immediately. Unfortunately, other OS's do not. - - ALREADY_NONBLOCK = 1 << 2 - // Indicates that the file descriptor is known already to be in non-blocking mode, so the flag - // need not be set again. Otherwise, all wrap*Fd() methods will enable non-blocking mode - // automatically. - // - // On Linux, all system calls which yield new file descriptors have flags or variants which - // enable non-blocking mode immediately. Unfortunately, other OS's do not. -#endif - }; - -#if _WIN32 - typedef uintptr_t Fd; - // On Windows, the `fd` parameter to each of these methods must be a SOCKET, and must have the - // flag WSA_FLAG_OVERLAPPED (which socket() uses by default, but WSASocket() wants you to specify - // explicitly). -#else - typedef int Fd; - // On Unix, any arbitrary file descriptor is supported. -#endif - - virtual Own wrapInputFd(Fd fd, uint flags = 0) = 0; - // Create an AsyncInputStream wrapping a file descriptor. - // - // `flags` is a bitwise-OR of the values of the `Flags` enum. - - virtual Own wrapOutputFd(Fd fd, uint flags = 0) = 0; - // Create an AsyncOutputStream wrapping a file descriptor. - // - // `flags` is a bitwise-OR of the values of the `Flags` enum. - - virtual Own wrapSocketFd(Fd fd, uint flags = 0) = 0; - // Create an AsyncIoStream wrapping a socket file descriptor. - // - // `flags` is a bitwise-OR of the values of the `Flags` enum. - - virtual Promise> wrapConnectingSocketFd( - Fd fd, const struct sockaddr* addr, uint addrlen, uint flags = 0) = 0; - // Create an AsyncIoStream wrapping a socket and initiate a connection to the given address. - // The returned promise does not resolve until connection has completed. - // - // `flags` is a bitwise-OR of the values of the `Flags` enum. - - virtual Own wrapListenSocketFd(Fd fd, uint flags = 0) = 0; - // Create an AsyncIoStream wrapping a listen socket file descriptor. This socket should already - // have had `bind()` and `listen()` called on it, so it's ready for `accept()`. - // - // `flags` is a bitwise-OR of the values of the `Flags` enum. - - virtual Own wrapDatagramSocketFd(Fd fd, uint flags = 0); - - virtual Timer& getTimer() = 0; - // Returns a `Timer` based on real time. Time does not pass while event handlers are running -- - // it only updates when the event loop polls for system events. This means that calling `now()` - // on this timer does not require a system call. - // - // This timer is not affected by changes to the system date. It is unspecified whether the timer - // continues to count while the system is suspended. -}; - -Own newAsyncIoProvider(LowLevelAsyncIoProvider& lowLevel); -// Make a new AsyncIoProvider wrapping a `LowLevelAsyncIoProvider`. - -struct AsyncIoContext { - Own lowLevelProvider; - Own provider; - WaitScope& waitScope; - -#if _WIN32 - Win32EventPort& win32EventPort; -#else - UnixEventPort& unixEventPort; - // TEMPORARY: Direct access to underlying UnixEventPort, mainly for waiting on signals. This - // field will go away at some point when we have a chance to improve these interfaces. -#endif -}; - -AsyncIoContext setupAsyncIo(); -// Convenience method which sets up the current thread with everything it needs to do async I/O. -// The returned objects contain an `EventLoop` which is wrapping an appropriate `EventPort` for -// doing I/O on the host system, so everything is ready for the thread to start making async calls -// and waiting on promises. -// -// You would typically call this in your main() loop or in the start function of a thread. -// Example: -// -// int main() { -// auto ioContext = kj::setupAsyncIo(); -// -// // Now we can call an async function. -// Promise textPromise = getHttp(*ioContext.provider, "http://example.com"); -// -// // And we can wait for the promise to complete. Note that you can only use `wait()` -// // from the top level, not from inside a promise callback. -// String text = textPromise.wait(ioContext.waitScope); -// print(text); -// return 0; -// } -// -// WARNING: An AsyncIoContext can only be used in the thread and process that created it. In -// particular, note that after a fork(), an AsyncIoContext created in the parent process will -// not work correctly in the child, even if the parent ceases to use its copy. In particular -// note that this means that server processes which daemonize themselves at startup must wait -// until after daemonization to create an AsyncIoContext. - -// ======================================================================================= -// inline implementation details - -inline AncillaryMessage::AncillaryMessage( - int level, int type, ArrayPtr data) - : level(level), type(type), data(data) {} - -inline int AncillaryMessage::getLevel() const { return level; } -inline int AncillaryMessage::getType() const { return type; } - -template -inline Maybe AncillaryMessage::as() { - if (data.size() >= sizeof(T)) { - return *reinterpret_cast(data.begin()); - } else { - return nullptr; - } -} - -template -inline ArrayPtr AncillaryMessage::asArray() { - return arrayPtr(reinterpret_cast(data.begin()), data.size() / sizeof(T)); -} - -} // namespace kj - -#endif // KJ_ASYNC_IO_H_ diff --git a/phonelibs/capnp-cpp/include/kj/async-prelude.h b/phonelibs/capnp-cpp/include/kj/async-prelude.h deleted file mode 100644 index 0a5843f88a4d77..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/async-prelude.h +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -// This file contains a bunch of internal declarations that must appear before async.h can start. -// We don't define these directly in async.h because it makes the file hard to read. - -#ifndef KJ_ASYNC_PRELUDE_H_ -#define KJ_ASYNC_PRELUDE_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "exception.h" -#include "tuple.h" - -namespace kj { - -class EventLoop; -template -class Promise; -class WaitScope; - -template -Promise> joinPromises(Array>&& promises); -Promise joinPromises(Array>&& promises); - -namespace _ { // private - -template struct JoinPromises_ { typedef T Type; }; -template struct JoinPromises_> { typedef T Type; }; - -template -using JoinPromises = typename JoinPromises_::Type; -// If T is Promise, resolves to U, otherwise resolves to T. -// -// TODO(cleanup): Rename to avoid confusion with joinPromises() call which is completely -// unrelated. - -class PropagateException { - // A functor which accepts a kj::Exception as a parameter and returns a broken promise of - // arbitrary type which simply propagates the exception. -public: - class Bottom { - public: - Bottom(Exception&& exception): exception(kj::mv(exception)) {} - - Exception asException() { return kj::mv(exception); } - - private: - Exception exception; - }; - - Bottom operator()(Exception&& e) { - return Bottom(kj::mv(e)); - } - Bottom operator()(const Exception& e) { - return Bottom(kj::cp(e)); - } -}; - -template -struct ReturnType_ { typedef decltype(instance()(instance())) Type; }; -template -struct ReturnType_ { typedef decltype(instance()()) Type; }; - -template -using ReturnType = typename ReturnType_::Type; -// The return type of functor Func given a parameter of type T, with the special exception that if -// T is void, this is the return type of Func called with no arguments. - -template struct SplitTuplePromise_ { typedef Promise Type; }; -template -struct SplitTuplePromise_> { - typedef kj::Tuple>...> Type; -}; - -template -using SplitTuplePromise = typename SplitTuplePromise_::Type; -// T -> Promise -// Tuple -> Tuple> - -struct Void {}; -// Application code should NOT refer to this! See `kj::READY_NOW` instead. - -template struct FixVoid_ { typedef T Type; }; -template <> struct FixVoid_ { typedef Void Type; }; -template using FixVoid = typename FixVoid_::Type; -// FixVoid is just T unless T is void in which case it is _::Void (an empty struct). - -template struct UnfixVoid_ { typedef T Type; }; -template <> struct UnfixVoid_ { typedef void Type; }; -template using UnfixVoid = typename UnfixVoid_::Type; -// UnfixVoid is the opposite of FixVoid. - -template -struct MaybeVoidCaller { - // Calls the function converting a Void input to an empty parameter list and a void return - // value to a Void output. - - template - static inline Out apply(Func& func, In&& in) { - return func(kj::mv(in)); - } -}; -template -struct MaybeVoidCaller { - template - static inline Out apply(Func& func, In& in) { - return func(in); - } -}; -template -struct MaybeVoidCaller { - template - static inline Out apply(Func& func, Void&& in) { - return func(); - } -}; -template -struct MaybeVoidCaller { - template - static inline Void apply(Func& func, In&& in) { - func(kj::mv(in)); - return Void(); - } -}; -template -struct MaybeVoidCaller { - template - static inline Void apply(Func& func, In& in) { - func(in); - return Void(); - } -}; -template <> -struct MaybeVoidCaller { - template - static inline Void apply(Func& func, Void&& in) { - func(); - return Void(); - } -}; - -template -inline T&& returnMaybeVoid(T&& t) { - return kj::fwd(t); -} -inline void returnMaybeVoid(Void&& v) {} - -class ExceptionOrValue; -class PromiseNode; -class ChainPromiseNode; -template -class ForkHub; - -class TaskSetImpl; - -class Event; - -class PromiseBase { -public: - kj::String trace(); - // Dump debug info about this promise. - -private: - Own node; - - PromiseBase() = default; - PromiseBase(Own&& node): node(kj::mv(node)) {} - - friend class kj::EventLoop; - friend class ChainPromiseNode; - template - friend class kj::Promise; - friend class TaskSetImpl; - template - friend Promise> kj::joinPromises(Array>&& promises); - friend Promise kj::joinPromises(Array>&& promises); -}; - -void detach(kj::Promise&& promise); -void waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result, WaitScope& waitScope); -Promise yield(); -Own neverDone(); - -class NeverDone { -public: - template - operator Promise() const { - return Promise(false, neverDone()); - } - - KJ_NORETURN(void wait(WaitScope& waitScope) const); -}; - -} // namespace _ (private) -} // namespace kj - -#endif // KJ_ASYNC_PRELUDE_H_ diff --git a/phonelibs/capnp-cpp/include/kj/async-unix.h b/phonelibs/capnp-cpp/include/kj/async-unix.h deleted file mode 100644 index 06f128a50eeddb..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/async-unix.h +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_ASYNC_UNIX_H_ -#define KJ_ASYNC_UNIX_H_ - -#if _WIN32 -#error "This file is Unix-specific. On Windows, include async-win32.h instead." -#endif - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "async.h" -#include "time.h" -#include "vector.h" -#include "io.h" -#include - -#if __linux__ && !__BIONIC__ && !defined(KJ_USE_EPOLL) -// Default to epoll on Linux, except on Bionic (Android) which doesn't have signalfd.h. -#define KJ_USE_EPOLL 1 -#endif - -namespace kj { - -class UnixEventPort: public EventPort { - // An EventPort implementation which can wait for events on file descriptors as well as signals. - // This API only makes sense on Unix. - // - // The implementation uses `poll()` or possibly a platform-specific API (e.g. epoll, kqueue). - // To also wait on signals without race conditions, the implementation may block signals until - // just before `poll()` while using a signal handler which `siglongjmp()`s back to just before - // the signal was unblocked, or it may use a nicer platform-specific API like signalfd. - // - // The implementation reserves a signal for internal use. By default, it uses SIGUSR1. If you - // need to use SIGUSR1 for something else, you must offer a different signal by calling - // setReservedSignal() at startup. - // - // WARNING: A UnixEventPort can only be used in the thread and process that created it. In - // particular, note that after a fork(), a UnixEventPort created in the parent process will - // not work correctly in the child, even if the parent ceases to use its copy. In particular - // note that this means that server processes which daemonize themselves at startup must wait - // until after daemonization to create a UnixEventPort. - -public: - UnixEventPort(); - ~UnixEventPort() noexcept(false); - - class FdObserver; - // Class that watches an fd for readability or writability. See definition below. - - Promise onSignal(int signum); - // When the given signal is delivered to this thread, return the corresponding siginfo_t. - // The signal must have been captured using `captureSignal()`. - // - // If `onSignal()` has not been called, the signal will remain blocked in this thread. - // Therefore, a signal which arrives before `onSignal()` was called will not be "missed" -- the - // next call to 'onSignal()' will receive it. Also, you can control which thread receives a - // process-wide signal by only calling `onSignal()` on that thread's event loop. - // - // The result of waiting on the same signal twice at once is undefined. - - static void captureSignal(int signum); - // Arranges for the given signal to be captured and handled via UnixEventPort, so that you may - // then pass it to `onSignal()`. This method is static because it registers a signal handler - // which applies process-wide. If any other threads exist in the process when `captureSignal()` - // is called, you *must* set the signal mask in those threads to block this signal, otherwise - // terrible things will happen if the signal happens to be delivered to those threads. If at - // all possible, call `captureSignal()` *before* creating threads, so that threads you create in - // the future will inherit the proper signal mask. - // - // To un-capture a signal, simply install a different signal handler and then un-block it from - // the signal mask. - - static void setReservedSignal(int signum); - // Sets the signal number which `UnixEventPort` reserves for internal use. If your application - // needs to use SIGUSR1, call this at startup (before any calls to `captureSignal()` and before - // constructing an `UnixEventPort`) to offer a different signal. - - Timer& getTimer() { return timerImpl; } - - // implements EventPort ------------------------------------------------------ - bool wait() override; - bool poll() override; - void wake() const override; - -private: - struct TimerSet; // Defined in source file to avoid STL include. - class TimerPromiseAdapter; - class SignalPromiseAdapter; - - TimerImpl timerImpl; - - SignalPromiseAdapter* signalHead = nullptr; - SignalPromiseAdapter** signalTail = &signalHead; - - TimePoint readClock(); - void gotSignal(const siginfo_t& siginfo); - - friend class TimerPromiseAdapter; - -#if KJ_USE_EPOLL - AutoCloseFd epollFd; - AutoCloseFd signalFd; - AutoCloseFd eventFd; // Used for cross-thread wakeups. - - sigset_t signalFdSigset; - // Signal mask as currently set on the signalFd. Tracked so we can detect whether or not it - // needs updating. - - bool doEpollWait(int timeout); - -#else - class PollContext; - - FdObserver* observersHead = nullptr; - FdObserver** observersTail = &observersHead; - - unsigned long long threadId; // actually pthread_t -#endif -}; - -class UnixEventPort::FdObserver { - // Object which watches a file descriptor to determine when it is readable or writable. - // - // For listen sockets, "readable" means that there is a connection to accept(). For everything - // else, it means that read() (or recv()) will return data. - // - // The presence of out-of-band data should NOT fire this event. However, the event may - // occasionally fire spuriously (when there is actually no data to read), and one thing that can - // cause such spurious events is the arrival of OOB data on certain platforms whose event - // interfaces fail to distinguish between regular and OOB data (e.g. Mac OSX). - // - // WARNING: The exact behavior of this class differs across systems, since event interfaces - // vary wildly. Be sure to read the documentation carefully and avoid depending on unspecified - // behavior. If at all possible, use the higher-level AsyncInputStream interface instead. - -public: - enum Flags { - OBSERVE_READ = 1, - OBSERVE_WRITE = 2, - OBSERVE_URGENT = 4, - OBSERVE_READ_WRITE = OBSERVE_READ | OBSERVE_WRITE - }; - - FdObserver(UnixEventPort& eventPort, int fd, uint flags); - // Begin watching the given file descriptor for readability. Only one ReadObserver may exist - // for a given file descriptor at a time. - - ~FdObserver() noexcept(false); - - KJ_DISALLOW_COPY(FdObserver); - - Promise whenBecomesReadable(); - // Resolves the next time the file descriptor transitions from having no data to read to having - // some data to read. - // - // KJ uses "edge-triggered" event notification whenever possible. As a result, it is an error - // to call this method when there is already data in the read buffer which has been there since - // prior to the last turn of the event loop or prior to creation FdWatcher. In this case, it is - // unspecified whether the promise will ever resolve -- it depends on the underlying event - // mechanism being used. - // - // In order to avoid this problem, make sure that you only call `whenBecomesReadable()` - // only at times when you know the buffer is empty. You know this for sure when one of the - // following happens: - // * read() or recv() fails with EAGAIN or EWOULDBLOCK. (You MUST have non-blocking mode - // enabled on the fd!) - // * The file descriptor is a regular byte-oriented object (like a socket or pipe), - // read() or recv() returns fewer than the number of bytes requested, and `atEndHint()` - // returns false. This can only happen if the buffer is empty but EOF is not reached. (Note, - // though, that for record-oriented file descriptors like Linux's inotify interface, this - // rule does not hold, because it could simply be that the next record did not fit into the - // space available.) - // - // It is an error to call `whenBecomesReadable()` again when the promise returned previously - // has not yet resolved. If you do this, the previous promise may throw an exception. - - inline Maybe atEndHint() { return atEnd; } - // Returns true if the event system has indicated that EOF has been received. There may still - // be data in the read buffer, but once that is gone, there's nothing left. - // - // Returns false if the event system has indicated that EOF had NOT been received as of the - // last turn of the event loop. - // - // Returns nullptr if the event system does not know whether EOF has been reached. In this - // case, the only way to know for sure is to call read() or recv() and check if it returns - // zero. - // - // This hint may be useful as an optimization to avoid an unnecessary system call. - - Promise whenBecomesWritable(); - // Resolves the next time the file descriptor transitions from having no space available in the - // write buffer to having some space available. - // - // KJ uses "edge-triggered" event notification whenever possible. As a result, it is an error - // to call this method when there is already space in the write buffer which has been there - // since prior to the last turn of the event loop or prior to creation FdWatcher. In this case, - // it is unspecified whether the promise will ever resolve -- it depends on the underlying - // event mechanism being used. - // - // In order to avoid this problem, make sure that you only call `whenBecomesWritable()` - // only at times when you know the buffer is full. You know this for sure when one of the - // following happens: - // * write() or send() fails with EAGAIN or EWOULDBLOCK. (You MUST have non-blocking mode - // enabled on the fd!) - // * write() or send() succeeds but accepts fewer than the number of bytes provided. This can - // only happen if the buffer is full. - // - // It is an error to call `whenBecomesWritable()` again when the promise returned previously - // has not yet resolved. If you do this, the previous promise may throw an exception. - - Promise whenUrgentDataAvailable(); - // Resolves the next time the file descriptor's read buffer contains "urgent" data. - // - // The conditions for availability of urgent data are specific to the file descriptor's - // underlying implementation. - // - // It is an error to call `whenUrgentDataAvailable()` again when the promise returned previously - // has not yet resolved. If you do this, the previous promise may throw an exception. - // - // WARNING: This has some known weird behavior on macOS. See - // https://github.com/sandstorm-io/capnproto/issues/374. - -private: - UnixEventPort& eventPort; - int fd; - uint flags; - - kj::Maybe>> readFulfiller; - kj::Maybe>> writeFulfiller; - kj::Maybe>> urgentFulfiller; - // Replaced each time `whenBecomesReadable()` or `whenBecomesWritable()` is called. Reverted to - // null every time an event is fired. - - Maybe atEnd; - - void fire(short events); - -#if !KJ_USE_EPOLL - FdObserver* next; - FdObserver** prev; - // Linked list of observers which currently have a non-null readFulfiller or writeFulfiller. - // If `prev` is null then the observer is not currently in the list. - - short getEventMask(); -#endif - - friend class UnixEventPort; -}; - -} // namespace kj - -#endif // KJ_ASYNC_UNIX_H_ diff --git a/phonelibs/capnp-cpp/include/kj/async-win32.h b/phonelibs/capnp-cpp/include/kj/async-win32.h deleted file mode 100644 index b70c42e016c5ba..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/async-win32.h +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright (c) 2016 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_ASYNC_WIN32_H_ -#define KJ_ASYNC_WIN32_H_ - -#if !_WIN32 -#error "This file is Windows-specific. On Unix, include async-unix.h instead." -#endif - -#include "async.h" -#include "time.h" -#include "io.h" -#include -#include - -// Include windows.h as lean as possible. (If you need more of the Windows API for your app, -// #include windows.h yourself before including this header.) -#define WIN32_LEAN_AND_MEAN 1 -#define NOSERVICE 1 -#define NOMCX 1 -#define NOIME 1 -#include -#include "windows-sanity.h" - -namespace kj { - -class Win32EventPort: public EventPort { - // Abstract base interface for EventPorts that can listen on Win32 event types. Due to the - // absurd complexity of the Win32 API, it's not possible to standardize on a single - // implementation of EventPort. In particular, there is no way for a single thread to use I/O - // completion ports (the most efficient way of handling I/O) while at the same time waiting for - // signalable handles or UI messages. - // - // Note that UI messages are not supported at all by this interface because the message queue - // is implemented by user32.dll and we want libkj to depend only on kernel32.dll. A separate - // compat library could provide a Win32EventPort implementation that works with the UI message - // queue. - -public: - // --------------------------------------------------------------------------- - // overlapped I/O - - struct IoResult { - DWORD errorCode; - DWORD bytesTransferred; - }; - - class IoOperation { - public: - virtual LPOVERLAPPED getOverlapped() = 0; - // Gets the OVERLAPPED structure to pass to the Win32 I/O call. Do NOT modify it; just pass it - // on. - - virtual Promise onComplete() = 0; - // After making the Win32 call, if the return value indicates that the operation was - // successfully queued (i.e. the completion event will definitely occur), call this to wait - // for completion. - // - // You MUST call this if the operation was successfully queued, and you MUST NOT call this - // otherwise. If the Win32 call failed (without queuing any operation or event) then you should - // simply drop the IoOperation object. - // - // Dropping the returned Promise cancels the operation via Win32's CancelIoEx(). The destructor - // will wait for the cancellation to complete, such that after dropping the proimse it is safe - // to free the buffer that the operation was reading from / writing to. - // - // You may safely drop the `IoOperation` while still waiting for this promise. You may not, - // however, drop the `IoObserver`. - }; - - class IoObserver { - public: - virtual Own newOperation(uint64_t offset) = 0; - // Begin an I/O operation. For file operations, `offset` is the offset within the file at - // which the operation will start. For stream operations, `offset` is ignored. - }; - - virtual Own observeIo(HANDLE handle) = 0; - // Given a handle which supports overlapped I/O, arrange to receive I/O completion events via - // this EventPort. - // - // Different Win32EventPort implementations may handle this in different ways, such as by using - // completion routines (APCs) or by using I/O completion ports. The caller should not assume - // any particular technique. - // - // WARNING: It is only safe to call observeIo() on a particular handle once during its lifetime. - // You cannot observe the same handle from multiple Win32EventPorts, even if not at the same - // time. This is because the Win32 API provides no way to disassociate a handle from an I/O - // completion port once it is associated. - - // --------------------------------------------------------------------------- - // signalable handles - // - // Warning: Due to limitations in the Win32 API, implementations of EventPort may be forced to - // spawn additional threads to wait for signaled objects. This is necessary if the EventPort - // implementation is based on I/O completion ports, or if you need to wait on more than 64 - // handles at once. - - class SignalObserver { - public: - virtual Promise onSignaled() = 0; - // Returns a promise that completes the next time the handle enters the signaled state. - // - // Depending on the type of handle, the handle may automatically be reset to a non-signaled - // state before the promise resolves. The underlying implementaiton uses WaitForSingleObject() - // or an equivalent wait call, so check the documentation for that to understand the semantics. - // - // If the handle is a mutex and it is abandoned without being unlocked, the promise breaks with - // an exception. - - virtual Promise onSignaledOrAbandoned() = 0; - // Like onSingaled(), but instead of throwing when a mutex is abandoned, resolves to `true`. - // Resolves to `false` for non-abandoned signals. - }; - - virtual Own observeSignalState(HANDLE handle) = 0; - // Given a handle that supports waiting for it to become "signaled" via WaitForSingleObject(), - // return an object that can wait for this state using the EventPort. - - // --------------------------------------------------------------------------- - // APCs - - virtual void allowApc() = 0; - // If this is ever called, the Win32EventPort will switch modes so that APCs can be scheduled - // on the thread, e.g. through the Win32 QueueUserAPC() call. In the future, this may be enabled - // by default. However, as of this writing, Wine does not support the necessary - // GetQueuedCompletionStatusEx() call, thus allowApc() breaks Wine support. (Tested on Wine - // 1.8.7.) - // - // If the event port implementation can't support APCs for some reason, this throws. - - // --------------------------------------------------------------------------- - // time - - virtual Timer& getTimer() = 0; -}; - -class Win32WaitObjectThreadPool { - // Helper class that implements Win32EventPort::observeSignalState() by spawning additional - // threads as needed to perform the actual waiting. - // - // This class is intended to be used to assist in building Win32EventPort implementations. - -public: - Win32WaitObjectThreadPool(uint mainThreadCount = 0); - // `mainThreadCount` indicates the number of objects the main thread is able to listen on - // directly. Typically this would be zero (e.g. if the main thread watches an I/O completion - // port) or MAXIMUM_WAIT_OBJECTS (e.g. if the main thread is a UI thread but can use - // MsgWaitForMultipleObjectsEx() to wait on some handles at the same time as messages). - - Own observeSignalState(HANDLE handle); - // Implemetns Win32EventPort::observeSignalState(). - - uint prepareMainThreadWait(HANDLE* handles[]); - // Call immediately before invoking WaitForMultipleObjects() or similar in the main thread. - // Fills in `handles` with the handle pointers to wait on, and returns the number of handles - // in this array. (The array should be allocated to be at least the size passed to the - // constructor). - // - // There's no need to call this if `mainThreadCount` as passed to the constructor was zero. - - bool finishedMainThreadWait(DWORD returnCode); - // Call immediately after invoking WaitForMultipleObjects() or similar in the main thread, - // passing the value returend by that call. Returns true if the event indicated by `returnCode` - // has been handled (i.e. it was WAIT_OBJECT_n or WAIT_ABANDONED_n where n is in-range for the - // last call to prepareMainThreadWait()). -}; - -class Win32IocpEventPort final: public Win32EventPort { - // An EventPort implementation which uses Windows I/O completion ports to listen for events. - // - // With this implementation, observeSignalState() requires spawning a separate thread. - -public: - Win32IocpEventPort(); - ~Win32IocpEventPort() noexcept(false); - - // implements EventPort ------------------------------------------------------ - bool wait() override; - bool poll() override; - void wake() const override; - - // implements Win32IocpEventPort --------------------------------------------- - Own observeIo(HANDLE handle) override; - Own observeSignalState(HANDLE handle) override; - Timer& getTimer() override { return timerImpl; } - void allowApc() override { isAllowApc = true; } - -private: - class IoPromiseAdapter; - class IoOperationImpl; - class IoObserverImpl; - - AutoCloseHandle iocp; - AutoCloseHandle thread; - Win32WaitObjectThreadPool waitThreads; - TimerImpl timerImpl; - mutable std::atomic sentWake {false}; - bool isAllowApc = false; - - static TimePoint readClock(); - - void waitIocp(DWORD timeoutMs); - // Wait on the I/O completion port for up to timeoutMs and pump events. Does not advance the - // timer; caller must do that. - - bool receivedWake(); - - static AutoCloseHandle newIocpHandle(); - static AutoCloseHandle openCurrentThread(); -}; - -} // namespace kj - -#endif // KJ_ASYNC_WIN32_H_ diff --git a/phonelibs/capnp-cpp/include/kj/async.h b/phonelibs/capnp-cpp/include/kj/async.h deleted file mode 100644 index 5a9d9bdae717dc..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/async.h +++ /dev/null @@ -1,682 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_ASYNC_H_ -#define KJ_ASYNC_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "async-prelude.h" -#include "exception.h" -#include "refcount.h" - -namespace kj { - -class EventLoop; -class WaitScope; - -template -class Promise; -template -class ForkedPromise; -template -class PromiseFulfiller; -template -struct PromiseFulfillerPair; - -template -using PromiseForResult = Promise<_::JoinPromises<_::ReturnType>>; -// Evaluates to the type of Promise for the result of calling functor type Func with parameter type -// T. If T is void, then the promise is for the result of calling Func with no arguments. If -// Func itself returns a promise, the promises are joined, so you never get Promise>. - -// ======================================================================================= -// Promises - -template -class Promise: protected _::PromiseBase { - // The basic primitive of asynchronous computation in KJ. Similar to "futures", but designed - // specifically for event loop concurrency. Similar to E promises and JavaScript Promises/A. - // - // A Promise represents a promise to produce a value of type T some time in the future. Once - // that value has been produced, the promise is "fulfilled". Alternatively, a promise can be - // "broken", with an Exception describing what went wrong. You may implicitly convert a value of - // type T to an already-fulfilled Promise. You may implicitly convert the constant - // `kj::READY_NOW` to an already-fulfilled Promise. You may also implicitly convert a - // `kj::Exception` to an already-broken promise of any type. - // - // Promises are linear types -- they are moveable but not copyable. If a Promise is destroyed - // or goes out of scope (without being moved elsewhere), any ongoing asynchronous operations - // meant to fulfill the promise will be canceled if possible. All methods of `Promise` (unless - // otherwise noted) actually consume the promise in the sense of move semantics. (Arguably they - // should be rvalue-qualified, but at the time this interface was created compilers didn't widely - // support that yet and anyway it would be pretty ugly typing kj::mv(promise).whatever().) If - // you want to use one Promise in two different places, you must fork it with `fork()`. - // - // To use the result of a Promise, you must call `then()` and supply a callback function to - // call with the result. `then()` returns another promise, for the result of the callback. - // Any time that this would result in Promise>, the promises are collapsed into a - // simple Promise that first waits for the outer promise, then the inner. Example: - // - // // Open a remote file, read the content, and then count the - // // number of lines of text. - // // Note that none of the calls here block. `file`, `content` - // // and `lineCount` are all initialized immediately before any - // // asynchronous operations occur. The lambda callbacks are - // // called later. - // Promise> file = openFtp("ftp://host/foo/bar"); - // Promise content = file.then( - // [](Own file) -> Promise { - // return file.readAll(); - // }); - // Promise lineCount = content.then( - // [](String text) -> int { - // uint count = 0; - // for (char c: text) count += (c == '\n'); - // return count; - // }); - // - // For `then()` to work, the current thread must have an active `EventLoop`. Each callback - // is scheduled to execute in that loop. Since `then()` schedules callbacks only on the current - // thread's event loop, you do not need to worry about two callbacks running at the same time. - // You will need to set up at least one `EventLoop` at the top level of your program before you - // can use promises. - // - // To adapt a non-Promise-based asynchronous API to promises, use `newAdaptedPromise()`. - // - // Systems using promises should consider supporting the concept of "pipelining". Pipelining - // means allowing a caller to start issuing method calls against a promised object before the - // promise has actually been fulfilled. This is particularly useful if the promise is for a - // remote object living across a network, as this can avoid round trips when chaining a series - // of calls. It is suggested that any class T which supports pipelining implement a subclass of - // Promise which adds "eventual send" methods -- methods which, when called, say "please - // invoke the corresponding method on the promised value once it is available". These methods - // should in turn return promises for the eventual results of said invocations. Cap'n Proto, - // for example, implements the type `RemotePromise` which supports pipelining RPC requests -- see - // `capnp/capability.h`. - // - // KJ Promises are based on E promises: - // http://wiki.erights.org/wiki/Walnut/Distributed_Computing#Promises - // - // KJ Promises are also inspired in part by the evolving standards for JavaScript/ECMAScript - // promises, which are themselves influenced by E promises: - // http://promisesaplus.com/ - // https://github.com/domenic/promises-unwrapping - -public: - Promise(_::FixVoid value); - // Construct an already-fulfilled Promise from a value of type T. For non-void promises, the - // parameter type is simply T. So, e.g., in a function that returns `Promise`, you can - // say `return 123;` to return a promise that is already fulfilled to 123. - // - // For void promises, use `kj::READY_NOW` as the value, e.g. `return kj::READY_NOW`. - - Promise(kj::Exception&& e); - // Construct an already-broken Promise. - - inline Promise(decltype(nullptr)) {} - - template - PromiseForResult then(Func&& func, ErrorFunc&& errorHandler = _::PropagateException()) - KJ_WARN_UNUSED_RESULT; - // Register a continuation function to be executed when the promise completes. The continuation - // (`func`) takes the promised value (an rvalue of type `T`) as its parameter. The continuation - // may return a new value; `then()` itself returns a promise for the continuation's eventual - // result. If the continuation itself returns a `Promise`, then `then()` shall also return - // a `Promise` which first waits for the original promise, then executes the continuation, - // then waits for the inner promise (i.e. it automatically "unwraps" the promise). - // - // In all cases, `then()` returns immediately. The continuation is executed later. The - // continuation is always executed on the same EventLoop (and, therefore, the same thread) which - // called `then()`, therefore no synchronization is necessary on state shared by the continuation - // and the surrounding scope. If no EventLoop is running on the current thread, `then()` throws - // an exception. - // - // You may also specify an error handler continuation as the second parameter. `errorHandler` - // must be a functor taking a parameter of type `kj::Exception&&`. It must return the same - // type as `func` returns (except when `func` returns `Promise`, in which case `errorHandler` - // may return either `Promise` or just `U`). The default error handler simply propagates the - // exception to the returned promise. - // - // Either `func` or `errorHandler` may, of course, throw an exception, in which case the promise - // is broken. When compiled with -fno-exceptions, the framework will still detect when a - // recoverable exception was thrown inside of a continuation and will consider the promise - // broken even though a (presumably garbage) result was returned. - // - // If the returned promise is destroyed before the callback runs, the callback will be canceled - // (it will never run). - // - // Note that `then()` -- like all other Promise methods -- consumes the promise on which it is - // called, in the sense of move semantics. After returning, the original promise is no longer - // valid, but `then()` returns a new promise. - // - // *Advanced implementation tips:* Most users will never need to worry about the below, but - // it is good to be aware of. - // - // As an optimization, if the callback function `func` does _not_ return another promise, then - // execution of `func` itself may be delayed until its result is known to be needed. The - // expectation here is that `func` is just doing some transformation on the results, not - // scheduling any other actions, therefore the system doesn't need to be proactive about - // evaluating it. This way, a chain of trivial then() transformations can be executed all at - // once without repeatedly re-scheduling through the event loop. Use the `eagerlyEvaluate()` - // method to suppress this behavior. - // - // On the other hand, if `func` _does_ return another promise, then the system evaluates `func` - // as soon as possible, because the promise it returns might be for a newly-scheduled - // long-running asynchronous task. - // - // As another optimization, when a callback function registered with `then()` is actually - // scheduled, it is scheduled to occur immediately, preempting other work in the event queue. - // This allows a long chain of `then`s to execute all at once, improving cache locality by - // clustering operations on the same data. However, this implies that starvation can occur - // if a chain of `then()`s takes a very long time to execute without ever stopping to wait for - // actual I/O. To solve this, use `kj::evalLater()` to yield control; this way, all other events - // in the queue will get a chance to run before your callback is executed. - - Promise ignoreResult() KJ_WARN_UNUSED_RESULT { return then([](T&&) {}); } - // Convenience method to convert the promise to a void promise by ignoring the return value. - // - // You must still wait on the returned promise if you want the task to execute. - - template - Promise catch_(ErrorFunc&& errorHandler) KJ_WARN_UNUSED_RESULT; - // Equivalent to `.then(identityFunc, errorHandler)`, where `identifyFunc` is a function that - // just returns its input. - - T wait(WaitScope& waitScope); - // Run the event loop until the promise is fulfilled, then return its result. If the promise - // is rejected, throw an exception. - // - // wait() is primarily useful at the top level of a program -- typically, within the function - // that allocated the EventLoop. For example, a program that performs one or two RPCs and then - // exits would likely use wait() in its main() function to wait on each RPC. On the other hand, - // server-side code generally cannot use wait(), because it has to be able to accept multiple - // requests at once. - // - // If the promise is rejected, `wait()` throws an exception. If the program was compiled without - // exceptions (-fno-exceptions), this will usually abort. In this case you really should first - // use `then()` to set an appropriate handler for the exception case, so that the promise you - // actually wait on never throws. - // - // `waitScope` is an object proving that the caller is in a scope where wait() is allowed. By - // convention, any function which might call wait(), or which might call another function which - // might call wait(), must take `WaitScope&` as one of its parameters. This is needed for two - // reasons: - // * `wait()` is not allowed during an event callback, because event callbacks are themselves - // called during some other `wait()`, and such recursive `wait()`s would only be able to - // complete in LIFO order, which might mean that the outer `wait()` ends up waiting longer - // than it is supposed to. To prevent this, a `WaitScope` cannot be constructed or used during - // an event callback. - // * Since `wait()` runs the event loop, unrelated event callbacks may execute before `wait()` - // returns. This means that anyone calling `wait()` must be reentrant -- state may change - // around them in arbitrary ways. Therefore, callers really need to know if a function they - // are calling might wait(), and the `WaitScope&` parameter makes this clear. - // - // TODO(someday): Implement fibers, and let them call wait() even when they are handling an - // event. - - ForkedPromise fork() KJ_WARN_UNUSED_RESULT; - // Forks the promise, so that multiple different clients can independently wait on the result. - // `T` must be copy-constructable for this to work. Or, in the special case where `T` is - // `Own`, `U` must have a method `Own addRef()` which returns a new reference to the same - // (or an equivalent) object (probably implemented via reference counting). - - _::SplitTuplePromise split(); - // Split a promise for a tuple into a tuple of promises. - // - // E.g. if you have `Promise>`, `split()` returns - // `kj::Tuple, Promise>`. - - Promise exclusiveJoin(Promise&& other) KJ_WARN_UNUSED_RESULT; - // Return a new promise that resolves when either the original promise resolves or `other` - // resolves (whichever comes first). The promise that didn't resolve first is canceled. - - // TODO(someday): inclusiveJoin(), or perhaps just join(), which waits for both completions - // and produces a tuple? - - template - Promise attach(Attachments&&... attachments) KJ_WARN_UNUSED_RESULT; - // "Attaches" one or more movable objects (often, Owns) to the promise, such that they will - // be destroyed when the promise resolves. This is useful when a promise's callback contains - // pointers into some object and you want to make sure the object still exists when the callback - // runs -- after calling then(), use attach() to add necessary objects to the result. - - template - Promise eagerlyEvaluate(ErrorFunc&& errorHandler) KJ_WARN_UNUSED_RESULT; - Promise eagerlyEvaluate(decltype(nullptr)) KJ_WARN_UNUSED_RESULT; - // Force eager evaluation of this promise. Use this if you are going to hold on to the promise - // for awhile without consuming the result, but you want to make sure that the system actually - // processes it. - // - // `errorHandler` is a function that takes `kj::Exception&&`, like the second parameter to - // `then()`, except that it must return void. We make you specify this because otherwise it's - // easy to forget to handle errors in a promise that you never use. You may specify nullptr for - // the error handler if you are sure that ignoring errors is fine, or if you know that you'll - // eventually wait on the promise somewhere. - - template - void detach(ErrorFunc&& errorHandler); - // Allows the promise to continue running in the background until it completes or the - // `EventLoop` is destroyed. Be careful when using this: since you can no longer cancel this - // promise, you need to make sure that the promise owns all the objects it touches or make sure - // those objects outlive the EventLoop. - // - // `errorHandler` is a function that takes `kj::Exception&&`, like the second parameter to - // `then()`, except that it must return void. - // - // This function exists mainly to implement the Cap'n Proto requirement that RPC calls cannot be - // canceled unless the callee explicitly permits it. - - kj::String trace(); - // Returns a dump of debug info about this promise. Not for production use. Requires RTTI. - // This method does NOT consume the promise as other methods do. - -private: - Promise(bool, Own<_::PromiseNode>&& node): PromiseBase(kj::mv(node)) {} - // Second parameter prevent ambiguity with immediate-value constructor. - - template - friend class Promise; - friend class EventLoop; - template - friend Promise newAdaptedPromise(Params&&... adapterConstructorParams); - template - friend PromiseFulfillerPair newPromiseAndFulfiller(); - template - friend class _::ForkHub; - friend class _::TaskSetImpl; - friend Promise _::yield(); - friend class _::NeverDone; - template - friend Promise> joinPromises(Array>&& promises); - friend Promise joinPromises(Array>&& promises); -}; - -template -class ForkedPromise { - // The result of `Promise::fork()` and `EventLoop::fork()`. Allows branches to be created. - // Like `Promise`, this is a pass-by-move type. - -public: - inline ForkedPromise(decltype(nullptr)) {} - - Promise addBranch(); - // Add a new branch to the fork. The branch is equivalent to the original promise. - -private: - Own<_::ForkHub<_::FixVoid>> hub; - - inline ForkedPromise(bool, Own<_::ForkHub<_::FixVoid>>&& hub): hub(kj::mv(hub)) {} - - friend class Promise; - friend class EventLoop; -}; - -constexpr _::Void READY_NOW = _::Void(); -// Use this when you need a Promise that is already fulfilled -- this value can be implicitly -// cast to `Promise`. - -constexpr _::NeverDone NEVER_DONE = _::NeverDone(); -// The opposite of `READY_NOW`, return this when the promise should never resolve. This can be -// implicitly converted to any promise type. You may also call `NEVER_DONE.wait()` to wait -// forever (useful for servers). - -template -PromiseForResult evalLater(Func&& func) KJ_WARN_UNUSED_RESULT; -// Schedule for the given zero-parameter function to be executed in the event loop at some -// point in the near future. Returns a Promise for its result -- or, if `func()` itself returns -// a promise, `evalLater()` returns a Promise for the result of resolving that promise. -// -// Example usage: -// Promise x = evalLater([]() { return 123; }); -// -// The above is exactly equivalent to: -// Promise x = Promise(READY_NOW).then([]() { return 123; }); -// -// If the returned promise is destroyed before the callback runs, the callback will be canceled -// (never called). -// -// If you schedule several evaluations with `evalLater` during the same callback, they are -// guaranteed to be executed in order. - -template -PromiseForResult evalNow(Func&& func) KJ_WARN_UNUSED_RESULT; -// Run `func()` and return a promise for its result. `func()` executes before `evalNow()` returns. -// If `func()` throws an exception, the exception is caught and wrapped in a promise -- this is the -// main reason why `evalNow()` is useful. - -template -Promise> joinPromises(Array>&& promises); -// Join an array of promises into a promise for an array. - -// ======================================================================================= -// Hack for creating a lambda that holds an owned pointer. - -template -class CaptureByMove { -public: - inline CaptureByMove(Func&& func, MovedParam&& param) - : func(kj::mv(func)), param(kj::mv(param)) {} - - template - inline auto operator()(Params&&... params) - -> decltype(kj::instance()(kj::instance(), kj::fwd(params)...)) { - return func(kj::mv(param), kj::fwd(params)...); - } - -private: - Func func; - MovedParam param; -}; - -template -inline CaptureByMove> mvCapture(MovedParam&& param, Func&& func) { - // Hack to create a "lambda" which captures a variable by moving it rather than copying or - // referencing. C++14 generalized captures should make this obsolete, but for now in C++11 this - // is commonly needed for Promise continuations that own their state. Example usage: - // - // Own ptr = makeFoo(); - // Promise promise = callRpc(); - // promise.then(mvCapture(ptr, [](Own&& ptr, int result) { - // return ptr->finish(result); - // })); - - return CaptureByMove>(kj::fwd(func), kj::mv(param)); -} - -// ======================================================================================= -// Advanced promise construction - -template -class PromiseFulfiller { - // A callback which can be used to fulfill a promise. Only the first call to fulfill() or - // reject() matters; subsequent calls are ignored. - -public: - virtual void fulfill(T&& value) = 0; - // Fulfill the promise with the given value. - - virtual void reject(Exception&& exception) = 0; - // Reject the promise with an error. - - virtual bool isWaiting() = 0; - // Returns true if the promise is still unfulfilled and someone is potentially waiting for it. - // Returns false if fulfill()/reject() has already been called *or* if the promise to be - // fulfilled has been discarded and therefore the result will never be used anyway. - - template - bool rejectIfThrows(Func&& func); - // Call the function (with no arguments) and return true. If an exception is thrown, call - // `fulfiller.reject()` and then return false. When compiled with exceptions disabled, - // non-fatal exceptions are still detected and handled correctly. -}; - -template <> -class PromiseFulfiller { - // Specialization of PromiseFulfiller for void promises. See PromiseFulfiller. - -public: - virtual void fulfill(_::Void&& value = _::Void()) = 0; - // Call with zero parameters. The parameter is a dummy that only exists so that subclasses don't - // have to specialize for . - - virtual void reject(Exception&& exception) = 0; - virtual bool isWaiting() = 0; - - template - bool rejectIfThrows(Func&& func); -}; - -template -Promise newAdaptedPromise(Params&&... adapterConstructorParams); -// Creates a new promise which owns an instance of `Adapter` which encapsulates the operation -// that will eventually fulfill the promise. This is primarily useful for adapting non-KJ -// asynchronous APIs to use promises. -// -// An instance of `Adapter` will be allocated and owned by the returned `Promise`. A -// `PromiseFulfiller&` will be passed as the first parameter to the adapter's constructor, -// and `adapterConstructorParams` will be forwarded as the subsequent parameters. The adapter -// is expected to perform some asynchronous operation and call the `PromiseFulfiller` once -// it is finished. -// -// The adapter is destroyed when its owning Promise is destroyed. This may occur before the -// Promise has been fulfilled. In this case, the adapter's destructor should cancel the -// asynchronous operation. Once the adapter is destroyed, the fulfillment callback cannot be -// called. -// -// An adapter implementation should be carefully written to ensure that it cannot accidentally -// be left unfulfilled permanently because of an exception. Consider making liberal use of -// `PromiseFulfiller::rejectIfThrows()`. - -template -struct PromiseFulfillerPair { - Promise<_::JoinPromises> promise; - Own> fulfiller; -}; - -template -PromiseFulfillerPair newPromiseAndFulfiller(); -// Construct a Promise and a separate PromiseFulfiller which can be used to fulfill the promise. -// If the PromiseFulfiller is destroyed before either of its methods are called, the Promise is -// implicitly rejected. -// -// Although this function is easier to use than `newAdaptedPromise()`, it has the serious drawback -// that there is no way to handle cancellation (i.e. detect when the Promise is discarded). -// -// You can arrange to fulfill a promise with another promise by using a promise type for T. E.g. -// `newPromiseAndFulfiller>()` will produce a promise of type `Promise` but the -// fulfiller will be of type `PromiseFulfiller>`. Thus you pass a `Promise` to the -// `fulfill()` callback, and the promises are chained. - -// ======================================================================================= -// TaskSet - -class TaskSet { - // Holds a collection of Promises and ensures that each executes to completion. Memory - // associated with each promise is automatically freed when the promise completes. Destroying - // the TaskSet itself automatically cancels all unfinished promises. - // - // This is useful for "daemon" objects that perform background tasks which aren't intended to - // fulfill any particular external promise, but which may need to be canceled (and thus can't - // use `Promise::detach()`). The daemon object holds a TaskSet to collect these tasks it is - // working on. This way, if the daemon itself is destroyed, the TaskSet is detroyed as well, - // and everything the daemon is doing is canceled. - -public: - class ErrorHandler { - public: - virtual void taskFailed(kj::Exception&& exception) = 0; - }; - - TaskSet(ErrorHandler& errorHandler); - // `loop` will be used to wait on promises. `errorHandler` will be executed any time a task - // throws an exception, and will execute within the given EventLoop. - - ~TaskSet() noexcept(false); - - void add(Promise&& promise); - - kj::String trace(); - // Return debug info about all promises currently in the TaskSet. - -private: - Own<_::TaskSetImpl> impl; -}; - -// ======================================================================================= -// The EventLoop class - -class EventPort { - // Interfaces between an `EventLoop` and events originating from outside of the loop's thread. - // All such events come in through the `EventPort` implementation. - // - // An `EventPort` implementation may interface with low-level operating system APIs and/or other - // threads. You can also write an `EventPort` which wraps some other (non-KJ) event loop - // framework, allowing the two to coexist in a single thread. - -public: - virtual bool wait() = 0; - // Wait for an external event to arrive, sleeping if necessary. Once at least one event has - // arrived, queue it to the event loop (e.g. by fulfilling a promise) and return. - // - // This is called during `Promise::wait()` whenever the event queue becomes empty, in order to - // wait for new events to populate the queue. - // - // It is safe to return even if nothing has actually been queued, so long as calling `wait()` in - // a loop will eventually sleep. (That is to say, false positives are fine.) - // - // Returns true if wake() has been called from another thread. (Precisely, returns true if - // no previous call to wait `wait()` nor `poll()` has returned true since `wake()` was last - // called.) - - virtual bool poll() = 0; - // Check if any external events have arrived, but do not sleep. If any events have arrived, - // add them to the event queue (e.g. by fulfilling promises) before returning. - // - // This may be called during `Promise::wait()` when the EventLoop has been executing for a while - // without a break but is still non-empty. - // - // Returns true if wake() has been called from another thread. (Precisely, returns true if - // no previous call to wait `wait()` nor `poll()` has returned true since `wake()` was last - // called.) - - virtual void setRunnable(bool runnable); - // Called to notify the `EventPort` when the `EventLoop` has work to do; specifically when it - // transitions from empty -> runnable or runnable -> empty. This is typically useful when - // integrating with an external event loop; if the loop is currently runnable then you should - // arrange to call run() on it soon. The default implementation does nothing. - - virtual void wake() const; - // Wake up the EventPort's thread from another thread. - // - // Unlike all other methods on this interface, `wake()` may be called from another thread, hence - // it is `const`. - // - // Technically speaking, `wake()` causes the target thread to cease sleeping and not to sleep - // again until `wait()` or `poll()` has returned true at least once. - // - // The default implementation throws an UNIMPLEMENTED exception. -}; - -class EventLoop { - // Represents a queue of events being executed in a loop. Most code won't interact with - // EventLoop directly, but instead use `Promise`s to interact with it indirectly. See the - // documentation for `Promise`. - // - // Each thread can have at most one current EventLoop. To make an `EventLoop` current for - // the thread, create a `WaitScope`. Async APIs require that the thread has a current EventLoop, - // or they will throw exceptions. APIs that use `Promise::wait()` additionally must explicitly - // be passed a reference to the `WaitScope` to make the caller aware that they might block. - // - // Generally, you will want to construct an `EventLoop` at the top level of your program, e.g. - // in the main() function, or in the start function of a thread. You can then use it to - // construct some promises and wait on the result. Example: - // - // int main() { - // // `loop` becomes the official EventLoop for the thread. - // MyEventPort eventPort; - // EventLoop loop(eventPort); - // - // // Now we can call an async function. - // Promise textPromise = getHttp("http://example.com"); - // - // // And we can wait for the promise to complete. Note that you can only use `wait()` - // // from the top level, not from inside a promise callback. - // String text = textPromise.wait(); - // print(text); - // return 0; - // } - // - // Most applications that do I/O will prefer to use `setupAsyncIo()` from `async-io.h` rather - // than allocate an `EventLoop` directly. - -public: - EventLoop(); - // Construct an `EventLoop` which does not receive external events at all. - - explicit EventLoop(EventPort& port); - // Construct an `EventLoop` which receives external events through the given `EventPort`. - - ~EventLoop() noexcept(false); - - void run(uint maxTurnCount = maxValue); - // Run the event loop for `maxTurnCount` turns or until there is nothing left to be done, - // whichever comes first. This never calls the `EventPort`'s `sleep()` or `poll()`. It will - // call the `EventPort`'s `setRunnable(false)` if the queue becomes empty. - - bool isRunnable(); - // Returns true if run() would currently do anything, or false if the queue is empty. - -private: - EventPort& port; - - bool running = false; - // True while looping -- wait() is then not allowed. - - bool lastRunnableState = false; - // What did we last pass to port.setRunnable()? - - _::Event* head = nullptr; - _::Event** tail = &head; - _::Event** depthFirstInsertPoint = &head; - - Own<_::TaskSetImpl> daemons; - - bool turn(); - void setRunnable(bool runnable); - void enterScope(); - void leaveScope(); - - friend void _::detach(kj::Promise&& promise); - friend void _::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result, - WaitScope& waitScope); - friend class _::Event; - friend class WaitScope; -}; - -class WaitScope { - // Represents a scope in which asynchronous programming can occur. A `WaitScope` should usually - // be allocated on the stack and serves two purposes: - // * While the `WaitScope` exists, its `EventLoop` is registered as the current loop for the - // thread. Most operations dealing with `Promise` (including all of its methods) do not work - // unless the thread has a current `EventLoop`. - // * `WaitScope` may be passed to `Promise::wait()` to synchronously wait for a particular - // promise to complete. See `Promise::wait()` for an extended discussion. - -public: - inline explicit WaitScope(EventLoop& loop): loop(loop) { loop.enterScope(); } - inline ~WaitScope() { loop.leaveScope(); } - KJ_DISALLOW_COPY(WaitScope); - -private: - EventLoop& loop; - friend class EventLoop; - friend void _::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result, - WaitScope& waitScope); -}; - -} // namespace kj - -#include "async-inl.h" - -#endif // KJ_ASYNC_H_ diff --git a/phonelibs/capnp-cpp/include/kj/common.h b/phonelibs/capnp-cpp/include/kj/common.h deleted file mode 100644 index 4a908ae0007fd7..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/common.h +++ /dev/null @@ -1,1400 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -// Header that should be #included by everyone. -// -// This defines very simple utilities that are widely applicable. - -#ifndef KJ_COMMON_H_ -#define KJ_COMMON_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#ifndef KJ_NO_COMPILER_CHECK -#if __cplusplus < 201103L && !__CDT_PARSER__ && !_MSC_VER - #error "This code requires C++11. Either your compiler does not support it or it is not enabled." - #ifdef __GNUC__ - // Compiler claims compatibility with GCC, so presumably supports -std. - #error "Pass -std=c++11 on the compiler command line to enable C++11." - #endif -#endif - -#ifdef __GNUC__ - #if __clang__ - #if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2) - #warning "This library requires at least Clang 3.2." - #elif defined(__apple_build_version__) && __apple_build_version__ <= 4250028 - #warning "This library requires at least Clang 3.2. XCode 4.6's Clang, which claims to be "\ - "version 4.2 (wat?), is actually built from some random SVN revision between 3.1 "\ - "and 3.2. Unfortunately, it is insufficient for compiling this library. You can "\ - "download the real Clang 3.2 (or newer) from the Clang web site. Step-by-step "\ - "instructions can be found in Cap'n Proto's documentation: "\ - "http://kentonv.github.io/capnproto/install.html#clang_32_on_mac_osx" - #elif __cplusplus >= 201103L && !__has_include() - #warning "Your compiler supports C++11 but your C++ standard library does not. If your "\ - "system has libc++ installed (as should be the case on e.g. Mac OSX), try adding "\ - "-stdlib=libc++ to your CXXFLAGS." - #endif - #else - #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) - #warning "This library requires at least GCC 4.7." - #endif - #endif -#elif defined(_MSC_VER) - #if _MSC_VER < 1900 - #error "You need Visual Studio 2015 or better to compile this code." - #endif -#else - #warning "I don't recognize your compiler. As of this writing, Clang and GCC are the only "\ - "known compilers with enough C++11 support for this library. "\ - "#define KJ_NO_COMPILER_CHECK to make this warning go away." -#endif -#endif - -#include -#include - -#if __linux__ && __cplusplus > 201200L -// Hack around stdlib bug with C++14 that exists on some Linux systems. -// Apparently in this mode the C library decides not to define gets() but the C++ library still -// tries to import it into the std namespace. This bug has been fixed at the source but is still -// widely present in the wild e.g. on Ubuntu 14.04. -#undef _GLIBCXX_HAVE_GETS -#endif - -#if defined(_MSC_VER) -#ifndef NOMINMAX -#define NOMINMAX 1 -#endif -#include // __popcnt -#endif - -// ======================================================================================= - -namespace kj { - -typedef unsigned int uint; -typedef unsigned char byte; - -// ======================================================================================= -// Common macros, especially for common yet compiler-specific features. - -// Detect whether RTTI and exceptions are enabled, assuming they are unless we have specific -// evidence to the contrary. Clients can always define KJ_NO_RTTI or KJ_NO_EXCEPTIONS explicitly -// to override these checks. -#ifdef __GNUC__ - #if !defined(KJ_NO_RTTI) && !__GXX_RTTI - #define KJ_NO_RTTI 1 - #endif - #if !defined(KJ_NO_EXCEPTIONS) && !__EXCEPTIONS - #define KJ_NO_EXCEPTIONS 1 - #endif -#elif defined(_MSC_VER) - #if !defined(KJ_NO_RTTI) && !defined(_CPPRTTI) - #define KJ_NO_RTTI 1 - #endif - #if !defined(KJ_NO_EXCEPTIONS) && !defined(_CPPUNWIND) - #define KJ_NO_EXCEPTIONS 1 - #endif -#endif - -#if !defined(KJ_DEBUG) && !defined(KJ_NDEBUG) -// Heuristically decide whether to enable debug mode. If DEBUG or NDEBUG is defined, use that. -// Otherwise, fall back to checking whether optimization is enabled. -#if defined(DEBUG) || defined(_DEBUG) -#define KJ_DEBUG -#elif defined(NDEBUG) -#define KJ_NDEBUG -#elif __OPTIMIZE__ -#define KJ_NDEBUG -#else -#define KJ_DEBUG -#endif -#endif - -#define KJ_DISALLOW_COPY(classname) \ - classname(const classname&) = delete; \ - classname& operator=(const classname&) = delete -// Deletes the implicit copy constructor and assignment operator. - -#ifdef __GNUC__ -#define KJ_LIKELY(condition) __builtin_expect(condition, true) -#define KJ_UNLIKELY(condition) __builtin_expect(condition, false) -// Branch prediction macros. Evaluates to the condition given, but also tells the compiler that we -// expect the condition to be true/false enough of the time that it's worth hard-coding branch -// prediction. -#else -#define KJ_LIKELY(condition) (condition) -#define KJ_UNLIKELY(condition) (condition) -#endif - -#if defined(KJ_DEBUG) || __NO_INLINE__ -#define KJ_ALWAYS_INLINE(...) inline __VA_ARGS__ -// Don't force inline in debug mode. -#else -#if defined(_MSC_VER) -#define KJ_ALWAYS_INLINE(...) __forceinline __VA_ARGS__ -#else -#define KJ_ALWAYS_INLINE(...) inline __VA_ARGS__ __attribute__((always_inline)) -#endif -// Force a function to always be inlined. Apply only to the prototype, not to the definition. -#endif - -#if defined(_MSC_VER) -#define KJ_NOINLINE __declspec(noinline) -#else -#define KJ_NOINLINE __attribute__((noinline)) -#endif - -#if defined(_MSC_VER) -#define KJ_NORETURN(prototype) __declspec(noreturn) prototype -#define KJ_UNUSED -#define KJ_WARN_UNUSED_RESULT -// TODO(msvc): KJ_WARN_UNUSED_RESULT can use _Check_return_ on MSVC, but it's a prefix, so -// wrapping the whole prototype is needed. http://msdn.microsoft.com/en-us/library/jj159529.aspx -// Similarly, KJ_UNUSED could use __pragma(warning(suppress:...)), but again that's a prefix. -#else -#define KJ_NORETURN(prototype) prototype __attribute__((noreturn)) -#define KJ_UNUSED __attribute__((unused)) -#define KJ_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#endif - -#if __clang__ -#define KJ_UNUSED_MEMBER __attribute__((unused)) -// Inhibits "unused" warning for member variables. Only Clang produces such a warning, while GCC -// complains if the attribute is set on members. -#else -#define KJ_UNUSED_MEMBER -#endif - -#if __clang__ -#define KJ_DEPRECATED(reason) \ - __attribute__((deprecated(reason))) -#define KJ_UNAVAILABLE(reason) \ - __attribute__((unavailable(reason))) -#elif __GNUC__ -#define KJ_DEPRECATED(reason) \ - __attribute__((deprecated)) -#define KJ_UNAVAILABLE(reason) -#else -#define KJ_DEPRECATED(reason) -#define KJ_UNAVAILABLE(reason) -// TODO(msvc): Again, here, MSVC prefers a prefix, __declspec(deprecated). -#endif - -namespace _ { // private - -KJ_NORETURN(void inlineRequireFailure( - const char* file, int line, const char* expectation, const char* macroArgs, - const char* message = nullptr)); - -KJ_NORETURN(void unreachable()); - -} // namespace _ (private) - -#ifdef KJ_DEBUG -#if _MSC_VER -#define KJ_IREQUIRE(condition, ...) \ - if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \ - __FILE__, __LINE__, #condition, "" #__VA_ARGS__, __VA_ARGS__) -// Version of KJ_DREQUIRE() which is safe to use in headers that are #included by users. Used to -// check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that -// it will be enabled depending on whether the application is compiled in debug mode rather than -// whether libkj is. -#else -#define KJ_IREQUIRE(condition, ...) \ - if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \ - __FILE__, __LINE__, #condition, #__VA_ARGS__, ##__VA_ARGS__) -// Version of KJ_DREQUIRE() which is safe to use in headers that are #included by users. Used to -// check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that -// it will be enabled depending on whether the application is compiled in debug mode rather than -// whether libkj is. -#endif -#else -#define KJ_IREQUIRE(condition, ...) -#endif - -#define KJ_IASSERT KJ_IREQUIRE - -#define KJ_UNREACHABLE ::kj::_::unreachable(); -// Put this on code paths that cannot be reached to suppress compiler warnings about missing -// returns. - -#if __clang__ -#define KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT -#else -#define KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT KJ_UNREACHABLE -#endif - -// #define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) -// -// Allocate an array, preferably on the stack, unless it is too big. On GCC this will use -// variable-sized arrays. For other compilers we could just use a fixed-size array. `minStack` -// is the stack array size to use if variable-width arrays are not supported. `maxStack` is the -// maximum stack array size if variable-width arrays *are* supported. -#if __GNUC__ && !__clang__ -#define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) \ - size_t name##_size = (size); \ - bool name##_isOnStack = name##_size <= (maxStack); \ - type name##_stack[name##_isOnStack ? size : 0]; \ - ::kj::Array name##_heap = name##_isOnStack ? \ - nullptr : kj::heapArray(name##_size); \ - ::kj::ArrayPtr name = name##_isOnStack ? \ - kj::arrayPtr(name##_stack, name##_size) : name##_heap -#else -#define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) \ - size_t name##_size = (size); \ - bool name##_isOnStack = name##_size <= (minStack); \ - type name##_stack[minStack]; \ - ::kj::Array name##_heap = name##_isOnStack ? \ - nullptr : kj::heapArray(name##_size); \ - ::kj::ArrayPtr name = name##_isOnStack ? \ - kj::arrayPtr(name##_stack, name##_size) : name##_heap -#endif - -#define KJ_CONCAT_(x, y) x##y -#define KJ_CONCAT(x, y) KJ_CONCAT_(x, y) -#define KJ_UNIQUE_NAME(prefix) KJ_CONCAT(prefix, __LINE__) -// Create a unique identifier name. We use concatenate __LINE__ rather than __COUNTER__ so that -// the name can be used multiple times in the same macro. - -#if _MSC_VER - -#define KJ_CONSTEXPR(...) __VA_ARGS__ -// Use in cases where MSVC barfs on constexpr. A replacement keyword (e.g. "const") can be -// provided, or just leave blank to remove the keyword entirely. -// -// TODO(msvc): Remove this hack once MSVC fully supports constexpr. - -#ifndef __restrict__ -#define __restrict__ __restrict -// TODO(msvc): Would it be better to define a KJ_RESTRICT macro? -#endif - -#pragma warning(disable: 4521 4522) -// This warning complains when there are two copy constructors, one for a const reference and -// one for a non-const reference. It is often quite necessary to do this in wrapper templates, -// therefore this warning is dumb and we disable it. - -#pragma warning(disable: 4458) -// Warns when a parameter name shadows a class member. Unfortunately my code does this a lot, -// since I don't use a special name format for members. - -#else // _MSC_VER -#define KJ_CONSTEXPR(...) constexpr -#endif - -// ======================================================================================= -// Template metaprogramming helpers. - -template struct NoInfer_ { typedef T Type; }; -template using NoInfer = typename NoInfer_::Type; -// Use NoInfer::Type in place of T for a template function parameter to prevent inference of -// the type based on the parameter value. - -template struct RemoveConst_ { typedef T Type; }; -template struct RemoveConst_ { typedef T Type; }; -template using RemoveConst = typename RemoveConst_::Type; - -template struct IsLvalueReference_ { static constexpr bool value = false; }; -template struct IsLvalueReference_ { static constexpr bool value = true; }; -template -inline constexpr bool isLvalueReference() { return IsLvalueReference_::value; } - -template struct Decay_ { typedef T Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template struct Decay_ { typedef typename Decay_::Type Type; }; -template using Decay = typename Decay_::Type; - -template struct EnableIf_; -template <> struct EnableIf_ { typedef void Type; }; -template using EnableIf = typename EnableIf_::Type; -// Use like: -// -// template ()> -// void func(T&& t); - -template struct VoidSfinae_ { using Type = void; }; -template using VoidSfinae = typename VoidSfinae_::Type; -// Note: VoidSfinae is std::void_t from C++17. - -template -T instance() noexcept; -// Like std::declval, but doesn't transform T into an rvalue reference. If you want that, specify -// instance(). - -struct DisallowConstCopy { - // Inherit from this, or declare a member variable of this type, to prevent the class from being - // copyable from a const reference -- instead, it will only be copyable from non-const references. - // This is useful for enforcing transitive constness of contained pointers. - // - // For example, say you have a type T which contains a pointer. T has non-const methods which - // modify the value at that pointer, but T's const methods are designed to allow reading only. - // Unfortunately, if T has a regular copy constructor, someone can simply make a copy of T and - // then use it to modify the pointed-to value. However, if T inherits DisallowConstCopy, then - // callers will only be able to copy non-const instances of T. Ideally, there is some - // parallel type ImmutableT which is like a version of T that only has const methods, and can - // be copied from a const T. - // - // Note that due to C++ rules about implicit copy constructors and assignment operators, any - // type that contains or inherits from a type that disallows const copies will also automatically - // disallow const copies. Hey, cool, that's exactly what we want. - -#if CAPNP_DEBUG_TYPES - // Alas! Declaring a defaulted non-const copy constructor tickles a bug which causes GCC and - // Clang to disagree on ABI, using different calling conventions to pass this type, leading to - // immediate segfaults. See: - // https://bugs.llvm.org/show_bug.cgi?id=23764 - // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58074 - // - // Because of this, we can't use this technique. We guard it by CAPNP_DEBUG_TYPES so that it - // still applies to the Cap'n Proto developers during internal testing. - - DisallowConstCopy() = default; - DisallowConstCopy(DisallowConstCopy&) = default; - DisallowConstCopy(DisallowConstCopy&&) = default; - DisallowConstCopy& operator=(DisallowConstCopy&) = default; - DisallowConstCopy& operator=(DisallowConstCopy&&) = default; -#endif -}; - -#if _MSC_VER - -#define KJ_CPCAP(obj) obj=::kj::cp(obj) -// TODO(msvc): MSVC refuses to invoke non-const versions of copy constructors in by-value lambda -// captures. Wrap your captured object in this macro to force the compiler to perform a copy. -// Example: -// -// struct Foo: DisallowConstCopy {}; -// Foo foo; -// auto lambda = [KJ_CPCAP(foo)] {}; - -#else - -#define KJ_CPCAP(obj) obj -// Clang and gcc both already perform copy capturing correctly with non-const copy constructors. - -#endif - -template -struct DisallowConstCopyIfNotConst: public DisallowConstCopy { - // Inherit from this when implementing a template that contains a pointer to T and which should - // enforce transitive constness. If T is a const type, this has no effect. Otherwise, it is - // an alias for DisallowConstCopy. -}; - -template -struct DisallowConstCopyIfNotConst {}; - -template struct IsConst_ { static constexpr bool value = false; }; -template struct IsConst_ { static constexpr bool value = true; }; -template constexpr bool isConst() { return IsConst_::value; } - -template struct EnableIfNotConst_ { typedef T Type; }; -template struct EnableIfNotConst_; -template using EnableIfNotConst = typename EnableIfNotConst_::Type; - -template struct EnableIfConst_; -template struct EnableIfConst_ { typedef T Type; }; -template using EnableIfConst = typename EnableIfConst_::Type; - -template struct RemoveConstOrDisable_ { struct Type; }; -template struct RemoveConstOrDisable_ { typedef T Type; }; -template using RemoveConstOrDisable = typename RemoveConstOrDisable_::Type; - -template struct IsReference_ { static constexpr bool value = false; }; -template struct IsReference_ { static constexpr bool value = true; }; -template constexpr bool isReference() { return IsReference_::value; } - -template -struct PropagateConst_ { typedef To Type; }; -template -struct PropagateConst_ { typedef const To Type; }; -template -using PropagateConst = typename PropagateConst_::Type; - -namespace _ { // private - -template -T refIfLvalue(T&&); - -} // namespace _ (private) - -#define KJ_DECLTYPE_REF(exp) decltype(::kj::_::refIfLvalue(exp)) -// Like decltype(exp), but if exp is an lvalue, produces a reference type. -// -// int i; -// decltype(i) i1(i); // i1 has type int. -// KJ_DECLTYPE_REF(i + 1) i2(i + 1); // i2 has type int. -// KJ_DECLTYPE_REF(i) i3(i); // i3 has type int&. -// KJ_DECLTYPE_REF(kj::mv(i)) i4(kj::mv(i)); // i4 has type int. - -template -struct CanConvert_ { - static int sfinae(T); - static bool sfinae(...); -}; - -template -constexpr bool canConvert() { - return sizeof(CanConvert_::sfinae(instance())) == sizeof(int); -} - -#if __GNUC__ && !__clang__ && __GNUC__ < 5 -template -constexpr bool canMemcpy() { - // Returns true if T can be copied using memcpy instead of using the copy constructor or - // assignment operator. - - // GCC 4 does not have __is_trivially_constructible and friends, and there doesn't seem to be - // any reliable alternative. __has_trivial_copy() and __has_trivial_assign() return the right - // thing at one point but later on they changed such that a deleted copy constructor was - // considered "trivial" (apparently technically correct, though useless). So, on GCC 4 we give up - // and assume we can't memcpy() at all, and must explicitly copy-construct everything. - return false; -} -#define KJ_ASSERT_CAN_MEMCPY(T) -#else -template -constexpr bool canMemcpy() { - // Returns true if T can be copied using memcpy instead of using the copy constructor or - // assignment operator. - - return __is_trivially_constructible(T, const T&) && __is_trivially_assignable(T, const T&); -} -#define KJ_ASSERT_CAN_MEMCPY(T) \ - static_assert(kj::canMemcpy(), "this code expects this type to be memcpy()-able"); -#endif - -// ======================================================================================= -// Equivalents to std::move() and std::forward(), since these are very commonly needed and the -// std header pulls in lots of other stuff. -// -// We use abbreviated names mv and fwd because these helpers (especially mv) are so commonly used -// that the cost of typing more letters outweighs the cost of being slightly harder to understand -// when first encountered. - -template constexpr T&& mv(T& t) noexcept { return static_cast(t); } -template constexpr T&& fwd(NoInfer& t) noexcept { return static_cast(t); } - -template constexpr T cp(T& t) noexcept { return t; } -template constexpr T cp(const T& t) noexcept { return t; } -// Useful to force a copy, particularly to pass into a function that expects T&&. - -template struct ChooseType_; -template struct ChooseType_ { typedef T Type; }; -template struct ChooseType_ { typedef T Type; }; -template struct ChooseType_ { typedef U Type; }; - -template -using WiderType = typename ChooseType_= sizeof(U)>::Type; - -template -inline constexpr auto min(T&& a, U&& b) -> WiderType, Decay> { - return a < b ? WiderType, Decay>(a) : WiderType, Decay>(b); -} - -template -inline constexpr auto max(T&& a, U&& b) -> WiderType, Decay> { - return a > b ? WiderType, Decay>(a) : WiderType, Decay>(b); -} - -template -inline constexpr size_t size(T (&arr)[s]) { return s; } -template -inline constexpr size_t size(T&& arr) { return arr.size(); } -// Returns the size of the parameter, whether the parameter is a regular C array or a container -// with a `.size()` method. - -class MaxValue_ { -private: - template - inline constexpr T maxSigned() const { - return (1ull << (sizeof(T) * 8 - 1)) - 1; - } - template - inline constexpr T maxUnsigned() const { - return ~static_cast(0u); - } - -public: -#define _kJ_HANDLE_TYPE(T) \ - inline constexpr operator signed T() const { return MaxValue_::maxSigned < signed T>(); } \ - inline constexpr operator unsigned T() const { return MaxValue_::maxUnsigned(); } - _kJ_HANDLE_TYPE(char) - _kJ_HANDLE_TYPE(short) - _kJ_HANDLE_TYPE(int) - _kJ_HANDLE_TYPE(long) - _kJ_HANDLE_TYPE(long long) -#undef _kJ_HANDLE_TYPE - - inline constexpr operator char() const { - // `char` is different from both `signed char` and `unsigned char`, and may be signed or - // unsigned on different platforms. Ugh. - return char(-1) < 0 ? MaxValue_::maxSigned() - : MaxValue_::maxUnsigned(); - } -}; - -class MinValue_ { -private: - template - inline constexpr T minSigned() const { - return 1ull << (sizeof(T) * 8 - 1); - } - template - inline constexpr T minUnsigned() const { - return 0u; - } - -public: -#define _kJ_HANDLE_TYPE(T) \ - inline constexpr operator signed T() const { return MinValue_::minSigned < signed T>(); } \ - inline constexpr operator unsigned T() const { return MinValue_::minUnsigned(); } - _kJ_HANDLE_TYPE(char) - _kJ_HANDLE_TYPE(short) - _kJ_HANDLE_TYPE(int) - _kJ_HANDLE_TYPE(long) - _kJ_HANDLE_TYPE(long long) -#undef _kJ_HANDLE_TYPE - - inline constexpr operator char() const { - // `char` is different from both `signed char` and `unsigned char`, and may be signed or - // unsigned on different platforms. Ugh. - return char(-1) < 0 ? MinValue_::minSigned() - : MinValue_::minUnsigned(); - } -}; - -static KJ_CONSTEXPR(const) MaxValue_ maxValue = MaxValue_(); -// A special constant which, when cast to an integer type, takes on the maximum possible value of -// that type. This is useful to use as e.g. a parameter to a function because it will be robust -// in the face of changes to the parameter's type. -// -// `char` is not supported, but `signed char` and `unsigned char` are. - -static KJ_CONSTEXPR(const) MinValue_ minValue = MinValue_(); -// A special constant which, when cast to an integer type, takes on the minimum possible value -// of that type. This is useful to use as e.g. a parameter to a function because it will be robust -// in the face of changes to the parameter's type. -// -// `char` is not supported, but `signed char` and `unsigned char` are. - -template -inline bool operator==(T t, MaxValue_) { return t == Decay(maxValue); } -template -inline bool operator==(T t, MinValue_) { return t == Decay(minValue); } - -template -inline constexpr unsigned long long maxValueForBits() { - // Get the maximum integer representable in the given number of bits. - - // 1ull << 64 is unfortunately undefined. - return (bits == 64 ? 0 : (1ull << bits)) - 1; -} - -struct ThrowOverflow { - // Functor which throws an exception complaining about integer overflow. Usually this is used - // with the interfaces in units.h, but is defined here because Cap'n Proto wants to avoid - // including units.h when not using CAPNP_DEBUG_TYPES. - void operator()() const; -}; - -#if __GNUC__ -inline constexpr float inf() { return __builtin_huge_valf(); } -inline constexpr float nan() { return __builtin_nanf(""); } - -#elif _MSC_VER - -// Do what MSVC math.h does -#pragma warning(push) -#pragma warning(disable: 4756) // "overflow in constant arithmetic" -inline constexpr float inf() { return (float)(1e300 * 1e300); } -#pragma warning(pop) - -float nan(); -// Unfortunatley, inf() * 0.0f produces a NaN with the sign bit set, whereas our preferred -// canonical NaN should not have the sign bit set. std::numeric_limits::quiet_NaN() -// returns the correct NaN, but we don't want to #include that here. So, we give up and make -// this out-of-line on MSVC. -// -// TODO(msvc): Can we do better? - -#else -#error "Not sure how to support your compiler." -#endif - -inline constexpr bool isNaN(float f) { return f != f; } -inline constexpr bool isNaN(double f) { return f != f; } - -inline int popCount(unsigned int x) { -#if defined(_MSC_VER) - return __popcnt(x); - // Note: __popcnt returns unsigned int, but the value is clearly guaranteed to fit into an int -#else - return __builtin_popcount(x); -#endif -} - -// ======================================================================================= -// Useful fake containers - -template -class Range { -public: - inline constexpr Range(const T& begin, const T& end): begin_(begin), end_(end) {} - inline explicit constexpr Range(const T& end): begin_(0), end_(end) {} - - class Iterator { - public: - Iterator() = default; - inline Iterator(const T& value): value(value) {} - - inline const T& operator* () const { return value; } - inline const T& operator[](size_t index) const { return value + index; } - inline Iterator& operator++() { ++value; return *this; } - inline Iterator operator++(int) { return Iterator(value++); } - inline Iterator& operator--() { --value; return *this; } - inline Iterator operator--(int) { return Iterator(value--); } - inline Iterator& operator+=(ptrdiff_t amount) { value += amount; return *this; } - inline Iterator& operator-=(ptrdiff_t amount) { value -= amount; return *this; } - inline Iterator operator+ (ptrdiff_t amount) const { return Iterator(value + amount); } - inline Iterator operator- (ptrdiff_t amount) const { return Iterator(value - amount); } - inline ptrdiff_t operator- (const Iterator& other) const { return value - other.value; } - - inline bool operator==(const Iterator& other) const { return value == other.value; } - inline bool operator!=(const Iterator& other) const { return value != other.value; } - inline bool operator<=(const Iterator& other) const { return value <= other.value; } - inline bool operator>=(const Iterator& other) const { return value >= other.value; } - inline bool operator< (const Iterator& other) const { return value < other.value; } - inline bool operator> (const Iterator& other) const { return value > other.value; } - - private: - T value; - }; - - inline Iterator begin() const { return Iterator(begin_); } - inline Iterator end() const { return Iterator(end_); } - - inline auto size() const -> decltype(instance() - instance()) { return end_ - begin_; } - -private: - T begin_; - T end_; -}; - -template -inline constexpr Range, Decay>> range(T begin, U end) { - return Range, Decay>>(begin, end); -} - -template -inline constexpr Range> range(T begin, T end) { return Range>(begin, end); } -// Returns a fake iterable container containing all values of T from `begin` (inclusive) to `end` -// (exclusive). Example: -// -// // Prints 1, 2, 3, 4, 5, 6, 7, 8, 9. -// for (int i: kj::range(1, 10)) { print(i); } - -template -inline constexpr Range> zeroTo(T end) { return Range>(end); } -// Returns a fake iterable container containing all values of T from zero (inclusive) to `end` -// (exclusive). Example: -// -// // Prints 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. -// for (int i: kj::zeroTo(10)) { print(i); } - -template -inline constexpr Range indices(T&& container) { - // Shortcut for iterating over the indices of a container: - // - // for (size_t i: kj::indices(myArray)) { handle(myArray[i]); } - - return range(0, kj::size(container)); -} - -template -class Repeat { -public: - inline constexpr Repeat(const T& value, size_t count): value(value), count(count) {} - - class Iterator { - public: - Iterator() = default; - inline Iterator(const T& value, size_t index): value(value), index(index) {} - - inline const T& operator* () const { return value; } - inline const T& operator[](ptrdiff_t index) const { return value; } - inline Iterator& operator++() { ++index; return *this; } - inline Iterator operator++(int) { return Iterator(value, index++); } - inline Iterator& operator--() { --index; return *this; } - inline Iterator operator--(int) { return Iterator(value, index--); } - inline Iterator& operator+=(ptrdiff_t amount) { index += amount; return *this; } - inline Iterator& operator-=(ptrdiff_t amount) { index -= amount; return *this; } - inline Iterator operator+ (ptrdiff_t amount) const { return Iterator(value, index + amount); } - inline Iterator operator- (ptrdiff_t amount) const { return Iterator(value, index - amount); } - inline ptrdiff_t operator- (const Iterator& other) const { return index - other.index; } - - inline bool operator==(const Iterator& other) const { return index == other.index; } - inline bool operator!=(const Iterator& other) const { return index != other.index; } - inline bool operator<=(const Iterator& other) const { return index <= other.index; } - inline bool operator>=(const Iterator& other) const { return index >= other.index; } - inline bool operator< (const Iterator& other) const { return index < other.index; } - inline bool operator> (const Iterator& other) const { return index > other.index; } - - private: - T value; - size_t index; - }; - - inline Iterator begin() const { return Iterator(value, 0); } - inline Iterator end() const { return Iterator(value, count); } - - inline size_t size() const { return count; } - inline const T& operator[](ptrdiff_t) const { return value; } - -private: - T value; - size_t count; -}; - -template -inline constexpr Repeat> repeat(T&& value, size_t count) { - // Returns a fake iterable which contains `count` repeats of `value`. Useful for e.g. creating - // a bunch of spaces: `kj::repeat(' ', indent * 2)` - - return Repeat>(value, count); -} - -// ======================================================================================= -// Manually invoking constructors and destructors -// -// ctor(x, ...) and dtor(x) invoke x's constructor or destructor, respectively. - -// We want placement new, but we don't want to #include . operator new cannot be defined in -// a namespace, and defining it globally conflicts with the definition in . So we have to -// define a dummy type and an operator new that uses it. - -namespace _ { // private -struct PlacementNew {}; -} // namespace _ (private) -} // namespace kj - -inline void* operator new(size_t, kj::_::PlacementNew, void* __p) noexcept { - return __p; -} - -inline void operator delete(void*, kj::_::PlacementNew, void* __p) noexcept {} - -namespace kj { - -template -inline void ctor(T& location, Params&&... params) { - new (_::PlacementNew(), &location) T(kj::fwd(params)...); -} - -template -inline void dtor(T& location) { - location.~T(); -} - -// ======================================================================================= -// Maybe -// -// Use in cases where you want to indicate that a value may be null. Using Maybe instead of T* -// forces the caller to handle the null case in order to satisfy the compiler, thus reliably -// preventing null pointer dereferences at runtime. -// -// Maybe can be implicitly constructed from T and from nullptr. Additionally, it can be -// implicitly constructed from T*, in which case the pointer is checked for nullness at runtime. -// To read the value of a Maybe, do: -// -// KJ_IF_MAYBE(value, someFuncReturningMaybe()) { -// doSomething(*value); -// } else { -// maybeWasNull(); -// } -// -// KJ_IF_MAYBE's first parameter is a variable name which will be defined within the following -// block. The variable will behave like a (guaranteed non-null) pointer to the Maybe's value, -// though it may or may not actually be a pointer. -// -// Note that Maybe actually just wraps a pointer, whereas Maybe wraps a T and a boolean -// indicating nullness. - -template -class Maybe; - -namespace _ { // private - -template -class NullableValue { - // Class whose interface behaves much like T*, but actually contains an instance of T and a - // boolean flag indicating nullness. - -public: - inline NullableValue(NullableValue&& other) noexcept(noexcept(T(instance()))) - : isSet(other.isSet) { - if (isSet) { - ctor(value, kj::mv(other.value)); - } - } - inline NullableValue(const NullableValue& other) - : isSet(other.isSet) { - if (isSet) { - ctor(value, other.value); - } - } - inline NullableValue(NullableValue& other) - : isSet(other.isSet) { - if (isSet) { - ctor(value, other.value); - } - } - inline ~NullableValue() -#if _MSC_VER - // TODO(msvc): MSVC has a hard time with noexcept specifier expressions that are more complex - // than `true` or `false`. We had a workaround for VS2015, but VS2017 regressed. - noexcept(false) -#else - noexcept(noexcept(instance().~T())) -#endif - { - if (isSet) { - dtor(value); - } - } - - inline T& operator*() & { return value; } - inline const T& operator*() const & { return value; } - inline T&& operator*() && { return kj::mv(value); } - inline const T&& operator*() const && { return kj::mv(value); } - inline T* operator->() { return &value; } - inline const T* operator->() const { return &value; } - inline operator T*() { return isSet ? &value : nullptr; } - inline operator const T*() const { return isSet ? &value : nullptr; } - - template - inline T& emplace(Params&&... params) { - if (isSet) { - isSet = false; - dtor(value); - } - ctor(value, kj::fwd(params)...); - isSet = true; - return value; - } - -private: // internal interface used by friends only - inline NullableValue() noexcept: isSet(false) {} - inline NullableValue(T&& t) noexcept(noexcept(T(instance()))) - : isSet(true) { - ctor(value, kj::mv(t)); - } - inline NullableValue(T& t) - : isSet(true) { - ctor(value, t); - } - inline NullableValue(const T& t) - : isSet(true) { - ctor(value, t); - } - inline NullableValue(const T* t) - : isSet(t != nullptr) { - if (isSet) ctor(value, *t); - } - template - inline NullableValue(NullableValue&& other) noexcept(noexcept(T(instance()))) - : isSet(other.isSet) { - if (isSet) { - ctor(value, kj::mv(other.value)); - } - } - template - inline NullableValue(const NullableValue& other) - : isSet(other.isSet) { - if (isSet) { - ctor(value, other.value); - } - } - template - inline NullableValue(const NullableValue& other) - : isSet(other.isSet) { - if (isSet) { - ctor(value, *other.ptr); - } - } - inline NullableValue(decltype(nullptr)): isSet(false) {} - - inline NullableValue& operator=(NullableValue&& other) { - if (&other != this) { - // Careful about throwing destructors/constructors here. - if (isSet) { - isSet = false; - dtor(value); - } - if (other.isSet) { - ctor(value, kj::mv(other.value)); - isSet = true; - } - } - return *this; - } - - inline NullableValue& operator=(NullableValue& other) { - if (&other != this) { - // Careful about throwing destructors/constructors here. - if (isSet) { - isSet = false; - dtor(value); - } - if (other.isSet) { - ctor(value, other.value); - isSet = true; - } - } - return *this; - } - - inline NullableValue& operator=(const NullableValue& other) { - if (&other != this) { - // Careful about throwing destructors/constructors here. - if (isSet) { - isSet = false; - dtor(value); - } - if (other.isSet) { - ctor(value, other.value); - isSet = true; - } - } - return *this; - } - - inline bool operator==(decltype(nullptr)) const { return !isSet; } - inline bool operator!=(decltype(nullptr)) const { return isSet; } - -private: - bool isSet; - -#if _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4624) -// Warns that the anonymous union has a deleted destructor when T is non-trivial. This warning -// seems broken. -#endif - - union { - T value; - }; - -#if _MSC_VER -#pragma warning(pop) -#endif - - friend class kj::Maybe; - template - friend NullableValue&& readMaybe(Maybe&& maybe); -}; - -template -inline NullableValue&& readMaybe(Maybe&& maybe) { return kj::mv(maybe.ptr); } -template -inline T* readMaybe(Maybe& maybe) { return maybe.ptr; } -template -inline const T* readMaybe(const Maybe& maybe) { return maybe.ptr; } -template -inline T* readMaybe(Maybe&& maybe) { return maybe.ptr; } -template -inline T* readMaybe(const Maybe& maybe) { return maybe.ptr; } - -template -inline T* readMaybe(T* ptr) { return ptr; } -// Allow KJ_IF_MAYBE to work on regular pointers. - -} // namespace _ (private) - -#define KJ_IF_MAYBE(name, exp) if (auto name = ::kj::_::readMaybe(exp)) - -template -class Maybe { - // A T, or nullptr. - - // IF YOU CHANGE THIS CLASS: Note that there is a specialization of it in memory.h. - -public: - Maybe(): ptr(nullptr) {} - Maybe(T&& t) noexcept(noexcept(T(instance()))): ptr(kj::mv(t)) {} - Maybe(T& t): ptr(t) {} - Maybe(const T& t): ptr(t) {} - Maybe(const T* t) noexcept: ptr(t) {} - Maybe(Maybe&& other) noexcept(noexcept(T(instance()))): ptr(kj::mv(other.ptr)) {} - Maybe(const Maybe& other): ptr(other.ptr) {} - Maybe(Maybe& other): ptr(other.ptr) {} - - template - Maybe(Maybe&& other) noexcept(noexcept(T(instance()))) { - KJ_IF_MAYBE(val, kj::mv(other)) { - ptr.emplace(kj::mv(*val)); - } - } - template - Maybe(const Maybe& other) { - KJ_IF_MAYBE(val, other) { - ptr.emplace(*val); - } - } - - Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} - - template - inline T& emplace(Params&&... params) { - // Replace this Maybe's content with a new value constructed by passing the given parametrs to - // T's constructor. This can be used to initialize a Maybe without copying or even moving a T. - // Returns a reference to the newly-constructed value. - - return ptr.emplace(kj::fwd(params)...); - } - - inline Maybe& operator=(Maybe&& other) { ptr = kj::mv(other.ptr); return *this; } - inline Maybe& operator=(Maybe& other) { ptr = other.ptr; return *this; } - inline Maybe& operator=(const Maybe& other) { ptr = other.ptr; return *this; } - - inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } - - T& orDefault(T& defaultValue) { - if (ptr == nullptr) { - return defaultValue; - } else { - return *ptr; - } - } - const T& orDefault(const T& defaultValue) const { - if (ptr == nullptr) { - return defaultValue; - } else { - return *ptr; - } - } - - template - auto map(Func&& f) & -> Maybe()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(*ptr); - } - } - - template - auto map(Func&& f) const & -> Maybe()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(*ptr); - } - } - - template - auto map(Func&& f) && -> Maybe()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(kj::mv(*ptr)); - } - } - - template - auto map(Func&& f) const && -> Maybe()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(kj::mv(*ptr)); - } - } - -private: - _::NullableValue ptr; - - template - friend class Maybe; - template - friend _::NullableValue&& _::readMaybe(Maybe&& maybe); - template - friend U* _::readMaybe(Maybe& maybe); - template - friend const U* _::readMaybe(const Maybe& maybe); -}; - -template -class Maybe: public DisallowConstCopyIfNotConst { -public: - Maybe() noexcept: ptr(nullptr) {} - Maybe(T& t) noexcept: ptr(&t) {} - Maybe(T* t) noexcept: ptr(t) {} - - template - inline Maybe(Maybe& other) noexcept: ptr(other.ptr) {} - template - inline Maybe(const Maybe& other) noexcept: ptr(other.ptr) {} - inline Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} - - inline Maybe& operator=(T& other) noexcept { ptr = &other; return *this; } - inline Maybe& operator=(T* other) noexcept { ptr = other; return *this; } - template - inline Maybe& operator=(Maybe& other) noexcept { ptr = other.ptr; return *this; } - template - inline Maybe& operator=(const Maybe& other) noexcept { ptr = other.ptr; return *this; } - - inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } - - T& orDefault(T& defaultValue) { - if (ptr == nullptr) { - return defaultValue; - } else { - return *ptr; - } - } - const T& orDefault(const T& defaultValue) const { - if (ptr == nullptr) { - return defaultValue; - } else { - return *ptr; - } - } - - template - auto map(Func&& f) -> Maybe()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(*ptr); - } - } - -private: - T* ptr; - - template - friend class Maybe; - template - friend U* _::readMaybe(Maybe&& maybe); - template - friend U* _::readMaybe(const Maybe& maybe); -}; - -// ======================================================================================= -// ArrayPtr -// -// So common that we put it in common.h rather than array.h. - -template -class ArrayPtr: public DisallowConstCopyIfNotConst { - // A pointer to an array. Includes a size. Like any pointer, it doesn't own the target data, - // and passing by value only copies the pointer, not the target. - -public: - inline constexpr ArrayPtr(): ptr(nullptr), size_(0) {} - inline constexpr ArrayPtr(decltype(nullptr)): ptr(nullptr), size_(0) {} - inline constexpr ArrayPtr(T* ptr, size_t size): ptr(ptr), size_(size) {} - inline constexpr ArrayPtr(T* begin, T* end): ptr(begin), size_(end - begin) {} - inline KJ_CONSTEXPR() ArrayPtr(::std::initializer_list> init) - : ptr(init.begin()), size_(init.size()) {} - - template - inline constexpr ArrayPtr(T (&native)[size]): ptr(native), size_(size) {} - // Construct an ArrayPtr from a native C-style array. - - inline operator ArrayPtr() const { - return ArrayPtr(ptr, size_); - } - inline ArrayPtr asConst() const { - return ArrayPtr(ptr, size_); - } - - inline size_t size() const { return size_; } - inline const T& operator[](size_t index) const { - KJ_IREQUIRE(index < size_, "Out-of-bounds ArrayPtr access."); - return ptr[index]; - } - inline T& operator[](size_t index) { - KJ_IREQUIRE(index < size_, "Out-of-bounds ArrayPtr access."); - return ptr[index]; - } - - inline T* begin() { return ptr; } - inline T* end() { return ptr + size_; } - inline T& front() { return *ptr; } - inline T& back() { return *(ptr + size_ - 1); } - inline const T* begin() const { return ptr; } - inline const T* end() const { return ptr + size_; } - inline const T& front() const { return *ptr; } - inline const T& back() const { return *(ptr + size_ - 1); } - - inline ArrayPtr slice(size_t start, size_t end) const { - KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds ArrayPtr::slice()."); - return ArrayPtr(ptr + start, end - start); - } - inline ArrayPtr slice(size_t start, size_t end) { - KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds ArrayPtr::slice()."); - return ArrayPtr(ptr + start, end - start); - } - - inline ArrayPtr> asBytes() const { - // Reinterpret the array as a byte array. This is explicitly legal under C++ aliasing - // rules. - return { reinterpret_cast*>(ptr), size_ * sizeof(T) }; - } - inline ArrayPtr> asChars() const { - // Reinterpret the array as a char array. This is explicitly legal under C++ aliasing - // rules. - return { reinterpret_cast*>(ptr), size_ * sizeof(T) }; - } - - inline bool operator==(decltype(nullptr)) const { return size_ == 0; } - inline bool operator!=(decltype(nullptr)) const { return size_ != 0; } - - inline bool operator==(const ArrayPtr& other) const { - if (size_ != other.size_) return false; - for (size_t i = 0; i < size_; i++) { - if (ptr[i] != other[i]) return false; - } - return true; - } - inline bool operator!=(const ArrayPtr& other) const { return !(*this == other); } - -private: - T* ptr; - size_t size_; -}; - -template -inline constexpr ArrayPtr arrayPtr(T* ptr, size_t size) { - // Use this function to construct ArrayPtrs without writing out the type name. - return ArrayPtr(ptr, size); -} - -template -inline constexpr ArrayPtr arrayPtr(T* begin, T* end) { - // Use this function to construct ArrayPtrs without writing out the type name. - return ArrayPtr(begin, end); -} - -// ======================================================================================= -// Casts - -template -To implicitCast(From&& from) { - // `implicitCast(value)` casts `value` to type `T` only if the conversion is implicit. Useful - // for e.g. resolving ambiguous overloads without sacrificing type-safety. - return kj::fwd(from); -} - -template -Maybe dynamicDowncastIfAvailable(From& from) { - // If RTTI is disabled, always returns nullptr. Otherwise, works like dynamic_cast. Useful - // in situations where dynamic_cast could allow an optimization, but isn't strictly necessary - // for correctness. It is highly recommended that you try to arrange all your dynamic_casts - // this way, as a dynamic_cast that is necessary for correctness implies a flaw in the interface - // design. - - // Force a compile error if To is not a subtype of From. Cross-casting is rare; if it is needed - // we should have a separate cast function like dynamicCrosscastIfAvailable(). - if (false) { - kj::implicitCast(kj::implicitCast(nullptr)); - } - -#if KJ_NO_RTTI - return nullptr; -#else - return dynamic_cast(&from); -#endif -} - -template -To& downcast(From& from) { - // Down-cast a value to a sub-type, asserting that the cast is valid. In opt mode this is a - // static_cast, but in debug mode (when RTTI is enabled) a dynamic_cast will be used to verify - // that the value really has the requested type. - - // Force a compile error if To is not a subtype of From. - if (false) { - kj::implicitCast(kj::implicitCast(nullptr)); - } - -#if !KJ_NO_RTTI - KJ_IREQUIRE(dynamic_cast(&from) != nullptr, "Value cannot be downcast() to requested type."); -#endif - - return static_cast(from); -} - -// ======================================================================================= -// Defer - -namespace _ { // private - -template -class Deferred { -public: - inline Deferred(Func&& func): func(kj::fwd(func)), canceled(false) {} - inline ~Deferred() noexcept(false) { if (!canceled) func(); } - KJ_DISALLOW_COPY(Deferred); - - // This move constructor is usually optimized away by the compiler. - inline Deferred(Deferred&& other): func(kj::mv(other.func)), canceled(false) { - other.canceled = true; - } -private: - Func func; - bool canceled; -}; - -} // namespace _ (private) - -template -_::Deferred defer(Func&& func) { - // Returns an object which will invoke the given functor in its destructor. The object is not - // copyable but is movable with the semantics you'd expect. Since the return type is private, - // you need to assign to an `auto` variable. - // - // The KJ_DEFER macro provides slightly more convenient syntax for the common case where you - // want some code to run at current scope exit. - - return _::Deferred(kj::fwd(func)); -} - -#define KJ_DEFER(code) auto KJ_UNIQUE_NAME(_kjDefer) = ::kj::defer([&](){code;}) -// Run the given code when the function exits, whether by return or exception. - -} // namespace kj - -#endif // KJ_COMMON_H_ diff --git a/phonelibs/capnp-cpp/include/kj/compat/gtest.h b/phonelibs/capnp-cpp/include/kj/compat/gtest.h deleted file mode 100644 index 016dbdfac322ee..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/compat/gtest.h +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_COMPAT_GTEST_H_ -#define KJ_COMPAT_GTEST_H_ -// This file defines compatibility macros converting Google Test tests into KJ tests. -// -// This is only intended to cover the most common functionality. Many tests will likely need -// additional tweaks. For instance: -// - Using operator<< to print information on failure is not supported. Instead, switch to -// KJ_ASSERT/KJ_EXPECT and pass in stuff to print as additional parameters. -// - Test fixtures are not supported. Allocate your "test fixture" on the stack instead. Do setup -// in the constructor, teardown in the destructor. - -#include "../test.h" - -namespace kj { - -namespace _ { // private - -template -T abs(T value) { return value < 0 ? -value : value; } - -inline bool floatAlmostEqual(float a, float b) { - return a == b || abs(a - b) < (abs(a) + abs(b)) * 1e-5; -} - -inline bool doubleAlmostEqual(double a, double b) { - return a == b || abs(a - b) < (abs(a) + abs(b)) * 1e-12; -} - -} // namespace _ (private) - -#define EXPECT_FALSE(x) KJ_EXPECT(!(x)) -#define EXPECT_TRUE(x) KJ_EXPECT(x) -#define EXPECT_EQ(x, y) KJ_EXPECT((x) == (y), x, y) -#define EXPECT_NE(x, y) KJ_EXPECT((x) != (y), x, y) -#define EXPECT_LE(x, y) KJ_EXPECT((x) <= (y), x, y) -#define EXPECT_GE(x, y) KJ_EXPECT((x) >= (y), x, y) -#define EXPECT_LT(x, y) KJ_EXPECT((x) < (y), x, y) -#define EXPECT_GT(x, y) KJ_EXPECT((x) > (y), x, y) -#define EXPECT_STREQ(x, y) KJ_EXPECT(::strcmp(x, y) == 0, x, y) -#define EXPECT_FLOAT_EQ(x, y) KJ_EXPECT(::kj::_::floatAlmostEqual(y, x), y, x); -#define EXPECT_DOUBLE_EQ(x, y) KJ_EXPECT(::kj::_::doubleAlmostEqual(y, x), y, x); - -#define ASSERT_FALSE(x) KJ_ASSERT(!(x)) -#define ASSERT_TRUE(x) KJ_ASSERT(x) -#define ASSERT_EQ(x, y) KJ_ASSERT((x) == (y), x, y) -#define ASSERT_NE(x, y) KJ_ASSERT((x) != (y), x, y) -#define ASSERT_LE(x, y) KJ_ASSERT((x) <= (y), x, y) -#define ASSERT_GE(x, y) KJ_ASSERT((x) >= (y), x, y) -#define ASSERT_LT(x, y) KJ_ASSERT((x) < (y), x, y) -#define ASSERT_GT(x, y) KJ_ASSERT((x) > (y), x, y) -#define ASSERT_STREQ(x, y) KJ_ASSERT(::strcmp(x, y) == 0, x, y) -#define ASSERT_FLOAT_EQ(x, y) KJ_ASSERT(::kj::_::floatAlmostEqual(y, x), y, x); -#define ASSERT_DOUBLE_EQ(x, y) KJ_ASSERT(::kj::_::doubleAlmostEqual(y, x), y, x); - -class AddFailureAdapter { -public: - AddFailureAdapter(const char* file, int line): file(file), line(line) {} - - ~AddFailureAdapter() { - if (!handled) { - _::Debug::log(file, line, LogSeverity::ERROR, "expectation failed"); - } - } - - template - void operator<<(T&& info) { - handled = true; - _::Debug::log(file, line, LogSeverity::ERROR, "\"expectation failed\", info", - "expectation failed", kj::fwd(info)); - } - -private: - bool handled = false; - const char* file; - int line; -}; - -#define ADD_FAILURE() ::kj::AddFailureAdapter(__FILE__, __LINE__) - -#if KJ_NO_EXCEPTIONS -#define EXPECT_ANY_THROW(code) \ - KJ_EXPECT(::kj::_::expectFatalThrow(nullptr, nullptr, [&]() { code; })) -#else -#define EXPECT_ANY_THROW(code) \ - KJ_EXPECT(::kj::runCatchingExceptions([&]() { code; }) != nullptr) -#endif - -#define EXPECT_NONFATAL_FAILURE(code) \ - EXPECT_TRUE(kj::runCatchingExceptions([&]() { code; }) != nullptr); - -#ifdef KJ_DEBUG -#define EXPECT_DEBUG_ANY_THROW EXPECT_ANY_THROW -#else -#define EXPECT_DEBUG_ANY_THROW(EXP) -#endif - -#define TEST(x, y) KJ_TEST("legacy test: " #x "/" #y) - -} // namespace kj - -#endif // KJ_COMPAT_GTEST_H_ diff --git a/phonelibs/capnp-cpp/include/kj/compat/http.h b/phonelibs/capnp-cpp/include/kj/compat/http.h deleted file mode 100644 index 8d455cc2588543..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/compat/http.h +++ /dev/null @@ -1,636 +0,0 @@ -// Copyright (c) 2017 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_COMPAT_HTTP_H_ -#define KJ_COMPAT_HTTP_H_ -// The KJ HTTP client/server library. -// -// This is a simple library which can be used to implement an HTTP client or server. Properties -// of this library include: -// - Uses KJ async framework. -// - Agnostic to transport layer -- you can provide your own. -// - Header parsing is zero-copy -- it results in strings that point directly into the buffer -// received off the wire. -// - Application code which reads and writes headers refers to headers by symbolic names, not by -// string literals, with lookups being array-index-based, not map-based. To make this possible, -// the application announces what headers it cares about in advance, in order to assign numeric -// values to them. -// - Methods are identified by an enum. - -#include -#include -#include -#include -#include - -namespace kj { - -#define KJ_HTTP_FOR_EACH_METHOD(MACRO) \ - MACRO(GET) \ - MACRO(HEAD) \ - MACRO(POST) \ - MACRO(PUT) \ - MACRO(DELETE) \ - MACRO(PATCH) \ - MACRO(PURGE) \ - MACRO(OPTIONS) \ - MACRO(TRACE) \ - /* standard methods */ \ - /* */ \ - /* (CONNECT is intentionally omitted since it is handled specially in HttpHandler) */ \ - \ - MACRO(COPY) \ - MACRO(LOCK) \ - MACRO(MKCOL) \ - MACRO(MOVE) \ - MACRO(PROPFIND) \ - MACRO(PROPPATCH) \ - MACRO(SEARCH) \ - MACRO(UNLOCK) \ - /* WebDAV */ \ - \ - MACRO(REPORT) \ - MACRO(MKACTIVITY) \ - MACRO(CHECKOUT) \ - MACRO(MERGE) \ - /* Subversion */ \ - \ - MACRO(MSEARCH) \ - MACRO(NOTIFY) \ - MACRO(SUBSCRIBE) \ - MACRO(UNSUBSCRIBE) - /* UPnP */ - -#define KJ_HTTP_FOR_EACH_CONNECTION_HEADER(MACRO) \ - MACRO(connection, "Connection") \ - MACRO(contentLength, "Content-Length") \ - MACRO(keepAlive, "Keep-Alive") \ - MACRO(te, "TE") \ - MACRO(trailer, "Trailer") \ - MACRO(transferEncoding, "Transfer-Encoding") \ - MACRO(upgrade, "Upgrade") - -enum class HttpMethod { - // Enum of known HTTP methods. - // - // We use an enum rather than a string to allow for faster parsing and switching and to reduce - // ambiguity. - -#define DECLARE_METHOD(id) id, -KJ_HTTP_FOR_EACH_METHOD(DECLARE_METHOD) -#undef DECLARE_METHOD -}; - -kj::StringPtr KJ_STRINGIFY(HttpMethod method); -kj::Maybe tryParseHttpMethod(kj::StringPtr name); - -class HttpHeaderTable; - -class HttpHeaderId { - // Identifies an HTTP header by numeric ID that indexes into an HttpHeaderTable. - // - // The KJ HTTP API prefers that headers be identified by these IDs for a few reasons: - // - Integer lookups are much more efficient than string lookups. - // - Case-insensitivity is awkward to deal with when const strings are being passed to the lookup - // method. - // - Writing out strings less often means fewer typos. - // - // See HttpHeaderTable for usage hints. - -public: - HttpHeaderId() = default; - - inline bool operator==(const HttpHeaderId& other) const { return id == other.id; } - inline bool operator!=(const HttpHeaderId& other) const { return id != other.id; } - inline bool operator< (const HttpHeaderId& other) const { return id < other.id; } - inline bool operator> (const HttpHeaderId& other) const { return id > other.id; } - inline bool operator<=(const HttpHeaderId& other) const { return id <= other.id; } - inline bool operator>=(const HttpHeaderId& other) const { return id >= other.id; } - - inline size_t hashCode() const { return id; } - - kj::StringPtr toString() const; - - void requireFrom(HttpHeaderTable& table) const; - // In debug mode, throws an exception if the HttpHeaderId is not from the given table. - // - // In opt mode, no-op. - -#define KJ_HTTP_FOR_EACH_BUILTIN_HEADER(MACRO) \ - MACRO(HOST, "Host") \ - MACRO(DATE, "Date") \ - MACRO(LOCATION, "Location") \ - MACRO(CONTENT_TYPE, "Content-Type") - // For convenience, these very-common headers are valid for all HttpHeaderTables. You can refer - // to them like: - // - // HttpHeaderId::HOST - // - // TODO(0.7): Fill this out with more common headers. - -#define DECLARE_HEADER(id, name) \ - static const HttpHeaderId id; - // Declare a constant for each builtin header, e.g.: HttpHeaderId::CONNECTION - - KJ_HTTP_FOR_EACH_BUILTIN_HEADER(DECLARE_HEADER); -#undef DECLARE_HEADER - -private: - HttpHeaderTable* table; - uint id; - - inline explicit constexpr HttpHeaderId(HttpHeaderTable* table, uint id): table(table), id(id) {} - friend class HttpHeaderTable; - friend class HttpHeaders; -}; - -class HttpHeaderTable { - // Construct an HttpHeaderTable to declare which headers you'll be interested in later on, and - // to manufacture IDs for them. - // - // Example: - // - // // Build a header table with the headers we are interested in. - // kj::HttpHeaderTable::Builder builder; - // const HttpHeaderId accept = builder.add("Accept"); - // const HttpHeaderId contentType = builder.add("Content-Type"); - // kj::HttpHeaderTable table(kj::mv(builder)); - // - // // Create an HTTP client. - // auto client = kj::newHttpClient(table, network); - // - // // Get http://example.com. - // HttpHeaders headers(table); - // headers.set(accept, "text/html"); - // auto response = client->send(kj::HttpMethod::GET, "http://example.com", headers) - // .wait(waitScope); - // auto msg = kj::str("Response content type: ", response.headers.get(contentType)); - - struct IdsByNameMap; - -public: - HttpHeaderTable(); - // Constructs a table that only contains the builtin headers. - - class Builder { - public: - Builder(); - HttpHeaderId add(kj::StringPtr name); - Own build(); - - HttpHeaderTable& getFutureTable(); - // Get the still-unbuilt header table. You cannot actually use it until build() has been - // called. - // - // This method exists to help when building a shared header table -- the Builder may be passed - // to several components, each of which will register the headers they need and get a reference - // to the future table. - - private: - kj::Own table; - }; - - KJ_DISALLOW_COPY(HttpHeaderTable); // Can't copy because HttpHeaderId points to the table. - ~HttpHeaderTable() noexcept(false); - - uint idCount(); - // Return the number of IDs in the table. - - kj::Maybe stringToId(kj::StringPtr name); - // Try to find an ID for the given name. The matching is case-insensitive, per the HTTP spec. - // - // Note: if `name` contains characters that aren't allowed in HTTP header names, this may return - // a bogus value rather than null, due to optimizations used in case-insensitive matching. - - kj::StringPtr idToString(HttpHeaderId id); - // Get the canonical string name for the given ID. - -private: - kj::Vector namesById; - kj::Own idsByName; -}; - -class HttpHeaders { - // Represents a set of HTTP headers. - // - // This class guards against basic HTTP header injection attacks: Trying to set a header name or - // value containing a newline, carriage return, or other invalid character will throw an - // exception. - -public: - explicit HttpHeaders(HttpHeaderTable& table); - - KJ_DISALLOW_COPY(HttpHeaders); - HttpHeaders(HttpHeaders&&) = default; - HttpHeaders& operator=(HttpHeaders&&) = default; - - void clear(); - // Clears all contents, as if the object was freshly-allocated. However, calling this rather - // than actually re-allocating the object may avoid re-allocation of internal objects. - - HttpHeaders clone() const; - // Creates a deep clone of the HttpHeaders. The returned object owns all strings it references. - - HttpHeaders cloneShallow() const; - // Creates a shallow clone of the HttpHeaders. The returned object references the same strings - // as the original, owning none of them. - - kj::Maybe get(HttpHeaderId id) const; - // Read a header. - - template - void forEach(Func&& func) const; - // Calls `func(name, value)` for each header in the set -- including headers that aren't mapped - // to IDs in the header table. Both inputs are of type kj::StringPtr. - - void set(HttpHeaderId id, kj::StringPtr value); - void set(HttpHeaderId id, kj::String&& value); - // Sets a header value, overwriting the existing value. - // - // The String&& version is equivalent to calling the other version followed by takeOwnership(). - // - // WARNING: It is the caller's responsibility to ensure that `value` remains valid until the - // HttpHeaders object is destroyed. This allows string literals to be passed without making a - // copy, but complicates the use of dynamic values. Hint: Consider using `takeOwnership()`. - - void add(kj::StringPtr name, kj::StringPtr value); - void add(kj::StringPtr name, kj::String&& value); - void add(kj::String&& name, kj::String&& value); - // Append a header. `name` will be looked up in the header table, but if it's not mapped, the - // header will be added to the list of unmapped headers. - // - // The String&& versions are equivalent to calling the other version followed by takeOwnership(). - // - // WARNING: It is the caller's responsibility to ensure that `name` and `value` remain valid - // until the HttpHeaders object is destroyed. This allows string literals to be passed without - // making a copy, but complicates the use of dynamic values. Hint: Consider using - // `takeOwnership()`. - - void unset(HttpHeaderId id); - // Removes a header. - // - // It's not possible to remove a header by string name because non-indexed headers would take - // O(n) time to remove. Instead, construct a new HttpHeaders object and copy contents. - - void takeOwnership(kj::String&& string); - void takeOwnership(kj::Array&& chars); - void takeOwnership(HttpHeaders&& otherHeaders); - // Takes overship of a string so that it lives until the HttpHeaders object is destroyed. Useful - // when you've passed a dynamic value to set() or add() or parse*(). - - struct ConnectionHeaders { - // These headers govern details of the specific HTTP connection or framing of the content. - // Hence, they are managed internally within the HTTP library, and never appear in an - // HttpHeaders structure. - -#define DECLARE_HEADER(id, name) \ - kj::StringPtr id; - KJ_HTTP_FOR_EACH_CONNECTION_HEADER(DECLARE_HEADER) -#undef DECLARE_HEADER - }; - - struct Request { - HttpMethod method; - kj::StringPtr url; - ConnectionHeaders connectionHeaders; - }; - struct Response { - uint statusCode; - kj::StringPtr statusText; - ConnectionHeaders connectionHeaders; - }; - - kj::Maybe tryParseRequest(kj::ArrayPtr content); - kj::Maybe tryParseResponse(kj::ArrayPtr content); - // Parse an HTTP header blob and add all the headers to this object. - // - // `content` should be all text from the start of the request to the first occurrance of two - // newlines in a row -- including the first of these two newlines, but excluding the second. - // - // The parse is performed with zero copies: The callee clobbers `content` with '\0' characters - // to split it into a bunch of shorter strings. The caller must keep `content` valid until the - // `HttpHeaders` is destroyed, or pass it to `takeOwnership()`. - - kj::String serializeRequest(HttpMethod method, kj::StringPtr url, - const ConnectionHeaders& connectionHeaders) const; - kj::String serializeResponse(uint statusCode, kj::StringPtr statusText, - const ConnectionHeaders& connectionHeaders) const; - // Serialize the headers as a complete request or response blob. The blob uses '\r\n' newlines - // and includes the double-newline to indicate the end of the headers. - - kj::String toString() const; - -private: - HttpHeaderTable* table; - - kj::Array indexedHeaders; - // Size is always table->idCount(). - - struct Header { - kj::StringPtr name; - kj::StringPtr value; - }; - kj::Vector

unindexedHeaders; - - kj::Vector> ownedStrings; - - kj::Maybe addNoCheck(kj::StringPtr name, kj::StringPtr value); - - kj::StringPtr cloneToOwn(kj::StringPtr str); - - kj::String serialize(kj::ArrayPtr word1, - kj::ArrayPtr word2, - kj::ArrayPtr word3, - const ConnectionHeaders& connectionHeaders) const; - - bool parseHeaders(char* ptr, char* end, ConnectionHeaders& connectionHeaders); - - // TODO(perf): Arguably we should store a map, but header sets are never very long - // TODO(perf): We could optimize for common headers by storing them directly as fields. We could - // also add direct accessors for those headers. -}; - -class WebSocket { -public: - WebSocket(kj::Own stream); - // Create a WebSocket wrapping the given I/O stream. - - kj::Promise send(kj::ArrayPtr message); - kj::Promise send(kj::ArrayPtr message); -}; - -class HttpClient { - // Interface to the client end of an HTTP connection. - // - // There are two kinds of clients: - // * Host clients are used when talking to a specific host. The `url` specified in a request - // is actually just a path. (A `Host` header is still required in all requests.) - // * Proxy clients are used when the target could be any arbitrary host on the internet. - // The `url` specified in a request is a full URL including protocol and hostname. - -public: - struct Response { - uint statusCode; - kj::StringPtr statusText; - const HttpHeaders* headers; - kj::Own body; - // `statusText` and `headers` remain valid until `body` is dropped. - }; - - struct Request { - kj::Own body; - // Write the request entity body to this stream, then drop it when done. - // - // May be null for GET and HEAD requests (which have no body) and requests that have - // Content-Length: 0. - - kj::Promise response; - // Promise for the eventual respnose. - }; - - virtual Request request(HttpMethod method, kj::StringPtr url, const HttpHeaders& headers, - kj::Maybe expectedBodySize = nullptr) = 0; - // Perform an HTTP request. - // - // `url` may be a full URL (with protocol and host) or it may be only the path part of the URL, - // depending on whether the client is a proxy client or a host client. - // - // `url` and `headers` need only remain valid until `request()` returns (they can be - // stack-allocated). - // - // `expectedBodySize`, if provided, must be exactly the number of bytes that will be written to - // the body. This will trigger use of the `Content-Length` connection header. Otherwise, - // `Transfer-Encoding: chunked` will be used. - - struct WebSocketResponse { - uint statusCode; - kj::StringPtr statusText; - const HttpHeaders* headers; - kj::OneOf, kj::Own> upstreamOrBody; - // `statusText` and `headers` remain valid until `upstreamOrBody` is dropped. - }; - virtual kj::Promise openWebSocket( - kj::StringPtr url, const HttpHeaders& headers, kj::Own downstream); - // Tries to open a WebSocket. Default implementation calls send() and never returns a WebSocket. - // - // `url` and `headers` are invalidated when the returned promise resolves. - - virtual kj::Promise> connect(kj::String host); - // Handles CONNECT requests. Only relevant for proxy clients. Default implementation throws - // UNIMPLEMENTED. -}; - -class HttpService { - // Interface which HTTP services should implement. - // - // This interface is functionally equivalent to HttpClient, but is intended for applications to - // implement rather than call. The ergonomics and performance of the method signatures are - // optimized for the serving end. - // - // As with clients, there are two kinds of services: - // * Host services are used when talking to a specific host. The `url` specified in a request - // is actually just a path. (A `Host` header is still required in all requests, and the service - // may in fact serve multiple origins via this header.) - // * Proxy services are used when the target could be any arbitrary host on the internet, i.e. to - // implement an HTTP proxy. The `url` specified in a request is a full URL including protocol - // and hostname. - -public: - class Response { - public: - virtual kj::Own send( - uint statusCode, kj::StringPtr statusText, const HttpHeaders& headers, - kj::Maybe expectedBodySize = nullptr) = 0; - // Begin the response. - // - // `statusText` and `headers` need only remain valid until send() returns (they can be - // stack-allocated). - }; - - virtual kj::Promise request( - HttpMethod method, kj::StringPtr url, const HttpHeaders& headers, - kj::AsyncInputStream& requestBody, Response& response) = 0; - // Perform an HTTP request. - // - // `url` may be a full URL (with protocol and host) or it may be only the path part of the URL, - // depending on whether the service is a proxy service or a host service. - // - // `url` and `headers` are invalidated on the first read from `requestBody` or when the returned - // promise resolves, whichever comes first. - - class WebSocketResponse: public Response { - public: - kj::Own startWebSocket( - uint statusCode, kj::StringPtr statusText, const HttpHeaders& headers, - WebSocket& upstream); - // Begin the response. - // - // `statusText` and `headers` need only remain valid until startWebSocket() returns (they can - // be stack-allocated). - }; - - virtual kj::Promise openWebSocket( - kj::StringPtr url, const HttpHeaders& headers, WebSocketResponse& response); - // Tries to open a WebSocket. Default implementation calls request() and never returns a - // WebSocket. - // - // `url` and `headers` are invalidated when the returned promise resolves. - - virtual kj::Promise> connect(kj::String host); - // Handles CONNECT requests. Only relevant for proxy services. Default implementation throws - // UNIMPLEMENTED. -}; - -kj::Own newHttpClient(HttpHeaderTable& responseHeaderTable, kj::Network& network, - kj::Maybe tlsNetwork = nullptr); -// Creates a proxy HttpClient that connects to hosts over the given network. -// -// `responseHeaderTable` is used when parsing HTTP responses. Requests can use any header table. -// -// `tlsNetwork` is required to support HTTPS destination URLs. Otherwise, only HTTP URLs can be -// fetched. - -kj::Own newHttpClient(HttpHeaderTable& responseHeaderTable, kj::AsyncIoStream& stream); -// Creates an HttpClient that speaks over the given pre-established connection. The client may -// be used as a proxy client or a host client depending on whether the peer is operating as -// a proxy. -// -// Note that since this client has only one stream to work with, it will try to pipeline all -// requests on this stream. If one request or response has an I/O failure, all subsequent requests -// fail as well. If the destination server chooses to close the connection after a response, -// subsequent requests will fail. If a response takes a long time, it blocks subsequent responses. -// If a WebSocket is opened successfully, all subsequent requests fail. - -kj::Own newHttpClient(HttpService& service); -kj::Own newHttpService(HttpClient& client); -// Adapts an HttpClient to an HttpService and vice versa. - -struct HttpServerSettings { - kj::Duration headerTimeout = 15 * kj::SECONDS; - // After initial connection open, or after receiving the first byte of a pipelined request, - // the client must send the complete request within this time. - - kj::Duration pipelineTimeout = 5 * kj::SECONDS; - // After one request/response completes, we'll wait up to this long for a pipelined request to - // arrive. -}; - -class HttpServer: private kj::TaskSet::ErrorHandler { - // Class which listens for requests on ports or connections and sends them to an HttpService. - -public: - typedef HttpServerSettings Settings; - - HttpServer(kj::Timer& timer, HttpHeaderTable& requestHeaderTable, HttpService& service, - Settings settings = Settings()); - // Set up an HttpServer that directs incoming connections to the given service. The service - // may be a host service or a proxy service depending on whether you are intending to implement - // an HTTP server or an HTTP proxy. - - kj::Promise drain(); - // Stop accepting new connections or new requests on existing connections. Finish any requests - // that are already executing, then close the connections. Returns once no more requests are - // in-flight. - - kj::Promise listenHttp(kj::ConnectionReceiver& port); - // Accepts HTTP connections on the given port and directs them to the handler. - // - // The returned promise never completes normally. It may throw if port.accept() throws. Dropping - // the returned promise will cause the server to stop listening on the port, but already-open - // connections will continue to be served. Destroy the whole HttpServer to cancel all I/O. - - kj::Promise listenHttp(kj::Own connection); - // Reads HTTP requests from the given connection and directs them to the handler. A successful - // completion of the promise indicates that all requests received on the connection resulted in - // a complete response, and the client closed the connection gracefully or drain() was called. - // The promise throws if an unparseable request is received or if some I/O error occurs. Dropping - // the returned promise will cancel all I/O on the connection and cancel any in-flight requests. - -private: - class Connection; - - kj::Timer& timer; - HttpHeaderTable& requestHeaderTable; - HttpService& service; - Settings settings; - - bool draining = false; - kj::ForkedPromise onDrain; - kj::Own> drainFulfiller; - - uint connectionCount = 0; - kj::Maybe>> zeroConnectionsFulfiller; - - kj::TaskSet tasks; - - HttpServer(kj::Timer& timer, HttpHeaderTable& requestHeaderTable, HttpService& service, - Settings settings, kj::PromiseFulfillerPair paf); - - kj::Promise listenLoop(kj::ConnectionReceiver& port); - - void taskFailed(kj::Exception&& exception) override; -}; - -// ======================================================================================= -// inline implementation - -inline void HttpHeaderId::requireFrom(HttpHeaderTable& table) const { - KJ_IREQUIRE(this->table == nullptr || this->table == &table, - "the provided HttpHeaderId is from the wrong HttpHeaderTable"); -} - -inline kj::Own HttpHeaderTable::Builder::build() { return kj::mv(table); } -inline HttpHeaderTable& HttpHeaderTable::Builder::getFutureTable() { return *table; } - -inline uint HttpHeaderTable::idCount() { return namesById.size(); } - -inline kj::StringPtr HttpHeaderTable::idToString(HttpHeaderId id) { - id.requireFrom(*this); - return namesById[id.id]; -} - -inline kj::Maybe HttpHeaders::get(HttpHeaderId id) const { - id.requireFrom(*table); - auto result = indexedHeaders[id.id]; - return result == nullptr ? kj::Maybe(nullptr) : result; -} - -inline void HttpHeaders::unset(HttpHeaderId id) { - id.requireFrom(*table); - indexedHeaders[id.id] = nullptr; -} - -template -inline void HttpHeaders::forEach(Func&& func) const { - for (auto i: kj::indices(indexedHeaders)) { - if (indexedHeaders[i] != nullptr) { - func(table->idToString(HttpHeaderId(table, i)), indexedHeaders[i]); - } - } - - for (auto& header: unindexedHeaders) { - func(header.name, header.value); - } -} - -} // namespace kj - -#endif // KJ_COMPAT_HTTP_H_ diff --git a/phonelibs/capnp-cpp/include/kj/debug.h b/phonelibs/capnp-cpp/include/kj/debug.h deleted file mode 100644 index fff7f98bc02bb5..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/debug.h +++ /dev/null @@ -1,555 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -// This file declares convenient macros for debug logging and error handling. The macros make -// it excessively easy to extract useful context information from code. Example: -// -// KJ_ASSERT(a == b, a, b, "a and b must be the same."); -// -// On failure, this will throw an exception whose description looks like: -// -// myfile.c++:43: bug in code: expected a == b; a = 14; b = 72; a and b must be the same. -// -// As you can see, all arguments after the first provide additional context. -// -// The macros available are: -// -// * `KJ_LOG(severity, ...)`: Just writes a log message, to stderr by default (but you can -// intercept messages by implementing an ExceptionCallback). `severity` is `INFO`, `WARNING`, -// `ERROR`, or `FATAL`. By default, `INFO` logs are not written, but for command-line apps the -// user should be able to pass a flag like `--verbose` to enable them. Other log levels are -// enabled by default. Log messages -- like exceptions -- can be intercepted by registering an -// ExceptionCallback. -// -// * `KJ_DBG(...)`: Like `KJ_LOG`, but intended specifically for temporary log lines added while -// debugging a particular problem. Calls to `KJ_DBG` should always be deleted before committing -// code. It is suggested that you set up a pre-commit hook that checks for this. -// -// * `KJ_ASSERT(condition, ...)`: Throws an exception if `condition` is false, or aborts if -// exceptions are disabled. This macro should be used to check for bugs in the surrounding code -// and its dependencies, but NOT to check for invalid input. The macro may be followed by a -// brace-delimited code block; if so, the block will be executed in the case where the assertion -// fails, before throwing the exception. If control jumps out of the block (e.g. with "break", -// "return", or "goto"), then the error is considered "recoverable" -- in this case, if -// exceptions are disabled, execution will continue normally rather than aborting (but if -// exceptions are enabled, an exception will still be thrown on exiting the block). A "break" -// statement in particular will jump to the code immediately after the block (it does not break -// any surrounding loop or switch). Example: -// -// KJ_ASSERT(value >= 0, "Value cannot be negative.", value) { -// // Assertion failed. Set value to zero to "recover". -// value = 0; -// // Don't abort if exceptions are disabled. Continue normally. -// // (Still throw an exception if they are enabled, though.) -// break; -// } -// // When exceptions are disabled, we'll get here even if the assertion fails. -// // Otherwise, we get here only if the assertion passes. -// -// * `KJ_REQUIRE(condition, ...)`: Like `KJ_ASSERT` but used to check preconditions -- e.g. to -// validate parameters passed from a caller. A failure indicates that the caller is buggy. -// -// * `KJ_SYSCALL(code, ...)`: Executes `code` assuming it makes a system call. A negative result -// is considered an error, with error code reported via `errno`. EINTR is handled by retrying. -// Other errors are handled by throwing an exception. If you need to examine the return code, -// assign it to a variable like so: -// -// int fd; -// KJ_SYSCALL(fd = open(filename, O_RDONLY), filename); -// -// `KJ_SYSCALL` can be followed by a recovery block, just like `KJ_ASSERT`. -// -// * `KJ_NONBLOCKING_SYSCALL(code, ...)`: Like KJ_SYSCALL, but will not throw an exception on -// EAGAIN/EWOULDBLOCK. The calling code should check the syscall's return value to see if it -// indicates an error; in this case, it can assume the error was EAGAIN because any other error -// would have caused an exception to be thrown. -// -// * `KJ_CONTEXT(...)`: Notes additional contextual information relevant to any exceptions thrown -// from within the current scope. That is, until control exits the block in which KJ_CONTEXT() -// is used, if any exception is generated, it will contain the given information in its context -// chain. This is helpful because it can otherwise be very difficult to come up with error -// messages that make sense within low-level helper code. Note that the parameters to -// KJ_CONTEXT() are only evaluated if an exception is thrown. This implies that any variables -// used must remain valid until the end of the scope. -// -// Notes: -// * Do not write expressions with side-effects in the message content part of the macro, as the -// message will not necessarily be evaluated. -// * For every macro `FOO` above except `LOG`, there is also a `FAIL_FOO` macro used to report -// failures that already happened. For the macros that check a boolean condition, `FAIL_FOO` -// omits the first parameter and behaves like it was `false`. `FAIL_SYSCALL` and -// `FAIL_RECOVERABLE_SYSCALL` take a string and an OS error number as the first two parameters. -// The string should be the name of the failed system call. -// * For every macro `FOO` above, there is a `DFOO` version (or `RECOVERABLE_DFOO`) which is only -// executed in debug mode, i.e. when KJ_DEBUG is defined. KJ_DEBUG is defined automatically -// by common.h when compiling without optimization (unless NDEBUG is defined), but you can also -// define it explicitly (e.g. -DKJ_DEBUG). Generally, production builds should NOT use KJ_DEBUG -// as it may enable expensive checks that are unlikely to fail. - -#ifndef KJ_DEBUG_H_ -#define KJ_DEBUG_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "string.h" -#include "exception.h" - -#ifdef ERROR -// This is problematic because windows.h #defines ERROR, which we use in an enum here. -#error "Make sure to to undefine ERROR (or just #include ) before this file" -#endif - -namespace kj { - -#if _MSC_VER -// MSVC does __VA_ARGS__ differently from GCC: -// - A trailing comma before an empty __VA_ARGS__ is removed automatically, whereas GCC wants -// you to request this behavior with "##__VA_ARGS__". -// - If __VA_ARGS__ is passed directly as an argument to another macro, it will be treated as a -// *single* argument rather than an argument list. This can be worked around by wrapping the -// outer macro call in KJ_EXPAND(), which appraently forces __VA_ARGS__ to be expanded before -// the macro is evaluated. I don't understand the C preprocessor. -// - Using "#__VA_ARGS__" to stringify __VA_ARGS__ expands to zero tokens when __VA_ARGS__ is -// empty, rather than expanding to an empty string literal. We can work around by concatenating -// with an empty string literal. - -#define KJ_EXPAND(X) X - -#define KJ_LOG(severity, ...) \ - if (!::kj::_::Debug::shouldLog(::kj::LogSeverity::severity)) {} else \ - ::kj::_::Debug::log(__FILE__, __LINE__, ::kj::LogSeverity::severity, \ - "" #__VA_ARGS__, __VA_ARGS__) - -#define KJ_DBG(...) KJ_EXPAND(KJ_LOG(DBG, __VA_ARGS__)) - -#define KJ_REQUIRE(cond, ...) \ - if (KJ_LIKELY(cond)) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ - #cond, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) - -#define KJ_FAIL_REQUIRE(...) \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ - nullptr, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) - -#define KJ_SYSCALL(call, ...) \ - if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, false)) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - _kjSyscallResult.getErrorNumber(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) - -#define KJ_NONBLOCKING_SYSCALL(call, ...) \ - if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, true)) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - _kjSyscallResult.getErrorNumber(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) - -#define KJ_FAIL_SYSCALL(code, errorNumber, ...) \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - errorNumber, code, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) - -#if _WIN32 - -#define KJ_WIN32(call, ...) \ - if (::kj::_::Debug::isWin32Success(call)) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - ::kj::_::Debug::getWin32Error(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) - -#define KJ_WINSOCK(call, ...) \ - if ((call) != SOCKET_ERROR) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - ::kj::_::Debug::getWin32Error(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) - -#define KJ_FAIL_WIN32(code, errorNumber, ...) \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - ::kj::_::Debug::Win32Error(errorNumber), code, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) - -#endif - -#define KJ_UNIMPLEMENTED(...) \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::UNIMPLEMENTED, \ - nullptr, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) - -// TODO(msvc): MSVC mis-deduces `ContextImpl` as `ContextImpl` in some edge -// cases, such as inside nested lambdas inside member functions. Wrapping the type in -// `decltype(instance<...>())` helps it deduce the context function's type correctly. -#define KJ_CONTEXT(...) \ - auto KJ_UNIQUE_NAME(_kjContextFunc) = [&]() -> ::kj::_::Debug::Context::Value { \ - return ::kj::_::Debug::Context::Value(__FILE__, __LINE__, \ - ::kj::_::Debug::makeDescription("" #__VA_ARGS__, __VA_ARGS__)); \ - }; \ - decltype(::kj::instance<::kj::_::Debug::ContextImpl>()) \ - KJ_UNIQUE_NAME(_kjContext)(KJ_UNIQUE_NAME(_kjContextFunc)) - -#define KJ_REQUIRE_NONNULL(value, ...) \ - (*[&] { \ - auto _kj_result = ::kj::_::readMaybe(value); \ - if (KJ_UNLIKELY(!_kj_result)) { \ - ::kj::_::Debug::Fault(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ - #value " != nullptr", "" #__VA_ARGS__, __VA_ARGS__).fatal(); \ - } \ - return _kj_result; \ - }()) - -#define KJ_EXCEPTION(type, ...) \ - ::kj::Exception(::kj::Exception::Type::type, __FILE__, __LINE__, \ - ::kj::_::Debug::makeDescription("" #__VA_ARGS__, __VA_ARGS__)) - -#else - -#define KJ_LOG(severity, ...) \ - if (!::kj::_::Debug::shouldLog(::kj::LogSeverity::severity)) {} else \ - ::kj::_::Debug::log(__FILE__, __LINE__, ::kj::LogSeverity::severity, \ - #__VA_ARGS__, ##__VA_ARGS__) - -#define KJ_DBG(...) KJ_LOG(DBG, ##__VA_ARGS__) - -#define KJ_REQUIRE(cond, ...) \ - if (KJ_LIKELY(cond)) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ - #cond, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) - -#define KJ_FAIL_REQUIRE(...) \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ - nullptr, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) - -#define KJ_SYSCALL(call, ...) \ - if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, false)) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - _kjSyscallResult.getErrorNumber(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) - -#define KJ_NONBLOCKING_SYSCALL(call, ...) \ - if (auto _kjSyscallResult = ::kj::_::Debug::syscall([&](){return (call);}, true)) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - _kjSyscallResult.getErrorNumber(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) - -#define KJ_FAIL_SYSCALL(code, errorNumber, ...) \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - errorNumber, code, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) - -#if _WIN32 - -#define KJ_WIN32(call, ...) \ - if (::kj::_::Debug::isWin32Success(call)) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - ::kj::_::Debug::getWin32Error(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) - -#define KJ_WINSOCK(call, ...) \ - if ((call) != SOCKET_ERROR) {} else \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - ::kj::_::Debug::getWin32Error(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) - -#define KJ_FAIL_WIN32(code, errorNumber, ...) \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ - ::kj::_::Debug::Win32Error(errorNumber), code, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) - -#endif - -#define KJ_UNIMPLEMENTED(...) \ - for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::UNIMPLEMENTED, \ - nullptr, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) - -#define KJ_CONTEXT(...) \ - auto KJ_UNIQUE_NAME(_kjContextFunc) = [&]() -> ::kj::_::Debug::Context::Value { \ - return ::kj::_::Debug::Context::Value(__FILE__, __LINE__, \ - ::kj::_::Debug::makeDescription(#__VA_ARGS__, ##__VA_ARGS__)); \ - }; \ - ::kj::_::Debug::ContextImpl \ - KJ_UNIQUE_NAME(_kjContext)(KJ_UNIQUE_NAME(_kjContextFunc)) - -#define KJ_REQUIRE_NONNULL(value, ...) \ - (*({ \ - auto _kj_result = ::kj::_::readMaybe(value); \ - if (KJ_UNLIKELY(!_kj_result)) { \ - ::kj::_::Debug::Fault(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \ - #value " != nullptr", #__VA_ARGS__, ##__VA_ARGS__).fatal(); \ - } \ - kj::mv(_kj_result); \ - })) - -#define KJ_EXCEPTION(type, ...) \ - ::kj::Exception(::kj::Exception::Type::type, __FILE__, __LINE__, \ - ::kj::_::Debug::makeDescription(#__VA_ARGS__, ##__VA_ARGS__)) - -#endif - -#define KJ_SYSCALL_HANDLE_ERRORS(call) \ - if (int _kjSyscallError = ::kj::_::Debug::syscallError([&](){return (call);}, false)) \ - switch (int error = _kjSyscallError) -// Like KJ_SYSCALL, but doesn't throw. Instead, the block after the macro is a switch block on the -// error. Additionally, the int value `error` is defined within the block. So you can do: -// -// KJ_SYSCALL_HANDLE_ERRORS(foo()) { -// case ENOENT: -// handleNoSuchFile(); -// break; -// case EEXIST: -// handleExists(); -// break; -// default: -// KJ_FAIL_SYSCALL("foo()", error); -// } else { -// handleSuccessCase(); -// } - -#define KJ_ASSERT KJ_REQUIRE -#define KJ_FAIL_ASSERT KJ_FAIL_REQUIRE -#define KJ_ASSERT_NONNULL KJ_REQUIRE_NONNULL -// Use "ASSERT" in place of "REQUIRE" when the problem is local to the immediate surrounding code. -// That is, if the assert ever fails, it indicates that the immediate surrounding code is broken. - -#ifdef KJ_DEBUG -#define KJ_DLOG KJ_LOG -#define KJ_DASSERT KJ_ASSERT -#define KJ_DREQUIRE KJ_REQUIRE -#else -#define KJ_DLOG(...) do {} while (false) -#define KJ_DASSERT(...) do {} while (false) -#define KJ_DREQUIRE(...) do {} while (false) -#endif - -namespace _ { // private - -class Debug { -public: - Debug() = delete; - - typedef LogSeverity Severity; // backwards-compatibility - -#if _WIN32 - struct Win32Error { - // Hack for overloading purposes. - uint number; - inline explicit Win32Error(uint number): number(number) {} - }; -#endif - - static inline bool shouldLog(LogSeverity severity) { return severity >= minSeverity; } - // Returns whether messages of the given severity should be logged. - - static inline void setLogLevel(LogSeverity severity) { minSeverity = severity; } - // Set the minimum message severity which will be logged. - // - // TODO(someday): Expose publicly. - - template - static void log(const char* file, int line, LogSeverity severity, const char* macroArgs, - Params&&... params); - - class Fault { - public: - template - Fault(const char* file, int line, Code code, - const char* condition, const char* macroArgs, Params&&... params); - Fault(const char* file, int line, Exception::Type type, - const char* condition, const char* macroArgs); - Fault(const char* file, int line, int osErrorNumber, - const char* condition, const char* macroArgs); -#if _WIN32 - Fault(const char* file, int line, Win32Error osErrorNumber, - const char* condition, const char* macroArgs); -#endif - ~Fault() noexcept(false); - - KJ_NOINLINE KJ_NORETURN(void fatal()); - // Throw the exception. - - private: - void init(const char* file, int line, Exception::Type type, - const char* condition, const char* macroArgs, ArrayPtr argValues); - void init(const char* file, int line, int osErrorNumber, - const char* condition, const char* macroArgs, ArrayPtr argValues); -#if _WIN32 - void init(const char* file, int line, Win32Error osErrorNumber, - const char* condition, const char* macroArgs, ArrayPtr argValues); -#endif - - Exception* exception; - }; - - class SyscallResult { - public: - inline SyscallResult(int errorNumber): errorNumber(errorNumber) {} - inline operator void*() { return errorNumber == 0 ? this : nullptr; } - inline int getErrorNumber() { return errorNumber; } - - private: - int errorNumber; - }; - - template - static SyscallResult syscall(Call&& call, bool nonblocking); - template - static int syscallError(Call&& call, bool nonblocking); - -#if _WIN32 - static bool isWin32Success(int boolean); - static bool isWin32Success(void* handle); - static Win32Error getWin32Error(); -#endif - - class Context: public ExceptionCallback { - public: - Context(); - KJ_DISALLOW_COPY(Context); - virtual ~Context() noexcept(false); - - struct Value { - const char* file; - int line; - String description; - - inline Value(const char* file, int line, String&& description) - : file(file), line(line), description(mv(description)) {} - }; - - virtual Value evaluate() = 0; - - virtual void onRecoverableException(Exception&& exception) override; - virtual void onFatalException(Exception&& exception) override; - virtual void logMessage(LogSeverity severity, const char* file, int line, int contextDepth, - String&& text) override; - - private: - bool logged; - Maybe value; - - Value ensureInitialized(); - }; - - template - class ContextImpl: public Context { - public: - inline ContextImpl(Func& func): func(func) {} - KJ_DISALLOW_COPY(ContextImpl); - - Value evaluate() override { - return func(); - } - private: - Func& func; - }; - - template - static String makeDescription(const char* macroArgs, Params&&... params); - -private: - static LogSeverity minSeverity; - - static void logInternal(const char* file, int line, LogSeverity severity, const char* macroArgs, - ArrayPtr argValues); - static String makeDescriptionInternal(const char* macroArgs, ArrayPtr argValues); - - static int getOsErrorNumber(bool nonblocking); - // Get the error code of the last error (e.g. from errno). Returns -1 on EINTR. -}; - -template -void Debug::log(const char* file, int line, LogSeverity severity, const char* macroArgs, - Params&&... params) { - String argValues[sizeof...(Params)] = {str(params)...}; - logInternal(file, line, severity, macroArgs, arrayPtr(argValues, sizeof...(Params))); -} - -template <> -inline void Debug::log<>(const char* file, int line, LogSeverity severity, const char* macroArgs) { - logInternal(file, line, severity, macroArgs, nullptr); -} - -template -Debug::Fault::Fault(const char* file, int line, Code code, - const char* condition, const char* macroArgs, Params&&... params) - : exception(nullptr) { - String argValues[sizeof...(Params)] = {str(params)...}; - init(file, line, code, condition, macroArgs, - arrayPtr(argValues, sizeof...(Params))); -} - -inline Debug::Fault::Fault(const char* file, int line, int osErrorNumber, - const char* condition, const char* macroArgs) - : exception(nullptr) { - init(file, line, osErrorNumber, condition, macroArgs, nullptr); -} - -inline Debug::Fault::Fault(const char* file, int line, kj::Exception::Type type, - const char* condition, const char* macroArgs) - : exception(nullptr) { - init(file, line, type, condition, macroArgs, nullptr); -} - -#if _WIN32 -inline Debug::Fault::Fault(const char* file, int line, Win32Error osErrorNumber, - const char* condition, const char* macroArgs) - : exception(nullptr) { - init(file, line, osErrorNumber, condition, macroArgs, nullptr); -} - -inline bool Debug::isWin32Success(int boolean) { - return boolean; -} -inline bool Debug::isWin32Success(void* handle) { - // Assume null and INVALID_HANDLE_VALUE mean failure. - return handle != nullptr && handle != (void*)-1; -} -#endif - -template -Debug::SyscallResult Debug::syscall(Call&& call, bool nonblocking) { - while (call() < 0) { - int errorNum = getOsErrorNumber(nonblocking); - // getOsErrorNumber() returns -1 to indicate EINTR. - // Also, if nonblocking is true, then it returns 0 on EAGAIN, which will then be treated as a - // non-error. - if (errorNum != -1) { - return SyscallResult(errorNum); - } - } - return SyscallResult(0); -} - -template -int Debug::syscallError(Call&& call, bool nonblocking) { - while (call() < 0) { - int errorNum = getOsErrorNumber(nonblocking); - // getOsErrorNumber() returns -1 to indicate EINTR. - // Also, if nonblocking is true, then it returns 0 on EAGAIN, which will then be treated as a - // non-error. - if (errorNum != -1) { - return errorNum; - } - } - return 0; -} - -template -String Debug::makeDescription(const char* macroArgs, Params&&... params) { - String argValues[sizeof...(Params)] = {str(params)...}; - return makeDescriptionInternal(macroArgs, arrayPtr(argValues, sizeof...(Params))); -} - -template <> -inline String Debug::makeDescription<>(const char* macroArgs) { - return makeDescriptionInternal(macroArgs, nullptr); -} - -} // namespace _ (private) -} // namespace kj - -#endif // KJ_DEBUG_H_ diff --git a/phonelibs/capnp-cpp/include/kj/exception.h b/phonelibs/capnp-cpp/include/kj/exception.h deleted file mode 100644 index f6c0b2daa61eeb..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/exception.h +++ /dev/null @@ -1,363 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_EXCEPTION_H_ -#define KJ_EXCEPTION_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "memory.h" -#include "array.h" -#include "string.h" - -namespace kj { - -class ExceptionImpl; - -class Exception { - // Exception thrown in case of fatal errors. - // - // Actually, a subclass of this which also implements std::exception will be thrown, but we hide - // that fact from the interface to avoid #including . - -public: - enum class Type { - // What kind of failure? - - FAILED = 0, - // Something went wrong. This is the usual error type. KJ_ASSERT and KJ_REQUIRE throw this - // error type. - - OVERLOADED = 1, - // The call failed because of a temporary lack of resources. This could be space resources - // (out of memory, out of disk space) or time resources (request queue overflow, operation - // timed out). - // - // The operation might work if tried again, but it should NOT be repeated immediately as this - // may simply exacerbate the problem. - - DISCONNECTED = 2, - // The call required communication over a connection that has been lost. The callee will need - // to re-establish connections and try again. - - UNIMPLEMENTED = 3 - // The requested method is not implemented. The caller may wish to revert to a fallback - // approach based on other methods. - - // IF YOU ADD A NEW VALUE: - // - Update the stringifier. - // - Update Cap'n Proto's RPC protocol's Exception.Type enum. - }; - - Exception(Type type, const char* file, int line, String description = nullptr) noexcept; - Exception(Type type, String file, int line, String description = nullptr) noexcept; - Exception(const Exception& other) noexcept; - Exception(Exception&& other) = default; - ~Exception() noexcept; - - const char* getFile() const { return file; } - int getLine() const { return line; } - Type getType() const { return type; } - StringPtr getDescription() const { return description; } - ArrayPtr getStackTrace() const { return arrayPtr(trace, traceCount); } - - struct Context { - // Describes a bit about what was going on when the exception was thrown. - - const char* file; - int line; - String description; - Maybe> next; - - Context(const char* file, int line, String&& description, Maybe>&& next) - : file(file), line(line), description(mv(description)), next(mv(next)) {} - Context(const Context& other) noexcept; - }; - - inline Maybe getContext() const { - KJ_IF_MAYBE(c, context) { - return **c; - } else { - return nullptr; - } - } - - void wrapContext(const char* file, int line, String&& description); - // Wraps the context in a new node. This becomes the head node returned by getContext() -- it - // is expected that contexts will be added in reverse order as the exception passes up the - // callback stack. - - KJ_NOINLINE void extendTrace(uint ignoreCount); - // Append the current stack trace to the exception's trace, ignoring the first `ignoreCount` - // frames (see `getStackTrace()` for discussion of `ignoreCount`). - - KJ_NOINLINE void truncateCommonTrace(); - // Remove the part of the stack trace which the exception shares with the caller of this method. - // This is used by the async library to remove the async infrastructure from the stack trace - // before replacing it with the async trace. - - void addTrace(void* ptr); - // Append the given pointer to the backtrace, if it is not already full. This is used by the - // async library to trace through the promise chain that led to the exception. - -private: - String ownFile; - const char* file; - int line; - Type type; - String description; - Maybe> context; - void* trace[32]; - uint traceCount; - - friend class ExceptionImpl; -}; - -StringPtr KJ_STRINGIFY(Exception::Type type); -String KJ_STRINGIFY(const Exception& e); - -// ======================================================================================= - -enum class LogSeverity { - INFO, // Information describing what the code is up to, which users may request to see - // with a flag like `--verbose`. Does not indicate a problem. Not printed by - // default; you must call setLogLevel(INFO) to enable. - WARNING, // A problem was detected but execution can continue with correct output. - ERROR, // Something is wrong, but execution can continue with garbage output. - FATAL, // Something went wrong, and execution cannot continue. - DBG // Temporary debug logging. See KJ_DBG. - - // Make sure to update the stringifier if you add a new severity level. -}; - -StringPtr KJ_STRINGIFY(LogSeverity severity); - -class ExceptionCallback { - // If you don't like C++ exceptions, you may implement and register an ExceptionCallback in order - // to perform your own exception handling. For example, a reasonable thing to do is to have - // onRecoverableException() set a flag indicating that an error occurred, and then check for that - // flag just before writing to storage and/or returning results to the user. If the flag is set, - // discard whatever you have and return an error instead. - // - // ExceptionCallbacks must always be allocated on the stack. When an exception is thrown, the - // newest ExceptionCallback on the calling thread's stack is called. The default implementation - // of each method calls the next-oldest ExceptionCallback for that thread. Thus the callbacks - // behave a lot like try/catch blocks, except that they are called before any stack unwinding - // occurs. - -public: - ExceptionCallback(); - KJ_DISALLOW_COPY(ExceptionCallback); - virtual ~ExceptionCallback() noexcept(false); - - virtual void onRecoverableException(Exception&& exception); - // Called when an exception has been raised, but the calling code has the ability to continue by - // producing garbage output. This method _should_ throw the exception, but is allowed to simply - // return if garbage output is acceptable. - // - // The global default implementation throws an exception unless the library was compiled with - // -fno-exceptions, in which case it logs an error and returns. - - virtual void onFatalException(Exception&& exception); - // Called when an exception has been raised and the calling code cannot continue. If this method - // returns normally, abort() will be called. The method must throw the exception to avoid - // aborting. - // - // The global default implementation throws an exception unless the library was compiled with - // -fno-exceptions, in which case it logs an error and returns. - - virtual void logMessage(LogSeverity severity, const char* file, int line, int contextDepth, - String&& text); - // Called when something wants to log some debug text. `contextDepth` indicates how many levels - // of context the message passed through; it may make sense to indent the message accordingly. - // - // The global default implementation writes the text to stderr. - - enum class StackTraceMode { - FULL, - // Stringifying a stack trace will attempt to determine source file and line numbers. This may - // be expensive. For example, on Linux, this shells out to `addr2line`. - // - // This is the default in debug builds. - - ADDRESS_ONLY, - // Stringifying a stack trace will only generate a list of code addresses. - // - // This is the default in release builds. - - NONE - // Generating a stack trace will always return an empty array. - // - // This avoids ever unwinding the stack. On Windows in particular, the stack unwinding library - // has been observed to be pretty slow, so exception-heavy code might benefit significantly - // from this setting. (But exceptions should be rare...) - }; - - virtual StackTraceMode stackTraceMode(); - // Returns the current preferred stack trace mode. - -protected: - ExceptionCallback& next; - -private: - ExceptionCallback(ExceptionCallback& next); - - class RootExceptionCallback; - friend ExceptionCallback& getExceptionCallback(); -}; - -ExceptionCallback& getExceptionCallback(); -// Returns the current exception callback. - -KJ_NOINLINE KJ_NORETURN(void throwFatalException(kj::Exception&& exception, uint ignoreCount = 0)); -// Invoke the exception callback to throw the given fatal exception. If the exception callback -// returns, abort. - -KJ_NOINLINE void throwRecoverableException(kj::Exception&& exception, uint ignoreCount = 0); -// Invoke the exception callback to throw the given recoverable exception. If the exception -// callback returns, return normally. - -// ======================================================================================= - -namespace _ { class Runnable; } - -template -Maybe runCatchingExceptions(Func&& func) noexcept; -// Executes the given function (usually, a lambda returning nothing) catching any exceptions that -// are thrown. Returns the Exception if there was one, or null if the operation completed normally. -// Non-KJ exceptions will be wrapped. -// -// If exception are disabled (e.g. with -fno-exceptions), this will still detect whether any -// recoverable exceptions occurred while running the function and will return those. - -class UnwindDetector { - // Utility for detecting when a destructor is called due to unwind. Useful for: - // - Avoiding throwing exceptions in this case, which would terminate the program. - // - Detecting whether to commit or roll back a transaction. - // - // To use this class, either inherit privately from it or declare it as a member. The detector - // works by comparing the exception state against that when the constructor was called, so for - // an object that was actually constructed during exception unwind, it will behave as if no - // unwind is taking place. This is usually the desired behavior. - -public: - UnwindDetector(); - - bool isUnwinding() const; - // Returns true if the current thread is in a stack unwind that it wasn't in at the time the - // object was constructed. - - template - void catchExceptionsIfUnwinding(Func&& func) const; - // Runs the given function (e.g., a lambda). If isUnwinding() is true, any exceptions are - // caught and treated as secondary faults, meaning they are considered to be side-effects of the - // exception that is unwinding the stack. Otherwise, exceptions are passed through normally. - -private: - uint uncaughtCount; - - void catchExceptionsAsSecondaryFaults(_::Runnable& runnable) const; -}; - -namespace _ { // private - -class Runnable { -public: - virtual void run() = 0; -}; - -template -class RunnableImpl: public Runnable { -public: - RunnableImpl(Func&& func): func(kj::mv(func)) {} - void run() override { - func(); - } -private: - Func func; -}; - -Maybe runCatchingExceptions(Runnable& runnable) noexcept; - -} // namespace _ (private) - -template -Maybe runCatchingExceptions(Func&& func) noexcept { - _::RunnableImpl> runnable(kj::fwd(func)); - return _::runCatchingExceptions(runnable); -} - -template -void UnwindDetector::catchExceptionsIfUnwinding(Func&& func) const { - if (isUnwinding()) { - _::RunnableImpl> runnable(kj::fwd(func)); - catchExceptionsAsSecondaryFaults(runnable); - } else { - func(); - } -} - -#define KJ_ON_SCOPE_SUCCESS(code) \ - ::kj::UnwindDetector KJ_UNIQUE_NAME(_kjUnwindDetector); \ - KJ_DEFER(if (!KJ_UNIQUE_NAME(_kjUnwindDetector).isUnwinding()) { code; }) -// Runs `code` if the current scope is exited normally (not due to an exception). - -#define KJ_ON_SCOPE_FAILURE(code) \ - ::kj::UnwindDetector KJ_UNIQUE_NAME(_kjUnwindDetector); \ - KJ_DEFER(if (KJ_UNIQUE_NAME(_kjUnwindDetector).isUnwinding()) { code; }) -// Runs `code` if the current scope is exited due to an exception. - -// ======================================================================================= - -KJ_NOINLINE ArrayPtr getStackTrace(ArrayPtr space, uint ignoreCount); -// Attempt to get the current stack trace, returning a list of pointers to instructions. The -// returned array is a slice of `space`. Provide a larger `space` to get a deeper stack trace. -// If the platform doesn't support stack traces, returns an empty array. -// -// `ignoreCount` items will be truncated from the front of the trace. This is useful for chopping -// off a prefix of the trace that is uninteresting to the developer because it's just locations -// inside the debug infrastructure that is requesting the trace. Be careful to mark functions as -// KJ_NOINLINE if you intend to count them in `ignoreCount`. Note that, unfortunately, the -// ignored entries will still waste space in the `space` array (and the returned array's `begin()` -// is never exactly equal to `space.begin()` due to this effect, even if `ignoreCount` is zero -// since `getStackTrace()` needs to ignore its own internal frames). - -String stringifyStackTrace(ArrayPtr); -// Convert the stack trace to a string with file names and line numbers. This may involve executing -// suprocesses. - -String getStackTrace(); -// Get a stack trace right now and stringify it. Useful for debugging. - -void printStackTraceOnCrash(); -// Registers signal handlers on common "crash" signals like SIGSEGV that will (attempt to) print -// a stack trace. You should call this as early as possible on program startup. Programs using -// KJ_MAIN get this automatically. - -kj::StringPtr trimSourceFilename(kj::StringPtr filename); -// Given a source code file name, trim off noisy prefixes like "src/" or -// "/ekam-provider/canonical/". - -} // namespace kj - -#endif // KJ_EXCEPTION_H_ diff --git a/phonelibs/capnp-cpp/include/kj/function.h b/phonelibs/capnp-cpp/include/kj/function.h deleted file mode 100644 index ba6601b560cd8e..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/function.h +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_FUNCTION_H_ -#define KJ_FUNCTION_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "memory.h" - -namespace kj { - -template -class Function; -// Function wrapper using virtual-based polymorphism. Use this when template polymorphism is -// not possible. You can, for example, accept a Function as a parameter: -// -// void setFilter(Function filter); -// -// The caller of `setFilter()` may then pass any callable object as the parameter. The callable -// object does not have to have the exact signature specified, just one that is "compatible" -- -// i.e. the return type is covariant and the parameters are contravariant. -// -// Unlike `std::function`, `kj::Function`s are movable but not copyable, just like `kj::Own`. This -// is to avoid unexpected heap allocation or slow atomic reference counting. -// -// When a `Function` is constructed from an lvalue, it captures only a reference to the value. -// When constructed from an rvalue, it invokes the value's move constructor. So, for example: -// -// struct AddN { -// int n; -// int operator(int i) { return i + n; } -// } -// -// Function f1 = AddN{2}; -// // f1 owns an instance of AddN. It may safely be moved out -// // of the local scope. -// -// AddN adder(2); -// Function f2 = adder; -// // f2 contains a reference to `adder`. Thus, it becomes invalid -// // when `adder` goes out-of-scope. -// -// AddN adder2(2); -// Function f3 = kj::mv(adder2); -// // f3 owns an insatnce of AddN moved from `adder2`. f3 may safely -// // be moved out of the local scope. -// -// Additionally, a Function may be bound to a class method using KJ_BIND_METHOD(object, methodName). -// For example: -// -// class Printer { -// public: -// void print(int i); -// void print(kj::StringPtr s); -// }; -// -// Printer p; -// -// Function intPrinter = KJ_BIND_METHOD(p, print); -// // Will call Printer::print(int). -// -// Function strPrinter = KJ_BIND_METHOD(p, print); -// // Will call Printer::print(kj::StringPtr). -// -// Notice how KJ_BIND_METHOD is able to figure out which overload to use depending on the kind of -// Function it is binding to. - -template -class ConstFunction; -// Like Function, but wraps a "const" (i.e. thread-safe) call. - -template -class Function { -public: - template - inline Function(F&& f): impl(heap>(kj::fwd(f))) {} - Function() = default; - - // Make sure people don't accidentally end up wrapping a reference when they meant to return - // a function. - KJ_DISALLOW_COPY(Function); - Function(Function&) = delete; - Function& operator=(Function&) = delete; - template Function(const Function&) = delete; - template Function& operator=(const Function&) = delete; - template Function(const ConstFunction&) = delete; - template Function& operator=(const ConstFunction&) = delete; - Function(Function&&) = default; - Function& operator=(Function&&) = default; - - inline Return operator()(Params... params) { - return (*impl)(kj::fwd(params)...); - } - - Function reference() { - // Forms a new Function of the same type that delegates to this Function by reference. - // Therefore, this Function must outlive the returned Function, but otherwise they behave - // exactly the same. - - return *impl; - } - -private: - class Iface { - public: - virtual Return operator()(Params... params) = 0; - }; - - template - class Impl final: public Iface { - public: - explicit Impl(F&& f): f(kj::fwd(f)) {} - - Return operator()(Params... params) override { - return f(kj::fwd(params)...); - } - - private: - F f; - }; - - Own impl; -}; - -template -class ConstFunction { -public: - template - inline ConstFunction(F&& f): impl(heap>(kj::fwd(f))) {} - ConstFunction() = default; - - // Make sure people don't accidentally end up wrapping a reference when they meant to return - // a function. - KJ_DISALLOW_COPY(ConstFunction); - ConstFunction(ConstFunction&) = delete; - ConstFunction& operator=(ConstFunction&) = delete; - template ConstFunction(const ConstFunction&) = delete; - template ConstFunction& operator=(const ConstFunction&) = delete; - template ConstFunction(const Function&) = delete; - template ConstFunction& operator=(const Function&) = delete; - ConstFunction(ConstFunction&&) = default; - ConstFunction& operator=(ConstFunction&&) = default; - - inline Return operator()(Params... params) const { - return (*impl)(kj::fwd(params)...); - } - - ConstFunction reference() const { - // Forms a new ConstFunction of the same type that delegates to this ConstFunction by reference. - // Therefore, this ConstFunction must outlive the returned ConstFunction, but otherwise they - // behave exactly the same. - - return *impl; - } - -private: - class Iface { - public: - virtual Return operator()(Params... params) const = 0; - }; - - template - class Impl final: public Iface { - public: - explicit Impl(F&& f): f(kj::fwd(f)) {} - - Return operator()(Params... params) const override { - return f(kj::fwd(params)...); - } - - private: - F f; - }; - - Own impl; -}; - -#if 1 - -namespace _ { // private - -template -class BoundMethod; - -template ::*method)(Params...)> -class BoundMethod::*)(Params...), method> { -public: - BoundMethod(T&& t): t(kj::fwd(t)) {} - - Return operator()(Params&&... params) { - return (t.*method)(kj::fwd(params)...); - } - -private: - T t; -}; - -template ::*method)(Params...) const> -class BoundMethod::*)(Params...) const, method> { -public: - BoundMethod(T&& t): t(kj::fwd(t)) {} - - Return operator()(Params&&... params) const { - return (t.*method)(kj::fwd(params)...); - } - -private: - T t; -}; - -} // namespace _ (private) - -#define KJ_BIND_METHOD(obj, method) \ - ::kj::_::BoundMethod::method), \ - &::kj::Decay::method>(obj) -// Macro that produces a functor object which forwards to the method `obj.name`. If `obj` is an -// lvalue, the functor will hold a reference to it. If `obj` is an rvalue, the functor will -// contain a copy (by move) of it. -// -// The current implementation requires that the method is not overloaded. -// -// TODO(someday): C++14's generic lambdas may be able to simplify this code considerably, and -// probably make it work with overloaded methods. - -#else -// Here's a better implementation of the above that doesn't work with GCC (but does with Clang) -// because it uses a local class with a template method. Sigh. This implementation supports -// overloaded methods. - -#define KJ_BIND_METHOD(obj, method) \ - ({ \ - typedef KJ_DECLTYPE_REF(obj) T; \ - class F { \ - public: \ - inline F(T&& t): t(::kj::fwd(t)) {} \ - template \ - auto operator()(Params&&... params) \ - -> decltype(::kj::instance().method(::kj::fwd(params)...)) { \ - return t.method(::kj::fwd(params)...); \ - } \ - private: \ - T t; \ - }; \ - (F(obj)); \ - }) -// Macro that produces a functor object which forwards to the method `obj.name`. If `obj` is an -// lvalue, the functor will hold a reference to it. If `obj` is an rvalue, the functor will -// contain a copy (by move) of it. - -#endif - -} // namespace kj - -#endif // KJ_FUNCTION_H_ diff --git a/phonelibs/capnp-cpp/include/kj/io.h b/phonelibs/capnp-cpp/include/kj/io.h deleted file mode 100644 index f5c03bfe7b8a39..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/io.h +++ /dev/null @@ -1,419 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_IO_H_ -#define KJ_IO_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include -#include "common.h" -#include "array.h" -#include "exception.h" - -namespace kj { - -// ======================================================================================= -// Abstract interfaces - -class InputStream { -public: - virtual ~InputStream() noexcept(false); - - size_t read(void* buffer, size_t minBytes, size_t maxBytes); - // Reads at least minBytes and at most maxBytes, copying them into the given buffer. Returns - // the size read. Throws an exception on errors. Implemented in terms of tryRead(). - // - // maxBytes is the number of bytes the caller really wants, but minBytes is the minimum amount - // needed by the caller before it can start doing useful processing. If the stream returns less - // than maxBytes, the caller will usually call read() again later to get the rest. Returning - // less than maxBytes is useful when it makes sense for the caller to parallelize processing - // with I/O. - // - // Never blocks if minBytes is zero. If minBytes is zero and maxBytes is non-zero, this may - // attempt a non-blocking read or may just return zero. To force a read, use a non-zero minBytes. - // To detect EOF without throwing an exception, use tryRead(). - // - // If the InputStream can't produce minBytes, it MUST throw an exception, as the caller is not - // expected to understand how to deal with partial reads. - - virtual size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) = 0; - // Like read(), but may return fewer than minBytes on EOF. - - inline void read(void* buffer, size_t bytes) { read(buffer, bytes, bytes); } - // Convenience method for reading an exact number of bytes. - - virtual void skip(size_t bytes); - // Skips past the given number of bytes, discarding them. The default implementation read()s - // into a scratch buffer. -}; - -class OutputStream { -public: - virtual ~OutputStream() noexcept(false); - - virtual void write(const void* buffer, size_t size) = 0; - // Always writes the full size. Throws exception on error. - - virtual void write(ArrayPtr> pieces); - // Equivalent to write()ing each byte array in sequence, which is what the default implementation - // does. Override if you can do something better, e.g. use writev() to do the write in a single - // syscall. -}; - -class BufferedInputStream: public InputStream { - // An input stream which buffers some bytes in memory to reduce system call overhead. - // - OR - - // An input stream that actually reads from some in-memory data structure and wants to give its - // caller a direct pointer to that memory to potentially avoid a copy. - -public: - virtual ~BufferedInputStream() noexcept(false); - - ArrayPtr getReadBuffer(); - // Get a direct pointer into the read buffer, which contains the next bytes in the input. If the - // caller consumes any bytes, it should then call skip() to indicate this. This always returns a - // non-empty buffer or throws an exception. Implemented in terms of tryGetReadBuffer(). - - virtual ArrayPtr tryGetReadBuffer() = 0; - // Like getReadBuffer() but may return an empty buffer on EOF. -}; - -class BufferedOutputStream: public OutputStream { - // An output stream which buffers some bytes in memory to reduce system call overhead. - // - OR - - // An output stream that actually writes into some in-memory data structure and wants to give its - // caller a direct pointer to that memory to potentially avoid a copy. - -public: - virtual ~BufferedOutputStream() noexcept(false); - - virtual ArrayPtr getWriteBuffer() = 0; - // Get a direct pointer into the write buffer. The caller may choose to fill in some prefix of - // this buffer and then pass it to write(), in which case write() may avoid a copy. It is - // incorrect to pass to write any slice of this buffer which is not a prefix. -}; - -// ======================================================================================= -// Buffered streams implemented as wrappers around regular streams - -class BufferedInputStreamWrapper: public BufferedInputStream { - // Implements BufferedInputStream in terms of an InputStream. - // - // Note that the underlying stream's position is unpredictable once the wrapper is destroyed, - // unless the entire stream was consumed. To read a predictable number of bytes in a buffered - // way without going over, you'd need this wrapper to wrap some other wrapper which itself - // implements an artificial EOF at the desired point. Such a stream should be trivial to write - // but is not provided by the library at this time. - -public: - explicit BufferedInputStreamWrapper(InputStream& inner, ArrayPtr buffer = nullptr); - // Creates a buffered stream wrapping the given non-buffered stream. No guarantee is made about - // the position of the inner stream after a buffered wrapper has been created unless the entire - // input is read. - // - // If the second parameter is non-null, the stream uses the given buffer instead of allocating - // its own. This may improve performance if the buffer can be reused. - - KJ_DISALLOW_COPY(BufferedInputStreamWrapper); - ~BufferedInputStreamWrapper() noexcept(false); - - // implements BufferedInputStream ---------------------------------- - ArrayPtr tryGetReadBuffer() override; - size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; - void skip(size_t bytes) override; - -private: - InputStream& inner; - Array ownedBuffer; - ArrayPtr buffer; - ArrayPtr bufferAvailable; -}; - -class BufferedOutputStreamWrapper: public BufferedOutputStream { - // Implements BufferedOutputStream in terms of an OutputStream. Note that writes to the - // underlying stream may be delayed until flush() is called or the wrapper is destroyed. - -public: - explicit BufferedOutputStreamWrapper(OutputStream& inner, ArrayPtr buffer = nullptr); - // Creates a buffered stream wrapping the given non-buffered stream. - // - // If the second parameter is non-null, the stream uses the given buffer instead of allocating - // its own. This may improve performance if the buffer can be reused. - - KJ_DISALLOW_COPY(BufferedOutputStreamWrapper); - ~BufferedOutputStreamWrapper() noexcept(false); - - void flush(); - // Force the wrapper to write any remaining bytes in its buffer to the inner stream. Note that - // this only flushes this object's buffer; this object has no idea how to flush any other buffers - // that may be present in the underlying stream. - - // implements BufferedOutputStream --------------------------------- - ArrayPtr getWriteBuffer() override; - void write(const void* buffer, size_t size) override; - -private: - OutputStream& inner; - Array ownedBuffer; - ArrayPtr buffer; - byte* bufferPos; - UnwindDetector unwindDetector; -}; - -// ======================================================================================= -// Array I/O - -class ArrayInputStream: public BufferedInputStream { -public: - explicit ArrayInputStream(ArrayPtr array); - KJ_DISALLOW_COPY(ArrayInputStream); - ~ArrayInputStream() noexcept(false); - - // implements BufferedInputStream ---------------------------------- - ArrayPtr tryGetReadBuffer() override; - size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; - void skip(size_t bytes) override; - -private: - ArrayPtr array; -}; - -class ArrayOutputStream: public BufferedOutputStream { -public: - explicit ArrayOutputStream(ArrayPtr array); - KJ_DISALLOW_COPY(ArrayOutputStream); - ~ArrayOutputStream() noexcept(false); - - ArrayPtr getArray() { - // Get the portion of the array which has been filled in. - return arrayPtr(array.begin(), fillPos); - } - - // implements BufferedInputStream ---------------------------------- - ArrayPtr getWriteBuffer() override; - void write(const void* buffer, size_t size) override; - -private: - ArrayPtr array; - byte* fillPos; -}; - -class VectorOutputStream: public BufferedOutputStream { -public: - explicit VectorOutputStream(size_t initialCapacity = 4096); - KJ_DISALLOW_COPY(VectorOutputStream); - ~VectorOutputStream() noexcept(false); - - ArrayPtr getArray() { - // Get the portion of the array which has been filled in. - return arrayPtr(vector.begin(), fillPos); - } - - // implements BufferedInputStream ---------------------------------- - ArrayPtr getWriteBuffer() override; - void write(const void* buffer, size_t size) override; - -private: - Array vector; - byte* fillPos; - - void grow(size_t minSize); -}; - -// ======================================================================================= -// File descriptor I/O - -class AutoCloseFd { - // A wrapper around a file descriptor which automatically closes the descriptor when destroyed. - // The wrapper supports move construction for transferring ownership of the descriptor. If - // close() returns an error, the destructor throws an exception, UNLESS the destructor is being - // called during unwind from another exception, in which case the close error is ignored. - // - // If your code is not exception-safe, you should not use AutoCloseFd. In this case you will - // have to call close() yourself and handle errors appropriately. - -public: - inline AutoCloseFd(): fd(-1) {} - inline AutoCloseFd(decltype(nullptr)): fd(-1) {} - inline explicit AutoCloseFd(int fd): fd(fd) {} - inline AutoCloseFd(AutoCloseFd&& other) noexcept: fd(other.fd) { other.fd = -1; } - KJ_DISALLOW_COPY(AutoCloseFd); - ~AutoCloseFd() noexcept(false); - - inline AutoCloseFd& operator=(AutoCloseFd&& other) { - AutoCloseFd old(kj::mv(*this)); - fd = other.fd; - other.fd = -1; - return *this; - } - - inline AutoCloseFd& operator=(decltype(nullptr)) { - AutoCloseFd old(kj::mv(*this)); - return *this; - } - - inline operator int() const { return fd; } - inline int get() const { return fd; } - - operator bool() const = delete; - // Deleting this operator prevents accidental use in boolean contexts, which - // the int conversion operator above would otherwise allow. - - inline bool operator==(decltype(nullptr)) { return fd < 0; } - inline bool operator!=(decltype(nullptr)) { return fd >= 0; } - -private: - int fd; - UnwindDetector unwindDetector; -}; - -inline auto KJ_STRINGIFY(const AutoCloseFd& fd) - -> decltype(kj::toCharSequence(implicitCast(fd))) { - return kj::toCharSequence(implicitCast(fd)); -} - -class FdInputStream: public InputStream { - // An InputStream wrapping a file descriptor. - -public: - explicit FdInputStream(int fd): fd(fd) {} - explicit FdInputStream(AutoCloseFd fd): fd(fd), autoclose(mv(fd)) {} - KJ_DISALLOW_COPY(FdInputStream); - ~FdInputStream() noexcept(false); - - size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; - - inline int getFd() const { return fd; } - -private: - int fd; - AutoCloseFd autoclose; -}; - -class FdOutputStream: public OutputStream { - // An OutputStream wrapping a file descriptor. - -public: - explicit FdOutputStream(int fd): fd(fd) {} - explicit FdOutputStream(AutoCloseFd fd): fd(fd), autoclose(mv(fd)) {} - KJ_DISALLOW_COPY(FdOutputStream); - ~FdOutputStream() noexcept(false); - - void write(const void* buffer, size_t size) override; - void write(ArrayPtr> pieces) override; - - inline int getFd() const { return fd; } - -private: - int fd; - AutoCloseFd autoclose; -}; - -// ======================================================================================= -// Win32 Handle I/O - -#ifdef _WIN32 - -class AutoCloseHandle { - // A wrapper around a Win32 HANDLE which automatically closes the handle when destroyed. - // The wrapper supports move construction for transferring ownership of the handle. If - // CloseHandle() returns an error, the destructor throws an exception, UNLESS the destructor is - // being called during unwind from another exception, in which case the close error is ignored. - // - // If your code is not exception-safe, you should not use AutoCloseHandle. In this case you will - // have to call close() yourself and handle errors appropriately. - -public: - inline AutoCloseHandle(): handle((void*)-1) {} - inline AutoCloseHandle(decltype(nullptr)): handle((void*)-1) {} - inline explicit AutoCloseHandle(void* handle): handle(handle) {} - inline AutoCloseHandle(AutoCloseHandle&& other) noexcept: handle(other.handle) { - other.handle = (void*)-1; - } - KJ_DISALLOW_COPY(AutoCloseHandle); - ~AutoCloseHandle() noexcept(false); - - inline AutoCloseHandle& operator=(AutoCloseHandle&& other) { - AutoCloseHandle old(kj::mv(*this)); - handle = other.handle; - other.handle = (void*)-1; - return *this; - } - - inline AutoCloseHandle& operator=(decltype(nullptr)) { - AutoCloseHandle old(kj::mv(*this)); - return *this; - } - - inline operator void*() const { return handle; } - inline void* get() const { return handle; } - - operator bool() const = delete; - // Deleting this operator prevents accidental use in boolean contexts, which - // the void* conversion operator above would otherwise allow. - - inline bool operator==(decltype(nullptr)) { return handle != (void*)-1; } - inline bool operator!=(decltype(nullptr)) { return handle == (void*)-1; } - -private: - void* handle; // -1 (aka INVALID_HANDLE_VALUE) if not valid. -}; - -class HandleInputStream: public InputStream { - // An InputStream wrapping a Win32 HANDLE. - -public: - explicit HandleInputStream(void* handle): handle(handle) {} - explicit HandleInputStream(AutoCloseHandle handle): handle(handle), autoclose(mv(handle)) {} - KJ_DISALLOW_COPY(HandleInputStream); - ~HandleInputStream() noexcept(false); - - size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override; - -private: - void* handle; - AutoCloseHandle autoclose; -}; - -class HandleOutputStream: public OutputStream { - // An OutputStream wrapping a Win32 HANDLE. - -public: - explicit HandleOutputStream(void* handle): handle(handle) {} - explicit HandleOutputStream(AutoCloseHandle handle): handle(handle), autoclose(mv(handle)) {} - KJ_DISALLOW_COPY(HandleOutputStream); - ~HandleOutputStream() noexcept(false); - - void write(const void* buffer, size_t size) override; - -private: - void* handle; - AutoCloseHandle autoclose; -}; - -#endif // _WIN32 - -} // namespace kj - -#endif // KJ_IO_H_ diff --git a/phonelibs/capnp-cpp/include/kj/main.h b/phonelibs/capnp-cpp/include/kj/main.h deleted file mode 100644 index 4dcd804fd4d224..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/main.h +++ /dev/null @@ -1,407 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_MAIN_H_ -#define KJ_MAIN_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "array.h" -#include "string.h" -#include "vector.h" -#include "function.h" - -namespace kj { - -class ProcessContext { - // Context for command-line programs. - -public: - virtual StringPtr getProgramName() = 0; - // Get argv[0] as passed to main(). - - KJ_NORETURN(virtual void exit()) = 0; - // Indicates program completion. The program is considered successful unless `error()` was - // called. Typically this exits with _Exit(), meaning that the stack is not unwound, buffers - // are not flushed, etc. -- it is the responsibility of the caller to flush any buffers that - // matter. However, an alternate context implementation e.g. for unit testing purposes could - // choose to throw an exception instead. - // - // At first this approach may sound crazy. Isn't it much better to shut down cleanly? What if - // you lose data? However, it turns out that if you look at each common class of program, _Exit() - // is almost always preferable. Let's break it down: - // - // * Commands: A typical program you might run from the command line is single-threaded and - // exits quickly and deterministically. Commands often use buffered I/O and need to flush - // those buffers before exit. However, most of the work performed by destructors is not - // flushing buffers, but rather freeing up memory, placing objects into freelists, and closing - // file descriptors. All of this is irrelevant if the process is about to exit anyway, and - // for a command that runs quickly, time wasted freeing heap space may make a real difference - // in the overall runtime of a script. Meanwhile, it is usually easy to determine exactly what - // resources need to be flushed before exit, and easy to tell if they are not being flushed - // (because the command fails to produce the expected output). Therefore, it is reasonably - // easy for commands to explicitly ensure all output is flushed before exiting, and it is - // probably a good idea for them to do so anyway, because write failures should be detected - // and handled. For commands, a good strategy is to allocate any objects that require clean - // destruction on the stack, and allow them to go out of scope before the command exits. - // Meanwhile, any resources which do not need to be cleaned up should be allocated as members - // of the command's main class, whose destructor normally will not be called. - // - // * Interactive apps: Programs that interact with the user (whether they be graphical apps - // with windows or console-based apps like emacs) generally exit only when the user asks them - // to. Such applications may store large data structures in memory which need to be synced - // to disk, such as documents or user preferences. However, relying on stack unwind or global - // destructors as the mechanism for ensuring such syncing occurs is probably wrong. First of - // all, it's 2013, and applications ought to be actively syncing changes to non-volatile - // storage the moment those changes are made. Applications can crash at any time and a crash - // should never lose data that is more than half a second old. Meanwhile, if a user actually - // does try to close an application while unsaved changes exist, the application UI should - // prompt the user to decide what to do. Such a UI mechanism is obviously too high level to - // be implemented via destructors, so KJ's use of _Exit() shouldn't make a difference here. - // - // * Servers: A good server is fault-tolerant, prepared for the possibility that at any time - // it could crash, the OS could decide to kill it off, or the machine it is running on could - // just die. So, using _Exit() should be no problem. In fact, servers generally never even - // call exit anyway; they are killed externally. - // - // * Batch jobs: A long-running batch job is something between a command and a server. It - // probably knows exactly what needs to be flushed before exiting, and it probably should be - // fault-tolerant. - // - // Meanwhile, regardless of program type, if you are adhering to KJ style, then the use of - // _Exit() shouldn't be a problem anyway: - // - // * KJ style forbids global mutable state (singletons) in general and global constructors and - // destructors in particular. Therefore, everything that could possibly need cleanup either - // lives on the stack or is transitively owned by something living on the stack. - // - // * Calling exit() simply means "Don't clean up anything older than this stack frame.". If you - // have resources that require cleanup before exit, make sure they are owned by stack frames - // beyond the one that eventually calls exit(). To be as safe as possible, don't place any - // state in your program's main class, and don't call exit() yourself. Then, runMainAndExit() - // will do it, and the only thing on the stack at that time will be your main class, which - // has no state anyway. - // - // TODO(someday): Perhaps we should use the new std::quick_exit(), so that at_quick_exit() is - // available for those who really think they need it. Unfortunately, it is not yet available - // on many platforms. - - virtual void warning(StringPtr message) = 0; - // Print the given message to standard error. A newline is printed after the message if it - // doesn't already have one. - - virtual void error(StringPtr message) = 0; - // Like `warning()`, but also sets a flag indicating that the process has failed, and that when - // it eventually exits it should indicate an error status. - - KJ_NORETURN(virtual void exitError(StringPtr message)) = 0; - // Equivalent to `error(message)` followed by `exit()`. - - KJ_NORETURN(virtual void exitInfo(StringPtr message)) = 0; - // Displays the given non-error message to the user and then calls `exit()`. This is used to - // implement things like --help. - - virtual void increaseLoggingVerbosity() = 0; - // Increase the level of detail produced by the debug logging system. `MainBuilder` invokes - // this if the caller uses the -v flag. - - // TODO(someday): Add interfaces representing standard OS resources like the filesystem, so that - // these things can be mocked out. -}; - -class TopLevelProcessContext final: public ProcessContext { - // A ProcessContext implementation appropriate for use at the actual entry point of a process - // (as opposed to when you are trying to call a program's main function from within some other - // program). This implementation writes errors to stderr, and its `exit()` method actually - // calls the C `quick_exit()` function. - -public: - explicit TopLevelProcessContext(StringPtr programName); - - struct CleanShutdownException { int exitCode; }; - // If the environment variable KJ_CLEAN_SHUTDOWN is set, then exit() will actually throw this - // exception rather than exiting. `kj::runMain()` catches this exception and returns normally. - // This is useful primarily for testing purposes, to assist tools like memory leak checkers that - // are easily confused by quick_exit(). - - StringPtr getProgramName() override; - KJ_NORETURN(void exit() override); - void warning(StringPtr message) override; - void error(StringPtr message) override; - KJ_NORETURN(void exitError(StringPtr message) override); - KJ_NORETURN(void exitInfo(StringPtr message) override); - void increaseLoggingVerbosity() override; - -private: - StringPtr programName; - bool cleanShutdown; - bool hadErrors = false; -}; - -typedef Function params)> MainFunc; - -int runMainAndExit(ProcessContext& context, MainFunc&& func, int argc, char* argv[]); -// Runs the given main function and then exits using the given context. If an exception is thrown, -// this will catch it, report it via the context and exit with an error code. -// -// Normally this function does not return, because returning would probably lead to wasting time -// on cleanup when the process is just going to exit anyway. However, to facilitate memory leak -// checkers and other tools that require a clean shutdown to do their job, if the environment -// variable KJ_CLEAN_SHUTDOWN is set, the function will in fact return an exit code, which should -// then be returned from main(). -// -// Most users will use the KJ_MAIN() macro rather than call this function directly. - -#define KJ_MAIN(MainClass) \ - int main(int argc, char* argv[]) { \ - ::kj::TopLevelProcessContext context(argv[0]); \ - MainClass mainObject(context); \ - return ::kj::runMainAndExit(context, mainObject.getMain(), argc, argv); \ - } -// Convenience macro for declaring a main function based on the given class. The class must have -// a constructor that accepts a ProcessContext& and a method getMain() which returns -// kj::MainFunc (probably building it using a MainBuilder). - -class MainBuilder { - // Builds a main() function with nice argument parsing. As options and arguments are parsed, - // corresponding callbacks are called, so that you never have to write a massive switch() - // statement to interpret arguments. Additionally, this approach encourages you to write - // main classes that have a reasonable API that can be used as an alternative to their - // command-line interface. - // - // All StringPtrs passed to MainBuilder must remain valid until option parsing completes. The - // assumption is that these strings will all be literals, making this an easy requirement. If - // not, consider allocating them in an Arena. - // - // Some flags are automatically recognized by the main functions built by this class: - // --help: Prints help text and exits. The help text is constructed based on the - // information you provide to the builder as you define each flag. - // --verbose: Increase logging verbosity. - // --version: Print version information and exit. - // - // Example usage: - // - // class FooMain { - // public: - // FooMain(kj::ProcessContext& context): context(context) {} - // - // bool setAll() { all = true; return true; } - // // Enable the --all flag. - // - // kj::MainBuilder::Validity setOutput(kj::StringPtr name) { - // // Set the output file. - // - // if (name.endsWith(".foo")) { - // outputFile = name; - // return true; - // } else { - // return "Output file must have extension .foo."; - // } - // } - // - // kj::MainBuilder::Validity processInput(kj::StringPtr name) { - // // Process an input file. - // - // if (!exists(name)) { - // return kj::str(name, ": file not found"); - // } - // // ... process the input file ... - // return true; - // } - // - // kj::MainFunc getMain() { - // return MainBuilder(context, "Foo Builder v1.5", "Reads s and builds a Foo.") - // .addOption({'a', "all"}, KJ_BIND_METHOD(*this, setAll), - // "Frob all the widgets. Otherwise, only some widgets are frobbed.") - // .addOptionWithArg({'o', "output"}, KJ_BIND_METHOD(*this, setOutput), - // "", "Output to . Must be a .foo file.") - // .expectOneOrMoreArgs("", KJ_BIND_METHOD(*this, processInput)) - // .build(); - // } - // - // private: - // bool all = false; - // kj::StringPtr outputFile; - // kj::ProcessContext& context; - // }; - -public: - MainBuilder(ProcessContext& context, StringPtr version, - StringPtr briefDescription, StringPtr extendedDescription = nullptr); - ~MainBuilder() noexcept(false); - - class OptionName { - public: - OptionName() = default; - inline OptionName(char shortName): isLong(false), shortName(shortName) {} - inline OptionName(const char* longName): isLong(true), longName(longName) {} - - private: - bool isLong; - union { - char shortName; - const char* longName; - }; - friend class MainBuilder; - }; - - class Validity { - public: - inline Validity(bool valid) { - if (!valid) errorMessage = heapString("invalid argument"); - } - inline Validity(const char* errorMessage) - : errorMessage(heapString(errorMessage)) {} - inline Validity(String&& errorMessage) - : errorMessage(kj::mv(errorMessage)) {} - - inline const Maybe& getError() const { return errorMessage; } - inline Maybe releaseError() { return kj::mv(errorMessage); } - - private: - Maybe errorMessage; - friend class MainBuilder; - }; - - MainBuilder& addOption(std::initializer_list names, Function callback, - StringPtr helpText); - // Defines a new option (flag). `names` is a list of characters and strings that can be used to - // specify the option on the command line. Single-character names are used with "-" while string - // names are used with "--". `helpText` is a natural-language description of the flag. - // - // `callback` is called when the option is seen. Its return value indicates whether the option - // was accepted. If not, further option processing stops, and error is written, and the process - // exits. - // - // Example: - // - // builder.addOption({'a', "all"}, KJ_BIND_METHOD(*this, showAll), "Show all files."); - // - // This option could be specified in the following ways: - // - // -a - // --all - // - // Note that single-character option names can be combined into a single argument. For example, - // `-abcd` is equivalent to `-a -b -c -d`. - // - // The help text for this option would look like: - // - // -a, --all - // Show all files. - // - // Note that help text is automatically word-wrapped. - - MainBuilder& addOptionWithArg(std::initializer_list names, - Function callback, - StringPtr argumentTitle, StringPtr helpText); - // Like `addOption()`, but adds an option which accepts an argument. `argumentTitle` is used in - // the help text. The argument text is passed to the callback. - // - // Example: - // - // builder.addOptionWithArg({'o', "output"}, KJ_BIND_METHOD(*this, setOutput), - // "", "Output to ."); - // - // This option could be specified with an argument of "foo" in the following ways: - // - // -ofoo - // -o foo - // --output=foo - // --output foo - // - // Note that single-character option names can be combined, but only the last option can have an - // argument, since the characters after the option letter are interpreted as the argument. E.g. - // `-abofoo` would be equivalent to `-a -b -o foo`. - // - // The help text for this option would look like: - // - // -o FILENAME, --output=FILENAME - // Output to FILENAME. - - MainBuilder& addSubCommand(StringPtr name, Function getSubParser, - StringPtr briefHelpText); - // If exactly the given name is seen as an argument, invoke getSubParser() and then pass all - // remaining arguments to the parser it returns. This is useful for implementing commands which - // have lots of sub-commands, like "git" (which has sub-commands "checkout", "branch", "pull", - // etc.). - // - // `getSubParser` is only called if the command is seen. This avoids building main functions - // for commands that aren't used. - // - // `briefHelpText` should be brief enough to show immediately after the command name on a single - // line. It will not be wrapped. Users can use the built-in "help" command to get extended - // help on a particular command. - - MainBuilder& expectArg(StringPtr title, Function callback); - MainBuilder& expectOptionalArg(StringPtr title, Function callback); - MainBuilder& expectZeroOrMoreArgs(StringPtr title, Function callback); - MainBuilder& expectOneOrMoreArgs(StringPtr title, Function callback); - // Set callbacks to handle arguments. `expectArg()` and `expectOptionalArg()` specify positional - // arguments with special handling, while `expect{Zero,One}OrMoreArgs()` specifies a handler for - // an argument list (the handler is called once for each argument in the list). `title` - // specifies how the argument should be represented in the usage text. - // - // All options callbacks are called before argument callbacks, regardless of their ordering on - // the command line. This matches GNU getopt's behavior of permuting non-flag arguments to the - // end of the argument list. Also matching getopt, the special option "--" indicates that the - // rest of the command line is all arguments, not options, even if they start with '-'. - // - // The interpretation of positional arguments is fairly flexible. The non-optional arguments can - // be expected at the beginning, end, or in the middle. If more arguments are specified than - // the number of non-optional args, they are assigned to the optional argument handlers in the - // order of registration. - // - // For example, say you called: - // builder.expectArg("", ...); - // builder.expectOptionalArg("", ...); - // builder.expectArg("", ...); - // builder.expectZeroOrMoreArgs("", ...); - // builder.expectArg("", ...); - // - // This command requires at least three arguments: foo, baz, and corge. If four arguments are - // given, the second is assigned to bar. If five or more arguments are specified, then the - // arguments between the third and last are assigned to qux. Note that it never makes sense - // to call `expect*OrMoreArgs()` more than once since only the first call would ever be used. - // - // In practice, you probably shouldn't create such complicated commands as in the above example. - // But, this flexibility seems necessary to support commands where the first argument is special - // as well as commands (like `cp`) where the last argument is special. - - MainBuilder& callAfterParsing(Function callback); - // Call the given function after all arguments have been parsed. - - MainFunc build(); - // Build the "main" function, which simply parses the arguments. Once this returns, the - // `MainBuilder` is no longer valid. - -private: - struct Impl; - Own impl; - - class MainImpl; -}; - -} // namespace kj - -#endif // KJ_MAIN_H_ diff --git a/phonelibs/capnp-cpp/include/kj/memory.h b/phonelibs/capnp-cpp/include/kj/memory.h deleted file mode 100644 index 60912b0a344fce..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/memory.h +++ /dev/null @@ -1,406 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_MEMORY_H_ -#define KJ_MEMORY_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "common.h" - -namespace kj { - -// ======================================================================================= -// Disposer -- Implementation details. - -class Disposer { - // Abstract interface for a thing that "disposes" of objects, where "disposing" usually means - // calling the destructor followed by freeing the underlying memory. `Own` encapsulates an - // object pointer with corresponding Disposer. - // - // Few developers will ever touch this interface. It is primarily useful for those implementing - // custom memory allocators. - -protected: - // Do not declare a destructor, as doing so will force a global initializer for each HeapDisposer - // instance. Eww! - - virtual void disposeImpl(void* pointer) const = 0; - // Disposes of the object, given a pointer to the beginning of the object. If the object is - // polymorphic, this pointer is determined by dynamic_cast(). For non-polymorphic types, - // Own does not allow any casting, so the pointer exactly matches the original one given to - // Own. - -public: - - template - void dispose(T* object) const; - // Helper wrapper around disposeImpl(). - // - // If T is polymorphic, calls `disposeImpl(dynamic_cast(object))`, otherwise calls - // `disposeImpl(implicitCast(object))`. - // - // Callers must not call dispose() on the same pointer twice, even if the first call throws - // an exception. - -private: - template - struct Dispose_; -}; - -template -class DestructorOnlyDisposer: public Disposer { - // A disposer that merely calls the type's destructor and nothing else. - -public: - static const DestructorOnlyDisposer instance; - - void disposeImpl(void* pointer) const override { - reinterpret_cast(pointer)->~T(); - } -}; - -template -const DestructorOnlyDisposer DestructorOnlyDisposer::instance = DestructorOnlyDisposer(); - -class NullDisposer: public Disposer { - // A disposer that does nothing. - -public: - static const NullDisposer instance; - - void disposeImpl(void* pointer) const override {} -}; - -// ======================================================================================= -// Own -- An owned pointer. - -template -class Own { - // A transferrable title to a T. When an Own goes out of scope, the object's Disposer is - // called to dispose of it. An Own can be efficiently passed by move, without relocating the - // underlying object; this transfers ownership. - // - // This is much like std::unique_ptr, except: - // - You cannot release(). An owned object is not necessarily allocated with new (see next - // point), so it would be hard to use release() correctly. - // - The deleter is made polymorphic by virtual call rather than by template. This is much - // more powerful -- it allows the use of custom allocators, freelists, etc. This could - // _almost_ be accomplished with unique_ptr by forcing everyone to use something like - // std::unique_ptr, except that things get hairy in the presence of multiple - // inheritance and upcasting, and anyway if you force everyone to use a custom deleter - // then you've lost any benefit to interoperating with the "standard" unique_ptr. - -public: - KJ_DISALLOW_COPY(Own); - inline Own(): disposer(nullptr), ptr(nullptr) {} - inline Own(Own&& other) noexcept - : disposer(other.disposer), ptr(other.ptr) { other.ptr = nullptr; } - inline Own(Own>&& other) noexcept - : disposer(other.disposer), ptr(other.ptr) { other.ptr = nullptr; } - template ()>> - inline Own(Own&& other) noexcept - : disposer(other.disposer), ptr(other.ptr) { - static_assert(__is_polymorphic(T), - "Casting owned pointers requires that the target type is polymorphic."); - other.ptr = nullptr; - } - inline Own(T* ptr, const Disposer& disposer) noexcept: disposer(&disposer), ptr(ptr) {} - - ~Own() noexcept(false) { dispose(); } - - inline Own& operator=(Own&& other) { - // Move-assingnment operator. - - // Careful, this might own `other`. Therefore we have to transfer the pointers first, then - // dispose. - const Disposer* disposerCopy = disposer; - T* ptrCopy = ptr; - disposer = other.disposer; - ptr = other.ptr; - other.ptr = nullptr; - if (ptrCopy != nullptr) { - disposerCopy->dispose(const_cast*>(ptrCopy)); - } - return *this; - } - - inline Own& operator=(decltype(nullptr)) { - dispose(); - return *this; - } - - template - Own downcast() { - // Downcast the pointer to Own, destroying the original pointer. If this pointer does not - // actually point at an instance of U, the results are undefined (throws an exception in debug - // mode if RTTI is enabled, otherwise you're on your own). - - Own result; - if (ptr != nullptr) { - result.ptr = &kj::downcast(*ptr); - result.disposer = disposer; - ptr = nullptr; - } - return result; - } - -#define NULLCHECK KJ_IREQUIRE(ptr != nullptr, "null Own<> dereference") - inline T* operator->() { NULLCHECK; return ptr; } - inline const T* operator->() const { NULLCHECK; return ptr; } - inline T& operator*() { NULLCHECK; return *ptr; } - inline const T& operator*() const { NULLCHECK; return *ptr; } -#undef NULLCHECK - inline T* get() { return ptr; } - inline const T* get() const { return ptr; } - inline operator T*() { return ptr; } - inline operator const T*() const { return ptr; } - -private: - const Disposer* disposer; // Only valid if ptr != nullptr. - T* ptr; - - inline explicit Own(decltype(nullptr)): disposer(nullptr), ptr(nullptr) {} - - inline bool operator==(decltype(nullptr)) { return ptr == nullptr; } - inline bool operator!=(decltype(nullptr)) { return ptr != nullptr; } - // Only called by Maybe>. - - inline void dispose() { - // Make sure that if an exception is thrown, we are left with a null ptr, so we won't possibly - // dispose again. - T* ptrCopy = ptr; - if (ptrCopy != nullptr) { - ptr = nullptr; - disposer->dispose(const_cast*>(ptrCopy)); - } - } - - template - friend class Own; - friend class Maybe>; -}; - -namespace _ { // private - -template -class OwnOwn { -public: - inline OwnOwn(Own&& value) noexcept: value(kj::mv(value)) {} - - inline Own& operator*() & { return value; } - inline const Own& operator*() const & { return value; } - inline Own&& operator*() && { return kj::mv(value); } - inline const Own&& operator*() const && { return kj::mv(value); } - inline Own* operator->() { return &value; } - inline const Own* operator->() const { return &value; } - inline operator Own*() { return value ? &value : nullptr; } - inline operator const Own*() const { return value ? &value : nullptr; } - -private: - Own value; -}; - -template -OwnOwn readMaybe(Maybe>&& maybe) { return OwnOwn(kj::mv(maybe.ptr)); } -template -Own* readMaybe(Maybe>& maybe) { return maybe.ptr ? &maybe.ptr : nullptr; } -template -const Own* readMaybe(const Maybe>& maybe) { return maybe.ptr ? &maybe.ptr : nullptr; } - -} // namespace _ (private) - -template -class Maybe> { -public: - inline Maybe(): ptr(nullptr) {} - inline Maybe(Own&& t) noexcept: ptr(kj::mv(t)) {} - inline Maybe(Maybe&& other) noexcept: ptr(kj::mv(other.ptr)) {} - - template - inline Maybe(Maybe>&& other): ptr(mv(other.ptr)) {} - template - inline Maybe(Own&& other): ptr(mv(other)) {} - - inline Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} - - inline operator Maybe() { return ptr.get(); } - inline operator Maybe() const { return ptr.get(); } - - inline Maybe& operator=(Maybe&& other) { ptr = kj::mv(other.ptr); return *this; } - - inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } - inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } - - Own& orDefault(Own& defaultValue) { - if (ptr == nullptr) { - return defaultValue; - } else { - return ptr; - } - } - const Own& orDefault(const Own& defaultValue) const { - if (ptr == nullptr) { - return defaultValue; - } else { - return ptr; - } - } - - template - auto map(Func&& f) & -> Maybe&>()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(ptr); - } - } - - template - auto map(Func&& f) const & -> Maybe&>()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(ptr); - } - } - - template - auto map(Func&& f) && -> Maybe&&>()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(kj::mv(ptr)); - } - } - - template - auto map(Func&& f) const && -> Maybe&&>()))> { - if (ptr == nullptr) { - return nullptr; - } else { - return f(kj::mv(ptr)); - } - } - -private: - Own ptr; - - template - friend class Maybe; - template - friend _::OwnOwn _::readMaybe(Maybe>&& maybe); - template - friend Own* _::readMaybe(Maybe>& maybe); - template - friend const Own* _::readMaybe(const Maybe>& maybe); -}; - -namespace _ { // private - -template -class HeapDisposer final: public Disposer { -public: - virtual void disposeImpl(void* pointer) const override { delete reinterpret_cast(pointer); } - - static const HeapDisposer instance; -}; - -template -const HeapDisposer HeapDisposer::instance = HeapDisposer(); - -} // namespace _ (private) - -template -Own heap(Params&&... params) { - // heap(...) allocates a T on the heap, forwarding the parameters to its constructor. The - // exact heap implementation is unspecified -- for now it is operator new, but you should not - // assume this. (Since we know the object size at delete time, we could actually implement an - // allocator that is more efficient than operator new.) - - return Own(new T(kj::fwd(params)...), _::HeapDisposer::instance); -} - -template -Own> heap(T&& orig) { - // Allocate a copy (or move) of the argument on the heap. - // - // The purpose of this overload is to allow you to omit the template parameter as there is only - // one argument and the purpose is to copy it. - - typedef Decay T2; - return Own(new T2(kj::fwd(orig)), _::HeapDisposer::instance); -} - -// ======================================================================================= -// SpaceFor -- assists in manual allocation - -template -class SpaceFor { - // A class which has the same size and alignment as T but does not call its constructor or - // destructor automatically. Instead, call construct() to construct a T in the space, which - // returns an Own which will take care of calling T's destructor later. - -public: - inline SpaceFor() {} - inline ~SpaceFor() {} - - template - Own construct(Params&&... params) { - ctor(value, kj::fwd(params)...); - return Own(&value, DestructorOnlyDisposer::instance); - } - -private: - union { - T value; - }; -}; - -// ======================================================================================= -// Inline implementation details - -template -struct Disposer::Dispose_ { - static void dispose(T* object, const Disposer& disposer) { - // Note that dynamic_cast does not require RTTI to be enabled, because the offset to - // the top of the object is in the vtable -- as it obviously needs to be to correctly implement - // operator delete. - disposer.disposeImpl(dynamic_cast(object)); - } -}; -template -struct Disposer::Dispose_ { - static void dispose(T* object, const Disposer& disposer) { - disposer.disposeImpl(static_cast(object)); - } -}; - -template -void Disposer::dispose(T* object) const { - Dispose_::dispose(object, *this); -} - -} // namespace kj - -#endif // KJ_MEMORY_H_ diff --git a/phonelibs/capnp-cpp/include/kj/mutex.h b/phonelibs/capnp-cpp/include/kj/mutex.h deleted file mode 100644 index d211ebfeb1c603..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/mutex.h +++ /dev/null @@ -1,369 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_MUTEX_H_ -#define KJ_MUTEX_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "memory.h" -#include - -#if __linux__ && !defined(KJ_USE_FUTEX) -#define KJ_USE_FUTEX 1 -#endif - -#if !KJ_USE_FUTEX && !_WIN32 -// On Linux we use futex. On other platforms we wrap pthreads. -// TODO(someday): Write efficient low-level locking primitives for other platforms. -#include -#endif - -namespace kj { - -// ======================================================================================= -// Private details -- public interfaces follow below. - -namespace _ { // private - -class Mutex { - // Internal implementation details. See `MutexGuarded`. - -public: - Mutex(); - ~Mutex(); - KJ_DISALLOW_COPY(Mutex); - - enum Exclusivity { - EXCLUSIVE, - SHARED - }; - - void lock(Exclusivity exclusivity); - void unlock(Exclusivity exclusivity); - - void assertLockedByCaller(Exclusivity exclusivity); - // In debug mode, assert that the mutex is locked by the calling thread, or if that is - // non-trivial, assert that the mutex is locked (which should be good enough to catch problems - // in unit tests). In non-debug builds, do nothing. - -private: -#if KJ_USE_FUTEX - uint futex; - // bit 31 (msb) = set if exclusive lock held - // bit 30 (msb) = set if threads are waiting for exclusive lock - // bits 0-29 = count of readers; If an exclusive lock is held, this is the count of threads - // waiting for a read lock, otherwise it is the count of threads that currently hold a read - // lock. - - static constexpr uint EXCLUSIVE_HELD = 1u << 31; - static constexpr uint EXCLUSIVE_REQUESTED = 1u << 30; - static constexpr uint SHARED_COUNT_MASK = EXCLUSIVE_REQUESTED - 1; - -#elif _WIN32 - uintptr_t srwLock; // Actually an SRWLOCK, but don't want to #include in header. - -#else - mutable pthread_rwlock_t mutex; -#endif -}; - -class Once { - // Internal implementation details. See `Lazy`. - -public: -#if KJ_USE_FUTEX - inline Once(bool startInitialized = false) - : futex(startInitialized ? INITIALIZED : UNINITIALIZED) {} -#else - Once(bool startInitialized = false); - ~Once(); -#endif - KJ_DISALLOW_COPY(Once); - - class Initializer { - public: - virtual void run() = 0; - }; - - void runOnce(Initializer& init); - -#if _WIN32 // TODO(perf): Can we make this inline on win32 somehow? - bool isInitialized() noexcept; - -#else - inline bool isInitialized() noexcept { - // Fast path check to see if runOnce() would simply return immediately. -#if KJ_USE_FUTEX - return __atomic_load_n(&futex, __ATOMIC_ACQUIRE) == INITIALIZED; -#else - return __atomic_load_n(&state, __ATOMIC_ACQUIRE) == INITIALIZED; -#endif - } -#endif - - void reset(); - // Returns the state from initialized to uninitialized. It is an error to call this when - // not already initialized, or when runOnce() or isInitialized() might be called concurrently in - // another thread. - -private: -#if KJ_USE_FUTEX - uint futex; - - enum State { - UNINITIALIZED, - INITIALIZING, - INITIALIZING_WITH_WAITERS, - INITIALIZED - }; - -#elif _WIN32 - uintptr_t initOnce; // Actually an INIT_ONCE, but don't want to #include in header. - -#else - enum State { - UNINITIALIZED, - INITIALIZED - }; - State state; - pthread_mutex_t mutex; -#endif -}; - -} // namespace _ (private) - -// ======================================================================================= -// Public interface - -template -class Locked { - // Return type for `MutexGuarded::lock()`. `Locked` provides access to the bounded object - // and unlocks the mutex when it goes out of scope. - -public: - KJ_DISALLOW_COPY(Locked); - inline Locked(): mutex(nullptr), ptr(nullptr) {} - inline Locked(Locked&& other): mutex(other.mutex), ptr(other.ptr) { - other.mutex = nullptr; - other.ptr = nullptr; - } - inline ~Locked() { - if (mutex != nullptr) mutex->unlock(isConst() ? _::Mutex::SHARED : _::Mutex::EXCLUSIVE); - } - - inline Locked& operator=(Locked&& other) { - if (mutex != nullptr) mutex->unlock(isConst() ? _::Mutex::SHARED : _::Mutex::EXCLUSIVE); - mutex = other.mutex; - ptr = other.ptr; - other.mutex = nullptr; - other.ptr = nullptr; - return *this; - } - - inline void release() { - if (mutex != nullptr) mutex->unlock(isConst() ? _::Mutex::SHARED : _::Mutex::EXCLUSIVE); - mutex = nullptr; - ptr = nullptr; - } - - inline T* operator->() { return ptr; } - inline const T* operator->() const { return ptr; } - inline T& operator*() { return *ptr; } - inline const T& operator*() const { return *ptr; } - inline T* get() { return ptr; } - inline const T* get() const { return ptr; } - inline operator T*() { return ptr; } - inline operator const T*() const { return ptr; } - -private: - _::Mutex* mutex; - T* ptr; - - inline Locked(_::Mutex& mutex, T& value): mutex(&mutex), ptr(&value) {} - - template - friend class MutexGuarded; -}; - -template -class MutexGuarded { - // An object of type T, bounded by a mutex. In order to access the object, you must lock it. - // - // Write locks are not "recursive" -- trying to lock again in a thread that already holds a lock - // will deadlock. Recursive write locks are usually a sign of bad design. - // - // Unfortunately, **READ LOCKS ARE NOT RECURSIVE** either. Common sense says they should be. - // But on many operating systems (BSD, OSX), recursively read-locking a pthread_rwlock is - // actually unsafe. The problem is that writers are "prioritized" over readers, so a read lock - // request will block if any write lock requests are outstanding. So, if thread A takes a read - // lock, thread B requests a write lock (and starts waiting), and then thread A tries to take - // another read lock recursively, the result is deadlock. - -public: - template - explicit MutexGuarded(Params&&... params); - // Initialize the mutex-bounded object by passing the given parameters to its constructor. - - Locked lockExclusive() const; - // Exclusively locks the object and returns it. The returned `Locked` can be passed by - // move, similar to `Own`. - // - // This method is declared `const` in accordance with KJ style rules which say that constness - // should be used to indicate thread-safety. It is safe to share a const pointer between threads, - // but it is not safe to share a mutable pointer. Since the whole point of MutexGuarded is to - // be shared between threads, its methods should be const, even though locking it produces a - // non-const pointer to the contained object. - - Locked lockShared() const; - // Lock the value for shared access. Multiple shared locks can be taken concurrently, but cannot - // be held at the same time as a non-shared lock. - - inline const T& getWithoutLock() const { return value; } - inline T& getWithoutLock() { return value; } - // Escape hatch for cases where some external factor guarantees that it's safe to get the - // value. You should treat these like const_cast -- be highly suspicious of any use. - - inline const T& getAlreadyLockedShared() const; - inline T& getAlreadyLockedShared(); - inline T& getAlreadyLockedExclusive() const; - // Like `getWithoutLock()`, but asserts that the lock is already held by the calling thread. - -private: - mutable _::Mutex mutex; - mutable T value; -}; - -template -class MutexGuarded { - // MutexGuarded cannot guard a const type. This would be pointless anyway, and would complicate - // the implementation of Locked, which uses constness to decide what kind of lock it holds. - static_assert(sizeof(T) < 0, "MutexGuarded's type cannot be const."); -}; - -template -class Lazy { - // A lazily-initialized value. - -public: - template - T& get(Func&& init); - template - const T& get(Func&& init) const; - // The first thread to call get() will invoke the given init function to construct the value. - // Other threads will block until construction completes, then return the same value. - // - // `init` is a functor(typically a lambda) which takes `SpaceFor&` as its parameter and returns - // `Own`. If `init` throws an exception, the exception is propagated out of that thread's - // call to `get()`, and subsequent calls behave as if `get()` hadn't been called at all yet -- - // in other words, subsequent calls retry initialization until it succeeds. - -private: - mutable _::Once once; - mutable SpaceFor space; - mutable Own value; - - template - class InitImpl; -}; - -// ======================================================================================= -// Inline implementation details - -template -template -inline MutexGuarded::MutexGuarded(Params&&... params) - : value(kj::fwd(params)...) {} - -template -inline Locked MutexGuarded::lockExclusive() const { - mutex.lock(_::Mutex::EXCLUSIVE); - return Locked(mutex, value); -} - -template -inline Locked MutexGuarded::lockShared() const { - mutex.lock(_::Mutex::SHARED); - return Locked(mutex, value); -} - -template -inline const T& MutexGuarded::getAlreadyLockedShared() const { -#ifdef KJ_DEBUG - mutex.assertLockedByCaller(_::Mutex::SHARED); -#endif - return value; -} -template -inline T& MutexGuarded::getAlreadyLockedShared() { -#ifdef KJ_DEBUG - mutex.assertLockedByCaller(_::Mutex::SHARED); -#endif - return value; -} -template -inline T& MutexGuarded::getAlreadyLockedExclusive() const { -#ifdef KJ_DEBUG - mutex.assertLockedByCaller(_::Mutex::EXCLUSIVE); -#endif - return const_cast(value); -} - -template -template -class Lazy::InitImpl: public _::Once::Initializer { -public: - inline InitImpl(const Lazy& lazy, Func&& func): lazy(lazy), func(kj::fwd(func)) {} - - void run() override { - lazy.value = func(lazy.space); - } - -private: - const Lazy& lazy; - Func func; -}; - -template -template -inline T& Lazy::get(Func&& init) { - if (!once.isInitialized()) { - InitImpl initImpl(*this, kj::fwd(init)); - once.runOnce(initImpl); - } - return *value; -} - -template -template -inline const T& Lazy::get(Func&& init) const { - if (!once.isInitialized()) { - InitImpl initImpl(*this, kj::fwd(init)); - once.runOnce(initImpl); - } - return *value; -} - -} // namespace kj - -#endif // KJ_MUTEX_H_ diff --git a/phonelibs/capnp-cpp/include/kj/one-of.h b/phonelibs/capnp-cpp/include/kj/one-of.h deleted file mode 100644 index 6e143c44cf26dd..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/one-of.h +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_ONE_OF_H_ -#define KJ_ONE_OF_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "common.h" - -namespace kj { - -namespace _ { // private - -template -struct TypeIndex_ { static constexpr uint value = TypeIndex_::value; }; -template -struct TypeIndex_ { static constexpr uint value = i; }; - -} // namespace _ (private) - -template -class OneOf { - template - static inline constexpr uint typeIndex() { return _::TypeIndex_<1, Key, Variants...>::value; } - // Get the 1-based index of Key within the type list Types. - -public: - inline OneOf(): tag(0) {} - OneOf(const OneOf& other) { copyFrom(other); } - OneOf(OneOf&& other) { moveFrom(other); } - ~OneOf() { destroy(); } - - OneOf& operator=(const OneOf& other) { if (tag != 0) destroy(); copyFrom(other); return *this; } - OneOf& operator=(OneOf&& other) { if (tag != 0) destroy(); moveFrom(other); return *this; } - - inline bool operator==(decltype(nullptr)) const { return tag == 0; } - inline bool operator!=(decltype(nullptr)) const { return tag != 0; } - - template - bool is() const { - return tag == typeIndex(); - } - - template - T& get() { - KJ_IREQUIRE(is(), "Must check OneOf::is() before calling get()."); - return *reinterpret_cast(space); - } - template - const T& get() const { - KJ_IREQUIRE(is(), "Must check OneOf::is() before calling get()."); - return *reinterpret_cast(space); - } - - template - T& init(Params&&... params) { - if (tag != 0) destroy(); - ctor(*reinterpret_cast(space), kj::fwd(params)...); - tag = typeIndex(); - return *reinterpret_cast(space); - } - -private: - uint tag; - - static inline constexpr size_t maxSize(size_t a) { - return a; - } - template - static inline constexpr size_t maxSize(size_t a, size_t b, Rest... rest) { - return maxSize(kj::max(a, b), rest...); - } - // Returns the maximum of all the parameters. - // TODO(someday): Generalize the above template and make it common. I tried, but C++ decided to - // be difficult so I cut my losses. - - static constexpr auto spaceSize = maxSize(sizeof(Variants)...); - // TODO(msvc): This constant could just as well go directly inside space's bracket's, where it's - // used, but MSVC suffers a parse error on `...`. - - union { - byte space[spaceSize]; - - void* forceAligned; - // TODO(someday): Use C++11 alignas() once we require GCC 4.8 / Clang 3.3. - }; - - template - inline void doAll(T... t) {} - - template - inline bool destroyVariant() { - if (tag == typeIndex()) { - tag = 0; - dtor(*reinterpret_cast(space)); - } - return false; - } - void destroy() { - doAll(destroyVariant()...); - } - - template - inline bool copyVariantFrom(const OneOf& other) { - if (other.is()) { - ctor(*reinterpret_cast(space), other.get()); - } - return false; - } - void copyFrom(const OneOf& other) { - // Initialize as a copy of `other`. Expects that `this` starts out uninitialized, so the tag - // is invalid. - tag = other.tag; - doAll(copyVariantFrom(other)...); - } - - template - inline bool moveVariantFrom(OneOf& other) { - if (other.is()) { - ctor(*reinterpret_cast(space), kj::mv(other.get())); - } - return false; - } - void moveFrom(OneOf& other) { - // Initialize as a copy of `other`. Expects that `this` starts out uninitialized, so the tag - // is invalid. - tag = other.tag; - doAll(moveVariantFrom(other)...); - } -}; - -} // namespace kj - -#endif // KJ_ONE_OF_H_ diff --git a/phonelibs/capnp-cpp/include/kj/parse/char.h b/phonelibs/capnp-cpp/include/kj/parse/char.h deleted file mode 100644 index 2e6d51921d86ce..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/parse/char.h +++ /dev/null @@ -1,361 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -// This file contains parsers useful for character stream inputs, including parsers to parse -// common kinds of tokens like identifiers, numbers, and quoted strings. - -#ifndef KJ_PARSE_CHAR_H_ -#define KJ_PARSE_CHAR_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "common.h" -#include "../string.h" -#include - -namespace kj { -namespace parse { - -// ======================================================================================= -// Exact char/string. - -class ExactString_ { -public: - constexpr inline ExactString_(const char* str): str(str) {} - - template - Maybe> operator()(Input& input) const { - const char* ptr = str; - - while (*ptr != '\0') { - if (input.atEnd() || input.current() != *ptr) return nullptr; - input.next(); - ++ptr; - } - - return Tuple<>(); - } - -private: - const char* str; -}; - -constexpr inline ExactString_ exactString(const char* str) { - return ExactString_(str); -} - -template -constexpr ExactlyConst_ exactChar() { - // Returns a parser that matches exactly the character given by the template argument (returning - // no result). - return ExactlyConst_(); -} - -// ======================================================================================= -// Char ranges / sets - -class CharGroup_ { -public: - constexpr inline CharGroup_(): bits{0, 0, 0, 0} {} - - constexpr inline CharGroup_ orRange(unsigned char first, unsigned char last) const { - return CharGroup_(bits[0] | (oneBits(last + 1) & ~oneBits(first )), - bits[1] | (oneBits(last - 63) & ~oneBits(first - 64)), - bits[2] | (oneBits(last - 127) & ~oneBits(first - 128)), - bits[3] | (oneBits(last - 191) & ~oneBits(first - 192))); - } - - constexpr inline CharGroup_ orAny(const char* chars) const { - return *chars == 0 ? *this : orChar(*chars).orAny(chars + 1); - } - - constexpr inline CharGroup_ orChar(unsigned char c) const { - return CharGroup_(bits[0] | bit(c), - bits[1] | bit(c - 64), - bits[2] | bit(c - 128), - bits[3] | bit(c - 256)); - } - - constexpr inline CharGroup_ orGroup(CharGroup_ other) const { - return CharGroup_(bits[0] | other.bits[0], - bits[1] | other.bits[1], - bits[2] | other.bits[2], - bits[3] | other.bits[3]); - } - - constexpr inline CharGroup_ invert() const { - return CharGroup_(~bits[0], ~bits[1], ~bits[2], ~bits[3]); - } - - constexpr inline bool contains(unsigned char c) const { - return (bits[c / 64] & (1ll << (c % 64))) != 0; - } - - template - Maybe operator()(Input& input) const { - if (input.atEnd()) return nullptr; - unsigned char c = input.current(); - if (contains(c)) { - input.next(); - return c; - } else { - return nullptr; - } - } - -private: - typedef unsigned long long Bits64; - - constexpr inline CharGroup_(Bits64 a, Bits64 b, Bits64 c, Bits64 d): bits{a, b, c, d} {} - Bits64 bits[4]; - - static constexpr inline Bits64 oneBits(int count) { - return count <= 0 ? 0ll : count >= 64 ? -1ll : ((1ll << count) - 1); - } - static constexpr inline Bits64 bit(int index) { - return index < 0 ? 0 : index >= 64 ? 0 : (1ll << index); - } -}; - -constexpr inline CharGroup_ charRange(char first, char last) { - // Create a parser which accepts any character in the range from `first` to `last`, inclusive. - // For example: `charRange('a', 'z')` matches all lower-case letters. The parser's result is the - // character matched. - // - // The returned object has methods which can be used to match more characters. The following - // produces a parser which accepts any letter as well as '_', '+', '-', and '.'. - // - // charRange('a', 'z').orRange('A', 'Z').orChar('_').orAny("+-.") - // - // You can also use `.invert()` to match the opposite set of characters. - - return CharGroup_().orRange(first, last); -} - -#if _MSC_VER -#define anyOfChars(chars) CharGroup_().orAny(chars) -// TODO(msvc): MSVC ICEs on the proper definition of `anyOfChars()`, which in turn prevents us from -// building the compiler or schema parser. We don't know why this happens, but Harris found that -// this horrible, horrible hack makes things work. This is awful, but it's better than nothing. -// Hopefully, MSVC will get fixed soon and we'll be able to remove this. -#else -constexpr inline CharGroup_ anyOfChars(const char* chars) { - // Returns a parser that accepts any of the characters in the given string (which should usually - // be a literal). The returned parser is of the same type as returned by `charRange()` -- see - // that function for more info. - - return CharGroup_().orAny(chars); -} -#endif - -// ======================================================================================= - -namespace _ { // private - -struct ArrayToString { - inline String operator()(const Array& arr) const { - return heapString(arr); - } -}; - -} // namespace _ (private) - -template -constexpr inline auto charsToString(SubParser&& subParser) - -> decltype(transform(kj::fwd(subParser), _::ArrayToString())) { - // Wraps a parser that returns Array such that it returns String instead. - return parse::transform(kj::fwd(subParser), _::ArrayToString()); -} - -// ======================================================================================= -// Basic character classes. - -constexpr auto alpha = charRange('a', 'z').orRange('A', 'Z'); -constexpr auto digit = charRange('0', '9'); -constexpr auto alphaNumeric = alpha.orGroup(digit); -constexpr auto nameStart = alpha.orChar('_'); -constexpr auto nameChar = alphaNumeric.orChar('_'); -constexpr auto hexDigit = charRange('0', '9').orRange('a', 'f').orRange('A', 'F'); -constexpr auto octDigit = charRange('0', '7'); -constexpr auto whitespaceChar = anyOfChars(" \f\n\r\t\v"); -constexpr auto controlChar = charRange(0, 0x1f).invert().orGroup(whitespaceChar).invert(); - -constexpr auto whitespace = many(anyOfChars(" \f\n\r\t\v")); - -constexpr auto discardWhitespace = discard(many(discard(anyOfChars(" \f\n\r\t\v")))); -// Like discard(whitespace) but avoids some memory allocation. - -// ======================================================================================= -// Identifiers - -namespace _ { // private - -struct IdentifierToString { - inline String operator()(char first, const Array& rest) const { - String result = heapString(rest.size() + 1); - result[0] = first; - memcpy(result.begin() + 1, rest.begin(), rest.size()); - return result; - } -}; - -} // namespace _ (private) - -constexpr auto identifier = transform(sequence(nameStart, many(nameChar)), _::IdentifierToString()); -// Parses an identifier (e.g. a C variable name). - -// ======================================================================================= -// Integers - -namespace _ { // private - -inline char parseDigit(char c) { - if (c < 'A') return c - '0'; - if (c < 'a') return c - 'A' + 10; - return c - 'a' + 10; -} - -template -struct ParseInteger { - inline uint64_t operator()(const Array& digits) const { - return operator()('0', digits); - } - uint64_t operator()(char first, const Array& digits) const { - uint64_t result = parseDigit(first); - for (char digit: digits) { - result = result * base + parseDigit(digit); - } - return result; - } -}; - - -} // namespace _ (private) - -constexpr auto integer = sequence( - oneOf( - transform(sequence(exactChar<'0'>(), exactChar<'x'>(), oneOrMore(hexDigit)), _::ParseInteger<16>()), - transform(sequence(exactChar<'0'>(), many(octDigit)), _::ParseInteger<8>()), - transform(sequence(charRange('1', '9'), many(digit)), _::ParseInteger<10>())), - notLookingAt(alpha.orAny("_."))); - -// ======================================================================================= -// Numbers (i.e. floats) - -namespace _ { // private - -struct ParseFloat { - double operator()(const Array& digits, - const Maybe>& fraction, - const Maybe, Array>>& exponent) const; -}; - -} // namespace _ (private) - -constexpr auto number = transform( - sequence( - oneOrMore(digit), - optional(sequence(exactChar<'.'>(), many(digit))), - optional(sequence(discard(anyOfChars("eE")), optional(anyOfChars("+-")), many(digit))), - notLookingAt(alpha.orAny("_."))), - _::ParseFloat()); - -// ======================================================================================= -// Quoted strings - -namespace _ { // private - -struct InterpretEscape { - char operator()(char c) const { - switch (c) { - case 'a': return '\a'; - case 'b': return '\b'; - case 'f': return '\f'; - case 'n': return '\n'; - case 'r': return '\r'; - case 't': return '\t'; - case 'v': return '\v'; - default: return c; - } - } -}; - -struct ParseHexEscape { - inline char operator()(char first, char second) const { - return (parseDigit(first) << 4) | parseDigit(second); - } -}; - -struct ParseHexByte { - inline byte operator()(char first, char second) const { - return (parseDigit(first) << 4) | parseDigit(second); - } -}; - -struct ParseOctEscape { - inline char operator()(char first, Maybe second, Maybe third) const { - char result = first - '0'; - KJ_IF_MAYBE(digit1, second) { - result = (result << 3) | (*digit1 - '0'); - KJ_IF_MAYBE(digit2, third) { - result = (result << 3) | (*digit2 - '0'); - } - } - return result; - } -}; - -} // namespace _ (private) - -constexpr auto escapeSequence = - sequence(exactChar<'\\'>(), oneOf( - transform(anyOfChars("abfnrtv'\"\\\?"), _::InterpretEscape()), - transform(sequence(exactChar<'x'>(), hexDigit, hexDigit), _::ParseHexEscape()), - transform(sequence(octDigit, optional(octDigit), optional(octDigit)), - _::ParseOctEscape()))); -// A parser that parses a C-string-style escape sequence (starting with a backslash). Returns -// a char. - -constexpr auto doubleQuotedString = charsToString(sequence( - exactChar<'\"'>(), - many(oneOf(anyOfChars("\\\n\"").invert(), escapeSequence)), - exactChar<'\"'>())); -// Parses a C-style double-quoted string. - -constexpr auto singleQuotedString = charsToString(sequence( - exactChar<'\''>(), - many(oneOf(anyOfChars("\\\n\'").invert(), escapeSequence)), - exactChar<'\''>())); -// Parses a C-style single-quoted string. - -constexpr auto doubleQuotedHexBinary = sequence( - exactChar<'0'>(), exactChar<'x'>(), exactChar<'\"'>(), - oneOrMore(transform(sequence(discardWhitespace, hexDigit, hexDigit), _::ParseHexByte())), - discardWhitespace, - exactChar<'\"'>()); -// Parses a double-quoted hex binary literal. Returns Array. - -} // namespace parse -} // namespace kj - -#endif // KJ_PARSE_CHAR_H_ diff --git a/phonelibs/capnp-cpp/include/kj/parse/common.h b/phonelibs/capnp-cpp/include/kj/parse/common.h deleted file mode 100644 index 3af3a8760d5e7e..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/parse/common.h +++ /dev/null @@ -1,824 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -// Parser combinator framework! -// -// This file declares several functions which construct parsers, usually taking other parsers as -// input, thus making them parser combinators. -// -// A valid parser is any functor which takes a reference to an input cursor (defined below) as its -// input and returns a Maybe. The parser returns null on parse failure, or returns the parsed -// result on success. -// -// An "input cursor" is any type which implements the same interface as IteratorInput, below. Such -// a type acts as a pointer to the current input location. When a parser returns successfully, it -// will have updated the input cursor to point to the position just past the end of what was parsed. -// On failure, the cursor position is unspecified. - -#ifndef KJ_PARSE_COMMON_H_ -#define KJ_PARSE_COMMON_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "../common.h" -#include "../memory.h" -#include "../array.h" -#include "../tuple.h" -#include "../vector.h" -#if _MSC_VER -#include // result_of_t -#endif - -namespace kj { -namespace parse { - -template -class IteratorInput { - // A parser input implementation based on an iterator range. - -public: - IteratorInput(Iterator begin, Iterator end) - : parent(nullptr), pos(begin), end(end), best(begin) {} - explicit IteratorInput(IteratorInput& parent) - : parent(&parent), pos(parent.pos), end(parent.end), best(parent.pos) {} - ~IteratorInput() { - if (parent != nullptr) { - parent->best = kj::max(kj::max(pos, best), parent->best); - } - } - KJ_DISALLOW_COPY(IteratorInput); - - void advanceParent() { - parent->pos = pos; - } - void forgetParent() { - parent = nullptr; - } - - bool atEnd() { return pos == end; } - auto current() -> decltype(*instance()) { - KJ_IREQUIRE(!atEnd()); - return *pos; - } - auto consume() -> decltype(*instance()) { - KJ_IREQUIRE(!atEnd()); - return *pos++; - } - void next() { - KJ_IREQUIRE(!atEnd()); - ++pos; - } - - Iterator getBest() { return kj::max(pos, best); } - - Iterator getPosition() { return pos; } - -private: - IteratorInput* parent; - Iterator pos; - Iterator end; - Iterator best; // furthest we got with any sub-input -}; - -template struct OutputType_; -template struct OutputType_> { typedef T Type; }; -template -using OutputType = typename OutputType_< -#if _MSC_VER - std::result_of_t - // The instance() based version below results in: - // C2064: term does not evaluate to a function taking 1 arguments -#else - decltype(instance()(instance())) -#endif - >::Type; -// Synonym for the output type of a parser, given the parser type and the input type. - -// ======================================================================================= - -template -class ParserRef { - // Acts as a reference to some other parser, with simplified type. The referenced parser - // is polymorphic by virtual call rather than templates. For grammars of non-trivial size, - // it is important to inject refs into the grammar here and there to prevent the parser types - // from becoming ridiculous. Using too many of them can hurt performance, though. - -public: - ParserRef(): parser(nullptr), wrapper(nullptr) {} - ParserRef(const ParserRef&) = default; - ParserRef(ParserRef&&) = default; - ParserRef& operator=(const ParserRef& other) = default; - ParserRef& operator=(ParserRef&& other) = default; - - template - constexpr ParserRef(Other&& other) - : parser(&other), wrapper(&WrapperImplInstance>::instance) { - static_assert(kj::isReference(), "ParserRef should not be assigned to a temporary."); - } - - template - inline ParserRef& operator=(Other&& other) { - static_assert(kj::isReference(), "ParserRef should not be assigned to a temporary."); - parser = &other; - wrapper = &WrapperImplInstance>::instance; - return *this; - } - - KJ_ALWAYS_INLINE(Maybe operator()(Input& input) const) { - // Always inline in the hopes that this allows branch prediction to kick in so the virtual call - // doesn't hurt so much. - return wrapper->parse(parser, input); - } - -private: - struct Wrapper { - virtual Maybe parse(const void* parser, Input& input) const = 0; - }; - template - struct WrapperImpl: public Wrapper { - Maybe parse(const void* parser, Input& input) const override { - return (*reinterpret_cast(parser))(input); - } - }; - template - struct WrapperImplInstance { -#if _MSC_VER - // TODO(msvc): MSVC currently fails to initialize vtable pointers for constexpr values so - // we have to make this just const instead. - static const WrapperImpl instance; -#else - static constexpr WrapperImpl instance = WrapperImpl(); -#endif - }; - - const void* parser; - const Wrapper* wrapper; -}; - -template -template -#if _MSC_VER -const typename ParserRef::template WrapperImpl -ParserRef::WrapperImplInstance::instance = WrapperImpl(); -#else -constexpr typename ParserRef::template WrapperImpl -ParserRef::WrapperImplInstance::instance; -#endif - -template -constexpr ParserRef> ref(ParserImpl& impl) { - // Constructs a ParserRef. You must specify the input type explicitly, e.g. - // `ref(myParser)`. - - return ParserRef>(impl); -} - -// ------------------------------------------------------------------- -// any -// Output = one token - -class Any_ { -public: - template - Maybe().consume())>> operator()(Input& input) const { - if (input.atEnd()) { - return nullptr; - } else { - return input.consume(); - } - } -}; - -constexpr Any_ any = Any_(); -// A parser which matches any token and simply returns it. - -// ------------------------------------------------------------------- -// exactly() -// Output = Tuple<> - -template -class Exactly_ { -public: - explicit constexpr Exactly_(T&& expected): expected(expected) {} - - template - Maybe> operator()(Input& input) const { - if (input.atEnd() || input.current() != expected) { - return nullptr; - } else { - input.next(); - return Tuple<>(); - } - } - -private: - T expected; -}; - -template -constexpr Exactly_ exactly(T&& expected) { - // Constructs a parser which succeeds when the input is exactly the token specified. The - // result is always the empty tuple. - - return Exactly_(kj::fwd(expected)); -} - -// ------------------------------------------------------------------- -// exactlyConst() -// Output = Tuple<> - -template -class ExactlyConst_ { -public: - explicit constexpr ExactlyConst_() {} - - template - Maybe> operator()(Input& input) const { - if (input.atEnd() || input.current() != expected) { - return nullptr; - } else { - input.next(); - return Tuple<>(); - } - } -}; - -template -constexpr ExactlyConst_ exactlyConst() { - // Constructs a parser which succeeds when the input is exactly the token specified. The - // result is always the empty tuple. This parser is templated on the token value which may cause - // it to perform better -- or worse. Be sure to measure. - - return ExactlyConst_(); -} - -// ------------------------------------------------------------------- -// constResult() - -template -class ConstResult_ { -public: - explicit constexpr ConstResult_(SubParser&& subParser, Result&& result) - : subParser(kj::fwd(subParser)), result(kj::fwd(result)) {} - - template - Maybe operator()(Input& input) const { - if (subParser(input) == nullptr) { - return nullptr; - } else { - return result; - } - } - -private: - SubParser subParser; - Result result; -}; - -template -constexpr ConstResult_ constResult(SubParser&& subParser, Result&& result) { - // Constructs a parser which returns exactly `result` if `subParser` is successful. - return ConstResult_(kj::fwd(subParser), kj::fwd(result)); -} - -template -constexpr ConstResult_> discard(SubParser&& subParser) { - // Constructs a parser which wraps `subParser` but discards the result. - return constResult(kj::fwd(subParser), Tuple<>()); -} - -// ------------------------------------------------------------------- -// sequence() -// Output = Flattened Tuple of outputs of sub-parsers. - -template class Sequence_; - -template -class Sequence_ { -public: - template - explicit constexpr Sequence_(T&& firstSubParser, U&&... rest) - : first(kj::fwd(firstSubParser)), rest(kj::fwd(rest)...) {} - - // TODO(msvc): The trailing return types on `operator()` and `parseNext()` expose at least two - // bugs in MSVC: - // - // 1. An ICE. - // 2. 'error C2672: 'operator __surrogate_func': no matching overloaded function found)', - // which crops up in numerous places when trying to build the capnp command line tools. - // - // The only workaround I found for both bugs is to omit the trailing return types and instead - // rely on C++14's return type deduction. - - template - auto operator()(Input& input) const -#ifndef _MSC_VER - -> Maybe>(), - instance>()...))> -#endif - { - return parseNext(input); - } - - template - auto parseNext(Input& input, InitialParams&&... initialParams) const -#ifndef _MSC_VER - -> Maybe(initialParams)..., - instance>(), - instance>()...))> -#endif - { - KJ_IF_MAYBE(firstResult, first(input)) { - return rest.parseNext(input, kj::fwd(initialParams)..., - kj::mv(*firstResult)); - } else { - // TODO(msvc): MSVC depends on return type deduction to compile this function, so we need to - // help it deduce the right type on this code path. - return Maybe(initialParams)..., - instance>(), - instance>()...))>{nullptr}; - } - } - -private: - FirstSubParser first; - Sequence_ rest; -}; - -template <> -class Sequence_<> { -public: - template - Maybe> operator()(Input& input) const { - return parseNext(input); - } - - template - auto parseNext(Input& input, Params&&... params) const -> - Maybe(params)...))> { - return tuple(kj::fwd(params)...); - } -}; - -template -constexpr Sequence_ sequence(SubParsers&&... subParsers) { - // Constructs a parser that executes each of the parameter parsers in sequence and returns a - // tuple of their results. - - return Sequence_(kj::fwd(subParsers)...); -} - -// ------------------------------------------------------------------- -// many() -// Output = Array of output of sub-parser, or just a uint count if the sub-parser returns Tuple<>. - -template -class Many_ { - template > - struct Impl; -public: - explicit constexpr Many_(SubParser&& subParser) - : subParser(kj::fwd(subParser)) {} - - template - auto operator()(Input& input) const - -> decltype(Impl::apply(instance(), input)); - -private: - SubParser subParser; -}; - -template -template -struct Many_::Impl { - static Maybe> apply(const SubParser& subParser, Input& input) { - typedef Vector> Results; - Results results; - - while (!input.atEnd()) { - Input subInput(input); - - KJ_IF_MAYBE(subResult, subParser(subInput)) { - subInput.advanceParent(); - results.add(kj::mv(*subResult)); - } else { - break; - } - } - - if (atLeastOne && results.empty()) { - return nullptr; - } - - return results.releaseAsArray(); - } -}; - -template -template -struct Many_::Impl> { - // If the sub-parser output is Tuple<>, just return a count. - - static Maybe apply(const SubParser& subParser, Input& input) { - uint count = 0; - - while (!input.atEnd()) { - Input subInput(input); - - KJ_IF_MAYBE(subResult, subParser(subInput)) { - subInput.advanceParent(); - ++count; - } else { - break; - } - } - - if (atLeastOne && count == 0) { - return nullptr; - } - - return count; - } -}; - -template -template -auto Many_::operator()(Input& input) const - -> decltype(Impl::apply(instance(), input)) { - return Impl>::apply(subParser, input); -} - -template -constexpr Many_ many(SubParser&& subParser) { - // Constructs a parser that repeatedly executes the given parser until it fails, returning an - // Array of the results (or a uint count if `subParser` returns an empty tuple). - return Many_(kj::fwd(subParser)); -} - -template -constexpr Many_ oneOrMore(SubParser&& subParser) { - // Like `many()` but the parser must parse at least one item to be successful. - return Many_(kj::fwd(subParser)); -} - -// ------------------------------------------------------------------- -// times() -// Output = Array of output of sub-parser, or Tuple<> if sub-parser returns Tuple<>. - -template -class Times_ { - template > - struct Impl; -public: - explicit constexpr Times_(SubParser&& subParser, uint count) - : subParser(kj::fwd(subParser)), count(count) {} - - template - auto operator()(Input& input) const - -> decltype(Impl::apply(instance(), instance(), input)); - -private: - SubParser subParser; - uint count; -}; - -template -template -struct Times_::Impl { - static Maybe> apply(const SubParser& subParser, uint count, Input& input) { - auto results = heapArrayBuilder>(count); - - while (results.size() < count) { - if (input.atEnd()) { - return nullptr; - } else KJ_IF_MAYBE(subResult, subParser(input)) { - results.add(kj::mv(*subResult)); - } else { - return nullptr; - } - } - - return results.finish(); - } -}; - -template -template -struct Times_::Impl> { - // If the sub-parser output is Tuple<>, just return a count. - - static Maybe> apply(const SubParser& subParser, uint count, Input& input) { - uint actualCount = 0; - - while (actualCount < count) { - if (input.atEnd()) { - return nullptr; - } else KJ_IF_MAYBE(subResult, subParser(input)) { - ++actualCount; - } else { - return nullptr; - } - } - - return tuple(); - } -}; - -template -template -auto Times_::operator()(Input& input) const - -> decltype(Impl::apply(instance(), instance(), input)) { - return Impl>::apply(subParser, count, input); -} - -template -constexpr Times_ times(SubParser&& subParser, uint count) { - // Constructs a parser that repeats the subParser exactly `count` times. - return Times_(kj::fwd(subParser), count); -} - -// ------------------------------------------------------------------- -// optional() -// Output = Maybe - -template -class Optional_ { -public: - explicit constexpr Optional_(SubParser&& subParser) - : subParser(kj::fwd(subParser)) {} - - template - Maybe>> operator()(Input& input) const { - typedef Maybe> Result; - - Input subInput(input); - KJ_IF_MAYBE(subResult, subParser(subInput)) { - subInput.advanceParent(); - return Result(kj::mv(*subResult)); - } else { - return Result(nullptr); - } - } - -private: - SubParser subParser; -}; - -template -constexpr Optional_ optional(SubParser&& subParser) { - // Constructs a parser that accepts zero or one of the given sub-parser, returning a Maybe - // of the sub-parser's result. - return Optional_(kj::fwd(subParser)); -} - -// ------------------------------------------------------------------- -// oneOf() -// All SubParsers must have same output type, which becomes the output type of the -// OneOfParser. - -template -class OneOf_; - -template -class OneOf_ { -public: - explicit constexpr OneOf_(FirstSubParser&& firstSubParser, SubParsers&&... rest) - : first(kj::fwd(firstSubParser)), rest(kj::fwd(rest)...) {} - - template - Maybe> operator()(Input& input) const { - { - Input subInput(input); - Maybe> firstResult = first(subInput); - - if (firstResult != nullptr) { - subInput.advanceParent(); - return kj::mv(firstResult); - } - } - - // Hoping for some tail recursion here... - return rest(input); - } - -private: - FirstSubParser first; - OneOf_ rest; -}; - -template <> -class OneOf_<> { -public: - template - decltype(nullptr) operator()(Input& input) const { - return nullptr; - } -}; - -template -constexpr OneOf_ oneOf(SubParsers&&... parsers) { - // Constructs a parser that accepts one of a set of options. The parser behaves as the first - // sub-parser in the list which returns successfully. All of the sub-parsers must return the - // same type. - return OneOf_(kj::fwd(parsers)...); -} - -// ------------------------------------------------------------------- -// transform() -// Output = Result of applying transform functor to input value. If input is a tuple, it is -// unpacked to form the transformation parameters. - -template -struct Span { -public: - inline const Position& begin() const { return begin_; } - inline const Position& end() const { return end_; } - - Span() = default; - inline constexpr Span(Position&& begin, Position&& end): begin_(mv(begin)), end_(mv(end)) {} - -private: - Position begin_; - Position end_; -}; - -template -constexpr Span> span(Position&& start, Position&& end) { - return Span>(kj::fwd(start), kj::fwd(end)); -} - -template -class Transform_ { -public: - explicit constexpr Transform_(SubParser&& subParser, TransformFunc&& transform) - : subParser(kj::fwd(subParser)), transform(kj::fwd(transform)) {} - - template - Maybe(), - instance&&>()))> - operator()(Input& input) const { - KJ_IF_MAYBE(subResult, subParser(input)) { - return kj::apply(transform, kj::mv(*subResult)); - } else { - return nullptr; - } - } - -private: - SubParser subParser; - TransformFunc transform; -}; - -template -class TransformOrReject_ { -public: - explicit constexpr TransformOrReject_(SubParser&& subParser, TransformFunc&& transform) - : subParser(kj::fwd(subParser)), transform(kj::fwd(transform)) {} - - template - decltype(kj::apply(instance(), instance&&>())) - operator()(Input& input) const { - KJ_IF_MAYBE(subResult, subParser(input)) { - return kj::apply(transform, kj::mv(*subResult)); - } else { - return nullptr; - } - } - -private: - SubParser subParser; - TransformFunc transform; -}; - -template -class TransformWithLocation_ { -public: - explicit constexpr TransformWithLocation_(SubParser&& subParser, TransformFunc&& transform) - : subParser(kj::fwd(subParser)), transform(kj::fwd(transform)) {} - - template - Maybe(), - instance().getPosition())>>>(), - instance&&>()))> - operator()(Input& input) const { - auto start = input.getPosition(); - KJ_IF_MAYBE(subResult, subParser(input)) { - return kj::apply(transform, Span(kj::mv(start), input.getPosition()), - kj::mv(*subResult)); - } else { - return nullptr; - } - } - -private: - SubParser subParser; - TransformFunc transform; -}; - -template -constexpr Transform_ transform( - SubParser&& subParser, TransformFunc&& functor) { - // Constructs a parser which executes some other parser and then transforms the result by invoking - // `functor` on it. Typically `functor` is a lambda. It is invoked using `kj::apply`, - // meaning tuples will be unpacked as arguments. - return Transform_( - kj::fwd(subParser), kj::fwd(functor)); -} - -template -constexpr TransformOrReject_ transformOrReject( - SubParser&& subParser, TransformFunc&& functor) { - // Like `transform()` except that `functor` returns a `Maybe`. If it returns null, parsing fails, - // otherwise the parser's result is the content of the `Maybe`. - return TransformOrReject_( - kj::fwd(subParser), kj::fwd(functor)); -} - -template -constexpr TransformWithLocation_ transformWithLocation( - SubParser&& subParser, TransformFunc&& functor) { - // Like `transform` except that `functor` also takes a `Span` as its first parameter specifying - // the location of the parsed content. The span's position type is whatever the parser input's - // getPosition() returns. - return TransformWithLocation_( - kj::fwd(subParser), kj::fwd(functor)); -} - -// ------------------------------------------------------------------- -// notLookingAt() -// Fails if the given parser succeeds at the current location. - -template -class NotLookingAt_ { -public: - explicit constexpr NotLookingAt_(SubParser&& subParser) - : subParser(kj::fwd(subParser)) {} - - template - Maybe> operator()(Input& input) const { - Input subInput(input); - subInput.forgetParent(); - if (subParser(subInput) == nullptr) { - return Tuple<>(); - } else { - return nullptr; - } - } - -private: - SubParser subParser; -}; - -template -constexpr NotLookingAt_ notLookingAt(SubParser&& subParser) { - // Constructs a parser which fails at any position where the given parser succeeds. Otherwise, - // it succeeds without consuming any input and returns an empty tuple. - return NotLookingAt_(kj::fwd(subParser)); -} - -// ------------------------------------------------------------------- -// endOfInput() -// Output = Tuple<>, only succeeds if at end-of-input - -class EndOfInput_ { -public: - template - Maybe> operator()(Input& input) const { - if (input.atEnd()) { - return Tuple<>(); - } else { - return nullptr; - } - } -}; - -constexpr EndOfInput_ endOfInput = EndOfInput_(); -// A parser that succeeds only if it is called with no input. - -} // namespace parse -} // namespace kj - -#endif // KJ_PARSE_COMMON_H_ diff --git a/phonelibs/capnp-cpp/include/kj/refcount.h b/phonelibs/capnp-cpp/include/kj/refcount.h deleted file mode 100644 index a24e4bf5b95e7d..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/refcount.h +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#include "memory.h" - -#ifndef KJ_REFCOUNT_H_ -#define KJ_REFCOUNT_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -namespace kj { - -class Refcounted: private Disposer { - // Subclass this to create a class that contains a reference count. Then, use - // `kj::refcounted()` to allocate a new refcounted pointer. - // - // Do NOT use this lightly. Refcounting is a crutch. Good designs should strive to make object - // ownership clear, so that refcounting is not necessary. All that said, reference counting can - // sometimes simplify code that would otherwise become convoluted with explicit ownership, even - // when ownership relationships are clear at an abstract level. - // - // NOT THREADSAFE: This refcounting implementation assumes that an object's references are - // manipulated only in one thread, because atomic (thread-safe) refcounting is surprisingly slow. - // - // In general, abstract classes should _not_ subclass this. The concrete class at the bottom - // of the hierarchy should be the one to decide how it implements refcounting. Interfaces should - // expose only an `addRef()` method that returns `Own`. There are two reasons for - // this rule: - // 1. Interfaces would need to virtually inherit Refcounted, otherwise two refcounted interfaces - // could not be inherited by the same subclass. Virtual inheritance is awkward and - // inefficient. - // 2. An implementation may decide that it would rather return a copy than a refcount, or use - // some other strategy. - // - // TODO(cleanup): Rethink above. Virtual inheritance is not necessarily that bad. OTOH, a - // virtual function call for every refcount is sad in its own way. A Ref type to replace - // Own could also be nice. - -public: - virtual ~Refcounted() noexcept(false); - - inline bool isShared() const { return refcount > 1; } - // Check if there are multiple references to this object. This is sometimes useful for deciding - // whether it's safe to modify the object vs. make a copy. - -private: - mutable uint refcount = 0; - // "mutable" because disposeImpl() is const. Bleh. - - void disposeImpl(void* pointer) const override; - template - static Own addRefInternal(T* object); - - template - friend Own addRef(T& object); - template - friend Own refcounted(Params&&... params); -}; - -template -inline Own refcounted(Params&&... params) { - // Allocate a new refcounted instance of T, passing `params` to its constructor. Returns an - // initial reference to the object. More references can be created with `kj::addRef()`. - - return Refcounted::addRefInternal(new T(kj::fwd(params)...)); -} - -template -Own addRef(T& object) { - // Return a new reference to `object`, which must subclass Refcounted and have been allocated - // using `kj::refcounted<>()`. It is suggested that subclasses implement a non-static addRef() - // method which wraps this and returns the appropriate type. - - KJ_IREQUIRE(object.Refcounted::refcount > 0, "Object not allocated with kj::refcounted()."); - return Refcounted::addRefInternal(&object); -} - -template -Own Refcounted::addRefInternal(T* object) { - Refcounted* refcounted = object; - ++refcounted->refcount; - return Own(object, *refcounted); -} - -} // namespace kj - -#endif // KJ_REFCOUNT_H_ diff --git a/phonelibs/capnp-cpp/include/kj/std/iostream.h b/phonelibs/capnp-cpp/include/kj/std/iostream.h deleted file mode 100644 index 627e0fcf8622fe..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/std/iostream.h +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -/* - * Compatibility layer for stdlib iostream - */ - -#ifndef KJ_STD_IOSTREAM_H_ -#define KJ_STD_IOSTREAM_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "../io.h" -#include - -namespace kj { -namespace std { - -class StdOutputStream: public kj::OutputStream { - -public: - explicit StdOutputStream(::std::ostream& stream) : stream_(stream) {} - ~StdOutputStream() noexcept(false) {} - - virtual void write(const void* src, size_t size) override { - // Always writes the full size. - - stream_.write((char*)src, size); - } - - virtual void write(ArrayPtr> pieces) override { - // Equivalent to write()ing each byte array in sequence, which is what the - // default implementation does. Override if you can do something better, - // e.g. use writev() to do the write in a single syscall. - - for (auto piece : pieces) { - write(piece.begin(), piece.size()); - } - } - -private: - ::std::ostream& stream_; - -}; - -class StdInputStream: public kj::InputStream { - -public: - explicit StdInputStream(::std::istream& stream) : stream_(stream) {} - ~StdInputStream() noexcept(false) {} - - virtual size_t tryRead( - void* buffer, size_t minBytes, size_t maxBytes) override { - // Like read(), but may return fewer than minBytes on EOF. - - stream_.read((char*)buffer, maxBytes); - return stream_.gcount(); - } - -private: - ::std::istream& stream_; - -}; - -} // namespace std -} // namespace kj - -#endif // KJ_STD_IOSTREAM_H_ diff --git a/phonelibs/capnp-cpp/include/kj/string-tree.h b/phonelibs/capnp-cpp/include/kj/string-tree.h deleted file mode 100644 index 70a46319ef82a5..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/string-tree.h +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_STRING_TREE_H_ -#define KJ_STRING_TREE_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "string.h" - -namespace kj { - -class StringTree { - // A long string, represented internally as a tree of strings. This data structure is like a - // String, but optimized for concatenation and iteration at the expense of seek time. The - // structure is intended to be used for building large text blobs from many small pieces, where - // repeatedly concatenating smaller strings into larger ones would waste copies. This structure - // is NOT intended for use cases requiring random access or computing substrings. For those, - // you should use a Rope, which is a much more complicated data structure. - // - // The proper way to construct a StringTree is via kj::strTree(...), which works just like - // kj::str(...) but returns a StringTree rather than a String. - // - // KJ_STRINGIFY() functions that construct large strings from many smaller strings are encouraged - // to return StringTree rather than a flat char container. - -public: - inline StringTree(): size_(0) {} - inline StringTree(String&& text): size_(text.size()), text(kj::mv(text)) {} - - StringTree(Array&& pieces, StringPtr delim); - // Build a StringTree by concatenating the given pieces, delimited by the given delimiter - // (e.g. ", "). - - inline size_t size() const { return size_; } - - template - void visit(Func&& func) const; - - String flatten() const; - // Return the contents as a string. - - // TODO(someday): flatten() when *this is an rvalue and when branches.size() == 0 could simply - // return `kj::mv(text)`. Requires reference qualifiers (Clang 3.3 / GCC 4.8). - - void flattenTo(char* __restrict__ target) const; - // Copy the contents to the given character array. Does not add a NUL terminator. - -private: - size_t size_; - String text; - - struct Branch; - Array branches; // In order. - - inline void fill(char* pos, size_t branchIndex); - template - void fill(char* pos, size_t branchIndex, First&& first, Rest&&... rest); - template - void fill(char* pos, size_t branchIndex, StringTree&& first, Rest&&... rest); - template - void fill(char* pos, size_t branchIndex, Array&& first, Rest&&... rest); - template - void fill(char* pos, size_t branchIndex, String&& first, Rest&&... rest); - - template - static StringTree concat(Params&&... params); - static StringTree&& concat(StringTree&& param) { return kj::mv(param); } - - template - static inline size_t flatSize(const T& t) { return t.size(); } - static inline size_t flatSize(String&& s) { return 0; } - static inline size_t flatSize(StringTree&& s) { return 0; } - - template - static inline size_t branchCount(const T& t) { return 0; } - static inline size_t branchCount(String&& s) { return 1; } - static inline size_t branchCount(StringTree&& s) { return 1; } - - template - friend StringTree strTree(Params&&... params); -}; - -inline StringTree&& KJ_STRINGIFY(StringTree&& tree) { return kj::mv(tree); } -inline const StringTree& KJ_STRINGIFY(const StringTree& tree) { return tree; } - -inline StringTree KJ_STRINGIFY(Array&& trees) { return StringTree(kj::mv(trees), ""); } - -template -StringTree strTree(Params&&... params); -// Build a StringTree by stringifying the given parameters and concatenating the results. -// If any of the parameters stringify to StringTree rvalues, they will be incorporated as -// branches to avoid a copy. - -// ======================================================================================= -// Inline implementation details - -namespace _ { // private - -template -char* fill(char* __restrict__ target, const StringTree& first, Rest&&... rest) { - // Make str() work with stringifiers that return StringTree by patching fill(). - - first.flattenTo(target); - return fill(target + first.size(), kj::fwd(rest)...); -} - -template constexpr bool isStringTree() { return false; } -template <> constexpr bool isStringTree() { return true; } - -inline StringTree&& toStringTreeOrCharSequence(StringTree&& tree) { return kj::mv(tree); } -inline StringTree toStringTreeOrCharSequence(String&& str) { return StringTree(kj::mv(str)); } - -template -inline auto toStringTreeOrCharSequence(T&& value) - -> decltype(toCharSequence(kj::fwd(value))) { - static_assert(!isStringTree>(), - "When passing a StringTree into kj::strTree(), either pass it by rvalue " - "(use kj::mv(value)) or explicitly call value.flatten() to make a copy."); - - return toCharSequence(kj::fwd(value)); -} - -} // namespace _ (private) - -struct StringTree::Branch { - size_t index; - // Index in `text` where this branch should be inserted. - - StringTree content; -}; - -template -void StringTree::visit(Func&& func) const { - size_t pos = 0; - for (auto& branch: branches) { - if (branch.index > pos) { - func(text.slice(pos, branch.index)); - pos = branch.index; - } - branch.content.visit(func); - } - if (text.size() > pos) { - func(text.slice(pos, text.size())); - } -} - -inline void StringTree::fill(char* pos, size_t branchIndex) { - KJ_IREQUIRE(pos == text.end() && branchIndex == branches.size(), - kj::str(text.end() - pos, ' ', branches.size() - branchIndex).cStr()); -} - -template -void StringTree::fill(char* pos, size_t branchIndex, First&& first, Rest&&... rest) { - pos = _::fill(pos, kj::fwd(first)); - fill(pos, branchIndex, kj::fwd(rest)...); -} - -template -void StringTree::fill(char* pos, size_t branchIndex, StringTree&& first, Rest&&... rest) { - branches[branchIndex].index = pos - text.begin(); - branches[branchIndex].content = kj::mv(first); - fill(pos, branchIndex + 1, kj::fwd(rest)...); -} - -template -void StringTree::fill(char* pos, size_t branchIndex, String&& first, Rest&&... rest) { - branches[branchIndex].index = pos - text.begin(); - branches[branchIndex].content = StringTree(kj::mv(first)); - fill(pos, branchIndex + 1, kj::fwd(rest)...); -} - -template -StringTree StringTree::concat(Params&&... params) { - StringTree result; - result.size_ = _::sum({params.size()...}); - result.text = heapString( - _::sum({StringTree::flatSize(kj::fwd(params))...})); - result.branches = heapArray( - _::sum({StringTree::branchCount(kj::fwd(params))...})); - result.fill(result.text.begin(), 0, kj::fwd(params)...); - return result; -} - -template -StringTree strTree(Params&&... params) { - return StringTree::concat(_::toStringTreeOrCharSequence(kj::fwd(params))...); -} - -} // namespace kj - -#endif // KJ_STRING_TREE_H_ diff --git a/phonelibs/capnp-cpp/include/kj/string.h b/phonelibs/capnp-cpp/include/kj/string.h deleted file mode 100644 index 9048be24170e5b..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/string.h +++ /dev/null @@ -1,534 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_STRING_H_ -#define KJ_STRING_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include -#include "array.h" -#include - -namespace kj { - -class StringPtr; -class String; - -class StringTree; // string-tree.h - -// Our STL string SFINAE trick does not work with GCC 4.7, but it works with Clang and GCC 4.8, so -// we'll just preprocess it out if not supported. -#if __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || _MSC_VER -#define KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP 1 -#endif - -// ======================================================================================= -// StringPtr -- A NUL-terminated ArrayPtr containing UTF-8 text. -// -// NUL bytes are allowed to appear before the end of the string. The only requirement is that -// a NUL byte appear immediately after the last byte of the content. This terminator byte is not -// counted in the string's size. - -class StringPtr { -public: - inline StringPtr(): content("", 1) {} - inline StringPtr(decltype(nullptr)): content("", 1) {} - inline StringPtr(const char* value): content(value, strlen(value) + 1) {} - inline StringPtr(const char* value, size_t size): content(value, size + 1) { - KJ_IREQUIRE(value[size] == '\0', "StringPtr must be NUL-terminated."); - } - inline StringPtr(const char* begin, const char* end): StringPtr(begin, end - begin) {} - inline StringPtr(const String& value); - -#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP - template ().c_str())> - inline StringPtr(const T& t): StringPtr(t.c_str()) {} - // Allow implicit conversion from any class that has a c_str() method (namely, std::string). - // We use a template trick to detect std::string in order to avoid including the header for - // those who don't want it. - - template ().c_str())> - inline operator T() const { return cStr(); } - // Allow implicit conversion to any class that has a c_str() method (namely, std::string). - // We use a template trick to detect std::string in order to avoid including the header for - // those who don't want it. -#endif - - inline operator ArrayPtr() const; - inline ArrayPtr asArray() const; - inline ArrayPtr asBytes() const { return asArray().asBytes(); } - // Result does not include NUL terminator. - - inline const char* cStr() const { return content.begin(); } - // Returns NUL-terminated string. - - inline size_t size() const { return content.size() - 1; } - // Result does not include NUL terminator. - - inline char operator[](size_t index) const { return content[index]; } - - inline const char* begin() const { return content.begin(); } - inline const char* end() const { return content.end() - 1; } - - inline bool operator==(decltype(nullptr)) const { return content.size() <= 1; } - inline bool operator!=(decltype(nullptr)) const { return content.size() > 1; } - - inline bool operator==(const StringPtr& other) const; - inline bool operator!=(const StringPtr& other) const { return !(*this == other); } - inline bool operator< (const StringPtr& other) const; - inline bool operator> (const StringPtr& other) const { return other < *this; } - inline bool operator<=(const StringPtr& other) const { return !(other < *this); } - inline bool operator>=(const StringPtr& other) const { return !(*this < other); } - - inline StringPtr slice(size_t start) const; - inline ArrayPtr slice(size_t start, size_t end) const; - // A string slice is only NUL-terminated if it is a suffix, so slice() has a one-parameter - // version that assumes end = size(). - - inline bool startsWith(const StringPtr& other) const; - inline bool endsWith(const StringPtr& other) const; - - inline Maybe findFirst(char c) const; - inline Maybe findLast(char c) const; - - template - T parseAs() const; - // Parse string as template number type. - // Integer numbers prefixed by "0x" and "0X" are parsed in base 16 (like strtoi with base 0). - // Integer numbers prefixed by "0" are parsed in base 10 (unlike strtoi with base 0). - // Overflowed integer numbers throw exception. - // Overflowed floating numbers return inf. - -private: - inline StringPtr(ArrayPtr content): content(content) {} - - ArrayPtr content; -}; - -inline bool operator==(const char* a, const StringPtr& b) { return b == a; } -inline bool operator!=(const char* a, const StringPtr& b) { return b != a; } - -template <> char StringPtr::parseAs() const; -template <> signed char StringPtr::parseAs() const; -template <> unsigned char StringPtr::parseAs() const; -template <> short StringPtr::parseAs() const; -template <> unsigned short StringPtr::parseAs() const; -template <> int StringPtr::parseAs() const; -template <> unsigned StringPtr::parseAs() const; -template <> long StringPtr::parseAs() const; -template <> unsigned long StringPtr::parseAs() const; -template <> long long StringPtr::parseAs() const; -template <> unsigned long long StringPtr::parseAs() const; -template <> float StringPtr::parseAs() const; -template <> double StringPtr::parseAs() const; - -// ======================================================================================= -// String -- A NUL-terminated Array containing UTF-8 text. -// -// NUL bytes are allowed to appear before the end of the string. The only requirement is that -// a NUL byte appear immediately after the last byte of the content. This terminator byte is not -// counted in the string's size. -// -// To allocate a String, you must call kj::heapString(). We do not implement implicit copying to -// the heap because this hides potential inefficiency from the developer. - -class String { -public: - String() = default; - inline String(decltype(nullptr)): content(nullptr) {} - inline String(char* value, size_t size, const ArrayDisposer& disposer); - // Does not copy. `size` does not include NUL terminator, but `value` must be NUL-terminated. - inline explicit String(Array buffer); - // Does not copy. Requires `buffer` ends with `\0`. - - inline operator ArrayPtr(); - inline operator ArrayPtr() const; - inline ArrayPtr asArray(); - inline ArrayPtr asArray() const; - inline ArrayPtr asBytes() { return asArray().asBytes(); } - inline ArrayPtr asBytes() const { return asArray().asBytes(); } - // Result does not include NUL terminator. - - inline Array releaseArray() { return kj::mv(content); } - // Disowns the backing array (which includes the NUL terminator) and returns it. The String value - // is clobbered (as if moved away). - - inline const char* cStr() const; - - inline size_t size() const; - // Result does not include NUL terminator. - - inline char operator[](size_t index) const; - inline char& operator[](size_t index); - - inline char* begin(); - inline char* end(); - inline const char* begin() const; - inline const char* end() const; - - inline bool operator==(decltype(nullptr)) const { return content.size() <= 1; } - inline bool operator!=(decltype(nullptr)) const { return content.size() > 1; } - - inline bool operator==(const StringPtr& other) const { return StringPtr(*this) == other; } - inline bool operator!=(const StringPtr& other) const { return StringPtr(*this) != other; } - inline bool operator< (const StringPtr& other) const { return StringPtr(*this) < other; } - inline bool operator> (const StringPtr& other) const { return StringPtr(*this) > other; } - inline bool operator<=(const StringPtr& other) const { return StringPtr(*this) <= other; } - inline bool operator>=(const StringPtr& other) const { return StringPtr(*this) >= other; } - - inline bool startsWith(const StringPtr& other) const { return StringPtr(*this).startsWith(other);} - inline bool endsWith(const StringPtr& other) const { return StringPtr(*this).endsWith(other); } - - inline StringPtr slice(size_t start) const { return StringPtr(*this).slice(start); } - inline ArrayPtr slice(size_t start, size_t end) const { - return StringPtr(*this).slice(start, end); - } - - inline Maybe findFirst(char c) const { return StringPtr(*this).findFirst(c); } - inline Maybe findLast(char c) const { return StringPtr(*this).findLast(c); } - - template - T parseAs() const { return StringPtr(*this).parseAs(); } - // Parse as number - -private: - Array content; -}; - -inline bool operator==(const char* a, const String& b) { return b == a; } -inline bool operator!=(const char* a, const String& b) { return b != a; } - -String heapString(size_t size); -// Allocate a String of the given size on the heap, not including NUL terminator. The NUL -// terminator will be initialized automatically but the rest of the content is not initialized. - -String heapString(const char* value); -String heapString(const char* value, size_t size); -String heapString(StringPtr value); -String heapString(const String& value); -String heapString(ArrayPtr value); -// Allocates a copy of the given value on the heap. - -// ======================================================================================= -// Magic str() function which transforms parameters to text and concatenates them into one big -// String. - -namespace _ { // private - -inline size_t sum(std::initializer_list nums) { - size_t result = 0; - for (auto num: nums) { - result += num; - } - return result; -} - -inline char* fill(char* ptr) { return ptr; } - -template -char* fill(char* __restrict__ target, const StringTree& first, Rest&&... rest); -// Make str() work with stringifiers that return StringTree by patching fill(). -// -// Defined in string-tree.h. - -template -char* fill(char* __restrict__ target, const First& first, Rest&&... rest) { - auto i = first.begin(); - auto end = first.end(); - while (i != end) { - *target++ = *i++; - } - return fill(target, kj::fwd(rest)...); -} - -template -String concat(Params&&... params) { - // Concatenate a bunch of containers into a single Array. The containers can be anything that - // is iterable and whose elements can be converted to `char`. - - String result = heapString(sum({params.size()...})); - fill(result.begin(), kj::fwd(params)...); - return result; -} - -inline String concat(String&& arr) { - return kj::mv(arr); -} - -struct Stringifier { - // This is a dummy type with only one instance: STR (below). To make an arbitrary type - // stringifiable, define `operator*(Stringifier, T)` to return an iterable container of `char`. - // The container type must have a `size()` method. Be sure to declare the operator in the same - // namespace as `T` **or** in the global scope. - // - // A more usual way to accomplish what we're doing here would be to require that you define - // a function like `toString(T)` and then rely on argument-dependent lookup. However, this has - // the problem that it pollutes other people's namespaces and even the global namespace. For - // example, some other project may already have functions called `toString` which do something - // different. Declaring `operator*` with `Stringifier` as the left operand cannot conflict with - // anything. - - inline ArrayPtr operator*(ArrayPtr s) const { return s; } - inline ArrayPtr operator*(ArrayPtr s) const { return s; } - inline ArrayPtr operator*(const Array& s) const { return s; } - inline ArrayPtr operator*(const Array& s) const { return s; } - template - inline ArrayPtr operator*(const CappedArray& s) const { return s; } - template - inline ArrayPtr operator*(const FixedArray& s) const { return s; } - inline ArrayPtr operator*(const char* s) const { return arrayPtr(s, strlen(s)); } - inline ArrayPtr operator*(const String& s) const { return s.asArray(); } - inline ArrayPtr operator*(const StringPtr& s) const { return s.asArray(); } - - inline Range operator*(const Range& r) const { return r; } - inline Repeat operator*(const Repeat& r) const { return r; } - - inline FixedArray operator*(char c) const { - FixedArray result; - result[0] = c; - return result; - } - - StringPtr operator*(decltype(nullptr)) const; - StringPtr operator*(bool b) const; - - CappedArray operator*(signed char i) const; - CappedArray operator*(unsigned char i) const; - CappedArray operator*(short i) const; - CappedArray operator*(unsigned short i) const; - CappedArray operator*(int i) const; - CappedArray operator*(unsigned int i) const; - CappedArray operator*(long i) const; - CappedArray operator*(unsigned long i) const; - CappedArray operator*(long long i) const; - CappedArray operator*(unsigned long long i) const; - CappedArray operator*(float f) const; - CappedArray operator*(double f) const; - CappedArray operator*(const void* s) const; - - template - String operator*(ArrayPtr arr) const; - template - String operator*(const Array& arr) const; - -#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP // supports expression SFINAE? - template ().toString())> - inline Result operator*(T&& value) const { return kj::fwd(value).toString(); } -#endif -}; -static KJ_CONSTEXPR(const) Stringifier STR = Stringifier(); - -} // namespace _ (private) - -template -auto toCharSequence(T&& value) -> decltype(_::STR * kj::fwd(value)) { - // Returns an iterable of chars that represent a textual representation of the value, suitable - // for debugging. - // - // Most users should use str() instead, but toCharSequence() may occasionally be useful to avoid - // heap allocation overhead that str() implies. - // - // To specialize this function for your type, see KJ_STRINGIFY. - - return _::STR * kj::fwd(value); -} - -CappedArray hex(unsigned char i); -CappedArray hex(unsigned short i); -CappedArray hex(unsigned int i); -CappedArray hex(unsigned long i); -CappedArray hex(unsigned long long i); - -template -String str(Params&&... params) { - // Magic function which builds a string from a bunch of arbitrary values. Example: - // str(1, " / ", 2, " = ", 0.5) - // returns: - // "1 / 2 = 0.5" - // To teach `str` how to stringify a type, see `Stringifier`. - - return _::concat(toCharSequence(kj::fwd(params))...); -} - -inline String str(String&& s) { return mv(s); } -// Overload to prevent redundant allocation. - -template -String strArray(T&& arr, const char* delim) { - size_t delimLen = strlen(delim); - KJ_STACK_ARRAY(decltype(_::STR * arr[0]), pieces, kj::size(arr), 8, 32); - size_t size = 0; - for (size_t i = 0; i < kj::size(arr); i++) { - if (i > 0) size += delimLen; - pieces[i] = _::STR * arr[i]; - size += pieces[i].size(); - } - - String result = heapString(size); - char* pos = result.begin(); - for (size_t i = 0; i < kj::size(arr); i++) { - if (i > 0) { - memcpy(pos, delim, delimLen); - pos += delimLen; - } - pos = _::fill(pos, pieces[i]); - } - return result; -} - -namespace _ { // private - -template -inline String Stringifier::operator*(ArrayPtr arr) const { - return strArray(arr, ", "); -} - -template -inline String Stringifier::operator*(const Array& arr) const { - return strArray(arr, ", "); -} - -} // namespace _ (private) - -#define KJ_STRINGIFY(...) operator*(::kj::_::Stringifier, __VA_ARGS__) -// Defines a stringifier for a custom type. Example: -// -// class Foo {...}; -// inline StringPtr KJ_STRINGIFY(const Foo& foo) { return foo.name(); } -// -// This allows Foo to be passed to str(). -// -// The function should be declared either in the same namespace as the target type or in the global -// namespace. It can return any type which is an iterable container of chars. - -// ======================================================================================= -// Inline implementation details. - -inline StringPtr::StringPtr(const String& value): content(value.begin(), value.size() + 1) {} - -inline StringPtr::operator ArrayPtr() const { - return content.slice(0, content.size() - 1); -} - -inline ArrayPtr StringPtr::asArray() const { - return content.slice(0, content.size() - 1); -} - -inline bool StringPtr::operator==(const StringPtr& other) const { - return content.size() == other.content.size() && - memcmp(content.begin(), other.content.begin(), content.size() - 1) == 0; -} - -inline bool StringPtr::operator<(const StringPtr& other) const { - bool shorter = content.size() < other.content.size(); - int cmp = memcmp(content.begin(), other.content.begin(), - shorter ? content.size() : other.content.size()); - return cmp < 0 || (cmp == 0 && shorter); -} - -inline StringPtr StringPtr::slice(size_t start) const { - return StringPtr(content.slice(start, content.size())); -} -inline ArrayPtr StringPtr::slice(size_t start, size_t end) const { - return content.slice(start, end); -} - -inline bool StringPtr::startsWith(const StringPtr& other) const { - return other.content.size() <= content.size() && - memcmp(content.begin(), other.content.begin(), other.size()) == 0; -} -inline bool StringPtr::endsWith(const StringPtr& other) const { - return other.content.size() <= content.size() && - memcmp(end() - other.size(), other.content.begin(), other.size()) == 0; -} - -inline Maybe StringPtr::findFirst(char c) const { - const char* pos = reinterpret_cast(memchr(content.begin(), c, size())); - if (pos == nullptr) { - return nullptr; - } else { - return pos - content.begin(); - } -} - -inline Maybe StringPtr::findLast(char c) const { - for (size_t i = size(); i > 0; --i) { - if (content[i-1] == c) { - return i-1; - } - } - return nullptr; -} - -inline String::operator ArrayPtr() { - return content == nullptr ? ArrayPtr(nullptr) : content.slice(0, content.size() - 1); -} -inline String::operator ArrayPtr() const { - return content == nullptr ? ArrayPtr(nullptr) : content.slice(0, content.size() - 1); -} - -inline ArrayPtr String::asArray() { - return content == nullptr ? ArrayPtr(nullptr) : content.slice(0, content.size() - 1); -} -inline ArrayPtr String::asArray() const { - return content == nullptr ? ArrayPtr(nullptr) : content.slice(0, content.size() - 1); -} - -inline const char* String::cStr() const { return content == nullptr ? "" : content.begin(); } - -inline size_t String::size() const { return content == nullptr ? 0 : content.size() - 1; } - -inline char String::operator[](size_t index) const { return content[index]; } -inline char& String::operator[](size_t index) { return content[index]; } - -inline char* String::begin() { return content == nullptr ? nullptr : content.begin(); } -inline char* String::end() { return content == nullptr ? nullptr : content.end() - 1; } -inline const char* String::begin() const { return content == nullptr ? nullptr : content.begin(); } -inline const char* String::end() const { return content == nullptr ? nullptr : content.end() - 1; } - -inline String::String(char* value, size_t size, const ArrayDisposer& disposer) - : content(value, size + 1, disposer) { - KJ_IREQUIRE(value[size] == '\0', "String must be NUL-terminated."); -} - -inline String::String(Array buffer): content(kj::mv(buffer)) { - KJ_IREQUIRE(content.size() > 0 && content.back() == '\0', "String must be NUL-terminated."); -} - -inline String heapString(const char* value) { - return heapString(value, strlen(value)); -} -inline String heapString(StringPtr value) { - return heapString(value.begin(), value.size()); -} -inline String heapString(const String& value) { - return heapString(value.begin(), value.size()); -} -inline String heapString(ArrayPtr value) { - return heapString(value.begin(), value.size()); -} - -} // namespace kj - -#endif // KJ_STRING_H_ diff --git a/phonelibs/capnp-cpp/include/kj/test.h b/phonelibs/capnp-cpp/include/kj/test.h deleted file mode 100644 index 69e1c80840b85d..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/test.h +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_TEST_H_ -#define KJ_TEST_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "debug.h" -#include "vector.h" -#include "function.h" - -namespace kj { - -class TestRunner; - -class TestCase { -public: - TestCase(const char* file, uint line, const char* description); - ~TestCase(); - - virtual void run() = 0; - -private: - const char* file; - uint line; - const char* description; - TestCase* next; - TestCase** prev; - bool matchedFilter; - - friend class TestRunner; -}; - -#define KJ_TEST(description) \ - /* Make sure the linker fails if tests are not in anonymous namespaces. */ \ - extern int KJ_CONCAT(YouMustWrapTestsInAnonymousNamespace, __COUNTER__) KJ_UNUSED; \ - class KJ_UNIQUE_NAME(TestCase): public ::kj::TestCase { \ - public: \ - KJ_UNIQUE_NAME(TestCase)(): ::kj::TestCase(__FILE__, __LINE__, description) {} \ - void run() override; \ - } KJ_UNIQUE_NAME(testCase); \ - void KJ_UNIQUE_NAME(TestCase)::run() - -#if _MSC_VER -#define KJ_INDIRECT_EXPAND(m, vargs) m vargs -#define KJ_FAIL_EXPECT(...) \ - KJ_INDIRECT_EXPAND(KJ_LOG, (ERROR , __VA_ARGS__)); -#define KJ_EXPECT(cond, ...) \ - if (cond); else KJ_INDIRECT_EXPAND(KJ_FAIL_EXPECT, ("failed: expected " #cond , __VA_ARGS__)) -#else -#define KJ_FAIL_EXPECT(...) \ - KJ_LOG(ERROR, ##__VA_ARGS__); -#define KJ_EXPECT(cond, ...) \ - if (cond); else KJ_FAIL_EXPECT("failed: expected " #cond, ##__VA_ARGS__) -#endif - -#define KJ_EXPECT_THROW_RECOVERABLE(type, code) \ - do { \ - KJ_IF_MAYBE(e, ::kj::runCatchingExceptions([&]() { code; })) { \ - KJ_EXPECT(e->getType() == ::kj::Exception::Type::type, \ - "code threw wrong exception type: " #code, e->getType()); \ - } else { \ - KJ_FAIL_EXPECT("code did not throw: " #code); \ - } \ - } while (false) - -#define KJ_EXPECT_THROW_RECOVERABLE_MESSAGE(message, code) \ - do { \ - KJ_IF_MAYBE(e, ::kj::runCatchingExceptions([&]() { code; })) { \ - KJ_EXPECT(::kj::_::hasSubstring(e->getDescription(), message), \ - "exception description didn't contain expected substring", e->getDescription()); \ - } else { \ - KJ_FAIL_EXPECT("code did not throw: " #code); \ - } \ - } while (false) - -#if KJ_NO_EXCEPTIONS -#define KJ_EXPECT_THROW(type, code) \ - do { \ - KJ_EXPECT(::kj::_::expectFatalThrow(type, nullptr, [&]() { code; })); \ - } while (false) -#define KJ_EXPECT_THROW_MESSAGE(message, code) \ - do { \ - KJ_EXPECT(::kj::_::expectFatalThrow(nullptr, kj::StringPtr(message), [&]() { code; })); \ - } while (false) -#else -#define KJ_EXPECT_THROW KJ_EXPECT_THROW_RECOVERABLE -#define KJ_EXPECT_THROW_MESSAGE KJ_EXPECT_THROW_RECOVERABLE_MESSAGE -#endif - -#define KJ_EXPECT_LOG(level, substring) \ - ::kj::_::LogExpectation KJ_UNIQUE_NAME(_kjLogExpectation)(::kj::LogSeverity::level, substring) -// Expects that a log message with the given level and substring text will be printed within -// the current scope. This message will not cause the test to fail, even if it is an error. - -// ======================================================================================= - -namespace _ { // private - -bool hasSubstring(kj::StringPtr haystack, kj::StringPtr needle); - -#if KJ_NO_EXCEPTIONS -bool expectFatalThrow(Maybe type, Maybe message, - Function code); -// Expects that the given code will throw a fatal exception matching the given type and/or message. -// Since exceptions are disabled, the test will fork() and run in a subprocess. On Windows, where -// fork() is not available, this always returns true. -#endif - -class LogExpectation: public ExceptionCallback { -public: - LogExpectation(LogSeverity severity, StringPtr substring); - ~LogExpectation(); - - void logMessage(LogSeverity severity, const char* file, int line, int contextDepth, - String&& text) override; - -private: - LogSeverity severity; - StringPtr substring; - bool seen; - UnwindDetector unwindDetector; -}; - -class GlobFilter { - // Implements glob filters for the --filter flag. - // - // Exposed in header only for testing. - -public: - explicit GlobFilter(const char* pattern); - explicit GlobFilter(ArrayPtr pattern); - - bool matches(StringPtr name); - -private: - String pattern; - Vector states; - - void applyState(char c, int state); -}; - -} // namespace _ (private) -} // namespace kj - -#endif // KJ_TEST_H_ diff --git a/phonelibs/capnp-cpp/include/kj/thread.h b/phonelibs/capnp-cpp/include/kj/thread.h deleted file mode 100644 index b17b88c520a2d8..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/thread.h +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_THREAD_H_ -#define KJ_THREAD_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "common.h" -#include "function.h" -#include "exception.h" - -namespace kj { - -class Thread { - // A thread! Pass a lambda to the constructor, and it runs in the thread. The destructor joins - // the thread. If the function throws an exception, it is rethrown from the thread's destructor - // (if not unwinding from another exception). - -public: - explicit Thread(Function func); - KJ_DISALLOW_COPY(Thread); - - ~Thread() noexcept(false); - -#if !_WIN32 - void sendSignal(int signo); - // Send a Unix signal to the given thread, using pthread_kill or an equivalent. -#endif - - void detach(); - // Don't join the thread in ~Thread(). - -private: - struct ThreadState { - Function func; - kj::Maybe exception; - - unsigned int refcount; - // Owned by the parent thread and the child thread. - - void unref(); - }; - ThreadState* state; - -#if _WIN32 - void* threadHandle; -#else - unsigned long long threadId; // actually pthread_t -#endif - bool detached = false; - -#if _WIN32 - static unsigned long __stdcall runThread(void* ptr); -#else - static void* runThread(void* ptr); -#endif -}; - -} // namespace kj - -#endif // KJ_THREAD_H_ diff --git a/phonelibs/capnp-cpp/include/kj/threadlocal.h b/phonelibs/capnp-cpp/include/kj/threadlocal.h deleted file mode 100644 index 67d0db60ef7d6c..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/threadlocal.h +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) 2014, Jason Choy -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_THREADLOCAL_H_ -#define KJ_THREADLOCAL_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif -// This file declares a macro `KJ_THREADLOCAL_PTR` for declaring thread-local pointer-typed -// variables. Use like: -// KJ_THREADLOCAL_PTR(MyType) foo = nullptr; -// This is equivalent to: -// thread_local MyType* foo = nullptr; -// This can only be used at the global scope. -// -// AVOID USING THIS. Use of thread-locals is discouraged because they often have many of the same -// properties as singletons: http://www.object-oriented-security.org/lets-argue/singletons -// -// Also, thread-locals tend to be hostile to event-driven code, which can be particularly -// surprising when using fibers (all fibers in the same thread will share the same threadlocals, -// even though they do not share a stack). -// -// That said, thread-locals are sometimes needed for runtime logistics in the KJ framework. For -// example, the current exception callback and current EventLoop are stored as thread-local -// pointers. Since KJ only ever needs to store pointers, not values, we avoid the question of -// whether these values' destructors need to be run, and we avoid the need for heap allocation. - -#include "common.h" - -#if !defined(KJ_USE_PTHREAD_THREADLOCAL) && defined(__APPLE__) -#include "TargetConditionals.h" -#if TARGET_OS_IPHONE -// iOS apparently does not support __thread (nor C++11 thread_local). -#define KJ_USE_PTHREAD_TLS 1 -#endif -#endif - -#if KJ_USE_PTHREAD_TLS -#include -#endif - -namespace kj { - -#if KJ_USE_PTHREAD_TLS -// If __thread is unavailable, we'll fall back to pthreads. - -#define KJ_THREADLOCAL_PTR(type) \ - namespace { struct KJ_UNIQUE_NAME(_kj_TlpTag); } \ - static ::kj::_::ThreadLocalPtr< type, KJ_UNIQUE_NAME(_kj_TlpTag)> -// Hack: In order to ensure each thread-local results in a unique template instance, we declare -// a one-off dummy type to use as the second type parameter. - -namespace _ { // private - -template -class ThreadLocalPtr { - // Hacky type to emulate __thread T*. We need a separate instance of the ThreadLocalPtr template - // for every thread-local variable, because we don't want to require a global constructor, and in - // order to initialize the TLS on first use we need to use a local static variable (in getKey()). - // Each template instance will get a separate such local static variable, fulfilling our need. - -public: - ThreadLocalPtr() = default; - constexpr ThreadLocalPtr(decltype(nullptr)) {} - // Allow initialization to nullptr without a global constructor. - - inline ThreadLocalPtr& operator=(T* val) { - pthread_setspecific(getKey(), val); - return *this; - } - - inline operator T*() const { - return get(); - } - - inline T& operator*() const { - return *get(); - } - - inline T* operator->() const { - return get(); - } - -private: - inline T* get() const { - return reinterpret_cast(pthread_getspecific(getKey())); - } - - inline static pthread_key_t getKey() { - static pthread_key_t key = createKey(); - return key; - } - - static pthread_key_t createKey() { - pthread_key_t key; - pthread_key_create(&key, 0); - return key; - } -}; - -} // namespace _ (private) - -#elif __GNUC__ - -#define KJ_THREADLOCAL_PTR(type) static __thread type* -// GCC's __thread is lighter-weight than thread_local and is good enough for our purposes. - -#else - -#define KJ_THREADLOCAL_PTR(type) static thread_local type* - -#endif // KJ_USE_PTHREAD_TLS - -} // namespace kj - -#endif // KJ_THREADLOCAL_H_ diff --git a/phonelibs/capnp-cpp/include/kj/time.h b/phonelibs/capnp-cpp/include/kj/time.h deleted file mode 100644 index 37d7b8a90eea91..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/time.h +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright (c) 2014 Google Inc. (contributed by Remy Blank ) -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_TIME_H_ -#define KJ_TIME_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "async.h" -#include "units.h" -#include - -namespace kj { -namespace _ { // private - -class NanosecondLabel; -class TimeLabel; -class DateLabel; - -} // namespace _ (private) - -using Duration = Quantity; -// A time value, in nanoseconds. - -constexpr Duration NANOSECONDS = unit(); -constexpr Duration MICROSECONDS = 1000 * NANOSECONDS; -constexpr Duration MILLISECONDS = 1000 * MICROSECONDS; -constexpr Duration SECONDS = 1000 * MILLISECONDS; -constexpr Duration MINUTES = 60 * SECONDS; -constexpr Duration HOURS = 60 * MINUTES; -constexpr Duration DAYS = 24 * HOURS; - -using TimePoint = Absolute; -// An absolute time measured by some particular instance of `Timer`. `Time`s from two different -// `Timer`s may be measured from different origins and so are not necessarily compatible. - -using Date = Absolute; -// A point in real-world time, measured relative to the Unix epoch (Jan 1, 1970 00:00:00 UTC). - -constexpr Date UNIX_EPOCH = origin(); -// The `Date` representing Jan 1, 1970 00:00:00 UTC. - -class Clock { - // Interface to read the current date and time. -public: - virtual Date now() = 0; -}; - -Clock& nullClock(); -// A clock which always returns UNIX_EPOCH as the current time. Useful when you don't care about -// time. - -class Timer { - // Interface to time and timer functionality. - // - // Each `Timer` may have a different origin, and some `Timer`s may in fact tick at a different - // rate than real time (e.g. a `Timer` could represent CPU time consumed by a thread). However, - // all `Timer`s are monotonic: time will never appear to move backwards, even if the calendar - // date as tracked by the system is manually modified. - -public: - virtual TimePoint now() = 0; - // Returns the current value of a clock that moves steadily forward, independent of any - // changes in the wall clock. The value is updated every time the event loop waits, - // and is constant in-between waits. - - virtual Promise atTime(TimePoint time) = 0; - // Returns a promise that returns as soon as now() >= time. - - virtual Promise afterDelay(Duration delay) = 0; - // Equivalent to atTime(now() + delay). - - template - Promise timeoutAt(TimePoint time, Promise&& promise) KJ_WARN_UNUSED_RESULT; - // Return a promise equivalent to `promise` but which throws an exception (and cancels the - // original promise) if it hasn't completed by `time`. The thrown exception is of type - // "OVERLOADED". - - template - Promise timeoutAfter(Duration delay, Promise&& promise) KJ_WARN_UNUSED_RESULT; - // Return a promise equivalent to `promise` but which throws an exception (and cancels the - // original promise) if it hasn't completed after `delay` from now. The thrown exception is of - // type "OVERLOADED". - -private: - static kj::Exception makeTimeoutException(); -}; - -class TimerImpl final: public Timer { - // Implementation of Timer that expects an external caller -- usually, the EventPort - // implementation -- to tell it when time has advanced. - -public: - TimerImpl(TimePoint startTime); - ~TimerImpl() noexcept(false); - - Maybe nextEvent(); - // Returns the time at which the next scheduled timer event will occur, or null if no timer - // events are scheduled. - - Maybe timeoutToNextEvent(TimePoint start, Duration unit, uint64_t max); - // Convenience method which computes a timeout value to pass to an event-waiting system call to - // cause it to time out when the next timer event occurs. - // - // `start` is the time at which the timeout starts counting. This is typically not the same as - // now() since some time may have passed since the last time advanceTo() was called. - // - // `unit` is the time unit in which the timeout is measured. This is often MILLISECONDS. Note - // that this method will fractional values *up*, to guarantee that the returned timeout waits - // until just *after* the time the event is scheduled. - // - // The timeout will be clamped to `max`. Use this to avoid an overflow if e.g. the OS wants a - // 32-bit value or a signed value. - // - // Returns nullptr if there are no future events. - - void advanceTo(TimePoint newTime); - // Set the time to `time` and fire any at() events that have been passed. - - // implements Timer ---------------------------------------------------------- - TimePoint now() override; - Promise atTime(TimePoint time) override; - Promise afterDelay(Duration delay) override; - -private: - struct Impl; - class TimerPromiseAdapter; - TimePoint time; - Own impl; -}; - -// ======================================================================================= -// inline implementation details - -template -Promise Timer::timeoutAt(TimePoint time, Promise&& promise) { - return promise.exclusiveJoin(atTime(time).then([]() -> kj::Promise { - return makeTimeoutException(); - })); -} - -template -Promise Timer::timeoutAfter(Duration delay, Promise&& promise) { - return promise.exclusiveJoin(afterDelay(delay).then([]() -> kj::Promise { - return makeTimeoutException(); - })); -} - -inline TimePoint TimerImpl::now() { return time; } - -} // namespace kj - -#endif // KJ_TIME_H_ diff --git a/phonelibs/capnp-cpp/include/kj/tuple.h b/phonelibs/capnp-cpp/include/kj/tuple.h deleted file mode 100644 index 2ea7276ec5af9a..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/tuple.h +++ /dev/null @@ -1,364 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -// This file defines a notion of tuples that is simpler that `std::tuple`. It works as follows: -// - `kj::Tuple is the type of a tuple of an A, a B, and a C. -// - `kj::tuple(a, b, c)` returns a tuple containing a, b, and c. If any of these are themselves -// tuples, they are flattened, so `tuple(a, tuple(b, c), d)` is equivalent to `tuple(a, b, c, d)`. -// - `kj::get(myTuple)` returns the element of `myTuple` at index n. -// - `kj::apply(func, ...)` calls func on the following arguments after first expanding any tuples -// in the argument list. So `kj::apply(foo, a, tuple(b, c), d)` would call `foo(a, b, c, d)`. -// -// Note that: -// - The type `Tuple` is a synonym for T. This is why `get` and `apply` are not members of the -// type. -// - It is illegal for an element of `Tuple` to itself be a tuple, as tuples are meant to be -// flattened. -// - It is illegal for an element of `Tuple` to be a reference, due to problems this would cause -// with type inference and `tuple()`. - -#ifndef KJ_TUPLE_H_ -#define KJ_TUPLE_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "common.h" - -namespace kj { -namespace _ { // private - -template -struct TypeByIndex_; -template -struct TypeByIndex_<0, First, Rest...> { - typedef First Type; -}; -template -struct TypeByIndex_ - : public TypeByIndex_ {}; -template -struct TypeByIndex_ { - static_assert(index != index, "Index out-of-range."); -}; -template -using TypeByIndex = typename TypeByIndex_::Type; -// Chose a particular type out of a list of types, by index. - -template -struct Indexes {}; -// Dummy helper type that just encapsulates a sequential list of indexes, so that we can match -// templates against them and unpack them with '...'. - -template -struct MakeIndexes_: public MakeIndexes_ {}; -template -struct MakeIndexes_<0, prefix...> { - typedef Indexes Type; -}; -template -using MakeIndexes = typename MakeIndexes_::Type; -// Equivalent to Indexes<0, 1, 2, ..., end>. - -template -class Tuple; -template -inline TypeByIndex& getImpl(Tuple& tuple); -template -inline TypeByIndex&& getImpl(Tuple&& tuple); -template -inline const TypeByIndex& getImpl(const Tuple& tuple); - -template -struct TupleElement { - // Encapsulates one element of a tuple. The actual tuple implementation multiply-inherits - // from a TupleElement for each element, which is more efficient than a recursive definition. - - T value; - TupleElement() = default; - constexpr inline TupleElement(const T& value): value(value) {} - constexpr inline TupleElement(T&& value): value(kj::mv(value)) {} -}; - -template -struct TupleElement { - // If tuples contained references, one of the following would have to be true: - // - `auto x = tuple(y, z)` would cause x to be a tuple of references to y and z, which is - // probably not what you expected. - // - `Tuple x = tuple(a, b)` would not work, because `tuple()` returned - // Tuple. - static_assert(sizeof(T*) == 0, "Sorry, tuples cannot contain references."); -}; - -template -struct TupleElement> { - static_assert(sizeof(Tuple*) == 0, - "Tuples cannot contain other tuples -- they should be flattened."); -}; - -template -struct TupleImpl; - -template -struct TupleImpl, Types...> - : public TupleElement... { - // Implementation of Tuple. The only reason we need this rather than rolling this into class - // Tuple (below) is so that we can get "indexes" as an unpackable list. - - static_assert(sizeof...(indexes) == sizeof...(Types), "Incorrect use of TupleImpl."); - - template - inline TupleImpl(Params&&... params) - : TupleElement(kj::fwd(params))... { - // Work around Clang 3.2 bug 16303 where this is not detected. (Unfortunately, Clang sometimes - // segfaults instead.) - static_assert(sizeof...(params) == sizeof...(indexes), - "Wrong number of parameters to Tuple constructor."); - } - - template - constexpr inline TupleImpl(Tuple&& other) - : TupleElement(kj::mv(getImpl(other)))... {} - template - constexpr inline TupleImpl(Tuple& other) - : TupleElement(getImpl(other))... {} - template - constexpr inline TupleImpl(const Tuple& other) - : TupleElement(getImpl(other))... {} -}; - -struct MakeTupleFunc; - -template -class Tuple { - // The actual Tuple class (used for tuples of size other than 1). - -public: - template - constexpr inline Tuple(Tuple&& other): impl(kj::mv(other)) {} - template - constexpr inline Tuple(Tuple& other): impl(other) {} - template - constexpr inline Tuple(const Tuple& other): impl(other) {} - -private: - template - constexpr Tuple(Params&&... params): impl(kj::fwd(params)...) {} - - TupleImpl, T...> impl; - - template - friend inline TypeByIndex& getImpl(Tuple& tuple); - template - friend inline TypeByIndex&& getImpl(Tuple&& tuple); - template - friend inline const TypeByIndex& getImpl(const Tuple& tuple); - friend struct MakeTupleFunc; -}; - -template <> -class Tuple<> { - // Simplified zero-member version of Tuple. In particular this is important to make sure that - // Tuple<>() is constexpr. -}; - -template -class Tuple; -// Single-element tuple should never be used. The public API should ensure this. - -template -inline TypeByIndex& getImpl(Tuple& tuple) { - // Get member of a Tuple by index, e.g. `get<2>(myTuple)`. - static_assert(index < sizeof...(T), "Tuple element index out-of-bounds."); - return implicitCast>&>(tuple.impl).value; -} -template -inline TypeByIndex&& getImpl(Tuple&& tuple) { - // Get member of a Tuple by index, e.g. `get<2>(myTuple)`. - static_assert(index < sizeof...(T), "Tuple element index out-of-bounds."); - return kj::mv(implicitCast>&>(tuple.impl).value); -} -template -inline const TypeByIndex& getImpl(const Tuple& tuple) { - // Get member of a Tuple by index, e.g. `get<2>(myTuple)`. - static_assert(index < sizeof...(T), "Tuple element index out-of-bounds."); - return implicitCast>&>(tuple.impl).value; -} -template -inline T&& getImpl(T&& value) { - // Get member of a Tuple by index, e.g. `getImpl<2>(myTuple)`. - - // Non-tuples are equivalent to one-element tuples. - static_assert(index == 0, "Tuple element index out-of-bounds."); - return kj::fwd(value); -} - - -template -struct ExpandAndApplyResult_; -// Template which computes the return type of applying Func to T... after flattening tuples. -// SoFar starts as Tuple<> and accumulates the flattened parameter types -- so after this template -// is recursively expanded, T... is empty and SoFar is a Tuple containing all the parameters. - -template -struct ExpandAndApplyResult_, First, Rest...> - : public ExpandAndApplyResult_, Rest...> {}; -template -struct ExpandAndApplyResult_, Tuple, Rest...> - : public ExpandAndApplyResult_, FirstTypes&&..., Rest...> {}; -template -struct ExpandAndApplyResult_, Tuple&, Rest...> - : public ExpandAndApplyResult_, FirstTypes&..., Rest...> {}; -template -struct ExpandAndApplyResult_, const Tuple&, Rest...> - : public ExpandAndApplyResult_, const FirstTypes&..., Rest...> {}; -template -struct ExpandAndApplyResult_> { - typedef decltype(instance()(instance()...)) Type; -}; -template -using ExpandAndApplyResult = typename ExpandAndApplyResult_, T...>::Type; -// Computes the expected return type of `expandAndApply()`. - -template -inline auto expandAndApply(Func&& func) -> ExpandAndApplyResult { - return func(); -} - -template -struct ExpandAndApplyFunc { - Func&& func; - First&& first; - ExpandAndApplyFunc(Func&& func, First&& first) - : func(kj::fwd(func)), first(kj::fwd(first)) {} - template - auto operator()(T&&... params) - -> decltype(this->func(kj::fwd(first), kj::fwd(params)...)) { - return this->func(kj::fwd(first), kj::fwd(params)...); - } -}; - -template -inline auto expandAndApply(Func&& func, First&& first, Rest&&... rest) - -> ExpandAndApplyResult { - - return expandAndApply( - ExpandAndApplyFunc(kj::fwd(func), kj::fwd(first)), - kj::fwd(rest)...); -} - -template -inline auto expandAndApply(Func&& func, Tuple&& first, Rest&&... rest) - -> ExpandAndApplyResult { - return expandAndApplyWithIndexes(MakeIndexes(), - kj::fwd(func), kj::mv(first), kj::fwd(rest)...); -} - -template -inline auto expandAndApply(Func&& func, Tuple& first, Rest&&... rest) - -> ExpandAndApplyResult { - return expandAndApplyWithIndexes(MakeIndexes(), - kj::fwd(func), first, kj::fwd(rest)...); -} - -template -inline auto expandAndApply(Func&& func, const Tuple& first, Rest&&... rest) - -> ExpandAndApplyResult { - return expandAndApplyWithIndexes(MakeIndexes(), - kj::fwd(func), first, kj::fwd(rest)...); -} - -template -inline auto expandAndApplyWithIndexes( - Indexes, Func&& func, Tuple&& first, Rest&&... rest) - -> ExpandAndApplyResult { - return expandAndApply(kj::fwd(func), kj::mv(getImpl(first))..., - kj::fwd(rest)...); -} - -template -inline auto expandAndApplyWithIndexes( - Indexes, Func&& func, const Tuple& first, Rest&&... rest) - -> ExpandAndApplyResult { - return expandAndApply(kj::fwd(func), getImpl(first)..., - kj::fwd(rest)...); -} - -struct MakeTupleFunc { - template - Tuple...> operator()(Params&&... params) { - return Tuple...>(kj::fwd(params)...); - } - template - Decay operator()(Param&& param) { - return kj::fwd(param); - } -}; - -} // namespace _ (private) - -template struct Tuple_ { typedef _::Tuple Type; }; -template struct Tuple_ { typedef T Type; }; - -template using Tuple = typename Tuple_::Type; -// Tuple type. `Tuple` (i.e. a single-element tuple) is a synonym for `T`. Tuples of size -// other than 1 expand to an internal type. Either way, you can construct a Tuple using -// `kj::tuple(...)`, get an element by index `i` using `kj::get(myTuple)`, and expand the tuple -// as arguments to a function using `kj::apply(func, myTuple)`. -// -// Tuples are always flat -- that is, no element of a Tuple is ever itself a Tuple. If you -// construct a tuple from other tuples, the elements are flattened and concatenated. - -template -inline auto tuple(Params&&... params) - -> decltype(_::expandAndApply(_::MakeTupleFunc(), kj::fwd(params)...)) { - // Construct a new tuple from the given values. Any tuples in the argument list will be - // flattened into the result. - return _::expandAndApply(_::MakeTupleFunc(), kj::fwd(params)...); -} - -template -inline auto get(Tuple&& tuple) -> decltype(_::getImpl(kj::fwd(tuple))) { - // Unpack and return the tuple element at the given index. The index is specified as a template - // parameter, e.g. `kj::get<3>(myTuple)`. - return _::getImpl(kj::fwd(tuple)); -} - -template -inline auto apply(Func&& func, Params&&... params) - -> decltype(_::expandAndApply(kj::fwd(func), kj::fwd(params)...)) { - // Apply a function to some arguments, expanding tuples into separate arguments. - return _::expandAndApply(kj::fwd(func), kj::fwd(params)...); -} - -template struct TupleSize_ { static constexpr size_t size = 1; }; -template struct TupleSize_<_::Tuple> { - static constexpr size_t size = sizeof...(T); -}; - -template -constexpr size_t tupleSize() { return TupleSize_::size; } -// Returns size of the tuple T. - -} // namespace kj - -#endif // KJ_TUPLE_H_ diff --git a/phonelibs/capnp-cpp/include/kj/units.h b/phonelibs/capnp-cpp/include/kj/units.h deleted file mode 100644 index 8bba40338bcc05..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/units.h +++ /dev/null @@ -1,1172 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -// This file contains types which are intended to help detect incorrect usage at compile -// time, but should then be optimized down to basic primitives (usually, integers) by the -// compiler. - -#ifndef KJ_UNITS_H_ -#define KJ_UNITS_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "common.h" -#include - -namespace kj { - -// ======================================================================================= -// IDs - -template -struct Id { - // A type-safe numeric ID. `UnderlyingType` is the underlying integer representation. `Label` - // distinguishes this Id from other Id types. Sample usage: - // - // class Foo; - // typedef Id FooId; - // - // class Bar; - // typedef Id BarId; - // - // You can now use the FooId and BarId types without any possibility of accidentally using a - // FooId when you really wanted a BarId or vice-versa. - - UnderlyingType value; - - inline constexpr Id(): value(0) {} - inline constexpr explicit Id(int value): value(value) {} - - inline constexpr bool operator==(const Id& other) const { return value == other.value; } - inline constexpr bool operator!=(const Id& other) const { return value != other.value; } - inline constexpr bool operator<=(const Id& other) const { return value <= other.value; } - inline constexpr bool operator>=(const Id& other) const { return value >= other.value; } - inline constexpr bool operator< (const Id& other) const { return value < other.value; } - inline constexpr bool operator> (const Id& other) const { return value > other.value; } -}; - -// ======================================================================================= -// Quantity and UnitRatio -- implement unit analysis via the type system - -struct Unsafe_ {}; -constexpr Unsafe_ unsafe = Unsafe_(); -// Use as a parameter to constructors that are unsafe to indicate that you really do mean it. - -template -class Bounded; -template -class BoundedConst; - -template constexpr bool isIntegral() { return false; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } -template <> constexpr bool isIntegral() { return true; } - -template -struct IsIntegralOrBounded_ { static constexpr bool value = isIntegral(); }; -template -struct IsIntegralOrBounded_> { static constexpr bool value = true; }; -template -struct IsIntegralOrBounded_> { static constexpr bool value = true; }; - -template -inline constexpr bool isIntegralOrBounded() { return IsIntegralOrBounded_::value; } - -template -class UnitRatio { - // A multiplier used to convert Quantities of one unit to Quantities of another unit. See - // Quantity, below. - // - // Construct this type by dividing one Quantity by another of a different unit. Use this type - // by multiplying it by a Quantity, or dividing a Quantity by it. - - static_assert(isIntegralOrBounded(), - "Underlying type for UnitRatio must be integer."); - -public: - inline UnitRatio() {} - - constexpr UnitRatio(Number unit1PerUnit2, decltype(unsafe)): unit1PerUnit2(unit1PerUnit2) {} - // This constructor was intended to be private, but GCC complains about it being private in a - // bunch of places that don't appear to even call it, so I made it public. Oh well. - - template - inline constexpr UnitRatio(const UnitRatio& other) - : unit1PerUnit2(other.unit1PerUnit2) {} - - template - inline constexpr UnitRatio - operator+(UnitRatio other) const { - return UnitRatio( - unit1PerUnit2 + other.unit1PerUnit2, unsafe); - } - template - inline constexpr UnitRatio - operator-(UnitRatio other) const { - return UnitRatio( - unit1PerUnit2 - other.unit1PerUnit2, unsafe); - } - - template - inline constexpr UnitRatio - operator*(UnitRatio other) const { - // U1 / U2 * U3 / U1 = U3 / U2 - return UnitRatio( - unit1PerUnit2 * other.unit1PerUnit2, unsafe); - } - template - inline constexpr UnitRatio - operator*(UnitRatio other) const { - // U1 / U2 * U2 / U3 = U1 / U3 - return UnitRatio( - unit1PerUnit2 * other.unit1PerUnit2, unsafe); - } - - template - inline constexpr UnitRatio - operator/(UnitRatio other) const { - // (U1 / U2) / (U1 / U3) = U3 / U2 - return UnitRatio( - unit1PerUnit2 / other.unit1PerUnit2, unsafe); - } - template - inline constexpr UnitRatio - operator/(UnitRatio other) const { - // (U1 / U2) / (U3 / U2) = U1 / U3 - return UnitRatio( - unit1PerUnit2 / other.unit1PerUnit2, unsafe); - } - - template - inline decltype(Number() / OtherNumber()) - operator/(UnitRatio other) const { - return unit1PerUnit2 / other.unit1PerUnit2; - } - - inline bool operator==(UnitRatio other) const { return unit1PerUnit2 == other.unit1PerUnit2; } - inline bool operator!=(UnitRatio other) const { return unit1PerUnit2 != other.unit1PerUnit2; } - -private: - Number unit1PerUnit2; - - template - friend class Quantity; - template - friend class UnitRatio; - - template - friend inline constexpr UnitRatio - operator*(N1, UnitRatio); -}; - -template () && isIntegralOrBounded()>> -inline constexpr UnitRatio - operator*(N1 n, UnitRatio r) { - return UnitRatio(n * r.unit1PerUnit2, unsafe); -} - -template -class Quantity { - // A type-safe numeric quantity, specified in terms of some unit. Two Quantities cannot be used - // in arithmetic unless they use the same unit. The `Unit` type parameter is only used to prevent - // accidental mixing of units; this type is never instantiated and can very well be incomplete. - // `Number` is the underlying primitive numeric type. - // - // Quantities support most basic arithmetic operators, intelligently handling units, and - // automatically casting the underlying type in the same way that the compiler would. - // - // To convert a primitive number to a Quantity, multiply it by unit>(). - // To convert a Quantity to a primitive number, divide it by unit>(). - // To convert a Quantity of one unit to another unit, multiply or divide by a UnitRatio. - // - // The Quantity class is not well-suited to hardcore physics as it does not allow multiplying - // one quantity by another. For example, multiplying meters by meters won't get you square - // meters; it will get you a compiler error. It would be interesting to see if template - // metaprogramming could properly deal with such things but this isn't needed for the present - // use case. - // - // Sample usage: - // - // class SecondsLabel; - // typedef Quantity Seconds; - // constexpr Seconds SECONDS = unit(); - // - // class MinutesLabel; - // typedef Quantity Minutes; - // constexpr Minutes MINUTES = unit(); - // - // constexpr UnitRatio SECONDS_PER_MINUTE = - // 60 * SECONDS / MINUTES; - // - // void waitFor(Seconds seconds) { - // sleep(seconds / SECONDS); - // } - // void waitFor(Minutes minutes) { - // waitFor(minutes * SECONDS_PER_MINUTE); - // } - // - // void waitThreeMinutes() { - // waitFor(3 * MINUTES); - // } - - static_assert(isIntegralOrBounded(), - "Underlying type for Quantity must be integer."); - -public: - inline constexpr Quantity() = default; - - inline constexpr Quantity(MaxValue_): value(maxValue) {} - inline constexpr Quantity(MinValue_): value(minValue) {} - // Allow initialization from maxValue and minValue. - // TODO(msvc): decltype(maxValue) and decltype(minValue) deduce unknown-type for these function - // parameters, causing the compiler to complain of a duplicate constructor definition, so we - // specify MaxValue_ and MinValue_ types explicitly. - - inline constexpr Quantity(Number value, decltype(unsafe)): value(value) {} - // This constructor was intended to be private, but GCC complains about it being private in a - // bunch of places that don't appear to even call it, so I made it public. Oh well. - - template - inline constexpr Quantity(const Quantity& other) - : value(other.value) {} - - template - inline Quantity& operator=(const Quantity& other) { - value = other.value; - return *this; - } - - template - inline constexpr Quantity - operator+(const Quantity& other) const { - return Quantity(value + other.value, unsafe); - } - template - inline constexpr Quantity - operator-(const Quantity& other) const { - return Quantity(value - other.value, unsafe); - } - template ()>> - inline constexpr Quantity - operator*(OtherNumber other) const { - return Quantity(value * other, unsafe); - } - template ()>> - inline constexpr Quantity - operator/(OtherNumber other) const { - return Quantity(value / other, unsafe); - } - template - inline constexpr decltype(Number() / OtherNumber()) - operator/(const Quantity& other) const { - return value / other.value; - } - template - inline constexpr Quantity - operator%(const Quantity& other) const { - return Quantity(value % other.value, unsafe); - } - - template - inline constexpr Quantity - operator*(UnitRatio ratio) const { - return Quantity( - value * ratio.unit1PerUnit2, unsafe); - } - template - inline constexpr Quantity - operator/(UnitRatio ratio) const { - return Quantity( - value / ratio.unit1PerUnit2, unsafe); - } - template - inline constexpr Quantity - operator%(UnitRatio ratio) const { - return Quantity( - value % ratio.unit1PerUnit2, unsafe); - } - template - inline constexpr UnitRatio - operator/(Quantity other) const { - return UnitRatio( - value / other.value, unsafe); - } - - template - inline constexpr bool operator==(const Quantity& other) const { - return value == other.value; - } - template - inline constexpr bool operator!=(const Quantity& other) const { - return value != other.value; - } - template - inline constexpr bool operator<=(const Quantity& other) const { - return value <= other.value; - } - template - inline constexpr bool operator>=(const Quantity& other) const { - return value >= other.value; - } - template - inline constexpr bool operator<(const Quantity& other) const { - return value < other.value; - } - template - inline constexpr bool operator>(const Quantity& other) const { - return value > other.value; - } - - template - inline Quantity& operator+=(const Quantity& other) { - value += other.value; - return *this; - } - template - inline Quantity& operator-=(const Quantity& other) { - value -= other.value; - return *this; - } - template - inline Quantity& operator*=(OtherNumber other) { - value *= other; - return *this; - } - template - inline Quantity& operator/=(OtherNumber other) { - value /= other.value; - return *this; - } - -private: - Number value; - - template - friend class Quantity; - - template - friend inline constexpr auto operator*(Number1 a, Quantity b) - -> Quantity; -}; - -template struct Unit_ { - static inline constexpr T get() { return T(1); } -}; -template -struct Unit_> { - static inline constexpr Quantity::get()), U> get() { - return Quantity::get()), U>(Unit_::get(), unsafe); - } -}; - -template -inline constexpr auto unit() -> decltype(Unit_::get()) { return Unit_::get(); } -// unit>() returns a Quantity of value 1. It also, intentionally, works on basic -// numeric types. - -template -inline constexpr auto operator*(Number1 a, Quantity b) - -> Quantity { - return Quantity(a * b.value, unsafe); -} - -template -inline constexpr auto operator*(UnitRatio ratio, - Quantity measure) - -> decltype(measure * ratio) { - return measure * ratio; -} - -// ======================================================================================= -// Absolute measures - -template -class Absolute { - // Wraps some other value -- typically a Quantity -- but represents a value measured based on - // some absolute origin. For example, if `Duration` is a type representing a time duration, - // Absolute might be a calendar date. - // - // Since Absolute represents measurements relative to some arbitrary origin, the only sensible - // arithmetic to perform on them is addition and subtraction. - - // TODO(someday): Do the same automatic expansion of integer width that Quantity does? Doesn't - // matter for our time use case, where we always use 64-bit anyway. Note that fixing this - // would implicitly allow things like multiplying an Absolute by a UnitRatio to change its - // units, which is actually totally logical and kind of neat. - -public: - inline constexpr Absolute operator+(const T& other) const { return Absolute(value + other); } - inline constexpr Absolute operator-(const T& other) const { return Absolute(value - other); } - inline constexpr T operator-(const Absolute& other) const { return value - other.value; } - - inline Absolute& operator+=(const T& other) { value += other; return *this; } - inline Absolute& operator-=(const T& other) { value -= other; return *this; } - - inline constexpr bool operator==(const Absolute& other) const { return value == other.value; } - inline constexpr bool operator!=(const Absolute& other) const { return value != other.value; } - inline constexpr bool operator<=(const Absolute& other) const { return value <= other.value; } - inline constexpr bool operator>=(const Absolute& other) const { return value >= other.value; } - inline constexpr bool operator< (const Absolute& other) const { return value < other.value; } - inline constexpr bool operator> (const Absolute& other) const { return value > other.value; } - -private: - T value; - - explicit constexpr Absolute(T value): value(value) {} - - template - friend inline constexpr U origin(); -}; - -template -inline constexpr Absolute operator+(const T& a, const Absolute& b) { - return b + a; -} - -template struct UnitOf_ { typedef T Type; }; -template struct UnitOf_> { typedef T Type; }; -template -using UnitOf = typename UnitOf_::Type; -// UnitOf> is T. UnitOf is AnythingElse. - -template -inline constexpr T origin() { return T(0 * unit>()); } -// origin>() returns an Absolute of value 0. It also, intentionally, works on basic -// numeric types. - -// ======================================================================================= -// Overflow avoidance - -template -struct BitCount_ { - static constexpr uint value = BitCount_<(n >> 1), accum + 1>::value; -}; -template -struct BitCount_<0, accum> { - static constexpr uint value = accum; -}; - -template -inline constexpr uint bitCount() { return BitCount_::value; } -// Number of bits required to represent the number `n`. - -template struct AtLeastUInt_ { - static_assert(bitCountBitCount < 7, "don't know how to represent integers over 64 bits"); -}; -template <> struct AtLeastUInt_<0> { typedef uint8_t Type; }; -template <> struct AtLeastUInt_<1> { typedef uint8_t Type; }; -template <> struct AtLeastUInt_<2> { typedef uint8_t Type; }; -template <> struct AtLeastUInt_<3> { typedef uint8_t Type; }; -template <> struct AtLeastUInt_<4> { typedef uint16_t Type; }; -template <> struct AtLeastUInt_<5> { typedef uint32_t Type; }; -template <> struct AtLeastUInt_<6> { typedef uint64_t Type; }; - -template -using AtLeastUInt = typename AtLeastUInt_()>::Type; -// AtLeastUInt is an unsigned integer of at least n bits. E.g. AtLeastUInt<12> is uint16_t. - -// ------------------------------------------------------------------- - -template -class BoundedConst { - // A constant integer value on which we can do bit size analysis. - -public: - BoundedConst() = default; - - inline constexpr uint unwrap() const { return value; } - -#define OP(op, check) \ - template \ - inline constexpr BoundedConst<(value op other)> \ - operator op(BoundedConst) const { \ - static_assert(check, "overflow in BoundedConst arithmetic"); \ - return BoundedConst<(value op other)>(); \ - } -#define COMPARE_OP(op) \ - template \ - inline constexpr bool operator op(BoundedConst) const { \ - return value op other; \ - } - - OP(+, value + other >= value) - OP(-, value - other <= value) - OP(*, value * other / other == value) - OP(/, true) // div by zero already errors out; no other division ever overflows - OP(%, true) // mod by zero already errors out; no other modulus ever overflows - OP(<<, value << other >= value) - OP(>>, true) // right shift can't overflow - OP(&, true) // bitwise ops can't overflow - OP(|, true) // bitwise ops can't overflow - - COMPARE_OP(==) - COMPARE_OP(!=) - COMPARE_OP(< ) - COMPARE_OP(> ) - COMPARE_OP(<=) - COMPARE_OP(>=) -#undef OP -#undef COMPARE_OP -}; - -template -struct Unit_> { - static inline constexpr BoundedConst<1> get() { return BoundedConst<1>(); } -}; - -template -struct Unit_> { - static inline constexpr BoundedConst<1> get() { return BoundedConst<1>(); } -}; - -template -inline constexpr BoundedConst bounded() { - return BoundedConst(); -} - -template -static constexpr uint64_t boundedAdd() { - static_assert(a + b >= a, "possible overflow detected"); - return a + b; -} -template -static constexpr uint64_t boundedSub() { - static_assert(a - b <= a, "possible underflow detected"); - return a - b; -} -template -static constexpr uint64_t boundedMul() { - static_assert(a * b / b == a, "possible overflow detected"); - return a * b; -} -template -static constexpr uint64_t boundedLShift() { - static_assert(a << b >= a, "possible overflow detected"); - return a << b; -} - -template -inline constexpr BoundedConst min(BoundedConst, BoundedConst) { - return bounded(); -} -template -inline constexpr BoundedConst max(BoundedConst, BoundedConst) { - return bounded(); -} -// We need to override min() and max() between constants because the ternary operator in the -// default implementation would complain. - -// ------------------------------------------------------------------- - -template -class Bounded { -public: - static_assert(maxN <= T(kj::maxValue), "possible overflow detected"); - - Bounded() = default; - - Bounded(const Bounded& other) = default; - template ()>> - inline constexpr Bounded(OtherInt value): value(value) { - static_assert(OtherInt(maxValue) <= maxN, "possible overflow detected"); - } - template - inline constexpr Bounded(const Bounded& other) - : value(other.value) { - static_assert(otherMax <= maxN, "possible overflow detected"); - } - template - inline constexpr Bounded(BoundedConst) - : value(otherValue) { - static_assert(otherValue <= maxN, "overflow detected"); - } - - Bounded& operator=(const Bounded& other) = default; - template ()>> - Bounded& operator=(OtherInt other) { - static_assert(OtherInt(maxValue) <= maxN, "possible overflow detected"); - value = other; - return *this; - } - template - inline Bounded& operator=(const Bounded& other) { - static_assert(otherMax <= maxN, "possible overflow detected"); - value = other.value; - return *this; - } - template - inline Bounded& operator=(BoundedConst) { - static_assert(otherValue <= maxN, "overflow detected"); - value = otherValue; - return *this; - } - - inline constexpr T unwrap() const { return value; } - -#define OP(op, newMax) \ - template \ - inline constexpr Bounded \ - operator op(const Bounded& other) const { \ - return Bounded(value op other.value, unsafe); \ - } -#define COMPARE_OP(op) \ - template \ - inline constexpr bool operator op(const Bounded& other) const { \ - return value op other.value; \ - } - - OP(+, (boundedAdd())) - OP(*, (boundedMul())) - OP(/, maxN) - OP(%, otherMax - 1) - - // operator- is intentionally omitted because we mostly use this with unsigned types, and - // subtraction requires proof that subtrahend is not greater than the minuend. - - COMPARE_OP(==) - COMPARE_OP(!=) - COMPARE_OP(< ) - COMPARE_OP(> ) - COMPARE_OP(<=) - COMPARE_OP(>=) - -#undef OP -#undef COMPARE_OP - - template - inline Bounded assertMax(ErrorFunc&& func) const { - // Assert that the number is no more than `newMax`. Otherwise, call `func`. - static_assert(newMax < maxN, "this bounded size assertion is redundant"); - if (KJ_UNLIKELY(value > newMax)) func(); - return Bounded(value, unsafe); - } - - template - inline Bounded subtractChecked( - const Bounded& other, ErrorFunc&& func) const { - // Subtract a number, calling func() if the result would underflow. - if (KJ_UNLIKELY(value < other.value)) func(); - return Bounded(value - other.value, unsafe); - } - - template - inline Bounded subtractChecked( - BoundedConst, ErrorFunc&& func) const { - // Subtract a number, calling func() if the result would underflow. - static_assert(otherValue <= maxN, "underflow detected"); - if (KJ_UNLIKELY(value < otherValue)) func(); - return Bounded(value - otherValue, unsafe); - } - - template - inline Maybe> trySubtract( - const Bounded& other) const { - // Subtract a number, calling func() if the result would underflow. - if (value < other.value) { - return nullptr; - } else { - return Bounded(value - other.value, unsafe); - } - } - - template - inline Maybe> trySubtract(BoundedConst) const { - // Subtract a number, calling func() if the result would underflow. - if (value < otherValue) { - return nullptr; - } else { - return Bounded(value - otherValue, unsafe); - } - } - - inline constexpr Bounded(T value, decltype(unsafe)): value(value) {} - template - inline constexpr Bounded(Bounded value, decltype(unsafe)) - : value(value.value) {} - // Mainly for internal use. - // - // Only use these as a last resort, with ample commentary on why you think it's safe. - -private: - T value; - - template - friend class Bounded; -}; - -template -inline constexpr Bounded bounded(Number value) { - return Bounded(value, unsafe); -} - -inline constexpr Bounded<1, uint8_t> bounded(bool value) { - return Bounded<1, uint8_t>(value, unsafe); -} - -template -inline constexpr Bounded(), Number> assumeBits(Number value) { - return Bounded(), Number>(value, unsafe); -} - -template -inline constexpr Bounded(), T> assumeBits(Bounded value) { - return Bounded(), T>(value, unsafe); -} - -template -inline constexpr auto assumeBits(Quantity value) - -> Quantity(value / unit>())), Unit> { - return Quantity(value / unit>())), Unit>( - assumeBits(value / unit>()), unsafe); -} - -template -inline constexpr Bounded assumeMax(Number value) { - return Bounded(value, unsafe); -} - -template -inline constexpr Bounded assumeMax(Bounded value) { - return Bounded(value, unsafe); -} - -template -inline constexpr auto assumeMax(Quantity value) - -> Quantity(value / unit>())), Unit> { - return Quantity(value / unit>())), Unit>( - assumeMax(value / unit>()), unsafe); -} - -template -inline constexpr Bounded assumeMax(BoundedConst, Number value) { - return assumeMax(value); -} - -template -inline constexpr Bounded assumeMax(BoundedConst, Bounded value) { - return assumeMax(value); -} - -template -inline constexpr auto assumeMax(Quantity, Unit>, Quantity value) - -> decltype(assumeMax(value)) { - return assumeMax(value); -} - -template -inline Bounded assertMax(Bounded value, ErrorFunc&& errorFunc) { - // Assert that the bounded value is less than or equal to the given maximum, calling errorFunc() - // if not. - static_assert(newMax < maxN, "this bounded size assertion is redundant"); - return value.template assertMax(kj::fwd(errorFunc)); -} - -template -inline Quantity, Unit> assertMax( - Quantity, Unit> value, ErrorFunc&& errorFunc) { - // Assert that the bounded value is less than or equal to the given maximum, calling errorFunc() - // if not. - static_assert(newMax < maxN, "this bounded size assertion is redundant"); - return (value / unit()).template assertMax( - kj::fwd(errorFunc)) * unit(); -} - -template -inline Bounded assertMax( - BoundedConst, Bounded value, ErrorFunc&& errorFunc) { - return assertMax(value, kj::mv(errorFunc)); -} - -template -inline Quantity, Unit> assertMax( - Quantity, Unit>, - Quantity, Unit> value, ErrorFunc&& errorFunc) { - return assertMax(value, kj::mv(errorFunc)); -} - -template -inline Bounded(), T> assertMaxBits( - Bounded value, ErrorFunc&& errorFunc = ErrorFunc()) { - // Assert that the bounded value requires no more than the given number of bits, calling - // errorFunc() if not. - return assertMax()>(value, kj::fwd(errorFunc)); -} - -template -inline Quantity(), T>, Unit> assertMaxBits( - Quantity, Unit> value, ErrorFunc&& errorFunc = ErrorFunc()) { - // Assert that the bounded value requires no more than the given number of bits, calling - // errorFunc() if not. - return assertMax()>(value, kj::fwd(errorFunc)); -} - -template -inline constexpr Bounded upgradeBound(Bounded value) { - return value; -} - -template -inline constexpr Quantity, Unit> upgradeBound( - Quantity, Unit> value) { - return value; -} - -template -inline auto subtractChecked(Bounded value, Other other, ErrorFunc&& errorFunc) - -> decltype(value.subtractChecked(other, kj::fwd(errorFunc))) { - return value.subtractChecked(other, kj::fwd(errorFunc)); -} - -template -inline auto subtractChecked(Quantity value, Quantity other, ErrorFunc&& errorFunc) - -> Quantity(errorFunc))), Unit> { - return subtractChecked(value / unit>(), - other / unit>(), - kj::fwd(errorFunc)) - * unit>(); -} - -template -inline auto trySubtract(Bounded value, Other other) - -> decltype(value.trySubtract(other)) { - return value.trySubtract(other); -} - -template -inline auto trySubtract(Quantity value, Quantity other) - -> Maybe> { - return trySubtract(value / unit>(), - other / unit>()) - .map([](decltype(subtractChecked(T(), U(), int())) x) { - return x * unit>(); - }); -} - -template -inline constexpr Bounded> -min(Bounded a, Bounded b) { - return Bounded>(kj::min(a.unwrap(), b.unwrap()), unsafe); -} -template -inline constexpr Bounded> -max(Bounded a, Bounded b) { - return Bounded>(kj::max(a.unwrap(), b.unwrap()), unsafe); -} -// We need to override min() and max() because: -// 1) WiderType<> might not choose the correct bounds. -// 2) One of the two sides of the ternary operator in the default implementation would fail to -// typecheck even though it is OK in practice. - -// ------------------------------------------------------------------- -// Operators between Bounded and BoundedConst - -#define OP(op, newMax) \ -template \ -inline constexpr Bounded<(newMax), decltype(T() op uint())> operator op( \ - Bounded value, BoundedConst) { \ - return Bounded<(newMax), decltype(T() op uint())>(value.unwrap() op cvalue, unsafe); \ -} - -#define REVERSE_OP(op, newMax) \ -template \ -inline constexpr Bounded<(newMax), decltype(uint() op T())> operator op( \ - BoundedConst, Bounded value) { \ - return Bounded<(newMax), decltype(uint() op T())>(cvalue op value.unwrap(), unsafe); \ -} - -#define COMPARE_OP(op) \ -template \ -inline constexpr bool operator op(Bounded value, BoundedConst) { \ - return value.unwrap() op cvalue; \ -} \ -template \ -inline constexpr bool operator op(BoundedConst, Bounded value) { \ - return cvalue op value.unwrap(); \ -} - -OP(+, (boundedAdd())) -REVERSE_OP(+, (boundedAdd())) - -OP(*, (boundedMul())) -REVERSE_OP(*, (boundedAdd())) - -OP(/, maxN / cvalue) -REVERSE_OP(/, cvalue) // denominator could be 1 - -OP(%, cvalue - 1) -REVERSE_OP(%, maxN - 1) - -OP(<<, (boundedLShift())) -REVERSE_OP(<<, (boundedLShift())) - -OP(>>, maxN >> cvalue) -REVERSE_OP(>>, cvalue >> maxN) - -OP(&, maxValueForBits()>() & cvalue) -REVERSE_OP(&, maxValueForBits()>() & cvalue) - -OP(|, maxN | cvalue) -REVERSE_OP(|, maxN | cvalue) - -COMPARE_OP(==) -COMPARE_OP(!=) -COMPARE_OP(< ) -COMPARE_OP(> ) -COMPARE_OP(<=) -COMPARE_OP(>=) - -#undef OP -#undef REVERSE_OP -#undef COMPARE_OP - -template -inline constexpr Bounded - operator-(BoundedConst, Bounded value) { - // We allow subtraction of a variable from a constant only if the constant is greater than or - // equal to the maximum possible value of the variable. Since the variable could be zero, the - // result can be as large as the constant. - // - // We do not allow subtraction of a constant from a variable because there's never a guarantee it - // won't underflow (unless the constant is zero, which is silly). - static_assert(cvalue >= maxN, "possible underflow detected"); - return Bounded(cvalue - value.unwrap(), unsafe); -} - -template -inline constexpr Bounded min(Bounded a, BoundedConst) { - return Bounded(kj::min(b, a.unwrap()), unsafe); -} -template -inline constexpr Bounded min(BoundedConst, Bounded a) { - return Bounded(kj::min(a.unwrap(), b), unsafe); -} -template -inline constexpr Bounded max(Bounded a, BoundedConst) { - return Bounded(kj::max(b, a.unwrap()), unsafe); -} -template -inline constexpr Bounded max(BoundedConst, Bounded a) { - return Bounded(kj::max(a.unwrap(), b), unsafe); -} -// We need to override min() between a Bounded and a constant since: -// 1) WiderType<> might choose BoundedConst over a 1-byte Bounded, which is wrong. -// 2) To clamp the bounds of the output type. -// 3) Same ternary operator typechecking issues. - -// ------------------------------------------------------------------- - -template -class SafeUnwrapper { -public: - inline explicit constexpr SafeUnwrapper(Bounded value): value(value.unwrap()) {} - - template ()>> - inline constexpr operator U() const { - static_assert(maxN <= U(maxValue), "possible truncation detected"); - return value; - } - - inline constexpr operator bool() const { - static_assert(maxN <= 1, "possible truncation detected"); - return value; - } - -private: - T value; -}; - -template -inline constexpr SafeUnwrapper unbound(Bounded bounded) { - // Unwraps the bounded value, returning a value that can be implicitly cast to any integer type. - // If this implicit cast could truncate, a compile-time error will be raised. - return SafeUnwrapper(bounded); -} - -template -class SafeConstUnwrapper { -public: - template ()>> - inline constexpr operator T() const { - static_assert(value <= T(maxValue), "this operation will truncate"); - return value; - } - - inline constexpr operator bool() const { - static_assert(value <= 1, "this operation will truncate"); - return value; - } -}; - -template -inline constexpr SafeConstUnwrapper unbound(BoundedConst) { - return SafeConstUnwrapper(); -} - -template -inline constexpr T unboundAs(U value) { - return unbound(value); -} - -template -inline constexpr T unboundMax(Bounded value) { - // Explicitly ungaurd expecting a value that is at most `maxN`. - static_assert(maxN <= requestedMax, "possible overflow detected"); - return value.unwrap(); -} - -template -inline constexpr uint unboundMax(BoundedConst) { - // Explicitly ungaurd expecting a value that is at most `maxN`. - static_assert(value <= requestedMax, "overflow detected"); - return value; -} - -template -inline constexpr auto unboundMaxBits(T value) -> - decltype(unboundMax()>(value)) { - // Explicitly ungaurd expecting a value that fits into `bits` bits. - return unboundMax()>(value); -} - -#define OP(op) \ -template \ -inline constexpr auto operator op(T a, SafeUnwrapper b) -> decltype(a op (T)b) { \ - return a op (AtLeastUInt)b; \ -} \ -template \ -inline constexpr auto operator op(SafeUnwrapper b, T a) -> decltype((T)b op a) { \ - return (AtLeastUInt)b op a; \ -} \ -template \ -inline constexpr auto operator op(T a, SafeConstUnwrapper b) -> decltype(a op (T)b) { \ - return a op (AtLeastUInt)b; \ -} \ -template \ -inline constexpr auto operator op(SafeConstUnwrapper b, T a) -> decltype((T)b op a) { \ - return (AtLeastUInt)b op a; \ -} - -OP(+) -OP(-) -OP(*) -OP(/) -OP(%) -OP(<<) -OP(>>) -OP(&) -OP(|) -OP(==) -OP(!=) -OP(<=) -OP(>=) -OP(<) -OP(>) - -#undef OP - -// ------------------------------------------------------------------- - -template -class Range> { -public: - inline constexpr Range(Bounded begin, Bounded end) - : inner(unbound(begin), unbound(end)) {} - inline explicit constexpr Range(Bounded end) - : inner(unbound(end)) {} - - class Iterator { - public: - Iterator() = default; - inline explicit Iterator(typename Range::Iterator inner): inner(inner) {} - - inline Bounded operator* () const { return Bounded(*inner, unsafe); } - inline Iterator& operator++() { ++inner; return *this; } - - inline bool operator==(const Iterator& other) const { return inner == other.inner; } - inline bool operator!=(const Iterator& other) const { return inner != other.inner; } - - private: - typename Range::Iterator inner; - }; - - inline Iterator begin() const { return Iterator(inner.begin()); } - inline Iterator end() const { return Iterator(inner.end()); } - -private: - Range inner; -}; - -template -class Range> { -public: - inline constexpr Range(Quantity begin, Quantity end) - : inner(begin / unit>(), end / unit>()) {} - inline explicit constexpr Range(Quantity end) - : inner(end / unit>()) {} - - class Iterator { - public: - Iterator() = default; - inline explicit Iterator(typename Range::Iterator inner): inner(inner) {} - - inline Quantity operator* () const { return *inner * unit>(); } - inline Iterator& operator++() { ++inner; return *this; } - - inline bool operator==(const Iterator& other) const { return inner == other.inner; } - inline bool operator!=(const Iterator& other) const { return inner != other.inner; } - - private: - typename Range::Iterator inner; - }; - - inline Iterator begin() const { return Iterator(inner.begin()); } - inline Iterator end() const { return Iterator(inner.end()); } - -private: - Range inner; -}; - -template -inline constexpr Range> zeroTo(BoundedConst end) { - return Range>(end); -} - -template -inline constexpr Range, Unit>> - zeroTo(Quantity, Unit> end) { - return Range, Unit>>(end); -} - -} // namespace kj - -#endif // KJ_UNITS_H_ diff --git a/phonelibs/capnp-cpp/include/kj/vector.h b/phonelibs/capnp-cpp/include/kj/vector.h deleted file mode 100644 index 44613f333173cd..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/vector.h +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_VECTOR_H_ -#define KJ_VECTOR_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#include "array.h" - -namespace kj { - -template -class Vector { - // Similar to std::vector, but based on KJ framework. - // - // This implementation always uses move constructors when growing the backing array. If the - // move constructor throws, the Vector is left in an inconsistent state. This is acceptable - // under KJ exception theory which assumes that exceptions leave things in inconsistent states. - - // TODO(someday): Allow specifying a custom allocator. - -public: - inline Vector() = default; - inline explicit Vector(size_t capacity): builder(heapArrayBuilder(capacity)) {} - - inline operator ArrayPtr() { return builder; } - inline operator ArrayPtr() const { return builder; } - inline ArrayPtr asPtr() { return builder.asPtr(); } - inline ArrayPtr asPtr() const { return builder.asPtr(); } - - inline size_t size() const { return builder.size(); } - inline bool empty() const { return size() == 0; } - inline size_t capacity() const { return builder.capacity(); } - inline T& operator[](size_t index) const { return builder[index]; } - - inline const T* begin() const { return builder.begin(); } - inline const T* end() const { return builder.end(); } - inline const T& front() const { return builder.front(); } - inline const T& back() const { return builder.back(); } - inline T* begin() { return builder.begin(); } - inline T* end() { return builder.end(); } - inline T& front() { return builder.front(); } - inline T& back() { return builder.back(); } - - inline Array releaseAsArray() { - // TODO(perf): Avoid a copy/move by allowing Array to point to incomplete space? - if (!builder.isFull()) { - setCapacity(size()); - } - return builder.finish(); - } - - template - inline T& add(Params&&... params) { - if (builder.isFull()) grow(); - return builder.add(kj::fwd(params)...); - } - - template - inline void addAll(Iterator begin, Iterator end) { - size_t needed = builder.size() + (end - begin); - if (needed > builder.capacity()) grow(needed); - builder.addAll(begin, end); - } - - template - inline void addAll(Container&& container) { - addAll(container.begin(), container.end()); - } - - inline void removeLast() { - builder.removeLast(); - } - - inline void resize(size_t size) { - if (size > builder.capacity()) grow(size); - builder.resize(size); - } - - inline void operator=(decltype(nullptr)) { - builder = nullptr; - } - - inline void clear() { - while (builder.size() > 0) { - builder.removeLast(); - } - } - - inline void truncate(size_t size) { - builder.truncate(size); - } - - inline void reserve(size_t size) { - if (size > builder.capacity()) { - setCapacity(size); - } - } - -private: - ArrayBuilder builder; - - void grow(size_t minCapacity = 0) { - setCapacity(kj::max(minCapacity, capacity() == 0 ? 4 : capacity() * 2)); - } - void setCapacity(size_t newSize) { - if (builder.size() > newSize) { - builder.truncate(newSize); - } - ArrayBuilder newBuilder = heapArrayBuilder(newSize); - newBuilder.addAll(kj::mv(builder)); - builder = kj::mv(newBuilder); - } -}; - -template -inline auto KJ_STRINGIFY(const Vector& v) -> decltype(toCharSequence(v.asPtr())) { - return toCharSequence(v.asPtr()); -} - -} // namespace kj - -#endif // KJ_VECTOR_H_ diff --git a/phonelibs/capnp-cpp/include/kj/windows-sanity.h b/phonelibs/capnp-cpp/include/kj/windows-sanity.h deleted file mode 100644 index 766ba2cbd67047..00000000000000 --- a/phonelibs/capnp-cpp/include/kj/windows-sanity.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors -// Licensed under the MIT License: -// -// 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. - -#ifndef KJ_WINDOWS_SANITY_H_ -#define KJ_WINDOWS_SANITY_H_ - -#if defined(__GNUC__) && !KJ_HEADER_WARNINGS -#pragma GCC system_header -#endif - -#ifndef _INC_WINDOWS -#error "windows.h needs to be included before kj/windows-sanity.h (or perhaps you don't need either?)" -#endif - -namespace win32 { - const auto ERROR_ = ERROR; -#undef ERROR - const auto ERROR = ERROR_; -} - -using win32::ERROR; - -#endif // KJ_WINDOWS_SANITY_H_ diff --git a/phonelibs/hierarchy/lib/_hierarchy.so b/phonelibs/hierarchy/lib/_hierarchy.so deleted file mode 100755 index 367b717758b2c8..00000000000000 Binary files a/phonelibs/hierarchy/lib/_hierarchy.so and /dev/null differ diff --git a/phonelibs/install_capnp.sh b/phonelibs/install_capnp.sh new file mode 100755 index 00000000000000..b1ea7602f1d4f0 --- /dev/null +++ b/phonelibs/install_capnp.sh @@ -0,0 +1,42 @@ +set -e +echo "Installing capnp" + +cd /tmp +VERSION=0.6.1 +wget https://capnproto.org/capnproto-c++-${VERSION}.tar.gz +tar xvf capnproto-c++-${VERSION}.tar.gz +cd capnproto-c++-${VERSION} +CXXFLAGS="-fPIC" ./configure + +make -j4 +make install + +# manually build binaries statically +g++ -std=gnu++11 -I./src -I./src -DKJ_HEADER_WARNINGS -DCAPNP_HEADER_WARNINGS -DCAPNP_INCLUDE_DIR=\"/usr/local/include\" -pthread -O2 -DNDEBUG -pthread -pthread -o .libs/capnp src/capnp/compiler/module-loader.o src/capnp/compiler/capnp.o ./.libs/libcapnpc.a ./.libs/libcapnp.a ./.libs/libkj.a -lpthread -pthread + +g++ -std=gnu++11 -I./src -I./src -DKJ_HEADER_WARNINGS -DCAPNP_HEADER_WARNINGS -DCAPNP_INCLUDE_DIR=\"/usr/local/include\" -pthread -O2 -DNDEBUG -pthread -pthread -o .libs/capnpc-c++ src/capnp/compiler/capnpc-c++.o ./.libs/libcapnp.a ./.libs/libkj.a -lpthread -pthread + +g++ -std=gnu++11 -I./src -I./src -DKJ_HEADER_WARNINGS -DCAPNP_HEADER_WARNINGS -DCAPNP_INCLUDE_DIR=\"/usr/local/include\" -pthread -O2 -DNDEBUG -pthread -pthread -o .libs/capnpc-capnp src/capnp/compiler/capnpc-capnp.o ./.libs/libcapnp.a ./.libs/libkj.a -lpthread -pthread + +cp .libs/capnp /usr/local/bin/ +rm /usr/local/bin/capnpc +ln -s /usr/local/bin/capnp /usr/local/bin/capnpc +cp .libs/capnpc-c++ /usr/local/bin/ +cp .libs/capnpc-capnp /usr/local/bin/ +cp .libs/*.a /usr/local/lib + +cd /tmp +echo "Installing c-capnp" +git clone https://github.com/commaai/c-capnproto.git +cd c-capnproto +git submodule update --init --recursive +autoreconf -f -i -s +CXXFLAGS="-fPIC" ./configure +make -j4 +make install + +# manually build binaries statically +gcc -fPIC -o .libs/capnpc-c compiler/capnpc-c.o compiler/schema.capnp.o compiler/str.o ./.libs/libcapnp_c.a + +cp .libs/capnpc-c /usr/local/bin/ +cp .libs/*.a /usr/local/lib diff --git a/phonelibs/json11/json11.o b/phonelibs/json11/json11.o index 1e32cca71ffc3b..516adf37346d2f 100644 Binary files a/phonelibs/json11/json11.o and b/phonelibs/json11/json11.o differ diff --git a/phonelibs/libyuv/LICENSE b/phonelibs/libyuv/LICENSE new file mode 100644 index 00000000000000..c911747a6b53f0 --- /dev/null +++ b/phonelibs/libyuv/LICENSE @@ -0,0 +1,29 @@ +Copyright 2011 The LibYuv Project 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 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 +HOLDER 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. diff --git a/phonelibs/linux/include/linux/ion.h b/phonelibs/linux/include/linux/ion.h new file mode 100644 index 00000000000000..7b5b031f57fa0e --- /dev/null +++ b/phonelibs/linux/include/linux/ion.h @@ -0,0 +1,78 @@ +/**************************************************************************** + **************************************************************************** + *** + *** This header was automatically generated from a Linux kernel header + *** of the same name, to make information necessary for userspace to + *** call into the kernel available to libc. It contains only constants, + *** structures, and macros generated from the original header, and thus, + *** contains no copyrightable information. + *** + *** To edit the content of this header, modify the corresponding + *** source file (e.g. under external/kernel-headers/original/) then + *** run bionic/libc/kernel/tools/update_all.py + *** + *** Any manual change here will be lost the next time this script will + *** be run. You've been warned! + *** + **************************************************************************** + ****************************************************************************/ +#ifndef _UAPI_LINUX_ION_H +#define _UAPI_LINUX_ION_H +#include +#include +typedef int ion_user_handle_t; +enum ion_heap_type { + ION_HEAP_TYPE_SYSTEM, + ION_HEAP_TYPE_SYSTEM_CONTIG, + ION_HEAP_TYPE_CARVEOUT, + ION_HEAP_TYPE_CHUNK, + ION_HEAP_TYPE_DMA, + ION_HEAP_TYPE_CUSTOM, +}; +#define ION_NUM_HEAP_IDS (sizeof(unsigned int) * 8) +#define ION_FLAG_CACHED 1 +#define ION_FLAG_CACHED_NEEDS_SYNC 2 +struct ion_allocation_data { + size_t len; + size_t align; + unsigned int heap_id_mask; + unsigned int flags; + ion_user_handle_t handle; +}; +struct ion_fd_data { + ion_user_handle_t handle; + int fd; +}; +struct ion_handle_data { + ion_user_handle_t handle; +}; +struct ion_custom_data { + unsigned int cmd; + unsigned long arg; +}; +#define MAX_HEAP_NAME 32 +struct ion_heap_data { + char name[MAX_HEAP_NAME]; + __u32 type; + __u32 heap_id; + __u32 reserved0; + __u32 reserved1; + __u32 reserved2; +}; +struct ion_heap_query { + __u32 cnt; + __u32 reserved0; + __u64 heaps; + __u32 reserved1; + __u32 reserved2; +}; +#define ION_IOC_MAGIC 'I' +#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, struct ion_allocation_data) +#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) +#define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data) +#define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data) +#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data) +#define ION_IOC_SYNC _IOWR(ION_IOC_MAGIC, 7, struct ion_fd_data) +#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data) +#define ION_IOC_HEAP_QUERY _IOWR(ION_IOC_MAGIC, 8, struct ion_heap_query) +#endif diff --git a/phonelibs/openblas/libopenblas.so b/phonelibs/openblas/libopenblas.so deleted file mode 120000 index 7a792bc9071885..00000000000000 --- a/phonelibs/openblas/libopenblas.so +++ /dev/null @@ -1 +0,0 @@ -libopenblas_armv8p-r0.2.19.so \ No newline at end of file diff --git a/phonelibs/openblas/libopenblas_armv8p-r0.2.19.so b/phonelibs/openblas/libopenblas_armv8p-r0.2.19.so deleted file mode 100755 index ace58c8a13122f..00000000000000 Binary files a/phonelibs/openblas/libopenblas_armv8p-r0.2.19.so and /dev/null differ diff --git a/phonelibs/openmax/include/OMX_Audio.h b/phonelibs/openmax/include/OMX_Audio.h new file mode 100644 index 00000000000000..0d455766c50048 --- /dev/null +++ b/phonelibs/openmax/include/OMX_Audio.h @@ -0,0 +1,1312 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** @file OMX_Audio.h - OpenMax IL version 1.1.2 + * The structures needed by Audio components to exchange + * parameters and configuration data with the componenmilts. + */ + +#ifndef OMX_Audio_h +#define OMX_Audio_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + +/** @defgroup midi MIDI + * @ingroup audio + */ + +/** @defgroup effects Audio effects + * @ingroup audio + */ + +/** @defgroup audio OpenMAX IL Audio Domain + * Structures for OpenMAX IL Audio domain + * @{ + */ + +/** Enumeration used to define the possible audio codings. + * If "OMX_AUDIO_CodingUnused" is selected, the coding selection must + * be done in a vendor specific way. Since this is for an audio + * processing element this enum is relevant. However, for another + * type of component other enums would be in this area. + */ +typedef enum OMX_AUDIO_CODINGTYPE { + OMX_AUDIO_CodingUnused = 0, /**< Placeholder value when coding is N/A */ + OMX_AUDIO_CodingAutoDetect, /**< auto detection of audio format */ + OMX_AUDIO_CodingPCM, /**< Any variant of PCM coding */ + OMX_AUDIO_CodingADPCM, /**< Any variant of ADPCM encoded data */ + OMX_AUDIO_CodingAMR, /**< Any variant of AMR encoded data */ + OMX_AUDIO_CodingGSMFR, /**< Any variant of GSM fullrate (i.e. GSM610) */ + OMX_AUDIO_CodingGSMEFR, /**< Any variant of GSM Enhanced Fullrate encoded data*/ + OMX_AUDIO_CodingGSMHR, /**< Any variant of GSM Halfrate encoded data */ + OMX_AUDIO_CodingPDCFR, /**< Any variant of PDC Fullrate encoded data */ + OMX_AUDIO_CodingPDCEFR, /**< Any variant of PDC Enhanced Fullrate encoded data */ + OMX_AUDIO_CodingPDCHR, /**< Any variant of PDC Halfrate encoded data */ + OMX_AUDIO_CodingTDMAFR, /**< Any variant of TDMA Fullrate encoded data (TIA/EIA-136-420) */ + OMX_AUDIO_CodingTDMAEFR, /**< Any variant of TDMA Enhanced Fullrate encoded data (TIA/EIA-136-410) */ + OMX_AUDIO_CodingQCELP8, /**< Any variant of QCELP 8kbps encoded data */ + OMX_AUDIO_CodingQCELP13, /**< Any variant of QCELP 13kbps encoded data */ + OMX_AUDIO_CodingEVRC, /**< Any variant of EVRC encoded data */ + OMX_AUDIO_CodingSMV, /**< Any variant of SMV encoded data */ + OMX_AUDIO_CodingG711, /**< Any variant of G.711 encoded data */ + OMX_AUDIO_CodingG723, /**< Any variant of G.723 dot 1 encoded data */ + OMX_AUDIO_CodingG726, /**< Any variant of G.726 encoded data */ + OMX_AUDIO_CodingG729, /**< Any variant of G.729 encoded data */ + OMX_AUDIO_CodingAAC, /**< Any variant of AAC encoded data */ + OMX_AUDIO_CodingMP3, /**< Any variant of MP3 encoded data */ + OMX_AUDIO_CodingSBC, /**< Any variant of SBC encoded data */ + OMX_AUDIO_CodingVORBIS, /**< Any variant of VORBIS encoded data */ + OMX_AUDIO_CodingWMA, /**< Any variant of WMA encoded data */ + OMX_AUDIO_CodingRA, /**< Any variant of RA encoded data */ + OMX_AUDIO_CodingMIDI, /**< Any variant of MIDI encoded data */ + OMX_AUDIO_CodingAC3, /**< Any variant of AC3 encoded data */ + OMX_AUDIO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_CodingMax = 0x7FFFFFFF +} OMX_AUDIO_CODINGTYPE; + + +/** The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output audio + * path. If additional information is needed to define the parameters of the + * port (such as frequency), additional structures must be sent such as the + * OMX_AUDIO_PARAM_PCMMODETYPE structure to supply the extra parameters for the port. + */ +typedef struct OMX_AUDIO_PORTDEFINITIONTYPE { + OMX_STRING cMIMEType; /**< MIME type of data for the port */ + OMX_NATIVE_DEVICETYPE pNativeRender; /** < platform specific reference + for an output device, + otherwise this field is 0 */ + OMX_BOOL bFlagErrorConcealment; /**< Turns on error concealment if it is + supported by the OMX component */ + OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this + port (e.g. PCM, AMR, MP3, etc) */ +} OMX_AUDIO_PORTDEFINITIONTYPE; + + +/** Port format parameter. This structure is used to enumerate + * the various data input/output format supported by the port. + */ +typedef struct OMX_AUDIO_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Indicates which port to set */ + OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */ + OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this port (e.g. PCM, AMR, MP3, etc) */ +} OMX_AUDIO_PARAM_PORTFORMATTYPE; + + +/** PCM mode type */ +typedef enum OMX_AUDIO_PCMMODETYPE { + OMX_AUDIO_PCMModeLinear = 0, /**< Linear PCM encoded data */ + OMX_AUDIO_PCMModeALaw, /**< A law PCM encoded data (G.711) */ + OMX_AUDIO_PCMModeMULaw, /**< Mu law PCM encoded data (G.711) */ + OMX_AUDIO_PCMModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_PCMModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_PCMModeMax = 0x7FFFFFFF +} OMX_AUDIO_PCMMODETYPE; + + +typedef enum OMX_AUDIO_CHANNELTYPE { + OMX_AUDIO_ChannelNone = 0x0, /**< Unused or empty */ + OMX_AUDIO_ChannelLF = 0x1, /**< Left front */ + OMX_AUDIO_ChannelRF = 0x2, /**< Right front */ + OMX_AUDIO_ChannelCF = 0x3, /**< Center front */ + OMX_AUDIO_ChannelLS = 0x4, /**< Left surround */ + OMX_AUDIO_ChannelRS = 0x5, /**< Right surround */ + OMX_AUDIO_ChannelLFE = 0x6, /**< Low frequency effects */ + OMX_AUDIO_ChannelCS = 0x7, /**< Back surround */ + OMX_AUDIO_ChannelLR = 0x8, /**< Left rear. */ + OMX_AUDIO_ChannelRR = 0x9, /**< Right rear. */ + OMX_AUDIO_ChannelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_ChannelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_ChannelMax = 0x7FFFFFFF +} OMX_AUDIO_CHANNELTYPE; + +#define OMX_AUDIO_MAXCHANNELS 16 /**< maximum number distinct audio channels that a buffer may contain */ +#define OMX_MIN_PCMPAYLOAD_MSEC 5 /**< Minimum audio buffer payload size for uncompressed (PCM) audio */ + +/** PCM format description */ +typedef struct OMX_AUDIO_PARAM_PCMMODETYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels (e.g. 2 for stereo) */ + OMX_NUMERICALDATATYPE eNumData; /**< indicates PCM data as signed or unsigned */ + OMX_ENDIANTYPE eEndian; /**< indicates PCM data as little or big endian */ + OMX_BOOL bInterleaved; /**< True for normal interleaved data; false for + non-interleaved data (e.g. block data) */ + OMX_U32 nBitPerSample; /**< Bit per sample */ + OMX_U32 nSamplingRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_AUDIO_PCMMODETYPE ePCMMode; /**< PCM mode enumeration */ + OMX_AUDIO_CHANNELTYPE eChannelMapping[OMX_AUDIO_MAXCHANNELS]; /**< Slot i contains channel defined by eChannelMap[i] */ + +} OMX_AUDIO_PARAM_PCMMODETYPE; + + +/** Audio channel mode. This is used by both AAC and MP3, although the names are more appropriate + * for the MP3. For example, JointStereo for MP3 is CouplingChannels for AAC. + */ +typedef enum OMX_AUDIO_CHANNELMODETYPE { + OMX_AUDIO_ChannelModeStereo = 0, /**< 2 channels, the bitrate allocation between those + two channels changes accordingly to each channel information */ + OMX_AUDIO_ChannelModeJointStereo, /**< mode that takes advantage of what is common between + 2 channels for higher compression gain */ + OMX_AUDIO_ChannelModeDual, /**< 2 mono-channels, each channel is encoded with half + the bitrate of the overall bitrate */ + OMX_AUDIO_ChannelModeMono, /**< Mono channel mode */ + OMX_AUDIO_ChannelModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_ChannelModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_ChannelModeMax = 0x7FFFFFFF +} OMX_AUDIO_CHANNELMODETYPE; + + +typedef enum OMX_AUDIO_MP3STREAMFORMATTYPE { + OMX_AUDIO_MP3StreamFormatMP1Layer3 = 0, /**< MP3 Audio MPEG 1 Layer 3 Stream format */ + OMX_AUDIO_MP3StreamFormatMP2Layer3, /**< MP3 Audio MPEG 2 Layer 3 Stream format */ + OMX_AUDIO_MP3StreamFormatMP2_5Layer3, /**< MP3 Audio MPEG2.5 Layer 3 Stream format */ + OMX_AUDIO_MP3StreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MP3StreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MP3StreamFormatMax = 0x7FFFFFFF +} OMX_AUDIO_MP3STREAMFORMATTYPE; + +/** MP3 params */ +typedef struct OMX_AUDIO_PARAM_MP3TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should + limit the audio signal. Use 0 to let encoder decide */ + OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ + OMX_AUDIO_MP3STREAMFORMATTYPE eFormat; /**< MP3 stream format */ +} OMX_AUDIO_PARAM_MP3TYPE; + + +typedef enum OMX_AUDIO_AACSTREAMFORMATTYPE { + OMX_AUDIO_AACStreamFormatMP2ADTS = 0, /**< AAC Audio Data Transport Stream 2 format */ + OMX_AUDIO_AACStreamFormatMP4ADTS, /**< AAC Audio Data Transport Stream 4 format */ + OMX_AUDIO_AACStreamFormatMP4LOAS, /**< AAC Low Overhead Audio Stream format */ + OMX_AUDIO_AACStreamFormatMP4LATM, /**< AAC Low overhead Audio Transport Multiplex */ + OMX_AUDIO_AACStreamFormatADIF, /**< AAC Audio Data Interchange Format */ + OMX_AUDIO_AACStreamFormatMP4FF, /**< AAC inside MPEG-4/ISO File Format */ + OMX_AUDIO_AACStreamFormatRAW, /**< AAC Raw Format */ + OMX_AUDIO_AACStreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AACStreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AACStreamFormatMax = 0x7FFFFFFF +} OMX_AUDIO_AACSTREAMFORMATTYPE; + + +/** AAC mode type. Note that the term profile is used with the MPEG-2 + * standard and the term object type and profile is used with MPEG-4 */ +typedef enum OMX_AUDIO_AACPROFILETYPE{ + OMX_AUDIO_AACObjectNull = 0, /**< Null, not used */ + OMX_AUDIO_AACObjectMain = 1, /**< AAC Main object */ + OMX_AUDIO_AACObjectLC, /**< AAC Low Complexity object (AAC profile) */ + OMX_AUDIO_AACObjectSSR, /**< AAC Scalable Sample Rate object */ + OMX_AUDIO_AACObjectLTP, /**< AAC Long Term Prediction object */ + OMX_AUDIO_AACObjectHE, /**< AAC High Efficiency (object type SBR, HE-AAC profile) */ + OMX_AUDIO_AACObjectScalable, /**< AAC Scalable object */ + OMX_AUDIO_AACObjectERLC = 17, /**< ER AAC Low Complexity object (Error Resilient AAC-LC) */ + OMX_AUDIO_AACObjectLD = 23, /**< AAC Low Delay object (Error Resilient) */ + OMX_AUDIO_AACObjectHE_PS = 29, /**< AAC High Efficiency with Parametric Stereo coding (HE-AAC v2, object type PS) */ + OMX_AUDIO_AACObjectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AACObjectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AACObjectMax = 0x7FFFFFFF +} OMX_AUDIO_AACPROFILETYPE; + + +/** AAC tool usage (for nAACtools in OMX_AUDIO_PARAM_AACPROFILETYPE). + * Required for encoder configuration and optional as decoder info output. + * For MP3, OMX_AUDIO_CHANNELMODETYPE is sufficient. */ +#define OMX_AUDIO_AACToolNone 0x00000000 /**< no AAC tools allowed (encoder config) or active (decoder info output) */ +#define OMX_AUDIO_AACToolMS 0x00000001 /**< MS: Mid/side joint coding tool allowed or active */ +#define OMX_AUDIO_AACToolIS 0x00000002 /**< IS: Intensity stereo tool allowed or active */ +#define OMX_AUDIO_AACToolTNS 0x00000004 /**< TNS: Temporal Noise Shaping tool allowed or active */ +#define OMX_AUDIO_AACToolPNS 0x00000008 /**< PNS: MPEG-4 Perceptual Noise substitution tool allowed or active */ +#define OMX_AUDIO_AACToolLTP 0x00000010 /**< LTP: MPEG-4 Long Term Prediction tool allowed or active */ +#define OMX_AUDIO_AACToolAll 0x7FFFFFFF /**< all AAC tools allowed or active (*/ + +/** MPEG-4 AAC error resilience (ER) tool usage (for nAACERtools in OMX_AUDIO_PARAM_AACPROFILETYPE). + * Required for ER encoder configuration and optional as decoder info output */ +#define OMX_AUDIO_AACERNone 0x00000000 /**< no AAC ER tools allowed/used */ +#define OMX_AUDIO_AACERVCB11 0x00000001 /**< VCB11: Virtual Code Books for AAC section data */ +#define OMX_AUDIO_AACERRVLC 0x00000002 /**< RVLC: Reversible Variable Length Coding */ +#define OMX_AUDIO_AACERHCR 0x00000004 /**< HCR: Huffman Codeword Reordering */ +#define OMX_AUDIO_AACERAll 0x7FFFFFFF /**< all AAC ER tools allowed/used */ + + +/** AAC params */ +typedef struct OMX_AUDIO_PARAM_AACPROFILETYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should + limit the audio signal. Use 0 to let encoder decide */ + OMX_U32 nFrameLength; /**< Frame length (in audio samples per channel) of the codec. + Can be 1024 or 960 (AAC-LC), 2048 (HE-AAC), 480 or 512 (AAC-LD). + Use 0 to let encoder decide */ + OMX_U32 nAACtools; /**< AAC tool usage */ + OMX_U32 nAACERtools; /**< MPEG-4 AAC error resilience tool usage */ + OMX_AUDIO_AACPROFILETYPE eAACProfile; /**< AAC profile enumeration */ + OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat; /**< AAC stream format enumeration */ + OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ +} OMX_AUDIO_PARAM_AACPROFILETYPE; + + +/** VORBIS params */ +typedef struct OMX_AUDIO_PARAM_VORBISTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the encoded data data. Use 0 for variable + rate or unknown bit rates. Encoding is set to the + bitrate closest to specified value (in bps) */ + OMX_U32 nMinBitRate; /**< Sets minimum bitrate (in bps). */ + OMX_U32 nMaxBitRate; /**< Sets maximum bitrate (in bps). */ + + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should + limit the audio signal. Use 0 to let encoder decide */ + OMX_S32 nQuality; /**< Sets encoding quality to n, between -1 (low) and 10 (high). + In the default mode of operation, teh quality level is 3. + Normal quality range is 0 - 10. */ + OMX_BOOL bManaged; /**< Set bitrate management mode. This turns off the + normal VBR encoding, but allows hard or soft bitrate + constraints to be enforced by the encoder. This mode can + be slower, and may also be lower quality. It is + primarily useful for streaming. */ + OMX_BOOL bDownmix; /**< Downmix input from stereo to mono (has no effect on + non-stereo streams). Useful for lower-bitrate encoding. */ +} OMX_AUDIO_PARAM_VORBISTYPE; + + +/** WMA Version */ +typedef enum OMX_AUDIO_WMAFORMATTYPE { + OMX_AUDIO_WMAFormatUnused = 0, /**< format unused or unknown */ + OMX_AUDIO_WMAFormat7, /**< Windows Media Audio format 7 */ + OMX_AUDIO_WMAFormat8, /**< Windows Media Audio format 8 */ + OMX_AUDIO_WMAFormat9, /**< Windows Media Audio format 9 */ + OMX_AUDIO_WMAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_WMAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_WMAFormatMax = 0x7FFFFFFF +} OMX_AUDIO_WMAFORMATTYPE; + + +/** WMA Profile */ +typedef enum OMX_AUDIO_WMAPROFILETYPE { + OMX_AUDIO_WMAProfileUnused = 0, /**< profile unused or unknown */ + OMX_AUDIO_WMAProfileL1, /**< Windows Media audio version 9 profile L1 */ + OMX_AUDIO_WMAProfileL2, /**< Windows Media audio version 9 profile L2 */ + OMX_AUDIO_WMAProfileL3, /**< Windows Media audio version 9 profile L3 */ + OMX_AUDIO_WMAProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_WMAProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_WMAProfileMax = 0x7FFFFFFF +} OMX_AUDIO_WMAPROFILETYPE; + + +/** WMA params */ +typedef struct OMX_AUDIO_PARAM_WMATYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U16 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_AUDIO_WMAFORMATTYPE eFormat; /**< Version of WMA stream / data */ + OMX_AUDIO_WMAPROFILETYPE eProfile; /**< Profile of WMA stream / data */ + OMX_U32 nSamplingRate; /**< Sampling rate of the source data */ + OMX_U16 nBlockAlign; /**< is the block alignment, or block size, in bytes of the audio codec */ + OMX_U16 nEncodeOptions; /**< WMA Type-specific data */ + OMX_U32 nSuperBlockAlign; /**< WMA Type-specific data */ +} OMX_AUDIO_PARAM_WMATYPE; + +/** + * RealAudio format + */ +typedef enum OMX_AUDIO_RAFORMATTYPE { + OMX_AUDIO_RAFormatUnused = 0, /**< Format unused or unknown */ + OMX_AUDIO_RA8, /**< RealAudio 8 codec */ + OMX_AUDIO_RA9, /**< RealAudio 9 codec */ + OMX_AUDIO_RA10_AAC, /**< MPEG-4 AAC codec for bitrates of more than 128kbps */ + OMX_AUDIO_RA10_CODEC, /**< RealAudio codec for bitrates less than 128 kbps */ + OMX_AUDIO_RA10_LOSSLESS, /**< RealAudio Lossless */ + OMX_AUDIO_RA10_MULTICHANNEL, /**< RealAudio Multichannel */ + OMX_AUDIO_RA10_VOICE, /**< RealAudio Voice for bitrates below 15 kbps */ + OMX_AUDIO_RAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_RAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_RAFormatMax = 0x7FFFFFFF +} OMX_AUDIO_RAFORMATTYPE; + +/** RA (Real Audio) params */ +typedef struct OMX_AUDIO_PARAM_RATYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nSamplingRate; /**< is the sampling rate of the source data */ + OMX_U32 nBitsPerFrame; /**< is the value for bits per frame */ + OMX_U32 nSamplePerFrame; /**< is the value for samples per frame */ + OMX_U32 nCouplingQuantBits; /**< is the number of coupling quantization bits in the stream */ + OMX_U32 nCouplingStartRegion; /**< is the coupling start region in the stream */ + OMX_U32 nNumRegions; /**< is the number of regions value */ + OMX_AUDIO_RAFORMATTYPE eFormat; /**< is the RealAudio audio format */ +} OMX_AUDIO_PARAM_RATYPE; + + +/** SBC Allocation Method Type */ +typedef enum OMX_AUDIO_SBCALLOCMETHODTYPE { + OMX_AUDIO_SBCAllocMethodLoudness, /**< Loudness allocation method */ + OMX_AUDIO_SBCAllocMethodSNR, /**< SNR allocation method */ + OMX_AUDIO_SBCAllocMethodKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_SBCAllocMethodVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_SBCAllocMethodMax = 0x7FFFFFFF +} OMX_AUDIO_SBCALLOCMETHODTYPE; + + +/** SBC params */ +typedef struct OMX_AUDIO_PARAM_SBCTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nBlocks; /**< Number of blocks */ + OMX_U32 nSubbands; /**< Number of subbands */ + OMX_U32 nBitPool; /**< Bitpool value */ + OMX_BOOL bEnableBitrate; /**< Use bitrate value instead of bitpool */ + OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ + OMX_AUDIO_SBCALLOCMETHODTYPE eSBCAllocType; /**< SBC Allocation method type */ +} OMX_AUDIO_PARAM_SBCTYPE; + + +/** ADPCM stream format parameters */ +typedef struct OMX_AUDIO_PARAM_ADPCMTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_U32 nBitsPerSample; /**< Number of bits in each sample */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ +} OMX_AUDIO_PARAM_ADPCMTYPE; + + +/** G723 rate */ +typedef enum OMX_AUDIO_G723RATE { + OMX_AUDIO_G723ModeUnused = 0, /**< AMRNB Mode unused / unknown */ + OMX_AUDIO_G723ModeLow, /**< 5300 bps */ + OMX_AUDIO_G723ModeHigh, /**< 6300 bps */ + OMX_AUDIO_G723ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_G723ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_G723ModeMax = 0x7FFFFFFF +} OMX_AUDIO_G723RATE; + + +/** G723 - Sample rate must be 8 KHz */ +typedef struct OMX_AUDIO_PARAM_G723TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_AUDIO_G723RATE eBitRate; /**< todo: Should this be moved to a config? */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ + OMX_BOOL bPostFilter; /**< Enable Post Filter */ +} OMX_AUDIO_PARAM_G723TYPE; + + +/** ITU G726 (ADPCM) rate */ +typedef enum OMX_AUDIO_G726MODE { + OMX_AUDIO_G726ModeUnused = 0, /**< G726 Mode unused / unknown */ + OMX_AUDIO_G726Mode16, /**< 16 kbps */ + OMX_AUDIO_G726Mode24, /**< 24 kbps */ + OMX_AUDIO_G726Mode32, /**< 32 kbps, most common rate, also G721 */ + OMX_AUDIO_G726Mode40, /**< 40 kbps */ + OMX_AUDIO_G726ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_G726ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_G726ModeMax = 0x7FFFFFFF +} OMX_AUDIO_G726MODE; + + +/** G.726 stream format parameters - must be at 8KHz */ +typedef struct OMX_AUDIO_PARAM_G726TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_G726MODE eG726Mode; +} OMX_AUDIO_PARAM_G726TYPE; + + +/** G729 coder type */ +typedef enum OMX_AUDIO_G729TYPE { + OMX_AUDIO_G729 = 0, /**< ITU G.729 encoded data */ + OMX_AUDIO_G729A, /**< ITU G.729 annex A encoded data */ + OMX_AUDIO_G729B, /**< ITU G.729 with annex B encoded data */ + OMX_AUDIO_G729AB, /**< ITU G.729 annexes A and B encoded data */ + OMX_AUDIO_G729KhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_G729VendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_G729Max = 0x7FFFFFFF +} OMX_AUDIO_G729TYPE; + + +/** G729 stream format parameters - fixed 6KHz sample rate */ +typedef struct OMX_AUDIO_PARAM_G729TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_AUDIO_G729TYPE eBitType; +} OMX_AUDIO_PARAM_G729TYPE; + + +/** AMR Frame format */ +typedef enum OMX_AUDIO_AMRFRAMEFORMATTYPE { + OMX_AUDIO_AMRFrameFormatConformance = 0, /**< Frame Format is AMR Conformance + (Standard) Format */ + OMX_AUDIO_AMRFrameFormatIF1, /**< Frame Format is AMR Interface + Format 1 */ + OMX_AUDIO_AMRFrameFormatIF2, /**< Frame Format is AMR Interface + Format 2*/ + OMX_AUDIO_AMRFrameFormatFSF, /**< Frame Format is AMR File Storage + Format */ + OMX_AUDIO_AMRFrameFormatRTPPayload, /**< Frame Format is AMR Real-Time + Transport Protocol Payload Format */ + OMX_AUDIO_AMRFrameFormatITU, /**< Frame Format is ITU Format (added at Motorola request) */ + OMX_AUDIO_AMRFrameFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AMRFrameFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AMRFrameFormatMax = 0x7FFFFFFF +} OMX_AUDIO_AMRFRAMEFORMATTYPE; + + +/** AMR band mode */ +typedef enum OMX_AUDIO_AMRBANDMODETYPE { + OMX_AUDIO_AMRBandModeUnused = 0, /**< AMRNB Mode unused / unknown */ + OMX_AUDIO_AMRBandModeNB0, /**< AMRNB Mode 0 = 4750 bps */ + OMX_AUDIO_AMRBandModeNB1, /**< AMRNB Mode 1 = 5150 bps */ + OMX_AUDIO_AMRBandModeNB2, /**< AMRNB Mode 2 = 5900 bps */ + OMX_AUDIO_AMRBandModeNB3, /**< AMRNB Mode 3 = 6700 bps */ + OMX_AUDIO_AMRBandModeNB4, /**< AMRNB Mode 4 = 7400 bps */ + OMX_AUDIO_AMRBandModeNB5, /**< AMRNB Mode 5 = 7950 bps */ + OMX_AUDIO_AMRBandModeNB6, /**< AMRNB Mode 6 = 10200 bps */ + OMX_AUDIO_AMRBandModeNB7, /**< AMRNB Mode 7 = 12200 bps */ + OMX_AUDIO_AMRBandModeWB0, /**< AMRWB Mode 0 = 6600 bps */ + OMX_AUDIO_AMRBandModeWB1, /**< AMRWB Mode 1 = 8850 bps */ + OMX_AUDIO_AMRBandModeWB2, /**< AMRWB Mode 2 = 12650 bps */ + OMX_AUDIO_AMRBandModeWB3, /**< AMRWB Mode 3 = 14250 bps */ + OMX_AUDIO_AMRBandModeWB4, /**< AMRWB Mode 4 = 15850 bps */ + OMX_AUDIO_AMRBandModeWB5, /**< AMRWB Mode 5 = 18250 bps */ + OMX_AUDIO_AMRBandModeWB6, /**< AMRWB Mode 6 = 19850 bps */ + OMX_AUDIO_AMRBandModeWB7, /**< AMRWB Mode 7 = 23050 bps */ + OMX_AUDIO_AMRBandModeWB8, /**< AMRWB Mode 8 = 23850 bps */ + OMX_AUDIO_AMRBandModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AMRBandModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AMRBandModeMax = 0x7FFFFFFF +} OMX_AUDIO_AMRBANDMODETYPE; + + +/** AMR Discontinuous Transmission mode */ +typedef enum OMX_AUDIO_AMRDTXMODETYPE { + OMX_AUDIO_AMRDTXModeOff = 0, /**< AMR Discontinuous Transmission Mode is disabled */ + OMX_AUDIO_AMRDTXModeOnVAD1, /**< AMR Discontinuous Transmission Mode using + Voice Activity Detector 1 (VAD1) is enabled */ + OMX_AUDIO_AMRDTXModeOnVAD2, /**< AMR Discontinuous Transmission Mode using + Voice Activity Detector 2 (VAD2) is enabled */ + OMX_AUDIO_AMRDTXModeOnAuto, /**< The codec will automatically select between + Off, VAD1 or VAD2 modes */ + + OMX_AUDIO_AMRDTXasEFR, /**< DTX as EFR instead of AMR standard (3GPP 26.101, frame type =8,9,10) */ + + OMX_AUDIO_AMRDTXModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AMRDTXModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AMRDTXModeMax = 0x7FFFFFFF +} OMX_AUDIO_AMRDTXMODETYPE; + + +/** AMR params */ +typedef struct OMX_AUDIO_PARAM_AMRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate read only field */ + OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode; /**< AMR Band Mode enumeration */ + OMX_AUDIO_AMRDTXMODETYPE eAMRDTXMode; /**< AMR DTX Mode enumeration */ + OMX_AUDIO_AMRFRAMEFORMATTYPE eAMRFrameFormat; /**< AMR frame format enumeration */ +} OMX_AUDIO_PARAM_AMRTYPE; + + +/** GSM_FR (ETSI 06.10, 3GPP 46.010) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_GSMFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_GSMFRTYPE; + + +/** GSM-HR (ETSI 06.20, 3GPP 46.020) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_GSMHRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_GSMHRTYPE; + + +/** GSM-EFR (ETSI 06.60, 3GPP 46.060) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_GSMEFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_GSMEFRTYPE; + + +/** TDMA FR (TIA/EIA-136-420, VSELP 7.95kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_TDMAFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_TDMAFRTYPE; + + +/** TDMA EFR (TIA/EIA-136-410, ACELP 7.4kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_TDMAEFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_TDMAEFRTYPE; + + +/** PDC FR ( RCR-27, VSELP 6.7kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_PDCFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_PDCFRTYPE; + + +/** PDC EFR ( RCR-27, ACELP 6.7kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_PDCEFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_PDCEFRTYPE; + +/** PDC HR ( RCR-27, PSI-CELP 3.45kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_PDCHRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_PDCHRTYPE; + + +/** CDMA Rate types */ +typedef enum OMX_AUDIO_CDMARATETYPE { + OMX_AUDIO_CDMARateBlank = 0, /**< CDMA encoded frame is blank */ + OMX_AUDIO_CDMARateFull, /**< CDMA encoded frame in full rate */ + OMX_AUDIO_CDMARateHalf, /**< CDMA encoded frame in half rate */ + OMX_AUDIO_CDMARateQuarter, /**< CDMA encoded frame in quarter rate */ + OMX_AUDIO_CDMARateEighth, /**< CDMA encoded frame in eighth rate (DTX)*/ + OMX_AUDIO_CDMARateErasure, /**< CDMA erasure frame */ + OMX_AUDIO_CDMARateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_CDMARateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_CDMARateMax = 0x7FFFFFFF +} OMX_AUDIO_CDMARATETYPE; + + +/** QCELP8 (TIA/EIA-96, up to 8kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_QCELP8TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ +} OMX_AUDIO_PARAM_QCELP8TYPE; + + +/** QCELP13 ( CDMA, EIA/TIA-733, 13.3kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_QCELP13TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ +} OMX_AUDIO_PARAM_QCELP13TYPE; + + +/** EVRC ( CDMA, EIA/TIA-127, RCELP up to 8.55kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_EVRCTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< actual Frame rate */ + OMX_BOOL bRATE_REDUCon; /**< RATE_REDUCtion is requested for this frame */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ + OMX_BOOL bHiPassFilter; /**< Enable encoder's High Pass Filter */ + OMX_BOOL bNoiseSuppressor; /**< Enable encoder's noise suppressor pre-processing */ + OMX_BOOL bPostFilter; /**< Enable decoder's post Filter */ +} OMX_AUDIO_PARAM_EVRCTYPE; + + +/** SMV ( up to 8.55kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_SMVTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ + OMX_BOOL bRATE_REDUCon; /**< RATE_REDUCtion is requested for this frame */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 ??*/ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 ??*/ + OMX_BOOL bHiPassFilter; /**< Enable encoder's High Pass Filter ??*/ + OMX_BOOL bNoiseSuppressor; /**< Enable encoder's noise suppressor pre-processing */ + OMX_BOOL bPostFilter; /**< Enable decoder's post Filter ??*/ +} OMX_AUDIO_PARAM_SMVTYPE; + + +/** MIDI Format + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDIFORMATTYPE +{ + OMX_AUDIO_MIDIFormatUnknown = 0, /**< MIDI Format unknown or don't care */ + OMX_AUDIO_MIDIFormatSMF0, /**< Standard MIDI File Type 0 */ + OMX_AUDIO_MIDIFormatSMF1, /**< Standard MIDI File Type 1 */ + OMX_AUDIO_MIDIFormatSMF2, /**< Standard MIDI File Type 2 */ + OMX_AUDIO_MIDIFormatSPMIDI, /**< SP-MIDI */ + OMX_AUDIO_MIDIFormatXMF0, /**< eXtensible Music Format type 0 */ + OMX_AUDIO_MIDIFormatXMF1, /**< eXtensible Music Format type 1 */ + OMX_AUDIO_MIDIFormatMobileXMF, /**< Mobile XMF (eXtensible Music Format type 2) */ + OMX_AUDIO_MIDIFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDIFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDIFormatMax = 0x7FFFFFFF +} OMX_AUDIO_MIDIFORMATTYPE; + + +/** MIDI params + * @ingroup midi + */ +typedef struct OMX_AUDIO_PARAM_MIDITYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nFileSize; /**< size of the MIDI file in bytes, where the entire + MIDI file passed in, otherwise if 0x0, the MIDI data + is merged and streamed (instead of passed as an + entire MIDI file) */ + OMX_BU32 sMaxPolyphony; /**< Specifies the maximum simultaneous polyphonic + voices. A value of zero indicates that the default + polyphony of the device is used */ + OMX_BOOL bLoadDefaultSound; /**< Whether to load default sound + bank at initialization */ + OMX_AUDIO_MIDIFORMATTYPE eMidiFormat; /**< Version of the MIDI file */ +} OMX_AUDIO_PARAM_MIDITYPE; + + +/** Type of the MIDI sound bank + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDISOUNDBANKTYPE { + OMX_AUDIO_MIDISoundBankUnused = 0, /**< unused/unknown soundbank type */ + OMX_AUDIO_MIDISoundBankDLS1, /**< DLS version 1 */ + OMX_AUDIO_MIDISoundBankDLS2, /**< DLS version 2 */ + OMX_AUDIO_MIDISoundBankMobileDLSBase, /**< Mobile DLS, using the base functionality */ + OMX_AUDIO_MIDISoundBankMobileDLSPlusOptions, /**< Mobile DLS, using the specification-defined optional feature set */ + OMX_AUDIO_MIDISoundBankKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDISoundBankVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDISoundBankMax = 0x7FFFFFFF +} OMX_AUDIO_MIDISOUNDBANKTYPE; + + +/** Bank Layout describes how bank MSB & LSB are used in the DLS instrument definitions sound bank + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE { + OMX_AUDIO_MIDISoundBankLayoutUnused = 0, /**< unused/unknown soundbank type */ + OMX_AUDIO_MIDISoundBankLayoutGM, /**< GS layout (based on bank MSB 0x00) */ + OMX_AUDIO_MIDISoundBankLayoutGM2, /**< General MIDI 2 layout (using MSB 0x78/0x79, LSB 0x00) */ + OMX_AUDIO_MIDISoundBankLayoutUser, /**< Does not conform to any bank numbering standards */ + OMX_AUDIO_MIDISoundBankLayoutKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDISoundBankLayoutVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDISoundBankLayoutMax = 0x7FFFFFFF +} OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE; + + +/** MIDI params to load/unload user soundbank + * @ingroup midi + */ +typedef struct OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nDLSIndex; /**< DLS file index to be loaded */ + OMX_U32 nDLSSize; /**< Size in bytes */ + OMX_PTR pDLSData; /**< Pointer to DLS file data */ + OMX_AUDIO_MIDISOUNDBANKTYPE eMidiSoundBank; /**< Midi sound bank type enumeration */ + OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE eMidiSoundBankLayout; /**< Midi sound bank layout enumeration */ +} OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE; + + +/** Structure for Live MIDI events and MIP messages. + * (MIP = Maximum Instantaneous Polyphony; part of the SP-MIDI standard.) + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nMidiEventSize; /**< Size of immediate MIDI events or MIP message in bytes */ + OMX_U8 nMidiEvents[1]; /**< MIDI event array to be rendered immediately, or an + array for the MIP message buffer, where the size is + indicated by nMidiEventSize */ +} OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE; + + +/** MIDI sound bank/ program pair in a given channel + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nChannel; /**< Valid channel values range from 1 to 16 */ + OMX_U16 nIDProgram; /**< Valid program ID range is 1 to 128 */ + OMX_U16 nIDSoundBank; /**< Sound bank ID */ + OMX_U32 nUserSoundBankIndex;/**< User soundbank index, easier to access soundbanks + by index if multiple banks are present */ +} OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE; + + +/** MIDI control + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDICONTROLTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BS32 sPitchTransposition; /**< Pitch transposition in semitones, stored as Q22.10 + format based on JAVA MMAPI (JSR-135) requirement */ + OMX_BU32 sPlayBackRate; /**< Relative playback rate, stored as Q14.17 fixed-point + number based on JSR-135 requirement */ + OMX_BU32 sTempo ; /**< Tempo in beats per minute (BPM), stored as Q22.10 + fixed-point number based on JSR-135 requirement */ + OMX_U32 nMaxPolyphony; /**< Specifies the maximum simultaneous polyphonic + voices. A value of zero indicates that the default + polyphony of the device is used */ + OMX_U32 nNumRepeat; /**< Number of times to repeat playback */ + OMX_U32 nStopTime; /**< Time in milliseconds to indicate when playback + will stop automatically. Set to zero if not used */ + OMX_U16 nChannelMuteMask; /**< 16 bit mask for channel mute status */ + OMX_U16 nChannelSoloMask; /**< 16 bit mask for channel solo status */ + OMX_U32 nTrack0031MuteMask; /**< 32 bit mask for track mute status. Note: This is for tracks 0-31 */ + OMX_U32 nTrack3263MuteMask; /**< 32 bit mask for track mute status. Note: This is for tracks 32-63 */ + OMX_U32 nTrack0031SoloMask; /**< 32 bit mask for track solo status. Note: This is for tracks 0-31 */ + OMX_U32 nTrack3263SoloMask; /**< 32 bit mask for track solo status. Note: This is for tracks 32-63 */ + +} OMX_AUDIO_CONFIG_MIDICONTROLTYPE; + + +/** MIDI Playback States + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDIPLAYBACKSTATETYPE { + OMX_AUDIO_MIDIPlayBackStateUnknown = 0, /**< Unknown state or state does not map to + other defined states */ + OMX_AUDIO_MIDIPlayBackStateClosedEngaged, /**< No MIDI resource is currently open. + The MIDI engine is currently processing + MIDI events. */ + OMX_AUDIO_MIDIPlayBackStateParsing, /**< A MIDI resource is open and is being + primed. The MIDI engine is currently + processing MIDI events. */ + OMX_AUDIO_MIDIPlayBackStateOpenEngaged, /**< A MIDI resource is open and primed but + not playing. The MIDI engine is currently + processing MIDI events. The transition to + this state is only possible from the + OMX_AUDIO_MIDIPlayBackStatePlaying state, + when the 'playback head' reaches the end + of media data or the playback stops due + to stop time set.*/ + OMX_AUDIO_MIDIPlayBackStatePlaying, /**< A MIDI resource is open and currently + playing. The MIDI engine is currently + processing MIDI events.*/ + OMX_AUDIO_MIDIPlayBackStatePlayingPartially, /**< Best-effort playback due to SP-MIDI/DLS + resource constraints */ + OMX_AUDIO_MIDIPlayBackStatePlayingSilently, /**< Due to system resource constraints and + SP-MIDI content constraints, there is + no audible MIDI content during playback + currently. The situation may change if + resources are freed later.*/ + OMX_AUDIO_MIDIPlayBackStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDIPlayBackStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDIPlayBackStateMax = 0x7FFFFFFF +} OMX_AUDIO_MIDIPLAYBACKSTATETYPE; + + +/** MIDI status + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDISTATUSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U16 nNumTracks; /**< Number of MIDI tracks in the file, read only field. + NOTE: May not return a meaningful value until the entire + file is parsed and buffered. */ + OMX_U32 nDuration; /**< The length of the currently open MIDI resource + in milliseconds. NOTE: May not return a meaningful value + until the entire file is parsed and buffered. */ + OMX_U32 nPosition; /**< Current Position of the MIDI resource being played + in milliseconds */ + OMX_BOOL bVibra; /**< Does Vibra track exist? NOTE: May not return a meaningful + value until the entire file is parsed and buffered. */ + OMX_U32 nNumMetaEvents; /**< Total number of MIDI Meta Events in the currently + open MIDI resource. NOTE: May not return a meaningful value + until the entire file is parsed and buffered. */ + OMX_U32 nNumActiveVoices; /**< Number of active voices in the currently playing + MIDI resource. NOTE: May not return a meaningful value until + the entire file is parsed and buffered. */ + OMX_AUDIO_MIDIPLAYBACKSTATETYPE eMIDIPlayBackState; /**< MIDI playback state enumeration, read only field */ +} OMX_AUDIO_CONFIG_MIDISTATUSTYPE; + + +/** MIDI Meta Event structure one per Meta Event. + * MIDI Meta Events are like audio metadata, except that they are interspersed + * with the MIDI content throughout the file and are not localized in the header. + * As such, it is necessary to retrieve information about these Meta Events from + * the engine, as it encounters these Meta Events within the MIDI content. + * For example, SMF files can have up to 14 types of MIDI Meta Events (copyright, + * author, default tempo, etc.) scattered throughout the file. + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nIndex; /**< Index of Meta Event */ + OMX_U8 nMetaEventType; /**< Meta Event Type, 7bits (i.e. 0 - 127) */ + OMX_U32 nMetaEventSize; /**< size of the Meta Event in bytes */ + OMX_U32 nTrack; /**< track number for the meta event */ + OMX_U32 nPosition; /**< Position of the meta-event in milliseconds */ +} OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE; + + +/** MIDI Meta Event Data structure - one per Meta Event. + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nIndex; /**< Index of Meta Event */ + OMX_U32 nMetaEventSize; /**< size of the Meta Event in bytes */ + OMX_U8 nData[1]; /**< array of one or more bytes of meta data + as indicated by the nMetaEventSize field */ +} OMX_AUDIO_CONFIG__MIDIMETAEVENTDATATYPE; + + +/** Audio Volume adjustment for a port */ +typedef struct OMX_AUDIO_CONFIG_VOLUMETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's volume. Select the + output port to adjust the master + volume. */ + OMX_BOOL bLinear; /**< Is the volume to be set in linear (0.100) + or logarithmic scale (mB) */ + OMX_BS32 sVolume; /**< Volume linear setting in the 0..100 range, OR + Volume logarithmic setting for this port. The values + for volume are in mB (millibels = 1/100 dB) relative + to a gain of 1 (e.g. the output is the same as the + input level). Values are in mB from nMax + (maximum volume) to nMin mB (typically negative). + Since the volume is "voltage" + and not a "power", it takes a setting of + -600 mB to decrease the volume by 1/2. If + a component cannot accurately set the + volume to the requested value, it must + set the volume to the closest value BELOW + the requested value. When getting the + volume setting, the current actual volume + must be returned. */ +} OMX_AUDIO_CONFIG_VOLUMETYPE; + + +/** Audio Volume adjustment for a channel */ +typedef struct OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's volume. Select the + output port to adjust the master + volume. */ + OMX_U32 nChannel; /**< channel to select from 0 to N-1, + using OMX_ALL to apply volume settings + to all channels */ + OMX_BOOL bLinear; /**< Is the volume to be set in linear (0.100) or + logarithmic scale (mB) */ + OMX_BS32 sVolume; /**< Volume linear setting in the 0..100 range, OR + Volume logarithmic setting for this port. + The values for volume are in mB + (millibels = 1/100 dB) relative to a gain + of 1 (e.g. the output is the same as the + input level). Values are in mB from nMax + (maximum volume) to nMin mB (typically negative). + Since the volume is "voltage" + and not a "power", it takes a setting of + -600 mB to decrease the volume by 1/2. If + a component cannot accurately set the + volume to the requested value, it must + set the volume to the closest value BELOW + the requested value. When getting the + volume setting, the current actual volume + must be returned. */ + OMX_BOOL bIsMIDI; /**< TRUE if nChannel refers to a MIDI channel, + FALSE otherwise */ +} OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE; + + +/** Audio balance setting */ +typedef struct OMX_AUDIO_CONFIG_BALANCETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's balance. Select the + output port to adjust the master + balance. */ + OMX_S32 nBalance; /**< balance setting for this port + (-100 to 100, where -100 indicates + all left, and no right */ +} OMX_AUDIO_CONFIG_BALANCETYPE; + + +/** Audio Port mute */ +typedef struct OMX_AUDIO_CONFIG_MUTETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's mute. Select the + output port to adjust the master + mute. */ + OMX_BOOL bMute; /**< Mute setting for this port */ +} OMX_AUDIO_CONFIG_MUTETYPE; + + +/** Audio Channel mute */ +typedef struct OMX_AUDIO_CONFIG_CHANNELMUTETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannel; /**< channel to select from 0 to N-1, + using OMX_ALL to apply mute settings + to all channels */ + OMX_BOOL bMute; /**< Mute setting for this channel */ + OMX_BOOL bIsMIDI; /**< TRUE if nChannel refers to a MIDI channel, + FALSE otherwise */ +} OMX_AUDIO_CONFIG_CHANNELMUTETYPE; + + + +/** Enable / Disable for loudness control, which boosts bass and to a + * smaller extent high end frequencies to compensate for hearing + * ability at the extreme ends of the audio spectrum + */ +typedef struct OMX_AUDIO_CONFIG_LOUDNESSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bLoudness; /**< Enable/disable for loudness */ +} OMX_AUDIO_CONFIG_LOUDNESSTYPE; + + +/** Enable / Disable for bass, which controls low frequencies + */ +typedef struct OMX_AUDIO_CONFIG_BASSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for bass control */ + OMX_S32 nBass; /**< bass setting for the port, as a + continuous value from -100 to 100 + (0 means no change in bass level)*/ +} OMX_AUDIO_CONFIG_BASSTYPE; + + +/** Enable / Disable for treble, which controls high frequencies tones + */ +typedef struct OMX_AUDIO_CONFIG_TREBLETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for treble control */ + OMX_S32 nTreble; /**< treble setting for the port, as a + continuous value from -100 to 100 + (0 means no change in treble level) */ +} OMX_AUDIO_CONFIG_TREBLETYPE; + + +/** An equalizer is typically used for two reasons: to compensate for an + * sub-optimal frequency response of a system to make it sound more natural + * or to create intentionally some unnatural coloring to the sound to create + * an effect. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_EQUALIZERTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for equalizer */ + OMX_BU32 sBandIndex; /**< Band number to be set. Upper Limit is + N-1, where N is the number of bands, lower limit is 0 */ + OMX_BU32 sCenterFreq; /**< Center frequecies in Hz. This is a + read only element and is used to determine + the lower, center and upper frequency of + this band. */ + OMX_BS32 sBandLevel; /**< band level in millibels */ +} OMX_AUDIO_CONFIG_EQUALIZERTYPE; + + +/** Stereo widening mode type + * @ingroup effects + */ +typedef enum OMX_AUDIO_STEREOWIDENINGTYPE { + OMX_AUDIO_StereoWideningHeadphones, /**< Stereo widening for loudspeakers */ + OMX_AUDIO_StereoWideningLoudspeakers, /**< Stereo widening for closely spaced loudspeakers */ + OMX_AUDIO_StereoWideningKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_StereoWideningVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_StereoWideningMax = 0x7FFFFFFF +} OMX_AUDIO_STEREOWIDENINGTYPE; + + +/** Control for stereo widening, which is a special 2-channel + * case of the audio virtualizer effect. For example, for 5.1-channel + * output, it translates to virtual surround sound. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for stereo widening control */ + OMX_AUDIO_STEREOWIDENINGTYPE eWideningType; /**< Stereo widening algorithm type */ + OMX_U32 nStereoWidening; /**< stereo widening setting for the port, + as a continuous value from 0 to 100 */ +} OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE; + + +/** The chorus effect (or ``choralizer'') is any signal processor which makes + * one sound source (such as a voice) sound like many such sources singing + * (or playing) in unison. Since performance in unison is never exact, chorus + * effects simulate this by making independently modified copies of the input + * signal. Modifications may include (1) delay, (2) frequency shift, and + * (3) amplitude modulation. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_CHORUSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for chorus */ + OMX_BU32 sDelay; /**< average delay in milliseconds */ + OMX_BU32 sModulationRate; /**< rate of modulation in millihertz */ + OMX_U32 nModulationDepth; /**< depth of modulation as a percentage of + delay (i.e. 0 to 100) */ + OMX_BU32 nFeedback; /**< Feedback from chorus output to input in percentage */ +} OMX_AUDIO_CONFIG_CHORUSTYPE; + + +/** Reverberation is part of the reflected sound that follows the early + * reflections. In a typical room, this consists of a dense succession of + * echoes whose energy decays exponentially. The reverberation effect structure + * as defined here includes both (early) reflections as well as (late) reverberations. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_REVERBERATIONTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for reverberation control */ + OMX_BS32 sRoomLevel; /**< Intensity level for the whole room effect + (i.e. both early reflections and late + reverberation) in millibels */ + OMX_BS32 sRoomHighFreqLevel; /**< Attenuation at high frequencies + relative to the intensity at low + frequencies in millibels */ + OMX_BS32 sReflectionsLevel; /**< Intensity level of early reflections + (relative to room value), in millibels */ + OMX_BU32 sReflectionsDelay; /**< Delay time of the first reflection relative + to the direct path, in milliseconds */ + OMX_BS32 sReverbLevel; /**< Intensity level of late reverberation + relative to room level, in millibels */ + OMX_BU32 sReverbDelay; /**< Time delay from the first early reflection + to the beginning of the late reverberation + section, in milliseconds */ + OMX_BU32 sDecayTime; /**< Late reverberation decay time at low + frequencies, in milliseconds */ + OMX_BU32 nDecayHighFreqRatio; /**< Ratio of high frequency decay time relative + to low frequency decay time in percent */ + OMX_U32 nDensity; /**< Modal density in the late reverberation decay, + in percent (i.e. 0 - 100) */ + OMX_U32 nDiffusion; /**< Echo density in the late reverberation decay, + in percent (i.e. 0 - 100) */ + OMX_BU32 sReferenceHighFreq; /**< Reference high frequency in Hertz. This is + the frequency used as the reference for all + the high-frequency settings above */ + +} OMX_AUDIO_CONFIG_REVERBERATIONTYPE; + + +/** Possible settings for the Echo Cancelation structure to use + * @ingroup effects + */ +typedef enum OMX_AUDIO_ECHOCANTYPE { + OMX_AUDIO_EchoCanOff = 0, /**< Echo Cancellation is disabled */ + OMX_AUDIO_EchoCanNormal, /**< Echo Cancellation normal operation - + echo from plastics and face */ + OMX_AUDIO_EchoCanHFree, /**< Echo Cancellation optimized for + Hands Free operation */ + OMX_AUDIO_EchoCanCarKit, /**< Echo Cancellation optimized for + Car Kit (longer echo) */ + OMX_AUDIO_EchoCanKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_EchoCanVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_EchoCanMax = 0x7FFFFFFF +} OMX_AUDIO_ECHOCANTYPE; + + +/** Enable / Disable for echo cancelation, which removes undesired echo's + * from the audio + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_AUDIO_ECHOCANTYPE eEchoCancelation; /**< Echo cancelation settings */ +} OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE; + + +/** Enable / Disable for noise reduction, which undesired noise from + * the audio + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bNoiseReduction; /**< Enable/disable for noise reduction */ +} OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE; + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ + diff --git a/phonelibs/openmax/include/OMX_Component.h b/phonelibs/openmax/include/OMX_Component.h new file mode 100644 index 00000000000000..d5956405e20a1c --- /dev/null +++ b/phonelibs/openmax/include/OMX_Component.h @@ -0,0 +1,579 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** OMX_Component.h - OpenMax IL version 1.1.2 + * The OMX_Component header file contains the definitions used to define + * the public interface of a component. This header file is intended to + * be used by both the application and the component. + */ + +#ifndef OMX_Component_h +#define OMX_Component_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + +/* Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include +#include +#include +#include + +/** @ingroup comp */ +typedef enum OMX_PORTDOMAINTYPE { + OMX_PortDomainAudio, + OMX_PortDomainVideo, + OMX_PortDomainImage, + OMX_PortDomainOther, + OMX_PortDomainKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_PortDomainVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_PortDomainMax = 0x7ffffff +} OMX_PORTDOMAINTYPE; + +/** @ingroup comp */ +typedef struct OMX_PARAM_PORTDEFINITIONTYPE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port number the structure applies to */ + OMX_DIRTYPE eDir; /**< Direction (input or output) of this port */ + OMX_U32 nBufferCountActual; /**< The actual number of buffers allocated on this port */ + OMX_U32 nBufferCountMin; /**< The minimum number of buffers this port requires */ + OMX_U32 nBufferSize; /**< Size, in bytes, for buffers to be used for this channel */ + OMX_BOOL bEnabled; /**< Ports default to enabled and are enabled/disabled by + OMX_CommandPortEnable/OMX_CommandPortDisable. + When disabled a port is unpopulated. A disabled port + is not populated with buffers on a transition to IDLE. */ + OMX_BOOL bPopulated; /**< Port is populated with all of its buffers as indicated by + nBufferCountActual. A disabled port is always unpopulated. + An enabled port is populated on a transition to OMX_StateIdle + and unpopulated on a transition to loaded. */ + OMX_PORTDOMAINTYPE eDomain; /**< Domain of the port. Determines the contents of metadata below. */ + union { + OMX_AUDIO_PORTDEFINITIONTYPE audio; + OMX_VIDEO_PORTDEFINITIONTYPE video; + OMX_IMAGE_PORTDEFINITIONTYPE image; + OMX_OTHER_PORTDEFINITIONTYPE other; + } format; + OMX_BOOL bBuffersContiguous; + OMX_U32 nBufferAlignment; +} OMX_PARAM_PORTDEFINITIONTYPE; + +/** @ingroup comp */ +typedef struct OMX_PARAM_U32TYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nU32; /**< U32 value */ +} OMX_PARAM_U32TYPE; + +/** @ingroup rpm */ +typedef enum OMX_SUSPENSIONPOLICYTYPE { + OMX_SuspensionDisabled, /**< No suspension; v1.0 behavior */ + OMX_SuspensionEnabled, /**< Suspension allowed */ + OMX_SuspensionPolicyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_SuspensionPolicyStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_SuspensionPolicyMax = 0x7fffffff +} OMX_SUSPENSIONPOLICYTYPE; + +/** @ingroup rpm */ +typedef struct OMX_PARAM_SUSPENSIONPOLICYTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_SUSPENSIONPOLICYTYPE ePolicy; +} OMX_PARAM_SUSPENSIONPOLICYTYPE; + +/** @ingroup rpm */ +typedef enum OMX_SUSPENSIONTYPE { + OMX_NotSuspended, /**< component is not suspended */ + OMX_Suspended, /**< component is suspended */ + OMX_SuspensionKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_SuspensionVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_SuspendMax = 0x7FFFFFFF +} OMX_SUSPENSIONTYPE; + +/** @ingroup rpm */ +typedef struct OMX_PARAM_SUSPENSIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_SUSPENSIONTYPE eType; +} OMX_PARAM_SUSPENSIONTYPE ; + +typedef struct OMX_CONFIG_BOOLEANTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bEnabled; +} OMX_CONFIG_BOOLEANTYPE; + +/* Parameter specifying the content uri to use. */ +/** @ingroup cp */ +typedef struct OMX_PARAM_CONTENTURITYPE +{ + OMX_U32 nSize; /**< size of the structure in bytes, including + actual URI name */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U8 contentURI[1]; /**< The URI name */ +} OMX_PARAM_CONTENTURITYPE; + +/* Parameter specifying the pipe to use. */ +/** @ingroup cp */ +typedef struct OMX_PARAM_CONTENTPIPETYPE +{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_HANDLETYPE hPipe; /**< The pipe handle*/ +} OMX_PARAM_CONTENTPIPETYPE; + +/** @ingroup rpm */ +typedef struct OMX_RESOURCECONCEALMENTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_BOOL bResourceConcealmentForbidden; /**< disallow the use of resource concealment + methods (like degrading algorithm quality to + lower resource consumption or functional bypass) + on a component as a resolution to resource conflicts. */ +} OMX_RESOURCECONCEALMENTTYPE; + + +/** @ingroup metadata */ +typedef enum OMX_METADATACHARSETTYPE { + OMX_MetadataCharsetUnknown = 0, + OMX_MetadataCharsetASCII, + OMX_MetadataCharsetBinary, + OMX_MetadataCharsetCodePage1252, + OMX_MetadataCharsetUTF8, + OMX_MetadataCharsetJavaConformantUTF8, + OMX_MetadataCharsetUTF7, + OMX_MetadataCharsetImapUTF7, + OMX_MetadataCharsetUTF16LE, + OMX_MetadataCharsetUTF16BE, + OMX_MetadataCharsetGB12345, + OMX_MetadataCharsetHZGB2312, + OMX_MetadataCharsetGB2312, + OMX_MetadataCharsetGB18030, + OMX_MetadataCharsetGBK, + OMX_MetadataCharsetBig5, + OMX_MetadataCharsetISO88591, + OMX_MetadataCharsetISO88592, + OMX_MetadataCharsetISO88593, + OMX_MetadataCharsetISO88594, + OMX_MetadataCharsetISO88595, + OMX_MetadataCharsetISO88596, + OMX_MetadataCharsetISO88597, + OMX_MetadataCharsetISO88598, + OMX_MetadataCharsetISO88599, + OMX_MetadataCharsetISO885910, + OMX_MetadataCharsetISO885913, + OMX_MetadataCharsetISO885914, + OMX_MetadataCharsetISO885915, + OMX_MetadataCharsetShiftJIS, + OMX_MetadataCharsetISO2022JP, + OMX_MetadataCharsetISO2022JP1, + OMX_MetadataCharsetISOEUCJP, + OMX_MetadataCharsetSMS7Bit, + OMX_MetadataCharsetKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MetadataCharsetVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_MetadataCharsetTypeMax= 0x7FFFFFFF +} OMX_METADATACHARSETTYPE; + +/** @ingroup metadata */ +typedef enum OMX_METADATASCOPETYPE +{ + OMX_MetadataScopeAllLevels, + OMX_MetadataScopeTopLevel, + OMX_MetadataScopePortLevel, + OMX_MetadataScopeNodeLevel, + OMX_MetadataScopeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MetadataScopeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_MetadataScopeTypeMax = 0x7fffffff +} OMX_METADATASCOPETYPE; + +/** @ingroup metadata */ +typedef enum OMX_METADATASEARCHMODETYPE +{ + OMX_MetadataSearchValueSizeByIndex, + OMX_MetadataSearchItemByIndex, + OMX_MetadataSearchNextItemByKey, + OMX_MetadataSearchKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MetadataSearchVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_MetadataSearchTypeMax = 0x7fffffff +} OMX_METADATASEARCHMODETYPE; +/** @ingroup metadata */ +typedef struct OMX_CONFIG_METADATAITEMCOUNTTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_METADATASCOPETYPE eScopeMode; + OMX_U32 nScopeSpecifier; + OMX_U32 nMetadataItemCount; +} OMX_CONFIG_METADATAITEMCOUNTTYPE; + +/** @ingroup metadata */ +typedef struct OMX_CONFIG_METADATAITEMTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_METADATASCOPETYPE eScopeMode; + OMX_U32 nScopeSpecifier; + OMX_U32 nMetadataItemIndex; + OMX_METADATASEARCHMODETYPE eSearchMode; + OMX_METADATACHARSETTYPE eKeyCharset; + OMX_U8 nKeySizeUsed; + OMX_U8 nKey[128]; + OMX_METADATACHARSETTYPE eValueCharset; + OMX_STRING sLanguageCountry; + OMX_U32 nValueMaxSize; + OMX_U32 nValueSizeUsed; + OMX_U8 nValue[1]; +} OMX_CONFIG_METADATAITEMTYPE; + +/* @ingroup metadata */ +typedef struct OMX_CONFIG_CONTAINERNODECOUNTTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bAllKeys; + OMX_U32 nParentNodeID; + OMX_U32 nNumNodes; +} OMX_CONFIG_CONTAINERNODECOUNTTYPE; + +/** @ingroup metadata */ +typedef struct OMX_CONFIG_CONTAINERNODEIDTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bAllKeys; + OMX_U32 nParentNodeID; + OMX_U32 nNodeIndex; + OMX_U32 nNodeID; + OMX_STRING cNodeName; + OMX_BOOL bIsLeafType; +} OMX_CONFIG_CONTAINERNODEIDTYPE; + +/** @ingroup metadata */ +typedef struct OMX_PARAM_METADATAFILTERTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bAllKeys; /* if true then this structure refers to all keys and + * the three key fields below are ignored */ + OMX_METADATACHARSETTYPE eKeyCharset; + OMX_U32 nKeySizeUsed; + OMX_U8 nKey [128]; + OMX_U32 nLanguageCountrySizeUsed; + OMX_U8 nLanguageCountry[128]; + OMX_BOOL bEnabled; /* if true then key is part of filter (e.g. + * retained for query later). If false then + * key is not part of filter */ +} OMX_PARAM_METADATAFILTERTYPE; + +/** The OMX_HANDLETYPE structure defines the component handle. The component + * handle is used to access all of the component's public methods and also + * contains pointers to the component's private data area. The component + * handle is initialized by the OMX core (with help from the component) + * during the process of loading the component. After the component is + * successfully loaded, the application can safely access any of the + * component's public functions (although some may return an error because + * the state is inappropriate for the access). + * + * @ingroup comp + */ +typedef struct OMX_COMPONENTTYPE +{ + /** The size of this structure, in bytes. It is the responsibility + of the allocator of this structure to fill in this value. Since + this structure is allocated by the GetHandle function, this + function will fill in this value. */ + OMX_U32 nSize; + + /** nVersion is the version of the OMX specification that the structure + is built against. It is the responsibility of the creator of this + structure to initialize this value and every user of this structure + should verify that it knows how to use the exact version of + this structure found herein. */ + OMX_VERSIONTYPE nVersion; + + /** pComponentPrivate is a pointer to the component private data area. + This member is allocated and initialized by the component when the + component is first loaded. The application should not access this + data area. */ + OMX_PTR pComponentPrivate; + + /** pApplicationPrivate is a pointer that is a parameter to the + OMX_GetHandle method, and contains an application private value + provided by the IL client. This application private data is + returned to the IL Client by OMX in all callbacks */ + OMX_PTR pApplicationPrivate; + + /** refer to OMX_GetComponentVersion in OMX_core.h or the OMX IL + specification for details on the GetComponentVersion method. + */ + OMX_ERRORTYPE (*GetComponentVersion)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_STRING pComponentName, + OMX_OUT OMX_VERSIONTYPE* pComponentVersion, + OMX_OUT OMX_VERSIONTYPE* pSpecVersion, + OMX_OUT OMX_UUIDTYPE* pComponentUUID); + + /** refer to OMX_SendCommand in OMX_core.h or the OMX IL + specification for details on the SendCommand method. + */ + OMX_ERRORTYPE (*SendCommand)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_COMMANDTYPE Cmd, + OMX_IN OMX_U32 nParam1, + OMX_IN OMX_PTR pCmdData); + + /** refer to OMX_GetParameter in OMX_core.h or the OMX IL + specification for details on the GetParameter method. + */ + OMX_ERRORTYPE (*GetParameter)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure); + + + /** refer to OMX_SetParameter in OMX_core.h or the OMX IL + specification for details on the SetParameter method. + */ + OMX_ERRORTYPE (*SetParameter)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure); + + + /** refer to OMX_GetConfig in OMX_core.h or the OMX IL + specification for details on the GetConfig method. + */ + OMX_ERRORTYPE (*GetConfig)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_INOUT OMX_PTR pComponentConfigStructure); + + + /** refer to OMX_SetConfig in OMX_core.h or the OMX IL + specification for details on the SetConfig method. + */ + OMX_ERRORTYPE (*SetConfig)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure); + + + /** refer to OMX_GetExtensionIndex in OMX_core.h or the OMX IL + specification for details on the GetExtensionIndex method. + */ + OMX_ERRORTYPE (*GetExtensionIndex)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE* pIndexType); + + + /** refer to OMX_GetState in OMX_core.h or the OMX IL + specification for details on the GetState method. + */ + OMX_ERRORTYPE (*GetState)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_STATETYPE* pState); + + + /** The ComponentTunnelRequest method will interact with another OMX + component to determine if tunneling is possible and to setup the + tunneling. The return codes for this method can be used to + determine if tunneling is not possible, or if tunneling is not + supported. + + Base profile components (i.e. non-interop) do not support this + method and should return OMX_ErrorNotImplemented + + The interop profile component MUST support tunneling to another + interop profile component with a compatible port parameters. + A component may also support proprietary communication. + + If proprietary communication is supported the negotiation of + proprietary communication is done outside of OMX in a vendor + specific way. It is only required that the proper result be + returned and the details of how the setup is done is left + to the component implementation. + + When this method is invoked when nPort in an output port, the + component will: + 1. Populate the pTunnelSetup structure with the output port's + requirements and constraints for the tunnel. + + When this method is invoked when nPort in an input port, the + component will: + 1. Query the necessary parameters from the output port to + determine if the ports are compatible for tunneling + 2. If the ports are compatible, the component should store + the tunnel step provided by the output port + 3. Determine which port (either input or output) is the buffer + supplier, and call OMX_SetParameter on the output port to + indicate this selection. + + The component will return from this call within 5 msec. + + @param [in] hComp + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle method. + @param [in] nPort + nPort is used to select the port on the component to be used + for tunneling. + @param [in] hTunneledComp + Handle of the component to tunnel with. This is the component + handle returned by the call to the OMX_GetHandle method. When + this parameter is 0x0 the component should setup the port for + communication with the application / IL Client. + @param [in] nPortOutput + nPortOutput is used indicate the port the component should + tunnel with. + @param [in] pTunnelSetup + Pointer to the tunnel setup structure. When nPort is an output port + the component should populate the fields of this structure. When + When nPort is an input port the component should review the setup + provided by the component with the output port. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup tun + */ + + OMX_ERRORTYPE (*ComponentTunnelRequest)( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 nPort, + OMX_IN OMX_HANDLETYPE hTunneledComp, + OMX_IN OMX_U32 nTunneledPort, + OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup); + + /** refer to OMX_UseBuffer in OMX_core.h or the OMX IL + specification for details on the UseBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*UseBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes, + OMX_IN OMX_U8* pBuffer); + + /** refer to OMX_AllocateBuffer in OMX_core.h or the OMX IL + specification for details on the AllocateBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*AllocateBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes); + + /** refer to OMX_FreeBuffer in OMX_core.h or the OMX IL + specification for details on the FreeBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*FreeBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** refer to OMX_EmptyThisBuffer in OMX_core.h or the OMX IL + specification for details on the EmptyThisBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*EmptyThisBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** refer to OMX_FillThisBuffer in OMX_core.h or the OMX IL + specification for details on the FillThisBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*FillThisBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** The SetCallbacks method is used by the core to specify the callback + structure from the application to the component. This is a blocking + call. The component will return from this call within 5 msec. + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @param [in] pCallbacks + pointer to an OMX_CALLBACKTYPE structure used to provide the + callback information to the component + @param [in] pAppData + pointer to an application defined value. It is anticipated that + the application will pass a pointer to a data structure or a "this + pointer" in this area to allow the callback (in the application) + to determine the context of the call + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + */ + OMX_ERRORTYPE (*SetCallbacks)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_CALLBACKTYPE* pCallbacks, + OMX_IN OMX_PTR pAppData); + + /** ComponentDeInit method is used to deinitialize the component + providing a means to free any resources allocated at component + initialization. NOTE: After this call the component handle is + not valid for further use. + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + */ + OMX_ERRORTYPE (*ComponentDeInit)( + OMX_IN OMX_HANDLETYPE hComponent); + + /** @ingroup buf */ + OMX_ERRORTYPE (*UseEGLImage)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN void* eglImage); + + OMX_ERRORTYPE (*ComponentRoleEnum)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_U8 *cRole, + OMX_IN OMX_U32 nIndex); + +} OMX_COMPONENTTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/phonelibs/openmax/include/OMX_ContentPipe.h b/phonelibs/openmax/include/OMX_ContentPipe.h new file mode 100644 index 00000000000000..5f6310c28a38a2 --- /dev/null +++ b/phonelibs/openmax/include/OMX_ContentPipe.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** OMX_ContentPipe.h - OpenMax IL version 1.1.2 + * The OMX_ContentPipe header file contains the definitions used to define + * the public interface for content piples. This header file is intended to + * be used by the component. + */ + +#ifndef OMX_CONTENTPIPE_H +#define OMX_CONTENTPIPE_H + +#ifndef KD_EACCES +/* OpenKODE error codes. CPResult values may be zero (indicating success + or one of the following values) */ +#define KD_EACCES (1) +#define KD_EADDRINUSE (2) +#define KD_EAGAIN (5) +#define KD_EBADF (7) +#define KD_EBUSY (8) +#define KD_ECONNREFUSED (9) +#define KD_ECONNRESET (10) +#define KD_EDEADLK (11) +#define KD_EDESTADDRREQ (12) +#define KD_ERANGE (35) +#define KD_EEXIST (13) +#define KD_EFBIG (14) +#define KD_EHOSTUNREACH (15) +#define KD_EINVAL (17) +#define KD_EIO (18) +#define KD_EISCONN (20) +#define KD_EISDIR (21) +#define KD_EMFILE (22) +#define KD_ENAMETOOLONG (23) +#define KD_ENOENT (24) +#define KD_ENOMEM (25) +#define KD_ENOSPC (26) +#define KD_ENOSYS (27) +#define KD_ENOTCONN (28) +#define KD_EPERM (33) +#define KD_ETIMEDOUT (36) +#define KD_EILSEQ (19) +#endif + +/** Map types from OMX standard types only here so interface is as generic as possible. */ +typedef OMX_U32 CPresult; +typedef char * CPstring; +typedef void * CPhandle; +typedef OMX_U32 CPuint; +typedef OMX_S32 CPint; +typedef char CPbyte; +typedef OMX_BOOL CPbool; + +/** enumeration of origin types used in the CP_PIPETYPE's Seek function + * @ingroup cp + */ +typedef enum CP_ORIGINTYPE { + CP_OriginBegin, + CP_OriginCur, + CP_OriginEnd, + CP_OriginKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_OriginVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_OriginMax = 0X7FFFFFFF +} CP_ORIGINTYPE; + +/** enumeration of contact access types used in the CP_PIPETYPE's Open function + * @ingroup cp + */ +typedef enum CP_ACCESSTYPE { + CP_AccessRead, + CP_AccessWrite, + CP_AccessReadWrite , + CP_AccessKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_AccessVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_AccessMax = 0X7FFFFFFF +} CP_ACCESSTYPE; + +/** enumeration of results returned by the CP_PIPETYPE's CheckAvailableBytes function + * @ingroup cp + */ +typedef enum CP_CHECKBYTESRESULTTYPE +{ + CP_CheckBytesOk, /**< There are at least the request number + of bytes available */ + CP_CheckBytesNotReady, /**< The pipe is still retrieving bytes + and presently lacks sufficient bytes. + Client will be called when they are + sufficient bytes are available. */ + CP_CheckBytesInsufficientBytes , /**< The pipe has retrieved all bytes + but those available are less than those + requested */ + CP_CheckBytesAtEndOfStream, /**< The pipe has reached the end of stream + and no more bytes are available. */ + CP_CheckBytesOutOfBuffers, /**< All read/write buffers are currently in use. */ + CP_CheckBytesKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_CheckBytesVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_CheckBytesMax = 0X7FFFFFFF +} CP_CHECKBYTESRESULTTYPE; + +/** enumeration of content pipe events sent to the client callback. + * @ingroup cp + */ +typedef enum CP_EVENTTYPE{ + CP_BytesAvailable, /** bytes requested in a CheckAvailableBytes call are now available*/ + CP_Overflow, /** enumeration of content pipe events sent to the client callback*/ + CP_PipeDisconnected , /** enumeration of content pipe events sent to the client callback*/ + CP_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_EventMax = 0X7FFFFFFF +} CP_EVENTTYPE; + +/** content pipe definition + * @ingroup cp + */ +typedef struct CP_PIPETYPE +{ + /** Open a content stream for reading or writing. */ + CPresult (*Open)( CPhandle* hContent, CPstring szURI, CP_ACCESSTYPE eAccess ); + + /** Close a content stream. */ + CPresult (*Close)( CPhandle hContent ); + + /** Create a content source and open it for writing. */ + CPresult (*Create)( CPhandle *hContent, CPstring szURI ); + + /** Check the that specified number of bytes are available for reading or writing (depending on access type).*/ + CPresult (*CheckAvailableBytes)( CPhandle hContent, CPuint nBytesRequested, CP_CHECKBYTESRESULTTYPE *eResult ); + + /** Seek to certain position in the content relative to the specified origin. */ + CPresult (*SetPosition)( CPhandle hContent, CPint nOffset, CP_ORIGINTYPE eOrigin); + + /** Retrieve the current position relative to the start of the content. */ + CPresult (*GetPosition)( CPhandle hContent, CPuint *pPosition); + + /** Retrieve data of the specified size from the content stream (advance content pointer by size of data). + Note: pipe client provides pointer. This function is appropriate for small high frequency reads. */ + CPresult (*Read)( CPhandle hContent, CPbyte *pData, CPuint nSize); + + /** Retrieve a buffer allocated by the pipe that contains the requested number of bytes. + Buffer contains the next block of bytes, as specified by nSize, of the content. nSize also + returns the size of the block actually read. Content pointer advances the by the returned size. + Note: pipe provides pointer. This function is appropriate for large reads. The client must call + ReleaseReadBuffer when done with buffer. + + In some cases the requested block may not reside in contiguous memory within the + pipe implementation. For instance if the pipe leverages a circular buffer then the requested + block may straddle the boundary of the circular buffer. By default a pipe implementation + performs a copy in this case to provide the block to the pipe client in one contiguous buffer. + If, however, the client sets bForbidCopy, then the pipe returns only those bytes preceding the memory + boundary. Here the client may retrieve the data in segments over successive calls. */ + CPresult (*ReadBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint *nSize, CPbool bForbidCopy); + + /** Release a buffer obtained by ReadBuffer back to the pipe. */ + CPresult (*ReleaseReadBuffer)(CPhandle hContent, CPbyte *pBuffer); + + /** Write data of the specified size to the content (advance content pointer by size of data). + Note: pipe client provides pointer. This function is appropriate for small high frequency writes. */ + CPresult (*Write)( CPhandle hContent, CPbyte *data, CPuint nSize); + + /** Retrieve a buffer allocated by the pipe used to write data to the content. + Client will fill buffer with output data. Note: pipe provides pointer. This function is appropriate + for large writes. The client must call WriteBuffer when done it has filled the buffer with data.*/ + CPresult (*GetWriteBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint nSize); + + /** Deliver a buffer obtained via GetWriteBuffer to the pipe. Pipe will write the + the contents of the buffer to content and advance content pointer by the size of the buffer */ + CPresult (*WriteBuffer)( CPhandle hContent, CPbyte *pBuffer, CPuint nFilledSize); + + /** Register a per-handle client callback with the content pipe. */ + CPresult (*RegisterCallback)( CPhandle hContent, CPresult (*ClientCallback)(CP_EVENTTYPE eEvent, CPuint iParam)); + +} CP_PIPETYPE; + +#endif + diff --git a/phonelibs/openmax/include/OMX_Core.h b/phonelibs/openmax/include/OMX_Core.h new file mode 100644 index 00000000000000..52d211f0dc3846 --- /dev/null +++ b/phonelibs/openmax/include/OMX_Core.h @@ -0,0 +1,1440 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** OMX_Core.h - OpenMax IL version 1.1.2 + * The OMX_Core header file contains the definitions used by both the + * application and the component to access common items. + */ + +#ifndef OMX_Core_h +#define OMX_Core_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Each OMX header shall include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + + +/** The OMX_COMMANDTYPE enumeration is used to specify the action in the + * OMX_SendCommand macro. + * @ingroup core + */ +typedef enum OMX_COMMANDTYPE +{ + OMX_CommandStateSet, /**< Change the component state */ + OMX_CommandFlush, /**< Flush the data queue(s) of a component */ + OMX_CommandPortDisable, /**< Disable a port on a component. */ + OMX_CommandPortEnable, /**< Enable a port on a component. */ + OMX_CommandMarkBuffer, /**< Mark a component/buffer for observation */ + OMX_CommandKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_CommandVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_CommandMax = 0X7FFFFFFF +} OMX_COMMANDTYPE; + + + +/** The OMX_STATETYPE enumeration is used to indicate or change the component + * state. This enumeration reflects the current state of the component when + * used with the OMX_GetState macro or becomes the parameter in a state change + * command when used with the OMX_SendCommand macro. + * + * The component will be in the Loaded state after the component is initially + * loaded into memory. In the Loaded state, the component is not allowed to + * allocate or hold resources other than to build it's internal parameter + * and configuration tables. The application will send one or more + * SetParameters/GetParameters and SetConfig/GetConfig commands to the + * component and the component will record each of these parameter and + * configuration changes for use later. When the application sends the + * Idle command, the component will acquire the resources needed for the + * specified configuration and will transition to the idle state if the + * allocation is successful. If the component cannot successfully + * transition to the idle state for any reason, the state of the component + * shall be fully rolled back to the Loaded state (e.g. all allocated + * resources shall be released). When the component receives the command + * to go to the Executing state, it shall begin processing buffers by + * sending all input buffers it holds to the application. While + * the component is in the Idle state, the application may also send the + * Pause command. If the component receives the pause command while in the + * Idle state, the component shall send all input buffers it holds to the + * application, but shall not begin processing buffers. This will allow the + * application to prefill buffers. + * + * @ingroup comp + */ + +typedef enum OMX_STATETYPE +{ + OMX_StateInvalid, /**< component has detected that it's internal data + structures are corrupted to the point that + it cannot determine it's state properly */ + OMX_StateLoaded, /**< component has been loaded but has not completed + initialization. The OMX_SetParameter macro + and the OMX_GetParameter macro are the only + valid macros allowed to be sent to the + component in this state. */ + OMX_StateIdle, /**< component initialization has been completed + successfully and the component is ready to + to start. */ + OMX_StateExecuting, /**< component has accepted the start command and + is processing data (if data is available) */ + OMX_StatePause, /**< component has received pause command */ + OMX_StateWaitForResources, /**< component is waiting for resources, either after + preemption or before it gets the resources requested. + See specification for complete details. */ + OMX_StateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_StateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_StateMax = 0X7FFFFFFF +} OMX_STATETYPE; + +/** The OMX_ERRORTYPE enumeration defines the standard OMX Errors. These + * errors should cover most of the common failure cases. However, + * vendors are free to add additional error messages of their own as + * long as they follow these rules: + * 1. Vendor error messages shall be in the range of 0x90000000 to + * 0x9000FFFF. + * 2. Vendor error messages shall be defined in a header file provided + * with the component. No error messages are allowed that are + * not defined. + */ +typedef enum OMX_ERRORTYPE +{ + OMX_ErrorNone = 0, + + /** There were insufficient resources to perform the requested operation */ + OMX_ErrorInsufficientResources = (OMX_S32) 0x80001000, + + /** There was an error, but the cause of the error could not be determined */ + OMX_ErrorUndefined = (OMX_S32) 0x80001001, + + /** The component name string was not valid */ + OMX_ErrorInvalidComponentName = (OMX_S32) 0x80001002, + + /** No component with the specified name string was found */ + OMX_ErrorComponentNotFound = (OMX_S32) 0x80001003, + + /** The component specified did not have a "OMX_ComponentInit" or + "OMX_ComponentDeInit entry point */ + OMX_ErrorInvalidComponent = (OMX_S32) 0x80001004, + + /** One or more parameters were not valid */ + OMX_ErrorBadParameter = (OMX_S32) 0x80001005, + + /** The requested function is not implemented */ + OMX_ErrorNotImplemented = (OMX_S32) 0x80001006, + + /** The buffer was emptied before the next buffer was ready */ + OMX_ErrorUnderflow = (OMX_S32) 0x80001007, + + /** The buffer was not available when it was needed */ + OMX_ErrorOverflow = (OMX_S32) 0x80001008, + + /** The hardware failed to respond as expected */ + OMX_ErrorHardware = (OMX_S32) 0x80001009, + + /** The component is in the state OMX_StateInvalid */ + OMX_ErrorInvalidState = (OMX_S32) 0x8000100A, + + /** Stream is found to be corrupt */ + OMX_ErrorStreamCorrupt = (OMX_S32) 0x8000100B, + + /** Ports being connected are not compatible */ + OMX_ErrorPortsNotCompatible = (OMX_S32) 0x8000100C, + + /** Resources allocated to an idle component have been + lost resulting in the component returning to the loaded state */ + OMX_ErrorResourcesLost = (OMX_S32) 0x8000100D, + + /** No more indicies can be enumerated */ + OMX_ErrorNoMore = (OMX_S32) 0x8000100E, + + /** The component detected a version mismatch */ + OMX_ErrorVersionMismatch = (OMX_S32) 0x8000100F, + + /** The component is not ready to return data at this time */ + OMX_ErrorNotReady = (OMX_S32) 0x80001010, + + /** There was a timeout that occurred */ + OMX_ErrorTimeout = (OMX_S32) 0x80001011, + + /** This error occurs when trying to transition into the state you are already in */ + OMX_ErrorSameState = (OMX_S32) 0x80001012, + + /** Resources allocated to an executing or paused component have been + preempted, causing the component to return to the idle state */ + OMX_ErrorResourcesPreempted = (OMX_S32) 0x80001013, + + /** A non-supplier port sends this error to the IL client (via the EventHandler callback) + during the allocation of buffers (on a transition from the LOADED to the IDLE state or + on a port restart) when it deems that it has waited an unusually long time for the supplier + to send it an allocated buffer via a UseBuffer call. */ + OMX_ErrorPortUnresponsiveDuringAllocation = (OMX_S32) 0x80001014, + + /** A non-supplier port sends this error to the IL client (via the EventHandler callback) + during the deallocation of buffers (on a transition from the IDLE to LOADED state or + on a port stop) when it deems that it has waited an unusually long time for the supplier + to request the deallocation of a buffer header via a FreeBuffer call. */ + OMX_ErrorPortUnresponsiveDuringDeallocation = (OMX_S32) 0x80001015, + + /** A supplier port sends this error to the IL client (via the EventHandler callback) + during the stopping of a port (either on a transition from the IDLE to LOADED + state or a port stop) when it deems that it has waited an unusually long time for + the non-supplier to return a buffer via an EmptyThisBuffer or FillThisBuffer call. */ + OMX_ErrorPortUnresponsiveDuringStop = (OMX_S32) 0x80001016, + + /** Attempting a state transtion that is not allowed */ + OMX_ErrorIncorrectStateTransition = (OMX_S32) 0x80001017, + + /* Attempting a command that is not allowed during the present state. */ + OMX_ErrorIncorrectStateOperation = (OMX_S32) 0x80001018, + + /** The values encapsulated in the parameter or config structure are not supported. */ + OMX_ErrorUnsupportedSetting = (OMX_S32) 0x80001019, + + /** The parameter or config indicated by the given index is not supported. */ + OMX_ErrorUnsupportedIndex = (OMX_S32) 0x8000101A, + + /** The port index supplied is incorrect. */ + OMX_ErrorBadPortIndex = (OMX_S32) 0x8000101B, + + /** The port has lost one or more of its buffers and it thus unpopulated. */ + OMX_ErrorPortUnpopulated = (OMX_S32) 0x8000101C, + + /** Component suspended due to temporary loss of resources */ + OMX_ErrorComponentSuspended = (OMX_S32) 0x8000101D, + + /** Component suspended due to an inability to acquire dynamic resources */ + OMX_ErrorDynamicResourcesUnavailable = (OMX_S32) 0x8000101E, + + /** When the macroblock error reporting is enabled the component returns new error + for every frame that has errors */ + OMX_ErrorMbErrorsInFrame = (OMX_S32) 0x8000101F, + + /** A component reports this error when it cannot parse or determine the format of an input stream. */ + OMX_ErrorFormatNotDetected = (OMX_S32) 0x80001020, + + /** The content open operation failed. */ + OMX_ErrorContentPipeOpenFailed = (OMX_S32) 0x80001021, + + /** The content creation operation failed. */ + OMX_ErrorContentPipeCreationFailed = (OMX_S32) 0x80001022, + + /** Separate table information is being used */ + OMX_ErrorSeperateTablesUsed = (OMX_S32) 0x80001023, + + /** Tunneling is unsupported by the component*/ + OMX_ErrorTunnelingUnsupported = (OMX_S32) 0x80001024, + + OMX_ErrorKhronosExtensions = (OMX_S32)0x8F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_ErrorVendorStartUnused = (OMX_S32)0x90000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_ErrorMax = 0x7FFFFFFF +} OMX_ERRORTYPE; + +/** @ingroup core */ +typedef OMX_ERRORTYPE (* OMX_COMPONENTINITTYPE)(OMX_IN OMX_HANDLETYPE hComponent); + +/** @ingroup core */ +typedef struct OMX_COMPONENTREGISTERTYPE +{ + const char * pName; /* Component name, 128 byte limit (including '\0') applies */ + OMX_COMPONENTINITTYPE pInitialize; /* Component instance initialization function */ +} OMX_COMPONENTREGISTERTYPE; + +/** @ingroup core */ +extern OMX_COMPONENTREGISTERTYPE OMX_ComponentRegistered[]; + +/** @ingroup rpm */ +typedef struct OMX_PRIORITYMGMTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nGroupPriority; /**< Priority of the component group */ + OMX_U32 nGroupID; /**< ID of the component group */ +} OMX_PRIORITYMGMTTYPE; + +/* Component name and Role names are limited to 128 characters including the terminating '\0'. */ +#define OMX_MAX_STRINGNAME_SIZE 128 + +/** @ingroup comp */ +typedef struct OMX_PARAM_COMPONENTROLETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U8 cRole[OMX_MAX_STRINGNAME_SIZE]; /**< name of standard component which defines component role */ +} OMX_PARAM_COMPONENTROLETYPE; + +/** End of Stream Buffer Flag: + * + * A component sets EOS when it has no more data to emit on a particular + * output port. Thus an output port shall set EOS on the last buffer it + * emits. A component's determination of when an output port should + * cease sending data is implemenation specific. + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_EOS 0x00000001 + +/** Start Time Buffer Flag: + * + * The source of a stream (e.g. a demux component) sets the STARTTIME + * flag on the buffer that contains the starting timestamp for the + * stream. The starting timestamp corresponds to the first data that + * should be displayed at startup or after a seek. + * The first timestamp of the stream is not necessarily the start time. + * For instance, in the case of a seek to a particular video frame, + * the target frame may be an interframe. Thus the first buffer of + * the stream will be the intra-frame preceding the target frame and + * the starttime will occur with the target frame (with any other + * required frames required to reconstruct the target intervening). + * + * The STARTTIME flag is directly associated with the buffer's + * timestamp ' thus its association to buffer data and its + * propagation is identical to the timestamp's. + * + * When a Sync Component client receives a buffer with the + * STARTTIME flag it shall perform a SetConfig on its sync port + * using OMX_ConfigTimeClientStartTime and passing the buffer's + * timestamp. + * + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_STARTTIME 0x00000002 + + + +/** Decode Only Buffer Flag: + * + * The source of a stream (e.g. a demux component) sets the DECODEONLY + * flag on any buffer that should shall be decoded but should not be + * displayed. This flag is used, for instance, when a source seeks to + * a target interframe that requires the decode of frames preceding the + * target to facilitate the target's reconstruction. In this case the + * source would emit the frames preceding the target downstream + * but mark them as decode only. + * + * The DECODEONLY is associated with buffer data and propagated in a + * manner identical to the buffer timestamp. + * + * A component that renders data should ignore all buffers with + * the DECODEONLY flag set. + * + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_DECODEONLY 0x00000004 + + +/* Data Corrupt Flag: This flag is set when the IL client believes the data in the associated buffer is corrupt + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_DATACORRUPT 0x00000008 + +/* End of Frame: The buffer contains exactly one end of frame and no data + * occurs after the end of frame. This flag is an optional hint. The absence + * of this flag does not imply the absence of an end of frame within the buffer. + * @ingroup buf +*/ +#define OMX_BUFFERFLAG_ENDOFFRAME 0x00000010 + +/* Sync Frame Flag: This flag is set when the buffer content contains a coded sync frame ' + * a frame that has no dependency on any other frame information + * @ingroup buf + */ +#define OMX_BUFFERFLAG_SYNCFRAME 0x00000020 + +/* Extra data present flag: there is extra data appended to the data stream + * residing in the buffer + * @ingroup buf + */ +#define OMX_BUFFERFLAG_EXTRADATA 0x00000040 + +/** Codec Config Buffer Flag: +* OMX_BUFFERFLAG_CODECCONFIG is an optional flag that is set by an +* output port when all bytes in the buffer form part or all of a set of +* codec specific configuration data. Examples include SPS/PPS nal units +* for OMX_VIDEO_CodingAVC or AudioSpecificConfig data for +* OMX_AUDIO_CodingAAC. Any component that for a given stream sets +* OMX_BUFFERFLAG_CODECCONFIG shall not mix codec configuration bytes +* with frame data in the same buffer, and shall send all buffers +* containing codec configuration bytes before any buffers containing +* frame data that those configurations bytes describe. +* If the stream format for a particular codec has a frame specific +* header at the start of each frame, for example OMX_AUDIO_CodingMP3 or +* OMX_AUDIO_CodingAAC in ADTS mode, then these shall be presented as +* normal without setting OMX_BUFFERFLAG_CODECCONFIG. + * @ingroup buf + */ +#define OMX_BUFFERFLAG_CODECCONFIG 0x00000080 + +/* +* OMX_BUFFERFLAG_READONLY: This flag is set when a component emitting the +* buffer on an output port or the IL client wishes to identify the buffer +* payload contents to be read-only. An IL client or an input port +* shall not alter the contents of the buffer. This flag shall only be +* cleared by the originator of the buffer when the buffer is returned. +* For tunneled ports, the usage of this flag shall be allowed only if the +* components negotiated a read-only tunnel +*/ +#define OMX_BUFFERFLAG_READONLY 0x00000200 + +/** @ingroup buf */ +typedef struct OMX_BUFFERHEADERTYPE +{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U8* pBuffer; /**< Pointer to actual block of memory + that is acting as the buffer */ + OMX_U32 nAllocLen; /**< size of the buffer allocated, in bytes */ + OMX_U32 nFilledLen; /**< number of bytes currently in the + buffer */ + OMX_U32 nOffset; /**< start offset of valid data in bytes from + the start of the buffer */ + OMX_PTR pAppPrivate; /**< pointer to any data the application + wants to associate with this buffer */ + OMX_PTR pPlatformPrivate; /**< pointer to any data the platform + wants to associate with this buffer */ + OMX_PTR pInputPortPrivate; /**< pointer to any data the input port + wants to associate with this buffer */ + OMX_PTR pOutputPortPrivate; /**< pointer to any data the output port + wants to associate with this buffer */ + OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will generate a + mark event upon processing this buffer. */ + OMX_PTR pMarkData; /**< Application specific data associated with + the mark sent on a mark event to disambiguate + this mark from others. */ + OMX_U32 nTickCount; /**< Optional entry that the component and + application can update with a tick count + when they access the component. This + value should be in microseconds. Since + this is a value relative to an arbitrary + starting point, this value cannot be used + to determine absolute time. This is an + optional entry and not all components + will update it.*/ + OMX_TICKS nTimeStamp; /**< Timestamp corresponding to the sample + starting at the first logical sample + boundary in the buffer. Timestamps of + successive samples within the buffer may + be inferred by adding the duration of the + of the preceding buffer to the timestamp + of the preceding buffer.*/ + OMX_U32 nFlags; /**< buffer specific flags */ + OMX_U32 nOutputPortIndex; /**< The index of the output port (if any) using + this buffer */ + OMX_U32 nInputPortIndex; /**< The index of the input port (if any) using + this buffer */ +} OMX_BUFFERHEADERTYPE; + +/** The OMX_EXTRADATATYPE enumeration is used to define the + * possible extra data payload types. + * NB: this enum is binary backwards compatible with the previous + * OMX_EXTRADATA_QUANT define. This should be replaced with + * OMX_ExtraDataQuantization. + */ +typedef enum OMX_EXTRADATATYPE +{ + OMX_ExtraDataNone = 0, /**< Indicates that no more extra data sections follow */ + OMX_ExtraDataQuantization, /**< The data payload contains quantization data */ + OMX_ExtraDataKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_ExtraDataVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_ExtraDataMax = 0x7FFFFFFF +} OMX_EXTRADATATYPE; + + +typedef struct OMX_OTHER_EXTRADATATYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_EXTRADATATYPE eType; /* Extra Data type */ + OMX_U32 nDataSize; /* Size of the supporting data to follow */ + OMX_U8 data[1]; /* Supporting data hint */ +} OMX_OTHER_EXTRADATATYPE; + +/** @ingroup comp */ +typedef struct OMX_PORT_PARAM_TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPorts; /**< The number of ports for this component */ + OMX_U32 nStartPortNumber; /** first port number for this type of port */ +} OMX_PORT_PARAM_TYPE; + +/** @ingroup comp */ +typedef enum OMX_EVENTTYPE +{ + OMX_EventCmdComplete, /**< component has sucessfully completed a command */ + OMX_EventError, /**< component has detected an error condition */ + OMX_EventMark, /**< component has detected a buffer mark */ + OMX_EventPortSettingsChanged, /**< component is reported a port settings change */ + OMX_EventBufferFlag, /**< component has detected an EOS */ + OMX_EventResourcesAcquired, /**< component has been granted resources and is + automatically starting the state change from + OMX_StateWaitForResources to OMX_StateIdle. */ + OMX_EventComponentResumed, /**< Component resumed due to reacquisition of resources */ + OMX_EventDynamicResourcesAvailable, /**< Component has acquired previously unavailable dynamic resources */ + OMX_EventPortFormatDetected, /**< Component has detected a supported format. */ + OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_EventMax = 0x7FFFFFFF +} OMX_EVENTTYPE; + +typedef struct OMX_CALLBACKTYPE +{ + /** The EventHandler method is used to notify the application when an + event of interest occurs. Events are defined in the OMX_EVENTTYPE + enumeration. Please see that enumeration for details of what will + be returned for each type of event. Callbacks should not return + an error to the component, so if an error occurs, the application + shall handle it internally. This is a blocking call. + + The application should return from this call within 5 msec to avoid + blocking the component for an excessively long period of time. + + @param hComponent + handle of the component to access. This is the component + handle returned by the call to the GetHandle function. + @param pAppData + pointer to an application defined value that was provided in the + pAppData parameter to the OMX_GetHandle method for the component. + This application defined value is provided so that the application + can have a component specific context when receiving the callback. + @param eEvent + Event that the component wants to notify the application about. + @param nData1 + nData will be the OMX_ERRORTYPE for an error event and will be + an OMX_COMMANDTYPE for a command complete event and OMX_INDEXTYPE for a OMX_PortSettingsChanged event. + @param nData2 + nData2 will hold further information related to the event. Can be OMX_STATETYPE for + a OMX_CommandStateSet command or port index for a OMX_PortSettingsChanged event. + Default value is 0 if not used. ) + @param pEventData + Pointer to additional event-specific data (see spec for meaning). + */ + + OMX_ERRORTYPE (*EventHandler)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_EVENTTYPE eEvent, + OMX_IN OMX_U32 nData1, + OMX_IN OMX_U32 nData2, + OMX_IN OMX_PTR pEventData); + + /** The EmptyBufferDone method is used to return emptied buffers from an + input port back to the application for reuse. This is a blocking call + so the application should not attempt to refill the buffers during this + call, but should queue them and refill them in another thread. There + is no error return, so the application shall handle any errors generated + internally. + + The application should return from this call within 5 msec. + + @param hComponent + handle of the component to access. This is the component + handle returned by the call to the GetHandle function. + @param pAppData + pointer to an application defined value that was provided in the + pAppData parameter to the OMX_GetHandle method for the component. + This application defined value is provided so that the application + can have a component specific context when receiving the callback. + @param pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer indicating the buffer that was emptied. + @ingroup buf + */ + OMX_ERRORTYPE (*EmptyBufferDone)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** The FillBufferDone method is used to return filled buffers from an + output port back to the application for emptying and then reuse. + This is a blocking call so the application should not attempt to + empty the buffers during this call, but should queue the buffers + and empty them in another thread. There is no error return, so + the application shall handle any errors generated internally. The + application shall also update the buffer header to indicate the + number of bytes placed into the buffer. + + The application should return from this call within 5 msec. + + @param hComponent + handle of the component to access. This is the component + handle returned by the call to the GetHandle function. + @param pAppData + pointer to an application defined value that was provided in the + pAppData parameter to the OMX_GetHandle method for the component. + This application defined value is provided so that the application + can have a component specific context when receiving the callback. + @param pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer indicating the buffer that was filled. + @ingroup buf + */ + OMX_ERRORTYPE (*FillBufferDone)( + OMX_OUT OMX_HANDLETYPE hComponent, + OMX_OUT OMX_PTR pAppData, + OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer); + +} OMX_CALLBACKTYPE; + +/** The OMX_BUFFERSUPPLIERTYPE enumeration is used to dictate port supplier + preference when tunneling between two ports. + @ingroup tun buf +*/ +typedef enum OMX_BUFFERSUPPLIERTYPE +{ + OMX_BufferSupplyUnspecified = 0x0, /**< port supplying the buffers is unspecified, + or don't care */ + OMX_BufferSupplyInput, /**< input port supplies the buffers */ + OMX_BufferSupplyOutput, /**< output port supplies the buffers */ + OMX_BufferSupplyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_BufferSupplyVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_BufferSupplyMax = 0x7FFFFFFF +} OMX_BUFFERSUPPLIERTYPE; + + +/** buffer supplier parameter + * @ingroup tun + */ +typedef struct OMX_PARAM_BUFFERSUPPLIERTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BUFFERSUPPLIERTYPE eBufferSupplier; /**< buffer supplier */ +} OMX_PARAM_BUFFERSUPPLIERTYPE; + + +/**< indicates that buffers received by an input port of a tunnel + may not modify the data in the buffers + @ingroup tun + */ +#define OMX_PORTTUNNELFLAG_READONLY 0x00000001 + + +/** The OMX_TUNNELSETUPTYPE structure is used to pass data from an output + port to an input port as part the two ComponentTunnelRequest calls + resulting from a OMX_SetupTunnel call from the IL Client. + @ingroup tun + */ +typedef struct OMX_TUNNELSETUPTYPE +{ + OMX_U32 nTunnelFlags; /**< bit flags for tunneling */ + OMX_BUFFERSUPPLIERTYPE eSupplier; /**< supplier preference */ +} OMX_TUNNELSETUPTYPE; + +/* OMX Component headers is included to enable the core to use + macros for functions into the component for OMX release 1.0. + Developers should not access any structures or data from within + the component header directly */ +/* TO BE REMOVED - #include */ + +/** GetComponentVersion will return information about the component. + This is a blocking call. This macro will go directly from the + application to the component (via a core macro). The + component will return from this call within 5 msec. + @param [in] hComponent + handle of component to execute the command + @param [out] pComponentName + pointer to an empty string of length 128 bytes. The component + will write its name into this string. The name will be + terminated by a single zero byte. The name of a component will + be 127 bytes or less to leave room for the trailing zero byte. + An example of a valid component name is "OMX.ABC.ChannelMixer\0". + @param [out] pComponentVersion + pointer to an OMX Version structure that the component will fill + in. The component will fill in a value that indicates the + component version. NOTE: the component version is NOT the same + as the OMX Specification version (found in all structures). The + component version is defined by the vendor of the component and + its value is entirely up to the component vendor. + @param [out] pSpecVersion + pointer to an OMX Version structure that the component will fill + in. The SpecVersion is the version of the specification that the + component was built against. Please note that this value may or + may not match the structure's version. For example, if the + component was built against the 2.0 specification, but the + application (which creates the structure is built against the + 1.0 specification the versions would be different. + @param [out] pComponentUUID + pointer to the UUID of the component which will be filled in by + the component. The UUID is a unique identifier that is set at + RUN time for the component and is unique to each instantion of + the component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetComponentVersion( \ + hComponent, \ + pComponentName, \ + pComponentVersion, \ + pSpecVersion, \ + pComponentUUID) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetComponentVersion( \ + hComponent, \ + pComponentName, \ + pComponentVersion, \ + pSpecVersion, \ + pComponentUUID) /* Macro End */ + + +/** Send a command to the component. This call is a non-blocking call. + The component should check the parameters and then queue the command + to the component thread to be executed. The component thread shall + send the EventHandler() callback at the conclusion of the command. + This macro will go directly from the application to the component (via + a core macro). The component will return from this call within 5 msec. + + When the command is "OMX_CommandStateSet" the component will queue a + state transition to the new state idenfied in nParam. + + When the command is "OMX_CommandFlush", to flush a port's buffer queues, + the command will force the component to return all buffers NOT CURRENTLY + BEING PROCESSED to the application, in the order in which the buffers + were received. + + When the command is "OMX_CommandPortDisable" or + "OMX_CommandPortEnable", the component's port (given by the value of + nParam) will be stopped or restarted. + + When the command "OMX_CommandMarkBuffer" is used to mark a buffer, the + pCmdData will point to a OMX_MARKTYPE structure containing the component + handle of the component to examine the buffer chain for the mark. nParam1 + contains the index of the port on which the buffer mark is applied. + + Specification text for more details. + + @param [in] hComponent + handle of component to execute the command + @param [in] Cmd + Command for the component to execute + @param [in] nParam + Parameter for the command to be executed. When Cmd has the value + OMX_CommandStateSet, value is a member of OMX_STATETYPE. When Cmd has + the value OMX_CommandFlush, value of nParam indicates which port(s) + to flush. -1 is used to flush all ports a single port index will + only flush that port. When Cmd has the value "OMX_CommandPortDisable" + or "OMX_CommandPortEnable", the component's port is given by + the value of nParam. When Cmd has the value "OMX_CommandMarkBuffer" + the components pot is given by the value of nParam. + @param [in] pCmdData + Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value + "OMX_CommandMarkBuffer". + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_SendCommand( \ + hComponent, \ + Cmd, \ + nParam, \ + pCmdData) \ + ((OMX_COMPONENTTYPE*)hComponent)->SendCommand( \ + hComponent, \ + Cmd, \ + nParam, \ + pCmdData) /* Macro End */ + + +/** The OMX_GetParameter macro will get one of the current parameter + settings from the component. This macro cannot only be invoked when + the component is in the OMX_StateInvalid state. The nParamIndex + parameter is used to indicate which structure is being requested from + the component. The application shall allocate the correct structure + and shall fill in the structure size and version information before + invoking this macro. When the parameter applies to a port, the + caller shall fill in the appropriate nPortIndex value indicating the + port on which the parameter applies. If the component has not had + any settings changed, then the component should return a set of + valid DEFAULT parameters for the component. This is a blocking + call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nParamIndex + Index of the structure to be filled. This value is from the + OMX_INDEXTYPE enumeration. + @param [in,out] pComponentParameterStructure + Pointer to application allocated structure to be filled by the + component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) /* Macro End */ + + +/** The OMX_SetParameter macro will send an initialization parameter + structure to a component. Each structure shall be sent one at a time, + in a separate invocation of the macro. This macro can only be + invoked when the component is in the OMX_StateLoaded state, or the + port is disabled (when the parameter applies to a port). The + nParamIndex parameter is used to indicate which structure is being + passed to the component. The application shall allocate the + correct structure and shall fill in the structure size and version + information (as well as the actual data) before invoking this macro. + The application is free to dispose of this structure after the call + as the component is required to copy any data it shall retain. This + is a blocking call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nIndex + Index of the structure to be sent. This value is from the + OMX_INDEXTYPE enumeration. + @param [in] pComponentParameterStructure + pointer to application allocated structure to be used for + initialization by the component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_SetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->SetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) /* Macro End */ + + +/** The OMX_GetConfig macro will get one of the configuration structures + from a component. This macro can be invoked anytime after the + component has been loaded. The nParamIndex call parameter is used to + indicate which structure is being requested from the component. The + application shall allocate the correct structure and shall fill in the + structure size and version information before invoking this macro. + If the component has not had this configuration parameter sent before, + then the component should return a set of valid DEFAULT values for the + component. This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nIndex + Index of the structure to be filled. This value is from the + OMX_INDEXTYPE enumeration. + @param [in,out] pComponentConfigStructure + pointer to application allocated structure to be filled by the + component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp +*/ +#define OMX_GetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) /* Macro End */ + + +/** The OMX_SetConfig macro will send one of the configuration + structures to a component. Each structure shall be sent one at a time, + each in a separate invocation of the macro. This macro can be invoked + anytime after the component has been loaded. The application shall + allocate the correct structure and shall fill in the structure size + and version information (as well as the actual data) before invoking + this macro. The application is free to dispose of this structure after + the call as the component is required to copy any data it shall retain. + This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nConfigIndex + Index of the structure to be sent. This value is from the + OMX_INDEXTYPE enumeration above. + @param [in] pComponentConfigStructure + pointer to application allocated structure to be used for + initialization by the component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_SetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->SetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) /* Macro End */ + + +/** The OMX_GetExtensionIndex macro will invoke a component to translate + a vendor specific configuration or parameter string into an OMX + structure index. There is no requirement for the vendor to support + this command for the indexes already found in the OMX_INDEXTYPE + enumeration (this is done to save space in small components). The + component shall support all vendor supplied extension indexes not found + in the master OMX_INDEXTYPE enumeration. This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @param [in] cParameterName + OMX_STRING that shall be less than 128 characters long including + the trailing null byte. This is the string that will get + translated by the component into a configuration index. + @param [out] pIndexType + a pointer to a OMX_INDEXTYPE to receive the index value. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetExtensionIndex( \ + hComponent, \ + cParameterName, \ + pIndexType) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetExtensionIndex( \ + hComponent, \ + cParameterName, \ + pIndexType) /* Macro End */ + + +/** The OMX_GetState macro will invoke the component to get the current + state of the component and place the state value into the location + pointed to by pState. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] pState + pointer to the location to receive the state. The value returned + is one of the OMX_STATETYPE members + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetState( \ + hComponent, \ + pState) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetState( \ + hComponent, \ + pState) /* Macro End */ + + +/** The OMX_UseBuffer macro will request that the component use + a buffer (and allocate its own buffer header) already allocated + by another component, or by the IL Client. This is a blocking + call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] ppBuffer + pointer to an OMX_BUFFERHEADERTYPE structure used to receive the + pointer to the buffer header + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ + +#define OMX_UseBuffer( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->UseBuffer( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes, \ + pBuffer) + + +/** The OMX_AllocateBuffer macro will request that the component allocate + a new buffer and buffer header. The component will allocate the + buffer and the buffer header and return a pointer to the buffer + header. This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] ppBuffer + pointer to an OMX_BUFFERHEADERTYPE structure used to receive + the pointer to the buffer header + @param [in] nPortIndex + nPortIndex is used to select the port on the component the buffer will + be used with. The port can be found by using the nPortIndex + value as an index into the Port Definition array of the component. + @param [in] pAppPrivate + pAppPrivate is used to initialize the pAppPrivate member of the + buffer header structure. + @param [in] nSizeBytes + size of the buffer to allocate. Used when bAllocateNew is true. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_AllocateBuffer( \ + hComponent, \ + ppBuffer, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes) \ + ((OMX_COMPONENTTYPE*)hComponent)->AllocateBuffer( \ + hComponent, \ + ppBuffer, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes) /* Macro End */ + + +/** The OMX_FreeBuffer macro will release a buffer header from the component + which was allocated using either OMX_AllocateBuffer or OMX_UseBuffer. If + the component allocated the buffer (see the OMX_UseBuffer macro) then + the component shall free the buffer and buffer header. This is a + blocking call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nPortIndex + nPortIndex is used to select the port on the component the buffer will + be used with. + @param [in] pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_FreeBuffer( \ + hComponent, \ + nPortIndex, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->FreeBuffer( \ + hComponent, \ + nPortIndex, \ + pBuffer) /* Macro End */ + + +/** The OMX_EmptyThisBuffer macro will send a buffer full of data to an + input port of a component. The buffer will be emptied by the component + and returned to the application via the EmptyBufferDone call back. + This is a non-blocking call in that the component will record the buffer + and return immediately and then empty the buffer, later, at the proper + time. As expected, this macro may be invoked only while the component + is in the OMX_StateExecuting. If nPortIndex does not specify an input + port, the component shall return an error. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_EmptyThisBuffer( \ + hComponent, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->EmptyThisBuffer( \ + hComponent, \ + pBuffer) /* Macro End */ + + +/** The OMX_FillThisBuffer macro will send an empty buffer to an + output port of a component. The buffer will be filled by the component + and returned to the application via the FillBufferDone call back. + This is a non-blocking call in that the component will record the buffer + and return immediately and then fill the buffer, later, at the proper + time. As expected, this macro may be invoked only while the component + is in the OMX_ExecutingState. If nPortIndex does not specify an output + port, the component shall return an error. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_FillThisBuffer( \ + hComponent, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->FillThisBuffer( \ + hComponent, \ + pBuffer) /* Macro End */ + + + +/** The OMX_UseEGLImage macro will request that the component use + a EGLImage provided by EGL (and allocate its own buffer header) + This is a blocking call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] ppBuffer + pointer to an OMX_BUFFERHEADERTYPE structure used to receive the + pointer to the buffer header. Note that the memory location used + for this buffer is NOT visible to the IL Client. + @param [in] nPortIndex + nPortIndex is used to select the port on the component the buffer will + be used with. The port can be found by using the nPortIndex + value as an index into the Port Definition array of the component. + @param [in] pAppPrivate + pAppPrivate is used to initialize the pAppPrivate member of the + buffer header structure. + @param [in] eglImage + eglImage contains the handle of the EGLImage to use as a buffer on the + specified port. The component is expected to validate properties of + the EGLImage against the configuration of the port to ensure the component + can use the EGLImage as a buffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_UseEGLImage( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + eglImage) \ + ((OMX_COMPONENTTYPE*)hComponent)->UseEGLImage( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + eglImage) + +/** The OMX_Init method is used to initialize the OMX core. It shall be the + first call made into OMX and it should only be executed one time without + an interviening OMX_Deinit call. + + The core should return from this call within 20 msec. + + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void); + + +/** The OMX_Deinit method is used to deinitialize the OMX core. It shall be + the last call made into OMX. In the event that the core determines that + thare are components loaded when this call is made, the core may return + with an error rather than try to unload the components. + + The core should return from this call within 20 msec. + + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void); + + +/** The OMX_ComponentNameEnum method will enumerate through all the names of + recognised valid components in the system. This function is provided + as a means to detect all the components in the system run-time. There is + no strict ordering to the enumeration order of component names, although + each name will only be enumerated once. If the OMX core supports run-time + installation of new components, it is only requried to detect newly + installed components when the first call to enumerate component names + is made (i.e. when nIndex is 0x0). + + The core should return from this call in 20 msec. + + @param [out] cComponentName + pointer to a null terminated string with the component name. The + names of the components are strings less than 127 bytes in length + plus the trailing null for a maximum size of 128 bytes. An example + of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are + assigned by the vendor, but shall start with "OMX." and then have + the Vendor designation next. + @param [in] nNameLength + number of characters in the cComponentName string. With all + component name strings restricted to less than 128 characters + (including the trailing null) it is recomended that the caller + provide a input string for the cComponentName of 128 characters. + @param [in] nIndex + number containing the enumeration index for the component. + Multiple calls to OMX_ComponentNameEnum with increasing values + of nIndex will enumerate through the component names in the + system until OMX_ErrorNoMore is returned. The value of nIndex + is 0 to (N-1), where N is the number of valid installed components + in the system. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. When the value of nIndex exceeds the number of + components in the system minus 1, OMX_ErrorNoMore will be + returned. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum( + OMX_OUT OMX_STRING cComponentName, + OMX_IN OMX_U32 nNameLength, + OMX_IN OMX_U32 nIndex); + + +/** The OMX_GetHandle method will locate the component specified by the + component name given, load that component into memory and then invoke + the component's methods to create an instance of the component. + + The core should return from this call within 20 msec. + + @param [out] pHandle + pointer to an OMX_HANDLETYPE pointer to be filled in by this method. + @param [in] cComponentName + pointer to a null terminated string with the component name. The + names of the components are strings less than 127 bytes in length + plus the trailing null for a maximum size of 128 bytes. An example + of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are + assigned by the vendor, but shall start with "OMX." and then have + the Vendor designation next. + @param [in] pAppData + pointer to an application defined value that will be returned + during callbacks so that the application can identify the source + of the callback. + @param [in] pCallBacks + pointer to a OMX_CALLBACKTYPE structure that will be passed to the + component to initialize it with. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle( + OMX_OUT OMX_HANDLETYPE* pHandle, + OMX_IN OMX_STRING cComponentName, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_CALLBACKTYPE* pCallBacks); + + +/** The OMX_FreeHandle method will free a handle allocated by the OMX_GetHandle + method. If the component reference count goes to zero, the component will + be unloaded from memory. + + The core should return from this call within 20 msec when the component is + in the OMX_StateLoaded state. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle( + OMX_IN OMX_HANDLETYPE hComponent); + + + +/** The OMX_SetupTunnel method will handle the necessary calls to the components + to setup the specified tunnel the two components. NOTE: This is + an actual method (not a #define macro). This method will make calls into + the component ComponentTunnelRequest method to do the actual tunnel + connection. + + The ComponentTunnelRequest method on both components will be called. + This method shall not be called unless the component is in the + OMX_StateLoaded state except when the ports used for the tunnel are + disabled. In this case, the component may be in the OMX_StateExecuting, + OMX_StatePause, or OMX_StateIdle states. + + The core should return from this call within 20 msec. + + @param [in] hOutput + Handle of the component to be accessed. Also this is the handle + of the component whose port, specified in the nPortOutput parameter + will be used the source for the tunnel. This is the component handle + returned by the call to the OMX_GetHandle function. There is a + requirement that hOutput be the source for the data when + tunelling (i.e. nPortOutput is an output port). If 0x0, the component + specified in hInput will have it's port specified in nPortInput + setup for communication with the application / IL client. + @param [in] nPortOutput + nPortOutput is used to select the source port on component to be + used in the tunnel. + @param [in] hInput + This is the component to setup the tunnel with. This is the handle + of the component whose port, specified in the nPortInput parameter + will be used the destination for the tunnel. This is the component handle + returned by the call to the OMX_GetHandle function. There is a + requirement that hInput be the destination for the data when + tunelling (i.e. nPortInut is an input port). If 0x0, the component + specified in hOutput will have it's port specified in nPortPOutput + setup for communication with the application / IL client. + @param [in] nPortInput + nPortInput is used to select the destination port on component to be + used in the tunnel. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + When OMX_ErrorNotImplemented is returned, one or both components is + a non-interop component and does not support tunneling. + + On failure, the ports of both components are setup for communication + with the application / IL Client. + @ingroup core tun + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel( + OMX_IN OMX_HANDLETYPE hOutput, + OMX_IN OMX_U32 nPortOutput, + OMX_IN OMX_HANDLETYPE hInput, + OMX_IN OMX_U32 nPortInput); + +/** @ingroup cp */ +OMX_API OMX_ERRORTYPE OMX_GetContentPipe( + OMX_OUT OMX_HANDLETYPE *hPipe, + OMX_IN OMX_STRING szURI); + +/** The OMX_GetComponentsOfRole method will return the number of components that support the given + role and (if the compNames field is non-NULL) the names of those components. The call will fail if + an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the + client should: + * first call this function with the compNames field NULL to determine the number of component names + * second call this function with the compNames field pointing to an array of names allocated + according to the number returned by the first call. + + The core should return from this call within 5 msec. + + @param [in] role + This is generic standard component name consisting only of component class + name and the type within that class (e.g. 'audio_decoder.aac'). + @param [inout] pNumComps + This is used both as input and output. + + If compNames is NULL, the input is ignored and the output specifies how many components support + the given role. + + If compNames is not NULL, on input it bounds the size of the input structure and + on output, it specifies the number of components string names listed within the compNames parameter. + @param [inout] compNames + If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings which accepts + a list of the names of all physical components that implement the specified standard component name. + Each name is NULL terminated. numComps indicates the number of names. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole ( + OMX_IN OMX_STRING role, + OMX_INOUT OMX_U32 *pNumComps, + OMX_INOUT OMX_U8 **compNames); + +/** The OMX_GetRolesOfComponent method will return the number of roles supported by the given + component and (if the roles field is non-NULL) the names of those roles. The call will fail if + an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the + client should: + * first call this function with the roles field NULL to determine the number of role names + * second call this function with the roles field pointing to an array of names allocated + according to the number returned by the first call. + + The core should return from this call within 5 msec. + + @param [in] compName + This is the name of the component being queried about. + @param [inout] pNumRoles + This is used both as input and output. + + If roles is NULL, the input is ignored and the output specifies how many roles the component supports. + + If compNames is not NULL, on input it bounds the size of the input structure and + on output, it specifies the number of roles string names listed within the roles parameter. + @param [out] roles + If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings + which accepts a list of the names of all standard components roles implemented on the + specified component name. numComps indicates the number of names. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent ( + OMX_IN OMX_STRING compName, + OMX_INOUT OMX_U32 *pNumRoles, + OMX_OUT OMX_U8 **roles); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ + diff --git a/phonelibs/openmax/include/OMX_CoreExt.h b/phonelibs/openmax/include/OMX_CoreExt.h new file mode 100644 index 00000000000000..3ec14b05f323a6 --- /dev/null +++ b/phonelibs/openmax/include/OMX_CoreExt.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009 The Khronos Group Inc. + * + * 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. + * + */ + +/** OMX_CoreExt.h - OpenMax IL version 1.1.2 + * The OMX_CoreExt header file contains extensions to the definitions used + * by both the application and the component to access common items. + */ + +#ifndef OMX_CoreExt_h +#define OMX_CoreExt_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Each OMX header shall include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ +#include + + +/** Event type extensions. */ +typedef enum OMX_EVENTEXTTYPE +{ + OMX_EventIndexSettingChanged = OMX_EventKhronosExtensions, /**< component signals the IL client of a change + in a param, config, or extension */ + OMX_EventExtMax = 0x7FFFFFFF +} OMX_EVENTEXTTYPE; + + +/** Enable or disable a callback event. */ +typedef struct OMX_CONFIG_CALLBACKREQUESTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_INDEXTYPE nIndex; /**< the index the callback is requested for */ + OMX_BOOL bEnable; /**< enable (OMX_TRUE) or disable (OMX_FALSE) the callback */ +} OMX_CONFIG_CALLBACKREQUESTTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* OMX_CoreExt_h */ +/* File EOF */ diff --git a/phonelibs/openmax/include/OMX_IVCommon.h b/phonelibs/openmax/include/OMX_IVCommon.h new file mode 100644 index 00000000000000..ec717565a09929 --- /dev/null +++ b/phonelibs/openmax/include/OMX_IVCommon.h @@ -0,0 +1,933 @@ +/** + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** + * @file OMX_IVCommon.h - OpenMax IL version 1.1.2 + * The structures needed by Video and Image components to exchange + * parameters and configuration data with the components. + */ +#ifndef OMX_IVCommon_h +#define OMX_IVCommon_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * Each OMX header must include all required header files to allow the header + * to compile without errors. The includes below are required for this header + * file to compile successfully + */ + +#include + +/** @defgroup iv OpenMAX IL Imaging and Video Domain + * Common structures for OpenMAX IL Imaging and Video domains + * @{ + */ + + +/** + * Enumeration defining possible uncompressed image/video formats. + * + * ENUMS: + * Unused : Placeholder value when format is N/A + * Monochrome : black and white + * 8bitRGB332 : Red 7:5, Green 4:2, Blue 1:0 + * 12bitRGB444 : Red 11:8, Green 7:4, Blue 3:0 + * 16bitARGB4444 : Alpha 15:12, Red 11:8, Green 7:4, Blue 3:0 + * 16bitARGB1555 : Alpha 15, Red 14:10, Green 9:5, Blue 4:0 + * 16bitRGB565 : Red 15:11, Green 10:5, Blue 4:0 + * 16bitBGR565 : Blue 15:11, Green 10:5, Red 4:0 + * 18bitRGB666 : Red 17:12, Green 11:6, Blue 5:0 + * 18bitARGB1665 : Alpha 17, Red 16:11, Green 10:5, Blue 4:0 + * 19bitARGB1666 : Alpha 18, Red 17:12, Green 11:6, Blue 5:0 + * 24bitRGB888 : Red 24:16, Green 15:8, Blue 7:0 + * 24bitBGR888 : Blue 24:16, Green 15:8, Red 7:0 + * 24bitARGB1887 : Alpha 23, Red 22:15, Green 14:7, Blue 6:0 + * 25bitARGB1888 : Alpha 24, Red 23:16, Green 15:8, Blue 7:0 + * 32bitBGRA8888 : Blue 31:24, Green 23:16, Red 15:8, Alpha 7:0 + * 32bitARGB8888 : Alpha 31:24, Red 23:16, Green 15:8, Blue 7:0 + * YUV411Planar : U,Y are subsampled by a factor of 4 horizontally + * YUV411PackedPlanar : packed per payload in planar slices + * YUV420Planar : Three arrays Y,U,V. + * YUV420PackedPlanar : packed per payload in planar slices + * YUV420SemiPlanar : Two arrays, one is all Y, the other is U and V + * YUV422Planar : Three arrays Y,U,V. + * YUV422PackedPlanar : packed per payload in planar slices + * YUV422SemiPlanar : Two arrays, one is all Y, the other is U and V + * YCbYCr : Organized as 16bit YUYV (i.e. YCbYCr) + * YCrYCb : Organized as 16bit YVYU (i.e. YCrYCb) + * CbYCrY : Organized as 16bit UYVY (i.e. CbYCrY) + * CrYCbY : Organized as 16bit VYUY (i.e. CrYCbY) + * YUV444Interleaved : Each pixel contains equal parts YUV + * RawBayer8bit : SMIA camera output format + * RawBayer10bit : SMIA camera output format + * RawBayer8bitcompressed : SMIA camera output format + */ +typedef enum OMX_COLOR_FORMATTYPE { + OMX_COLOR_FormatUnused, + OMX_COLOR_FormatMonochrome, + OMX_COLOR_Format8bitRGB332, + OMX_COLOR_Format12bitRGB444, + OMX_COLOR_Format16bitARGB4444, + OMX_COLOR_Format16bitARGB1555, + OMX_COLOR_Format16bitRGB565, + OMX_COLOR_Format16bitBGR565, + OMX_COLOR_Format18bitRGB666, + OMX_COLOR_Format18bitARGB1665, + OMX_COLOR_Format19bitARGB1666, + OMX_COLOR_Format24bitRGB888, + OMX_COLOR_Format24bitBGR888, + OMX_COLOR_Format24bitARGB1887, + OMX_COLOR_Format25bitARGB1888, + OMX_COLOR_Format32bitBGRA8888, + OMX_COLOR_Format32bitARGB8888, + OMX_COLOR_FormatYUV411Planar, + OMX_COLOR_FormatYUV411PackedPlanar, + OMX_COLOR_FormatYUV420Planar, + OMX_COLOR_FormatYUV420PackedPlanar, + OMX_COLOR_FormatYUV420SemiPlanar, + OMX_COLOR_FormatYUV422Planar, + OMX_COLOR_FormatYUV422PackedPlanar, + OMX_COLOR_FormatYUV422SemiPlanar, + OMX_COLOR_FormatYCbYCr, + OMX_COLOR_FormatYCrYCb, + OMX_COLOR_FormatCbYCrY, + OMX_COLOR_FormatCrYCbY, + OMX_COLOR_FormatYUV444Interleaved, + OMX_COLOR_FormatRawBayer8bit, + OMX_COLOR_FormatRawBayer10bit, + OMX_COLOR_FormatRawBayer8bitcompressed, + OMX_COLOR_FormatL2, + OMX_COLOR_FormatL4, + OMX_COLOR_FormatL8, + OMX_COLOR_FormatL16, + OMX_COLOR_FormatL24, + OMX_COLOR_FormatL32, + OMX_COLOR_FormatYUV420PackedSemiPlanar, + OMX_COLOR_FormatYUV422PackedSemiPlanar, + OMX_COLOR_Format18BitBGR666, + OMX_COLOR_Format24BitARGB6666, + OMX_COLOR_Format24BitABGR6666, + OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_COLOR_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + /** + +/** @defgroup imaging OpenMAX IL Imaging Domain + * @ingroup iv + * Structures for OpenMAX IL Imaging domain + * @{ + */ + +/** + * Enumeration used to define the possible image compression coding. + */ +typedef enum OMX_IMAGE_CODINGTYPE { + OMX_IMAGE_CodingUnused, /**< Value when format is N/A */ + OMX_IMAGE_CodingAutoDetect, /**< Auto detection of image format */ + OMX_IMAGE_CodingJPEG, /**< JPEG/JFIF image format */ + OMX_IMAGE_CodingJPEG2K, /**< JPEG 2000 image format */ + OMX_IMAGE_CodingEXIF, /**< EXIF image format */ + OMX_IMAGE_CodingTIFF, /**< TIFF image format */ + OMX_IMAGE_CodingGIF, /**< Graphics image format */ + OMX_IMAGE_CodingPNG, /**< PNG image format */ + OMX_IMAGE_CodingLZW, /**< LZW image format */ + OMX_IMAGE_CodingBMP, /**< Windows Bitmap format */ + OMX_IMAGE_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_CodingMax = 0x7FFFFFFF +} OMX_IMAGE_CODINGTYPE; + + +/** + * Data structure used to define an image path. The number of image paths + * for input and output will vary by type of the image component. + * + * Input (aka Source) : Zero Inputs, one Output, + * Splitter : One Input, 2 or more Outputs, + * Processing Element : One Input, one output, + * Mixer : 2 or more inputs, one output, + * Output (aka Sink) : One Input, zero outputs. + * + * The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output + * image path. If additional vendor specific data is required, it should + * be transmitted to the component using the CustomCommand function. + * Compliant components will prepopulate this structure with optimal + * values during the OMX_GetParameter() command. + * + * STRUCT MEMBERS: + * cMIMEType : MIME type of data for the port + * pNativeRender : Platform specific reference for a display if a + * sync, otherwise this field is 0 + * nFrameWidth : Width of frame to be used on port if + * uncompressed format is used. Use 0 for + * unknown, don't care or variable + * nFrameHeight : Height of frame to be used on port if + * uncompressed format is used. Use 0 for + * unknown, don't care or variable + * nStride : Number of bytes per span of an image (i.e. + * indicates the number of bytes to get from + * span N to span N+1, where negative stride + * indicates the image is bottom up + * nSliceHeight : Height used when encoding in slices + * bFlagErrorConcealment : Turns on error concealment if it is supported by + * the OMX component + * eCompressionFormat : Compression format used in this instance of + * the component. When OMX_IMAGE_CodingUnused is + * specified, eColorFormat is valid + * eColorFormat : Decompressed format used by this component + * pNativeWindow : Platform specific reference for a window object if a + * display sink , otherwise this field is 0x0. + */ +typedef struct OMX_IMAGE_PORTDEFINITIONTYPE { + OMX_STRING cMIMEType; + OMX_NATIVE_DEVICETYPE pNativeRender; + OMX_U32 nFrameWidth; + OMX_U32 nFrameHeight; + OMX_S32 nStride; + OMX_U32 nSliceHeight; + OMX_BOOL bFlagErrorConcealment; + OMX_IMAGE_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; + OMX_NATIVE_WINDOWTYPE pNativeWindow; +} OMX_IMAGE_PORTDEFINITIONTYPE; + + +/** + * Port format parameter. This structure is used to enumerate the various + * data input/output format supported by the port. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Indicates which port to set + * nIndex : Indicates the enumeration index for the format from + * 0x0 to N-1 + * eCompressionFormat : Compression format used in this instance of the + * component. When OMX_IMAGE_CodingUnused is specified, + * eColorFormat is valid + * eColorFormat : Decompressed format used by this component + */ +typedef struct OMX_IMAGE_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nIndex; + OMX_IMAGE_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; +} OMX_IMAGE_PARAM_PORTFORMATTYPE; + + +/** + * Flash control type + * + * ENUMS + * Torch : Flash forced constantly on + */ +typedef enum OMX_IMAGE_FLASHCONTROLTYPE { + OMX_IMAGE_FlashControlOn = 0, + OMX_IMAGE_FlashControlOff, + OMX_IMAGE_FlashControlAuto, + OMX_IMAGE_FlashControlRedEyeReduction, + OMX_IMAGE_FlashControlFillin, + OMX_IMAGE_FlashControlTorch, + OMX_IMAGE_FlashControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_FlashControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_FlashControlMax = 0x7FFFFFFF +} OMX_IMAGE_FLASHCONTROLTYPE; + + +/** + * Flash control configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFlashControl : Flash control type + */ +typedef struct OMX_IMAGE_PARAM_FLASHCONTROLTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_FLASHCONTROLTYPE eFlashControl; +} OMX_IMAGE_PARAM_FLASHCONTROLTYPE; + + +/** + * Focus control type + */ +typedef enum OMX_IMAGE_FOCUSCONTROLTYPE { + OMX_IMAGE_FocusControlOn = 0, + OMX_IMAGE_FocusControlOff, + OMX_IMAGE_FocusControlAuto, + OMX_IMAGE_FocusControlAutoLock, + OMX_IMAGE_FocusControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_FocusControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_FocusControlMax = 0x7FFFFFFF +} OMX_IMAGE_FOCUSCONTROLTYPE; + + +/** + * Focus control configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFocusControl : Focus control + * nFocusSteps : Focus can take on values from 0 mm to infinity. + * Interest is only in number of steps over this range. + * nFocusStepIndex : Current focus step index + */ +typedef struct OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_FOCUSCONTROLTYPE eFocusControl; + OMX_U32 nFocusSteps; + OMX_U32 nFocusStepIndex; +} OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE; + + +/** + * Q Factor for JPEG compression, which controls the tradeoff between image + * quality and size. Q Factor provides a more simple means of controlling + * JPEG compression quality, without directly programming Quantization + * tables for chroma and luma + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nQFactor : JPEG Q factor value in the range of 1-100. A factor of 1 + * produces the smallest, worst quality images, and a factor + * of 100 produces the largest, best quality images. A + * typical default is 75 for small good quality images + */ +typedef struct OMX_IMAGE_PARAM_QFACTORTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nQFactor; +} OMX_IMAGE_PARAM_QFACTORTYPE; + +/** + * Quantization table type + */ + +typedef enum OMX_IMAGE_QUANTIZATIONTABLETYPE { + OMX_IMAGE_QuantizationTableLuma = 0, + OMX_IMAGE_QuantizationTableChroma, + OMX_IMAGE_QuantizationTableChromaCb, + OMX_IMAGE_QuantizationTableChromaCr, + OMX_IMAGE_QuantizationTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_QuantizationTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_QuantizationTableMax = 0x7FFFFFFF +} OMX_IMAGE_QUANTIZATIONTABLETYPE; + +/** + * JPEG quantization tables are used to determine DCT compression for + * YUV data, as an alternative to specifying Q factor, providing exact + * control of compression + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eQuantizationTable : Quantization table type + * nQuantizationMatrix[64] : JPEG quantization table of coefficients stored + * in increasing columns then by rows of data (i.e. + * row 1, ... row 8). Quantization values are in + * the range 0-255 and stored in linear order + * (i.e. the component will zig-zag the + * quantization table data if required internally) + */ +typedef struct OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_QUANTIZATIONTABLETYPE eQuantizationTable; + OMX_U8 nQuantizationMatrix[64]; +} OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE; + + +/** + * Huffman table type, the same Huffman table is applied for chroma and + * luma component + */ +typedef enum OMX_IMAGE_HUFFMANTABLETYPE { + OMX_IMAGE_HuffmanTableAC = 0, + OMX_IMAGE_HuffmanTableDC, + OMX_IMAGE_HuffmanTableACLuma, + OMX_IMAGE_HuffmanTableACChroma, + OMX_IMAGE_HuffmanTableDCLuma, + OMX_IMAGE_HuffmanTableDCChroma, + OMX_IMAGE_HuffmanTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_HuffmanTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_HuffmanTableMax = 0x7FFFFFFF +} OMX_IMAGE_HUFFMANTABLETYPE; + +/** + * JPEG Huffman table + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eHuffmanTable : Huffman table type + * nNumberOfHuffmanCodeOfLength[16] : 0-16, number of Huffman codes of each + * possible length + * nHuffmanTable[256] : 0-255, the size used for AC and DC + * HuffmanTable are 16 and 162 + */ +typedef struct OMX_IMAGE_PARAM_HUFFMANTTABLETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_HUFFMANTABLETYPE eHuffmanTable; + OMX_U8 nNumberOfHuffmanCodeOfLength[16]; + OMX_U8 nHuffmanTable[256]; +}OMX_IMAGE_PARAM_HUFFMANTTABLETYPE; + +/** @} */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/phonelibs/openmax/include/OMX_Index.h b/phonelibs/openmax/include/OMX_Index.h new file mode 100644 index 00000000000000..a1f17487d3c1e7 --- /dev/null +++ b/phonelibs/openmax/include/OMX_Index.h @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** @file OMX_Index.h - OpenMax IL version 1.1.2 + * The OMX_Index header file contains the definitions for both applications + * and components . + */ + + +#ifndef OMX_Index_h +#define OMX_Index_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ +#include + + +/** The OMX_INDEXTYPE enumeration is used to select a structure when either + * getting or setting parameters and/or configuration data. Each entry in + * this enumeration maps to an OMX specified structure. When the + * OMX_GetParameter, OMX_SetParameter, OMX_GetConfig or OMX_SetConfig methods + * are used, the second parameter will always be an entry from this enumeration + * and the third entry will be the structure shown in the comments for the entry. + * For example, if the application is initializing a cropping function, the + * OMX_SetConfig command would have OMX_IndexConfigCommonInputCrop as the second parameter + * and would send a pointer to an initialized OMX_RECTTYPE structure as the + * third parameter. + * + * The enumeration entries named with the OMX_Config prefix are sent using + * the OMX_SetConfig command and the enumeration entries named with the + * OMX_PARAM_ prefix are sent using the OMX_SetParameter command. + */ +typedef enum OMX_INDEXTYPE { + + OMX_IndexComponentStartUnused = 0x01000000, + OMX_IndexParamPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ + OMX_IndexParamAudioInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamImageInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamVideoInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamOtherInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamNumAvailableStreams, /**< reference: OMX_PARAM_U32TYPE */ + OMX_IndexParamActiveStream, /**< reference: OMX_PARAM_U32TYPE */ + OMX_IndexParamSuspensionPolicy, /**< reference: OMX_PARAM_SUSPENSIONPOLICYTYPE */ + OMX_IndexParamComponentSuspended, /**< reference: OMX_PARAM_SUSPENSIONTYPE */ + OMX_IndexConfigCapturing, /**< reference: OMX_CONFIG_BOOLEANTYPE */ + OMX_IndexConfigCaptureMode, /**< reference: OMX_CONFIG_CAPTUREMODETYPE */ + OMX_IndexAutoPauseAfterCapture, /**< reference: OMX_CONFIG_BOOLEANTYPE */ + OMX_IndexParamContentURI, /**< reference: OMX_PARAM_CONTENTURITYPE */ + OMX_IndexParamCustomContentPipe, /**< reference: OMX_PARAM_CONTENTPIPETYPE */ + OMX_IndexParamDisableResourceConcealment, /**< reference: OMX_RESOURCECONCEALMENTTYPE */ + OMX_IndexConfigMetadataItemCount, /**< reference: OMX_CONFIG_METADATAITEMCOUNTTYPE */ + OMX_IndexConfigContainerNodeCount, /**< reference: OMX_CONFIG_CONTAINERNODECOUNTTYPE */ + OMX_IndexConfigMetadataItem, /**< reference: OMX_CONFIG_METADATAITEMTYPE */ + OMX_IndexConfigCounterNodeID, /**< reference: OMX_CONFIG_CONTAINERNODEIDTYPE */ + OMX_IndexParamMetadataFilterType, /**< reference: OMX_PARAM_METADATAFILTERTYPE */ + OMX_IndexParamMetadataKeyFilter, /**< reference: OMX_PARAM_METADATAFILTERTYPE */ + OMX_IndexConfigPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ + OMX_IndexParamStandardComponentRole, /**< reference: OMX_PARAM_COMPONENTROLETYPE */ + + OMX_IndexPortStartUnused = 0x02000000, + OMX_IndexParamPortDefinition, /**< reference: OMX_PARAM_PORTDEFINITIONTYPE */ + OMX_IndexParamCompBufferSupplier, /**< reference: OMX_PARAM_BUFFERSUPPLIERTYPE */ + OMX_IndexReservedStartUnused = 0x03000000, + + /* Audio parameters and configurations */ + OMX_IndexAudioStartUnused = 0x04000000, + OMX_IndexParamAudioPortFormat, /**< reference: OMX_AUDIO_PARAM_PORTFORMATTYPE */ + OMX_IndexParamAudioPcm, /**< reference: OMX_AUDIO_PARAM_PCMMODETYPE */ + OMX_IndexParamAudioAac, /**< reference: OMX_AUDIO_PARAM_AACPROFILETYPE */ + OMX_IndexParamAudioRa, /**< reference: OMX_AUDIO_PARAM_RATYPE */ + OMX_IndexParamAudioMp3, /**< reference: OMX_AUDIO_PARAM_MP3TYPE */ + OMX_IndexParamAudioAdpcm, /**< reference: OMX_AUDIO_PARAM_ADPCMTYPE */ + OMX_IndexParamAudioG723, /**< reference: OMX_AUDIO_PARAM_G723TYPE */ + OMX_IndexParamAudioG729, /**< reference: OMX_AUDIO_PARAM_G729TYPE */ + OMX_IndexParamAudioAmr, /**< reference: OMX_AUDIO_PARAM_AMRTYPE */ + OMX_IndexParamAudioWma, /**< reference: OMX_AUDIO_PARAM_WMATYPE */ + OMX_IndexParamAudioSbc, /**< reference: OMX_AUDIO_PARAM_SBCTYPE */ + OMX_IndexParamAudioMidi, /**< reference: OMX_AUDIO_PARAM_MIDITYPE */ + OMX_IndexParamAudioGsm_FR, /**< reference: OMX_AUDIO_PARAM_GSMFRTYPE */ + OMX_IndexParamAudioMidiLoadUserSound, /**< reference: OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE */ + OMX_IndexParamAudioG726, /**< reference: OMX_AUDIO_PARAM_G726TYPE */ + OMX_IndexParamAudioGsm_EFR, /**< reference: OMX_AUDIO_PARAM_GSMEFRTYPE */ + OMX_IndexParamAudioGsm_HR, /**< reference: OMX_AUDIO_PARAM_GSMHRTYPE */ + OMX_IndexParamAudioPdc_FR, /**< reference: OMX_AUDIO_PARAM_PDCFRTYPE */ + OMX_IndexParamAudioPdc_EFR, /**< reference: OMX_AUDIO_PARAM_PDCEFRTYPE */ + OMX_IndexParamAudioPdc_HR, /**< reference: OMX_AUDIO_PARAM_PDCHRTYPE */ + OMX_IndexParamAudioTdma_FR, /**< reference: OMX_AUDIO_PARAM_TDMAFRTYPE */ + OMX_IndexParamAudioTdma_EFR, /**< reference: OMX_AUDIO_PARAM_TDMAEFRTYPE */ + OMX_IndexParamAudioQcelp8, /**< reference: OMX_AUDIO_PARAM_QCELP8TYPE */ + OMX_IndexParamAudioQcelp13, /**< reference: OMX_AUDIO_PARAM_QCELP13TYPE */ + OMX_IndexParamAudioEvrc, /**< reference: OMX_AUDIO_PARAM_EVRCTYPE */ + OMX_IndexParamAudioSmv, /**< reference: OMX_AUDIO_PARAM_SMVTYPE */ + OMX_IndexParamAudioVorbis, /**< reference: OMX_AUDIO_PARAM_VORBISTYPE */ + + OMX_IndexConfigAudioMidiImmediateEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE */ + OMX_IndexConfigAudioMidiControl, /**< reference: OMX_AUDIO_CONFIG_MIDICONTROLTYPE */ + OMX_IndexConfigAudioMidiSoundBankProgram, /**< reference: OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE */ + OMX_IndexConfigAudioMidiStatus, /**< reference: OMX_AUDIO_CONFIG_MIDISTATUSTYPE */ + OMX_IndexConfigAudioMidiMetaEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE */ + OMX_IndexConfigAudioMidiMetaEventData, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE */ + OMX_IndexConfigAudioVolume, /**< reference: OMX_AUDIO_CONFIG_VOLUMETYPE */ + OMX_IndexConfigAudioBalance, /**< reference: OMX_AUDIO_CONFIG_BALANCETYPE */ + OMX_IndexConfigAudioChannelMute, /**< reference: OMX_AUDIO_CONFIG_CHANNELMUTETYPE */ + OMX_IndexConfigAudioMute, /**< reference: OMX_AUDIO_CONFIG_MUTETYPE */ + OMX_IndexConfigAudioLoudness, /**< reference: OMX_AUDIO_CONFIG_LOUDNESSTYPE */ + OMX_IndexConfigAudioEchoCancelation, /**< reference: OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE */ + OMX_IndexConfigAudioNoiseReduction, /**< reference: OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE */ + OMX_IndexConfigAudioBass, /**< reference: OMX_AUDIO_CONFIG_BASSTYPE */ + OMX_IndexConfigAudioTreble, /**< reference: OMX_AUDIO_CONFIG_TREBLETYPE */ + OMX_IndexConfigAudioStereoWidening, /**< reference: OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE */ + OMX_IndexConfigAudioChorus, /**< reference: OMX_AUDIO_CONFIG_CHORUSTYPE */ + OMX_IndexConfigAudioEqualizer, /**< reference: OMX_AUDIO_CONFIG_EQUALIZERTYPE */ + OMX_IndexConfigAudioReverberation, /**< reference: OMX_AUDIO_CONFIG_REVERBERATIONTYPE */ + OMX_IndexConfigAudioChannelVolume, /**< reference: OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE */ + + /* Image specific parameters and configurations */ + OMX_IndexImageStartUnused = 0x05000000, + OMX_IndexParamImagePortFormat, /**< reference: OMX_IMAGE_PARAM_PORTFORMATTYPE */ + OMX_IndexParamFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */ + OMX_IndexConfigFocusControl, /**< reference: OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE */ + OMX_IndexParamQFactor, /**< reference: OMX_IMAGE_PARAM_QFACTORTYPE */ + OMX_IndexParamQuantizationTable, /**< reference: OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE */ + OMX_IndexParamHuffmanTable, /**< reference: OMX_IMAGE_PARAM_HUFFMANTTABLETYPE */ + OMX_IndexConfigFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */ + + /* Video specific parameters and configurations */ + OMX_IndexVideoStartUnused = 0x06000000, + OMX_IndexParamVideoPortFormat, /**< reference: OMX_VIDEO_PARAM_PORTFORMATTYPE */ + OMX_IndexParamVideoQuantization, /**< reference: OMX_VIDEO_PARAM_QUANTIZATIONTYPE */ + OMX_IndexParamVideoFastUpdate, /**< reference: OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE */ + OMX_IndexParamVideoBitrate, /**< reference: OMX_VIDEO_PARAM_BITRATETYPE */ + OMX_IndexParamVideoMotionVector, /**< reference: OMX_VIDEO_PARAM_MOTIONVECTORTYPE */ + OMX_IndexParamVideoIntraRefresh, /**< reference: OMX_VIDEO_PARAM_INTRAREFRESHTYPE */ + OMX_IndexParamVideoErrorCorrection, /**< reference: OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE */ + OMX_IndexParamVideoVBSMC, /**< reference: OMX_VIDEO_PARAM_VBSMCTYPE */ + OMX_IndexParamVideoMpeg2, /**< reference: OMX_VIDEO_PARAM_MPEG2TYPE */ + OMX_IndexParamVideoMpeg4, /**< reference: OMX_VIDEO_PARAM_MPEG4TYPE */ + OMX_IndexParamVideoWmv, /**< reference: OMX_VIDEO_PARAM_WMVTYPE */ + OMX_IndexParamVideoRv, /**< reference: OMX_VIDEO_PARAM_RVTYPE */ + OMX_IndexParamVideoAvc, /**< reference: OMX_VIDEO_PARAM_AVCTYPE */ + OMX_IndexParamVideoH263, /**< reference: OMX_VIDEO_PARAM_H263TYPE */ + OMX_IndexParamVideoProfileLevelQuerySupported, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */ + OMX_IndexParamVideoProfileLevelCurrent, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */ + OMX_IndexConfigVideoBitrate, /**< reference: OMX_VIDEO_CONFIG_BITRATETYPE */ + OMX_IndexConfigVideoFramerate, /**< reference: OMX_CONFIG_FRAMERATETYPE */ + OMX_IndexConfigVideoIntraVOPRefresh, /**< reference: OMX_CONFIG_INTRAREFRESHVOPTYPE */ + OMX_IndexConfigVideoIntraMBRefresh, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */ + OMX_IndexConfigVideoMBErrorReporting, /**< reference: OMX_CONFIG_MBERRORREPORTINGTYPE */ + OMX_IndexParamVideoMacroblocksPerFrame, /**< reference: OMX_PARAM_MACROBLOCKSTYPE */ + OMX_IndexConfigVideoMacroBlockErrorMap, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */ + OMX_IndexParamVideoSliceFMO, /**< reference: OMX_VIDEO_PARAM_AVCSLICEFMO */ + OMX_IndexConfigVideoAVCIntraPeriod, /**< reference: OMX_VIDEO_CONFIG_AVCINTRAPERIOD */ + OMX_IndexConfigVideoNalSize, /**< reference: OMX_VIDEO_CONFIG_NALSIZE */ + OMX_IndexConfigCommonDeinterlace, /**< reference: OMX_VIDEO_CONFIG_DEINTERLACE */ + + /* Image & Video common Configurations */ + OMX_IndexCommonStartUnused = 0x07000000, + OMX_IndexParamCommonDeblocking, /**< reference: OMX_PARAM_DEBLOCKINGTYPE */ + OMX_IndexParamCommonSensorMode, /**< reference: OMX_PARAM_SENSORMODETYPE */ + OMX_IndexParamCommonInterleave, /**< reference: OMX_PARAM_INTERLEAVETYPE */ + OMX_IndexConfigCommonColorFormatConversion, /**< reference: OMX_CONFIG_COLORCONVERSIONTYPE */ + OMX_IndexConfigCommonScale, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ + OMX_IndexConfigCommonImageFilter, /**< reference: OMX_CONFIG_IMAGEFILTERTYPE */ + OMX_IndexConfigCommonColorEnhancement, /**< reference: OMX_CONFIG_COLORENHANCEMENTTYPE */ + OMX_IndexConfigCommonColorKey, /**< reference: OMX_CONFIG_COLORKEYTYPE */ + OMX_IndexConfigCommonColorBlend, /**< reference: OMX_CONFIG_COLORBLENDTYPE */ + OMX_IndexConfigCommonFrameStabilisation,/**< reference: OMX_CONFIG_FRAMESTABTYPE */ + OMX_IndexConfigCommonRotate, /**< reference: OMX_CONFIG_ROTATIONTYPE */ + OMX_IndexConfigCommonMirror, /**< reference: OMX_CONFIG_MIRRORTYPE */ + OMX_IndexConfigCommonOutputPosition, /**< reference: OMX_CONFIG_POINTTYPE */ + OMX_IndexConfigCommonInputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ + OMX_IndexConfigCommonOutputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ + OMX_IndexConfigCommonDigitalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ + OMX_IndexConfigCommonOpticalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE*/ + OMX_IndexConfigCommonWhiteBalance, /**< reference: OMX_CONFIG_WHITEBALCONTROLTYPE */ + OMX_IndexConfigCommonExposure, /**< reference: OMX_CONFIG_EXPOSURECONTROLTYPE */ + OMX_IndexConfigCommonContrast, /**< reference: OMX_CONFIG_CONTRASTTYPE */ + OMX_IndexConfigCommonBrightness, /**< reference: OMX_CONFIG_BRIGHTNESSTYPE */ + OMX_IndexConfigCommonBacklight, /**< reference: OMX_CONFIG_BACKLIGHTTYPE */ + OMX_IndexConfigCommonGamma, /**< reference: OMX_CONFIG_GAMMATYPE */ + OMX_IndexConfigCommonSaturation, /**< reference: OMX_CONFIG_SATURATIONTYPE */ + OMX_IndexConfigCommonLightness, /**< reference: OMX_CONFIG_LIGHTNESSTYPE */ + OMX_IndexConfigCommonExclusionRect, /**< reference: OMX_CONFIG_RECTTYPE */ + OMX_IndexConfigCommonDithering, /**< reference: OMX_CONFIG_DITHERTYPE */ + OMX_IndexConfigCommonPlaneBlend, /**< reference: OMX_CONFIG_PLANEBLENDTYPE */ + OMX_IndexConfigCommonExposureValue, /**< reference: OMX_CONFIG_EXPOSUREVALUETYPE */ + OMX_IndexConfigCommonOutputSize, /**< reference: OMX_FRAMESIZETYPE */ + OMX_IndexParamCommonExtraQuantData, /**< reference: OMX_OTHER_EXTRADATATYPE */ + OMX_IndexConfigCommonFocusRegion, /**< reference: OMX_CONFIG_FOCUSREGIONTYPE */ + OMX_IndexConfigCommonFocusStatus, /**< reference: OMX_PARAM_FOCUSSTATUSTYPE */ + OMX_IndexConfigCommonTransitionEffect, /**< reference: OMX_CONFIG_TRANSITIONEFFECTTYPE */ + + /* Reserved Configuration range */ + OMX_IndexOtherStartUnused = 0x08000000, + OMX_IndexParamOtherPortFormat, /**< reference: OMX_OTHER_PARAM_PORTFORMATTYPE */ + OMX_IndexConfigOtherPower, /**< reference: OMX_OTHER_CONFIG_POWERTYPE */ + OMX_IndexConfigOtherStats, /**< reference: OMX_OTHER_CONFIG_STATSTYPE */ + + + /* Reserved Time range */ + OMX_IndexTimeStartUnused = 0x09000000, + OMX_IndexConfigTimeScale, /**< reference: OMX_TIME_CONFIG_SCALETYPE */ + OMX_IndexConfigTimeClockState, /**< reference: OMX_TIME_CONFIG_CLOCKSTATETYPE */ + OMX_IndexConfigTimeActiveRefClock, /**< reference: OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE */ + OMX_IndexConfigTimeCurrentMediaTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */ + OMX_IndexConfigTimeCurrentWallTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */ + OMX_IndexConfigTimeCurrentAudioReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ + OMX_IndexConfigTimeCurrentVideoReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ + OMX_IndexConfigTimeMediaTimeRequest, /**< reference: OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE (write only) */ + OMX_IndexConfigTimeClientStartTime, /** + + +/** Khronos standard extension indices. + +This enum lists the current Khronos extension indices to OpenMAX IL. +*/ +typedef enum OMX_INDEXEXTTYPE { + + /* Component parameters and configurations */ + OMX_IndexExtComponentStartUnused = OMX_IndexKhronosExtensions + 0x00100000, + OMX_IndexConfigCallbackRequest, /**< reference: OMX_CONFIG_CALLBACKREQUESTTYPE */ + OMX_IndexConfigCommitMode, /**< reference: OMX_CONFIG_COMMITMODETYPE */ + OMX_IndexConfigCommit, /**< reference: OMX_CONFIG_COMMITTYPE */ + + /* Port parameters and configurations */ + OMX_IndexExtPortStartUnused = OMX_IndexKhronosExtensions + 0x00200000, + + /* Audio parameters and configurations */ + OMX_IndexExtAudioStartUnused = OMX_IndexKhronosExtensions + 0x00400000, + + /* Image parameters and configurations */ + OMX_IndexExtImageStartUnused = OMX_IndexKhronosExtensions + 0x00500000, + + /* Video parameters and configurations */ + OMX_IndexExtVideoStartUnused = OMX_IndexKhronosExtensions + 0x00600000, + OMX_IndexParamNalStreamFormatSupported, /**< reference: OMX_NALSTREAMFORMATTYPE */ + OMX_IndexParamNalStreamFormat, /**< reference: OMX_NALSTREAMFORMATTYPE */ + OMX_IndexParamNalStreamFormatSelect, /**< reference: OMX_NALSTREAMFORMATTYPE */ + OMX_IndexParamVideoVp8, /**< reference: OMX_VIDEO_PARAM_VP8TYPE */ + OMX_IndexConfigVideoVp8ReferenceFrame, /**< reference: OMX_VIDEO_VP8REFERENCEFRAMETYPE */ + OMX_IndexConfigVideoVp8ReferenceFrameType, /**< reference: OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE */ + OMX_IndexParamVideoReserved, /**< Reserved for future index */ + OMX_IndexParamVideoHevc, /**< reference: OMX_VIDEO_PARAM_HEVCTYPE */ + + /* Image & Video common configurations */ + OMX_IndexExtCommonStartUnused = OMX_IndexKhronosExtensions + 0x00700000, + + /* Other configurations */ + OMX_IndexExtOtherStartUnused = OMX_IndexKhronosExtensions + 0x00800000, + OMX_IndexConfigAutoFramerateConversion, /**< reference: OMX_CONFIG_BOOLEANTYPE */ + OMX_IndexConfigPriority, /**< reference: OMX_PARAM_U32TYPE */ + OMX_IndexConfigOperatingRate, /**< reference: OMX_PARAM_U32TYPE in Q16 format for video and in Hz for audio */ + + /* Time configurations */ + OMX_IndexExtTimeStartUnused = OMX_IndexKhronosExtensions + 0x00900000, + + OMX_IndexExtMax = 0x7FFFFFFF +} OMX_INDEXEXTTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* OMX_IndexExt_h */ +/* File EOF */ diff --git a/phonelibs/openmax/include/OMX_Other.h b/phonelibs/openmax/include/OMX_Other.h new file mode 100644 index 00000000000000..caf7f384480844 --- /dev/null +++ b/phonelibs/openmax/include/OMX_Other.h @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** @file OMX_Other.h - OpenMax IL version 1.1.2 + * The structures needed by Other components to exchange + * parameters and configuration data with the components. + */ + +#ifndef OMX_Other_h +#define OMX_Other_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + + +/** + * Enumeration of possible data types which match to multiple domains or no + * domain at all. For types which are vendor specific, a value above + * OMX_OTHER_VENDORTSTART should be used. + */ +typedef enum OMX_OTHER_FORMATTYPE { + OMX_OTHER_FormatTime = 0, /**< Transmission of various timestamps, elapsed time, + time deltas, etc */ + OMX_OTHER_FormatPower, /**< Perhaps used for enabling/disabling power + management, setting clocks? */ + OMX_OTHER_FormatStats, /**< Could be things such as frame rate, frames + dropped, etc */ + OMX_OTHER_FormatBinary, /**< Arbitrary binary data */ + OMX_OTHER_FormatVendorReserved = 1000, /**< Starting value for vendor specific + formats */ + + OMX_OTHER_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_OTHER_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_OTHER_FormatMax = 0x7FFFFFFF +} OMX_OTHER_FORMATTYPE; + +/** + * Enumeration of seek modes. + */ +typedef enum OMX_TIME_SEEKMODETYPE { + OMX_TIME_SeekModeFast = 0, /**< Prefer seeking to an approximation + * of the requested seek position over + * the actual seek position if it + * results in a faster seek. */ + OMX_TIME_SeekModeAccurate, /**< Prefer seeking to the actual seek + * position over an approximation + * of the requested seek position even + * if it results in a slower seek. */ + OMX_TIME_SeekModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_SeekModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_SeekModeMax = 0x7FFFFFFF +} OMX_TIME_SEEKMODETYPE; + +/* Structure representing the seekmode of the component */ +typedef struct OMX_TIME_CONFIG_SEEKMODETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_TIME_SEEKMODETYPE eType; /**< The seek mode */ +} OMX_TIME_CONFIG_SEEKMODETYPE; + +/** Structure representing a time stamp used with the following configs + * on the Clock Component (CC): + * + * OMX_IndexConfigTimeCurrentWallTime: query of the CC’s current wall + * time + * OMX_IndexConfigTimeCurrentMediaTime: query of the CC’s current media + * time + * OMX_IndexConfigTimeCurrentAudioReference and + * OMX_IndexConfigTimeCurrentVideoReference: audio/video reference + * clock sending SC its reference time + * OMX_IndexConfigTimeClientStartTime: a Clock Component client sends + * this structure to the Clock Component via a SetConfig on its + * client port when it receives a buffer with + * OMX_BUFFERFLAG_STARTTIME set. It must use the timestamp + * specified by that buffer for nStartTimestamp. + * + * It’s also used with the following config on components in general: + * + * OMX_IndexConfigTimePosition: IL client querying component position + * (GetConfig) or commanding a component to seek to the given location + * (SetConfig) + */ +typedef struct OMX_TIME_CONFIG_TIMESTAMPTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version + * information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_TICKS nTimestamp; /**< timestamp .*/ +} OMX_TIME_CONFIG_TIMESTAMPTYPE; + +/** Enumeration of possible reference clocks to the media time. */ +typedef enum OMX_TIME_UPDATETYPE { + OMX_TIME_UpdateRequestFulfillment, /**< Update is the fulfillment of a media time request. */ + OMX_TIME_UpdateScaleChanged, /**< Update was generated because the scale chagned. */ + OMX_TIME_UpdateClockStateChanged, /**< Update was generated because the clock state changed. */ + OMX_TIME_UpdateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_UpdateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_UpdateMax = 0x7FFFFFFF +} OMX_TIME_UPDATETYPE; + +/** Enumeration of possible reference clocks to the media time. */ +typedef enum OMX_TIME_REFCLOCKTYPE { + OMX_TIME_RefClockNone, /**< Use no references. */ + OMX_TIME_RefClockAudio, /**< Use references sent through OMX_IndexConfigTimeCurrentAudioReference */ + OMX_TIME_RefClockVideo, /**< Use references sent through OMX_IndexConfigTimeCurrentVideoReference */ + OMX_TIME_RefClockKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_RefClockVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_RefClockMax = 0x7FFFFFFF +} OMX_TIME_REFCLOCKTYPE; + +/** Enumeration of clock states. */ +typedef enum OMX_TIME_CLOCKSTATE { + OMX_TIME_ClockStateRunning, /**< Clock running. */ + OMX_TIME_ClockStateWaitingForStartTime, /**< Clock waiting until the + * prescribed clients emit their + * start time. */ + OMX_TIME_ClockStateStopped, /**< Clock stopped. */ + OMX_TIME_ClockStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_ClockStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_ClockStateMax = 0x7FFFFFFF +} OMX_TIME_CLOCKSTATE; + +/** Structure representing a media time request to the clock component. + * + * A client component sends this structure to the Clock Component via a SetConfig + * on its client port to specify a media timestamp the Clock Component + * should emit. The Clock Component should fulfill the request by sending a + * OMX_TIME_MEDIATIMETYPE when its media clock matches the requested + * timestamp. + * + * The client may require a media time request be fulfilled slightly + * earlier than the media time specified. In this case the client specifies + * an offset which is equal to the difference between wall time corresponding + * to the requested media time and the wall time when it will be + * fulfilled. + * + * A client component may uses these requests and the OMX_TIME_MEDIATIMETYPE to + * time events according to timestamps. If a client must perform an operation O at + * a time T (e.g. deliver a video frame at its corresponding timestamp), it makes a + * media time request at T (perhaps specifying an offset to ensure the request fulfillment + * is a little early). When the clock component passes the resulting OMX_TIME_MEDIATIMETYPE + * structure back to the client component, the client may perform operation O (perhaps having + * to wait a slight amount more time itself as specified by the return values). + */ + +typedef struct OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_PTR pClientPrivate; /**< Client private data to disabiguate this media time + * from others (e.g. the number of the frame to deliver). + * Duplicated in the media time structure that fulfills + * this request. A value of zero is reserved for time scale + * updates. */ + OMX_TICKS nMediaTimestamp; /**< Media timestamp requested.*/ + OMX_TICKS nOffset; /**< Amount of wall clock time by which this + * request should be fulfilled early */ +} OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE; + +/**< Structure sent from the clock component client either when fulfilling + * a media time request or when the time scale has changed. + * + * In the former case the Clock Component fills this structure and times its emission + * to a client component (via the client port) according to the corresponding media + * time request sent by the client. The Clock Component should time the emission to occur + * when the requested timestamp matches the Clock Component's media time but also the + * prescribed offset early. + * + * Upon scale changes the clock component clears the nClientPrivate data, sends the current + * media time and sets the nScale to the new scale via the client port. It emits a + * OMX_TIME_MEDIATIMETYPE to all clients independent of any requests. This allows clients to + * alter processing to accomodate scaling. For instance a video component might skip inter-frames + * in the case of extreme fastforward. Likewise an audio component might add or remove samples + * from an audio frame to scale audio data. + * + * It is expected that some clock components may not be able to fulfill requests + * at exactly the prescribed time. This is acceptable so long as the request is + * fulfilled at least as early as described and not later. This structure provides + * fields the client may use to wait for the remaining time. + * + * The client may use either the nOffset or nWallTimeAtMedia fields to determine the + * wall time until the nMediaTimestamp actually occurs. In the latter case the + * client can get a more accurate value for offset by getting the current wall + * from the cloc component and subtracting it from nWallTimeAtMedia. + */ + +typedef struct OMX_TIME_MEDIATIMETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nClientPrivate; /**< Client private data to disabiguate this media time + * from others. Copied from the media time request. + * A value of zero is reserved for time scale updates. */ + OMX_TIME_UPDATETYPE eUpdateType; /**< Reason for the update */ + OMX_TICKS nMediaTimestamp; /**< Media time requested. If no media time was + * requested then this is the current media time. */ + OMX_TICKS nOffset; /**< Amount of wall clock time by which this + * request was actually fulfilled early */ + + OMX_TICKS nWallTimeAtMediaTime; /**< Wall time corresponding to nMediaTimeStamp. + * A client may compare this value to current + * media time obtained from the Clock Component to determine + * the wall time until the media timestamp is really + * current. */ + OMX_S32 xScale; /**< Current media time scale in Q16 format. */ + OMX_TIME_CLOCKSTATE eState; /* Seeking Change. Added 7/12.*/ + /**< State of the media time. */ +} OMX_TIME_MEDIATIMETYPE; + +/** Structure representing the current media time scale factor. Applicable only to clock + * component, other components see scale changes via OMX_TIME_MEDIATIMETYPE buffers sent via + * the clock component client ports. Upon recieving this config the clock component changes + * the rate by which the media time increases or decreases effectively implementing trick modes. + */ +typedef struct OMX_TIME_CONFIG_SCALETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_S32 xScale; /**< This is a value in Q16 format which is used for + * scaling the media time */ +} OMX_TIME_CONFIG_SCALETYPE; + +/** Bits used to identify a clock port. Used in OMX_TIME_CONFIG_CLOCKSTATETYPE’s nWaitMask field */ +#define OMX_CLOCKPORT0 0x00000001 +#define OMX_CLOCKPORT1 0x00000002 +#define OMX_CLOCKPORT2 0x00000004 +#define OMX_CLOCKPORT3 0x00000008 +#define OMX_CLOCKPORT4 0x00000010 +#define OMX_CLOCKPORT5 0x00000020 +#define OMX_CLOCKPORT6 0x00000040 +#define OMX_CLOCKPORT7 0x00000080 + +/** Structure representing the current mode of the media clock. + * IL Client uses this config to change or query the mode of the + * media clock of the clock component. Applicable only to clock + * component. + * + * On a SetConfig if eState is OMX_TIME_ClockStateRunning media time + * starts immediately at the prescribed start time. If + * OMX_TIME_ClockStateWaitingForStartTime the Clock Component ignores + * the given nStartTime and waits for all clients specified in the + * nWaitMask to send starttimes (via + * OMX_IndexConfigTimeClientStartTime). The Clock Component then starts + * the media clock using the earliest start time supplied. */ +typedef struct OMX_TIME_CONFIG_CLOCKSTATETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version + * information */ + OMX_TIME_CLOCKSTATE eState; /**< State of the media time. */ + OMX_TICKS nStartTime; /**< Start time of the media time. */ + OMX_TICKS nOffset; /**< Time to offset the media time by + * (e.g. preroll). Media time will be + * reported to be nOffset ticks earlier. + */ + OMX_U32 nWaitMask; /**< Mask of OMX_CLOCKPORT values. */ +} OMX_TIME_CONFIG_CLOCKSTATETYPE; + +/** Structure representing the reference clock currently being used to + * compute media time. IL client uses this config to change or query the + * clock component's active reference clock */ +typedef struct OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_TIME_REFCLOCKTYPE eClock; /**< Reference clock used to compute media time */ +} OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE; + +/** Descriptor for setting specifics of power type. + * Note: this structure is listed for backwards compatibility. */ +typedef struct OMX_OTHER_CONFIG_POWERTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_BOOL bEnablePM; /**< Flag to enable Power Management */ +} OMX_OTHER_CONFIG_POWERTYPE; + + +/** Descriptor for setting specifics of stats type. + * Note: this structure is listed for backwards compatibility. */ +typedef struct OMX_OTHER_CONFIG_STATSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + /* what goes here */ +} OMX_OTHER_CONFIG_STATSTYPE; + + +/** + * The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output other + * path. + */ +typedef struct OMX_OTHER_PORTDEFINITIONTYPE { + OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */ +} OMX_OTHER_PORTDEFINITIONTYPE; + +/** Port format parameter. This structure is used to enumerate + * the various data input/output format supported by the port. + */ +typedef struct OMX_OTHER_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Indicates which port to set */ + OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */ + OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */ +} OMX_OTHER_PARAM_PORTFORMATTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/phonelibs/openmax/include/OMX_QCOMExtns.h b/phonelibs/openmax/include/OMX_QCOMExtns.h new file mode 100644 index 00000000000000..20917932be1b15 --- /dev/null +++ b/phonelibs/openmax/include/OMX_QCOMExtns.h @@ -0,0 +1,1888 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2009-2015, The Linux Foundation. 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 Linux Foundation 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, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT 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. +--------------------------------------------------------------------------*/ +#ifndef __OMX_QCOM_EXTENSIONS_H__ +#define __OMX_QCOM_EXTENSIONS_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*============================================================================ +*//** @file OMX_QCOMExtns.h + This header contains constants and type definitions that specify the + extensions added to the OpenMAX Vendor specific APIs. + +*//*========================================================================*/ + + +/////////////////////////////////////////////////////////////////////////////// +// Include Files +/////////////////////////////////////////////////////////////////////////////// +#include "OMX_Core.h" +#include "OMX_Video.h" + +#define OMX_VIDEO_MAX_HP_LAYERS 6 +/** + * This extension is used to register mapping of a virtual + * address to a physical address. This extension is a parameter + * which can be set using the OMX_SetParameter macro. The data + * pointer corresponding to this extension is + * OMX_QCOM_MemMapEntry. This parameter is a 'write only' + * parameter (Current value cannot be queried using + * OMX_GetParameter macro). + */ +#define OMX_QCOM_EXTN_REGISTER_MMAP "OMX.QCOM.index.param.register_mmap" + +/** + * This structure describes the data pointer corresponding to + * the OMX_QCOM_MMAP_REGISTER_EXTN extension. This parameter + * must be set only 'after' populating a port with a buffer + * using OMX_UseBuffer, wherein the data pointer of the buffer + * corresponds to the virtual address as specified in this + * structure. + */ +struct OMX_QCOM_PARAM_MEMMAPENTRYTYPE +{ + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port number the structure applies to */ + + /** + * The virtual address of memory block + */ + OMX_U64 nVirtualAddress; + + /** + * The physical address corresponding to the virtual address. The physical + * address is contiguous for the entire valid range of the virtual + * address. + */ + OMX_U64 nPhysicalAddress; +}; + +#define QOMX_VIDEO_IntraRefreshRandom (OMX_VIDEO_IntraRefreshVendorStartUnused + 0) + +/* This error event is used for H.264 long-term reference (LTR) encoding. + * When IL client specifies an LTR frame with its identifier via + * OMX_QCOM_INDEX_CONFIG_VIDEO_LTRUSE to the encoder, if the specified + * LTR frame can not be located by the encoder in its LTR list, the encoder + * issues this error event to IL client to notify the failure of LTRUse config. + */ +#define QOMX_ErrorLTRUseFailed (OMX_ErrorVendorStartUnused + 1) + +#define QOMX_VIDEO_BUFFERFLAG_BFRAME 0x00100000 + +#define QOMX_VIDEO_BUFFERFLAG_EOSEQ 0x00200000 + +#define QOMX_VIDEO_BUFFERFLAG_MBAFF 0x00400000 + +#define QOMX_VIDEO_BUFFERFLAG_CANCEL 0x00800000 + +#define OMX_QCOM_PORTDEFN_EXTN "OMX.QCOM.index.param.portdefn" +/* Allowed APIs on the above Index: OMX_GetParameter() and OMX_SetParameter() */ + +typedef enum OMX_QCOMMemoryRegion +{ + OMX_QCOM_MemRegionInvalid, + OMX_QCOM_MemRegionEBI1, + OMX_QCOM_MemRegionSMI, + OMX_QCOM_MemRegionMax = 0X7FFFFFFF +} OMX_QCOMMemoryRegion; + +typedef enum OMX_QCOMCacheAttr +{ + OMX_QCOM_CacheAttrNone, + OMX_QCOM_CacheAttrWriteBack, + OMX_QCOM_CacheAttrWriteThrough, + OMX_QCOM_CacheAttrMAX = 0X7FFFFFFF +} OMX_QCOMCacheAttr; + +typedef struct OMX_QCOMRectangle +{ + OMX_S32 x; + OMX_S32 y; + OMX_S32 dx; + OMX_S32 dy; +} OMX_QCOMRectangle; + +/** OMX_QCOMFramePackingFormat + * Input or output buffer format + */ +typedef enum OMX_QCOMFramePackingFormat +{ + /* 0 - unspecified + */ + OMX_QCOM_FramePacking_Unspecified, + + /* 1 - Partial frames may be present OMX IL 1.1.1 Figure 2-10: + * Case 1??Each Buffer Filled In Whole or In Part + */ + OMX_QCOM_FramePacking_Arbitrary, + + /* 2 - Multiple complete frames per buffer (integer number) + * OMX IL 1.1.1 Figure 2-11: Case 2—Each Buffer Filled with + * Only Complete Frames of Data + */ + OMX_QCOM_FramePacking_CompleteFrames, + + /* 3 - Only one complete frame per buffer, no partial frame + * OMX IL 1.1.1 Figure 2-12: Case 3—Each Buffer Filled with + * Only One Frame of Compressed Data. Usually at least one + * complete unit of data will be delivered in a buffer for + * uncompressed data formats. + */ + OMX_QCOM_FramePacking_OnlyOneCompleteFrame, + + /* 4 - Only one complete subframe per buffer, no partial subframe + * Example: In H264, one complete NAL per buffer, where one frame + * can contatin multiple NAL + */ + OMX_QCOM_FramePacking_OnlyOneCompleteSubFrame, + + OMX_QCOM_FramePacking_MAX = 0X7FFFFFFF +} OMX_QCOMFramePackingFormat; + +typedef struct OMX_QCOM_PARAM_PORTDEFINITIONTYPE { + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion;/** OMX specification version information */ + OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ + + /** Platform specific memory region EBI1, SMI, etc.,*/ + OMX_QCOMMemoryRegion nMemRegion; + + OMX_QCOMCacheAttr nCacheAttr; /** Cache attributes */ + + /** Input or output buffer format */ + OMX_U32 nFramePackingFormat; + +} OMX_QCOM_PARAM_PORTDEFINITIONTYPE; + +typedef struct OMX_QCOM_VIDEO_PARAM_QPRANGETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 minQP; + OMX_U32 maxQP; +} OMX_QCOM_VIDEO_PARAM_QPRANGETYPE; + +#define OMX_QCOM_PLATFORMPVT_EXTN "OMX.QCOM.index.param.platformprivate" +/** Allowed APIs on the above Index: OMX_SetParameter() */ + +typedef enum OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE +{ + /** Enum for PMEM information */ + OMX_QCOM_PLATFORM_PRIVATE_PMEM = 0x1 +} OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE; + +/** IL client will set the following structure. A failure + * code will be returned if component does not support the + * value provided for 'type'. + */ +struct OMX_QCOM_PLATFORMPRIVATE_EXTN +{ + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /** OMX spec version information */ + OMX_U32 nPortIndex; /** Port number on which usebuffer extn is applied */ + + /** Type of extensions should match an entry from + OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE + */ + OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE type; +}; + +typedef struct OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO +{ + /** pmem file descriptor */ + unsigned long pmem_fd; + /** Offset from pmem device base address */ + OMX_U32 offset; + OMX_U32 size; + OMX_U32 mapped_size; + OMX_PTR buffer; +}OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO; + +typedef struct OMX_QCOM_PLATFORM_PRIVATE_ENTRY +{ + /** Entry type */ + OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE type; + + /** Pointer to platform specific entry */ + OMX_PTR entry; +}OMX_QCOM_PLATFORM_PRIVATE_ENTRY; + +typedef struct OMX_QCOM_PLATFORM_PRIVATE_LIST +{ + /** Number of entries */ + OMX_U32 nEntries; + + /** Pointer to array of platform specific entries * + * Contiguous block of OMX_QCOM_PLATFORM_PRIVATE_ENTRY element + */ + OMX_QCOM_PLATFORM_PRIVATE_ENTRY* entryList; +}OMX_QCOM_PLATFORM_PRIVATE_LIST; + +#define OMX_QCOM_FRAME_PACKING_FORMAT "OMX.QCOM.index.param.framepackfmt" +/* Allowed API call: OMX_GetParameter() */ +/* IL client can use this index to rerieve the list of frame formats * + * supported by the component */ + +typedef struct OMX_QCOM_FRAME_PACKINGFORMAT_TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nIndex; + OMX_QCOMFramePackingFormat eframePackingFormat; +} OMX_QCOM_FRAME_PACKINGFORMAT_TYPE; + + +/** + * Following is the enum for color formats supported on Qualcomm + * MSMs YVU420SemiPlanar color format is not defined in OpenMAX + * 1.1.1 and prior versions of OpenMAX specification. + */ + +enum OMX_QCOM_COLOR_FORMATTYPE +{ + +/** YVU420SemiPlanar: YVU planar format, organized with a first + * plane containing Y pixels, and a second plane containing + * interleaved V and U pixels. V and U pixels are sub-sampled + * by a factor of two both horizontally and vertically. + */ + QOMX_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00, + QOMX_COLOR_FormatYVU420PackedSemiPlanar32m4ka, + QOMX_COLOR_FormatYUV420PackedSemiPlanar16m2ka, + QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka, + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m, + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView, + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed, + QOMX_COLOR_Format32bitRGBA8888, + QOMX_COLOR_Format32bitRGBA8888Compressed, + QOMX_COLOR_FormatAndroidOpaque = (OMX_COLOR_FORMATTYPE) OMX_COLOR_FormatVendorStartUnused + 0x789, +}; + +enum OMX_QCOM_VIDEO_CODINGTYPE +{ +/** Codecs support by qualcomm which are not listed in OMX 1.1.x + * spec + * */ + OMX_QCOM_VIDEO_CodingVC1 = 0x7FA30C00 , + OMX_QCOM_VIDEO_CodingWMV9 = 0x7FA30C01, + QOMX_VIDEO_CodingDivx = 0x7FA30C02, /**< Value when coding is Divx */ + QOMX_VIDEO_CodingSpark = 0x7FA30C03, /**< Value when coding is Sorenson Spark */ + QOMX_VIDEO_CodingVp = 0x7FA30C04, + QOMX_VIDEO_CodingVp8 = OMX_VIDEO_CodingVP8, /**< keeping old enum for backwards compatibility*/ + QOMX_VIDEO_CodingHevc = OMX_VIDEO_CodingHEVC, /**< keeping old enum for backwards compatibility*/ + QOMX_VIDEO_CodingMVC = 0x7FA30C07, + QOMX_VIDEO_CodingVp9 = OMX_VIDEO_CodingVP9, /**< keeping old enum for backwards compatibility*/ +}; + +enum OMX_QCOM_EXTN_INDEXTYPE +{ + /** Qcom proprietary extension index list */ + + /* "OMX.QCOM.index.param.register_mmap" */ + OMX_QcomIndexRegmmap = 0x7F000000, + + /* "OMX.QCOM.index.param.platformprivate" */ + OMX_QcomIndexPlatformPvt = 0x7F000001, + + /* "OMX.QCOM.index.param.portdefn" */ + OMX_QcomIndexPortDefn = 0x7F000002, + + /* "OMX.QCOM.index.param.framepackingformat" */ + OMX_QcomIndexPortFramePackFmt = 0x7F000003, + + /*"OMX.QCOM.index.param.Interlaced */ + OMX_QcomIndexParamInterlaced = 0x7F000004, + + /*"OMX.QCOM.index.config.interlaceformat */ + OMX_QcomIndexConfigInterlaced = 0x7F000005, + + /*"OMX.QCOM.index.param.syntaxhdr" */ + QOMX_IndexParamVideoSyntaxHdr = 0x7F000006, + + /*"OMX.QCOM.index.config.intraperiod" */ + QOMX_IndexConfigVideoIntraperiod = 0x7F000007, + + /*"OMX.QCOM.index.config.randomIntrarefresh" */ + QOMX_IndexConfigVideoIntraRefresh = 0x7F000008, + + /*"OMX.QCOM.index.config.video.TemporalSpatialTradeOff" */ + QOMX_IndexConfigVideoTemporalSpatialTradeOff = 0x7F000009, + + /*"OMX.QCOM.index.param.video.EncoderMode" */ + QOMX_IndexParamVideoEncoderMode = 0x7F00000A, + + /*"OMX.QCOM.index.param.Divxtype */ + OMX_QcomIndexParamVideoDivx = 0x7F00000B, + + /*"OMX.QCOM.index.param.Sparktype */ + OMX_QcomIndexParamVideoSpark = 0x7F00000C, + + /*"OMX.QCOM.index.param.Vptype */ + OMX_QcomIndexParamVideoVp = 0x7F00000D, + + OMX_QcomIndexQueryNumberOfVideoDecInstance = 0x7F00000E, + + OMX_QcomIndexParamVideoSyncFrameDecodingMode = 0x7F00000F, + + OMX_QcomIndexParamVideoDecoderPictureOrder = 0x7F000010, + + /* "OMX.QCOM.index.config.video.FramePackingInfo" */ + OMX_QcomIndexConfigVideoFramePackingArrangement = 0x7F000011, + + OMX_QcomIndexParamConcealMBMapExtraData = 0x7F000012, + + OMX_QcomIndexParamFrameInfoExtraData = 0x7F000013, + + OMX_QcomIndexParamInterlaceExtraData = 0x7F000014, + + OMX_QcomIndexParamH264TimeInfo = 0x7F000015, + + OMX_QcomIndexParamIndexExtraDataType = 0x7F000016, + + OMX_GoogleAndroidIndexEnableAndroidNativeBuffers = 0x7F000017, + + OMX_GoogleAndroidIndexUseAndroidNativeBuffer = 0x7F000018, + + OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage = 0x7F000019, + + /*"OMX.QCOM.index.config.video.QPRange" */ + OMX_QcomIndexConfigVideoQPRange = 0x7F00001A, + + /*"OMX.QCOM.index.param.EnableTimeStampReoder"*/ + OMX_QcomIndexParamEnableTimeStampReorder = 0x7F00001B, + + /*"OMX.google.android.index.storeMetaDataInBuffers"*/ + OMX_QcomIndexParamVideoMetaBufferMode = 0x7F00001C, + + /*"OMX.google.android.index.useAndroidNativeBuffer2"*/ + OMX_GoogleAndroidIndexUseAndroidNativeBuffer2 = 0x7F00001D, + + /*"OMX.QCOM.index.param.VideoMaxAllowedBitrateCheck"*/ + OMX_QcomIndexParamVideoMaxAllowedBitrateCheck = 0x7F00001E, + + OMX_QcomIndexEnableSliceDeliveryMode = 0x7F00001F, + + /* "OMX.QCOM.index.param.video.ExtnUserExtraData" */ + OMX_QcomIndexEnableExtnUserData = 0x7F000020, + + /*"OMX.QCOM.index.param.video.EnableSmoothStreaming"*/ + OMX_QcomIndexParamEnableSmoothStreaming = 0x7F000021, + + /*"OMX.QCOM.index.param.video.QPRange" */ + OMX_QcomIndexParamVideoQPRange = 0x7F000022, + + OMX_QcomIndexEnableH263PlusPType = 0x7F000023, + + /*"OMX.QCOM.index.param.video.LTRCountRangeSupported"*/ + QOMX_IndexParamVideoLTRCountRangeSupported = 0x7F000024, + + /*"OMX.QCOM.index.param.video.LTRMode"*/ + QOMX_IndexParamVideoLTRMode = 0x7F000025, + + /*"OMX.QCOM.index.param.video.LTRCount"*/ + QOMX_IndexParamVideoLTRCount = 0x7F000026, + + /*"OMX.QCOM.index.config.video.LTRPeriod"*/ + QOMX_IndexConfigVideoLTRPeriod = 0x7F000027, + + /*"OMX.QCOM.index.config.video.LTRUse"*/ + QOMX_IndexConfigVideoLTRUse = 0x7F000028, + + /*"OMX.QCOM.index.config.video.LTRMark"*/ + QOMX_IndexConfigVideoLTRMark = 0x7F000029, + + /* OMX.google.android.index.prependSPSPPSToIDRFrames */ + OMX_QcomIndexParamSequenceHeaderWithIDR = 0x7F00002A, + + OMX_QcomIndexParamH264AUDelimiter = 0x7F00002B, + + OMX_QcomIndexParamVideoDownScalar = 0x7F00002C, + + /* "OMX.QCOM.index.param.video.FramePackingExtradata" */ + OMX_QcomIndexParamVideoFramePackingExtradata = 0x7F00002D, + + /* "OMX.QCOM.index.config.activeregiondetection" */ + OMX_QcomIndexConfigActiveRegionDetection = 0x7F00002E, + + /* "OMX.QCOM.index.config.activeregiondetectionstatus" */ + OMX_QcomIndexConfigActiveRegionDetectionStatus = 0x7F00002F, + + /* "OMX.QCOM.index.config.scalingmode" */ + OMX_QcomIndexConfigScalingMode = 0x7F000030, + + /* "OMX.QCOM.index.config.noisereduction" */ + OMX_QcomIndexConfigNoiseReduction = 0x7F000031, + + /* "OMX.QCOM.index.config.imageenhancement" */ + OMX_QcomIndexConfigImageEnhancement = 0x7F000032, + + /* google smooth-streaming support */ + OMX_QcomIndexParamVideoAdaptivePlaybackMode = 0x7F000033, + + /* H.264 MVC codec index */ + QOMX_IndexParamVideoMvc = 0x7F000034, + + /* "OMX.QCOM.index.param.video.QPExtradata" */ + OMX_QcomIndexParamVideoQPExtraData = 0x7F000035, + + /* "OMX.QCOM.index.param.video.InputBitsInfoExtradata" */ + OMX_QcomIndexParamVideoInputBitsInfoExtraData = 0x7F000036, + + /* VP8 Hierarchical P support */ + OMX_QcomIndexHierarchicalStructure = 0x7F000037, + + OMX_QcomIndexParamPerfLevel = 0x7F000038, + + OMX_QcomIndexParamH264VUITimingInfo = 0x7F000039, + + OMX_QcomIndexParamPeakBitrate = 0x7F00003A, + + /* Enable InitialQP index */ + QOMX_IndexParamVideoInitialQp = 0x7F00003B, + + OMX_QcomIndexParamSetMVSearchrange = 0x7F00003C, + + OMX_QcomIndexConfigPerfLevel = 0x7F00003D, + + /*"OMX.QCOM.index.param.video.LTRCount"*/ + OMX_QcomIndexParamVideoLTRCount = QOMX_IndexParamVideoLTRCount, + + /*"OMX.QCOM.index.config.video.LTRUse"*/ + OMX_QcomIndexConfigVideoLTRUse = QOMX_IndexConfigVideoLTRUse, + + /*"OMX.QCOM.index.config.video.LTRMark"*/ + OMX_QcomIndexConfigVideoLTRMark = QOMX_IndexConfigVideoLTRMark, + + /*"OMX.QCOM.index.param.video.CustomBufferSize"*/ + OMX_QcomIndexParamVideoCustomBufferSize = 0x7F00003E, + + /* Max Hierarchical P layers */ + OMX_QcomIndexMaxHierarchicallayers = 0x7F000041, + + /* Set Encoder Performance Index */ + OMX_QcomIndexConfigVideoVencPerfMode = 0x7F000042, + + /* Set Hybrid Hier-p layers */ + OMX_QcomIndexParamVideoHybridHierpMode = 0x7F000043, + + OMX_QcomIndexFlexibleYUVDescription = 0x7F000044, + + /* Vpp Hqv Control Type */ + OMX_QcomIndexParamVppHqvControl = 0x7F000045, + + /* Enable VPP */ + OMX_QcomIndexParamEnableVpp = 0x7F000046, + + /* MBI statistics mode */ + OMX_QcomIndexParamMBIStatisticsMode = 0x7F000047, + + /* Set PictureTypeDecode */ + OMX_QcomIndexConfigPictureTypeDecode = 0x7F000048, + + OMX_QcomIndexConfigH264EntropyCodingCabac = 0x7F000049, + + /* "OMX.QCOM.index.param.video.InputBatch" */ + OMX_QcomIndexParamBatchSize = 0x7F00004A, + + OMX_QcomIndexConfigNumHierPLayers = 0x7F00004B, + + OMX_QcomIndexConfigRectType = 0x7F00004C, + + OMX_QcomIndexConfigBaseLayerId = 0x7F00004E, + + OMX_QcomIndexParamDriverVersion = 0x7F00004F, + + OMX_QcomIndexConfigQp = 0x7F000050, + + OMX_QcomIndexParamVencAspectRatio = 0x7F000051, + + OMX_QTIIndexParamVQZipSEIExtraData = 0x7F000052, + + /* Enable VQZIP SEI NAL type */ + OMX_QTIIndexParamVQZIPSEIType = 0x7F000053, + + OMX_QTIIndexParamPassInputBufferFd = 0x7F000054, + + /* Set Prefer-adaptive playback*/ + /* "OMX.QTI.index.param.video.PreferAdaptivePlayback" */ + OMX_QTIIndexParamVideoPreferAdaptivePlayback = 0x7F000055, + + /* Set time params */ + OMX_QTIIndexConfigSetTimeData = 0x7F000056, + /* Force Compressed format for DPB when resolution <=1080p + * and OPB is cpu_access */ + /* OMX.QTI.index.param.video.ForceCompressedForDPB */ + OMX_QTIIndexParamForceCompressedForDPB = 0x7F000057, + + /* Enable ROI info */ + OMX_QTIIndexParamVideoEnableRoiInfo = 0x7F000058, + + /* Configure ROI info */ + OMX_QTIIndexConfigVideoRoiInfo = 0x7F000059, + + /* Set Low Latency Mode */ + OMX_QTIIndexParamLowLatencyMode = 0x7F00005A, + + /* Force OPB to UnCompressed mode */ + OMX_QTIIndexParamForceUnCompressedForOPB = 0x7F00005B, + +}; + +/** +* This is custom extension to configure Low Latency Mode. +* +* STRUCT MEMBERS +* +* nSize : Size of Structure in bytes +* nVersion : OpenMAX IL specification version information +* bLowLatencyMode : Enable/Disable Low Latency mode +*/ + +typedef struct QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bLowLatencyMode; +} QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE; + +/** +* This is custom extension to configure Encoder Aspect Ratio. +* +* STRUCT MEMBERS +* +* nSize : Size of Structure in bytes +* nVersion : OpenMAX IL specification version information +* nSARWidth : Horizontal aspect size +* nSARHeight : Vertical aspect size +*/ + +typedef struct QOMX_EXTNINDEX_VIDEO_VENC_SAR +{ + OMX_U32 nSize; + OMX_U32 nVersion; + OMX_U32 nSARWidth; + OMX_U32 nSARHeight; +} QOMX_EXTNINDEX_VIDEO_VENC_SAR; + +/** +* This is custom extension to configure Hier-p layers. +* This mode configures Hier-p layers dynamically. +* +* STRUCT MEMBERS +* +* nSize : Size of Structure in bytes +* nVersion : OpenMAX IL specification version information +* nNumHierLayers: Set the number of Hier-p layers for the session +* - This should be less than the MAX Hier-P +* layers set for the session. +*/ + +typedef struct QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nNumHierLayers; +} QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS; + + +/** +* This is custom extension to configure Hybrid Hier-p settings. +* This mode is different from enabling Hier-p mode. This +* property enables Hier-p encoding with LTR referencing in each +* sub-GOP. +* +* STRUCT MEMBERS +* +* nSize : Size of Structure in bytes +* nVersion : OpenMAX IL specification version information +* nKeyFrameInterval : Indicates the I frame interval +* nHpLayers : Set the number of Hier-p layers for the session +* - This should be <= 6. (1 Base layer + +* 5 Enhancement layers) +* nTemporalLayerBitrateRatio[OMX_VIDEO_MAX_HP_LAYERS] : Bitrate to +* be set for each enhancement layer +* nMinQuantizer : minimum session QP +* nMaxQuantizer : Maximun session QP +*/ + +typedef struct QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nKeyFrameInterval; + OMX_U32 nTemporalLayerBitrateRatio[OMX_VIDEO_MAX_HP_LAYERS]; + OMX_U32 nMinQuantizer; + OMX_U32 nMaxQuantizer; + OMX_U32 nHpLayers; +} QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE; + +/** + * Encoder Performance Mode. This structure is used to set + * performance mode or power save mode when encoding. The search + * range is modified to save power or improve quality. + * + * STRUCT MEMBERS: + * OMX_U32 nPerfMode : Performance mode: + * 1: MAX_QUALITY + * 2: POWER_SAVE + */ + +typedef struct QOMX_EXTNINDEX_VIDEO_PERFMODE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPerfMode; +} QOMX_EXTNINDEX_VIDEO_PERFMODE; + +/** + * Initial QP parameter. This structure is used to enable + * vendor specific extension to let client enable setting + * initial QP values to I P B Frames + * + * STRUCT MEMBERS: + * nSize : Size of Structure in bytes + * nVersion : OpenMAX IL specification version information + * nPortIndex : Index of the port to which this structure applies + * OMX_U32 nQpI : First Iframe QP + * OMX_U32 nQpP : First Pframe QP + * OMX_U32 nQpB : First Bframe QP + * OMX_U32 bEnableInitQp : Bit field indicating which frame type(s) shall + * use the specified initial QP. + * Bit 0: Enable initial QP for I/IDR + * and use value specified in nInitQpI + * Bit 1: Enable initial QP for P + * and use value specified in nInitQpP + * Bit 2: Enable initial QP for B + * and use value specified in nInitQpB + */ + +typedef struct QOMX_EXTNINDEX_VIDEO_INITIALQP { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nQpI; + OMX_U32 nQpP; + OMX_U32 nQpB; + OMX_U32 bEnableInitQp; +} QOMX_EXTNINDEX_VIDEO_INITIALQP; + +/** + * Extension index parameter. This structure is used to enable + * vendor specific extension on input/output port and + * to pass the required flags and data, if any. + * The format of flags and data being passed is known to + * the client and component apriori. + * + * STRUCT MEMBERS: + * nSize : Size of Structure plus pData size + * nVersion : OMX specification version information + * nPortIndex : Indicates which port to set + * bEnable : Extension index enable (1) or disable (0) + * nFlags : Extension index flags, if any + * nDataSize : Size of the extension index data to follow + * pData : Extension index data, if present. + */ +typedef struct QOMX_EXTNINDEX_PARAMTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnable; + OMX_U32 nFlags; + OMX_U32 nDataSize; + OMX_PTR pData; +} QOMX_EXTNINDEX_PARAMTYPE; + +/** + * Range index parameter. This structure is used to enable + * vendor specific extension on input/output port and + * to pass the required minimum and maximum values + * + * STRUCT MEMBERS: + * nSize : Size of Structure in bytes + * nVersion : OpenMAX IL specification version information + * nPortIndex : Index of the port to which this structure applies + * nMin : Minimum value + * nMax : Maximum value + * nSteSize : Step size + */ +typedef struct QOMX_EXTNINDEX_RANGETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nMin; + OMX_S32 nMax; + OMX_S32 nStepSize; +} QOMX_EXTNINDEX_RANGETYPE; + +/** + * Specifies LTR mode types. + */ +typedef enum QOMX_VIDEO_LTRMODETYPE +{ + QOMX_VIDEO_LTRMode_Disable = 0x0, /**< LTR encoding is disabled */ + QOMX_VIDEO_LTRMode_Manual = 0x1, /**< In this mode, IL client configures + ** the encoder the LTR count and manually + ** controls the marking and use of LTR + ** frames during video encoding. + */ + QOMX_VIDEO_LTRMode_Auto = 0x2, /**< In this mode, IL client configures + ** the encoder the LTR count and LTR + ** period. The encoder marks LTR frames + ** automatically based on the LTR period + ** during video encoding. IL client controls + ** the use of LTR frames. + */ + QOMX_VIDEO_LTRMode_MAX = 0x7FFFFFFF /** Maximum LTR Mode type */ +} QOMX_VIDEO_LTRMODETYPE; + +/** + * LTR mode index parameter. This structure is used + * to enable vendor specific extension on output port + * to pass the LTR mode information. + * + * STRUCT MEMBERS: + * nSize : Size of Structure in bytes + * nVersion : OpenMAX IL specification version information + * nPortIndex : Index of the port to which this structure applies + * eLTRMode : Specifies the LTR mode used in encoder + */ +typedef struct QOMX_VIDEO_PARAM_LTRMODE_TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + QOMX_VIDEO_LTRMODETYPE eLTRMode; +} QOMX_VIDEO_PARAM_LTRMODE_TYPE; + +/** + * LTR count index parameter. This structure is used + * to enable vendor specific extension on output port + * to pass the LTR count information. + * + * STRUCT MEMBERS: + * nSize : Size of Structure in bytes + * nVersion : OpenMAX IL specification version information + * nPortIndex : Index of the port to which this structure applies + * nCount : Specifies the number of LTR frames stored in the + * encoder component + */ +typedef struct QOMX_VIDEO_PARAM_LTRCOUNT_TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nCount; +} QOMX_VIDEO_PARAM_LTRCOUNT_TYPE; + + +/** + * This should be used with OMX_QcomIndexParamVideoLTRCount extension. + */ +typedef QOMX_VIDEO_PARAM_LTRCOUNT_TYPE OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE; + +/** + * LTR period index parameter. This structure is used + * to enable vendor specific extension on output port + * to pass the LTR period information. + * + * STRUCT MEMBERS: + * nSize : Size of Structure in bytes + * nVersion : OpenMAX IL specification version information + * nPortIndex : Index of the port to which this structure applies + * nFrames : Specifies the number of frames between two consecutive + * LTR frames. + */ +typedef struct QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nFrames; +} QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE; + +/** + * Marks the next encoded frame as an LTR frame. + * STRUCT MEMBERS: + * nSize : Size of Structure in bytes + * nVersion : OpenMAX IL specification version information + * nPortIndex : Index of the port to which this structure applies + * nID : Specifies the identifier of the LTR frame to be marked + * as reference frame for encoding subsequent frames. + */ +typedef struct QOMX_VIDEO_CONFIG_LTRMARK_TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nID; +} QOMX_VIDEO_CONFIG_LTRMARK_TYPE; + +/** + * This should be used with OMX_QcomIndexConfigVideoLTRMark extension. + */ +typedef QOMX_VIDEO_CONFIG_LTRMARK_TYPE OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE; + +/** + * Specifies an LTR frame to encode subsequent frames. + * STRUCT MEMBERS: + * nSize : Size of Structure in bytes + * nVersion : OpenMAX IL specification version information + * nPortIndex : Index of the port to which this structure applies + * nID : Specifies the identifier of the LTR frame to be used + as reference frame for encoding subsequent frames. + * nFrames : Specifies the number of subsequent frames to be + encoded using the LTR frame with its identifier + nID as reference frame. Short-term reference frames + will be used thereafter. The value of 0xFFFFFFFF + indicates that all subsequent frames will be + encodedusing this LTR frame as reference frame. + */ +typedef struct QOMX_VIDEO_CONFIG_LTRUSE_TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nID; + OMX_U32 nFrames; +} QOMX_VIDEO_CONFIG_LTRUSE_TYPE; + +/** + * This should be used with OMX_QcomIndexConfigVideoLTRUse extension. + */ +typedef QOMX_VIDEO_CONFIG_LTRUSE_TYPE OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE; + +/** + * Enumeration used to define the video encoder modes + * + * ENUMS: + * EncoderModeDefault : Default video recording mode. + * All encoder settings made through + * OMX_SetParameter/OMX_SetConfig are applied. No + * parameter is overridden. + * EncoderModeMMS : Video recording mode for MMS (Multimedia Messaging + * Service). This mode is similar to EncoderModeDefault + * except that here the Rate control mode is overridden + * internally and set as a variant of variable bitrate with + * variable frame rate. After this mode is set if the IL + * client tries to set OMX_VIDEO_CONTROLRATETYPE via + * OMX_IndexParamVideoBitrate that would be rejected. For + * this, client should set mode back to EncoderModeDefault + * first and then change OMX_VIDEO_CONTROLRATETYPE. + */ +typedef enum QOMX_VIDEO_ENCODERMODETYPE +{ + QOMX_VIDEO_EncoderModeDefault = 0x00, + QOMX_VIDEO_EncoderModeMMS = 0x01, + QOMX_VIDEO_EncoderModeMax = 0x7FFFFFFF +} QOMX_VIDEO_ENCODERMODETYPE; + +/** + * This structure is used to set the video encoder mode. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version info + * nPortIndex : Port that this structure applies to + * nMode : defines the video encoder mode + */ +typedef struct QOMX_VIDEO_PARAM_ENCODERMODETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + QOMX_VIDEO_ENCODERMODETYPE nMode; +} QOMX_VIDEO_PARAM_ENCODERMODETYPE; + +/** + * This structure describes the parameters corresponding to the + * QOMX_VIDEO_SYNTAXHDRTYPE extension. This parameter can be queried + * during the loaded state. + */ + +typedef struct QOMX_VIDEO_SYNTAXHDRTYPE +{ + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion;/** OMX specification version information */ + OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ + OMX_U32 nBytes; /** The number of bytes filled in to the buffer */ + OMX_U8 data[1]; /** Buffer to store the header information */ +} QOMX_VIDEO_SYNTAXHDRTYPE; + +/** + * This structure describes the parameters corresponding to the + * QOMX_VIDEO_TEMPORALSPATIALTYPE extension. This parameter can be set + * dynamically during any state except the state invalid. This is primarily + * used for setting MaxQP from the application. This is set on the out port. + */ + +typedef struct QOMX_VIDEO_TEMPORALSPATIALTYPE +{ + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion;/** OMX specification version information */ + OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ + OMX_U32 nTSFactor; /** Temoral spatial tradeoff factor value in 0-100 */ +} QOMX_VIDEO_TEMPORALSPATIALTYPE; + +/** + * This structure describes the parameters corresponding to the + * OMX_QCOM_VIDEO_CONFIG_INTRAPERIODTYPE extension. This parameter can be set + * dynamically during any state except the state invalid. This is set on the out port. + */ + +typedef struct QOMX_VIDEO_INTRAPERIODTYPE +{ + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion;/** OMX specification version information */ + OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ + OMX_U32 nIDRPeriod; /** This specifies coding a frame as IDR after every nPFrames + of intra frames. If this parameter is set to 0, only the + first frame of the encode session is an IDR frame. This + field is ignored for non-AVC codecs and is used only for + codecs that support IDR Period */ + OMX_U32 nPFrames; /** The number of "P" frames between two "I" frames */ + OMX_U32 nBFrames; /** The number of "B" frames between two "I" frames */ +} QOMX_VIDEO_INTRAPERIODTYPE; + +/** + * This structure describes the parameters corresponding to the + * OMX_QCOM_VIDEO_CONFIG_ULBUFFEROCCUPANCYTYPE extension. This parameter can be set + * dynamically during any state except the state invalid. This is used for the buffer negotiation + * with other clients. This is set on the out port. + */ +typedef struct OMX_QCOM_VIDEO_CONFIG_ULBUFFEROCCUPANCYTYPE +{ + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /** OMX specification version information */ + OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ + OMX_U32 nBufferOccupancy; /** The number of bytes to be set for the buffer occupancy */ +} OMX_QCOM_VIDEO_CONFIG_ULBUFFEROCCUPANCYTYPE; + +/** + * This structure describes the parameters corresponding to the + * OMX_QCOM_VIDEO_CONFIG_RANDOMINTRAREFRESHTYPE extension. This parameter can be set + * dynamically during any state except the state invalid. This is primarily used for the dynamic/random + * intrarefresh. This is set on the out port. + */ +typedef struct OMX_QCOM_VIDEO_CONFIG_RANDOMINTRAREFRESHTYPE +{ + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion;/** OMX specification version information */ + OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ + OMX_U32 nRirMBs; /** The number of MBs to be set for intrarefresh */ +} OMX_QCOM_VIDEO_CONFIG_RANDOMINTRAREFRESHTYPE; + + +/** + * This structure describes the parameters corresponding to the + * OMX_QCOM_VIDEO_CONFIG_QPRANGE extension. This parameter can be set + * dynamically during any state except the state invalid. This is primarily + * used for the min/max QP to be set from the application. This + * is set on the out port. + */ +typedef struct OMX_QCOM_VIDEO_CONFIG_QPRANGE +{ + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion;/** OMX specification version information */ + OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ + OMX_U32 nMinQP; /** The number for minimum quantization parameter */ + OMX_U32 nMaxQP; /** The number for maximum quantization parameter */ +} OMX_QCOM_VIDEO_CONFIG_QPRANGE; + +/** + * This structure describes the parameters for the + * OMX_QcomIndexParamH264AUDelimiter extension. It enables/disables + * the AU delimiters in the H264 stream, which is used by WFD. + */ +typedef struct OMX_QCOM_VIDEO_CONFIG_H264_AUD +{ + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion;/** OMX specification version information */ + OMX_BOOL bEnable; /** Enable/disable the setting */ +} OMX_QCOM_VIDEO_CONFIG_H264_AUD; + +typedef enum QOMX_VIDEO_PERF_LEVEL +{ + OMX_QCOM_PerfLevelNominal, + OMX_QCOM_PerfLevelTurbo +} QOMX_VIDEO_PERF_LEVEL; + +/** + * This structure describes the parameters corresponding + * to OMX_QcomIndexParamPerfLevel extension. It will set + * the performance mode specified as QOMX_VIDEO_PERF_LEVEL. + */ +typedef struct OMX_QCOM_VIDEO_PARAM_PERF_LEVEL { + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /** OMX specification version information */ + QOMX_VIDEO_PERF_LEVEL ePerfLevel; /** Performance level */ +} OMX_QCOM_VIDEO_PARAM_PERF_LEVEL; + +/** + * This structure describes the parameters corresponding + * to OMX_QcomIndexConfigPerfLevel extension. It will set + * the performance mode specified as QOMX_VIDEO_PERF_LEVEL. + */ +typedef struct OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL { + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /** OMX specification version information */ + QOMX_VIDEO_PERF_LEVEL ePerfLevel; /** Performance level */ +} OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL; + +typedef enum QOMX_VIDEO_PICTURE_TYPE_DECODE +{ + OMX_QCOM_PictypeDecode_IPB, + OMX_QCOM_PictypeDecode_I +} QOMX_VIDEO_PICTURE_TYPE_DECODE; + +/** + * This structure describes the parameters corresponding + * to OMX_QcomIndexConfigPictureTypeDecode extension. It + * will set the picture type decode specified by eDecodeType. + */ +typedef struct OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE { + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /** OMX specification version information */ + QOMX_VIDEO_PICTURE_TYPE_DECODE eDecodeType; /** Decode type */ +} OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE; + +/** + * This structure describes the parameters corresponding + * to OMX_QcomIndexParamH264VUITimingInfo extension. It + * will enable/disable the VUI timing info. + */ +typedef struct OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO { + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /** OMX specification version information */ + OMX_BOOL bEnable; /** Enable/disable the setting */ +} OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO; + +/** + * This structure describes the parameters corresponding + * to OMX_QcomIndexParamVQZIPSEIType extension. It + * will enable/disable the VQZIP SEI info. + */ +typedef struct OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE { + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /** OMX specification version information */ + OMX_BOOL bEnable; /** Enable/disable the setting */ +} OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE; + +/** + * This structure describes the parameters corresponding + * to OMX_QcomIndexParamPeakBitrate extension. It will + * set the peak bitrate specified by nPeakBitrate. + */ +typedef struct OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE { + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /** OMX specification version information */ + OMX_U32 nPeakBitrate; /** Peak bitrate value */ +} OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE; + +/** + * This structure describes the parameters corresponding + * to OMX_QTIIndexParamForceCompressedForDPB extension. Enabling + * this extension will force the split mode DPB(compressed)/OPB(Linear) + * for all resolutions.On some chipsets preferred mode would be combined + * Linear for both DPB/OPB to save memory. For example on 8996 preferred mode + * would be combined linear for resolutions <= 1080p . + * Enabling this might save power but with the cost + * of increased memory i.e almost double the number on output YUV buffers. + */ +typedef struct OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE { + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /** OMX specification version information */ + OMX_BOOL bEnable; /** Enable/disable the setting */ +} OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE; + +/** + * This structure describes the parameters corresponding + * to OMX_QTIIndexParamForceUnCompressedForOPB extension. Enabling this + * extension will force the OPB to be linear for the current video session. + * If this property is not set, then the OPB will be set to linear or compressed + * based on resolution selected and/or if cpu access is requested on the + * OPB buffer. + */ +typedef struct OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE { + OMX_U32 nSize; /** Sizeo f the structure in bytes */ + OMX_VERSIONTYPE nVersion; /** OMX specification version information */ + OMX_BOOL bEnable; /** Enable/disable the setting */ +} OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE; + +typedef struct OMX_VENDOR_EXTRADATATYPE { + OMX_U32 nPortIndex; + OMX_U32 nDataSize; + OMX_U8 *pData; // cdata (codec_data/extradata) +} OMX_VENDOR_EXTRADATATYPE; + +/** + * This structure describes the parameters corresponding to the + * OMX_VENDOR_VIDEOFRAMERATE extension. This parameter can be set + * dynamically during any state except the state invalid. This is + * used for frame rate to be set from the application. This + * is set on the in port. + */ +typedef struct OMX_VENDOR_VIDEOFRAMERATE { + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion;/** OMX specification version information */ + OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ + OMX_U32 nFps; /** Frame rate value */ + OMX_BOOL bEnabled; /** Flag to enable or disable client's frame rate value */ +} OMX_VENDOR_VIDEOFRAMERATE; + +typedef enum OMX_INDEXVENDORTYPE { + OMX_IndexVendorFileReadInputFilename = 0xFF000001, + OMX_IndexVendorParser3gpInputFilename = 0xFF000002, + OMX_IndexVendorVideoExtraData = 0xFF000003, + OMX_IndexVendorAudioExtraData = 0xFF000004, + OMX_IndexVendorVideoFrameRate = 0xFF000005, +} OMX_INDEXVENDORTYPE; + +typedef enum OMX_QCOM_VC1RESOLUTIONTYPE +{ + OMX_QCOM_VC1_PICTURE_RES_1x1, + OMX_QCOM_VC1_PICTURE_RES_2x1, + OMX_QCOM_VC1_PICTURE_RES_1x2, + OMX_QCOM_VC1_PICTURE_RES_2x2 +} OMX_QCOM_VC1RESOLUTIONTYPE; + +typedef enum OMX_QCOM_INTERLACETYPE +{ + OMX_QCOM_InterlaceFrameProgressive, + OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst, + OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst, + OMX_QCOM_InterlaceFrameTopFieldFirst, + OMX_QCOM_InterlaceFrameBottomFieldFirst, + OMX_QCOM_InterlaceFieldTop, + OMX_QCOM_InterlaceFieldBottom +}OMX_QCOM_INTERLACETYPE; + +typedef struct OMX_QCOM_PARAM_VIDEO_INTERLACETYPE +{ + OMX_U32 nSize; /** Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion;/** OMX specification version information */ + OMX_U32 nPortIndex; /** Portindex which is extended by this structure */ + OMX_BOOL bInterlace; /** Interlace content **/ +}OMX_QCOM_PARAM_VIDEO_INTERLACETYPE; + +typedef struct OMX_QCOM_CONFIG_INTERLACETYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nIndex; + OMX_QCOM_INTERLACETYPE eInterlaceType; +}OMX_QCOM_CONFIG_INTERLACETYPE; + +#define MAX_PAN_SCAN_WINDOWS 4 + +typedef struct OMX_QCOM_PANSCAN +{ + OMX_U32 numWindows; + OMX_QCOMRectangle window[MAX_PAN_SCAN_WINDOWS]; +} OMX_QCOM_PANSCAN; + +typedef struct OMX_QCOM_ASPECT_RATIO +{ + OMX_U32 aspectRatioX; + OMX_U32 aspectRatioY; +} OMX_QCOM_ASPECT_RATIO; + +typedef struct OMX_QCOM_DISPLAY_ASPECT_RATIO +{ + OMX_U32 displayVerticalSize; + OMX_U32 displayHorizontalSize; +} OMX_QCOM_DISPLAY_ASPECT_RATIO; + +typedef struct OMX_QCOM_FRAME_PACK_ARRANGEMENT +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 id; + OMX_U32 cancel_flag; + OMX_U32 type; + OMX_U32 quincunx_sampling_flag; + OMX_U32 content_interpretation_type; + OMX_U32 spatial_flipping_flag; + OMX_U32 frame0_flipped_flag; + OMX_U32 field_views_flag; + OMX_U32 current_frame_is_frame0_flag; + OMX_U32 frame0_self_contained_flag; + OMX_U32 frame1_self_contained_flag; + OMX_U32 frame0_grid_position_x; + OMX_U32 frame0_grid_position_y; + OMX_U32 frame1_grid_position_x; + OMX_U32 frame1_grid_position_y; + OMX_U32 reserved_byte; + OMX_U32 repetition_period; + OMX_U32 extension_flag; +} OMX_QCOM_FRAME_PACK_ARRANGEMENT; + +typedef struct OMX_QCOM_EXTRADATA_QP +{ + OMX_U32 nQP; +} OMX_QCOM_EXTRADATA_QP; + +typedef struct OMX_QCOM_EXTRADATA_BITS_INFO +{ + OMX_U32 header_bits; + OMX_U32 frame_bits; +} OMX_QCOM_EXTRADATA_BITS_INFO; + +typedef struct OMX_QCOM_EXTRADATA_USERDATA { + OMX_U32 type; + OMX_U32 data[1]; +} OMX_QCOM_EXTRADATA_USERDATA; + +typedef struct OMX_QCOM_EXTRADATA_FRAMEINFO +{ + // common frame meta data. interlace related info removed + OMX_VIDEO_PICTURETYPE ePicType; + OMX_QCOM_INTERLACETYPE interlaceType; + OMX_QCOM_PANSCAN panScan; + OMX_QCOM_ASPECT_RATIO aspectRatio; + OMX_QCOM_DISPLAY_ASPECT_RATIO displayAspectRatio; + OMX_U32 nConcealedMacroblocks; + OMX_U32 nFrameRate; + OMX_TICKS nTimeStamp; +} OMX_QCOM_EXTRADATA_FRAMEINFO; + +typedef struct OMX_QCOM_EXTRADATA_FRAMEDIMENSION +{ + /** Frame Dimensions added to each YUV buffer */ + OMX_U32 nDecWidth; /** Width rounded to multiple of 16 */ + OMX_U32 nDecHeight; /** Height rounded to multiple of 16 */ + OMX_U32 nActualWidth; /** Actual Frame Width */ + OMX_U32 nActualHeight; /** Actual Frame Height */ + +} OMX_QCOM_EXTRADATA_FRAMEDIMENSION; + +typedef struct OMX_QCOM_H264EXTRADATA +{ + OMX_U64 seiTimeStamp; +} OMX_QCOM_H264EXTRADATA; + +typedef struct OMX_QCOM_VC1EXTRADATA +{ + OMX_U32 nVC1RangeY; + OMX_U32 nVC1RangeUV; + OMX_QCOM_VC1RESOLUTIONTYPE eVC1PicResolution; +} OMX_QCOM_VC1EXTRADATA; + +typedef union OMX_QCOM_EXTRADATA_CODEC_DATA +{ + OMX_QCOM_H264EXTRADATA h264ExtraData; + OMX_QCOM_VC1EXTRADATA vc1ExtraData; +} OMX_QCOM_EXTRADATA_CODEC_DATA; + +typedef struct OMX_QCOM_EXTRADATA_MBINFO +{ + OMX_U32 nFormat; + OMX_U32 nDataSize; + OMX_U8 data[0]; +} OMX_QCOM_EXTRADATA_MBINFO; + +typedef struct OMX_QCOM_EXTRADATA_VQZIPSEI { + OMX_U32 nSize; + OMX_U8 data[0]; +} OMX_QCOM_EXTRADATA_VQZIPSEI; + +typedef struct OMX_QTI_VIDEO_PARAM_ENABLE_ROIINFO { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnableRoiInfo; +} OMX_QTI_VIDEO_PARAM_ENABLE_ROIINFO; + +typedef struct OMX_QTI_VIDEO_CONFIG_ROIINFO { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nUpperQpOffset; + OMX_S32 nLowerQpOffset; + OMX_BOOL bUseRoiInfo; + OMX_S32 nRoiMBInfoSize; + OMX_PTR pRoiMBInfo; +} OMX_QTI_VIDEO_CONFIG_ROIINFO; + +typedef enum OMX_QCOM_EXTRADATATYPE +{ + OMX_ExtraDataFrameInfo = 0x7F000001, + OMX_ExtraDataH264 = 0x7F000002, + OMX_ExtraDataVC1 = 0x7F000003, + OMX_ExtraDataFrameDimension = 0x7F000004, + OMX_ExtraDataVideoEncoderSliceInfo = 0x7F000005, + OMX_ExtraDataConcealMB = 0x7F000006, + OMX_ExtraDataInterlaceFormat = 0x7F000007, + OMX_ExtraDataPortDef = 0x7F000008, + OMX_ExtraDataMP2ExtnData = 0x7F000009, + OMX_ExtraDataMP2UserData = 0x7F00000a, + OMX_ExtraDataVideoLTRInfo = 0x7F00000b, + OMX_ExtraDataFramePackingArrangement = 0x7F00000c, + OMX_ExtraDataQP = 0x7F00000d, + OMX_ExtraDataInputBitsInfo = 0x7F00000e, + OMX_ExtraDataVideoEncoderMBInfo = 0x7F00000f, + OMX_ExtraDataVQZipSEI = 0x7F000010, +} OMX_QCOM_EXTRADATATYPE; + +typedef struct OMX_STREAMINTERLACEFORMATTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bInterlaceFormat; + OMX_U32 nInterlaceFormats; +} OMX_STREAMINTERLACEFORMAT; + +typedef enum OMX_INTERLACETYPE +{ + OMX_InterlaceFrameProgressive, + OMX_InterlaceInterleaveFrameTopFieldFirst, + OMX_InterlaceInterleaveFrameBottomFieldFirst, + OMX_InterlaceFrameTopFieldFirst, + OMX_InterlaceFrameBottomFieldFirst +} OMX_INTERLACES; + + +#define OMX_EXTRADATA_HEADER_SIZE 20 + +/** + * AVC profile types, each profile indicates support for various + * performance bounds and different annexes. + */ +typedef enum QOMX_VIDEO_AVCPROFILETYPE { + QOMX_VIDEO_AVCProfileBaseline = OMX_VIDEO_AVCProfileBaseline, + QOMX_VIDEO_AVCProfileMain = OMX_VIDEO_AVCProfileMain, + QOMX_VIDEO_AVCProfileExtended = OMX_VIDEO_AVCProfileExtended, + QOMX_VIDEO_AVCProfileHigh = OMX_VIDEO_AVCProfileHigh, + QOMX_VIDEO_AVCProfileHigh10 = OMX_VIDEO_AVCProfileHigh10, + QOMX_VIDEO_AVCProfileHigh422 = OMX_VIDEO_AVCProfileHigh422, + QOMX_VIDEO_AVCProfileHigh444 = OMX_VIDEO_AVCProfileHigh444, + /* QCom specific profile indexes */ + QOMX_VIDEO_AVCProfileConstrained = OMX_VIDEO_AVCProfileVendorStartUnused, + QOMX_VIDEO_AVCProfileConstrainedBaseline, + QOMX_VIDEO_AVCProfileConstrainedHigh, +} QOMX_VIDEO_AVCPROFILETYPE; + + +/** + * H.264 MVC Profiles + */ +typedef enum QOMX_VIDEO_MVCPROFILETYPE { + QOMX_VIDEO_MVCProfileStereoHigh = 0x1, + QOMX_VIDEO_MVCProfileMultiViewHigh = 0x2, + QOMX_VIDEO_MVCProfileKhronosExtensions = 0x6F000000, + QOMX_VIDEO_MVCProfileVendorStartUnused = 0x7F000000, + QOMX_VIDEO_MVCProfileMax = 0x7FFFFFFF +} QOMX_VIDEO_MVCPROFILETYPE; + +/** + * H.264 MVC Levels + */ +typedef enum QOMX_VIDEO_MVCLEVELTYPE { + QOMX_VIDEO_MVCLevel1 = 0x01, /**< Level 1 */ + QOMX_VIDEO_MVCLevel1b = 0x02, /**< Level 1b */ + QOMX_VIDEO_MVCLevel11 = 0x04, /**< Level 1.1 */ + QOMX_VIDEO_MVCLevel12 = 0x08, /**< Level 1.2 */ + QOMX_VIDEO_MVCLevel13 = 0x10, /**< Level 1.3 */ + QOMX_VIDEO_MVCLevel2 = 0x20, /**< Level 2 */ + QOMX_VIDEO_MVCLevel21 = 0x40, /**< Level 2.1 */ + QOMX_VIDEO_MVCLevel22 = 0x80, /**< Level 2.2 */ + QOMX_VIDEO_MVCLevel3 = 0x100, /**< Level 3 */ + QOMX_VIDEO_MVCLevel31 = 0x200, /**< Level 3.1 */ + QOMX_VIDEO_MVCLevel32 = 0x400, /**< Level 3.2 */ + QOMX_VIDEO_MVCLevel4 = 0x800, /**< Level 4 */ + QOMX_VIDEO_MVCLevel41 = 0x1000, /**< Level 4.1 */ + QOMX_VIDEO_MVCLevel42 = 0x2000, /**< Level 4.2 */ + QOMX_VIDEO_MVCLevel5 = 0x4000, /**< Level 5 */ + QOMX_VIDEO_MVCLevel51 = 0x8000, /**< Level 5.1 */ + QOMX_VIDEO_MVCLevelKhronosExtensions = 0x6F000000, + QOMX_VIDEO_MVCLevelVendorStartUnused = 0x7F000000, + QOMX_VIDEO_MVCLevelMax = 0x7FFFFFFF +} QOMX_VIDEO_MVCLEVELTYPE; + +/** + * DivX Versions + */ +typedef enum QOMX_VIDEO_DIVXFORMATTYPE { + QOMX_VIDEO_DIVXFormatUnused = 0x01, /**< Format unused or unknown */ + QOMX_VIDEO_DIVXFormat311 = 0x02, /**< DivX 3.11 */ + QOMX_VIDEO_DIVXFormat4 = 0x04, /**< DivX 4 */ + QOMX_VIDEO_DIVXFormat5 = 0x08, /**< DivX 5 */ + QOMX_VIDEO_DIVXFormat6 = 0x10, /**< DivX 6 */ + QOMX_VIDEO_DIVXFormatKhronosExtensions = 0x6F000000, + QOMX_VIDEO_DIVXFormatVendorStartUnused = 0x7F000000, + QOMX_VIDEO_DIVXFormatMax = 0x7FFFFFFF +} QOMX_VIDEO_DIVXFORMATTYPE; + +/** + * DivX profile types, each profile indicates support for + * various performance bounds. + */ +typedef enum QOMX_VIDEO_DIVXPROFILETYPE { + QOMX_VIDEO_DivXProfileqMobile = 0x01, /**< qMobile Profile */ + QOMX_VIDEO_DivXProfileMobile = 0x02, /**< Mobile Profile */ + QOMX_VIDEO_DivXProfileMT = 0x04, /**< Mobile Theatre Profile */ + QOMX_VIDEO_DivXProfileHT = 0x08, /**< Home Theatre Profile */ + QOMX_VIDEO_DivXProfileHD = 0x10, /**< High Definition Profile */ + QOMX_VIDEO_DIVXProfileKhronosExtensions = 0x6F000000, + QOMX_VIDEO_DIVXProfileVendorStartUnused = 0x7F000000, + QOMX_VIDEO_DIVXProfileMax = 0x7FFFFFFF +} QOMX_VIDEO_DIVXPROFILETYPE; + +/** + * DivX Video Params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFormat : Version of DivX stream / data + * eProfile : Profile of DivX stream / data + */ +typedef struct QOMX_VIDEO_PARAM_DIVXTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + QOMX_VIDEO_DIVXFORMATTYPE eFormat; + QOMX_VIDEO_DIVXPROFILETYPE eProfile; +} QOMX_VIDEO_PARAM_DIVXTYPE; + + + +/** + * VP Versions + */ +typedef enum QOMX_VIDEO_VPFORMATTYPE { + QOMX_VIDEO_VPFormatUnused = 0x01, /**< Format unused or unknown */ + QOMX_VIDEO_VPFormat6 = 0x02, /**< VP6 Video Format */ + QOMX_VIDEO_VPFormat7 = 0x04, /**< VP7 Video Format */ + QOMX_VIDEO_VPFormat8 = 0x08, /**< VP8 Video Format */ + QOMX_VIDEO_VPFormat9 = 0x10, /**< VP9 Video Format */ + QOMX_VIDEO_VPFormatKhronosExtensions = 0x6F000000, + QOMX_VIDEO_VPFormatVendorStartUnused = 0x7F000000, + QOMX_VIDEO_VPFormatMax = 0x7FFFFFFF +} QOMX_VIDEO_VPFORMATTYPE; + +/** + * VP profile types, each profile indicates support for various + * encoding tools. + */ +typedef enum QOMX_VIDEO_VPPROFILETYPE { + QOMX_VIDEO_VPProfileSimple = 0x01, /**< Simple Profile, applies to VP6 only */ + QOMX_VIDEO_VPProfileAdvanced = 0x02, /**< Advanced Profile, applies to VP6 only */ + QOMX_VIDEO_VPProfileVersion0 = 0x04, /**< Version 0, applies to VP7 and VP8 */ + QOMX_VIDEO_VPProfileVersion1 = 0x08, /**< Version 1, applies to VP7 and VP8 */ + QOMX_VIDEO_VPProfileVersion2 = 0x10, /**< Version 2, applies to VP8 only */ + QOMX_VIDEO_VPProfileVersion3 = 0x20, /**< Version 3, applies to VP8 only */ + QOMX_VIDEO_VPProfileKhronosExtensions = 0x6F000000, + QOMX_VIDEO_VPProfileVendorStartUnused = 0x7F000000, + QOMX_VIDEO_VPProfileMax = 0x7FFFFFFF +} QOMX_VIDEO_VPPROFILETYPE; + +/** + * VP Video Params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFormat : Format of VP stream / data + * eProfile : Profile or Version of VP stream / data + */ +typedef struct QOMX_VIDEO_PARAM_VPTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + QOMX_VIDEO_VPFORMATTYPE eFormat; + QOMX_VIDEO_VPPROFILETYPE eProfile; +} QOMX_VIDEO_PARAM_VPTYPE; + +/** + * Spark Versions + */ +typedef enum QOMX_VIDEO_SPARKFORMATTYPE { + QOMX_VIDEO_SparkFormatUnused = 0x01, /**< Format unused or unknown */ + QOMX_VIDEO_SparkFormat0 = 0x02, /**< Video Format Version 0 */ + QOMX_VIDEO_SparkFormat1 = 0x04, /**< Video Format Version 1 */ + QOMX_VIDEO_SparkFormatKhronosExtensions = 0x6F000000, + QOMX_VIDEO_SparkFormatVendorStartUnused = 0x7F000000, + QOMX_VIDEO_SparkFormatMax = 0x7FFFFFFF +} QOMX_VIDEO_SPARKFORMATTYPE; + +/** + * Spark Video Params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFormat : Version of Spark stream / data + */ +typedef struct QOMX_VIDEO_PARAM_SPARKTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + QOMX_VIDEO_SPARKFORMATTYPE eFormat; +} QOMX_VIDEO_PARAM_SPARKTYPE; + + +typedef struct QOMX_VIDEO_QUERY_DECODER_INSTANCES { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nNumOfInstances; +} QOMX_VIDEO_QUERY_DECODER_INSTANCES; + +typedef struct QOMX_ENABLETYPE { + OMX_BOOL bEnable; +} QOMX_ENABLETYPE; + +typedef enum QOMX_VIDEO_EVENTS { + OMX_EventIndexsettingChanged = OMX_EventVendorStartUnused +} QOMX_VIDEO_EVENTS; + +typedef enum QOMX_VIDEO_PICTURE_ORDER { + QOMX_VIDEO_DISPLAY_ORDER = 0x1, + QOMX_VIDEO_DECODE_ORDER = 0x2 +} QOMX_VIDEO_PICTURE_ORDER; + +typedef struct QOMX_VIDEO_DECODER_PICTURE_ORDER { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + QOMX_VIDEO_PICTURE_ORDER eOutputPictureOrder; +} QOMX_VIDEO_DECODER_PICTURE_ORDER; + +typedef struct QOMX_INDEXEXTRADATATYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnabled; + OMX_INDEXTYPE nIndex; +} QOMX_INDEXEXTRADATATYPE; + +typedef struct QOMX_INDEXTIMESTAMPREORDER { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnable; +} QOMX_INDEXTIMESTAMPREORDER; + +typedef struct QOMX_INDEXDOWNSCALAR { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnable; +} QOMX_INDEXDOWNSCALAR; + +typedef struct QOMX_VIDEO_CUSTOM_BUFFERSIZE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nBufferSize; +} QOMX_VIDEO_CUSTOM_BUFFERSIZE; + +#define OMX_QCOM_INDEX_PARAM_VIDEO_SYNCFRAMEDECODINGMODE "OMX.QCOM.index.param.video.SyncFrameDecodingMode" +#define OMX_QCOM_INDEX_PARAM_INDEXEXTRADATA "OMX.QCOM.index.param.IndexExtraData" +#define OMX_QCOM_INDEX_PARAM_VIDEO_SLICEDELIVERYMODE "OMX.QCOM.index.param.SliceDeliveryMode" +#define OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA "OMX.QCOM.index.param.video.FramePackingExtradata" +#define OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA "OMX.QCOM.index.param.video.QPExtradata" +#define OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA "OMX.QCOM.index.param.video.InputBitsInfoExtradata" +#define OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA "OMX.QCOM.index.param.video.ExtnUserExtraData" +#define OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO "OMX.QCOM.index.config.video.FramePackingInfo" +#define OMX_QCOM_INDEX_PARAM_VIDEO_MPEG2SEQDISP_EXTRADATA "OMX.QCOM.index.param.video.Mpeg2SeqDispExtraData" + +#define OMX_QCOM_INDEX_PARAM_VIDEO_HIERSTRUCTURE "OMX.QCOM.index.param.video.HierStructure" +#define OMX_QCOM_INDEX_PARAM_VIDEO_LTRCOUNT "OMX.QCOM.index.param.video.LTRCount" +#define OMX_QCOM_INDEX_PARAM_VIDEO_LTRPERIOD "OMX.QCOM.index.param.video.LTRPeriod" +#define OMX_QCOM_INDEX_CONFIG_VIDEO_LTRUSE "OMX.QCOM.index.config.video.LTRUse" +#define OMX_QCOM_INDEX_CONFIG_VIDEO_LTRMARK "OMX.QCOM.index.config.video.LTRMark" +#define OMX_QCOM_INDEX_CONFIG_VIDEO_HIER_P_LAYERS "OMX.QCOM.index.config.video.hierplayers" +#define OMX_QCOM_INDEX_CONFIG_RECTANGLE_TYPE "OMX.QCOM.index.config.video.rectangle" +#define OMX_QCOM_INDEX_PARAM_VIDEO_BASE_LAYER_ID "OMX.QCOM.index.param.video.baselayerid" +#define OMX_QCOM_INDEX_CONFIG_VIDEO_QP "OMX.QCOM.index.config.video.qp" +#define OMX_QCOM_INDEX_PARAM_VIDEO_SAR "OMX.QCOM.index.param.video.sar" +#define OMX_QTI_INDEX_PARAM_VIDEO_LOW_LATENCY "OMX.QTI.index.param.video.LowLatency" + +#define OMX_QCOM_INDEX_PARAM_VIDEO_PASSINPUTBUFFERFD "OMX.QCOM.index.param.video.PassInputBufferFd" +#define OMX_QTI_INDEX_PARAM_VIDEO_PREFER_ADAPTIVE_PLAYBACK "OMX.QTI.index.param.video.PreferAdaptivePlayback" +#define OMX_QTI_INDEX_CONFIG_VIDEO_SETTIMEDATA "OMX.QTI.index.config.video.settimedata" +#define OMX_QTI_INDEX_PARAM_VIDEO_FORCE_COMPRESSED_FOR_DPB "OMX.QTI.index.param.video.ForceCompressedForDPB" +#define OMX_QTI_INDEX_PARAM_VIDEO_ENABLE_ROIINFO "OMX.QTI.index.param.enableRoiInfo" +#define OMX_QTI_INDEX_CONFIG_VIDEO_ROIINFO "OMX.QTI.index.config.RoiInfo" + +typedef enum { + QOMX_VIDEO_FRAME_PACKING_CHECKERBOARD = 0, + QOMX_VIDEO_FRAME_PACKING_COLUMN_INTERLEAVE = 1, + QOMX_VIDEO_FRAME_PACKING_ROW_INTERLEAVE = 2, + QOMX_VIDEO_FRAME_PACKING_SIDE_BY_SIDE = 3, + QOMX_VIDEO_FRAME_PACKING_TOP_BOTTOM = 4, + QOMX_VIDEO_FRAME_PACKING_TEMPORAL = 5, +} QOMX_VIDEO_FRAME_PACKING_ARRANGEMENT; + +typedef enum { + QOMX_VIDEO_CONTENT_UNSPECIFIED = 0, + QOMX_VIDEO_CONTENT_LR_VIEW = 1, + QOMX_VIDEO_CONTENT_RL_VIEW = 2, +} QOMX_VIDEO_CONTENT_INTERPRETATION; + +/** + * Specifies the extended picture types. These values should be + * OR'd along with the types defined in OMX_VIDEO_PICTURETYPE to + * signal all pictures types which are allowed. + * + * ENUMS: + * H.264 Specific Picture Types: IDR + */ +typedef enum QOMX_VIDEO_PICTURETYPE { + QOMX_VIDEO_PictureTypeIDR = OMX_VIDEO_PictureTypeVendorStartUnused + 0x1000 +} QOMX_VIDEO_PICTURETYPE; + +#define OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION "OMX.QCOM.index.config.activeregiondetection" +#define OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION_STATUS "OMX.QCOM.index.config.activeregiondetectionstatus" +#define OMX_QCOM_INDEX_CONFIG_SCALING_MODE "OMX.QCOM.index.config.scalingmode" +#define OMX_QCOM_INDEX_CONFIG_NOISEREDUCTION "OMX.QCOM.index.config.noisereduction" +#define OMX_QCOM_INDEX_CONFIG_IMAGEENHANCEMENT "OMX.QCOM.index.config.imageenhancement" +#define OMX_QCOM_INDEX_PARAM_HELDBUFFERCOUNT "OMX.QCOM.index.param.HeldBufferCount" /**< reference: QOMX_HELDBUFFERCOUNTTYPE */ + + +typedef struct QOMX_RECTTYPE { + OMX_S32 nLeft; + OMX_S32 nTop; + OMX_U32 nWidth; + OMX_U32 nHeight; +} QOMX_RECTTYPE; + +typedef struct QOMX_ACTIVEREGIONDETECTIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnable; + QOMX_RECTTYPE sROI; + OMX_U32 nNumExclusionRegions; + QOMX_RECTTYPE sExclusionRegions[1]; +} QOMX_ACTIVEREGIONDETECTIONTYPE; + +typedef struct QOMX_ACTIVEREGIONDETECTION_STATUSTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bDetected; + QOMX_RECTTYPE sDetectedRegion; +} QOMX_ACTIVEREGIONDETECTION_STATUSTYPE; + +typedef enum QOMX_SCALE_MODETYPE { + QOMX_SCALE_MODE_Normal, + QOMX_SCALE_MODE_Anamorphic, + QOMX_SCALE_MODE_Max = 0x7FFFFFFF +} QOMX_SCALE_MODETYPE; + +typedef struct QOMX_SCALINGMODETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + QOMX_SCALE_MODETYPE eScaleMode; +} QOMX_SCALINGMODETYPE; + +typedef struct QOMX_NOISEREDUCTIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnable; + OMX_BOOL bAutoMode; + OMX_S32 nNoiseReduction; +} QOMX_NOISEREDUCTIONTYPE; + +typedef struct QOMX_IMAGEENHANCEMENTTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnable; + OMX_BOOL bAutoMode; + OMX_S32 nImageEnhancement; +} QOMX_IMAGEENHANCEMENTTYPE; + +/* + * these are part of OMX1.2 but JB MR2 branch doesn't have them defined + * OMX_IndexParamInterlaceFormat + * OMX_INTERLACEFORMATTYPE + */ +#ifndef OMX_IndexParamInterlaceFormat +#define OMX_IndexParamInterlaceFormat (0x7FF00000) +typedef struct OMX_INTERLACEFORMATTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nFormat; + OMX_TICKS nTimeStamp; +} OMX_INTERLACEFORMATTYPE; +#endif + +/** + * This structure is used to indicate the maximum number of buffers + * that a port will hold during data flow. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version info + * nPortIndex : Port that this structure applies to + * nHeldBufferCount : Read-only, maximum number of buffers that will be held + */ +typedef struct QOMX_HELDBUFFERCOUNTTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nHeldBufferCount; +} QOMX_HELDBUFFERCOUNTTYPE; + +typedef enum QOMX_VIDEO_HIERARCHICALCODINGTYPE { + QOMX_HIERARCHICALCODING_P = 0x01, + QOMX_HIERARCHICALCODING_B = 0x02, +} QOMX_VIDEO_HIERARCHICALCODINGTYPE; + +typedef struct QOMX_VIDEO_HIERARCHICALLAYERS { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nNumLayers; + QOMX_VIDEO_HIERARCHICALCODINGTYPE eHierarchicalCodingType; +} QOMX_VIDEO_HIERARCHICALLAYERS; + +typedef struct QOMX_VIDEO_H264ENTROPYCODINGTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bCabac; + OMX_U32 nCabacInitIdc; +} QOMX_VIDEO_H264ENTROPYCODINGTYPE; + + +/* VIDEO POSTPROCESSING CTRLS AND ENUMS */ +#define QOMX_VPP_HQV_CUSTOMPAYLOAD_SZ 256 +#define VPP_HQV_CONTROL_GLOBAL_START (VPP_HQV_CONTROL_CUST + 1) + +typedef enum QOMX_VPP_HQV_MODE { + VPP_HQV_MODE_OFF, + VPP_HQV_MODE_AUTO, + VPP_HQV_MODE_MANUAL, + VPP_HQV_MODE_MAX +} QOMX_VPP_HQV_MODE; + +typedef enum QOMX_VPP_HQVCONTROLTYPE { + VPP_HQV_CONTROL_CADE = 0x1, + VPP_HQV_CONTROL_CNR = 0x04, + VPP_HQV_CONTROL_AIE = 0x05, + VPP_HQV_CONTROL_FRC = 0x06, + VPP_HQV_CONTROL_CUST = 0x07, + VPP_HQV_CONTROL_GLOBAL_DEMO = VPP_HQV_CONTROL_GLOBAL_START, + VPP_HQV_CONTROL_MAX, +} QOMX_VPP_HQVCONTROLTYPE; + +typedef enum QOMX_VPP_HQV_HUE_MODE { + VPP_HQV_HUE_MODE_OFF, + VPP_HQV_HUE_MODE_ON, + VPP_HQV_HUE_MODE_MAX, +} QOMX_VPP_HQV_HUE_MODE; + +typedef enum QOMX_VPP_HQV_FRC_MODE { + VPP_HQV_FRC_MODE_OFF, + VPP_HQV_FRC_MODE_LOW, + VPP_HQV_FRC_MODE_MED, + VPP_HQV_FRC_MODE_HIGH, + VPP_HQV_FRC_MODE_MAX, +} QOMX_VPP_HQV_FRC_MODE; + + +typedef struct QOMX_VPP_HQVCTRL_CADE { + QOMX_VPP_HQV_MODE mode; + OMX_U32 level; + OMX_S32 contrast; + OMX_S32 saturation; +} QOMX_VPP_HQVCTRL_CADE; + +typedef struct QOMX_VPP_HQVCTRL_CNR { + QOMX_VPP_HQV_MODE mode; + OMX_U32 level; +} QOMX_VPP_HQVCTRL_CNR; + +typedef struct QOMX_VPP_HQVCTRL_AIE { + QOMX_VPP_HQV_MODE mode; + QOMX_VPP_HQV_HUE_MODE hue_mode; + OMX_U32 cade_level; + OMX_U32 ltm_level; +} QOMX_VPP_HQVCTRL_AIE; + +typedef struct QOMX_VPP_HQVCTRL_CUSTOM { + OMX_U32 id; + OMX_U32 len; + OMX_U8 data[QOMX_VPP_HQV_CUSTOMPAYLOAD_SZ]; +} QOMX_VPP_HQVCTRL_CUSTOM; + +typedef struct QOMX_VPP_HQVCTRL_GLOBAL_DEMO { + OMX_U32 process_percent; +} QOMX_VPP_HQVCTRL_GLOBAL_DEMO; + +typedef struct QOMX_VPP_HQVCTRL_FRC { + QOMX_VPP_HQV_FRC_MODE mode; +} QOMX_VPP_HQVCTRL_FRC; + +typedef struct QOMX_VPP_HQVCONTROL { + QOMX_VPP_HQV_MODE mode; + QOMX_VPP_HQVCONTROLTYPE ctrl_type; + union { + QOMX_VPP_HQVCTRL_CADE cade; + QOMX_VPP_HQVCTRL_CNR cnr; + QOMX_VPP_HQVCTRL_AIE aie; + QOMX_VPP_HQVCTRL_CUSTOM custom; + QOMX_VPP_HQVCTRL_GLOBAL_DEMO global_demo; + QOMX_VPP_HQVCTRL_FRC frc; + }; +} QOMX_VPP_HQVCONTROL; + +/* STRUCTURE TO TURN VPP ON */ +typedef struct QOMX_VPP_ENABLE { + OMX_BOOL enable_vpp; +} QOMX_VPP_ENABLE; + +typedef enum OMX_QOMX_VIDEO_MBISTATISTICSTYPE { + QOMX_MBI_STATISTICS_MODE_DEFAULT = 0, + QOMX_MBI_STATISTICS_MODE_1 = 0x01, + QOMX_MBI_STATISTICS_MODE_2 = 0x02, +} OMX_QOMX_VIDEO_MBISTATISTICSTYPE; + +typedef struct OMX_QOMX_VIDEO_MBI_STATISTICS { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_QOMX_VIDEO_MBISTATISTICSTYPE eMBIStatisticsType; +} OMX_QOMX_VIDEO_MBI_STATISTICS; + +typedef struct QOMX_VIDEO_BATCHSIZETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nBatchSize; +} QOMX_VIDEO_BATCHSIZETYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __OMX_QCOM_EXTENSIONS_H__ */ diff --git a/phonelibs/openmax/include/OMX_Skype_VideoExtensions.h b/phonelibs/openmax/include/OMX_Skype_VideoExtensions.h new file mode 100644 index 00000000000000..5cc832930f1801 --- /dev/null +++ b/phonelibs/openmax/include/OMX_Skype_VideoExtensions.h @@ -0,0 +1,155 @@ +/*@@@+++@@@@****************************************************************** + + Microsoft Skype Engineering + Copyright (C) 2014 Microsoft Corporation. + +MIT License + +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. + +*@@@---@@@@******************************************************************/ + + +#ifndef __OMX_SKYPE_VIDEOEXTENSIONS_H__ +#define __OMX_SKYPE_VIDEOEXTENSIONS_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +#pragma pack(push, 1) + + +typedef enum OMX_SKYPE_VIDEO_SliceControlMode +{ + OMX_SKYPE_VIDEO_SliceControlModeNone = 0, + OMX_SKYPE_VIDEO_SliceControlModeMB = 1, + OMX_SKYPE_VIDEO_SliceControlModeByte = 2, + OMX_SKYPE_VIDEO_SliceControlModMBRow = 3, +} OMX_SKYPE_VIDEO_SliceControlMode; + + +typedef enum OMX_SKYPE_VIDEO_HierarType +{ + OMX_SKYPE_VIDEO_HierarType_P = 0x01, + OMX_SKYPE_VIDEO_HierarType_B = 0x02, +} OMX_SKYPE_VIDEO_HIERAR_HierarType; + +typedef enum OMX_VIDEO_EXTENSION_AVCPROFILETYPE +{ + OMX_VIDEO_EXT_AVCProfileConstrainedBaseline = 0x01, + OMX_VIDEO_EXT_AVCProfileConstrainedHigh = 0x02, +} OMX_VIDEO_EXTENSION_AVCPROFILETYPE; + +typedef struct OMX_SKYPE_VIDEO_ENCODERPARAMS { + OMX_BOOL bLowLatency; + OMX_BOOL bUseExtendedProfile; + OMX_BOOL bSequenceHeaderWithIDR; + OMX_VIDEO_EXTENSION_AVCPROFILETYPE eProfile; + OMX_U32 nLTRFrames; + OMX_SKYPE_VIDEO_HierarType eHierarType; + OMX_U32 nMaxTemporalLayerCount; + OMX_SKYPE_VIDEO_SliceControlMode eSliceControlMode; + OMX_U32 nSarIndex; + OMX_U32 nSarWidth; + OMX_U32 nSarHeight; +} OMX_SKYPE_VIDEO_ENCODERPARAMS; + +typedef struct OMX_SKYPE_VIDEO_PARAM_ENCODERSETTING { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_SKYPE_VIDEO_ENCODERPARAMS stEncParam; +} OMX_SKYPE_VIDEO_PARAM_ENCODESETTING; + +typedef struct OMX_SKYPE_VIDEO_ENCODERCAP { + OMX_BOOL bLowLatency; + OMX_U32 nMaxFrameWidth; + OMX_U32 nMaxFrameHeight; + OMX_U32 nMaxInstances; + OMX_U32 nMaxTemporaLayerCount; + OMX_U32 nMaxRefFrames; + OMX_U32 nMaxLTRFrames; + OMX_VIDEO_AVCLEVELTYPE nMaxLevel; + OMX_U32 nSliceControlModesBM; + OMX_U32 nMaxMacroblockProcessingRate; + OMX_U32 xMinScaleFactor; +} OMX_SKYPE_VIDEO_ENCODERCAP; + +typedef struct OMX_SKYPE_VIDEO_PARAM_ENCODERCAP { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_SKYPE_VIDEO_ENCODERCAP stEncCap; +} OMX_SKYPE_VIDEO_PARAM_ENCODERCAP; + +typedef struct OMX_SKYPE_VIDEO_DECODERCAP { + OMX_BOOL bLowLatency; + OMX_U32 nMaxFrameWidth; + OMX_U32 nMaxFrameHeight; + OMX_U32 nMaxInstances; + OMX_VIDEO_AVCLEVELTYPE nMaxLevel; + OMX_U32 nMaxMacroblockProcessingRate; +} OMX_SKYPE_VIDEO_DECODERCAP; + +typedef struct OMX_SKYPE_VIDEO_PARAM_DECODERCAP { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_SKYPE_VIDEO_DECODERCAP stDecoderCap; +} OMX_SKYPE_VIDEO_PARAM_DECODERCAP; + +typedef struct OMX_SKYPE_VIDEO_CONFIG_QP { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nQP; +} OMX_SKYPE_VIDEO_CONFIG_QP; + +typedef struct OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nPID; +} OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID; + +typedef struct OMX_SKYPE_VIDEO_PARAM_DRIVERVER { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U64 nDriverVersion; +} OMX_SKYPE_VIDEO_PARAM_DRIVERVER; + +typedef enum OMX_SKYPE_VIDEO_DownScaleFactor +{ + OMX_SKYPE_VIDEO_DownScaleFactor_1_1 = 0, + OMX_SKYPE_VIDEO_DownScaleFactor_Equal_AR = 1, + OMX_SKYPE_VIDEO_DownScaleFactor_Any = 2, +} OMX_SKYPE_VIDEO_DownScaleFactor; + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/phonelibs/openmax/include/OMX_Types.h b/phonelibs/openmax/include/OMX_Types.h new file mode 100644 index 00000000000000..3b9fab4fc2e057 --- /dev/null +++ b/phonelibs/openmax/include/OMX_Types.h @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** OMX_Types.h - OpenMax IL version 1.1.2 + * The OMX_Types header file contains the primitive type definitions used by + * the core, the application and the component. This file may need to be + * modified to be used on systems that do not have "char" set to 8 bits, + * "short" set to 16 bits and "long" set to 32 bits. + */ + +#ifndef OMX_Types_h +#define OMX_Types_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** The OMX_API and OMX_APIENTRY are platform specific definitions used + * to declare OMX function prototypes. They are modified to meet the + * requirements for a particular platform */ +#ifdef __SYMBIAN32__ +# ifdef __OMX_EXPORTS +# define OMX_API __declspec(dllexport) +# else +# ifdef _WIN32 +# define OMX_API __declspec(dllexport) +# else +# define OMX_API __declspec(dllimport) +# endif +# endif +#else +# ifdef _WIN32 +# ifdef __OMX_EXPORTS +# define OMX_API __declspec(dllexport) +# else +# define OMX_API __declspec(dllimport) +# endif +# else +# ifdef __OMX_EXPORTS +# define OMX_API +# else +# define OMX_API extern +# endif +# endif +#endif + +#ifndef OMX_APIENTRY +#define OMX_APIENTRY +#endif + +/** OMX_IN is used to identify inputs to an OMX function. This designation + will also be used in the case of a pointer that points to a parameter + that is used as an output. */ +#ifndef OMX_IN +#define OMX_IN +#endif + +/** OMX_OUT is used to identify outputs from an OMX function. This + designation will also be used in the case of a pointer that points + to a parameter that is used as an input. */ +#ifndef OMX_OUT +#define OMX_OUT +#endif + + +/** OMX_INOUT is used to identify parameters that may be either inputs or + outputs from an OMX function at the same time. This designation will + also be used in the case of a pointer that points to a parameter that + is used both as an input and an output. */ +#ifndef OMX_INOUT +#define OMX_INOUT +#endif + +/** OMX_ALL is used to as a wildcard to select all entities of the same type + * when specifying the index, or referring to a object by an index. (i.e. + * use OMX_ALL to indicate all N channels). When used as a port index + * for a config or parameter this OMX_ALL denotes that the config or + * parameter applies to the entire component not just one port. */ +#define OMX_ALL 0xFFFFFFFF + +/** In the following we define groups that help building doxygen documentation */ + +/** @defgroup core OpenMAX IL core + * Functions and structure related to the OMX IL core + */ + + /** @defgroup comp OpenMAX IL component + * Functions and structure related to the OMX IL component + */ + +/** @defgroup rpm Resource and Policy Management + * Structures for resource and policy management of components + */ + +/** @defgroup buf Buffer Management + * Buffer handling functions and structures + */ + +/** @defgroup tun Tunneling + * @ingroup core comp + * Structures and functions to manage tunnels among component ports + */ + +/** @defgroup cp Content Pipes + * @ingroup core + */ + + /** @defgroup metadata Metadata handling + * + */ + +/** OMX_U8 is an 8 bit unsigned quantity that is byte aligned */ +typedef unsigned char OMX_U8; + +/** OMX_S8 is an 8 bit signed quantity that is byte aligned */ +typedef signed char OMX_S8; + +/** OMX_U16 is a 16 bit unsigned quantity that is 16 bit word aligned */ +typedef unsigned short OMX_U16; + +/** OMX_S16 is a 16 bit signed quantity that is 16 bit word aligned */ +typedef signed short OMX_S16; + +/** OMX_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */ +typedef unsigned int OMX_U32; + +/** OMX_S32 is a 32 bit signed quantity that is 32 bit word aligned */ +typedef signed int OMX_S32; + + +/* Users with compilers that cannot accept the "long long" designation should + define the OMX_SKIP64BIT macro. It should be noted that this may cause + some components to fail to compile if the component was written to require + 64 bit integral types. However, these components would NOT compile anyway + since the compiler does not support the way the component was written. +*/ +#ifndef OMX_SKIP64BIT +#ifdef __SYMBIAN32__ +/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ +typedef unsigned long long OMX_U64; + +/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ +typedef signed long long OMX_S64; + +#elif defined(WIN32) + +/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ +typedef unsigned __int64 OMX_U64; + +/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ +typedef signed __int64 OMX_S64; + +#else /* WIN32 */ + +/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ +typedef unsigned long long OMX_U64; + +/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ +typedef signed long long OMX_S64; + +#endif /* WIN32 */ +#endif + + +/** The OMX_BOOL type is intended to be used to represent a true or a false + value when passing parameters to and from the OMX core and components. The + OMX_BOOL is a 32 bit quantity and is aligned on a 32 bit word boundary. + */ +typedef enum OMX_BOOL { + OMX_FALSE = 0, + OMX_TRUE = !OMX_FALSE, + OMX_BOOL_MAX = 0x7FFFFFFF +} OMX_BOOL; + +#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS + +typedef OMX_U32 OMX_PTR; +typedef OMX_PTR OMX_STRING; +typedef OMX_PTR OMX_BYTE; + +#else + +/** The OMX_PTR type is intended to be used to pass pointers between the OMX + applications and the OMX Core and components. This is a 32 bit pointer and + is aligned on a 32 bit boundary. + */ +typedef void* OMX_PTR; + +/** The OMX_STRING type is intended to be used to pass "C" type strings between + the application and the core and component. The OMX_STRING type is a 32 + bit pointer to a zero terminated string. The pointer is word aligned and + the string is byte aligned. + */ +typedef char* OMX_STRING; + +/** The OMX_BYTE type is intended to be used to pass arrays of bytes such as + buffers between the application and the component and core. The OMX_BYTE + type is a 32 bit pointer to a zero terminated string. The pointer is word + aligned and the string is byte aligned. + */ +typedef unsigned char* OMX_BYTE; + +/** OMX_UUIDTYPE is a very long unique identifier to uniquely identify + at runtime. This identifier should be generated by a component in a way + that guarantees that every instance of the identifier running on the system + is unique. */ + + +#endif + +typedef unsigned char OMX_UUIDTYPE[128]; + +/** The OMX_DIRTYPE enumeration is used to indicate if a port is an input or + an output port. This enumeration is common across all component types. + */ +typedef enum OMX_DIRTYPE +{ + OMX_DirInput, /**< Port is an input port */ + OMX_DirOutput, /**< Port is an output port */ + OMX_DirMax = 0x7FFFFFFF +} OMX_DIRTYPE; + +/** The OMX_ENDIANTYPE enumeration is used to indicate the bit ordering + for numerical data (i.e. big endian, or little endian). + */ +typedef enum OMX_ENDIANTYPE +{ + OMX_EndianBig, /**< big endian */ + OMX_EndianLittle, /**< little endian */ + OMX_EndianMax = 0x7FFFFFFF +} OMX_ENDIANTYPE; + + +/** The OMX_NUMERICALDATATYPE enumeration is used to indicate if data + is signed or unsigned + */ +typedef enum OMX_NUMERICALDATATYPE +{ + OMX_NumericalDataSigned, /**< signed data */ + OMX_NumericalDataUnsigned, /**< unsigned data */ + OMX_NumercialDataMax = 0x7FFFFFFF +} OMX_NUMERICALDATATYPE; + + +/** Unsigned bounded value type */ +typedef struct OMX_BU32 { + OMX_U32 nValue; /**< actual value */ + OMX_U32 nMin; /**< minimum for value (i.e. nValue >= nMin) */ + OMX_U32 nMax; /**< maximum for value (i.e. nValue <= nMax) */ +} OMX_BU32; + + +/** Signed bounded value type */ +typedef struct OMX_BS32 { + OMX_S32 nValue; /**< actual value */ + OMX_S32 nMin; /**< minimum for value (i.e. nValue >= nMin) */ + OMX_S32 nMax; /**< maximum for value (i.e. nValue <= nMax) */ +} OMX_BS32; + + +/** Structure representing some time or duration in microseconds. This structure + * must be interpreted as a signed 64 bit value. The quantity is signed to accommodate + * negative deltas and preroll scenarios. The quantity is represented in microseconds + * to accomodate high resolution timestamps (e.g. DVD presentation timestamps based + * on a 90kHz clock) and to allow more accurate and synchronized delivery (e.g. + * individual audio samples delivered at 192 kHz). The quantity is 64 bit to + * accommodate a large dynamic range (signed 32 bit values would allow only for plus + * or minus 35 minutes). + * + * Implementations with limited precision may convert the signed 64 bit value to + * a signed 32 bit value internally but risk loss of precision. + */ +#ifndef OMX_SKIP64BIT +typedef OMX_S64 OMX_TICKS; +#else +typedef struct OMX_TICKS +{ + OMX_U32 nLowPart; /** low bits of the signed 64 bit tick value */ + OMX_U32 nHighPart; /** high bits of the signed 64 bit tick value */ +} OMX_TICKS; +#endif +#define OMX_TICKS_PER_SECOND 1000000 + +/** Define the public interface for the OMX Handle. The core will not use + this value internally, but the application should only use this value. + */ +typedef void* OMX_HANDLETYPE; + +typedef struct OMX_MARKTYPE +{ + OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will + generate a mark event upon + processing the mark. */ + OMX_PTR pMarkData; /**< Application specific data associated with + the mark sent on a mark event to disambiguate + this mark from others. */ +} OMX_MARKTYPE; + + +/** OMX_NATIVE_DEVICETYPE is used to map a OMX video port to the + * platform & operating specific object used to reference the display + * or can be used by a audio port for native audio rendering */ +typedef void* OMX_NATIVE_DEVICETYPE; + +/** OMX_NATIVE_WINDOWTYPE is used to map a OMX video port to the + * platform & operating specific object used to reference the window */ +typedef void* OMX_NATIVE_WINDOWTYPE; + +/** The OMX_VERSIONTYPE union is used to specify the version for + a structure or component. For a component, the version is entirely + specified by the component vendor. Components doing the same function + from different vendors may or may not have the same version. For + structures, the version shall be set by the entity that allocates the + structure. For structures specified in the OMX 1.1 specification, the + value of the version shall be set to 1.1.0.0 in all cases. Access to the + OMX_VERSIONTYPE can be by a single 32 bit access (e.g. by nVersion) or + by accessing one of the structure elements to, for example, check only + the Major revision. + */ +typedef union OMX_VERSIONTYPE +{ + struct + { + OMX_U8 nVersionMajor; /**< Major version accessor element */ + OMX_U8 nVersionMinor; /**< Minor version accessor element */ + OMX_U8 nRevision; /**< Revision version accessor element */ + OMX_U8 nStep; /**< Step version accessor element */ + } s; + OMX_U32 nVersion; /**< 32 bit value to make accessing the + version easily done in a single word + size copy/compare operation */ +} OMX_VERSIONTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/phonelibs/openmax/include/OMX_Video.h b/phonelibs/openmax/include/OMX_Video.h new file mode 100644 index 00000000000000..64dbe87b4329d1 --- /dev/null +++ b/phonelibs/openmax/include/OMX_Video.h @@ -0,0 +1,1082 @@ +/** + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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. + * + */ + +/** + * @file OMX_Video.h - OpenMax IL version 1.1.2 + * The structures is needed by Video components to exchange parameters + * and configuration data with OMX components. + */ +#ifndef OMX_Video_h +#define OMX_Video_h + +/** @defgroup video OpenMAX IL Video Domain + * @ingroup iv + * Structures for OpenMAX IL Video domain + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + * Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + + +/** + * Enumeration used to define the possible video compression codings. + * NOTE: This essentially refers to file extensions. If the coding is + * being used to specify the ENCODE type, then additional work + * must be done to configure the exact flavor of the compression + * to be used. For decode cases where the user application can + * not differentiate between MPEG-4 and H.264 bit streams, it is + * up to the codec to handle this. + */ +typedef enum OMX_VIDEO_CODINGTYPE { + OMX_VIDEO_CodingUnused, /**< Value when coding is N/A */ + OMX_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */ + OMX_VIDEO_CodingMPEG2, /**< AKA: H.262 */ + OMX_VIDEO_CodingH263, /**< H.263 */ + OMX_VIDEO_CodingMPEG4, /**< MPEG-4 */ + OMX_VIDEO_CodingWMV, /**< all versions of Windows Media Video */ + OMX_VIDEO_CodingRV, /**< all versions of Real Video */ + OMX_VIDEO_CodingAVC, /**< H.264/AVC */ + OMX_VIDEO_CodingMJPEG, /**< Motion JPEG */ + OMX_VIDEO_CodingVP8, /**< Google VP8, formerly known as On2 VP8 */ + OMX_VIDEO_CodingVP9, /**< Google VP9 */ + OMX_VIDEO_CodingHEVC, /**< HEVC */ + OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_CodingMax = 0x7FFFFFFF +} OMX_VIDEO_CODINGTYPE; + + +/** + * Data structure used to define a video path. The number of Video paths for + * input and output will vary by type of the Video component. + * + * Input (aka Source) : zero Inputs, one Output, + * Splitter : one Input, 2 or more Outputs, + * Processing Element : one Input, one output, + * Mixer : 2 or more inputs, one output, + * Output (aka Sink) : one Input, zero outputs. + * + * The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output video + * path. If additional vendor specific data is required, it should be + * transmitted to the component using the CustomCommand function. Compliant + * components will prepopulate this structure with optimal values during the + * GetDefaultInitParams command. + * + * STRUCT MEMBERS: + * cMIMEType : MIME type of data for the port + * pNativeRender : Platform specific reference for a display if a + * sync, otherwise this field is 0 + * nFrameWidth : Width of frame to be used on channel if + * uncompressed format is used. Use 0 for unknown, + * don't care or variable + * nFrameHeight : Height of frame to be used on channel if + * uncompressed format is used. Use 0 for unknown, + * don't care or variable + * nStride : Number of bytes per span of an image + * (i.e. indicates the number of bytes to get + * from span N to span N+1, where negative stride + * indicates the image is bottom up + * nSliceHeight : Height used when encoding in slices + * nBitrate : Bit rate of frame to be used on channel if + * compressed format is used. Use 0 for unknown, + * don't care or variable + * xFramerate : Frame rate to be used on channel if uncompressed + * format is used. Use 0 for unknown, don't care or + * variable. Units are Q16 frames per second. + * bFlagErrorConcealment : Turns on error concealment if it is supported by + * the OMX component + * eCompressionFormat : Compression format used in this instance of the + * component. When OMX_VIDEO_CodingUnused is + * specified, eColorFormat is used + * eColorFormat : Decompressed format used by this component + * pNativeWindow : Platform specific reference for a window object if a + * display sink , otherwise this field is 0x0. + */ +typedef struct OMX_VIDEO_PORTDEFINITIONTYPE { + OMX_STRING cMIMEType; + OMX_NATIVE_DEVICETYPE pNativeRender; + OMX_U32 nFrameWidth; + OMX_U32 nFrameHeight; + OMX_S32 nStride; + OMX_U32 nSliceHeight; + OMX_U32 nBitrate; + OMX_U32 xFramerate; + OMX_BOOL bFlagErrorConcealment; + OMX_VIDEO_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; + OMX_NATIVE_WINDOWTYPE pNativeWindow; +} OMX_VIDEO_PORTDEFINITIONTYPE; + +/** + * Port format parameter. This structure is used to enumerate the various + * data input/output format supported by the port. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Indicates which port to set + * nIndex : Indicates the enumeration index for the format from + * 0x0 to N-1 + * eCompressionFormat : Compression format used in this instance of the + * component. When OMX_VIDEO_CodingUnused is specified, + * eColorFormat is used + * eColorFormat : Decompressed format used by this component + * xFrameRate : Indicates the video frame rate in Q16 format + */ +typedef struct OMX_VIDEO_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nIndex; + OMX_VIDEO_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; + OMX_U32 xFramerate; +} OMX_VIDEO_PARAM_PORTFORMATTYPE; + + +/** + * This is a structure for configuring video compression quantization + * parameter values. Codecs may support different QP values for different + * frame types. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version info + * nPortIndex : Port that this structure applies to + * nQpI : QP value to use for index frames + * nQpP : QP value to use for P frames + * nQpB : QP values to use for bidirectional frames + */ +typedef struct OMX_VIDEO_PARAM_QUANTIZATIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nQpI; + OMX_U32 nQpP; + OMX_U32 nQpB; +} OMX_VIDEO_PARAM_QUANTIZATIONTYPE; + + +/** + * Structure for configuration of video fast update parameters. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version info + * nPortIndex : Port that this structure applies to + * bEnableVFU : Enable/Disable video fast update + * nFirstGOB : Specifies the number of the first macroblock row + * nFirstMB : specifies the first MB relative to the specified first GOB + * nNumMBs : Specifies the number of MBs to be refreshed from nFirstGOB + * and nFirstMB + */ +typedef struct OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnableVFU; + OMX_U32 nFirstGOB; + OMX_U32 nFirstMB; + OMX_U32 nNumMBs; +} OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE; + + +/** + * Enumeration of possible bitrate control types + */ +typedef enum OMX_VIDEO_CONTROLRATETYPE { + OMX_Video_ControlRateDisable, + OMX_Video_ControlRateVariable, + OMX_Video_ControlRateConstant, + OMX_Video_ControlRateVariableSkipFrames, + OMX_Video_ControlRateConstantSkipFrames, + OMX_Video_ControlRateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_Video_ControlRateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_Video_ControlRateMax = 0x7FFFFFFF +} OMX_VIDEO_CONTROLRATETYPE; + + +/** + * Structure for configuring bitrate mode of a codec. + * + * STRUCT MEMBERS: + * nSize : Size of the struct in bytes + * nVersion : OMX spec version info + * nPortIndex : Port that this struct applies to + * eControlRate : Control rate type enum + * nTargetBitrate : Target bitrate to encode with + */ +typedef struct OMX_VIDEO_PARAM_BITRATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_CONTROLRATETYPE eControlRate; + OMX_U32 nTargetBitrate; +} OMX_VIDEO_PARAM_BITRATETYPE; + + +/** + * Enumeration of possible motion vector (MV) types + */ +typedef enum OMX_VIDEO_MOTIONVECTORTYPE { + OMX_Video_MotionVectorPixel, + OMX_Video_MotionVectorHalfPel, + OMX_Video_MotionVectorQuarterPel, + OMX_Video_MotionVectorEighthPel, + OMX_Video_MotionVectorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_Video_MotionVectorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_Video_MotionVectorMax = 0x7FFFFFFF +} OMX_VIDEO_MOTIONVECTORTYPE; + + +/** + * Structure for configuring the number of motion vectors used as well + * as their accuracy. + * + * STRUCT MEMBERS: + * nSize : Size of the struct in bytes + * nVersion : OMX spec version info + * nPortIndex : port that this structure applies to + * eAccuracy : Enumerated MV accuracy + * bUnrestrictedMVs : Allow unrestricted MVs + * bFourMV : Allow use of 4 MVs + * sXSearchRange : Search range in horizontal direction for MVs + * sYSearchRange : Search range in vertical direction for MVs + */ +typedef struct OMX_VIDEO_PARAM_MOTIONVECTORTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_MOTIONVECTORTYPE eAccuracy; + OMX_BOOL bUnrestrictedMVs; + OMX_BOOL bFourMV; + OMX_S32 sXSearchRange; + OMX_S32 sYSearchRange; +} OMX_VIDEO_PARAM_MOTIONVECTORTYPE; + + +/** + * Enumeration of possible methods to use for Intra Refresh + */ +typedef enum OMX_VIDEO_INTRAREFRESHTYPE { + OMX_VIDEO_IntraRefreshCyclic, + OMX_VIDEO_IntraRefreshAdaptive, + OMX_VIDEO_IntraRefreshBoth, + OMX_VIDEO_IntraRefreshKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_IntraRefreshVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_IntraRefreshRandom, + OMX_VIDEO_IntraRefreshMax = 0x7FFFFFFF +} OMX_VIDEO_INTRAREFRESHTYPE; + + +/** + * Structure for configuring intra refresh mode + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eRefreshMode : Cyclic, Adaptive, or Both + * nAirMBs : Number of intra macroblocks to refresh in a frame when + * AIR is enabled + * nAirRef : Number of times a motion marked macroblock has to be + * intra coded + * nCirMBs : Number of consecutive macroblocks to be coded as "intra" + * when CIR is enabled + */ +typedef struct OMX_VIDEO_PARAM_INTRAREFRESHTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_INTRAREFRESHTYPE eRefreshMode; + OMX_U32 nAirMBs; + OMX_U32 nAirRef; + OMX_U32 nCirMBs; +} OMX_VIDEO_PARAM_INTRAREFRESHTYPE; + + +/** + * Structure for enabling various error correction methods for video + * compression. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * bEnableHEC : Enable/disable header extension codes (HEC) + * bEnableResync : Enable/disable resynchronization markers + * nResynchMarkerSpacing : Resynch markers interval (in bits) to be + * applied in the stream + * bEnableDataPartitioning : Enable/disable data partitioning + * bEnableRVLC : Enable/disable reversible variable length + * coding + */ +typedef struct OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnableHEC; + OMX_BOOL bEnableResync; + OMX_U32 nResynchMarkerSpacing; + OMX_BOOL bEnableDataPartitioning; + OMX_BOOL bEnableRVLC; +} OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE; + + +/** + * Configuration of variable block-size motion compensation (VBSMC) + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * b16x16 : Enable inter block search 16x16 + * b16x8 : Enable inter block search 16x8 + * b8x16 : Enable inter block search 8x16 + * b8x8 : Enable inter block search 8x8 + * b8x4 : Enable inter block search 8x4 + * b4x8 : Enable inter block search 4x8 + * b4x4 : Enable inter block search 4x4 + */ +typedef struct OMX_VIDEO_PARAM_VBSMCTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL b16x16; + OMX_BOOL b16x8; + OMX_BOOL b8x16; + OMX_BOOL b8x8; + OMX_BOOL b8x4; + OMX_BOOL b4x8; + OMX_BOOL b4x4; +} OMX_VIDEO_PARAM_VBSMCTYPE; + + +/** + * H.263 profile types, each profile indicates support for various + * performance bounds and different annexes. + * + * ENUMS: + * Baseline : Baseline Profile: H.263 (V1), no optional modes + * H320 Coding : H.320 Coding Efficiency Backward Compatibility + * Profile: H.263+ (V2), includes annexes I, J, L.4 + * and T + * BackwardCompatible : Backward Compatibility Profile: H.263 (V1), + * includes annex F + * ISWV2 : Interactive Streaming Wireless Profile: H.263+ + * (V2), includes annexes I, J, K and T + * ISWV3 : Interactive Streaming Wireless Profile: H.263++ + * (V3), includes profile 3 and annexes V and W.6.3.8 + * HighCompression : Conversational High Compression Profile: H.263++ + * (V3), includes profiles 1 & 2 and annexes D and U + * Internet : Conversational Internet Profile: H.263++ (V3), + * includes profile 5 and annex K + * Interlace : Conversational Interlace Profile: H.263++ (V3), + * includes profile 5 and annex W.6.3.11 + * HighLatency : High Latency Profile: H.263++ (V3), includes + * profile 6 and annexes O.1 and P.5 + */ +typedef enum OMX_VIDEO_H263PROFILETYPE { + OMX_VIDEO_H263ProfileBaseline = 0x01, + OMX_VIDEO_H263ProfileH320Coding = 0x02, + OMX_VIDEO_H263ProfileBackwardCompatible = 0x04, + OMX_VIDEO_H263ProfileISWV2 = 0x08, + OMX_VIDEO_H263ProfileISWV3 = 0x10, + OMX_VIDEO_H263ProfileHighCompression = 0x20, + OMX_VIDEO_H263ProfileInternet = 0x40, + OMX_VIDEO_H263ProfileInterlace = 0x80, + OMX_VIDEO_H263ProfileHighLatency = 0x100, + OMX_VIDEO_H263ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_H263ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_H263ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_H263PROFILETYPE; + + +/** + * H.263 level types, each level indicates support for various frame sizes, + * bit rates, decoder frame rates. + */ +typedef enum OMX_VIDEO_H263LEVELTYPE { + OMX_VIDEO_H263Level10 = 0x01, + OMX_VIDEO_H263Level20 = 0x02, + OMX_VIDEO_H263Level30 = 0x04, + OMX_VIDEO_H263Level40 = 0x08, + OMX_VIDEO_H263Level45 = 0x10, + OMX_VIDEO_H263Level50 = 0x20, + OMX_VIDEO_H263Level60 = 0x40, + OMX_VIDEO_H263Level70 = 0x80, + OMX_VIDEO_H263LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_H263LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_H263LevelMax = 0x7FFFFFFF +} OMX_VIDEO_H263LEVELTYPE; + + +/** + * Specifies the picture type. These values should be OR'd to signal all + * pictures types which are allowed. + * + * ENUMS: + * Generic Picture Types: I, P and B + * H.263 Specific Picture Types: SI and SP + * H.264 Specific Picture Types: EI and EP + * MPEG-4 Specific Picture Types: S + */ +typedef enum OMX_VIDEO_PICTURETYPE { + OMX_VIDEO_PictureTypeI = 0x01, + OMX_VIDEO_PictureTypeP = 0x02, + OMX_VIDEO_PictureTypeB = 0x04, + OMX_VIDEO_PictureTypeSI = 0x08, + OMX_VIDEO_PictureTypeSP = 0x10, + OMX_VIDEO_PictureTypeEI = 0x11, + OMX_VIDEO_PictureTypeEP = 0x12, + OMX_VIDEO_PictureTypeS = 0x14, + OMX_VIDEO_PictureTypeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_PictureTypeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_PictureTypeMax = 0x7FFFFFFF +} OMX_VIDEO_PICTURETYPE; + + +/** + * H.263 Params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nPFrames : Number of P frames between each I frame + * nBFrames : Number of B frames between each I frame + * eProfile : H.263 profile(s) to use + * eLevel : H.263 level(s) to use + * bPLUSPTYPEAllowed : Indicating that it is allowed to use PLUSPTYPE + * (specified in the 1998 version of H.263) to + * indicate custom picture sizes or clock + * frequencies + * nAllowedPictureTypes : Specifies the picture types allowed in the + * bitstream + * bForceRoundingTypeToZero : value of the RTYPE bit (bit 6 of MPPTYPE) is + * not constrained. It is recommended to change + * the value of the RTYPE bit for each reference + * picture in error-free communication + * nPictureHeaderRepetition : Specifies the frequency of picture header + * repetition + * nGOBHeaderInterval : Specifies the interval of non-empty GOB + * headers in units of GOBs + */ +typedef struct OMX_VIDEO_PARAM_H263TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_VIDEO_H263PROFILETYPE eProfile; + OMX_VIDEO_H263LEVELTYPE eLevel; + OMX_BOOL bPLUSPTYPEAllowed; + OMX_U32 nAllowedPictureTypes; + OMX_BOOL bForceRoundingTypeToZero; + OMX_U32 nPictureHeaderRepetition; + OMX_U32 nGOBHeaderInterval; +} OMX_VIDEO_PARAM_H263TYPE; + + +/** + * MPEG-2 profile types, each profile indicates support for various + * performance bounds and different annexes. + */ +typedef enum OMX_VIDEO_MPEG2PROFILETYPE { + OMX_VIDEO_MPEG2ProfileSimple = 0, /**< Simple Profile */ + OMX_VIDEO_MPEG2ProfileMain, /**< Main Profile */ + OMX_VIDEO_MPEG2Profile422, /**< 4:2:2 Profile */ + OMX_VIDEO_MPEG2ProfileSNR, /**< SNR Profile */ + OMX_VIDEO_MPEG2ProfileSpatial, /**< Spatial Profile */ + OMX_VIDEO_MPEG2ProfileHigh, /**< High Profile */ + OMX_VIDEO_MPEG2ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG2ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG2ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG2PROFILETYPE; + + +/** + * MPEG-2 level types, each level indicates support for various frame + * sizes, bit rates, decoder frame rates. No need + */ +typedef enum OMX_VIDEO_MPEG2LEVELTYPE { + OMX_VIDEO_MPEG2LevelLL = 0, /**< Low Level */ + OMX_VIDEO_MPEG2LevelML, /**< Main Level */ + OMX_VIDEO_MPEG2LevelH14, /**< High 1440 */ + OMX_VIDEO_MPEG2LevelHL, /**< High Level */ + OMX_VIDEO_MPEG2LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG2LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG2LevelMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG2LEVELTYPE; + + +/** + * MPEG-2 params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nPFrames : Number of P frames between each I frame + * nBFrames : Number of B frames between each I frame + * eProfile : MPEG-2 profile(s) to use + * eLevel : MPEG-2 levels(s) to use + */ +typedef struct OMX_VIDEO_PARAM_MPEG2TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_VIDEO_MPEG2PROFILETYPE eProfile; + OMX_VIDEO_MPEG2LEVELTYPE eLevel; +} OMX_VIDEO_PARAM_MPEG2TYPE; + + +/** + * MPEG-4 profile types, each profile indicates support for various + * performance bounds and different annexes. + * + * ENUMS: + * - Simple Profile, Levels 1-3 + * - Simple Scalable Profile, Levels 1-2 + * - Core Profile, Levels 1-2 + * - Main Profile, Levels 2-4 + * - N-bit Profile, Level 2 + * - Scalable Texture Profile, Level 1 + * - Simple Face Animation Profile, Levels 1-2 + * - Simple Face and Body Animation (FBA) Profile, Levels 1-2 + * - Basic Animated Texture Profile, Levels 1-2 + * - Hybrid Profile, Levels 1-2 + * - Advanced Real Time Simple Profiles, Levels 1-4 + * - Core Scalable Profile, Levels 1-3 + * - Advanced Coding Efficiency Profile, Levels 1-4 + * - Advanced Core Profile, Levels 1-2 + * - Advanced Scalable Texture, Levels 2-3 + */ +typedef enum OMX_VIDEO_MPEG4PROFILETYPE { + OMX_VIDEO_MPEG4ProfileSimple = 0x01, + OMX_VIDEO_MPEG4ProfileSimpleScalable = 0x02, + OMX_VIDEO_MPEG4ProfileCore = 0x04, + OMX_VIDEO_MPEG4ProfileMain = 0x08, + OMX_VIDEO_MPEG4ProfileNbit = 0x10, + OMX_VIDEO_MPEG4ProfileScalableTexture = 0x20, + OMX_VIDEO_MPEG4ProfileSimpleFace = 0x40, + OMX_VIDEO_MPEG4ProfileSimpleFBA = 0x80, + OMX_VIDEO_MPEG4ProfileBasicAnimated = 0x100, + OMX_VIDEO_MPEG4ProfileHybrid = 0x200, + OMX_VIDEO_MPEG4ProfileAdvancedRealTime = 0x400, + OMX_VIDEO_MPEG4ProfileCoreScalable = 0x800, + OMX_VIDEO_MPEG4ProfileAdvancedCoding = 0x1000, + OMX_VIDEO_MPEG4ProfileAdvancedCore = 0x2000, + OMX_VIDEO_MPEG4ProfileAdvancedScalable = 0x4000, + OMX_VIDEO_MPEG4ProfileAdvancedSimple = 0x8000, + OMX_VIDEO_MPEG4ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG4ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG4ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG4PROFILETYPE; + + +/** + * MPEG-4 level types, each level indicates support for various frame + * sizes, bit rates, decoder frame rates. No need + */ +typedef enum OMX_VIDEO_MPEG4LEVELTYPE { + OMX_VIDEO_MPEG4Level0 = 0x01, /**< Level 0 */ + OMX_VIDEO_MPEG4Level0b = 0x02, /**< Level 0b */ + OMX_VIDEO_MPEG4Level1 = 0x04, /**< Level 1 */ + OMX_VIDEO_MPEG4Level2 = 0x08, /**< Level 2 */ + OMX_VIDEO_MPEG4Level3 = 0x10, /**< Level 3 */ + OMX_VIDEO_MPEG4Level4 = 0x20, /**< Level 4 */ + OMX_VIDEO_MPEG4Level4a = 0x40, /**< Level 4a */ + OMX_VIDEO_MPEG4Level5 = 0x80, /**< Level 5 */ + OMX_VIDEO_MPEG4LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG4LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG4LevelMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG4LEVELTYPE; + + +/** + * MPEG-4 configuration. This structure handles configuration options + * which are specific to MPEG4 algorithms + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nSliceHeaderSpacing : Number of macroblocks between slice header (H263+ + * Annex K). Put zero if not used + * bSVH : Enable Short Video Header mode + * bGov : Flag to enable GOV + * nPFrames : Number of P frames between each I frame (also called + * GOV period) + * nBFrames : Number of B frames between each I frame + * nIDCVLCThreshold : Value of intra DC VLC threshold + * bACPred : Flag to use ac prediction + * nMaxPacketSize : Maximum size of packet in bytes. + * nTimeIncRes : Used to pass VOP time increment resolution for MPEG4. + * Interpreted as described in MPEG4 standard. + * eProfile : MPEG-4 profile(s) to use. + * eLevel : MPEG-4 level(s) to use. + * nAllowedPictureTypes : Specifies the picture types allowed in the bitstream + * nHeaderExtension : Specifies the number of consecutive video packet + * headers within a VOP + * bReversibleVLC : Specifies whether reversible variable length coding + * is in use + */ +typedef struct OMX_VIDEO_PARAM_MPEG4TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nSliceHeaderSpacing; + OMX_BOOL bSVH; + OMX_BOOL bGov; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_U32 nIDCVLCThreshold; + OMX_BOOL bACPred; + OMX_U32 nMaxPacketSize; + OMX_U32 nTimeIncRes; + OMX_VIDEO_MPEG4PROFILETYPE eProfile; + OMX_VIDEO_MPEG4LEVELTYPE eLevel; + OMX_U32 nAllowedPictureTypes; + OMX_U32 nHeaderExtension; + OMX_BOOL bReversibleVLC; +} OMX_VIDEO_PARAM_MPEG4TYPE; + + +/** + * WMV Versions + */ +typedef enum OMX_VIDEO_WMVFORMATTYPE { + OMX_VIDEO_WMVFormatUnused = 0x01, /**< Format unused or unknown */ + OMX_VIDEO_WMVFormat7 = 0x02, /**< Windows Media Video format 7 */ + OMX_VIDEO_WMVFormat8 = 0x04, /**< Windows Media Video format 8 */ + OMX_VIDEO_WMVFormat9 = 0x08, /**< Windows Media Video format 9 */ + OMX_VIDEO_WMFFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_WMFFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_WMVFormatMax = 0x7FFFFFFF +} OMX_VIDEO_WMVFORMATTYPE; + + +/** + * WMV Params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFormat : Version of WMV stream / data + */ +typedef struct OMX_VIDEO_PARAM_WMVTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_WMVFORMATTYPE eFormat; +} OMX_VIDEO_PARAM_WMVTYPE; + + +/** + * Real Video Version + */ +typedef enum OMX_VIDEO_RVFORMATTYPE { + OMX_VIDEO_RVFormatUnused = 0, /**< Format unused or unknown */ + OMX_VIDEO_RVFormat8, /**< Real Video format 8 */ + OMX_VIDEO_RVFormat9, /**< Real Video format 9 */ + OMX_VIDEO_RVFormatG2, /**< Real Video Format G2 */ + OMX_VIDEO_RVFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_RVFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_RVFormatMax = 0x7FFFFFFF +} OMX_VIDEO_RVFORMATTYPE; + + +/** + * Real Video Params + * + * STUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFormat : Version of RV stream / data + * nBitsPerPixel : Bits per pixel coded in the frame + * nPaddedWidth : Padded width in pixel of a video frame + * nPaddedHeight : Padded Height in pixels of a video frame + * nFrameRate : Rate of video in frames per second + * nBitstreamFlags : Flags which internal information about the bitstream + * nBitstreamVersion : Bitstream version + * nMaxEncodeFrameSize: Max encoded frame size + * bEnablePostFilter : Turn on/off post filter + * bEnableTemporalInterpolation : Turn on/off temporal interpolation + * bEnableLatencyMode : When enabled, the decoder does not display a decoded + * frame until it has detected that no enhancement layer + * frames or dependent B frames will be coming. This + * detection usually occurs when a subsequent non-B + * frame is encountered + */ +typedef struct OMX_VIDEO_PARAM_RVTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_RVFORMATTYPE eFormat; + OMX_U16 nBitsPerPixel; + OMX_U16 nPaddedWidth; + OMX_U16 nPaddedHeight; + OMX_U32 nFrameRate; + OMX_U32 nBitstreamFlags; + OMX_U32 nBitstreamVersion; + OMX_U32 nMaxEncodeFrameSize; + OMX_BOOL bEnablePostFilter; + OMX_BOOL bEnableTemporalInterpolation; + OMX_BOOL bEnableLatencyMode; +} OMX_VIDEO_PARAM_RVTYPE; + + +/** + * AVC profile types, each profile indicates support for various + * performance bounds and different annexes. + */ +typedef enum OMX_VIDEO_AVCPROFILETYPE { + OMX_VIDEO_AVCProfileBaseline = 0x01, /**< Baseline profile */ + OMX_VIDEO_AVCProfileMain = 0x02, /**< Main profile */ + OMX_VIDEO_AVCProfileExtended = 0x04, /**< Extended profile */ + OMX_VIDEO_AVCProfileHigh = 0x08, /**< High profile */ + OMX_VIDEO_AVCProfileHigh10 = 0x10, /**< High 10 profile */ + OMX_VIDEO_AVCProfileHigh422 = 0x20, /**< High 4:2:2 profile */ + OMX_VIDEO_AVCProfileHigh444 = 0x40, /**< High 4:4:4 profile */ + OMX_VIDEO_AVCProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_AVCProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_AVCProfileMax = 0x7FFFFFFF +} OMX_VIDEO_AVCPROFILETYPE; + + +/** + * AVC level types, each level indicates support for various frame sizes, + * bit rates, decoder frame rates. No need + */ +typedef enum OMX_VIDEO_AVCLEVELTYPE { + OMX_VIDEO_AVCLevel1 = 0x01, /**< Level 1 */ + OMX_VIDEO_AVCLevel1b = 0x02, /**< Level 1b */ + OMX_VIDEO_AVCLevel11 = 0x04, /**< Level 1.1 */ + OMX_VIDEO_AVCLevel12 = 0x08, /**< Level 1.2 */ + OMX_VIDEO_AVCLevel13 = 0x10, /**< Level 1.3 */ + OMX_VIDEO_AVCLevel2 = 0x20, /**< Level 2 */ + OMX_VIDEO_AVCLevel21 = 0x40, /**< Level 2.1 */ + OMX_VIDEO_AVCLevel22 = 0x80, /**< Level 2.2 */ + OMX_VIDEO_AVCLevel3 = 0x100, /**< Level 3 */ + OMX_VIDEO_AVCLevel31 = 0x200, /**< Level 3.1 */ + OMX_VIDEO_AVCLevel32 = 0x400, /**< Level 3.2 */ + OMX_VIDEO_AVCLevel4 = 0x800, /**< Level 4 */ + OMX_VIDEO_AVCLevel41 = 0x1000, /**< Level 4.1 */ + OMX_VIDEO_AVCLevel42 = 0x2000, /**< Level 4.2 */ + OMX_VIDEO_AVCLevel5 = 0x4000, /**< Level 5 */ + OMX_VIDEO_AVCLevel51 = 0x8000, /**< Level 5.1 */ + OMX_VIDEO_AVCLevel52 = 0x10000, /**< Level 5.2 */ + OMX_VIDEO_AVCLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_AVCLevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_AVCLevelMax = 0x7FFFFFFF +} OMX_VIDEO_AVCLEVELTYPE; + + +/** + * AVC loop filter modes + * + * OMX_VIDEO_AVCLoopFilterEnable : Enable + * OMX_VIDEO_AVCLoopFilterDisable : Disable + * OMX_VIDEO_AVCLoopFilterDisableSliceBoundary : Disabled on slice boundaries + */ +typedef enum OMX_VIDEO_AVCLOOPFILTERTYPE { + OMX_VIDEO_AVCLoopFilterEnable = 0, + OMX_VIDEO_AVCLoopFilterDisable, + OMX_VIDEO_AVCLoopFilterDisableSliceBoundary, + OMX_VIDEO_AVCLoopFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_AVCLoopFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_AVCLoopFilterMax = 0x7FFFFFFF +} OMX_VIDEO_AVCLOOPFILTERTYPE; + + +/** + * AVC params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nSliceHeaderSpacing : Number of macroblocks between slice header, put + * zero if not used + * nPFrames : Number of P frames between each I frame + * nBFrames : Number of B frames between each I frame + * bUseHadamard : Enable/disable Hadamard transform + * nRefFrames : Max number of reference frames to use for inter + * motion search (1-16) + * nRefIdxTrailing : Pic param set ref frame index (index into ref + * frame buffer of trailing frames list), B frame + * support + * nRefIdxForward : Pic param set ref frame index (index into ref + * frame buffer of forward frames list), B frame + * support + * bEnableUEP : Enable/disable unequal error protection. This + * is only valid of data partitioning is enabled. + * bEnableFMO : Enable/disable flexible macroblock ordering + * bEnableASO : Enable/disable arbitrary slice ordering + * bEnableRS : Enable/disable sending of redundant slices + * eProfile : AVC profile(s) to use + * eLevel : AVC level(s) to use + * nAllowedPictureTypes : Specifies the picture types allowed in the + * bitstream + * bFrameMBsOnly : specifies that every coded picture of the + * coded video sequence is a coded frame + * containing only frame macroblocks + * bMBAFF : Enable/disable switching between frame and + * field macroblocks within a picture + * bEntropyCodingCABAC : Entropy decoding method to be applied for the + * syntax elements for which two descriptors appear + * in the syntax tables + * bWeightedPPrediction : Enable/disable weighted prediction shall not + * be applied to P and SP slices + * nWeightedBipredicitonMode : Default weighted prediction is applied to B + * slices + * bconstIpred : Enable/disable intra prediction + * bDirect8x8Inference : Specifies the method used in the derivation + * process for luma motion vectors for B_Skip, + * B_Direct_16x16 and B_Direct_8x8 as specified + * in subclause 8.4.1.2 of the AVC spec + * bDirectSpatialTemporal : Flag indicating spatial or temporal direct + * mode used in B slice coding (related to + * bDirect8x8Inference) . Spatial direct mode is + * more common and should be the default. + * nCabacInitIdx : Index used to init CABAC contexts + * eLoopFilterMode : Enable/disable loop filter + */ +typedef struct OMX_VIDEO_PARAM_AVCTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nSliceHeaderSpacing; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_BOOL bUseHadamard; + OMX_U32 nRefFrames; + OMX_U32 nRefIdx10ActiveMinus1; + OMX_U32 nRefIdx11ActiveMinus1; + OMX_BOOL bEnableUEP; + OMX_BOOL bEnableFMO; + OMX_BOOL bEnableASO; + OMX_BOOL bEnableRS; + OMX_VIDEO_AVCPROFILETYPE eProfile; + OMX_VIDEO_AVCLEVELTYPE eLevel; + OMX_U32 nAllowedPictureTypes; + OMX_BOOL bFrameMBsOnly; + OMX_BOOL bMBAFF; + OMX_BOOL bEntropyCodingCABAC; + OMX_BOOL bWeightedPPrediction; + OMX_U32 nWeightedBipredicitonMode; + OMX_BOOL bconstIpred ; + OMX_BOOL bDirect8x8Inference; + OMX_BOOL bDirectSpatialTemporal; + OMX_U32 nCabacInitIdc; + OMX_VIDEO_AVCLOOPFILTERTYPE eLoopFilterMode; +} OMX_VIDEO_PARAM_AVCTYPE; + +typedef struct OMX_VIDEO_PARAM_PROFILELEVELTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 eProfile; /**< type is OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE, + or OMX_VIDEO_MPEG4PROFILETYPE depending on context */ + OMX_U32 eLevel; /**< type is OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE, + or OMX_VIDEO_MPEG4PROFILETYPE depending on context */ + OMX_U32 nProfileIndex; /**< Used to query for individual profile support information, + This parameter is valid only for + OMX_IndexParamVideoProfileLevelQuerySupported index, + For all other indices this parameter is to be ignored. */ +} OMX_VIDEO_PARAM_PROFILELEVELTYPE; + +/** + * Structure for dynamically configuring bitrate mode of a codec. + * + * STRUCT MEMBERS: + * nSize : Size of the struct in bytes + * nVersion : OMX spec version info + * nPortIndex : Port that this struct applies to + * nEncodeBitrate : Target average bitrate to be generated in bps + */ +typedef struct OMX_VIDEO_CONFIG_BITRATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nEncodeBitrate; +} OMX_VIDEO_CONFIG_BITRATETYPE; + +/** + * Defines Encoder Frame Rate setting + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * xEncodeFramerate : Encoding framerate represented in Q16 format + */ +typedef struct OMX_CONFIG_FRAMERATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 xEncodeFramerate; /* Q16 format */ +} OMX_CONFIG_FRAMERATETYPE; + +typedef struct OMX_CONFIG_INTRAREFRESHVOPTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL IntraRefreshVOP; +} OMX_CONFIG_INTRAREFRESHVOPTYPE; + +typedef struct OMX_CONFIG_MACROBLOCKERRORMAPTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nErrMapSize; /* Size of the Error Map in bytes */ + OMX_U8 ErrMap[1]; /* Error map hint */ +} OMX_CONFIG_MACROBLOCKERRORMAPTYPE; + +typedef struct OMX_CONFIG_MBERRORREPORTINGTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnabled; +} OMX_CONFIG_MBERRORREPORTINGTYPE; + +typedef struct OMX_PARAM_MACROBLOCKSTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nMacroblocks; +} OMX_PARAM_MACROBLOCKSTYPE; + +/** + * AVC Slice Mode modes + * + * OMX_VIDEO_SLICEMODE_AVCDefault : Normal frame encoding, one slice per frame + * OMX_VIDEO_SLICEMODE_AVCMBSlice : NAL mode, number of MBs per frame + * OMX_VIDEO_SLICEMODE_AVCByteSlice : NAL mode, number of bytes per frame + */ +typedef enum OMX_VIDEO_AVCSLICEMODETYPE { + OMX_VIDEO_SLICEMODE_AVCDefault = 0, + OMX_VIDEO_SLICEMODE_AVCMBSlice, + OMX_VIDEO_SLICEMODE_AVCByteSlice, + OMX_VIDEO_SLICEMODE_AVCKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_SLICEMODE_AVCVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_SLICEMODE_AVCLevelMax = 0x7FFFFFFF +} OMX_VIDEO_AVCSLICEMODETYPE; + +/** + * AVC FMO Slice Mode Params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nNumSliceGroups : Specifies the number of slice groups + * nSliceGroupMapType : Specifies the type of slice groups + * eSliceMode : Specifies the type of slice + */ +typedef struct OMX_VIDEO_PARAM_AVCSLICEFMO { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U8 nNumSliceGroups; + OMX_U8 nSliceGroupMapType; + OMX_VIDEO_AVCSLICEMODETYPE eSliceMode; +} OMX_VIDEO_PARAM_AVCSLICEFMO; + +/** + * AVC IDR Period Configs + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nIDRPeriod : Specifies periodicity of IDR frames + * nPFrames : Specifies internal of coding Intra frames + */ +typedef struct OMX_VIDEO_CONFIG_AVCINTRAPERIOD { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nIDRPeriod; + OMX_U32 nPFrames; +} OMX_VIDEO_CONFIG_AVCINTRAPERIOD; + +/** + * AVC NAL Size Configs + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nNaluBytes : Specifies the NAL unit size + */ +typedef struct OMX_VIDEO_CONFIG_NALSIZE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nNaluBytes; +} OMX_VIDEO_CONFIG_NALSIZE; + + +/** + * Deinterlace Config + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nEnable : Specifies to enable deinterlace + */ +typedef struct OMX_VIDEO_CONFIG_DEINTERLACE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nEnable; +} OMX_VIDEO_CONFIG_DEINTERLACE; + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ + diff --git a/phonelibs/openmax/include/OMX_VideoExt.h b/phonelibs/openmax/include/OMX_VideoExt.h new file mode 100644 index 00000000000000..5bf6fd48786405 --- /dev/null +++ b/phonelibs/openmax/include/OMX_VideoExt.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2010 The Khronos Group Inc. + * + * 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. + * + */ + +/** OMX_VideoExt.h - OpenMax IL version 1.1.2 + * The OMX_VideoExt header file contains extensions to the + * definitions used by both the application and the component to + * access video items. + */ + +#ifndef OMX_VideoExt_h +#define OMX_VideoExt_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Each OMX header shall include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ +#include + +/** NALU Formats */ +typedef enum OMX_NALUFORMATSTYPE { + OMX_NaluFormatStartCodes = 1, + OMX_NaluFormatOneNaluPerBuffer = 2, + OMX_NaluFormatOneByteInterleaveLength = 4, + OMX_NaluFormatTwoByteInterleaveLength = 8, + OMX_NaluFormatFourByteInterleaveLength = 16, + OMX_NaluFormatCodingMax = 0x7FFFFFFF +} OMX_NALUFORMATSTYPE; + +/** NAL Stream Format */ +typedef struct OMX_NALSTREAMFORMATTYPE{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_NALUFORMATSTYPE eNaluFormat; +} OMX_NALSTREAMFORMATTYPE; + +/** VP8 profiles */ +typedef enum OMX_VIDEO_VP8PROFILETYPE { + OMX_VIDEO_VP8ProfileMain = 0x01, + OMX_VIDEO_VP8ProfileUnknown = 0x6EFFFFFF, + OMX_VIDEO_VP8ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_VP8PROFILETYPE; + +/** VP8 levels */ +typedef enum OMX_VIDEO_VP8LEVELTYPE { + OMX_VIDEO_VP8Level_Version0 = 0x01, + OMX_VIDEO_VP8Level_Version1 = 0x02, + OMX_VIDEO_VP8Level_Version2 = 0x04, + OMX_VIDEO_VP8Level_Version3 = 0x08, + OMX_VIDEO_VP8LevelUnknown = 0x6EFFFFFF, + OMX_VIDEO_VP8LevelMax = 0x7FFFFFFF +} OMX_VIDEO_VP8LEVELTYPE; + +/** VP8 Param */ +typedef struct OMX_VIDEO_PARAM_VP8TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_VP8PROFILETYPE eProfile; + OMX_VIDEO_VP8LEVELTYPE eLevel; + OMX_U32 nDCTPartitions; + OMX_BOOL bErrorResilientMode; +} OMX_VIDEO_PARAM_VP8TYPE; + +/** Structure for configuring VP8 reference frames */ +typedef struct OMX_VIDEO_VP8REFERENCEFRAMETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bPreviousFrameRefresh; + OMX_BOOL bGoldenFrameRefresh; + OMX_BOOL bAlternateFrameRefresh; + OMX_BOOL bUsePreviousFrame; + OMX_BOOL bUseGoldenFrame; + OMX_BOOL bUseAlternateFrame; +} OMX_VIDEO_VP8REFERENCEFRAMETYPE; + +/** Structure for querying VP8 reference frame type */ +typedef struct OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bIsIntraFrame; + OMX_BOOL bIsGoldenOrAlternateFrame; +} OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE; + +/** HEVC Profiles */ +typedef enum OMX_VIDEO_HEVCPROFILETYPE { + OMX_VIDEO_HEVCProfileMain = 0x01, + OMX_VIDEO_HEVCProfileMain10 = 0x02, + OMX_VIDEO_HEVCProfileUnknown = 0x6EFFFFFF, + OMX_VIDEO_HEVCProfileMax = 0x7FFFFFFF +} OMX_VIDEO_HEVCPROFILETYPE; + +/** HEVC levels */ +typedef enum OMX_VIDEO_HEVCLEVELTYPE { + OMX_VIDEO_HEVCLevel_Version0 = 0x0, + OMX_VIDEO_HEVCMainTierLevel1 = 0x1, + OMX_VIDEO_HEVCHighTierLevel1 = 0x2, + OMX_VIDEO_HEVCMainTierLevel2 = 0x4, + OMX_VIDEO_HEVCHighTierLevel2 = 0x8, + OMX_VIDEO_HEVCMainTierLevel21 = 0x10, + OMX_VIDEO_HEVCHighTierLevel21 = 0x20, + OMX_VIDEO_HEVCMainTierLevel3 = 0x40, + OMX_VIDEO_HEVCHighTierLevel3 = 0x80, + OMX_VIDEO_HEVCMainTierLevel31 = 0x100, + OMX_VIDEO_HEVCHighTierLevel31 = 0x200, + OMX_VIDEO_HEVCMainTierLevel4 = 0x400, + OMX_VIDEO_HEVCHighTierLevel4 = 0x800, + OMX_VIDEO_HEVCMainTierLevel41 = 0x1000, + OMX_VIDEO_HEVCHighTierLevel41 = 0x2000, + OMX_VIDEO_HEVCMainTierLevel5 = 0x4000, + OMX_VIDEO_HEVCHighTierLevel5 = 0x8000, + OMX_VIDEO_HEVCMainTierLevel51 = 0x10000, + OMX_VIDEO_HEVCHighTierLevel51 = 0x20000, + OMX_VIDEO_HEVCMainTierLevel52 = 0x40000, + OMX_VIDEO_HEVCHighTierLevel52 = 0x80000, + OMX_VIDEO_HEVCMainTierLevel6 = 0x100000, + OMX_VIDEO_HEVCHighTierLevel6 = 0x200000, + OMX_VIDEO_HEVCMainTierLevel61 = 0x400000, + OMX_VIDEO_HEVCHighTierLevel61 = 0x800000, + OMX_VIDEO_HEVCMainTierLevel62 = 0x1000000, + OMX_VIDEO_HEVCLevelUnknown = 0x6EFFFFFF, + OMX_VIDEO_HEVCLevelMax = 0x7FFFFFFF +} OMX_VIDEO_HEVCLEVELTYPE; + +/** HEVC Param */ +typedef struct OMX_VIDEO_PARAM_HEVCTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_HEVCPROFILETYPE eProfile; + OMX_VIDEO_HEVCLEVELTYPE eLevel; +} OMX_VIDEO_PARAM_HEVCTYPE; + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* OMX_VideoExt_h */ +/* File EOF */ diff --git a/phonelibs/snpe/x86_64-linux-clang/libSNPE.so b/phonelibs/snpe/x86_64-linux-clang/libSNPE.so new file mode 100644 index 00000000000000..cc1de85075bfba Binary files /dev/null and b/phonelibs/snpe/x86_64-linux-clang/libSNPE.so differ diff --git a/phonelibs/snpe/x86_64-linux-clang/libsymphony-cpu.so b/phonelibs/snpe/x86_64-linux-clang/libsymphony-cpu.so new file mode 100755 index 00000000000000..70d6f146a34a0a Binary files /dev/null and b/phonelibs/snpe/x86_64-linux-clang/libsymphony-cpu.so differ diff --git a/phonelibs/yaml-cpp/LICENSE b/phonelibs/yaml-cpp/LICENSE new file mode 100644 index 00000000000000..991fdbbe7d3d03 --- /dev/null +++ b/phonelibs/yaml-cpp/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2008-2015 Jesse Beder. + +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. diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/anchor.h b/phonelibs/yaml-cpp/include/yaml-cpp/anchor.h new file mode 100644 index 00000000000000..06759c724d28e8 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/anchor.h @@ -0,0 +1,17 @@ +#ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include + +namespace YAML { +typedef std::size_t anchor_t; +const anchor_t NullAnchor = 0; +} + +#endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/binary.h b/phonelibs/yaml-cpp/include/yaml-cpp/binary.h new file mode 100644 index 00000000000000..29d5dbd027a94b --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/binary.h @@ -0,0 +1,67 @@ +#ifndef BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include + +#include "yaml-cpp/dll.h" + +namespace YAML { +YAML_CPP_API std::string EncodeBase64(const unsigned char *data, + std::size_t size); +YAML_CPP_API std::vector DecodeBase64(const std::string &input); + +class YAML_CPP_API Binary { + public: + Binary() : m_unownedData(0), m_unownedSize(0) {} + Binary(const unsigned char *data_, std::size_t size_) + : m_unownedData(data_), m_unownedSize(size_) {} + + bool owned() const { return !m_unownedData; } + std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; } + const unsigned char *data() const { + return owned() ? &m_data[0] : m_unownedData; + } + + void swap(std::vector &rhs) { + if (m_unownedData) { + m_data.swap(rhs); + rhs.clear(); + rhs.resize(m_unownedSize); + std::copy(m_unownedData, m_unownedData + m_unownedSize, rhs.begin()); + m_unownedData = 0; + m_unownedSize = 0; + } else { + m_data.swap(rhs); + } + } + + bool operator==(const Binary &rhs) const { + const std::size_t s = size(); + if (s != rhs.size()) + return false; + const unsigned char *d1 = data(); + const unsigned char *d2 = rhs.data(); + for (std::size_t i = 0; i < s; i++) { + if (*d1++ != *d2++) + return false; + } + return true; + } + + bool operator!=(const Binary &rhs) const { return !(*this == rhs); } + + private: + std::vector m_data; + const unsigned char *m_unownedData; + std::size_t m_unownedSize; +}; +} + +#endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/contrib/anchordict.h b/phonelibs/yaml-cpp/include/yaml-cpp/contrib/anchordict.h new file mode 100644 index 00000000000000..78db9ec9288275 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/contrib/anchordict.h @@ -0,0 +1,39 @@ +#ifndef ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include + +#include "../anchor.h" + +namespace YAML { +/** + * An object that stores and retrieves values correlating to {@link anchor_t} + * values. + * + *

Efficient implementation that can make assumptions about how + * {@code anchor_t} values are assigned by the {@link Parser} class. + */ +template +class AnchorDict { + public: + void Register(anchor_t anchor, T value) { + if (anchor > m_data.size()) { + m_data.resize(anchor); + } + m_data[anchor - 1] = value; + } + + T Get(anchor_t anchor) const { return m_data[anchor - 1]; } + + private: + std::vector m_data; +}; +} + +#endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h b/phonelibs/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h new file mode 100644 index 00000000000000..7c2159b4659742 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/contrib/graphbuilder.h @@ -0,0 +1,147 @@ +#ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/mark.h" +#include + +namespace YAML { +class Parser; + +// GraphBuilderInterface +// . Abstraction of node creation +// . pParentNode is always NULL or the return value of one of the NewXXX() +// functions. +class GraphBuilderInterface { + public: + // Create and return a new node with a null value. + virtual void *NewNull(const Mark &mark, void *pParentNode) = 0; + + // Create and return a new node with the given tag and value. + virtual void *NewScalar(const Mark &mark, const std::string &tag, + void *pParentNode, const std::string &value) = 0; + + // Create and return a new sequence node + virtual void *NewSequence(const Mark &mark, const std::string &tag, + void *pParentNode) = 0; + + // Add pNode to pSequence. pNode was created with one of the NewXxx() + // functions and pSequence with NewSequence(). + virtual void AppendToSequence(void *pSequence, void *pNode) = 0; + + // Note that no moew entries will be added to pSequence + virtual void SequenceComplete(void *pSequence) { (void)pSequence; } + + // Create and return a new map node + virtual void *NewMap(const Mark &mark, const std::string &tag, + void *pParentNode) = 0; + + // Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode + // were created with one of the NewXxx() methods and pMap with NewMap(). + virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0; + + // Note that no more assignments will be made in pMap + virtual void MapComplete(void *pMap) { (void)pMap; } + + // Return the node that should be used in place of an alias referencing + // pNode (pNode by default) + virtual void *AnchorReference(const Mark &mark, void *pNode) { + (void)mark; + return pNode; + } +}; + +// Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines +// Node, Sequence, and Map types. Sequence and Map must derive from Node +// (unless Node is defined as void). Impl must also implement function with +// all of the same names as the virtual functions in GraphBuilderInterface +// -- including the ones with default implementations -- but with the +// prototypes changed to accept an explicit Node*, Sequence*, or Map* where +// appropriate. +template +class GraphBuilder : public GraphBuilderInterface { + public: + typedef typename Impl::Node Node; + typedef typename Impl::Sequence Sequence; + typedef typename Impl::Map Map; + + GraphBuilder(Impl &impl) : m_impl(impl) { + Map *pMap = NULL; + Sequence *pSeq = NULL; + Node *pNode = NULL; + + // Type consistency checks + pNode = pMap; + pNode = pSeq; + } + + GraphBuilderInterface &AsBuilderInterface() { return *this; } + + virtual void *NewNull(const Mark &mark, void *pParentNode) { + return CheckType(m_impl.NewNull(mark, AsNode(pParentNode))); + } + + virtual void *NewScalar(const Mark &mark, const std::string &tag, + void *pParentNode, const std::string &value) { + return CheckType( + m_impl.NewScalar(mark, tag, AsNode(pParentNode), value)); + } + + virtual void *NewSequence(const Mark &mark, const std::string &tag, + void *pParentNode) { + return CheckType( + m_impl.NewSequence(mark, tag, AsNode(pParentNode))); + } + virtual void AppendToSequence(void *pSequence, void *pNode) { + m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode)); + } + virtual void SequenceComplete(void *pSequence) { + m_impl.SequenceComplete(AsSequence(pSequence)); + } + + virtual void *NewMap(const Mark &mark, const std::string &tag, + void *pParentNode) { + return CheckType(m_impl.NewMap(mark, tag, AsNode(pParentNode))); + } + virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) { + m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode)); + } + virtual void MapComplete(void *pMap) { m_impl.MapComplete(AsMap(pMap)); } + + virtual void *AnchorReference(const Mark &mark, void *pNode) { + return CheckType(m_impl.AnchorReference(mark, AsNode(pNode))); + } + + private: + Impl &m_impl; + + // Static check for pointer to T + template + static T *CheckType(U *p) { + return p; + } + + static Node *AsNode(void *pNode) { return static_cast(pNode); } + static Sequence *AsSequence(void *pSeq) { + return static_cast(pSeq); + } + static Map *AsMap(void *pMap) { return static_cast(pMap); } +}; + +void *BuildGraphOfNextDocument(Parser &parser, + GraphBuilderInterface &graphBuilder); + +template +typename Impl::Node *BuildGraphOfNextDocument(Parser &parser, Impl &impl) { + GraphBuilder graphBuilder(impl); + return static_cast( + BuildGraphOfNextDocument(parser, graphBuilder)); +} +} + +#endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/dll.h b/phonelibs/yaml-cpp/include/yaml-cpp/dll.h new file mode 100644 index 00000000000000..a32c06b2e308aa --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/dll.h @@ -0,0 +1,33 @@ +#ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +// The following ifdef block is the standard way of creating macros which make +// exporting from a DLL simpler. All files within this DLL are compiled with the +// yaml_cpp_EXPORTS symbol defined on the command line. This symbol should not +// be defined on any project that uses this DLL. This way any other project +// whose source files include this file see YAML_CPP_API functions as being +// imported from a DLL, whereas this DLL sees symbols defined with this macro as +// being exported. +#undef YAML_CPP_API + +#ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined + // manually) +#ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake + // or defined manually) +// #pragma message( "Defining YAML_CPP_API for DLL export" ) +#define YAML_CPP_API __declspec(dllexport) +#else // yaml_cpp_EXPORTS +// #pragma message( "Defining YAML_CPP_API for DLL import" ) +#define YAML_CPP_API __declspec(dllimport) +#endif // yaml_cpp_EXPORTS +#else // YAML_CPP_DLL +#define YAML_CPP_API +#endif // YAML_CPP_DLL + +#endif // DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/emitfromevents.h b/phonelibs/yaml-cpp/include/yaml-cpp/emitfromevents.h new file mode 100644 index 00000000000000..f14b051ab0ee8b --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/emitfromevents.h @@ -0,0 +1,57 @@ +#ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include + +#include "yaml-cpp/anchor.h" +#include "yaml-cpp/emitterstyle.h" +#include "yaml-cpp/eventhandler.h" + +namespace YAML { +struct Mark; +} // namespace YAML + +namespace YAML { +class Emitter; + +class EmitFromEvents : public EventHandler { + public: + EmitFromEvents(Emitter& emitter); + + virtual void OnDocumentStart(const Mark& mark); + virtual void OnDocumentEnd(); + + virtual void OnNull(const Mark& mark, anchor_t anchor); + virtual void OnAlias(const Mark& mark, anchor_t anchor); + virtual void OnScalar(const Mark& mark, const std::string& tag, + anchor_t anchor, const std::string& value); + + virtual void OnSequenceStart(const Mark& mark, const std::string& tag, + anchor_t anchor, EmitterStyle::value style); + virtual void OnSequenceEnd(); + + virtual void OnMapStart(const Mark& mark, const std::string& tag, + anchor_t anchor, EmitterStyle::value style); + virtual void OnMapEnd(); + + private: + void BeginNode(); + void EmitProps(const std::string& tag, anchor_t anchor); + + private: + Emitter& m_emitter; + + struct State { + enum value { WaitingForSequenceEntry, WaitingForKey, WaitingForValue }; + }; + std::stack m_stateStack; +}; +} + +#endif // EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/emitter.h b/phonelibs/yaml-cpp/include/yaml-cpp/emitter.h new file mode 100644 index 00000000000000..ef92cc4035b441 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/emitter.h @@ -0,0 +1,254 @@ +#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include +#include +#include + +#include "yaml-cpp/binary.h" +#include "yaml-cpp/dll.h" +#include "yaml-cpp/emitterdef.h" +#include "yaml-cpp/emittermanip.h" +#include "yaml-cpp/noncopyable.h" +#include "yaml-cpp/null.h" +#include "yaml-cpp/ostream_wrapper.h" + +namespace YAML { +class Binary; +struct _Null; +} // namespace YAML + +namespace YAML { +class EmitterState; + +class YAML_CPP_API Emitter : private noncopyable { + public: + Emitter(); + explicit Emitter(std::ostream& stream); + ~Emitter(); + + // output + const char* c_str() const; + std::size_t size() const; + + // state checking + bool good() const; + const std::string GetLastError() const; + + // global setters + bool SetOutputCharset(EMITTER_MANIP value); + bool SetStringFormat(EMITTER_MANIP value); + bool SetBoolFormat(EMITTER_MANIP value); + bool SetIntBase(EMITTER_MANIP value); + bool SetSeqFormat(EMITTER_MANIP value); + bool SetMapFormat(EMITTER_MANIP value); + bool SetIndent(std::size_t n); + bool SetPreCommentIndent(std::size_t n); + bool SetPostCommentIndent(std::size_t n); + bool SetFloatPrecision(std::size_t n); + bool SetDoublePrecision(std::size_t n); + + // local setters + Emitter& SetLocalValue(EMITTER_MANIP value); + Emitter& SetLocalIndent(const _Indent& indent); + Emitter& SetLocalPrecision(const _Precision& precision); + + // overloads of write + Emitter& Write(const std::string& str); + Emitter& Write(bool b); + Emitter& Write(char ch); + Emitter& Write(const _Alias& alias); + Emitter& Write(const _Anchor& anchor); + Emitter& Write(const _Tag& tag); + Emitter& Write(const _Comment& comment); + Emitter& Write(const _Null& n); + Emitter& Write(const Binary& binary); + + template + Emitter& WriteIntegralType(T value); + + template + Emitter& WriteStreamable(T value); + + private: + template + void SetStreamablePrecision(std::stringstream&) {} + std::size_t GetFloatPrecision() const; + std::size_t GetDoublePrecision() const; + + void PrepareIntegralStream(std::stringstream& stream) const; + void StartedScalar(); + + private: + void EmitBeginDoc(); + void EmitEndDoc(); + void EmitBeginSeq(); + void EmitEndSeq(); + void EmitBeginMap(); + void EmitEndMap(); + void EmitNewline(); + void EmitKindTag(); + void EmitTag(bool verbatim, const _Tag& tag); + + void PrepareNode(EmitterNodeType::value child); + void PrepareTopNode(EmitterNodeType::value child); + void FlowSeqPrepareNode(EmitterNodeType::value child); + void BlockSeqPrepareNode(EmitterNodeType::value child); + + void FlowMapPrepareNode(EmitterNodeType::value child); + + void FlowMapPrepareLongKey(EmitterNodeType::value child); + void FlowMapPrepareLongKeyValue(EmitterNodeType::value child); + void FlowMapPrepareSimpleKey(EmitterNodeType::value child); + void FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child); + + void BlockMapPrepareNode(EmitterNodeType::value child); + + void BlockMapPrepareLongKey(EmitterNodeType::value child); + void BlockMapPrepareLongKeyValue(EmitterNodeType::value child); + void BlockMapPrepareSimpleKey(EmitterNodeType::value child); + void BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child); + + void SpaceOrIndentTo(bool requireSpace, std::size_t indent); + + const char* ComputeFullBoolName(bool b) const; + bool CanEmitNewline() const; + + private: + std::unique_ptr m_pState; + ostream_wrapper m_stream; +}; + +template +inline Emitter& Emitter::WriteIntegralType(T value) { + if (!good()) + return *this; + + PrepareNode(EmitterNodeType::Scalar); + + std::stringstream stream; + PrepareIntegralStream(stream); + stream << value; + m_stream << stream.str(); + + StartedScalar(); + + return *this; +} + +template +inline Emitter& Emitter::WriteStreamable(T value) { + if (!good()) + return *this; + + PrepareNode(EmitterNodeType::Scalar); + + std::stringstream stream; + SetStreamablePrecision(stream); + stream << value; + m_stream << stream.str(); + + StartedScalar(); + + return *this; +} + +template <> +inline void Emitter::SetStreamablePrecision(std::stringstream& stream) { + stream.precision(static_cast(GetFloatPrecision())); +} + +template <> +inline void Emitter::SetStreamablePrecision(std::stringstream& stream) { + stream.precision(static_cast(GetDoublePrecision())); +} + +// overloads of insertion +inline Emitter& operator<<(Emitter& emitter, const std::string& v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, bool v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, char v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, unsigned char v) { + return emitter.Write(static_cast(v)); +} +inline Emitter& operator<<(Emitter& emitter, const _Alias& v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, const _Anchor& v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, const _Tag& v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, const _Comment& v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, const _Null& v) { + return emitter.Write(v); +} +inline Emitter& operator<<(Emitter& emitter, const Binary& b) { + return emitter.Write(b); +} + +inline Emitter& operator<<(Emitter& emitter, const char* v) { + return emitter.Write(std::string(v)); +} + +inline Emitter& operator<<(Emitter& emitter, int v) { + return emitter.WriteIntegralType(v); +} +inline Emitter& operator<<(Emitter& emitter, unsigned int v) { + return emitter.WriteIntegralType(v); +} +inline Emitter& operator<<(Emitter& emitter, short v) { + return emitter.WriteIntegralType(v); +} +inline Emitter& operator<<(Emitter& emitter, unsigned short v) { + return emitter.WriteIntegralType(v); +} +inline Emitter& operator<<(Emitter& emitter, long v) { + return emitter.WriteIntegralType(v); +} +inline Emitter& operator<<(Emitter& emitter, unsigned long v) { + return emitter.WriteIntegralType(v); +} +inline Emitter& operator<<(Emitter& emitter, long long v) { + return emitter.WriteIntegralType(v); +} +inline Emitter& operator<<(Emitter& emitter, unsigned long long v) { + return emitter.WriteIntegralType(v); +} + +inline Emitter& operator<<(Emitter& emitter, float v) { + return emitter.WriteStreamable(v); +} +inline Emitter& operator<<(Emitter& emitter, double v) { + return emitter.WriteStreamable(v); +} + +inline Emitter& operator<<(Emitter& emitter, EMITTER_MANIP value) { + return emitter.SetLocalValue(value); +} + +inline Emitter& operator<<(Emitter& emitter, _Indent indent) { + return emitter.SetLocalIndent(indent); +} + +inline Emitter& operator<<(Emitter& emitter, _Precision precision) { + return emitter.SetLocalPrecision(precision); +} +} + +#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/emitterdef.h b/phonelibs/yaml-cpp/include/yaml-cpp/emitterdef.h new file mode 100644 index 00000000000000..0b426957fae276 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/emitterdef.h @@ -0,0 +1,16 @@ +#ifndef EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +namespace YAML { +struct EmitterNodeType { + enum value { NoType, Property, Scalar, FlowSeq, BlockSeq, FlowMap, BlockMap }; +}; +} + +#endif // EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/emittermanip.h b/phonelibs/yaml-cpp/include/yaml-cpp/emittermanip.h new file mode 100644 index 00000000000000..89f7256714e30f --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/emittermanip.h @@ -0,0 +1,137 @@ +#ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include + +namespace YAML { +enum EMITTER_MANIP { + // general manipulators + Auto, + TagByKind, + Newline, + + // output character set + EmitNonAscii, + EscapeNonAscii, + + // string manipulators + // Auto, // duplicate + SingleQuoted, + DoubleQuoted, + Literal, + + // bool manipulators + YesNoBool, // yes, no + TrueFalseBool, // true, false + OnOffBool, // on, off + UpperCase, // TRUE, N + LowerCase, // f, yes + CamelCase, // No, Off + LongBool, // yes, On + ShortBool, // y, t + + // int manipulators + Dec, + Hex, + Oct, + + // document manipulators + BeginDoc, + EndDoc, + + // sequence manipulators + BeginSeq, + EndSeq, + Flow, + Block, + + // map manipulators + BeginMap, + EndMap, + Key, + Value, + // Flow, // duplicate + // Block, // duplicate + // Auto, // duplicate + LongKey +}; + +struct _Indent { + _Indent(int value_) : value(value_) {} + int value; +}; + +inline _Indent Indent(int value) { return _Indent(value); } + +struct _Alias { + _Alias(const std::string& content_) : content(content_) {} + std::string content; +}; + +inline _Alias Alias(const std::string content) { return _Alias(content); } + +struct _Anchor { + _Anchor(const std::string& content_) : content(content_) {} + std::string content; +}; + +inline _Anchor Anchor(const std::string content) { return _Anchor(content); } + +struct _Tag { + struct Type { + enum value { Verbatim, PrimaryHandle, NamedHandle }; + }; + + explicit _Tag(const std::string& prefix_, const std::string& content_, + Type::value type_) + : prefix(prefix_), content(content_), type(type_) {} + std::string prefix; + std::string content; + Type::value type; +}; + +inline _Tag VerbatimTag(const std::string content) { + return _Tag("", content, _Tag::Type::Verbatim); +} + +inline _Tag LocalTag(const std::string content) { + return _Tag("", content, _Tag::Type::PrimaryHandle); +} + +inline _Tag LocalTag(const std::string& prefix, const std::string content) { + return _Tag(prefix, content, _Tag::Type::NamedHandle); +} + +inline _Tag SecondaryTag(const std::string content) { + return _Tag("", content, _Tag::Type::NamedHandle); +} + +struct _Comment { + _Comment(const std::string& content_) : content(content_) {} + std::string content; +}; + +inline _Comment Comment(const std::string content) { return _Comment(content); } + +struct _Precision { + _Precision(int floatPrecision_, int doublePrecision_) + : floatPrecision(floatPrecision_), doublePrecision(doublePrecision_) {} + + int floatPrecision; + int doublePrecision; +}; + +inline _Precision FloatPrecision(int n) { return _Precision(n, -1); } + +inline _Precision DoublePrecision(int n) { return _Precision(-1, n); } + +inline _Precision Precision(int n) { return _Precision(n, n); } +} + +#endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/emitterstyle.h b/phonelibs/yaml-cpp/include/yaml-cpp/emitterstyle.h new file mode 100644 index 00000000000000..67bb3981b12cb2 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/emitterstyle.h @@ -0,0 +1,16 @@ +#ifndef EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +namespace YAML { +struct EmitterStyle { + enum value { Default, Block, Flow }; +}; +} + +#endif // EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/eventhandler.h b/phonelibs/yaml-cpp/include/yaml-cpp/eventhandler.h new file mode 100644 index 00000000000000..efe381c62187e5 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/eventhandler.h @@ -0,0 +1,40 @@ +#ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include + +#include "yaml-cpp/anchor.h" +#include "yaml-cpp/emitterstyle.h" + +namespace YAML { +struct Mark; + +class EventHandler { + public: + virtual ~EventHandler() {} + + virtual void OnDocumentStart(const Mark& mark) = 0; + virtual void OnDocumentEnd() = 0; + + virtual void OnNull(const Mark& mark, anchor_t anchor) = 0; + virtual void OnAlias(const Mark& mark, anchor_t anchor) = 0; + virtual void OnScalar(const Mark& mark, const std::string& tag, + anchor_t anchor, const std::string& value) = 0; + + virtual void OnSequenceStart(const Mark& mark, const std::string& tag, + anchor_t anchor, EmitterStyle::value style) = 0; + virtual void OnSequenceEnd() = 0; + + virtual void OnMapStart(const Mark& mark, const std::string& tag, + anchor_t anchor, EmitterStyle::value style) = 0; + virtual void OnMapEnd() = 0; +}; +} + +#endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/exceptions.h b/phonelibs/yaml-cpp/include/yaml-cpp/exceptions.h new file mode 100644 index 00000000000000..a0b7e3c72b79d8 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/exceptions.h @@ -0,0 +1,257 @@ +#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/mark.h" +#include "yaml-cpp/traits.h" +#include +#include +#include + +namespace YAML { +// error messages +namespace ErrorMsg { +const char* const YAML_DIRECTIVE_ARGS = + "YAML directives must have exactly one argument"; +const char* const YAML_VERSION = "bad YAML version: "; +const char* const YAML_MAJOR_VERSION = "YAML major version too large"; +const char* const REPEATED_YAML_DIRECTIVE = "repeated YAML directive"; +const char* const TAG_DIRECTIVE_ARGS = + "TAG directives must have exactly two arguments"; +const char* const REPEATED_TAG_DIRECTIVE = "repeated TAG directive"; +const char* const CHAR_IN_TAG_HANDLE = + "illegal character found while scanning tag handle"; +const char* const TAG_WITH_NO_SUFFIX = "tag handle with no suffix"; +const char* const END_OF_VERBATIM_TAG = "end of verbatim tag not found"; +const char* const END_OF_MAP = "end of map not found"; +const char* const END_OF_MAP_FLOW = "end of map flow not found"; +const char* const END_OF_SEQ = "end of sequence not found"; +const char* const END_OF_SEQ_FLOW = "end of sequence flow not found"; +const char* const MULTIPLE_TAGS = + "cannot assign multiple tags to the same node"; +const char* const MULTIPLE_ANCHORS = + "cannot assign multiple anchors to the same node"; +const char* const MULTIPLE_ALIASES = + "cannot assign multiple aliases to the same node"; +const char* const ALIAS_CONTENT = + "aliases can't have any content, *including* tags"; +const char* const INVALID_HEX = "bad character found while scanning hex number"; +const char* const INVALID_UNICODE = "invalid unicode: "; +const char* const INVALID_ESCAPE = "unknown escape character: "; +const char* const UNKNOWN_TOKEN = "unknown token"; +const char* const DOC_IN_SCALAR = "illegal document indicator in scalar"; +const char* const EOF_IN_SCALAR = "illegal EOF in scalar"; +const char* const CHAR_IN_SCALAR = "illegal character in scalar"; +const char* const TAB_IN_INDENTATION = + "illegal tab when looking for indentation"; +const char* const FLOW_END = "illegal flow end"; +const char* const BLOCK_ENTRY = "illegal block entry"; +const char* const MAP_KEY = "illegal map key"; +const char* const MAP_VALUE = "illegal map value"; +const char* const ALIAS_NOT_FOUND = "alias not found after *"; +const char* const ANCHOR_NOT_FOUND = "anchor not found after &"; +const char* const CHAR_IN_ALIAS = + "illegal character found while scanning alias"; +const char* const CHAR_IN_ANCHOR = + "illegal character found while scanning anchor"; +const char* const ZERO_INDENT_IN_BLOCK = + "cannot set zero indentation for a block scalar"; +const char* const CHAR_IN_BLOCK = "unexpected character in block scalar"; +const char* const AMBIGUOUS_ANCHOR = + "cannot assign the same alias to multiple nodes"; +const char* const UNKNOWN_ANCHOR = "the referenced anchor is not defined"; + +const char* const INVALID_NODE = + "invalid node; this may result from using a map iterator as a sequence " + "iterator, or vice-versa"; +const char* const INVALID_SCALAR = "invalid scalar"; +const char* const KEY_NOT_FOUND = "key not found"; +const char* const BAD_CONVERSION = "bad conversion"; +const char* const BAD_DEREFERENCE = "bad dereference"; +const char* const BAD_SUBSCRIPT = "operator[] call on a scalar"; +const char* const BAD_PUSHBACK = "appending to a non-sequence"; +const char* const BAD_INSERT = "inserting in a non-convertible-to-map"; + +const char* const UNMATCHED_GROUP_TAG = "unmatched group tag"; +const char* const UNEXPECTED_END_SEQ = "unexpected end sequence token"; +const char* const UNEXPECTED_END_MAP = "unexpected end map token"; +const char* const SINGLE_QUOTED_CHAR = + "invalid character in single-quoted string"; +const char* const INVALID_ANCHOR = "invalid anchor"; +const char* const INVALID_ALIAS = "invalid alias"; +const char* const INVALID_TAG = "invalid tag"; +const char* const BAD_FILE = "bad file"; + +template +inline const std::string KEY_NOT_FOUND_WITH_KEY( + const T&, typename disable_if>::type* = 0) { + return KEY_NOT_FOUND; +} + +inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) { + std::stringstream stream; + stream << KEY_NOT_FOUND << ": " << key; + return stream.str(); +} + +template +inline const std::string KEY_NOT_FOUND_WITH_KEY( + const T& key, typename enable_if>::type* = 0) { + std::stringstream stream; + stream << KEY_NOT_FOUND << ": " << key; + return stream.str(); +} +} + +class YAML_CPP_API Exception : public std::runtime_error { + public: + Exception(const Mark& mark_, const std::string& msg_) + : std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {} + virtual ~Exception() noexcept; + + Exception(const Exception&) = default; + + Mark mark; + std::string msg; + + private: + static const std::string build_what(const Mark& mark, + const std::string& msg) { + if (mark.is_null()) { + return msg.c_str(); + } + + std::stringstream output; + output << "yaml-cpp: error at line " << mark.line + 1 << ", column " + << mark.column + 1 << ": " << msg; + return output.str(); + } +}; + +class YAML_CPP_API ParserException : public Exception { + public: + ParserException(const Mark& mark_, const std::string& msg_) + : Exception(mark_, msg_) {} + ParserException(const ParserException&) = default; + virtual ~ParserException() noexcept; +}; + +class YAML_CPP_API RepresentationException : public Exception { + public: + RepresentationException(const Mark& mark_, const std::string& msg_) + : Exception(mark_, msg_) {} + RepresentationException(const RepresentationException&) = default; + virtual ~RepresentationException() noexcept; +}; + +// representation exceptions +class YAML_CPP_API InvalidScalar : public RepresentationException { + public: + InvalidScalar(const Mark& mark_) + : RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {} + InvalidScalar(const InvalidScalar&) = default; + virtual ~InvalidScalar() noexcept; +}; + +class YAML_CPP_API KeyNotFound : public RepresentationException { + public: + template + KeyNotFound(const Mark& mark_, const T& key_) + : RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) { + } + KeyNotFound(const KeyNotFound&) = default; + virtual ~KeyNotFound() noexcept; +}; + +template +class YAML_CPP_API TypedKeyNotFound : public KeyNotFound { + public: + TypedKeyNotFound(const Mark& mark_, const T& key_) + : KeyNotFound(mark_, key_), key(key_) {} + virtual ~TypedKeyNotFound() noexcept {} + + T key; +}; + +template +inline TypedKeyNotFound MakeTypedKeyNotFound(const Mark& mark, + const T& key) { + return TypedKeyNotFound(mark, key); +} + +class YAML_CPP_API InvalidNode : public RepresentationException { + public: + InvalidNode() + : RepresentationException(Mark::null_mark(), ErrorMsg::INVALID_NODE) {} + InvalidNode(const InvalidNode&) = default; + virtual ~InvalidNode() noexcept; +}; + +class YAML_CPP_API BadConversion : public RepresentationException { + public: + explicit BadConversion(const Mark& mark_) + : RepresentationException(mark_, ErrorMsg::BAD_CONVERSION) {} + BadConversion(const BadConversion&) = default; + virtual ~BadConversion() noexcept; +}; + +template +class TypedBadConversion : public BadConversion { + public: + explicit TypedBadConversion(const Mark& mark_) : BadConversion(mark_) {} +}; + +class YAML_CPP_API BadDereference : public RepresentationException { + public: + BadDereference() + : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {} + BadDereference(const BadDereference&) = default; + virtual ~BadDereference() noexcept; +}; + +class YAML_CPP_API BadSubscript : public RepresentationException { + public: + BadSubscript() + : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_SUBSCRIPT) {} + BadSubscript(const BadSubscript&) = default; + virtual ~BadSubscript() noexcept; +}; + +class YAML_CPP_API BadPushback : public RepresentationException { + public: + BadPushback() + : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {} + BadPushback(const BadPushback&) = default; + virtual ~BadPushback() noexcept; +}; + +class YAML_CPP_API BadInsert : public RepresentationException { + public: + BadInsert() + : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {} + BadInsert(const BadInsert&) = default; + virtual ~BadInsert() noexcept; +}; + +class YAML_CPP_API EmitterException : public Exception { + public: + EmitterException(const std::string& msg_) + : Exception(Mark::null_mark(), msg_) {} + EmitterException(const EmitterException&) = default; + virtual ~EmitterException() noexcept; +}; + +class YAML_CPP_API BadFile : public Exception { + public: + BadFile() : Exception(Mark::null_mark(), ErrorMsg::BAD_FILE) {} + BadFile(const BadFile&) = default; + virtual ~BadFile() noexcept; +}; +} + +#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/mark.h b/phonelibs/yaml-cpp/include/yaml-cpp/mark.h new file mode 100644 index 00000000000000..bf94b4f41fc6c9 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/mark.h @@ -0,0 +1,29 @@ +#ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" + +namespace YAML { +struct YAML_CPP_API Mark { + Mark() : pos(0), line(0), column(0) {} + + static const Mark null_mark() { return Mark(-1, -1, -1); } + + bool is_null() const { return pos == -1 && line == -1 && column == -1; } + + int pos; + int line, column; + + private: + Mark(int pos_, int line_, int column_) + : pos(pos_), line(line_), column(column_) {} +}; +} + +#endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/convert.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/convert.h new file mode 100644 index 00000000000000..45a878ab0c021c --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/convert.h @@ -0,0 +1,331 @@ +#ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +#include "yaml-cpp/binary.h" +#include "yaml-cpp/node/impl.h" +#include "yaml-cpp/node/iterator.h" +#include "yaml-cpp/node/node.h" +#include "yaml-cpp/node/type.h" +#include "yaml-cpp/null.h" + +namespace YAML { +class Binary; +struct _Null; +template +struct convert; +} // namespace YAML + +namespace YAML { +namespace conversion { +inline bool IsInfinity(const std::string& input) { + return input == ".inf" || input == ".Inf" || input == ".INF" || + input == "+.inf" || input == "+.Inf" || input == "+.INF"; +} + +inline bool IsNegativeInfinity(const std::string& input) { + return input == "-.inf" || input == "-.Inf" || input == "-.INF"; +} + +inline bool IsNaN(const std::string& input) { + return input == ".nan" || input == ".NaN" || input == ".NAN"; +} +} + +// Node +template <> +struct convert { + static Node encode(const Node& rhs) { return rhs; } + + static bool decode(const Node& node, Node& rhs) { + rhs.reset(node); + return true; + } +}; + +// std::string +template <> +struct convert { + static Node encode(const std::string& rhs) { return Node(rhs); } + + static bool decode(const Node& node, std::string& rhs) { + if (!node.IsScalar()) + return false; + rhs = node.Scalar(); + return true; + } +}; + +// C-strings can only be encoded +template <> +struct convert { + static Node encode(const char*& rhs) { return Node(rhs); } +}; + +template +struct convert { + static Node encode(const char(&rhs)[N]) { return Node(rhs); } +}; + +template <> +struct convert<_Null> { + static Node encode(const _Null& /* rhs */) { return Node(); } + + static bool decode(const Node& node, _Null& /* rhs */) { + return node.IsNull(); + } +}; + +#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \ + template <> \ + struct convert { \ + static Node encode(const type& rhs) { \ + std::stringstream stream; \ + stream.precision(std::numeric_limits::digits10 + 1); \ + stream << rhs; \ + return Node(stream.str()); \ + } \ + \ + static bool decode(const Node& node, type& rhs) { \ + if (node.Type() != NodeType::Scalar) \ + return false; \ + const std::string& input = node.Scalar(); \ + std::stringstream stream(input); \ + stream.unsetf(std::ios::dec); \ + if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) \ + return true; \ + if (std::numeric_limits::has_infinity) { \ + if (conversion::IsInfinity(input)) { \ + rhs = std::numeric_limits::infinity(); \ + return true; \ + } else if (conversion::IsNegativeInfinity(input)) { \ + rhs = negative_op std::numeric_limits::infinity(); \ + return true; \ + } \ + } \ + \ + if (std::numeric_limits::has_quiet_NaN && \ + conversion::IsNaN(input)) { \ + rhs = std::numeric_limits::quiet_NaN(); \ + return true; \ + } \ + \ + return false; \ + } \ + } + +#define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \ + YAML_DEFINE_CONVERT_STREAMABLE(type, -) + +#define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type) \ + YAML_DEFINE_CONVERT_STREAMABLE(type, +) + +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int); +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short); +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long); +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long); +YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned); +YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short); +YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long); +YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long); + +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char); +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(signed char); +YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned char); + +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(float); +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double); +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double); + +#undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED +#undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED +#undef YAML_DEFINE_CONVERT_STREAMABLE + +// bool +template <> +struct convert { + static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); } + + YAML_CPP_API static bool decode(const Node& node, bool& rhs); +}; + +// std::map +template +struct convert> { + static Node encode(const std::map& rhs) { + Node node(NodeType::Map); + for (typename std::map::const_iterator it = rhs.begin(); + it != rhs.end(); ++it) + node.force_insert(it->first, it->second); + return node; + } + + static bool decode(const Node& node, std::map& rhs) { + if (!node.IsMap()) + return false; + + rhs.clear(); + for (const_iterator it = node.begin(); it != node.end(); ++it) +#if defined(__GNUC__) && __GNUC__ < 4 + // workaround for GCC 3: + rhs[it->first.template as()] = it->second.template as(); +#else + rhs[it->first.as()] = it->second.as(); +#endif + return true; + } +}; + +// std::vector +template +struct convert> { + static Node encode(const std::vector& rhs) { + Node node(NodeType::Sequence); + for (typename std::vector::const_iterator it = rhs.begin(); + it != rhs.end(); ++it) + node.push_back(*it); + return node; + } + + static bool decode(const Node& node, std::vector& rhs) { + if (!node.IsSequence()) + return false; + + rhs.clear(); + for (const_iterator it = node.begin(); it != node.end(); ++it) +#if defined(__GNUC__) && __GNUC__ < 4 + // workaround for GCC 3: + rhs.push_back(it->template as()); +#else + rhs.push_back(it->as()); +#endif + return true; + } +}; + +// std::list +template +struct convert> { + static Node encode(const std::list& rhs) { + Node node(NodeType::Sequence); + for (typename std::list::const_iterator it = rhs.begin(); + it != rhs.end(); ++it) + node.push_back(*it); + return node; + } + + static bool decode(const Node& node, std::list& rhs) { + if (!node.IsSequence()) + return false; + + rhs.clear(); + for (const_iterator it = node.begin(); it != node.end(); ++it) +#if defined(__GNUC__) && __GNUC__ < 4 + // workaround for GCC 3: + rhs.push_back(it->template as()); +#else + rhs.push_back(it->as()); +#endif + return true; + } +}; + +// std::array +template +struct convert> { + static Node encode(const std::array& rhs) { + Node node(NodeType::Sequence); + for (const auto& element : rhs) { + node.push_back(element); + } + return node; + } + + static bool decode(const Node& node, std::array& rhs) { + if (!isNodeValid(node)) { + return false; + } + + for (auto i = 0u; i < node.size(); ++i) { +#if defined(__GNUC__) && __GNUC__ < 4 + // workaround for GCC 3: + rhs[i] = node[i].template as(); +#else + rhs[i] = node[i].as(); +#endif + } + return true; + } + + private: + static bool isNodeValid(const Node& node) { + return node.IsSequence() && node.size() == N; + } +}; + +// std::pair +template +struct convert> { + static Node encode(const std::pair& rhs) { + Node node(NodeType::Sequence); + node.push_back(rhs.first); + node.push_back(rhs.second); + return node; + } + + static bool decode(const Node& node, std::pair& rhs) { + if (!node.IsSequence()) + return false; + if (node.size() != 2) + return false; + +#if defined(__GNUC__) && __GNUC__ < 4 + // workaround for GCC 3: + rhs.first = node[0].template as(); +#else + rhs.first = node[0].as(); +#endif +#if defined(__GNUC__) && __GNUC__ < 4 + // workaround for GCC 3: + rhs.second = node[1].template as(); +#else + rhs.second = node[1].as(); +#endif + return true; + } +}; + +// binary +template <> +struct convert { + static Node encode(const Binary& rhs) { + return Node(EncodeBase64(rhs.data(), rhs.size())); + } + + static bool decode(const Node& node, Binary& rhs) { + if (!node.IsScalar()) + return false; + + std::vector data = DecodeBase64(node.Scalar()); + if (data.empty() && !node.Scalar().empty()) + return false; + + rhs.swap(data); + return true; + } +}; +} + +#endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/bool_type.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/bool_type.h new file mode 100644 index 00000000000000..2c80705c9ae749 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/bool_type.h @@ -0,0 +1,26 @@ +#ifndef NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +namespace YAML { +namespace detail { +struct unspecified_bool { + struct NOT_ALLOWED; + static void true_value(NOT_ALLOWED*) {} +}; +typedef void (*unspecified_bool_type)(unspecified_bool::NOT_ALLOWED*); +} +} + +#define YAML_CPP_OPERATOR_BOOL() \ + operator YAML::detail::unspecified_bool_type() const { \ + return this->operator!() ? 0 \ + : &YAML::detail::unspecified_bool::true_value; \ + } + +#endif // NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/impl.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/impl.h new file mode 100644 index 00000000000000..59318264ad6599 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/impl.h @@ -0,0 +1,185 @@ +#ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/node/detail/node.h" +#include "yaml-cpp/node/detail/node_data.h" +#include + +namespace YAML { +namespace detail { +template +struct get_idx { + static node* get(const std::vector& /* sequence */, + const Key& /* key */, shared_memory_holder /* pMemory */) { + return 0; + } +}; + +template +struct get_idx::value && + !std::is_same::value>::type> { + static node* get(const std::vector& sequence, const Key& key, + shared_memory_holder /* pMemory */) { + return key < sequence.size() ? sequence[key] : 0; + } + + static node* get(std::vector& sequence, const Key& key, + shared_memory_holder pMemory) { + if (key > sequence.size() || (key > 0 && !sequence[key-1]->is_defined())) + return 0; + if (key == sequence.size()) + sequence.push_back(&pMemory->create_node()); + return sequence[key]; + } +}; + +template +struct get_idx::value>::type> { + static node* get(const std::vector& sequence, const Key& key, + shared_memory_holder pMemory) { + return key >= 0 ? get_idx::get( + sequence, static_cast(key), pMemory) + : 0; + } + static node* get(std::vector& sequence, const Key& key, + shared_memory_holder pMemory) { + return key >= 0 ? get_idx::get( + sequence, static_cast(key), pMemory) + : 0; + } +}; + +template +inline bool node::equals(const T& rhs, shared_memory_holder pMemory) { + T lhs; + if (convert::decode(Node(*this, pMemory), lhs)) { + return lhs == rhs; + } + return false; +} + +inline bool node::equals(const char* rhs, shared_memory_holder pMemory) { + return equals(rhs, pMemory); +} + +// indexing +template +inline node* node_data::get(const Key& key, + shared_memory_holder pMemory) const { + switch (m_type) { + case NodeType::Map: + break; + case NodeType::Undefined: + case NodeType::Null: + return NULL; + case NodeType::Sequence: + if (node* pNode = get_idx::get(m_sequence, key, pMemory)) + return pNode; + return NULL; + case NodeType::Scalar: + throw BadSubscript(); + } + + for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { + if (it->first->equals(key, pMemory)) { + return it->second; + } + } + + return NULL; +} + +template +inline node& node_data::get(const Key& key, shared_memory_holder pMemory) { + switch (m_type) { + case NodeType::Map: + break; + case NodeType::Undefined: + case NodeType::Null: + case NodeType::Sequence: + if (node* pNode = get_idx::get(m_sequence, key, pMemory)) { + m_type = NodeType::Sequence; + return *pNode; + } + + convert_to_map(pMemory); + break; + case NodeType::Scalar: + throw BadSubscript(); + } + + for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { + if (it->first->equals(key, pMemory)) { + return *it->second; + } + } + + node& k = convert_to_node(key, pMemory); + node& v = pMemory->create_node(); + insert_map_pair(k, v); + return v; +} + +template +inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) { + if (m_type != NodeType::Map) + return false; + + kv_pairs::iterator it = m_undefinedPairs.begin(); + while (it != m_undefinedPairs.end()) { + kv_pairs::iterator jt = std::next(it); + if (it->first->equals(key, pMemory)) + m_undefinedPairs.erase(it); + it = jt; + } + + for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) { + if (it->first->equals(key, pMemory)) { + m_map.erase(it); + return true; + } + } + + return false; +} + +// map +template +inline void node_data::force_insert(const Key& key, const Value& value, + shared_memory_holder pMemory) { + switch (m_type) { + case NodeType::Map: + break; + case NodeType::Undefined: + case NodeType::Null: + case NodeType::Sequence: + convert_to_map(pMemory); + break; + case NodeType::Scalar: + throw BadInsert(); + } + + node& k = convert_to_node(key, pMemory); + node& v = convert_to_node(value, pMemory); + insert_map_pair(k, v); +} + +template +inline node& node_data::convert_to_node(const T& rhs, + shared_memory_holder pMemory) { + Node value = convert::encode(rhs); + value.EnsureNodeExists(); + pMemory->merge(*value.m_pMemory); + return *value.m_pNode; +} +} +} + +#endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/iterator.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/iterator.h new file mode 100644 index 00000000000000..65f81524988748 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/iterator.h @@ -0,0 +1,91 @@ +#ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/node/ptr.h" +#include "yaml-cpp/node/detail/node_iterator.h" +#include +#include + +namespace YAML { +namespace detail { +struct iterator_value; + +template +class iterator_base : public std::iterator { + + private: + template + friend class iterator_base; + struct enabler {}; + typedef node_iterator base_type; + + struct proxy { + explicit proxy(const V& x) : m_ref(x) {} + V* operator->() { return std::addressof(m_ref); } + operator V*() { return std::addressof(m_ref); } + + V m_ref; + }; + + public: + typedef typename iterator_base::value_type value_type; + + public: + iterator_base() : m_iterator(), m_pMemory() {} + explicit iterator_base(base_type rhs, shared_memory_holder pMemory) + : m_iterator(rhs), m_pMemory(pMemory) {} + + template + iterator_base(const iterator_base& rhs, + typename std::enable_if::value, + enabler>::type = enabler()) + : m_iterator(rhs.m_iterator), m_pMemory(rhs.m_pMemory) {} + + iterator_base& operator++() { + ++m_iterator; + return *this; + } + + iterator_base operator++(int) { + iterator_base iterator_pre(*this); + ++(*this); + return iterator_pre; + } + + template + bool operator==(const iterator_base& rhs) const { + return m_iterator == rhs.m_iterator; + } + + template + bool operator!=(const iterator_base& rhs) const { + return m_iterator != rhs.m_iterator; + } + + value_type operator*() const { + const typename base_type::value_type& v = *m_iterator; + if (v.pNode) + return value_type(Node(*v, m_pMemory)); + if (v.first && v.second) + return value_type(Node(*v.first, m_pMemory), Node(*v.second, m_pMemory)); + return value_type(); + } + + proxy operator->() const { return proxy(**this); } + + private: + base_type m_iterator; + shared_memory_holder m_pMemory; +}; +} +} + +#endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h new file mode 100644 index 00000000000000..5f1ffe7436d735 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h @@ -0,0 +1,27 @@ +#ifndef VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" +#include +#include +#include + +namespace YAML { + +namespace detail { +struct iterator_value; +template +class iterator_base; +} + +typedef detail::iterator_base iterator; +typedef detail::iterator_base const_iterator; +} + +#endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/memory.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/memory.h new file mode 100644 index 00000000000000..8f2bc2657a2286 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/memory.h @@ -0,0 +1,46 @@ +#ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/node/ptr.h" + +namespace YAML { +namespace detail { +class node; +} // namespace detail +} // namespace YAML + +namespace YAML { +namespace detail { +class YAML_CPP_API memory { + public: + node& create_node(); + void merge(const memory& rhs); + + private: + typedef std::set Nodes; + Nodes m_nodes; +}; + +class YAML_CPP_API memory_holder { + public: + memory_holder() : m_pMemory(new memory) {} + + node& create_node() { return m_pMemory->create_node(); } + void merge(memory_holder& rhs); + + private: + shared_memory m_pMemory; +}; +} +} + +#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/node.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/node.h new file mode 100644 index 00000000000000..3154a527c327d7 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/node.h @@ -0,0 +1,169 @@ +#ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/emitterstyle.h" +#include "yaml-cpp/dll.h" +#include "yaml-cpp/node/type.h" +#include "yaml-cpp/node/ptr.h" +#include "yaml-cpp/node/detail/node_ref.h" +#include + +namespace YAML { +namespace detail { +class node { + public: + node() : m_pRef(new node_ref) {} + node(const node&) = delete; + node& operator=(const node&) = delete; + + bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; } + const node_ref* ref() const { return m_pRef.get(); } + + bool is_defined() const { return m_pRef->is_defined(); } + const Mark& mark() const { return m_pRef->mark(); } + NodeType::value type() const { return m_pRef->type(); } + + const std::string& scalar() const { return m_pRef->scalar(); } + const std::string& tag() const { return m_pRef->tag(); } + EmitterStyle::value style() const { return m_pRef->style(); } + + template + bool equals(const T& rhs, shared_memory_holder pMemory); + bool equals(const char* rhs, shared_memory_holder pMemory); + + void mark_defined() { + if (is_defined()) + return; + + m_pRef->mark_defined(); + for (nodes::iterator it = m_dependencies.begin(); + it != m_dependencies.end(); ++it) + (*it)->mark_defined(); + m_dependencies.clear(); + } + + void add_dependency(node& rhs) { + if (is_defined()) + rhs.mark_defined(); + else + m_dependencies.insert(&rhs); + } + + void set_ref(const node& rhs) { + if (rhs.is_defined()) + mark_defined(); + m_pRef = rhs.m_pRef; + } + void set_data(const node& rhs) { + if (rhs.is_defined()) + mark_defined(); + m_pRef->set_data(*rhs.m_pRef); + } + + void set_mark(const Mark& mark) { m_pRef->set_mark(mark); } + + void set_type(NodeType::value type) { + if (type != NodeType::Undefined) + mark_defined(); + m_pRef->set_type(type); + } + void set_null() { + mark_defined(); + m_pRef->set_null(); + } + void set_scalar(const std::string& scalar) { + mark_defined(); + m_pRef->set_scalar(scalar); + } + void set_tag(const std::string& tag) { + mark_defined(); + m_pRef->set_tag(tag); + } + + // style + void set_style(EmitterStyle::value style) { + mark_defined(); + m_pRef->set_style(style); + } + + // size/iterator + std::size_t size() const { return m_pRef->size(); } + + const_node_iterator begin() const { + return static_cast(*m_pRef).begin(); + } + node_iterator begin() { return m_pRef->begin(); } + + const_node_iterator end() const { + return static_cast(*m_pRef).end(); + } + node_iterator end() { return m_pRef->end(); } + + // sequence + void push_back(node& node, shared_memory_holder pMemory) { + m_pRef->push_back(node, pMemory); + node.add_dependency(*this); + } + void insert(node& key, node& value, shared_memory_holder pMemory) { + m_pRef->insert(key, value, pMemory); + key.add_dependency(*this); + value.add_dependency(*this); + } + + // indexing + template + node* get(const Key& key, shared_memory_holder pMemory) const { + // NOTE: this returns a non-const node so that the top-level Node can wrap + // it, and returns a pointer so that it can be NULL (if there is no such + // key). + return static_cast(*m_pRef).get(key, pMemory); + } + template + node& get(const Key& key, shared_memory_holder pMemory) { + node& value = m_pRef->get(key, pMemory); + value.add_dependency(*this); + return value; + } + template + bool remove(const Key& key, shared_memory_holder pMemory) { + return m_pRef->remove(key, pMemory); + } + + node* get(node& key, shared_memory_holder pMemory) const { + // NOTE: this returns a non-const node so that the top-level Node can wrap + // it, and returns a pointer so that it can be NULL (if there is no such + // key). + return static_cast(*m_pRef).get(key, pMemory); + } + node& get(node& key, shared_memory_holder pMemory) { + node& value = m_pRef->get(key, pMemory); + key.add_dependency(*this); + value.add_dependency(*this); + return value; + } + bool remove(node& key, shared_memory_holder pMemory) { + return m_pRef->remove(key, pMemory); + } + + // map + template + void force_insert(const Key& key, const Value& value, + shared_memory_holder pMemory) { + m_pRef->force_insert(key, value, pMemory); + } + + private: + shared_node_ref m_pRef; + typedef std::set nodes; + nodes m_dependencies; +}; +} +} + +#endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/node_data.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/node_data.h new file mode 100644 index 00000000000000..50bcd74352da9b --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/node_data.h @@ -0,0 +1,127 @@ +#ifndef VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include +#include +#include +#include + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/node/detail/node_iterator.h" +#include "yaml-cpp/node/iterator.h" +#include "yaml-cpp/node/ptr.h" +#include "yaml-cpp/node/type.h" + +namespace YAML { +namespace detail { +class node; +} // namespace detail +} // namespace YAML + +namespace YAML { +namespace detail { +class YAML_CPP_API node_data { + public: + node_data(); + node_data(const node_data&) = delete; + node_data& operator=(const node_data&) = delete; + + void mark_defined(); + void set_mark(const Mark& mark); + void set_type(NodeType::value type); + void set_tag(const std::string& tag); + void set_null(); + void set_scalar(const std::string& scalar); + void set_style(EmitterStyle::value style); + + bool is_defined() const { return m_isDefined; } + const Mark& mark() const { return m_mark; } + NodeType::value type() const { + return m_isDefined ? m_type : NodeType::Undefined; + } + const std::string& scalar() const { return m_scalar; } + const std::string& tag() const { return m_tag; } + EmitterStyle::value style() const { return m_style; } + + // size/iterator + std::size_t size() const; + + const_node_iterator begin() const; + node_iterator begin(); + + const_node_iterator end() const; + node_iterator end(); + + // sequence + void push_back(node& node, shared_memory_holder pMemory); + void insert(node& key, node& value, shared_memory_holder pMemory); + + // indexing + template + node* get(const Key& key, shared_memory_holder pMemory) const; + template + node& get(const Key& key, shared_memory_holder pMemory); + template + bool remove(const Key& key, shared_memory_holder pMemory); + + node* get(node& key, shared_memory_holder pMemory) const; + node& get(node& key, shared_memory_holder pMemory); + bool remove(node& key, shared_memory_holder pMemory); + + // map + template + void force_insert(const Key& key, const Value& value, + shared_memory_holder pMemory); + + public: + static std::string empty_scalar; + + private: + void compute_seq_size() const; + void compute_map_size() const; + + void reset_sequence(); + void reset_map(); + + void insert_map_pair(node& key, node& value); + void convert_to_map(shared_memory_holder pMemory); + void convert_sequence_to_map(shared_memory_holder pMemory); + + template + static node& convert_to_node(const T& rhs, shared_memory_holder pMemory); + + private: + bool m_isDefined; + Mark m_mark; + NodeType::value m_type; + std::string m_tag; + EmitterStyle::value m_style; + + // scalar + std::string m_scalar; + + // sequence + typedef std::vector node_seq; + node_seq m_sequence; + + mutable std::size_t m_seqSize; + + // map + typedef std::vector> node_map; + node_map m_map; + + typedef std::pair kv_pair; + typedef std::list kv_pairs; + mutable kv_pairs m_undefinedPairs; +}; +} +} + +#endif // VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/node_iterator.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/node_iterator.h new file mode 100644 index 00000000000000..4337df4167375c --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/node_iterator.h @@ -0,0 +1,180 @@ +#ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/node/ptr.h" +#include +#include +#include +#include +#include +#include + +namespace YAML { +namespace detail { +struct iterator_type { + enum value { None, Sequence, Map }; +}; + +template +struct node_iterator_value : public std::pair { + typedef std::pair kv; + + node_iterator_value() : kv(), pNode(0) {} + explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {} + explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(0) {} + + V& operator*() const { return *pNode; } + V& operator->() const { return *pNode; } + + V* pNode; +}; + +typedef std::vector node_seq; +typedef std::vector> node_map; + +template +struct node_iterator_type { + typedef node_seq::iterator seq; + typedef node_map::iterator map; +}; + +template +struct node_iterator_type { + typedef node_seq::const_iterator seq; + typedef node_map::const_iterator map; +}; + +template +class node_iterator_base + : public std::iterator, + std::ptrdiff_t, node_iterator_value*, + node_iterator_value> { + private: + struct enabler {}; + + struct proxy { + explicit proxy(const node_iterator_value& x) : m_ref(x) {} + node_iterator_value* operator->() { return std::addressof(m_ref); } + operator node_iterator_value*() { return std::addressof(m_ref); } + + node_iterator_value m_ref; + }; + + public: + typedef typename node_iterator_type::seq SeqIter; + typedef typename node_iterator_type::map MapIter; + typedef node_iterator_value value_type; + + node_iterator_base() + : m_type(iterator_type::None), m_seqIt(), m_mapIt(), m_mapEnd() {} + explicit node_iterator_base(SeqIter seqIt) + : m_type(iterator_type::Sequence), + m_seqIt(seqIt), + m_mapIt(), + m_mapEnd() {} + explicit node_iterator_base(MapIter mapIt, MapIter mapEnd) + : m_type(iterator_type::Map), + m_seqIt(), + m_mapIt(mapIt), + m_mapEnd(mapEnd) { + m_mapIt = increment_until_defined(m_mapIt); + } + + template + node_iterator_base(const node_iterator_base& rhs, + typename std::enable_if::value, + enabler>::type = enabler()) + : m_type(rhs.m_type), + m_seqIt(rhs.m_seqIt), + m_mapIt(rhs.m_mapIt), + m_mapEnd(rhs.m_mapEnd) {} + + template + friend class node_iterator_base; + + template + bool operator==(const node_iterator_base& rhs) const { + if (m_type != rhs.m_type) + return false; + + switch (m_type) { + case iterator_type::None: + return true; + case iterator_type::Sequence: + return m_seqIt == rhs.m_seqIt; + case iterator_type::Map: + return m_mapIt == rhs.m_mapIt; + } + return true; + } + + template + bool operator!=(const node_iterator_base& rhs) const { + return !(*this == rhs); + } + + node_iterator_base& operator++() { + switch (m_type) { + case iterator_type::None: + break; + case iterator_type::Sequence: + ++m_seqIt; + break; + case iterator_type::Map: + ++m_mapIt; + m_mapIt = increment_until_defined(m_mapIt); + break; + } + return *this; + } + + node_iterator_base operator++(int) { + node_iterator_base iterator_pre(*this); + ++(*this); + return iterator_pre; + } + + value_type operator*() const { + switch (m_type) { + case iterator_type::None: + return value_type(); + case iterator_type::Sequence: + return value_type(**m_seqIt); + case iterator_type::Map: + return value_type(*m_mapIt->first, *m_mapIt->second); + } + return value_type(); + } + + proxy operator->() const { return proxy(**this); } + + MapIter increment_until_defined(MapIter it) { + while (it != m_mapEnd && !is_defined(it)) + ++it; + return it; + } + + bool is_defined(MapIter it) const { + return it->first->is_defined() && it->second->is_defined(); + } + + private: + typename iterator_type::value m_type; + + SeqIter m_seqIt; + MapIter m_mapIt, m_mapEnd; +}; + +typedef node_iterator_base node_iterator; +typedef node_iterator_base const_node_iterator; +} +} + +#endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/node_ref.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/node_ref.h new file mode 100644 index 00000000000000..d8a94f8b8045cf --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/detail/node_ref.h @@ -0,0 +1,98 @@ +#ifndef VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/node/type.h" +#include "yaml-cpp/node/ptr.h" +#include "yaml-cpp/node/detail/node_data.h" + +namespace YAML { +namespace detail { +class node_ref { + public: + node_ref() : m_pData(new node_data) {} + node_ref(const node_ref&) = delete; + node_ref& operator=(const node_ref&) = delete; + + bool is_defined() const { return m_pData->is_defined(); } + const Mark& mark() const { return m_pData->mark(); } + NodeType::value type() const { return m_pData->type(); } + const std::string& scalar() const { return m_pData->scalar(); } + const std::string& tag() const { return m_pData->tag(); } + EmitterStyle::value style() const { return m_pData->style(); } + + void mark_defined() { m_pData->mark_defined(); } + void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; } + + void set_mark(const Mark& mark) { m_pData->set_mark(mark); } + void set_type(NodeType::value type) { m_pData->set_type(type); } + void set_tag(const std::string& tag) { m_pData->set_tag(tag); } + void set_null() { m_pData->set_null(); } + void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); } + void set_style(EmitterStyle::value style) { m_pData->set_style(style); } + + // size/iterator + std::size_t size() const { return m_pData->size(); } + + const_node_iterator begin() const { + return static_cast(*m_pData).begin(); + } + node_iterator begin() { return m_pData->begin(); } + + const_node_iterator end() const { + return static_cast(*m_pData).end(); + } + node_iterator end() { return m_pData->end(); } + + // sequence + void push_back(node& node, shared_memory_holder pMemory) { + m_pData->push_back(node, pMemory); + } + void insert(node& key, node& value, shared_memory_holder pMemory) { + m_pData->insert(key, value, pMemory); + } + + // indexing + template + node* get(const Key& key, shared_memory_holder pMemory) const { + return static_cast(*m_pData).get(key, pMemory); + } + template + node& get(const Key& key, shared_memory_holder pMemory) { + return m_pData->get(key, pMemory); + } + template + bool remove(const Key& key, shared_memory_holder pMemory) { + return m_pData->remove(key, pMemory); + } + + node* get(node& key, shared_memory_holder pMemory) const { + return static_cast(*m_pData).get(key, pMemory); + } + node& get(node& key, shared_memory_holder pMemory) { + return m_pData->get(key, pMemory); + } + bool remove(node& key, shared_memory_holder pMemory) { + return m_pData->remove(key, pMemory); + } + + // map + template + void force_insert(const Key& key, const Value& value, + shared_memory_holder pMemory) { + m_pData->force_insert(key, value, pMemory); + } + + private: + shared_node_data m_pData; +}; +} +} + +#endif // VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/emit.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/emit.h new file mode 100644 index 00000000000000..032268c5d04af8 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/emit.h @@ -0,0 +1,32 @@ +#ifndef NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include + +#include "yaml-cpp/dll.h" + +namespace YAML { +class Emitter; +class Node; + +/** + * Emits the node to the given {@link Emitter}. If there is an error in writing, + * {@link Emitter#good} will return false. + */ +YAML_CPP_API Emitter& operator<<(Emitter& out, const Node& node); + +/** Emits the node to the given output stream. */ +YAML_CPP_API std::ostream& operator<<(std::ostream& out, const Node& node); + +/** Converts the node to a YAML string. */ +YAML_CPP_API std::string Dump(const Node& node); +} // namespace YAML + +#endif // NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/impl.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/impl.h new file mode 100644 index 00000000000000..20c487a687f62f --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/impl.h @@ -0,0 +1,448 @@ +#ifndef NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/node/node.h" +#include "yaml-cpp/node/iterator.h" +#include "yaml-cpp/node/detail/memory.h" +#include "yaml-cpp/node/detail/node.h" +#include "yaml-cpp/exceptions.h" +#include + +namespace YAML { +inline Node::Node() : m_isValid(true), m_pNode(NULL) {} + +inline Node::Node(NodeType::value type) + : m_isValid(true), + m_pMemory(new detail::memory_holder), + m_pNode(&m_pMemory->create_node()) { + m_pNode->set_type(type); +} + +template +inline Node::Node(const T& rhs) + : m_isValid(true), + m_pMemory(new detail::memory_holder), + m_pNode(&m_pMemory->create_node()) { + Assign(rhs); +} + +inline Node::Node(const detail::iterator_value& rhs) + : m_isValid(rhs.m_isValid), + m_pMemory(rhs.m_pMemory), + m_pNode(rhs.m_pNode) {} + +inline Node::Node(const Node& rhs) + : m_isValid(rhs.m_isValid), + m_pMemory(rhs.m_pMemory), + m_pNode(rhs.m_pNode) {} + +inline Node::Node(Zombie) : m_isValid(false), m_pNode(NULL) {} + +inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory) + : m_isValid(true), m_pMemory(pMemory), m_pNode(&node) {} + +inline Node::~Node() {} + +inline void Node::EnsureNodeExists() const { + if (!m_isValid) + throw InvalidNode(); + if (!m_pNode) { + m_pMemory.reset(new detail::memory_holder); + m_pNode = &m_pMemory->create_node(); + m_pNode->set_null(); + } +} + +inline bool Node::IsDefined() const { + if (!m_isValid) { + return false; + } + return m_pNode ? m_pNode->is_defined() : true; +} + +inline Mark Node::Mark() const { + if (!m_isValid) { + throw InvalidNode(); + } + return m_pNode ? m_pNode->mark() : Mark::null_mark(); +} + +inline NodeType::value Node::Type() const { + if (!m_isValid) + throw InvalidNode(); + return m_pNode ? m_pNode->type() : NodeType::Null; +} + +// access + +// template helpers +template +struct as_if { + explicit as_if(const Node& node_) : node(node_) {} + const Node& node; + + T operator()(const S& fallback) const { + if (!node.m_pNode) + return fallback; + + T t; + if (convert::decode(node, t)) + return t; + return fallback; + } +}; + +template +struct as_if { + explicit as_if(const Node& node_) : node(node_) {} + const Node& node; + + std::string operator()(const S& fallback) const { + if (node.Type() != NodeType::Scalar) + return fallback; + return node.Scalar(); + } +}; + +template +struct as_if { + explicit as_if(const Node& node_) : node(node_) {} + const Node& node; + + T operator()() const { + if (!node.m_pNode) + throw TypedBadConversion(node.Mark()); + + T t; + if (convert::decode(node, t)) + return t; + throw TypedBadConversion(node.Mark()); + } +}; + +template <> +struct as_if { + explicit as_if(const Node& node_) : node(node_) {} + const Node& node; + + std::string operator()() const { + if (node.Type() != NodeType::Scalar) + throw TypedBadConversion(node.Mark()); + return node.Scalar(); + } +}; + +// access functions +template +inline T Node::as() const { + if (!m_isValid) + throw InvalidNode(); + return as_if(*this)(); +} + +template +inline T Node::as(const S& fallback) const { + if (!m_isValid) + return fallback; + return as_if(*this)(fallback); +} + +inline const std::string& Node::Scalar() const { + if (!m_isValid) + throw InvalidNode(); + return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar; +} + +inline const std::string& Node::Tag() const { + if (!m_isValid) + throw InvalidNode(); + return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar; +} + +inline void Node::SetTag(const std::string& tag) { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + m_pNode->set_tag(tag); +} + +inline EmitterStyle::value Node::Style() const { + if (!m_isValid) + throw InvalidNode(); + return m_pNode ? m_pNode->style() : EmitterStyle::Default; +} + +inline void Node::SetStyle(EmitterStyle::value style) { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + m_pNode->set_style(style); +} + +// assignment +inline bool Node::is(const Node& rhs) const { + if (!m_isValid || !rhs.m_isValid) + throw InvalidNode(); + if (!m_pNode || !rhs.m_pNode) + return false; + return m_pNode->is(*rhs.m_pNode); +} + +template +inline Node& Node::operator=(const T& rhs) { + if (!m_isValid) + throw InvalidNode(); + Assign(rhs); + return *this; +} + +inline void Node::reset(const YAML::Node& rhs) { + if (!m_isValid || !rhs.m_isValid) + throw InvalidNode(); + m_pMemory = rhs.m_pMemory; + m_pNode = rhs.m_pNode; +} + +template +inline void Node::Assign(const T& rhs) { + if (!m_isValid) + throw InvalidNode(); + AssignData(convert::encode(rhs)); +} + +template <> +inline void Node::Assign(const std::string& rhs) { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + m_pNode->set_scalar(rhs); +} + +inline void Node::Assign(const char* rhs) { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + m_pNode->set_scalar(rhs); +} + +inline void Node::Assign(char* rhs) { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + m_pNode->set_scalar(rhs); +} + +inline Node& Node::operator=(const Node& rhs) { + if (!m_isValid || !rhs.m_isValid) + throw InvalidNode(); + if (is(rhs)) + return *this; + AssignNode(rhs); + return *this; +} + +inline void Node::AssignData(const Node& rhs) { + if (!m_isValid || !rhs.m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + rhs.EnsureNodeExists(); + + m_pNode->set_data(*rhs.m_pNode); + m_pMemory->merge(*rhs.m_pMemory); +} + +inline void Node::AssignNode(const Node& rhs) { + if (!m_isValid || !rhs.m_isValid) + throw InvalidNode(); + rhs.EnsureNodeExists(); + + if (!m_pNode) { + m_pNode = rhs.m_pNode; + m_pMemory = rhs.m_pMemory; + return; + } + + m_pNode->set_ref(*rhs.m_pNode); + m_pMemory->merge(*rhs.m_pMemory); + m_pNode = rhs.m_pNode; +} + +// size/iterator +inline std::size_t Node::size() const { + if (!m_isValid) + throw InvalidNode(); + return m_pNode ? m_pNode->size() : 0; +} + +inline const_iterator Node::begin() const { + if (!m_isValid) + return const_iterator(); + return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory) + : const_iterator(); +} + +inline iterator Node::begin() { + if (!m_isValid) + return iterator(); + return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator(); +} + +inline const_iterator Node::end() const { + if (!m_isValid) + return const_iterator(); + return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator(); +} + +inline iterator Node::end() { + if (!m_isValid) + return iterator(); + return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator(); +} + +// sequence +template +inline void Node::push_back(const T& rhs) { + if (!m_isValid) + throw InvalidNode(); + push_back(Node(rhs)); +} + +inline void Node::push_back(const Node& rhs) { + if (!m_isValid || !rhs.m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + rhs.EnsureNodeExists(); + + m_pNode->push_back(*rhs.m_pNode, m_pMemory); + m_pMemory->merge(*rhs.m_pMemory); +} + +// helpers for indexing +namespace detail { +template +struct to_value_t { + explicit to_value_t(const T& t_) : t(t_) {} + const T& t; + typedef const T& return_type; + + const T& operator()() const { return t; } +}; + +template <> +struct to_value_t { + explicit to_value_t(const char* t_) : t(t_) {} + const char* t; + typedef std::string return_type; + + const std::string operator()() const { return t; } +}; + +template <> +struct to_value_t { + explicit to_value_t(char* t_) : t(t_) {} + const char* t; + typedef std::string return_type; + + const std::string operator()() const { return t; } +}; + +template +struct to_value_t { + explicit to_value_t(const char* t_) : t(t_) {} + const char* t; + typedef std::string return_type; + + const std::string operator()() const { return t; } +}; + +// converts C-strings to std::strings so they can be copied +template +inline typename to_value_t::return_type to_value(const T& t) { + return to_value_t(t)(); +} +} + +// indexing +template +inline const Node Node::operator[](const Key& key) const { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + detail::node* value = static_cast(*m_pNode) + .get(detail::to_value(key), m_pMemory); + if (!value) { + return Node(ZombieNode); + } + return Node(*value, m_pMemory); +} + +template +inline Node Node::operator[](const Key& key) { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory); + return Node(value, m_pMemory); +} + +template +inline bool Node::remove(const Key& key) { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + return m_pNode->remove(detail::to_value(key), m_pMemory); +} + +inline const Node Node::operator[](const Node& key) const { + if (!m_isValid || !key.m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + key.EnsureNodeExists(); + m_pMemory->merge(*key.m_pMemory); + detail::node* value = + static_cast(*m_pNode).get(*key.m_pNode, m_pMemory); + if (!value) { + return Node(ZombieNode); + } + return Node(*value, m_pMemory); +} + +inline Node Node::operator[](const Node& key) { + if (!m_isValid || !key.m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + key.EnsureNodeExists(); + m_pMemory->merge(*key.m_pMemory); + detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory); + return Node(value, m_pMemory); +} + +inline bool Node::remove(const Node& key) { + if (!m_isValid || !key.m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + key.EnsureNodeExists(); + return m_pNode->remove(*key.m_pNode, m_pMemory); +} + +// map +template +inline void Node::force_insert(const Key& key, const Value& value) { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + m_pNode->force_insert(detail::to_value(key), detail::to_value(value), + m_pMemory); +} + +// free functions +inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); } +} + +#endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/iterator.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/iterator.h new file mode 100644 index 00000000000000..366a9c807fe899 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/iterator.h @@ -0,0 +1,31 @@ +#ifndef VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/node/node.h" +#include "yaml-cpp/node/detail/iterator_fwd.h" +#include "yaml-cpp/node/detail/iterator.h" +#include +#include +#include + +namespace YAML { +namespace detail { +struct iterator_value : public Node, std::pair { + iterator_value() {} + explicit iterator_value(const Node& rhs) + : Node(rhs), + std::pair(Node(Node::ZombieNode), Node(Node::ZombieNode)) {} + explicit iterator_value(const Node& key, const Node& value) + : Node(Node::ZombieNode), std::pair(key, value) {} +}; +} +} + +#endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/node.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/node.h new file mode 100644 index 00000000000000..1ded7d27b72f8b --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/node.h @@ -0,0 +1,145 @@ +#ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/emitterstyle.h" +#include "yaml-cpp/mark.h" +#include "yaml-cpp/node/detail/bool_type.h" +#include "yaml-cpp/node/detail/iterator_fwd.h" +#include "yaml-cpp/node/ptr.h" +#include "yaml-cpp/node/type.h" + +namespace YAML { +namespace detail { +class node; +class node_data; +struct iterator_value; +} // namespace detail +} // namespace YAML + +namespace YAML { +class YAML_CPP_API Node { + public: + friend class NodeBuilder; + friend class NodeEvents; + friend struct detail::iterator_value; + friend class detail::node; + friend class detail::node_data; + template + friend class detail::iterator_base; + template + friend struct as_if; + + typedef YAML::iterator iterator; + typedef YAML::const_iterator const_iterator; + + Node(); + explicit Node(NodeType::value type); + template + explicit Node(const T& rhs); + explicit Node(const detail::iterator_value& rhs); + Node(const Node& rhs); + ~Node(); + + YAML::Mark Mark() const; + NodeType::value Type() const; + bool IsDefined() const; + bool IsNull() const { return Type() == NodeType::Null; } + bool IsScalar() const { return Type() == NodeType::Scalar; } + bool IsSequence() const { return Type() == NodeType::Sequence; } + bool IsMap() const { return Type() == NodeType::Map; } + + // bool conversions + YAML_CPP_OPERATOR_BOOL() + bool operator!() const { return !IsDefined(); } + + // access + template + T as() const; + template + T as(const S& fallback) const; + const std::string& Scalar() const; + + const std::string& Tag() const; + void SetTag(const std::string& tag); + + // style + // WARNING: This API might change in future releases. + EmitterStyle::value Style() const; + void SetStyle(EmitterStyle::value style); + + // assignment + bool is(const Node& rhs) const; + template + Node& operator=(const T& rhs); + Node& operator=(const Node& rhs); + void reset(const Node& rhs = Node()); + + // size/iterator + std::size_t size() const; + + const_iterator begin() const; + iterator begin(); + + const_iterator end() const; + iterator end(); + + // sequence + template + void push_back(const T& rhs); + void push_back(const Node& rhs); + + // indexing + template + const Node operator[](const Key& key) const; + template + Node operator[](const Key& key); + template + bool remove(const Key& key); + + const Node operator[](const Node& key) const; + Node operator[](const Node& key); + bool remove(const Node& key); + + // map + template + void force_insert(const Key& key, const Value& value); + + private: + enum Zombie { ZombieNode }; + explicit Node(Zombie); + explicit Node(detail::node& node, detail::shared_memory_holder pMemory); + + void EnsureNodeExists() const; + + template + void Assign(const T& rhs); + void Assign(const char* rhs); + void Assign(char* rhs); + + void AssignData(const Node& rhs); + void AssignNode(const Node& rhs); + + private: + bool m_isValid; + mutable detail::shared_memory_holder m_pMemory; + mutable detail::node* m_pNode; +}; + +YAML_CPP_API bool operator==(const Node& lhs, const Node& rhs); + +YAML_CPP_API Node Clone(const Node& node); + +template +struct convert; +} + +#endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/parse.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/parse.h new file mode 100644 index 00000000000000..7745fd7245bec0 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/parse.h @@ -0,0 +1,78 @@ +#ifndef VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include +#include + +#include "yaml-cpp/dll.h" + +namespace YAML { +class Node; + +/** + * Loads the input string as a single YAML document. + * + * @throws {@link ParserException} if it is malformed. + */ +YAML_CPP_API Node Load(const std::string& input); + +/** + * Loads the input string as a single YAML document. + * + * @throws {@link ParserException} if it is malformed. + */ +YAML_CPP_API Node Load(const char* input); + +/** + * Loads the input stream as a single YAML document. + * + * @throws {@link ParserException} if it is malformed. + */ +YAML_CPP_API Node Load(std::istream& input); + +/** + * Loads the input file as a single YAML document. + * + * @throws {@link ParserException} if it is malformed. + * @throws {@link BadFile} if the file cannot be loaded. + */ +YAML_CPP_API Node LoadFile(const std::string& filename); + +/** + * Loads the input string as a list of YAML documents. + * + * @throws {@link ParserException} if it is malformed. + */ +YAML_CPP_API std::vector LoadAll(const std::string& input); + +/** + * Loads the input string as a list of YAML documents. + * + * @throws {@link ParserException} if it is malformed. + */ +YAML_CPP_API std::vector LoadAll(const char* input); + +/** + * Loads the input stream as a list of YAML documents. + * + * @throws {@link ParserException} if it is malformed. + */ +YAML_CPP_API std::vector LoadAll(std::istream& input); + +/** + * Loads the input file as a list of YAML documents. + * + * @throws {@link ParserException} if it is malformed. + * @throws {@link BadFile} if the file cannot be loaded. + */ +YAML_CPP_API std::vector LoadAllFromFile(const std::string& filename); +} // namespace YAML + +#endif // VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/ptr.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/ptr.h new file mode 100644 index 00000000000000..ce085dd5cd8ad1 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/ptr.h @@ -0,0 +1,29 @@ +#ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" +#include + +namespace YAML { +namespace detail { +class node; +class node_ref; +class node_data; +class memory; +class memory_holder; + +typedef std::shared_ptr shared_node; +typedef std::shared_ptr shared_node_ref; +typedef std::shared_ptr shared_node_data; +typedef std::shared_ptr shared_memory_holder; +typedef std::shared_ptr shared_memory; +} +} + +#endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/node/type.h b/phonelibs/yaml-cpp/include/yaml-cpp/node/type.h new file mode 100644 index 00000000000000..9d55ca96621619 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/node/type.h @@ -0,0 +1,16 @@ +#ifndef VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +namespace YAML { +struct NodeType { + enum value { Undefined, Null, Scalar, Sequence, Map }; +}; +} + +#endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/noncopyable.h b/phonelibs/yaml-cpp/include/yaml-cpp/noncopyable.h new file mode 100644 index 00000000000000..a261040739bc17 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/noncopyable.h @@ -0,0 +1,25 @@ +#ifndef NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" + +namespace YAML { +// this is basically boost::noncopyable +class YAML_CPP_API noncopyable { + protected: + noncopyable() {} + ~noncopyable() {} + + private: + noncopyable(const noncopyable&); + const noncopyable& operator=(const noncopyable&); +}; +} + +#endif // NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/null.h b/phonelibs/yaml-cpp/include/yaml-cpp/null.h new file mode 100644 index 00000000000000..b9521d488a6acb --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/null.h @@ -0,0 +1,26 @@ +#ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/dll.h" +#include + +namespace YAML { +class Node; + +struct YAML_CPP_API _Null {}; +inline bool operator==(const _Null&, const _Null&) { return true; } +inline bool operator!=(const _Null&, const _Null&) { return false; } + +YAML_CPP_API bool IsNull(const Node& node); // old API only +YAML_CPP_API bool IsNullString(const std::string& str); + +extern YAML_CPP_API _Null Null; +} + +#endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/ostream_wrapper.h b/phonelibs/yaml-cpp/include/yaml-cpp/ostream_wrapper.h new file mode 100644 index 00000000000000..09d45f39b78b15 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/ostream_wrapper.h @@ -0,0 +1,72 @@ +#ifndef OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include + +#include "yaml-cpp/dll.h" + +namespace YAML { +class YAML_CPP_API ostream_wrapper { + public: + ostream_wrapper(); + explicit ostream_wrapper(std::ostream& stream); + ~ostream_wrapper(); + + void write(const std::string& str); + void write(const char* str, std::size_t size); + + void set_comment() { m_comment = true; } + + const char* str() const { + if (m_pStream) { + return 0; + } else { + m_buffer[m_pos] = '\0'; + return &m_buffer[0]; + } + } + + std::size_t row() const { return m_row; } + std::size_t col() const { return m_col; } + std::size_t pos() const { return m_pos; } + bool comment() const { return m_comment; } + + private: + void update_pos(char ch); + + private: + mutable std::vector m_buffer; + std::ostream* const m_pStream; + + std::size_t m_pos; + std::size_t m_row, m_col; + bool m_comment; +}; + +template +inline ostream_wrapper& operator<<(ostream_wrapper& stream, + const char(&str)[N]) { + stream.write(str, N - 1); + return stream; +} + +inline ostream_wrapper& operator<<(ostream_wrapper& stream, + const std::string& str) { + stream.write(str); + return stream; +} + +inline ostream_wrapper& operator<<(ostream_wrapper& stream, char ch) { + stream.write(&ch, 1); + return stream; +} +} + +#endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/parser.h b/phonelibs/yaml-cpp/include/yaml-cpp/parser.h new file mode 100644 index 00000000000000..ceac22d0268929 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/parser.h @@ -0,0 +1,86 @@ +#ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include + +#include "yaml-cpp/dll.h" +#include "yaml-cpp/noncopyable.h" + +namespace YAML { +class EventHandler; +class Node; +class Scanner; +struct Directives; +struct Token; + +/** + * A parser turns a stream of bytes into one stream of "events" per YAML + * document in the input stream. + */ +class YAML_CPP_API Parser : private noncopyable { + public: + /** Constructs an empty parser (with no input. */ + Parser(); + + /** + * Constructs a parser from the given input stream. The input stream must + * live as long as the parser. + */ + explicit Parser(std::istream& in); + + ~Parser(); + + /** Evaluates to true if the parser has some valid input to be read. */ + explicit operator bool() const; + + /** + * Resets the parser with the given input stream. Any existing state is + * erased. + */ + void Load(std::istream& in); + + /** + * Handles the next document by calling events on the {@code eventHandler}. + * + * @throw a ParserException on error. + * @return false if there are no more documents + */ + bool HandleNextDocument(EventHandler& eventHandler); + + void PrintTokens(std::ostream& out); + + private: + /** + * Reads any directives that are next in the queue, setting the internal + * {@code m_pDirectives} state. + */ + void ParseDirectives(); + + void HandleDirective(const Token& token); + + /** + * Handles a "YAML" directive, which should be of the form 'major.minor' (like + * a version number). + */ + void HandleYamlDirective(const Token& token); + + /** + * Handles a "TAG" directive, which should be of the form 'handle prefix', + * where 'handle' is converted to 'prefix' in the file. + */ + void HandleTagDirective(const Token& token); + + private: + std::unique_ptr m_pScanner; + std::unique_ptr m_pDirectives; +}; +} + +#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/stlemitter.h b/phonelibs/yaml-cpp/include/yaml-cpp/stlemitter.h new file mode 100644 index 00000000000000..06780c861f16c1 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/stlemitter.h @@ -0,0 +1,51 @@ +#ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include +#include +#include +#include + +namespace YAML { +template +inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) { + emitter << BeginSeq; + for (typename Seq::const_iterator it = seq.begin(); it != seq.end(); ++it) + emitter << *it; + emitter << EndSeq; + return emitter; +} + +template +inline Emitter& operator<<(Emitter& emitter, const std::vector& v) { + return EmitSeq(emitter, v); +} + +template +inline Emitter& operator<<(Emitter& emitter, const std::list& v) { + return EmitSeq(emitter, v); +} + +template +inline Emitter& operator<<(Emitter& emitter, const std::set& v) { + return EmitSeq(emitter, v); +} + +template +inline Emitter& operator<<(Emitter& emitter, const std::map& m) { + typedef typename std::map map; + emitter << BeginMap; + for (typename map::const_iterator it = m.begin(); it != m.end(); ++it) + emitter << Key << it->first << Value << it->second; + emitter << EndMap; + return emitter; +} +} + +#endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/traits.h b/phonelibs/yaml-cpp/include/yaml-cpp/traits.h new file mode 100644 index 00000000000000..f33d0e1f637385 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/traits.h @@ -0,0 +1,103 @@ +#ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +namespace YAML { +template +struct is_numeric { + enum { value = false }; +}; + +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +#if defined(_MSC_VER) && (_MSC_VER < 1310) +template <> +struct is_numeric<__int64> { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +#else +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +#endif +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; +template <> +struct is_numeric { + enum { value = true }; +}; + +template +struct enable_if_c { + typedef T type; +}; + +template +struct enable_if_c {}; + +template +struct enable_if : public enable_if_c {}; + +template +struct disable_if_c { + typedef T type; +}; + +template +struct disable_if_c {}; + +template +struct disable_if : public disable_if_c {}; +} + +#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/include/yaml-cpp/yaml.h b/phonelibs/yaml-cpp/include/yaml-cpp/yaml.h new file mode 100644 index 00000000000000..7f515efb961056 --- /dev/null +++ b/phonelibs/yaml-cpp/include/yaml-cpp/yaml.h @@ -0,0 +1,24 @@ +#ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || \ + (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ + (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +#include "yaml-cpp/parser.h" +#include "yaml-cpp/emitter.h" +#include "yaml-cpp/emitterstyle.h" +#include "yaml-cpp/stlemitter.h" +#include "yaml-cpp/exceptions.h" + +#include "yaml-cpp/node/node.h" +#include "yaml-cpp/node/impl.h" +#include "yaml-cpp/node/convert.h" +#include "yaml-cpp/node/iterator.h" +#include "yaml-cpp/node/detail/impl.h" +#include "yaml-cpp/node/parse.h" +#include "yaml-cpp/node/emit.h" + +#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/phonelibs/yaml-cpp/lib/libyaml-cpp.a b/phonelibs/yaml-cpp/lib/libyaml-cpp.a new file mode 100644 index 00000000000000..f871781d35c297 Binary files /dev/null and b/phonelibs/yaml-cpp/lib/libyaml-cpp.a differ diff --git a/phonelibs/yaml-cpp/x64/lib/libyaml-cpp.a b/phonelibs/yaml-cpp/x64/lib/libyaml-cpp.a new file mode 100644 index 00000000000000..eb1a3637d93605 Binary files /dev/null and b/phonelibs/yaml-cpp/x64/lib/libyaml-cpp.a differ diff --git a/phonelibs/zmq/aarch64-linux/bin/curve_keygen b/phonelibs/zmq/aarch64-linux/bin/curve_keygen deleted file mode 100755 index 3d76817f73c7f9..00000000000000 Binary files a/phonelibs/zmq/aarch64-linux/bin/curve_keygen and /dev/null differ diff --git a/phonelibs/zmq/aarch64-linux/lib/libczmq.a b/phonelibs/zmq/aarch64-linux/lib/libczmq.a deleted file mode 100644 index ba2b0a3ca663dd..00000000000000 Binary files a/phonelibs/zmq/aarch64-linux/lib/libczmq.a and /dev/null differ diff --git a/phonelibs/zmq/aarch64-linux/lib/libczmq.la b/phonelibs/zmq/aarch64-linux/lib/libczmq.la deleted file mode 100755 index 81ef66bdbb0340..00000000000000 --- a/phonelibs/zmq/aarch64-linux/lib/libczmq.la +++ /dev/null @@ -1,41 +0,0 @@ -# libczmq.la - a libtool library file -# Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='libczmq.so.4' - -# Names of this library. -library_names='libczmq.so.4.0.2 libczmq.so.4 libczmq.so' - -# The name of the static archive. -old_library='libczmq.a' - -# Linker flags that can not go in dependency_libs. -inherited_linker_flags=' -pthread' - -# Libraries that this one depends upon. -dependency_libs=' -L/home/nvidia/build/zmq/lib /home/nvidia/build/zmq/lib/libzmq.la -lrt -lpthread -ldl -luuid' - -# Names of additional weak libraries provided by this library -weak_library_names='' - -# Version information for libczmq. -current=4 -age=0 -revision=2 - -# Is this an already installed library? -installed=yes - -# Should we warn about portability when linking against -modules? -shouldnotlink=no - -# Files to dlopen/dlpreopen -dlopen='' -dlpreopen='' - -# Directory that this library needs to be installed in: -libdir='/home/nvidia/build/zmq/lib' diff --git a/phonelibs/zmq/aarch64-linux/lib/libczmq.so.4.0.2 b/phonelibs/zmq/aarch64-linux/lib/libczmq.so.4.0.2 deleted file mode 100755 index bb9c2d52ebdaea..00000000000000 Binary files a/phonelibs/zmq/aarch64-linux/lib/libczmq.so.4.0.2 and /dev/null differ diff --git a/phonelibs/zmq/aarch64-linux/lib/libzmq.a b/phonelibs/zmq/aarch64-linux/lib/libzmq.a deleted file mode 100644 index 7578d109e45ed4..00000000000000 Binary files a/phonelibs/zmq/aarch64-linux/lib/libzmq.a and /dev/null differ diff --git a/phonelibs/zmq/aarch64-linux/lib/libzmq.la b/phonelibs/zmq/aarch64-linux/lib/libzmq.la deleted file mode 100755 index 2aef5c45d0f8a6..00000000000000 --- a/phonelibs/zmq/aarch64-linux/lib/libzmq.la +++ /dev/null @@ -1,41 +0,0 @@ -# libzmq.la - a libtool library file -# Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1.7ubuntu1 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='libzmq.so.5' - -# Names of this library. -library_names='libzmq.so.5.1.2 libzmq.so.5 libzmq.so' - -# The name of the static archive. -old_library='libzmq.a' - -# Linker flags that can not go in dependency_libs. -inherited_linker_flags='' - -# Libraries that this one depends upon. -dependency_libs=' -lrt -lpthread -ldl' - -# Names of additional weak libraries provided by this library -weak_library_names='' - -# Version information for libzmq. -current=6 -age=1 -revision=2 - -# Is this an already installed library? -installed=yes - -# Should we warn about portability when linking against -modules? -shouldnotlink=no - -# Files to dlopen/dlpreopen -dlopen='' -dlpreopen='' - -# Directory that this library needs to be installed in: -libdir='/home/nvidia/build/zmq/lib' diff --git a/phonelibs/zmq/aarch64-linux/lib/libzmq.so.5.1.2 b/phonelibs/zmq/aarch64-linux/lib/libzmq.so.5.1.2 deleted file mode 100755 index e96750a8ef4365..00000000000000 Binary files a/phonelibs/zmq/aarch64-linux/lib/libzmq.so.5.1.2 and /dev/null differ diff --git a/phonelibs/zmq/aarch64-linux/lib/pkgconfig/libzmq.pc b/phonelibs/zmq/aarch64-linux/lib/pkgconfig/libzmq.pc deleted file mode 100644 index 885271757d640f..00000000000000 --- a/phonelibs/zmq/aarch64-linux/lib/pkgconfig/libzmq.pc +++ /dev/null @@ -1,11 +0,0 @@ -prefix=/home/nvidia/build/zmq -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include - -Name: libzmq -Description: 0MQ c++ library -Version: 4.2.2 -Libs: -L${libdir} -lzmq -Libs.private: -lstdc++ -Cflags: -I${includedir} diff --git a/phonelibs/zmq/aarch64-linux/share/man/man1/zmakecert.1 b/phonelibs/zmq/aarch64-linux/share/man/man1/zmakecert.1 deleted file mode 100644 index 7a702496b821e8..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man1/zmakecert.1 +++ /dev/null @@ -1,73 +0,0 @@ -'\" t -.\" Title: zmakecert -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZMAKECERT" "1" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmakecert \- no title found -.SH "SYNOPSIS" -.sp -.nf -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zmakecert\&.c\*(Aq\&. -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zmakecert\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -Please add \fI@header\fR section in \fI\&./\&.\&./src/zmakecert\&.c\fR\&. -.sp -Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zmakecert\&.c\fR\&. -.SH "EXAMPLE" -.PP -\fBFrom zmakecert_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -Please add \*(Aq@selftest\*(Aq section in \*(Aq\&./\&.\&./src/zmakecert\&.c\*(Aq\&. -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zactor.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zactor.3 deleted file mode 100644 index 481edc396e61fb..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zactor.3 +++ /dev/null @@ -1,127 +0,0 @@ -'\" t -.\" Title: zactor -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZACTOR" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zactor \- simple actor framework -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// Actors get a pipe and arguments from caller -typedef void (zactor_fn) ( - zsock_t *pipe, void *args); - -// Create a new actor passing arbitrary arguments reference\&. -CZMQ_EXPORT zactor_t * - zactor_new (zactor_fn task, void *args); - -// Destroy an actor\&. -CZMQ_EXPORT void - zactor_destroy (zactor_t **self_p); - -// Send a zmsg message to the actor, take ownership of the message -// and destroy when it has been sent\&. -CZMQ_EXPORT int - zactor_send (zactor_t *self, zmsg_t **msg_p); - -// Receive a zmsg message from the actor\&. Returns NULL if the actor -// was interrupted before the message could be received, or if there -// was a timeout on the actor\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zmsg_t * - zactor_recv (zactor_t *self); - -// Probe the supplied object, and report if it looks like a zactor_t\&. -CZMQ_EXPORT bool - zactor_is (void *self); - -// Probe the supplied reference\&. If it looks like a zactor_t instance, -// return the underlying libzmq actor handle; else if it looks like -// a libzmq actor handle, return the supplied value\&. -CZMQ_EXPORT void * - zactor_resolve (void *self); - -// Return the actor\*(Aqs zsock handle\&. Use this when you absolutely need -// to work with the zsock instance rather than the actor\&. -CZMQ_EXPORT zsock_t * - zactor_sock (zactor_t *self); - -// Self test of this class\&. -CZMQ_EXPORT void - zactor_test (bool verbose); - -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zactor\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zactor class provides a simple actor framework\&. It replaces the CZMQ zthread class, which had a complex API that did not fit the CLASS standard\&. A CZMQ actor is implemented as a thread plus a PAIR\-PAIR pipe\&. The constructor and destructor are always synchronized, so the caller can be sure all resources are created, and destroyed, when these calls complete\&. (This solves a major problem with zthread, that a caller could not be sure when a child thread had finished\&.) -.sp -A zactor_t instance acts like a zsock_t and you can pass it to any CZMQ method that would take a zsock_t argument, including methods in zframe, zmsg, zstr, and zpoller\&. (zloop somehow escaped and needs catching\&.) -.sp -An actor function MUST call zsock_signal (pipe) when initialized and MUST listen to pipe and exit on $TERM command\&. -.sp -Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zactor\&.c\fR\&. -.SH "EXAMPLE" -.PP -\fBFrom zactor_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zactor_t *actor = zactor_new (echo_actor, "Hello, World"); -assert (actor); -zstr_sendx (actor, "ECHO", "This is a string", NULL); -char *string = zstr_recv (actor); -assert (streq (string, "This is a string")); -free (string); -zactor_destroy (&actor); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zarmour.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zarmour.3 deleted file mode 100644 index ea806777259889..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zarmour.3 +++ /dev/null @@ -1,372 +0,0 @@ -'\" t -.\" Title: zarmour -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZARMOUR" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zarmour \- armoured text encoding and decoding -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -#define ZARMOUR_MODE_BASE64_STD 0 // Standard base 64 -#define ZARMOUR_MODE_BASE64_URL 1 // URL and filename friendly base 64 -#define ZARMOUR_MODE_BASE32_STD 2 // Standard base 32 -#define ZARMOUR_MODE_BASE32_HEX 3 // Extended hex base 32 -#define ZARMOUR_MODE_BASE16 4 // Standard base 16 -#define ZARMOUR_MODE_Z85 5 // Z85 from ZeroMQ RFC 32 - -// Create a new zarmour -CZMQ_EXPORT zarmour_t * - zarmour_new (void); - -// Destroy the zarmour -CZMQ_EXPORT void - zarmour_destroy (zarmour_t **self_p); - -// Encode a stream of bytes into an armoured string\&. Returns the armoured -// string, or NULL if there was insufficient memory available to allocate -// a new string\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zarmour_encode (zarmour_t *self, const byte *data, size_t size); - -// Decode an armoured string into a chunk\&. The decoded output is -// null\-terminated, so it may be treated as a string, if that\*(Aqs what -// it was prior to encoding\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zchunk_t * - zarmour_decode (zarmour_t *self, const char *data); - -// Get the mode property\&. -CZMQ_EXPORT int - zarmour_mode (zarmour_t *self); - -// Get printable string for mode\&. -CZMQ_EXPORT const char * - zarmour_mode_str (zarmour_t *self); - -// Set the mode property\&. -CZMQ_EXPORT void - zarmour_set_mode (zarmour_t *self, int mode); - -// Return true if padding is turned on\&. -CZMQ_EXPORT bool - zarmour_pad (zarmour_t *self); - -// Turn padding on or off\&. Default is on\&. -CZMQ_EXPORT void - zarmour_set_pad (zarmour_t *self, bool pad); - -// Get the padding character\&. -CZMQ_EXPORT char - zarmour_pad_char (zarmour_t *self); - -// Set the padding character\&. -CZMQ_EXPORT void - zarmour_set_pad_char (zarmour_t *self, char pad_char); - -// Return if splitting output into lines is turned on\&. Default is off\&. -CZMQ_EXPORT bool - zarmour_line_breaks (zarmour_t *self); - -// Turn splitting output into lines on or off\&. -CZMQ_EXPORT void - zarmour_set_line_breaks (zarmour_t *self, bool line_breaks); - -// Get the line length used for splitting lines\&. -CZMQ_EXPORT size_t - zarmour_line_length (zarmour_t *self); - -// Set the line length used for splitting lines\&. -CZMQ_EXPORT void - zarmour_set_line_length (zarmour_t *self, size_t line_length); - -// Print properties of object -CZMQ_EXPORT void - zarmour_print (zarmour_t *self); - -// Self test of this class\&. -CZMQ_EXPORT void - zarmour_test (bool verbose); - -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zarmour\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -zarmour \- armoured text encoding and decoding -.sp -The zarmour class implements encoding and decoding of armoured text data\&. The following codecs are implemented: * RFC 4648 (\m[blue]\fBhttp://www\&.ietf\&.org/rfc/rfc4648\&.txt\fR\m[]) \- base64 \- base64url \- base32 \- base32hex \- base16 * Z85 (\m[blue]\fBhttp://rfc\&.zeromq\&.org/spec:32\fR\m[]) All RFC4648 base64 and base32 variants support padding the output\&. The pad character is configurable\&. Default is padding on, with character \fI=\fR\&. Additionally, in some cases (e\&.g\&. MIME), splitting the output into lines of a specific length is required\&. This feature is also supported, though turned off by default\&. The z85 mode does neither padding nor line breaks; it is merely a wrapping of the corresponding libzmq methods\&. Encoding will assert if input length is not divisible by 4 and decoding will assert if input length is not divisible by 5\&. -.SH "EXAMPLE" -.PP -\fBFrom zarmour_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zarmour_t *self = zarmour_new (); -assert (self); - -int mode = zarmour_mode (self); -assert (mode == ZARMOUR_MODE_BASE64_STD); - -zarmour_set_mode (self, ZARMOUR_MODE_BASE64_URL); -mode = zarmour_mode (self); -assert (mode == ZARMOUR_MODE_BASE64_URL); - -assert (zarmour_pad (self)); -zarmour_set_pad (self, false); -assert (!zarmour_pad (self)); - -assert (zarmour_pad_char (self) == \*(Aq=\*(Aq); -zarmour_set_pad_char (self, \*(Aq!\*(Aq); -assert (zarmour_pad_char (self) == \*(Aq!\*(Aq); -zarmour_set_pad_char (self, \*(Aq=\*(Aq); -assert (zarmour_pad_char (self) == \*(Aq=\*(Aq); - -assert (!zarmour_line_breaks (self)); -zarmour_set_line_breaks (self, true); -assert (zarmour_line_breaks (self)); - -assert (zarmour_line_length (self) == 72); -zarmour_set_line_length (self, 64); -assert (zarmour_line_length (self) == 64); - -// Test against test vectors from RFC4648\&. -zarmour_set_mode (self, ZARMOUR_MODE_BASE64_STD); -if (verbose) - zarmour_print (self); - -s_armour_test (self, "", "", verbose); -s_armour_test (self, "f", "Zg", verbose); -s_armour_test (self, "fo", "Zm8", verbose); -s_armour_test (self, "foo", "Zm9v", verbose); -s_armour_test (self, "foob", "Zm9vYg", verbose); -s_armour_test (self, "fooba", "Zm9vYmE", verbose); -s_armour_test (self, "foobar", "Zm9vYmFy", verbose); -zarmour_set_pad (self, true); -if (verbose) - zarmour_print (self); - -s_armour_test (self, "", "", verbose); -s_armour_test (self, "f", "Zg==", verbose); -s_armour_test (self, "fo", "Zm8=", verbose); -s_armour_test (self, "foo", "Zm9v", verbose); -s_armour_test (self, "foob", "Zm9vYg==", verbose); -s_armour_test (self, "fooba", "Zm9vYmE=", verbose); -s_armour_test (self, "foobar", "Zm9vYmFy", verbose); - -zarmour_set_pad (self, false); -zarmour_set_mode (self, ZARMOUR_MODE_BASE64_URL); -if (verbose) - zarmour_print (self); - -s_armour_test (self, "", "", verbose); -s_armour_test (self, "f", "Zg", verbose); -s_armour_test (self, "fo", "Zm8", verbose); -s_armour_test (self, "foo", "Zm9v", verbose); -s_armour_test (self, "foob", "Zm9vYg", verbose); -s_armour_test (self, "fooba", "Zm9vYmE", verbose); -s_armour_test (self, "foobar", "Zm9vYmFy", verbose); -zarmour_set_pad (self, true); -if (verbose) - zarmour_print (self); - -s_armour_test (self, "", "", verbose); -s_armour_test (self, "f", "Zg==", verbose); -s_armour_test (self, "fo", "Zm8=", verbose); -s_armour_test (self, "foo", "Zm9v", verbose); -s_armour_test (self, "foob", "Zm9vYg==", verbose); -s_armour_test (self, "fooba", "Zm9vYmE=", verbose); -s_armour_test (self, "foobar", "Zm9vYmFy", verbose); - -zarmour_set_pad (self, false); -zarmour_set_mode (self, ZARMOUR_MODE_BASE32_STD); -if (verbose) - zarmour_print (self); - -s_armour_test (self, "", "", verbose); -s_armour_test (self, "f", "MY", verbose); -s_armour_test (self, "fo", "MZXQ", verbose); -s_armour_test (self, "foo", "MZXW6", verbose); -s_armour_test (self, "foob", "MZXW6YQ", verbose); -s_armour_test (self, "fooba", "MZXW6YTB", verbose); -s_armour_test (self, "foobar", "MZXW6YTBOI", verbose); -s_armour_decode (self, "my", "f", verbose); -s_armour_decode (self, "mzxq", "fo", verbose); -s_armour_decode (self, "mzxw6", "foo", verbose); -s_armour_decode (self, "mzxw6yq", "foob", verbose); -s_armour_decode (self, "mzxw6ytb", "fooba", verbose); -s_armour_decode (self, "mzxw6ytboi", "foobar", verbose); -zarmour_set_pad (self, true); -if (verbose) - zarmour_print (self); - -s_armour_test (self, "", "", verbose); -s_armour_test (self, "f", "MY======", verbose); -s_armour_test (self, "fo", "MZXQ====", verbose); -s_armour_test (self, "foo", "MZXW6===", verbose); -s_armour_test (self, "foob", "MZXW6YQ=", verbose); -s_armour_test (self, "fooba", "MZXW6YTB", verbose); -s_armour_test (self, "foobar", "MZXW6YTBOI======", verbose); -s_armour_decode (self, "my======", "f", verbose); -s_armour_decode (self, "mzxq====", "fo", verbose); -s_armour_decode (self, "mzxw6===", "foo", verbose); -s_armour_decode (self, "mzxw6yq=", "foob", verbose); -s_armour_decode (self, "mzxw6ytb", "fooba", verbose); -s_armour_decode (self, "mzxw6ytboi======", "foobar", verbose); - -zarmour_set_pad (self, false); -zarmour_set_mode (self, ZARMOUR_MODE_BASE32_HEX); -if (verbose) - zarmour_print (self); - -s_armour_test (self, "", "", verbose); -s_armour_test (self, "f", "CO", verbose); -s_armour_test (self, "fo", "CPNG", verbose); -s_armour_test (self, "foo", "CPNMU", verbose); -s_armour_test (self, "foob", "CPNMUOG", verbose); -s_armour_test (self, "fooba", "CPNMUOJ1", verbose); -s_armour_test (self, "foobar", "CPNMUOJ1E8", verbose); -s_armour_decode (self, "co", "f", verbose); -s_armour_decode (self, "cpng", "fo", verbose); -s_armour_decode (self, "cpnmu", "foo", verbose); -s_armour_decode (self, "cpnmuog", "foob", verbose); -s_armour_decode (self, "cpnmuoj1", "fooba", verbose); -s_armour_decode (self, "cpnmuoj1e8", "foobar", verbose); -zarmour_set_pad (self, true); -if (verbose) - zarmour_print (self); - -s_armour_test (self, "", "", verbose); -s_armour_test (self, "f", "CO======", verbose); -s_armour_test (self, "fo", "CPNG====", verbose); -s_armour_test (self, "foo", "CPNMU===", verbose); -s_armour_test (self, "foob", "CPNMUOG=", verbose); -s_armour_test (self, "fooba", "CPNMUOJ1", verbose); -s_armour_test (self, "foobar", "CPNMUOJ1E8======", verbose); -s_armour_decode (self, "co======", "f", verbose); -s_armour_decode (self, "cpng====", "fo", verbose); -s_armour_decode (self, "cpnmu===", "foo", verbose); -s_armour_decode (self, "cpnmuog=", "foob", verbose); -s_armour_decode (self, "cpnmuoj1", "fooba", verbose); -s_armour_decode (self, "cpnmuoj1e8======", "foobar", verbose); -zarmour_set_pad (self, true); - -zarmour_set_mode (self, ZARMOUR_MODE_BASE16); -if (verbose) - zarmour_print (self); - -s_armour_test (self, "", "", verbose); -s_armour_test (self, "f", "66", verbose); -s_armour_test (self, "fo", "666F", verbose); -s_armour_test (self, "foo", "666F6F", verbose); -s_armour_test (self, "foob", "666F6F62", verbose); -s_armour_test (self, "fooba", "666F6F6261", verbose); -s_armour_test (self, "foobar", "666F6F626172", verbose); -s_armour_decode (self, "666f", "fo", verbose); -s_armour_decode (self, "666f6f", "foo", verbose); -s_armour_decode (self, "666f6f62", "foob", verbose); -s_armour_decode (self, "666f6f6261", "fooba", verbose); -s_armour_decode (self, "666f6f626172", "foobar", verbose); - -#ifdef _INCLUDE_Z85 -// Z85 test is homemade; using 0, 4 and 8 bytes, with precalculated -// test vectors created with a libzmq test\&. -// \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- - -// Make a fake curve key from hex (base16) string, making sure -// there are no null bytes inside, so we can use our test utility -zarmour_set_mode (self, ZARMOUR_MODE_BASE16); -zarmour_set_line_breaks (self, false); - -zchunk_t *chunk = zarmour_decode (self, - "4E6F87E2FB6EB22A1EF5E257B75D79124949565F0B8B36A878A4F03111C96E0B"); -assert (chunk); - -zarmour_set_mode (self, ZARMOUR_MODE_Z85); // Z85 mode does not support padding or line breaks -zarmour_set_pad (self, false); // so these two are superfluous; -zarmour_set_line_breaks (self, false); // just for consistency -if (verbose) - zarmour_print (self); - -s_armour_test (self, "", "", verbose); -s_armour_test (self, "foob", "w]zP%", verbose); -s_armour_test (self, "foobar!!", "w]zP%vr9Im", verbose); -s_armour_test (self, (char *) zchunk_data (chunk), - "ph+{E}!&X?9}!I]W{sm(nL8@&3Yu{wC+<*\-5Y[[#", verbose); -zchunk_destroy (&chunk); -#endif - -// Armouring longer byte array to test line breaks -zarmour_set_pad (self, true); -zarmour_set_line_breaks (self, true); -byte test_data [256]; -int index; -for (index = 0; index < 256; index++) - test_data [index] = index; - -zarmour_set_mode (self, ZARMOUR_MODE_BASE64_STD); -s_armour_test_long (self, test_data, 256, verbose); -zarmour_set_mode (self, ZARMOUR_MODE_BASE64_URL); -s_armour_test_long (self, test_data, 256, verbose); -zarmour_set_mode (self, ZARMOUR_MODE_BASE32_STD); -s_armour_test_long (self, test_data, 256, verbose); -zarmour_set_mode (self, ZARMOUR_MODE_BASE32_HEX); -s_armour_test_long (self, test_data, 256, verbose); -zarmour_set_mode (self, ZARMOUR_MODE_BASE16); -s_armour_test_long (self, test_data, 256, verbose); -#ifdef _INCLUDE_Z85 -zarmour_set_mode (self, ZARMOUR_MODE_Z85); -s_armour_test_long (self, test_data, 256, verbose); -#endif - -zarmour_destroy (&self); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zauth.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zauth.3 deleted file mode 100644 index b119d13e9afec2..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zauth.3 +++ /dev/null @@ -1,309 +0,0 @@ -'\" t -.\" Title: zauth -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZAUTH" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zauth \- authentication for ZeroMQ security mechanisms -.SH "SYNOPSIS" -.sp -.nf -#define CURVE_ALLOW_ANY "*" - -// CZMQ v3 API (for use with zsock, not zsocket, which is deprecated)\&. -// -// Create new zauth actor instance\&. This installs authentication on all -// zsock sockets\&. Until you add policies, all incoming NULL connections are -// allowed (classic ZeroMQ behaviour), and all PLAIN and CURVE connections -// are denied: -// -// zactor_t *auth = zactor_new (zauth, NULL); -// -// Destroy zauth instance\&. This removes authentication and allows all -// connections to pass, without authentication: -// -// zactor_destroy (&auth); -// -// Note that all zauth commands are synchronous, so your application always -// waits for a signal from the actor after each command\&. -// -// Enable verbose logging of commands and activity\&. Verbose logging can help -// debug non\-trivial authentication policies: -// -// zstr_send (auth, "VERBOSE"); -// zsock_wait (auth); -// -// Allow (whitelist) a list of IP addresses\&. For NULL, all clients from -// these addresses will be accepted\&. For PLAIN and CURVE, they will be -// allowed to continue with authentication\&. You can call this method -// multiple times to whitelist more IP addresses\&. If you whitelist one -// or more addresses, any non\-whitelisted addresses are treated as -// blacklisted: -// -// zstr_sendx (auth, "ALLOW", "127\&.0\&.0\&.1", "127\&.0\&.0\&.2", NULL); -// zsock_wait (auth); -// -// Deny (blacklist) a list of IP addresses\&. For all security mechanisms, -// this rejects the connection without any further authentication\&. Use -// either a whitelist, or a blacklist, not not both\&. If you define both -// a whitelist and a blacklist, only the whitelist takes effect: -// -// zstr_sendx (auth, "DENY", "192\&.168\&.0\&.1", "192\&.168\&.0\&.2", NULL); -// zsock_wait (auth); -// -// Configure PLAIN authentication using a plain\-text password file\&. You can -// modify the password file at any time; zauth will reload it automatically -// if modified externally: -// -// zstr_sendx (auth, "PLAIN", filename, NULL); -// zsock_wait (auth); -// -// Configure CURVE authentication, using a directory that holds all public -// client certificates, i\&.e\&. their public keys\&. The certificates must be in -// zcert_save format\&. You can add and remove certificates in that directory -// at any time\&. To allow all client keys without checking, specify -// CURVE_ALLOW_ANY for the directory name: -// -// zstr_sendx (auth, "CURVE", directory, NULL); -// zsock_wait (auth); -// -// Configure GSSAPI authentication, using an underlying mechanism (usually -// Kerberos) to establish a secure context and perform mutual authentication: -// -// zstr_sendx (auth, "GSSAPI", NULL); -// zsock_wait (auth); -// -// This is the zauth constructor as a zactor_fn: -CZMQ_EXPORT void - zauth (zsock_t *pipe, void *certstore); - -// Selftest -CZMQ_EXPORT void - zauth_test (bool verbose); -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zauth\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -A zauth actor takes over authentication for all incoming connections in its context\&. You can whitelist or blacklist peers based on IP address, and define policies for securing PLAIN, CURVE, and GSSAPI connections\&. -.sp -This class replaces zauth_v2, and is meant for applications that use the CZMQ v3 API (meaning, zsock)\&. -.SH "EXAMPLE" -.PP -\fBFrom zauth_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Create temporary directory for test files -# define TESTDIR "\&.test_zauth" -zsys_dir_create (TESTDIR); - -// Check there\*(Aqs no authentication -zsock_t *server = zsock_new (ZMQ_PULL); -assert (server); -zsock_t *client = zsock_new (ZMQ_PUSH); -assert (client); -bool success = s_can_connect (&server, &client, true); -assert (success); - -// Install the authenticator -zactor_t *auth = zactor_new (zauth, NULL); -assert (auth); -if (verbose) { - zstr_sendx (auth, "VERBOSE", NULL); - zsock_wait (auth); -} -// Check there\*(Aqs no authentication on a default NULL server -success = s_can_connect (&server, &client, true); -assert (success); - -// When we set a domain on the server, we switch on authentication -// for NULL sockets, but with no policies, the client connection -// will be allowed\&. -zsock_set_zap_domain (server, "global"); -success = s_can_connect (&server, &client, true); -assert (success); - -// Blacklist 127\&.0\&.0\&.1, connection should fail -zsock_set_zap_domain (server, "global"); -zstr_sendx (auth, "DENY", "127\&.0\&.0\&.1", NULL); -zsock_wait (auth); -success = s_can_connect (&server, &client, true); -assert (!success); - -// Whitelist our address, which overrides the blacklist -zsock_set_zap_domain (server, "global"); -zstr_sendx (auth, "ALLOW", "127\&.0\&.0\&.1", NULL); -zsock_wait (auth); -success = s_can_connect (&server, &client, true); -assert (success); - -// Try PLAIN authentication -zsock_set_plain_server (server, 1); -zsock_set_plain_username (client, "admin"); -zsock_set_plain_password (client, "Password"); -success = s_can_connect (&server, &client, true); -assert (!success); - -FILE *password = fopen (TESTDIR "/password\-file", "w"); -assert (password); -fprintf (password, "admin=Password\en"); -fclose (password); -zsock_set_plain_server (server, 1); -zsock_set_plain_username (client, "admin"); -zsock_set_plain_password (client, "Password"); -zstr_sendx (auth, "PLAIN", TESTDIR "/password\-file", NULL); -zsock_wait (auth); -success = s_can_connect (&server, &client, true); -assert (success); - -zsock_set_plain_server (server, 1); -zsock_set_plain_username (client, "admin"); -zsock_set_plain_password (client, "Bogus"); -success = s_can_connect (&server, &client, true); -assert (!success); - -if (zsys_has_curve ()) { - // Try CURVE authentication - // We\*(Aqll create two new certificates and save the client public - // certificate on disk; in a real case we\*(Aqd transfer this securely - // from the client machine to the server machine\&. - zcert_t *server_cert = zcert_new (); - assert (server_cert); - zcert_t *client_cert = zcert_new (); - assert (client_cert); - const char *server_key = zcert_public_txt (server_cert); - - // Test without setting\-up any authentication - zcert_apply (server_cert, server); - zcert_apply (client_cert, client); - zsock_set_curve_server (server, 1); - zsock_set_curve_serverkey (client, server_key); - success = s_can_connect (&server, &client, true); - assert (!success); - - // Test CURVE_ALLOW_ANY - zcert_apply (server_cert, server); - zcert_apply (client_cert, client); - zsock_set_curve_server (server, 1); - zsock_set_curve_serverkey (client, server_key); - zstr_sendx (auth, "CURVE", CURVE_ALLOW_ANY, NULL); - zsock_wait (auth); - success = s_can_connect (&server, &client, true); - assert (success); - - // Test full client authentication using certificates - zcert_set_meta (client_cert, "Hello", "%s", "World!"); - zcert_apply (server_cert, server); - zcert_apply (client_cert, client); - zsock_set_curve_server (server, 1); - zsock_set_curve_serverkey (client, server_key); - zcert_save_public (client_cert, TESTDIR "/mycert\&.txt"); - zstr_sendx (auth, "CURVE", TESTDIR, NULL); - zsock_wait (auth); - success = s_can_connect (&server, &client, false); - assert (success); - -#if (ZMQ_VERSION >= ZMQ_MAKE_VERSION (4, 1, 0)) - // Test send/recv certificate metadata - zframe_t *frame = zframe_recv (server); - assert (frame != NULL); - const char *meta = zframe_meta (frame, "Hello"); - assert (meta != NULL); - assert (streq (meta, "World!")); - zframe_destroy (&frame); - s_renew_sockets(&server, &client); -#endif - - zcert_destroy (&server_cert); - zcert_destroy (&client_cert); - - // Test custom zcertstore - zcertstore_t *certstore = zcertstore_new (NULL); - zcertstore_set_loader (certstore, s_test_loader, NULL, NULL); - zactor_destroy(&auth); - auth = zactor_new (zauth, certstore); - assert (auth); - if (verbose) { - zstr_sendx (auth, "VERBOSE", NULL); - zsock_wait (auth); - } - - byte public_key [32] = { 105, 76, 150, 58, 214, 191, 218, 65, 50, 172, - 131, 188, 247, 211, 136, 170, 227, 26, 57, 170, - 185, 63, 246, 225, 177, 230, 12, 8, 134, 136, - 105, 106 }; - byte secret_key [32] = { 245, 217, 172, 73, 106, 28, 195, 17, 218, 132, - 135, 209, 99, 240, 98, 232, 7, 137, 244, 100, - 242, 23, 29, 114, 70, 223, 83, 1, 113, 207, - 132, 149 }; - zcert_t *shared_cert = zcert_new_from (public_key, secret_key); - assert (shared_cert); - zcert_apply (shared_cert, server); - zcert_apply (shared_cert, client); - zsock_set_curve_server (server, 1); - zsock_set_curve_serverkey (client, "x?T*N/1Y{8goubv{Ts}#&#f}TXJ//DVe#D2HkoLU"); - success = s_can_connect (&server, &client, true); - assert (success); - zcert_destroy (&shared_cert); -} -// Remove the authenticator and check a normal connection works -zactor_destroy (&auth); -success = s_can_connect (&server, &client, true); -assert (success); - -zsock_destroy (&client); -zsock_destroy (&server); - -// Delete all test files -zdir_t *dir = zdir_new (TESTDIR, NULL); -assert (dir); -zdir_remove (dir, true); -zdir_destroy (&dir); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zbeacon.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zbeacon.3 deleted file mode 100644 index 40e3abbac4056a..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zbeacon.3 +++ /dev/null @@ -1,236 +0,0 @@ -'\" t -.\" Title: zbeacon -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZBEACON" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zbeacon \- LAN discovery and presence -.SH "SYNOPSIS" -.sp -.nf -// Create new zbeacon actor instance: -// -// zactor_t *beacon = zactor_new (zbeacon, NULL); -// -// Destroy zbeacon instance: -// -// zactor_destroy (&beacon); -// -// Enable verbose logging of commands and activity: -// -// zstr_send (beacon, "VERBOSE"); -// -// Configure beacon to run on specified UDP port, and return the name of -// the host, which can be used as endpoint for incoming connections\&. To -// force the beacon to operate on a given interface, set the environment -// variable ZSYS_INTERFACE, or call zsys_set_interface() before creating -// the beacon\&. If the system does not support UDP broadcasts (lacking a -// workable interface), returns an empty hostname: -// -// // Pictures: \*(Aqs\*(Aq = C string, \*(Aqi\*(Aq = int -// zsock_send (beacon, "si", "CONFIGURE", port_number); -// char *hostname = zstr_recv (beacon); -// -// Start broadcasting a beacon at a specified interval in msec\&. The beacon -// data can be at most UDP_FRAME_MAX bytes; this constant is defined in -// zsys\&.h to be 255: -// -// // Pictures: \*(Aqb\*(Aq = byte * data + size_t size -// zsock_send (beacon, "sbi", "PUBLISH", data, size, interval); -// -// Stop broadcasting the beacon: -// -// zstr_sendx (beacon, "SILENCE", NULL); -// -// Start listening to beacons from peers\&. The filter is used to do a prefix -// match on received beacons, to remove junk\&. Note that any received data -// that is identical to our broadcast beacon_data is discarded in any case\&. -// If the filter size is zero, we get all peer beacons: -// -// zsock_send (beacon, "sb", "SUBSCRIBE", filter_data, filter_size); -// -// Stop listening to other peers -// -// zstr_sendx (beacon, "UNSUBSCRIBE", NULL); -// -// Receive next beacon from a peer\&. Received beacons are always a 2\-frame -// message containing the ipaddress of the sender, and then the binary -// beacon data as published by the sender: -// -// zmsg_t *msg = zmsg_recv (beacon); -// -// This is the zbeacon constructor as a zactor_fn: -CZMQ_EXPORT void - zbeacon (zsock_t *pipe, void *unused); - -// Self test of this class -CZMQ_EXPORT void - zbeacon_test (bool verbose); -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zbeacon\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zbeacon class implements a peer\-to\-peer discovery service for local networks\&. A beacon can broadcast and/or capture service announcements using UDP messages on the local area network\&. This implementation uses IPv4 UDP broadcasts\&. You can define the format of your outgoing beacons, and set a filter that validates incoming beacons\&. Beacons are sent and received asynchronously in the background\&. -.sp -This class replaces zbeacon_v2, and is meant for applications that use the CZMQ v3 API (meaning, zsock)\&. -.SH "EXAMPLE" -.PP -\fBFrom zbeacon_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Test 1 \- two beacons, one speaking, one listening -// Create speaker beacon to broadcast our service -zactor_t *speaker = zactor_new (zbeacon, NULL); -assert (speaker); -if (verbose) - zstr_sendx (speaker, "VERBOSE", NULL); - -zsock_send (speaker, "si", "CONFIGURE", 9999); -char *hostname = zstr_recv (speaker); -if (!*hostname) { - printf ("OK (skipping test, no UDP broadcasting)\en"); - zactor_destroy (&speaker); - free (hostname); - return; -} -free (hostname); - -// Create listener beacon on port 9999 to lookup service -zactor_t *listener = zactor_new (zbeacon, NULL); -assert (listener); -if (verbose) - zstr_sendx (listener, "VERBOSE", NULL); -zsock_send (listener, "si", "CONFIGURE", 9999); -hostname = zstr_recv (listener); -assert (*hostname); -free (hostname); - -// We will broadcast the magic value 0xCAFE -byte announcement [2] = { 0xCA, 0xFE }; -zsock_send (speaker, "sbi", "PUBLISH", announcement, 2, 100); -// We will listen to anything (empty subscription) -zsock_send (listener, "sb", "SUBSCRIBE", "", 0); - -// Wait for at most 1/2 second if there\*(Aqs no broadcasting -zsock_set_rcvtimeo (listener, 500); -char *ipaddress = zstr_recv (listener); -if (ipaddress) { - zframe_t *content = zframe_recv (listener); - assert (zframe_size (content) == 2); - assert (zframe_data (content) [0] == 0xCA); - assert (zframe_data (content) [1] == 0xFE); - zframe_destroy (&content); - zstr_free (&ipaddress); - zstr_sendx (speaker, "SILENCE", NULL); -} -zactor_destroy (&listener); -zactor_destroy (&speaker); - -// Test subscription filter using a 3\-node setup -zactor_t *node1 = zactor_new (zbeacon, NULL); -assert (node1); -zsock_send (node1, "si", "CONFIGURE", 5670); -hostname = zstr_recv (node1); -assert (*hostname); -free (hostname); - -zactor_t *node2 = zactor_new (zbeacon, NULL); -assert (node2); -zsock_send (node2, "si", "CONFIGURE", 5670); -hostname = zstr_recv (node2); -assert (*hostname); -free (hostname); - -zactor_t *node3 = zactor_new (zbeacon, NULL); -assert (node3); -zsock_send (node3, "si", "CONFIGURE", 5670); -hostname = zstr_recv (node3); -assert (*hostname); -free (hostname); - -zsock_send (node1, "sbi", "PUBLISH", "NODE/1", 6, 250); -zsock_send (node2, "sbi", "PUBLISH", "NODE/2", 6, 250); -zsock_send (node3, "sbi", "PUBLISH", "RANDOM", 6, 250); -zsock_send (node1, "sb", "SUBSCRIBE", "NODE", 4); - -// Poll on three API sockets at once -zpoller_t *poller = zpoller_new (node1, node2, node3, NULL); -assert (poller); -int64_t stop_at = zclock_mono () + 1000; -while (zclock_mono () < stop_at) { - long timeout = (long) (stop_at \- zclock_mono ()); - if (timeout < 0) - timeout = 0; - void *which = zpoller_wait (poller, timeout * ZMQ_POLL_MSEC); - if (which) { - assert (which == node1); - char *ipaddress, *received; - zstr_recvx (node1, &ipaddress, &received, NULL); - assert (streq (received, "NODE/2")); - zstr_free (&ipaddress); - zstr_free (&received); - } -} -zpoller_destroy (&poller); - -// Stop listening -zstr_sendx (node1, "UNSUBSCRIBE", NULL); - -// Stop all node broadcasts -zstr_sendx (node1, "SILENCE", NULL); -zstr_sendx (node2, "SILENCE", NULL); -zstr_sendx (node3, "SILENCE", NULL); - -// Destroy the test nodes -zactor_destroy (&node1); -zactor_destroy (&node2); -zactor_destroy (&node3); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zcert.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zcert.3 deleted file mode 100644 index e2c81dbf10bd64..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zcert.3 +++ /dev/null @@ -1,215 +0,0 @@ -'\" t -.\" Title: zcert -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZCERT" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zcert \- work with CURVE security certificates -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// This class has draft methods, which may change over time\&. They are not -// in stable releases, by default\&. Use \-\-enable\-drafts to enable\&. -// Create and initialize a new certificate in memory -CZMQ_EXPORT zcert_t * - zcert_new (void); - -// Accepts public/secret key pair from caller -CZMQ_EXPORT zcert_t * - zcert_new_from (const byte *public_key, const byte *secret_key); - -// Load certificate from file -CZMQ_EXPORT zcert_t * - zcert_load (const char *filename); - -// Destroy a certificate in memory -CZMQ_EXPORT void - zcert_destroy (zcert_t **self_p); - -// Return public part of key pair as 32\-byte binary string -CZMQ_EXPORT const byte * - zcert_public_key (zcert_t *self); - -// Return secret part of key pair as 32\-byte binary string -CZMQ_EXPORT const byte * - zcert_secret_key (zcert_t *self); - -// Return public part of key pair as Z85 armored string -CZMQ_EXPORT const char * - zcert_public_txt (zcert_t *self); - -// Return secret part of key pair as Z85 armored string -CZMQ_EXPORT const char * - zcert_secret_txt (zcert_t *self); - -// Set certificate metadata from formatted string\&. -CZMQ_EXPORT void - zcert_set_meta (zcert_t *self, const char *name, const char *format, \&.\&.\&.) CHECK_PRINTF (3); - -// Get metadata value from certificate; if the metadata value doesn\*(Aqt -// exist, returns NULL\&. -CZMQ_EXPORT const char * - zcert_meta (zcert_t *self, const char *name); - -// Get list of metadata fields from certificate\&. Caller is responsible for -// destroying list\&. Caller should not modify the values of list items\&. -CZMQ_EXPORT zlist_t * - zcert_meta_keys (zcert_t *self); - -// Save full certificate (public + secret) to file for persistent storage -// This creates one public file and one secret file (filename + "_secret")\&. -CZMQ_EXPORT int - zcert_save (zcert_t *self, const char *filename); - -// Save public certificate only to file for persistent storage -CZMQ_EXPORT int - zcert_save_public (zcert_t *self, const char *filename); - -// Save secret certificate only to file for persistent storage -CZMQ_EXPORT int - zcert_save_secret (zcert_t *self, const char *filename); - -// Apply certificate to socket, i\&.e\&. use for CURVE security on socket\&. -// If certificate was loaded from public file, the secret key will be -// undefined, and this certificate will not work successfully\&. -CZMQ_EXPORT void - zcert_apply (zcert_t *self, void *socket); - -// Return copy of certificate; if certificate is NULL or we exhausted -// heap memory, returns NULL\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zcert_t * - zcert_dup (zcert_t *self); - -// Return true if two certificates have the same keys -CZMQ_EXPORT bool - zcert_eq (zcert_t *self, zcert_t *compare); - -// Print certificate contents to stdout -CZMQ_EXPORT void - zcert_print (zcert_t *self); - -// Self test of this class -CZMQ_EXPORT void - zcert_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Unset certificate metadata\&. -CZMQ_EXPORT void - zcert_unset_meta (zcert_t *self, const char *name); - -#endif // CZMQ_BUILD_DRAFT_API -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zcert\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zcert class provides a way to create and work with security certificates for the ZMQ CURVE mechanism\&. A certificate contains a public + secret key pair, plus metadata\&. It can be used as a temporary object in memory, or persisted to disk\&. On disk, a certificate is stored as two files\&. One is public and contains only the public key\&. The second is secret and contains both keys\&. The two have the same filename, with the secret file adding "_secret"\&. To exchange certificates, send the public file via some secure route\&. Certificates are not signed but are text files that can be verified by eye\&. -.sp -Certificates are stored in the ZPL (ZMQ RFC 4) format\&. They have two sections, "metadata" and "curve"\&. The first contains a list of \fIname = value\fR pairs, one per line\&. Values may be enclosed in quotes\&. The curve section has a \fIpublic\-key = keyvalue\fR and, for secret certificates, a \fIsecret\-key = keyvalue\fR line\&. The keyvalue is a Z85\-encoded CURVE key\&. -.SH "EXAMPLE" -.PP -\fBFrom zcert_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Create temporary directory for test files -# define TESTDIR "\&.test_zcert" -zsys_dir_create (TESTDIR); - -// Create a simple certificate with metadata -zcert_t *cert = zcert_new (); -assert (cert); -zcert_set_meta (cert, "email", "ph@imatix\&.com"); -zcert_set_meta (cert, "name", "Pieter Hintjens"); -zcert_set_meta (cert, "organization", "iMatix Corporation"); -zcert_set_meta (cert, "version", "%d", 1); -zcert_set_meta (cert, "delete_me", "now"); -zcert_unset_meta (cert, "delete_me"); -assert (streq (zcert_meta (cert, "email"), "ph@imatix\&.com")); -zlist_t *keys = zcert_meta_keys (cert); -assert (zlist_size (keys) == 4); -zlist_destroy (&keys); - -// Check the dup and eq methods -zcert_t *shadow = zcert_dup (cert); -assert (zcert_eq (cert, shadow)); -zcert_destroy (&shadow); - -// Check we can save and load certificate -zcert_save (cert, TESTDIR "/mycert\&.txt"); -assert (zsys_file_exists (TESTDIR "/mycert\&.txt")); -assert (zsys_file_exists (TESTDIR "/mycert\&.txt_secret")); - -// Load certificate, will in fact load secret one -shadow = zcert_load (TESTDIR "/mycert\&.txt"); -assert (shadow); -assert (zcert_eq (cert, shadow)); -zcert_destroy (&shadow); - -// Delete secret certificate, load public one -int rc = zsys_file_delete (TESTDIR "/mycert\&.txt_secret"); -assert (rc == 0); -shadow = zcert_load (TESTDIR "/mycert\&.txt"); - -// 32\-byte null key encodes as 40 \*(Aq0\*(Aq characters -assert (streq (zcert_secret_txt (shadow), FORTY_ZEROES)); - -zcert_destroy (&shadow); -zcert_destroy (&cert); - -// Delete all test files -zdir_t *dir = zdir_new (TESTDIR, NULL); -assert (dir); -zdir_remove (dir, true); -zdir_destroy (&dir); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zcertstore.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zcertstore.3 deleted file mode 100644 index 5b76f253db8c1b..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zcertstore.3 +++ /dev/null @@ -1,173 +0,0 @@ -'\" t -.\" Title: zcertstore -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZCERTSTORE" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zcertstore \- work with CURVE security certificate stores -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// This class has draft methods, which may change over time\&. They are not -// in stable releases, by default\&. Use \-\-enable\-drafts to enable\&. -// Create a new certificate store from a disk directory, loading and -// indexing all certificates in that location\&. The directory itself may be -// absent, and created later, or modified at any time\&. The certificate store -// is automatically refreshed on any zcertstore_lookup() call\&. If the -// location is specified as NULL, creates a pure\-memory store, which you -// can work with by inserting certificates at runtime\&. -CZMQ_EXPORT zcertstore_t * - zcertstore_new (const char *location); - -// Destroy a certificate store object in memory\&. Does not affect anything -// stored on disk\&. -CZMQ_EXPORT void - zcertstore_destroy (zcertstore_t **self_p); - -// Look up certificate by public key, returns zcert_t object if found, -// else returns NULL\&. The public key is provided in Z85 text format\&. -CZMQ_EXPORT zcert_t * - zcertstore_lookup (zcertstore_t *self, const char *public_key); - -// Insert certificate into certificate store in memory\&. Note that this -// does not save the certificate to disk\&. To do that, use zcert_save() -// directly on the certificate\&. Takes ownership of zcert_t object\&. -CZMQ_EXPORT void - zcertstore_insert (zcertstore_t *self, zcert_t **cert_p); - -// Print list of certificates in store to logging facility -CZMQ_EXPORT void - zcertstore_print (zcertstore_t *self); - -// Self test of this class -CZMQ_EXPORT void - zcertstore_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// Loaders retrieve certificates from an arbitrary source\&. -typedef void (zcertstore_loader) ( - zcertstore_t *self); - -// Destructor for loader state\&. -typedef void (zcertstore_destructor) ( - void **self_p); - -// *** Draft method, for development use, may change without warning *** -// Override the default disk loader with a custom loader fn\&. -CZMQ_EXPORT void - zcertstore_set_loader (zcertstore_t *self, zcertstore_loader loader, zcertstore_destructor destructor, void *state); - -// *** Draft method, for development use, may change without warning *** -// Empty certificate hashtable\&. This wrapper exists to be friendly to bindings, -// which don\*(Aqt usually have access to struct internals\&. -CZMQ_EXPORT void - zcertstore_empty (zcertstore_t *self); - -#endif // CZMQ_BUILD_DRAFT_API -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zcertstore\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -To authenticate new clients using the ZeroMQ CURVE security mechanism, we have to check that the client\(cqs public key matches a key we know and accept\&. There are numerous ways to store accepted client public keys\&. The mechanism CZMQ implements is "certificates" (plain text files) held in a "certificate store" (a disk directory)\&. This class works with such certificate stores, and lets you easily load them from disk, and check if a given client public key is known or not\&. The zcert class does the work of managing a single certificate\&. -.sp -The certificate store can be memory\-only, in which case you can load it yourself by inserting certificate objects one by one, or it can be loaded from disk, in which case you can add, modify, or remove certificates on disk at any time, and the store will detect such changes and refresh itself automatically\&. In most applications you won\(cqt use this class directly but through the zauth class, which provides a high\-level API for authentication (and manages certificate stores for you)\&. To actually create certificates on disk, use the zcert class in code, or the tools/zmakecert\&.c command line tool, or any text editor\&. The format of a certificate file is defined in the zcert man page\&. -.SH "EXAMPLE" -.PP -\fBFrom zcertstore_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Create temporary directory for test files -# define TESTDIR "\&.test_zcertstore" -zsys_dir_create (TESTDIR); - -// Load certificate store from disk; it will be empty -zcertstore_t *certstore = zcertstore_new (TESTDIR); -assert (certstore); - -// Create a single new certificate and save to disk -zcert_t *cert = zcert_new (); -assert (cert); -char *client_key = strdup (zcert_public_txt (cert)); -assert (client_key); -zcert_set_meta (cert, "name", "John Doe"); -zcert_save (cert, TESTDIR "/mycert\&.txt"); -zcert_destroy (&cert); - -// Check that certificate store refreshes as expected -cert = zcertstore_lookup (certstore, client_key); -assert (cert); -assert (streq (zcert_meta (cert, "name"), "John Doe")); - -// Test custom loader -test_loader_state *state = (test_loader_state *) zmalloc (sizeof (test_loader_state)); -state\->index = 0; -zcertstore_set_loader (certstore, s_test_loader, s_test_destructor, (void *)state); -#if (ZMQ_VERSION_MAJOR >= 4) -cert = zcertstore_lookup (certstore, client_key); -assert (cert == NULL); -cert = zcertstore_lookup (certstore, "abcdefghijklmnopqrstuvwxyzabcdefghijklmn"); -assert (cert); -#endif - -free (client_key); - -if (verbose) - zcertstore_print (certstore); -zcertstore_destroy (&certstore); - -// Delete all test files -zdir_t *dir = zdir_new (TESTDIR, NULL); -assert (dir); -zdir_remove (dir, true); -zdir_destroy (&dir); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zchunk.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zchunk.3 deleted file mode 100644 index 5b5d4378609b24..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zchunk.3 +++ /dev/null @@ -1,266 +0,0 @@ -'\" t -.\" Title: zchunk -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZCHUNK" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zchunk \- work with memory chunks -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// Create a new chunk of the specified size\&. If you specify the data, it -// is copied into the chunk\&. If you do not specify the data, the chunk is -// allocated and left empty, and you can then add data using zchunk_append\&. -CZMQ_EXPORT zchunk_t * - zchunk_new (const void *data, size_t size); - -// Destroy a chunk -CZMQ_EXPORT void - zchunk_destroy (zchunk_t **self_p); - -// Resizes chunk max_size as requested; chunk_cur size is set to zero -CZMQ_EXPORT void - zchunk_resize (zchunk_t *self, size_t size); - -// Return chunk cur size -CZMQ_EXPORT size_t - zchunk_size (zchunk_t *self); - -// Return chunk max size -CZMQ_EXPORT size_t - zchunk_max_size (zchunk_t *self); - -// Return chunk data -CZMQ_EXPORT byte * - zchunk_data (zchunk_t *self); - -// Set chunk data from user\-supplied data; truncate if too large\&. Data may -// be null\&. Returns actual size of chunk -CZMQ_EXPORT size_t - zchunk_set (zchunk_t *self, const void *data, size_t size); - -// Fill chunk data from user\-supplied octet -CZMQ_EXPORT size_t - zchunk_fill (zchunk_t *self, byte filler, size_t size); - -// Append user\-supplied data to chunk, return resulting chunk size\&. If the -// data would exceeded the available space, it is truncated\&. If you want to -// grow the chunk to accommodate new data, use the zchunk_extend method\&. -CZMQ_EXPORT size_t - zchunk_append (zchunk_t *self, const void *data, size_t size); - -// Append user\-supplied data to chunk, return resulting chunk size\&. If the -// data would exceeded the available space, the chunk grows in size\&. -CZMQ_EXPORT size_t - zchunk_extend (zchunk_t *self, const void *data, size_t size); - -// Copy as much data from \*(Aqsource\*(Aq into the chunk as possible; returns the -// new size of chunk\&. If all data from \*(Aqsource\*(Aq is used, returns exhausted -// on the source chunk\&. Source can be consumed as many times as needed until -// it is exhausted\&. If source was already exhausted, does not change chunk\&. -CZMQ_EXPORT size_t - zchunk_consume (zchunk_t *self, zchunk_t *source); - -// Returns true if the chunk was exhausted by consume methods, or if the -// chunk has a size of zero\&. -CZMQ_EXPORT bool - zchunk_exhausted (zchunk_t *self); - -// Read chunk from an open file descriptor -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zchunk_t * - zchunk_read (FILE *handle, size_t bytes); - -// Write chunk to an open file descriptor -CZMQ_EXPORT int - zchunk_write (zchunk_t *self, FILE *handle); - -// Try to slurp an entire file into a chunk\&. Will read up to maxsize of -// the file\&. If maxsize is 0, will attempt to read the entire file and -// fail with an assertion if that cannot fit into memory\&. Returns a new -// chunk containing the file data, or NULL if the file could not be read\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zchunk_t * - zchunk_slurp (const char *filename, size_t maxsize); - -// Create copy of chunk, as new chunk object\&. Returns a fresh zchunk_t -// object, or null if there was not enough heap memory\&. If chunk is null, -// returns null\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zchunk_t * - zchunk_dup (zchunk_t *self); - -// Return chunk data encoded as printable hex string\&. Caller must free -// string when finished with it\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zchunk_strhex (zchunk_t *self); - -// Return chunk data copied into freshly allocated string -// Caller must free string when finished with it\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zchunk_strdup (zchunk_t *self); - -// Return TRUE if chunk body is equal to string, excluding terminator -CZMQ_EXPORT bool - zchunk_streq (zchunk_t *self, const char *string); - -// Transform zchunk into a zframe that can be sent in a message\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zframe_t * - zchunk_pack (zchunk_t *self); - -// Transform a zframe into a zchunk\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zchunk_t * - zchunk_unpack (zframe_t *frame); - -// Calculate SHA1 digest for chunk, using zdigest class\&. -CZMQ_EXPORT const char * - zchunk_digest (zchunk_t *self); - -// Dump chunk to FILE stream, for debugging and tracing\&. -CZMQ_EXPORT void - zchunk_fprint (zchunk_t *self, FILE *file); - -// Dump message to stderr, for debugging and tracing\&. -// See zchunk_fprint for details -CZMQ_EXPORT void - zchunk_print (zchunk_t *self); - -// Probe the supplied object, and report if it looks like a zchunk_t\&. -CZMQ_EXPORT bool - zchunk_is (void *self); - -// Self test of this class\&. -CZMQ_EXPORT void - zchunk_test (bool verbose); - -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zchunk\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zchunk class works with variable sized blobs\&. Not as efficient as ZeroMQ\(cqs messages but they do less weirdness and so are easier to understand\&. The chunk class has methods to read and write chunks from disk\&. -.sp -Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zchunk\&.c\fR\&. -.SH "EXAMPLE" -.PP -\fBFrom zchunk_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zchunk_t *chunk = zchunk_new ("1234567890", 10); -assert (chunk); -assert (zchunk_size (chunk) == 10); -assert (memcmp (zchunk_data (chunk), "1234567890", 10) == 0); -zchunk_destroy (&chunk); - -chunk = zchunk_new (NULL, 10); -assert (chunk); -zchunk_append (chunk, "12345678", 8); -zchunk_append (chunk, "90ABCDEF", 8); -zchunk_append (chunk, "GHIJKLMN", 8); -assert (memcmp (zchunk_data (chunk), "1234567890", 10) == 0); -assert (zchunk_size (chunk) == 10); -assert (zchunk_streq (chunk, "1234567890")); -assert (streq (zchunk_digest (chunk), "01B307ACBA4F54F55AAFC33BB06BBBF6CA803E9A")); -char *string = zchunk_strdup (chunk); -assert (streq (string, "1234567890")); -free (string); -string = zchunk_strhex (chunk); -assert (streq (string, "31323334353637383930")); -free (string); - -zframe_t *frame = zchunk_pack (chunk); -assert (frame); - -zchunk_t *chunk2 = zchunk_unpack (frame); -assert (chunk2); -assert (memcmp (zchunk_data (chunk2), "1234567890", 10) == 0); -zframe_destroy (&frame); -zchunk_destroy (&chunk2); - -zchunk_t *copy = zchunk_dup (chunk); -assert (copy); -assert (memcmp (zchunk_data (copy), "1234567890", 10) == 0); -assert (zchunk_size (copy) == 10); -zchunk_destroy (©); -zchunk_destroy (&chunk); - -chunk = zchunk_new (NULL, 0); -zchunk_extend (chunk, "12345678", 8); -zchunk_extend (chunk, "90ABCDEF", 8); -zchunk_extend (chunk, "GHIJKLMN", 8); -assert (zchunk_size (chunk) == 24); -assert (zchunk_streq (chunk, "1234567890ABCDEFGHIJKLMN")); -zchunk_destroy (&chunk); - -copy = zchunk_new ("1234567890abcdefghij", 20); -assert (copy); -chunk = zchunk_new (NULL, 8); -assert (chunk); -zchunk_consume (chunk, copy); -assert (!zchunk_exhausted (copy)); -assert (memcmp (zchunk_data (chunk), "12345678", 8) == 0); -zchunk_set (chunk, NULL, 0); -zchunk_consume (chunk, copy); -assert (!zchunk_exhausted (copy)); -assert (memcmp (zchunk_data (chunk), "90abcdef", 8) == 0); -zchunk_set (chunk, NULL, 0); -zchunk_consume (chunk, copy); -assert (zchunk_exhausted (copy)); -assert (zchunk_size (chunk) == 4); -assert (memcmp (zchunk_data (chunk), "ghij", 4) == 0); -zchunk_destroy (©); -zchunk_destroy (&chunk); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zclock.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zclock.3 deleted file mode 100644 index 10691d17aa7e0d..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zclock.3 +++ /dev/null @@ -1,116 +0,0 @@ -'\" t -.\" Title: zclock -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZCLOCK" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zclock \- millisecond clocks and delays -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// Sleep for a number of milliseconds -CZMQ_EXPORT void - zclock_sleep (int msecs); - -// Return current system clock as milliseconds\&. Note that this clock can -// jump backwards (if the system clock is changed) so is unsafe to use for -// timers and time offsets\&. Use zclock_mono for that instead\&. -CZMQ_EXPORT int64_t - zclock_time (void); - -// Return current monotonic clock in milliseconds\&. Use this when you compute -// time offsets\&. The monotonic clock is not affected by system changes and -// so will never be reset backwards, unlike a system clock\&. -CZMQ_EXPORT int64_t - zclock_mono (void); - -// Return current monotonic clock in microseconds\&. Use this when you compute -// time offsets\&. The monotonic clock is not affected by system changes and -// so will never be reset backwards, unlike a system clock\&. -CZMQ_EXPORT int64_t - zclock_usecs (void); - -// Return formatted date/time as fresh string\&. Free using zstr_free()\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zclock_timestr (void); - -// Self test of this class\&. -CZMQ_EXPORT void - zclock_test (bool verbose); - -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zclock\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zclock class provides essential sleep and system time functions, used to slow down threads for testing, and calculate timers for polling\&. Wraps the non\-portable system calls in a simple portable API\&. -.sp -The Win32 Sleep() call defaults to 16ms resolution unless the system timer resolution is increased with a call to timeBeginPeriod() permitting 1ms granularity\&. -.SH "EXAMPLE" -.PP -\fBFrom zclock_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -int64_t start = zclock_time (); -zclock_sleep (10); -assert ((zclock_time () \- start) >= 10); -start = zclock_mono (); -int64_t usecs = zclock_usecs (); -zclock_sleep (10); -assert ((zclock_mono () \- start) >= 10); -assert ((zclock_usecs () \- usecs) >= 10000); -char *timestr = zclock_timestr (); -if (verbose) - puts (timestr); -free (timestr); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zconfig.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zconfig.3 deleted file mode 100644 index 5cd00c97073ed0..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zconfig.3 +++ /dev/null @@ -1,342 +0,0 @@ -'\" t -.\" Title: zconfig -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZCONFIG" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zconfig \- work with config files written in rfc\&.zeromq\&.org/spec:4/ZPL\&. -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// -typedef int (zconfig_fct) ( - zconfig_t *self, void *arg, int level); - -// Create new config item -CZMQ_EXPORT zconfig_t * - zconfig_new (const char *name, zconfig_t *parent); - -// Load a config tree from a specified ZPL text file; returns a zconfig_t -// reference for the root, if the file exists and is readable\&. Returns NULL -// if the file does not exist\&. -CZMQ_EXPORT zconfig_t * - zconfig_load (const char *filename); - -// Equivalent to zconfig_load, taking a format string instead of a fixed -// filename\&. -CZMQ_EXPORT zconfig_t * - zconfig_loadf (const char *format, \&.\&.\&.) CHECK_PRINTF (1); - -// Destroy a config item and all its children -CZMQ_EXPORT void - zconfig_destroy (zconfig_t **self_p); - -// Return name of config item -CZMQ_EXPORT char * - zconfig_name (zconfig_t *self); - -// Return value of config item -CZMQ_EXPORT char * - zconfig_value (zconfig_t *self); - -// Insert or update configuration key with value -CZMQ_EXPORT void - zconfig_put (zconfig_t *self, const char *path, const char *value); - -// Equivalent to zconfig_put, accepting a format specifier and variable -// argument list, instead of a single string value\&. -CZMQ_EXPORT void - zconfig_putf (zconfig_t *self, const char *path, const char *format, \&.\&.\&.) CHECK_PRINTF (3); - -// Get value for config item into a string value; leading slash is optional -// and ignored\&. -CZMQ_EXPORT char * - zconfig_get (zconfig_t *self, const char *path, const char *default_value); - -// Set config item name, name may be NULL -CZMQ_EXPORT void - zconfig_set_name (zconfig_t *self, const char *name); - -// Set new value for config item\&. The new value may be a string, a printf -// format, or NULL\&. Note that if string may possibly contain \*(Aq%\*(Aq, or if it -// comes from an insecure source, you must use \*(Aq%s\*(Aq as the format, followed -// by the string\&. -CZMQ_EXPORT void - zconfig_set_value (zconfig_t *self, const char *format, \&.\&.\&.) CHECK_PRINTF (2); - -// Find our first child, if any -CZMQ_EXPORT zconfig_t * - zconfig_child (zconfig_t *self); - -// Find our first sibling, if any -CZMQ_EXPORT zconfig_t * - zconfig_next (zconfig_t *self); - -// Find a config item along a path; leading slash is optional and ignored\&. -CZMQ_EXPORT zconfig_t * - zconfig_locate (zconfig_t *self, const char *path); - -// Locate the last config item at a specified depth -CZMQ_EXPORT zconfig_t * - zconfig_at_depth (zconfig_t *self, int level); - -// Execute a callback for each config item in the tree; returns zero if -// successful, else \-1\&. -CZMQ_EXPORT int - zconfig_execute (zconfig_t *self, zconfig_fct handler, void *arg); - -// Add comment to config item before saving to disk\&. You can add as many -// comment lines as you like\&. If you use a null format, all comments are -// deleted\&. -CZMQ_EXPORT void - zconfig_set_comment (zconfig_t *self, const char *format, \&.\&.\&.) CHECK_PRINTF (2); - -// Return comments of config item, as zlist\&. -CZMQ_EXPORT zlist_t * - zconfig_comments (zconfig_t *self); - -// Save a config tree to a specified ZPL text file, where a filename -// "\-" means dump to standard output\&. -CZMQ_EXPORT int - zconfig_save (zconfig_t *self, const char *filename); - -// Equivalent to zconfig_save, taking a format string instead of a fixed -// filename\&. -CZMQ_EXPORT int - zconfig_savef (zconfig_t *self, const char *format, \&.\&.\&.) CHECK_PRINTF (2); - -// Report filename used during zconfig_load, or NULL if none -CZMQ_EXPORT const char * - zconfig_filename (zconfig_t *self); - -// Reload config tree from same file that it was previously loaded from\&. -// Returns 0 if OK, \-1 if there was an error (and then does not change -// existing data)\&. -CZMQ_EXPORT int - zconfig_reload (zconfig_t **self_p); - -// Load a config tree from a memory chunk -CZMQ_EXPORT zconfig_t * - zconfig_chunk_load (zchunk_t *chunk); - -// Save a config tree to a new memory chunk -CZMQ_EXPORT zchunk_t * - zconfig_chunk_save (zconfig_t *self); - -// Load a config tree from a null\-terminated string -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zconfig_t * - zconfig_str_load (const char *string); - -// Save a config tree to a new null terminated string -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zconfig_str_save (zconfig_t *self); - -// Return true if a configuration tree was loaded from a file and that -// file has changed in since the tree was loaded\&. -CZMQ_EXPORT bool - zconfig_has_changed (zconfig_t *self); - -// Print the config file to open stream -CZMQ_EXPORT void - zconfig_fprint (zconfig_t *self, FILE *file); - -// Print properties of object -CZMQ_EXPORT void - zconfig_print (zconfig_t *self); - -// Self test of this class -CZMQ_EXPORT void - zconfig_test (bool verbose); - -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zconfig\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -Lets applications load, work with, and save configuration files\&. This implements rfc\&.zeromq\&.org/spec:4/ZPL, which is a simple structured text format for configuration files\&. -.sp -Here is an example ZPL stream and corresponding config structure: -.sp -.if n \{\ -.RS 4 -.\} -.nf -context - iothreads = 1 - verbose = 1 # Ask for a trace -main - type = zqueue # ZMQ_DEVICE type - frontend - option - hwm = 1000 - swap = 25000000 # 25MB - bind = \*(Aqinproc://addr1\*(Aq - bind = \*(Aqipc://addr2\*(Aq - backend - bind = inproc://addr3 -.fi -.if n \{\ -.RE -.\} -.sp -.if n \{\ -.RS 4 -.\} -.nf -root Down = child -| Across = next -v -context\-\->main -| | -| v -| type=queue\-\->frontend\-\->backend -| | | -| | v -| | bind=inproc://addr3 -| v -| option\-\->bind=inproc://addr1\-\->bind=ipc://addr2 -| | -| v -| hwm=1000\-\->swap=25000000 -v -iothreads=1\-\->verbose=false -.fi -.if n \{\ -.RE -.\} -.SH "EXAMPLE" -.PP -\fBFrom zconfig_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Create temporary directory for test files -# define TESTDIR "\&.test_zconfig" -zsys_dir_create (TESTDIR); - -zconfig_t *root = zconfig_new ("root", NULL); -assert (root); -zconfig_t *section, *item; - -section = zconfig_new ("headers", root); -assert (section); -item = zconfig_new ("email", section); -assert (item); -zconfig_set_value (item, "some@random\&.com"); -item = zconfig_new ("name", section); -assert (item); -zconfig_set_value (item, "Justin Kayce"); -zconfig_putf (root, "/curve/secret\-key", "%s", "Top Secret"); -zconfig_set_comment (root, " CURVE certificate"); -zconfig_set_comment (root, " \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-"); -assert (zconfig_comments (root)); -zconfig_save (root, TESTDIR "/test\&.cfg"); -zconfig_destroy (&root); -root = zconfig_load (TESTDIR "/test\&.cfg"); -if (verbose) - zconfig_save (root, "\-"); -assert (streq (zconfig_filename (root), TESTDIR "/test\&.cfg")); - -char *email = zconfig_get (root, "/headers/email", NULL); -assert (email); -assert (streq (email, "some@random\&.com")); -char *passwd = zconfig_get (root, "/curve/secret\-key", NULL); -assert (passwd); -assert (streq (passwd, "Top Secret")); - -zconfig_savef (root, "%s/%s", TESTDIR, "test\&.cfg"); -assert (!zconfig_has_changed (root)); -int rc = zconfig_reload (&root); -assert (rc == 0); -assert (!zconfig_has_changed (root)); -zconfig_destroy (&root); - -// Test chunk load/save -root = zconfig_new ("root", NULL); -assert (root); -section = zconfig_new ("section", root); -assert (section); -item = zconfig_new ("value", section); -assert (item); -zconfig_set_value (item, "somevalue"); -zconfig_t *search = zconfig_locate (root, "section/value"); -assert (search == item); -zchunk_t *chunk = zconfig_chunk_save (root); -assert (strlen ((char *) zchunk_data (chunk)) == 32); -char *string = zconfig_str_save (root); -assert (string); -assert (streq (string, (char *) zchunk_data (chunk))); -free (string); -assert (chunk); -zconfig_destroy (&root); - -root = zconfig_chunk_load (chunk); -assert (root); -char *value = zconfig_get (root, "/section/value", NULL); -assert (value); -assert (streq (value, "somevalue")); - -// Test config can\*(Aqt be saved to a file in a path that doesn\*(Aqt -// exist or isn\*(Aqt writable -rc = zconfig_savef (root, "%s/path/that/doesnt/exist/%s", TESTDIR, "test\&.cfg"); -assert (rc == \-1); - -zconfig_destroy (&root); -zchunk_destroy (&chunk); - -// Delete all test files -zdir_t *dir = zdir_new (TESTDIR, NULL); -assert (dir); -zdir_remove (dir, true); -zdir_destroy (&dir); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zdigest.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zdigest.3 deleted file mode 100644 index cabae72d053426..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zdigest.3 +++ /dev/null @@ -1,120 +0,0 @@ -'\" t -.\" Title: zdigest -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZDIGEST" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zdigest \- provides hashing functions (SHA\-1 at present) -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// Constructor \- creates new digest object, which you use to build up a -// digest by repeatedly calling zdigest_update() on chunks of data\&. -CZMQ_EXPORT zdigest_t * - zdigest_new (void); - -// Destroy a digest object -CZMQ_EXPORT void - zdigest_destroy (zdigest_t **self_p); - -// Add buffer into digest calculation -CZMQ_EXPORT void - zdigest_update (zdigest_t *self, const byte *buffer, size_t length); - -// Return final digest hash data\&. If built without crypto support, -// returns NULL\&. -CZMQ_EXPORT const byte * - zdigest_data (zdigest_t *self); - -// Return final digest hash size -CZMQ_EXPORT size_t - zdigest_size (zdigest_t *self); - -// Return digest as printable hex string; caller should not modify nor -// free this string\&. After calling this, you may not use zdigest_update() -// on the same digest\&. If built without crypto support, returns NULL\&. -CZMQ_EXPORT char * - zdigest_string (zdigest_t *self); - -// Self test of this class\&. -CZMQ_EXPORT void - zdigest_test (bool verbose); - -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zdigest\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zdigest class generates a hash from zchunks of data\&. The current algorithm is SHA\-1, chosen for speed\&. We are aiming to generate a unique digest for a file, and there are no security issues in this use case\&. -.sp -The current code depends on OpenSSL, which might be replaced by hard coded SHA\-1 implementation to reduce build dependencies\&. -.SH "EXAMPLE" -.PP -\fBFrom zdigest_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -byte *buffer = (byte *) zmalloc (1024); -memset (buffer, 0xAA, 1024); - -zdigest_t *digest = zdigest_new (); -assert (digest); -zdigest_update (digest, buffer, 1024); -const byte *data = zdigest_data (digest); -assert (data [0] == 0xDE); -assert (data [1] == 0xB2); -assert (data [2] == 0x38); -assert (data [3] == 0x07); -assert (streq (zdigest_string (digest), - "DEB23807D4FE025E900FE9A9C7D8410C3DDE9671")); -zdigest_destroy (&digest); -free (buffer); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zdir.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zdir.3 deleted file mode 100644 index 04cbc80542e838..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zdir.3 +++ /dev/null @@ -1,287 +0,0 @@ -'\" t -.\" Title: zdir -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZDIR" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zdir \- work with file\-system directories -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// Create a new directory item that loads in the full tree of the specified -// path, optionally located under some parent path\&. If parent is "\-", then -// loads only the top\-level directory, and does not use parent as a path\&. -CZMQ_EXPORT zdir_t * - zdir_new (const char *path, const char *parent); - -// Destroy a directory tree and all children it contains\&. -CZMQ_EXPORT void - zdir_destroy (zdir_t **self_p); - -// Return directory path -CZMQ_EXPORT const char * - zdir_path (zdir_t *self); - -// Return last modification time for directory\&. -CZMQ_EXPORT time_t - zdir_modified (zdir_t *self); - -// Return total hierarchy size, in bytes of data contained in all files -// in the directory tree\&. -CZMQ_EXPORT off_t - zdir_cursize (zdir_t *self); - -// Return directory count -CZMQ_EXPORT size_t - zdir_count (zdir_t *self); - -// Returns a sorted list of zfile objects; Each entry in the list is a pointer -// to a zfile_t item already allocated in the zdir tree\&. Do not destroy the -// original zdir tree until you are done with this list\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zlist_t * - zdir_list (zdir_t *self); - -// Remove directory, optionally including all files that it contains, at -// all levels\&. If force is false, will only remove the directory if empty\&. -// If force is true, will remove all files and all subdirectories\&. -CZMQ_EXPORT void - zdir_remove (zdir_t *self, bool force); - -// Calculate differences between two versions of a directory tree\&. -// Returns a list of zdir_patch_t patches\&. Either older or newer may -// be null, indicating the directory is empty/absent\&. If alias is set, -// generates virtual filename (minus path, plus alias)\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zlist_t * - zdir_diff (zdir_t *older, zdir_t *newer, const char *alias); - -// Return full contents of directory as a zdir_patch list\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zlist_t * - zdir_resync (zdir_t *self, const char *alias); - -// Load directory cache; returns a hash table containing the SHA\-1 digests -// of every file in the tree\&. The cache is saved between runs in \&.cache\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zhash_t * - zdir_cache (zdir_t *self); - -// Print contents of directory to open stream -CZMQ_EXPORT void - zdir_fprint (zdir_t *self, FILE *file, int indent); - -// Print contents of directory to stdout -CZMQ_EXPORT void - zdir_print (zdir_t *self, int indent); - -// Create a new zdir_watch actor instance: -// -// zactor_t *watch = zactor_new (zdir_watch, NULL); -// -// Destroy zdir_watch instance: -// -// zactor_destroy (&watch); -// -// Enable verbose logging of commands and activity: -// -// zstr_send (watch, "VERBOSE"); -// -// Subscribe to changes to a directory path: -// -// zsock_send (watch, "ss", "SUBSCRIBE", "directory_path"); -// -// Unsubscribe from changes to a directory path: -// -// zsock_send (watch, "ss", "UNSUBSCRIBE", "directory_path"); -// -// Receive directory changes: -// zsock_recv (watch, "sp", &path, &patches); -// -// // Delete the received data\&. -// free (path); -// zlist_destroy (&patches); -CZMQ_EXPORT void - zdir_watch (zsock_t *pipe, void *unused); - -// Self test of this class\&. -CZMQ_EXPORT void - zdir_test (bool verbose); - -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zdir\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zdir class gives access to the file system index\&. It will load a directory tree (a directory plus all child directories) into a zdir structure and then let you navigate that structure\&. It exists mainly to wrap non\-portable OS functions to do this\&. -.sp -Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zdir\&.c\fR\&. -.SH "EXAMPLE" -.PP -\fBFrom zdir_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// need to create a file in the test directory we\*(Aqre watching -// in order to ensure the directory exists -zfile_t *initfile = zfile_new ("\&./zdir\-test\-dir", "initial_file"); -assert (initfile); -zfile_output (initfile); -fprintf (zfile_handle (initfile), "initial file\en"); -zfile_close (initfile); -zfile_destroy (&initfile); - -zdir_t *older = zdir_new ("zdir\-test\-dir", NULL); -assert (older); -if (verbose) { - printf ("\en"); - zdir_dump (older, 0); -} -zdir_t *newer = zdir_new ("\&.", NULL); -assert (newer); -zlist_t *patches = zdir_diff (older, newer, "/"); -assert (patches); -while (zlist_size (patches)) { - zdir_patch_t *patch = (zdir_patch_t *) zlist_pop (patches); - zdir_patch_destroy (&patch); -} -zlist_destroy (&patches); -zdir_destroy (&older); -zdir_destroy (&newer); - -zdir_t *nosuch = zdir_new ("does\-not\-exist", NULL); -assert (nosuch == NULL); - -// zdir_watch test: -zactor_t *watch = zactor_new (zdir_watch, NULL); -assert (watch); - -if (verbose) { - zsock_send (watch, "s", "VERBOSE"); - assert (zsock_wait (watch) == 0); -} - -zclock_sleep (1001); // wait for initial file to become \*(Aqstable\*(Aq - -zsock_send (watch, "si", "TIMEOUT", 100); -assert (zsock_wait (watch) == 0); - -zsock_send (watch, "ss", "SUBSCRIBE", "zdir\-test\-dir"); -assert (zsock_wait (watch) == 0); - -zsock_send (watch, "ss", "UNSUBSCRIBE", "zdir\-test\-dir"); -assert (zsock_wait (watch) == 0); - -zsock_send (watch, "ss", "SUBSCRIBE", "zdir\-test\-dir"); -assert (zsock_wait (watch) == 0); - -zfile_t *newfile = zfile_new ("zdir\-test\-dir", "test_abc"); -zfile_output (newfile); -fprintf (zfile_handle (newfile), "test file\en"); -zfile_close (newfile); - -zpoller_t *watch_poll = zpoller_new (watch, NULL); - -// poll for a certain timeout before giving up and failing the test\&. -assert (zpoller_wait (watch_poll, 1001) == watch); - -// wait for notification of the file being added -char *path; -int rc = zsock_recv (watch, "sp", &path, &patches); -assert (rc == 0); - -assert (streq (path, "zdir\-test\-dir")); -free (path); - -assert (zlist_size (patches) == 1); - -zdir_patch_t *patch = (zdir_patch_t *) zlist_pop (patches); -assert (streq (zdir_patch_path (patch), "zdir\-test\-dir")); - -zfile_t *patch_file = zdir_patch_file (patch); -assert (streq (zfile_filename (patch_file, ""), "zdir\-test\-dir/test_abc")); - -zdir_patch_destroy (&patch); -zlist_destroy (&patches); - -// remove the file -zfile_remove (newfile); -zfile_destroy (&newfile); - -// poll for a certain timeout before giving up and failing the test\&. -assert (zpoller_wait (watch_poll, 1001) == watch); - -// wait for notification of the file being removed -rc = zsock_recv (watch, "sp", &path, &patches); -assert (rc == 0); - -assert (streq (path, "zdir\-test\-dir")); -free (path); - -assert (zlist_size (patches) == 1); - -patch = (zdir_patch_t *) zlist_pop (patches); -assert (streq (zdir_patch_path (patch), "zdir\-test\-dir")); - -patch_file = zdir_patch_file (patch); -assert (streq (zfile_filename (patch_file, ""), "zdir\-test\-dir/test_abc")); - -zdir_patch_destroy (&patch); -zlist_destroy (&patches); - -zpoller_destroy (&watch_poll); -zactor_destroy (&watch); - -// clean up by removing the test directory\&. -zdir_t *testdir = zdir_new ("zdir\-test\-dir", NULL); -zdir_remove (testdir, true); -zdir_destroy (&testdir); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zdir_patch.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zdir_patch.3 deleted file mode 100644 index 61789b32c0477c..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zdir_patch.3 +++ /dev/null @@ -1,129 +0,0 @@ -'\" t -.\" Title: zdir_patch -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZDIR_PATCH" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zdir_patch \- work with directory patches -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -#define ZDIR_PATCH_CREATE 1 // Creates a new file -#define ZDIR_PATCH_DELETE 2 // Delete a file - -// Create new patch -CZMQ_EXPORT zdir_patch_t * - zdir_patch_new (const char *path, zfile_t *file, int op, const char *alias); - -// Destroy a patch -CZMQ_EXPORT void - zdir_patch_destroy (zdir_patch_t **self_p); - -// Create copy of a patch\&. If the patch is null, or memory was exhausted, -// returns null\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zdir_patch_t * - zdir_patch_dup (zdir_patch_t *self); - -// Return patch file directory path -CZMQ_EXPORT const char * - zdir_patch_path (zdir_patch_t *self); - -// Return patch file item -CZMQ_EXPORT zfile_t * - zdir_patch_file (zdir_patch_t *self); - -// Return operation -CZMQ_EXPORT int - zdir_patch_op (zdir_patch_t *self); - -// Return patch virtual file path -CZMQ_EXPORT const char * - zdir_patch_vpath (zdir_patch_t *self); - -// Calculate hash digest for file (create only) -CZMQ_EXPORT void - zdir_patch_digest_set (zdir_patch_t *self); - -// Return hash digest for patch file -CZMQ_EXPORT const char * - zdir_patch_digest (zdir_patch_t *self); - -// Self test of this class\&. -CZMQ_EXPORT void - zdir_patch_test (bool verbose); - -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zdir_patch\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zdir_patch class works with one patch, which says "create this file" or "delete this file" (referring to a zfile item each time)\&. -.sp -Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zdir_patch\&.c\fR\&. -.SH "EXAMPLE" -.PP -\fBFrom zdir_patch_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zfile_t *file = zfile_new ("\&.", "bilbo"); -assert (file); -zdir_patch_t *patch = zdir_patch_new ("\&.", file, patch_create, "/"); -assert (patch); -zfile_destroy (&file); - -file = zdir_patch_file (patch); -assert (file); -assert (streq (zfile_filename (file, "\&."), "bilbo")); -assert (streq (zdir_patch_vpath (patch), "/bilbo")); -zdir_patch_destroy (&patch); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zfile.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zfile.3 deleted file mode 100644 index f3b6591812528f..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zfile.3 +++ /dev/null @@ -1,340 +0,0 @@ -'\" t -.\" Title: zfile -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZFILE" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zfile \- provides methods to work with files in a portable fashion\&. -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// If file exists, populates properties\&. CZMQ supports portable symbolic -// links, which are files with the extension "\&.ln"\&. A symbolic link is a -// text file containing one line, the filename of a target file\&. Reading -// data from the symbolic link actually reads from the target file\&. Path -// may be NULL, in which case it is not used\&. -CZMQ_EXPORT zfile_t * - zfile_new (const char *path, const char *name); - -// Destroy a file item -CZMQ_EXPORT void - zfile_destroy (zfile_t **self_p); - -// Duplicate a file item, returns a newly constructed item\&. If the file -// is null, or memory was exhausted, returns null\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zfile_t * - zfile_dup (zfile_t *self); - -// Return file name, remove path if provided -CZMQ_EXPORT const char * - zfile_filename (zfile_t *self, const char *path); - -// Refresh file properties from disk; this is not done automatically -// on access methods, otherwise it is not possible to compare directory -// snapshots\&. -CZMQ_EXPORT void - zfile_restat (zfile_t *self); - -// Return when the file was last modified\&. If you want this to reflect the -// current situation, call zfile_restat before checking this property\&. -CZMQ_EXPORT time_t - zfile_modified (zfile_t *self); - -// Return the last\-known size of the file\&. If you want this to reflect the -// current situation, call zfile_restat before checking this property\&. -CZMQ_EXPORT off_t - zfile_cursize (zfile_t *self); - -// Return true if the file is a directory\&. If you want this to reflect -// any external changes, call zfile_restat before checking this property\&. -CZMQ_EXPORT bool - zfile_is_directory (zfile_t *self); - -// Return true if the file is a regular file\&. If you want this to reflect -// any external changes, call zfile_restat before checking this property\&. -CZMQ_EXPORT bool - zfile_is_regular (zfile_t *self); - -// Return true if the file is readable by this process\&. If you want this to -// reflect any external changes, call zfile_restat before checking this -// property\&. -CZMQ_EXPORT bool - zfile_is_readable (zfile_t *self); - -// Return true if the file is writeable by this process\&. If you want this -// to reflect any external changes, call zfile_restat before checking this -// property\&. -CZMQ_EXPORT bool - zfile_is_writeable (zfile_t *self); - -// Check if file has stopped changing and can be safely processed\&. -// Updates the file statistics from disk at every call\&. -CZMQ_EXPORT bool - zfile_is_stable (zfile_t *self); - -// Return true if the file was changed on disk since the zfile_t object -// was created, or the last zfile_restat() call made on it\&. -CZMQ_EXPORT bool - zfile_has_changed (zfile_t *self); - -// Remove the file from disk -CZMQ_EXPORT void - zfile_remove (zfile_t *self); - -// Open file for reading -// Returns 0 if OK, \-1 if not found or not accessible -CZMQ_EXPORT int - zfile_input (zfile_t *self); - -// Open file for writing, creating directory if needed -// File is created if necessary; chunks can be written to file at any -// location\&. Returns 0 if OK, \-1 if error\&. -CZMQ_EXPORT int - zfile_output (zfile_t *self); - -// Read chunk from file at specified position\&. If this was the last chunk, -// sets the eof property\&. Returns a null chunk in case of error\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zchunk_t * - zfile_read (zfile_t *self, size_t bytes, off_t offset); - -// Returns true if zfile_read() just read the last chunk in the file\&. -CZMQ_EXPORT bool - zfile_eof (zfile_t *self); - -// Write chunk to file at specified position -// Return 0 if OK, else \-1 -CZMQ_EXPORT int - zfile_write (zfile_t *self, zchunk_t *chunk, off_t offset); - -// Read next line of text from file\&. Returns a pointer to the text line, -// or NULL if there was nothing more to read from the file\&. -CZMQ_EXPORT const char * - zfile_readln (zfile_t *self); - -// Close file, if open -CZMQ_EXPORT void - zfile_close (zfile_t *self); - -// Return file handle, if opened -CZMQ_EXPORT FILE * - zfile_handle (zfile_t *self); - -// Calculate SHA1 digest for file, using zdigest class\&. -CZMQ_EXPORT const char * - zfile_digest (zfile_t *self); - -// Self test of this class\&. -CZMQ_EXPORT void - zfile_test (bool verbose); - -// These methods are deprecated, and now moved to zsys class\&. -CZMQ_EXPORT bool - zfile_exists (const char *filename); -CZMQ_EXPORT ssize_t - zfile_size (const char *filename); -CZMQ_EXPORT mode_t - zfile_mode (const char *filename); -CZMQ_EXPORT int - zfile_delete (const char *filename); -CZMQ_EXPORT bool - zfile_stable (const char *filename); -CZMQ_EXPORT int - zfile_mkdir (const char *pathname); -CZMQ_EXPORT int - zfile_rmdir (const char *pathname); -CZMQ_EXPORT void - zfile_mode_private (void); -CZMQ_EXPORT void - zfile_mode_default (void); -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zfile\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zfile class provides methods to work with disk files\&. A file object provides the modified date, current size, and type of the file\&. You can create a file object for a filename that does not yet exist\&. To read or write data from the file, use the input and output methods, and then read and write chunks\&. The output method lets you both read and write chunks, at any offset\&. Finally, this class provides portable symbolic links\&. If a filename ends in "\&.ln", the first line of text in the file is read, and used as the underlying file for read/write operations\&. This lets you manipulate (e\&.g\&.) copy symbolic links without copying the perhaps very large files they point to\&. -.sp -This class is a new API, deprecating the old zfile class (which still exists but is implemented in zsys now)\&. -.SH "EXAMPLE" -.PP -\fBFrom zfile_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zfile_t *file = zfile_new (NULL, "bilbo"); -assert (file); -assert (streq (zfile_filename (file, "\&."), "bilbo")); -assert (zfile_is_readable (file) == false); -zfile_destroy (&file); - -// Create a test file in some random subdirectory -file = zfile_new ("\&./this/is/a/test", "bilbo"); -assert (file); -int rc = zfile_output (file); -assert (rc == 0); -zchunk_t *chunk = zchunk_new (NULL, 100); -assert (chunk); -zchunk_fill (chunk, 0, 100); - -// Write 100 bytes at position 1,000,000 in the file -rc = zfile_write (file, chunk, 1000000); -assert (rc == 0); -zchunk_destroy (&chunk); -zfile_close (file); -assert (zfile_is_readable (file)); -assert (zfile_cursize (file) == 1000100); -assert (!zfile_is_stable (file)); -assert (zfile_digest (file)); - -// Now truncate file from outside -int handle = open ("\&./this/is/a/test/bilbo", O_WRONLY | O_TRUNC | O_BINARY, 0); -assert (handle >= 0); -rc = write (handle, "Hello, World\en", 13); -assert (rc == 13); -close (handle); -assert (zfile_has_changed (file)); -zclock_sleep (1001); -assert (zfile_has_changed (file)); - -assert (!zfile_is_stable (file)); -zfile_restat (file); -assert (zfile_is_stable (file)); -assert (streq (zfile_digest (file), "4AB299C8AD6ED14F31923DD94F8B5F5CB89DFB54")); - -// Check we can read from file -rc = zfile_input (file); -assert (rc == 0); -chunk = zfile_read (file, 1000100, 0); -assert (chunk); -assert (zchunk_size (chunk) == 13); -zchunk_destroy (&chunk); -zfile_close (file); - -// Check we can read lines from file -rc = zfile_input (file); -assert (rc == 0); -const char *line = zfile_readln (file); -assert (streq (line, "Hello, World")); -line = zfile_readln (file); -assert (line == NULL); -zfile_close (file); - -// Try some fun with symbolic links -zfile_t *link = zfile_new ("\&./this/is/a/test", "bilbo\&.ln"); -assert (link); -rc = zfile_output (link); -assert (rc == 0); -fprintf (zfile_handle (link), "\&./this/is/a/test/bilbo\en"); -zfile_destroy (&link); - -link = zfile_new ("\&./this/is/a/test", "bilbo\&.ln"); -assert (link); -rc = zfile_input (link); -assert (rc == 0); -chunk = zfile_read (link, 1000100, 0); -assert (chunk); -assert (zchunk_size (chunk) == 13); -zchunk_destroy (&chunk); -zfile_destroy (&link); - -// Remove file and directory -zdir_t *dir = zdir_new ("\&./this", NULL); -assert (dir); -assert (zdir_cursize (dir) == 26); -zdir_remove (dir, true); -assert (zdir_cursize (dir) == 0); -zdir_destroy (&dir); - -// Check we can no longer read from file -assert (zfile_is_readable (file)); -zfile_restat (file); -assert (!zfile_is_readable (file)); -rc = zfile_input (file); -assert (rc == \-1); -zfile_destroy (&file); - -file = zfile_new ("\&./", "eof_checkfile"); -assert (file); -// 1\&. Write something first -rc = zfile_output (file); -assert (rc == 0); -chunk = zchunk_new ("123456789", 9); -assert (chunk); - -rc = zfile_write (file, chunk, 0); -assert (rc == 0); -zchunk_destroy (&chunk); -zfile_close (file); -assert (zfile_cursize (file) == 9); - -// 2\&. Read the written something -rc = zfile_input (file); -assert (rc != \-1); -// try to read more bytes than there is in the file -chunk = zfile_read (file, 1000, 0); -assert (zfile_eof(file)); -assert (zchunk_streq (chunk, "123456789")); -zchunk_destroy (&chunk); - -// reading is ok -chunk = zfile_read (file, 5, 0); -assert (!zfile_eof(file)); -assert (zchunk_streq (chunk, "12345")); -zchunk_destroy (&chunk); - -// read from non zero offset until the end -chunk = zfile_read (file, 5, 5); -assert (zfile_eof(file)); -assert (zchunk_streq (chunk, "6789")); -zchunk_destroy (&chunk); -zfile_remove (file); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zframe.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zframe.3 deleted file mode 100644 index f723dd61054003..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zframe.3 +++ /dev/null @@ -1,357 +0,0 @@ -'\" t -.\" Title: zframe -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZFRAME" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zframe \- working with single message frames -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// This class has draft methods, which may change over time\&. They are not -// in stable releases, by default\&. Use \-\-enable\-drafts to enable\&. -#define ZFRAME_MORE 1 // -#define ZFRAME_REUSE 2 // -#define ZFRAME_DONTWAIT 4 // - -// Create a new frame\&. If size is not null, allocates the frame data -// to the specified size\&. If additionally, data is not null, copies -// size octets from the specified data into the frame body\&. -CZMQ_EXPORT zframe_t * - zframe_new (const void *data, size_t size); - -// Create an empty (zero\-sized) frame -CZMQ_EXPORT zframe_t * - zframe_new_empty (void); - -// Create a frame with a specified string content\&. -CZMQ_EXPORT zframe_t * - zframe_from (const char *string); - -// Receive frame from socket, returns zframe_t object or NULL if the recv -// was interrupted\&. Does a blocking recv, if you want to not block then use -// zpoller or zloop\&. -CZMQ_EXPORT zframe_t * - zframe_recv (void *source); - -// Destroy a frame -CZMQ_EXPORT void - zframe_destroy (zframe_t **self_p); - -// Send a frame to a socket, destroy frame after sending\&. -// Return \-1 on error, 0 on success\&. -CZMQ_EXPORT int - zframe_send (zframe_t **self_p, void *dest, int flags); - -// Return number of bytes in frame data -CZMQ_EXPORT size_t - zframe_size (zframe_t *self); - -// Return address of frame data -CZMQ_EXPORT byte * - zframe_data (zframe_t *self); - -// Return meta data property for frame -// Caller must free string when finished with it\&. -CZMQ_EXPORT const char * - zframe_meta (zframe_t *self, const char *property); - -// Create a new frame that duplicates an existing frame\&. If frame is null, -// or memory was exhausted, returns null\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zframe_t * - zframe_dup (zframe_t *self); - -// Return frame data encoded as printable hex string, useful for 0MQ UUIDs\&. -// Caller must free string when finished with it\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zframe_strhex (zframe_t *self); - -// Return frame data copied into freshly allocated string -// Caller must free string when finished with it\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zframe_strdup (zframe_t *self); - -// Return TRUE if frame body is equal to string, excluding terminator -CZMQ_EXPORT bool - zframe_streq (zframe_t *self, const char *string); - -// Return frame MORE indicator (1 or 0), set when reading frame from socket -// or by the zframe_set_more() method -CZMQ_EXPORT int - zframe_more (zframe_t *self); - -// Set frame MORE indicator (1 or 0)\&. Note this is NOT used when sending -// frame to socket, you have to specify flag explicitly\&. -CZMQ_EXPORT void - zframe_set_more (zframe_t *self, int more); - -// Return TRUE if two frames have identical size and data -// If either frame is NULL, equality is always false\&. -CZMQ_EXPORT bool - zframe_eq (zframe_t *self, zframe_t *other); - -// Set new contents for frame -CZMQ_EXPORT void - zframe_reset (zframe_t *self, const void *data, size_t size); - -// Send message to zsys log sink (may be stdout, or system facility as -// configured by zsys_set_logstream)\&. Prefix shows before frame, if not null\&. -CZMQ_EXPORT void - zframe_print (zframe_t *self, const char *prefix); - -// Probe the supplied object, and report if it looks like a zframe_t\&. -CZMQ_EXPORT bool - zframe_is (void *self); - -// Self test of this class\&. -CZMQ_EXPORT void - zframe_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Return frame routing ID, if the frame came from a ZMQ_SERVER socket\&. -// Else returns zero\&. -CZMQ_EXPORT uint32_t - zframe_routing_id (zframe_t *self); - -// *** Draft method, for development use, may change without warning *** -// Set routing ID on frame\&. This is used if/when the frame is sent to a -// ZMQ_SERVER socket\&. -CZMQ_EXPORT void - zframe_set_routing_id (zframe_t *self, uint32_t routing_id); - -// *** Draft method, for development use, may change without warning *** -// Return frame group of radio\-dish pattern\&. -CZMQ_EXPORT const char * - zframe_group (zframe_t *self); - -// *** Draft method, for development use, may change without warning *** -// Set group on frame\&. This is used if/when the frame is sent to a -// ZMQ_RADIO socket\&. -// Return \-1 on error, 0 on success\&. -CZMQ_EXPORT int - zframe_set_group (zframe_t *self, const char *group); - -#endif // CZMQ_BUILD_DRAFT_API -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zframe\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zframe class provides methods to send and receive single message frames across 0MQ sockets\&. A \fIframe\fR corresponds to one zmq_msg_t\&. When you read a frame from a socket, the zframe_more() method indicates if the frame is part of an unfinished multipart message\&. The zframe_send method normally destroys the frame, but with the ZFRAME_REUSE flag, you can send the same frame many times\&. Frames are binary, and this class has no special support for text data\&. -.sp -Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zframe\&.c\fR\&. -.SH "EXAMPLE" -.PP -\fBFrom zframe_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Create two PAIR sockets and connect over inproc -zsock_t *output = zsock_new_pair ("@tcp://127\&.0\&.0\&.1:9001"); -assert (output); -zsock_t *input = zsock_new_pair (">tcp://127\&.0\&.0\&.1:9001"); -assert (input); - -// Send five different frames, test ZFRAME_MORE -int frame_nbr; -for (frame_nbr = 0; frame_nbr < 5; frame_nbr++) { - frame = zframe_new ("Hello", 5); - assert (frame); - rc = zframe_send (&frame, output, ZFRAME_MORE); - assert (rc == 0); -} -// Send same frame five times, test ZFRAME_REUSE -frame = zframe_new ("Hello", 5); -assert (frame); -for (frame_nbr = 0; frame_nbr < 5; frame_nbr++) { - rc = zframe_send (&frame, output, ZFRAME_MORE + ZFRAME_REUSE); - assert (rc == 0); -} -assert (frame); -zframe_t *copy = zframe_dup (frame); -assert (zframe_eq (frame, copy)); -zframe_destroy (&frame); -assert (!zframe_eq (frame, copy)); -assert (zframe_size (copy) == 5); -zframe_destroy (©); -assert (!zframe_eq (frame, copy)); - -// Test zframe_new_empty -frame = zframe_new_empty (); -assert (frame); -assert (zframe_size (frame) == 0); -zframe_destroy (&frame); - -// Send END frame -frame = zframe_new ("NOT", 3); -assert (frame); -zframe_reset (frame, "END", 3); -char *string = zframe_strhex (frame); -assert (streq (string, "454E44")); -free (string); -string = zframe_strdup (frame); -assert (streq (string, "END")); -free (string); -rc = zframe_send (&frame, output, 0); -assert (rc == 0); - -// Read and count until we receive END -frame_nbr = 0; -for (frame_nbr = 0;; frame_nbr++) { - zframe_t *frame = zframe_recv (input); - if (zframe_streq (frame, "END")) { - zframe_destroy (&frame); - break; - } - assert (zframe_more (frame)); - zframe_set_more (frame, 0); - assert (zframe_more (frame) == 0); - zframe_destroy (&frame); -} -assert (frame_nbr == 10); - -#if (ZMQ_VERSION >= ZMQ_MAKE_VERSION (4, 1, 0)) -// Test zframe_meta -frame = zframe_new ("Hello", 5); -assert (frame); -rc = zframe_send (&frame, output, 0); -assert (rc == 0); -frame = zframe_recv (input); -const char *meta = zframe_meta (frame, "Socket\-Type"); -assert (meta != NULL); -assert (streq (meta, "PAIR")); -assert (zframe_meta (frame, "nonexistent") == NULL); -zframe_destroy (&frame); -#endif - -zsock_destroy (&input); -zsock_destroy (&output); - -#if defined (ZMQ_SERVER) -// Create server and client sockets and connect over inproc -zsock_t *server = zsock_new_server ("inproc://zframe\-test\-routing"); -assert (server); -zsock_t *client = zsock_new_client ("inproc://zframe\-test\-routing"); -assert (client); - -// Send request from client to server -zframe_t *request = zframe_new ("Hello", 5); -assert (request); -rc = zframe_send (&request, client, 0); -assert (rc == 0); -assert (!request); - -// Read request and send reply -request = zframe_recv (server); -assert (request); -assert (zframe_streq (request, "Hello")); -assert (zframe_routing_id (request)); - -zframe_t *reply = zframe_new ("World", 5); -assert (reply); -zframe_set_routing_id (reply, zframe_routing_id (request)); -rc = zframe_send (&reply, server, 0); -assert (rc == 0); -zframe_destroy (&request); - -// Read reply -reply = zframe_recv (client); -assert (zframe_streq (reply, "World")); -assert (zframe_routing_id (reply) == 0); -zframe_destroy (&reply); - -// Client and server disallow multipart -frame = zframe_new ("Hello", 5); -rc = zframe_send (&frame, client, ZFRAME_MORE); -assert (rc == \-1); -rc = zframe_send (&frame, server, ZFRAME_MORE); -assert (rc == \-1); -zframe_destroy (&frame); - -zsock_destroy (&client); -zsock_destroy (&server); -#endif - -#ifdef ZMQ_RADIO -// Create radio and dish sockets and connect over inproc -zsock_t *radio = zsock_new_radio ("inproc://zframe\-test\-radio"); -assert (radio); -zsock_t *dish = zsock_new_dish ("inproc://zframe\-test\-radio"); -assert (dish); - -// Join the group -rc = zsock_join (dish, "World"); -assert (rc == 0); - -// Publish message from radio -zframe_t *message = zframe_new ("Hello", 5); -assert (message); -rc = zframe_set_group (message, "World"); -assert (rc == 0); -rc = zframe_send (&message, radio, 0); -assert (rc == 0); -assert (!message); - -// Receive the message from dish -message = zframe_recv (dish); -assert (message); -assert (zframe_streq (message, "Hello")); -assert (strcmp("World", zframe_group (message)) == 0); -zframe_destroy (&message); - -zsock_destroy (&dish); -zsock_destroy (&radio); -#endif -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zgossip.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zgossip.3 deleted file mode 100644 index 170d3a2271bc83..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zgossip.3 +++ /dev/null @@ -1,338 +0,0 @@ -'\" t -.\" Title: zgossip -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZGOSSIP" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zgossip \- decentralized configuration management -.SH "SYNOPSIS" -.sp -.nf -// To work with zgossip, use the CZMQ zactor API: -// -// Create new zgossip instance, passing logging prefix: -// -// zactor_t *zgossip = zactor_new (zgossip, "myname"); -// -// Destroy zgossip instance -// -// zactor_destroy (&zgossip); -// -// Enable verbose logging of commands and activity: -// -// zstr_send (zgossip, "VERBOSE"); -// -// Bind zgossip to specified endpoint\&. TCP endpoints may specify -// the port number as "*" to aquire an ephemeral port: -// -// zstr_sendx (zgossip, "BIND", endpoint, NULL); -// -// Return assigned port number, specifically when BIND was done using an -// an ephemeral port: -// -// zstr_sendx (zgossip, "PORT", NULL); -// char *command, *port_str; -// zstr_recvx (zgossip, &command, &port_str, NULL); -// assert (streq (command, "PORT")); -// -// Specify configuration file to load, overwriting any previous loaded -// configuration file or options: -// -// zstr_sendx (zgossip, "LOAD", filename, NULL); -// -// Set configuration path value: -// -// zstr_sendx (zgossip, "SET", path, value, NULL); -// -// Save configuration data to config file on disk: -// -// zstr_sendx (zgossip, "SAVE", filename, NULL); -// -// Send zmsg_t instance to zgossip: -// -// zactor_send (zgossip, &msg); -// -// Receive zmsg_t instance from zgossip: -// -// zmsg_t *msg = zactor_recv (zgossip); -// -// This is the zgossip constructor as a zactor_fn: -// -CZMQ_EXPORT void - zgossip (zsock_t *pipe, void *args); - -// Self test of this class -CZMQ_EXPORT void - zgossip_test (bool verbose); -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zgossip\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -Implements a gossip protocol for decentralized configuration management\&. Your applications nodes form a loosely connected network (which can have cycles), and publish name/value tuples\&. Each node re\-distributes the new tuples it receives, so that the entire network eventually achieves a consistent state\&. The current design does not expire tuples\&. -.sp -Provides these commands (sent as multipart strings to the actor): -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -BIND endpoint \(em binds the gossip service to specified endpoint -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -PORT \(em returns the last TCP port, if any, used for binding -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -LOAD configfile \(em load configuration from specified file -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -SET configpath value \(em set configuration path = value -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -SAVE configfile \(em save configuration to specified file -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -CONNECT endpoint \(em connect the gossip service to the specified peer -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -PUBLISH key value \(em publish a key/value pair to the gossip cluster -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -STATUS \(em return number of key/value pairs held by gossip service -.RE -.sp -Returns these messages: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -PORT number \(em reply to PORT command -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -STATUS number \(em reply to STATUS command -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -DELIVER key value \(em new tuple delivered from network -.RE -.sp -The gossip protocol distributes information around a loosely\-connected network of gossip services\&. The information consists of name/value pairs published by applications at any point in the network\&. The goal of the gossip protocol is to create eventual consistency between all the using applications\&. -.sp -The name/value pairs (tuples) can be used for configuration data, for status updates, for presence, or for discovery\&. When used for discovery, the gossip protocol works as an alternative to e\&.g\&. UDP beaconing\&. -.sp -The gossip network consists of a set of loosely\-coupled nodes that exchange tuples\&. Nodes can be connected across arbitrary transports, so the gossip network can have nodes that communicate over inproc, over IPC, and/or over TCP, at the same time\&. -.sp -Each node runs the same stack, which is a server\-client hybrid using a modified Harmony pattern (from Chapter 8 of the Guide): \m[blue]\fBhttp://zguide\&.zeromq\&.org/page:all#True\-Peer\-Connectivity\-Harmony\-Pattern\fR\m[] -.sp -Each node provides a ROUTER socket that accepts client connections on an key defined by the application via a BIND command\&. The state machine for these connections is in zgossip\&.xml, and the generated code is in zgossip_engine\&.inc\&. -.sp -Each node additionally creates outbound connections via DEALER sockets to a set of servers ("remotes"), and under control of the calling app, which sends CONNECT commands for each configured remote\&. -.sp -The messages between client and server are defined in zgossip_msg\&.xml\&. We built this stack using the zeromq/zproto toolkit\&. -.sp -To join the gossip network, a node connects to one or more peers\&. Each peer acts as a forwarder\&. This loosely\-coupled network can scale to thousands of nodes\&. However the gossip protocol is NOT designed to be efficient, and should not be used for application data, as the same tuples may be sent many times across the network\&. -.sp -The basic logic of the gossip service is to accept PUBLISH messages from its owning application, and to forward these to every remote, and every client it talks to\&. When a node gets a duplicate tuple, it throws it away\&. When a node gets a new tuple, it stores it, and fowards it as just described\&. At any point the application can access the node\(cqs set of tuples\&. -.sp -At present there is no way to expire tuples from the network\&. -.sp -The assumptions in this design are: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The data set is slow\-changing\&. Thus, the cost of the gossip protocol is irrelevant with respect to other traffic\&. -.RE -.SH "EXAMPLE" -.PP -\fBFrom zgossip_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Test basic client\-to\-server operation of the protocol -zactor_t *server = zactor_new (zgossip, "server"); -assert (server); -if (verbose) - zstr_send (server, "VERBOSE"); -zstr_sendx (server, "BIND", "inproc://zgossip", NULL); - -zsock_t *client = zsock_new (ZMQ_DEALER); -assert (client); -zsock_set_rcvtimeo (client, 2000); -int rc = zsock_connect (client, "inproc://zgossip"); -assert (rc == 0); - -// Send HELLO, which gets no message -zgossip_msg_t *message = zgossip_msg_new (); -zgossip_msg_set_id (message, ZGOSSIP_MSG_HELLO); -zgossip_msg_send (message, client); - -// Send PING, expect PONG back -zgossip_msg_set_id (message, ZGOSSIP_MSG_PING); -zgossip_msg_send (message, client); -zgossip_msg_recv (message, client); -assert (zgossip_msg_id (message) == ZGOSSIP_MSG_PONG); -zgossip_msg_destroy (&message); - -zactor_destroy (&server); -zsock_destroy (&client); - -// Test peer\-to\-peer operations -zactor_t *base = zactor_new (zgossip, "base"); -assert (base); -if (verbose) - zstr_send (base, "VERBOSE"); -// Set a 100msec timeout on clients so we can test expiry -zstr_sendx (base, "SET", "server/timeout", "100", NULL); -zstr_sendx (base, "BIND", "inproc://base", NULL); - -zactor_t *alpha = zactor_new (zgossip, "alpha"); -assert (alpha); -zstr_sendx (alpha, "CONNECT", "inproc://base", NULL); -zstr_sendx (alpha, "PUBLISH", "inproc://alpha\-1", "service1", NULL); -zstr_sendx (alpha, "PUBLISH", "inproc://alpha\-2", "service2", NULL); - -zactor_t *beta = zactor_new (zgossip, "beta"); -assert (beta); -zstr_sendx (beta, "CONNECT", "inproc://base", NULL); -zstr_sendx (beta, "PUBLISH", "inproc://beta\-1", "service1", NULL); -zstr_sendx (beta, "PUBLISH", "inproc://beta\-2", "service2", NULL); - -// got nothing -zclock_sleep (200); - -zactor_destroy (&base); -zactor_destroy (&alpha); -zactor_destroy (&beta); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zhash.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zhash.3 deleted file mode 100644 index 8d0d45ab3f3184..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zhash.3 +++ /dev/null @@ -1,382 +0,0 @@ -'\" t -.\" Title: zhash -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZHASH" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zhash \- simple generic hash container -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// Callback function for zhash_freefn method -typedef void (zhash_free_fn) ( - void *data); - -// Create a new, empty hash container -CZMQ_EXPORT zhash_t * - zhash_new (void); - -// Unpack binary frame into a new hash table\&. Packed data must follow format -// defined by zhash_pack\&. Hash table is set to autofree\&. An empty frame -// unpacks to an empty hash table\&. -CZMQ_EXPORT zhash_t * - zhash_unpack (zframe_t *frame); - -// Destroy a hash container and all items in it -CZMQ_EXPORT void - zhash_destroy (zhash_t **self_p); - -// Insert item into hash table with specified key and item\&. -// If key is already present returns \-1 and leaves existing item unchanged -// Returns 0 on success\&. -CZMQ_EXPORT int - zhash_insert (zhash_t *self, const char *key, void *item); - -// Update item into hash table with specified key and item\&. -// If key is already present, destroys old item and inserts new one\&. -// Use free_fn method to ensure deallocator is properly called on item\&. -CZMQ_EXPORT void - zhash_update (zhash_t *self, const char *key, void *item); - -// Remove an item specified by key from the hash table\&. If there was no such -// item, this function does nothing\&. -CZMQ_EXPORT void - zhash_delete (zhash_t *self, const char *key); - -// Return the item at the specified key, or null -CZMQ_EXPORT void * - zhash_lookup (zhash_t *self, const char *key); - -// Reindexes an item from an old key to a new key\&. If there was no such -// item, does nothing\&. Returns 0 if successful, else \-1\&. -CZMQ_EXPORT int - zhash_rename (zhash_t *self, const char *old_key, const char *new_key); - -// Set a free function for the specified hash table item\&. When the item is -// destroyed, the free function, if any, is called on that item\&. -// Use this when hash items are dynamically allocated, to ensure that -// you don\*(Aqt have memory leaks\&. You can pass \*(Aqfree\*(Aq or NULL as a free_fn\&. -// Returns the item, or NULL if there is no such item\&. -CZMQ_EXPORT void * - zhash_freefn (zhash_t *self, const char *key, zhash_free_fn free_fn); - -// Return the number of keys/items in the hash table -CZMQ_EXPORT size_t - zhash_size (zhash_t *self); - -// Make copy of hash table; if supplied table is null, returns null\&. -// Does not copy items themselves\&. Rebuilds new table so may be slow on -// very large tables\&. NOTE: only works with item values that are strings -// since there\*(Aqs no other way to know how to duplicate the item value\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zhash_t * - zhash_dup (zhash_t *self); - -// Return keys for items in table -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zlist_t * - zhash_keys (zhash_t *self); - -// Simple iterator; returns first item in hash table, in no given order, -// or NULL if the table is empty\&. This method is simpler to use than the -// foreach() method, which is deprecated\&. To access the key for this item -// use zhash_cursor()\&. NOTE: do NOT modify the table while iterating\&. -CZMQ_EXPORT void * - zhash_first (zhash_t *self); - -// Simple iterator; returns next item in hash table, in no given order, -// or NULL if the last item was already returned\&. Use this together with -// zhash_first() to process all items in a hash table\&. If you need the -// items in sorted order, use zhash_keys() and then zlist_sort()\&. To -// access the key for this item use zhash_cursor()\&. NOTE: do NOT modify -// the table while iterating\&. -CZMQ_EXPORT void * - zhash_next (zhash_t *self); - -// After a successful first/next method, returns the key for the item that -// was returned\&. This is a constant string that you may not modify or -// deallocate, and which lasts as long as the item in the hash\&. After an -// unsuccessful first/next, returns NULL\&. -CZMQ_EXPORT const char * - zhash_cursor (zhash_t *self); - -// Add a comment to hash table before saving to disk\&. You can add as many -// comment lines as you like\&. These comment lines are discarded when loading -// the file\&. If you use a null format, all comments are deleted\&. -CZMQ_EXPORT void - zhash_comment (zhash_t *self, const char *format, \&.\&.\&.) CHECK_PRINTF (2); - -// Serialize hash table to a binary frame that can be sent in a message\&. -// The packed format is compatible with the \*(Aqdictionary\*(Aq type defined in -// http://rfc\&.zeromq\&.org/spec:35/FILEMQ, and implemented by zproto: -// -// ; A list of name/value pairs -// dictionary = dict\-count *( dict\-name dict\-value ) -// dict\-count = number\-4 -// dict\-value = longstr -// dict\-name = string -// -// ; Strings are always length + text contents -// longstr = number\-4 *VCHAR -// string = number\-1 *VCHAR -// -// ; Numbers are unsigned integers in network byte order -// number\-1 = 1OCTET -// number\-4 = 4OCTET -// -// Comments are not included in the packed data\&. Item values MUST be -// strings\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zframe_t * - zhash_pack (zhash_t *self); - -// Save hash table to a text file in name=value format\&. Hash values must be -// printable strings; keys may not contain \*(Aq=\*(Aq character\&. Returns 0 if OK, -// else \-1 if a file error occurred\&. -CZMQ_EXPORT int - zhash_save (zhash_t *self, const char *filename); - -// Load hash table from a text file in name=value format; hash table must -// already exist\&. Hash values must printable strings; keys may not contain -// \*(Aq=\*(Aq character\&. Returns 0 if OK, else \-1 if a file was not readable\&. -CZMQ_EXPORT int - zhash_load (zhash_t *self, const char *filename); - -// When a hash table was loaded from a file by zhash_load, this method will -// reload the file if it has been modified since, and is "stable", i\&.e\&. not -// still changing\&. Returns 0 if OK, \-1 if there was an error reloading the -// file\&. -CZMQ_EXPORT int - zhash_refresh (zhash_t *self); - -// Set hash for automatic value destruction -CZMQ_EXPORT void - zhash_autofree (zhash_t *self); - -// Self test of this class\&. -CZMQ_EXPORT void - zhash_test (bool verbose); - -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zhash\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -zhash is an expandable hash table container\&. This is a simple container\&. For heavy\-duty applications we recommend using zhashx\&. -.sp -Note that it\(cqs relatively slow (50K insertions/deletes per second), so don\(cqt do inserts/updates on the critical path for message I/O\&. It can do 2\&.5M lookups per second for 16\-char keys\&. Timed on a 1\&.6GHz CPU\&. -.SH "EXAMPLE" -.PP -\fBFrom zhash_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zhash_t *hash = zhash_new (); -assert (hash); -assert (zhash_size (hash) == 0); -assert (zhash_first (hash) == NULL); -assert (zhash_cursor (hash) == NULL); - -// Insert some items -int rc; -rc = zhash_insert (hash, "DEADBEEF", "dead beef"); -char *item = (char *) zhash_first (hash); -assert (streq (zhash_cursor (hash), "DEADBEEF")); -assert (streq (item, "dead beef")); -assert (rc == 0); -rc = zhash_insert (hash, "ABADCAFE", "a bad cafe"); -assert (rc == 0); -rc = zhash_insert (hash, "C0DEDBAD", "coded bad"); -assert (rc == 0); -rc = zhash_insert (hash, "DEADF00D", "dead food"); -assert (rc == 0); -assert (zhash_size (hash) == 4); - -// Look for existing items -item = (char *) zhash_lookup (hash, "DEADBEEF"); -assert (streq (item, "dead beef")); -item = (char *) zhash_lookup (hash, "ABADCAFE"); -assert (streq (item, "a bad cafe")); -item = (char *) zhash_lookup (hash, "C0DEDBAD"); -assert (streq (item, "coded bad")); -item = (char *) zhash_lookup (hash, "DEADF00D"); -assert (streq (item, "dead food")); - -// Look for non\-existent items -item = (char *) zhash_lookup (hash, "foo"); -assert (item == NULL); - -// Try to insert duplicate items -rc = zhash_insert (hash, "DEADBEEF", "foo"); -assert (rc == \-1); -item = (char *) zhash_lookup (hash, "DEADBEEF"); -assert (streq (item, "dead beef")); - -// Some rename tests - -// Valid rename, key is now LIVEBEEF -rc = zhash_rename (hash, "DEADBEEF", "LIVEBEEF"); -assert (rc == 0); -item = (char *) zhash_lookup (hash, "LIVEBEEF"); -assert (streq (item, "dead beef")); - -// Trying to rename an unknown item to a non\-existent key -rc = zhash_rename (hash, "WHATBEEF", "NONESUCH"); -assert (rc == \-1); - -// Trying to rename an unknown item to an existing key -rc = zhash_rename (hash, "WHATBEEF", "LIVEBEEF"); -assert (rc == \-1); -item = (char *) zhash_lookup (hash, "LIVEBEEF"); -assert (streq (item, "dead beef")); - -// Trying to rename an existing item to another existing item -rc = zhash_rename (hash, "LIVEBEEF", "ABADCAFE"); -assert (rc == \-1); -item = (char *) zhash_lookup (hash, "LIVEBEEF"); -assert (streq (item, "dead beef")); -item = (char *) zhash_lookup (hash, "ABADCAFE"); -assert (streq (item, "a bad cafe")); - -// Test keys method -zlist_t *keys = zhash_keys (hash); -assert (zlist_size (keys) == 4); -zlist_destroy (&keys); - -// Test dup method -zhash_t *copy = zhash_dup (hash); -assert (zhash_size (copy) == 4); -item = (char *) zhash_lookup (copy, "LIVEBEEF"); -assert (item); -assert (streq (item, "dead beef")); -zhash_destroy (©); - -// Test pack/unpack methods -zframe_t *frame = zhash_pack (hash); -copy = zhash_unpack (frame); -zframe_destroy (&frame); -assert (zhash_size (copy) == 4); -item = (char *) zhash_lookup (copy, "LIVEBEEF"); -assert (item); -assert (streq (item, "dead beef")); -zhash_destroy (©); - -// Test save and load -zhash_comment (hash, "This is a test file"); -zhash_comment (hash, "Created by %s", "czmq_selftest"); -zhash_save (hash, "\&.cache"); -copy = zhash_new (); -assert (copy); -zhash_load (copy, "\&.cache"); -item = (char *) zhash_lookup (copy, "LIVEBEEF"); -assert (item); -assert (streq (item, "dead beef")); -zhash_destroy (©); -zsys_file_delete ("\&.cache"); - -// Delete a item -zhash_delete (hash, "LIVEBEEF"); -item = (char *) zhash_lookup (hash, "LIVEBEEF"); -assert (item == NULL); -assert (zhash_size (hash) == 3); - -// Check that the queue is robust against random usage -struct { - char name [100]; - bool exists; -} testset [200]; -memset (testset, 0, sizeof (testset)); -int testmax = 200, testnbr, iteration; - -srandom ((unsigned) time (NULL)); -for (iteration = 0; iteration < 25000; iteration++) { - testnbr = randof (testmax); - assert (testnbr != testmax); - assert (testnbr < testmax); - if (testset [testnbr]\&.exists) { - item = (char *) zhash_lookup (hash, testset [testnbr]\&.name); - assert (item); - zhash_delete (hash, testset [testnbr]\&.name); - testset [testnbr]\&.exists = false; - } - else { - sprintf (testset [testnbr]\&.name, "%x\-%x", rand (), rand ()); - if (zhash_insert (hash, testset [testnbr]\&.name, "") == 0) - testset [testnbr]\&.exists = true; - } -} -// Test 10K lookups -for (iteration = 0; iteration < 10000; iteration++) - item = (char *) zhash_lookup (hash, "DEADBEEFABADCAFE"); - -// Destructor should be safe to call twice -zhash_destroy (&hash); -zhash_destroy (&hash); -assert (hash == NULL); - -// Test autofree; automatically copies and frees string values -hash = zhash_new (); -assert (hash); -zhash_autofree (hash); -char value [255]; -strcpy (value, "This is a string"); -rc = zhash_insert (hash, "key1", value); -assert (rc == 0); -strcpy (value, "Inserting with the same key will fail"); -rc = zhash_insert (hash, "key1", value); -assert (rc == \-1); -strcpy (value, "Ring a ding ding"); -rc = zhash_insert (hash, "key2", value); -assert (rc == 0); -assert (streq ((char *) zhash_lookup (hash, "key1"), "This is a string")); -assert (streq ((char *) zhash_lookup (hash, "key2"), "Ring a ding ding")); -zhash_destroy (&hash); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zhashx.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zhashx.3 deleted file mode 100644 index d78b29a4312ecb..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zhashx.3 +++ /dev/null @@ -1,498 +0,0 @@ -'\" t -.\" Title: zhashx -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZHASHX" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zhashx \- extended generic hash container -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// This class has draft methods, which may change over time\&. They are not -// in stable releases, by default\&. Use \-\-enable\-drafts to enable\&. -// Destroy an item -typedef void (zhashx_destructor_fn) ( - void **item); - -// Duplicate an item -typedef void * (zhashx_duplicator_fn) ( - const void *item); - -// Compare two items, for sorting -typedef int (zhashx_comparator_fn) ( - const void *item1, const void *item2); - -// compare two items, for sorting -typedef void (zhashx_free_fn) ( - void *data); - -// compare two items, for sorting -typedef size_t (zhashx_hash_fn) ( - const void *key); - -// Serializes an item to a longstr\&. -// The caller takes ownership of the newly created object\&. -typedef char * (zhashx_serializer_fn) ( - const void *item); - -// Deserializes a longstr into an item\&. -// The caller takes ownership of the newly created object\&. -typedef void * (zhashx_deserializer_fn) ( - const char *item_str); - -// Create a new, empty hash container -CZMQ_EXPORT zhashx_t * - zhashx_new (void); - -// Unpack binary frame into a new hash table\&. Packed data must follow format -// defined by zhashx_pack\&. Hash table is set to autofree\&. An empty frame -// unpacks to an empty hash table\&. -CZMQ_EXPORT zhashx_t * - zhashx_unpack (zframe_t *frame); - -// Destroy a hash container and all items in it -CZMQ_EXPORT void - zhashx_destroy (zhashx_t **self_p); - -// Insert item into hash table with specified key and item\&. -// If key is already present returns \-1 and leaves existing item unchanged -// Returns 0 on success\&. -CZMQ_EXPORT int - zhashx_insert (zhashx_t *self, const void *key, void *item); - -// Update or insert item into hash table with specified key and item\&. If the -// key is already present, destroys old item and inserts new one\&. If you set -// a container item destructor, this is called on the old value\&. If the key -// was not already present, inserts a new item\&. Sets the hash cursor to the -// new item\&. -CZMQ_EXPORT void - zhashx_update (zhashx_t *self, const void *key, void *item); - -// Remove an item specified by key from the hash table\&. If there was no such -// item, this function does nothing\&. -CZMQ_EXPORT void - zhashx_delete (zhashx_t *self, const void *key); - -// Delete all items from the hash table\&. If the key destructor is -// set, calls it on every key\&. If the item destructor is set, calls -// it on every item\&. -CZMQ_EXPORT void - zhashx_purge (zhashx_t *self); - -// Return the item at the specified key, or null -CZMQ_EXPORT void * - zhashx_lookup (zhashx_t *self, const void *key); - -// Reindexes an item from an old key to a new key\&. If there was no such -// item, does nothing\&. Returns 0 if successful, else \-1\&. -CZMQ_EXPORT int - zhashx_rename (zhashx_t *self, const void *old_key, const void *new_key); - -// Set a free function for the specified hash table item\&. When the item is -// destroyed, the free function, if any, is called on that item\&. -// Use this when hash items are dynamically allocated, to ensure that -// you don\*(Aqt have memory leaks\&. You can pass \*(Aqfree\*(Aq or NULL as a free_fn\&. -// Returns the item, or NULL if there is no such item\&. -CZMQ_EXPORT void * - zhashx_freefn (zhashx_t *self, const void *key, zhashx_free_fn free_fn); - -// Return the number of keys/items in the hash table -CZMQ_EXPORT size_t - zhashx_size (zhashx_t *self); - -// Return a zlistx_t containing the keys for the items in the -// table\&. Uses the key_duplicator to duplicate all keys and sets the -// key_destructor as destructor for the list\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zlistx_t * - zhashx_keys (zhashx_t *self); - -// Return a zlistx_t containing the values for the items in the -// table\&. Uses the duplicator to duplicate all items and sets the -// destructor as destructor for the list\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zlistx_t * - zhashx_values (zhashx_t *self); - -// Simple iterator; returns first item in hash table, in no given order, -// or NULL if the table is empty\&. This method is simpler to use than the -// foreach() method, which is deprecated\&. To access the key for this item -// use zhashx_cursor()\&. NOTE: do NOT modify the table while iterating\&. -CZMQ_EXPORT void * - zhashx_first (zhashx_t *self); - -// Simple iterator; returns next item in hash table, in no given order, -// or NULL if the last item was already returned\&. Use this together with -// zhashx_first() to process all items in a hash table\&. If you need the -// items in sorted order, use zhashx_keys() and then zlistx_sort()\&. To -// access the key for this item use zhashx_cursor()\&. NOTE: do NOT modify -// the table while iterating\&. -CZMQ_EXPORT void * - zhashx_next (zhashx_t *self); - -// After a successful first/next method, returns the key for the item that -// was returned\&. This is a constant string that you may not modify or -// deallocate, and which lasts as long as the item in the hash\&. After an -// unsuccessful first/next, returns NULL\&. -CZMQ_EXPORT const void * - zhashx_cursor (zhashx_t *self); - -// Add a comment to hash table before saving to disk\&. You can add as many -// comment lines as you like\&. These comment lines are discarded when loading -// the file\&. If you use a null format, all comments are deleted\&. -CZMQ_EXPORT void - zhashx_comment (zhashx_t *self, const char *format, \&.\&.\&.) CHECK_PRINTF (2); - -// Save hash table to a text file in name=value format\&. Hash values must be -// printable strings; keys may not contain \*(Aq=\*(Aq character\&. Returns 0 if OK, -// else \-1 if a file error occurred\&. -CZMQ_EXPORT int - zhashx_save (zhashx_t *self, const char *filename); - -// Load hash table from a text file in name=value format; hash table must -// already exist\&. Hash values must printable strings; keys may not contain -// \*(Aq=\*(Aq character\&. Returns 0 if OK, else \-1 if a file was not readable\&. -CZMQ_EXPORT int - zhashx_load (zhashx_t *self, const char *filename); - -// When a hash table was loaded from a file by zhashx_load, this method will -// reload the file if it has been modified since, and is "stable", i\&.e\&. not -// still changing\&. Returns 0 if OK, \-1 if there was an error reloading the -// file\&. -CZMQ_EXPORT int - zhashx_refresh (zhashx_t *self); - -// Serialize hash table to a binary frame that can be sent in a message\&. -// The packed format is compatible with the \*(Aqdictionary\*(Aq type defined in -// http://rfc\&.zeromq\&.org/spec:35/FILEMQ, and implemented by zproto: -// -// ; A list of name/value pairs -// dictionary = dict\-count *( dict\-name dict\-value ) -// dict\-count = number\-4 -// dict\-value = longstr -// dict\-name = string -// -// ; Strings are always length + text contents -// longstr = number\-4 *VCHAR -// string = number\-1 *VCHAR -// -// ; Numbers are unsigned integers in network byte order -// number\-1 = 1OCTET -// number\-4 = 4OCTET -// -// Comments are not included in the packed data\&. Item values MUST be -// strings\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zframe_t * - zhashx_pack (zhashx_t *self); - -// Make a copy of the list; items are duplicated if you set a duplicator -// for the list, otherwise not\&. Copying a null reference returns a null -// reference\&. Note that this method\*(Aqs behavior changed slightly for CZMQ -// v3\&.x, as it does not set nor respect autofree\&. It does however let you -// duplicate any hash table safely\&. The old behavior is in zhashx_dup_v2\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zhashx_t * - zhashx_dup (zhashx_t *self); - -// Set a user\-defined deallocator for hash items; by default items are not -// freed when the hash is destroyed\&. -CZMQ_EXPORT void - zhashx_set_destructor (zhashx_t *self, zhashx_destructor_fn destructor); - -// Set a user\-defined duplicator for hash items; by default items are not -// copied when the hash is duplicated\&. -CZMQ_EXPORT void - zhashx_set_duplicator (zhashx_t *self, zhashx_duplicator_fn duplicator); - -// Set a user\-defined deallocator for keys; by default keys are freed -// when the hash is destroyed using free()\&. -CZMQ_EXPORT void - zhashx_set_key_destructor (zhashx_t *self, zhashx_destructor_fn destructor); - -// Set a user\-defined duplicator for keys; by default keys are duplicated -// using strdup\&. -CZMQ_EXPORT void - zhashx_set_key_duplicator (zhashx_t *self, zhashx_duplicator_fn duplicator); - -// Set a user\-defined comparator for keys; by default keys are -// compared using strcmp\&. -CZMQ_EXPORT void - zhashx_set_key_comparator (zhashx_t *self, zhashx_comparator_fn comparator); - -// Set a user\-defined comparator for keys; by default keys are -// compared using strcmp\&. -CZMQ_EXPORT void - zhashx_set_key_hasher (zhashx_t *self, zhashx_hash_fn hasher); - -// Make copy of hash table; if supplied table is null, returns null\&. -// Does not copy items themselves\&. Rebuilds new table so may be slow on -// very large tables\&. NOTE: only works with item values that are strings -// since there\*(Aqs no other way to know how to duplicate the item value\&. -CZMQ_EXPORT zhashx_t * - zhashx_dup_v2 (zhashx_t *self); - -// Self test of this class\&. -CZMQ_EXPORT void - zhashx_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Same as unpack but uses a user\-defined deserializer function to convert -// a longstr back into item format\&. -CZMQ_EXPORT zhashx_t * - zhashx_unpack_own (zframe_t *frame, zhashx_deserializer_fn deserializer); - -// *** Draft method, for development use, may change without warning *** -// Same as pack but uses a user\-defined serializer function to convert items -// into longstr\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zframe_t * - zhashx_pack_own (zhashx_t *self, zhashx_serializer_fn serializer); - -#endif // CZMQ_BUILD_DRAFT_API -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zhashx\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -zhashx is an extended hash table container with more functionality than zhash, its simpler cousin\&. -.sp -The hash table always has a size that is prime and roughly doubles its size when 75% full\&. In case of hash collisions items are chained in a linked list\&. The hash table size is increased slightly (up to 5 times before roughly doubling the size) when an overly long chain (between 1 and 63 items depending on table size) is detected\&. -.SH "EXAMPLE" -.PP -\fBFrom zhashx_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zhashx_t *hash = zhashx_new (); -assert (hash); -assert (zhashx_size (hash) == 0); -assert (zhashx_first (hash) == NULL); -assert (zhashx_cursor (hash) == NULL); - -// Insert some items -int rc; -rc = zhashx_insert (hash, "DEADBEEF", "dead beef"); -char *item = (char *) zhashx_first (hash); -assert (streq ((char *) zhashx_cursor (hash), "DEADBEEF")); -assert (streq (item, "dead beef")); -assert (rc == 0); -rc = zhashx_insert (hash, "ABADCAFE", "a bad cafe"); -assert (rc == 0); -rc = zhashx_insert (hash, "C0DEDBAD", "coded bad"); -assert (rc == 0); -rc = zhashx_insert (hash, "DEADF00D", "dead food"); -assert (rc == 0); -assert (zhashx_size (hash) == 4); - -// Look for existing items -item = (char *) zhashx_lookup (hash, "DEADBEEF"); -assert (streq (item, "dead beef")); -item = (char *) zhashx_lookup (hash, "ABADCAFE"); -assert (streq (item, "a bad cafe")); -item = (char *) zhashx_lookup (hash, "C0DEDBAD"); -assert (streq (item, "coded bad")); -item = (char *) zhashx_lookup (hash, "DEADF00D"); -assert (streq (item, "dead food")); - -// Look for non\-existent items -item = (char *) zhashx_lookup (hash, "foo"); -assert (item == NULL); - -// Try to insert duplicate items -rc = zhashx_insert (hash, "DEADBEEF", "foo"); -assert (rc == \-1); -item = (char *) zhashx_lookup (hash, "DEADBEEF"); -assert (streq (item, "dead beef")); - -// Some rename tests - -// Valid rename, key is now LIVEBEEF -rc = zhashx_rename (hash, "DEADBEEF", "LIVEBEEF"); -assert (rc == 0); -item = (char *) zhashx_lookup (hash, "LIVEBEEF"); -assert (streq (item, "dead beef")); - -// Trying to rename an unknown item to a non\-existent key -rc = zhashx_rename (hash, "WHATBEEF", "NONESUCH"); -assert (rc == \-1); - -// Trying to rename an unknown item to an existing key -rc = zhashx_rename (hash, "WHATBEEF", "LIVEBEEF"); -assert (rc == \-1); -item = (char *) zhashx_lookup (hash, "LIVEBEEF"); -assert (streq (item, "dead beef")); - -// Trying to rename an existing item to another existing item -rc = zhashx_rename (hash, "LIVEBEEF", "ABADCAFE"); -assert (rc == \-1); -item = (char *) zhashx_lookup (hash, "LIVEBEEF"); -assert (streq (item, "dead beef")); -item = (char *) zhashx_lookup (hash, "ABADCAFE"); -assert (streq (item, "a bad cafe")); - -// Test keys method -zlistx_t *keys = zhashx_keys (hash); -assert (zlistx_size (keys) == 4); -zlistx_destroy (&keys); - -zlistx_t *values = zhashx_values(hash); -assert (zlistx_size (values) == 4); -zlistx_destroy (&values); - -// Test dup method -zhashx_t *copy = zhashx_dup (hash); -assert (zhashx_size (copy) == 4); -item = (char *) zhashx_lookup (copy, "LIVEBEEF"); -assert (item); -assert (streq (item, "dead beef")); -zhashx_destroy (©); - -// Test pack/unpack methods -zframe_t *frame = zhashx_pack (hash); -copy = zhashx_unpack (frame); -zframe_destroy (&frame); -assert (zhashx_size (copy) == 4); -item = (char *) zhashx_lookup (copy, "LIVEBEEF"); -assert (item); -assert (streq (item, "dead beef")); -zhashx_destroy (©); - -#ifdef CZMQ_BUILD_DRAFT_API -// Test own pack/unpack methods -zhashx_t *own_hash = zhashx_new (); -zhashx_set_destructor (own_hash, s_test_destroy_int); -assert (own_hash); -int *val1 = (int *) zmalloc (sizeof (int)); -int *val2 = (int *) zmalloc (sizeof (int)); -*val1 = 25; -*val2 = 100; -zhashx_insert (own_hash, "val1", val1); -zhashx_insert (own_hash, "val2", val2); -frame = zhashx_pack_own (own_hash, s_test_serialize_int); -copy = zhashx_unpack_own (frame, s_test_deserialze_int); -zhashx_set_destructor (copy, s_test_destroy_int); -zframe_destroy (&frame); -assert (zhashx_size (copy) == 2); -assert (*((int *) zhashx_lookup (copy, "val1")) == 25); -assert (*((int *) zhashx_lookup (copy, "val2")) == 100); -zhashx_destroy (©); -zhashx_destroy (&own_hash); -#endif // CZMQ_BUILD_DRAFT_API - -// Test save and load -zhashx_comment (hash, "This is a test file"); -zhashx_comment (hash, "Created by %s", "czmq_selftest"); -zhashx_save (hash, "\&.cache"); -copy = zhashx_new (); -assert (copy); -zhashx_load (copy, "\&.cache"); -item = (char *) zhashx_lookup (copy, "LIVEBEEF"); -assert (item); -assert (streq (item, "dead beef")); -zhashx_destroy (©); -zsys_file_delete ("\&.cache"); - -// Delete a item -zhashx_delete (hash, "LIVEBEEF"); -item = (char *) zhashx_lookup (hash, "LIVEBEEF"); -assert (item == NULL); -assert (zhashx_size (hash) == 3); - -// Check that the queue is robust against random usage -struct { - char name [100]; - bool exists; -} testset [200]; -memset (testset, 0, sizeof (testset)); -int testmax = 200, testnbr, iteration; - -srandom ((unsigned) time (NULL)); -for (iteration = 0; iteration < 25000; iteration++) { - testnbr = randof (testmax); - if (testset [testnbr]\&.exists) { - item = (char *) zhashx_lookup (hash, testset [testnbr]\&.name); - assert (item); - zhashx_delete (hash, testset [testnbr]\&.name); - testset [testnbr]\&.exists = false; - } - else { - sprintf (testset [testnbr]\&.name, "%x\-%x", rand (), rand ()); - if (zhashx_insert (hash, testset [testnbr]\&.name, "") == 0) - testset [testnbr]\&.exists = true; - } -} -// Test 10K lookups -for (iteration = 0; iteration < 10000; iteration++) - item = (char *) zhashx_lookup (hash, "DEADBEEFABADCAFE"); - -// Destructor should be safe to call twice -zhashx_destroy (&hash); -zhashx_destroy (&hash); -assert (hash == NULL); - -// Test destructor; automatically copies and frees string values -hash = zhashx_new (); -assert (hash); -zhashx_set_destructor (hash, (zhashx_destructor_fn *) zstr_free); -zhashx_set_duplicator (hash, (zhashx_duplicator_fn *) strdup); -char value [255]; -strcpy (value, "This is a string"); -rc = zhashx_insert (hash, "key1", value); -assert (rc == 0); -strcpy (value, "Ring a ding ding"); -rc = zhashx_insert (hash, "key2", value); -assert (rc == 0); -assert (streq ((char *) zhashx_lookup (hash, "key1"), "This is a string")); -assert (streq ((char *) zhashx_lookup (hash, "key2"), "Ring a ding ding")); -zhashx_destroy (&hash); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/ziflist.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/ziflist.3 deleted file mode 100644 index b50b06c0f3b98c..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/ziflist.3 +++ /dev/null @@ -1,134 +0,0 @@ -'\" t -.\" Title: ziflist -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZIFLIST" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -ziflist \- list of network interfaces available on system -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// Get a list of network interfaces currently defined on the system -CZMQ_EXPORT ziflist_t * - ziflist_new (void); - -// Destroy a ziflist instance -CZMQ_EXPORT void - ziflist_destroy (ziflist_t **self_p); - -// Reload network interfaces from system -CZMQ_EXPORT void - ziflist_reload (ziflist_t *self); - -// Return the number of network interfaces on system -CZMQ_EXPORT size_t - ziflist_size (ziflist_t *self); - -// Get first network interface, return NULL if there are none -CZMQ_EXPORT const char * - ziflist_first (ziflist_t *self); - -// Get next network interface, return NULL if we hit the last one -CZMQ_EXPORT const char * - ziflist_next (ziflist_t *self); - -// Return the current interface IP address as a printable string -CZMQ_EXPORT const char * - ziflist_address (ziflist_t *self); - -// Return the current interface broadcast address as a printable string -CZMQ_EXPORT const char * - ziflist_broadcast (ziflist_t *self); - -// Return the current interface network mask as a printable string -CZMQ_EXPORT const char * - ziflist_netmask (ziflist_t *self); - -// Return the list of interfaces\&. -CZMQ_EXPORT void - ziflist_print (ziflist_t *self); - -// Self test of this class\&. -CZMQ_EXPORT void - ziflist_test (bool verbose); - -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/ziflist\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The ziflist class takes a snapshot of the network interfaces that the system currently supports (this can change arbitrarily, especially on mobile devices)\&. The caller can then access the network interface information using an iterator that works like zlistx\&. Only stores those interfaces with broadcast capability, and ignores the loopback interface\&. -.sp -Please add \fI@discuss\fR section in \fI\&./\&.\&./src/ziflist\&.c\fR\&. -.SH "EXAMPLE" -.PP -\fBFrom ziflist_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -ziflist_t *iflist = ziflist_new (); -assert (iflist); - -size_t items = ziflist_size (iflist); - -if (verbose) { - printf ("ziflist: interfaces=%zu\en", ziflist_size (iflist)); - const char *name = ziflist_first (iflist); - while (name) { - printf (" \- name=%s address=%s netmask=%s broadcast=%s\en", - name, ziflist_address (iflist), ziflist_netmask (iflist), ziflist_broadcast (iflist)); - name = ziflist_next (iflist); - } -} -ziflist_reload (iflist); -assert (items == ziflist_size (iflist)); -ziflist_destroy (&iflist); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zlist.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zlist.3 deleted file mode 100644 index a7131f40e00e1f..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zlist.3 +++ /dev/null @@ -1,316 +0,0 @@ -'\" t -.\" Title: zlist -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZLIST" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zlist \- simple generic list container -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// Comparison function e\&.g\&. for sorting and removing\&. -typedef int (zlist_compare_fn) ( - void *item1, void *item2); - -// Callback function for zlist_freefn method -typedef void (zlist_free_fn) ( - void *data); - -// Create a new list container -CZMQ_EXPORT zlist_t * - zlist_new (void); - -// Destroy a list container -CZMQ_EXPORT void - zlist_destroy (zlist_t **self_p); - -// Return the item at the head of list\&. If the list is empty, returns NULL\&. -// Leaves cursor pointing at the head item, or NULL if the list is empty\&. -CZMQ_EXPORT void * - zlist_first (zlist_t *self); - -// Return the next item\&. If the list is empty, returns NULL\&. To move to -// the start of the list call zlist_first ()\&. Advances the cursor\&. -CZMQ_EXPORT void * - zlist_next (zlist_t *self); - -// Return the item at the tail of list\&. If the list is empty, returns NULL\&. -// Leaves cursor pointing at the tail item, or NULL if the list is empty\&. -CZMQ_EXPORT void * - zlist_last (zlist_t *self); - -// Return first item in the list, or null, leaves the cursor -CZMQ_EXPORT void * - zlist_head (zlist_t *self); - -// Return last item in the list, or null, leaves the cursor -CZMQ_EXPORT void * - zlist_tail (zlist_t *self); - -// Return the current item of list\&. If the list is empty, returns NULL\&. -// Leaves cursor pointing at the current item, or NULL if the list is empty\&. -CZMQ_EXPORT void * - zlist_item (zlist_t *self); - -// Append an item to the end of the list, return 0 if OK or \-1 if this -// failed for some reason (out of memory)\&. Note that if a duplicator has -// been set, this method will also duplicate the item\&. -CZMQ_EXPORT int - zlist_append (zlist_t *self, void *item); - -// Push an item to the start of the list, return 0 if OK or \-1 if this -// failed for some reason (out of memory)\&. Note that if a duplicator has -// been set, this method will also duplicate the item\&. -CZMQ_EXPORT int - zlist_push (zlist_t *self, void *item); - -// Pop the item off the start of the list, if any -CZMQ_EXPORT void * - zlist_pop (zlist_t *self); - -// Checks if an item already is present\&. Uses compare method to determine if -// items are equal\&. If the compare method is NULL the check will only compare -// pointers\&. Returns true if item is present else false\&. -CZMQ_EXPORT bool - zlist_exists (zlist_t *self, void *item); - -// Remove the specified item from the list if present -CZMQ_EXPORT void - zlist_remove (zlist_t *self, void *item); - -// Make a copy of list\&. If the list has autofree set, the copied list will -// duplicate all items, which must be strings\&. Otherwise, the list will hold -// pointers back to the items in the original list\&. If list is null, returns -// NULL\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zlist_t * - zlist_dup (zlist_t *self); - -// Purge all items from list -CZMQ_EXPORT void - zlist_purge (zlist_t *self); - -// Return number of items in the list -CZMQ_EXPORT size_t - zlist_size (zlist_t *self); - -// Sort the list\&. If the compare function is null, sorts the list by -// ascending key value using a straight ASCII comparison\&. If you specify -// a compare function, this decides how items are sorted\&. The sort is not -// stable, so may reorder items with the same keys\&. The algorithm used is -// combsort, a compromise between performance and simplicity\&. -CZMQ_EXPORT void - zlist_sort (zlist_t *self, zlist_compare_fn compare); - -// Set list for automatic item destruction; item values MUST be strings\&. -// By default a list item refers to a value held elsewhere\&. When you set -// this, each time you append or push a list item, zlist will take a copy -// of the string value\&. Then, when you destroy the list, it will free all -// item values automatically\&. If you use any other technique to allocate -// list values, you must free them explicitly before destroying the list\&. -// The usual technique is to pop list items and destroy them, until the -// list is empty\&. -CZMQ_EXPORT void - zlist_autofree (zlist_t *self); - -// Sets a compare function for this list\&. The function compares two items\&. -// It returns an integer less than, equal to, or greater than zero if the -// first item is found, respectively, to be less than, to match, or be -// greater than the second item\&. -// This function is used for sorting, removal and exists checking\&. -CZMQ_EXPORT void - zlist_comparefn (zlist_t *self, zlist_compare_fn fn); - -// Set a free function for the specified list item\&. When the item is -// destroyed, the free function, if any, is called on that item\&. -// Use this when list items are dynamically allocated, to ensure that -// you don\*(Aqt have memory leaks\&. You can pass \*(Aqfree\*(Aq or NULL as a free_fn\&. -// Returns the item, or NULL if there is no such item\&. -CZMQ_EXPORT void * - zlist_freefn (zlist_t *self, void *item, zlist_free_fn fn, bool at_tail); - -// Self test of this class\&. -CZMQ_EXPORT void - zlist_test (bool verbose); - -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zlist\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -Provides a generic container implementing a fast singly\-linked list\&. You can use this to construct multi\-dimensional lists, and other structures together with other generic containers like zhash\&. This is a simple class\&. For demanding applications we recommend using zlistx\&. -.sp -To iterate through a list, use zlist_first to get the first item, then loop while not null, and do zlist_next at the end of each iteration\&. -.SH "EXAMPLE" -.PP -\fBFrom zlist_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zlist_t *list = zlist_new (); -assert (list); -assert (zlist_size (list) == 0); - -// Three items we\*(Aqll use as test data -// List items are void *, not particularly strings -char *cheese = "boursin"; -char *bread = "baguette"; -char *wine = "bordeaux"; - -zlist_append (list, cheese); -assert (zlist_size (list) == 1); -assert ( zlist_exists (list, cheese)); -assert (!zlist_exists (list, bread)); -assert (!zlist_exists (list, wine)); -zlist_append (list, bread); -assert (zlist_size (list) == 2); -assert ( zlist_exists (list, cheese)); -assert ( zlist_exists (list, bread)); -assert (!zlist_exists (list, wine)); -zlist_append (list, wine); -assert (zlist_size (list) == 3); -assert ( zlist_exists (list, cheese)); -assert ( zlist_exists (list, bread)); -assert ( zlist_exists (list, wine)); - -assert (zlist_head (list) == cheese); -assert (zlist_next (list) == cheese); - -assert (zlist_first (list) == cheese); -assert (zlist_tail (list) == wine); -assert (zlist_next (list) == bread); - -assert (zlist_first (list) == cheese); -assert (zlist_next (list) == bread); -assert (zlist_next (list) == wine); -assert (zlist_next (list) == NULL); -// After we reach end of list, next wraps around -assert (zlist_next (list) == cheese); -assert (zlist_size (list) == 3); - -zlist_remove (list, wine); -assert (zlist_size (list) == 2); - -assert (zlist_first (list) == cheese); -zlist_remove (list, cheese); -assert (zlist_size (list) == 1); -assert (zlist_first (list) == bread); - -zlist_remove (list, bread); -assert (zlist_size (list) == 0); - -zlist_append (list, cheese); -zlist_append (list, bread); -assert (zlist_last (list) == bread); -zlist_remove (list, bread); -assert (zlist_last (list) == cheese); -zlist_remove (list, cheese); -assert (zlist_last (list) == NULL); - -zlist_push (list, cheese); -assert (zlist_size (list) == 1); -assert (zlist_first (list) == cheese); - -zlist_push (list, bread); -assert (zlist_size (list) == 2); -assert (zlist_first (list) == bread); -assert (zlist_item (list) == bread); - -zlist_append (list, wine); -assert (zlist_size (list) == 3); -assert (zlist_first (list) == bread); - -zlist_t *sub_list = zlist_dup (list); -assert (sub_list); -assert (zlist_size (sub_list) == 3); - -zlist_sort (list, NULL); -char *item; -item = (char *) zlist_pop (list); -assert (item == bread); -item = (char *) zlist_pop (list); -assert (item == wine); -item = (char *) zlist_pop (list); -assert (item == cheese); -assert (zlist_size (list) == 0); - -assert (zlist_size (sub_list) == 3); -zlist_push (list, sub_list); -zlist_t *sub_list_2 = zlist_dup (sub_list); -zlist_append (list, sub_list_2); -assert (zlist_freefn (list, sub_list, &s_zlist_free, false) == sub_list); -assert (zlist_freefn (list, sub_list_2, &s_zlist_free, true) == sub_list_2); -zlist_destroy (&list); - -// Test autofree functionality -list = zlist_new (); -assert (list); -zlist_autofree (list); -// Set equals function otherwise equals will not work as autofree copies strings -zlist_comparefn (list, (zlist_compare_fn *) strcmp); -zlist_push (list, bread); -zlist_append (list, cheese); -assert (zlist_size (list) == 2); -zlist_append (list, wine); -assert (zlist_exists (list, wine)); -zlist_remove (list, wine); -assert (!zlist_exists (list, wine)); -assert (streq ((const char *) zlist_first (list), bread)); -item = (char *) zlist_pop (list); -assert (streq (item, bread)); -free (item); -item = (char *) zlist_pop (list); -assert (streq (item, cheese)); -free (item); - -zlist_destroy (&list); -assert (list == NULL); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zlistx.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zlistx.3 deleted file mode 100644 index 2e1068554b6945..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zlistx.3 +++ /dev/null @@ -1,346 +0,0 @@ -'\" t -.\" Title: zlistx -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZLISTX" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zlistx \- extended generic list container -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// Destroy an item -typedef void (zlistx_destructor_fn) ( - void **item); - -// Duplicate an item -typedef void * (zlistx_duplicator_fn) ( - const void *item); - -// Compare two items, for sorting -typedef int (zlistx_comparator_fn) ( - const void *item1, const void *item2); - -// Create a new, empty list\&. -CZMQ_EXPORT zlistx_t * - zlistx_new (void); - -// Destroy a list\&. If an item destructor was specified, all items in the -// list are automatically destroyed as well\&. -CZMQ_EXPORT void - zlistx_destroy (zlistx_t **self_p); - -// Add an item to the head of the list\&. Calls the item duplicator, if any, -// on the item\&. Resets cursor to list head\&. Returns an item handle on -// success, NULL if memory was exhausted\&. -CZMQ_EXPORT void * - zlistx_add_start (zlistx_t *self, void *item); - -// Add an item to the tail of the list\&. Calls the item duplicator, if any, -// on the item\&. Resets cursor to list head\&. Returns an item handle on -// success, NULL if memory was exhausted\&. -CZMQ_EXPORT void * - zlistx_add_end (zlistx_t *self, void *item); - -// Return the number of items in the list -CZMQ_EXPORT size_t - zlistx_size (zlistx_t *self); - -// Return first item in the list, or null, leaves the cursor -CZMQ_EXPORT void * - zlistx_head (zlistx_t *self); - -// Return last item in the list, or null, leaves the cursor -CZMQ_EXPORT void * - zlistx_tail (zlistx_t *self); - -// Return the item at the head of list\&. If the list is empty, returns NULL\&. -// Leaves cursor pointing at the head item, or NULL if the list is empty\&. -CZMQ_EXPORT void * - zlistx_first (zlistx_t *self); - -// Return the next item\&. At the end of the list (or in an empty list), -// returns NULL\&. Use repeated zlistx_next () calls to work through the list -// from zlistx_first ()\&. First time, acts as zlistx_first()\&. -CZMQ_EXPORT void * - zlistx_next (zlistx_t *self); - -// Return the previous item\&. At the start of the list (or in an empty list), -// returns NULL\&. Use repeated zlistx_prev () calls to work through the list -// backwards from zlistx_last ()\&. First time, acts as zlistx_last()\&. -CZMQ_EXPORT void * - zlistx_prev (zlistx_t *self); - -// Return the item at the tail of list\&. If the list is empty, returns NULL\&. -// Leaves cursor pointing at the tail item, or NULL if the list is empty\&. -CZMQ_EXPORT void * - zlistx_last (zlistx_t *self); - -// Returns the value of the item at the cursor, or NULL if the cursor is -// not pointing to an item\&. -CZMQ_EXPORT void * - zlistx_item (zlistx_t *self); - -// Returns the handle of the item at the cursor, or NULL if the cursor is -// not pointing to an item\&. -CZMQ_EXPORT void * - zlistx_cursor (zlistx_t *self); - -// Returns the item associated with the given list handle, or NULL if passed -// in handle is NULL\&. Asserts that the passed in handle points to a list element\&. -CZMQ_EXPORT void * - zlistx_handle_item (void *handle); - -// Find an item in the list, searching from the start\&. Uses the item -// comparator, if any, else compares item values directly\&. Returns the -// item handle found, or NULL\&. Sets the cursor to the found item, if any\&. -CZMQ_EXPORT void * - zlistx_find (zlistx_t *self, void *item); - -// Detach an item from the list, using its handle\&. The item is not modified, -// and the caller is responsible for destroying it if necessary\&. If handle is -// null, detaches the first item on the list\&. Returns item that was detached, -// or null if none was\&. If cursor was at item, moves cursor to previous item, -// so you can detach items while iterating forwards through a list\&. -CZMQ_EXPORT void * - zlistx_detach (zlistx_t *self, void *handle); - -// Detach item at the cursor, if any, from the list\&. The item is not modified, -// and the caller is responsible for destroying it as necessary\&. Returns item -// that was detached, or null if none was\&. Moves cursor to previous item, so -// you can detach items while iterating forwards through a list\&. -CZMQ_EXPORT void * - zlistx_detach_cur (zlistx_t *self); - -// Delete an item, using its handle\&. Calls the item destructor is any is -// set\&. If handle is null, deletes the first item on the list\&. Returns 0 -// if an item was deleted, \-1 if not\&. If cursor was at item, moves cursor -// to previous item, so you can delete items while iterating forwards -// through a list\&. -CZMQ_EXPORT int - zlistx_delete (zlistx_t *self, void *handle); - -// Move an item to the start of the list, via its handle\&. -CZMQ_EXPORT void - zlistx_move_start (zlistx_t *self, void *handle); - -// Move an item to the end of the list, via its handle\&. -CZMQ_EXPORT void - zlistx_move_end (zlistx_t *self, void *handle); - -// Remove all items from the list, and destroy them if the item destructor -// is set\&. -CZMQ_EXPORT void - zlistx_purge (zlistx_t *self); - -// Sort the list\&. If an item comparator was set, calls that to compare -// items, otherwise compares on item value\&. The sort is not stable, so may -// reorder equal items\&. -CZMQ_EXPORT void - zlistx_sort (zlistx_t *self); - -// Create a new node and insert it into a sorted list\&. Calls the item -// duplicator, if any, on the item\&. If low_value is true, starts searching -// from the start of the list, otherwise searches from the end\&. Use the item -// comparator, if any, to find where to place the new node\&. Returns a handle -// to the new node, or NULL if memory was exhausted\&. Resets the cursor to the -// list head\&. -CZMQ_EXPORT void * - zlistx_insert (zlistx_t *self, void *item, bool low_value); - -// Move an item, specified by handle, into position in a sorted list\&. Uses -// the item comparator, if any, to determine the new location\&. If low_value -// is true, starts searching from the start of the list, otherwise searches -// from the end\&. -CZMQ_EXPORT void - zlistx_reorder (zlistx_t *self, void *handle, bool low_value); - -// Make a copy of the list; items are duplicated if you set a duplicator -// for the list, otherwise not\&. Copying a null reference returns a null -// reference\&. -CZMQ_EXPORT zlistx_t * - zlistx_dup (zlistx_t *self); - -// Set a user\-defined deallocator for list items; by default items are not -// freed when the list is destroyed\&. -CZMQ_EXPORT void - zlistx_set_destructor (zlistx_t *self, zlistx_destructor_fn destructor); - -// Set a user\-defined duplicator for list items; by default items are not -// copied when the list is duplicated\&. -CZMQ_EXPORT void - zlistx_set_duplicator (zlistx_t *self, zlistx_duplicator_fn duplicator); - -// Set a user\-defined comparator for zlistx_find and zlistx_sort; the method -// must return \-1, 0, or 1 depending on whether item1 is less than, equal to, -// or greater than, item2\&. -CZMQ_EXPORT void - zlistx_set_comparator (zlistx_t *self, zlistx_comparator_fn comparator); - -// Self test of this class\&. -CZMQ_EXPORT void - zlistx_test (bool verbose); - -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zlistx\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -Provides a generic doubly\-linked list container\&. This container provides hooks for duplicator, comparator, and destructor functions\&. These tie into CZMQ and standard C semantics, so e\&.g\&. for string items you can use strdup, strcmp, and zstr_free\&. To store custom objects, define your own duplicator and comparator, and use the standard object destructor\&. -.sp -This is a reworking of the simpler zlist container\&. It is faster to insert and delete items anywhere in the list, and to keep ordered lists\&. -.SH "EXAMPLE" -.PP -\fBFrom zlistx_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zlistx_t *list = zlistx_new (); -assert (list); -assert (zlistx_size (list) == 0); - -// Test operations on an empty list -assert (zlistx_first (list) == NULL); -assert (zlistx_last (list) == NULL); -assert (zlistx_next (list) == NULL); -assert (zlistx_prev (list) == NULL); -assert (zlistx_find (list, "hello") == NULL); -assert (zlistx_delete (list, NULL) == \-1); -assert (zlistx_detach (list, NULL) == NULL); -assert (zlistx_delete (list, NULL) == \-1); -assert (zlistx_detach (list, NULL) == NULL); -zlistx_purge (list); -zlistx_sort (list); - -// Use item handlers -zlistx_set_destructor (list, (zlistx_destructor_fn *) zstr_free); -zlistx_set_duplicator (list, (zlistx_duplicator_fn *) strdup); -zlistx_set_comparator (list, (zlistx_comparator_fn *) strcmp); - -// Try simple insert/sort/delete/next -assert (zlistx_next (list) == NULL); -zlistx_add_end (list, "world"); -assert (streq ((char *) zlistx_next (list), "world")); -zlistx_add_end (list, "hello"); -assert (streq ((char *) zlistx_prev (list), "hello")); -zlistx_sort (list); -assert (zlistx_size (list) == 2); -void *handle = zlistx_find (list, "hello"); -char *item1 = (char *) zlistx_item (list); -char *item2 = (char *) zlistx_handle_item (handle); -assert (item1 == item2); -assert (streq (item1, "hello")); -zlistx_delete (list, handle); -assert (zlistx_size (list) == 1); -char *string = (char *) zlistx_detach (list, NULL); -assert (streq (string, "world")); -free (string); -assert (zlistx_size (list) == 0); - -// Check next/back work -// Now populate the list with items -zlistx_add_start (list, "five"); -zlistx_add_end (list, "six"); -zlistx_add_start (list, "four"); -zlistx_add_end (list, "seven"); -zlistx_add_start (list, "three"); -zlistx_add_end (list, "eight"); -zlistx_add_start (list, "two"); -zlistx_add_end (list, "nine"); -zlistx_add_start (list, "one"); -zlistx_add_end (list, "ten"); - -// Test our navigation skills -assert (zlistx_size (list) == 10); -assert (streq ((char *) zlistx_last (list), "ten")); -assert (streq ((char *) zlistx_prev (list), "nine")); -assert (streq ((char *) zlistx_prev (list), "eight")); -assert (streq ((char *) zlistx_prev (list), "seven")); -assert (streq ((char *) zlistx_prev (list), "six")); -assert (streq ((char *) zlistx_prev (list), "five")); -assert (streq ((char *) zlistx_first (list), "one")); -assert (streq ((char *) zlistx_next (list), "two")); -assert (streq ((char *) zlistx_next (list), "three")); -assert (streq ((char *) zlistx_next (list), "four")); - -// Sort by alphabetical order -zlistx_sort (list); -assert (streq ((char *) zlistx_first (list), "eight")); -assert (streq ((char *) zlistx_last (list), "two")); - -// Moving items around -handle = zlistx_find (list, "six"); -zlistx_move_start (list, handle); -assert (streq ((char *) zlistx_first (list), "six")); -zlistx_move_end (list, handle); -assert (streq ((char *) zlistx_last (list), "six")); -zlistx_sort (list); -assert (streq ((char *) zlistx_last (list), "two")); - -// Copying a list -zlistx_t *copy = zlistx_dup (list); -assert (copy); -assert (zlistx_size (copy) == 10); -assert (streq ((char *) zlistx_first (copy), "eight")); -assert (streq ((char *) zlistx_last (copy), "two")); -zlistx_destroy (©); - -// Delete items while iterating -string = (char *) zlistx_first (list); -assert (streq (string, "eight")); -string = (char *) zlistx_next (list); -assert (streq (string, "five")); -zlistx_delete (list, zlistx_cursor (list)); -string = (char *) zlistx_next (list); -assert (streq (string, "four")); - -zlistx_purge (list); -zlistx_destroy (&list); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zloop.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zloop.3 deleted file mode 100644 index 7d5c84949f542e..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zloop.3 +++ /dev/null @@ -1,261 +0,0 @@ -'\" t -.\" Title: zloop -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZLOOP" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zloop \- event\-driven reactor -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// Callback function for reactor socket activity -typedef int (zloop_reader_fn) ( - zloop_t *loop, zsock_t *reader, void *arg); - -// Callback function for reactor events (low\-level) -typedef int (zloop_fn) ( - zloop_t *loop, zmq_pollitem_t *item, void *arg); - -// Callback for reactor timer events -typedef int (zloop_timer_fn) ( - zloop_t *loop, int timer_id, void *arg); - -// Create a new zloop reactor -CZMQ_EXPORT zloop_t * - zloop_new (void); - -// Destroy a reactor -CZMQ_EXPORT void - zloop_destroy (zloop_t **self_p); - -// Register socket reader with the reactor\&. When the reader has messages, -// the reactor will call the handler, passing the arg\&. Returns 0 if OK, \-1 -// if there was an error\&. If you register the same socket more than once, -// each instance will invoke its corresponding handler\&. -CZMQ_EXPORT int - zloop_reader (zloop_t *self, zsock_t *sock, zloop_reader_fn handler, void *arg); - -// Cancel a socket reader from the reactor\&. If multiple readers exist for -// same socket, cancels ALL of them\&. -CZMQ_EXPORT void - zloop_reader_end (zloop_t *self, zsock_t *sock); - -// Configure a registered reader to ignore errors\&. If you do not set this, -// then readers that have errors are removed from the reactor silently\&. -CZMQ_EXPORT void - zloop_reader_set_tolerant (zloop_t *self, zsock_t *sock); - -// Register low\-level libzmq pollitem with the reactor\&. When the pollitem -// is ready, will call the handler, passing the arg\&. Returns 0 if OK, \-1 -// if there was an error\&. If you register the pollitem more than once, each -// instance will invoke its corresponding handler\&. A pollitem with -// socket=NULL and fd=0 means \*(Aqpoll on FD zero\*(Aq\&. -CZMQ_EXPORT int - zloop_poller (zloop_t *self, zmq_pollitem_t *item, zloop_fn handler, void *arg); - -// Cancel a pollitem from the reactor, specified by socket or FD\&. If both -// are specified, uses only socket\&. If multiple poll items exist for same -// socket/FD, cancels ALL of them\&. -CZMQ_EXPORT void - zloop_poller_end (zloop_t *self, zmq_pollitem_t *item); - -// Configure a registered poller to ignore errors\&. If you do not set this, -// then poller that have errors are removed from the reactor silently\&. -CZMQ_EXPORT void - zloop_poller_set_tolerant (zloop_t *self, zmq_pollitem_t *item); - -// Register a timer that expires after some delay and repeats some number of -// times\&. At each expiry, will call the handler, passing the arg\&. To run a -// timer forever, use 0 times\&. Returns a timer_id that is used to cancel the -// timer in the future\&. Returns \-1 if there was an error\&. -CZMQ_EXPORT int - zloop_timer (zloop_t *self, size_t delay, size_t times, zloop_timer_fn handler, void *arg); - -// Cancel a specific timer identified by a specific timer_id (as returned by -// zloop_timer)\&. -CZMQ_EXPORT int - zloop_timer_end (zloop_t *self, int timer_id); - -// Register a ticket timer\&. Ticket timers are very fast in the case where -// you use a lot of timers (thousands), and frequently remove and add them\&. -// The main use case is expiry timers for servers that handle many clients, -// and which reset the expiry timer for each message received from a client\&. -// Whereas normal timers perform poorly as the number of clients grows, the -// cost of ticket timers is constant, no matter the number of clients\&. You -// must set the ticket delay using zloop_set_ticket_delay before creating a -// ticket\&. Returns a handle to the timer that you should use in -// zloop_ticket_reset and zloop_ticket_delete\&. -CZMQ_EXPORT void * - zloop_ticket (zloop_t *self, zloop_timer_fn handler, void *arg); - -// Reset a ticket timer, which moves it to the end of the ticket list and -// resets its execution time\&. This is a very fast operation\&. -CZMQ_EXPORT void - zloop_ticket_reset (zloop_t *self, void *handle); - -// Delete a ticket timer\&. We do not actually delete the ticket here, as -// other code may still refer to the ticket\&. We mark as deleted, and remove -// later and safely\&. -CZMQ_EXPORT void - zloop_ticket_delete (zloop_t *self, void *handle); - -// Set the ticket delay, which applies to all tickets\&. If you lower the -// delay and there are already tickets created, the results are undefined\&. -CZMQ_EXPORT void - zloop_set_ticket_delay (zloop_t *self, size_t ticket_delay); - -// Set hard limit on number of timers allowed\&. Setting more than a small -// number of timers (10\-100) can have a dramatic impact on the performance -// of the reactor\&. For high\-volume cases, use ticket timers\&. If the hard -// limit is reached, the reactor stops creating new timers and logs an -// error\&. -CZMQ_EXPORT void - zloop_set_max_timers (zloop_t *self, size_t max_timers); - -// Set verbose tracing of reactor on/off\&. The default verbose setting is -// off (false)\&. -CZMQ_EXPORT void - zloop_set_verbose (zloop_t *self, bool verbose); - -// By default the reactor stops if the process receives a SIGINT or SIGTERM -// signal\&. This makes it impossible to shut\-down message based architectures -// like zactors\&. This method lets you switch off break handling\&. The default -// nonstop setting is off (false)\&. -CZMQ_EXPORT void - zloop_set_nonstop (zloop_t *self, bool nonstop); - -// Start the reactor\&. Takes control of the thread and returns when the 0MQ -// context is terminated or the process is interrupted, or any event handler -// returns \-1\&. Event handlers may register new sockets and timers, and -// cancel sockets\&. Returns 0 if interrupted, \-1 if canceled by a handler\&. -CZMQ_EXPORT int - zloop_start (zloop_t *self); - -// Self test of this class\&. -CZMQ_EXPORT void - zloop_test (bool verbose); - -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zloop\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zloop class provides an event\-driven reactor pattern\&. The reactor handles zmq_pollitem_t items (pollers or writers, sockets or fds), and once\-off or repeated timers\&. Its resolution is 1 msec\&. It uses a tickless timer to reduce CPU interrupts in inactive processes\&. -.sp -Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zloop\&.c\fR\&. -.SH "EXAMPLE" -.PP -\fBFrom zloop_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Create two PAIR sockets and connect over inproc -zsock_t *output = zsock_new (ZMQ_PAIR); -assert (output); -zsock_bind (output, "inproc://zloop\&.test"); - -zsock_t *input = zsock_new (ZMQ_PAIR); -assert (input); -zsock_connect (input, "inproc://zloop\&.test"); - -zloop_t *loop = zloop_new (); -assert (loop); -zloop_set_verbose (loop, verbose); - -// Create a timer that will be cancelled -int timer_id = zloop_timer (loop, 1000, 1, s_timer_event, NULL); -zloop_timer (loop, 5, 1, s_cancel_timer_event, &timer_id); - -// After 20 msecs, send a ping message to output3 -zloop_timer (loop, 20, 1, s_timer_event, output); - -// Set up some tickets that will never expire -zloop_set_ticket_delay (loop, 10000); -void *ticket1 = zloop_ticket (loop, s_timer_event, NULL); -void *ticket2 = zloop_ticket (loop, s_timer_event, NULL); -void *ticket3 = zloop_ticket (loop, s_timer_event, NULL); - -// When we get the ping message, end the reactor -rc = zloop_reader (loop, input, s_socket_event, NULL); -assert (rc == 0); -zloop_reader_set_tolerant (loop, input); -zloop_start (loop); - -zloop_ticket_delete (loop, ticket1); -zloop_ticket_delete (loop, ticket2); -zloop_ticket_delete (loop, ticket3); - -// Check whether loop properly ignores zsys_interrupted flag -// when asked to -zloop_destroy (&loop); -loop = zloop_new (); - -bool timer_event_called = false; -zloop_timer (loop, 1, 1, s_timer_event3, &timer_event_called); - -zsys_interrupted = 1; -zloop_start (loop); -// zloop returns immediately without giving any handler a chance to run -assert (!timer_event_called); - -zloop_set_nonstop (loop, true); -zloop_start (loop); -// zloop runs the handler which will terminate the loop -assert (timer_event_called); -zsys_interrupted = 0; - -// cleanup -zloop_destroy (&loop); -assert (loop == NULL); - -zsock_destroy (&input); -zsock_destroy (&output); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmonitor.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmonitor.3 deleted file mode 100644 index 8d716863d4544c..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmonitor.3 +++ /dev/null @@ -1,157 +0,0 @@ -'\" t -.\" Title: zmonitor -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZMONITOR" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmonitor \- socket event monitor -.SH "SYNOPSIS" -.sp -.nf -// Create new zmonitor actor instance to monitor a zsock_t socket: -// -// zactor_t *monitor = zactor_new (zmonitor, mysocket); -// -// Destroy zmonitor instance\&. -// -// zactor_destroy (&monitor); -// -// Enable verbose logging of commands and activity\&. -// -// zstr_send (monitor, "VERBOSE"); -// -// Listen to monitor event type (zero or types, ending in NULL): -// zstr_sendx (monitor, "LISTEN", type, \&.\&.\&., NULL); -// -// Events: -// CONNECTED -// CONNECT_DELAYED -// CONNECT_RETRIED -// LISTENING -// BIND_FAILED -// ACCEPTED -// ACCEPT_FAILED -// CLOSED -// CLOSE_FAILED -// DISCONNECTED -// MONITOR_STOPPED -// ALL -// -// Start monitor; after this, any further LISTEN commands are ignored\&. -// -// zstr_send (monitor, "START"); -// zsock_wait (monitor); -// -// Receive next monitor event: -// -// zmsg_t *msg = zmsg_recv (monitor); -// -// This is the zmonitor constructor as a zactor_fn; the argument can be -// a zactor_t, zsock_t, or libzmq void * socket: -CZMQ_EXPORT void - zmonitor (zsock_t *pipe, void *sock); - -// Selftest -CZMQ_EXPORT void - zmonitor_test (bool verbose); -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zmonitor\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zmonitor actor provides an API for obtaining socket events such as connected, listen, disconnected, etc\&. Socket events are only available for sockets connecting or bound to ipc:// and tcp:// endpoints\&. -.sp -This class wraps the ZMQ socket monitor API, see zmq_socket_monitor for details\&. Works on all versions of libzmq from 3\&.2 onwards\&. This class replaces zproxy_v2, and is meant for applications that use the CZMQ v3 API (meaning, zsock)\&. -.SH "EXAMPLE" -.PP -\fBFrom zmonitor_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zsock_t *client = zsock_new (ZMQ_DEALER); -assert (client); -zactor_t *clientmon = zactor_new (zmonitor, client); -assert (clientmon); -if (verbose) - zstr_sendx (clientmon, "VERBOSE", NULL); -zstr_sendx (clientmon, "LISTEN", "LISTENING", "ACCEPTED", NULL); -zstr_sendx (clientmon, "START", NULL); -zsock_wait (clientmon); - -zsock_t *server = zsock_new (ZMQ_DEALER); -assert (server); -zactor_t *servermon = zactor_new (zmonitor, server); -assert (servermon); -if (verbose) - zstr_sendx (servermon, "VERBOSE", NULL); -zstr_sendx (servermon, "LISTEN", "CONNECTED", "DISCONNECTED", NULL); -zstr_sendx (servermon, "START", NULL); -zsock_wait (servermon); - -// Allow a brief time for the message to get there\&.\&.\&. -zmq_poll (NULL, 0, 200); - -// Check client is now listening -int port_nbr = zsock_bind (client, "tcp://127\&.0\&.0\&.1:*"); -assert (port_nbr != \-1); -s_assert_event (clientmon, "LISTENING"); - -// Check server connected to client -zsock_connect (server, "tcp://127\&.0\&.0\&.1:%d", port_nbr); -s_assert_event (servermon, "CONNECTED"); - -// Check client accepted connection -s_assert_event (clientmon, "ACCEPTED"); - -zactor_destroy (&clientmon); -zactor_destroy (&servermon); -zsock_destroy (&client); -zsock_destroy (&server); -#endif -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_dec.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_dec.3 deleted file mode 100644 index 40fde8be8d9bfb..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_dec.3 +++ /dev/null @@ -1,73 +0,0 @@ -'\" t -.\" Title: zmq_atomic_counter_dec -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_ATOMIC_COUNTER_D" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_atomic_counter_dec \- decrement an atomic counter -.SH "SYNOPSIS" -.sp -\fBint zmq_atomic_counter_dec (void *counter);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_atomic_counter_dec\fR function decrements an atomic counter in a threadsafe fashion\&. This function uses platform specific atomic operations\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_atomic_counter_dec()\fR function returns 1 if the counter is greater than zero after decrementing, or zero if the counter reached zero\&. -.SH "EXAMPLE" -.PP -\fBTest code for atomic counters\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -void *counter = zmq_atomic_counter_new (); -assert (zmq_atomic_counter_value (counter) == 0); -assert (zmq_atomic_counter_inc (counter) == 0); -assert (zmq_atomic_counter_inc (counter) == 1); -assert (zmq_atomic_counter_inc (counter) == 2); -assert (zmq_atomic_counter_value (counter) == 3); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 0); -zmq_atomic_counter_set (counter, 2); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 0); -zmq_atomic_counter_destroy (&counter); -return 0; -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_atomic_counter_new\fR(3) \fBzmq_atomic_counter_set\fR(3) \fBzmq_atomic_counter_inc\fR(3) \fBzmq_atomic_counter_value\fR(3) \fBzmq_atomic_counter_destroy\fR(3) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_destroy.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_destroy.3 deleted file mode 100644 index b37bd42407a586..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_destroy.3 +++ /dev/null @@ -1,73 +0,0 @@ -'\" t -.\" Title: zmq_atomic_counter_destroy -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_ATOMIC_COUNTER_D" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_atomic_counter_destroy \- destroy an atomic counter -.SH "SYNOPSIS" -.sp -\fBvoid zmq_atomic_counter_destroy (void **counter_p);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_atomic_counter_destroy\fR function destroys an atomic counter and nullifies its reference\&. Pass the address of an atomic counter (void **) rather than the counter itself\&. You must destroy all counters that you create, to avoid memory leakage\&. This function uses platform specific atomic operations\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_atomic_counter_destroy()\fR function has no return value\&. -.SH "EXAMPLE" -.PP -\fBTest code for atomic counters\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -void *counter = zmq_atomic_counter_new (); -assert (zmq_atomic_counter_value (counter) == 0); -assert (zmq_atomic_counter_inc (counter) == 0); -assert (zmq_atomic_counter_inc (counter) == 1); -assert (zmq_atomic_counter_inc (counter) == 2); -assert (zmq_atomic_counter_value (counter) == 3); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 0); -zmq_atomic_counter_set (counter, 2); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 0); -zmq_atomic_counter_destroy (&counter); -return 0; -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_atomic_counter_new\fR(3) \fBzmq_atomic_counter_set\fR(3) \fBzmq_atomic_counter_inc\fR(3) \fBzmq_atomic_counter_dec\fR(3) \fBzmq_atomic_counter_value\fR(3) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_inc.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_inc.3 deleted file mode 100644 index 8d7064f9ccd5b6..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_inc.3 +++ /dev/null @@ -1,73 +0,0 @@ -'\" t -.\" Title: zmq_atomic_counter_inc -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_ATOMIC_COUNTER_I" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_atomic_counter_inc \- increment an atomic counter -.SH "SYNOPSIS" -.sp -\fBint zmq_atomic_counter_inc (void *counter);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_atomic_counter_inc\fR function increments an atomic counter in a threadsafe fashion\&. This function uses platform specific atomic operations\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_atomic_counter_inc()\fR function returns the old value of the counter, before incrementing\&. -.SH "EXAMPLE" -.PP -\fBTest code for atomic counters\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -void *counter = zmq_atomic_counter_new (); -assert (zmq_atomic_counter_value (counter) == 0); -assert (zmq_atomic_counter_inc (counter) == 0); -assert (zmq_atomic_counter_inc (counter) == 1); -assert (zmq_atomic_counter_inc (counter) == 2); -assert (zmq_atomic_counter_value (counter) == 3); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 0); -zmq_atomic_counter_set (counter, 2); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 0); -zmq_atomic_counter_destroy (&counter); -return 0; -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_atomic_counter_new\fR(3) \fBzmq_atomic_counter_set\fR(3) \fBzmq_atomic_counter_dec\fR(3) \fBzmq_atomic_counter_value\fR(3) \fBzmq_atomic_counter_destroy\fR(3) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_new.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_new.3 deleted file mode 100644 index 124130917b0936..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_new.3 +++ /dev/null @@ -1,73 +0,0 @@ -'\" t -.\" Title: zmq_atomic_counter_new -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_ATOMIC_COUNTER_N" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_atomic_counter_new \- create a new atomic counter -.SH "SYNOPSIS" -.sp -\fBvoid *zmq_atomic_counter_new (void);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_atomic_counter_new\fR function creates a new atomic counter\&. You can use this in multithreaded applications to do, for example, reference counting of shared objects\&. The atomic counter is at least 32 bits large\&. This function uses platform specific atomic operations\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_atomic_counter_new()\fR function returns the new atomic counter if successful\&. Otherwise it returns NULL\&. -.SH "EXAMPLE" -.PP -\fBTest code for atomic counters\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -void *counter = zmq_atomic_counter_new (); -assert (zmq_atomic_counter_value (counter) == 0); -assert (zmq_atomic_counter_inc (counter) == 0); -assert (zmq_atomic_counter_inc (counter) == 1); -assert (zmq_atomic_counter_inc (counter) == 2); -assert (zmq_atomic_counter_value (counter) == 3); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 0); -zmq_atomic_counter_set (counter, 2); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 0); -zmq_atomic_counter_destroy (&counter); -return 0; -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_atomic_counter_set\fR(3) \fBzmq_atomic_counter_inc\fR(3) \fBzmq_atomic_counter_dec\fR(3) \fBzmq_atomic_counter_value\fR(3) \fBzmq_atomic_counter_destroy\fR(3) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_set.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_set.3 deleted file mode 100644 index 5cdac995d6ceec..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_set.3 +++ /dev/null @@ -1,73 +0,0 @@ -'\" t -.\" Title: zmq_atomic_counter_set -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_ATOMIC_COUNTER_S" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_atomic_counter_set \- set atomic counter to new value -.SH "SYNOPSIS" -.sp -\fBvoid zmq_atomic_counter_set (void *counter, int value);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_atomic_counter_set\fR function sets the counter to a new value, in a threadsafe fashion\&. The largest value that is guaranteed to work across all platforms is 2^31\-1\&. This function uses platform specific atomic operations\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_atomic_counter_set()\fR function has no return value\&. -.SH "EXAMPLE" -.PP -\fBTest code for atomic counters\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -void *counter = zmq_atomic_counter_new (); -assert (zmq_atomic_counter_value (counter) == 0); -assert (zmq_atomic_counter_inc (counter) == 0); -assert (zmq_atomic_counter_inc (counter) == 1); -assert (zmq_atomic_counter_inc (counter) == 2); -assert (zmq_atomic_counter_value (counter) == 3); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 0); -zmq_atomic_counter_set (counter, 2); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 0); -zmq_atomic_counter_destroy (&counter); -return 0; -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_atomic_counter_new\fR(3) \fBzmq_atomic_counter_inc\fR(3) \fBzmq_atomic_counter_dec\fR(3) \fBzmq_atomic_counter_value\fR(3) \fBzmq_atomic_counter_destroy\fR(3) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_value.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_value.3 deleted file mode 100644 index f62f8b4714758e..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_atomic_counter_value.3 +++ /dev/null @@ -1,73 +0,0 @@ -'\" t -.\" Title: zmq_atomic_counter_value -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_ATOMIC_COUNTER_V" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_atomic_counter_value \- return value of atomic counter -.SH "SYNOPSIS" -.sp -\fBint zmq_atomic_counter_value (void *counter);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_atomic_counter_value\fR function returns the value of an atomic counter\&. This function uses platform specific atomic operations\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_atomic_counter_value()\fR function returns the new atomic counter if successful\&. Otherwise it returns NULL\&. -.SH "EXAMPLE" -.PP -\fBTest code for atomic counters\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -void *counter = zmq_atomic_counter_new (); -assert (zmq_atomic_counter_value (counter) == 0); -assert (zmq_atomic_counter_inc (counter) == 0); -assert (zmq_atomic_counter_inc (counter) == 1); -assert (zmq_atomic_counter_inc (counter) == 2); -assert (zmq_atomic_counter_value (counter) == 3); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 0); -zmq_atomic_counter_set (counter, 2); -assert (zmq_atomic_counter_dec (counter) == 1); -assert (zmq_atomic_counter_dec (counter) == 0); -zmq_atomic_counter_destroy (&counter); -return 0; -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_atomic_counter_new\fR(3) \fBzmq_atomic_counter_set\fR(3) \fBzmq_atomic_counter_inc\fR(3) \fBzmq_atomic_counter_dec\fR(3) \fBzmq_atomic_counter_destroy\fR(3) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_bind.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_bind.3 deleted file mode 100644 index 472961186563c6..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_bind.3 +++ /dev/null @@ -1,200 +0,0 @@ -'\" t -.\" Title: zmq_bind -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_BIND" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_bind \- accept incoming connections on a socket -.SH "SYNOPSIS" -.sp -\fBint zmq_bind (void \fR\fB\fI*socket\fR\fR\fB, const char \fR\fB\fI*endpoint\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_bind()\fR function binds the \fIsocket\fR to a local \fIendpoint\fR and then accepts incoming connections on that endpoint\&. -.sp -The \fIendpoint\fR is a string consisting of a \fItransport\fR:// followed by an \fIaddress\fR\&. The \fItransport\fR specifies the underlying protocol to use\&. The \fIaddress\fR specifies the transport\-specific address to bind to\&. -.sp -0MQ provides the the following transports: -.PP -\fItcp\fR -.RS 4 -unicast transport using TCP, see -\fBzmq_tcp\fR(7) -.RE -.PP -\fIipc\fR -.RS 4 -local inter\-process communication transport, see -\fBzmq_ipc\fR(7) -.RE -.PP -\fIinproc\fR -.RS 4 -local in\-process (inter\-thread) communication transport, see -\fBzmq_inproc\fR(7) -.RE -.PP -\fIpgm\fR, \fIepgm\fR -.RS 4 -reliable multicast transport using PGM, see -\fBzmq_pgm\fR(7) -.RE -.PP -\fIvmci\fR -.RS 4 -virtual machine communications interface (VMCI), see -\fBzmq_vmci\fR(7) -.RE -.sp -Every 0MQ socket type except \fIZMQ_PAIR\fR supports one\-to\-many and many\-to\-one semantics\&. The precise semantics depend on the socket type and are defined in \fBzmq_socket\fR(3)\&. -.sp -The \fIipc\fR, \fItcp\fR and \fIvmci\fR transports accept wildcard addresses: see \fBzmq_ipc\fR(7), \fBzmq_tcp\fR(7) and \fBzmq_vmci\fR(7) for details\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -the address syntax may be different for \fIzmq_bind()\fR and \fIzmq_connect()\fR especially for the \fItcp\fR, \fIpgm\fR and \fIepgm\fR transports\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -following a \fIzmq_bind()\fR, the socket enters a \fImute\fR state unless or until at least one incoming or outgoing connection is made, at which point the socket enters a \fIready\fR state\&. In the mute state, the socket blocks or drops messages according to the socket type, as defined in \fBzmq_socket\fR(3)\&. By contrast, following a libzmq:zmq_connect[3], the socket enters the \fIready\fR state\&. -.sp .5v -.RE -.SH "RETURN VALUE" -.sp -The \fIzmq_bind()\fR function returns zero if successful\&. Otherwise it returns \-1 and sets \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEINVAL\fR -.RS 4 -The endpoint supplied is invalid\&. -.RE -.PP -\fBEPROTONOSUPPORT\fR -.RS 4 -The requested -\fItransport\fR -protocol is not supported\&. -.RE -.PP -\fBENOCOMPATPROTO\fR -.RS 4 -The requested -\fItransport\fR -protocol is not compatible with the socket type\&. -.RE -.PP -\fBEADDRINUSE\fR -.RS 4 -The requested -\fIaddress\fR -is already in use\&. -.RE -.PP -\fBEADDRNOTAVAIL\fR -.RS 4 -The requested -\fIaddress\fR -was not local\&. -.RE -.PP -\fBENODEV\fR -.RS 4 -The requested -\fIaddress\fR -specifies a nonexistent interface\&. -.RE -.PP -\fBETERM\fR -.RS 4 -The 0MQ -\fIcontext\fR -associated with the specified -\fIsocket\fR -was terminated\&. -.RE -.PP -\fBENOTSOCK\fR -.RS 4 -The provided -\fIsocket\fR -was invalid\&. -.RE -.PP -\fBEMTHREAD\fR -.RS 4 -No I/O thread is available to accomplish the task\&. -.RE -.SH "EXAMPLE" -.PP -\fBBinding a publisher socket to an in-process and a TCP transport\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -/* Create a ZMQ_PUB socket */ -void *socket = zmq_socket (context, ZMQ_PUB); -assert (socket); -/* Bind it to a in\-process transport with the address \*(Aqmy_publisher\*(Aq */ -int rc = zmq_bind (socket, "inproc://my_publisher"); -assert (rc == 0); -/* Bind it to a TCP transport on port 5555 of the \*(Aqeth0\*(Aq interface */ -rc = zmq_bind (socket, "tcp://eth0:5555"); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_connect\fR(3) \fBzmq_socket\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_close.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_close.3 deleted file mode 100644 index f3b45dc49e8cbf..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_close.3 +++ /dev/null @@ -1,70 +0,0 @@ -'\" t -.\" Title: zmq_close -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_CLOSE" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_close \- close 0MQ socket -.SH "SYNOPSIS" -.sp -\fBint zmq_close (void \fR\fB\fI*socket\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_close()\fR function shall destroy the socket referenced by the \fIsocket\fR argument\&. Any outstanding messages physically received from the network but not yet received by the application with \fIzmq_recv()\fR shall be discarded\&. The behaviour for discarding messages sent by the application with \fIzmq_send()\fR but not yet physically transferred to the network depends on the value of the \fIZMQ_LINGER\fR socket option for the specified \fIsocket\fR\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -The default setting of \fIZMQ_LINGER\fR does not discard unsent messages; this behaviour may cause the application to block when calling \fIzmq_ctx_term()\fR\&. For details refer to \fBzmq_setsockopt\fR(3) and \fBzmq_ctx_term\fR(3)\&. -.sp .5v -.RE -.SH "RETURN VALUE" -.sp -The \fIzmq_close()\fR function shall return zero if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBENOTSOCK\fR -.RS 4 -The provided -\fIsocket\fR -was invalid\&. -.RE -.SH "SEE ALSO" -.sp -\fBzmq_socket\fR(3) \fBzmq_ctx_term\fR(3) \fBzmq_setsockopt\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_connect.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_connect.3 deleted file mode 100644 index ba263b85f82616..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_connect.3 +++ /dev/null @@ -1,177 +0,0 @@ -'\" t -.\" Title: zmq_connect -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_CONNECT" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_connect \- create outgoing connection from socket -.SH "SYNOPSIS" -.sp -\fBint zmq_connect (void \fR\fB\fI*socket\fR\fR\fB, const char \fR\fB\fI*endpoint\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_connect()\fR function connects the \fIsocket\fR to an \fIendpoint\fR and then accepts incoming connections on that endpoint\&. -.sp -The \fIendpoint\fR is a string consisting of a \fItransport\fR:// followed by an \fIaddress\fR\&. The \fItransport\fR specifies the underlying protocol to use\&. The \fIaddress\fR specifies the transport\-specific address to connect to\&. -.sp -0MQ provides the the following transports: -.PP -\fItcp\fR -.RS 4 -unicast transport using TCP, see -\fBzmq_tcp\fR(7) -.RE -.PP -\fIipc\fR -.RS 4 -local inter\-process communication transport, see -\fBzmq_ipc\fR(7) -.RE -.PP -\fIinproc\fR -.RS 4 -local in\-process (inter\-thread) communication transport, see -\fBzmq_inproc\fR(7) -.RE -.PP -\fIpgm\fR, \fIepgm\fR -.RS 4 -reliable multicast transport using PGM, see -\fBzmq_pgm\fR(7) -.RE -.PP -\fIvmci\fR -.RS 4 -virtual machine communications interface (VMCI), see -\fBzmq_vmci\fR(7) -.RE -.sp -Every 0MQ socket type except \fIZMQ_PAIR\fR supports one\-to\-many and many\-to\-one semantics\&. The precise semantics depend on the socket type and are defined in \fBzmq_socket\fR(3)\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -for most transports and socket types the connection is not performed immediately but as needed by 0MQ\&. Thus a successful call to \fIzmq_connect()\fR does not mean that the connection was or could actually be established\&. Because of this, for most transports and socket types the order in which a \fIserver\fR socket is bound and a \fIclient\fR socket is connected to it does not matter\&. The first exception is when using the inproc:// transport: you must call \fIzmq_bind()\fR before calling \fIzmq_connect()\fR\&. The second exception are \fIZMQ_PAIR\fR sockets, which do not automatically reconnect to endpoints\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -following a \fIzmq_connect()\fR, for socket types except for ZMQ_ROUTER, the socket enters its normal \fIready\fR state\&. By contrast, following a \fIzmq_bind()\fR alone, the socket enters a \fImute\fR state in which the socket blocks or drops messages according to the socket type, as defined in \fBzmq_socket\fR(3)\&. A ZMQ_ROUTER socket enters its normal \fIready\fR state for a specific peer only when handshaking is complete for that peer, which may take an arbitrary time\&. -.sp .5v -.RE -.SH "RETURN VALUE" -.sp -The \fIzmq_connect()\fR function returns zero if successful\&. Otherwise it returns \-1 and sets \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEINVAL\fR -.RS 4 -The endpoint supplied is invalid\&. -.RE -.PP -\fBEPROTONOSUPPORT\fR -.RS 4 -The requested -\fItransport\fR -protocol is not supported\&. -.RE -.PP -\fBENOCOMPATPROTO\fR -.RS 4 -The requested -\fItransport\fR -protocol is not compatible with the socket type\&. -.RE -.PP -\fBETERM\fR -.RS 4 -The 0MQ -\fIcontext\fR -associated with the specified -\fIsocket\fR -was terminated\&. -.RE -.PP -\fBENOTSOCK\fR -.RS 4 -The provided -\fIsocket\fR -was invalid\&. -.RE -.PP -\fBEMTHREAD\fR -.RS 4 -No I/O thread is available to accomplish the task\&. -.RE -.SH "EXAMPLE" -.PP -\fBConnecting a subscriber socket to an in-process and a TCP transport\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -/* Create a ZMQ_SUB socket */ -void *socket = zmq_socket (context, ZMQ_SUB); -assert (socket); -/* Connect it to an in\-process transport with the address \*(Aqmy_publisher\*(Aq */ -int rc = zmq_connect (socket, "inproc://my_publisher"); -assert (rc == 0); -/* Connect it to the host server001, port 5555 using a TCP transport */ -rc = zmq_connect (socket, "tcp://server001:5555"); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_bind\fR(3) \fBzmq_socket\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_ctx_get.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_ctx_get.3 deleted file mode 100644 index fef5be66499bd1..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_ctx_get.3 +++ /dev/null @@ -1,106 +0,0 @@ -'\" t -.\" Title: zmq_ctx_get -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_CTX_GET" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_ctx_get \- get context options -.SH "SYNOPSIS" -.sp -\fBint zmq_ctx_get (void \fR\fB\fI*context\fR\fR\fB, int \fR\fB\fIoption_name\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_ctx_get()\fR function shall return the option specified by the \fIoption_name\fR argument\&. -.sp -The \fIzmq_ctx_get()\fR function accepts the following option names: -.SS "ZMQ_IO_THREADS: Get number of I/O threads" -.sp -The \fIZMQ_IO_THREADS\fR argument returns the size of the 0MQ thread pool for this context\&. -.SS "ZMQ_MAX_SOCKETS: Get maximum number of sockets" -.sp -The \fIZMQ_MAX_SOCKETS\fR argument returns the maximum number of sockets allowed for this context\&. -.SS "ZMQ_MAX_MSGSZ: Get maximum message size" -.sp -The \fIZMQ_MAX_MSGSZ\fR argument returns the maximum size of a message allowed for this context\&. Default value is INT_MAX\&. -.SS "ZMQ_SOCKET_LIMIT: Get largest configurable number of sockets" -.sp -The \fIZMQ_SOCKET_LIMIT\fR argument returns the largest number of sockets that \fBzmq_ctx_set\fR(3) will accept\&. -.SS "ZMQ_IPV6: Set IPv6 option" -.sp -The \fIZMQ_IPV6\fR argument returns the IPv6 option for the context\&. -.SS "ZMQ_BLOCKY: Get blocky setting" -.sp -The \fIZMQ_BLOCKY\fR argument returns 1 if the context will block on terminate, zero if the "block forever on context termination" gambit was disabled by setting ZMQ_BLOCKY to false on all new contexts\&. -.SS "ZMQ_MSG_T_SIZE: Get the zmq_msg_t size at runtime" -.sp -The \fIZMQ_MSG_T_SIZE\fR argument returns the size of the zmq_msg_t structure at runtime, as defined in the include/zmq\&.h public header\&. This is useful for example for FFI bindings that can\(cqt simply do a sizeof()\&. NOTE: in DRAFT state, not yet available in stable releases\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_ctx_get()\fR function returns a value of 0 or greater if successful\&. Otherwise it returns \-1 and sets \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEINVAL\fR -.RS 4 -The requested option -\fIoption_name\fR -is unknown\&. -.RE -.SH "EXAMPLE" -.PP -\fBSetting a limit on the number of sockets\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -void *context = zmq_ctx_new (); -zmq_ctx_set (context, ZMQ_MAX_SOCKETS, 256); -int max_sockets = zmq_ctx_get (context, ZMQ_MAX_SOCKETS); -assert (max_sockets == 256); -.fi -.if n \{\ -.RE -.\} -.PP -\fBSwitching off the context deadlock gambit\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zmq_ctx_set (ctx, ZMQ_BLOCKY, false); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_ctx_set\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_ctx_new.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_ctx_new.3 deleted file mode 100644 index 23d1af87f73c83..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_ctx_new.3 +++ /dev/null @@ -1,55 +0,0 @@ -'\" t -.\" Title: zmq_ctx_new -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_CTX_NEW" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_ctx_new \- create new 0MQ context -.SH "SYNOPSIS" -.sp -\fBvoid *zmq_ctx_new ();\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_ctx_new()\fR function creates a new 0MQ \fIcontext\fR\&. -.sp -This function replaces the deprecated function \fBzmq_init\fR(3)\&. -.PP -\fBThread safety\fR. A 0MQ -\fIcontext\fR -is thread safe and may be shared among as many application threads as necessary, without any additional locking required on the part of the caller\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_ctx_new()\fR function shall return an opaque handle to the newly created \fIcontext\fR if successful\&. Otherwise it shall return NULL and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.sp -No error values are defined for this function\&. -.SH "SEE ALSO" -.sp -\fBzmq\fR(7) \fBzmq_ctx_set\fR(3) \fBzmq_ctx_get\fR(3) \fBzmq_ctx_term\fR(3) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_ctx_set.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_ctx_set.3 deleted file mode 100644 index b7d3e39cbc9945..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_ctx_set.3 +++ /dev/null @@ -1,186 +0,0 @@ -'\" t -.\" Title: zmq_ctx_set -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_CTX_SET" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_ctx_set \- set context options -.SH "SYNOPSIS" -.sp -\fBint zmq_ctx_set (void \fR\fB\fI*context\fR\fR\fB, int \fR\fB\fIoption_name\fR\fR\fB, int \fR\fB\fIoption_value\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_ctx_set()\fR function shall set the option specified by the \fIoption_name\fR argument to the value of the \fIoption_value\fR argument\&. -.sp -The \fIzmq_ctx_set()\fR function accepts the following options: -.SS "ZMQ_BLOCKY: Fix blocky behavior" -.sp -By default the context will block, forever, on a zmq_ctx_term call\&. The assumption behind this behavior is that abrupt termination will cause message loss\&. Most real applications use some form of handshaking to ensure applications receive termination messages, and then terminate the context with \fIZMQ_LINGER\fR set to zero on all sockets\&. This setting is an easier way to get the same result\&. When \fIZMQ_BLOCKY\fR is set to false, all new sockets are given a linger timeout of zero\&. You must still close all sockets before calling zmq_ctx_term\&. -.TS -tab(:); -lt lt. -T{ -.sp -Default value -T}:T{ -.sp -true (old behavior) -T} -.TE -.sp 1 -.SS "ZMQ_IO_THREADS: Set number of I/O threads" -.sp -The \fIZMQ_IO_THREADS\fR argument specifies the size of the 0MQ thread pool to handle I/O operations\&. If your application is using only the \fIinproc\fR transport for messaging you may set this to zero, otherwise set it to at least one\&. This option only applies before creating any sockets on the context\&. -.TS -tab(:); -lt lt. -T{ -.sp -Default value -T}:T{ -.sp -1 -T} -.TE -.sp 1 -.SS "ZMQ_THREAD_SCHED_POLICY: Set scheduling policy for I/O threads" -.sp -The \fIZMQ_THREAD_SCHED_POLICY\fR argument sets the scheduling policy for internal context\(cqs thread pool\&. This option is not available on windows\&. Supported values for this option can be found in sched\&.h file, or at \m[blue]\fBhttp://man7\&.org/linux/man\-pages/man2/sched_setscheduler\&.2\&.html\fR\m[]\&. This option only applies before creating any sockets on the context\&. -.TS -tab(:); -lt lt. -T{ -.sp -Default value -T}:T{ -.sp -\-1 -T} -.TE -.sp 1 -.SS "ZMQ_THREAD_PRIORITY: Set scheduling priority for I/O threads" -.sp -The \fIZMQ_THREAD_PRIORITY\fR argument sets scheduling priority for internal context\(cqs thread pool\&. This option is not available on windows\&. Supported values for this option depend on chosen scheduling policy\&. Details can be found in sched\&.h file, or at \m[blue]\fBhttp://man7\&.org/linux/man\-pages/man2/sched_setscheduler\&.2\&.html\fR\m[]\&. This option only applies before creating any sockets on the context\&. -.TS -tab(:); -lt lt. -T{ -.sp -Default value -T}:T{ -.sp -\-1 -T} -.TE -.sp 1 -.SS "ZMQ_MAX_MSGSZ: Set maximum message size" -.sp -The \fIZMQ_MAX_MSGSZ\fR argument sets the maximum allowed size of a message sent in the context\&. You can query the maximal allowed value with \fBzmq_ctx_get\fR(3) using the \fIZMQ_MAX_MSGSZ\fR option\&. -.TS -tab(:); -lt lt -lt lt. -T{ -.sp -Default value -T}:T{ -.sp -INT_MAX -T} -T{ -.sp -Maximum value -T}:T{ -.sp -INT_MAX -T} -.TE -.sp 1 -.SS "ZMQ_MAX_SOCKETS: Set maximum number of sockets" -.sp -The \fIZMQ_MAX_SOCKETS\fR argument sets the maximum number of sockets allowed on the context\&. You can query the maximal allowed value with \fBzmq_ctx_get\fR(3) using the \fIZMQ_SOCKET_LIMIT\fR option\&. -.TS -tab(:); -lt lt. -T{ -.sp -Default value -T}:T{ -.sp -1024 -T} -.TE -.sp 1 -.SS "ZMQ_IPV6: Set IPv6 option" -.sp -The \fIZMQ_IPV6\fR argument sets the IPv6 value for all sockets created in the context from this point onwards\&. A value of 1 means IPv6 is enabled, while 0 means the socket will use only IPv4\&. When IPv6 is enabled, a socket will connect to, or accept connections from, both IPv4 and IPv6 hosts\&. -.TS -tab(:); -lt lt. -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -.TE -.sp 1 -.SH "RETURN VALUE" -.sp -The \fIzmq_ctx_set()\fR function returns zero if successful\&. Otherwise it returns \-1 and sets \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEINVAL\fR -.RS 4 -The requested option -\fIoption_name\fR -is unknown\&. -.RE -.SH "EXAMPLE" -.PP -\fBSetting a limit on the number of sockets\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -void *context = zmq_ctx_new (); -zmq_ctx_set (context, ZMQ_MAX_SOCKETS, 256); -int max_sockets = zmq_ctx_get (context, ZMQ_MAX_SOCKETS); -assert (max_sockets == 256); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_ctx_get\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_ctx_shutdown.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_ctx_shutdown.3 deleted file mode 100644 index 1e1d21dea3891f..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_ctx_shutdown.3 +++ /dev/null @@ -1,58 +0,0 @@ -'\" t -.\" Title: zmq_ctx_shutdown -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_CTX_SHUTDOWN" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_ctx_shutdown \- shutdown a 0MQ context -.SH "SYNOPSIS" -.sp -\fBint zmq_ctx_shutdown (void \fR\fB\fI*context\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_ctx_shutdown()\fR function shall shutdown the 0MQ context \fIcontext\fR\&. -.sp -Context shutdown will cause any blocking operations currently in progress on sockets open within \fIcontext\fR to return immediately with an error code of ETERM\&. With the exception of \fIzmq_close()\fR, any further operations on sockets open within \fIcontext\fR shall fail with an error code of ETERM\&. -.sp -This function is optional, client code is still required to call the \fBzmq_ctx_term\fR(3) function to free all resources allocated by zeromq\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_ctx_shutdown()\fR function shall return zero if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEFAULT\fR -.RS 4 -The provided -\fIcontext\fR -was invalid\&. -.RE -.SH "SEE ALSO" -.sp -\fBzmq\fR(7) \fBzmq_init\fR(3) \fBzmq_ctx_term\fR(3) \fBzmq_close\fR(3) \fBzmq_setsockopt\fR(3) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_ctx_term.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_ctx_term.3 deleted file mode 100644 index c7a5700f4e862b..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_ctx_term.3 +++ /dev/null @@ -1,126 +0,0 @@ -'\" t -.\" Title: zmq_ctx_term -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_CTX_TERM" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_ctx_term \- terminate a 0MQ context -.SH "SYNOPSIS" -.sp -\fBint zmq_ctx_term (void \fR\fB\fI*context\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_ctx_term()\fR function shall destroy the 0MQ context \fIcontext\fR\&. -.sp -Context termination is performed in the following steps: -.sp -.RS 4 -.ie n \{\ -\h'-04' 1.\h'+01'\c -.\} -.el \{\ -.sp -1 -.IP " 1." 4.2 -.\} -Any blocking operations currently in progress on sockets open within -\fIcontext\fR -shall return immediately with an error code of ETERM\&. With the exception of -\fIzmq_close()\fR, any further operations on sockets open within -\fIcontext\fR -shall fail with an error code of ETERM\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04' 2.\h'+01'\c -.\} -.el \{\ -.sp -1 -.IP " 2." 4.2 -.\} -After interrupting all blocking calls, -\fIzmq_ctx_term()\fR -shall -\fIblock\fR -until the following conditions are satisfied: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -All sockets open within -\fIcontext\fR -have been closed with -\fIzmq_close()\fR\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -For each socket within -\fIcontext\fR, all messages sent by the application with -\fIzmq_send()\fR -have either been physically transferred to a network peer, or the socket\(cqs linger period set with the -\fIZMQ_LINGER\fR -socket option has expired\&. -.RE -.RE -.sp -For further details regarding socket linger behaviour refer to the \fIZMQ_LINGER\fR option in \fBzmq_setsockopt\fR(3)\&. -.sp -This function replaces the deprecated functions \fBzmq_term\fR(3) and \fBzmq_ctx_destroy\fR(3)\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_ctx_term()\fR function shall return zero if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEFAULT\fR -.RS 4 -The provided -\fIcontext\fR -was invalid\&. -.RE -.PP -\fBEINTR\fR -.RS 4 -Termination was interrupted by a signal\&. It can be restarted if needed\&. -.RE -.SH "SEE ALSO" -.sp -\fBzmq\fR(7) \fBzmq_init\fR(3) \fBzmq_close\fR(3) \fBzmq_setsockopt\fR(3) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_curve_keypair.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_curve_keypair.3 deleted file mode 100644 index 5a58963cff6361..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_curve_keypair.3 +++ /dev/null @@ -1,69 +0,0 @@ -'\" t -.\" Title: zmq_curve_keypair -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_CURVE_KEYPAIR" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_curve_keypair \- generate a new CURVE keypair -.SH "SYNOPSIS" -.sp -\fBint zmq_curve_keypair (char *z85_public_key, char *z85_secret_key);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_curve_keypair()\fR function shall return a newly generated random keypair consisting of a public key and a secret key\&. The caller provides two buffers, each at least 41 octets large, in which this method will store the keys\&. The keys are encoded using \fBzmq_z85_encode\fR(3)\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_curve_keypair()\fR function shall return 0 if successful, else it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBENOTSUP\fR -.RS 4 -The libzmq library was not built with cryptographic support (libsodium)\&. -.RE -.SH "EXAMPLE" -.PP -\fBGenerating a new CURVE keypair\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -char public_key [41]; -char secret_key [41]; -int rc = zmq_curve_keypair (public_key, secret_key); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_z85_decode\fR(3) \fBzmq_z85_encode\fR(3) \fBzmq_curve\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_curve_public.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_curve_public.3 deleted file mode 100644 index f7dceeb5d94d3e..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_curve_public.3 +++ /dev/null @@ -1,73 +0,0 @@ -'\" t -.\" Title: zmq_curve_public -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_CURVE_PUBLIC" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_curve_public \- derive the public key from a private key -.SH "SYNOPSIS" -.sp -\fBint zmq_curve_public (char *z85_public_key, char *z85_secret_key);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_curve_public()\fR function shall derive the public key from a private key\&. The caller provides two buffers, each at least 41 octets large\&. In z85_secret_key the caller shall provide the private key, and the function will store the public key in z85_public_key\&. The keys are encoded using \fBzmq_z85_encode\fR(3)\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_curve_public()\fR function shall return 0 if successful, else it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBENOTSUP\fR -.RS 4 -The libzmq library was not built with cryptographic support (libsodium)\&. -.RE -.SH "EXAMPLE" -.PP -\fBDeriving the public key from a CURVE private key\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -char public_key [41]; -char secret_key [41]; -int rc = zmq_curve_keypair (public_key, secret_key); -assert (rc == 0); -char derived_public[41]; -rc = zmq_curve_public (derived_public, secret_key); -assert (rc == 0); -assert (!strcmp (derived_public, public_key)); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_z85_decode\fR(3) \fBzmq_z85_encode\fR(3) \fBzmq_curve_keypair\fR(3) \fBzmq_curve\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_disconnect.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_disconnect.3 deleted file mode 100644 index ff5075fd31f794..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_disconnect.3 +++ /dev/null @@ -1,113 +0,0 @@ -'\" t -.\" Title: zmq_disconnect -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_DISCONNECT" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_disconnect \- Disconnect a socket -.SH "SYNOPSIS" -.sp -\fBint zmq_disconnect (void \fR\fB\fI*socket\fR\fR\fB, const char \fR\fB\fI*endpoint\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_disconnect()\fR function shall disconnect a socket specified by the \fIsocket\fR argument from the endpoint specified by the \fIendpoint\fR argument\&. Any outstanding messages physically received from the network but not yet received by the application with \fIzmq_recv()\fR shall be discarded\&. The behaviour for discarding messages sent by the application with \fIzmq_send()\fR but not yet physically transferred to the network depends on the value of the \fIZMQ_LINGER\fR socket option for the specified \fIsocket\fR\&. -.sp -The \fIendpoint\fR argument is as described in \fBzmq_connect\fR(3) -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -The default setting of \fIZMQ_LINGER\fR does not discard unsent messages; this behaviour may cause the application to block when calling \fIzmq_ctx_term()\fR\&. For details refer to \fBzmq_setsockopt\fR(3) and \fBzmq_ctx_term\fR(3)\&. -.sp .5v -.RE -.SH "RETURN VALUE" -.sp -The \fIzmq_disconnect()\fR function shall return zero if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEINVAL\fR -.RS 4 -The endpoint supplied is invalid\&. -.RE -.PP -\fBETERM\fR -.RS 4 -The 0MQ -\fIcontext\fR -associated with the specified -\fIsocket\fR -was terminated\&. -.RE -.PP -\fBENOTSOCK\fR -.RS 4 -The provided -\fIsocket\fR -was invalid\&. -.RE -.PP -\fBENOENT\fR -.RS 4 -The provided endpoint is not connected\&. -.RE -.SH "EXAMPLE" -.PP -\fBConnecting a subscriber socket to an in-process and a TCP transport\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -/* Create a ZMQ_SUB socket */ -void *socket = zmq_socket (context, ZMQ_SUB); -assert (socket); -/* Connect it to the host server001, port 5555 using a TCP transport */ -rc = zmq_connect (socket, "tcp://server001:5555"); -assert (rc == 0); -/* Disconnect from the previously connected endpoint */ -rc = zmq_disconnect (socket, "tcp://server001:5555"); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_connect\fR(3) \fBzmq_socket\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_errno.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_errno.3 deleted file mode 100644 index b7cb977fd1906e..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_errno.3 +++ /dev/null @@ -1,67 +0,0 @@ -'\" t -.\" Title: zmq_errno -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_ERRNO" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_errno \- retrieve value of errno for the calling thread -.SH "SYNOPSIS" -.sp -\fBint zmq_errno (void);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_errno()\fR function shall retrieve the value of the \fIerrno\fR variable for the calling thread\&. -.sp -The \fIzmq_errno()\fR function is provided to assist users on non\-POSIX systems who are experiencing issues with retrieving the correct value of \fIerrno\fR directly\&. Specifically, users on Win32 systems whose application is using a different C run\-time library from the C run\-time library in use by 0MQ will need to use \fIzmq_errno()\fR for correct operation\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBImportant\fR -.ps -1 -.br -.sp -Users not experiencing issues with retrieving the correct value of \fIerrno\fR should not use this function and should instead access the \fIerrno\fR variable directly\&. -.sp .5v -.RE -.SH "RETURN VALUE" -.sp -The \fIzmq_errno()\fR function shall return the value of the \fIerrno\fR variable for the calling thread\&. -.SH "ERRORS" -.sp -No errors are defined\&. -.SH "SEE ALSO" -.sp -\fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_getsockopt.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_getsockopt.3 deleted file mode 100644 index 7a51c1e6788c02..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_getsockopt.3 +++ /dev/null @@ -1,2298 +0,0 @@ -'\" t -.\" Title: zmq_getsockopt -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_GETSOCKOPT" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_getsockopt \- get 0MQ socket options -.SH "SYNOPSIS" -.sp -\fBint zmq_getsockopt (void \fR\fB\fI*socket\fR\fR\fB, int \fR\fB\fIoption_name\fR\fR\fB, void \fR\fB\fI*option_value\fR\fR\fB, size_t \fR\fB\fI*option_len\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_getsockopt()\fR function shall retrieve the value for the option specified by the \fIoption_name\fR argument for the 0MQ socket pointed to by the \fIsocket\fR argument, and store it in the buffer pointed to by the \fIoption_value\fR argument\&. The \fIoption_len\fR argument is the size in bytes of the buffer pointed to by \fIoption_value\fR; upon successful completion \fIzmq_getsockopt()\fR shall modify the \fIoption_len\fR argument to indicate the actual size of the option value stored in the buffer\&. -.sp -The following options can be retrieved with the \fIzmq_getsockopt()\fR function: -.SS "ZMQ_AFFINITY: Retrieve I/O thread affinity" -.sp -The \fIZMQ_AFFINITY\fR option shall retrieve the I/O thread affinity for newly created connections on the specified \fIsocket\fR\&. -.sp -Affinity determines which threads from the 0MQ I/O thread pool associated with the socket\(cqs \fIcontext\fR shall handle newly created connections\&. A value of zero specifies no affinity, meaning that work shall be distributed fairly among all 0MQ I/O threads in the thread pool\&. For non\-zero values, the lowest bit corresponds to thread 1, second lowest bit to thread 2 and so on\&. For example, a value of 3 specifies that subsequent connections on \fIsocket\fR shall be handled exclusively by I/O threads 1 and 2\&. -.sp -See also \fBzmq_init\fR(3) for details on allocating the number of I/O threads for a specific \fIcontext\fR\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -uint64_t -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A (bitmap) -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -N/A -T} -.TE -.sp 1 -.SS "ZMQ_BACKLOG: Retrieve maximum length of the queue of outstanding connections" -.sp -The \fIZMQ_BACKLOG\fR option shall retrieve the maximum length of the queue of outstanding peer connections for the specified \fIsocket\fR; this only applies to connection\-oriented transports\&. For details refer to your operating system documentation for the \fIlisten\fR function\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -connections -T} -T{ -.sp -Default value -T}:T{ -.sp -100 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, only for connection\-oriented transports -T} -.TE -.sp 1 -.SS "ZMQ_CONNECT_TIMEOUT: Retrieve connect() timeout" -.sp -Retrieves how long to wait before timing\-out a connect() system call\&. The connect() system call normally takes a long time before it returns a time out error\&. Setting this option allows the library to time out the call at an earlier interval\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -0 (disabled) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_CURVE_PUBLICKEY: Retrieve current CURVE public key" -.sp -Retrieves the current long term public key for the socket\&. You can provide either a 32 byte buffer, to retrieve the binary key value, or a 41 byte buffer, to retrieve the key in a printable Z85 format\&. NOTE: to fetch a printable key, the buffer must be 41 bytes large to hold the 40\-char key value and one null byte\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -binary data or Z85 text string -T} -T{ -.sp -Option value size -T}:T{ -.sp -32 or 41 -T} -T{ -.sp -Default value -T}:T{ -.sp -null -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_CURVE_SECRETKEY: Retrieve current CURVE secret key" -.sp -Retrieves the current long term secret key for the socket\&. You can provide either a 32 byte buffer, to retrieve the binary key value, or a 41 byte buffer, to retrieve the key in a printable Z85 format\&. NOTE: to fetch a printable key, the buffer must be 41 bytes large to hold the 40\-char key value and one null byte\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -binary data or Z85 text string -T} -T{ -.sp -Option value size -T}:T{ -.sp -32 or 41 -T} -T{ -.sp -Default value -T}:T{ -.sp -null -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_CURVE_SERVERKEY: Retrieve current CURVE server key" -.sp -Retrieves the current server key for the client socket\&. You can provide either a 32 byte buffer, to retrieve the binary key value, or a 41\-byte buffer, to retrieve the key in a printable Z85 format\&. NOTE: to fetch a printable key, the buffer must be 41 bytes large to hold the 40\-char key value and one null byte\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -binary data or Z85 text string -T} -T{ -.sp -Option value size -T}:T{ -.sp -32 or 41 -T} -T{ -.sp -Default value -T}:T{ -.sp -null -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_EVENTS: Retrieve socket event state" -.sp -The \fIZMQ_EVENTS\fR option shall retrieve the event state for the specified \fIsocket\fR\&. The returned value is a bit mask constructed by OR\(cqing a combination of the following event flags: -.PP -\fBZMQ_POLLIN\fR -.RS 4 -Indicates that at least one message may be received from the specified socket without blocking\&. -.RE -.PP -\fBZMQ_POLLOUT\fR -.RS 4 -Indicates that at least one message may be sent to the specified socket without blocking\&. -.RE -.sp -The combination of a file descriptor returned by the \fIZMQ_FD\fR option being ready for reading but no actual events returned by a subsequent retrieval of the \fIZMQ_EVENTS\fR option is valid; applications should simply ignore this case and restart their polling operation/event loop\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A (flags) -T} -T{ -.sp -Default value -T}:T{ -.sp -N/A -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_FD: Retrieve file descriptor associated with the socket" -.sp -The \fIZMQ_FD\fR option shall retrieve the file descriptor associated with the specified \fIsocket\fR\&. The returned file descriptor can be used to integrate the socket into an existing event loop; the 0MQ library shall signal any pending events on the socket in an \fIedge\-triggered\fR fashion by making the file descriptor become ready for reading\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -The ability to read from the returned file descriptor does not necessarily indicate that messages are available to be read from, or can be written to, the underlying socket; applications must retrieve the actual event state with a subsequent retrieval of the \fIZMQ_EVENTS\fR option\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -The returned file descriptor is also used internally by the \fIzmq_send\fR and \fIzmq_recv\fR functions\&. As the descriptor is edge triggered, applications must update the state of \fIZMQ_EVENTS\fR after each invocation of \fIzmq_send\fR or \fIzmq_recv\fR\&.To be more explicit: after calling \fIzmq_send\fR the socket may become readable (and vice versa) without triggering a read event on the file descriptor\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -The returned file descriptor is intended for use with a \fIpoll\fR or similar system call only\&. Applications must never attempt to read or write data to it directly, neither should they try to close it\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int on POSIX systems, SOCKET on Windows -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -N/A -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_GSSAPI_PLAINTEXT: Retrieve GSSAPI plaintext or encrypted status" -.sp -Returns the \fIZMQ_GSSAPI_PLAINTEXT\fR option, if any, previously set on the socket\&. A value of \fI1\fR means that communications will be plaintext\&. A value of \fI0\fR means communications will be encrypted\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 (false) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP or IPC transports -T} -.TE -.sp 1 -.SS "ZMQ_GSSAPI_PRINCIPAL: Retrieve the name of the GSSAPI principal" -.sp -The \fIZMQ_GSSAPI_PRINCIPAL\fR option shall retrieve the principal name set for the GSSAPI security mechanism\&. The returned value shall be a NULL\-terminated string and MAY be empty\&. The returned size SHALL include the terminating null byte\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -NULL\-terminated character string -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -null string -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP or IPC transports -T} -.TE -.sp 1 -.SS "ZMQ_GSSAPI_SERVER: Retrieve current GSSAPI server role" -.sp -Returns the \fIZMQ_GSSAPI_SERVER\fR option, if any, previously set on the socket\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 (false) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP or IPC transports -T} -.TE -.sp 1 -.SS "ZMQ_GSSAPI_SERVICE_PRINCIPAL: Retrieve the name of the GSSAPI service principal" -.sp -The \fIZMQ_GSSAPI_SERVICE_PRINCIPAL\fR option shall retrieve the principal name of the GSSAPI server to which a GSSAPI client socket intends to connect\&. The returned value shall be a NULL\-terminated string and MAY be empty\&. The returned size SHALL include the terminating null byte\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -NULL\-terminated character string -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -null string -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP or IPC transports -T} -.TE -.sp 1 -.SS "ZMQ_HANDSHAKE_IVL: Retrieve maximum handshake interval" -.sp -The \fIZMQ_HANDSHAKE_IVL\fR option shall retrieve the maximum handshake interval for the specified \fIsocket\fR\&. Handshaking is the exchange of socket configuration information (socket type, identity, security) that occurs when a connection is first opened, only for connection\-oriented transports\&. If handshaking does not complete within the configured time, the connection shall be closed\&. The value 0 means no handshake time limit\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -30000 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all but ZMQ_STREAM, only for connection\-oriented transports -T} -.TE -.sp 1 -.SS "ZMQ_IDENTITY: Retrieve socket identity" -.sp -The \fIZMQ_IDENTITY\fR option shall retrieve the identity of the specified \fIsocket\fR\&. Socket identity is used only by request/reply pattern\&. Namely, it can be used in tandem with ROUTER socket to route messages to the peer with specific identity\&. -.sp -Identity should be at least one byte and at most 255 bytes long\&. Identities starting with binary zero are reserved for use by 0MQ infrastructure\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -binary data -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -NULL -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_REP, ZMQ_REQ, ZMQ_ROUTER, ZMQ_DEALER\&. -T} -.TE -.sp 1 -.SS "ZMQ_IMMEDIATE: Retrieve attach\-on\-connect value" -.sp -Retrieve the state of the attach on connect value\&. If set to 1, will delay the attachment of a pipe on connect until the underlying connection has completed\&. This will cause the socket to block if there are no other connections, but will prevent queues from filling on pipes awaiting connection\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -boolean -T} -T{ -.sp -Default value -T}:T{ -.sp -0 (false) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, primarily when using TCP/IPC transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_INVERT_MATCHING: Retrieve inverted filtering status" -.sp -Returns the value of the \fIZMQ_INVERT_MATCHING\fR option\&. A value of 1 means the socket uses inverted prefix matching\&. -.sp -On \fIPUB\fR and \fIXPUB\fR sockets, this causes messages to be sent to all connected sockets \fIexcept\fR those subscribed to a prefix that matches the message\&. On \fISUB\fR sockets, this causes only incoming messages that do \fInot\fR match any of the socket\(cqs subscriptions to be received by the user\&. -.sp -Whenever \fIZMQ_INVERT_MATCHING\fR is set to 1 on a \fIPUB\fR socket, all \fISUB\fR sockets connecting to it must also have the option set to 1\&. Failure to do so will have the \fISUB\fR sockets reject everything the \fIPUB\fR socket sends them\&. \fIXSUB\fR sockets do not need to do this because they do not filter incoming messages\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0,1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_PUB, ZMQ_XPUB, ZMQ_SUB -T} -.TE -.sp 1 -.SS "ZMQ_IPV4ONLY: Retrieve IPv4\-only socket override status" -.sp -Retrieve the IPv4\-only option for the socket\&. This option is deprecated\&. Please use the ZMQ_IPV6 option\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -boolean -T} -T{ -.sp -Default value -T}:T{ -.sp -1 (true) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_IPV6: Retrieve IPv6 socket status" -.sp -Retrieve the IPv6 option for the socket\&. A value of 1 means IPv6 is enabled on the socket, while 0 means the socket will use only IPv4\&. When IPv6 is enabled the socket will connect to, or accept connections from, both IPv4 and IPv6 hosts\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -boolean -T} -T{ -.sp -Default value -T}:T{ -.sp -0 (false) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_LAST_ENDPOINT: Retrieve the last endpoint set" -.sp -The \fIZMQ_LAST_ENDPOINT\fR option shall retrieve the last endpoint bound for TCP and IPC transports\&. The returned value will be a string in the form of a ZMQ DSN\&. Note that if the TCP host is INADDR_ANY, indicated by a *, then the returned address will be 0\&.0\&.0\&.0 (for IPv4)\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -NULL\-terminated character string -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -NULL -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when binding TCP or IPC transports -T} -.TE -.sp 1 -.SS "ZMQ_LINGER: Retrieve linger period for socket shutdown" -.sp -The \fIZMQ_LINGER\fR option shall retrieve the linger period for the specified \fIsocket\fR\&. The linger period determines how long pending messages which have yet to be sent to a peer shall linger in memory after a socket is closed with \fBzmq_close\fR(3), and further affects the termination of the socket\(cqs context with \fBzmq_ctx_term\fR(3)\&. The following outlines the different behaviours: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The default value of -\fI\-1\fR -specifies an infinite linger period\&. Pending messages shall not be discarded after a call to -\fIzmq_close()\fR; attempting to terminate the socket\(cqs context with -\fIzmq_ctx_term()\fR -shall block until all pending messages have been sent to a peer\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The value of -\fI0\fR -specifies no linger period\&. Pending messages shall be discarded immediately when the socket is closed with -\fIzmq_close()\fR\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Positive values specify an upper bound for the linger period in milliseconds\&. Pending messages shall not be discarded after a call to -\fIzmq_close()\fR; attempting to terminate the socket\(cqs context with -\fIzmq_ctx_term()\fR -shall block until either all pending messages have been sent to a peer, or the linger period expires, after which any pending messages shall be discarded\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -Option value type -T}:T{ -int -T} -T{ -Option value unit -T}:T{ -milliseconds -T} -T{ -Default value -T}:T{ -\-1 (infinite) -T} -T{ -Applicable socket types -T}:T{ -all -T} -.TE -.sp 1 -.RE -.SS "ZMQ_MAXMSGSIZE: Maximum acceptable inbound message size" -.sp -The option shall retrieve limit for the inbound messages\&. If a peer sends a message larger than ZMQ_MAXMSGSIZE it is disconnected\&. Value of \-1 means \fIno limit\fR\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int64_t -T} -T{ -.sp -Option value unit -T}:T{ -.sp -bytes -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_MECHANISM: Retrieve current security mechanism" -.sp -The \fIZMQ_MECHANISM\fR option shall retrieve the current security mechanism for the socket\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -ZMQ_NULL, ZMQ_PLAIN, ZMQ_CURVE, or ZMQ_GSSAPI -T} -T{ -.sp -Default value -T}:T{ -.sp -ZMQ_NULL -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP or IPC transports -T} -.TE -.sp 1 -.SS "ZMQ_MULTICAST_HOPS: Maximum network hops for multicast packets" -.sp -The option shall retrieve time\-to\-live used for outbound multicast packets\&. The default of 1 means that the multicast packets don\(cqt leave the local network\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -network hops -T} -T{ -.sp -Default value -T}:T{ -.sp -1 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using multicast transports -T} -.TE -.sp 1 -.SS "ZMQ_MULTICAST_MAXTPDU: Maximum transport data unit size for multicast packets" -.sp -The \fIZMQ_MULTICAST_MAXTPDU\fR option shall retrieve the maximum transport data unit size used for outbound multicast packets\&. -.sp -This must be set at or below the minimum Maximum Transmission Unit (MTU) for all network paths over which multicast reception is required\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -bytes -T} -T{ -.sp -Default value -T}:T{ -.sp -1500 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using multicast transports -T} -.TE -.sp 1 -.SS "ZMQ_PLAIN_PASSWORD: Retrieve current password" -.sp -The \fIZMQ_PLAIN_PASSWORD\fR option shall retrieve the last password set for the PLAIN security mechanism\&. The returned value shall be a NULL\-terminated string and MAY be empty\&. The returned size SHALL include the terminating null byte\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -NULL\-terminated character string -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -null string -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP or IPC transports -T} -.TE -.sp 1 -.SS "ZMQ_PLAIN_SERVER: Retrieve current PLAIN server role" -.sp -Returns the \fIZMQ_PLAIN_SERVER\fR option, if any, previously set on the socket\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -int -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP or IPC transports -T} -.TE -.sp 1 -.SS "ZMQ_PLAIN_USERNAME: Retrieve current PLAIN username" -.sp -The \fIZMQ_PLAIN_USERNAME\fR option shall retrieve the last username set for the PLAIN security mechanism\&. The returned value shall be a NULL\-terminated string and MAY be empty\&. The returned size SHALL include the terminating null byte\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -NULL\-terminated character string -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -null string -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP or IPC transports -T} -.TE -.sp 1 -.SS "ZMQ_USE_FD: Retrieve the pre\-allocated socket file descriptor" -.sp -The \fIZMQ_USE_FD\fR option shall retrieve the pre\-allocated file descriptor that has been assigned to a ZMQ socket, if any\&. \-1 shall be returned if a pre\-allocated file descriptor was not set for the socket\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -file descriptor -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all bound sockets, when using IPC or TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_RATE: Retrieve multicast data rate" -.sp -The \fIZMQ_RATE\fR option shall retrieve the maximum send or receive data rate for multicast transports using the specified \fIsocket\fR\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -kilobits per second -T} -T{ -.sp -Default value -T}:T{ -.sp -100 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using multicast transports -T} -.TE -.sp 1 -.SS "ZMQ_RCVBUF: Retrieve kernel receive buffer size" -.sp -The \fIZMQ_RCVBUF\fR option shall retrieve the underlying kernel receive buffer size for the specified \fIsocket\fR\&. For details refer to your operating system documentation for the \fISO_RCVBUF\fR socket option\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -bytes -T} -T{ -.sp -Default value -T}:T{ -.sp -8192 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_RCVHWM: Retrieve high water mark for inbound messages" -.sp -The \fIZMQ_RCVHWM\fR option shall return the high water mark for inbound messages on the specified \fIsocket\fR\&. The high water mark is a hard limit on the maximum number of outstanding messages 0MQ shall queue in memory for any single peer that the specified \fIsocket\fR is communicating with\&. A value of zero means no limit\&. -.sp -If this limit has been reached the socket shall enter an exceptional state and depending on the socket type, 0MQ shall take appropriate action such as blocking or dropping sent messages\&. Refer to the individual socket descriptions in \fBzmq_socket\fR(3) for details on the exact action taken for each socket type\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -messages -T} -T{ -.sp -Default value -T}:T{ -.sp -1000 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_RCVMORE: More message data parts to follow" -.sp -The \fIZMQ_RCVMORE\fR option shall return True (1) if the message part last received from the \fIsocket\fR was a data part with more parts to follow\&. If there are no data parts to follow, this option shall return False (0)\&. -.sp -Refer to \fBzmq_send\fR(3) and \fBzmq_recv\fR(3) for a detailed description of multi\-part messages\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -boolean -T} -T{ -.sp -Default value -T}:T{ -.sp -N/A -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_RCVTIMEO: Maximum time before a socket operation returns with EAGAIN" -.sp -Retrieve the timeout for recv operation on the socket\&. If the value is 0, \fIzmq_recv(3)\fR will return immediately, with a EAGAIN error if there is no message to receive\&. If the value is \-1, it will block until a message is available\&. For all other values, it will wait for a message for that amount of time before returning with an EAGAIN error\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 (infinite) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_RECONNECT_IVL: Retrieve reconnection interval" -.sp -The \fIZMQ_RECONNECT_IVL\fR option shall retrieve the initial reconnection interval for the specified \fIsocket\fR\&. The reconnection interval is the period 0MQ shall wait between attempts to reconnect disconnected peers when using connection\-oriented transports\&. The value \-1 means no reconnection\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -The reconnection interval may be randomized by 0MQ to prevent reconnection storms in topologies with a large number of peers per socket\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -100 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, only for connection\-oriented transports -T} -.TE -.sp 1 -.SS "ZMQ_RECONNECT_IVL_MAX: Retrieve maximum reconnection interval" -.sp -The \fIZMQ_RECONNECT_IVL_MAX\fR option shall retrieve the maximum reconnection interval for the specified \fIsocket\fR\&. This is the maximum period 0MQ shall wait between attempts to reconnect\&. On each reconnect attempt, the previous interval shall be doubled untill ZMQ_RECONNECT_IVL_MAX is reached\&. This allows for exponential backoff strategy\&. Default value means no exponential backoff is performed and reconnect interval calculations are only based on ZMQ_RECONNECT_IVL\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -Values less than ZMQ_RECONNECT_IVL will be ignored\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -0 (only use ZMQ_RECONNECT_IVL) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, only for connection\-oriented transport -T} -.TE -.sp 1 -.SS "ZMQ_RECOVERY_IVL: Get multicast recovery interval" -.sp -The \fIZMQ_RECOVERY_IVL\fR option shall retrieve the recovery interval for multicast transports using the specified \fIsocket\fR\&. The recovery interval determines the maximum time in milliseconds that a receiver can be absent from a multicast group before unrecoverable data loss will occur\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -10000 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using multicast transports -T} -.TE -.sp 1 -.SS "ZMQ_SNDBUF: Retrieve kernel transmit buffer size" -.sp -The \fIZMQ_SNDBUF\fR option shall retrieve the underlying kernel transmit buffer size for the specified \fIsocket\fR\&. For details refer to your operating system documentation for the \fISO_SNDBUF\fR socket option\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -bytes -T} -T{ -.sp -Default value -T}:T{ -.sp -8192 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_SNDHWM: Retrieves high water mark for outbound messages" -.sp -The \fIZMQ_SNDHWM\fR option shall return the high water mark for outbound messages on the specified \fIsocket\fR\&. The high water mark is a hard limit on the maximum number of outstanding messages 0MQ shall queue in memory for any single peer that the specified \fIsocket\fR is communicating with\&. A value of zero means no limit\&. -.sp -If this limit has been reached the socket shall enter an exceptional state and depending on the socket type, 0MQ shall take appropriate action such as blocking or dropping sent messages\&. Refer to the individual socket descriptions in \fBzmq_socket\fR(3) for details on the exact action taken for each socket type\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -messages -T} -T{ -.sp -Default value -T}:T{ -.sp -1000 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_SNDTIMEO: Maximum time before a socket operation returns with EAGAIN" -.sp -Retrieve the timeout for send operation on the socket\&. If the value is 0, \fIzmq_send(3)\fR will return immediately, with a EAGAIN error if the message cannot be sent\&. If the value is \-1, it will block until the message is sent\&. For all other values, it will try to send the message for that amount of time before returning with an EAGAIN error\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 (infinite) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_SOCKS_PROXY: Retrieve SOCKS5 proxy address" -.sp -The \fIZMQ_SOCKS_PROXY\fR option shall retrieve the SOCKS5 proxy address in string format\&. The returned value shall be a NULL\-terminated string and MAY be empty\&. The returned size SHALL include the terminating null byte\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -NULL\-terminated character string -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -null string -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports -T} -.TE -.sp 1 -.SS "ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option" -.sp -Override \fISO_KEEPALIVE\fR socket option(where supported by OS)\&. The default value of \-1 means to skip any overrides and leave it to OS default\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -\-1,0,1 -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 (leave to OS default) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option" -.sp -Override \fITCP_KEEPCNT\fR socket option(where supported by OS)\&. The default value of \-1 means to skip any overrides and leave it to OS default\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -\-1,>0 -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 (leave to OS default) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPIDLE (or TCP_KEEPALIVE on some OS)" -.sp -Override \fITCP_KEEPIDLE\fR(or \fITCP_KEEPALIVE\fR on some OS) socket option (where supported by OS)\&. The default value of \-1 means to skip any overrides and leave it to OS default\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -\-1,>0 -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 (leave to OS default) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option" -.sp -Override \fITCP_KEEPINTVL\fR socket option(where supported by OS)\&. The default value of \-1 means to skip any overrides and leave it to OS default\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -\-1,>0 -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 (leave to OS default) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_TCP_MAXRT: Retrieve Max TCP Retransmit Timeout" -.sp -On OSes where it is supported, retrieves how long before an unacknowledged TCP retransmit times out\&. The system normally attempts many TCP retransmits following an exponential backoff strategy\&. This means that after a network outage, it may take a long time before the session can be re\-established\&. Setting this option allows the timeout to happen at a shorter interval\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -0 (leave to OS default) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_THREAD_SAFE: Retrieve socket thread safety" -.sp -The \fIZMQ_THREAD_SAFE\fR option shall retrieve a boolean value indicating whether or not the socket is threadsafe\&. Currently \fIZMQ_CLIENT\fR and \fIZMQ_SERVER\fR sockets are threadsafe\&. -.TS -tab(:); -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -boolean -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_TOS: Retrieve the Type\-of\-Service socket override status" -.sp -Retrieve the IP_TOS option for the socket\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp ->0 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, only for connection\-oriented transports -T} -.TE -.sp 1 -.SS "ZMQ_TYPE: Retrieve socket type" -.sp -The \fIZMQ_TYPE\fR option shall retrieve the socket type for the specified \fIsocket\fR\&. The socket type is specified at socket creation time and cannot be modified afterwards\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -N/A -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_ZAP_DOMAIN: Retrieve RFC 27 authentication domain" -.sp -The \fIZMQ_ZAP_DOMAIN\fR option shall retrieve the last ZAP domain set for the socket\&. The returned value shall be a NULL\-terminated string and MAY be empty\&. The returned size SHALL include the terminating null byte\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -character string -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -not set -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_VMCI_BUFFER_SIZE: Retrieve buffer size of the VMCI socket" -.sp -The ZMQ_VMCI_BUFFER_SIZE option shall retrieve the size of the underlying buffer for the socket\&. Used during negotiation before the connection is established\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -uint64_t -T} -T{ -.sp -Option value unit -T}:T{ -.sp -bytes -T} -T{ -.sp -Default value -T}:T{ -.sp -65546 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using VMCI transport -T} -.TE -.sp 1 -.SS "ZMQ_VMCI_BUFFER_MIN_SIZE: Retrieve min buffer size of the VMCI socket" -.sp -The ZMQ_VMCI_BUFFER_MIN_SIZE option shall retrieve the min size of the underlying buffer for the socket\&. Used during negotiation before the connection is established\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -uint64_t -T} -T{ -.sp -Option value unit -T}:T{ -.sp -bytes -T} -T{ -.sp -Default value -T}:T{ -.sp -128 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using VMCI transport -T} -.TE -.sp 1 -.SS "ZMQ_VMCI_BUFFER_MAX_SIZE: Retrieve max buffer size of the VMCI socket" -.sp -The ZMQ_VMCI_BUFFER_MAX_SIZE option shall retrieve the max size of the underlying buffer for the socket\&. Used during negotiation before the connection is established\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -uint64_t -T} -T{ -.sp -Option value unit -T}:T{ -.sp -bytes -T} -T{ -.sp -Default value -T}:T{ -.sp -262144 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using VMCI transport -T} -.TE -.sp 1 -.SS "ZMQ_VMCI_CONNECT_TIMEOUT: Retrieve connection timeout of the VMCI socket" -.sp -The ZMQ_VMCI_CONNECT_TIMEOUT option shall retrieve connection timeout for the socket\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using VMCI transport -T} -.TE -.sp 1 -.SH "RETURN VALUE" -.sp -The \fIzmq_getsockopt()\fR function shall return zero if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEINVAL\fR -.RS 4 -The requested option -\fIoption_name\fR -is unknown, or the requested -\fIoption_len\fR -or -\fIoption_value\fR -is invalid, or the size of the buffer pointed to by -\fIoption_value\fR, as specified by -\fIoption_len\fR, is insufficient for storing the option value\&. -.RE -.PP -\fBETERM\fR -.RS 4 -The 0MQ -\fIcontext\fR -associated with the specified -\fIsocket\fR -was terminated\&. -.RE -.PP -\fBENOTSOCK\fR -.RS 4 -The provided -\fIsocket\fR -was invalid\&. -.RE -.PP -\fBEINTR\fR -.RS 4 -The operation was interrupted by delivery of a signal\&. -.RE -.SH "EXAMPLE" -.PP -\fBRetrieving the high water mark for outgoing messages\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -/* Retrieve high water mark into sndhwm */ -int sndhwm; -size_t sndhwm_size = sizeof (sndhwm); -rc = zmq_getsockopt (socket, ZMQ_SNDHWM, &sndhwm, &sndhwm_size); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_setsockopt\fR(3) \fBzmq_socket\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_has.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_has.3 deleted file mode 100644 index 37a01001056863..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_has.3 +++ /dev/null @@ -1,124 +0,0 @@ -'\" t -.\" Title: zmq_has -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_HAS" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_has \- check a ZMQ capability -.SH "SYNOPSIS" -.sp -\fBint zmq_has (const char *capability);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_has()\fR function shall report whether a specified capability is available in the library\&. This allows bindings and applications to probe a library directly, for transport and security options\&. -.sp -Capabilities shall be lowercase strings\&. The following capabilities are defined: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -ipc \- the library supports the ipc:// protocol -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -pgm \- the library supports the pgm:// protocol -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -tipc \- the library supports the tipc:// protocol -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -norm \- the library supports the norm:// protocol -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -curve \- the library supports the CURVE security mechanism -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -gssapi \- the library supports the GSSAPI security mechanism -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -draft \- the library is built with the draft api -.RE -.sp -When this method is provided, the zmq\&.h header file will define ZMQ_HAS_CAPABILITIES\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_has()\fR function shall return 1 if the specified capability is provided\&. Otherwise it shall return 0\&. -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_close.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_close.3 deleted file mode 100644 index 098a5a8b3c4eba..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_close.3 +++ /dev/null @@ -1,70 +0,0 @@ -'\" t -.\" Title: zmq_msg_close -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_CLOSE" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_close \- release 0MQ message -.SH "SYNOPSIS" -.sp -\fBint zmq_msg_close (zmq_msg_t \fR\fB\fI*msg\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_close()\fR function shall inform the 0MQ infrastructure that any resources associated with the message object referenced by \fImsg\fR are no longer required and may be released\&. Actual release of resources associated with the message object shall be postponed by 0MQ until all users of the message or underlying data buffer have indicated it is no longer required\&. -.sp -Applications should ensure that \fIzmq_msg_close()\fR is called once a message is no longer required, otherwise memory leaks may occur\&. Note that this is NOT necessary after a successful \fIzmq_msg_send()\fR\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -Never access \fIzmq_msg_t\fR members directly, instead always use the \fIzmq_msg\fR family of functions\&. -.sp .5v -.RE -.SH "RETURN VALUE" -.sp -The \fIzmq_msg_close()\fR function shall return zero if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEFAULT\fR -.RS 4 -Invalid message\&. -.RE -.SH "SEE ALSO" -.sp -\fBzmq_msg_init\fR(3) \fBzmq_msg_init_size\fR(3) \fBzmq_msg_init_data\fR(3) \fBzmq_msg_data\fR(3) \fBzmq_msg_size\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_copy.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_copy.3 deleted file mode 100644 index d8136ef9aaa45c..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_copy.3 +++ /dev/null @@ -1,106 +0,0 @@ -'\" t -.\" Title: zmq_msg_copy -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_COPY" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_copy \- copy content of a message to another message -.SH "SYNOPSIS" -.sp -\fBint zmq_msg_copy (zmq_msg_t \fR\fB\fI*dest\fR\fR\fB, zmq_msg_t \fR\fB\fI*src\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_copy()\fR function shall copy the message object referenced by \fIsrc\fR to the message object referenced by \fIdest\fR\&. The original content of \fIdest\fR, if any, shall be released\&. You must initialise \fIdest\fR before copying to it\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -The implementation may choose not to physically copy the message content, rather to share the underlying buffer between \fIsrc\fR and \fIdest\fR\&. Avoid modifying message content after a message has been copied with \fIzmq_msg_copy()\fR, doing so can result in undefined behaviour\&. If what you need is an actual hard copy, allocate a new message using \fIzmq_msg_init_size()\fR and copy the message content using \fImemcpy()\fR\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -Never access \fIzmq_msg_t\fR members directly, instead always use the \fIzmq_msg\fR family of functions\&. -.sp .5v -.RE -.SH "RETURN VALUE" -.sp -The \fIzmq_msg_copy()\fR function shall return zero if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEFAULT\fR -.RS 4 -Invalid message\&. -.RE -.SH "EXAMPLE" -.PP -\fBCopying a message\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zmq_msg_t msg; -zmq_msg_init_size (&msg, 255); -memcpy (zmq_msg_data (&msg, "Hello, World", 12); -zmq_msg_t copy; -zmq_msg_init (©); -zmq_msg_copy (©, &msg); -\&.\&.\&. -zmq_msg_close (©); -zmq_msg_close (&msg); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_msg_move\fR(3) \fBzmq_msg_init\fR(3) \fBzmq_msg_init_size\fR(3) \fBzmq_msg_init_data\fR(3) \fBzmq_msg_close\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_data.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_data.3 deleted file mode 100644 index 7525f5cce86928..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_data.3 +++ /dev/null @@ -1,65 +0,0 @@ -'\" t -.\" Title: zmq_msg_data -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_DATA" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_data \- retrieve pointer to message content -.SH "SYNOPSIS" -.sp -\fBvoid *zmq_msg_data (zmq_msg_t \fR\fB\fI*msg\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_data()\fR function shall return a pointer to the message content of the message object referenced by \fImsg\fR\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -Never access \fIzmq_msg_t\fR members directly, instead always use the \fIzmq_msg\fR family of functions\&. -.sp .5v -.RE -.SH "RETURN VALUE" -.sp -Upon successful completion, \fIzmq_msg_data()\fR shall return a pointer to the message content\&. -.SH "ERRORS" -.sp -No errors are defined\&. -.SH "SEE ALSO" -.sp -\fBzmq_msg_size\fR(3) \fBzmq_msg_init\fR(3) \fBzmq_msg_init_size\fR(3) \fBzmq_msg_init_data\fR(3) \fBzmq_msg_close\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_get.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_get.3 deleted file mode 100644 index ec1764be3848a3..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_get.3 +++ /dev/null @@ -1,104 +0,0 @@ -'\" t -.\" Title: zmq_msg_get -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_GET" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_get \- get message property -.SH "SYNOPSIS" -.sp -\fBint zmq_msg_get (zmq_msg_t \fR\fB\fI*message\fR\fR\fB, int \fR\fB\fIproperty\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_get()\fR function shall return the value for the property specified by the \fIproperty\fR argument for the message pointed to by the \fImessage\fR argument\&. -.sp -The following properties can be retrieved with the \fIzmq_msg_get()\fR function: -.PP -\fBZMQ_MORE\fR -.RS 4 -Indicates that there are more message frames to follow after the -\fImessage\fR\&. -.RE -.PP -\fBZMQ_SRCFD\fR -.RS 4 -Returns the file descriptor of the socket the -\fImessage\fR -was read from\&. This allows application to retrieve the remote endpoint via -\fIgetpeername(2)\fR\&. Be aware that the respective socket might be closed already, reused even\&. Currently only implemented for TCP sockets\&. -.RE -.PP -\fBZMQ_SHARED\fR -.RS 4 -Indicates that a message MAY share underlying storage with another copy of this message\&. -.RE -.SH "RETURN VALUE" -.sp -The \fIzmq_msg_get()\fR function shall return the value for the property if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEINVAL\fR -.RS 4 -The requested -\fIproperty\fR -is unknown\&. -.RE -.SH "EXAMPLE" -.PP -\fBReceiving a multi-frame message\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zmq_msg_t frame; -while (true) { - // Create an empty 0MQ message to hold the message frame - int rc = zmq_msg_init (&frame); - assert (rc == 0); - // Block until a message is available to be received from socket - rc = zmq_msg_recv (socket, &frame, 0); - assert (rc != \-1); - if (zmq_msg_get (&frame, ZMQ_MORE)) - fprintf (stderr, "more\en"); - else { - fprintf (stderr, "end\en"); - break; - } - zmq_msg_close (&frame); -} -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_msg_set\fR(3) \fBzmq_msg_init\fR(3) \fBzmq_msg_close\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_gets.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_gets.3 deleted file mode 100644 index 2624896f605299..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_gets.3 +++ /dev/null @@ -1,93 +0,0 @@ -'\" t -.\" Title: zmq_msg_gets -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_GETS" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_gets \- get message metadata property -.SH "SYNOPSIS" -.sp -\fBconst char *zmq_msg_gets (zmq_msg_t \fR\fB\fI*message\fR\fR\fB, const char *\fR\fB\fIproperty\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_gets()\fR function shall return the string value for the metadata property specified by the \fIproperty\fR argument for the message pointed to by the \fImessage\fR argument\&. Both the \fIproperty\fR argument and the \fIvalue\fR shall be NULL\-terminated UTF8\-encoded strings\&. -.sp -Metadata is defined on a per\-connection basis during the ZeroMQ connection handshake as specified in \&. -.sp -The following ZMTP properties can be retrieved with the \fIzmq_msg_gets()\fR function: -.sp -.if n \{\ -.RS 4 -.\} -.nf -Socket\-Type -Identity -Resource -.fi -.if n \{\ -.RE -.\} -.sp -Additionally, when available for the underlying transport, the \fBPeer\-Address\fR property will return the IP address of the remote endpoint as returned by getnameinfo(2)\&. -.sp -Other properties may be defined based on the underlying security mechanism, see ZAP authenticated connection sample below\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_msg_gets()\fR function shall return the string value for the property if successful\&. Otherwise it shall return NULL and set \fIerrno\fR to one of the values defined below\&. The caller shall not modify or free the returned value, which shall be owned by the message\&. The encoding of the property and value shall be UTF8\&. -.SH "ERRORS" -.PP -\fBEINVAL\fR -.RS 4 -The requested -\fIproperty\fR -is unknown\&. -.RE -.SH "EXAMPLE" -.PP -\fBGetting the ZAP authenticated user id for a message:\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zmq_msg_t msg; -zmq_msg_init (&msg); -rc = zmq_msg_recv (&msg, dealer, 0); -assert (rc != \-1); -const char *user_id = zmq_msg_gets (&msg, "User\-Id"); -zmq_msg_close (&msg); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_init.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_init.3 deleted file mode 100644 index baf280b251f482..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_init.3 +++ /dev/null @@ -1,99 +0,0 @@ -'\" t -.\" Title: zmq_msg_init -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_INIT" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_init \- initialise empty 0MQ message -.SH "SYNOPSIS" -.sp -\fBint zmq_msg_init (zmq_msg_t \fR\fB\fI*msg\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_init()\fR function shall initialise the message object referenced by \fImsg\fR to represent an empty message\&. This function is most useful when called before receiving a message with \fIzmq_recv()\fR\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -Never access \fIzmq_msg_t\fR members directly, instead always use the \fIzmq_msg\fR family of functions\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -The functions \fIzmq_msg_init()\fR, \fIzmq_msg_init_data()\fR and \fIzmq_msg_init_size()\fR are mutually exclusive\&. Never initialise the same \fIzmq_msg_t\fR twice\&. -.sp .5v -.RE -.SH "RETURN VALUE" -.sp -The \fIzmq_msg_init()\fR function always returns zero\&. -.SH "ERRORS" -.sp -No errors are defined\&. -.SH "EXAMPLE" -.PP -\fBReceiving a message from a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zmq_msg_t msg; -rc = zmq_msg_init (&msg); -assert (rc == 0); -int nbytes = zmq_recv (socket, &msg, 0); -assert (nbytes != \-1); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_msg_init_size\fR(3) \fBzmq_msg_init_data\fR(3) \fBzmq_msg_close\fR(3) \fBzmq_msg_data\fR(3) \fBzmq_msg_size\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_init_data.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_init_data.3 deleted file mode 100644 index 1130b76c72251f..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_init_data.3 +++ /dev/null @@ -1,146 +0,0 @@ -'\" t -.\" Title: zmq_msg_init_data -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_INIT_DATA" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_init_data \- initialise 0MQ message from a supplied buffer -.SH "SYNOPSIS" -.sp -\fBtypedef void (zmq_free_fn) (void \fR\fB\fI*data\fR\fR\fB, void \fR\fB\fI*hint\fR\fR\fB);\fR -.sp -\fBint zmq_msg_init_data (zmq_msg_t \fR\fB\fI*msg\fR\fR\fB, void \fR\fB\fI*data\fR\fR\fB, size_t \fR\fB\fIsize\fR\fR\fB, zmq_free_fn \fR\fB\fI*ffn\fR\fR\fB, void \fR\fB\fI*hint\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_init_data()\fR function shall initialise the message object referenced by \fImsg\fR to represent the content referenced by the buffer located at address \fIdata\fR, \fIsize\fR bytes long\&. No copy of \fIdata\fR shall be performed and 0MQ shall take ownership of the supplied buffer\&. -.sp -If provided, the deallocation function \fIffn\fR shall be called once the data buffer is no longer required by 0MQ, with the \fIdata\fR and \fIhint\fR arguments supplied to \fIzmq_msg_init_data()\fR\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -Never access \fIzmq_msg_t\fR members directly, instead always use the \fIzmq_msg\fR family of functions\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -The deallocation function \fIffn\fR needs to be thread\-safe, since it will be called from an arbitrary thread\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -If the deallocation function is not provided, the allocated memory will not be freed, and this may cause a memory leak\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -The functions \fIzmq_msg_init()\fR, \fIzmq_msg_init_data()\fR and \fIzmq_msg_init_size()\fR are mutually exclusive\&. Never initialise the same \fIzmq_msg_t\fR twice\&. -.sp .5v -.RE -.SH "RETURN VALUE" -.sp -The \fIzmq_msg_init_data()\fR function shall return zero if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBENOMEM\fR -.RS 4 -Insufficient storage space is available\&. -.RE -.SH "EXAMPLE" -.PP -\fBInitialising a message from a supplied buffer\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -void my_free (void *data, void *hint) -{ - free (data); -} - - /* \&.\&.\&. */ - -void *data = malloc (6); -assert (data); -memcpy (data, "ABCDEF", 6); -zmq_msg_t msg; -rc = zmq_msg_init_data (&msg, data, 6, my_free, NULL); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_msg_init_size\fR(3) \fBzmq_msg_init\fR(3) \fBzmq_msg_close\fR(3) \fBzmq_msg_data\fR(3) \fBzmq_msg_size\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_init_size.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_init_size.3 deleted file mode 100644 index f0f4eb51edafec..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_init_size.3 +++ /dev/null @@ -1,86 +0,0 @@ -'\" t -.\" Title: zmq_msg_init_size -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_INIT_SIZE" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_init_size \- initialise 0MQ message of a specified size -.SH "SYNOPSIS" -.sp -\fBint zmq_msg_init_size (zmq_msg_t \fR\fB\fI*msg\fR\fR\fB, size_t \fR\fB\fIsize\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_init_size()\fR function shall allocate any resources required to store a message \fIsize\fR bytes long and initialise the message object referenced by \fImsg\fR to represent the newly allocated message\&. -.sp -The implementation shall choose whether to store message content on the stack (small messages) or on the heap (large messages)\&. For performance reasons \fIzmq_msg_init_size()\fR shall not clear the message data\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -Never access \fIzmq_msg_t\fR members directly, instead always use the \fIzmq_msg\fR family of functions\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -The functions \fIzmq_msg_init()\fR, \fIzmq_msg_init_data()\fR and \fIzmq_msg_init_size()\fR are mutually exclusive\&. Never initialise the same \fIzmq_msg_t\fR twice\&. -.sp .5v -.RE -.SH "RETURN VALUE" -.sp -The \fIzmq_msg_init_size()\fR function shall return zero if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBENOMEM\fR -.RS 4 -Insufficient storage space is available\&. -.RE -.SH "SEE ALSO" -.sp -\fBzmq_msg_init_data\fR(3) \fBzmq_msg_init\fR(3) \fBzmq_msg_close\fR(3) \fBzmq_msg_data\fR(3) \fBzmq_msg_size\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_more.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_more.3 deleted file mode 100644 index d10ff83f8923b1..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_more.3 +++ /dev/null @@ -1,75 +0,0 @@ -'\" t -.\" Title: zmq_msg_more -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_MORE" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_more \- indicate if there are more message parts to receive -.SH "SYNOPSIS" -.sp -\fBint zmq_msg_more (zmq_msg_t \fR\fB\fI*message\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_more()\fR function indicates whether this is part of a multi\-part message, and there are further parts to receive\&. This method can safely be called after \fIzmq_msg_close()\fR\&. This method is identical to \fIzmq_msg_get()\fR with an argument of ZMQ_MORE\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_msg_more()\fR function shall return zero if this is the final part of a multi\-part message, or the only part of a single\-part message\&. It shall return 1 if there are further parts to receive\&. -.SH "EXAMPLE" -.PP -\fBReceiving a multi-part message\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zmq_msg_t part; -while (true) { - // Create an empty 0MQ message to hold the message part - int rc = zmq_msg_init (&part); - assert (rc == 0); - // Block until a message is available to be received from socket - rc = zmq_msg_recv (socket, &part, 0); - assert (rc != \-1); - if (zmq_msg_more (&part)) - fprintf (stderr, "more\en"); - else { - fprintf (stderr, "end\en"); - break; - } - zmq_msg_close (&part); -} -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_msg_get\fR(3) \fBzmq_msg_set\fR(3) \fBzmq_msg_init\fR(3) \fBzmq_msg_close\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_move.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_move.3 deleted file mode 100644 index 7328f994645581..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_move.3 +++ /dev/null @@ -1,68 +0,0 @@ -'\" t -.\" Title: zmq_msg_move -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_MOVE" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_move \- move content of a message to another message -.SH "SYNOPSIS" -.sp -\fBint zmq_msg_move (zmq_msg_t \fR\fB\fI*dest\fR\fR\fB, zmq_msg_t \fR\fB\fI*src\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_move()\fR function shall move the content of the message object referenced by \fIsrc\fR to the message object referenced by \fIdest\fR\&. No actual copying of message content is performed, \fIdest\fR is simply updated to reference the new content\&. \fIsrc\fR becomes an empty message after calling \fIzmq_msg_move()\fR\&. The original content of \fIdest\fR, if any, shall be released\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -Never access \fIzmq_msg_t\fR members directly, instead always use the \fIzmq_msg\fR family of functions\&. -.sp .5v -.RE -.SH "RETURN VALUE" -.sp -The \fIzmq_msg_move()\fR function shall return zero if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEFAULT\fR -.RS 4 -Invalid message\&. -.RE -.SH "SEE ALSO" -.sp -\fBzmq_msg_copy\fR(3) \fBzmq_msg_init\fR(3) \fBzmq_msg_init_size\fR(3) \fBzmq_msg_init_data\fR(3) \fBzmq_msg_close\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_recv.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_recv.3 deleted file mode 100644 index 3f8b8a3e7b9cb7..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_recv.3 +++ /dev/null @@ -1,161 +0,0 @@ -'\" t -.\" Title: zmq_msg_recv -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_RECV" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_recv \- receive a message part from a socket -.SH "SYNOPSIS" -.sp -\fBint zmq_msg_recv (zmq_msg_t \fR\fB\fI*msg\fR\fR\fB, void \fR\fB\fI*socket\fR\fR\fB, int \fR\fB\fIflags\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_recv()\fR function is identical to \fBzmq_recvmsg\fR(3), which shall be deprecated in future versions\&. \fIzmq_msg_recv()\fR is more consistent with other message manipulation functions\&. -.sp -The \fIzmq_msg_recv()\fR function shall receive a message part from the socket referenced by the \fIsocket\fR argument and store it in the message referenced by the \fImsg\fR argument\&. Any content previously stored in \fImsg\fR shall be properly deallocated\&. If there are no message parts available on the specified \fIsocket\fR the \fIzmq_msg_recv()\fR function shall block until the request can be satisfied\&. The \fIflags\fR argument is a combination of the flags defined below: -.PP -\fBZMQ_DONTWAIT\fR -.RS 4 -Specifies that the operation should be performed in non\-blocking mode\&. If there are no messages available on the specified -\fIsocket\fR, the -\fIzmq_msg_recv()\fR -function shall fail with -\fIerrno\fR -set to EAGAIN\&. -.RE -.SS "Multi\-part messages" -.sp -A 0MQ message is composed of 1 or more message parts\&. Each message part is an independent \fIzmq_msg_t\fR in its own right\&. 0MQ ensures atomic delivery of messages: peers shall receive either all \fImessage parts\fR of a message or none at all\&. The total number of message parts is unlimited except by available memory\&. -.sp -An application that processes multi\-part messages must use the \fIZMQ_RCVMORE\fR \fBzmq_getsockopt\fR(3) option after calling \fIzmq_msg_recv()\fR to determine if there are further parts to receive\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_msg_recv()\fR function shall return number of bytes in the message if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEAGAIN\fR -.RS 4 -Non\-blocking mode was requested and no messages are available at the moment\&. -.RE -.PP -\fBENOTSUP\fR -.RS 4 -The -\fIzmq_msg_recv()\fR -operation is not supported by this socket type\&. -.RE -.PP -\fBEFSM\fR -.RS 4 -The -\fIzmq_msg_recv()\fR -operation cannot be performed on this socket at the moment due to the socket not being in the appropriate state\&. This error may occur with socket types that switch between several states, such as ZMQ_REP\&. See the -\fImessaging patterns\fR -section of -\fBzmq_socket\fR(3) -for more information\&. -.RE -.PP -\fBETERM\fR -.RS 4 -The 0MQ -\fIcontext\fR -associated with the specified -\fIsocket\fR -was terminated\&. -.RE -.PP -\fBENOTSOCK\fR -.RS 4 -The provided -\fIsocket\fR -was invalid\&. -.RE -.PP -\fBEINTR\fR -.RS 4 -The operation was interrupted by delivery of a signal before a message was available\&. -.RE -.PP -\fBEFAULT\fR -.RS 4 -The message passed to the function was invalid\&. -.RE -.SH "EXAMPLE" -.PP -\fBReceiving a message from a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -/* Create an empty 0MQ message */ -zmq_msg_t msg; -int rc = zmq_msg_init (&msg); -assert (rc == 0); -/* Block until a message is available to be received from socket */ -rc = zmq_msg_recv (&msg, socket, 0); -assert (rc != \-1); -/* Release message */ -zmq_msg_close (&msg); -.fi -.if n \{\ -.RE -.\} -.PP -\fBReceiving a multi-part message\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -int more; -size_t more_size = sizeof (more); -do { - /* Create an empty 0MQ message to hold the message part */ - zmq_msg_t part; - int rc = zmq_msg_init (&part); - assert (rc == 0); - /* Block until a message is available to be received from socket */ - rc = zmq_msg_recv (&part, socket, 0); - assert (rc != \-1); - /* Determine if more message parts are to follow */ - rc = zmq_getsockopt (socket, ZMQ_RCVMORE, &more, &more_size); - assert (rc == 0); - zmq_msg_close (&part); -} while (more); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_recv\fR(3) \fBzmq_send\fR(3) \fBzmq_msg_send\fR(3) \fBzmq_getsockopt\fR(3) \fBzmq_socket\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_routing_id.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_routing_id.3 deleted file mode 100644 index 94a832143b458f..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_routing_id.3 +++ /dev/null @@ -1,76 +0,0 @@ -'\" t -.\" Title: zmq_msg_routing_id -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_ROUTING_ID" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_routing_id \- return routing ID for message, if any -.SH "SYNOPSIS" -.sp -\fBuint32_t zmq_msg_routing_id (zmq_msg_t \fR\fB\fI*message\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_routing_id()\fR function returns the routing ID for the message, if any\&. The routing ID is set on all messages received from a \fIZMQ_SERVER\fR socket\&. To send a message to a \fIZMQ_SERVER\fR socket you must set the routing ID of a connected \fIZMQ_CLIENT\fR peer\&. Routing IDs are transient\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_msg_routing_id()\fR function shall return zero if there is no routing ID, otherwise it shall return an unsigned 32\-bit integer greater than zero\&. -.SH "EXAMPLE" -.PP -\fBReceiving a client message and routing ID\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -void *ctx = zmq_ctx_new (); -assert (ctx); - -void *server = zmq_socket (ctx, ZMQ_SERVER); -assert (server); -int rc = zmq_bind (server, "tcp://127\&.0\&.0\&.1:8080"); -assert (rc == 0); - -zmq_msg_t message; -rc = zmq_msg_init (&message); -assert (rc == 0); - -// Receive a message from socket -rc = zmq_msg_recv (server, &message, 0); -assert (rc != \-1); -uint32_t routing_id = zmq_msg_routing_id (&message); -assert (routing_id); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_msg_set_routing_id\fR(3) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_send.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_send.3 deleted file mode 100644 index a6070a8672b301..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_send.3 +++ /dev/null @@ -1,184 +0,0 @@ -'\" t -.\" Title: zmq_msg_send -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_SEND" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_send \- send a message part on a socket -.SH "SYNOPSIS" -.sp -\fBint zmq_msg_send (zmq_msg_t \fR\fB\fI*msg\fR\fR\fB, void \fR\fB\fI*socket\fR\fR\fB, int \fR\fB\fIflags\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_send()\fR function is identical to \fBzmq_sendmsg\fR(3), which shall be deprecated in future versions\&. \fIzmq_msg_send()\fR is more consistent with other message manipulation functions\&. -.sp -The \fIzmq_msg_send()\fR function shall queue the message referenced by the \fImsg\fR argument to be sent to the socket referenced by the \fIsocket\fR argument\&. The \fIflags\fR argument is a combination of the flags defined below: -.PP -\fBZMQ_DONTWAIT\fR -.RS 4 -For socket types (DEALER, PUSH) that block when there are no available peers (or all peers have full high\-water mark), specifies that the operation should be performed in non\-blocking mode\&. If the message cannot be queued on the -\fIsocket\fR, the -\fIzmq_msg_send()\fR -function shall fail with -\fIerrno\fR -set to EAGAIN\&. -.RE -.PP -\fBZMQ_SNDMORE\fR -.RS 4 -Specifies that the message being sent is a multi\-part message, and that further message parts are to follow\&. Refer to the section regarding multi\-part messages below for a detailed description\&. -.RE -.sp -The \fIzmq_msg_t\fR structure passed to \fIzmq_msg_send()\fR is nullified during the call\&. If you want to send the same message to multiple sockets you have to copy it (e\&.g\&. using \fIzmq_msg_copy()\fR)\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -A successful invocation of \fIzmq_msg_send()\fR does not indicate that the message has been transmitted to the network, only that it has been queued on the \fIsocket\fR and 0MQ has assumed responsibility for the message\&. You do not need to call \fIzmq_msg_close()\fR after a successful \fIzmq_msg_send()\fR\&. -.sp .5v -.RE -.SS "Multi\-part messages" -.sp -A 0MQ message is composed of 1 or more message parts\&. Each message part is an independent \fIzmq_msg_t\fR in its own right\&. 0MQ ensures atomic delivery of messages: peers shall receive either all \fImessage parts\fR of a message or none at all\&. The total number of message parts is unlimited except by available memory\&. -.sp -An application that sends multi\-part messages must use the \fIZMQ_SNDMORE\fR flag when sending each message part except the final one\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_msg_send()\fR function shall return number of bytes in the message if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEAGAIN\fR -.RS 4 -Non\-blocking mode was requested and the message cannot be sent at the moment\&. -.RE -.PP -\fBENOTSUP\fR -.RS 4 -The -\fIzmq_msg_send()\fR -operation is not supported by this socket type\&. -.RE -.PP -\fBEINVAL\fR -.RS 4 -The sender tried to send multipart data, which the socket type does not allow\&. -.RE -.PP -\fBEFSM\fR -.RS 4 -The -\fIzmq_msg_send()\fR -operation cannot be performed on this socket at the moment due to the socket not being in the appropriate state\&. This error may occur with socket types that switch between several states, such as ZMQ_REP\&. See the -\fImessaging patterns\fR -section of -\fBzmq_socket\fR(3) -for more information\&. -.RE -.PP -\fBETERM\fR -.RS 4 -The 0MQ -\fIcontext\fR -associated with the specified -\fIsocket\fR -was terminated\&. -.RE -.PP -\fBENOTSOCK\fR -.RS 4 -The provided -\fIsocket\fR -was invalid\&. -.RE -.PP -\fBEINTR\fR -.RS 4 -The operation was interrupted by delivery of a signal before the message was sent\&. -.RE -.PP -\fBEFAULT\fR -.RS 4 -Invalid message\&. -.RE -.PP -\fBEHOSTUNREACH\fR -.RS 4 -The message cannot be routed\&. -.RE -.SH "EXAMPLE" -.PP -\fBFilling in a message and sending it to a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -/* Create a new message, allocating 6 bytes for message content */ -zmq_msg_t msg; -int rc = zmq_msg_init_size (&msg, 6); -assert (rc == 0); -/* Fill in message content with \*(AqAAAAAA\*(Aq */ -memset (zmq_msg_data (&msg), \*(AqA\*(Aq, 6); -/* Send the message to the socket */ -rc = zmq_msg_send (&msg, socket, 0); -assert (rc == 6); -.fi -.if n \{\ -.RE -.\} -.PP -\fBSending a multi-part message\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -/* Send a multi\-part message consisting of three parts to socket */ -rc = zmq_msg_send (&part1, socket, ZMQ_SNDMORE); -rc = zmq_msg_send (&part2, socket, ZMQ_SNDMORE); -/* Final part; no more parts to follow */ -rc = zmq_msg_send (&part3, socket, 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_recv\fR(3) \fBzmq_send\fR(3) \fBzmq_msg_recv\fR(3) \fBzmq_socket\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_set.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_set.3 deleted file mode 100644 index a2c5da543ba0a4..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_set.3 +++ /dev/null @@ -1,56 +0,0 @@ -'\" t -.\" Title: zmq_msg_set -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_SET" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_set \- set message property -.SH "SYNOPSIS" -.sp -\fBint zmq_msg_set (zmq_msg_t \fR\fB\fI*message\fR\fR\fB, int \fR\fB\fIproperty\fR\fR\fB, int \fR\fB\fIvalue\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_set()\fR function shall set the property specified by the \fIproperty\fR argument to the value of the \fIvalue\fR argument for the 0MQ message fragment pointed to by the \fImessage\fR argument\&. -.sp -Currently the \fIzmq_msg_set()\fR function does not support any property names\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_msg_set()\fR function shall return zero if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEINVAL\fR -.RS 4 -The requested property -\fIproperty\fR -is unknown\&. -.RE -.SH "SEE ALSO" -.sp -\fBzmq_msg_get\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_set_routing_id.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_set_routing_id.3 deleted file mode 100644 index c11c84cd678e38..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_set_routing_id.3 +++ /dev/null @@ -1,54 +0,0 @@ -'\" t -.\" Title: zmq_msg_set_routing_id -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_SET_ROUTING_" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_set_routing_id \- set routing ID property on message -.SH "SYNOPSIS" -.sp -\fBint zmq_msg_set_routing_id (zmq_msg_t \fR\fB\fI*message\fR\fR\fB, uint32_t \fR\fB\fIrouting_id\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_set_routing_id()\fR function sets the \fIrouting_id\fR specified, on the the message pointed to by the \fImessage\fR argument\&. The \fIrouting_id\fR must be greater than zero\&. To get a valid routing ID, you must receive a message from a \fIZMQ_SERVER\fR socket, and use the libzmq:zmq_msg_routing_id method\&. Routing IDs are transient\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_msg_set_routing_id()\fR function shall return zero if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEINVAL\fR -.RS 4 -The provided -\fIrouting_id\fR -is zero\&. -.RE -.SH "SEE ALSO" -.sp -\fBzmq_msg_routing_id\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_size.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_size.3 deleted file mode 100644 index 7e808b7223e21c..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_msg_size.3 +++ /dev/null @@ -1,65 +0,0 @@ -'\" t -.\" Title: zmq_msg_size -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_MSG_SIZE" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_msg_size \- retrieve message content size in bytes -.SH "SYNOPSIS" -.sp -\fBsize_t zmq_msg_size (zmq_msg_t \fR\fB\fI*msg\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_msg_size()\fR function shall return the size in bytes of the content of the message object referenced by \fImsg\fR\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -Never access \fIzmq_msg_t\fR members directly, instead always use the \fIzmq_msg\fR family of functions\&. -.sp .5v -.RE -.SH "RETURN VALUE" -.sp -Upon successful completion, \fIzmq_msg_size()\fR shall return the size of the message content in bytes\&. -.SH "ERRORS" -.sp -No errors are defined\&. -.SH "SEE ALSO" -.sp -\fBzmq_msg_data\fR(3) \fBzmq_msg_init\fR(3) \fBzmq_msg_init_size\fR(3) \fBzmq_msg_init_data\fR(3) \fBzmq_msg_close\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_poll.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_poll.3 deleted file mode 100644 index 928bde440e2110..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_poll.3 +++ /dev/null @@ -1,182 +0,0 @@ -'\" t -.\" Title: zmq_poll -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_POLL" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_poll \- input/output multiplexing -.SH "SYNOPSIS" -.sp -\fBint zmq_poll (zmq_pollitem_t \fR\fB\fI*items\fR\fR\fB, int \fR\fB\fInitems\fR\fR\fB, long \fR\fB\fItimeout\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_poll()\fR function provides a mechanism for applications to multiplex input/output events in a level\-triggered fashion over a set of sockets\&. Each member of the array pointed to by the \fIitems\fR argument is a \fBzmq_pollitem_t\fR structure\&. The \fInitems\fR argument specifies the number of items in the \fIitems\fR array\&. The \fBzmq_pollitem_t\fR structure is defined as follows: -.sp -.if n \{\ -.RS 4 -.\} -.nf -typedef struct -{ - void \fI*socket\fR; - int \fIfd\fR; - short \fIevents\fR; - short \fIrevents\fR; -} zmq_pollitem_t; -.fi -.if n \{\ -.RE -.\} -.sp -For each \fBzmq_pollitem_t\fR item, \fIzmq_poll()\fR shall examine either the 0MQ socket referenced by \fIsocket\fR \fBor\fR the standard socket specified by the file descriptor \fIfd\fR, for the event(s) specified in \fIevents\fR\&. If both \fIsocket\fR and \fIfd\fR are set in a single \fBzmq_pollitem_t\fR, the 0MQ socket referenced by \fIsocket\fR shall take precedence and the value of \fIfd\fR shall be ignored\&. -.sp -For each \fBzmq_pollitem_t\fR item, \fIzmq_poll()\fR shall first clear the \fIrevents\fR member, and then indicate any requested events that have occurred by setting the bit corresponding to the event condition in the \fIrevents\fR member\&. -.sp -If none of the requested events have occurred on any \fBzmq_pollitem_t\fR item, \fIzmq_poll()\fR shall wait \fItimeout\fR milliseconds for an event to occur on any of the requested items\&. If the value of \fItimeout\fR is 0, \fIzmq_poll()\fR shall return immediately\&. If the value of \fItimeout\fR is \-1, \fIzmq_poll()\fR shall block indefinitely until a requested event has occurred on at least one \fBzmq_pollitem_t\fR\&. -.sp -The \fIevents\fR and \fIrevents\fR members of \fBzmq_pollitem_t\fR are bit masks constructed by OR\(cqing a combination of the following event flags: -.PP -\fBZMQ_POLLIN\fR -.RS 4 -For 0MQ sockets, at least one message may be received from the -\fIsocket\fR -without blocking\&. For standard sockets this is equivalent to the -\fIPOLLIN\fR -flag of the -\fIpoll()\fR -system call and generally means that at least one byte of data may be read from -\fIfd\fR -without blocking\&. -.RE -.PP -\fBZMQ_POLLOUT\fR -.RS 4 -For 0MQ sockets, at least one message may be sent to the -\fIsocket\fR -without blocking\&. For standard sockets this is equivalent to the -\fIPOLLOUT\fR -flag of the -\fIpoll()\fR -system call and generally means that at least one byte of data may be written to -\fIfd\fR -without blocking\&. -.RE -.PP -\fBZMQ_POLLERR\fR -.RS 4 -For standard sockets, this flag is passed through -\fIzmq_poll()\fR -to the underlying -\fIpoll()\fR -system call and generally means that some sort of error condition is present on the socket specified by -\fIfd\fR\&. For 0MQ sockets this flag has no effect if set in -\fIevents\fR, and shall never be returned in -\fIrevents\fR -by -\fIzmq_poll()\fR\&. -.RE -.PP -\fBZMQ_POLLPRI\fR -.RS 4 -For 0MQ sockets this flags is of no use\&. For standard sockets this means there is urgent data to read\&. Refer to the POLLPRI flag for more informations\&. For file descriptor, refer to your use case: as an example, GPIO interrupts are signaled through a POLLPRI event\&. This flag has no effect on Windows\&. -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -The \fIzmq_poll()\fR function may be implemented or emulated using operating system interfaces other than \fIpoll()\fR, and as such may be subject to the limits of those interfaces in ways not defined in this documentation\&. -.sp .5v -.RE -.SH "RETURN VALUE" -.sp -Upon successful completion, the \fIzmq_poll()\fR function shall return the number of \fBzmq_pollitem_t\fR structures with events signaled in \fIrevents\fR or 0 if no events have been signaled\&. Upon failure, \fIzmq_poll()\fR shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBETERM\fR -.RS 4 -At least one of the members of the -\fIitems\fR -array refers to a -\fIsocket\fR -whose associated 0MQ -\fIcontext\fR -was terminated\&. -.RE -.PP -\fBEFAULT\fR -.RS 4 -The provided -\fIitems\fR -was not valid (NULL)\&. -.RE -.PP -\fBEINTR\fR -.RS 4 -The operation was interrupted by delivery of a signal before any events were available\&. -.RE -.SH "EXAMPLE" -.PP -\fBPolling indefinitely for input events on both a 0MQ socket and a standard socket.\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zmq_pollitem_t items [2]; -/* First item refers to 0MQ socket \*(Aqsocket\*(Aq */ -items[0]\&.socket = socket; -items[0]\&.events = ZMQ_POLLIN; -/* Second item refers to standard socket \*(Aqfd\*(Aq */ -items[1]\&.socket = NULL; -items[1]\&.fd = fd; -items[1]\&.events = ZMQ_POLLIN; -/* Poll for events indefinitely */ -int rc = zmq_poll (items, 2, \-1); -assert (rc >= 0); -/* Returned events will be stored in items[]\&.revents */ -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_socket\fR(3) \fBzmq_send\fR(3) \fBzmq_recv\fR(3) \fBzmq\fR(7) -.sp -Your operating system documentation for the \fIpoll()\fR system call\&. -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_proxy.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_proxy.3 deleted file mode 100644 index 73b244b7f377c8..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_proxy.3 +++ /dev/null @@ -1,89 +0,0 @@ -'\" t -.\" Title: zmq_proxy -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_PROXY" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_proxy \- start built\-in 0MQ proxy -.SH "SYNOPSIS" -.sp -\fBint zmq_proxy (const void \fR\fB\fI*frontend\fR\fR\fB, const void \fR\fB\fI*backend\fR\fR\fB, const void \fR\fB\fI*capture\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_proxy()\fR function starts the built\-in 0MQ proxy in the current application thread\&. -.sp -The proxy connects a frontend socket to a backend socket\&. Conceptually, data flows from frontend to backend\&. Depending on the socket types, replies may flow in the opposite direction\&. The direction is conceptual only; the proxy is fully symmetric and there is no technical difference between frontend and backend\&. -.sp -Before calling \fIzmq_proxy()\fR you must set any socket options, and connect or bind both frontend and backend sockets\&. The two conventional proxy models are: -.sp -\fIzmq_proxy()\fR runs in the current thread and returns only if/when the current context is closed\&. -.sp -If the capture socket is not NULL, the proxy shall send all messages, received on both frontend and backend, to the capture socket\&. The capture socket should be a \fIZMQ_PUB\fR, \fIZMQ_DEALER\fR, \fIZMQ_PUSH\fR, or \fIZMQ_PAIR\fR socket\&. -.sp -Refer to \fBzmq_socket\fR(3) for a description of the available socket types\&. -.SH "EXAMPLE USAGE" -.SS "Shared Queue" -.sp -When the frontend is a ZMQ_ROUTER socket, and the backend is a ZMQ_DEALER socket, the proxy shall act as a shared queue that collects requests from a set of clients, and distributes these fairly among a set of services\&. Requests shall be fair\-queued from frontend connections and distributed evenly across backend connections\&. Replies shall automatically return to the client that made the original request\&. -.SS "Forwarder" -.sp -When the frontend is a ZMQ_XSUB socket, and the backend is a ZMQ_XPUB socket, the proxy shall act as a message forwarder that collects messages from a set of publishers and forwards these to a set of subscribers\&. This may be used to bridge networks transports, e\&.g\&. read on tcp:// and forward on pgm://\&. -.SS "Streamer" -.sp -When the frontend is a ZMQ_PULL socket, and the backend is a ZMQ_PUSH socket, the proxy shall collect tasks from a set of clients and forwards these to a set of workers using the pipeline pattern\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_proxy()\fR function always returns \-1 and \fIerrno\fR set to \fBETERM\fR or \fBEINTR\fR (the 0MQ \fIcontext\fR associated with either of the specified sockets was terminated)\&. -.SH "EXAMPLE" -.PP -\fBCreating a shared queue proxy\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Create frontend and backend sockets -void *frontend = zmq_socket (context, ZMQ_ROUTER); -assert (backend); -void *backend = zmq_socket (context, ZMQ_DEALER); -assert (frontend); -// Bind both sockets to TCP ports -assert (zmq_bind (frontend, "tcp://*:5555") == 0); -assert (zmq_bind (backend, "tcp://*:5556") == 0); -// Start the queue proxy, which runs until ETERM -zmq_proxy (frontend, backend, NULL); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_bind\fR(3) \fBzmq_connect\fR(3) \fBzmq_socket\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_proxy_steerable.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_proxy_steerable.3 deleted file mode 100644 index 2cf1209e9c7dd5..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_proxy_steerable.3 +++ /dev/null @@ -1,112 +0,0 @@ -'\" t -.\" Title: zmq_proxy_steerable -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_PROXY_STEERABLE" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_proxy_steerable \- built\-in 0MQ proxy with control flow -.SH "SYNOPSIS" -.sp -\fBint zmq_proxy_steerable (const void \fR\fB\fI*frontend\fR\fR\fB, const void \fR\fB\fI*backend\fR\fR\fB, const void \fR\fB\fI*capture\fR\fR\fB, const void \fR\fB\fI*control\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_proxy_steerable()\fR function starts the built\-in 0MQ proxy in the current application thread, as \fIzmq_proxy()\fR do\&. Please, refer to this function for the general description and usage\&. We describe here only the additional control flow provided by the socket passed as the fourth argument "control"\&. -.sp -If the control socket is not NULL, the proxy supports control flow\&. If \fIPAUSE\fR is received on this socket, the proxy suspends its activities\&. If \fIRESUME\fR is received, it goes on\&. If \fITERMINATE\fR is received, it terminates smoothly\&. At start, the proxy runs normally as if zmq_proxy was used\&. -.sp -If the control socket is NULL, the function behave exactly as if zmq_proxy had been called\&. -.sp -Refer to \fBzmq_socket\fR(3) for a description of the available socket types\&. Refer to \fBzmq_proxy\fR(3) for a description of the zmq_proxy\&. -.SH "EXAMPLE USAGE" -.sp -cf zmq_proxy -.SH "RETURN VALUE" -.sp -The \fIzmq_proxy_steerable()\fR function returns 0 if TERMINATE is sent to its control socket\&. Otherwise, it returns \-1 and \fIerrno\fR set to \fBETERM\fR or \fBEINTR\fR (the 0MQ \fIcontext\fR associated with either of the specified sockets was terminated)\&. -.SH "EXAMPLE" -.PP -\fBCreating a shared queue proxy\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Create frontend, backend and control sockets -void *frontend = zmq_socket (context, ZMQ_ROUTER); -assert (backend); -void *backend = zmq_socket (context, ZMQ_DEALER); -assert (frontend); -void *control = zmq_socket (context, ZMQ_SUB); -assert (control); - -// Bind sockets to TCP ports -assert (zmq_bind (frontend, "tcp://*:5555") == 0); -assert (zmq_bind (backend, "tcp://*:5556") == 0); -assert (zmq_connect (control, "tcp://*:5557") == 0); - -// Subscribe to the control socket since we have chosen SUB here -assert (zmq_setsockopt (control, ZMQ_SUBSCRIBE, "", 0)); - -// Start the queue proxy, which runs until ETERM or "TERMINATE" -// received on the control socket -zmq_proxy_steerable (frontend, backend, NULL, control); -.fi -.if n \{\ -.RE -.\} -.PP -\fBSet up a controller in another node, process or whatever\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -void *control = zmq_socket (context, ZMQ_PUB); -assert (control); -assert (zmq_bind (control, "tcp://*:5557") == 0); - -// pause the proxy -assert (zmq_send (control, "PAUSE", 5, 0) == 0); - -// resume the proxy -assert (zmq_send (control, "RESUME", 6, 0) == 0); - -// terminate the proxy -assert (zmq_send (control, "TERMINATE", 9, 0) == 0); -\-\-\- - - -SEE ALSO -.fi -.if n \{\ -.RE -.\} -.sp -\fBzmq_proxy\fR(3) \fBzmq_bind\fR(3) \fBzmq_connect\fR(3) \fBzmq_socket\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_recv.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_recv.3 deleted file mode 100644 index f90366ae309170..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_recv.3 +++ /dev/null @@ -1,122 +0,0 @@ -'\" t -.\" Title: zmq_recv -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_RECV" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_recv \- receive a message part from a socket -.SH "SYNOPSIS" -.sp -\fBint zmq_recv (void \fR\fB\fI*socket\fR\fR\fB, void \fR\fB\fI*buf\fR\fR\fB, size_t \fR\fB\fIlen\fR\fR\fB, int \fR\fB\fIflags\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_recv()\fR function shall receive a message from the socket referenced by the \fIsocket\fR argument and store it in the buffer referenced by the \fIbuf\fR argument\&. Any bytes exceeding the length specified by the \fIlen\fR argument shall be truncated\&. If there are no messages available on the specified \fIsocket\fR the \fIzmq_recv()\fR function shall block until the request can be satisfied\&. The \fIflags\fR argument is a combination of the flags defined below: The \fIbuf\fR argument may be null if len is zero\&. -.PP -\fBZMQ_DONTWAIT\fR -.RS 4 -Specifies that the operation should be performed in non\-blocking mode\&. If there are no messages available on the specified -\fIsocket\fR, the -\fIzmq_recv()\fR -function shall fail with -\fIerrno\fR -set to EAGAIN\&. -.RE -.SS "Multi\-part messages" -.sp -A 0MQ message is composed of 1 or more message parts\&. 0MQ ensures atomic delivery of messages: peers shall receive either all \fImessage parts\fR of a message or none at all\&. The total number of message parts is unlimited except by available memory\&. -.sp -An application that processes multi\-part messages must use the \fIZMQ_RCVMORE\fR \fBzmq_getsockopt\fR(3) option after calling \fIzmq_recv()\fR to determine if there are further parts to receive\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_recv()\fR function shall return number of bytes in the message if successful\&. Note that the value can exceed the value of the \fIlen\fR parameter in case the message was truncated\&. If not successful the function shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEAGAIN\fR -.RS 4 -Non\-blocking mode was requested and no messages are available at the moment\&. -.RE -.PP -\fBENOTSUP\fR -.RS 4 -The -\fIzmq_recv()\fR -operation is not supported by this socket type\&. -.RE -.PP -\fBEFSM\fR -.RS 4 -The -\fIzmq_recv()\fR -operation cannot be performed on this socket at the moment due to the socket not being in the appropriate state\&. This error may occur with socket types that switch between several states, such as ZMQ_REP\&. See the -\fImessaging patterns\fR -section of -\fBzmq_socket\fR(3) -for more information\&. -.RE -.PP -\fBETERM\fR -.RS 4 -The 0MQ -\fIcontext\fR -associated with the specified -\fIsocket\fR -was terminated\&. -.RE -.PP -\fBENOTSOCK\fR -.RS 4 -The provided -\fIsocket\fR -was invalid\&. -.RE -.PP -\fBEINTR\fR -.RS 4 -The operation was interrupted by delivery of a signal before a message was available\&. -.RE -.SH "EXAMPLE" -.PP -\fBReceiving a message from a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -char buf [256]; -nbytes = zmq_recv (socket, buf, 256, 0); -assert (nbytes != \-1); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_send\fR(3) \fBzmq_getsockopt\fR(3) \fBzmq_socket\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_recvmsg.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_recvmsg.3 deleted file mode 100644 index c3b0b44bb10e3f..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_recvmsg.3 +++ /dev/null @@ -1,175 +0,0 @@ -'\" t -.\" Title: zmq_recvmsg -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_RECVMSG" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_recvmsg \- receive a message part from a socket -.SH "SYNOPSIS" -.sp -\fBint zmq_recvmsg (void \fR\fB\fI*socket\fR\fR\fB, zmq_msg_t \fR\fB\fI*msg\fR\fR\fB, int \fR\fB\fIflags\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_recvmsg()\fR function shall receive a message part from the socket referenced by the \fIsocket\fR argument and store it in the message referenced by the \fImsg\fR argument\&. Any content previously stored in \fImsg\fR shall be properly deallocated\&. If there are no message parts available on the specified \fIsocket\fR the \fIzmq_recvmsg()\fR function shall block until the request can be satisfied\&. The \fIflags\fR argument is a combination of the flags defined below: -.PP -\fBZMQ_DONTWAIT\fR -.RS 4 -Specifies that the operation should be performed in non\-blocking mode\&. If there are no messages available on the specified -\fIsocket\fR, the -\fIzmq_recvmsg()\fR -function shall fail with -\fIerrno\fR -set to EAGAIN\&. -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -this API method is deprecated in favor of zmq_msg_recv(3)\&. -.sp .5v -.RE -.SS "Multi\-part messages" -.sp -A 0MQ message is composed of 1 or more message parts\&. Each message part is an independent \fIzmq_msg_t\fR in its own right\&. 0MQ ensures atomic delivery of messages: peers shall receive either all \fImessage parts\fR of a message or none at all\&. The total number of message parts is unlimited except by available memory\&. -.sp -An application that processes multi\-part messages must use the \fIZMQ_RCVMORE\fR \fBzmq_getsockopt\fR(3) option after calling \fIzmq_recvmsg()\fR to determine if there are further parts to receive\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_recvmsg()\fR function shall return number of bytes in the message if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEAGAIN\fR -.RS 4 -Non\-blocking mode was requested and no messages are available at the moment\&. -.RE -.PP -\fBENOTSUP\fR -.RS 4 -The -\fIzmq_recvmsg()\fR -operation is not supported by this socket type\&. -.RE -.PP -\fBEFSM\fR -.RS 4 -The -\fIzmq_recvmsg()\fR -operation cannot be performed on this socket at the moment due to the socket not being in the appropriate state\&. This error may occur with socket types that switch between several states, such as ZMQ_REP\&. See the -\fImessaging patterns\fR -section of -\fBzmq_socket\fR(3) -for more information\&. -.RE -.PP -\fBETERM\fR -.RS 4 -The 0MQ -\fIcontext\fR -associated with the specified -\fIsocket\fR -was terminated\&. -.RE -.PP -\fBENOTSOCK\fR -.RS 4 -The provided -\fIsocket\fR -was invalid\&. -.RE -.PP -\fBEINTR\fR -.RS 4 -The operation was interrupted by delivery of a signal before a message was available\&. -.RE -.PP -\fBEFAULT\fR -.RS 4 -The message passed to the function was invalid\&. -.RE -.SH "EXAMPLE" -.PP -\fBReceiving a message from a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -/* Create an empty 0MQ message */ -zmq_msg_t msg; -int rc = zmq_msg_init (&msg); -assert (rc == 0); -/* Block until a message is available to be received from socket */ -rc = zmq_recvmsg (socket, &msg, 0); -assert (rc != \-1); -/* Release message */ -zmq_msg_close (&msg); -.fi -.if n \{\ -.RE -.\} -.PP -\fBReceiving a multi-part message\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -int more; -size_t more_size = sizeof (more); -do { - /* Create an empty 0MQ message to hold the message part */ - zmq_msg_t part; - int rc = zmq_msg_init (&part); - assert (rc == 0); - /* Block until a message is available to be received from socket */ - rc = zmq_recvmsg (socket, &part, 0); - assert (rc != \-1); - /* Determine if more message parts are to follow */ - rc = zmq_getsockopt (socket, ZMQ_RCVMORE, &more, &more_size); - assert (rc == 0); - zmq_msg_close (&part); -} while (more); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_recv\fR(3) \fBzmq_send\fR(3) \fBzmq_getsockopt\fR(3) \fBzmq_socket\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_send.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_send.3 deleted file mode 100644 index f0bb2adadb310b..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_send.3 +++ /dev/null @@ -1,158 +0,0 @@ -'\" t -.\" Title: zmq_send -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_SEND" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_send \- send a message part on a socket -.SH "SYNOPSIS" -.sp -\fBint zmq_send (void \fR\fB\fI*socket\fR\fR\fB, void \fR\fB\fI*buf\fR\fR\fB, size_t \fR\fB\fIlen\fR\fR\fB, int \fR\fB\fIflags\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_send()\fR function shall queue a message created from the buffer referenced by the \fIbuf\fR and \fIlen\fR arguments\&. The \fIflags\fR argument is a combination of the flags defined below: -.PP -\fBZMQ_DONTWAIT\fR -.RS 4 -For socket types (DEALER, PUSH) that block when there are no available peers (or all peers have full high\-water mark), specifies that the operation should be performed in non\-blocking mode\&. If the message cannot be queued on the -\fIsocket\fR, the -\fIzmq_send()\fR -function shall fail with -\fIerrno\fR -set to EAGAIN\&. -.RE -.PP -\fBZMQ_SNDMORE\fR -.RS 4 -Specifies that the message being sent is a multi\-part message, and that further message parts are to follow\&. Refer to the section regarding multi\-part messages below for a detailed description\&. -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -A successful invocation of \fIzmq_send()\fR does not indicate that the message has been transmitted to the network, only that it has been queued on the \fIsocket\fR and 0MQ has assumed responsibility for the message\&. -.sp .5v -.RE -.SS "Multi\-part messages" -.sp -A 0MQ message is composed of 1 or more message parts\&. 0MQ ensures atomic delivery of messages: peers shall receive either all \fImessage parts\fR of a message or none at all\&. The total number of message parts is unlimited except by available memory\&. -.sp -An application that sends multi\-part messages must use the \fIZMQ_SNDMORE\fR flag when sending each message part except the final one\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_send()\fR function shall return number of bytes in the message if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEAGAIN\fR -.RS 4 -Non\-blocking mode was requested and the message cannot be sent at the moment\&. -.RE -.PP -\fBENOTSUP\fR -.RS 4 -The -\fIzmq_send()\fR -operation is not supported by this socket type\&. -.RE -.PP -\fBEINVAL\fR -.RS 4 -The sender tried to send multipart data, which the socket type does not allow\&. -.RE -.PP -\fBEFSM\fR -.RS 4 -The -\fIzmq_send()\fR -operation cannot be performed on this socket at the moment due to the socket not being in the appropriate state\&. This error may occur with socket types that switch between several states, such as ZMQ_REP\&. See the -\fImessaging patterns\fR -section of -\fBzmq_socket\fR(3) -for more information\&. -.RE -.PP -\fBETERM\fR -.RS 4 -The 0MQ -\fIcontext\fR -associated with the specified -\fIsocket\fR -was terminated\&. -.RE -.PP -\fBENOTSOCK\fR -.RS 4 -The provided -\fIsocket\fR -was invalid\&. -.RE -.PP -\fBEINTR\fR -.RS 4 -The operation was interrupted by delivery of a signal before the message was sent\&. -.RE -.PP -\fBEHOSTUNREACH\fR -.RS 4 -The message cannot be routed\&. -.RE -.SH "EXAMPLE" -.PP -\fBSending a multi-part message\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -/* Send a multi\-part message consisting of three parts to socket */ -rc = zmq_send (socket, "ABC", 3, ZMQ_SNDMORE); -assert (rc == 3); -rc = zmq_send (socket, "DEFGH", 5, ZMQ_SNDMORE); -assert (rc == 5); -/* Final part; no more parts to follow */ -rc = zmq_send (socket, "JK", 2, 0); -assert (rc == 2); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_send_const\fR(3) \fBzmq_recv\fR(3) \fBzmq_socket\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_send_const.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_send_const.3 deleted file mode 100644 index 11175ff3267475..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_send_const.3 +++ /dev/null @@ -1,153 +0,0 @@ -'\" t -.\" Title: zmq_send_const -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_SEND_CONST" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_send_const \- send a constant\-memory message part on a socket -.SH "SYNOPSIS" -.sp -\fBint zmq_send_const (void \fR\fB\fI*socket\fR\fR\fB, void \fR\fB\fI*buf\fR\fR\fB, size_t \fR\fB\fIlen\fR\fR\fB, int \fR\fB\fIflags\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_send_const()\fR function shall queue a message created from the buffer referenced by the \fIbuf\fR and \fIlen\fR arguments\&. The message buffer is assumed to be constant\-memory and will therefore not be copied or deallocated in any way\&. The \fIflags\fR argument is a combination of the flags defined below: -.PP -\fBZMQ_DONTWAIT\fR -.RS 4 -For socket types (DEALER, PUSH) that block when there are no available peers (or all peers have full high\-water mark), specifies that the operation should be performed in non\-blocking mode\&. If the message cannot be queued on the -\fIsocket\fR, the -\fIzmq_send_const()\fR -function shall fail with -\fIerrno\fR -set to EAGAIN\&. -.RE -.PP -\fBZMQ_SNDMORE\fR -.RS 4 -Specifies that the message being sent is a multi\-part message, and that further message parts are to follow\&. Refer to the section regarding multi\-part messages below for a detailed description\&. -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -A successful invocation of \fIzmq_send_const()\fR does not indicate that the message has been transmitted to the network, only that it has been queued on the \fIsocket\fR and 0MQ has assumed responsibility for the message\&. -.sp .5v -.RE -.SS "Multi\-part messages" -.sp -A 0MQ message is composed of 1 or more message parts\&. 0MQ ensures atomic delivery of messages: peers shall receive either all \fImessage parts\fR of a message or none at all\&. The total number of message parts is unlimited except by available memory\&. -.sp -An application that sends multi\-part messages must use the \fIZMQ_SNDMORE\fR flag when sending each message part except the final one\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_send_const()\fR function shall return number of bytes in the message if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEAGAIN\fR -.RS 4 -Non\-blocking mode was requested and the message cannot be sent at the moment\&. -.RE -.PP -\fBENOTSUP\fR -.RS 4 -The -\fIzmq_send_const()\fR -operation is not supported by this socket type\&. -.RE -.PP -\fBEFSM\fR -.RS 4 -The -\fIzmq_send_const()\fR -operation cannot be performed on this socket at the moment due to the socket not being in the appropriate state\&. This error may occur with socket types that switch between several states, such as ZMQ_REP\&. See the -\fImessaging patterns\fR -section of -\fBzmq_socket\fR(3) -for more information\&. -.RE -.PP -\fBETERM\fR -.RS 4 -The 0MQ -\fIcontext\fR -associated with the specified -\fIsocket\fR -was terminated\&. -.RE -.PP -\fBENOTSOCK\fR -.RS 4 -The provided -\fIsocket\fR -was invalid\&. -.RE -.PP -\fBEINTR\fR -.RS 4 -The operation was interrupted by delivery of a signal before the message was sent\&. -.RE -.PP -\fBEHOSTUNREACH\fR -.RS 4 -The message cannot be routed\&. -.RE -.SH "EXAMPLE" -.PP -\fBSending a multi-part message\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -/* Send a multi\-part message consisting of three parts to socket */ -rc = zmq_send_const (socket, "ABC", 3, ZMQ_SNDMORE); -assert (rc == 3); -rc = zmq_send_const (socket, "DEFGH", 5, ZMQ_SNDMORE); -assert (rc == 5); -/* Final part; no more parts to follow */ -rc = zmq_send_const (socket, "JK", 2, 0); -assert (rc == 2); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_send\fR(3) \fBzmq_recv\fR(3) \fBzmq_socket\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_sendmsg.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_sendmsg.3 deleted file mode 100644 index 4074be3a45056a..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_sendmsg.3 +++ /dev/null @@ -1,198 +0,0 @@ -'\" t -.\" Title: zmq_sendmsg -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_SENDMSG" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_sendmsg \- send a message part on a socket -.SH "SYNOPSIS" -.sp -\fBint zmq_sendmsg (void \fR\fB\fI*socket\fR\fR\fB, zmq_msg_t \fR\fB\fI*msg\fR\fR\fB, int \fR\fB\fIflags\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_sendmsg()\fR function shall queue the message referenced by the \fImsg\fR argument to be sent to the socket referenced by the \fIsocket\fR argument\&. The \fIflags\fR argument is a combination of the flags defined below: -.PP -\fBZMQ_DONTWAIT\fR -.RS 4 -For socket types (DEALER, PUSH) that block when there are no available peers (or all peers have full high\-water mark), specifies that the operation should be performed in non\-blocking mode\&. If the message cannot be queued on the -\fIsocket\fR, the -\fIzmq_sendmsg()\fR -function shall fail with -\fIerrno\fR -set to EAGAIN\&. -.RE -.PP -\fBZMQ_SNDMORE\fR -.RS 4 -Specifies that the message being sent is a multi\-part message, and that further message parts are to follow\&. Refer to the section regarding multi\-part messages below for a detailed description\&. -.RE -.sp -The \fIzmq_msg_t\fR structure passed to \fIzmq_sendmsg()\fR is nullified during the call\&. If you want to send the same message to multiple sockets you have to copy it (e\&.g\&. using \fIzmq_msg_copy()\fR)\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -A successful invocation of \fIzmq_sendmsg()\fR does not indicate that the message has been transmitted to the network, only that it has been queued on the \fIsocket\fR and 0MQ has assumed responsibility for the message\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -this API method is deprecated in favor of zmq_msg_send(3)\&. -.sp .5v -.RE -.SS "Multi\-part messages" -.sp -A 0MQ message is composed of 1 or more message parts\&. Each message part is an independent \fIzmq_msg_t\fR in its own right\&. 0MQ ensures atomic delivery of messages: peers shall receive either all \fImessage parts\fR of a message or none at all\&. The total number of message parts is unlimited except by available memory\&. -.sp -An application that sends multi\-part messages must use the \fIZMQ_SNDMORE\fR flag when sending each message part except the final one\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_sendmsg()\fR function shall return number of bytes in the message if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEAGAIN\fR -.RS 4 -Non\-blocking mode was requested and the message cannot be sent at the moment\&. -.RE -.PP -\fBENOTSUP\fR -.RS 4 -The -\fIzmq_sendmsg()\fR -operation is not supported by this socket type\&. -.RE -.PP -\fBEINVAL\fR -.RS 4 -The sender tried to send multipart data, which the socket type does not allow\&. -.RE -.PP -\fBEFSM\fR -.RS 4 -The -\fIzmq_sendmsg()\fR -operation cannot be performed on this socket at the moment due to the socket not being in the appropriate state\&. This error may occur with socket types that switch between several states, such as ZMQ_REP\&. See the -\fImessaging patterns\fR -section of -\fBzmq_socket\fR(3) -for more information\&. -.RE -.PP -\fBETERM\fR -.RS 4 -The 0MQ -\fIcontext\fR -associated with the specified -\fIsocket\fR -was terminated\&. -.RE -.PP -\fBENOTSOCK\fR -.RS 4 -The provided -\fIsocket\fR -was invalid\&. -.RE -.PP -\fBEINTR\fR -.RS 4 -The operation was interrupted by delivery of a signal before the message was sent\&. -.RE -.PP -\fBEFAULT\fR -.RS 4 -Invalid message\&. -.RE -.PP -\fBEHOSTUNREACH\fR -.RS 4 -The message cannot be routed\&. -.RE -.SH "EXAMPLE" -.PP -\fBFilling in a message and sending it to a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -/* Create a new message, allocating 6 bytes for message content */ -zmq_msg_t msg; -int rc = zmq_msg_init_size (&msg, 6); -assert (rc == 0); -/* Fill in message content with \*(AqAAAAAA\*(Aq */ -memset (zmq_msg_data (&msg), \*(AqA\*(Aq, 6); -/* Send the message to the socket */ -rc = zmq_sendmsg (socket, &msg, 0); -assert (rc == 6); -.fi -.if n \{\ -.RE -.\} -.PP -\fBSending a multi-part message\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -/* Send a multi\-part message consisting of three parts to socket */ -rc = zmq_sendmsg (socket, &part1, ZMQ_SNDMORE); -rc = zmq_sendmsg (socket, &part2, ZMQ_SNDMORE); -/* Final part; no more parts to follow */ -rc = zmq_sendmsg (socket, &part3, 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_recv\fR(3) \fBzmq_socket\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_setsockopt.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_setsockopt.3 deleted file mode 100644 index af381286e8fb3d..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_setsockopt.3 +++ /dev/null @@ -1,3201 +0,0 @@ -'\" t -.\" Title: zmq_setsockopt -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_SETSOCKOPT" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_setsockopt \- set 0MQ socket options -.SH "SYNOPSIS" -.sp -\fBint zmq_setsockopt (void \fR\fB\fI*socket\fR\fR\fB, int \fR\fB\fIoption_name\fR\fR\fB, const void \fR\fB\fI*option_value\fR\fR\fB, size_t \fR\fB\fIoption_len\fR\fR\fB);\fR -.sp -Caution: All options, with the exception of ZMQ_SUBSCRIBE, ZMQ_UNSUBSCRIBE, ZMQ_LINGER, ZMQ_ROUTER_HANDOVER, ZMQ_ROUTER_MANDATORY, ZMQ_PROBE_ROUTER, ZMQ_XPUB_VERBOSE, ZMQ_XPUB_VERBOSER, ZMQ_REQ_CORRELATE, ZMQ_REQ_RELAXED, ZMQ_SNDHWM and ZMQ_RCVHWM, only take effect for subsequent socket bind/connects\&. -.sp -Specifically, security options take effect for subsequent bind/connect calls, and can be changed at any time to affect subsequent binds and/or connects\&. -.SH "DESCRIPTION" -.sp -The \fIzmq_setsockopt()\fR function shall set the option specified by the \fIoption_name\fR argument to the value pointed to by the \fIoption_value\fR argument for the 0MQ socket pointed to by the \fIsocket\fR argument\&. The \fIoption_len\fR argument is the size of the option value in bytes\&. For options taking a value of type "character string", the provided byte data should either contain no zero bytes, or end in a single zero byte (terminating ASCII NUL character)\&. -.sp -The following socket options can be set with the \fIzmq_setsockopt()\fR function: -.SS "ZMQ_AFFINITY: Set I/O thread affinity" -.sp -The \fIZMQ_AFFINITY\fR option shall set the I/O thread affinity for newly created connections on the specified \fIsocket\fR\&. -.sp -Affinity determines which threads from the 0MQ I/O thread pool associated with the socket\(cqs \fIcontext\fR shall handle newly created connections\&. A value of zero specifies no affinity, meaning that work shall be distributed fairly among all 0MQ I/O threads in the thread pool\&. For non\-zero values, the lowest bit corresponds to thread 1, second lowest bit to thread 2 and so on\&. For example, a value of 3 specifies that subsequent connections on \fIsocket\fR shall be handled exclusively by I/O threads 1 and 2\&. -.sp -See also \fBzmq_init\fR(3) for details on allocating the number of I/O threads for a specific \fIcontext\fR\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -uint64_t -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A (bitmap) -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -N/A -T} -.TE -.sp 1 -.SS "ZMQ_BACKLOG: Set maximum length of the queue of outstanding connections" -.sp -The \fIZMQ_BACKLOG\fR option shall set the maximum length of the queue of outstanding peer connections for the specified \fIsocket\fR; this only applies to connection\-oriented transports\&. For details refer to your operating system documentation for the \fIlisten\fR function\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -connections -T} -T{ -.sp -Default value -T}:T{ -.sp -100 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, only for connection\-oriented transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_CONNECT_RID: Assign the next outbound connection id" -.sp -The \fIZMQ_CONNECT_RID\fR option sets the peer id of the next host connected via the zmq_connect() call, and immediately readies that connection for data transfer with the named id\&. This option applies only to the first subsequent call to zmq_connect(), calls thereafter use default connection behaviour\&. -.sp -Typical use is to set this socket option ahead of each zmq_connect() attempt to a new host\&. Each connection MUST be assigned a unique name\&. Assigning a name that is already in use is not allowed\&. -.sp -Useful when connecting ROUTER to ROUTER, or STREAM to STREAM, as it allows for immediate sending to peers\&. Outbound id framing requirements for ROUTER and STREAM sockets apply\&. -.sp -The peer id should be from 1 to 255 bytes long and MAY NOT start with binary zero\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -binary data -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -NULL -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_ROUTER, ZMQ_STREAM -T} -.TE -.sp 1 -.SS "ZMQ_CONFLATE: Keep only last message" -.sp -If set, a socket shall keep only one message in its inbound/outbound queue, this message being the last message received/the last message to be sent\&. Ignores \fIZMQ_RCVHWM\fR and \fIZMQ_SNDHWM\fR options\&. Does not support multi\-part messages, in particular, only one part of it is kept in the socket internal queue\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -boolean -T} -T{ -.sp -Default value -T}:T{ -.sp -0 (false) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_PULL, ZMQ_PUSH, ZMQ_SUB, ZMQ_PUB, ZMQ_DEALER -T} -.TE -.sp 1 -.SS "ZMQ_CONNECT_TIMEOUT: Set connect() timeout" -.sp -Sets how long to wait before timing\-out a connect() system call\&. The connect() system call normally takes a long time before it returns a time out error\&. Setting this option allows the library to time out the call at an earlier interval\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -0 (disabled) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_CURVE_PUBLICKEY: Set CURVE public key" -.sp -Sets the socket\(cqs long term public key\&. You must set this on CURVE client sockets, see \fBzmq_curve\fR(7)\&. You can provide the key as 32 binary bytes, or as a 40\-character string encoded in the Z85 encoding format and terminated in a null byte\&. The public key must always be used with the matching secret key\&. To generate a public/secret key pair, use \fBzmq_curve_keypair\fR(3)\&. To derive the public key from a secret key, use \fBzmq_curve_public\fR(3)\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -an option value size of 40 is supported for backwards compatibility, though is deprecated\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -binary data or Z85 text string -T} -T{ -.sp -Option value size -T}:T{ -.sp -32 or 41 -T} -T{ -.sp -Default value -T}:T{ -.sp -NULL -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_CURVE_SECRETKEY: Set CURVE secret key" -.sp -Sets the socket\(cqs long term secret key\&. You must set this on both CURVE client and server sockets, see \fBzmq_curve\fR(7)\&. You can provide the key as 32 binary bytes, or as a 40\-character string encoded in the Z85 encoding format and terminated in a null byte\&. To generate a public/secret key pair, use \fBzmq_curve_keypair\fR(3)\&. To derive the public key from a secret key, use \fBzmq_curve_public\fR(3)\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -an option value size of 40 is supported for backwards compatibility, though is deprecated\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -binary data or Z85 text string -T} -T{ -.sp -Option value size -T}:T{ -.sp -32 or 41 -T} -T{ -.sp -Default value -T}:T{ -.sp -NULL -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_CURVE_SERVER: Set CURVE server role" -.sp -Defines whether the socket will act as server for CURVE security, see \fBzmq_curve\fR(7)\&. A value of \fI1\fR means the socket will act as CURVE server\&. A value of \fI0\fR means the socket will not act as CURVE server, and its security role then depends on other option settings\&. Setting this to \fI0\fR shall reset the socket security to NULL\&. When you set this you must also set the server\(cqs secret key using the ZMQ_CURVE_SECRETKEY option\&. A server socket does not need to know its own public key\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_CURVE_SERVERKEY: Set CURVE server key" -.sp -Sets the socket\(cqs long term server key\&. You must set this on CURVE client sockets, see \fBzmq_curve\fR(7)\&. You can provide the key as 32 binary bytes, or as a 40\-character string encoded in the Z85 encoding format and terminated in a null byte\&. This key must have been generated together with the server\(cqs secret key\&. To generate a public/secret key pair, use \fBzmq_curve_keypair\fR(3)\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -an option value size of 40 is supported for backwards compatibility, though is deprecated\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -binary data or Z85 text string -T} -T{ -.sp -Option value size -T}:T{ -.sp -32 or 41 -T} -T{ -.sp -Default value -T}:T{ -.sp -NULL -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_GSSAPI_PLAINTEXT: Disable GSSAPI encryption" -.sp -Defines whether communications on the socket will be encrypted, see \fBzmq_gssapi\fR(7)\&. A value of \fI1\fR means that communications will be plaintext\&. A value of \fI0\fR means communications will be encrypted\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 (false) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_GSSAPI_PRINCIPAL: Set name of GSSAPI principal" -.sp -Sets the name of the principal for whom GSSAPI credentials should be acquired\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -character string -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -not set -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_GSSAPI_SERVER: Set GSSAPI server role" -.sp -Defines whether the socket will act as server for GSSAPI security, see \fBzmq_gssapi\fR(7)\&. A value of \fI1\fR means the socket will act as GSSAPI server\&. A value of \fI0\fR means the socket will act as GSSAPI client\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 (false) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_GSSAPI_SERVICE_PRINCIPAL: Set name of GSSAPI service principal" -.sp -Sets the name of the principal of the GSSAPI server to which a GSSAPI client intends to connect\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -character string -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -not set -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_HANDSHAKE_IVL: Set maximum handshake interval" -.sp -The \fIZMQ_HANDSHAKE_IVL\fR option shall set the maximum handshake interval for the specified \fIsocket\fR\&. Handshaking is the exchange of socket configuration information (socket type, identity, security) that occurs when a connection is first opened, only for connection\-oriented transports\&. If handshaking does not complete within the configured time, the connection shall be closed\&. The value 0 means no handshake time limit\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -30000 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all but ZMQ_STREAM, only for connection\-oriented transports -T} -.TE -.sp 1 -.SS "ZMQ_HEARTBEAT_IVL: Set interval between sending ZMTP heartbeats" -.sp -The \fIZMQ_HEARTBEAT_IVL\fR option shall set the interval between sending ZMTP heartbeats for the specified \fIsocket\fR\&. If this option is set and is greater than 0, then a \fIPING\fR ZMTP command will be sent every \fIZMQ_HEARTBEAT_IVL\fR milliseconds\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using connection\-oriented transports -T} -.TE -.sp 1 -.SS "ZMQ_HEARTBEAT_TIMEOUT: Set timeout for ZMTP heartbeats" -.sp -The \fIZMQ_HEARTBEAT_TIMEOUT\fR option shall set how long to wait before timing\-out a connection after sending a \fIPING\fR ZMTP command and not receiving any traffic\&. This option is only valid if \fIZMQ_HEARTBEAT_IVL\fR is also set, and is greater than 0\&. The connection will time out if there is no traffic received after sending the \fIPING\fR command, but the received traffic does not have to be a \fIPONG\fR command \- any received traffic will cancel the timeout\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using connection\-oriented transports -T} -.TE -.sp 1 -.SS "ZMQ_HEARTBEAT_TTL: Set the TTL value for ZMTP heartbeats" -.sp -The \fIZMQ_HEARTBEAT_TTL\fR option shall set the timeout on the remote peer for ZMTP heartbeats\&. If this option is greater than 0, the remote side shall time out the connection if it does not receive any more traffic within the TTL period\&. This option does not have any effect if \fIZMQ_HEARTBEAT_IVL\fR is not set or is 0\&. Internally, this value is rounded down to the nearest decisecond, any value less than 100 will have no effect\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using connection\-oriented transports -T} -.TE -.sp 1 -.SS "ZMQ_IDENTITY: Set socket identity" -.sp -The \fIZMQ_IDENTITY\fR option shall set the identity of the specified \fIsocket\fR when connecting to a ROUTER socket\&. The identity should be from 1 to 255 bytes long and may contain any values\&. -.sp -If two clients use the same identity when connecting to a ROUTER, the results shall depend on the ZMQ_ROUTER_HANDOVER option setting\&. If that is not set (or set to the default of zero), the ROUTER socket shall reject clients trying to connect with an already\-used identity\&. If that option is set to 1, the ROUTER socket shall hand\-over the connection to the new client and disconnect the existing one\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -binary data -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -NULL -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_REQ, ZMQ_REP, ZMQ_ROUTER, ZMQ_DEALER\&. -T} -.TE -.sp 1 -.SS "ZMQ_IMMEDIATE: Queue messages only to completed connections" -.sp -By default queues will fill on outgoing connections even if the connection has not completed\&. This can lead to "lost" messages on sockets with round\-robin routing (REQ, PUSH, DEALER)\&. If this option is set to 1, messages shall be queued only to completed connections\&. This will cause the socket to block if there are no other connections, but will prevent queues from filling on pipes awaiting connection\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -boolean -T} -T{ -.sp -Default value -T}:T{ -.sp -0 (false) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, only for connection\-oriented transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_INVERT_MATCHING: Invert message filtering" -.sp -Reverses the filtering behavior of PUB\-SUB sockets, when set to 1\&. -.sp -On \fIPUB\fR and \fIXPUB\fR sockets, this causes messages to be sent to all connected sockets \fIexcept\fR those subscribed to a prefix that matches the message\&. On \fISUB\fR sockets, this causes only incoming messages that do \fInot\fR match any of the socket\(cqs subscriptions to be received by the user\&. -.sp -Whenever \fIZMQ_INVERT_MATCHING\fR is set to 1 on a \fIPUB\fR socket, all \fISUB\fR sockets connecting to it must also have the option set to 1\&. Failure to do so will have the \fISUB\fR sockets reject everything the \fIPUB\fR socket sends them\&. \fIXSUB\fR sockets do not need to do this because they do not filter incoming messages\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0,1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_PUB, ZMQ_XPUB, ZMQ_SUB -T} -.TE -.sp 1 -.SS "ZMQ_IPV6: Enable IPv6 on socket" -.sp -Set the IPv6 option for the socket\&. A value of 1 means IPv6 is enabled on the socket, while 0 means the socket will use only IPv4\&. When IPv6 is enabled the socket will connect to, or accept connections from, both IPv4 and IPv6 hosts\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -boolean -T} -T{ -.sp -Default value -T}:T{ -.sp -0 (false) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_LINGER: Set linger period for socket shutdown" -.sp -The \fIZMQ_LINGER\fR option shall set the linger period for the specified \fIsocket\fR\&. The linger period determines how long pending messages which have yet to be sent to a peer shall linger in memory after a socket is disconnected with \fBzmq_disconnect\fR(3) or closed with \fBzmq_close\fR(3), and further affects the termination of the socket\(cqs context with \fBzmq_ctx_term\fR(3)\&. The following outlines the different behaviours: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -A value of -\fI\-1\fR -specifies an infinite linger period\&. Pending messages shall not be discarded after a call to -\fIzmq_disconnect()\fR -or -\fIzmq_close()\fR; attempting to terminate the socket\(cqs context with -\fIzmq_ctx_term()\fR -shall block until all pending messages have been sent to a peer\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The value of -\fI0\fR -specifies no linger period\&. Pending messages shall be discarded immediately after a call to -\fIzmq_disconnect()\fR -or -\fIzmq_close()\fR\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Positive values specify an upper bound for the linger period in milliseconds\&. Pending messages shall not be discarded after a call to -\fIzmq_disconnect()\fR -or -\fIzmq_close()\fR; attempting to terminate the socket\(cqs context with -\fIzmq_ctx_term()\fR -shall block until either all pending messages have been sent to a peer, or the linger period expires, after which any pending messages shall be discarded\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -Option value type -T}:T{ -int -T} -T{ -Option value unit -T}:T{ -milliseconds -T} -T{ -Default value -T}:T{ -30000 (thirty seconds) -T} -T{ -Applicable socket types -T}:T{ -all -T} -.TE -.sp 1 -.RE -.SS "ZMQ_MAXMSGSIZE: Maximum acceptable inbound message size" -.sp -Limits the size of the inbound message\&. If a peer sends a message larger than ZMQ_MAXMSGSIZE it is disconnected\&. Value of \-1 means \fIno limit\fR\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int64_t -T} -T{ -.sp -Option value unit -T}:T{ -.sp -bytes -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_MULTICAST_HOPS: Maximum network hops for multicast packets" -.sp -Sets the time\-to\-live field in every multicast packet sent from this socket\&. The default is 1 which means that the multicast packets don\(cqt leave the local network\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -network hops -T} -T{ -.sp -Default value -T}:T{ -.sp -1 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using multicast transports -T} -.TE -.sp 1 -.SS "ZMQ_MULTICAST_MAXTPDU: Maximum transport data unit size for multicast packets" -.sp -Sets the maximum transport data unit size used for outbound multicast packets\&. -.sp -This must be set at or below the minimum Maximum Transmission Unit (MTU) for all network paths over which multicast reception is required\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -bytes -T} -T{ -.sp -Default value -T}:T{ -.sp -1500 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using multicast transports -T} -.TE -.sp 1 -.SS "ZMQ_PLAIN_PASSWORD: Set PLAIN security password" -.sp -Sets the password for outgoing connections over TCP or IPC\&. If you set this to a non\-null value, the security mechanism used for connections shall be PLAIN, see \fBzmq_plain\fR(7)\&. If you set this to a null value, the security mechanism used for connections shall be NULL, see \fBzmq_null\fR(3)\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -character string -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -not set -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_PLAIN_SERVER: Set PLAIN server role" -.sp -Defines whether the socket will act as server for PLAIN security, see \fBzmq_plain\fR(7)\&. A value of \fI1\fR means the socket will act as PLAIN server\&. A value of \fI0\fR means the socket will not act as PLAIN server, and its security role then depends on other option settings\&. Setting this to \fI0\fR shall reset the socket security to NULL\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_PLAIN_USERNAME: Set PLAIN security username" -.sp -Sets the username for outgoing connections over TCP or IPC\&. If you set this to a non\-null value, the security mechanism used for connections shall be PLAIN, see \fBzmq_plain\fR(7)\&. If you set this to a null value, the security mechanism used for connections shall be NULL, see \fBzmq_null\fR(3)\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -character string -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -not set -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_USE_FD: Set the pre\-allocated socket file descriptor" -.sp -When set to a positive integer value before zmq_bind is called on the socket, the socket shall use the corresponding file descriptor for connections over TCP or IPC instead of allocating a new file descriptor\&. Useful for writing systemd socket activated services\&. If set to \-1 (default), a new file descriptor will be allocated instead (default behaviour)\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -if set after calling zmq_bind, this option shall have no effect\&. NOTE: the file descriptor passed through MUST have been ran through the "bind" and "listen" system calls beforehand\&. Also, socket option that would normally be passed through zmq_setsockopt like TCP buffers length, IP_TOS or SO_REUSEADDR MUST be set beforehand by the caller, as they must be set before the socket is bound\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -file descriptor -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all bound sockets, when using IPC or TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_PROBE_ROUTER: bootstrap connections to ROUTER sockets" -.sp -When set to 1, the socket will automatically send an empty message when a new connection is made or accepted\&. You may set this on REQ, DEALER, or ROUTER sockets connected to a ROUTER socket\&. The application must filter such empty messages\&. The ZMQ_PROBE_ROUTER option in effect provides the ROUTER application with an event signaling the arrival of a new peer\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -do not set this option on a socket that talks to any other socket types: the results are undefined\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_ROUTER, ZMQ_DEALER, ZMQ_REQ -T} -.TE -.sp 1 -.SS "ZMQ_RATE: Set multicast data rate" -.sp -The \fIZMQ_RATE\fR option shall set the maximum send or receive data rate for multicast transports such as \fBzmq_pgm\fR(7) using the specified \fIsocket\fR\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -kilobits per second -T} -T{ -.sp -Default value -T}:T{ -.sp -100 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using multicast transports -T} -.TE -.sp 1 -.SS "ZMQ_RCVBUF: Set kernel receive buffer size" -.sp -The \fIZMQ_RCVBUF\fR option shall set the underlying kernel receive buffer size for the \fIsocket\fR to the specified size in bytes\&. A value of \-1 means leave the OS default unchanged\&. For details refer to your operating system documentation for the \fISO_RCVBUF\fR socket option\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -bytes -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_RCVHWM: Set high water mark for inbound messages" -.sp -The \fIZMQ_RCVHWM\fR option shall set the high water mark for inbound messages on the specified \fIsocket\fR\&. The high water mark is a hard limit on the maximum number of outstanding messages 0MQ shall queue in memory for any single peer that the specified \fIsocket\fR is communicating with\&. A value of zero means no limit\&. -.sp -If this limit has been reached the socket shall enter an exceptional state and depending on the socket type, 0MQ shall take appropriate action such as blocking or dropping sent messages\&. Refer to the individual socket descriptions in \fBzmq_socket\fR(3) for details on the exact action taken for each socket type\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -messages -T} -T{ -.sp -Default value -T}:T{ -.sp -1000 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_RCVTIMEO: Maximum time before a recv operation returns with EAGAIN" -.sp -Sets the timeout for receive operation on the socket\&. If the value is 0, \fIzmq_recv(3)\fR will return immediately, with a EAGAIN error if there is no message to receive\&. If the value is \-1, it will block until a message is available\&. For all other values, it will wait for a message for that amount of time before returning with an EAGAIN error\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 (infinite) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_RECONNECT_IVL: Set reconnection interval" -.sp -The \fIZMQ_RECONNECT_IVL\fR option shall set the initial reconnection interval for the specified \fIsocket\fR\&. The reconnection interval is the period 0MQ shall wait between attempts to reconnect disconnected peers when using connection\-oriented transports\&. The value \-1 means no reconnection\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -The reconnection interval may be randomized by 0MQ to prevent reconnection storms in topologies with a large number of peers per socket\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -100 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, only for connection\-oriented transports -T} -.TE -.sp 1 -.SS "ZMQ_RECONNECT_IVL_MAX: Set maximum reconnection interval" -.sp -The \fIZMQ_RECONNECT_IVL_MAX\fR option shall set the maximum reconnection interval for the specified \fIsocket\fR\&. This is the maximum period 0MQ shall wait between attempts to reconnect\&. On each reconnect attempt, the previous interval shall be doubled untill ZMQ_RECONNECT_IVL_MAX is reached\&. This allows for exponential backoff strategy\&. Default value means no exponential backoff is performed and reconnect interval calculations are only based on ZMQ_RECONNECT_IVL\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -Values less than ZMQ_RECONNECT_IVL will be ignored\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -0 (only use ZMQ_RECONNECT_IVL) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, only for connection\-oriented transports -T} -.TE -.sp 1 -.SS "ZMQ_RECOVERY_IVL: Set multicast recovery interval" -.sp -The \fIZMQ_RECOVERY_IVL\fR option shall set the recovery interval for multicast transports using the specified \fIsocket\fR\&. The recovery interval determines the maximum time in milliseconds that a receiver can be absent from a multicast group before unrecoverable data loss will occur\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -Exercise care when setting large recovery intervals as the data needed for recovery will be held in memory\&. For example, a 1 minute recovery interval at a data rate of 1Gbps requires a 7GB in\-memory buffer\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -10000 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using multicast transports -T} -.TE -.sp 1 -.SS "ZMQ_REQ_CORRELATE: match replies with requests" -.sp -The default behaviour of REQ sockets is to rely on the ordering of messages to match requests and responses and that is usually sufficient\&. When this option is set to 1, the REQ socket will prefix outgoing messages with an extra frame containing a request id\&. That means the full message is (request id, 0, user frames\&...)\&. The REQ socket will discard all incoming messages that don\(cqt begin with these two frames\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_REQ -T} -.TE -.sp 1 -.SS "ZMQ_REQ_RELAXED: relax strict alternation between request and reply" -.sp -By default, a REQ socket does not allow initiating a new request with \fIzmq_send(3)\fR until the reply to the previous one has been received\&. When set to 1, sending another message is allowed and previous replies will be discarded if any\&. The request\-reply state machine is reset and a new request is sent to the next available peer\&. -.sp -If set to 1, also enable ZMQ_REQ_CORRELATE to ensure correct matching of requests and replies\&. Otherwise a late reply to an aborted request can be reported as the reply to the superseding request\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_REQ -T} -.TE -.sp 1 -.SS "ZMQ_ROUTER_HANDOVER: handle duplicate client identities on ROUTER sockets" -.sp -If two clients use the same identity when connecting to a ROUTER, the results shall depend on the ZMQ_ROUTER_HANDOVER option setting\&. If that is not set (or set to the default of zero), the ROUTER socket shall reject clients trying to connect with an already\-used identity\&. If that option is set to 1, the ROUTER socket shall hand\-over the connection to the new client and disconnect the existing one\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_ROUTER -T} -.TE -.sp 1 -.SS "ZMQ_ROUTER_MANDATORY: accept only routable messages on ROUTER sockets" -.sp -Sets the ROUTER socket behaviour when an unroutable message is encountered\&. A value of 0 is the default and discards the message silently when it cannot be routed or the peers SNDHWM is reached\&. A value of 1 returns an \fIEHOSTUNREACH\fR error code if the message cannot be routed or \fIEAGAIN\fR error code if the SNDHWM is reached and ZMQ_DONTWAIT was used\&. Without ZMQ_DONTWAIT it will block until the SNDTIMEO is reached or a spot in the send queue opens up\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_ROUTER -T} -.TE -.sp 1 -.SS "ZMQ_ROUTER_RAW: switch ROUTER socket to raw mode" -.sp -Sets the raw mode on the ROUTER, when set to 1\&. When the ROUTER socket is in raw mode, and when using the tcp:// transport, it will read and write TCP data without 0MQ framing\&. This lets 0MQ applications talk to non\-0MQ applications\&. When using raw mode, you cannot set explicit identities, and the ZMQ_SNDMORE flag is ignored when sending data messages\&. In raw mode you can close a specific connection by sending it a zero\-length message (following the identity frame)\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -This option is deprecated, please use ZMQ_STREAM sockets instead\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_ROUTER -T} -.TE -.sp 1 -.SS "ZMQ_SNDBUF: Set kernel transmit buffer size" -.sp -The \fIZMQ_SNDBUF\fR option shall set the underlying kernel transmit buffer size for the \fIsocket\fR to the specified size in bytes\&. A value of \-1 means leave the OS default unchanged\&. For details please refer to your operating system documentation for the \fISO_SNDBUF\fR socket option\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -bytes -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_SNDHWM: Set high water mark for outbound messages" -.sp -The \fIZMQ_SNDHWM\fR option shall set the high water mark for outbound messages on the specified \fIsocket\fR\&. The high water mark is a hard limit on the maximum number of outstanding messages 0MQ shall queue in memory for any single peer that the specified \fIsocket\fR is communicating with\&. A value of zero means no limit\&. -.sp -If this limit has been reached the socket shall enter an exceptional state and depending on the socket type, 0MQ shall take appropriate action such as blocking or dropping sent messages\&. Refer to the individual socket descriptions in \fBzmq_socket\fR(3) for details on the exact action taken for each socket type\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -0MQ does not guarantee that the socket will accept as many as ZMQ_SNDHWM messages, and the actual limit may be as much as 60\-70% lower depending on the flow of messages on the socket\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -messages -T} -T{ -.sp -Default value -T}:T{ -.sp -1000 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_SNDTIMEO: Maximum time before a send operation returns with EAGAIN" -.sp -Sets the timeout for send operation on the socket\&. If the value is 0, \fIzmq_send(3)\fR will return immediately, with a EAGAIN error if the message cannot be sent\&. If the value is \-1, it will block until the message is sent\&. For all other values, it will try to send the message for that amount of time before returning with an EAGAIN error\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 (infinite) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all -T} -.TE -.sp 1 -.SS "ZMQ_SOCKS_PROXY: Set SOCKS5 proxy address" -.sp -Sets the SOCKS5 proxy address that shall be used by the socket for the TCP connection(s)\&. Does not support SOCKS5 authentication\&. If the endpoints are domain names instead of addresses they shall not be resolved and they shall be forwarded unchanged to the SOCKS proxy service in the client connection request message (address type 0x03 domain name)\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -character string -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -not set -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_STREAM_NOTIFY: send connect and disconnect notifications" -.sp -Enables connect and disconnect notifications on a STREAM socket, when set to 1\&. When notifications are enabled, the socket delivers a zero\-length message when a peer connects or disconnects\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -1 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_STREAM -T} -.TE -.sp 1 -.SS "ZMQ_SUBSCRIBE: Establish message filter" -.sp -The \fIZMQ_SUBSCRIBE\fR option shall establish a new message filter on a \fIZMQ_SUB\fR socket\&. Newly created \fIZMQ_SUB\fR sockets shall filter out all incoming messages, therefore you should call this option to establish an initial message filter\&. -.sp -An empty \fIoption_value\fR of length zero shall subscribe to all incoming messages\&. A non\-empty \fIoption_value\fR shall subscribe to all messages beginning with the specified prefix\&. Multiple filters may be attached to a single \fIZMQ_SUB\fR socket, in which case a message shall be accepted if it matches at least one filter\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -binary data -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -N/A -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_SUB -T} -.TE -.sp 1 -.SS "ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option" -.sp -Override \fISO_KEEPALIVE\fR socket option (where supported by OS)\&. The default value of \-1 means to skip any overrides and leave it to OS default\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -\-1,0,1 -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 (leave to OS default) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option" -.sp -Override \fITCP_KEEPCNT\fR socket option (where supported by OS)\&. The default value of \-1 means to skip any overrides and leave it to OS default\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -\-1,>0 -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 (leave to OS default) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPIDLE (or TCP_KEEPALIVE on some OS)" -.sp -Override \fITCP_KEEPIDLE\fR (or \fITCP_KEEPALIVE\fR on some OS) socket option (where supported by OS)\&. The default value of \-1 means to skip any overrides and leave it to OS default\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -\-1,>0 -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 (leave to OS default) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option" -.sp -Override \fITCP_KEEPINTVL\fR socket option(where supported by OS)\&. The default value of \-1 means to skip any overrides and leave it to OS default\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -\-1,>0 -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 (leave to OS default) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_TCP_MAXRT: Set TCP Maximum Retransmit Timeout" -.sp -On OSes where it is supported, sets how long before an unacknowledged TCP retransmit times out\&. The system normally attempts many TCP retransmits following an exponential backoff strategy\&. This means that after a network outage, it may take a long time before the session can be re\-established\&. Setting this option allows the timeout to happen at a shorter interval\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -0 (leave to OS default) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_TOS: Set the Type\-of\-Service on socket" -.sp -Sets the ToS fields (Differentiated services (DS) and Explicit Congestion Notification (ECN) field of the IP header\&. The ToS field is typically used to specify a packets priority\&. The availability of this option is dependent on intermediate network equipment that inspect the ToS field and provide a path for low\-delay, high\-throughput, highly\-reliable service, etc\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp ->0 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, only for connection\-oriented transports -T} -.TE -.sp 1 -.SS "ZMQ_UNSUBSCRIBE: Remove message filter" -.sp -The \fIZMQ_UNSUBSCRIBE\fR option shall remove an existing message filter on a \fIZMQ_SUB\fR socket\&. The filter specified must match an existing filter previously established with the \fIZMQ_SUBSCRIBE\fR option\&. If the socket has several instances of the same filter attached the \fIZMQ_UNSUBSCRIBE\fR option shall remove only one instance, leaving the rest in place and functional\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -binary data -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -N/A -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_SUB -T} -.TE -.sp 1 -.SS "ZMQ_XPUB_VERBOSE: pass subscribe messages on XPUB socket" -.sp -Sets the \fIXPUB\fR socket behaviour on new subscriptions\&. If enabled, the socket passes all subscribe messages to the caller\&. If disabled, these are not visible to the caller\&. The default is 0 (disabled)\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_XPUB -T} -.TE -.sp 1 -.SS "ZMQ_XPUB_VERBOSER: pass subscribe and unsubscribe messages on XPUB socket" -.sp -Sets the \fIXPUB\fR socket behaviour on new subscriptions and ubsubscriptions\&. If enabled, the socket passes all subscribe and unsubscribe messages to the caller\&. If disabled, these are not visible to the caller\&. The default is 0 (disabled)\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_XPUB -T} -.TE -.sp 1 -.SS "ZMQ_XPUB_MANUAL: change the subscription handling to manual" -.sp -Sets the \fIXPUB\fR socket subscription handling mode manual/automatic\&. A value of \fI0\fR is the default and subscription requests will be handled automatically\&. A value of \fI1\fR will change the subscription requests handling to manual, with manual mode subscription requests are not added to the subscription list\&. To add subscription the user need to call setsockopt with ZMQ_SUBSCRIBE on XPUB socket\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_XPUB -T} -.TE -.sp 1 -.SS "ZMQ_XPUB_NODROP: do not silently drop messages if SENDHWM is reached" -.sp -Sets the \fIXPUB\fR socket behaviour to return error EAGAIN if SENDHWM is reached and the message could not be send\&. -.sp -A value of 0 is the default and drops the message silently when the peers SNDHWM is reached\&. A value of 1 returns an \fIEAGAIN\fR error code if the SNDHWM is reached and ZMQ_DONTWAIT was used\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -0, 1 -T} -T{ -.sp -Default value -T}:T{ -.sp -0 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_XPUB, ZMQ_PUB -T} -.TE -.sp 1 -.SS "ZMQ_XPUB_WELCOME_MSG: set welcome message that will be received by subscriber when connecting" -.sp -Sets a welcome message the will be recieved by subscriber when connecting\&. Subscriber must subscribe to the Welcome message before connecting\&. Welcome message will also be sent on reconnecting\&. For welcome message to work well user must poll on incoming subscription messages on the XPUB socket and handle them\&. -.sp -Use NULL and lenght of zero to disable welcome message\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -binary data -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -NULL -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -ZMQ_XPUB -T} -.TE -.sp 1 -.SS "ZMQ_ZAP_DOMAIN: Set RFC 27 authentication domain" -.sp -Sets the domain for ZAP (ZMQ RFC 27) authentication\&. For NULL security (the default on all tcp:// connections), ZAP authentication only happens if you set a non\-empty domain\&. For PLAIN and CURVE security, ZAP requests are always made, if there is a ZAP handler present\&. See \m[blue]\fBhttp://rfc\&.zeromq\&.org/spec:27\fR\m[] for more details\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -character string -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -not set -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transport -T} -.TE -.sp 1 -.SS "ZMQ_TCP_ACCEPT_FILTER: Assign filters to allow new TCP connections" -.sp -Assign an arbitrary number of filters that will be applied for each new TCP transport connection on a listening socket\&. If no filters are applied, then the TCP transport allows connections from any IP address\&. If at least one filter is applied then new connection source ip should be matched\&. To clear all filters call zmq_setsockopt(socket, ZMQ_TCP_ACCEPT_FILTER, NULL, 0)\&. Filter is a null\-terminated string with ipv6 or ipv4 CIDR\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -This option is deprecated, please use authentication via the ZAP API and IP address whitelisting / blacklisting\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -binary data -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -no filters (allow from all) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all listening sockets, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_IPC_FILTER_GID: Assign group ID filters to allow new IPC connections" -.sp -Assign an arbitrary number of filters that will be applied for each new IPC transport connection on a listening socket\&. If no IPC filters are applied, then the IPC transport allows connections from any process\&. If at least one UID, GID, or PID filter is applied then new connection credentials should be matched\&. To clear all GID filters call zmq_setsockopt(socket, ZMQ_IPC_FILTER_GID, NULL, 0)\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -GID filters are only available on platforms supporting SO_PEERCRED or LOCAL_PEERCRED socket options (currently only Linux and later versions of OS X)\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -This option is deprecated, please use authentication via the ZAP API and IPC whitelisting / blacklisting\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -gid_t -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -no filters (allow from all) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all listening sockets, when using IPC transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_IPC_FILTER_PID: Assign process ID filters to allow new IPC connections" -.sp -Assign an arbitrary number of filters that will be applied for each new IPC transport connection on a listening socket\&. If no IPC filters are applied, then the IPC transport allows connections from any process\&. If at least one UID, GID, or PID filter is applied then new connection credentials should be matched\&. To clear all PID filters call zmq_setsockopt(socket, ZMQ_IPC_FILTER_PID, NULL, 0)\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -PID filters are only available on platforms supporting the SO_PEERCRED socket option (currently only Linux)\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -This option is deprecated, please use authentication via the ZAP API and IPC whitelisting / blacklisting\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -pid_t -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -no filters (allow from all) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all listening sockets, when using IPC transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_IPC_FILTER_UID: Assign user ID filters to allow new IPC connections" -.sp -Assign an arbitrary number of filters that will be applied for each new IPC transport connection on a listening socket\&. If no IPC filters are applied, then the IPC transport allows connections from any process\&. If at least one UID, GID, or PID filter is applied then new connection credentials should be matched\&. To clear all UID filters call zmq_setsockopt(socket, ZMQ_IPC_FILTER_UID, NULL, 0)\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -UID filters are only available on platforms supporting SO_PEERCRED or LOCAL_PEERCRED socket options (currently only Linux and later versions of OS X)\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -This option is deprecated, please use authentication via the ZAP API and IPC whitelisting / blacklisting\&. -.sp .5v -.RE -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -uid_t -T} -T{ -.sp -Option value unit -T}:T{ -.sp -N/A -T} -T{ -.sp -Default value -T}:T{ -.sp -no filters (allow from all) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all listening sockets, when using IPC transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_IPV4ONLY: Use IPv4\-only on socket" -.sp -Set the IPv4\-only option for the socket\&. This option is deprecated\&. Please use the ZMQ_IPV6 option\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -boolean -T} -T{ -.sp -Default value -T}:T{ -.sp -1 (true) -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using TCP transports\&. -T} -.TE -.sp 1 -.SS "ZMQ_VMCI_BUFFER_SIZE: Set buffer size of the VMCI socket" -.sp -The ZMQ_VMCI_BUFFER_SIZE option shall set the size of the underlying buffer for the socket\&. Used during negotiation before the connection is established\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -uint64_t -T} -T{ -.sp -Option value unit -T}:T{ -.sp -bytes -T} -T{ -.sp -Default value -T}:T{ -.sp -65546 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using VMCI transport -T} -.TE -.sp 1 -.SS "ZMQ_VMCI_BUFFER_MIN_SIZE: Set min buffer size of the VMCI socket" -.sp -The ZMQ_VMCI_BUFFER_MIN_SIZE option shall set the min size of the underlying buffer for the socket\&. Used during negotiation before the connection is established\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -uint64_t -T} -T{ -.sp -Option value unit -T}:T{ -.sp -bytes -T} -T{ -.sp -Default value -T}:T{ -.sp -128 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using VMCI transport -T} -.TE -.sp 1 -.SS "ZMQ_VMCI_BUFFER_MAX_SIZE: Set max buffer size of the VMCI socket" -.sp -The ZMQ_VMCI_BUFFER_MAX_SIZE option shall set the max size of the underlying buffer for the socket\&. Used during negotiation before the connection is established\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -uint64_t -T} -T{ -.sp -Option value unit -T}:T{ -.sp -bytes -T} -T{ -.sp -Default value -T}:T{ -.sp -262144 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using VMCI transport -T} -.TE -.sp 1 -.SS "ZMQ_VMCI_CONNECT_TIMEOUT: Set connection timeout of the VMCI socket" -.sp -The ZMQ_VMCI_CONNECT_TIMEOUT option shall set connection timeout for the socket\&. -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Option value type -T}:T{ -.sp -int -T} -T{ -.sp -Option value unit -T}:T{ -.sp -milliseconds -T} -T{ -.sp -Default value -T}:T{ -.sp -\-1 -T} -T{ -.sp -Applicable socket types -T}:T{ -.sp -all, when using VMCI transport -T} -.TE -.sp 1 -.SH "RETURN VALUE" -.sp -The \fIzmq_setsockopt()\fR function shall return zero if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEINVAL\fR -.RS 4 -The requested option -\fIoption_name\fR -is unknown, or the requested -\fIoption_len\fR -or -\fIoption_value\fR -is invalid\&. -.RE -.PP -\fBETERM\fR -.RS 4 -The 0MQ -\fIcontext\fR -associated with the specified -\fIsocket\fR -was terminated\&. -.RE -.PP -\fBENOTSOCK\fR -.RS 4 -The provided -\fIsocket\fR -was invalid\&. -.RE -.PP -\fBEINTR\fR -.RS 4 -The operation was interrupted by delivery of a signal\&. -.RE -.SH "EXAMPLE" -.PP -\fBSubscribing to messages on a ZMQ_SUB socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -/* Subscribe to all messages */ -rc = zmq_setsockopt (socket, ZMQ_SUBSCRIBE, "", 0); -assert (rc == 0); -/* Subscribe to messages prefixed with "ANIMALS\&.CATS" */ -rc = zmq_setsockopt (socket, ZMQ_SUBSCRIBE, "ANIMALS\&.CATS", 12); -.fi -.if n \{\ -.RE -.\} -.PP -\fBSetting I/O thread affinity\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -int64_t affinity; -/* Incoming connections on TCP port 5555 shall be handled by I/O thread 1 */ -affinity = 1; -rc = zmq_setsockopt (socket, ZMQ_AFFINITY, &affinity, sizeof (affinity)); -assert (rc); -rc = zmq_bind (socket, "tcp://lo:5555"); -assert (rc); -/* Incoming connections on TCP port 5556 shall be handled by I/O thread 2 */ -affinity = 2; -rc = zmq_setsockopt (socket, ZMQ_AFFINITY, &affinity, sizeof (affinity)); -assert (rc); -rc = zmq_bind (socket, "tcp://lo:5556"); -assert (rc); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_getsockopt\fR(3) \fBzmq_socket\fR(3) \fBzmq_plain\fR(7) \fBzmq_curve\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_socket.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_socket.3 deleted file mode 100644 index eaf039a03f9533..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_socket.3 +++ /dev/null @@ -1,1403 +0,0 @@ -'\" t -.\" Title: zmq_socket -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_SOCKET" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_socket \- create 0MQ socket -.SH "SYNOPSIS" -.sp -\fBvoid *zmq_socket (void \fR\fB\fI*context\fR\fR\fB, int \fR\fB\fItype\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_socket()\fR function shall create a 0MQ socket within the specified \fIcontext\fR and return an opaque handle to the newly created socket\&. The \fItype\fR argument specifies the socket type, which determines the semantics of communication over the socket\&. -.sp -The newly created socket is initially unbound, and not associated with any endpoints\&. In order to establish a message flow a socket must first be connected to at least one endpoint with \fBzmq_connect\fR(3), or at least one endpoint must be created for accepting incoming connections with \fBzmq_bind\fR(3)\&. -.PP -\fBKey differences to conventional sockets\fR. Generally speaking, conventional sockets present a -\fIsynchronous\fR -interface to either connection\-oriented reliable byte streams (SOCK_STREAM), or connection\-less unreliable datagrams (SOCK_DGRAM)\&. In comparison, 0MQ sockets present an abstraction of an asynchronous -\fImessage queue\fR, with the exact queueing semantics depending on the socket type in use\&. Where conventional sockets transfer streams of bytes or discrete datagrams, 0MQ sockets transfer discrete -\fImessages\fR\&. -.sp -0MQ sockets being \fIasynchronous\fR means that the timings of the physical connection setup and tear down, reconnect and effective delivery are transparent to the user and organized by 0MQ itself\&. Further, messages may be \fIqueued\fR in the event that a peer is unavailable to receive them\&. -.sp -Conventional sockets allow only strict one\-to\-one (two peers), many\-to\-one (many clients, one server), or in some cases one\-to\-many (multicast) relationships\&. With the exception of \fIZMQ_PAIR\fR, 0MQ sockets may be connected \fBto multiple endpoints\fR using \fIzmq_connect()\fR, while simultaneously accepting incoming connections \fBfrom multiple endpoints\fR bound to the socket using \fIzmq_bind()\fR, thus allowing many\-to\-many relationships\&. -.PP -\fBThread safety\fR. 0MQ has both thread safe socket type and -\fInot\fR -thread safe socket types\&. Applications MUST NOT use a -\fInot\fR -thread safe socket from multiple threads except after migrating a socket from one thread to another with a "full fence" memory barrier\&. -.sp -Following are the thread safe sockets: * ZMQ_CLIENT * ZMQ_SERVER * ZMQ_DISH * ZMQ_RADIO * ZMQ_SCATTER * ZMQ_GATHER -.PP -\fBSocket types\fR. The following sections present the socket types defined by 0MQ, grouped by the general -\fImessaging pattern\fR -which is built from related socket types\&. -.SS "Client\-server pattern" -.sp -The client\-server pattern is used to allow a single \fIZMQ_SERVER\fR \fIserver\fR talk to one or more \fIZMQ_CLIENT\fR \fIclients\fR\&. The client always starts the conversation, after which either peer can send messages asynchronously, to the other\&. -.sp -The client\-server pattern is formally defined by \m[blue]\fBhttp://rfc\&.zeromq\&.org/spec:41\fR\m[]\&. -.sp -Note: this pattern is meant to eventually deprecate the use of \fIZMQ_DEALER\fR and \fIZMQ_ROUTER\fR to build client\-server architectures, as well as \fIZMQ_REP\fR and \fIZMQ_REQ\fR for request\-reply\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_CLIENT\fR -.RS 4 -.sp -A \fIZMQ_CLIENT\fR socket talks to a \fIZMQ_SERVER\fR socket\&. Either peer can connect, though the usual and recommended model is to bind the \fIZMQ_SERVER\fR and connect the \fIZMQ_CLIENT\fR\&. -.sp -If the \fIZMQ_CLIENT\fR socket has established a connection, \fBzmq_send\fR(3) will accept messages, queue them, and send them as rapidly as the network allows\&. The outgoing buffer limit is defined by the high water mark for the socket\&. If the outgoing buffer is full, or if there is no connected peer, \fBzmq_send\fR(3) will block, by default\&. The \fIZMQ_CLIENT\fR socket will not drop messages\&. -.sp -When a \fIZMQ_CLIENT\fR socket is connected to multiple \fIZMQ_SERVER\fR sockets, outgoing messages are distributed between connected peers on a round\-robin basis\&. Likewise, the \fIZMQ_CLIENT\fR socket receives messages fairly from each connected peer\&. This usage is sensible only for stateless protocols\&. -.sp -\fIZMQ_CLIENT\fR sockets are threadsafe and can be used from multiple threads at the same time\&. Note that replies from a \fIZMQ_SERVER\fR socket will go to the first client thread that calls libzmq:zmq_msg_recv\&. If you need to get replies back to the originating thread, use one \fIZMQ_CLIENT\fR socket per thread\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -\fIZMQ_CLIENT\fR sockets are threadsafe\&. They do not accept the ZMQ_SNDMORE option on sends not ZMQ_RCVMORE on receives\&. This limits them to single part data\&. The intention is to extend the API to allow scatter/gather of multi\-part data\&. -.sp .5v -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&1.\ \&Summary of ZMQ_CLIENT characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -\fIZMQ_SERVER\fR -T} -T{ -.sp -Direction -T}:T{ -.sp -Bidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Unrestricted -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -Round\-robin -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -Fair\-queued -T} -T{ -.sp -Action in mute state -T}:T{ -.sp -Block -T} -.TE -.sp 1 -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_SERVER\fR -.RS 4 -.sp -A \fIZMQ_SERVER\fR socket talks to a set of \fIZMQ_CLIENT\fR sockets\&. A \fIZMQ_SERVER\fR socket can only reply to an incoming message: the \fIZMQ_CLIENT\fR peer must always initiate a conversation\&. -.sp -Each received message has a \fIrouting_id\fR that is a 32\-bit unsigned integer\&. The application can fetch this with \fBzmq_msg_routing_id\fR(3)\&. To send a message to a given \fIZMQ_CLIENT\fR peer the application must set the peer\(cqs \fIrouting_id\fR on the message, using \fBzmq_msg_set_routing_id\fR(3)\&. -.sp -If the \fIrouting_id\fR is not specified, or does not refer to a connected client peer, the send call will fail with EHOSTUNREACH\&. If the outgoing buffer for the client peer is full, the send call shall block, unless ZMQ_DONT_WAIT is used in the send, in which case it shall fail with EAGAIN\&. The \fIZMQ_SERVER\fR socket shall not drop messages in any case\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -\fIZMQ_SERVER\fR sockets are threadsafe\&. They do not accept the ZMQ_SNDMORE option on sends not ZMQ_RCVMORE on receives\&. This limits them to single part data\&. The intention is to extend the API to allow scatter/gather of multi\-part data\&. -.sp .5v -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&2.\ \&Summary of ZMQ_SERVER characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -\fIZMQ_CLIENT\fR -T} -T{ -.sp -Direction -T}:T{ -.sp -Bidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Unrestricted -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -See text -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -Fair\-queued -T} -T{ -.sp -Action in mute state -T}:T{ -.sp -Return EAGAIN -T} -.TE -.sp 1 -.RE -.SS "Radio\-dish pattern" -.sp -The radio\-dish pattern is used for one\-to\-many distribution of data from a single \fIpublisher\fR to multiple \fIsubscribers\fR in a fan out fashion\&. -.sp -Radio\-dish is using groups (vs Pub\-sub topics), Dish sockets can join a group and each message sent by Radio sockets belong to a group\&. -.sp -Groups are null terminated strings limited to 16 chars length (including null)\&. The intention is to increase the length to 40 chars (including null)\&. -.sp -Groups are matched using exact matching (vs prefix matching of PubSub)\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -Radio\-dish is still in draft phase\&. -.sp .5v -.RE -.sp -Note: this pattern is meant to eventually deprecate the use of \fIZMQ_PUB\fR and \fIZMQ_SUB\fR to build pub\-sub architectures\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_RADIO\fR -.RS 4 -.sp -A socket of type \fIZMQ_RADIO\fR is used by a \fIpublisher\fR to distribute data\&. Each message belong to a group, a group is specified with linkzmq_zmq_msg_set_group[3]\&. Messages are distributed to all members of a group\&. The \fBzmq_recv\fR(3) function is not implemented for this socket type\&. -.sp -When a \fIZMQ_RADIO\fR socket enters the \fImute\fR state due to having reached the high water mark for a \fIsubscriber\fR, then any messages that would be sent to the \fIsubscriber\fR in question shall instead be dropped until the mute state ends\&. The \fIzmq_send()\fR function shall never block for this socket type\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -\fIZMQ_RADIO\fR sockets are threadsafe\&. They do not accept the ZMQ_SNDMORE option on sends\&. This limits them to single part data\&. -.sp .5v -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&3.\ \&Summary of ZMQ_RADIO characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -\fIZMQ_DISH\fR -T} -T{ -.sp -Direction -T}:T{ -.sp -Unidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Send only -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -N/A -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -Fan out -T} -T{ -.sp -Action in mute state -T}:T{ -.sp -Drop -T} -.TE -.sp 1 -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_DISH\fR -.RS 4 -.sp -A socket of type \fIZMQ_DISH\fR is used by a \fIsubscriber\fR to subscribe to groups distributed by a \fIradio\fR\&. Initially a \fIZMQ_DISH\fR socket is not subscribed to any groups, use \fBzmq_join\fR(3) to join a group\&. To get the group the message belong to call \fBzmq_msg_group\fR(3)\&. The \fIzmq_send()\fR function is not implemented for this socket type\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -\fIZMQ_DISH\fR sockets are threadsafe\&. They do not accept ZMQ_RCVMORE on receives\&. This limits them to single part data\&. -.sp .5v -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&4.\ \&Summary of ZMQ_DISH characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -\fIZMQ_RADIO\fR -T} -T{ -.sp -Direction -T}:T{ -.sp -Unidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Receive only -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -Fair\-queued -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -N/A -T} -.TE -.sp 1 -.RE -.SS "Publish\-subscribe pattern" -.sp -The publish\-subscribe pattern is used for one\-to\-many distribution of data from a single \fIpublisher\fR to multiple \fIsubscribers\fR in a fan out fashion\&. -.sp -The publish\-subscribe pattern is formally defined by \m[blue]\fBhttp://rfc\&.zeromq\&.org/spec:29\fR\m[]\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_PUB\fR -.RS 4 -.sp -A socket of type \fIZMQ_PUB\fR is used by a \fIpublisher\fR to distribute data\&. Messages sent are distributed in a fan out fashion to all connected peers\&. The \fBzmq_recv\fR(3) function is not implemented for this socket type\&. -.sp -When a \fIZMQ_PUB\fR socket enters the \fImute\fR state due to having reached the high water mark for a \fIsubscriber\fR, then any messages that would be sent to the \fIsubscriber\fR in question shall instead be dropped until the mute state ends\&. The \fIzmq_send()\fR function shall never block for this socket type\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&5.\ \&Summary of ZMQ_PUB characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -\fIZMQ_SUB\fR, \fIZMQ_XSUB\fR -T} -T{ -.sp -Direction -T}:T{ -.sp -Unidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Send only -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -N/A -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -Fan out -T} -T{ -.sp -Action in mute state -T}:T{ -.sp -Drop -T} -.TE -.sp 1 -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_SUB\fR -.RS 4 -.sp -A socket of type \fIZMQ_SUB\fR is used by a \fIsubscriber\fR to subscribe to data distributed by a \fIpublisher\fR\&. Initially a \fIZMQ_SUB\fR socket is not subscribed to any messages, use the \fIZMQ_SUBSCRIBE\fR option of \fBzmq_setsockopt\fR(3) to specify which messages to subscribe to\&. The \fIzmq_send()\fR function is not implemented for this socket type\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&6.\ \&Summary of ZMQ_SUB characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -\fIZMQ_PUB\fR, \fIZMQ_XPUB\fR -T} -T{ -.sp -Direction -T}:T{ -.sp -Unidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Receive only -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -Fair\-queued -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -N/A -T} -.TE -.sp 1 -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_XPUB\fR -.RS 4 -.sp -Same as ZMQ_PUB except that you can receive subscriptions from the peers in form of incoming messages\&. Subscription message is a byte 1 (for subscriptions) or byte 0 (for unsubscriptions) followed by the subscription body\&. Messages without a sub/unsub prefix are also received, but have no effect on subscription status\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&7.\ \&Summary of ZMQ_XPUB characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -\fIZMQ_SUB\fR, \fIZMQ_XSUB\fR -T} -T{ -.sp -Direction -T}:T{ -.sp -Unidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Send messages, receive subscriptions -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -N/A -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -Fan out -T} -T{ -.sp -Action in mute state -T}:T{ -.sp -Drop -T} -.TE -.sp 1 -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_XSUB\fR -.RS 4 -.sp -Same as ZMQ_SUB except that you subscribe by sending subscription messages to the socket\&. Subscription message is a byte 1 (for subscriptions) or byte 0 (for unsubscriptions) followed by the subscription body\&. Messages without a sub/unsub prefix may also be sent, but have no effect on subscription status\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&8.\ \&Summary of ZMQ_XSUB characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -\fIZMQ_PUB\fR, \fIZMQ_XPUB\fR -T} -T{ -.sp -Direction -T}:T{ -.sp -Unidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Receive messages, send subscriptions -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -Fair\-queued -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -N/A -T} -T{ -.sp -Action in mute state -T}:T{ -.sp -Drop -T} -.TE -.sp 1 -.RE -.SS "Pipeline pattern" -.sp -The pipeline pattern is used for distributing data to \fInodes\fR arranged in a pipeline\&. Data always flows down the pipeline, and each stage of the pipeline is connected to at least one \fInode\fR\&. When a pipeline stage is connected to multiple \fInodes\fR data is round\-robined among all connected \fInodes\fR\&. -.sp -The pipeline pattern is formally defined by \m[blue]\fBhttp://rfc\&.zeromq\&.org/spec:30\fR\m[]\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_PUSH\fR -.RS 4 -.sp -A socket of type \fIZMQ_PUSH\fR is used by a pipeline \fInode\fR to send messages to downstream pipeline \fInodes\fR\&. Messages are round\-robined to all connected downstream \fInodes\fR\&. The \fIzmq_recv()\fR function is not implemented for this socket type\&. -.sp -When a \fIZMQ_PUSH\fR socket enters the \fImute\fR state due to having reached the high water mark for all downstream \fInodes\fR, or if there are no downstream \fInodes\fR at all, then any \fBzmq_send\fR(3) operations on the socket shall block until the mute state ends or at least one downstream \fInode\fR becomes available for sending; messages are not discarded\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&9.\ \&Summary of ZMQ_PUSH characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -\fIZMQ_PULL\fR -T} -T{ -.sp -Direction -T}:T{ -.sp -Unidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Send only -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -N/A -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -Round\-robin -T} -T{ -.sp -Action in mute state -T}:T{ -.sp -Block -T} -.TE -.sp 1 -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_PULL\fR -.RS 4 -.sp -A socket of type \fIZMQ_PULL\fR is used by a pipeline \fInode\fR to receive messages from upstream pipeline \fInodes\fR\&. Messages are fair\-queued from among all connected upstream \fInodes\fR\&. The \fIzmq_send()\fR function is not implemented for this socket type\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&10.\ \&Summary of ZMQ_PULL characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -\fIZMQ_PUSH\fR -T} -T{ -.sp -Direction -T}:T{ -.sp -Unidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Receive only -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -Fair\-queued -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -N/A -T} -T{ -.sp -Action in mute state -T}:T{ -.sp -Block -T} -.TE -.sp 1 -.RE -.SS "Exclusive pair pattern" -.sp -The exclusive pair pattern is used to connect a peer to precisely one other peer\&. This pattern is used for inter\-thread communication across the inproc transport\&. -.sp -The exclusive pair pattern is formally defined by \m[blue]\fBhttp://rfc\&.zeromq\&.org/spec:31\fR\m[]\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_PAIR\fR -.RS 4 -.sp -A socket of type \fIZMQ_PAIR\fR can only be connected to a single peer at any one time\&. No message routing or filtering is performed on messages sent over a \fIZMQ_PAIR\fR socket\&. -.sp -When a \fIZMQ_PAIR\fR socket enters the \fImute\fR state due to having reached the high water mark for the connected peer, or if no peer is connected, then any \fBzmq_send\fR(3) operations on the socket shall block until the peer becomes available for sending; messages are not discarded\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -\fIZMQ_PAIR\fR sockets are designed for inter\-thread communication across the \fBzmq_inproc\fR(7) transport and do not implement functionality such as auto\-reconnection\&. -.sp .5v -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&11.\ \&Summary of ZMQ_PAIR characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -\fIZMQ_PAIR\fR -T} -T{ -.sp -Direction -T}:T{ -.sp -Bidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Unrestricted -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -N/A -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -N/A -T} -T{ -.sp -Action in mute state -T}:T{ -.sp -Block -T} -.TE -.sp 1 -.RE -.SS "Native Pattern" -.sp -The native pattern is used for communicating with TCP peers and allows asynchronous requests and replies in either direction\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_STREAM\fR -.RS 4 -.sp -A socket of type \fIZMQ_STREAM\fR is used to send and receive TCP data from a non\-0MQ peer, when using the tcp:// transport\&. A \fIZMQ_STREAM\fR socket can act as client and/or server, sending and/or receiving TCP data asynchronously\&. -.sp -When receiving TCP data, a \fIZMQ_STREAM\fR socket shall prepend a message part containing the \fIidentity\fR of the originating peer to the message before passing it to the application\&. Messages received are fair\-queued from among all connected peers\&. -.sp -When sending TCP data, a \fIZMQ_STREAM\fR socket shall remove the first part of the message and use it to determine the \fIidentity\fR of the peer the message shall be routed to, and unroutable messages shall cause an EHOSTUNREACH or EAGAIN error\&. -.sp -To open a connection to a server, use the zmq_connect call, and then fetch the socket identity using the ZMQ_IDENTITY zmq_getsockopt call\&. -.sp -To close a specific connection, send the identity frame followed by a zero\-length message (see EXAMPLE section)\&. -.sp -When a connection is made, a zero\-length message will be received by the application\&. Similarly, when the peer disconnects (or the connection is lost), a zero\-length message will be received by the application\&. -.sp -You must send one identity frame followed by one data frame\&. The ZMQ_SNDMORE flag is required for identity frames but is ignored on data frames\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&12.\ \&Summary of ZMQ_STREAM characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -none\&. -T} -T{ -.sp -Direction -T}:T{ -.sp -Bidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Unrestricted -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -See text -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -Fair\-queued -T} -T{ -.sp -Action in mute state -T}:T{ -.sp -EAGAIN -T} -.TE -.sp 1 -.RE -.SS "Request\-reply pattern" -.sp -The request\-reply pattern is used for sending requests from a ZMQ_REQ \fIclient\fR to one or more ZMQ_REP \fIservices\fR, and receiving subsequent replies to each request sent\&. -.sp -The request\-reply pattern is formally defined by \m[blue]\fBhttp://rfc\&.zeromq\&.org/spec:28\fR\m[]\&. -.sp -Note: this pattern will be deprecated in favor of the client\-server pattern\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_REQ\fR -.RS 4 -.sp -A socket of type \fIZMQ_REQ\fR is used by a \fIclient\fR to send requests to and receive replies from a \fIservice\fR\&. This socket type allows only an alternating sequence of \fIzmq_send(request)\fR and subsequent \fIzmq_recv(reply)\fR calls\&. Each request sent is round\-robined among all \fIservices\fR, and each reply received is matched with the last issued request\&. -.sp -If no services are available, then any send operation on the socket shall block until at least one \fIservice\fR becomes available\&. The REQ socket shall not discard messages\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&13.\ \&Summary of ZMQ_REQ characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -\fIZMQ_REP\fR, \fIZMQ_ROUTER\fR -T} -T{ -.sp -Direction -T}:T{ -.sp -Bidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Send, Receive, Send, Receive, \&... -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -Round\-robin -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -Last peer -T} -T{ -.sp -Action in mute state -T}:T{ -.sp -Block -T} -.TE -.sp 1 -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_REP\fR -.RS 4 -.sp -A socket of type \fIZMQ_REP\fR is used by a \fIservice\fR to receive requests from and send replies to a \fIclient\fR\&. This socket type allows only an alternating sequence of \fIzmq_recv(request)\fR and subsequent \fIzmq_send(reply)\fR calls\&. Each request received is fair\-queued from among all \fIclients\fR, and each reply sent is routed to the \fIclient\fR that issued the last request\&. If the original requester does not exist any more the reply is silently discarded\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&14.\ \&Summary of ZMQ_REP characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -\fIZMQ_REQ\fR, \fIZMQ_DEALER\fR -T} -T{ -.sp -Direction -T}:T{ -.sp -Bidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Receive, Send, Receive, Send, \&... -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -Fair\-queued -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -Last peer -T} -.TE -.sp 1 -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_DEALER\fR -.RS 4 -.sp -A socket of type \fIZMQ_DEALER\fR is an advanced pattern used for extending request/reply sockets\&. Each message sent is round\-robined among all connected peers, and each message received is fair\-queued from all connected peers\&. -.sp -When a \fIZMQ_DEALER\fR socket enters the \fImute\fR state due to having reached the high water mark for all peers, or if there are no peers at all, then any \fBzmq_send\fR(3) operations on the socket shall block until the mute state ends or at least one peer becomes available for sending; messages are not discarded\&. -.sp -When a \fIZMQ_DEALER\fR socket is connected to a \fIZMQ_REP\fR socket each message sent must consist of an empty message part, the \fIdelimiter\fR, followed by one or more \fIbody parts\fR\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&15.\ \&Summary of ZMQ_DEALER characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -\fIZMQ_ROUTER\fR, \fIZMQ_REP\fR, \fIZMQ_DEALER\fR -T} -T{ -.sp -Direction -T}:T{ -.sp -Bidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Unrestricted -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -Round\-robin -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -Fair\-queued -T} -T{ -.sp -Action in mute state -T}:T{ -.sp -Block -T} -.TE -.sp 1 -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBZMQ_ROUTER\fR -.RS 4 -.sp -A socket of type \fIZMQ_ROUTER\fR is an advanced socket type used for extending request/reply sockets\&. When receiving messages a \fIZMQ_ROUTER\fR socket shall prepend a message part containing the \fIidentity\fR of the originating peer to the message before passing it to the application\&. Messages received are fair\-queued from among all connected peers\&. When sending messages a \fIZMQ_ROUTER\fR socket shall remove the first part of the message and use it to determine the \fIidentity\fR of the peer the message shall be routed to\&. If the peer does not exist anymore the message shall be silently discarded by default, unless \fIZMQ_ROUTER_MANDATORY\fR socket option is set to \fI1\fR\&. -.sp -When a \fIZMQ_ROUTER\fR socket enters the \fImute\fR state due to having reached the high water mark for all peers, then any messages sent to the socket shall be dropped until the mute state ends\&. Likewise, any messages routed to a peer for which the individual high water mark has been reached shall also be dropped, unless \fIZMQ_ROUTER_MANDATORY\fR socket option is set\&. -.sp -When a \fIZMQ_REQ\fR socket is connected to a \fIZMQ_ROUTER\fR socket, in addition to the \fIidentity\fR of the originating peer each message received shall contain an empty \fIdelimiter\fR message part\&. Hence, the entire structure of each received message as seen by the application becomes: one or more \fIidentity\fR parts, \fIdelimiter\fR part, one or more \fIbody parts\fR\&. When sending replies to a \fIZMQ_REQ\fR socket the application must include the \fIdelimiter\fR part\&. -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.B Table\ \&16.\ \&Summary of ZMQ_ROUTER characteristics -.TS -tab(:); -lt lt -lt lt -lt lt -lt lt -lt lt -lt lt. -T{ -.sp -Compatible peer sockets -T}:T{ -.sp -\fIZMQ_DEALER\fR, \fIZMQ_REQ\fR, \fIZMQ_ROUTER\fR -T} -T{ -.sp -Direction -T}:T{ -.sp -Bidirectional -T} -T{ -.sp -Send/receive pattern -T}:T{ -.sp -Unrestricted -T} -T{ -.sp -Outgoing routing strategy -T}:T{ -.sp -See text -T} -T{ -.sp -Incoming routing strategy -T}:T{ -.sp -Fair\-queued -T} -T{ -.sp -Action in mute state -T}:T{ -.sp -Drop (see text) -T} -.TE -.sp 1 -.RE -.SH "RETURN VALUE" -.sp -The \fIzmq_socket()\fR function shall return an opaque handle to the newly created socket if successful\&. Otherwise, it shall return NULL and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEINVAL\fR -.RS 4 -The requested socket -\fItype\fR -is invalid\&. -.RE -.PP -\fBEFAULT\fR -.RS 4 -The provided -\fIcontext\fR -is invalid\&. -.RE -.PP -\fBEMFILE\fR -.RS 4 -The limit on the total number of open 0MQ sockets has been reached\&. -.RE -.PP -\fBETERM\fR -.RS 4 -The context specified was terminated\&. -.RE -.SH "EXAMPLE" -.PP -\fBCreating a simple HTTP server using ZMQ_STREAM\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -void *ctx = zmq_ctx_new (); -assert (ctx); -/* Create ZMQ_STREAM socket */ -void *socket = zmq_socket (ctx, ZMQ_STREAM); -assert (socket); -int rc = zmq_bind (socket, "tcp://*:8080"); -assert (rc == 0); -/* Data structure to hold the ZMQ_STREAM ID */ -uint8_t id [256]; -size_t id_size = 256; -/* Data structure to hold the ZMQ_STREAM received data */ -uint8_t raw [256]; -size_t raw_size = 256; -while (1) { - /* Get HTTP request; ID frame and then request */ - id_size = zmq_recv (socket, id, 256, 0); - assert (id_size > 0); - do { - raw_size = zmq_recv (socket, raw, 256, 0); - assert (raw_size >= 0); - } while (raw_size == 256); - /* Prepares the response */ - char http_response [] = - "HTTP/1\&.0 200 OK\er\en" - "Content\-Type: text/plain\er\en" - "\er\en" - "Hello, World!"; - /* Sends the ID frame followed by the response */ - zmq_send (socket, id, id_size, ZMQ_SNDMORE); - zmq_send (socket, http_response, strlen (http_response), 0); - /* Closes the connection by sending the ID frame followed by a zero response */ - zmq_send (socket, id, id_size, ZMQ_SNDMORE); - zmq_send (socket, 0, 0, 0); -} -zmq_close (socket); -zmq_ctx_destroy (ctx); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_init\fR(3) \fBzmq_setsockopt\fR(3) \fBzmq_bind\fR(3) \fBzmq_connect\fR(3) \fBzmq_send\fR(3) \fBzmq_recv\fR(3) \fBzmq_inproc\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_socket_monitor.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_socket_monitor.3 deleted file mode 100644 index 26664be708ad3e..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_socket_monitor.3 +++ /dev/null @@ -1,241 +0,0 @@ -'\" t -.\" Title: zmq_socket_monitor -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_SOCKET_MONITOR" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_socket_monitor \- monitor socket events -.SH "SYNOPSIS" -.sp -\fBint zmq_socket_monitor (void \fR\fB\fI*socket\fR\fR\fB, char \fR\fB\fI*endpoint\fR\fR\fB, int \fR\fB\fIevents\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_socket_monitor()\fR method lets an application thread track socket events (like connects) on a ZeroMQ socket\&. Each call to this method creates a \fIZMQ_PAIR\fR socket and binds that to the specified inproc:// \fIendpoint\fR\&. To collect the socket events, you must create your own \fIZMQ_PAIR\fR socket, and connect that to the endpoint\&. -.sp -The \fIevents\fR argument is a bitmask of the socket events you wish to monitor, see \fISupported events\fR below\&. To monitor all events, use the event value ZMQ_EVENT_ALL\&. NOTE: as new events are added, the catch\-all value will start returning them\&. An application that relies on a strict and fixed sequence of events must not use ZMQ_EVENT_ALL in order to guarantee compatibility with future versions\&. -.sp -Each event is sent as two frames\&. The first frame contains an event number (16 bits), and an event value (32 bits) that provides additional data according to the event number\&. The second frame contains a string that specifies the affected TCP or IPC endpoint\&. -.sp -.if n \{\ -.RS 4 -.\} -.nf -The _zmq_socket_monitor()_ method supports only connection\-oriented -transports, that is, TCP, IPC, and TIPC\&. -.fi -.if n \{\ -.RE -.\} -.SH "SUPPORTED EVENTS" -.SS "ZMQ_EVENT_CONNECTED" -.sp -The socket has successfully connected to a remote peer\&. The event value is the file descriptor (FD) of the underlying network socket\&. Warning: there is no guarantee that the FD is still valid by the time your code receives this event\&. -.SS "ZMQ_EVENT_CONNECT_DELAYED" -.sp -A connect request on the socket is pending\&. The event value is unspecified\&. -.SS "ZMQ_EVENT_CONNECT_RETRIED" -.sp -A connect request failed, and is now being retried\&. The event value is the reconnect interval in milliseconds\&. Note that the reconnect interval is recalculated at each retry\&. -.SS "ZMQ_EVENT_LISTENING" -.sp -The socket was successfully bound to a network interface\&. The event value is the FD of the underlying network socket\&. Warning: there is no guarantee that the FD is still valid by the time your code receives this event\&. -.SS "ZMQ_EVENT_BIND_FAILED" -.sp -The socket could not bind to a given interface\&. The event value is the errno generated by the system bind call\&. -.SS "ZMQ_EVENT_ACCEPTED" -.sp -The socket has accepted a connection from a remote peer\&. The event value is the FD of the underlying network socket\&. Warning: there is no guarantee that the FD is still valid by the time your code receives this event\&. -.SS "ZMQ_EVENT_ACCEPT_FAILED" -.sp -The socket has rejected a connection from a remote peer\&. The event value is the errno generated by the accept call\&. -.SS "ZMQ_EVENT_CLOSED" -.sp -The socket was closed\&. The event value is the FD of the (now closed) network socket\&. -.SS "ZMQ_EVENT_CLOSE_FAILED" -.sp -The socket close failed\&. The event value is the errno returned by the system call\&. Note that this event occurs only on IPC transports\&. -.SS "ZMQ_EVENT_DISCONNECTED" -.sp -The socket was disconnected unexpectedly\&. The event value is the FD of the underlying network socket\&. Warning: this socket will be closed\&. -.SS "ZMQ_EVENT_MONITOR_STOPPED" -.sp -Monitoring on this socket ended\&. -.SS "ZMQ_EVENT_HANDSHAKE_FAILED" -.sp -The ZMTP security mechanism handshake failed\&. The event value is unspecified\&. NOTE: in DRAFT state, not yet available in stable releases\&. -.SS "ZMQ_EVENT_HANDSHAKE_SUCCEED" -.sp -The ZMTP security mechanism handshake succeeded\&. The event value is unspecified\&. NOTE: in DRAFT state, not yet available in stable releases\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_socket_monitor()\fR function returns a value of 0 or greater if successful\&. Otherwise it returns \-1 and sets \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBETERM\fR -.RS 4 -The 0MQ -\fIcontext\fR -associated with the specified -\fIsocket\fR -was terminated\&. -.RE -.PP -\fBEPROTONOSUPPORT\fR -.RS 4 -The requested -\fItransport\fR -protocol is not supported\&. Monitor sockets are required to use the inproc:// transport\&. -.RE -.PP -\fBEINVAL\fR -.RS 4 -The endpoint supplied is invalid\&. -.RE -.SH "EXAMPLE" -.PP -\fBMonitoring client and server sockets\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Read one event off the monitor socket; return value and address -// by reference, if not null, and event number by value\&. Returns \-1 -// in case of error\&. - -static int -get_monitor_event (void *monitor, int *value, char **address) -{ - // First frame in message contains event number and value - zmq_msg_t msg; - zmq_msg_init (&msg); - if (zmq_msg_recv (&msg, monitor, 0) == \-1) - return \-1; // Interrupted, presumably - assert (zmq_msg_more (&msg)); - - uint8_t *data = (uint8_t *) zmq_msg_data (&msg); - uint16_t event = *(uint16_t *) (data); - if (value) - *value = *(uint32_t *) (data + 2); - - // Second frame in message contains event address - zmq_msg_init (&msg); - if (zmq_msg_recv (&msg, monitor, 0) == \-1) - return \-1; // Interrupted, presumably - assert (!zmq_msg_more (&msg)); - - if (address) { - uint8_t *data = (uint8_t *) zmq_msg_data (&msg); - size_t size = zmq_msg_size (&msg); - *address = (char *) malloc (size + 1); - memcpy (*address, data, size); - (*address)[size] = 0; - } - return event; -} - -int main (void) -{ - void *ctx = zmq_ctx_new (); - assert (ctx); - - // We\*(Aqll monitor these two sockets - void *client = zmq_socket (ctx, ZMQ_DEALER); - assert (client); - void *server = zmq_socket (ctx, ZMQ_DEALER); - assert (server); - - // Socket monitoring only works over inproc:// - int rc = zmq_socket_monitor (client, "tcp://127\&.0\&.0\&.1:9999", 0); - assert (rc == \-1); - assert (zmq_errno () == EPROTONOSUPPORT); - - // Monitor all events on client and server sockets - rc = zmq_socket_monitor (client, "inproc://monitor\-client", ZMQ_EVENT_ALL); - assert (rc == 0); - rc = zmq_socket_monitor (server, "inproc://monitor\-server", ZMQ_EVENT_ALL); - assert (rc == 0); - - // Create two sockets for collecting monitor events - void *client_mon = zmq_socket (ctx, ZMQ_PAIR); - assert (client_mon); - void *server_mon = zmq_socket (ctx, ZMQ_PAIR); - assert (server_mon); - - // Connect these to the inproc endpoints so they\*(Aqll get events - rc = zmq_connect (client_mon, "inproc://monitor\-client"); - assert (rc == 0); - rc = zmq_connect (server_mon, "inproc://monitor\-server"); - assert (rc == 0); - - // Now do a basic ping test - rc = zmq_bind (server, "tcp://127\&.0\&.0\&.1:9998"); - assert (rc == 0); - rc = zmq_connect (client, "tcp://127\&.0\&.0\&.1:9998"); - assert (rc == 0); - bounce (client, server); - - // Close client and server - close_zero_linger (client); - close_zero_linger (server); - - // Now collect and check events from both sockets - int event = get_monitor_event (client_mon, NULL, NULL); - if (event == ZMQ_EVENT_CONNECT_DELAYED) - event = get_monitor_event (client_mon, NULL, NULL); - assert (event == ZMQ_EVENT_CONNECTED); - event = get_monitor_event (client_mon, NULL, NULL); - assert (event == ZMQ_EVENT_MONITOR_STOPPED); - - // This is the flow of server events - event = get_monitor_event (server_mon, NULL, NULL); - assert (event == ZMQ_EVENT_LISTENING); - event = get_monitor_event (server_mon, NULL, NULL); - assert (event == ZMQ_EVENT_ACCEPTED); - event = get_monitor_event (server_mon, NULL, NULL); - assert (event == ZMQ_EVENT_CLOSED); - event = get_monitor_event (server_mon, NULL, NULL); - assert (event == ZMQ_EVENT_MONITOR_STOPPED); - - // Close down the sockets - close_zero_linger (client_mon); - close_zero_linger (server_mon); - zmq_ctx_term (ctx); - - return 0 ; -} -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_strerror.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_strerror.3 deleted file mode 100644 index f77803861e7def..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_strerror.3 +++ /dev/null @@ -1,67 +0,0 @@ -'\" t -.\" Title: zmq_strerror -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_STRERROR" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_strerror \- get 0MQ error message string -.SH "SYNOPSIS" -.sp -\fBconst char *zmq_strerror (int \fR\fB\fIerrnum\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_strerror()\fR function shall return a pointer to an error message string corresponding to the error number specified by the \fIerrnum\fR argument\&. As 0MQ defines additional error numbers over and above those defined by the operating system, applications should use \fIzmq_strerror()\fR in preference to the standard \fIstrerror()\fR function\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_strerror()\fR function shall return a pointer to an error message string\&. -.SH "ERRORS" -.sp -No errors are defined\&. -.SH "EXAMPLE" -.PP -\fBDisplaying an error message when a 0MQ context cannot be initialised\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -void *ctx = zmq_init (1, 1, 0); -if (!ctx) { - printf ("Error occurred during zmq_init(): %s\en", zmq_strerror (errno)); - abort (); -} -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_unbind.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_unbind.3 deleted file mode 100644 index bef9c5002bb461..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_unbind.3 +++ /dev/null @@ -1,125 +0,0 @@ -'\" t -.\" Title: zmq_unbind -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_UNBIND" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_unbind \- Stop accepting connections on a socket -.SH "SYNOPSIS" -.sp -int zmq_unbind (void \fI*socket\fR, const char \fI*endpoint\fR); -.SH "DESCRIPTION" -.sp -The \fIzmq_unbind()\fR function shall unbind a socket specified by the \fIsocket\fR argument from the endpoint specified by the \fIendpoint\fR argument\&. -.sp -The \fIendpoint\fR argument is as described in \fBzmq_bind\fR(3) -.SS "Unbinding wild\-card address from a socket" -.sp -When wild\-card * \fIendpoint\fR (described in \fBzmq_tcp\fR(7), \fBzmq_ipc\fR(7) and \fBzmq_vmci\fR(7)) was used in \fIzmq_bind()\fR, the caller should use real \fIendpoint\fR obtained from the ZMQ_LAST_ENDPOINT socket option to unbind this \fIendpoint\fR from a socket\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_unbind()\fR function shall return zero if successful\&. Otherwise it shall return \-1 and set \fIerrno\fR to one of the values defined below\&. -.SH "ERRORS" -.PP -\fBEINVAL\fR -.RS 4 -The endpoint supplied is invalid\&. -.RE -.PP -\fBETERM\fR -.RS 4 -The 0MQ -\fIcontext\fR -associated with the specified -\fIsocket\fR -was terminated\&. -.RE -.PP -\fBENOTSOCK\fR -.RS 4 -The provided -\fIsocket\fR -was invalid\&. -.RE -.PP -\fBENOENT\fR -.RS 4 -The endpoint supplied was not previously bound\&. -.RE -.SH "EXAMPLES" -.PP -\fBUnbind a subscriber socket from a TCP transport\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -/* Create a ZMQ_SUB socket */ -void *socket = zmq_socket (context, ZMQ_SUB); -assert (socket); -/* Connect it to the host server001, port 5555 using a TCP transport */ -rc = zmq_bind (socket, "tcp://127\&.0\&.0\&.1:5555"); -assert (rc == 0); -/* Disconnect from the previously connected endpoint */ -rc = zmq_unbind (socket, "tcp://127\&.0\&.0\&.1:5555"); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.PP -\fBUnbind wild-card * binded socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -/* Create a ZMQ_SUB socket */ -void *socket = zmq_socket (context, ZMQ_SUB); -assert (socket); -/* Bind it to the system\-assigned ephemeral port using a TCP transport */ -rc = zmq_bind (socket, "tcp://127\&.0\&.0\&.1:*"); -assert (rc == 0); -/* Obtain real endpoint */ -const size_t buf_size = 32; -char buf[buf_size]; -rc = zmq_getsockopt (socket, ZMQ_LAST_ENDPOINT, buf, (size_t *)&buf_size); -assert (rc == 0); -/* Unbind socket by real endpoint */ -rc = zmq_unbind (socket, buf); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_bind\fR(3) \fBzmq_socket\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_version.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_version.3 deleted file mode 100644 index 2b0316947e6d20..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_version.3 +++ /dev/null @@ -1,67 +0,0 @@ -'\" t -.\" Title: zmq_version -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_VERSION" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_version \- report 0MQ library version -.SH "SYNOPSIS" -.sp -\fBvoid zmq_version (int \fR\fB\fI*major\fR\fR\fB, int \fR\fB\fI*minor\fR\fR\fB, int \fR\fB\fI*patch\fR\fR\fB);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_version()\fR function shall fill in the integer variables pointed to by the \fImajor\fR, \fIminor\fR and \fIpatch\fR arguments with the major, minor and patch level components of the 0MQ library version\&. -.sp -This functionality is intended for applications or language bindings dynamically linking to the 0MQ library that wish to determine the actual version of the 0MQ library they are using\&. -.SH "RETURN VALUE" -.sp -There is no return value\&. -.SH "ERRORS" -.sp -No errors are defined\&. -.SH "EXAMPLE" -.PP -\fBPrinting out the version of the 0MQ library\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -int major, minor, patch; -zmq_version (&major, &minor, &patch); -printf ("Current 0MQ version is %d\&.%d\&.%d\en", major, minor, patch); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_z85_decode.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_z85_decode.3 deleted file mode 100644 index a8c054b8f3e228..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_z85_decode.3 +++ /dev/null @@ -1,64 +0,0 @@ -'\" t -.\" Title: zmq_z85_decode -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_Z85_DECODE" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_z85_decode \- decode a binary key from Z85 printable text -.SH "SYNOPSIS" -.sp -\fBuint8_t *zmq_z85_decode (uint8_t *dest, const char *string);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_z85_decode()\fR function shall decode \fIstring\fR into \fIdest\fR\&. The length of \fIstring\fR shall be divisible by 5\&. \fIdest\fR must be large enough for the decoded value (0\&.8 x strlen (string))\&. -.sp -The encoding shall follow the ZMQ RFC 32 specification\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_z85_decode()\fR function shall return \fIdest\fR if successful, else it shall return NULL\&. -.SH "EXAMPLE" -.PP -\fBDecoding a CURVE key\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -const char decoded [] = "rq:rM>}U?@Lns47E1%kR\&.o@n%FcmmsL/@{H8]yf7"; -uint8_t public_key [32]; -zmq_z85_decode (public_key, decoded); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_z85_decode\fR(3) \fBzmq_curve_keypair\fR(3) \fBzmq_curve_public\fR(3) \fBzmq_curve\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_z85_encode.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_z85_encode.3 deleted file mode 100644 index 442f6bb827833a..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmq_z85_encode.3 +++ /dev/null @@ -1,69 +0,0 @@ -'\" t -.\" Title: zmq_z85_encode -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_Z85_ENCODE" "3" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_z85_encode \- encode a binary key as Z85 printable text -.SH "SYNOPSIS" -.sp -\fBchar *zmq_z85_encode (char *dest, const uint8_t *data, size_t size);\fR -.SH "DESCRIPTION" -.sp -The \fIzmq_z85_encode()\fR function shall encode the binary block specified by \fIdata\fR and \fIsize\fR into a string in \fIdest\fR\&. The size of the binary block must be divisible by 4\&. The \fIdest\fR must have sufficient space for size * 1\&.25 plus 1 for a null terminator\&. A 32\-byte CURVE key is encoded as 40 ASCII characters plus a null terminator\&. -.sp -The encoding shall follow the ZMQ RFC 32 specification\&. -.SH "RETURN VALUE" -.sp -The \fIzmq_z85_encode()\fR function shall return \fIdest\fR if successful, else it shall return NULL\&. -.SH "EXAMPLE" -.PP -\fBEncoding a CURVE key\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -#include -uint8_t public_key [32]; -uint8_t secret_key [32]; -int rc = crypto_box_keypair (public_key, secret_key); -assert (rc == 0); -char encoded [41]; -zmq_z85_encode (encoded, public_key, 32); -puts (encoded); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_z85_decode\fR(3) \fBzmq_curve_keypair\fR(3) \fBzmq_curve_public\fR(3) \fBzmq_curve\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zmsg.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zmsg.3 deleted file mode 100644 index 0be48b58cf5ac0..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zmsg.3 +++ /dev/null @@ -1,545 +0,0 @@ -'\" t -.\" Title: zmsg -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZMSG" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmsg \- working with multipart messages -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// This class has draft methods, which may change over time\&. They are not -// in stable releases, by default\&. Use \-\-enable\-drafts to enable\&. -// Create a new empty message object -CZMQ_EXPORT zmsg_t * - zmsg_new (void); - -// Receive message from socket, returns zmsg_t object or NULL if the recv -// was interrupted\&. Does a blocking recv\&. If you want to not block then use -// the zloop class or zmsg_recv_nowait or zmq_poll to check for socket input -// before receiving\&. -CZMQ_EXPORT zmsg_t * - zmsg_recv (void *source); - -// Load/append an open file into new message, return the message\&. -// Returns NULL if the message could not be loaded\&. -CZMQ_EXPORT zmsg_t * - zmsg_load (FILE *file); - -// Decodes a serialized message frame created by zmsg_encode () and returns -// a new zmsg_t object\&. Returns NULL if the frame was badly formatted or -// there was insufficient memory to work\&. -CZMQ_EXPORT zmsg_t * - zmsg_decode (zframe_t *frame); - -// Generate a signal message encoding the given status\&. A signal is a short -// message carrying a 1\-byte success/failure code (by convention, 0 means -// OK)\&. Signals are encoded to be distinguishable from "normal" messages\&. -CZMQ_EXPORT zmsg_t * - zmsg_new_signal (byte status); - -// Destroy a message object and all frames it contains -CZMQ_EXPORT void - zmsg_destroy (zmsg_t **self_p); - -// Send message to destination socket, and destroy the message after sending -// it successfully\&. If the message has no frames, sends nothing but destroys -// the message anyhow\&. Nullifies the caller\*(Aqs reference to the message (as -// it is a destructor)\&. -CZMQ_EXPORT int - zmsg_send (zmsg_t **self_p, void *dest); - -// Send message to destination socket as part of a multipart sequence, and -// destroy the message after sending it successfully\&. Note that after a -// zmsg_sendm, you must call zmsg_send or another method that sends a final -// message part\&. If the message has no frames, sends nothing but destroys -// the message anyhow\&. Nullifies the caller\*(Aqs reference to the message (as -// it is a destructor)\&. -CZMQ_EXPORT int - zmsg_sendm (zmsg_t **self_p, void *dest); - -// Return size of message, i\&.e\&. number of frames (0 or more)\&. -CZMQ_EXPORT size_t - zmsg_size (zmsg_t *self); - -// Return total size of all frames in message\&. -CZMQ_EXPORT size_t - zmsg_content_size (zmsg_t *self); - -// Push frame to the front of the message, i\&.e\&. before all other frames\&. -// Message takes ownership of frame, will destroy it when message is sent\&. -// Returns 0 on success, \-1 on error\&. Deprecates zmsg_push, which did not -// nullify the caller\*(Aqs frame reference\&. -CZMQ_EXPORT int - zmsg_prepend (zmsg_t *self, zframe_t **frame_p); - -// Add frame to the end of the message, i\&.e\&. after all other frames\&. -// Message takes ownership of frame, will destroy it when message is sent\&. -// Returns 0 on success\&. Deprecates zmsg_add, which did not nullify the -// caller\*(Aqs frame reference\&. -CZMQ_EXPORT int - zmsg_append (zmsg_t *self, zframe_t **frame_p); - -// Remove first frame from message, if any\&. Returns frame, or NULL\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zframe_t * - zmsg_pop (zmsg_t *self); - -// Push block of memory to front of message, as a new frame\&. -// Returns 0 on success, \-1 on error\&. -CZMQ_EXPORT int - zmsg_pushmem (zmsg_t *self, const void *data, size_t size); - -// Add block of memory to the end of the message, as a new frame\&. -// Returns 0 on success, \-1 on error\&. -CZMQ_EXPORT int - zmsg_addmem (zmsg_t *self, const void *data, size_t size); - -// Push string as new frame to front of message\&. -// Returns 0 on success, \-1 on error\&. -CZMQ_EXPORT int - zmsg_pushstr (zmsg_t *self, const char *string); - -// Push string as new frame to end of message\&. -// Returns 0 on success, \-1 on error\&. -CZMQ_EXPORT int - zmsg_addstr (zmsg_t *self, const char *string); - -// Push formatted string as new frame to front of message\&. -// Returns 0 on success, \-1 on error\&. -CZMQ_EXPORT int - zmsg_pushstrf (zmsg_t *self, const char *format, \&.\&.\&.) CHECK_PRINTF (2); - -// Push formatted string as new frame to end of message\&. -// Returns 0 on success, \-1 on error\&. -CZMQ_EXPORT int - zmsg_addstrf (zmsg_t *self, const char *format, \&.\&.\&.) CHECK_PRINTF (2); - -// Pop frame off front of message, return as fresh string\&. If there were -// no more frames in the message, returns NULL\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zmsg_popstr (zmsg_t *self); - -// Push encoded message as a new frame\&. Message takes ownership of -// submessage, so the original is destroyed in this call\&. Returns 0 on -// success, \-1 on error\&. -CZMQ_EXPORT int - zmsg_addmsg (zmsg_t *self, zmsg_t **msg_p); - -// Remove first submessage from message, if any\&. Returns zmsg_t, or NULL if -// decoding was not successful\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zmsg_t * - zmsg_popmsg (zmsg_t *self); - -// Remove specified frame from list, if present\&. Does not destroy frame\&. -CZMQ_EXPORT void - zmsg_remove (zmsg_t *self, zframe_t *frame); - -// Set cursor to first frame in message\&. Returns frame, or NULL, if the -// message is empty\&. Use this to navigate the frames as a list\&. -CZMQ_EXPORT zframe_t * - zmsg_first (zmsg_t *self); - -// Return the next frame\&. If there are no more frames, returns NULL\&. To move -// to the first frame call zmsg_first()\&. Advances the cursor\&. -CZMQ_EXPORT zframe_t * - zmsg_next (zmsg_t *self); - -// Return the last frame\&. If there are no frames, returns NULL\&. -CZMQ_EXPORT zframe_t * - zmsg_last (zmsg_t *self); - -// Save message to an open file, return 0 if OK, else \-1\&. The message is -// saved as a series of frames, each with length and data\&. Note that the -// file is NOT guaranteed to be portable between operating systems, not -// versions of CZMQ\&. The file format is at present undocumented and liable -// to arbitrary change\&. -CZMQ_EXPORT int - zmsg_save (zmsg_t *self, FILE *file); - -// Serialize multipart message to a single message frame\&. Use this method -// to send structured messages across transports that do not support -// multipart data\&. Allocates and returns a new frame containing the -// serialized message\&. To decode a serialized message frame, use -// zmsg_decode ()\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zframe_t * - zmsg_encode (zmsg_t *self); - -// Create copy of message, as new message object\&. Returns a fresh zmsg_t -// object\&. If message is null, or memory was exhausted, returns null\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT zmsg_t * - zmsg_dup (zmsg_t *self); - -// Send message to zsys log sink (may be stdout, or system facility as -// configured by zsys_set_logstream)\&. -CZMQ_EXPORT void - zmsg_print (zmsg_t *self); - -// Return true if the two messages have the same number of frames and each -// frame in the first message is identical to the corresponding frame in the -// other message\&. As with zframe_eq, return false if either message is NULL\&. -CZMQ_EXPORT bool - zmsg_eq (zmsg_t *self, zmsg_t *other); - -// Return signal value, 0 or greater, if message is a signal, \-1 if not\&. -CZMQ_EXPORT int - zmsg_signal (zmsg_t *self); - -// Probe the supplied object, and report if it looks like a zmsg_t\&. -CZMQ_EXPORT bool - zmsg_is (void *self); - -// Self test of this class\&. -CZMQ_EXPORT void - zmsg_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Return message routing ID, if the message came from a ZMQ_SERVER socket\&. -// Else returns zero\&. -CZMQ_EXPORT uint32_t - zmsg_routing_id (zmsg_t *self); - -// *** Draft method, for development use, may change without warning *** -// Set routing ID on message\&. This is used if/when the message is sent to a -// ZMQ_SERVER socket\&. -CZMQ_EXPORT void - zmsg_set_routing_id (zmsg_t *self, uint32_t routing_id); - -#endif // CZMQ_BUILD_DRAFT_API -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zmsg\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zmsg class provides methods to send and receive multipart messages across 0MQ sockets\&. This class provides a list\-like container interface, with methods to work with the overall container\&. zmsg_t messages are composed of zero or more zframe_t frames\&. -.sp -Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zmsg\&.c\fR\&. -.SH "EXAMPLE" -.PP -\fBFrom zmsg_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Create two PAIR sockets and connect over inproc -zsock_t *output = zsock_new_pair ("@inproc://zmsg\&.test"); -assert (output); -zsock_t *input = zsock_new_pair (">inproc://zmsg\&.test"); -assert (input); - -// Test send and receive of single\-frame message -zmsg_t *msg = zmsg_new (); -assert (msg); -zframe_t *frame = zframe_new ("Hello", 5); -assert (frame); -zmsg_prepend (msg, &frame); -assert (zmsg_size (msg) == 1); -assert (zmsg_content_size (msg) == 5); -rc = zmsg_send (&msg, output); -assert (msg == NULL); -assert (rc == 0); - -msg = zmsg_recv (input); -assert (msg); -assert (zmsg_size (msg) == 1); -assert (zmsg_content_size (msg) == 5); -zmsg_destroy (&msg); - -// Test send and receive of multi\-frame message -msg = zmsg_new (); -assert (msg); -rc = zmsg_addmem (msg, "Frame0", 6); -assert (rc == 0); -rc = zmsg_addmem (msg, "Frame1", 6); -assert (rc == 0); -rc = zmsg_addmem (msg, "Frame2", 6); -assert (rc == 0); -rc = zmsg_addmem (msg, "Frame3", 6); -assert (rc == 0); -rc = zmsg_addmem (msg, "Frame4", 6); -assert (rc == 0); -rc = zmsg_addmem (msg, "Frame5", 6); -assert (rc == 0); -rc = zmsg_addmem (msg, "Frame6", 6); -assert (rc == 0); -rc = zmsg_addmem (msg, "Frame7", 6); -assert (rc == 0); -rc = zmsg_addmem (msg, "Frame8", 6); -assert (rc == 0); -rc = zmsg_addmem (msg, "Frame9", 6); -assert (rc == 0); -zmsg_t *copy = zmsg_dup (msg); -assert (copy); -rc = zmsg_send (©, output); -assert (rc == 0); -rc = zmsg_send (&msg, output); -assert (rc == 0); - -copy = zmsg_recv (input); -assert (copy); -assert (zmsg_size (copy) == 10); -assert (zmsg_content_size (copy) == 60); -zmsg_destroy (©); - -msg = zmsg_recv (input); -assert (msg); -assert (zmsg_size (msg) == 10); -assert (zmsg_content_size (msg) == 60); - -// Save to a file, read back -FILE *file = fopen ("zmsg\&.test", "w"); -assert (file); -rc = zmsg_save (msg, file); -assert (rc == 0); -fclose (file); - -file = fopen ("zmsg\&.test", "r"); -rc = zmsg_save (msg, file); -assert (rc == \-1); -fclose (file); -zmsg_destroy (&msg); - -file = fopen ("zmsg\&.test", "r"); -msg = zmsg_load (file); -assert (msg); -fclose (file); -remove ("zmsg\&.test"); -assert (zmsg_size (msg) == 10); -assert (zmsg_content_size (msg) == 60); - -// Remove all frames except first and last -int frame_nbr; -for (frame_nbr = 0; frame_nbr < 8; frame_nbr++) { - zmsg_first (msg); - frame = zmsg_next (msg); - zmsg_remove (msg, frame); - zframe_destroy (&frame); -} -// Test message frame manipulation -assert (zmsg_size (msg) == 2); -frame = zmsg_last (msg); -assert (zframe_streq (frame, "Frame9")); -assert (zmsg_content_size (msg) == 12); -frame = zframe_new ("Address", 7); -assert (frame); -zmsg_prepend (msg, &frame); -assert (zmsg_size (msg) == 3); -rc = zmsg_addstr (msg, "Body"); -assert (rc == 0); -assert (zmsg_size (msg) == 4); -frame = zmsg_pop (msg); -zframe_destroy (&frame); -assert (zmsg_size (msg) == 3); -char *body = zmsg_popstr (msg); -assert (streq (body, "Frame0")); -free (body); -zmsg_destroy (&msg); - -// Test encoding/decoding -msg = zmsg_new (); -assert (msg); -byte *blank = (byte *) zmalloc (100000); -assert (blank); -rc = zmsg_addmem (msg, blank, 0); -assert (rc == 0); -rc = zmsg_addmem (msg, blank, 1); -assert (rc == 0); -rc = zmsg_addmem (msg, blank, 253); -assert (rc == 0); -rc = zmsg_addmem (msg, blank, 254); -assert (rc == 0); -rc = zmsg_addmem (msg, blank, 255); -assert (rc == 0); -rc = zmsg_addmem (msg, blank, 256); -assert (rc == 0); -rc = zmsg_addmem (msg, blank, 65535); -assert (rc == 0); -rc = zmsg_addmem (msg, blank, 65536); -assert (rc == 0); -rc = zmsg_addmem (msg, blank, 65537); -assert (rc == 0); -free (blank); -assert (zmsg_size (msg) == 9); -frame = zmsg_encode (msg); -zmsg_destroy (&msg); -msg = zmsg_decode (frame); -assert (msg); -zmsg_destroy (&msg); -zframe_destroy (&frame); - -// Test submessages -msg = zmsg_new (); -assert (msg); -zmsg_t *submsg = zmsg_new (); -zmsg_pushstr (msg, "matr"); -zmsg_pushstr (submsg, "joska"); -rc = zmsg_addmsg (msg, &submsg); -assert (rc == 0); -assert (submsg == NULL); -submsg = zmsg_popmsg (msg); -assert (submsg == NULL); // string "matr" is not encoded zmsg_t, so was discarded -submsg = zmsg_popmsg (msg); -assert (submsg); -body = zmsg_popstr (submsg); -assert (streq (body, "joska")); -free (body); -zmsg_destroy (&submsg); -frame = zmsg_pop (msg); -assert (frame == NULL); -zmsg_destroy (&msg); - -// Test comparison of two messages -msg = zmsg_new (); -zmsg_addstr (msg, "One"); -zmsg_addstr (msg, "Two"); -zmsg_addstr (msg, "Three"); -zmsg_t *msg_other = zmsg_new (); -zmsg_addstr (msg_other, "One"); -zmsg_addstr (msg_other, "Two"); -zmsg_addstr (msg_other, "One\-Hundred"); -zmsg_t *msg_dup = zmsg_dup (msg); -zmsg_t *empty_msg = zmsg_new (); -zmsg_t *empty_msg_2 = zmsg_new (); -assert (zmsg_eq (msg, msg_dup)); -assert (!zmsg_eq (msg, msg_other)); -assert (zmsg_eq (empty_msg, empty_msg_2)); -assert (!zmsg_eq (msg, NULL)); -assert (!zmsg_eq (NULL, empty_msg)); -assert (!zmsg_eq (NULL, NULL)); -zmsg_destroy (&msg); -zmsg_destroy (&msg_other); -zmsg_destroy (&msg_dup); -zmsg_destroy (&empty_msg); -zmsg_destroy (&empty_msg_2); - -// Test signal messages -msg = zmsg_new_signal (0); -assert (zmsg_signal (msg) == 0); -zmsg_destroy (&msg); -msg = zmsg_new_signal (\-1); -assert (zmsg_signal (msg) == 255); -zmsg_destroy (&msg); - -// Now try methods on an empty message -msg = zmsg_new (); -assert (msg); -assert (zmsg_size (msg) == 0); -assert (zmsg_unwrap (msg) == NULL); -assert (zmsg_first (msg) == NULL); -assert (zmsg_last (msg) == NULL); -assert (zmsg_next (msg) == NULL); -assert (zmsg_pop (msg) == NULL); -// Sending an empty message is valid and destroys the message -assert (zmsg_send (&msg, output) == 0); -assert (!msg); - -zsock_destroy (&input); -zsock_destroy (&output); - -#if defined (ZMQ_SERVER) -// Create server and client sockets and connect over inproc -zsock_t *server = zsock_new_server ("inproc://zmsg\-test\-routing"); -assert (server); -zsock_t *client = zsock_new_client ("inproc://zmsg\-test\-routing"); -assert (client); - -// Send request from client to server -zmsg_t *request = zmsg_new (); -assert (request); -zmsg_addstr (request, "Hello"); -rc = zmsg_send (&request, client); -assert (rc == 0); -assert (!request); - -// Read request and send reply -request = zmsg_recv (server); -assert (request); -char *string = zmsg_popstr (request); -assert (streq (string, "Hello")); -assert (zmsg_routing_id (request)); -zstr_free (&string); - -zmsg_t *reply = zmsg_new (); -assert (reply); -zmsg_addstr (reply, "World"); -zmsg_set_routing_id (reply, zmsg_routing_id (request)); -rc = zmsg_send (&reply, server); -assert (rc == 0); -zmsg_destroy (&request); - -// Read reply -reply = zmsg_recv (client); -string = zmsg_popstr (reply); -assert (streq (string, "World")); -assert (zmsg_routing_id (reply) == 0); -zmsg_destroy (&reply); -zstr_free (&string); - -// Client and server disallow multipart -msg = zmsg_new (); -zmsg_addstr (msg, "One"); -zmsg_addstr (msg, "Two"); -rc = zmsg_send (&msg, client); -assert (rc == \-1); -assert (zmsg_size (msg) == 2); -rc = zmsg_send (&msg, server); -assert (rc == \-1); -assert (zmsg_size (msg) == 2); -zmsg_destroy (&msg); - -zsock_destroy (&client); -zsock_destroy (&server); -#endif -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zpoller.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zpoller.3 deleted file mode 100644 index 33e0170d5e8a86..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zpoller.3 +++ /dev/null @@ -1,216 +0,0 @@ -'\" t -.\" Title: zpoller -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZPOLLER" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zpoller \- trivial socket poller class -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// Create new poller, specifying zero or more readers\&. The list of -// readers ends in a NULL\&. Each reader can be a zsock_t instance, a -// zactor_t instance, a libzmq socket (void *), or a file handle\&. -CZMQ_EXPORT zpoller_t * - zpoller_new (void *reader, \&.\&.\&.); - -// Destroy a poller -CZMQ_EXPORT void - zpoller_destroy (zpoller_t **self_p); - -// Add a reader to be polled\&. Returns 0 if OK, \-1 on failure\&. The reader may -// be a libzmq void * socket, a zsock_t instance, or a zactor_t instance\&. -CZMQ_EXPORT int - zpoller_add (zpoller_t *self, void *reader); - -// Remove a reader from the poller; returns 0 if OK, \-1 on failure\&. The reader -// must have been passed during construction, or in an zpoller_add () call\&. -CZMQ_EXPORT int - zpoller_remove (zpoller_t *self, void *reader); - -// By default the poller stops if the process receives a SIGINT or SIGTERM -// signal\&. This makes it impossible to shut\-down message based architectures -// like zactors\&. This method lets you switch off break handling\&. The default -// nonstop setting is off (false)\&. -CZMQ_EXPORT void - zpoller_set_nonstop (zpoller_t *self, bool nonstop); - -// Poll the registered readers for I/O, return first reader that has input\&. -// The reader will be a libzmq void * socket, or a zsock_t or zactor_t -// instance as specified in zpoller_new/zpoller_add\&. The timeout should be -// zero or greater, or \-1 to wait indefinitely\&. Socket priority is defined -// by their order in the poll list\&. If you need a balanced poll, use the low -// level zmq_poll method directly\&. If the poll call was interrupted (SIGINT), -// or the ZMQ context was destroyed, or the timeout expired, returns NULL\&. -// You can test the actual exit condition by calling zpoller_expired () and -// zpoller_terminated ()\&. The timeout is in msec\&. -CZMQ_EXPORT void * - zpoller_wait (zpoller_t *self, int timeout); - -// Return true if the last zpoller_wait () call ended because the timeout -// expired, without any error\&. -CZMQ_EXPORT bool - zpoller_expired (zpoller_t *self); - -// Return true if the last zpoller_wait () call ended because the process -// was interrupted, or the parent context was destroyed\&. -CZMQ_EXPORT bool - zpoller_terminated (zpoller_t *self); - -// Self test of this class\&. -CZMQ_EXPORT void - zpoller_test (bool verbose); - -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zpoller\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zpoller class provides a minimalist interface to ZeroMQ\(cqs zmq_poll API, for the very common case of reading from a number of sockets\&. It does not provide polling for output, nor polling on file handles\&. If you need either of these, use the zmq_poll API directly\&. -.sp -The class implements the poller using the zmq_poller API if that exists, else does the work itself\&. -.SH "EXAMPLE" -.PP -\fBFrom zpoller_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Create a few sockets -zsock_t *vent = zsock_new (ZMQ_PUSH); -assert (vent); -int port_nbr = zsock_bind (vent, "tcp://127\&.0\&.0\&.1:*"); -assert (port_nbr != \-1); -zsock_t *sink = zsock_new (ZMQ_PULL); -assert (sink); -int rc = zsock_connect (sink, "tcp://127\&.0\&.0\&.1:%d", port_nbr); -assert (rc != \-1); -zsock_t *bowl = zsock_new (ZMQ_PULL); -assert (bowl); -zsock_t *dish = zsock_new (ZMQ_PULL); -assert (dish); - -// Set up poller -zpoller_t *poller = zpoller_new (bowl, dish, NULL); -assert (poller); - -// Add a reader to the existing poller -rc = zpoller_add (poller, sink); -assert (rc == 0); - -zstr_send (vent, "Hello, World"); - -// We expect a message only on the sink -zsock_t *which = (zsock_t *) zpoller_wait (poller, \-1); -assert (which == sink); -assert (zpoller_expired (poller) == false); -assert (zpoller_terminated (poller) == false); -char *message = zstr_recv (which); -assert (streq (message, "Hello, World")); -zstr_free (&message); - -// Stop polling reader -rc = zpoller_remove (poller, sink); -assert (rc == 0); - -// Check we can poll an FD -rc = zsock_connect (bowl, "tcp://127\&.0\&.0\&.1:%d", port_nbr); -assert (rc != \-1); -SOCKET fd = zsock_fd (bowl); -rc = zpoller_add (poller, (void *) &fd); -assert (rc != \-1); -zstr_send (vent, "Hello again, world"); -assert (zpoller_wait (poller, 500) == &fd); - -// Check zpoller_set_nonstop () -zsys_interrupted = 1; -zpoller_wait (poller, 0); -assert (zpoller_terminated (poller)); -zpoller_set_nonstop (poller, true); -zpoller_wait (poller, 0); -assert (!zpoller_terminated (poller)); -zsys_interrupted = 0; - -zpoller_destroy (&poller); -zsock_destroy (&vent); -zsock_destroy (&sink); -zsock_destroy (&bowl); -zsock_destroy (&dish); - -#ifdef ZMQ_SERVER -// Check thread safe sockets -zpoller_destroy (&poller); -zsock_t *client = zsock_new (ZMQ_CLIENT); -assert (client); -zsock_t *server = zsock_new (ZMQ_SERVER); -assert (server); -poller = zpoller_new (client, server, NULL); -assert (poller); -port_nbr = zsock_bind (server, "tcp://127\&.0\&.0\&.1:*"); -assert (port_nbr != \-1); -rc = zsock_connect (client, "tcp://127\&.0\&.0\&.1:%d", port_nbr); -assert (rc != \-1); - -zstr_send (client, "Hello, World"); - -// We expect a message only on the server -which = (zsock_t *) zpoller_wait (poller, \-1); -assert (which == server); -assert (zpoller_expired (poller) == false); -assert (zpoller_terminated (poller) == false); -message = zstr_recv (which); -assert (streq (message, "Hello, World")); -zstr_free (&message); - -zpoller_destroy (&poller); -zsock_destroy (&client); -zsock_destroy (&server); -#endif -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zproc.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zproc.3 deleted file mode 100644 index 9bfcfa9c84b840..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zproc.3 +++ /dev/null @@ -1,208 +0,0 @@ -'\" t -.\" Title: zproc -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZPROC" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zproc \- process configuration and status -.SH "SYNOPSIS" -.sp -.nf -// This is a draft class, and may change without notice\&. It is disabled in -// stable builds by default\&. If you use this in applications, please ask -// for it to be pushed to stable state\&. Use \-\-enable\-drafts to enable\&. -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Returns CZMQ version as a single 6\-digit integer encoding the major -// version (x 10000), the minor version (x 100) and the patch\&. -CZMQ_EXPORT int - zproc_czmq_version (void); - -// *** Draft method, for development use, may change without warning *** -// Returns true if the process received a SIGINT or SIGTERM signal\&. -// It is good practice to use this method to exit any infinite loop -// processing messages\&. -CZMQ_EXPORT bool - zproc_interrupted (void); - -// *** Draft method, for development use, may change without warning *** -// Returns true if the underlying libzmq supports CURVE security\&. -CZMQ_EXPORT bool - zproc_has_curve (void); - -// *** Draft method, for development use, may change without warning *** -// Return current host name, for use in public tcp:// endpoints\&. -// If the host name is not resolvable, returns NULL\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zproc_hostname (void); - -// *** Draft method, for development use, may change without warning *** -// Move the current process into the background\&. The precise effect -// depends on the operating system\&. On POSIX boxes, moves to a specified -// working directory (if specified), closes all file handles, reopens -// stdin, stdout, and stderr to the null device, and sets the process to -// ignore SIGHUP\&. On Windows, does nothing\&. Returns 0 if OK, \-1 if there -// was an error\&. -CZMQ_EXPORT void - zproc_daemonize (const char *workdir); - -// *** Draft method, for development use, may change without warning *** -// Drop the process ID into the lockfile, with exclusive lock, and -// switch the process to the specified group and/or user\&. Any of the -// arguments may be null, indicating a no\-op\&. Returns 0 on success, -// \-1 on failure\&. Note if you combine this with zsys_daemonize, run -// after, not before that method, or the lockfile will hold the wrong -// process ID\&. -CZMQ_EXPORT void - zproc_run_as (const char *lockfile, const char *group, const char *user); - -// *** Draft method, for development use, may change without warning *** -// Configure the number of I/O threads that ZeroMQ will use\&. A good -// rule of thumb is one thread per gigabit of traffic in or out\&. The -// default is 1, sufficient for most applications\&. If the environment -// variable ZSYS_IO_THREADS is defined, that provides the default\&. -// Note that this method is valid only before any socket is created\&. -CZMQ_EXPORT void - zproc_set_io_threads (size_t io_threads); - -// *** Draft method, for development use, may change without warning *** -// Configure the number of sockets that ZeroMQ will allow\&. The default -// is 1024\&. The actual limit depends on the system, and you can query it -// by using zsys_socket_limit ()\&. A value of zero means "maximum"\&. -// Note that this method is valid only before any socket is created\&. -CZMQ_EXPORT void - zproc_set_max_sockets (size_t max_sockets); - -// *** Draft method, for development use, may change without warning *** -// Set network interface name to use for broadcasts, particularly zbeacon\&. -// This lets the interface be configured for test environments where required\&. -// For example, on Mac OS X, zbeacon cannot bind to 255\&.255\&.255\&.255 which is -// the default when there is no specified interface\&. If the environment -// variable ZSYS_INTERFACE is set, use that as the default interface name\&. -// Setting the interface to "*" means "use all available interfaces"\&. -CZMQ_EXPORT void - zproc_set_biface (const char *value); - -// *** Draft method, for development use, may change without warning *** -// Return network interface to use for broadcasts, or "" if none was set\&. -CZMQ_EXPORT const char * - zproc_biface (void); - -// *** Draft method, for development use, may change without warning *** -// Set log identity, which is a string that prefixes all log messages sent -// by this process\&. The log identity defaults to the environment variable -// ZSYS_LOGIDENT, if that is set\&. -CZMQ_EXPORT void - zproc_set_log_ident (const char *value); - -// *** Draft method, for development use, may change without warning *** -// Sends log output to a PUB socket bound to the specified endpoint\&. To -// collect such log output, create a SUB socket, subscribe to the traffic -// you care about, and connect to the endpoint\&. Log traffic is sent as a -// single string frame, in the same format as when sent to stdout\&. The -// log system supports a single sender; multiple calls to this method will -// bind the same sender to multiple endpoints\&. To disable the sender, call -// this method with a null argument\&. -CZMQ_EXPORT void - zproc_set_log_sender (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Enable or disable logging to the system facility (syslog on POSIX boxes, -// event log on Windows)\&. By default this is disabled\&. -CZMQ_EXPORT void - zproc_set_log_system (bool logsystem); - -// *** Draft method, for development use, may change without warning *** -// Log error condition \- highest priority -CZMQ_EXPORT void - zproc_log_error (const char *format, \&.\&.\&.) CHECK_PRINTF (1); - -// *** Draft method, for development use, may change without warning *** -// Log warning condition \- high priority -CZMQ_EXPORT void - zproc_log_warning (const char *format, \&.\&.\&.) CHECK_PRINTF (1); - -// *** Draft method, for development use, may change without warning *** -// Log normal, but significant, condition \- normal priority -CZMQ_EXPORT void - zproc_log_notice (const char *format, \&.\&.\&.) CHECK_PRINTF (1); - -// *** Draft method, for development use, may change without warning *** -// Log informational message \- low priority -CZMQ_EXPORT void - zproc_log_info (const char *format, \&.\&.\&.) CHECK_PRINTF (1); - -// *** Draft method, for development use, may change without warning *** -// Log debug\-level message \- lowest priority -CZMQ_EXPORT void - zproc_log_debug (const char *format, \&.\&.\&.) CHECK_PRINTF (1); - -// *** Draft method, for development use, may change without warning *** -// Self test of this class\&. -CZMQ_EXPORT void - zproc_test (bool verbose); - -#endif // CZMQ_BUILD_DRAFT_API -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zproc\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -zproc \- process configuration and status -.sp -Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zproc\&.c\fR\&. -.SH "EXAMPLE" -.PP -\fBFrom zproc_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -Please add \*(Aq@selftest\*(Aq section in \*(Aq\&./\&.\&./src/zproc\&.c\*(Aq\&. -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zproxy.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zproxy.3 deleted file mode 100644 index 037d3da6bb92bd..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zproxy.3 +++ /dev/null @@ -1,402 +0,0 @@ -'\" t -.\" Title: zproxy -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZPROXY" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zproxy \- run a steerable proxy in the background -.SH "SYNOPSIS" -.sp -.nf -// Create new zproxy actor instance\&. The proxy switches messages between -// a frontend socket and a backend socket; use the FRONTEND and BACKEND -// commands to configure these: -// -// zactor_t *proxy = zactor_new (zproxy, NULL); -// -// Destroy zproxy instance\&. This destroys the two sockets and stops any -// message flow between them: -// -// zactor_destroy (&proxy); -// -// Note that all zproxy commands are synchronous, so your application always -// waits for a signal from the actor after each command\&. -// -// Enable verbose logging of commands and activity: -// -// zstr_send (proxy, "VERBOSE"); -// zsock_wait (proxy); -// -// Specify frontend socket type \-\- see zsock_type_str () \-\- and attach to -// endpoints, see zsock_attach ()\&. Note that a proxy socket is always -// serverish: -// -// zstr_sendx (proxy, "FRONTEND", "XSUB", endpoints, NULL); -// zsock_wait (proxy); -// -// Specify backend socket type \-\- see zsock_type_str () \-\- and attach to -// endpoints, see zsock_attach ()\&. Note that a proxy socket is always -// serverish: -// -// zstr_sendx (proxy, "BACKEND", "XPUB", endpoints, NULL); -// zsock_wait (proxy); -// -// Capture all proxied messages; these are delivered to the application -// via an inproc PULL socket that you have already bound to the specified -// endpoint: -// -// zstr_sendx (proxy, "CAPTURE", endpoint, NULL); -// zsock_wait (proxy); -// -// Pause the proxy\&. A paused proxy will cease processing messages, causing -// them to be queued up and potentially hit the high\-water mark on the -// frontend or backend socket, causing messages to be dropped, or writing -// applications to block: -// -// zstr_sendx (proxy, "PAUSE", NULL); -// zsock_wait (proxy); -// -// Resume the proxy\&. Note that the proxy starts automatically as soon as it -// has a properly attached frontend and backend socket: -// -// zstr_sendx (proxy, "RESUME", NULL); -// zsock_wait (proxy); -// -// Configure an authentication domain for the "FRONTEND" or "BACKEND" proxy -// socket \-\- see zsock_set_zap_domain ()\&. Call before binding socket: -// -// zstr_sendx (proxy, "DOMAIN", "FRONTEND", "global", NULL); -// zsock_wait (proxy); -// -// Configure PLAIN authentication for the "FRONTEND" or "BACKEND" proxy -// socket \-\- see zsock_set_plain_server ()\&. Call before binding socket: -// -// zstr_sendx (proxy, "PLAIN", "BACKEND", NULL); -// zsock_wait (proxy); -// -// Configure CURVE authentication for the "FRONTEND" or "BACKEND" proxy -// socket \-\- see zsock_set_curve_server () \-\- specifying both the public and -// secret keys of a certificate as Z85 armored strings \-\- see -// zcert_public_txt () and zcert_secret_txt ()\&. Call before binding socket: -// -// zstr_sendx (proxy, "CURVE", "FRONTEND", public_txt, secret_txt, NULL); -// zsock_wait (proxy); -// -// This is the zproxy constructor as a zactor_fn; the argument is a -// character string specifying frontend and backend socket types as two -// uppercase strings separated by a hyphen: -CZMQ_EXPORT void - zproxy (zsock_t *pipe, void *unused); - -// Selftest -CZMQ_EXPORT void - zproxy_test (bool verbose); -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zproxy\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -A zproxy actor switches messages between a frontend and a backend socket\&. It acts much like the zmq_proxy_steerable method, though it makes benefit of CZMQ\(cqs facilities, to be somewhat simpler to set\-up\&. -.sp -This class replaces zproxy_v2, and is meant for applications that use the CZMQ v3 API (meaning, zsock)\&. -.SH "EXAMPLE" -.PP -\fBFrom zproxy_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Create and configure our proxy -zactor_t *proxy = zactor_new (zproxy, NULL); -assert (proxy); -if (verbose) { - zstr_sendx (proxy, "VERBOSE", NULL); - zsock_wait (proxy); -} -zstr_sendx (proxy, "FRONTEND", "PULL", "inproc://frontend", NULL); -zsock_wait (proxy); -zstr_sendx (proxy, "BACKEND", "PUSH", "inproc://backend", NULL); -zsock_wait (proxy); - -// Connect application sockets to proxy -zsock_t *faucet = zsock_new_push (">inproc://frontend"); -assert (faucet); -zsock_t *sink = zsock_new_pull (">inproc://backend"); -assert (sink); - -// Send some messages and check they arrived -char *hello, *world; -zstr_sendx (faucet, "Hello", "World", NULL); -zstr_recvx (sink, &hello, &world, NULL); -assert (streq (hello, "Hello")); -assert (streq (world, "World")); -zstr_free (&hello); -zstr_free (&world); - -// Test pause/resume functionality -zstr_sendx (proxy, "PAUSE", NULL); -zsock_wait (proxy); -zstr_sendx (faucet, "Hello", "World", NULL); -zsock_set_rcvtimeo (sink, 100); -zstr_recvx (sink, &hello, &world, NULL); -assert (!hello && !world); - -zstr_sendx (proxy, "RESUME", NULL); -zsock_wait (proxy); -zstr_recvx (sink, &hello, &world, NULL); -assert (streq (hello, "Hello")); -assert (streq (world, "World")); -zstr_free (&hello); -zstr_free (&world); - -// Test capture functionality -zsock_t *capture = zsock_new_pull ("inproc://capture"); -assert (capture); - -// Switch on capturing, check that it works -zstr_sendx (proxy, "CAPTURE", "inproc://capture", NULL); -zsock_wait (proxy); -zstr_sendx (faucet, "Hello", "World", NULL); -zstr_recvx (sink, &hello, &world, NULL); -assert (streq (hello, "Hello")); -assert (streq (world, "World")); -zstr_free (&hello); -zstr_free (&world); - -zstr_recvx (capture, &hello, &world, NULL); -assert (streq (hello, "Hello")); -assert (streq (world, "World")); -zstr_free (&hello); -zstr_free (&world); - -zsock_destroy (&faucet); -zsock_destroy (&sink); -zsock_destroy (&capture); -zactor_destroy (&proxy); - -// Test socket creation dependency -proxy = zactor_new (zproxy, NULL); -assert (proxy); - -sink = zsock_new_sub (">ipc://backend", "whatever"); -assert (sink); - -zstr_sendx (proxy, "BACKEND", "XPUB", "ipc://backend", NULL); -zsock_wait (proxy); - -zsock_destroy(&sink); -zactor_destroy(&proxy); - -#if (ZMQ_VERSION_MAJOR == 4) -// Test authentication functionality -# define TESTDIR "\&.test_zproxy" - -// Create temporary directory for test files -zsys_dir_create (TESTDIR); - -char *frontend = NULL; -char *backend = NULL; - -// Check there\*(Aqs no authentication -s_create_test_sockets (&proxy, &faucet, &sink, verbose); -s_bind_test_sockets (proxy, &frontend, &backend); -bool success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); -assert (success); - -// Install the authenticator -zactor_t *auth = zactor_new (zauth, NULL); -assert (auth); -if (verbose) { - zstr_sendx (auth, "VERBOSE", NULL); - zsock_wait (auth); -} - -// Check there\*(Aqs no authentication on a default NULL server -s_bind_test_sockets (proxy, &frontend, &backend); -success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); -assert (success); - -// When we set a domain on the server, we switch on authentication -// for NULL sockets, but with no policies, the client connection -// will be allowed\&. -zstr_sendx (proxy, "DOMAIN", "FRONTEND", "global", NULL); -zsock_wait (proxy); -s_bind_test_sockets (proxy, &frontend, &backend); -success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); -assert (success); - -// Blacklist 127\&.0\&.0\&.1, connection should fail -zstr_sendx (proxy, "DOMAIN", "FRONTEND", "global", NULL); -zsock_wait (proxy); -s_bind_test_sockets (proxy, &frontend, &backend); -zstr_sendx (auth, "DENY", "127\&.0\&.0\&.1", NULL); -zsock_wait (auth); -success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); -assert (!success); - -// Whitelist our address, which overrides the blacklist -zstr_sendx (proxy, "DOMAIN", "FRONTEND", "global", NULL); -zsock_wait (proxy); -zstr_sendx (proxy, "DOMAIN", "BACKEND", "global", NULL); -zsock_wait (proxy); -s_bind_test_sockets (proxy, &frontend, &backend); -zstr_sendx (auth, "ALLOW", "127\&.0\&.0\&.1", NULL); -zsock_wait (auth); -success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); -assert (success); - -// Try PLAIN authentication - -// Test negative case (no server\-side passwords defined) -zstr_sendx (proxy, "PLAIN", "FRONTEND", NULL); -zsock_wait (proxy); -s_bind_test_sockets (proxy, &frontend, &backend); -zsock_set_plain_username (faucet, "admin"); -zsock_set_plain_password (faucet, "Password"); -success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); -assert (!success); - -// Test positive case (server\-side passwords defined) -FILE *password = fopen (TESTDIR "/password\-file", "w"); -assert (password); -fprintf (password, "admin=Password\en"); -fclose (password); -zstr_sendx (proxy, "PLAIN", "FRONTEND", NULL); -zsock_wait (proxy); -zstr_sendx (proxy, "PLAIN", "BACKEND", NULL); -zsock_wait (proxy); -s_bind_test_sockets (proxy, &frontend, &backend); -zsock_set_plain_username (faucet, "admin"); -zsock_set_plain_password (faucet, "Password"); -zsock_set_plain_username (sink, "admin"); -zsock_set_plain_password (sink, "Password"); -zstr_sendx (auth, "PLAIN", TESTDIR "/password\-file", NULL); -zsock_wait (auth); -success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); -assert (success); - -// Test negative case (bad client password) -zstr_sendx (proxy, "PLAIN", "FRONTEND", NULL); -zsock_wait (proxy); -s_bind_test_sockets (proxy, &frontend, &backend); -zsock_set_plain_username (faucet, "admin"); -zsock_set_plain_password (faucet, "Bogus"); -success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); -assert (!success); - -if (zsys_has_curve ()) { - // We\*(Aqll create two new certificates and save the client public - // certificate on disk - zcert_t *server_cert = zcert_new (); - assert (server_cert); - zcert_t *client_cert = zcert_new (); - assert (client_cert); - const char *public_key = zcert_public_txt (server_cert); - const char *secret_key = zcert_secret_txt (server_cert); - - // Try CURVE authentication - - // Test without setting\-up any authentication - zstr_sendx (proxy, "CURVE", "FRONTEND", public_key, secret_key, NULL); - zsock_wait (proxy); - s_bind_test_sockets (proxy, &frontend, &backend); - zcert_apply (client_cert, faucet); - zsock_set_curve_serverkey (faucet, public_key); - success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); - assert (!success); - - // Test CURVE_ALLOW_ANY - zstr_sendx (proxy, "CURVE", "FRONTEND", public_key, secret_key, NULL); - zsock_wait (proxy); - s_bind_test_sockets (proxy, &frontend, &backend); - zcert_apply (client_cert, faucet); - zsock_set_curve_serverkey (faucet, public_key); - zstr_sendx (auth, "CURVE", CURVE_ALLOW_ANY, NULL); - zsock_wait (auth); - success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); - assert (success); - - // Test with client certificate file in authentication folder - zstr_sendx (proxy, "CURVE", "FRONTEND", public_key, secret_key, NULL); - zsock_wait (proxy); - zstr_sendx (proxy, "CURVE", "BACKEND", public_key, secret_key, NULL); - zsock_wait (proxy); - s_bind_test_sockets (proxy, &frontend, &backend); - zcert_apply (client_cert, faucet); - zsock_set_curve_serverkey (faucet, public_key); - zcert_apply (client_cert, sink); - zsock_set_curve_serverkey (sink, public_key); - zcert_save_public (client_cert, TESTDIR "/mycert\&.txt"); - zstr_sendx (auth, "CURVE", TESTDIR, NULL); - zsock_wait (auth); - success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); - assert (success); - - zcert_destroy (&server_cert); - zcert_destroy (&client_cert); -} - -// Remove the authenticator and check a normal connection works -zactor_destroy (&auth); -s_bind_test_sockets (proxy, &frontend, &backend); -success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); -assert (success); - -// Cleanup -zsock_destroy (&faucet); -zsock_destroy (&sink); -zactor_destroy (&proxy); -zstr_free (&frontend); -zstr_free (&backend); - -// Delete temporary directory and test files -zsys_file_delete (TESTDIR "/password\-file"); -zsys_file_delete (TESTDIR "/mycert\&.txt"); -zsys_dir_delete (TESTDIR); -#endif -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zrex.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zrex.3 deleted file mode 100644 index 99c7337d403609..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zrex.3 +++ /dev/null @@ -1,199 +0,0 @@ -'\" t -.\" Title: zrex -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZREX" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zrex \- work with regular expressions -.SH "SYNOPSIS" -.sp -.nf -// Constructor\&. Optionally, sets an expression against which we can match -// text and capture hits\&. If there is an error in the expression, reports -// zrex_valid() as false and provides the error in zrex_strerror()\&. If you -// set a pattern, you can call zrex_matches() to test it against text\&. -CZMQ_EXPORT zrex_t * - zrex_new (const char *expression); - -// Destructor -CZMQ_EXPORT void - zrex_destroy (zrex_t **self_p); - -// Return true if the expression was valid and compiled without errors\&. -CZMQ_EXPORT bool - zrex_valid (zrex_t *self); - -// Return the error message generated during compilation of the expression\&. -CZMQ_EXPORT const char * - zrex_strerror (zrex_t *self); - -// Returns true if the text matches the previously compiled expression\&. -// Use this method to compare one expression against many strings\&. -CZMQ_EXPORT bool - zrex_matches (zrex_t *self, const char *text); - -// Returns true if the text matches the supplied expression\&. Use this -// method to compare one string against several expressions\&. -CZMQ_EXPORT bool - zrex_eq (zrex_t *self, const char *text, const char *expression); - -// Returns number of hits from last zrex_matches or zrex_eq\&. If the text -// matched, returns 1 plus the number of capture groups\&. If the text did -// not match, returns zero\&. To retrieve individual capture groups, call -// zrex_hit ()\&. -CZMQ_EXPORT int - zrex_hits (zrex_t *self); - -// Returns the Nth capture group from the last expression match, where -// N is 0 to the value returned by zrex_hits()\&. Capture group 0 is the -// whole matching string\&. Sequence 1 is the first capture group, if any, -// and so on\&. -CZMQ_EXPORT const char * - zrex_hit (zrex_t *self, uint index); - -// Fetches hits into string variables provided by caller; this makes for -// nicer code than accessing hits by index\&. Caller should not modify nor -// free the returned values\&. Returns number of strings returned\&. This -// method starts at hit 1, i\&.e\&. first capture group, as hit 0 is always -// the original matched string\&. -CZMQ_EXPORT int - zrex_fetch (zrex_t *self, const char **string_p, \&.\&.\&.); - -// Self test of this class -CZMQ_EXPORT void - zrex_test (bool verbose); -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zrex\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -Wraps a very simple regular expression library (SLRE) as a CZMQ class\&. Supports this syntax: -.sp -.if n \{\ -.RS 4 -.\} -.nf -^ Match beginning of a buffer -$ Match end of a buffer -() Grouping and substring capturing -[\&.\&.\&.] Match any character from set -[^\&.\&.\&.] Match any character but ones from set -\&. Match any character -\es Match whitespace -\eS Match non\-whitespace -\ed Match decimal digit -\eD Match non decimal digit -\ea Match alphabetic character -\eA Match non\-alphabetic character -\ew Match alphanumeric character -\eW Match non\-alphanumeric character -\er Match carriage return -\en Match newline -+ Match one or more times (greedy) -+? Match one or more times (non\-greedy) -* Match zero or more times (greedy) -*? Match zero or more times (non\-greedy) -? Match zero or once -\exDD Match byte with hex value 0xDD -\emeta Match one of the meta character: ^$()\&.[*+?\e -.fi -.if n \{\ -.RE -.\} -.sp -Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zrex\&.c\fR\&. -.SH "EXAMPLE" -.PP -\fBFrom zrex_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// This shows the pattern of matching many lines to a single pattern -zrex_t *rex = zrex_new ("\e\ed+\-\e\ed+\-\e\ed+"); -assert (rex); -assert (zrex_valid (rex)); -bool matches = zrex_matches (rex, "123\-456\-789"); -assert (matches); -assert (zrex_hits (rex) == 1); -assert (streq (zrex_hit (rex, 0), "123\-456\-789")); -assert (zrex_hit (rex, 1) == NULL); -zrex_destroy (&rex); - -// Here we pick out hits using capture groups -rex = zrex_new ("(\e\ed+)\-(\e\ed+)\-(\e\ed+)"); -assert (rex); -assert (zrex_valid (rex)); -matches = zrex_matches (rex, "123\-456\-ABC"); -assert (!matches); -matches = zrex_matches (rex, "123\-456\-789"); -assert (matches); -assert (zrex_hits (rex) == 4); -assert (streq (zrex_hit (rex, 0), "123\-456\-789")); -assert (streq (zrex_hit (rex, 1), "123")); -assert (streq (zrex_hit (rex, 2), "456")); -assert (streq (zrex_hit (rex, 3), "789")); -zrex_destroy (&rex); - -// This shows the pattern of matching one line against many -// patterns and then handling the case when it hits -rex = zrex_new (NULL); // No initial pattern -assert (rex); -char *input = "Mechanism: CURVE"; -matches = zrex_eq (rex, input, "Version: (\&.+)"); -assert (!matches); -assert (zrex_hits (rex) == 0); -matches = zrex_eq (rex, input, "Mechanism: (\&.+)"); -assert (matches); -assert (zrex_hits (rex) == 2); -const char *mechanism; -zrex_fetch (rex, &mechanism, NULL); -assert (streq (zrex_hit (rex, 1), "CURVE")); -assert (streq (mechanism, "CURVE")); -zrex_destroy (&rex); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zsock.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zsock.3 deleted file mode 100644 index fc4a7e8b44c21b..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zsock.3 +++ /dev/null @@ -1,1469 +0,0 @@ -'\" t -.\" Title: zsock -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZSOCK" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zsock \- high\-level socket API that hides libzmq contexts and sockets -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// This class has draft methods, which may change over time\&. They are not -// in stable releases, by default\&. Use \-\-enable\-drafts to enable\&. -// Create a new socket\&. Returns the new socket, or NULL if the new socket -// could not be created\&. Note that the symbol zsock_new (and other -// constructors/destructors for zsock) are redirected to the *_checked -// variant, enabling intelligent socket leak detection\&. This can have -// performance implications if you use a LOT of sockets\&. To turn off this -// redirection behaviour, define ZSOCK_NOCHECK\&. -CZMQ_EXPORT zsock_t * - zsock_new (int type); - -// Create a PUB socket\&. Default action is bind\&. -CZMQ_EXPORT zsock_t * - zsock_new_pub (const char *endpoint); - -// Create a SUB socket, and optionally subscribe to some prefix string\&. Default -// action is connect\&. -CZMQ_EXPORT zsock_t * - zsock_new_sub (const char *endpoint, const char *subscribe); - -// Create a REQ socket\&. Default action is connect\&. -CZMQ_EXPORT zsock_t * - zsock_new_req (const char *endpoint); - -// Create a REP socket\&. Default action is bind\&. -CZMQ_EXPORT zsock_t * - zsock_new_rep (const char *endpoint); - -// Create a DEALER socket\&. Default action is connect\&. -CZMQ_EXPORT zsock_t * - zsock_new_dealer (const char *endpoint); - -// Create a ROUTER socket\&. Default action is bind\&. -CZMQ_EXPORT zsock_t * - zsock_new_router (const char *endpoint); - -// Create a PUSH socket\&. Default action is connect\&. -CZMQ_EXPORT zsock_t * - zsock_new_push (const char *endpoint); - -// Create a PULL socket\&. Default action is bind\&. -CZMQ_EXPORT zsock_t * - zsock_new_pull (const char *endpoint); - -// Create an XPUB socket\&. Default action is bind\&. -CZMQ_EXPORT zsock_t * - zsock_new_xpub (const char *endpoint); - -// Create an XSUB socket\&. Default action is connect\&. -CZMQ_EXPORT zsock_t * - zsock_new_xsub (const char *endpoint); - -// Create a PAIR socket\&. Default action is connect\&. -CZMQ_EXPORT zsock_t * - zsock_new_pair (const char *endpoint); - -// Create a STREAM socket\&. Default action is connect\&. -CZMQ_EXPORT zsock_t * - zsock_new_stream (const char *endpoint); - -// Destroy the socket\&. You must use this for any socket created via the -// zsock_new method\&. -CZMQ_EXPORT void - zsock_destroy (zsock_t **self_p); - -// Bind a socket to a formatted endpoint\&. For tcp:// endpoints, supports -// ephemeral ports, if you specify the port number as "*"\&. By default -// zsock uses the IANA designated range from C000 (49152) to FFFF (65535)\&. -// To override this range, follow the "*" with "[first\-last]"\&. Either or -// both first and last may be empty\&. To bind to a random port within the -// range, use "!" in place of "*"\&. -// -// Examples: -// tcp://127\&.0\&.0\&.1:* bind to first free port from C000 up -// tcp://127\&.0\&.0\&.1:! bind to random port from C000 to FFFF -// tcp://127\&.0\&.0\&.1:*[60000\-] bind to first free port from 60000 up -// tcp://127\&.0\&.0\&.1:![\-60000] bind to random port from C000 to 60000 -// tcp://127\&.0\&.0\&.1:![55000\-55999] -// bind to random port from 55000 to 55999 -// -// On success, returns the actual port number used, for tcp:// endpoints, -// and 0 for other transports\&. On failure, returns \-1\&. Note that when using -// ephemeral ports, a port may be reused by different services without -// clients being aware\&. Protocols that run on ephemeral ports should take -// this into account\&. -CZMQ_EXPORT int - zsock_bind (zsock_t *self, const char *format, \&.\&.\&.) CHECK_PRINTF (2); - -// Returns last bound endpoint, if any\&. -CZMQ_EXPORT const char * - zsock_endpoint (zsock_t *self); - -// Unbind a socket from a formatted endpoint\&. -// Returns 0 if OK, \-1 if the endpoint was invalid or the function -// isn\*(Aqt supported\&. -CZMQ_EXPORT int - zsock_unbind (zsock_t *self, const char *format, \&.\&.\&.) CHECK_PRINTF (2); - -// Connect a socket to a formatted endpoint -// Returns 0 if OK, \-1 if the endpoint was invalid\&. -CZMQ_EXPORT int - zsock_connect (zsock_t *self, const char *format, \&.\&.\&.) CHECK_PRINTF (2); - -// Disconnect a socket from a formatted endpoint -// Returns 0 if OK, \-1 if the endpoint was invalid or the function -// isn\*(Aqt supported\&. -CZMQ_EXPORT int - zsock_disconnect (zsock_t *self, const char *format, \&.\&.\&.) CHECK_PRINTF (2); - -// Attach a socket to zero or more endpoints\&. If endpoints is not null, -// parses as list of ZeroMQ endpoints, separated by commas, and prefixed by -// \*(Aq@\*(Aq (to bind the socket) or \*(Aq>\*(Aq (to connect the socket)\&. Returns 0 if all -// endpoints were valid, or \-1 if there was a syntax error\&. If the endpoint -// does not start with \*(Aq@\*(Aq or \*(Aq>\*(Aq, the serverish argument defines whether -// it is used to bind (serverish = true) or connect (serverish = false)\&. -CZMQ_EXPORT int - zsock_attach (zsock_t *self, const char *endpoints, bool serverish); - -// Returns socket type as printable constant string\&. -CZMQ_EXPORT const char * - zsock_type_str (zsock_t *self); - -// Send a \*(Aqpicture\*(Aq message to the socket (or actor)\&. The picture is a -// string that defines the type of each frame\&. This makes it easy to send -// a complex multiframe message in one call\&. The picture can contain any -// of these characters, each corresponding to one or two arguments: -// -// i = int (signed) -// 1 = uint8_t -// 2 = uint16_t -// 4 = uint32_t -// 8 = uint64_t -// s = char * -// b = byte *, size_t (2 arguments) -// c = zchunk_t * -// f = zframe_t * -// h = zhashx_t * -// U = zuuid_t * -// p = void * (sends the pointer value, only meaningful over inproc) -// m = zmsg_t * (sends all frames in the zmsg) -// z = sends zero\-sized frame (0 arguments) -// u = uint (deprecated) -// -// Note that s, b, c, and f are encoded the same way and the choice is -// offered as a convenience to the sender, which may or may not already -// have data in a zchunk or zframe\&. Does not change or take ownership of -// any arguments\&. Returns 0 if successful, \-1 if sending failed for any -// reason\&. -CZMQ_EXPORT int - zsock_send (void *self, const char *picture, \&.\&.\&.); - -// Send a \*(Aqpicture\*(Aq message to the socket (or actor)\&. This is a va_list -// version of zsock_send (), so please consult its documentation for the -// details\&. -CZMQ_EXPORT int - zsock_vsend (void *self, const char *picture, va_list argptr); - -// Receive a \*(Aqpicture\*(Aq message to the socket (or actor)\&. See zsock_send for -// the format and meaning of the picture\&. Returns the picture elements into -// a series of pointers as provided by the caller: -// -// i = int * (stores signed integer) -// 4 = uint32_t * (stores 32\-bit unsigned integer) -// 8 = uint64_t * (stores 64\-bit unsigned integer) -// s = char ** (allocates new string) -// b = byte **, size_t * (2 arguments) (allocates memory) -// c = zchunk_t ** (creates zchunk) -// f = zframe_t ** (creates zframe) -// U = zuuid_t * (creates a zuuid with the data) -// h = zhashx_t ** (creates zhashx) -// p = void ** (stores pointer) -// m = zmsg_t ** (creates a zmsg with the remaing frames) -// z = null, asserts empty frame (0 arguments) -// u = uint * (stores unsigned integer, deprecated) -// -// Note that zsock_recv creates the returned objects, and the caller must -// destroy them when finished with them\&. The supplied pointers do not need -// to be initialized\&. Returns 0 if successful, or \-1 if it failed to recv -// a message, in which case the pointers are not modified\&. When message -// frames are truncated (a short message), sets return values to zero/null\&. -// If an argument pointer is NULL, does not store any value (skips it)\&. -// An \*(Aqn\*(Aq picture matches an empty frame; if the message does not match, -// the method will return \-1\&. -CZMQ_EXPORT int - zsock_recv (void *self, const char *picture, \&.\&.\&.); - -// Receive a \*(Aqpicture\*(Aq message from the socket (or actor)\&. This is a -// va_list version of zsock_recv (), so please consult its documentation -// for the details\&. -CZMQ_EXPORT int - zsock_vrecv (void *self, const char *picture, va_list argptr); - -// Send a binary encoded \*(Aqpicture\*(Aq message to the socket (or actor)\&. This -// method is similar to zsock_send, except the arguments are encoded in a -// binary format that is compatible with zproto, and is designed to reduce -// memory allocations\&. The pattern argument is a string that defines the -// type of each argument\&. Supports these argument types: -// -// pattern C type zproto type: -// 1 uint8_t type = "number" size = "1" -// 2 uint16_t type = "number" size = "2" -// 4 uint32_t type = "number" size = "3" -// 8 uint64_t type = "number" size = "4" -// s char *, 0\-255 chars type = "string" -// S char *, 0\-2^32\-1 chars type = "longstr" -// c zchunk_t * type = "chunk" -// f zframe_t * type = "frame" -// u zuuid_t * type = "uuid" -// m zmsg_t * type = "msg" -// p void *, sends pointer value, only over inproc -// -// Does not change or take ownership of any arguments\&. Returns 0 if -// successful, \-1 if sending failed for any reason\&. -CZMQ_EXPORT int - zsock_bsend (void *self, const char *picture, \&.\&.\&.); - -// Receive a binary encoded \*(Aqpicture\*(Aq message from the socket (or actor)\&. -// This method is similar to zsock_recv, except the arguments are encoded -// in a binary format that is compatible with zproto, and is designed to -// reduce memory allocations\&. The pattern argument is a string that defines -// the type of each argument\&. See zsock_bsend for the supported argument -// types\&. All arguments must be pointers; this call sets them to point to -// values held on a per\-socket basis\&. -// Note that zsock_brecv creates the returned objects, and the caller must -// destroy them when finished with them\&. The supplied pointers do not need -// to be initialized\&. Returns 0 if successful, or \-1 if it failed to read -// a message\&. -CZMQ_EXPORT int - zsock_brecv (void *self, const char *picture, \&.\&.\&.); - -// Set socket to use unbounded pipes (HWM=0); use this in cases when you are -// totally certain the message volume can fit in memory\&. This method works -// across all versions of ZeroMQ\&. Takes a polymorphic socket reference\&. -CZMQ_EXPORT void - zsock_set_unbounded (void *self); - -// Send a signal over a socket\&. A signal is a short message carrying a -// success/failure code (by convention, 0 means OK)\&. Signals are encoded -// to be distinguishable from "normal" messages\&. Accepts a zsock_t or a -// zactor_t argument, and returns 0 if successful, \-1 if the signal could -// not be sent\&. Takes a polymorphic socket reference\&. -CZMQ_EXPORT int - zsock_signal (void *self, byte status); - -// Wait on a signal\&. Use this to coordinate between threads, over pipe -// pairs\&. Blocks until the signal is received\&. Returns \-1 on error, 0 or -// greater on success\&. Accepts a zsock_t or a zactor_t as argument\&. -// Takes a polymorphic socket reference\&. -CZMQ_EXPORT int - zsock_wait (void *self); - -// If there is a partial message still waiting on the socket, remove and -// discard it\&. This is useful when reading partial messages, to get specific -// message types\&. -CZMQ_EXPORT void - zsock_flush (void *self); - -// Probe the supplied object, and report if it looks like a zsock_t\&. -// Takes a polymorphic socket reference\&. -CZMQ_EXPORT bool - zsock_is (void *self); - -// Probe the supplied reference\&. If it looks like a zsock_t instance, return -// the underlying libzmq socket handle; else if it looks like a file -// descriptor, return NULL; else if it looks like a libzmq socket handle, -// return the supplied value\&. Takes a polymorphic socket reference\&. -CZMQ_EXPORT void * - zsock_resolve (void *self); - -// Get socket option `heartbeat_ivl`\&. -// Available from libzmq 4\&.2\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_heartbeat_ivl (void *self); - -// Set socket option `heartbeat_ivl`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_heartbeat_ivl (void *self, int heartbeat_ivl); - -// Get socket option `heartbeat_ttl`\&. -// Available from libzmq 4\&.2\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_heartbeat_ttl (void *self); - -// Set socket option `heartbeat_ttl`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_heartbeat_ttl (void *self, int heartbeat_ttl); - -// Get socket option `heartbeat_timeout`\&. -// Available from libzmq 4\&.2\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_heartbeat_timeout (void *self); - -// Set socket option `heartbeat_timeout`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_heartbeat_timeout (void *self, int heartbeat_timeout); - -// Get socket option `use_fd`\&. -// Available from libzmq 4\&.2\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_use_fd (void *self); - -// Set socket option `use_fd`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_use_fd (void *self, int use_fd); - -// Set socket option `xpub_manual`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_xpub_manual (void *self, int xpub_manual); - -// Set socket option `xpub_welcome_msg`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_xpub_welcome_msg (void *self, const char *xpub_welcome_msg); - -// Set socket option `stream_notify`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_stream_notify (void *self, int stream_notify); - -// Get socket option `invert_matching`\&. -// Available from libzmq 4\&.2\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_invert_matching (void *self); - -// Set socket option `invert_matching`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_invert_matching (void *self, int invert_matching); - -// Set socket option `xpub_verboser`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_xpub_verboser (void *self, int xpub_verboser); - -// Get socket option `connect_timeout`\&. -// Available from libzmq 4\&.2\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_connect_timeout (void *self); - -// Set socket option `connect_timeout`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_connect_timeout (void *self, int connect_timeout); - -// Get socket option `tcp_maxrt`\&. -// Available from libzmq 4\&.2\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_tcp_maxrt (void *self); - -// Set socket option `tcp_maxrt`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_tcp_maxrt (void *self, int tcp_maxrt); - -// Get socket option `thread_safe`\&. -// Available from libzmq 4\&.2\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_thread_safe (void *self); - -// Get socket option `multicast_maxtpdu`\&. -// Available from libzmq 4\&.2\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_multicast_maxtpdu (void *self); - -// Set socket option `multicast_maxtpdu`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_multicast_maxtpdu (void *self, int multicast_maxtpdu); - -// Get socket option `vmci_buffer_size`\&. -// Available from libzmq 4\&.2\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_vmci_buffer_size (void *self); - -// Set socket option `vmci_buffer_size`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_vmci_buffer_size (void *self, int vmci_buffer_size); - -// Get socket option `vmci_buffer_min_size`\&. -// Available from libzmq 4\&.2\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_vmci_buffer_min_size (void *self); - -// Set socket option `vmci_buffer_min_size`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_vmci_buffer_min_size (void *self, int vmci_buffer_min_size); - -// Get socket option `vmci_buffer_max_size`\&. -// Available from libzmq 4\&.2\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_vmci_buffer_max_size (void *self); - -// Set socket option `vmci_buffer_max_size`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_vmci_buffer_max_size (void *self, int vmci_buffer_max_size); - -// Get socket option `vmci_connect_timeout`\&. -// Available from libzmq 4\&.2\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_vmci_connect_timeout (void *self); - -// Set socket option `vmci_connect_timeout`\&. -// Available from libzmq 4\&.2\&.0\&. -CZMQ_EXPORT void - zsock_set_vmci_connect_timeout (void *self, int vmci_connect_timeout); - -// Get socket option `tos`\&. -// Available from libzmq 4\&.1\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_tos (void *self); - -// Set socket option `tos`\&. -// Available from libzmq 4\&.1\&.0\&. -CZMQ_EXPORT void - zsock_set_tos (void *self, int tos); - -// Set socket option `router_handover`\&. -// Available from libzmq 4\&.1\&.0\&. -CZMQ_EXPORT void - zsock_set_router_handover (void *self, int router_handover); - -// Set socket option `connect_rid`\&. -// Available from libzmq 4\&.1\&.0\&. -CZMQ_EXPORT void - zsock_set_connect_rid (void *self, const char *connect_rid); - -// Set socket option `connect_rid` from 32\-octet binary -// Available from libzmq 4\&.1\&.0\&. -CZMQ_EXPORT void - zsock_set_connect_rid_bin (void *self, const byte *connect_rid); - -// Get socket option `handshake_ivl`\&. -// Available from libzmq 4\&.1\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_handshake_ivl (void *self); - -// Set socket option `handshake_ivl`\&. -// Available from libzmq 4\&.1\&.0\&. -CZMQ_EXPORT void - zsock_set_handshake_ivl (void *self, int handshake_ivl); - -// Get socket option `socks_proxy`\&. -// Available from libzmq 4\&.1\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zsock_socks_proxy (void *self); - -// Set socket option `socks_proxy`\&. -// Available from libzmq 4\&.1\&.0\&. -CZMQ_EXPORT void - zsock_set_socks_proxy (void *self, const char *socks_proxy); - -// Set socket option `xpub_nodrop`\&. -// Available from libzmq 4\&.1\&.0\&. -CZMQ_EXPORT void - zsock_set_xpub_nodrop (void *self, int xpub_nodrop); - -// Set socket option `router_mandatory`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_router_mandatory (void *self, int router_mandatory); - -// Set socket option `probe_router`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_probe_router (void *self, int probe_router); - -// Set socket option `req_relaxed`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_req_relaxed (void *self, int req_relaxed); - -// Set socket option `req_correlate`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_req_correlate (void *self, int req_correlate); - -// Set socket option `conflate`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_conflate (void *self, int conflate); - -// Get socket option `zap_domain`\&. -// Available from libzmq 4\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zsock_zap_domain (void *self); - -// Set socket option `zap_domain`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_zap_domain (void *self, const char *zap_domain); - -// Get socket option `mechanism`\&. -// Available from libzmq 4\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_mechanism (void *self); - -// Get socket option `plain_server`\&. -// Available from libzmq 4\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_plain_server (void *self); - -// Set socket option `plain_server`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_plain_server (void *self, int plain_server); - -// Get socket option `plain_username`\&. -// Available from libzmq 4\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zsock_plain_username (void *self); - -// Set socket option `plain_username`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_plain_username (void *self, const char *plain_username); - -// Get socket option `plain_password`\&. -// Available from libzmq 4\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zsock_plain_password (void *self); - -// Set socket option `plain_password`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_plain_password (void *self, const char *plain_password); - -// Get socket option `curve_server`\&. -// Available from libzmq 4\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_curve_server (void *self); - -// Set socket option `curve_server`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_curve_server (void *self, int curve_server); - -// Get socket option `curve_publickey`\&. -// Available from libzmq 4\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zsock_curve_publickey (void *self); - -// Set socket option `curve_publickey`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_curve_publickey (void *self, const char *curve_publickey); - -// Set socket option `curve_publickey` from 32\-octet binary -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_curve_publickey_bin (void *self, const byte *curve_publickey); - -// Get socket option `curve_secretkey`\&. -// Available from libzmq 4\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zsock_curve_secretkey (void *self); - -// Set socket option `curve_secretkey`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_curve_secretkey (void *self, const char *curve_secretkey); - -// Set socket option `curve_secretkey` from 32\-octet binary -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_curve_secretkey_bin (void *self, const byte *curve_secretkey); - -// Get socket option `curve_serverkey`\&. -// Available from libzmq 4\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zsock_curve_serverkey (void *self); - -// Set socket option `curve_serverkey`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_curve_serverkey (void *self, const char *curve_serverkey); - -// Set socket option `curve_serverkey` from 32\-octet binary -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_curve_serverkey_bin (void *self, const byte *curve_serverkey); - -// Get socket option `gssapi_server`\&. -// Available from libzmq 4\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_gssapi_server (void *self); - -// Set socket option `gssapi_server`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_gssapi_server (void *self, int gssapi_server); - -// Get socket option `gssapi_plaintext`\&. -// Available from libzmq 4\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_gssapi_plaintext (void *self); - -// Set socket option `gssapi_plaintext`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_gssapi_plaintext (void *self, int gssapi_plaintext); - -// Get socket option `gssapi_principal`\&. -// Available from libzmq 4\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zsock_gssapi_principal (void *self); - -// Set socket option `gssapi_principal`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_gssapi_principal (void *self, const char *gssapi_principal); - -// Get socket option `gssapi_service_principal`\&. -// Available from libzmq 4\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zsock_gssapi_service_principal (void *self); - -// Set socket option `gssapi_service_principal`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_gssapi_service_principal (void *self, const char *gssapi_service_principal); - -// Get socket option `ipv6`\&. -// Available from libzmq 4\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_ipv6 (void *self); - -// Set socket option `ipv6`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_ipv6 (void *self, int ipv6); - -// Get socket option `immediate`\&. -// Available from libzmq 4\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_immediate (void *self); - -// Set socket option `immediate`\&. -// Available from libzmq 4\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_immediate (void *self, int immediate); - -// Get socket option `type`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_type (void *self); - -// Get socket option `sndhwm`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_sndhwm (void *self); - -// Set socket option `sndhwm`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_sndhwm (void *self, int sndhwm); - -// Get socket option `rcvhwm`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_rcvhwm (void *self); - -// Set socket option `rcvhwm`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_rcvhwm (void *self, int rcvhwm); - -// Get socket option `affinity`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_affinity (void *self); - -// Set socket option `affinity`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_affinity (void *self, int affinity); - -// Set socket option `subscribe`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_subscribe (void *self, const char *subscribe); - -// Set socket option `unsubscribe`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_unsubscribe (void *self, const char *unsubscribe); - -// Get socket option `identity`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zsock_identity (void *self); - -// Set socket option `identity`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_identity (void *self, const char *identity); - -// Get socket option `rate`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_rate (void *self); - -// Set socket option `rate`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_rate (void *self, int rate); - -// Get socket option `recovery_ivl`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_recovery_ivl (void *self); - -// Set socket option `recovery_ivl`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_recovery_ivl (void *self, int recovery_ivl); - -// Get socket option `sndbuf`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_sndbuf (void *self); - -// Set socket option `sndbuf`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_sndbuf (void *self, int sndbuf); - -// Get socket option `rcvbuf`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_rcvbuf (void *self); - -// Set socket option `rcvbuf`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_rcvbuf (void *self, int rcvbuf); - -// Get socket option `linger`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_linger (void *self); - -// Set socket option `linger`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_linger (void *self, int linger); - -// Get socket option `reconnect_ivl`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_reconnect_ivl (void *self); - -// Set socket option `reconnect_ivl`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_reconnect_ivl (void *self, int reconnect_ivl); - -// Get socket option `reconnect_ivl_max`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_reconnect_ivl_max (void *self); - -// Set socket option `reconnect_ivl_max`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_reconnect_ivl_max (void *self, int reconnect_ivl_max); - -// Get socket option `backlog`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_backlog (void *self); - -// Set socket option `backlog`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_backlog (void *self, int backlog); - -// Get socket option `maxmsgsize`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_maxmsgsize (void *self); - -// Set socket option `maxmsgsize`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_maxmsgsize (void *self, int maxmsgsize); - -// Get socket option `multicast_hops`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_multicast_hops (void *self); - -// Set socket option `multicast_hops`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_multicast_hops (void *self, int multicast_hops); - -// Get socket option `rcvtimeo`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_rcvtimeo (void *self); - -// Set socket option `rcvtimeo`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_rcvtimeo (void *self, int rcvtimeo); - -// Get socket option `sndtimeo`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_sndtimeo (void *self); - -// Set socket option `sndtimeo`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_sndtimeo (void *self, int sndtimeo); - -// Set socket option `xpub_verbose`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_xpub_verbose (void *self, int xpub_verbose); - -// Get socket option `tcp_keepalive`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_tcp_keepalive (void *self); - -// Set socket option `tcp_keepalive`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_tcp_keepalive (void *self, int tcp_keepalive); - -// Get socket option `tcp_keepalive_idle`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_tcp_keepalive_idle (void *self); - -// Set socket option `tcp_keepalive_idle`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_tcp_keepalive_idle (void *self, int tcp_keepalive_idle); - -// Get socket option `tcp_keepalive_cnt`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_tcp_keepalive_cnt (void *self); - -// Set socket option `tcp_keepalive_cnt`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_tcp_keepalive_cnt (void *self, int tcp_keepalive_cnt); - -// Get socket option `tcp_keepalive_intvl`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_tcp_keepalive_intvl (void *self); - -// Set socket option `tcp_keepalive_intvl`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_tcp_keepalive_intvl (void *self, int tcp_keepalive_intvl); - -// Get socket option `tcp_accept_filter`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zsock_tcp_accept_filter (void *self); - -// Set socket option `tcp_accept_filter`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_tcp_accept_filter (void *self, const char *tcp_accept_filter); - -// Get socket option `rcvmore`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_rcvmore (void *self); - -// Get socket option `fd`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT SOCKET - zsock_fd (void *self); - -// Get socket option `events`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_events (void *self); - -// Get socket option `last_endpoint`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zsock_last_endpoint (void *self); - -// Set socket option `router_raw`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_router_raw (void *self, int router_raw); - -// Get socket option `ipv4only`\&. -// Available from libzmq 3\&.0\&.0\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT int - zsock_ipv4only (void *self); - -// Set socket option `ipv4only`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_ipv4only (void *self, int ipv4only); - -// Set socket option `delay_attach_on_connect`\&. -// Available from libzmq 3\&.0\&.0\&. -CZMQ_EXPORT void - zsock_set_delay_attach_on_connect (void *self, int delay_attach_on_connect); - -// Self test of this class\&. -CZMQ_EXPORT void - zsock_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Create a SERVER socket\&. Default action is bind\&. -CZMQ_EXPORT zsock_t * - zsock_new_server (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Create a CLIENT socket\&. Default action is connect\&. -CZMQ_EXPORT zsock_t * - zsock_new_client (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Create a RADIO socket\&. Default action is bind\&. -CZMQ_EXPORT zsock_t * - zsock_new_radio (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Create a DISH socket\&. Default action is connect\&. -CZMQ_EXPORT zsock_t * - zsock_new_dish (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Create a GATHER socket\&. Default action is bind\&. -CZMQ_EXPORT zsock_t * - zsock_new_gather (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Create a SCATTER socket\&. Default action is connect\&. -CZMQ_EXPORT zsock_t * - zsock_new_scatter (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Return socket routing ID if any\&. This returns 0 if the socket is not -// of type ZMQ_SERVER or if no request was already received on it\&. -CZMQ_EXPORT uint32_t - zsock_routing_id (zsock_t *self); - -// *** Draft method, for development use, may change without warning *** -// Set routing ID on socket\&. The socket MUST be of type ZMQ_SERVER\&. -// This will be used when sending messages on the socket via the zsock API\&. -CZMQ_EXPORT void - zsock_set_routing_id (zsock_t *self, uint32_t routing_id); - -// *** Draft method, for development use, may change without warning *** -// Join a group for the RADIO\-DISH pattern\&. Call only on ZMQ_DISH\&. -// Returns 0 if OK, \-1 if failed\&. -CZMQ_EXPORT int - zsock_join (void *self, const char *group); - -// *** Draft method, for development use, may change without warning *** -// Leave a group for the RADIO\-DISH pattern\&. Call only on ZMQ_DISH\&. -// Returns 0 if OK, \-1 if failed\&. -CZMQ_EXPORT int - zsock_leave (void *self, const char *group); - -#endif // CZMQ_BUILD_DRAFT_API -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zsock\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zsock class wraps the libzmq socket handle (a void *) with a proper structure that follows the CLASS rules for construction and destruction\&. Some zsock methods take a void * "polymorphic" reference, which can be either a zsock_t or a zactor_t reference, or a libzmq void *\&. -.sp -Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zsock\&.c\fR\&. -.SH "EXAMPLE" -.PP -\fBFrom zsock_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zsock_t *writer = zsock_new_push ("@tcp://127\&.0\&.0\&.1:5560"); -assert (writer); -assert (zsock_resolve (writer) != writer); -assert (streq (zsock_type_str (writer), "PUSH")); - -int rc; -#if (ZMQ_VERSION >= ZMQ_MAKE_VERSION (3, 2, 0)) -// Check unbind -rc = zsock_unbind (writer, "tcp://127\&.0\&.0\&.1:%d", 5560); -assert (rc == 0); - -// In some cases and especially when running under Valgrind, doing -// a bind immediately after an unbind causes an EADDRINUSE error\&. -// Even a short sleep allows the OS to release the port for reuse\&. -zclock_sleep (100); - -// Bind again -rc = zsock_bind (writer, "tcp://127\&.0\&.0\&.1:%d", 5560); -assert (rc == 5560); -assert (streq (zsock_endpoint (writer), "tcp://127\&.0\&.0\&.1:5560")); -#endif - -zsock_t *reader = zsock_new_pull (">tcp://127\&.0\&.0\&.1:5560"); -assert (reader); -assert (zsock_resolve (reader) != reader); -assert (streq (zsock_type_str (reader), "PULL")); - -// Basic Hello, World -zstr_send (writer, "Hello, World"); -zmsg_t *msg = zmsg_recv (reader); -assert (msg); -char *string = zmsg_popstr (msg); -assert (streq (string, "Hello, World")); -free (string); -zmsg_destroy (&msg); - -// Test resolve libzmq socket -#if (ZMQ_VERSION >= ZMQ_MAKE_VERSION (3, 2, 0)) -void *zmq_ctx = zmq_ctx_new (); -#else -void *zmq_ctx = zmq_ctx_new (1); -#endif -assert (zmq_ctx); -void *zmq_sock = zmq_socket (zmq_ctx, ZMQ_PUB); -assert (zmq_sock); -assert (zsock_resolve (zmq_sock) == zmq_sock); -zmq_close (zmq_sock); -zmq_ctx_term (zmq_ctx); - -// Test resolve zsock -zsock_t *resolve = zsock_new_pub("@tcp://127\&.0\&.0\&.1:5561"); -assert (resolve); -assert (zsock_resolve (resolve) == resolve\->handle); -zsock_destroy (&resolve); - -// Test resolve FD -SOCKET fd = zsock_fd (reader); -assert (zsock_resolve ((void *) &fd) == NULL); - -// Test binding to ephemeral ports, sequential and random -int port = zsock_bind (writer, "tcp://127\&.0\&.0\&.1:*"); -assert (port >= DYNAMIC_FIRST && port <= DYNAMIC_LAST); -port = zsock_bind (writer, "tcp://127\&.0\&.0\&.1:*[50000\-]"); -assert (port >= 50000 && port <= DYNAMIC_LAST); -port = zsock_bind (writer, "tcp://127\&.0\&.0\&.1:*[\-50001]"); -assert (port >= DYNAMIC_FIRST && port <= 50001); -port = zsock_bind (writer, "tcp://127\&.0\&.0\&.1:*[60000\-60050]"); -assert (port >= 60000 && port <= 60050); - -port = zsock_bind (writer, "tcp://127\&.0\&.0\&.1:!"); -assert (port >= DYNAMIC_FIRST && port <= DYNAMIC_LAST); -port = zsock_bind (writer, "tcp://127\&.0\&.0\&.1:![50000\-]"); -assert (port >= 50000 && port <= DYNAMIC_LAST); -port = zsock_bind (writer, "tcp://127\&.0\&.0\&.1:![\-50001]"); -assert (port >= DYNAMIC_FIRST && port <= 50001); -port = zsock_bind (writer, "tcp://127\&.0\&.0\&.1:![60000\-60050]"); -assert (port >= 60000 && port <= 60050); - -// Test zsock_attach method -zsock_t *server = zsock_new (ZMQ_DEALER); -assert (server); -rc = zsock_attach (server, "@inproc://myendpoint,tcp://127\&.0\&.0\&.1:5556,inproc://others", true); -assert (rc == 0); -rc = zsock_attach (server, "", false); -assert (rc == 0); -rc = zsock_attach (server, NULL, true); -assert (rc == 0); -rc = zsock_attach (server, ">a,@b, c,, ", false); -assert (rc == \-1); -zsock_destroy (&server); - -// Test zsock_endpoint method -rc = zsock_bind (writer, "inproc://test\&.%s", "writer"); -assert (rc == 0); -assert (streq (zsock_endpoint (writer), "inproc://test\&.writer")); - -// Test error state when connecting to an invalid socket type -// (\*(Aqtxp://\*(Aq instead of \*(Aqtcp://\*(Aq, typo intentional) -rc = zsock_connect (reader, "txp://127\&.0\&.0\&.1:5560"); -assert (rc == \-1); - -// Test signal/wait methods -rc = zsock_signal (writer, 123); -assert (rc == 0); -rc = zsock_wait (reader); -assert (rc == 123); - -// Test zsock_send/recv pictures -uint8_t number1 = 123; -uint16_t number2 = 123 * 123; -uint32_t number4 = 123 * 123; -number4 *= 123; -uint32_t number4_MAX = UINT32_MAX; -uint64_t number8 = 123 * 123; -number8 *= 123; -number8 *= 123; -uint64_t number8_MAX = UINT64_MAX; - -zchunk_t *chunk = zchunk_new ("HELLO", 5); -assert (chunk); -zframe_t *frame = zframe_new ("WORLD", 5); -assert (frame); -zhashx_t *hash = zhashx_new (); -assert (hash); -zuuid_t *uuid = zuuid_new (); -assert (uuid); -zhashx_set_destructor (hash, (zhashx_destructor_fn *) zstr_free); -zhashx_set_duplicator (hash, (zhashx_duplicator_fn *) strdup); -zhashx_insert (hash, "1", "value A"); -zhashx_insert (hash, "2", "value B"); -char *original = "pointer"; - -// Test zsock_recv into each supported type -zsock_send (writer, "i124488zsbcfUhp", - \-12345, number1, number2, number4, number4_MAX, - number8, number8_MAX, - "This is a string", "ABCDE", 5, - chunk, frame, uuid, hash, original); -char *uuid_str = strdup (zuuid_str (uuid)); -zchunk_destroy (&chunk); -zframe_destroy (&frame); -zuuid_destroy (&uuid); -zhashx_destroy (&hash); - -int integer; -byte *data; -size_t size; -char *pointer; -number8_MAX = number8 = number4_MAX = number4 = number2 = number1 = 0ULL; -rc = zsock_recv (reader, "i124488zsbcfUhp", - &integer, &number1, &number2, &number4, &number4_MAX, - &number8, &number8_MAX, &string, &data, &size, &chunk, - &frame, &uuid, &hash, &pointer); -assert (rc == 0); -assert (integer == \-12345); -assert (number1 == 123); -assert (number2 == 123 * 123); -assert (number4 == 123 * 123 * 123); -assert (number4_MAX == UINT32_MAX); -assert (number8 == 123 * 123 * 123 * 123); -assert (number8_MAX == UINT64_MAX); -assert (streq (string, "This is a string")); -assert (memcmp (data, "ABCDE", 5) == 0); -assert (size == 5); -assert (memcmp (zchunk_data (chunk), "HELLO", 5) == 0); -assert (zchunk_size (chunk) == 5); -assert (streq (uuid_str, zuuid_str (uuid))); -assert (memcmp (zframe_data (frame), "WORLD", 5) == 0); -assert (zframe_size (frame) == 5); -char *value = (char *) zhashx_lookup (hash, "1"); -assert (streq (value, "value A")); -value = (char *) zhashx_lookup (hash, "2"); -assert (streq (value, "value B")); -assert (original == pointer); -free (string); -free (data); -free (uuid_str); -zframe_destroy (&frame); -zchunk_destroy (&chunk); -zhashx_destroy (&hash); -zuuid_destroy (&uuid); - -// Test zsock_recv of short message; this lets us return a failure -// with a status code and then nothing else; the receiver will get -// the status code and NULL/zero for all other values -zsock_send (writer, "i", \-1); -zsock_recv (reader, "izsbcfp", - &integer, &string, &data, &size, &chunk, &frame, &pointer); -assert (integer == \-1); -assert (string == NULL); -assert (data == NULL); -assert (size == 0); -assert (chunk == NULL); -assert (frame == NULL); -assert (pointer == NULL); - -msg = zmsg_new (); -zmsg_addstr (msg, "frame 1"); -zmsg_addstr (msg, "frame 2"); -zsock_send (writer, "szm", "header", msg); -zmsg_destroy (&msg); - -zsock_recv (reader, "szm", &string, &msg); - -assert (streq ("header", string)); -assert (zmsg_size (msg) == 2); -assert (zframe_streq (zmsg_first (msg), "frame 1")); -assert (zframe_streq (zmsg_next (msg), "frame 2")); -zstr_free (&string); -zmsg_destroy (&msg); - -// Test zsock_recv with null arguments -chunk = zchunk_new ("HELLO", 5); -assert (chunk); -frame = zframe_new ("WORLD", 5); -assert (frame); -zsock_send (writer, "izsbcfp", - \-12345, "This is a string", "ABCDE", 5, chunk, frame, original); -zframe_destroy (&frame); -zchunk_destroy (&chunk); -zsock_recv (reader, "izsbcfp", &integer, NULL, NULL, NULL, &chunk, NULL, NULL); -assert (integer == \-12345); -assert (memcmp (zchunk_data (chunk), "HELLO", 5) == 0); -assert (zchunk_size (chunk) == 5); -zchunk_destroy (&chunk); - -// Test zsock_bsend/brecv pictures with binary encoding -frame = zframe_new ("Hello", 5); -chunk = zchunk_new ("World", 5); - -msg = zmsg_new (); -zmsg_addstr (msg, "Hello"); -zmsg_addstr (msg, "World"); - -zsock_bsend (writer, "1248sSpcfm", - number1, number2, number4, number8, - "Hello, World", - "Goodbye cruel World!", - original, - chunk, frame, msg); -zchunk_destroy (&chunk); -zframe_destroy (&frame); -zmsg_destroy (&msg); - -number8 = number4 = number2 = number1 = 0; -char *longstr; -zsock_brecv (reader, "1248sSpcfm", - &number1, &number2, &number4, &number8, - &string, &longstr, - &pointer, - &chunk, &frame, &msg); -assert (number1 == 123); -assert (number2 == 123 * 123); -assert (number4 == 123 * 123 * 123); -assert (number8 == 123 * 123 * 123 * 123); -assert (streq (string, "Hello, World")); -assert (streq (longstr, "Goodbye cruel World!")); -assert (pointer == original); -zstr_free (&longstr); -zchunk_destroy (&chunk); -zframe_destroy (&frame); -zmsg_destroy (&msg); - -#ifdef ZMQ_SERVER - -// Test zsock_bsend/brecv pictures with binary encoding on SERVER and CLIENT sockets -server = zsock_new_server ("tcp://127\&.0\&.0\&.1:5561"); -assert (server); -zsock_t* client = zsock_new_client ("tcp://127\&.0\&.0\&.1:5561"); -assert (client); - -// From client to server -chunk = zchunk_new ("World", 5); -zsock_bsend (client, "1248sSpc", - number1, number2, number4, number8, - "Hello, World", - "Goodbye cruel World!", - original, - chunk); -zchunk_destroy (&chunk); - -number8 = number4 = number2 = number1 = 0; -zsock_brecv (server, "1248sSpc", - &number1, &number2, &number4, &number8, - &string, &longstr, - &pointer, - &chunk); -assert (number1 == 123); -assert (number2 == 123 * 123); -assert (number4 == 123 * 123 * 123); -assert (number8 == 123 * 123 * 123 * 123); -assert (streq (string, "Hello, World")); -assert (streq (longstr, "Goodbye cruel World!")); -assert (pointer == original); -assert (zsock_routing_id (server)); -zstr_free (&longstr); -zchunk_destroy (&chunk); - -// From server to client -chunk = zchunk_new ("World", 5); -zsock_bsend (server, "1248sSpc", - number1, number2, number4, number8, - "Hello, World", - "Goodbye cruel World!", - original, - chunk); -zchunk_destroy (&chunk); - -number8 = number4 = number2 = number1 = 0; -zsock_brecv (client, "1248sSpc", - &number1, &number2, &number4, &number8, - &string, &longstr, - &pointer, - &chunk); -assert (number1 == 123); -assert (number2 == 123 * 123); -assert (number4 == 123 * 123 * 123); -assert (number8 == 123 * 123 * 123 * 123); -assert (streq (string, "Hello, World")); -assert (streq (longstr, "Goodbye cruel World!")); -assert (pointer == original); -assert (zsock_routing_id (client) == 0); -zstr_free (&longstr); -zchunk_destroy (&chunk); - -zsock_destroy (&client); -zsock_destroy (&server); - -#endif - -#ifdef ZMQ_SCATTER - -zsock_t* gather = zsock_new_gather ("inproc://test\-gather\-scatter"); -assert (gather); -zsock_t* scatter = zsock_new_scatter ("inproc://test\-gather\-scatter"); -assert (scatter); - -rc = zstr_send (scatter, "HELLO"); -assert (rc == 0); - -char* message; -message = zstr_recv (gather); -assert (streq(message, "HELLO")); -zstr_free (&message); - -zsock_destroy (&gather); -zsock_destroy (&scatter); - -#endif - -// Check that we can send a zproto format message -zsock_bsend (writer, "1111sS4", 0xAA, 0xA0, 0x02, 0x01, "key", "value", 1234); -zgossip_msg_t *gossip = zgossip_msg_new (); -zgossip_msg_recv (gossip, reader); -assert (zgossip_msg_id (gossip) == ZGOSSIP_MSG_PUBLISH); -zgossip_msg_destroy (&gossip); - -zsock_destroy (&reader); -zsock_destroy (&writer); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zstr.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zstr.3 deleted file mode 100644 index c4ea4275458c67..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zstr.3 +++ /dev/null @@ -1,242 +0,0 @@ -'\" t -.\" Title: zstr -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZSTR" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zstr \- sending and receiving strings -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// This class has draft methods, which may change over time\&. They are not -// in stable releases, by default\&. Use \-\-enable\-drafts to enable\&. -// Receive C string from socket\&. Caller must free returned string using -// zstr_free()\&. Returns NULL if the context is being terminated or the -// process was interrupted\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zstr_recv (void *source); - -// Receive a series of strings (until NULL) from multipart data\&. -// Each string is allocated and filled with string data; if there -// are not enough frames, unallocated strings are set to NULL\&. -// Returns \-1 if the message could not be read, else returns the -// number of strings filled, zero or more\&. Free each returned string -// using zstr_free()\&. If not enough strings are provided, remaining -// multipart frames in the message are dropped\&. -CZMQ_EXPORT int - zstr_recvx (void *source, char **string_p, \&.\&.\&.); - -// Send a C string to a socket, as a frame\&. The string is sent without -// trailing null byte; to read this you can use zstr_recv, or a similar -// method that adds a null terminator on the received string\&. String -// may be NULL, which is sent as ""\&. -CZMQ_EXPORT int - zstr_send (void *dest, const char *string); - -// Send a C string to a socket, as zstr_send(), with a MORE flag, so that -// you can send further strings in the same multi\-part message\&. -CZMQ_EXPORT int - zstr_sendm (void *dest, const char *string); - -// Send a formatted string to a socket\&. Note that you should NOT use -// user\-supplied strings in the format (they may contain \*(Aq%\*(Aq which -// will create security holes)\&. -CZMQ_EXPORT int - zstr_sendf (void *dest, const char *format, \&.\&.\&.) CHECK_PRINTF (2); - -// Send a formatted string to a socket, as for zstr_sendf(), with a -// MORE flag, so that you can send further strings in the same multi\-part -// message\&. -CZMQ_EXPORT int - zstr_sendfm (void *dest, const char *format, \&.\&.\&.) CHECK_PRINTF (2); - -// Send a series of strings (until NULL) as multipart data -// Returns 0 if the strings could be sent OK, or \-1 on error\&. -CZMQ_EXPORT int - zstr_sendx (void *dest, const char *string, \&.\&.\&.); - -// Free a provided string, and nullify the parent pointer\&. Safe to call on -// a null pointer\&. -CZMQ_EXPORT void - zstr_free (char **string_p); - -// Self test of this class\&. -CZMQ_EXPORT void - zstr_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Accepts a void pointer and returns a fresh character string\&. If source -// is null, returns an empty string\&. -// Caller owns return value and must destroy it when done\&. -CZMQ_EXPORT char * - zstr_str (void *source); - -#endif // CZMQ_BUILD_DRAFT_API -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zstr\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zstr class provides utility functions for sending and receiving C strings across 0MQ sockets\&. It sends strings without a terminating null, and appends a null byte on received strings\&. This class is for simple message sending\&. -.sp -.if n \{\ -.RS 4 -.\} -.nf - Memory Wire - +\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-+ +\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-+ -Send | S t r i n g | 0 | \-\-\-\-> | 6 | S t r i n g | - +\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-+ +\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-+ -.fi -.if n \{\ -.RE -.\} -.sp -.if n \{\ -.RS 4 -.\} -.nf - Wire Heap - +\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-+ +\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-+ -Recv | 6 | S t r i n g | \-\-\-\-> | S t r i n g | 0 | - +\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-+ +\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-+ -.fi -.if n \{\ -.RE -.\} -.SH "EXAMPLE" -.PP -\fBFrom zstr_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Create two PAIR sockets and connect over inproc -zsock_t *output = zsock_new_pair ("@inproc://zstr\&.test"); -assert (output); -zsock_t *input = zsock_new_pair (">inproc://zstr\&.test"); -assert (input); - -// Send ten strings, five strings with MORE flag and then END -int string_nbr; -for (string_nbr = 0; string_nbr < 10; string_nbr++) - zstr_sendf (output, "this is string %d", string_nbr); -zstr_sendx (output, "This", "is", "almost", "the", "very", "END", NULL); - -// Read and count until we receive END -string_nbr = 0; -for (string_nbr = 0;; string_nbr++) { - char *string = zstr_recv (input); - assert (string); - if (streq (string, "END")) { - zstr_free (&string); - break; - } - zstr_free (&string); -} -assert (string_nbr == 15); - -zsock_destroy (&input); -zsock_destroy (&output); - -#if defined (ZMQ_SERVER) -// Test SERVER/CLIENT over zstr -zsock_t *server = zsock_new_server ("inproc://zstr\-test\-routing"); -zsock_t *client = zsock_new_client ("inproc://zstr\-test\-routing");; -assert (server); -assert (client); - -// Try normal ping\-pong to check reply routing ID -int rc = zstr_send (client, "Hello"); -assert (rc == 0); -char *request = zstr_recv (server); -assert (streq (request, "Hello")); -assert (zsock_routing_id (server)); -free (request); - -rc = zstr_send (server, "World"); -assert (rc == 0); -char *reply = zstr_recv (client); -assert (streq (reply, "World")); -free (reply); - -rc = zstr_sendf (server, "%s", "World"); -assert (rc == 0); -reply = zstr_recv (client); -assert (streq (reply, "World")); -free (reply); - -// Try ping\-pong using sendx and recx -rc = zstr_sendx (client, "Hello", NULL); -assert (rc == 0); -rc = zstr_recvx (server, &request, NULL); -assert (rc >= 0); -assert (streq (request, "Hello")); -free (request); - -rc = zstr_sendx (server, "World", NULL); -assert (rc == 0); -rc = zstr_recvx (client, &reply, NULL); -assert (rc >= 0); -assert (streq (reply, "World")); -free (reply); - -// Client and server disallow multipart -rc = zstr_sendm (client, "Hello"); -assert (rc == \-1); -rc = zstr_sendm (server, "World"); -assert (rc == \-1); - -zsock_destroy (&client); -zsock_destroy (&server); -#endif -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zsys.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zsys.3 deleted file mode 100644 index 2d4f5c2e45616d..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zsys.3 +++ /dev/null @@ -1,539 +0,0 @@ -'\" t -.\" Title: zsys -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZSYS" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zsys \- system\-level methods -.SH "SYNOPSIS" -.sp -.nf -#define UDP_FRAME_MAX 255 // Max size of UDP frame - -// Callback for interrupt signal handler -typedef void (zsys_handler_fn) (int signal_value); - -// Initialize CZMQ zsys layer; this happens automatically when you create -// a socket or an actor; however this call lets you force initialization -// earlier, so e\&.g\&. logging is properly set\-up before you start working\&. -// Not threadsafe, so call only from main thread\&. Safe to call multiple -// times\&. Returns global CZMQ context\&. -CZMQ_EXPORT void * - zsys_init (void); - -// Optionally shut down the CZMQ zsys layer; this normally happens automatically -// when the process exits; however this call lets you force a shutdown -// earlier, avoiding any potential problems with atexit() ordering, especially -// with Windows dlls\&. -CZMQ_EXPORT void - zsys_shutdown (void); - -// Get a new ZMQ socket, automagically creating a ZMQ context if this is -// the first time\&. Caller is responsible for destroying the ZMQ socket -// before process exits, to avoid a ZMQ deadlock\&. Note: you should not use -// this method in CZMQ apps, use zsock_new() instead\&. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT void * - zsys_socket (int type, const char *filename, size_t line_nbr); - -// Destroy/close a ZMQ socket\&. You should call this for every socket you -// create using zsys_socket()\&. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT int - zsys_close (void *handle, const char *filename, size_t line_nbr); - -// Return ZMQ socket name for socket type -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT char * - zsys_sockname (int socktype); - -// Create a pipe, which consists of two PAIR sockets connected over inproc\&. -// The pipe is configured to use the zsys_pipehwm setting\&. Returns the -// frontend socket successful, NULL if failed\&. -CZMQ_EXPORT zsock_t * - zsys_create_pipe (zsock_t **backend_p); - -// Set interrupt handler; this saves the default handlers so that a -// zsys_handler_reset () can restore them\&. If you call this multiple times -// then the last handler will take affect\&. If handler_fn is NULL, disables -// default SIGINT/SIGTERM handling in CZMQ\&. -CZMQ_EXPORT void - zsys_handler_set (zsys_handler_fn *handler_fn); - -// Reset interrupt handler, call this at exit if needed -CZMQ_EXPORT void - zsys_handler_reset (void); - -// Set default interrupt handler, so Ctrl\-C or SIGTERM will set -// zsys_interrupted\&. Idempotent; safe to call multiple times\&. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT void - zsys_catch_interrupts (void); - -// Return 1 if file exists, else zero -CZMQ_EXPORT bool - zsys_file_exists (const char *filename); - -// Return size of file, or \-1 if not found -CZMQ_EXPORT ssize_t - zsys_file_size (const char *filename); - -// Return file modification time\&. Returns 0 if the file does not exist\&. -CZMQ_EXPORT time_t - zsys_file_modified (const char *filename); - -// Return file mode; provides at least support for the POSIX S_ISREG(m) -// and S_ISDIR(m) macros and the S_IRUSR and S_IWUSR bits, on all boxes\&. -// Returns a mode_t cast to int, or \-1 in case of error\&. -CZMQ_EXPORT int - zsys_file_mode (const char *filename); - -// Delete file\&. Does not complain if the file is absent -CZMQ_EXPORT int - zsys_file_delete (const char *filename); - -// Check if file is \*(Aqstable\*(Aq -CZMQ_EXPORT bool - zsys_file_stable (const char *filename); - -// Create a file path if it doesn\*(Aqt exist\&. The file path is treated as a -// printf format\&. -CZMQ_EXPORT int - zsys_dir_create (const char *pathname, \&.\&.\&.); - -// Remove a file path if empty; the pathname is treated as printf format\&. -CZMQ_EXPORT int - zsys_dir_delete (const char *pathname, \&.\&.\&.); - -// Move to a specified working directory\&. Returns 0 if OK, \-1 if this failed\&. -CZMQ_EXPORT int - zsys_dir_change (const char *pathname); - -// Set private file creation mode; all files created from here will be -// readable/writable by the owner only\&. -CZMQ_EXPORT void - zsys_file_mode_private (void); - -// Reset default file creation mode; all files created from here will use -// process file mode defaults\&. -CZMQ_EXPORT void - zsys_file_mode_default (void); - -// Return the CZMQ version for run\-time API detection; returns version -// number into provided fields, providing reference isn\*(Aqt null in each case\&. -CZMQ_EXPORT void - zsys_version (int *major, int *minor, int *patch); - -// Format a string using printf formatting, returning a freshly allocated -// buffer\&. If there was insufficient memory, returns NULL\&. Free the returned -// string using zstr_free()\&. -CZMQ_EXPORT char * - zsys_sprintf (const char *format, \&.\&.\&.); - -// Format a string with a va_list argument, returning a freshly allocated -// buffer\&. If there was insufficient memory, returns NULL\&. Free the returned -// string using zstr_free()\&. -CZMQ_EXPORT char * - zsys_vprintf (const char *format, va_list argptr); - -// Create UDP beacon socket; if the routable option is true, uses -// multicast (not yet implemented), else uses broadcast\&. This method -// and related ones might _eventually_ be moved to a zudp class\&. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT SOCKET - zsys_udp_new (bool routable); - -// Close a UDP socket -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT int - zsys_udp_close (SOCKET handle); - -// Send zframe to UDP socket, return \-1 if sending failed due to -// interface having disappeared (happens easily with WiFi) -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT int - zsys_udp_send (SOCKET udpsock, zframe_t *frame, inaddr_t *address, int addrlen); - -// Receive zframe from UDP socket, and set address of peer that sent it -// The peername must be a char [INET_ADDRSTRLEN] array\&. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT zframe_t * - zsys_udp_recv (SOCKET udpsock, char *peername, int peerlen); - -// Handle an I/O error on some socket operation; will report and die on -// fatal errors, and continue silently on "try again" errors\&. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT void - zsys_socket_error (const char *reason); - -// Return current host name, for use in public tcp:// endpoints\&. Caller gets -// a freshly allocated string, should free it using zstr_free()\&. If the host -// name is not resolvable, returns NULL\&. -CZMQ_EXPORT char * - zsys_hostname (void); - -// Move the current process into the background\&. The precise effect depends -// on the operating system\&. On POSIX boxes, moves to a specified working -// directory (if specified), closes all file handles, reopens stdin, stdout, -// and stderr to the null device, and sets the process to ignore SIGHUP\&. On -// Windows, does nothing\&. Returns 0 if OK, \-1 if there was an error\&. -CZMQ_EXPORT int - zsys_daemonize (const char *workdir); - -// Drop the process ID into the lockfile, with exclusive lock, and switch -// the process to the specified group and/or user\&. Any of the arguments -// may be null, indicating a no\-op\&. Returns 0 on success, \-1 on failure\&. -// Note if you combine this with zsys_daemonize, run after, not before -// that method, or the lockfile will hold the wrong process ID\&. -CZMQ_EXPORT int - zsys_run_as (const char *lockfile, const char *group, const char *user); - -// Returns true if the underlying libzmq supports CURVE security\&. -// Uses a heuristic probe according to the version of libzmq being used\&. -CZMQ_EXPORT bool - zsys_has_curve (void); - -// Configure the number of I/O threads that ZeroMQ will use\&. A good -// rule of thumb is one thread per gigabit of traffic in or out\&. The -// default is 1, sufficient for most applications\&. If the environment -// variable ZSYS_IO_THREADS is defined, that provides the default\&. -// Note that this method is valid only before any socket is created\&. -CZMQ_EXPORT void - zsys_set_io_threads (size_t io_threads); - -// Configure the number of sockets that ZeroMQ will allow\&. The default -// is 1024\&. The actual limit depends on the system, and you can query it -// by using zsys_socket_limit ()\&. A value of zero means "maximum"\&. -// Note that this method is valid only before any socket is created\&. -CZMQ_EXPORT void - zsys_set_max_sockets (size_t max_sockets); - -// Return maximum number of ZeroMQ sockets that the system will support\&. -CZMQ_EXPORT size_t - zsys_socket_limit (void); - -// Configure the maximum allowed size of a message sent\&. -// The default is INT_MAX\&. -CZMQ_EXPORT void - zsys_set_max_msgsz (int max_msgsz); - -// Return maximum message size\&. -CZMQ_EXPORT int - zsys_max_msgsz (void); - -// Configure the default linger timeout in msecs for new zsock instances\&. -// You can also set this separately on each zsock_t instance\&. The default -// linger time is zero, i\&.e\&. any pending messages will be dropped\&. If the -// environment variable ZSYS_LINGER is defined, that provides the default\&. -// Note that process exit will typically be delayed by the linger time\&. -CZMQ_EXPORT void - zsys_set_linger (size_t linger); - -// Configure the default outgoing pipe limit (HWM) for new zsock instances\&. -// You can also set this separately on each zsock_t instance\&. The default -// HWM is 1,000, on all versions of ZeroMQ\&. If the environment variable -// ZSYS_SNDHWM is defined, that provides the default\&. Note that a value of -// zero means no limit, i\&.e\&. infinite memory consumption\&. -CZMQ_EXPORT void - zsys_set_sndhwm (size_t sndhwm); - -// Configure the default incoming pipe limit (HWM) for new zsock instances\&. -// You can also set this separately on each zsock_t instance\&. The default -// HWM is 1,000, on all versions of ZeroMQ\&. If the environment variable -// ZSYS_RCVHWM is defined, that provides the default\&. Note that a value of -// zero means no limit, i\&.e\&. infinite memory consumption\&. -CZMQ_EXPORT void - zsys_set_rcvhwm (size_t rcvhwm); - -// Configure the default HWM for zactor internal pipes; this is set on both -// ends of the pipe, for outgoing messages only (sndhwm)\&. The default HWM is -// 1,000, on all versions of ZeroMQ\&. If the environment var ZSYS_ACTORHWM is -// defined, that provides the default\&. Note that a value of zero means no -// limit, i\&.e\&. infinite memory consumption\&. -CZMQ_EXPORT void - zsys_set_pipehwm (size_t pipehwm); - -// Return the HWM for zactor internal pipes\&. -CZMQ_EXPORT size_t - zsys_pipehwm (void); - -// Configure use of IPv6 for new zsock instances\&. By default sockets accept -// and make only IPv4 connections\&. When you enable IPv6, sockets will accept -// and connect to both IPv4 and IPv6 peers\&. You can override the setting on -// each zsock_t instance\&. The default is IPv4 only (ipv6 set to 0)\&. If the -// environment variable ZSYS_IPV6 is defined (as 1 or 0), this provides the -// default\&. Note: has no effect on ZMQ v2\&. -CZMQ_EXPORT void - zsys_set_ipv6 (int ipv6); - -// Return use of IPv6 for zsock instances\&. -CZMQ_EXPORT int - zsys_ipv6 (void); - -// Set network interface name to use for broadcasts, particularly zbeacon\&. -// This lets the interface be configured for test environments where required\&. -// For example, on Mac OS X, zbeacon cannot bind to 255\&.255\&.255\&.255 which is -// the default when there is no specified interface\&. If the environment -// variable ZSYS_INTERFACE is set, use that as the default interface name\&. -// Setting the interface to "*" means "use all available interfaces"\&. -CZMQ_EXPORT void - zsys_set_interface (const char *value); - -// Return network interface to use for broadcasts, or "" if none was set\&. -CZMQ_EXPORT const char * - zsys_interface (void); - -// Set IPv6 address to use zbeacon socket, particularly for receiving zbeacon\&. -// This needs to be set IPv6 is enabled as IPv6 can have multiple addresses -// on a given interface\&. If the environment variable ZSYS_IPV6_ADDRESS is set, -// use that as the default IPv6 address\&. -CZMQ_EXPORT void - zsys_set_ipv6_address (const char *value); - -// Return IPv6 address to use for zbeacon reception, or "" if none was set\&. -CZMQ_EXPORT const char * - zsys_ipv6_address (void); - -// Set IPv6 milticast address to use for sending zbeacon messages\&. This needs -// to be set if IPv6 is enabled\&. If the environment variable -// ZSYS_IPV6_MCAST_ADDRESS is set, use that as the default IPv6 multicast -// address\&. -CZMQ_EXPORT void - zsys_set_ipv6_mcast_address (const char *value); - -// Return IPv6 multicast address to use for sending zbeacon, or "" if none was -// set\&. -CZMQ_EXPORT const char * - zsys_ipv6_mcast_address (void); - -// Configure the automatic use of pre\-allocated FDs when creating new sockets\&. -// If 0 (default), nothing will happen\&. Else, when a new socket is bound, the -// system API will be used to check if an existing pre\-allocated FD with a -// matching port (if TCP) or path (if IPC) exists, and if it does it will be -// set via the ZMQ_USE_FD socket option so that the library will use it -// instead of creating a new socket\&. -CZMQ_EXPORT void - zsys_set_auto_use_fd (int auto_use_fd); - -// Return use of automatic pre\-allocated FDs for zsock instances\&. -CZMQ_EXPORT int - zsys_auto_use_fd (void); - -// Set log identity, which is a string that prefixes all log messages sent -// by this process\&. The log identity defaults to the environment variable -// ZSYS_LOGIDENT, if that is set\&. -CZMQ_EXPORT void - zsys_set_logident (const char *value); - -// Set stream to receive log traffic\&. By default, log traffic is sent to -// stdout\&. If you set the stream to NULL, no stream will receive the log -// traffic (it may still be sent to the system facility)\&. -CZMQ_EXPORT void - zsys_set_logstream (FILE *stream); - -// Sends log output to a PUB socket bound to the specified endpoint\&. To -// collect such log output, create a SUB socket, subscribe to the traffic -// you care about, and connect to the endpoint\&. Log traffic is sent as a -// single string frame, in the same format as when sent to stdout\&. The -// log system supports a single sender; multiple calls to this method will -// bind the same sender to multiple endpoints\&. To disable the sender, call -// this method with a null argument\&. -CZMQ_EXPORT void - zsys_set_logsender (const char *endpoint); - -// Enable or disable logging to the system facility (syslog on POSIX boxes, -// event log on Windows)\&. By default this is disabled\&. -CZMQ_EXPORT void - zsys_set_logsystem (bool logsystem); - -// Log error condition \- highest priority -CZMQ_EXPORT void - zsys_error (const char *format, \&.\&.\&.); - -// Log warning condition \- high priority -CZMQ_EXPORT void - zsys_warning (const char *format, \&.\&.\&.); - -// Log normal, but significant, condition \- normal priority -CZMQ_EXPORT void - zsys_notice (const char *format, \&.\&.\&.); - -// Log informational message \- low priority -CZMQ_EXPORT void - zsys_info (const char *format, \&.\&.\&.); - -// Log debug\-level message \- lowest priority -CZMQ_EXPORT void - zsys_debug (const char *format, \&.\&.\&.); - -// Self test of this class -CZMQ_EXPORT void - zsys_test (bool verbose); - -// Global signal indicator, TRUE when user presses Ctrl\-C or the process -// gets a SIGTERM signal\&. -CZMQ_EXPORT extern volatile int zsys_interrupted; -// Deprecated name for this variable -CZMQ_EXPORT extern volatile int zctx_interrupted; -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zsys\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zsys class provides a portable wrapper for system calls\&. We collect them here to reduce the number of weird #ifdefs in other classes\&. As far as possible, the bulk of CZMQ classes are fully portable\&. -.sp -Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zsys\&.c\fR\&. -.SH "EXAMPLE" -.PP -\fBFrom zsys_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -zsys_catch_interrupts (); - -// Check capabilities without using the return value -int rc = zsys_has_curve (); - -if (verbose) { - char *hostname = zsys_hostname (); - zsys_info ("host name is %s", hostname); - free (hostname); - zsys_info ("system limit is %zu ZeroMQ sockets", zsys_socket_limit ()); -} -zsys_set_linger (0); -zsys_set_sndhwm (1000); -zsys_set_rcvhwm (1000); -zsys_set_pipehwm (2500); -assert (zsys_pipehwm () == 2500); -zsys_set_ipv6 (0); - -// Test pipe creation -zsock_t *pipe_back; -zsock_t *pipe_front = zsys_create_pipe (&pipe_back); -zstr_send (pipe_front, "Hello"); -char *string = zstr_recv (pipe_back); -assert (streq (string, "Hello")); -free (string); -zsock_destroy (&pipe_back); -zsock_destroy (&pipe_front); - -// Test file manipulation -rc = zsys_file_delete ("nosuchfile"); -assert (rc == \-1); - -bool rc_bool = zsys_file_exists ("nosuchfile"); -assert (rc_bool != true); - -rc = (int) zsys_file_size ("nosuchfile"); -assert (rc == \-1); - -time_t when = zsys_file_modified ("\&."); -assert (when > 0); - -int mode = zsys_file_mode ("\&."); -assert (S_ISDIR (mode)); -assert (mode & S_IRUSR); -assert (mode & S_IWUSR); - -zsys_file_mode_private (); -rc = zsys_dir_create ("%s/%s", "\&.", "\&.testsys/subdir"); -assert (rc == 0); -when = zsys_file_modified ("\&./\&.testsys/subdir"); -assert (when > 0); -assert (!zsys_file_stable ("\&./\&.testsys/subdir")); -rc = zsys_dir_delete ("%s/%s", "\&.", "\&.testsys/subdir"); -assert (rc == 0); -rc = zsys_dir_delete ("%s/%s", "\&.", "\&.testsys"); -assert (rc == 0); -zsys_file_mode_default (); -assert (zsys_dir_change ("\&.") == 0); - -int major, minor, patch; -zsys_version (&major, &minor, &patch); -assert (major == CZMQ_VERSION_MAJOR); -assert (minor == CZMQ_VERSION_MINOR); -assert (patch == CZMQ_VERSION_PATCH); - -string = zsys_sprintf ("%s %02x", "Hello", 16); -assert (streq (string, "Hello 10")); -free (string); - -char *str64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,\&."; -int num10 = 1234567890; -string = zsys_sprintf ("%s%s%s%s%d", str64, str64, str64, str64, num10); -assert (strlen (string) == (4 * 64 + 10)); -free (string); - -// Test logging system -zsys_set_logident ("czmq_selftest"); -zsys_set_logsender ("inproc://logging"); -void *logger = zsys_socket (ZMQ_SUB, NULL, 0); -assert (logger); -rc = zmq_connect (logger, "inproc://logging"); -assert (rc == 0); -rc = zmq_setsockopt (logger, ZMQ_SUBSCRIBE, "", 0); -assert (rc == 0); - -if (verbose) { - zsys_error ("This is an %s message", "error"); - zsys_warning ("This is a %s message", "warning"); - zsys_notice ("This is a %s message", "notice"); - zsys_info ("This is a %s message", "info"); - zsys_debug ("This is a %s message", "debug"); - zsys_set_logident ("hello, world"); - zsys_info ("This is a %s message", "info"); - zsys_debug ("This is a %s message", "debug"); - - // Check that logsender functionality is working - char *received = zstr_recv (logger); - assert (received); - zstr_free (&received); -} -zsys_close (logger, NULL, 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/ztimerset.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/ztimerset.3 deleted file mode 100644 index 1eaa5ab949caaf..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/ztimerset.3 +++ /dev/null @@ -1,180 +0,0 @@ -'\" t -.\" Title: ztimerset -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZTIMERSET" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -ztimerset \- timer set -.SH "SYNOPSIS" -.sp -.nf -// This is a draft class, and may change without notice\&. It is disabled in -// stable builds by default\&. If you use this in applications, please ask -// for it to be pushed to stable state\&. Use \-\-enable\-drafts to enable\&. -#ifdef CZMQ_BUILD_DRAFT_API -// Callback function for timer event\&. -typedef void (ztimerset_fn) ( - int timer_id, void *arg); - -// *** Draft method, for development use, may change without warning *** -// Create new timer set\&. -CZMQ_EXPORT ztimerset_t * - ztimerset_new (void); - -// *** Draft method, for development use, may change without warning *** -// Destroy a timer set -CZMQ_EXPORT void - ztimerset_destroy (ztimerset_t **self_p); - -// *** Draft method, for development use, may change without warning *** -// Add a timer to the set\&. Returns timer id if OK, \-1 on failure\&. -CZMQ_EXPORT int - ztimerset_add (ztimerset_t *self, size_t interval, ztimerset_fn handler, void *arg); - -// *** Draft method, for development use, may change without warning *** -// Cancel a timer\&. Returns 0 if OK, \-1 on failure\&. -CZMQ_EXPORT int - ztimerset_cancel (ztimerset_t *self, int timer_id); - -// *** Draft method, for development use, may change without warning *** -// Set timer interval\&. Returns 0 if OK, \-1 on failure\&. -// This method is slow, canceling the timer and adding a new one yield better performance\&. -CZMQ_EXPORT int - ztimerset_set_interval (ztimerset_t *self, int timer_id, size_t interval); - -// *** Draft method, for development use, may change without warning *** -// Reset timer to start interval counting from current time\&. Returns 0 if OK, \-1 on failure\&. -// This method is slow, canceling the timer and adding a new one yield better performance\&. -CZMQ_EXPORT int - ztimerset_reset (ztimerset_t *self, int timer_id); - -// *** Draft method, for development use, may change without warning *** -// Return the time until the next interval\&. -// Should be used as timeout parameter for the zpoller wait method\&. -// The timeout is in msec\&. -CZMQ_EXPORT int - ztimerset_timeout (ztimerset_t *self); - -// *** Draft method, for development use, may change without warning *** -// Invoke callback function of all timers which their interval has elapsed\&. -// Should be call after zpoller wait method\&. -// Returns 0 if OK, \-1 on failure\&. -CZMQ_EXPORT int - ztimerset_execute (ztimerset_t *self); - -// *** Draft method, for development use, may change without warning *** -// Self test of this class\&. -CZMQ_EXPORT void - ztimerset_test (bool verbose); - -#endif // CZMQ_BUILD_DRAFT_API -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/ztimerset\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -ztimerset \- timer set -.sp -Please add \fI@discuss\fR section in \fI\&./\&.\&./src/ztimerset\&.c\fR\&. -.SH "EXAMPLE" -.PP -\fBFrom ztimerset_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Simple create/destroy test -ztimerset_t *self = ztimerset_new (); -assert (self); - -// Adding timer -bool timer_invoked = false; -int timer_id = ztimerset_add (self, 100, handler, &timer_invoked); -assert (timer_id != \-1); -int rc = ztimerset_execute (self); -assert (rc == 0); -assert (!timer_invoked); -int timeout = ztimerset_timeout (self); -assert (timeout > 0); -zclock_sleep (timeout); -rc = ztimerset_execute (self); -assert (rc == 0); -assert (timer_invoked); - -// Cancel timer -timeout = ztimerset_timeout (self); -assert (timeout > 0); -rc = ztimerset_cancel (self, timer_id); -assert (rc == 0); -timeout = ztimerset_timeout (self); -assert(timeout == \-1); - -// Reset a timer -timer_id = ztimerset_add (self, 100, handler, &timer_invoked); -assert (timer_id != \-1); -timeout = ztimerset_timeout (self); -assert (timeout > 0); -zclock_sleep (timeout / 2); -timeout = ztimerset_timeout (self); -rc = ztimerset_reset(self, timer_id); -assert (rc == 0); -int timeout2 = ztimerset_timeout (self); -assert (timeout2 > timeout); -rc = ztimerset_cancel (self, timer_id); -assert (rc == 0); - -// Set interval -timer_id = ztimerset_add (self, 100, handler, &timer_invoked); -assert (timer_id != \-1); -timeout = ztimerset_timeout (self); -rc = ztimerset_set_interval(self, timer_id, 200); -timeout2 = ztimerset_timeout (self); -assert (timeout2 > timeout); - -ztimerset_destroy (&self); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/ztrie.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/ztrie.3 deleted file mode 100644 index 6cfb401a344658..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/ztrie.3 +++ /dev/null @@ -1,292 +0,0 @@ -'\" t -.\" Title: ztrie -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZTRIE" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -ztrie \- simple trie for tokenizable strings -.SH "SYNOPSIS" -.sp -.nf -// This is a draft class, and may change without notice\&. It is disabled in -// stable builds by default\&. If you use this in applications, please ask -// for it to be pushed to stable state\&. Use \-\-enable\-drafts to enable\&. -#ifdef CZMQ_BUILD_DRAFT_API -// Callback function for ztrie_node to destroy node data\&. -typedef void (ztrie_destroy_data_fn) ( - void **data); - -// *** Draft method, for development use, may change without warning *** -// Creates a new ztrie\&. -CZMQ_EXPORT ztrie_t * - ztrie_new (char delimiter); - -// *** Draft method, for development use, may change without warning *** -// Destroy the ztrie\&. -CZMQ_EXPORT void - ztrie_destroy (ztrie_t **self_p); - -// *** Draft method, for development use, may change without warning *** -// Inserts a new route into the tree and attaches the data\&. Returns \-1 -// if the route already exists, otherwise 0\&. This method takes ownership of -// the provided data if a destroy_data_fn is provided\&. -CZMQ_EXPORT int - ztrie_insert_route (ztrie_t *self, const char *path, void *data, ztrie_destroy_data_fn destroy_data_fn); - -// *** Draft method, for development use, may change without warning *** -// Removes a route from the trie and destroys its data\&. Returns \-1 if the -// route does not exists, otherwise 0\&. -// the start of the list call zlist_first ()\&. Advances the cursor\&. -CZMQ_EXPORT int - ztrie_remove_route (ztrie_t *self, const char *path); - -// *** Draft method, for development use, may change without warning *** -// Returns true if the path matches a route in the tree, otherwise false\&. -CZMQ_EXPORT bool - ztrie_matches (ztrie_t *self, const char *path); - -// *** Draft method, for development use, may change without warning *** -// Returns the data of a matched route from last ztrie_matches\&. If the path -// did not match, returns NULL\&. Do not delete the data as it\*(Aqs owned by -// ztrie\&. -CZMQ_EXPORT void * - ztrie_hit_data (ztrie_t *self); - -// *** Draft method, for development use, may change without warning *** -// Returns the count of parameters that a matched route has\&. -CZMQ_EXPORT size_t - ztrie_hit_parameter_count (ztrie_t *self); - -// *** Draft method, for development use, may change without warning *** -// Returns the parameters of a matched route with named regexes from last -// ztrie_matches\&. If the path did not match or the route did not contain any -// named regexes, returns NULL\&. -CZMQ_EXPORT zhashx_t * - ztrie_hit_parameters (ztrie_t *self); - -// *** Draft method, for development use, may change without warning *** -// Returns the asterisk matched part of a route, if there has been no match -// or no asterisk match, returns NULL\&. -CZMQ_EXPORT const char * - ztrie_hit_asterisk_match (ztrie_t *self); - -// *** Draft method, for development use, may change without warning *** -// Print the trie -CZMQ_EXPORT void - ztrie_print (ztrie_t *self); - -// *** Draft method, for development use, may change without warning *** -// Self test of this class\&. -CZMQ_EXPORT void - ztrie_test (bool verbose); - -#endif // CZMQ_BUILD_DRAFT_API -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/ztrie\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -This is a variant of a trie or prefix tree where all the descendants of a node have a common prefix of the string associated with that node\&. This implementation is specialized for strings that can be tokenized by a delimiter like a URL, URI or URN\&. Routes in the tree can be matched by regular expressions and by using capturing groups parts of a matched route can be easily obtained\&. -.sp -Note that the performance for pure string based matching is okay but on short strings zhash and zhashx are 3\-4 times faster\&. -.SH "EXAMPLE" -.PP -\fBFrom ztrie_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Create a new trie for matching strings that can be tokenized by a slash -// (e\&.g\&. URLs minus the protocol, address and port)\&. -ztrie_t *self = ztrie_new (\*(Aq/\*(Aq); -assert (self); - -int ret = 0; - -// Let\*(Aqs start by inserting a couple of routes into the trie\&. -// This one is for the route \*(Aq/foo/bar\*(Aq the slash at the beginning of the -// route is important because everything before the first delimiter will be -// discarded\&. A slash at the end of a route is optional though\&. The data -// associated with this node is passed without destroy function which means -// it must be destroyed by the caller\&. -int foo_bar_data = 10; -ret = ztrie_insert_route (self, "/foo/bar", &foo_bar_data, NULL); -assert (ret == 0); - -// Now suppose we like to match all routes with two tokens that start with -// \*(Aq/foo/\*(Aq but aren\*(Aqt \*(Aq/foo/bar\*(Aq\&. This is possible by using regular -// expressions which are enclosed in an opening and closing curly bracket\&. -// Tokens that contain regular expressions are always match after string -// based tokens\&. -// Note: There is no order in which regular expressions are sorted thus -// if you enter multiple expressions for a route you will have to make -// sure they don\*(Aqt have overlapping results\&. For example \*(Aq/foo/{[^/]+}\*(Aq -// and \*(Aq/foo/{\ed+} having could turn out badly\&. -int foo_other_data = 100; -ret = ztrie_insert_route (self, "/foo/{[^/]+}", &foo_other_data, NULL); -assert (ret == 0); - -// Regular expression are only matched against tokens of the same level\&. -// This allows us to append to are route with a regular expression as if -// it were a string\&. -ret = ztrie_insert_route (self, "/foo/{[^/]+}/gulp", NULL, NULL); -assert (ret == 0); - -// Routes are identified by their endpoint, which is the last token of the route\&. -// It is possible to insert routes for a node that already exists but isn\*(Aqt an -// endpoint yet\&. The delimiter at the end of a route is optional and has no effect\&. -ret = ztrie_insert_route (self, "/foo/", NULL, NULL); -assert (ret == 0); - -// If you try to insert a route which already exists the method will return \-1\&. -ret = ztrie_insert_route (self, "/foo", NULL, NULL); -assert (ret == \-1); - -// It is not allowed to insert routes with empty tokens\&. -ret = ztrie_insert_route (self, "//foo", NULL, NULL); -assert (ret == \-1); - -// Everything before the first delimiter is ignored so \*(Aqfoo/bar/baz\*(Aq is equivalent -// to \*(Aq/bar/baz\*(Aq\&. -ret = ztrie_insert_route (self, "foo/bar/baz", NULL, NULL); -assert (ret == 0); -ret = ztrie_insert_route (self, "/bar/baz", NULL, NULL); -assert (ret == \-1); - -// Of course you are allowed to remove routes, in case there is data associated with a -// route and a destroy data function has been supplied that data will be destroyed\&. -ret = ztrie_remove_route (self, "/foo"); -assert (ret == 0); - -// Removing a non existent route will as well return \-1\&. -ret = ztrie_remove_route (self, "/foo"); -assert (ret == \-1); - -// Removing a route with a regular expression must exactly match the entered one\&. -ret = ztrie_remove_route (self, "/foo/{[^/]+}"); -assert (ret == 0); - -// Next we like to match a path by regular expressions and also extract matched -// parts of a route\&. This can be done by naming the regular expression\&. The name of a -// regular expression is entered at the beginning of the curly brackets and separated -// by a colon from the regular expression\&. The first one in this examples is named -// \*(Aqname\*(Aq and names the expression \*(Aq[^/]\*(Aq\&. If there is no capturing group defined in -// the expression the whole matched string will be associated with this parameter\&. In -// case you don\*(Aqt like the get the whole matched string use a capturing group, like -// it has been done for the \*(Aqid\*(Aq parameter\&. This is nice but you can even match as -// many parameter for a token as you like\&. Therefore simply put the parameter names -// separated by colons in front of the regular expression and make sure to add a -// capturing group for each parameter\&. The first parameter will be associated with -// the first capturing and so on\&. -char *data = (char *) malloc (80); -sprintf (data, "%s", "Hello World!"); -ret = ztrie_insert_route (self, "/baz/{name:[^/]+}/{id:\-\-(\e\ed+)}/{street:nr:(\e\ea+)(\e\ed+)}", data, NULL); -assert (ret == 0); - -// There is a lot you can do with regular expression but matching routes -// of arbitrary length wont work\&. Therefore we make use of the asterisk -// operator\&. Just place it at the end of your route, e\&.g\&. \*(Aq/config/bar/*\*(Aq\&. -ret = ztrie_insert_route (self, "/config/bar/*", NULL, NULL); -assert (ret == 0); - -// Appending to an asterisk as you would to with a regular expression -// isn\*(Aqt valid\&. -ret = ztrie_insert_route (self, "/config/bar/*/bar", NULL, NULL); -assert (ret == \-1); - -// The asterisk operator will only work as a leaf in the tree\&. If you -// enter an asterisk in the middle of your route it will simply be -// interpreted as a string\&. -ret = ztrie_insert_route (self, "/test/*/bar", NULL, NULL); -assert (ret == 0); - -// If a parent has an asterisk as child it is not allowed to have -// other siblings\&. -ret = ztrie_insert_route (self, "/config/bar/foo/glup", NULL, NULL); -assert (ret != 0); - -// Test matches -bool hasMatch = false; - -// The route \*(Aq/bar/foo\*(Aq will fail to match as this route has never been inserted\&. -hasMatch = ztrie_matches (self, "/bar/foo"); -assert (!hasMatch); - -// The route \*(Aq/foo/bar\*(Aq will match and we can obtain the data associated with it\&. -hasMatch = ztrie_matches (self, "/foo/bar"); -assert (hasMatch); -int foo_bar_hit_data = *((int *) ztrie_hit_data (self)); -assert (foo_bar_data == foo_bar_hit_data); - -// This route is part of another but is no endpoint itself thus the matches will fail\&. -hasMatch = ztrie_matches (self, "/baz/blub"); -assert (!hasMatch); - -// This route will match our named regular expressions route\&. Thus we can extract data -// from the route by their names\&. -hasMatch = ztrie_matches (self, "/baz/blub/\-\-11/abc23"); -assert (hasMatch); -char *match_data = (char *) ztrie_hit_data (self); -assert (streq ("Hello World!", match_data)); -zhashx_t *parameters = ztrie_hit_parameters (self); -assert (zhashx_size (parameters) == 4); -assert (streq ("blub", (char *) zhashx_lookup (parameters, "name"))); -assert (streq ("11", (char *) zhashx_lookup (parameters, "id"))); -assert (streq ("abc", (char *) zhashx_lookup (parameters, "street"))); -assert (streq ("23", (char *) zhashx_lookup (parameters, "nr"))); -zhashx_destroy (¶meters); - -// This will match our asterisk route \*(Aq/config/bar/*\*(Aq\&. As the result we -// can obtain the asterisk matched part of the route\&. -hasMatch = ztrie_matches (self, "/config/bar/foo/bar"); -assert (hasMatch); -assert (streq (ztrie_hit_asterisk_match (self), "foo/bar")); - -zstr_free (&data); -ztrie_destroy (&self); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man3/zuuid.3 b/phonelibs/zmq/aarch64-linux/share/man/man3/zuuid.3 deleted file mode 100644 index c5431245eb2de4..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man3/zuuid.3 +++ /dev/null @@ -1,171 +0,0 @@ -'\" t -.\" Title: zuuid -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "ZUUID" "3" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zuuid \- UUID support class -.SH "SYNOPSIS" -.sp -.nf -// This is a stable class, and may not change except for emergencies\&. It -// is provided in stable builds\&. -// Create a new UUID object\&. -CZMQ_EXPORT zuuid_t * - zuuid_new (void); - -// Create UUID object from supplied ZUUID_LEN\-octet value\&. -CZMQ_EXPORT zuuid_t * - zuuid_new_from (const byte *source); - -// Destroy a specified UUID object\&. -CZMQ_EXPORT void - zuuid_destroy (zuuid_t **self_p); - -// Set UUID to new supplied ZUUID_LEN\-octet value\&. -CZMQ_EXPORT void - zuuid_set (zuuid_t *self, const byte *source); - -// Set UUID to new supplied string value skipping \*(Aq\-\*(Aq and \*(Aq{\*(Aq \*(Aq}\*(Aq -// optional delimiters\&. Return 0 if OK, else returns \-1\&. -CZMQ_EXPORT int - zuuid_set_str (zuuid_t *self, const char *source); - -// Return UUID binary data\&. -CZMQ_EXPORT const byte * - zuuid_data (zuuid_t *self); - -// Return UUID binary size -CZMQ_EXPORT size_t - zuuid_size (zuuid_t *self); - -// Returns UUID as string -CZMQ_EXPORT const char * - zuuid_str (zuuid_t *self); - -// Return UUID in the canonical string format: 8\-4\-4\-4\-12, in lower -// case\&. Caller does not modify or free returned value\&. See -// http://en\&.wikipedia\&.org/wiki/Universally_unique_identifier -CZMQ_EXPORT const char * - zuuid_str_canonical (zuuid_t *self); - -// Store UUID blob in target array -CZMQ_EXPORT void - zuuid_export (zuuid_t *self, byte *target); - -// Check if UUID is same as supplied value -CZMQ_EXPORT bool - zuuid_eq (zuuid_t *self, const byte *compare); - -// Check if UUID is different from supplied value -CZMQ_EXPORT bool - zuuid_neq (zuuid_t *self, const byte *compare); - -// Make copy of UUID object; if uuid is null, or memory was exhausted, -// returns null\&. -CZMQ_EXPORT zuuid_t * - zuuid_dup (zuuid_t *self); - -// Self test of this class\&. -CZMQ_EXPORT void - zuuid_test (bool verbose); - -Please add \*(Aq@interface\*(Aq section in \*(Aq\&./\&.\&./src/zuuid\&.c\*(Aq\&. -.fi -.SH "DESCRIPTION" -.sp -The zuuid class generates UUIDs and provides methods for working with them\&. If you build CZMQ with libuuid, on Unix/Linux, it will use that library\&. On Windows it will use UuidCreate()\&. Otherwise it will use a random number generator to produce convincing imitations of UUIDs\&. -.sp -Please add \fI@discuss\fR section in \fI\&./\&.\&./src/zuuid\&.c\fR\&. -.SH "EXAMPLE" -.PP -\fBFrom zuuid_test method\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Simple create/destroy test -assert (ZUUID_LEN == 16); -assert (ZUUID_STR_LEN == 32); - -zuuid_t *uuid = zuuid_new (); -assert (uuid); -assert (zuuid_size (uuid) == ZUUID_LEN); -assert (strlen (zuuid_str (uuid)) == ZUUID_STR_LEN); -zuuid_t *copy = zuuid_dup (uuid); -assert (streq (zuuid_str (uuid), zuuid_str (copy))); - -// Check set/set_str/export methods -const char *myuuid = "8CB3E9A9649B4BEF8DE225E9C2CEBB38"; -const char *myuuid2 = "8CB3E9A9\-649B\-4BEF\-8DE2\-25E9C2CEBB38"; -const char *myuuid3 = "{8CB3E9A9\-649B\-4BEF\-8DE2\-25E9C2CEBB38}"; -const char *myuuid4 = "8CB3E9A9649B4BEF8DE225E9C2CEBB3838"; -int rc = zuuid_set_str (uuid, myuuid); -assert (rc == 0); -assert (streq (zuuid_str (uuid), myuuid)); -rc = zuuid_set_str (uuid, myuuid2); -assert (rc == 0); -assert (streq (zuuid_str (uuid), myuuid)); -rc = zuuid_set_str (uuid, myuuid3); -assert (rc == 0); -assert (streq (zuuid_str (uuid), myuuid)); -rc = zuuid_set_str (uuid, myuuid4); -assert (rc == \-1); -byte copy_uuid [ZUUID_LEN]; -zuuid_export (uuid, copy_uuid); -zuuid_set (uuid, copy_uuid); -assert (streq (zuuid_str (uuid), myuuid)); - -// Check the canonical string format -assert (streq (zuuid_str_canonical (uuid), - "8cb3e9a9\-649b\-4bef\-8de2\-25e9c2cebb38")); - -zuuid_destroy (&uuid); -zuuid_destroy (©); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man7/czmq.7 b/phonelibs/zmq/aarch64-linux/share/man/man7/czmq.7 deleted file mode 100644 index 6de419cb00d516..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man7/czmq.7 +++ /dev/null @@ -1,1358 +0,0 @@ -'\" t -.\" Title: czmq -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" Date: 12/31/2016 -.\" Manual: CZMQ Manual -.\" Source: CZMQ 4.0.2 -.\" Language: English -.\" -.TH "CZMQ" "7" "12/31/2016" "CZMQ 4\&.0\&.2" "CZMQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -czmq \- high\-level C binding for ZeroMQ -.SH "SYNOPSIS" -.sp -.nf -#include - -cc [\*(Aqflags\*(Aq] \*(Aqfiles\*(Aq \-lzmq \-lczmq [\*(Aqlibraries\*(Aq] -.fi -.SH "DESCRIPTION" -.SS "Classes" -.sp -These classes provide the main socket and message API: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzsock\fR(3) -\- working with ZeroMQ sockets (high\-level) -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzstr\fR(3) -\- sending and receiving strings -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzmsg\fR(3) -\- working with multipart messages -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzframe\fR(3) -\- working with single message frames -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzactor\fR(3) -\- Actor class (socket + thread) -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzloop\fR(3) -\- event\-driven reactor -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzpoller\fR(3) -\- trivial socket poller class -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzproxy\fR(3) -\- proxy actor (like zmq_proxy_steerable) -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzmonitor\fR(3) -\- monitor events on ZeroMQ sockets -.RE -.sp -These classes support authentication and encryption: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzauth\fR(3) -\- authentication actor for ZeroMQ servers -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzcert\fR(3) -\- work with CURVE security certificates -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzcertstore\fR(3) -\- work with CURVE security certificate stores -.RE -.sp -These classes provide generic containers: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzhash\fR(3) -\- simple generic hash container -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzhashx\fR(3) -\- extended generic hash container -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzlist\fR(3) -\- simple generic list container -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzlistx\fR(3) -\- extended generic list container -.RE -.sp -These classes wrap\-up non\-portable functionality: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzbeacon\fR(3) -\- LAN discovery and presence -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzclock\fR(3) -\- millisecond clocks and delays -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzdir\fR(3) -\- work with file\-system directories -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzdir_patch\fR(3) -\- work with directory differences -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzfile\fR(3) -\- work with file\-system files -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzsys\fR(3) -\- system\-level methods -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzuuid\fR(3) -\- UUID support class -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBziflist\fR(3) -\- list available network interfaces -.RE -.sp -And these utility classes add value: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzchunk\fR(3) -\- work with memory chunks -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzconfig\fR(3) -\- work with textual config files -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzrex\fR(3) -\- work with regular expressions -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzgossip\fR(3) -\- decentralized configuration management -.RE -.sp -These classes are deprecated: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzctx\fR(3) -\- working with ZeroMQ contexts -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzsocket\fR(3) -\- working with ZeroMQ sockets (low\-level) -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzsockopt\fR(3) -\- get/set ZeroMQ socket options -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzthread\fR(3) -\- working with system threads -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzauth_v2\fR(3) -\- authentication for ZeroMQ servers -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzbeacon_v2\fR(3) -\- LAN discovery and presence -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzmonitor_v2\fR(3) -\- socket event monitor -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBzproxy_v2\fR(3) -\- zmq_proxy wrapper -.RE -.SS "Scope and Goals" -.sp -CZMQ has these goals: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -To wrap the \(/OMQ core API in semantics that are natural and lead to shorter, more readable applications\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -To hide the differences between versions of \(/OMQ\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -To provide a space for development of more sophisticated API semantics\&. -.RE -.SS "Ownership and License" -.sp -CZMQ is maintained by the ZeroMQ community at github\&.com/zeromq\&. Its other authors and contributors are listed in the AUTHORS file\&. -.sp -The contributors are listed in AUTHORS\&. This project uses the MPL v2 license, see LICENSE\&. -.SS "Contributing" -.sp -To submit an issue use the issue tracker at \m[blue]\fBhttp://github\&.com/zeromq/czmq/issues\fR\m[]\&. All discussion happens on the zeromq\-dev list or #zeromq IRC channel at irc\&.freenode\&.net\&. -.sp -The proper way to submit patches is to clone this repository, make your changes, and use git to create a patch or a pull request\&. See \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. All contributors are listed in AUTHORS\&. -.sp -All classes are maintained by a single person, who is the responsible editor for that class and who is named in the header as such\&. This is usually the originator of the class\&. When several people collaborate on a class, one single person is always the lead maintainer and the one to blame when it breaks\&. -.sp -The general rule is, if you contribute code to CZMQ you must be willing to maintain it as long as there are users of it\&. Code with no active maintainer will in general be deprecated and/or removed\&. -.SH "USING CZMQ" -.SS "Building and Installing" -.sp -CZMQ uses autotools for packaging\&. To build from git (all example commands are for Linux): -.sp -.if n \{\ -.RS 4 -.\} -.nf - git clone git://github\&.com/zeromq/czmq\&.git - cd czmq - sh autogen\&.sh - \&./configure - make all - sudo make install - sudo ldconfig -.fi -.if n \{\ -.RE -.\} -.sp -You will need the pkg\-config, libtool, and autoreconf packages\&. Set the LD_LIBRARY_PATH to /usr/local/libs unless you install elsewhere\&. -.sp -After building, you can run the CZMQ selftests: -.sp -.if n \{\ -.RS 4 -.\} -.nf - cd src - \&./czmq_selftest -.fi -.if n \{\ -.RE -.\} -.SS "Linking with an Application" -.sp -Include czmq\&.h in your application and link with CZMQ\&. Here is a typical gcc link command: -.sp -.if n \{\ -.RS 4 -.\} -.nf - gcc \-lczmq \-lzmq myapp\&.c \-o myapp -.fi -.if n \{\ -.RE -.\} -.sp -You should read czmq\&.h\&. This file includes zmq\&.h and the system header files that typical \(/OMQ applications will need\&. The provided \fIc\fR shell script lets you write simple portable build scripts: -.sp -.if n \{\ -.RS 4 -.\} -.nf - c \-lczmq \-lzmq \-l myapp -.fi -.if n \{\ -.RE -.\} -.SS "The Class Model" -.sp -CZMQ consists of classes, each class consisting of a \&.h and a \&.c\&. Classes may depend on other classes\&. -.sp -czmq\&.h includes all classes header files, all the time\&. For the user, CZMQ forms one single package\&. All classes start by including czmq\&.h\&. All applications that use CZMQ start by including czmq\&.h\&. czmq\&.h also defines a limited number of small, useful macros and typedefs that have proven useful for writing clearer C code\&. -.sp -All classes (with some exceptions) are based on a flat C class system and follow these rules (where \fIzclass\fR is the class name): -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Class typedef: -zclass_t -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Constructor: -zclass_new -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Destructor: -zclass_destroy -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Property methods: -zclass_property_set, -zclass_property -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Class structures are private (defined in the \&.c source but not the \&.h) -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Properties are accessed only via methods named as described above\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -In the class source code the object is always called -self\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The constructor may take arbitrary arguments, and returns NULL on failure, or a new object\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The destructor takes a pointer to an object reference and nullifies it\&. -.RE -.sp -Return values for methods are: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -For methods that return an object reference, either the reference, or NULL on failure\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -For methods that signal success/failure, a return value of 0 means success, \-1 failure\&. -.RE -.sp -Private/static functions in a class are named s_functionname and are not exported via the header file\&. -.sp -All classes (with some exceptions) have a test method called zclass_test\&. -.SH "DESIGN IDEOLOGY" -.SS "The Problem with C" -.sp -C has the significant advantage of being a small language that, if we take a little care with formatting and naming, can be easily interchanged between developers\&. Every C developer will use much the same 90% of the language\&. Larger languages like C++ provide powerful abstractions like STL containers but at the cost of interchange\&. -.sp -The huge problem with C is that any realistic application needs packages of functionality to bring the language up to the levels we expect for the 21st century\&. Much can be done by using external libraries but every additional library is a dependency that makes the resulting applications harder to build and port\&. While C itself is a highly portable language (and can be made more so by careful use of the preprocessor), most C libraries consider themselves part of the operating system, and as such do not attempt to be portable\&. -.sp -The answer to this, as we learned from building enterprise\-level C applications at iMatix from 1995\-2005, is to create our own fully portable, high\-quality libraries of pre\-packaged functionality, in C\&. Doing this right solves both the requirements of richness of the language, and of portability of the final applications\&. -.SS "A Simple Class Model" -.sp -C has no standard API style\&. It is one thing to write a useful component, but something else to provide an API that is consistent and obvious across many components\&. We learned from building OpenAMQ (\m[blue]\fBhttp://www\&.openamq\&.org\fR\m[]), a messaging client and server of 0\&.5M LoC, that a consistent model for extending C makes life for the application developer much easier\&. -.sp -The general model is that of a class (the source package) that provides objects (in fact C structures)\&. The application creates objects and then works with them\&. When done, the application destroys the object\&. In C, we tend to use the same name for the object as the class, when we can, and it looks like this (to take a fictitious CZMQ class): -.sp -.if n \{\ -.RS 4 -.\} -.nf - zregexp_t *regexp = zregexp_new (regexp_string); - if (!regexp) - printf ("E: invalid regular expression: %s\en", regexp_string); - else - if (zregexp_match (regexp, input_buffer)) - printf ("I: successful match for %s\en", input buffer); - zregexp_destroy (&regexp); -.fi -.if n \{\ -.RE -.\} -.sp -As far as the C program is concerned, the object is a reference to a structure (not a void pointer)\&. We pass the object reference to all methods, since this is still C\&. We could do weird stuff like put method addresses into the structure so that we can emulate a C++ syntax but it\(cqs not worthwhile\&. The goal is not to emulate an OO system, it\(cqs simply to gain consistency\&. The constructor returns an object reference, or NULL if it fails\&. The destructor nullifies the class pointer, and is idempotent\&. -.sp -What we aim at here is the simplest possible consistent syntax\&. -.sp -No model is fully consistent, and classes can define their own rules if it helps make a better result\&. For example: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Some classes may not be opaque\&. For example, we have cases of generated serialization classes that encode and decode structures to/from binary buffers\&. It feels clumsy to have to use methods to access the properties of these classes\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -While every class has a new method that is the formal constructor, some methods may also act as constructors\&. For example, a "dup" method might take one object and return a second object\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -While every class has a destroy method that is the formal destructor, some methods may also act as destructors\&. For example, a method that sends an object may also destroy the object (so that ownership of any buffers can passed to background threads)\&. Such methods take the same "pointer to a reference" argument as the destroy method\&. -.RE -.SS "Naming Style" -.sp -CZMQ aims for short, consistent names, following the theory that names we use most often should be shortest\&. Classes get one\-word names, unless they are part of a family of classes in which case they may be two words, the first being the family name\&. Methods, similarly, get one\-word names and we aim for consistency across classes (so a method that does something semantically similar in two classes will get the same name in both)\&. So the canonical name for any method is: -.sp -.if n \{\ -.RS 4 -.\} -.nf - zclassname_methodname -.fi -.if n \{\ -.RE -.\} -.sp -And the reader can easily parse this without needing special syntax to separate the class name from the method name\&. -.SS "Containers" -.sp -After a long experiment with containers, we\(cqve decided that we need exactly two containers: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -A singly\-linked list\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -A hash table using text keys\&. -.RE -.sp -These are zlist and zhash, respectively\&. Both store void pointers, with no attempt to manage the details of contained objects\&. You can use these containers to create lists of lists, hashes of lists, hashes of hashes, etc\&. -.sp -We assume that at some point we\(cqll need to switch to a doubly\-linked list\&. -.SS "Portability" -.sp -Creating a portable C application can be rewarding in terms of maintaining a single code base across many platforms, and keeping (expensive) system\-specific knowledge separate from application developers\&. In most projects (like \(/OMQ core), there is no portability layer and application code does conditional compilation for all mixes of platforms\&. This leads to quite messy code\&. -.sp -czmq acts as a portability layer, similar to but thinner than libraries like the [Apache Portable Runtime](\m[blue]\fBhttp://apr\&.apache\&.org\fR\m[]) (APR)\&. -.sp -These are the places a C application is subject to arbitrary system differences: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Different compilers may offer slightly different variants of the C language, often lacking specific types or using neat non\-portable names\&. Windows is a big culprit here\&. We solve this by -\fIpatching\fR -the language in czmq_prelude\&.h, e\&.g\&. defining int64_t on Windows\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -System header files are inconsistent, i\&.e\&. you need to include different files depending on the OS type and version\&. We solve this by pulling in all necessary header files in czmq_prelude\&.h\&. This is a proven brute\-force approach that increases recompilation times but eliminates a major source of pain\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -System libraries are inconsistent, i\&.e\&. you need to link with different libraries depending on the OS type and version\&. We solve this with an external compilation tool, -\fIC\fR, which detects the OS type and version (at runtime) and builds the necessary link commands\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -System functions are inconsistent, i\&.e\&. you need to call different functions depending, again, on OS type and version\&. We solve this by building small abstract classes that handle specific areas of functionality, and doing conditional compilation in these\&. -.RE -.sp -An example of the last: -.sp -.if n \{\ -.RS 4 -.\} -.nf - #if (defined (__UNIX__)) - pid = GetCurrentProcessId(); - #elif (defined (__WINDOWS__)) - pid = getpid (); - #else - pid = 0; - #endif -.fi -.if n \{\ -.RE -.\} -.sp -CZMQ uses the GNU autotools system, so non\-portable code can use the macros this defines\&. It can also use macros defined by the czmq_prelude\&.h header file\&. -.SS "Technical Aspects" -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBThread safety\fR: the use of opaque structures is thread safe, though \(/OMQ applications should not share state between threads in any case\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBName spaces\fR: we prefix class names with -z, which ensures that all exported functions are globally safe\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBLibrary versioning\fR: we don\(cqt make any attempt to version the library at this stage\&. Classes are in our experience highly stable once they are built and tested, the only changes typically being added methods\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBPerformance\fR: for critical path processing, you may want to avoid creating and destroying classes\&. However on modern Linux systems the heap allocator is very fast\&. Individual classes can choose whether or not to nullify their data on allocation\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBSelf\-testing\fR: every class has a -selftest -method that runs through the methods of the class\&. In theory, calling all selftest functions of all classes does a full unit test of the library\&. The -czmq_selftest -application does this\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} - -\fBMemory management\fR: CZMQ classes do not use any special memory management techiques to detect leaks\&. We\(cqve done this in the past but it makes the code relatively complex\&. Instead, we do memory leak testing using tools like valgrind\&. -.RE -.SH "UNDER THE HOOD" -.SS "Adding a New Class" -.sp -If you define a new CZMQ class myclass you need to: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Write the -zmyclass\&.c -and -zmyclass\&.h -source files, in -src -and -include -respectively\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Add`#include ` to -include/czmq\&.h\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Add the myclass header and test call to -src/czmq_selftest\&.c\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Add a reference documentation to -\fIdoc/zmyclass\&.txt\fR\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Add myclass to \*(Aqsrc/Makefile\&.am` and -doc/Makefile\&.am\&. -.RE -.sp -The bin/newclass\&.sh shell script will automate these steps for you\&. -.SS "Coding Style" -.sp -In general the zctx class defines the style for the whole library\&. The overriding rules for coding style are consistency, clarity, and ease of maintenance\&. We use the C99 standard for syntax including principally: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The // comment style\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Variables definitions placed in or before the code that uses them\&. -.RE -.sp -So while ANSI C code might say: -.sp -.if n \{\ -.RS 4 -.\} -.nf - zblob_t *file_buffer; /* Buffer for our file */ - \&.\&.\&. (100 lines of code) - file_buffer = zblob_new (); - \&.\&.\&. -.fi -.if n \{\ -.RE -.\} -.sp -The style in CZMQ would be: -.sp -.if n \{\ -.RS 4 -.\} -.nf - zblob_t *file_buffer = zblob_new (); -.fi -.if n \{\ -.RE -.\} -.SS "Assertions" -.sp -We use assertions heavily to catch bad argument values\&. The CZMQ classes do not attempt to validate arguments and report errors; bad arguments are treated as fatal application programming errors\&. -.sp -We also use assertions heavily on calls to system functions that are never supposed to fail, where failure is to be treated as a fatal non\-recoverable error (e\&.g\&. running out of memory)\&. -.sp -Assertion code should always take this form: -.sp -.if n \{\ -.RS 4 -.\} -.nf - int rc = some_function (arguments); - assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.sp -Rather than the side\-effect form: -.sp -.if n \{\ -.RS 4 -.\} -.nf - assert (some_function (arguments) == 0); -.fi -.if n \{\ -.RE -.\} -.sp -Since assertions may be removed by an optimizing compiler\&. -.SS "Documentation" -.sp -Man pages are generated from the class header and source files via the doc/mkman tool, and similar functionality in the gitdown tool (\m[blue]\fBhttp://github\&.com/imatix/gitdown\fR\m[])\&. The header file for a class must wrap its interface as follows (example is from include/zclock\&.h): -.sp -.if n \{\ -.RS 4 -.\} -.nf - // @interface - // Sleep for a number of milliseconds - void - zclock_sleep (int msecs); - - // Return current system clock as milliseconds - int64_t - zclock_time (void); - - // Self test of this class - int - zclock_test (Bool verbose); - // @end -.fi -.if n \{\ -.RE -.\} -.sp -The source file for a class must provide documentation as follows: -.sp -.if n \{\ -.RS 4 -.\} -.nf - /* - @header - \&.\&.\&.short explanation of class\&.\&.\&. - @discuss - \&.\&.\&.longer discussion of how it works\&.\&.\&. - @end - */ -.fi -.if n \{\ -.RE -.\} -.sp -The source file for a class then provides the self test example as follows: -.sp -.if n \{\ -.RS 4 -.\} -.nf - // @selftest - int64_t start = zclock_time (); - zclock_sleep (10); - assert ((zclock_time () \- start) >= 10); - // @end -.fi -.if n \{\ -.RE -.\} -.sp -The template for man pages is in doc/mkman\&. -.SS "Development" -.sp -CZMQ is developed through a test\-driven process that guarantees no memory violations or leaks in the code: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Modify a class or method\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Update the test method for that class\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Run the -\fIselftest\fR -script, which uses the Valgrind memcheck tool\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Repeat until perfect\&. -.RE -.SS "Porting CZMQ" -.sp -When you try CZMQ on an OS that it\(cqs not been used on (ever, or for a while), you will hit code that does not compile\&. In some cases the patches are trivial, in other cases (usually when porting to Windows), the work needed to build equivalent functionality may be quite heavy\&. In any case, the benefit is that once ported, the functionality is available to all applications\&. -.sp -Before attempting to patch code for portability, please read the czmq_prelude\&.h header file\&. There are several typical types of changes you may need to make to get functionality working on a specific operating system: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Defining typedefs which are missing on that specific compiler: do this in czmq_prelude\&.h\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Defining macros that rename exotic library functions to more conventional names: do this in czmq_prelude\&.h\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Reimplementing specific methods to use a non\-standard API: this is typically needed on Windows\&. Do this in the relevant class, using #ifdefs to properly differentiate code for different platforms\&. -.RE -.sp -The canonical \fIstandard operating system\fR for all CZMQ code is Linux, gcc, POSIX\&. -.SH "AUTHORS" -.sp -The czmq manual was written by the authors in the AUTHORS file\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fB\%\fR\m[] -.sp -Report bugs to the email <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYRIGHT" -.sp -Copyright (c) the Contributors as noted in the AUTHORS file\&. This file is part of CZMQ, the high\-level C binding for 0MQ: http://czmq\&.zeromq\&.org\&. This Source Code Form is subject to the terms of the Mozilla Public License, v\&. 2\&.0\&. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla\&.org/MPL/2\&.0/\&. LICENSE included with the czmq distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq.7 b/phonelibs/zmq/aarch64-linux/share/man/man7/zmq.7 deleted file mode 100644 index 45224c4859df39..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq.7 +++ /dev/null @@ -1,275 +0,0 @@ -'\" t -.\" Title: zmq -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ" "7" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq \- 0MQ lightweight messaging kernel -.SH "SYNOPSIS" -.sp -\fB#include \fR -.sp -\fBcc\fR [\fIflags\fR] \fIfiles\fR \fB\-lzmq\fR [\fIlibraries\fR] -.SH "DESCRIPTION" -.sp -The 0MQ lightweight messaging kernel is a library which extends the standard socket interfaces with features traditionally provided by specialised \fImessaging middleware\fR products\&. 0MQ sockets provide an abstraction of asynchronous \fImessage queues\fR, multiple \fImessaging patterns\fR, message filtering (\fIsubscriptions\fR), seamless access to multiple \fItransport protocols\fR and more\&. -.sp -This documentation presents an overview of 0MQ concepts, describes how 0MQ abstracts standard sockets and provides a reference manual for the functions provided by the 0MQ library\&. -.SS "Context" -.sp -The 0MQ \fIcontext\fR keeps the list of sockets and manages the async I/O thread and internal queries\&. -.sp -Before using any 0MQ library functions you must create a 0MQ \fIcontext\fR\&. When you exit your application you must destroy the \fIcontext\fR\&. These functions let you work with \fIcontexts\fR: -.PP -Create a new 0MQ context -.RS 4 -\fBzmq_ctx_new\fR(3) -.RE -.PP -Work with context properties -.RS 4 -\fBzmq_ctx_set\fR(3)\fBzmq_ctx_get\fR(3) -.RE -.PP -Destroy a 0MQ context -.RS 4 -\fBzmq_ctx_shutdown\fR(3)\fBzmq_ctx_term\fR(3) -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBThread safety\fR -.RS 4 -.sp -A 0MQ \fIcontext\fR is thread safe and may be shared among as many application threads as necessary, without any additional locking required on the part of the caller\&. -.sp -Individual 0MQ \fIsockets\fR are \fInot\fR thread safe except in the case where full memory barriers are issued when migrating a socket from one thread to another\&. In practice this means applications can create a socket in one thread with \fIzmq_socket()\fR and then pass it to a \fInewly created\fR thread as part of thread initialisation, for example via a structure passed as an argument to \fIpthread_create()\fR\&. -.RE -.sp -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBMultiple contexts\fR -.RS 4 -.sp -Multiple \fIcontexts\fR may coexist within a single application\&. Thus, an application can use 0MQ directly and at the same time make use of any number of additional libraries or components which themselves make use of 0MQ as long as the above guidelines regarding thread safety are adhered to\&. -.RE -.SS "Messages" -.sp -A 0MQ message is a discrete unit of data passed between applications or components of the same application\&. 0MQ messages have no internal structure and from the point of view of 0MQ itself they are considered to be opaque binary data\&. -.sp -The following functions are provided to work with messages: -.PP -Initialise a message -.RS 4 -\fBzmq_msg_init\fR(3)\fBzmq_msg_init_size\fR(3)\fBzmq_msg_init_data\fR(3) -.RE -.PP -Sending and receiving a message -.RS 4 -\fBzmq_msg_send\fR(3)\fBzmq_msg_recv\fR(3) -.RE -.PP -Release a message -.RS 4 -\fBzmq_msg_close\fR(3) -.RE -.PP -Access message content -.RS 4 -\fBzmq_msg_data\fR(3)\fBzmq_msg_size\fR(3)\fBzmq_msg_more\fR(3) -.RE -.PP -Work with message properties -.RS 4 -\fBzmq_msg_gets\fR(3)\fBzmq_msg_get\fR(3)\fBzmq_msg_set\fR(3) -.RE -.PP -Message manipulation -.RS 4 -\fBzmq_msg_copy\fR(3)\fBzmq_msg_move\fR(3) -.RE -.SS "Sockets" -.sp -0MQ sockets present an abstraction of a asynchronous \fImessage queue\fR, with the exact queueing semantics depending on the socket type in use\&. See \fBzmq_socket\fR(3) for the socket types provided\&. -.sp -The following functions are provided to work with sockets: -.PP -Creating a socket -.RS 4 -\fBzmq_socket\fR(3) -.RE -.PP -Closing a socket -.RS 4 -\fBzmq_close\fR(3) -.RE -.PP -Manipulating socket options -.RS 4 -\fBzmq_getsockopt\fR(3)\fBzmq_setsockopt\fR(3) -.RE -.PP -Establishing a message flow -.RS 4 -\fBzmq_bind\fR(3)\fBzmq_connect\fR(3) -.RE -.PP -Sending and receiving messages -.RS 4 -\fBzmq_msg_send\fR(3)\fBzmq_msg_recv\fR(3)\fBzmq_send\fR(3)\fBzmq_recv\fR(3)\fBzmq_send_const\fR(3) -.RE -.PP -Monitoring socket events -.RS 4 -\fBzmq_socket_monitor\fR(3) -.RE -.PP -\fBInput/output multiplexing\fR. 0MQ provides a mechanism for applications to multiplex input/output events over a set containing both 0MQ sockets and standard sockets\&. This mechanism mirrors the standard -\fIpoll()\fR -system call, and is described in detail in -\fBzmq_poll\fR(3)\&. -.SS "Transports" -.sp -A 0MQ socket can use multiple different underlying transport mechanisms\&. Each transport mechanism is suited to a particular purpose and has its own advantages and drawbacks\&. -.sp -The following transport mechanisms are provided: -.PP -Unicast transport using TCP -.RS 4 -\fBzmq_tcp\fR(7) -.RE -.PP -Reliable multicast transport using PGM -.RS 4 -\fBzmq_pgm\fR(7) -.RE -.PP -Local inter\-process communication transport -.RS 4 -\fBzmq_ipc\fR(7) -.RE -.PP -Local in\-process (inter\-thread) communication transport -.RS 4 -\fBzmq_inproc\fR(7) -.RE -.PP -Virtual Machine Communications Interface (VMC) transport -.RS 4 -\fBzmq_vmci\fR(7) -.RE -.PP -Unreliable unicast and multicast using UDP -.RS 4 -\fBzmq_udp\fR(7) -.RE -.SS "Proxies" -.sp -0MQ provides \fIproxies\fR to create fanout and fan\-in topologies\&. A proxy connects a \fIfrontend\fR socket to a \fIbackend\fR socket and switches all messages between the two sockets, opaquely\&. A proxy may optionally capture all traffic to a third socket\&. To start a proxy in an application thread, use \fBzmq_proxy\fR(3)\&. -.SS "Security" -.sp -A 0MQ socket can select a security mechanism\&. Both peers must use the same security mechanism\&. -.sp -The following security mechanisms are provided for IPC and TCP connections: -.PP -Null security -.RS 4 -\fBzmq_null\fR(7) -.RE -.PP -Plain\-text authentication using username and password -.RS 4 -\fBzmq_plain\fR(7) -.RE -.PP -Elliptic curve authentication and encryption -.RS 4 -\fBzmq_curve\fR(7) -.RE -.PP -Generate a CURVE keypair in armored text format -.RS 4 -\fBzmq_curve_keypair\fR(3) -.RE -.sp -Derive a CURVE public key from a secret key: \fBzmq_curve_public\fR(3) -.PP -Converting keys to/from armoured text strings -.RS 4 -\fBzmq_z85_decode\fR(3)\fBzmq_z85_encode\fR(3) -.RE -.SH "ERROR HANDLING" -.sp -The 0MQ library functions handle errors using the standard conventions found on POSIX systems\&. Generally, this means that upon failure a 0MQ library function shall return either a NULL value (if returning a pointer) or a negative value (if returning an integer), and the actual error code shall be stored in the \fIerrno\fR variable\&. -.sp -On non\-POSIX systems some users may experience issues with retrieving the correct value of the \fIerrno\fR variable\&. The \fIzmq_errno()\fR function is provided to assist in these cases; for details refer to \fBzmq_errno\fR(3)\&. -.sp -The \fIzmq_strerror()\fR function is provided to translate 0MQ\-specific error codes into error message strings; for details refer to \fBzmq_strerror\fR(3)\&. -.SH "UTILITY" -.sp -The following utility functions are provided: -.PP -Working with atomic counters -.RS 4 -\fBzmq_atomic_counter_new\fR(3)\fBzmq_atomic_counter_set\fR(3)\fBzmq_atomic_counter_inc\fR(3)\fBzmq_atomic_counter_dec\fR(3)\fBzmq_atomic_counter_value\fR(3)\fBzmq_atomic_counter_destroy\fR(3) -.RE -.SH "MISCELLANEOUS" -.sp -The following miscellaneous functions are provided: -.PP -Report 0MQ library version -.RS 4 -\fBzmq_version\fR(3) -.RE -.SH "LANGUAGE BINDINGS" -.sp -The 0MQ library provides interfaces suitable for calling from programs in any language; this documentation documents those interfaces as they would be used by C programmers\&. The intent is that programmers using 0MQ from other languages shall refer to this documentation alongside any documentation provided by the vendor of their language binding\&. -.sp -Language bindings (C++, Python, PHP, Ruby, Java and more) are provided by members of the 0MQ community and pointers can be found on the 0MQ website\&. -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. -.SH "RESOURCES" -.sp -Main web site: \m[blue]\fBhttp://www\&.zeromq\&.org/\fR\m[] -.sp -Report bugs to the 0MQ development mailing list: <\m[blue]\fBzeromq\-dev@lists\&.zeromq\&.org\fR\m[]\&\s-2\u[1]\d\s+2> -.SH "COPYING" -.sp -Free use of this software is granted under the terms of the GNU Lesser General Public License (LGPL)\&. For details see the files COPYING and COPYING\&.LESSER included with the 0MQ distribution\&. -.SH "NOTES" -.IP " 1." 4 -zeromq-dev@lists.zeromq.org -.RS 4 -\%mailto:zeromq-dev@lists.zeromq.org -.RE diff --git a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_curve.7 b/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_curve.7 deleted file mode 100644 index 675effc437045d..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_curve.7 +++ /dev/null @@ -1,93 +0,0 @@ -'\" t -.\" Title: zmq_curve -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_CURVE" "7" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_curve \- secure authentication and confidentiality -.SH "SYNOPSIS" -.sp -The CURVE mechanism defines a mechanism for secure authentication and confidentiality for communications between a client and a server\&. CURVE is intended for use on public networks\&. The CURVE mechanism is defined by this document: \m[blue]\fBhttp://rfc\&.zeromq\&.org/spec:25\fR\m[]\&. -.SH "CLIENT AND SERVER ROLES" -.sp -A socket using CURVE can be either client or server, at any moment, but not both\&. The role is independent of bind/connect direction\&. -.sp -A socket can change roles at any point by setting new options\&. The role affects all zmq_connect and zmq_bind calls that follow it\&. -.sp -To become a CURVE server, the application sets the ZMQ_CURVE_SERVER option on the socket, and then sets the ZMQ_CURVE_SECRETKEY option to provide the socket with its long\-term secret key\&. The application does not provide the socket with its long\-term public key, which is used only by clients\&. -.sp -To become a CURVE client, the application sets the ZMQ_CURVE_SERVERKEY option with the long\-term public key of the server it intends to connect to, or accept connections from, next\&. The application then sets the ZMQ_CURVE_PUBLICKEY and ZMQ_CURVE_SECRETKEY options with its client long\-term key pair\&. -.sp -If the server does authentication it will be based on the client\(cqs long term public key\&. -.SH "KEY ENCODING" -.sp -The standard representation for keys in source code is either 32 bytes of base 256 (binary) data, or 40 characters of base 85 data encoded using the Z85 algorithm defined by \m[blue]\fBhttp://rfc\&.zeromq\&.org/spec:32\fR\m[]\&. -.sp -The Z85 algorithm is designed to produce printable key strings for use in configuration files, the command line, and code\&. There is a reference implementation in C at \m[blue]\fBhttps://github\&.com/zeromq/rfc/tree/master/src\fR\m[]\&. -.SH "TEST KEY VALUES" -.sp -For test cases, the client shall use this long\-term key pair (specified as hexadecimal and in Z85): -.sp -.if n \{\ -.RS 4 -.\} -.nf -public: - BB88471D65E2659B30C55A5321CEBB5AAB2B70A398645C26DCA2B2FCB43FC518 - Yne@$w\-vo}U?@Lns47E1%kR\&.o@n%FcmmsL/@{H8]yf7 - -secret: - 8E0BDD697628B91D8F245587EE95C5B04D48963F79259877B49CD9063AEAD3B7 - JTKVSB%%)wK0E\&.X)V>+}o?pNmC{O&4W4b!Ni{Lh6 -.fi -.if n \{\ -.RE -.\} -.SH "SEE ALSO" -.sp -\fBzmq_z85_encode\fR(3) \fBzmq_z85_decode\fR(3) \fBzmq_setsockopt\fR(3) \fBzmq_null\fR(7) \fBzmq_plain\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_inproc.7 b/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_inproc.7 deleted file mode 100644 index a0b0e72d3f71d6..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_inproc.7 +++ /dev/null @@ -1,103 +0,0 @@ -'\" t -.\" Title: zmq_inproc -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_INPROC" "7" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_inproc \- 0MQ local in\-process (inter\-thread) communication transport -.SH "SYNOPSIS" -.sp -The in\-process transport passes messages via memory directly between threads sharing a single 0MQ \fIcontext\fR\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -No I/O threads are involved in passing messages using the \fIinproc\fR transport\&. Therefore, if you are using a 0MQ \fIcontext\fR for in\-process messaging only you can initialise the \fIcontext\fR with zero I/O threads\&. See \fBzmq_init\fR(3) for details\&. -.sp .5v -.RE -.SH "ADDRESSING" -.sp -A 0MQ endpoint is a string consisting of a \fItransport\fR:// followed by an \fIaddress\fR\&. The \fItransport\fR specifies the underlying protocol to use\&. The \fIaddress\fR specifies the transport\-specific address to connect to\&. -.sp -For the in\-process transport, the transport is inproc, and the meaning of the \fIaddress\fR part is defined below\&. -.SS "Assigning a local address to a socket" -.sp -When assigning a local address to a \fIsocket\fR using \fIzmq_bind()\fR with the \fIinproc\fR transport, the \fIendpoint\fR shall be interpreted as an arbitrary string identifying the \fIname\fR to create\&. The \fIname\fR must be unique within the 0MQ \fIcontext\fR associated with the \fIsocket\fR and may be up to 256 characters in length\&. No other restrictions are placed on the format of the \fIname\fR\&. -.SS "Connecting a socket" -.sp -When connecting a \fIsocket\fR to a peer address using \fIzmq_connect()\fR with the \fIinproc\fR transport, the \fIendpoint\fR shall be interpreted as an arbitrary string identifying the \fIname\fR to connect to\&. Before version 4\&.0 he \fIname\fR must have been previously created by assigning it to at least one \fIsocket\fR within the same 0MQ \fIcontext\fR as the \fIsocket\fR being connected\&. Since version 4\&.0 the order of \fIzmq_bind()\fR and \fIzmq_connect()\fR does not matter just like for the tcp transport type\&. -.SH "EXAMPLES" -.PP -\fBAssigning a local address to a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Assign the in\-process name "#1" -rc = zmq_bind(socket, "inproc://#1"); -assert (rc == 0); -// Assign the in\-process name "my\-endpoint" -rc = zmq_bind(socket, "inproc://my\-endpoint"); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.PP -\fBConnecting a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Connect to the in\-process name "#1" -rc = zmq_connect(socket, "inproc://#1"); -assert (rc == 0); -// Connect to the in\-process name "my\-endpoint" -rc = zmq_connect(socket, "inproc://my\-endpoint"); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_bind\fR(3) \fBzmq_connect\fR(3) \fBzmq_ipc\fR(7) \fBzmq_tcp\fR(7) \fBzmq_pgm\fR(7) \fBzmq_vmci\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_ipc.7 b/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_ipc.7 deleted file mode 100644 index c190b6f1215f10..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_ipc.7 +++ /dev/null @@ -1,166 +0,0 @@ -'\" t -.\" Title: zmq_ipc -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_IPC" "7" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_ipc \- 0MQ local inter\-process communication transport -.SH "SYNOPSIS" -.sp -The inter\-process transport passes messages between local processes using a system\-dependent IPC mechanism\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -The inter\-process transport is currently only implemented on operating systems that provide UNIX domain sockets\&. -.sp .5v -.RE -.SH "ADDRESSING" -.sp -A 0MQ endpoint is a string consisting of a \fItransport\fR:// followed by an \fIaddress\fR\&. The \fItransport\fR specifies the underlying protocol to use\&. The \fIaddress\fR specifies the transport\-specific address to connect to\&. -.sp -For the inter\-process transport, the transport is ipc, and the meaning of the \fIaddress\fR part is defined below\&. -.SS "Binding a socket" -.sp -When binding a \fIsocket\fR to a local address using \fIzmq_bind()\fR with the \fIipc\fR transport, the \fIendpoint\fR shall be interpreted as an arbitrary string identifying the \fIpathname\fR to create\&. The \fIpathname\fR must be unique within the operating system namespace used by the \fIipc\fR implementation, and must fulfill any restrictions placed by the operating system on the format and length of a \fIpathname\fR\&. -.sp -When the address is wild\-card *, \fIzmq_bind()\fR shall generate a unique temporary pathname\&. The caller should retrieve this pathname using the ZMQ_LAST_ENDPOINT socket option\&. See \fBzmq_getsockopt\fR(3) for details\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -any existing binding to the same endpoint shall be overridden\&. That is, if a second process binds to an endpoint already bound by a process, this will succeed and the first process will lose its binding\&. In this behaviour, the \fIipc\fR transport is not consistent with the \fItcp\fR or \fIinproc\fR transports\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -the endpoint pathname must be writable by the process\&. When the endpoint starts with \fI/\fR, e\&.g\&., ipc:///pathname, this will be an \fIabsolute\fR pathname\&. If the endpoint specifies a directory that does not exist, the bind shall fail\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -on Linux only, when the endpoint pathname starts with @, the abstract namespace shall be used\&. The abstract namespace is independent of the filesystem and if a process attempts to bind an endpoint already bound by a process, it will fail\&. See unix(7) for details\&. -.sp .5v -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -IPC pathnames have a maximum size that depends on the operating system\&. On Linux, the maximum is 113 characters including the "ipc://" prefix (107 characters for the real path name)\&. -.sp .5v -.RE -.SS "Unbinding wild\-card address from a socket" -.sp -When wild\-card * \fIendpoint\fR was used in \fIzmq_bind()\fR, the caller should use real \fIendpoint\fR obtained from the ZMQ_LAST_ENDPOINT socket option to unbind this \fIendpoint\fR from a socket using \fIzmq_unbind()\fR\&. -.SS "Connecting a socket" -.sp -When connecting a \fIsocket\fR to a peer address using \fIzmq_connect()\fR with the \fIipc\fR transport, the \fIendpoint\fR shall be interpreted as an arbitrary string identifying the \fIpathname\fR to connect to\&. The \fIpathname\fR must have been previously created within the operating system namespace by assigning it to a \fIsocket\fR with \fIzmq_bind()\fR\&. -.SH "EXAMPLES" -.PP -\fBAssigning a local address to a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Assign the pathname "/tmp/feeds/0" -rc = zmq_bind(socket, "ipc:///tmp/feeds/0"); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.PP -\fBConnecting a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Connect to the pathname "/tmp/feeds/0" -rc = zmq_connect(socket, "ipc:///tmp/feeds/0"); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_bind\fR(3) \fBzmq_connect\fR(3) \fBzmq_inproc\fR(7) \fBzmq_tcp\fR(7) \fBzmq_pgm\fR(7) \fBzmq_vmci\fR(7) \fBzmq_getsockopt\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_null.7 b/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_null.7 deleted file mode 100644 index 42497a11594113..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_null.7 +++ /dev/null @@ -1,40 +0,0 @@ -'\" t -.\" Title: zmq_null -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_NULL" "7" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_null \- no security or confidentiality -.SH "SYNOPSIS" -.sp -The NULL mechanism is defined by the ZMTP 3\&.0 specification: \m[blue]\fBhttp://rfc\&.zeromq\&.org/spec:23\fR\m[]\&. This is the default security mechanism for ZeroMQ sockets\&. -.SH "SEE ALSO" -.sp -\fBzmq_plain\fR(7) \fBzmq_curve\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_pgm.7 b/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_pgm.7 deleted file mode 100644 index ea8ca3fc155eb9..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_pgm.7 +++ /dev/null @@ -1,200 +0,0 @@ -'\" t -.\" Title: zmq_pgm -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_PGM" "7" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_pgm \- 0MQ reliable multicast transport using PGM -.SH "SYNOPSIS" -.sp -PGM (Pragmatic General Multicast) is a protocol for reliable multicast transport of data over IP networks\&. -.SH "DESCRIPTION" -.sp -0MQ implements two variants of PGM, the standard protocol where PGM datagrams are layered directly on top of IP datagrams as defined by RFC 3208 (the \fIpgm\fR transport) and "Encapsulated PGM" or EPGM where PGM datagrams are encapsulated inside UDP datagrams (the \fIepgm\fR transport)\&. -.sp -The \fIpgm\fR and \fIepgm\fR transports can only be used with the \fIZMQ_PUB\fR and \fIZMQ_SUB\fR socket types\&. -.sp -Further, PGM sockets are rate limited by default\&. For details, refer to the \fIZMQ_RATE\fR, and \fIZMQ_RECOVERY_IVL\fR options documented in \fBzmq_setsockopt\fR(3)\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBCaution\fR -.ps -1 -.br -.sp -The \fIpgm\fR transport implementation requires access to raw IP sockets\&. Additional privileges may be required on some operating systems for this operation\&. Applications not requiring direct interoperability with other PGM implementations are encouraged to use the \fIepgm\fR transport instead which does not require any special privileges\&. -.sp .5v -.RE -.SH "ADDRESSING" -.sp -A 0MQ endpoint is a string consisting of a \fItransport\fR:// followed by an \fIaddress\fR\&. The \fItransport\fR specifies the underlying protocol to use\&. The \fIaddress\fR specifies the transport\-specific address to connect to\&. -.sp -For the PGM transport, the transport is pgm, and for the EPGM protocol the transport is epgm\&. The meaning of the \fIaddress\fR part is defined below\&. -.SS "Connecting a socket" -.sp -When connecting a socket to a peer address using \fIzmq_connect()\fR with the \fIpgm\fR or \fIepgm\fR transport, the \fIendpoint\fR shall be interpreted as an \fIinterface\fR followed by a semicolon, followed by a \fImulticast address\fR, followed by a colon and a port number\&. -.sp -An \fIinterface\fR may be specified by either of the following: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The interface name as defined by the operating system\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The primary IPv4 address assigned to the interface, in its numeric representation\&. -.RE -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -Interface names are not standardised in any way and should be assumed to be arbitrary and platform dependent\&. On Win32 platforms no short interface names exist, thus only the primary IPv4 address may be used to specify an \fIinterface\fR\&. The \fIinterface\fR part can be omitted, in that case the default one will be selected\&. -.sp .5v -.RE -.sp -A \fImulticast address\fR is specified by an IPv4 multicast address in its numeric representation\&. -.SH "WIRE FORMAT" -.sp -Consecutive PGM datagrams are interpreted by 0MQ as a single continuous stream of data where 0MQ messages are not necessarily aligned with PGM datagram boundaries and a single 0MQ message may span several PGM datagrams\&. This stream of data consists of 0MQ messages encapsulated in \fIframes\fR as described in \fBzmq_tcp\fR(7)\&. -.SS "PGM datagram payload" -.sp -The following ABNF grammar represents the payload of a single PGM datagram as used by 0MQ: -.sp -.if n \{\ -.RS 4 -.\} -.nf -datagram = (offset data) -offset = 2OCTET -data = *OCTET -.fi -.if n \{\ -.RE -.\} -.sp -In order for late joining consumers to be able to identify message boundaries, each PGM datagram payload starts with a 16\-bit unsigned integer in network byte order specifying either the offset of the first message \fIframe\fR in the datagram or containing the value 0xFFFF if the datagram contains solely an intermediate part of a larger message\&. -.sp -Note that offset specifies where the first message begins rather than the first message part\&. Thus, if there are trailing message parts at the beginning of the packet the offset ignores them and points to first initial message part in the packet\&. -.sp -The following diagram illustrates the layout of a single PGM datagram payload: -.sp -.if n \{\ -.RS 4 -.\} -.nf -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| offset (16 bits) | data | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -.fi -.if n \{\ -.RE -.\} -.sp -The following diagram further illustrates how three example 0MQ frames are laid out in consecutive PGM datagram payloads: -.sp -.if n \{\ -.RS 4 -.\} -.nf -First datagram payload -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| Frame offset | Frame 1 | Frame 2, part 1 | -| 0x0000 | (Message 1) | (Message 2, part 1) | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ - -Second datagram payload -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| Frame offset | Frame 2, part 2 | -| 0xFFFF | (Message 2, part 2) | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ - -Third datagram payload -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| Frame offset | Frame 2, final 8 bytes | Frame 3 | -| 0x0008 | (Message 2, final 8 bytes) | (Message 3) | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-+ -.fi -.if n \{\ -.RE -.\} -.SH "EXAMPLE" -.PP -\fBConnecting a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Connecting to the multicast address 239\&.192\&.1\&.1, port 5555, -// using the first Ethernet network interface on Linux -// and the Encapsulated PGM protocol -rc = zmq_connect(socket, "epgm://eth0;239\&.192\&.1\&.1:5555"); -assert (rc == 0); -// Connecting to the multicast address 239\&.192\&.1\&.1, port 5555, -// using the network interface with the address 192\&.168\&.1\&.1 -// and the standard PGM protocol -rc = zmq_connect(socket, "pgm://192\&.168\&.1\&.1;239\&.192\&.1\&.1:5555"); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_connect\fR(3) \fBzmq_setsockopt\fR(3) \fBzmq_tcp\fR(7) \fBzmq_ipc\fR(7) \fBzmq_inproc\fR(7) \fBzmq_vmci\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_plain.7 b/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_plain.7 deleted file mode 100644 index 912c92d5a98bae..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_plain.7 +++ /dev/null @@ -1,43 +0,0 @@ -'\" t -.\" Title: zmq_plain -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_PLAIN" "7" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_plain \- clear\-text authentication -.SH "SYNOPSIS" -.sp -The PLAIN mechanism defines a simple username/password mechanism that lets a server authenticate a client\&. PLAIN makes no attempt at security or confidentiality\&. It is intended for use on internal networks where security requirements are low\&. The PLAIN mechanism is defined by this document: \m[blue]\fBhttp://rfc\&.zeromq\&.org/spec:24\fR\m[]\&. -.SH "USAGE" -.sp -To use PLAIN, the server shall set the ZMQ_PLAIN_SERVER option, and the client shall set the ZMQ_PLAIN_USERNAME and ZMQ_PLAIN_PASSWORD socket options\&. Which peer binds, and which connects, is not relevant\&. -.SH "SEE ALSO" -.sp -\fBzmq_setsockopt\fR(3) \fBzmq_null\fR(7) \fBzmq_curve\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_tcp.7 b/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_tcp.7 deleted file mode 100644 index e0e0e006779a55..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_tcp.7 +++ /dev/null @@ -1,188 +0,0 @@ -'\" t -.\" Title: zmq_tcp -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_TCP" "7" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_tcp \- 0MQ unicast transport using TCP -.SH "SYNOPSIS" -.sp -TCP is an ubiquitous, reliable, unicast transport\&. When connecting distributed applications over a network with 0MQ, using the TCP transport will likely be your first choice\&. -.SH "ADDRESSING" -.sp -A 0MQ endpoint is a string consisting of a \fItransport\fR:// followed by an \fIaddress\fR\&. The \fItransport\fR specifies the underlying protocol to use\&. The \fIaddress\fR specifies the transport\-specific address to connect to\&. -.sp -For the TCP transport, the transport is tcp, and the meaning of the \fIaddress\fR part is defined below\&. -.SS "Assigning a local address to a socket" -.sp -When assigning a local address to a socket using \fIzmq_bind()\fR with the \fItcp\fR transport, the \fIendpoint\fR shall be interpreted as an \fIinterface\fR followed by a colon and the TCP port number to use\&. -.sp -An \fIinterface\fR may be specified by either of the following: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The wild\-card -*, meaning all available interfaces\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The primary IPv4 or IPv6 address assigned to the interface, in its numeric representation\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The non\-portable interface name as defined by the operating system\&. -.RE -.sp -The TCP port number may be specified by: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -A numeric value, usually above 1024 on POSIX systems\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The wild\-card -*, meaning a system\-assigned ephemeral port\&. -.RE -.sp -When using ephemeral ports, the caller should retrieve the actual assigned port using the ZMQ_LAST_ENDPOINT socket option\&. See \fBzmq_getsockopt\fR(3) for details\&. -.SS "Unbinding wild\-card address from a socket" -.sp -When wild\-card * \fIendpoint\fR was used in \fIzmq_bind()\fR, the caller should use real \fIendpoint\fR obtained from the ZMQ_LAST_ENDPOINT socket option to unbind this \fIendpoint\fR from a socket using \fIzmq_unbind()\fR\&. -.SS "Connecting a socket" -.sp -When connecting a socket to a peer address using \fIzmq_connect()\fR with the \fItcp\fR transport, the \fIendpoint\fR shall be interpreted as a \fIpeer address\fR followed by a colon and the TCP port number to use\&. You can optionally specify a \fIsource_endpoint\fR which will be used as the source address for your connection; tcp://\fIsource_endpoint\fR;\*(Aqendpoint\*(Aq, see the \fIinterface\fR description above for details\&. -.sp -A \fIpeer address\fR may be specified by either of the following: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The DNS name of the peer\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The IPv4 or IPv6 address of the peer, in its numeric representation\&. -.RE -.sp -Note: A description of the ZeroMQ Message Transport Protocol (ZMTP) which is used by the TCP transport can be found at \m[blue]\fBhttp://rfc\&.zeromq\&.org/spec:15\fR\m[] -.SH "EXAMPLES" -.PP -\fBAssigning a local address to a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// TCP port 5555 on all available interfaces -rc = zmq_bind(socket, "tcp://*:5555"); -assert (rc == 0); -// TCP port 5555 on the local loop\-back interface on all platforms -rc = zmq_bind(socket, "tcp://127\&.0\&.0\&.1:5555"); -assert (rc == 0); -// TCP port 5555 on the first Ethernet network interface on Linux -rc = zmq_bind(socket, "tcp://eth0:5555"); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.PP -\fBConnecting a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Connecting using an IP address -rc = zmq_connect(socket, "tcp://192\&.168\&.1\&.1:5555"); -assert (rc == 0); -// Connecting using a DNS name -rc = zmq_connect(socket, "tcp://server1:5555"); -assert (rc == 0); -// Connecting using a DNS name and bind to eth1 -rc = zmq_connect(socket, "tcp://eth1:0;server1:5555"); -assert (rc == 0); -// Connecting using a IP address and bind to an IP address -rc = zmq_connect(socket, "tcp://192\&.168\&.1\&.17:5555;192\&.168\&.1\&.1:5555"); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_bind\fR(3) \fBzmq_connect\fR(3) \fBzmq_pgm\fR(7) \fBzmq_ipc\fR(7) \fBzmq_inproc\fR(7) \fBzmq_vmci\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_tipc.7 b/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_tipc.7 deleted file mode 100644 index cef14547579f7f..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_tipc.7 +++ /dev/null @@ -1,110 +0,0 @@ -'\" t -.\" Title: zmq_tipc -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_TIPC" "7" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_tipc \- 0MQ unicast transport using TIPC -.SH "SYNOPSIS" -.sp -TIPC is a cluster IPC protocol with a location transparent addressing scheme\&. -.SH "ADDRESSING" -.sp -A 0MQ endpoint is a string consisting of a \fItransport\fR:// followed by an \fIaddress\fR\&. The \fItransport\fR specifies the underlying protocol to use\&. The \fIaddress\fR specifies the transport\-specific address to connect to\&. -.sp -For the TIPC transport, the transport is tipc, and the meaning of the \fIaddress\fR part is defined below\&. -.SS "Assigning a port name to a socket" -.sp -When assigning a port name to a socket using \fIzmq_bind()\fR with the \fItipc\fR transport, the \fIendpoint\fR is defined in the form: {type, lower, upper} -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Type is the numerical (u32) ID of your service\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Lower and Upper specify a range for your service\&. -.RE -.sp -Publishing the same service with overlapping lower/upper ID\(cqs will cause connection requests to be distributed over these in a round\-robin manner\&. -.SS "Connecting a socket" -.sp -When connecting a socket to a peer address using \fIzmq_connect()\fR with the \fItipc\fR transport, the \fIendpoint\fR shall be interpreted as a service ID, followed by a comma and the instance ID\&. -.sp -The instance ID must be within the lower/upper range of a published port name for the endpoint to be valid\&. -.SH "EXAMPLES" -.PP -\fBAssigning a local address to a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Publish TIPC service ID 5555 -rc = zmq_bind(socket, "tipc://{5555,0,0}"); -assert (rc == 0); -// Publish TIPC service ID 5555 with a service range of 0\-100 -rc = zmq_bind(socket, "tipc://{5555,0,100}"); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.PP -\fBConnecting a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Connect to service 5555 instance id 50 -rc = zmq_connect(socket, "tipc://{5555,50}"); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_bind\fR(3) \fBzmq_connect\fR(3) \fBzmq_tcp\fR(7) \fBzmq_pgm\fR(7) \fBzmq_ipc\fR(7) \fBzmq_inproc\fR(7) \fBzmq_vmci\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_udp.7 b/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_udp.7 deleted file mode 100644 index cda022097f1ded..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_udp.7 +++ /dev/null @@ -1,139 +0,0 @@ -'\" t -.\" Title: zmq_udp -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_UDP" "7" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_udp \- 0MQ UDP multicast and unicast transport -.SH "SYNOPSIS" -.sp -UDP is unreliable protocol transport of data over IP networks\&. UDP support both unicast and multicast communication\&. -.SH "DESCRIPTION" -.sp -UDP transport can only be used with the \fIZMQ_RADIO\fR and \fIZMQ_DISH\fR socket types\&. -.SH "ADDRESSING" -.sp -A 0MQ endpoint is a string consisting of a \fItransport\fR:// followed by an \fIaddress\fR\&. The \fItransport\fR specifies the underlying protocol to use\&. The \fIaddress\fR specifies the transport\-specific address to connect to\&. -.sp -For the UDP transport, the transport is udp\&. The meaning of the \fIaddress\fR part is defined below\&. -.sp -Binding a socket -.sp -.if n \{\ -.RS 4 -.\} -.nf -With \*(Aqudp\*(Aq we can only bind the \*(AqZMQ_DISH\*(Aq socket type\&. -When binding a socket using _zmq_bind()_ with the \*(Aqudp\*(Aq -transport the \*(Aqendpoint\*(Aq shall be interpreted as an \*(Aqinterface\*(Aq followed by a -colon and the UDP port number to use\&. - -An \*(Aqinterface\*(Aq may be specified by either of the following: - -* The wild\-card `*`, meaning all available interfaces\&. -* The primary IPv4 address assigned to the interface, in its numeric - representation\&. -* Multicast address in its numeric representation the socket should join\&. - -The UDP port number may be specified a numeric value, usually above 1024 on POSIX systems\&. - -Connecting a socket -.fi -.if n \{\ -.RE -.\} -.sp -With \fIudp\fR we can only connect the \fIZMQ_RADIO\fR socket type\&. When connecting a socket to a peer address using \fIzmq_connect()\fR with the \fIudp\fR transport, the \fIendpoint\fR shall be interpreted as a \fIpeer address\fR followed by a colon and the UDP port number to use\&. -.sp -A \fIpeer address\fR may be specified by either of the following: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The IPv4 or IPv6 address of the peer, in its numeric representation\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -Multicast address in its numeric representation\&. -.RE -.SH "EXAMPLES" -.PP -\fBBinding a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Unicast \- UDP port 5555 on all available interfaces -rc = zmq_bind(dish, "udp://*:5555"); -assert (rc == 0); -// Unicast \- UDP port 5555 on the local loop\-back interface -rc = zmq_bind(dish, "udp://127\&.0\&.0\&.1:5555"); -assert (rc == 0); -// Multicast \- UDP port 5555 on a Multicast address -rc = zmq_bind(dish, "udp://239\&.0\&.0\&.1:5555"); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.PP -\fBConnecting a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Connecting using an Unicast IP address -rc = zmq_connect(radio, "udp://192\&.168\&.1\&.1:5555"); -assert (rc == 0); -// Connecting using a Multicast address" -rc = zmq_connect(socket, "udp://239\&.0\&.0\&.1:5555); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_connect\fR(3) \fBzmq_setsockopt\fR(3) \fBzmq_tcp\fR(7) \fBzmq_ipc\fR(7) \fBzmq_inproc\fR(7) \fBzmq_vmci\fR(7) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_vmci.7 b/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_vmci.7 deleted file mode 100644 index 5383060905483e..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/man/man7/zmq_vmci.7 +++ /dev/null @@ -1,162 +0,0 @@ -'\" t -.\" Title: zmq_vmci -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 02/18/2017 -.\" Manual: 0MQ Manual -.\" Source: 0MQ 4.2.2 -.\" Language: English -.\" -.TH "ZMQ_VMCI" "7" "02/18/2017" "0MQ 4\&.2\&.2" "0MQ Manual" -.\" ----------------------------------------------------------------- -.\" * Define some portability stuff -.\" ----------------------------------------------------------------- -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.\" http://bugs.debian.org/507673 -.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html -.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" ----------------------------------------------------------------- -.\" * set default formatting -.\" ----------------------------------------------------------------- -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.\" ----------------------------------------------------------------- -.\" * MAIN CONTENT STARTS HERE * -.\" ----------------------------------------------------------------- -.SH "NAME" -zmq_vmci \- 0MQ transport over virtual machine communicatios interface (VMCI) sockets -.SH "SYNOPSIS" -.sp -The VMCI transport passes messages between VMware virtual machines running on the same host, between virtual machine and the host and within virtual machines (inter\-process transport like ipc)\&. -.if n \{\ -.sp -.\} -.RS 4 -.it 1 an-trap -.nr an-no-space-flag 1 -.nr an-break-flag 1 -.br -.ps +1 -\fBNote\fR -.ps -1 -.br -.sp -Communication between a virtual machine and the host is not supported on Mac OS X 10\&.9 and above\&. -.sp .5v -.RE -.SH "ADDRESSING" -.sp -A 0MQ endpoint is a string consisting of a \fItransport\fR:// followed by an \fIaddress\fR\&. The \fItransport\fR specifies the underlying protocol to use\&. The \fIaddress\fR specifies the transport\-specific address to connect to\&. -.sp -For the VMCI transport, the transport is vmci, and the meaning of the \fIaddress\fR part is defined below\&. -.SS "Binding a socket" -.sp -When binding a \fIsocket\fR to a local address using \fIzmq_bind()\fR with the \fIvmci\fR transport, the \fIendpoint\fR shall be interpreted as an \fIinterface\fR followed by a colon and the TCP port number to use\&. -.sp -An \fIinterface\fR may be specified by either of the following: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The wild\-card -*, meaning all available interfaces\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -An integer returned by -VMCISock_GetLocalCID -or -@ -(ZeroMQ will call VMCISock_GetLocalCID internally)\&. -.RE -.sp -The port may be specified by: -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -A numeric value, usually above 1024 on POSIX systems\&. -.RE -.sp -.RS 4 -.ie n \{\ -\h'-04'\(bu\h'+03'\c -.\} -.el \{\ -.sp -1 -.IP \(bu 2.3 -.\} -The wild\-card -*, meaning a system\-assigned ephemeral port\&. -.RE -.SS "Unbinding wild\-card address from a socket" -.sp -When wild\-card * \fIendpoint\fR was used in \fIzmq_bind()\fR, the caller should use real \fIendpoint\fR obtained from the ZMQ_LAST_ENDPOINT socket option to unbind this \fIendpoint\fR from a socket using \fIzmq_unbind()\fR\&. -.SS "Connecting a socket" -.sp -When connecting a socket to a peer address using \fIzmq_connect()\fR with the \fIvmci\fR transport, the \fIendpoint\fR shall be interpreted as a \fIpeer address\fR followed by a colon and the port number to use\&. -.sp -A \fIpeer address\fR must be a CID of the peer\&. -.SH "EXAMPLES" -.PP -\fBAssigning a local address to a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// VMCI port 5555 on all available interfaces -rc = zmq_bind(socket, "vmci://*:5555"); -assert (rc == 0); -// VMCI port 5555 on the local loop\-back interface on all platforms -cid = VMCISock_GetLocalCID(); -sprintf(endpoint, "vmci://%d:5555", cid); -rc = zmq_bind(socket, endpoint); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.PP -\fBConnecting a socket\fR. -.sp -.if n \{\ -.RS 4 -.\} -.nf -// Connecting using a CID -sprintf(endpoint, "vmci://%d:5555", cid); -rc = zmq_connect(socket, endpoint); -assert (rc == 0); -.fi -.if n \{\ -.RE -.\} -.sp -.SH "SEE ALSO" -.sp -\fBzmq_bind\fR(3) \fBzmq_connect\fR(3) \fBzmq_inproc\fR(7) \fBzmq_tcp\fR(7) \fBzmq_pgm\fR(7) \fBzmq_vmci\fR(7) \fBzmq_getsockopt\fR(3) \fBzmq\fR(7) -.SH "AUTHORS" -.sp -This page was written by the 0MQ community\&. To make a change please read the 0MQ Contribution Policy at \m[blue]\fBhttp://www\&.zeromq\&.org/docs:contributing\fR\m[]\&. diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zactor.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zactor.api deleted file mode 100644 index 2ff128b36e61f0..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zactor.api +++ /dev/null @@ -1,62 +0,0 @@ - - - provides a simple actor framework - - - Actors get a pipe and arguments from caller - - - - - - Create a new actor passing arbitrary arguments reference. - - - - - - Destroy an actor. - - - - Send a zmsg message to the actor, take ownership of the message - and destroy when it has been sent. - - - - - - Receive a zmsg message from the actor. Returns NULL if the actor - was interrupted before the message could be received, or if there - was a timeout on the actor. - - - - - Probe the supplied object, and report if it looks like a zactor_t. - - - - - - Probe the supplied reference. If it looks like a zactor_t instance, - return the underlying libzmq actor handle; else if it looks like - a libzmq actor handle, return the supplied value. - - - - - - Return the actor's zsock handle. Use this when you absolutely need - to work with the zsock instance rather than the actor. - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zarmour.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zarmour.api deleted file mode 100644 index 887ca9ffdbc765..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zarmour.api +++ /dev/null @@ -1,103 +0,0 @@ - - - armoured text encoding and decoding - - Standard base 64 - URL and filename friendly base 64 - Standard base 32 - Extended hex base 32 - Standard base 16 - Z85 from ZeroMQ RFC 32 - - - Create a new zarmour - - - - Destroy the zarmour - - - - Encode a stream of bytes into an armoured string. Returns the armoured - string, or NULL if there was insufficient memory available to allocate - a new string. - - - - - - - Decode an armoured string into a chunk. The decoded output is - null-terminated, so it may be treated as a string, if that's what - it was prior to encoding. - - - - - - Get the mode property. - - - - - Get printable string for mode. - - - - - Set the mode property. - - - - - Return true if padding is turned on. - - - - - Turn padding on or off. Default is on. - - - - - Get the padding character. - - - - - Set the padding character. - - - - - Return if splitting output into lines is turned on. Default is off. - - - - - Turn splitting output into lines on or off. - - - - - Get the line length used for splitting lines. - - - - - Set the line length used for splitting lines. - - - - - Print properties of object - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zcert.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zcert.api deleted file mode 100644 index d361ba216525e2..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zcert.api +++ /dev/null @@ -1,122 +0,0 @@ - - - work with CURVE security certificates - - - Create and initialize a new certificate in memory - - - - Accepts public/secret key pair from caller - - - - - - Load certificate from file - - - - - Destroy a certificate in memory - - - - Return public part of key pair as 32-byte binary string - - - - - Return secret part of key pair as 32-byte binary string - - - - - Return public part of key pair as Z85 armored string - - - - - Return secret part of key pair as Z85 armored string - - - - - Set certificate metadata from formatted string. - - - - - - Unset certificate metadata. - - - - - Get metadata value from certificate; if the metadata value doesn't - exist, returns NULL. - - - - - - Get list of metadata fields from certificate. Caller is responsible for - destroying list. Caller should not modify the values of list items. - - - - - Save full certificate (public + secret) to file for persistent storage - This creates one public file and one secret file (filename + "_secret"). - - - - - - Save public certificate only to file for persistent storage - - - - - - Save secret certificate only to file for persistent storage - - - - - - Apply certificate to socket, i.e. use for CURVE security on socket. - If certificate was loaded from public file, the secret key will be - undefined, and this certificate will not work successfully. - - - - - Return copy of certificate; if certificate is NULL or we exhausted - heap memory, returns NULL. - - - - - Return true if two certificates have the same keys - - - - - - Print certificate contents to stdout - - - - Self test of this class - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zcertstore.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zcertstore.api deleted file mode 100644 index b566fefa533f24..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zcertstore.api +++ /dev/null @@ -1,72 +0,0 @@ - - - work with CURVE security certificate stores - - - Create a new certificate store from a disk directory, loading and - indexing all certificates in that location. The directory itself may be - absent, and created later, or modified at any time. The certificate store - is automatically refreshed on any zcertstore_lookup() call. If the - location is specified as NULL, creates a pure-memory store, which you - can work with by inserting certificates at runtime. - - - - - Destroy a certificate store object in memory. Does not affect anything - stored on disk. - - - - Loaders retrieve certificates from an arbitrary source. - - - - - Destructor for loader state. - - - - - Override the default disk loader with a custom loader fn. - - - - - - - Look up certificate by public key, returns zcert_t object if found, - else returns NULL. The public key is provided in Z85 text format. - - - - - - Insert certificate into certificate store in memory. Note that this - does not save the certificate to disk. To do that, use zcert_save() - directly on the certificate. Takes ownership of zcert_t object. - - - - - Empty certificate hashtable. This wrapper exists to be friendly to bindings, - which don't usually have access to struct internals. - - - - Print list of certificates in store to logging facility - - - - Self test of this class - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zchunk.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zchunk.api deleted file mode 100644 index 25b50e95815c00..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zchunk.api +++ /dev/null @@ -1,171 +0,0 @@ - - - work with memory chunks - - - Create a new chunk of the specified size. If you specify the data, it - is copied into the chunk. If you do not specify the data, the chunk is - allocated and left empty, and you can then add data using zchunk_append. - - - - - - Destroy a chunk - - - - Resizes chunk max_size as requested; chunk_cur size is set to zero - - - - - Return chunk cur size - - - - - Return chunk max size - - - - - Return chunk data - - - - - Set chunk data from user-supplied data; truncate if too large. Data may - be null. Returns actual size of chunk - - - - - - - Fill chunk data from user-supplied octet - - - - - - - Append user-supplied data to chunk, return resulting chunk size. If the - data would exceeded the available space, it is truncated. If you want to - grow the chunk to accommodate new data, use the zchunk_extend method. - - - - - - - Append user-supplied data to chunk, return resulting chunk size. If the - data would exceeded the available space, the chunk grows in size. - - - - - - - Copy as much data from 'source' into the chunk as possible; returns the - new size of chunk. If all data from 'source' is used, returns exhausted - on the source chunk. Source can be consumed as many times as needed until - it is exhausted. If source was already exhausted, does not change chunk. - - - - - - Returns true if the chunk was exhausted by consume methods, or if the - chunk has a size of zero. - - - - - Read chunk from an open file descriptor - - - - - - - Write chunk to an open file descriptor - - - - - - Try to slurp an entire file into a chunk. Will read up to maxsize of - the file. If maxsize is 0, will attempt to read the entire file and - fail with an assertion if that cannot fit into memory. Returns a new - chunk containing the file data, or NULL if the file could not be read. - - - - - - - Create copy of chunk, as new chunk object. Returns a fresh zchunk_t - object, or null if there was not enough heap memory. If chunk is null, - returns null. - - - - - Return chunk data encoded as printable hex string. Caller must free - string when finished with it. - - - - - Return chunk data copied into freshly allocated string - Caller must free string when finished with it. - - - - - Return TRUE if chunk body is equal to string, excluding terminator - - - - - - Transform zchunk into a zframe that can be sent in a message. - - - - - Transform a zframe into a zchunk. - - - - - - Calculate SHA1 digest for chunk, using zdigest class. - - - - - Dump chunk to FILE stream, for debugging and tracing. - - - - - Dump message to stderr, for debugging and tracing. - See zchunk_fprint for details - - - - Probe the supplied object, and report if it looks like a zchunk_t. - - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zclock.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zclock.api deleted file mode 100644 index a613180f1529cb..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zclock.api +++ /dev/null @@ -1,43 +0,0 @@ - - - millisecond clocks and delays - - - Sleep for a number of milliseconds - - - - - Return current system clock as milliseconds. Note that this clock can - jump backwards (if the system clock is changed) so is unsafe to use for - timers and time offsets. Use zclock_mono for that instead. - - - - - Return current monotonic clock in milliseconds. Use this when you compute - time offsets. The monotonic clock is not affected by system changes and - so will never be reset backwards, unlike a system clock. - - - - - Return current monotonic clock in microseconds. Use this when you compute - time offsets. The monotonic clock is not affected by system changes and - so will never be reset backwards, unlike a system clock. - - - - - Return formatted date/time as fresh string. Free using zstr_free(). - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zconfig.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zconfig.api deleted file mode 100644 index db46751fa8d7d9..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zconfig.api +++ /dev/null @@ -1,196 +0,0 @@ - - - work with config files written in rfc.zeromq.org/spec:4/ZPL. - - - - - - - - - - Create new config item - - - - - - Destroy a config item and all its children - - - - Return name of config item - - - - - Return value of config item - - - - - Insert or update configuration key with value - - - - - - Equivalent to zconfig_put, accepting a format specifier and variable - argument list, instead of a single string value. - - - - - - Get value for config item into a string value; leading slash is optional - and ignored. - - - - - - Set config item name, name may be NULL - - - - - Set new value for config item. The new value may be a string, a printf - format, or NULL. Note that if string may possibly contain '%', or if it - comes from an insecure source, you must use '%s' as the format, followed - by the string. - - - - - Find our first child, if any - - - - - Find our first sibling, if any - - - - - Find a config item along a path; leading slash is optional and ignored. - - - - - - Locate the last config item at a specified depth - - - - - - Execute a callback for each config item in the tree; returns zero if - successful, else -1. - - - - - - - Add comment to config item before saving to disk. You can add as many - comment lines as you like. If you use a null format, all comments are - deleted. - - - - - Return comments of config item, as zlist. - - - - - Load a config tree from a specified ZPL text file; returns a zconfig_t - reference for the root, if the file exists and is readable. Returns NULL - if the file does not exist. - - - - - Save a config tree to a specified ZPL text file, where a filename - "-" means dump to standard output. - - - - - - Equivalent to zconfig_load, taking a format string instead of a fixed - filename. - - - - - Equivalent to zconfig_save, taking a format string instead of a fixed - filename. - - - - - - Report filename used during zconfig_load, or NULL if none - - - - - Reload config tree from same file that it was previously loaded from. - Returns 0 if OK, -1 if there was an error (and then does not change - existing data). - - - - - - Load a config tree from a memory chunk - - - - - - Save a config tree to a new memory chunk - - - - - Load a config tree from a null-terminated string - - - - - - Save a config tree to a new null terminated string - - - - - Return true if a configuration tree was loaded from a file and that - file has changed in since the tree was loaded. - - - - - Print the config file to open stream - - - - - Print properties of object - - - - Self test of this class - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zdigest.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zdigest.api deleted file mode 100644 index 83abb9b121d6d8..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zdigest.api +++ /dev/null @@ -1,45 +0,0 @@ - - - provides hashing functions (SHA-1 at present) - - - Constructor - creates new digest object, which you use to build up a - digest by repeatedly calling zdigest_update() on chunks of data. - - - - Destroy a digest object - - - - Add buffer into digest calculation - - - - - - Return final digest hash data. If built without crypto support, - returns NULL. - - - - - Return final digest hash size - - - - - Return digest as printable hex string; caller should not modify nor - free this string. After calling this, you may not use zdigest_update() - on the same digest. If built without crypto support, returns NULL. - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zdir.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zdir.api deleted file mode 100644 index cb8283a7027e56..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zdir.api +++ /dev/null @@ -1,124 +0,0 @@ - - - work with file-system directories - - - Create a new directory item that loads in the full tree of the specified - path, optionally located under some parent path. If parent is "-", then - loads only the top-level directory, and does not use parent as a path. - - - - - - Destroy a directory tree and all children it contains. - - - - Return directory path - - - - - Return last modification time for directory. - - - - - Return total hierarchy size, in bytes of data contained in all files - in the directory tree. - - - - - Return directory count - - - - - Returns a sorted list of zfile objects; Each entry in the list is a pointer - to a zfile_t item already allocated in the zdir tree. Do not destroy the - original zdir tree until you are done with this list. - - - - - Remove directory, optionally including all files that it contains, at - all levels. If force is false, will only remove the directory if empty. - If force is true, will remove all files and all subdirectories. - - - - - Calculate differences between two versions of a directory tree. - Returns a list of zdir_patch_t patches. Either older or newer may - be null, indicating the directory is empty/absent. If alias is set, - generates virtual filename (minus path, plus alias). - - - - - - - - Return full contents of directory as a zdir_patch list. - - - - - - Load directory cache; returns a hash table containing the SHA-1 digests - of every file in the tree. The cache is saved between runs in .cache. - - - - - Print contents of directory to open stream - - - - - - Print contents of directory to stdout - - - - - Create a new zdir_watch actor instance: - - zactor_t *watch = zactor_new (zdir_watch, NULL); - - Destroy zdir_watch instance: - - zactor_destroy (&watch); - - Enable verbose logging of commands and activity: - - zstr_send (watch, "VERBOSE"); - - Subscribe to changes to a directory path: - - zsock_send (watch, "ss", "SUBSCRIBE", "directory_path"); - - Unsubscribe from changes to a directory path: - - zsock_send (watch, "ss", "UNSUBSCRIBE", "directory_path"); - - Receive directory changes: - zsock_recv (watch, "sp", &path, &patches); - - // Delete the received data. - free (path); - zlist_destroy (&patches); - - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zdir_patch.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zdir_patch.api deleted file mode 100644 index 8d102b887ae839..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zdir_patch.api +++ /dev/null @@ -1,62 +0,0 @@ - - - work with directory patches - - Creates a new file - Delete a file - - - Create new patch - - - - - - - - Destroy a patch - - - - Create copy of a patch. If the patch is null, or memory was exhausted, - returns null. - - - - - Return patch file directory path - - - - - Return patch file item - - - - - Return operation - - - - - Return patch virtual file path - - - - - Calculate hash digest for file (create only) - - - - Return hash digest for patch file - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zfile.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zfile.api deleted file mode 100644 index f60391bfeea16f..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zfile.api +++ /dev/null @@ -1,152 +0,0 @@ - - - helper functions for working with files. - - - If file exists, populates properties. CZMQ supports portable symbolic - links, which are files with the extension ".ln". A symbolic link is a - text file containing one line, the filename of a target file. Reading - data from the symbolic link actually reads from the target file. Path - may be NULL, in which case it is not used. - - - - - - Destroy a file item - - - - Duplicate a file item, returns a newly constructed item. If the file - is null, or memory was exhausted, returns null. - - - - - Return file name, remove path if provided - - - - - - Refresh file properties from disk; this is not done automatically - on access methods, otherwise it is not possible to compare directory - snapshots. - - - - Return when the file was last modified. If you want this to reflect the - current situation, call zfile_restat before checking this property. - - - - - Return the last-known size of the file. If you want this to reflect the - current situation, call zfile_restat before checking this property. - - - - - Return true if the file is a directory. If you want this to reflect - any external changes, call zfile_restat before checking this property. - - - - - Return true if the file is a regular file. If you want this to reflect - any external changes, call zfile_restat before checking this property. - - - - - Return true if the file is readable by this process. If you want this to - reflect any external changes, call zfile_restat before checking this - property. - - - - - Return true if the file is writeable by this process. If you want this - to reflect any external changes, call zfile_restat before checking this - property. - - - - - Check if file has stopped changing and can be safely processed. - Updates the file statistics from disk at every call. - - - - - Return true if the file was changed on disk since the zfile_t object - was created, or the last zfile_restat() call made on it. - - - - - Remove the file from disk - - - - Open file for reading - Returns 0 if OK, -1 if not found or not accessible - - - - - Open file for writing, creating directory if needed - File is created if necessary; chunks can be written to file at any - location. Returns 0 if OK, -1 if error. - - - - - Read chunk from file at specified position. If this was the last chunk, - sets the eof property. Returns a null chunk in case of error. - - - - - - - Returns true if zfile_read() just read the last chunk in the file. - - - - - Write chunk to file at specified position - Return 0 if OK, else -1 - - - - - - - Read next line of text from file. Returns a pointer to the text line, - or NULL if there was nothing more to read from the file. - - - - - Close file, if open - - - - Return file handle, if opened - - - - - Calculate SHA1 digest for file, using zdigest class. - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zframe.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zframe.api deleted file mode 100644 index cf3c3219f6f6c6..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zframe.api +++ /dev/null @@ -1,156 +0,0 @@ - - - working with single message frames - - - - - - - Create a new frame. If size is not null, allocates the frame data - to the specified size. If additionally, data is not null, copies - size octets from the specified data into the frame body. - - - - - - Destroy a frame - - - - Create an empty (zero-sized) frame - - - - Create a frame with a specified string content. - - - - - Receive frame from socket, returns zframe_t object or NULL if the recv - was interrupted. Does a blocking recv, if you want to not block then use - zpoller or zloop. - - - - - Send a frame to a socket, destroy frame after sending. - Return -1 on error, 0 on success. - - - - - - - - Return number of bytes in frame data - - - - - Return address of frame data - - - - - Return meta data property for frame - Caller must free string when finished with it. - - - - - - Create a new frame that duplicates an existing frame. If frame is null, - or memory was exhausted, returns null. - - - - - Return frame data encoded as printable hex string, useful for 0MQ UUIDs. - Caller must free string when finished with it. - - - - - Return frame data copied into freshly allocated string - Caller must free string when finished with it. - - - - - Return TRUE if frame body is equal to string, excluding terminator - - - - - - Return frame MORE indicator (1 or 0), set when reading frame from socket - or by the zframe_set_more() method - - - - - Set frame MORE indicator (1 or 0). Note this is NOT used when sending - frame to socket, you have to specify flag explicitly. - - - - - Return frame routing ID, if the frame came from a ZMQ_SERVER socket. - Else returns zero. - - - - - Set routing ID on frame. This is used if/when the frame is sent to a - ZMQ_SERVER socket. - - - - - Return frame group of radio-dish pattern. - - - - - Set group on frame. This is used if/when the frame is sent to a - ZMQ_RADIO socket. - Return -1 on error, 0 on success. - - - - - - Return TRUE if two frames have identical size and data - If either frame is NULL, equality is always false. - - - - - - Set new contents for frame - - - - - - Send message to zsys log sink (may be stdout, or system facility as - configured by zsys_set_logstream). Prefix shows before frame, if not null. - - - - - Probe the supplied object, and report if it looks like a zframe_t. - - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zgossip_msg.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zgossip_msg.api deleted file mode 100644 index 0f314fab7c5bf8..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zgossip_msg.api +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - Create a new empty zgossip_msg - - - - Destroy a zgossip_msg instance - - - - Receive a zgossip_msg from the socket. Returns 0 if OK, -1 if - there was an error. Blocks if there is no message waiting. - - - - - - Send the zgossip_msg to the output socket, does not destroy it - - - - - - Print contents of message to stdout - - - - Get the message routing id, as a frame - - - - - Set the message routing id from a frame - - - - - Get the zgossip_msg message id - - - - - Set the zgossip_msg message id - - - - - Get the zgossip_msg message id as printable text - - - - - Get the key field - - - - Set the key field - - - - Get the value field - - - - Set the value field - - - - Get the ttl field - - - - Set the ttl field - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zhash.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zhash.api deleted file mode 100644 index 36d58847af46e4..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zhash.api +++ /dev/null @@ -1,183 +0,0 @@ - - - generic type-free hash container (simple) - - - Callback function for zhash_freefn method - - - - - Create a new, empty hash container - - - - Destroy a hash container and all items in it - - - - Insert item into hash table with specified key and item. - If key is already present returns -1 and leaves existing item unchanged - Returns 0 on success. - - - - - - - Update item into hash table with specified key and item. - If key is already present, destroys old item and inserts new one. - Use free_fn method to ensure deallocator is properly called on item. - - - - - - Remove an item specified by key from the hash table. If there was no such - item, this function does nothing. - - - - - Return the item at the specified key, or null - - - - - - Reindexes an item from an old key to a new key. If there was no such - item, does nothing. Returns 0 if successful, else -1. - - - - - - - Set a free function for the specified hash table item. When the item is - destroyed, the free function, if any, is called on that item. - Use this when hash items are dynamically allocated, to ensure that - you don't have memory leaks. You can pass 'free' or NULL as a free_fn. - Returns the item, or NULL if there is no such item. - - - - - - - Return the number of keys/items in the hash table - - - - - Make copy of hash table; if supplied table is null, returns null. - Does not copy items themselves. Rebuilds new table so may be slow on - very large tables. NOTE: only works with item values that are strings - since there's no other way to know how to duplicate the item value. - - - - - Return keys for items in table - - - - - Simple iterator; returns first item in hash table, in no given order, - or NULL if the table is empty. This method is simpler to use than the - foreach() method, which is deprecated. To access the key for this item - use zhash_cursor(). NOTE: do NOT modify the table while iterating. - - - - - Simple iterator; returns next item in hash table, in no given order, - or NULL if the last item was already returned. Use this together with - zhash_first() to process all items in a hash table. If you need the - items in sorted order, use zhash_keys() and then zlist_sort(). To - access the key for this item use zhash_cursor(). NOTE: do NOT modify - the table while iterating. - - - - - After a successful first/next method, returns the key for the item that - was returned. This is a constant string that you may not modify or - deallocate, and which lasts as long as the item in the hash. After an - unsuccessful first/next, returns NULL. - - - - - Add a comment to hash table before saving to disk. You can add as many - comment lines as you like. These comment lines are discarded when loading - the file. If you use a null format, all comments are deleted. - - - - - Serialize hash table to a binary frame that can be sent in a message. - The packed format is compatible with the 'dictionary' type defined in - http://rfc.zeromq.org/spec:35/FILEMQ, and implemented by zproto: - - ; A list of name/value pairs - dictionary = dict-count *( dict-name dict-value ) - dict-count = number-4 - dict-value = longstr - dict-name = string - - ; Strings are always length + text contents - longstr = number-4 *VCHAR - string = number-1 *VCHAR - - ; Numbers are unsigned integers in network byte order - number-1 = 1OCTET - number-4 = 4OCTET - - Comments are not included in the packed data. Item values MUST be - strings. - - - - - Unpack binary frame into a new hash table. Packed data must follow format - defined by zhash_pack. Hash table is set to autofree. An empty frame - unpacks to an empty hash table. - - - - - Save hash table to a text file in name=value format. Hash values must be - printable strings; keys may not contain '=' character. Returns 0 if OK, - else -1 if a file error occurred. - - - - - - Load hash table from a text file in name=value format; hash table must - already exist. Hash values must printable strings; keys may not contain - '=' character. Returns 0 if OK, else -1 if a file was not readable. - - - - - - When a hash table was loaded from a file by zhash_load, this method will - reload the file if it has been modified since, and is "stable", i.e. not - still changing. Returns 0 if OK, -1 if there was an error reloading the - file. - - - - - Set hash for automatic value destruction - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zhashx.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zhashx.api deleted file mode 100644 index 22087e0fe9fcd2..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zhashx.api +++ /dev/null @@ -1,293 +0,0 @@ - - - extended generic type-free hash container - - - Destroy an item - - - - - Duplicate an item - - - - - - Compare two items, for sorting - - - - - - - compare two items, for sorting - - - - - compare two items, for sorting - - - - - - Serializes an item to a longstr. - The caller takes ownership of the newly created object. - - - - - - Deserializes a longstr into an item. - The caller takes ownership of the newly created object. - - - - - - Create a new, empty hash container - - - - Destroy a hash container and all items in it - - - - Insert item into hash table with specified key and item. - If key is already present returns -1 and leaves existing item unchanged - Returns 0 on success. - - - - - - - Update or insert item into hash table with specified key and item. If the - key is already present, destroys old item and inserts new one. If you set - a container item destructor, this is called on the old value. If the key - was not already present, inserts a new item. Sets the hash cursor to the - new item. - - - - - - Remove an item specified by key from the hash table. If there was no such - item, this function does nothing. - - - - - Delete all items from the hash table. If the key destructor is - set, calls it on every key. If the item destructor is set, calls - it on every item. - - - - Return the item at the specified key, or null - - - - - - Reindexes an item from an old key to a new key. If there was no such - item, does nothing. Returns 0 if successful, else -1. - - - - - - - Set a free function for the specified hash table item. When the item is - destroyed, the free function, if any, is called on that item. - Use this when hash items are dynamically allocated, to ensure that - you don't have memory leaks. You can pass 'free' or NULL as a free_fn. - Returns the item, or NULL if there is no such item. - - - - - - - Return the number of keys/items in the hash table - - - - - Return a zlistx_t containing the keys for the items in the - table. Uses the key_duplicator to duplicate all keys and sets the - key_destructor as destructor for the list. - - - - - Return a zlistx_t containing the values for the items in the - table. Uses the duplicator to duplicate all items and sets the - destructor as destructor for the list. - - - - - Simple iterator; returns first item in hash table, in no given order, - or NULL if the table is empty. This method is simpler to use than the - foreach() method, which is deprecated. To access the key for this item - use zhashx_cursor(). NOTE: do NOT modify the table while iterating. - - - - - Simple iterator; returns next item in hash table, in no given order, - or NULL if the last item was already returned. Use this together with - zhashx_first() to process all items in a hash table. If you need the - items in sorted order, use zhashx_keys() and then zlistx_sort(). To - access the key for this item use zhashx_cursor(). NOTE: do NOT modify - the table while iterating. - - - - - After a successful first/next method, returns the key for the item that - was returned. This is a constant string that you may not modify or - deallocate, and which lasts as long as the item in the hash. After an - unsuccessful first/next, returns NULL. - - - - - Add a comment to hash table before saving to disk. You can add as many - comment lines as you like. These comment lines are discarded when loading - the file. If you use a null format, all comments are deleted. - - - - - Save hash table to a text file in name=value format. Hash values must be - printable strings; keys may not contain '=' character. Returns 0 if OK, - else -1 if a file error occurred. - - - - - - Load hash table from a text file in name=value format; hash table must - already exist. Hash values must printable strings; keys may not contain - '=' character. Returns 0 if OK, else -1 if a file was not readable. - - - - - - When a hash table was loaded from a file by zhashx_load, this method will - reload the file if it has been modified since, and is "stable", i.e. not - still changing. Returns 0 if OK, -1 if there was an error reloading the - file. - - - - - Serialize hash table to a binary frame that can be sent in a message. - The packed format is compatible with the 'dictionary' type defined in - http://rfc.zeromq.org/spec:35/FILEMQ, and implemented by zproto: - - ; A list of name/value pairs - dictionary = dict-count *( dict-name dict-value ) - dict-count = number-4 - dict-value = longstr - dict-name = string - - ; Strings are always length + text contents - longstr = number-4 *VCHAR - string = number-1 *VCHAR - - ; Numbers are unsigned integers in network byte order - number-1 = 1OCTET - number-4 = 4OCTET - - Comments are not included in the packed data. Item values MUST be - strings. - - - - - Same as pack but uses a user-defined serializer function to convert items - into longstr. - - - - - - Unpack binary frame into a new hash table. Packed data must follow format - defined by zhashx_pack. Hash table is set to autofree. An empty frame - unpacks to an empty hash table. - - - - - Same as unpack but uses a user-defined deserializer function to convert - a longstr back into item format. - - - - - - Make a copy of the list; items are duplicated if you set a duplicator - for the list, otherwise not. Copying a null reference returns a null - reference. Note that this method's behavior changed slightly for CZMQ - v3.x, as it does not set nor respect autofree. It does however let you - duplicate any hash table safely. The old behavior is in zhashx_dup_v2. - - - - - Set a user-defined deallocator for hash items; by default items are not - freed when the hash is destroyed. - - - - - Set a user-defined duplicator for hash items; by default items are not - copied when the hash is duplicated. - - - - - Set a user-defined deallocator for keys; by default keys are freed - when the hash is destroyed using free(). - - - - - Set a user-defined duplicator for keys; by default keys are duplicated - using strdup. - - - - - Set a user-defined comparator for keys; by default keys are - compared using strcmp. - - - - - Set a user-defined comparator for keys; by default keys are - compared using strcmp. - - - - - Make copy of hash table; if supplied table is null, returns null. - Does not copy items themselves. Rebuilds new table so may be slow on - very large tables. NOTE: only works with item values that are strings - since there's no other way to know how to duplicate the item value. - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/ziflist.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/ziflist.api deleted file mode 100644 index 5dc362463c0dee..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/ziflist.api +++ /dev/null @@ -1,58 +0,0 @@ - - - List of network interfaces available on system - - - Get a list of network interfaces currently defined on the system - - - - Destroy a ziflist instance - - - - Reload network interfaces from system - - - - Return the number of network interfaces on system - - - - - Get first network interface, return NULL if there are none - - - - - Get next network interface, return NULL if we hit the last one - - - - - Return the current interface IP address as a printable string - - - - - Return the current interface broadcast address as a printable string - - - - - Return the current interface network mask as a printable string - - - - - Return the list of interfaces. - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zlist.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zlist.api deleted file mode 100644 index 67b4f01c577b5f..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zlist.api +++ /dev/null @@ -1,158 +0,0 @@ - - - simple generic list container - - - Comparison function e.g. for sorting and removing. - - - - - - - Callback function for zlist_freefn method - - - - - Create a new list container - - - - Destroy a list container - - - - Return the item at the head of list. If the list is empty, returns NULL. - Leaves cursor pointing at the head item, or NULL if the list is empty. - - - - - Return the next item. If the list is empty, returns NULL. To move to - the start of the list call zlist_first (). Advances the cursor. - - - - - Return the item at the tail of list. If the list is empty, returns NULL. - Leaves cursor pointing at the tail item, or NULL if the list is empty. - - - - - Return first item in the list, or null, leaves the cursor - - - - - Return last item in the list, or null, leaves the cursor - - - - - Return the current item of list. If the list is empty, returns NULL. - Leaves cursor pointing at the current item, or NULL if the list is empty. - - - - - Append an item to the end of the list, return 0 if OK or -1 if this - failed for some reason (out of memory). Note that if a duplicator has - been set, this method will also duplicate the item. - - - - - - Push an item to the start of the list, return 0 if OK or -1 if this - failed for some reason (out of memory). Note that if a duplicator has - been set, this method will also duplicate the item. - - - - - - Pop the item off the start of the list, if any - - - - - Checks if an item already is present. Uses compare method to determine if - items are equal. If the compare method is NULL the check will only compare - pointers. Returns true if item is present else false. - - - - - - Remove the specified item from the list if present - - - - - Make a copy of list. If the list has autofree set, the copied list will - duplicate all items, which must be strings. Otherwise, the list will hold - pointers back to the items in the original list. If list is null, returns - NULL. - - - - - Purge all items from list - - - - Return number of items in the list - - - - - Sort the list. If the compare function is null, sorts the list by - ascending key value using a straight ASCII comparison. If you specify - a compare function, this decides how items are sorted. The sort is not - stable, so may reorder items with the same keys. The algorithm used is - combsort, a compromise between performance and simplicity. - - - - - Set list for automatic item destruction; item values MUST be strings. - By default a list item refers to a value held elsewhere. When you set - this, each time you append or push a list item, zlist will take a copy - of the string value. Then, when you destroy the list, it will free all - item values automatically. If you use any other technique to allocate - list values, you must free them explicitly before destroying the list. - The usual technique is to pop list items and destroy them, until the - list is empty. - - - - Sets a compare function for this list. The function compares two items. - It returns an integer less than, equal to, or greater than zero if the - first item is found, respectively, to be less than, to match, or be - greater than the second item. - This function is used for sorting, removal and exists checking. - - - - - Set a free function for the specified list item. When the item is - destroyed, the free function, if any, is called on that item. - Use this when list items are dynamically allocated, to ensure that - you don't have memory leaks. You can pass 'free' or NULL as a free_fn. - Returns the item, or NULL if there is no such item. - - - - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zlistx.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zlistx.api deleted file mode 100644 index 1dc95ea6374f9c..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zlistx.api +++ /dev/null @@ -1,220 +0,0 @@ - - - extended generic list container - - - Destroy an item - - - - - Duplicate an item - - - - - - Compare two items, for sorting - - - - - - - Create a new, empty list. - - - - Destroy a list. If an item destructor was specified, all items in the - list are automatically destroyed as well. - - - - Add an item to the head of the list. Calls the item duplicator, if any, - on the item. Resets cursor to list head. Returns an item handle on - success, NULL if memory was exhausted. - - - - - - Add an item to the tail of the list. Calls the item duplicator, if any, - on the item. Resets cursor to list head. Returns an item handle on - success, NULL if memory was exhausted. - - - - - - Return the number of items in the list - - - - - Return first item in the list, or null, leaves the cursor - - - - - Return last item in the list, or null, leaves the cursor - - - - - Return the item at the head of list. If the list is empty, returns NULL. - Leaves cursor pointing at the head item, or NULL if the list is empty. - - - - - Return the next item. At the end of the list (or in an empty list), - returns NULL. Use repeated zlistx_next () calls to work through the list - from zlistx_first (). First time, acts as zlistx_first(). - - - - - Return the previous item. At the start of the list (or in an empty list), - returns NULL. Use repeated zlistx_prev () calls to work through the list - backwards from zlistx_last (). First time, acts as zlistx_last(). - - - - - Return the item at the tail of list. If the list is empty, returns NULL. - Leaves cursor pointing at the tail item, or NULL if the list is empty. - - - - - Returns the value of the item at the cursor, or NULL if the cursor is - not pointing to an item. - - - - - Returns the handle of the item at the cursor, or NULL if the cursor is - not pointing to an item. - - - - - Returns the item associated with the given list handle, or NULL if passed - in handle is NULL. Asserts that the passed in handle points to a list element. - - - - - - Find an item in the list, searching from the start. Uses the item - comparator, if any, else compares item values directly. Returns the - item handle found, or NULL. Sets the cursor to the found item, if any. - - - - - - Detach an item from the list, using its handle. The item is not modified, - and the caller is responsible for destroying it if necessary. If handle is - null, detaches the first item on the list. Returns item that was detached, - or null if none was. If cursor was at item, moves cursor to previous item, - so you can detach items while iterating forwards through a list. - - - - - - Detach item at the cursor, if any, from the list. The item is not modified, - and the caller is responsible for destroying it as necessary. Returns item - that was detached, or null if none was. Moves cursor to previous item, so - you can detach items while iterating forwards through a list. - - - - - Delete an item, using its handle. Calls the item destructor is any is - set. If handle is null, deletes the first item on the list. Returns 0 - if an item was deleted, -1 if not. If cursor was at item, moves cursor - to previous item, so you can delete items while iterating forwards - through a list. - - - - - - Move an item to the start of the list, via its handle. - - - - - Move an item to the end of the list, via its handle. - - - - - Remove all items from the list, and destroy them if the item destructor - is set. - - - - Sort the list. If an item comparator was set, calls that to compare - items, otherwise compares on item value. The sort is not stable, so may - reorder equal items. - - - - Create a new node and insert it into a sorted list. Calls the item - duplicator, if any, on the item. If low_value is true, starts searching - from the start of the list, otherwise searches from the end. Use the item - comparator, if any, to find where to place the new node. Returns a handle - to the new node, or NULL if memory was exhausted. Resets the cursor to the - list head. - - - - - - - Move an item, specified by handle, into position in a sorted list. Uses - the item comparator, if any, to determine the new location. If low_value - is true, starts searching from the start of the list, otherwise searches - from the end. - - - - - - Make a copy of the list; items are duplicated if you set a duplicator - for the list, otherwise not. Copying a null reference returns a null - reference. - - - - - Set a user-defined deallocator for list items; by default items are not - freed when the list is destroyed. - - - - - Set a user-defined duplicator for list items; by default items are not - copied when the list is duplicated. - - - - - Set a user-defined comparator for zlistx_find and zlistx_sort; the method - must return -1, 0, or 1 depending on whether item1 is less than, equal to, - or greater than, item2. - - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zloop.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zloop.api deleted file mode 100644 index 429e3b517a89fc..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zloop.api +++ /dev/null @@ -1,176 +0,0 @@ - - - event-driven reactor - - - Callback function for reactor socket activity - - - - - - - - Callback function for reactor events (low-level) - - - - - - - - Callback for reactor timer events - - - - - - - - Create a new zloop reactor - - - - Destroy a reactor - - - - Register socket reader with the reactor. When the reader has messages, - the reactor will call the handler, passing the arg. Returns 0 if OK, -1 - if there was an error. If you register the same socket more than once, - each instance will invoke its corresponding handler. - - - - - - - - Cancel a socket reader from the reactor. If multiple readers exist for - same socket, cancels ALL of them. - - - - - Configure a registered reader to ignore errors. If you do not set this, - then readers that have errors are removed from the reactor silently. - - - - - Register low-level libzmq pollitem with the reactor. When the pollitem - is ready, will call the handler, passing the arg. Returns 0 if OK, -1 - if there was an error. If you register the pollitem more than once, each - instance will invoke its corresponding handler. A pollitem with - socket=NULL and fd=0 means 'poll on FD zero'. - - - - - - - - Cancel a pollitem from the reactor, specified by socket or FD. If both - are specified, uses only socket. If multiple poll items exist for same - socket/FD, cancels ALL of them. - - - - - Configure a registered poller to ignore errors. If you do not set this, - then poller that have errors are removed from the reactor silently. - - - - - Register a timer that expires after some delay and repeats some number of - times. At each expiry, will call the handler, passing the arg. To run a - timer forever, use 0 times. Returns a timer_id that is used to cancel the - timer in the future. Returns -1 if there was an error. - - - - - - - - - Cancel a specific timer identified by a specific timer_id (as returned by - zloop_timer). - - - - - - Register a ticket timer. Ticket timers are very fast in the case where - you use a lot of timers (thousands), and frequently remove and add them. - The main use case is expiry timers for servers that handle many clients, - and which reset the expiry timer for each message received from a client. - Whereas normal timers perform poorly as the number of clients grows, the - cost of ticket timers is constant, no matter the number of clients. You - must set the ticket delay using zloop_set_ticket_delay before creating a - ticket. Returns a handle to the timer that you should use in - zloop_ticket_reset and zloop_ticket_delete. - - - - - - - Reset a ticket timer, which moves it to the end of the ticket list and - resets its execution time. This is a very fast operation. - - - - - Delete a ticket timer. We do not actually delete the ticket here, as - other code may still refer to the ticket. We mark as deleted, and remove - later and safely. - - - - - Set the ticket delay, which applies to all tickets. If you lower the - delay and there are already tickets created, the results are undefined. - - - - - Set hard limit on number of timers allowed. Setting more than a small - number of timers (10-100) can have a dramatic impact on the performance - of the reactor. For high-volume cases, use ticket timers. If the hard - limit is reached, the reactor stops creating new timers and logs an - error. - - - - - Set verbose tracing of reactor on/off. The default verbose setting is - off (false). - - - - - By default the reactor stops if the process receives a SIGINT or SIGTERM - signal. This makes it impossible to shut-down message based architectures - like zactors. This method lets you switch off break handling. The default - nonstop setting is off (false). - - - - - Start the reactor. Takes control of the thread and returns when the 0MQ - context is terminated or the process is interrupted, or any event handler - returns -1. Event handlers may register new sockets and timers, and - cancel sockets. Returns 0 if interrupted, -1 if canceled by a handler. - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zmsg.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zmsg.api deleted file mode 100644 index 6205fd02e3d50b..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zmsg.api +++ /dev/null @@ -1,250 +0,0 @@ - - - working with multipart messages - - - Create a new empty message object - - - - Destroy a message object and all frames it contains - - - - Receive message from socket, returns zmsg_t object or NULL if the recv - was interrupted. Does a blocking recv. If you want to not block then use - the zloop class or zmsg_recv_nowait or zmq_poll to check for socket input - before receiving. - - - - - Send message to destination socket, and destroy the message after sending - it successfully. If the message has no frames, sends nothing but destroys - the message anyhow. Nullifies the caller's reference to the message (as - it is a destructor). - - - - - - - Send message to destination socket as part of a multipart sequence, and - destroy the message after sending it successfully. Note that after a - zmsg_sendm, you must call zmsg_send or another method that sends a final - message part. If the message has no frames, sends nothing but destroys - the message anyhow. Nullifies the caller's reference to the message (as - it is a destructor). - - - - - - - Return size of message, i.e. number of frames (0 or more). - - - - - Return total size of all frames in message. - - - - - Return message routing ID, if the message came from a ZMQ_SERVER socket. - Else returns zero. - - - - - Set routing ID on message. This is used if/when the message is sent to a - ZMQ_SERVER socket. - - - - - Push frame to the front of the message, i.e. before all other frames. - Message takes ownership of frame, will destroy it when message is sent. - Returns 0 on success, -1 on error. Deprecates zmsg_push, which did not - nullify the caller's frame reference. - - - - - - Add frame to the end of the message, i.e. after all other frames. - Message takes ownership of frame, will destroy it when message is sent. - Returns 0 on success. Deprecates zmsg_add, which did not nullify the - caller's frame reference. - - - - - - Remove first frame from message, if any. Returns frame, or NULL. - - - - - Push block of memory to front of message, as a new frame. - Returns 0 on success, -1 on error. - - - - - - - Add block of memory to the end of the message, as a new frame. - Returns 0 on success, -1 on error. - - - - - - - Push string as new frame to front of message. - Returns 0 on success, -1 on error. - - - - - - Push string as new frame to end of message. - Returns 0 on success, -1 on error. - - - - - - Push formatted string as new frame to front of message. - Returns 0 on success, -1 on error. - - - - - - Push formatted string as new frame to end of message. - Returns 0 on success, -1 on error. - - - - - - Pop frame off front of message, return as fresh string. If there were - no more frames in the message, returns NULL. - - - - - Push encoded message as a new frame. Message takes ownership of - submessage, so the original is destroyed in this call. Returns 0 on - success, -1 on error. - - - - - - Remove first submessage from message, if any. Returns zmsg_t, or NULL if - decoding was not successful. - - - - - Remove specified frame from list, if present. Does not destroy frame. - - - - - Set cursor to first frame in message. Returns frame, or NULL, if the - message is empty. Use this to navigate the frames as a list. - - - - - Return the next frame. If there are no more frames, returns NULL. To move - to the first frame call zmsg_first(). Advances the cursor. - - - - - Return the last frame. If there are no frames, returns NULL. - - - - - Save message to an open file, return 0 if OK, else -1. The message is - saved as a series of frames, each with length and data. Note that the - file is NOT guaranteed to be portable between operating systems, not - versions of CZMQ. The file format is at present undocumented and liable - to arbitrary change. - - - - - - Load/append an open file into new message, return the message. - Returns NULL if the message could not be loaded. - - - - - Serialize multipart message to a single message frame. Use this method - to send structured messages across transports that do not support - multipart data. Allocates and returns a new frame containing the - serialized message. To decode a serialized message frame, use - zmsg_decode (). - - - - - Decodes a serialized message frame created by zmsg_encode () and returns - a new zmsg_t object. Returns NULL if the frame was badly formatted or - there was insufficient memory to work. - - - - - Create copy of message, as new message object. Returns a fresh zmsg_t - object. If message is null, or memory was exhausted, returns null. - - - - - Send message to zsys log sink (may be stdout, or system facility as - configured by zsys_set_logstream). - - - - Return true if the two messages have the same number of frames and each - frame in the first message is identical to the corresponding frame in the - other message. As with zframe_eq, return false if either message is NULL. - - - - - - Generate a signal message encoding the given status. A signal is a short - message carrying a 1-byte success/failure code (by convention, 0 means - OK). Signals are encoded to be distinguishable from "normal" messages. - - - - - Return signal value, 0 or greater, if message is a signal, -1 if not. - - - - - Probe the supplied object, and report if it looks like a zmsg_t. - - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zpoller.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zpoller.api deleted file mode 100644 index fc00f6a0751a94..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zpoller.api +++ /dev/null @@ -1,71 +0,0 @@ - - - event-driven reactor - - - Create new poller, specifying zero or more readers. The list of - readers ends in a NULL. Each reader can be a zsock_t instance, a - zactor_t instance, a libzmq socket (void *), or a file handle. - - - - - Destroy a poller - - - - Add a reader to be polled. Returns 0 if OK, -1 on failure. The reader may - be a libzmq void * socket, a zsock_t instance, or a zactor_t instance. - - - - - - Remove a reader from the poller; returns 0 if OK, -1 on failure. The reader - must have been passed during construction, or in an zpoller_add () call. - - - - - - By default the poller stops if the process receives a SIGINT or SIGTERM - signal. This makes it impossible to shut-down message based architectures - like zactors. This method lets you switch off break handling. The default - nonstop setting is off (false). - - - - - Poll the registered readers for I/O, return first reader that has input. - The reader will be a libzmq void * socket, or a zsock_t or zactor_t - instance as specified in zpoller_new/zpoller_add. The timeout should be - zero or greater, or -1 to wait indefinitely. Socket priority is defined - by their order in the poll list. If you need a balanced poll, use the low - level zmq_poll method directly. If the poll call was interrupted (SIGINT), - or the ZMQ context was destroyed, or the timeout expired, returns NULL. - You can test the actual exit condition by calling zpoller_expired () and - zpoller_terminated (). The timeout is in msec. - - - - - - Return true if the last zpoller_wait () call ended because the timeout - expired, without any error. - - - - - Return true if the last zpoller_wait () call ended because the process - was interrupted, or the parent context was destroyed. - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zproc.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zproc.api deleted file mode 100644 index 52c1c9123ba3ee..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zproc.api +++ /dev/null @@ -1,139 +0,0 @@ - - - process configuration and status - - - Returns CZMQ version as a single 6-digit integer encoding the major - version (x 10000), the minor version (x 100) and the patch. - - - - - Returns true if the process received a SIGINT or SIGTERM signal. - It is good practice to use this method to exit any infinite loop - processing messages. - - - - - Returns true if the underlying libzmq supports CURVE security. - - - - - Return current host name, for use in public tcp:// endpoints. - If the host name is not resolvable, returns NULL. - - - - - Move the current process into the background. The precise effect - depends on the operating system. On POSIX boxes, moves to a specified - working directory (if specified), closes all file handles, reopens - stdin, stdout, and stderr to the null device, and sets the process to - ignore SIGHUP. On Windows, does nothing. Returns 0 if OK, -1 if there - was an error. - - - - - Drop the process ID into the lockfile, with exclusive lock, and - switch the process to the specified group and/or user. Any of the - arguments may be null, indicating a no-op. Returns 0 on success, - -1 on failure. Note if you combine this with zsys_daemonize, run - after, not before that method, or the lockfile will hold the wrong - process ID. - - - - - - - Configure the number of I/O threads that ZeroMQ will use. A good - rule of thumb is one thread per gigabit of traffic in or out. The - default is 1, sufficient for most applications. If the environment - variable ZSYS_IO_THREADS is defined, that provides the default. - Note that this method is valid only before any socket is created. - - - - - Configure the number of sockets that ZeroMQ will allow. The default - is 1024. The actual limit depends on the system, and you can query it - by using zsys_socket_limit (). A value of zero means "maximum". - Note that this method is valid only before any socket is created. - - - - - Set network interface name to use for broadcasts, particularly zbeacon. - This lets the interface be configured for test environments where required. - For example, on Mac OS X, zbeacon cannot bind to 255.255.255.255 which is - the default when there is no specified interface. If the environment - variable ZSYS_INTERFACE is set, use that as the default interface name. - Setting the interface to "*" means "use all available interfaces". - - - - - Return network interface to use for broadcasts, or "" if none was set. - - - - - Set log identity, which is a string that prefixes all log messages sent - by this process. The log identity defaults to the environment variable - ZSYS_LOGIDENT, if that is set. - - - - - Sends log output to a PUB socket bound to the specified endpoint. To - collect such log output, create a SUB socket, subscribe to the traffic - you care about, and connect to the endpoint. Log traffic is sent as a - single string frame, in the same format as when sent to stdout. The - log system supports a single sender; multiple calls to this method will - bind the same sender to multiple endpoints. To disable the sender, call - this method with a null argument. - - - - - Enable or disable logging to the system facility (syslog on POSIX boxes, - event log on Windows). By default this is disabled. - - - - - Log error condition - highest priority - - - - - Log warning condition - high priority - - - - - Log normal, but significant, condition - normal priority - - - - - Log informational message - low priority - - - - - Log debug-level message - lowest priority - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zsock.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zsock.api deleted file mode 100644 index 26b15cf509624d..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zsock.api +++ /dev/null @@ -1,406 +0,0 @@ - - - high-level socket API that hides libzmq contexts and sockets - - - Create a new socket. Returns the new socket, or NULL if the new socket - could not be created. Note that the symbol zsock_new (and other - constructors/destructors for zsock) are redirected to the *_checked - variant, enabling intelligent socket leak detection. This can have - performance implications if you use a LOT of sockets. To turn off this - redirection behaviour, define ZSOCK_NOCHECK. - - - - - - - - - - - - - - - - - - - - - - - - - - Destroy the socket. You must use this for any socket created via the - zsock_new method. - - - - Create a PUB socket. Default action is bind. - - - - - Create a SUB socket, and optionally subscribe to some prefix string. Default - action is connect. - - - - - - Create a REQ socket. Default action is connect. - - - - - Create a REP socket. Default action is bind. - - - - - Create a DEALER socket. Default action is connect. - - - - - Create a ROUTER socket. Default action is bind. - - - - - Create a PUSH socket. Default action is connect. - - - - - Create a PULL socket. Default action is bind. - - - - - Create an XPUB socket. Default action is bind. - - - - - Create an XSUB socket. Default action is connect. - - - - - Create a PAIR socket. Default action is connect. - - - - - Create a STREAM socket. Default action is connect. - - - - - Create a SERVER socket. Default action is bind. - - - - - Create a CLIENT socket. Default action is connect. - - - - - Create a RADIO socket. Default action is bind. - - - - - Create a DISH socket. Default action is connect. - - - - - Create a GATHER socket. Default action is bind. - - - - - Create a SCATTER socket. Default action is connect. - - - - - Bind a socket to a formatted endpoint. For tcp:// endpoints, supports - ephemeral ports, if you specify the port number as "*". By default - zsock uses the IANA designated range from C000 (49152) to FFFF (65535). - To override this range, follow the "*" with "[first-last]". Either or - both first and last may be empty. To bind to a random port within the - range, use "!" in place of "*". - - Examples: - tcp://127.0.0.1:* bind to first free port from C000 up - tcp://127.0.0.1:! bind to random port from C000 to FFFF - tcp://127.0.0.1:*[60000-] bind to first free port from 60000 up - tcp://127.0.0.1:![-60000] bind to random port from C000 to 60000 - tcp://127.0.0.1:![55000-55999] - bind to random port from 55000 to 55999 - - On success, returns the actual port number used, for tcp:// endpoints, - and 0 for other transports. On failure, returns -1. Note that when using - ephemeral ports, a port may be reused by different services without - clients being aware. Protocols that run on ephemeral ports should take - this into account. - - - - - - Returns last bound endpoint, if any. - - - - - Unbind a socket from a formatted endpoint. - Returns 0 if OK, -1 if the endpoint was invalid or the function - isn't supported. - - - - - - Connect a socket to a formatted endpoint - Returns 0 if OK, -1 if the endpoint was invalid. - - - - - - Disconnect a socket from a formatted endpoint - Returns 0 if OK, -1 if the endpoint was invalid or the function - isn't supported. - - - - - - Attach a socket to zero or more endpoints. If endpoints is not null, - parses as list of ZeroMQ endpoints, separated by commas, and prefixed by - '@' (to bind the socket) or '>' (to connect the socket). Returns 0 if all - endpoints were valid, or -1 if there was a syntax error. If the endpoint - does not start with '@' or '>', the serverish argument defines whether - it is used to bind (serverish = true) or connect (serverish = false). - - - - - - - Returns socket type as printable constant string. - - - - - Send a 'picture' message to the socket (or actor). The picture is a - string that defines the type of each frame. This makes it easy to send - a complex multiframe message in one call. The picture can contain any - of these characters, each corresponding to one or two arguments: - - i = int (signed) - 1 = uint8_t - 2 = uint16_t - 4 = uint32_t - 8 = uint64_t - s = char * - b = byte *, size_t (2 arguments) - c = zchunk_t * - f = zframe_t * - h = zhashx_t * - U = zuuid_t * - p = void * (sends the pointer value, only meaningful over inproc) - m = zmsg_t * (sends all frames in the zmsg) - z = sends zero-sized frame (0 arguments) - u = uint (deprecated) - - Note that s, b, c, and f are encoded the same way and the choice is - offered as a convenience to the sender, which may or may not already - have data in a zchunk or zframe. Does not change or take ownership of - any arguments. Returns 0 if successful, -1 if sending failed for any - reason. - - - - - - Send a 'picture' message to the socket (or actor). This is a va_list - version of zsock_send (), so please consult its documentation for the - details. - - - - - - - Receive a 'picture' message to the socket (or actor). See zsock_send for - the format and meaning of the picture. Returns the picture elements into - a series of pointers as provided by the caller: - - i = int * (stores signed integer) - 4 = uint32_t * (stores 32-bit unsigned integer) - 8 = uint64_t * (stores 64-bit unsigned integer) - s = char ** (allocates new string) - b = byte **, size_t * (2 arguments) (allocates memory) - c = zchunk_t ** (creates zchunk) - f = zframe_t ** (creates zframe) - U = zuuid_t * (creates a zuuid with the data) - h = zhashx_t ** (creates zhashx) - p = void ** (stores pointer) - m = zmsg_t ** (creates a zmsg with the remaing frames) - z = null, asserts empty frame (0 arguments) - u = uint * (stores unsigned integer, deprecated) - - Note that zsock_recv creates the returned objects, and the caller must - destroy them when finished with them. The supplied pointers do not need - to be initialized. Returns 0 if successful, or -1 if it failed to recv - a message, in which case the pointers are not modified. When message - frames are truncated (a short message), sets return values to zero/null. - If an argument pointer is NULL, does not store any value (skips it). - An 'n' picture matches an empty frame; if the message does not match, - the method will return -1. - - - - - - Receive a 'picture' message from the socket (or actor). This is a - va_list version of zsock_recv (), so please consult its documentation - for the details. - - - - - - - Send a binary encoded 'picture' message to the socket (or actor). This - method is similar to zsock_send, except the arguments are encoded in a - binary format that is compatible with zproto, and is designed to reduce - memory allocations. The pattern argument is a string that defines the - type of each argument. Supports these argument types: - - pattern C type zproto type: - 1 uint8_t type = "number" size = "1" - 2 uint16_t type = "number" size = "2" - 4 uint32_t type = "number" size = "3" - 8 uint64_t type = "number" size = "4" - s char *, 0-255 chars type = "string" - S char *, 0-2^32-1 chars type = "longstr" - c zchunk_t * type = "chunk" - f zframe_t * type = "frame" - u zuuid_t * type = "uuid" - m zmsg_t * type = "msg" - p void *, sends pointer value, only over inproc - - Does not change or take ownership of any arguments. Returns 0 if - successful, -1 if sending failed for any reason. - - - - - - Receive a binary encoded 'picture' message from the socket (or actor). - This method is similar to zsock_recv, except the arguments are encoded - in a binary format that is compatible with zproto, and is designed to - reduce memory allocations. The pattern argument is a string that defines - the type of each argument. See zsock_bsend for the supported argument - types. All arguments must be pointers; this call sets them to point to - values held on a per-socket basis. - Note that zsock_brecv creates the returned objects, and the caller must - destroy them when finished with them. The supplied pointers do not need - to be initialized. Returns 0 if successful, or -1 if it failed to read - a message. - - - - - - Return socket routing ID if any. This returns 0 if the socket is not - of type ZMQ_SERVER or if no request was already received on it. - - - - - Set routing ID on socket. The socket MUST be of type ZMQ_SERVER. - This will be used when sending messages on the socket via the zsock API. - - - - - Set socket to use unbounded pipes (HWM=0); use this in cases when you are - totally certain the message volume can fit in memory. This method works - across all versions of ZeroMQ. Takes a polymorphic socket reference. - - - - Send a signal over a socket. A signal is a short message carrying a - success/failure code (by convention, 0 means OK). Signals are encoded - to be distinguishable from "normal" messages. Accepts a zsock_t or a - zactor_t argument, and returns 0 if successful, -1 if the signal could - not be sent. Takes a polymorphic socket reference. - - - - - - Wait on a signal. Use this to coordinate between threads, over pipe - pairs. Blocks until the signal is received. Returns -1 on error, 0 or - greater on success. Accepts a zsock_t or a zactor_t as argument. - Takes a polymorphic socket reference. - - - - - If there is a partial message still waiting on the socket, remove and - discard it. This is useful when reading partial messages, to get specific - message types. - - - - Join a group for the RADIO-DISH pattern. Call only on ZMQ_DISH. - Returns 0 if OK, -1 if failed. - - - - - - Leave a group for the RADIO-DISH pattern. Call only on ZMQ_DISH. - Returns 0 if OK, -1 if failed. - - - - - - Probe the supplied object, and report if it looks like a zsock_t. - Takes a polymorphic socket reference. - - - - - - Probe the supplied reference. If it looks like a zsock_t instance, return - the underlying libzmq socket handle; else if it looks like a file - descriptor, return NULL; else if it looks like a libzmq socket handle, - return the supplied value. Takes a polymorphic socket reference. - - - - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zsock_option.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zsock_option.api deleted file mode 100644 index c5799b027e5bab..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zsock_option.api +++ /dev/null @@ -1,797 +0,0 @@ - - - - - - Get socket option `heartbeat_ivl`. - Available from libzmq 4.2.0. - - - - - Set socket option `heartbeat_ivl`. - Available from libzmq 4.2.0. - - - - - Get socket option `heartbeat_ttl`. - Available from libzmq 4.2.0. - - - - - Set socket option `heartbeat_ttl`. - Available from libzmq 4.2.0. - - - - - Get socket option `heartbeat_timeout`. - Available from libzmq 4.2.0. - - - - - Set socket option `heartbeat_timeout`. - Available from libzmq 4.2.0. - - - - - Get socket option `use_fd`. - Available from libzmq 4.2.0. - - - - - Set socket option `use_fd`. - Available from libzmq 4.2.0. - - - - - Set socket option `xpub_manual`. - Available from libzmq 4.2.0. - - - - - Set socket option `xpub_welcome_msg`. - Available from libzmq 4.2.0. - - - - - Set socket option `stream_notify`. - Available from libzmq 4.2.0. - - - - - Get socket option `invert_matching`. - Available from libzmq 4.2.0. - - - - - Set socket option `invert_matching`. - Available from libzmq 4.2.0. - - - - - Set socket option `xpub_verboser`. - Available from libzmq 4.2.0. - - - - - Get socket option `connect_timeout`. - Available from libzmq 4.2.0. - - - - - Set socket option `connect_timeout`. - Available from libzmq 4.2.0. - - - - - Get socket option `tcp_maxrt`. - Available from libzmq 4.2.0. - - - - - Set socket option `tcp_maxrt`. - Available from libzmq 4.2.0. - - - - - Get socket option `thread_safe`. - Available from libzmq 4.2.0. - - - - - Get socket option `multicast_maxtpdu`. - Available from libzmq 4.2.0. - - - - - Set socket option `multicast_maxtpdu`. - Available from libzmq 4.2.0. - - - - - Get socket option `vmci_buffer_size`. - Available from libzmq 4.2.0. - - - - - Set socket option `vmci_buffer_size`. - Available from libzmq 4.2.0. - - - - - Get socket option `vmci_buffer_min_size`. - Available from libzmq 4.2.0. - - - - - Set socket option `vmci_buffer_min_size`. - Available from libzmq 4.2.0. - - - - - Get socket option `vmci_buffer_max_size`. - Available from libzmq 4.2.0. - - - - - Set socket option `vmci_buffer_max_size`. - Available from libzmq 4.2.0. - - - - - Get socket option `vmci_connect_timeout`. - Available from libzmq 4.2.0. - - - - - Set socket option `vmci_connect_timeout`. - Available from libzmq 4.2.0. - - - - - - - Get socket option `tos`. - Available from libzmq 4.1.0. - - - - - Set socket option `tos`. - Available from libzmq 4.1.0. - - - - - Set socket option `router_handover`. - Available from libzmq 4.1.0. - - - - - Set socket option `connect_rid`. - Available from libzmq 4.1.0. - - - - - Set socket option `connect_rid` from 32-octet binary - Available from libzmq 4.1.0. - - - - - Get socket option `handshake_ivl`. - Available from libzmq 4.1.0. - - - - - Set socket option `handshake_ivl`. - Available from libzmq 4.1.0. - - - - - Get socket option `socks_proxy`. - Available from libzmq 4.1.0. - - - - - Set socket option `socks_proxy`. - Available from libzmq 4.1.0. - - - - - Set socket option `xpub_nodrop`. - Available from libzmq 4.1.0. - - - - - - - Set socket option `router_mandatory`. - Available from libzmq 4.0.0. - - - - - Set socket option `probe_router`. - Available from libzmq 4.0.0. - - - - - Set socket option `req_relaxed`. - Available from libzmq 4.0.0. - - - - - Set socket option `req_correlate`. - Available from libzmq 4.0.0. - - - - - Set socket option `conflate`. - Available from libzmq 4.0.0. - - - - - Get socket option `zap_domain`. - Available from libzmq 4.0.0. - - - - - Set socket option `zap_domain`. - Available from libzmq 4.0.0. - - - - - Get socket option `mechanism`. - Available from libzmq 4.0.0. - - - - - Get socket option `plain_server`. - Available from libzmq 4.0.0. - - - - - Set socket option `plain_server`. - Available from libzmq 4.0.0. - - - - - Get socket option `plain_username`. - Available from libzmq 4.0.0. - - - - - Set socket option `plain_username`. - Available from libzmq 4.0.0. - - - - - Get socket option `plain_password`. - Available from libzmq 4.0.0. - - - - - Set socket option `plain_password`. - Available from libzmq 4.0.0. - - - - - Get socket option `curve_server`. - Available from libzmq 4.0.0. - - - - - Set socket option `curve_server`. - Available from libzmq 4.0.0. - - - - - Get socket option `curve_publickey`. - Available from libzmq 4.0.0. - - - - - Set socket option `curve_publickey`. - Available from libzmq 4.0.0. - - - - - Set socket option `curve_publickey` from 32-octet binary - Available from libzmq 4.0.0. - - - - - Get socket option `curve_secretkey`. - Available from libzmq 4.0.0. - - - - - Set socket option `curve_secretkey`. - Available from libzmq 4.0.0. - - - - - Set socket option `curve_secretkey` from 32-octet binary - Available from libzmq 4.0.0. - - - - - Get socket option `curve_serverkey`. - Available from libzmq 4.0.0. - - - - - Set socket option `curve_serverkey`. - Available from libzmq 4.0.0. - - - - - Set socket option `curve_serverkey` from 32-octet binary - Available from libzmq 4.0.0. - - - - - Get socket option `gssapi_server`. - Available from libzmq 4.0.0. - - - - - Set socket option `gssapi_server`. - Available from libzmq 4.0.0. - - - - - Get socket option `gssapi_plaintext`. - Available from libzmq 4.0.0. - - - - - Set socket option `gssapi_plaintext`. - Available from libzmq 4.0.0. - - - - - Get socket option `gssapi_principal`. - Available from libzmq 4.0.0. - - - - - Set socket option `gssapi_principal`. - Available from libzmq 4.0.0. - - - - - Get socket option `gssapi_service_principal`. - Available from libzmq 4.0.0. - - - - - Set socket option `gssapi_service_principal`. - Available from libzmq 4.0.0. - - - - - Get socket option `ipv6`. - Available from libzmq 4.0.0. - - - - - Set socket option `ipv6`. - Available from libzmq 4.0.0. - - - - - Get socket option `immediate`. - Available from libzmq 4.0.0. - - - - - Set socket option `immediate`. - Available from libzmq 4.0.0. - - - - - - - Get socket option `type`. - Available from libzmq 3.0.0. - - - - - Get socket option `sndhwm`. - Available from libzmq 3.0.0. - - - - - Set socket option `sndhwm`. - Available from libzmq 3.0.0. - - - - - Get socket option `rcvhwm`. - Available from libzmq 3.0.0. - - - - - Set socket option `rcvhwm`. - Available from libzmq 3.0.0. - - - - - Get socket option `affinity`. - Available from libzmq 3.0.0. - - - - - Set socket option `affinity`. - Available from libzmq 3.0.0. - - - - - Set socket option `subscribe`. - Available from libzmq 3.0.0. - - - - - Set socket option `unsubscribe`. - Available from libzmq 3.0.0. - - - - - Get socket option `identity`. - Available from libzmq 3.0.0. - - - - - Set socket option `identity`. - Available from libzmq 3.0.0. - - - - - Get socket option `rate`. - Available from libzmq 3.0.0. - - - - - Set socket option `rate`. - Available from libzmq 3.0.0. - - - - - Get socket option `recovery_ivl`. - Available from libzmq 3.0.0. - - - - - Set socket option `recovery_ivl`. - Available from libzmq 3.0.0. - - - - - Get socket option `sndbuf`. - Available from libzmq 3.0.0. - - - - - Set socket option `sndbuf`. - Available from libzmq 3.0.0. - - - - - Get socket option `rcvbuf`. - Available from libzmq 3.0.0. - - - - - Set socket option `rcvbuf`. - Available from libzmq 3.0.0. - - - - - Get socket option `linger`. - Available from libzmq 3.0.0. - - - - - Set socket option `linger`. - Available from libzmq 3.0.0. - - - - - Get socket option `reconnect_ivl`. - Available from libzmq 3.0.0. - - - - - Set socket option `reconnect_ivl`. - Available from libzmq 3.0.0. - - - - - Get socket option `reconnect_ivl_max`. - Available from libzmq 3.0.0. - - - - - Set socket option `reconnect_ivl_max`. - Available from libzmq 3.0.0. - - - - - Get socket option `backlog`. - Available from libzmq 3.0.0. - - - - - Set socket option `backlog`. - Available from libzmq 3.0.0. - - - - - Get socket option `maxmsgsize`. - Available from libzmq 3.0.0. - - - - - Set socket option `maxmsgsize`. - Available from libzmq 3.0.0. - - - - - Get socket option `multicast_hops`. - Available from libzmq 3.0.0. - - - - - Set socket option `multicast_hops`. - Available from libzmq 3.0.0. - - - - - Get socket option `rcvtimeo`. - Available from libzmq 3.0.0. - - - - - Set socket option `rcvtimeo`. - Available from libzmq 3.0.0. - - - - - Get socket option `sndtimeo`. - Available from libzmq 3.0.0. - - - - - Set socket option `sndtimeo`. - Available from libzmq 3.0.0. - - - - - Set socket option `xpub_verbose`. - Available from libzmq 3.0.0. - - - - - Get socket option `tcp_keepalive`. - Available from libzmq 3.0.0. - - - - - Set socket option `tcp_keepalive`. - Available from libzmq 3.0.0. - - - - - Get socket option `tcp_keepalive_idle`. - Available from libzmq 3.0.0. - - - - - Set socket option `tcp_keepalive_idle`. - Available from libzmq 3.0.0. - - - - - Get socket option `tcp_keepalive_cnt`. - Available from libzmq 3.0.0. - - - - - Set socket option `tcp_keepalive_cnt`. - Available from libzmq 3.0.0. - - - - - Get socket option `tcp_keepalive_intvl`. - Available from libzmq 3.0.0. - - - - - Set socket option `tcp_keepalive_intvl`. - Available from libzmq 3.0.0. - - - - - Get socket option `tcp_accept_filter`. - Available from libzmq 3.0.0. - - - - - Set socket option `tcp_accept_filter`. - Available from libzmq 3.0.0. - - - - - Get socket option `rcvmore`. - Available from libzmq 3.0.0. - - - - - Get socket option `fd`. - Available from libzmq 3.0.0. - - - - - Get socket option `events`. - Available from libzmq 3.0.0. - - - - - Get socket option `last_endpoint`. - Available from libzmq 3.0.0. - - - - - Set socket option `router_raw`. - Available from libzmq 3.0.0. - - - - - Get socket option `ipv4only`. - Available from libzmq 3.0.0. - - - - - Set socket option `ipv4only`. - Available from libzmq 3.0.0. - - - - - Set socket option `delay_attach_on_connect`. - Available from libzmq 3.0.0. - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zstr.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zstr.api deleted file mode 100644 index b4c951e7207ab5..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zstr.api +++ /dev/null @@ -1,90 +0,0 @@ - - - sending and receiving strings - - - Receive C string from socket. Caller must free returned string using - zstr_free(). Returns NULL if the context is being terminated or the - process was interrupted. - - - - - - Receive a series of strings (until NULL) from multipart data. - Each string is allocated and filled with string data; if there - are not enough frames, unallocated strings are set to NULL. - Returns -1 if the message could not be read, else returns the - number of strings filled, zero or more. Free each returned string - using zstr_free(). If not enough strings are provided, remaining - multipart frames in the message are dropped. - - - - - - - Send a C string to a socket, as a frame. The string is sent without - trailing null byte; to read this you can use zstr_recv, or a similar - method that adds a null terminator on the received string. String - may be NULL, which is sent as "". - - - - - - - Send a C string to a socket, as zstr_send(), with a MORE flag, so that - you can send further strings in the same multi-part message. - - - - - - - Send a formatted string to a socket. Note that you should NOT use - user-supplied strings in the format (they may contain '%' which - will create security holes). - - - - - - - Send a formatted string to a socket, as for zstr_sendf(), with a - MORE flag, so that you can send further strings in the same multi-part - message. - - - - - - - Send a series of strings (until NULL) as multipart data - Returns 0 if the strings could be sent OK, or -1 on error. - - - - - - - Accepts a void pointer and returns a fresh character string. If source - is null, returns an empty string. - - - - - - Free a provided string, and nullify the parent pointer. Safe to call on - a null pointer. - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/ztimerset.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/ztimerset.api deleted file mode 100644 index 20d3ca71ad9065..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/ztimerset.api +++ /dev/null @@ -1,69 +0,0 @@ - - - timer set - - - Create new timer set. - - - - Destroy a timer set - - - - Callback function for timer event. - - - - - - Add a timer to the set. Returns timer id if OK, -1 on failure. - - - - - - - - Cancel a timer. Returns 0 if OK, -1 on failure. - - - - - - Set timer interval. Returns 0 if OK, -1 on failure. - This method is slow, canceling the timer and adding a new one yield better performance. - - - - - - - Reset timer to start interval counting from current time. Returns 0 if OK, -1 on failure. - This method is slow, canceling the timer and adding a new one yield better performance. - - - - - - Return the time until the next interval. - Should be used as timeout parameter for the zpoller wait method. - The timeout is in msec. - - - - - Invoke callback function of all timers which their interval has elapsed. - Should be call after zpoller wait method. - Returns 0 if OK, -1 on failure. - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/ztrie.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/ztrie.api deleted file mode 100644 index 01fc3a4131e6a8..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/ztrie.api +++ /dev/null @@ -1,80 +0,0 @@ - - - simple trie for tokenizable strings - - - Callback function for ztrie_node to destroy node data. - - - - - Creates a new ztrie. - - - - - Destroy the ztrie. - - - - Inserts a new route into the tree and attaches the data. Returns -1 - if the route already exists, otherwise 0. This method takes ownership of - the provided data if a destroy_data_fn is provided. - - - - - - - - Removes a route from the trie and destroys its data. Returns -1 if the - route does not exists, otherwise 0. - the start of the list call zlist_first (). Advances the cursor. - - - - - - Returns true if the path matches a route in the tree, otherwise false. - - - - - - Returns the data of a matched route from last ztrie_matches. If the path - did not match, returns NULL. Do not delete the data as it's owned by - ztrie. - - - - - Returns the count of parameters that a matched route has. - - - - - Returns the parameters of a matched route with named regexes from last - ztrie_matches. If the path did not match or the route did not contain any - named regexes, returns NULL. - - - - - Returns the asterisk matched part of a route, if there has been no match - or no asterisk match, returns NULL. - - - - - Print the trie - - - diff --git a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zuuid.api b/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zuuid.api deleted file mode 100644 index 1fdb9c4e060f9e..00000000000000 --- a/phonelibs/zmq/aarch64-linux/share/zproject/czmq/zuuid.api +++ /dev/null @@ -1,82 +0,0 @@ - - - UUID support class - - - Create a new UUID object. - - - - Destroy a specified UUID object. - - - - Create UUID object from supplied ZUUID_LEN-octet value. - - - - - Set UUID to new supplied ZUUID_LEN-octet value. - - - - - Set UUID to new supplied string value skipping '-' and '{' '}' - optional delimiters. Return 0 if OK, else returns -1. - - - - - - Return UUID binary data. - - - - - Return UUID binary size - - - - - Returns UUID as string - - - - - Return UUID in the canonical string format: 8-4-4-4-12, in lower - case. Caller does not modify or free returned value. See - http://en.wikipedia.org/wiki/Universally_unique_identifier - - - - - Store UUID blob in target array - - - - - Check if UUID is same as supplied value - - - - - - Check if UUID is different from supplied value - - - - - - Make copy of UUID object; if uuid is null, or memory was exhausted, - returns null. - - - diff --git a/phonelibs/zmq/aarch64/include/czmq.h b/phonelibs/zmq/aarch64/include/czmq.h deleted file mode 100644 index ba21aa3bd1efdd..00000000000000 --- a/phonelibs/zmq/aarch64/include/czmq.h +++ /dev/null @@ -1,31 +0,0 @@ -/* ========================================================================= - CZMQ - a high-level binding in C for ZeroMQ - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __CZMQ_H_INCLUDED__ -#define __CZMQ_H_INCLUDED__ - -// These are signatures for handler functions that customize the -// behavior of CZMQ containers. These are shared between all CZMQ -// container types. - -// -- destroy an item -typedef void (czmq_destructor) (void **item); -// -- duplicate an item -typedef void *(czmq_duplicator) (const void *item); -// - compare two items, for sorting -typedef int (czmq_comparator) (const void *item1, const void *item2); - -// Include the project library file -#include "czmq_library.h" - -#endif diff --git a/phonelibs/zmq/aarch64/include/czmq_library.h b/phonelibs/zmq/aarch64/include/czmq_library.h deleted file mode 100644 index be348db3e9a414..00000000000000 --- a/phonelibs/zmq/aarch64/include/czmq_library.h +++ /dev/null @@ -1,199 +0,0 @@ -/* ========================================================================= - czmq - generated layer of public API - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -################################################################################ -# THIS FILE IS 100% GENERATED BY ZPROJECT; DO NOT EDIT EXCEPT EXPERIMENTALLY # -# Read the zproject/README.md for information about making permanent changes. # -################################################################################ - ========================================================================= -*/ - -#ifndef CZMQ_LIBRARY_H_INCLUDED -#define CZMQ_LIBRARY_H_INCLUDED - -// Set up environment for the application -#include "czmq_prelude.h" - -// External dependencies -#include - -// CZMQ version macros for compile-time API detection -#define CZMQ_VERSION_MAJOR 3 -#define CZMQ_VERSION_MINOR 0 -#define CZMQ_VERSION_PATCH 3 - -#define CZMQ_MAKE_VERSION(major, minor, patch) \ - ((major) * 10000 + (minor) * 100 + (patch)) -#define CZMQ_VERSION \ - CZMQ_MAKE_VERSION(CZMQ_VERSION_MAJOR, CZMQ_VERSION_MINOR, CZMQ_VERSION_PATCH) - -#if defined (__WINDOWS__) -# if defined CZMQ_STATIC -# define CZMQ_EXPORT -# elif defined CZMQ_INTERNAL_BUILD -# if defined DLL_EXPORT -# define CZMQ_EXPORT __declspec(dllexport) -# else -# define CZMQ_EXPORT -# endif -# elif defined CZMQ_EXPORTS -# define CZMQ_EXPORT __declspec(dllexport) -# else -# define CZMQ_EXPORT __declspec(dllimport) -# endif -#else -# define CZMQ_EXPORT -#endif - -// Opaque class structures to allow forward references -// These classes are stable or legacy and built in all releases -typedef struct _zactor_t zactor_t; -#define ZACTOR_T_DEFINED -typedef struct _zarmour_t zarmour_t; -#define ZARMOUR_T_DEFINED -typedef struct _zcert_t zcert_t; -#define ZCERT_T_DEFINED -typedef struct _zcertstore_t zcertstore_t; -#define ZCERTSTORE_T_DEFINED -typedef struct _zchunk_t zchunk_t; -#define ZCHUNK_T_DEFINED -typedef struct _zclock_t zclock_t; -#define ZCLOCK_T_DEFINED -typedef struct _zconfig_t zconfig_t; -#define ZCONFIG_T_DEFINED -typedef struct _zdigest_t zdigest_t; -#define ZDIGEST_T_DEFINED -typedef struct _zdir_t zdir_t; -#define ZDIR_T_DEFINED -typedef struct _zdir_patch_t zdir_patch_t; -#define ZDIR_PATCH_T_DEFINED -typedef struct _zfile_t zfile_t; -#define ZFILE_T_DEFINED -typedef struct _zframe_t zframe_t; -#define ZFRAME_T_DEFINED -typedef struct _zhash_t zhash_t; -#define ZHASH_T_DEFINED -typedef struct _zhashx_t zhashx_t; -#define ZHASHX_T_DEFINED -typedef struct _ziflist_t ziflist_t; -#define ZIFLIST_T_DEFINED -typedef struct _zlist_t zlist_t; -#define ZLIST_T_DEFINED -typedef struct _zlistx_t zlistx_t; -#define ZLISTX_T_DEFINED -typedef struct _zloop_t zloop_t; -#define ZLOOP_T_DEFINED -typedef struct _zmsg_t zmsg_t; -#define ZMSG_T_DEFINED -typedef struct _zpoller_t zpoller_t; -#define ZPOLLER_T_DEFINED -typedef struct _zsock_t zsock_t; -#define ZSOCK_T_DEFINED -typedef struct _zstr_t zstr_t; -#define ZSTR_T_DEFINED -typedef struct _zuuid_t zuuid_t; -#define ZUUID_T_DEFINED -typedef struct _zauth_t zauth_t; -#define ZAUTH_T_DEFINED -typedef struct _zbeacon_t zbeacon_t; -#define ZBEACON_T_DEFINED -typedef struct _zgossip_t zgossip_t; -#define ZGOSSIP_T_DEFINED -typedef struct _zmonitor_t zmonitor_t; -#define ZMONITOR_T_DEFINED -typedef struct _zproxy_t zproxy_t; -#define ZPROXY_T_DEFINED -typedef struct _zrex_t zrex_t; -#define ZREX_T_DEFINED -typedef struct _zsys_t zsys_t; -#define ZSYS_T_DEFINED -typedef struct _zauth_v2_t zauth_v2_t; -#define ZAUTH_V2_T_DEFINED -typedef struct _zbeacon_v2_t zbeacon_v2_t; -#define ZBEACON_V2_T_DEFINED -typedef struct _zctx_t zctx_t; -#define ZCTX_T_DEFINED -typedef struct _zmonitor_v2_t zmonitor_v2_t; -#define ZMONITOR_V2_T_DEFINED -typedef struct _zmutex_t zmutex_t; -#define ZMUTEX_T_DEFINED -typedef struct _zproxy_v2_t zproxy_v2_t; -#define ZPROXY_V2_T_DEFINED -typedef struct _zsocket_t zsocket_t; -#define ZSOCKET_T_DEFINED -typedef struct _zsockopt_t zsockopt_t; -#define ZSOCKOPT_T_DEFINED -typedef struct _zthread_t zthread_t; -#define ZTHREAD_T_DEFINED -// Draft classes are by default not built in stable releases -#ifdef CZMQ_BUILD_DRAFT_API -typedef struct _zproc_t zproc_t; -#define ZPROC_T_DEFINED -typedef struct _ztimerset_t ztimerset_t; -#define ZTIMERSET_T_DEFINED -typedef struct _ztrie_t ztrie_t; -#define ZTRIE_T_DEFINED -#endif // CZMQ_BUILD_DRAFT_API - - -// Public classes, each with its own header file -#include "zactor.h" -#include "zarmour.h" -#include "zcert.h" -#include "zcertstore.h" -#include "zchunk.h" -#include "zclock.h" -#include "zconfig.h" -#include "zdigest.h" -#include "zdir.h" -#include "zdir_patch.h" -#include "zfile.h" -#include "zframe.h" -#include "zhash.h" -#include "zhashx.h" -#include "ziflist.h" -#include "zlist.h" -#include "zlistx.h" -#include "zloop.h" -#include "zmsg.h" -#include "zpoller.h" -#include "zsock.h" -#include "zstr.h" -#include "zuuid.h" -#include "zauth.h" -#include "zbeacon.h" -#include "zgossip.h" -#include "zmonitor.h" -#include "zproxy.h" -#include "zrex.h" -#include "zsys.h" -#include "zauth_v2.h" -#include "zbeacon_v2.h" -#include "zctx.h" -#include "zmonitor_v2.h" -#include "zmutex.h" -#include "zproxy_v2.h" -#include "zsocket.h" -#include "zsockopt.h" -#include "zthread.h" -#ifdef CZMQ_BUILD_DRAFT_API -#include "zproc.h" -#include "ztimerset.h" -#include "ztrie.h" -#endif // CZMQ_BUILD_DRAFT_API - -#endif -/* -################################################################################ -# THIS FILE IS 100% GENERATED BY ZPROJECT; DO NOT EDIT EXCEPT EXPERIMENTALLY # -# Read the zproject/README.md for information about making permanent changes. # -################################################################################ -*/ diff --git a/phonelibs/zmq/aarch64/include/czmq_prelude.h b/phonelibs/zmq/aarch64/include/czmq_prelude.h deleted file mode 100644 index e9ceb691e839ef..00000000000000 --- a/phonelibs/zmq/aarch64/include/czmq_prelude.h +++ /dev/null @@ -1,641 +0,0 @@ -/* ========================================================================= - czmq_prelude.h - CZMQ environment - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __CZMQ_PRELUDE_H_INCLUDED__ -#define __CZMQ_PRELUDE_H_INCLUDED__ - -//- Establish the compiler and computer system ------------------------------ -/* - * Defines zero or more of these symbols, for use in any non-portable - * code: - * - * __WINDOWS__ Microsoft C/C++ with Windows calls - * __MSDOS__ System is MS-DOS (set if __WINDOWS__ set) - * __VMS__ System is VAX/VMS or Alpha/OpenVMS - * __UNIX__ System is UNIX - * __OS2__ System is OS/2 - * - * __IS_32BIT__ OS/compiler is 32 bits - * __IS_64BIT__ OS/compiler is 64 bits - * - * When __UNIX__ is defined, we also define exactly one of these: - * - * __UTYPE_AUX Apple AUX - * __UTYPE_BEOS BeOS - * __UTYPE_BSDOS BSD/OS - * __UTYPE_DECALPHA Digital UNIX (Alpha) - * __UTYPE_IBMAIX IBM RS/6000 AIX - * __UTYPE_FREEBSD FreeBSD - * __UTYPE_HPUX HP/UX - * __UTYPE_ANDROID Android - * __UTYPE_LINUX Linux - * __UTYPE_GNU GNU/Hurd - * __UTYPE_MIPS MIPS (BSD 4.3/System V mixture) - * __UTYPE_NETBSD NetBSD - * __UTYPE_NEXT NeXT - * __UTYPE_OPENBSD OpenBSD - * __UTYPE_OSX Apple Macintosh OS X - * __UTYPE_IOS Apple iOS - * __UTYPE_QNX QNX - * __UTYPE_IRIX Silicon Graphics IRIX - * __UTYPE_SINIX SINIX-N (Siemens-Nixdorf Unix) - * __UTYPE_SUNOS SunOS - * __UTYPE_SUNSOLARIS Sun Solaris - * __UTYPE_UNIXWARE SCO UnixWare - * ... these are the ones I know about so far. - * __UTYPE_GENERIC Any other UNIX - * - * When __VMS__ is defined, we may define one or more of these: - * - * __VMS_XOPEN Supports XOPEN functions - */ - -#if (defined (__64BIT__) || defined (__x86_64__)) -# define __IS_64BIT__ // May have 64-bit OS/compiler -#else -# define __IS_32BIT__ // Else assume 32-bit OS/compiler -#endif - -#if (defined WIN32 || defined _WIN32) -# undef __WINDOWS__ -# define __WINDOWS__ -# undef __MSDOS__ -# define __MSDOS__ -#endif - -#if (defined WINDOWS || defined _WINDOWS || defined __WINDOWS__) -# undef __WINDOWS__ -# define __WINDOWS__ -# undef __MSDOS__ -# define __MSDOS__ -// Stop cheeky warnings about "deprecated" functions like fopen -# if _MSC_VER >= 1500 -# undef _CRT_SECURE_NO_DEPRECATE -# define _CRT_SECURE_NO_DEPRECATE -# pragma warning(disable: 4996) -# endif -#endif - -// MSDOS Microsoft C -// _MSC_VER Microsoft C -#if (defined (MSDOS) || defined (_MSC_VER)) -# undef __MSDOS__ -# define __MSDOS__ -# if (defined (_DEBUG) && !defined (DEBUG)) -# define DEBUG -# endif -#endif - -#if (defined (__EMX__) && defined (__i386__)) -# undef __OS2__ -# define __OS2__ -#endif - -// VMS VAX C (VAX/VMS) -// __VMS Dec C (Alpha/OpenVMS) -// __vax__ gcc -#if (defined (VMS) || defined (__VMS) || defined (__vax__)) -# undef __VMS__ -# define __VMS__ -# if (__VMS_VER >= 70000000) -# define __VMS_XOPEN -# endif -#endif - -// Try to define a __UTYPE_xxx symbol... -// unix SunOS at least -// __unix__ gcc -// _POSIX_SOURCE is various UNIX systems, maybe also VAX/VMS -#if (defined (unix) || defined (__unix__) || defined (_POSIX_SOURCE)) -# if (!defined (__VMS__)) -# undef __UNIX__ -# define __UNIX__ -# if (defined (__alpha)) // Digital UNIX is 64-bit -# undef __IS_32BIT__ -# define __IS_64BIT__ -# define __UTYPE_DECALPHA -# endif -# endif -#endif - -#if (defined (_AUX)) -# define __UTYPE_AUX -# define __UNIX__ -#elif (defined (__BEOS__)) -# define __UTYPE_BEOS -# define __UNIX__ -#elif (defined (__hpux)) -# define __UTYPE_HPUX -# define __UNIX__ -# define _INCLUDE_HPUX_SOURCE -# define _INCLUDE_XOPEN_SOURCE -# define _INCLUDE_POSIX_SOURCE -#elif (defined (_AIX) || defined (AIX)) -# define __UTYPE_IBMAIX -# define __UNIX__ -#elif (defined (BSD) || defined (bsd)) -# define __UTYPE_BSDOS -# define __UNIX__ -#elif (defined (__ANDROID__)) -# define __UTYPE_ANDROID -# define __UNIX__ -#elif (defined (LINUX) || defined (linux) || defined (__linux__)) -# define __UTYPE_LINUX -# define __UNIX__ -# ifndef __NO_CTYPE -# define __NO_CTYPE // Suppress warnings on tolower() -# endif -# ifndef _DEFAULT_SOURCE -# define _DEFAULT_SOURCE // Include stuff from 4.3 BSD Unix -# endif -#elif (defined (__GNU__)) -# define __UTYPE_GNU -# define __UNIX__ -#elif (defined (Mips)) -# define __UTYPE_MIPS -# define __UNIX__ -#elif (defined (FreeBSD) || defined (__FreeBSD__)) -# define __UTYPE_FREEBSD -# define __UNIX__ -#elif (defined (NetBSD) || defined (__NetBSD__)) -# define __UTYPE_NETBSD -# define __UNIX__ -#elif (defined (OpenBSD) || defined (__OpenBSD__)) -# define __UTYPE_OPENBSD -# define __UNIX__ -#elif (defined (APPLE) || defined (__APPLE__)) -# include -# define __UNIX__ -# if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR -# define __UTYPE_IOS -# else -# define __UTYPE_OSX -# endif -#elif (defined (NeXT)) -# define __UTYPE_NEXT -# define __UNIX__ -#elif (defined (__QNX__)) -# define __UTYPE_QNX -# define __UNIX__ -#elif (defined (sgi)) -# define __UTYPE_IRIX -# define __UNIX__ -#elif (defined (sinix)) -# define __UTYPE_SINIX -# define __UNIX__ -#elif (defined (SOLARIS) || defined (__SRV4)) -# define __UTYPE_SUNSOLARIS -# define __UNIX__ -#elif (defined (SUNOS) || defined (SUN) || defined (sun)) -# define __UTYPE_SUNOS -# define __UNIX__ -#elif (defined (__USLC__) || defined (UnixWare)) -# define __UTYPE_UNIXWARE -# define __UNIX__ -#elif (defined (__CYGWIN__)) -# define __UTYPE_CYGWIN -# define __UNIX__ -#elif (defined (__UNIX__)) -# define __UTYPE_GENERIC -#endif - -//- Always include ZeroMQ headers ------------------------------------------- - -#include "zmq.h" -#if (ZMQ_VERSION < ZMQ_MAKE_VERSION (4, 2, 0)) -# include "zmq_utils.h" -#endif - -//- Standard ANSI include files --------------------------------------------- - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//- System-specific include files ------------------------------------------- - -#if (defined (__MSDOS__)) -# if (defined (__WINDOWS__)) -# if (_WIN32_WINNT < 0x0501) -# undef _WIN32_WINNT -# define _WIN32_WINNT 0x0501 -# endif -# if (!defined (FD_SETSIZE)) -# define FD_SETSIZE 1024 // Max. filehandles/sockets -# endif -# include -# include -# include -# include -# include // For getnameinfo () -# include // For GetAdaptersAddresses () -# endif -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#if (defined (__UNIX__)) -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include // Let CZMQ build with libzmq/3.x -# include // Must come before arpa/inet.h -# if (!defined (__UTYPE_ANDROID)) && (!defined (__UTYPE_IBMAIX)) \ - && (!defined (__UTYPE_HPUX)) -# include -# endif -# if defined (__UTYPE_SUNSOLARIS) || defined (__UTYPE_SUNOS) -# include -# endif -# if (!defined (__UTYPE_BEOS)) -# include -# if (!defined (TCP_NODELAY)) -# include -# endif -# endif -# if (defined (__UTYPE_IBMAIX) || defined(__UTYPE_QNX)) -# include -# endif -# if (defined (__UTYPE_BEOS)) -# include -# endif -# if ((defined (_XOPEN_REALTIME) && (_XOPEN_REALTIME >= 1)) \ - || (defined (_POSIX_VERSION) && (_POSIX_VERSION >= 199309L))) -# include -# endif -# if (defined (__UTYPE_OSX) || defined (__UTYPE_IOS)) -# include -# include // For monotonic clocks -# endif -# if (defined (__UTYPE_OSX)) -# include // For _NSGetEnviron() -# endif -# if (defined (__UTYPE_ANDROID)) -# include -# endif -# if (defined (__UTYPE_LINUX) && defined (HAVE_LIBSYSTEMD)) -# include -# endif -#endif - -#if (defined (__VMS__)) -# if (!defined (vaxc)) -# include // Not provided by Vax C -# endif -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#if (defined (__OS2__)) -# include // Required near top -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include // Must come before arpa/inet.h -# include -# include -# if (!defined (TCP_NODELAY)) -# include -# endif -#endif - -// Add missing defines for non-POSIX systems -#ifndef S_IRUSR -# define S_IRUSR S_IREAD -#endif -#ifndef S_IWUSR -# define S_IWUSR S_IWRITE -#endif -#ifndef S_ISDIR -# define S_ISDIR(m) (((m) & S_IFDIR) != 0) -#endif -#ifndef S_ISREG -# define S_ISREG(m) (((m) & S_IFREG) != 0) -#endif - - -//- Check compiler data type sizes ------------------------------------------ - -#if (UCHAR_MAX != 0xFF) -# error "Cannot compile: must change definition of 'byte'." -#endif -#if (USHRT_MAX != 0xFFFFU) -# error "Cannot compile: must change definition of 'dbyte'." -#endif -#if (UINT_MAX != 0xFFFFFFFFU) -# error "Cannot compile: must change definition of 'qbyte'." -#endif - -//- Data types -------------------------------------------------------------- - -typedef unsigned char byte; // Single unsigned byte = 8 bits -typedef unsigned short dbyte; // Double byte = 16 bits -typedef unsigned int qbyte; // Quad byte = 32 bits -typedef struct sockaddr_in inaddr_t; // Internet socket address structure -typedef struct sockaddr_in6 in6addr_t; // Internet 6 socket address structure - -// Common structure to hold inaddr_t and in6addr_t with length -typedef struct { - union { - inaddr_t __addr; // IPv4 address - in6addr_t __addr6; // IPv6 address - } __inaddr_u; -#define ipv4addr __inaddr_u.__addr -#define ipv6addr __inaddr_u.__addr6 - int inaddrlen; -} inaddr_storage_t; - -//- Inevitable macros ------------------------------------------------------- - -#define streq(s1,s2) (!strcmp ((s1), (s2))) -#define strneq(s1,s2) (strcmp ((s1), (s2))) - -// Provide random number from 0..(num-1) -#if (defined (__WINDOWS__)) || (defined (__UTYPE_IBMAIX)) \ - || (defined (__UTYPE_HPUX)) || (defined (__UTYPE_SUNOS)) -# define randof(num) (int) ((float) (num) * rand () / (RAND_MAX + 1.0)) -#else -# define randof(num) (int) ((float) (num) * random () / (RAND_MAX + 1.0)) -#endif - -// Windows MSVS doesn't have stdbool -#if (defined (_MSC_VER)) -# if (!defined (__cplusplus) && (!defined (true))) -# define true 1 -# define false 0 - typedef char bool; -# endif -#else -# include -#endif - -//- A number of POSIX and C99 keywords and data types ----------------------- -// CZMQ uses uint for array indices; equivalent to unsigned int, but more -// convenient in code. We define it in czmq_prelude.h on systems that do -// not define it by default. - -#if (defined (__WINDOWS__)) -# if (!defined (__cplusplus) && (!defined (inline))) -# define inline __inline -# endif -# define strtoull _strtoui64 -# define atoll _atoi64 -# define srandom srand -# define TIMEZONE _timezone -# if (!defined (__MINGW32__)) -# define snprintf _snprintf -# define vsnprintf _vsnprintf -# endif - typedef unsigned long ulong; - typedef unsigned int uint; -# if (!defined (__MINGW32__)) - typedef int mode_t; -# if !defined (_SSIZE_T_DEFINED) -typedef intptr_t ssize_t; -# define _SSIZE_T_DEFINED -# endif -# endif -# if ((!defined (__MINGW32__) \ - || (defined (__MINGW32__) && defined (__IS_64BIT__))) \ - && !defined (ZMQ_DEFINED_STDINT)) - typedef __int8 int8_t; - typedef __int16 int16_t; - typedef __int32 int32_t; - typedef __int64 int64_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; - typedef unsigned __int64 uint64_t; -# endif - typedef uint32_t in_addr_t; -# if (!defined (PRId8)) -# define PRId8 "d" -# endif -# if (!defined (PRId16)) -# define PRId16 "d" -# endif -# if (!defined (PRId32)) -# define PRId32 "d" -# endif -# if (!defined (PRId64)) -# define PRId64 "I64d" -# endif -# if (!defined (PRIu8)) -# define PRIu8 "u" -# endif -# if (!defined (PRIu16)) -# define PRIu16 "u" -# endif -# if (!defined (PRIu32)) -# define PRIu32 "u" -# endif -# if (!defined (PRIu64)) -# define PRIu64 "I64u" -# endif -# if (!defined (va_copy)) - // MSVC does not support C99's va_copy so we use a regular assignment -# define va_copy(dest,src) (dest) = (src) -# endif -#elif (defined (__UTYPE_OSX)) - typedef unsigned long ulong; - typedef unsigned int uint; - // This fixes header-order dependence problem with some Linux versions -#elif (defined (__UTYPE_LINUX)) -# if (__STDC_VERSION__ >= 199901L && !defined (__USE_MISC)) - typedef unsigned int uint; -# endif -#endif - -//- Non-portable declaration specifiers ------------------------------------- - -// For thread-local storage -#if defined (__WINDOWS__) -# define CZMQ_THREADLS __declspec(thread) -#else -# define CZMQ_THREADLS __thread -#endif - -// Replacement for malloc() which asserts if we run out of heap, and -// which zeroes the allocated block. -static inline void * -safe_malloc (size_t size, const char *file, unsigned line) -{ -// printf ("%s:%u %08d\n", file, line, (int) size); - void *mem = calloc (1, size); - if (mem == NULL) { - fprintf (stderr, "FATAL ERROR at %s:%u\n", file, line); - fprintf (stderr, "OUT OF MEMORY (malloc returned NULL)\n"); - fflush (stderr); - abort (); - } - return mem; -} - -// Define _ZMALLOC_DEBUG if you need to trace memory leaks using e.g. mtrace, -// otherwise all allocations will claim to come from czmq_prelude.h. For best -// results, compile all classes so you see dangling object allocations. -// _ZMALLOC_PEDANTIC does the same thing, but its intention is to propagate -// out of memory condition back up the call stack. -#if defined _ZMALLOC_DEBUG || _ZMALLOC_PEDANTIC -# define zmalloc(size) calloc(1,(size)) -#else -# define zmalloc(size) safe_malloc((size), __FILE__, __LINE__) -#endif - -// GCC supports validating format strings for functions that act like printf -#if defined (__GNUC__) && (__GNUC__ >= 2) -# define CHECK_PRINTF(a) __attribute__((format (printf, a, a + 1))) -#else -# define CHECK_PRINTF(a) -#endif - -// Lets us write code that compiles both on Windows and normal platforms -#if !defined (__WINDOWS__) -typedef int SOCKET; -# define closesocket close -# define INVALID_SOCKET -1 -# define SOCKET_ERROR -1 -# define O_BINARY 0 -#endif - -//- Include non-portable header files based on platform.h ------------------- - -#if defined (HAVE_LINUX_WIRELESS_H) -# include -// This would normally come from net/if.h -unsigned int if_nametoindex (const char *ifname); -#else -# if defined (HAVE_NET_IF_H) -# include -# endif -# if defined (HAVE_NET_IF_MEDIA_H) -# include -# endif -#endif - -#if defined (__WINDOWS__) && !defined (HAVE_UUID) -# define HAVE_UUID 1 -#endif -#if defined (__UTYPE_OSX) && !defined (HAVE_UUID) -# define HAVE_UUID 1 -#endif -#if defined (HAVE_UUID) -# if defined (__UTYPE_FREEBSD) || defined (__UTYPE_NETBSD) -# include -# elif defined __UTYPE_HPUX -# include -# elif defined (__UNIX__) -# include -# endif -#endif - -// ZMQ compatibility macros - -#if ZMQ_VERSION_MAJOR == 4 -# define ZMQ_POLL_MSEC 1 // zmq_poll is msec - -#elif ZMQ_VERSION_MAJOR == 3 -# define ZMQ_POLL_MSEC 1 // zmq_poll is msec -# if ZMQ_VERSION_MINOR < 2 -# define zmq_ctx_new zmq_init -# endif -# define zmq_ctx_term zmq_term - -#elif ZMQ_VERSION_MAJOR == 2 -# define ZMQ_POLL_MSEC 1000 // zmq_poll is usec -# define zmq_sendmsg zmq_send // Smooth out 2.x changes -# define zmq_recvmsg zmq_recv -# define zmq_ctx_new zmq_init -# define zmq_ctx_term zmq_term -# define zmq_msg_send(m,s,f) zmq_sendmsg ((s),(m),(f)) -# define zmq_msg_recv(m,s,f) zmq_recvmsg ((s),(m),(f)) - // Older libzmq APIs may be missing some aspects of libzmq v3.0 -# ifndef ZMQ_ROUTER -# define ZMQ_ROUTER ZMQ_XREP -# endif -# ifndef ZMQ_DEALER -# define ZMQ_DEALER ZMQ_XREQ -# endif -# ifndef ZMQ_DONTWAIT -# define ZMQ_DONTWAIT ZMQ_NOBLOCK -# endif -# ifndef ZMQ_XSUB -# error "please upgrade your libzmq from http://zeromq.org" -# endif -# if ZMQ_VERSION_MINOR == 0 \ - || (ZMQ_VERSION_MINOR == 1 && ZMQ_VERSION_PATCH < 7) -# error "CZMQ requires at least libzmq/2.1.7 stable" -# endif -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zactor.h b/phonelibs/zmq/aarch64/include/zactor.h deleted file mode 100644 index c865c65daf1efa..00000000000000 --- a/phonelibs/zmq/aarch64/include/zactor.h +++ /dev/null @@ -1,76 +0,0 @@ -/* ========================================================================= - zactor - actor - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZACTOR_H_INCLUDED__ -#define __ZACTOR_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zactor.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Actors get a pipe and arguments from caller -typedef void (zactor_fn) ( - zsock_t *pipe, void *args); - -// Create a new actor passing arbitrary arguments reference. -CZMQ_EXPORT zactor_t * - zactor_new (zactor_fn task, void *args); - -// Destroy an actor. -CZMQ_EXPORT void - zactor_destroy (zactor_t **self_p); - -// Send a zmsg message to the actor, take ownership of the message -// and destroy when it has been sent. -CZMQ_EXPORT int - zactor_send (zactor_t *self, zmsg_t **msg_p); - -// Receive a zmsg message from the actor. Returns NULL if the actor -// was interrupted before the message could be received, or if there -// was a timeout on the actor. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zmsg_t * - zactor_recv (zactor_t *self); - -// Probe the supplied object, and report if it looks like a zactor_t. -CZMQ_EXPORT bool - zactor_is (void *self); - -// Probe the supplied reference. If it looks like a zactor_t instance, -// return the underlying libzmq actor handle; else if it looks like -// a libzmq actor handle, return the supplied value. -CZMQ_EXPORT void * - zactor_resolve (void *self); - -// Return the actor's zsock handle. Use this when you absolutely need -// to work with the zsock instance rather than the actor. -CZMQ_EXPORT zsock_t * - zactor_sock (zactor_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zactor_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zarmour.h b/phonelibs/zmq/aarch64/include/zarmour.h deleted file mode 100644 index c7f299f7afe989..00000000000000 --- a/phonelibs/zmq/aarch64/include/zarmour.h +++ /dev/null @@ -1,114 +0,0 @@ -/* ========================================================================= - zarmour - armoured text encoding and decoding - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZARMOUR_H_INCLUDED__ -#define __ZARMOUR_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zarmour.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -#define ZARMOUR_MODE_BASE64_STD 0 // Standard base 64 -#define ZARMOUR_MODE_BASE64_URL 1 // URL and filename friendly base 64 -#define ZARMOUR_MODE_BASE32_STD 2 // Standard base 32 -#define ZARMOUR_MODE_BASE32_HEX 3 // Extended hex base 32 -#define ZARMOUR_MODE_BASE16 4 // Standard base 16 -#define ZARMOUR_MODE_Z85 5 // Z85 from ZeroMQ RFC 32 - -// Create a new zarmour -CZMQ_EXPORT zarmour_t * - zarmour_new (void); - -// Destroy the zarmour -CZMQ_EXPORT void - zarmour_destroy (zarmour_t **self_p); - -// Encode a stream of bytes into an armoured string. Returns the armoured -// string, or NULL if there was insufficient memory available to allocate -// a new string. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zarmour_encode (zarmour_t *self, const byte *data, size_t size); - -// Decode an armoured string into a chunk. The decoded output is -// null-terminated, so it may be treated as a string, if that's what -// it was prior to encoding. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zchunk_t * - zarmour_decode (zarmour_t *self, const char *data); - -// Get the mode property. -CZMQ_EXPORT int - zarmour_mode (zarmour_t *self); - -// Get printable string for mode. -CZMQ_EXPORT const char * - zarmour_mode_str (zarmour_t *self); - -// Set the mode property. -CZMQ_EXPORT void - zarmour_set_mode (zarmour_t *self, int mode); - -// Return true if padding is turned on. -CZMQ_EXPORT bool - zarmour_pad (zarmour_t *self); - -// Turn padding on or off. Default is on. -CZMQ_EXPORT void - zarmour_set_pad (zarmour_t *self, bool pad); - -// Get the padding character. -CZMQ_EXPORT char - zarmour_pad_char (zarmour_t *self); - -// Set the padding character. -CZMQ_EXPORT void - zarmour_set_pad_char (zarmour_t *self, char pad_char); - -// Return if splitting output into lines is turned on. Default is off. -CZMQ_EXPORT bool - zarmour_line_breaks (zarmour_t *self); - -// Turn splitting output into lines on or off. -CZMQ_EXPORT void - zarmour_set_line_breaks (zarmour_t *self, bool line_breaks); - -// Get the line length used for splitting lines. -CZMQ_EXPORT size_t - zarmour_line_length (zarmour_t *self); - -// Set the line length used for splitting lines. -CZMQ_EXPORT void - zarmour_set_line_length (zarmour_t *self, size_t line_length); - -// Print properties of object -CZMQ_EXPORT void - zarmour_print (zarmour_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zarmour_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zauth.h b/phonelibs/zmq/aarch64/include/zauth.h deleted file mode 100644 index ca6bb913c8f5aa..00000000000000 --- a/phonelibs/zmq/aarch64/include/zauth.h +++ /dev/null @@ -1,100 +0,0 @@ -/* ========================================================================= - zauth - authentication for ZeroMQ security mechanisms - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZAUTH_H_INCLUDED__ -#define __ZAUTH_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -#define CURVE_ALLOW_ANY "*" - -// CZMQ v3 API (for use with zsock, not zsocket, which is deprecated). -// -// Create new zauth actor instance. This installs authentication on all -// zsock sockets. Until you add policies, all incoming NULL connections are -// allowed (classic ZeroMQ behaviour), and all PLAIN and CURVE connections -// are denied: -// -// zactor_t *auth = zactor_new (zauth, NULL); -// -// Destroy zauth instance. This removes authentication and allows all -// connections to pass, without authentication: -// -// zactor_destroy (&auth); -// -// Note that all zauth commands are synchronous, so your application always -// waits for a signal from the actor after each command. -// -// Enable verbose logging of commands and activity. Verbose logging can help -// debug non-trivial authentication policies: -// -// zstr_send (auth, "VERBOSE"); -// zsock_wait (auth); -// -// Allow (whitelist) a list of IP addresses. For NULL, all clients from -// these addresses will be accepted. For PLAIN and CURVE, they will be -// allowed to continue with authentication. You can call this method -// multiple times to whitelist more IP addresses. If you whitelist one -// or nmore addresses, any non-whitelisted addresses are treated as -// blacklisted: -// -// zstr_sendx (auth, "ALLOW", "127.0.0.1", "127.0.0.2", NULL); -// zsock_wait (auth); -// -// Deny (blacklist) a list of IP addresses. For all security mechanisms, -// this rejects the connection without any further authentication. Use -// either a whitelist, or a blacklist, not not both. If you define both -// a whitelist and a blacklist, only the whitelist takes effect: -// -// zstr_sendx (auth, "DENY", "192.168.0.1", "192.168.0.2", NULL); -// zsock_wait (auth); -// -// Configure PLAIN authentication using a plain-text password file. You can -// modify the password file at any time; zauth will reload it automatically -// if modified externally: -// -// zstr_sendx (auth, "PLAIN", filename, NULL); -// zsock_wait (auth); -// -// Configure CURVE authentication, using a directory that holds all public -// client certificates, i.e. their public keys. The certificates must be in -// zcert_save format. You can add and remove certificates in that directory -// at any time. To allow all client keys without checking, specify -// CURVE_ALLOW_ANY for the directory name: -// -// zstr_sendx (auth, "CURVE", directory, NULL); -// zsock_wait (auth); -// -// Configure GSSAPI authentication, using an underlying mechanism (usually -// Kerberos) to establish a secure context and perform mutual authentication: -// -// zstr_sendx (auth, "GSSAPI", NULL); -// zsock_wait (auth); -// -// This is the zauth constructor as a zactor_fn: -CZMQ_EXPORT void - zauth (zsock_t *pipe, void *certstore); - -// Selftest -CZMQ_EXPORT void - zauth_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zauth_v2.h b/phonelibs/zmq/aarch64/include/zauth_v2.h deleted file mode 100644 index bbbee86b03e62d..00000000000000 --- a/phonelibs/zmq/aarch64/include/zauth_v2.h +++ /dev/null @@ -1,88 +0,0 @@ -/* ========================================================================= - zauth_v2 - authentication for ZeroMQ servers (deprecated) - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZAUTH_V2_H_INCLUDED__ -#define __ZAUTH_V2_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -#ifndef CURVE_ALLOW_ANY -# define CURVE_ALLOW_ANY "*" -#endif - -// Constructor -// Install authentication for the specified context. Returns a new zauth -// object that you can use to configure authentication. Note that until you -// add policies, all incoming NULL connections are allowed (classic ZeroMQ -// behaviour), and all PLAIN and CURVE connections are denied. If there was -// an error during initialization, returns NULL. -CZMQ_EXPORT zauth_t * - zauth_new (zctx_t *ctx); - -// Destructor -CZMQ_EXPORT void - zauth_destroy (zauth_t **self_p); - -// Allow (whitelist) a single IP address. For NULL, all clients from this -// address will be accepted. For PLAIN and CURVE, they will be allowed to -// continue with authentication. You can call this method multiple times -// to whitelist multiple IP addresses. If you whitelist a single address, -// any non-whitelisted addresses are treated as blacklisted. -CZMQ_EXPORT void - zauth_allow (zauth_t *self, const char *address); - -// Deny (blacklist) a single IP address. For all security mechanisms, this -// rejects the connection without any further authentication. Use either a -// whitelist, or a blacklist, not not both. If you define both a whitelist -// and a blacklist, only the whitelist takes effect. -CZMQ_EXPORT void - zauth_deny (zauth_t *self, const char *address); - -// Configure PLAIN authentication for a given domain. PLAIN authentication -// uses a plain-text password file. To cover all domains, use "*". You can -// modify the password file at any time; it is reloaded automatically. -CZMQ_EXPORT void - zauth_configure_plain (zauth_t *self, const char *domain, const char *filename); - -// Configure CURVE authentication for a given domain. CURVE authentication -// uses a directory that holds all public client certificates, i.e. their -// public keys. The certificates must be in zcert_save () format. To cover -// all domains, use "*". You can add and remove certificates in that -// directory at any time. To allow all client keys without checking, specify -// CURVE_ALLOW_ANY for the location. -CZMQ_EXPORT void - zauth_configure_curve (zauth_t *self, const char *domain, const char *location); - -// Configure GSSAPI authentication for a given domain. GSSAPI authentication -// uses an underlying mechanism (usually Kerberos) to establish a secure -// context and perform mutual authentication. To cover all domains, use "*". -CZMQ_EXPORT void - zauth_configure_gssapi (zauth_t *self, char *domain); - -// Enable verbose tracing of commands and activity -CZMQ_EXPORT void - zauth_set_verbose (zauth_t *self, bool verbose); - -// Selftest -CZMQ_EXPORT void - zauth_v2_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zbeacon.h b/phonelibs/zmq/aarch64/include/zbeacon.h deleted file mode 100644 index 78917e9577e40f..00000000000000 --- a/phonelibs/zmq/aarch64/include/zbeacon.h +++ /dev/null @@ -1,86 +0,0 @@ -/* ========================================================================= - zbeacon - LAN discovery and presence - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZBEACON_H_INCLUDED__ -#define __ZBEACON_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// Create new zbeacon actor instance: -// -// zactor_t *beacon = zactor_new (zbeacon, NULL); -// -// Destroy zbeacon instance: -// -// zactor_destroy (&beacon); -// -// Enable verbose logging of commands and activity: -// -// zstr_send (beacon, "VERBOSE"); -// -// Configure beacon to run on specified UDP port, and return the name of -// the host, which can be used as endpoint for incoming connections. To -// force the beacon to operate on a given interface, set the environment -// variable ZSYS_INTERFACE, or call zsys_set_interface() before creating -// the beacon. If the system does not support UDP broadcasts (lacking a -// workable interface), returns an empty hostname: -// -// // Pictures: 's' = C string, 'i' = int -// zsock_send (beacon, "si", "CONFIGURE", port_number); -// char *hostname = zstr_recv (beacon); -// -// Start broadcasting a beacon at a specified interval in msec. The beacon -// data can be at most UDP_FRAME_MAX bytes; this constant is defined in -// zsys.h to be 255: -// -// // Pictures: 'b' = byte * data + size_t size -// zsock_send (beacon, "sbi", "PUBLISH", data, size, interval); -// -// Stop broadcasting the beacon: -// -// zstr_sendx (beacon, "SILENCE", NULL); -// -// Start listening to beacons from peers. The filter is used to do a prefix -// match on received beacons, to remove junk. Note that any received data -// that is identical to our broadcast beacon_data is discarded in any case. -// If the filter size is zero, we get all peer beacons: -// -// zsock_send (beacon, "sb", "SUBSCRIBE", filter_data, filter_size); -// -// Stop listening to other peers -// -// zstr_sendx (beacon, "UNSUBSCRIBE", NULL); -// -// Receive next beacon from a peer. Received beacons are always a 2-frame -// message containing the ipaddress of the sender, and then the binary -// beacon data as published by the sender: -// -// zmsg_t *msg = zmsg_recv (beacon); -// -// This is the zbeacon constructor as a zactor_fn: -CZMQ_EXPORT void - zbeacon (zsock_t *pipe, void *unused); - -// Self test of this class -CZMQ_EXPORT void - zbeacon_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zbeacon_v2.h b/phonelibs/zmq/aarch64/include/zbeacon_v2.h deleted file mode 100644 index 8e8f3b4cde9967..00000000000000 --- a/phonelibs/zmq/aarch64/include/zbeacon_v2.h +++ /dev/null @@ -1,75 +0,0 @@ -/* ========================================================================= - zbeacon - LAN discovery and presence (deprecated) - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZBEACON_V2_H_INCLUDED__ -#define __ZBEACON_V2_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// Create a new beacon on a certain UDP port. If the system does not -// support UDP broadcasts (lacking a useful interface), returns NULL. -// To force the beacon to operate on a given port, set the environment -// variable ZSYS_INTERFACE, or call zsys_set_interface() beforehand. -// If you are using the new zsock API then pass NULL as the ctx here. -CZMQ_EXPORT zbeacon_t * - zbeacon_new (zctx_t *ctx, int port_nbr); - -// Destroy a beacon -CZMQ_EXPORT void - zbeacon_destroy (zbeacon_t **self_p); - -// Return our own IP address as printable string -CZMQ_EXPORT char * - zbeacon_hostname (zbeacon_t *self); - -// Set broadcast interval in milliseconds (default is 1000 msec) -CZMQ_EXPORT void - zbeacon_set_interval (zbeacon_t *self, int interval); - -// Filter out any beacon that looks exactly like ours -CZMQ_EXPORT void - zbeacon_noecho (zbeacon_t *self); - -// Start broadcasting beacon to peers at the specified interval -CZMQ_EXPORT void - zbeacon_publish (zbeacon_t *self, byte *transmit, size_t size); - -// Stop broadcasting beacons -CZMQ_EXPORT void - zbeacon_silence (zbeacon_t *self); - -// Start listening to other peers; zero-sized filter means get everything -CZMQ_EXPORT void - zbeacon_subscribe (zbeacon_t *self, byte *filter, size_t size); - -// Stop listening to other peers -CZMQ_EXPORT void - zbeacon_unsubscribe (zbeacon_t *self); - -// Get beacon ZeroMQ socket, for polling or receiving messages -CZMQ_EXPORT void * - zbeacon_socket (zbeacon_t *self); - -// Self test of this class -CZMQ_EXPORT void - zbeacon_v2_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zcert.h b/phonelibs/zmq/aarch64/include/zcert.h deleted file mode 100644 index 495b579cda9317..00000000000000 --- a/phonelibs/zmq/aarch64/include/zcert.h +++ /dev/null @@ -1,139 +0,0 @@ -/* ========================================================================= - zcert - work with CURVE security certificates - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZCERT_H_INCLUDED__ -#define __ZCERT_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zcert.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// This class has legacy methods, which will be removed over time. You -// should not use them, and migrate any code that is still using them. -// Create and initialize a new certificate in memory -CZMQ_EXPORT zcert_t * - zcert_new (void); - -// Accepts public/secret key pair from caller -CZMQ_EXPORT zcert_t * - zcert_new_from (const byte *public_key, const byte *secret_key); - -// Load certificate from file -CZMQ_EXPORT zcert_t * - zcert_load (const char *filename); - -// Destroy a certificate in memory -CZMQ_EXPORT void - zcert_destroy (zcert_t **self_p); - -// Return public part of key pair as 32-byte binary string -CZMQ_EXPORT const byte * - zcert_public_key (zcert_t *self); - -// Return secret part of key pair as 32-byte binary string -CZMQ_EXPORT const byte * - zcert_secret_key (zcert_t *self); - -// Return public part of key pair as Z85 armored string -CZMQ_EXPORT const char * - zcert_public_txt (zcert_t *self); - -// Return secret part of key pair as Z85 armored string -CZMQ_EXPORT const char * - zcert_secret_txt (zcert_t *self); - -// Set certificate metadata from formatted string. -CZMQ_EXPORT void - zcert_set_meta (zcert_t *self, const char *name, const char *format, ...); - -// Get metadata value from certificate; if the metadata value doesn't -// exist, returns NULL. -CZMQ_EXPORT const char * - zcert_meta (zcert_t *self, const char *name); - -// Get list of metadata fields from certificate. Caller is responsible for -// destroying list. Caller should not modify the values of list items. -CZMQ_EXPORT zlist_t * - zcert_meta_keys (zcert_t *self); - -// Save full certificate (public + secret) to file for persistent storage -// This creates one public file and one secret file (filename + "_secret"). -CZMQ_EXPORT int - zcert_save (zcert_t *self, const char *filename); - -// Save public certificate only to file for persistent storage -CZMQ_EXPORT int - zcert_save_public (zcert_t *self, const char *filename); - -// Save secret certificate only to file for persistent storage -CZMQ_EXPORT int - zcert_save_secret (zcert_t *self, const char *filename); - -// Apply certificate to socket, i.e. use for CURVE security on socket. -// If certificate was loaded from public file, the secret key will be -// undefined, and this certificate will not work successfully. -CZMQ_EXPORT void - zcert_apply (zcert_t *self, void *socket); - -// Return copy of certificate; if certificate is NULL or we exhausted -// heap memory, returns NULL. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zcert_t * - zcert_dup (zcert_t *self); - -// Return true if two certificates have the same keys -CZMQ_EXPORT bool - zcert_eq (zcert_t *self, zcert_t *compare); - -// Print certificate contents to stdout -CZMQ_EXPORT void - zcert_print (zcert_t *self); - -// *** Deprecated method, slated for removal: avoid using it *** -// Print certificate contents to open stream. This method is deprecated -// and you should use the print method. -CZMQ_EXPORT void - zcert_fprint (zcert_t *self, FILE *file); - -// Self test of this class -CZMQ_EXPORT void - zcert_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Unset certificate metadata. -CZMQ_EXPORT void - zcert_unset_meta (zcert_t *self, const char *name); - -#endif // CZMQ_BUILD_DRAFT_API -// @ignore -CZMQ_EXPORT void - zcert_set_meta (zcert_t *self, const char *name, const char *format, ...) CHECK_PRINTF (3); -// @end - - -#ifdef __cplusplus -} -#endif - -// Deprecated method aliases -#define zcert_dump(s) zcert_print(s) - -#endif diff --git a/phonelibs/zmq/aarch64/include/zcertstore.h b/phonelibs/zmq/aarch64/include/zcertstore.h deleted file mode 100644 index c7f93c5a7d4604..00000000000000 --- a/phonelibs/zmq/aarch64/include/zcertstore.h +++ /dev/null @@ -1,100 +0,0 @@ -/* ========================================================================= - zcertstore - work with CURVE security certificate stores - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZCERTSTORE_H_INCLUDED__ -#define __ZCERTSTORE_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zcertstore.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// This class has legacy methods, which will be removed over time. You -// should not use them, and migrate any code that is still using them. -// Create a new certificate store from a disk directory, loading and -// indexing all certificates in that location. The directory itself may be -// absent, and created later, or modified at any time. The certificate store -// is automatically refreshed on any zcertstore_lookup() call. If the -// location is specified as NULL, creates a pure-memory store, which you -// can work with by inserting certificates at runtime. -CZMQ_EXPORT zcertstore_t * - zcertstore_new (const char *location); - -// Destroy a certificate store object in memory. Does not affect anything -// stored on disk. -CZMQ_EXPORT void - zcertstore_destroy (zcertstore_t **self_p); - -// Look up certificate by public key, returns zcert_t object if found, -// else returns NULL. The public key is provided in Z85 text format. -CZMQ_EXPORT zcert_t * - zcertstore_lookup (zcertstore_t *self, const char *public_key); - -// Insert certificate into certificate store in memory. Note that this -// does not save the certificate to disk. To do that, use zcert_save() -// directly on the certificate. Takes ownership of zcert_t object. -CZMQ_EXPORT void - zcertstore_insert (zcertstore_t *self, zcert_t **cert_p); - -// Print list of certificates in store to logging facility -CZMQ_EXPORT void - zcertstore_print (zcertstore_t *self); - -// *** Deprecated method, slated for removal: avoid using it *** -// Print list of certificates in store to open stream. This method is -// deprecated, and you should use the print method. -CZMQ_EXPORT void - zcertstore_fprint (zcertstore_t *self, FILE *file); - -// Self test of this class -CZMQ_EXPORT void - zcertstore_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// Loaders retrieve certificates from an arbitrary source. -typedef void (zcertstore_loader) ( - zcertstore_t *self); - -// Destructor for loader state. -typedef void (zcertstore_destructor) ( - void **self_p); - -// *** Draft method, for development use, may change without warning *** -// Override the default disk loader with a custom loader fn. -CZMQ_EXPORT void - zcertstore_set_loader (zcertstore_t *self, zcertstore_loader loader, zcertstore_destructor destructor, void *state); - -// *** Draft method, for development use, may change without warning *** -// Empty certificate hashtable. This wrapper exists to be friendly to bindings, -// which don't usually have access to struct internals. -CZMQ_EXPORT void - zcertstore_empty (zcertstore_t *self); - -#endif // CZMQ_BUILD_DRAFT_API -// @end - - -#ifdef __cplusplus -} -#endif - -// Deprecated method aliases -#define zcertstore_dump(s) zcertstore_print(s) - -#endif diff --git a/phonelibs/zmq/aarch64/include/zchunk.h b/phonelibs/zmq/aarch64/include/zchunk.h deleted file mode 100644 index 56f29b161a37e5..00000000000000 --- a/phonelibs/zmq/aarch64/include/zchunk.h +++ /dev/null @@ -1,163 +0,0 @@ -/* ========================================================================= - zchunk - work with memory chunks - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZCHUNK_H_INCLUDED__ -#define __ZCHUNK_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zchunk.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Create a new chunk of the specified size. If you specify the data, it -// is copied into the chunk. If you do not specify the data, the chunk is -// allocated and left empty, and you can then add data using zchunk_append. -CZMQ_EXPORT zchunk_t * - zchunk_new (const void *data, size_t size); - -// Destroy a chunk -CZMQ_EXPORT void - zchunk_destroy (zchunk_t **self_p); - -// Resizes chunk max_size as requested; chunk_cur size is set to zero -CZMQ_EXPORT void - zchunk_resize (zchunk_t *self, size_t size); - -// Return chunk cur size -CZMQ_EXPORT size_t - zchunk_size (zchunk_t *self); - -// Return chunk max size -CZMQ_EXPORT size_t - zchunk_max_size (zchunk_t *self); - -// Return chunk data -CZMQ_EXPORT byte * - zchunk_data (zchunk_t *self); - -// Set chunk data from user-supplied data; truncate if too large. Data may -// be null. Returns actual size of chunk -CZMQ_EXPORT size_t - zchunk_set (zchunk_t *self, const void *data, size_t size); - -// Fill chunk data from user-supplied octet -CZMQ_EXPORT size_t - zchunk_fill (zchunk_t *self, byte filler, size_t size); - -// Append user-supplied data to chunk, return resulting chunk size. If the -// data would exceeded the available space, it is truncated. If you want to -// grow the chunk to accommodate new data, use the zchunk_extend method. -CZMQ_EXPORT size_t - zchunk_append (zchunk_t *self, const void *data, size_t size); - -// Append user-supplied data to chunk, return resulting chunk size. If the -// data would exceeded the available space, the chunk grows in size. -CZMQ_EXPORT size_t - zchunk_extend (zchunk_t *self, const void *data, size_t size); - -// Copy as much data from 'source' into the chunk as possible; returns the -// new size of chunk. If all data from 'source' is used, returns exhausted -// on the source chunk. Source can be consumed as many times as needed until -// it is exhausted. If source was already exhausted, does not change chunk. -CZMQ_EXPORT size_t - zchunk_consume (zchunk_t *self, zchunk_t *source); - -// Returns true if the chunk was exhausted by consume methods, or if the -// chunk has a size of zero. -CZMQ_EXPORT bool - zchunk_exhausted (zchunk_t *self); - -// Read chunk from an open file descriptor -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zchunk_t * - zchunk_read (FILE *handle, size_t bytes); - -// Write chunk to an open file descriptor -CZMQ_EXPORT int - zchunk_write (zchunk_t *self, FILE *handle); - -// Try to slurp an entire file into a chunk. Will read up to maxsize of -// the file. If maxsize is 0, will attempt to read the entire file and -// fail with an assertion if that cannot fit into memory. Returns a new -// chunk containing the file data, or NULL if the file could not be read. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zchunk_t * - zchunk_slurp (const char *filename, size_t maxsize); - -// Create copy of chunk, as new chunk object. Returns a fresh zchunk_t -// object, or null if there was not enough heap memory. If chunk is null, -// returns null. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zchunk_t * - zchunk_dup (zchunk_t *self); - -// Return chunk data encoded as printable hex string. Caller must free -// string when finished with it. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zchunk_strhex (zchunk_t *self); - -// Return chunk data copied into freshly allocated string -// Caller must free string when finished with it. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zchunk_strdup (zchunk_t *self); - -// Return TRUE if chunk body is equal to string, excluding terminator -CZMQ_EXPORT bool - zchunk_streq (zchunk_t *self, const char *string); - -// Transform zchunk into a zframe that can be sent in a message. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zframe_t * - zchunk_pack (zchunk_t *self); - -// Transform a zframe into a zchunk. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zchunk_t * - zchunk_unpack (zframe_t *frame); - -// Calculate SHA1 digest for chunk, using zdigest class. -CZMQ_EXPORT const char * - zchunk_digest (zchunk_t *self); - -// Dump chunk to FILE stream, for debugging and tracing. -CZMQ_EXPORT void - zchunk_fprint (zchunk_t *self, FILE *file); - -// Dump message to stderr, for debugging and tracing. -// See zchunk_fprint for details -CZMQ_EXPORT void - zchunk_print (zchunk_t *self); - -// Probe the supplied object, and report if it looks like a zchunk_t. -CZMQ_EXPORT bool - zchunk_is (void *self); - -// Self test of this class. -CZMQ_EXPORT void - zchunk_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/phonelibs/zmq/aarch64/include/zclock.h b/phonelibs/zmq/aarch64/include/zclock.h deleted file mode 100644 index eb064162c4722a..00000000000000 --- a/phonelibs/zmq/aarch64/include/zclock.h +++ /dev/null @@ -1,73 +0,0 @@ -/* ========================================================================= - zclock - millisecond clocks and delays - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZCLOCK_H_INCLUDED__ -#define __ZCLOCK_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zclock.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Sleep for a number of milliseconds -CZMQ_EXPORT void - zclock_sleep (int msecs); - -// Return current system clock as milliseconds. Note that this clock can -// jump backwards (if the system clock is changed) so is unsafe to use for -// timers and time offsets. Use zclock_mono for that instead. -CZMQ_EXPORT int64_t - zclock_time (void); - -// Return current monotonic clock in milliseconds. Use this when you compute -// time offsets. The monotonic clock is not affected by system changes and -// so will never be reset backwards, unlike a system clock. -CZMQ_EXPORT int64_t - zclock_mono (void); - -// Return current monotonic clock in microseconds. Use this when you compute -// time offsets. The monotonic clock is not affected by system changes and -// so will never be reset backwards, unlike a system clock. -CZMQ_EXPORT int64_t - zclock_usecs (void); - -// Return formatted date/time as fresh string. Free using zstr_free(). -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zclock_timestr (void); - -// Self test of this class. -CZMQ_EXPORT void - zclock_test (bool verbose); - -// @end - - -// DEPRECATED in favor of zsys logging, see issue #519 -// Print formatted string to stdout, prefixed by date/time and -// terminated with a newline. -CZMQ_EXPORT void - zclock_log (const char *format, ...); - -// Compiler hints -CZMQ_EXPORT void zclock_log (const char *format, ...) CHECK_PRINTF (1); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zconfig.h b/phonelibs/zmq/aarch64/include/zconfig.h deleted file mode 100644 index 4ec4e1c81f03e1..00000000000000 --- a/phonelibs/zmq/aarch64/include/zconfig.h +++ /dev/null @@ -1,194 +0,0 @@ -/* ========================================================================= - zconfig - work with config files written in rfc.zeromq.org/spec:4/ZPL. - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZCONFIG_H_INCLUDED__ -#define __ZCONFIG_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zconfig.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// -typedef int (zconfig_fct) ( - zconfig_t *self, void *arg, int level); - -// Create new config item -CZMQ_EXPORT zconfig_t * - zconfig_new (const char *name, zconfig_t *parent); - -// Load a config tree from a specified ZPL text file; returns a zconfig_t -// reference for the root, if the file exists and is readable. Returns NULL -// if the file does not exist. -CZMQ_EXPORT zconfig_t * - zconfig_load (const char *filename); - -// Equivalent to zconfig_load, taking a format string instead of a fixed -// filename. -CZMQ_EXPORT zconfig_t * - zconfig_loadf (const char *format, ...); - -// Destroy a config item and all its children -CZMQ_EXPORT void - zconfig_destroy (zconfig_t **self_p); - -// Return name of config item -CZMQ_EXPORT char * - zconfig_name (zconfig_t *self); - -// Return value of config item -CZMQ_EXPORT char * - zconfig_value (zconfig_t *self); - -// Insert or update configuration key with value -CZMQ_EXPORT void - zconfig_put (zconfig_t *self, const char *path, const char *value); - -// Equivalent to zconfig_put, accepting a format specifier and variable -// argument list, instead of a single string value. -CZMQ_EXPORT void - zconfig_putf (zconfig_t *self, const char *path, const char *format, ...); - -// Get value for config item into a string value; leading slash is optional -// and ignored. -CZMQ_EXPORT char * - zconfig_get (zconfig_t *self, const char *path, const char *default_value); - -// Set config item name, name may be NULL -CZMQ_EXPORT void - zconfig_set_name (zconfig_t *self, const char *name); - -// Set new value for config item. The new value may be a string, a printf -// format, or NULL. Note that if string may possibly contain '%', or if it -// comes from an insecure source, you must use '%s' as the format, followed -// by the string. -CZMQ_EXPORT void - zconfig_set_value (zconfig_t *self, const char *format, ...); - -// Find our first child, if any -CZMQ_EXPORT zconfig_t * - zconfig_child (zconfig_t *self); - -// Find our first sibling, if any -CZMQ_EXPORT zconfig_t * - zconfig_next (zconfig_t *self); - -// Find a config item along a path; leading slash is optional and ignored. -CZMQ_EXPORT zconfig_t * - zconfig_locate (zconfig_t *self, const char *path); - -// Locate the last config item at a specified depth -CZMQ_EXPORT zconfig_t * - zconfig_at_depth (zconfig_t *self, int level); - -// Execute a callback for each config item in the tree; returns zero if -// successful, else -1. -CZMQ_EXPORT int - zconfig_execute (zconfig_t *self, zconfig_fct handler, void *arg); - -// Add comment to config item before saving to disk. You can add as many -// comment lines as you like. If you use a null format, all comments are -// deleted. -CZMQ_EXPORT void - zconfig_set_comment (zconfig_t *self, const char *format, ...); - -// Return comments of config item, as zlist. -CZMQ_EXPORT zlist_t * - zconfig_comments (zconfig_t *self); - -// Save a config tree to a specified ZPL text file, where a filename -// "-" means dump to standard output. -CZMQ_EXPORT int - zconfig_save (zconfig_t *self, const char *filename); - -// Equivalent to zconfig_save, taking a format string instead of a fixed -// filename. -CZMQ_EXPORT int - zconfig_savef (zconfig_t *self, const char *format, ...); - -// Report filename used during zconfig_load, or NULL if none -CZMQ_EXPORT const char * - zconfig_filename (zconfig_t *self); - -// Reload config tree from same file that it was previously loaded from. -// Returns 0 if OK, -1 if there was an error (and then does not change -// existing data). -CZMQ_EXPORT int - zconfig_reload (zconfig_t **self_p); - -// Load a config tree from a memory chunk -CZMQ_EXPORT zconfig_t * - zconfig_chunk_load (zchunk_t *chunk); - -// Save a config tree to a new memory chunk -CZMQ_EXPORT zchunk_t * - zconfig_chunk_save (zconfig_t *self); - -// Load a config tree from a null-terminated string -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zconfig_t * - zconfig_str_load (const char *string); - -// Save a config tree to a new null terminated string -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zconfig_str_save (zconfig_t *self); - -// Return true if a configuration tree was loaded from a file and that -// file has changed in since the tree was loaded. -CZMQ_EXPORT bool - zconfig_has_changed (zconfig_t *self); - -// Print the config file to open stream -CZMQ_EXPORT void - zconfig_fprint (zconfig_t *self, FILE *file); - -// Print properties of object -CZMQ_EXPORT void - zconfig_print (zconfig_t *self); - -// Self test of this class -CZMQ_EXPORT void - zconfig_test (bool verbose); - -// @ignore -CZMQ_EXPORT void - zconfig_putf (zconfig_t *self, const char *path, const char *format, ...) CHECK_PRINTF (3); -CZMQ_EXPORT void - zconfig_set_value (zconfig_t *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT void - zconfig_set_comment (zconfig_t *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int - zconfig_savef (zconfig_t *self, const char *format, ...) CHECK_PRINTF (2); -// @end - -// Self test of this class -CZMQ_EXPORT void - zconfig_test (bool verbose); - -// Compiler hints -CZMQ_EXPORT void zconfig_set_value (zconfig_t *self, const char *format, ...) CHECK_PRINTF (2); - -#ifdef __cplusplus -} -#endif - -// Deprecated method aliases -#define zconfig_dump(s) zconfig_print(s) -#define zconfig_resolve(s,p,d) zconfig_get((s),(p),(d)) - -#endif diff --git a/phonelibs/zmq/aarch64/include/zctx.h b/phonelibs/zmq/aarch64/include/zctx.h deleted file mode 100644 index 88898410dc8e99..00000000000000 --- a/phonelibs/zmq/aarch64/include/zctx.h +++ /dev/null @@ -1,107 +0,0 @@ -/* ========================================================================= - zctx - working with 0MQ contexts - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZCTX_H_INCLUDED__ -#define __ZCTX_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - - -// @interface -// Create new context, returns context object, replaces zmq_init -CZMQ_EXPORT zctx_t * - zctx_new (void); - -// Destroy context and all sockets in it, replaces zmq_term -CZMQ_EXPORT void - zctx_destroy (zctx_t **self_p); - -// Create new shadow context, returns context object -CZMQ_EXPORT zctx_t * - zctx_shadow (zctx_t *self); -// @end - -// Create a new context by shadowing a plain zmq context -CZMQ_EXPORT zctx_t * -zctx_shadow_zmq_ctx (void *zmqctx); - -// @interface -// Raise default I/O threads from 1, for crazy heavy applications -// The rule of thumb is one I/O thread per gigabyte of traffic in -// or out. Call this method before creating any sockets on the context, -// or calling zctx_shadow, or the setting will have no effect. -CZMQ_EXPORT void - zctx_set_iothreads (zctx_t *self, int iothreads); - -// Set msecs to flush sockets when closing them, see the ZMQ_LINGER -// man page section for more details. By default, set to zero, so -// any in-transit messages are discarded when you destroy a socket or -// a context. -CZMQ_EXPORT void - zctx_set_linger (zctx_t *self, int linger); - -// Set initial high-water mark for inter-thread pipe sockets. Note that -// this setting is separate from the default for normal sockets. You -// should change the default for pipe sockets *with care*. Too low values -// will cause blocked threads, and an infinite setting can cause memory -// exhaustion. The default, no matter the underlying ZeroMQ version, is -// 1,000. -CZMQ_EXPORT void - zctx_set_pipehwm (zctx_t *self, int pipehwm); - -// Set initial send HWM for all new normal sockets created in context. -// You can set this per-socket after the socket is created. -// The default, no matter the underlying ZeroMQ version, is 1,000. -CZMQ_EXPORT void - zctx_set_sndhwm (zctx_t *self, int sndhwm); - -// Set initial receive HWM for all new normal sockets created in context. -// You can set this per-socket after the socket is created. -// The default, no matter the underlying ZeroMQ version, is 1,000. -CZMQ_EXPORT void - zctx_set_rcvhwm (zctx_t *self, int rcvhwm); - -// Return low-level 0MQ context object, will be NULL before first socket -// is created. Use with care. -CZMQ_EXPORT void * - zctx_underlying (zctx_t *self); - -// Self test of this class -CZMQ_EXPORT void - zctx_test (bool verbose); -// @end - -// Create socket within this context, for CZMQ use only -void * - zctx__socket_new (zctx_t *self, int type); - -// Create pipe socket within this context, for CZMQ use only -void * - zctx__socket_pipe (zctx_t *self); - -// Destroy socket within this context, for CZMQ use only -void - zctx__socket_destroy (zctx_t *self, void *socket); - -// Initialize the low-level 0MQ context object, for CZMQ use only -void - zctx__initialize_underlying(zctx_t *self); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zdigest.h b/phonelibs/zmq/aarch64/include/zdigest.h deleted file mode 100644 index def9e860537094..00000000000000 --- a/phonelibs/zmq/aarch64/include/zdigest.h +++ /dev/null @@ -1,65 +0,0 @@ -/* ========================================================================= - zdigest - provides hashing functions (SHA-1 at present) - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZDIGEST_H_INCLUDED__ -#define __ZDIGEST_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zdigest.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Constructor - creates new digest object, which you use to build up a -// digest by repeatedly calling zdigest_update() on chunks of data. -CZMQ_EXPORT zdigest_t * - zdigest_new (void); - -// Destroy a digest object -CZMQ_EXPORT void - zdigest_destroy (zdigest_t **self_p); - -// Add buffer into digest calculation -CZMQ_EXPORT void - zdigest_update (zdigest_t *self, const byte *buffer, size_t length); - -// Return final digest hash data. If built without crypto support, -// returns NULL. -CZMQ_EXPORT const byte * - zdigest_data (zdigest_t *self); - -// Return final digest hash size -CZMQ_EXPORT size_t - zdigest_size (zdigest_t *self); - -// Return digest as printable hex string; caller should not modify nor -// free this string. After calling this, you may not use zdigest_update() -// on the same digest. If built without crypto support, returns NULL. -CZMQ_EXPORT char * - zdigest_string (zdigest_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zdigest_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zdir.h b/phonelibs/zmq/aarch64/include/zdir.h deleted file mode 100644 index 6c5551b57eead4..00000000000000 --- a/phonelibs/zmq/aarch64/include/zdir.h +++ /dev/null @@ -1,149 +0,0 @@ -/* ========================================================================= - zdir - work with file-system directories - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZDIR_H_INCLUDED__ -#define __ZDIR_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zdir.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Create a new directory item that loads in the full tree of the specified -// path, optionally located under some parent path. If parent is "-", then -// loads only the top-level directory, and does not use parent as a path. -CZMQ_EXPORT zdir_t * - zdir_new (const char *path, const char *parent); - -// Destroy a directory tree and all children it contains. -CZMQ_EXPORT void - zdir_destroy (zdir_t **self_p); - -// Return directory path -CZMQ_EXPORT const char * - zdir_path (zdir_t *self); - -// Return last modification time for directory. -CZMQ_EXPORT time_t - zdir_modified (zdir_t *self); - -// Return total hierarchy size, in bytes of data contained in all files -// in the directory tree. -CZMQ_EXPORT off_t - zdir_cursize (zdir_t *self); - -// Return directory count -CZMQ_EXPORT size_t - zdir_count (zdir_t *self); - -// Returns a sorted list of zfile objects; Each entry in the list is a pointer -// to a zfile_t item already allocated in the zdir tree. Do not destroy the -// original zdir tree until you are done with this list. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zlist_t * - zdir_list (zdir_t *self); - -// Remove directory, optionally including all files that it contains, at -// all levels. If force is false, will only remove the directory if empty. -// If force is true, will remove all files and all subdirectories. -CZMQ_EXPORT void - zdir_remove (zdir_t *self, bool force); - -// Calculate differences between two versions of a directory tree. -// Returns a list of zdir_patch_t patches. Either older or newer may -// be null, indicating the directory is empty/absent. If alias is set, -// generates virtual filename (minus path, plus alias). -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zlist_t * - zdir_diff (zdir_t *older, zdir_t *newer, const char *alias); - -// Return full contents of directory as a zdir_patch list. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zlist_t * - zdir_resync (zdir_t *self, const char *alias); - -// Load directory cache; returns a hash table containing the SHA-1 digests -// of every file in the tree. The cache is saved between runs in .cache. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zhash_t * - zdir_cache (zdir_t *self); - -// Print contents of directory to open stream -CZMQ_EXPORT void - zdir_fprint (zdir_t *self, FILE *file, int indent); - -// Print contents of directory to stdout -CZMQ_EXPORT void - zdir_print (zdir_t *self, int indent); - -// Create a new zdir_watch actor instance: -// -// zactor_t *watch = zactor_new (zdir_watch, NULL); -// -// Destroy zdir_watch instance: -// -// zactor_destroy (&watch); -// -// Enable verbose logging of commands and activity: -// -// zstr_send (watch, "VERBOSE"); -// -// Subscribe to changes to a directory path: -// -// zsock_send (watch, "ss", "SUBSCRIBE", "directory_path"); -// -// Unsubscribe from changes to a directory path: -// -// zsock_send (watch, "ss", "UNSUBSCRIBE", "directory_path"); -// -// Receive directory changes: -// zsock_recv (watch, "sp", &path, &patches); -// -// // Delete the received data. -// free (path); -// zlist_destroy (&patches); -CZMQ_EXPORT void - zdir_watch (zsock_t *pipe, void *unused); - -// Self test of this class. -CZMQ_EXPORT void - zdir_test (bool verbose); - -// @end - - -// Returns a sorted array of zfile objects; returns a single block of memory, -// that you destroy by calling zstr_free(). Each entry in the array is a pointer -// to a zfile_t item already allocated in the zdir tree. The array ends with -// a null pointer. Do not destroy the original zdir tree until you are done -// with this array. -CZMQ_EXPORT zfile_t ** - zdir_flatten (zdir_t *self); - -// Free a provided string, and nullify the parent pointer. Safe to call on -// a null pointer. -CZMQ_EXPORT void - zdir_flatten_free (zfile_t ***files_p); - -#ifdef __cplusplus -} -#endif - -// Deprecated method aliases -#define zdir_dump(s,i) zdir_print(s,i) - -#endif diff --git a/phonelibs/zmq/aarch64/include/zdir_patch.h b/phonelibs/zmq/aarch64/include/zdir_patch.h deleted file mode 100644 index 8d15b9aeb40c42..00000000000000 --- a/phonelibs/zmq/aarch64/include/zdir_patch.h +++ /dev/null @@ -1,82 +0,0 @@ -/* ========================================================================= - zdir_patch - work with directory patches - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZDIR_PATCH_H_INCLUDED__ -#define __ZDIR_PATCH_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// un-namespaced enumeration values -#define patch_create ZDIR_PATCH_CREATE -#define patch_delete ZDIR_PATCH_DELETE - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zdir_patch.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -#define ZDIR_PATCH_CREATE 1 // Creates a new file -#define ZDIR_PATCH_DELETE 2 // Delete a file - -// Create new patch -CZMQ_EXPORT zdir_patch_t * - zdir_patch_new (const char *path, zfile_t *file, int op, const char *alias); - -// Destroy a patch -CZMQ_EXPORT void - zdir_patch_destroy (zdir_patch_t **self_p); - -// Create copy of a patch. If the patch is null, or memory was exhausted, -// returns null. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zdir_patch_t * - zdir_patch_dup (zdir_patch_t *self); - -// Return patch file directory path -CZMQ_EXPORT const char * - zdir_patch_path (zdir_patch_t *self); - -// Return patch file item -CZMQ_EXPORT zfile_t * - zdir_patch_file (zdir_patch_t *self); - -// Return operation -CZMQ_EXPORT int - zdir_patch_op (zdir_patch_t *self); - -// Return patch virtual file path -CZMQ_EXPORT const char * - zdir_patch_vpath (zdir_patch_t *self); - -// Calculate hash digest for file (create only) -CZMQ_EXPORT void - zdir_patch_digest_set (zdir_patch_t *self); - -// Return hash digest for patch file -CZMQ_EXPORT const char * - zdir_patch_digest (zdir_patch_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zdir_patch_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zfile.h b/phonelibs/zmq/aarch64/include/zfile.h deleted file mode 100644 index 75c35774b97fd1..00000000000000 --- a/phonelibs/zmq/aarch64/include/zfile.h +++ /dev/null @@ -1,177 +0,0 @@ -/* ========================================================================= - zfile - helper functions for working with files. - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZFILE_H_INCLUDED__ -#define __ZFILE_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zfile.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// If file exists, populates properties. CZMQ supports portable symbolic -// links, which are files with the extension ".ln". A symbolic link is a -// text file containing one line, the filename of a target file. Reading -// data from the symbolic link actually reads from the target file. Path -// may be NULL, in which case it is not used. -CZMQ_EXPORT zfile_t * - zfile_new (const char *path, const char *name); - -// Destroy a file item -CZMQ_EXPORT void - zfile_destroy (zfile_t **self_p); - -// Duplicate a file item, returns a newly constructed item. If the file -// is null, or memory was exhausted, returns null. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zfile_t * - zfile_dup (zfile_t *self); - -// Return file name, remove path if provided -CZMQ_EXPORT const char * - zfile_filename (zfile_t *self, const char *path); - -// Refresh file properties from disk; this is not done automatically -// on access methods, otherwise it is not possible to compare directory -// snapshots. -CZMQ_EXPORT void - zfile_restat (zfile_t *self); - -// Return when the file was last modified. If you want this to reflect the -// current situation, call zfile_restat before checking this property. -CZMQ_EXPORT time_t - zfile_modified (zfile_t *self); - -// Return the last-known size of the file. If you want this to reflect the -// current situation, call zfile_restat before checking this property. -CZMQ_EXPORT off_t - zfile_cursize (zfile_t *self); - -// Return true if the file is a directory. If you want this to reflect -// any external changes, call zfile_restat before checking this property. -CZMQ_EXPORT bool - zfile_is_directory (zfile_t *self); - -// Return true if the file is a regular file. If you want this to reflect -// any external changes, call zfile_restat before checking this property. -CZMQ_EXPORT bool - zfile_is_regular (zfile_t *self); - -// Return true if the file is readable by this process. If you want this to -// reflect any external changes, call zfile_restat before checking this -// property. -CZMQ_EXPORT bool - zfile_is_readable (zfile_t *self); - -// Return true if the file is writeable by this process. If you want this -// to reflect any external changes, call zfile_restat before checking this -// property. -CZMQ_EXPORT bool - zfile_is_writeable (zfile_t *self); - -// Check if file has stopped changing and can be safely processed. -// Updates the file statistics from disk at every call. -CZMQ_EXPORT bool - zfile_is_stable (zfile_t *self); - -// Return true if the file was changed on disk since the zfile_t object -// was created, or the last zfile_restat() call made on it. -CZMQ_EXPORT bool - zfile_has_changed (zfile_t *self); - -// Remove the file from disk -CZMQ_EXPORT void - zfile_remove (zfile_t *self); - -// Open file for reading -// Returns 0 if OK, -1 if not found or not accessible -CZMQ_EXPORT int - zfile_input (zfile_t *self); - -// Open file for writing, creating directory if needed -// File is created if necessary; chunks can be written to file at any -// location. Returns 0 if OK, -1 if error. -CZMQ_EXPORT int - zfile_output (zfile_t *self); - -// Read chunk from file at specified position. If this was the last chunk, -// sets the eof property. Returns a null chunk in case of error. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zchunk_t * - zfile_read (zfile_t *self, size_t bytes, off_t offset); - -// Returns true if zfile_read() just read the last chunk in the file. -CZMQ_EXPORT bool - zfile_eof (zfile_t *self); - -// Write chunk to file at specified position -// Return 0 if OK, else -1 -CZMQ_EXPORT int - zfile_write (zfile_t *self, zchunk_t *chunk, off_t offset); - -// Read next line of text from file. Returns a pointer to the text line, -// or NULL if there was nothing more to read from the file. -CZMQ_EXPORT const char * - zfile_readln (zfile_t *self); - -// Close file, if open -CZMQ_EXPORT void - zfile_close (zfile_t *self); - -// Return file handle, if opened -CZMQ_EXPORT FILE * - zfile_handle (zfile_t *self); - -// Calculate SHA1 digest for file, using zdigest class. -CZMQ_EXPORT const char * - zfile_digest (zfile_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zfile_test (bool verbose); - -// @end - - -// @interface -// These methods are deprecated, and now moved to zsys class. -CZMQ_EXPORT bool - zfile_exists (const char *filename); -CZMQ_EXPORT ssize_t - zfile_size (const char *filename); -CZMQ_EXPORT mode_t - zfile_mode (const char *filename); -CZMQ_EXPORT int - zfile_delete (const char *filename); -CZMQ_EXPORT bool - zfile_stable (const char *filename); -CZMQ_EXPORT int - zfile_mkdir (const char *pathname); -CZMQ_EXPORT int - zfile_rmdir (const char *pathname); -CZMQ_EXPORT void - zfile_mode_private (void); -CZMQ_EXPORT void - zfile_mode_default (void); -// @end - -#ifdef __cplusplus -} -#endif - - -#endif // __ZFILE_H_INCLUDED__ diff --git a/phonelibs/zmq/aarch64/include/zframe.h b/phonelibs/zmq/aarch64/include/zframe.h deleted file mode 100644 index 728093c36ce117..00000000000000 --- a/phonelibs/zmq/aarch64/include/zframe.h +++ /dev/null @@ -1,176 +0,0 @@ -/* ========================================================================= - zframe - working with single message frames - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZFRAME_H_INCLUDED__ -#define __ZFRAME_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zframe.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -#define ZFRAME_MORE 1 // -#define ZFRAME_REUSE 2 // -#define ZFRAME_DONTWAIT 4 // - -// Create a new frame. If size is not null, allocates the frame data -// to the specified size. If additionally, data is not null, copies -// size octets from the specified data into the frame body. -CZMQ_EXPORT zframe_t * - zframe_new (const void *data, size_t size); - -// Create an empty (zero-sized) frame -CZMQ_EXPORT zframe_t * - zframe_new_empty (void); - -// Create a frame with a specified string content. -CZMQ_EXPORT zframe_t * - zframe_from (const char *string); - -// Receive frame from socket, returns zframe_t object or NULL if the recv -// was interrupted. Does a blocking recv, if you want to not block then use -// zpoller or zloop. -CZMQ_EXPORT zframe_t * - zframe_recv (void *source); - -// Destroy a frame -CZMQ_EXPORT void - zframe_destroy (zframe_t **self_p); - -// Send a frame to a socket, destroy frame after sending. -// Return -1 on error, 0 on success. -CZMQ_EXPORT int - zframe_send (zframe_t **self_p, void *dest, int flags); - -// Return number of bytes in frame data -CZMQ_EXPORT size_t - zframe_size (zframe_t *self); - -// Return address of frame data -CZMQ_EXPORT byte * - zframe_data (zframe_t *self); - -// Return meta data property for frame -// Caller must free string when finished with it. -CZMQ_EXPORT const char * - zframe_meta (zframe_t *self, const char *property); - -// Create a new frame that duplicates an existing frame. If frame is null, -// or memory was exhausted, returns null. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zframe_t * - zframe_dup (zframe_t *self); - -// Return frame data encoded as printable hex string, useful for 0MQ UUIDs. -// Caller must free string when finished with it. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zframe_strhex (zframe_t *self); - -// Return frame data copied into freshly allocated string -// Caller must free string when finished with it. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zframe_strdup (zframe_t *self); - -// Return TRUE if frame body is equal to string, excluding terminator -CZMQ_EXPORT bool - zframe_streq (zframe_t *self, const char *string); - -// Return frame MORE indicator (1 or 0), set when reading frame from socket -// or by the zframe_set_more() method -CZMQ_EXPORT int - zframe_more (zframe_t *self); - -// Set frame MORE indicator (1 or 0). Note this is NOT used when sending -// frame to socket, you have to specify flag explicitly. -CZMQ_EXPORT void - zframe_set_more (zframe_t *self, int more); - -// Return TRUE if two frames have identical size and data -// If either frame is NULL, equality is always false. -CZMQ_EXPORT bool - zframe_eq (zframe_t *self, zframe_t *other); - -// Set new contents for frame -CZMQ_EXPORT void - zframe_reset (zframe_t *self, const void *data, size_t size); - -// Send message to zsys log sink (may be stdout, or system facility as -// configured by zsys_set_logstream). Prefix shows before frame, if not null. -CZMQ_EXPORT void - zframe_print (zframe_t *self, const char *prefix); - -// Probe the supplied object, and report if it looks like a zframe_t. -CZMQ_EXPORT bool - zframe_is (void *self); - -// Self test of this class. -CZMQ_EXPORT void - zframe_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Return frame routing ID, if the frame came from a ZMQ_SERVER socket. -// Else returns zero. -CZMQ_EXPORT uint32_t - zframe_routing_id (zframe_t *self); - -// *** Draft method, for development use, may change without warning *** -// Set routing ID on frame. This is used if/when the frame is sent to a -// ZMQ_SERVER socket. -CZMQ_EXPORT void - zframe_set_routing_id (zframe_t *self, uint32_t routing_id); - -// *** Draft method, for development use, may change without warning *** -// Return frame group of radio-dish pattern. -CZMQ_EXPORT const char * - zframe_group (zframe_t *self); - -// *** Draft method, for development use, may change without warning *** -// Set group on frame. This is used if/when the frame is sent to a -// ZMQ_RADIO socket. -// Return -1 on error, 0 on success. -CZMQ_EXPORT int - zframe_set_group (zframe_t *self, const char *group); - -#endif // CZMQ_BUILD_DRAFT_API -// @end - - -// DEPRECATED as poor style -- callers should use zloop or zpoller -// Receive a new frame off the socket. Returns newly allocated frame, or -// NULL if there was no input waiting, or if the read was interrupted. -CZMQ_EXPORT zframe_t * - zframe_recv_nowait (void *source); - -// DEPRECATED as inconsistent; breaks principle that logging should all go -// to a single destination. -// Print contents of the frame to FILE stream. -CZMQ_EXPORT void - zframe_fprint (zframe_t *self, const char *prefix, FILE *file); - -// Deprecated method aliases -#define zframe_print_to_stream(s,p,F) zframe_fprint(s,p,F) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zgossip.h b/phonelibs/zmq/aarch64/include/zgossip.h deleted file mode 100644 index 647cb28c080731..00000000000000 --- a/phonelibs/zmq/aarch64/include/zgossip.h +++ /dev/null @@ -1,95 +0,0 @@ -/* ========================================================================= - zgossip - zgossip server - - ** WARNING ************************************************************* - THIS SOURCE FILE IS 100% GENERATED. If you edit this file, you will lose - your changes at the next build cycle. This is great for temporary printf - statements. DO NOT MAKE ANY CHANGES YOU WISH TO KEEP. The correct places - for commits are: - - * The XML model used for this code generation: zgossip.xml, or - * The code generation script that built this file: zproto_server_c - ************************************************************************ - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef ZGOSSIP_H_INCLUDED -#define ZGOSSIP_H_INCLUDED - -#include "czmq.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// To work with zgossip, use the CZMQ zactor API: -// -// Create new zgossip instance, passing logging prefix: -// -// zactor_t *zgossip = zactor_new (zgossip, "myname"); -// -// Destroy zgossip instance -// -// zactor_destroy (&zgossip); -// -// Enable verbose logging of commands and activity: -// -// zstr_send (zgossip, "VERBOSE"); -// -// Bind zgossip to specified endpoint. TCP endpoints may specify -// the port number as "*" to aquire an ephemeral port: -// -// zstr_sendx (zgossip, "BIND", endpoint, NULL); -// -// Return assigned port number, specifically when BIND was done using an -// an ephemeral port: -// -// zstr_sendx (zgossip, "PORT", NULL); -// char *command, *port_str; -// zstr_recvx (zgossip, &command, &port_str, NULL); -// assert (streq (command, "PORT")); -// -// Specify configuration file to load, overwriting any previous loaded -// configuration file or options: -// -// zstr_sendx (zgossip, "LOAD", filename, NULL); -// -// Set configuration path value: -// -// zstr_sendx (zgossip, "SET", path, value, NULL); -// -// Save configuration data to config file on disk: -// -// zstr_sendx (zgossip, "SAVE", filename, NULL); -// -// Send zmsg_t instance to zgossip: -// -// zactor_send (zgossip, &msg); -// -// Receive zmsg_t instance from zgossip: -// -// zmsg_t *msg = zactor_recv (zgossip); -// -// This is the zgossip constructor as a zactor_fn: -// -CZMQ_EXPORT void - zgossip (zsock_t *pipe, void *args); - -// Self test of this class -CZMQ_EXPORT void - zgossip_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zhash.h b/phonelibs/zmq/aarch64/include/zhash.h deleted file mode 100644 index 929bc2683aec36..00000000000000 --- a/phonelibs/zmq/aarch64/include/zhash.h +++ /dev/null @@ -1,198 +0,0 @@ -/* ========================================================================= - zhash - generic type-free hash container (simple) - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZHASH_H_INCLUDED__ -#define __ZHASH_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zhash.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has legacy methods, which will be removed over time. You -// should not use them, and migrate any code that is still using them. -// Callback function for zhash_freefn method -typedef void (zhash_free_fn) ( - void *data); - -// Callback function for zhash_foreach method. Deprecated. -typedef int (zhash_foreach_fn) ( - const char *key, void *item, void *argument); - -// Create a new, empty hash container -CZMQ_EXPORT zhash_t * - zhash_new (void); - -// Unpack binary frame into a new hash table. Packed data must follow format -// defined by zhash_pack. Hash table is set to autofree. An empty frame -// unpacks to an empty hash table. -CZMQ_EXPORT zhash_t * - zhash_unpack (zframe_t *frame); - -// Destroy a hash container and all items in it -CZMQ_EXPORT void - zhash_destroy (zhash_t **self_p); - -// Insert item into hash table with specified key and item. -// If key is already present returns -1 and leaves existing item unchanged -// Returns 0 on success. -CZMQ_EXPORT int - zhash_insert (zhash_t *self, const char *key, void *item); - -// Update item into hash table with specified key and item. -// If key is already present, destroys old item and inserts new one. -// Use free_fn method to ensure deallocator is properly called on item. -CZMQ_EXPORT void - zhash_update (zhash_t *self, const char *key, void *item); - -// Remove an item specified by key from the hash table. If there was no such -// item, this function does nothing. -CZMQ_EXPORT void - zhash_delete (zhash_t *self, const char *key); - -// Return the item at the specified key, or null -CZMQ_EXPORT void * - zhash_lookup (zhash_t *self, const char *key); - -// Reindexes an item from an old key to a new key. If there was no such -// item, does nothing. Returns 0 if successful, else -1. -CZMQ_EXPORT int - zhash_rename (zhash_t *self, const char *old_key, const char *new_key); - -// Set a free function for the specified hash table item. When the item is -// destroyed, the free function, if any, is called on that item. -// Use this when hash items are dynamically allocated, to ensure that -// you don't have memory leaks. You can pass 'free' or NULL as a free_fn. -// Returns the item, or NULL if there is no such item. -CZMQ_EXPORT void * - zhash_freefn (zhash_t *self, const char *key, zhash_free_fn free_fn); - -// Return the number of keys/items in the hash table -CZMQ_EXPORT size_t - zhash_size (zhash_t *self); - -// Make copy of hash table; if supplied table is null, returns null. -// Does not copy items themselves. Rebuilds new table so may be slow on -// very large tables. NOTE: only works with item values that are strings -// since there's no other way to know how to duplicate the item value. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zhash_t * - zhash_dup (zhash_t *self); - -// Return keys for items in table -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zlist_t * - zhash_keys (zhash_t *self); - -// Simple iterator; returns first item in hash table, in no given order, -// or NULL if the table is empty. This method is simpler to use than the -// foreach() method, which is deprecated. To access the key for this item -// use zhash_cursor(). NOTE: do NOT modify the table while iterating. -CZMQ_EXPORT void * - zhash_first (zhash_t *self); - -// Simple iterator; returns next item in hash table, in no given order, -// or NULL if the last item was already returned. Use this together with -// zhash_first() to process all items in a hash table. If you need the -// items in sorted order, use zhash_keys() and then zlist_sort(). To -// access the key for this item use zhash_cursor(). NOTE: do NOT modify -// the table while iterating. -CZMQ_EXPORT void * - zhash_next (zhash_t *self); - -// After a successful first/next method, returns the key for the item that -// was returned. This is a constant string that you may not modify or -// deallocate, and which lasts as long as the item in the hash. After an -// unsuccessful first/next, returns NULL. -CZMQ_EXPORT const char * - zhash_cursor (zhash_t *self); - -// Add a comment to hash table before saving to disk. You can add as many -// comment lines as you like. These comment lines are discarded when loading -// the file. If you use a null format, all comments are deleted. -CZMQ_EXPORT void - zhash_comment (zhash_t *self, const char *format, ...); - -// Serialize hash table to a binary frame that can be sent in a message. -// The packed format is compatible with the 'dictionary' type defined in -// http://rfc.zeromq.org/spec:35/FILEMQ, and implemented by zproto: -// -// ; A list of name/value pairs -// dictionary = dict-count *( dict-name dict-value ) -// dict-count = number-4 -// dict-value = longstr -// dict-name = string -// -// ; Strings are always length + text contents -// longstr = number-4 *VCHAR -// string = number-1 *VCHAR -// -// ; Numbers are unsigned integers in network byte order -// number-1 = 1OCTET -// number-4 = 4OCTET -// -// Comments are not included in the packed data. Item values MUST be -// strings. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zframe_t * - zhash_pack (zhash_t *self); - -// Save hash table to a text file in name=value format. Hash values must be -// printable strings; keys may not contain '=' character. Returns 0 if OK, -// else -1 if a file error occurred. -CZMQ_EXPORT int - zhash_save (zhash_t *self, const char *filename); - -// Load hash table from a text file in name=value format; hash table must -// already exist. Hash values must printable strings; keys may not contain -// '=' character. Returns 0 if OK, else -1 if a file was not readable. -CZMQ_EXPORT int - zhash_load (zhash_t *self, const char *filename); - -// When a hash table was loaded from a file by zhash_load, this method will -// reload the file if it has been modified since, and is "stable", i.e. not -// still changing. Returns 0 if OK, -1 if there was an error reloading the -// file. -CZMQ_EXPORT int - zhash_refresh (zhash_t *self); - -// Set hash for automatic value destruction -CZMQ_EXPORT void - zhash_autofree (zhash_t *self); - -// *** Deprecated method, slated for removal: avoid using it *** -// Apply function to each item in the hash table. Items are iterated in no -// defined order. Stops if callback function returns non-zero and returns -// final return code from callback function (zero = success). Deprecated. -CZMQ_EXPORT int - zhash_foreach (zhash_t *self, zhash_foreach_fn callback, void *argument); - -// Self test of this class. -CZMQ_EXPORT void - zhash_test (bool verbose); - -// @ignore -CZMQ_EXPORT void - zhash_comment (zhash_t *self, const char *format, ...) CHECK_PRINTF (2); -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zhashx.h b/phonelibs/zmq/aarch64/include/zhashx.h deleted file mode 100644 index 8776073156cf3c..00000000000000 --- a/phonelibs/zmq/aarch64/include/zhashx.h +++ /dev/null @@ -1,301 +0,0 @@ -/* ========================================================================= - zhashx - extended generic type-free hash container - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZHASHX_H_INCLUDED__ -#define __ZHASHX_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zhashx.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// This class has legacy methods, which will be removed over time. You -// should not use them, and migrate any code that is still using them. -// Destroy an item -typedef void (zhashx_destructor_fn) ( - void **item); - -// Duplicate an item -typedef void * (zhashx_duplicator_fn) ( - const void *item); - -// Compare two items, for sorting -typedef int (zhashx_comparator_fn) ( - const void *item1, const void *item2); - -// compare two items, for sorting -typedef void (zhashx_free_fn) ( - void *data); - -// compare two items, for sorting -typedef size_t (zhashx_hash_fn) ( - const void *key); - -// Serializes an item to a longstr. -// The caller takes ownership of the newly created object. -typedef char * (zhashx_serializer_fn) ( - const void *item); - -// Deserializes a longstr into an item. -// The caller takes ownership of the newly created object. -typedef void * (zhashx_deserializer_fn) ( - const char *item_str); - -// Callback function for zhashx_foreach method. -// This callback is deprecated and you should use zhashx_first/_next instead. -typedef int (zhashx_foreach_fn) ( - const char *key, void *item, void *argument); - -// Create a new, empty hash container -CZMQ_EXPORT zhashx_t * - zhashx_new (void); - -// Unpack binary frame into a new hash table. Packed data must follow format -// defined by zhashx_pack. Hash table is set to autofree. An empty frame -// unpacks to an empty hash table. -CZMQ_EXPORT zhashx_t * - zhashx_unpack (zframe_t *frame); - -// Destroy a hash container and all items in it -CZMQ_EXPORT void - zhashx_destroy (zhashx_t **self_p); - -// Insert item into hash table with specified key and item. -// If key is already present returns -1 and leaves existing item unchanged -// Returns 0 on success. -CZMQ_EXPORT int - zhashx_insert (zhashx_t *self, const void *key, void *item); - -// Update or insert item into hash table with specified key and item. If the -// key is already present, destroys old item and inserts new one. If you set -// a container item destructor, this is called on the old value. If the key -// was not already present, inserts a new item. Sets the hash cursor to the -// new item. -CZMQ_EXPORT void - zhashx_update (zhashx_t *self, const void *key, void *item); - -// Remove an item specified by key from the hash table. If there was no such -// item, this function does nothing. -CZMQ_EXPORT void - zhashx_delete (zhashx_t *self, const void *key); - -// Delete all items from the hash table. If the key destructor is -// set, calls it on every key. If the item destructor is set, calls -// it on every item. -CZMQ_EXPORT void - zhashx_purge (zhashx_t *self); - -// Return the item at the specified key, or null -CZMQ_EXPORT void * - zhashx_lookup (zhashx_t *self, const void *key); - -// Reindexes an item from an old key to a new key. If there was no such -// item, does nothing. Returns 0 if successful, else -1. -CZMQ_EXPORT int - zhashx_rename (zhashx_t *self, const void *old_key, const void *new_key); - -// Set a free function for the specified hash table item. When the item is -// destroyed, the free function, if any, is called on that item. -// Use this when hash items are dynamically allocated, to ensure that -// you don't have memory leaks. You can pass 'free' or NULL as a free_fn. -// Returns the item, or NULL if there is no such item. -CZMQ_EXPORT void * - zhashx_freefn (zhashx_t *self, const void *key, zhashx_free_fn free_fn); - -// Return the number of keys/items in the hash table -CZMQ_EXPORT size_t - zhashx_size (zhashx_t *self); - -// Return a zlistx_t containing the keys for the items in the -// table. Uses the key_duplicator to duplicate all keys and sets the -// key_destructor as destructor for the list. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zlistx_t * - zhashx_keys (zhashx_t *self); - -// Return a zlistx_t containing the values for the items in the -// table. Uses the duplicator to duplicate all items and sets the -// destructor as destructor for the list. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zlistx_t * - zhashx_values (zhashx_t *self); - -// Simple iterator; returns first item in hash table, in no given order, -// or NULL if the table is empty. This method is simpler to use than the -// foreach() method, which is deprecated. To access the key for this item -// use zhashx_cursor(). NOTE: do NOT modify the table while iterating. -CZMQ_EXPORT void * - zhashx_first (zhashx_t *self); - -// Simple iterator; returns next item in hash table, in no given order, -// or NULL if the last item was already returned. Use this together with -// zhashx_first() to process all items in a hash table. If you need the -// items in sorted order, use zhashx_keys() and then zlistx_sort(). To -// access the key for this item use zhashx_cursor(). NOTE: do NOT modify -// the table while iterating. -CZMQ_EXPORT void * - zhashx_next (zhashx_t *self); - -// After a successful first/next method, returns the key for the item that -// was returned. This is a constant string that you may not modify or -// deallocate, and which lasts as long as the item in the hash. After an -// unsuccessful first/next, returns NULL. -CZMQ_EXPORT const void * - zhashx_cursor (zhashx_t *self); - -// Add a comment to hash table before saving to disk. You can add as many -// comment lines as you like. These comment lines are discarded when loading -// the file. If you use a null format, all comments are deleted. -CZMQ_EXPORT void - zhashx_comment (zhashx_t *self, const char *format, ...); - -// Save hash table to a text file in name=value format. Hash values must be -// printable strings; keys may not contain '=' character. Returns 0 if OK, -// else -1 if a file error occurred. -CZMQ_EXPORT int - zhashx_save (zhashx_t *self, const char *filename); - -// Load hash table from a text file in name=value format; hash table must -// already exist. Hash values must printable strings; keys may not contain -// '=' character. Returns 0 if OK, else -1 if a file was not readable. -CZMQ_EXPORT int - zhashx_load (zhashx_t *self, const char *filename); - -// When a hash table was loaded from a file by zhashx_load, this method will -// reload the file if it has been modified since, and is "stable", i.e. not -// still changing. Returns 0 if OK, -1 if there was an error reloading the -// file. -CZMQ_EXPORT int - zhashx_refresh (zhashx_t *self); - -// Serialize hash table to a binary frame that can be sent in a message. -// The packed format is compatible with the 'dictionary' type defined in -// http://rfc.zeromq.org/spec:35/FILEMQ, and implemented by zproto: -// -// ; A list of name/value pairs -// dictionary = dict-count *( dict-name dict-value ) -// dict-count = number-4 -// dict-value = longstr -// dict-name = string -// -// ; Strings are always length + text contents -// longstr = number-4 *VCHAR -// string = number-1 *VCHAR -// -// ; Numbers are unsigned integers in network byte order -// number-1 = 1OCTET -// number-4 = 4OCTET -// -// Comments are not included in the packed data. Item values MUST be -// strings. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zframe_t * - zhashx_pack (zhashx_t *self); - -// Make a copy of the list; items are duplicated if you set a duplicator -// for the list, otherwise not. Copying a null reference returns a null -// reference. Note that this method's behavior changed slightly for CZMQ -// v3.x, as it does not set nor respect autofree. It does however let you -// duplicate any hash table safely. The old behavior is in zhashx_dup_v2. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zhashx_t * - zhashx_dup (zhashx_t *self); - -// Set a user-defined deallocator for hash items; by default items are not -// freed when the hash is destroyed. -CZMQ_EXPORT void - zhashx_set_destructor (zhashx_t *self, zhashx_destructor_fn destructor); - -// Set a user-defined duplicator for hash items; by default items are not -// copied when the hash is duplicated. -CZMQ_EXPORT void - zhashx_set_duplicator (zhashx_t *self, zhashx_duplicator_fn duplicator); - -// Set a user-defined deallocator for keys; by default keys are freed -// when the hash is destroyed using free(). -CZMQ_EXPORT void - zhashx_set_key_destructor (zhashx_t *self, zhashx_destructor_fn destructor); - -// Set a user-defined duplicator for keys; by default keys are duplicated -// using strdup. -CZMQ_EXPORT void - zhashx_set_key_duplicator (zhashx_t *self, zhashx_duplicator_fn duplicator); - -// Set a user-defined comparator for keys; by default keys are -// compared using strcmp. -CZMQ_EXPORT void - zhashx_set_key_comparator (zhashx_t *self, zhashx_comparator_fn comparator); - -// Set a user-defined comparator for keys; by default keys are -// compared using strcmp. -CZMQ_EXPORT void - zhashx_set_key_hasher (zhashx_t *self, zhashx_hash_fn hasher); - -// Make copy of hash table; if supplied table is null, returns null. -// Does not copy items themselves. Rebuilds new table so may be slow on -// very large tables. NOTE: only works with item values that are strings -// since there's no other way to know how to duplicate the item value. -CZMQ_EXPORT zhashx_t * - zhashx_dup_v2 (zhashx_t *self); - -// *** Deprecated method, slated for removal: avoid using it *** -// Set hash for automatic value destruction. This method is deprecated -// and you should use set_destructor instead. -CZMQ_EXPORT void - zhashx_autofree (zhashx_t *self); - -// *** Deprecated method, slated for removal: avoid using it *** -// Apply function to each item in the hash table. Items are iterated in no -// defined order. Stops if callback function returns non-zero and returns -// final return code from callback function (zero = success). This method -// is deprecated and you should use zhashx_first/_next instead. -CZMQ_EXPORT int - zhashx_foreach (zhashx_t *self, zhashx_foreach_fn callback, void *argument); - -// Self test of this class. -CZMQ_EXPORT void - zhashx_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Same as unpack but uses a user-defined deserializer function to convert -// a longstr back into item format. -CZMQ_EXPORT zhashx_t * - zhashx_unpack_own (zframe_t *frame, zhashx_deserializer_fn deserializer); - -// *** Draft method, for development use, may change without warning *** -// Same as pack but uses a user-defined serializer function to convert items -// into longstr. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zframe_t * - zhashx_pack_own (zhashx_t *self, zhashx_serializer_fn serializer); - -#endif // CZMQ_BUILD_DRAFT_API -// @ignore -CZMQ_EXPORT void - zhashx_comment (zhashx_t *self, const char *format, ...) CHECK_PRINTF (2); -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/ziflist.h b/phonelibs/zmq/aarch64/include/ziflist.h deleted file mode 100644 index cb2b1448025f89..00000000000000 --- a/phonelibs/zmq/aarch64/include/ziflist.h +++ /dev/null @@ -1,77 +0,0 @@ -/* ========================================================================= - ziflist - List of network interfaces available on system - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZIFLIST_H_INCLUDED__ -#define __ZIFLIST_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/ziflist.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Get a list of network interfaces currently defined on the system -CZMQ_EXPORT ziflist_t * - ziflist_new (void); - -// Destroy a ziflist instance -CZMQ_EXPORT void - ziflist_destroy (ziflist_t **self_p); - -// Reload network interfaces from system -CZMQ_EXPORT void - ziflist_reload (ziflist_t *self); - -// Return the number of network interfaces on system -CZMQ_EXPORT size_t - ziflist_size (ziflist_t *self); - -// Get first network interface, return NULL if there are none -CZMQ_EXPORT const char * - ziflist_first (ziflist_t *self); - -// Get next network interface, return NULL if we hit the last one -CZMQ_EXPORT const char * - ziflist_next (ziflist_t *self); - -// Return the current interface IP address as a printable string -CZMQ_EXPORT const char * - ziflist_address (ziflist_t *self); - -// Return the current interface broadcast address as a printable string -CZMQ_EXPORT const char * - ziflist_broadcast (ziflist_t *self); - -// Return the current interface network mask as a printable string -CZMQ_EXPORT const char * - ziflist_netmask (ziflist_t *self); - -// Return the list of interfaces. -CZMQ_EXPORT void - ziflist_print (ziflist_t *self); - -// Self test of this class. -CZMQ_EXPORT void - ziflist_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zlist.h b/phonelibs/zmq/aarch64/include/zlist.h deleted file mode 100644 index 1dcd39b9955c9e..00000000000000 --- a/phonelibs/zmq/aarch64/include/zlist.h +++ /dev/null @@ -1,158 +0,0 @@ -/* ========================================================================= - zlist - simple generic list container - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZLIST_H_INCLUDED__ -#define __ZLIST_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zlist.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Comparison function e.g. for sorting and removing. -typedef int (zlist_compare_fn) ( - void *item1, void *item2); - -// Callback function for zlist_freefn method -typedef void (zlist_free_fn) ( - void *data); - -// Create a new list container -CZMQ_EXPORT zlist_t * - zlist_new (void); - -// Destroy a list container -CZMQ_EXPORT void - zlist_destroy (zlist_t **self_p); - -// Return the item at the head of list. If the list is empty, returns NULL. -// Leaves cursor pointing at the head item, or NULL if the list is empty. -CZMQ_EXPORT void * - zlist_first (zlist_t *self); - -// Return the next item. If the list is empty, returns NULL. To move to -// the start of the list call zlist_first (). Advances the cursor. -CZMQ_EXPORT void * - zlist_next (zlist_t *self); - -// Return the item at the tail of list. If the list is empty, returns NULL. -// Leaves cursor pointing at the tail item, or NULL if the list is empty. -CZMQ_EXPORT void * - zlist_last (zlist_t *self); - -// Return first item in the list, or null, leaves the cursor -CZMQ_EXPORT void * - zlist_head (zlist_t *self); - -// Return last item in the list, or null, leaves the cursor -CZMQ_EXPORT void * - zlist_tail (zlist_t *self); - -// Return the current item of list. If the list is empty, returns NULL. -// Leaves cursor pointing at the current item, or NULL if the list is empty. -CZMQ_EXPORT void * - zlist_item (zlist_t *self); - -// Append an item to the end of the list, return 0 if OK or -1 if this -// failed for some reason (out of memory). Note that if a duplicator has -// been set, this method will also duplicate the item. -CZMQ_EXPORT int - zlist_append (zlist_t *self, void *item); - -// Push an item to the start of the list, return 0 if OK or -1 if this -// failed for some reason (out of memory). Note that if a duplicator has -// been set, this method will also duplicate the item. -CZMQ_EXPORT int - zlist_push (zlist_t *self, void *item); - -// Pop the item off the start of the list, if any -CZMQ_EXPORT void * - zlist_pop (zlist_t *self); - -// Checks if an item already is present. Uses compare method to determine if -// items are equal. If the compare method is NULL the check will only compare -// pointers. Returns true if item is present else false. -CZMQ_EXPORT bool - zlist_exists (zlist_t *self, void *item); - -// Remove the specified item from the list if present -CZMQ_EXPORT void - zlist_remove (zlist_t *self, void *item); - -// Make a copy of list. If the list has autofree set, the copied list will -// duplicate all items, which must be strings. Otherwise, the list will hold -// pointers back to the items in the original list. If list is null, returns -// NULL. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zlist_t * - zlist_dup (zlist_t *self); - -// Purge all items from list -CZMQ_EXPORT void - zlist_purge (zlist_t *self); - -// Return number of items in the list -CZMQ_EXPORT size_t - zlist_size (zlist_t *self); - -// Sort the list. If the compare function is null, sorts the list by -// ascending key value using a straight ASCII comparison. If you specify -// a compare function, this decides how items are sorted. The sort is not -// stable, so may reorder items with the same keys. The algorithm used is -// combsort, a compromise between performance and simplicity. -CZMQ_EXPORT void - zlist_sort (zlist_t *self, zlist_compare_fn compare); - -// Set list for automatic item destruction; item values MUST be strings. -// By default a list item refers to a value held elsewhere. When you set -// this, each time you append or push a list item, zlist will take a copy -// of the string value. Then, when you destroy the list, it will free all -// item values automatically. If you use any other technique to allocate -// list values, you must free them explicitly before destroying the list. -// The usual technique is to pop list items and destroy them, until the -// list is empty. -CZMQ_EXPORT void - zlist_autofree (zlist_t *self); - -// Sets a compare function for this list. The function compares two items. -// It returns an integer less than, equal to, or greater than zero if the -// first item is found, respectively, to be less than, to match, or be -// greater than the second item. -// This function is used for sorting, removal and exists checking. -CZMQ_EXPORT void - zlist_comparefn (zlist_t *self, zlist_compare_fn fn); - -// Set a free function for the specified list item. When the item is -// destroyed, the free function, if any, is called on that item. -// Use this when list items are dynamically allocated, to ensure that -// you don't have memory leaks. You can pass 'free' or NULL as a free_fn. -// Returns the item, or NULL if there is no such item. -CZMQ_EXPORT void * - zlist_freefn (zlist_t *self, void *item, zlist_free_fn fn, bool at_tail); - -// Self test of this class. -CZMQ_EXPORT void - zlist_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zlistx.h b/phonelibs/zmq/aarch64/include/zlistx.h deleted file mode 100644 index 512637cef3bff5..00000000000000 --- a/phonelibs/zmq/aarch64/include/zlistx.h +++ /dev/null @@ -1,205 +0,0 @@ -/* ========================================================================= - zlistx - extended generic list container - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZLISTX_H_INCLUDED__ -#define __ZLISTX_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zlistx.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Destroy an item -typedef void (zlistx_destructor_fn) ( - void **item); - -// Duplicate an item -typedef void * (zlistx_duplicator_fn) ( - const void *item); - -// Compare two items, for sorting -typedef int (zlistx_comparator_fn) ( - const void *item1, const void *item2); - -// Create a new, empty list. -CZMQ_EXPORT zlistx_t * - zlistx_new (void); - -// Destroy a list. If an item destructor was specified, all items in the -// list are automatically destroyed as well. -CZMQ_EXPORT void - zlistx_destroy (zlistx_t **self_p); - -// Add an item to the head of the list. Calls the item duplicator, if any, -// on the item. Resets cursor to list head. Returns an item handle on -// success, NULL if memory was exhausted. -CZMQ_EXPORT void * - zlistx_add_start (zlistx_t *self, void *item); - -// Add an item to the tail of the list. Calls the item duplicator, if any, -// on the item. Resets cursor to list head. Returns an item handle on -// success, NULL if memory was exhausted. -CZMQ_EXPORT void * - zlistx_add_end (zlistx_t *self, void *item); - -// Return the number of items in the list -CZMQ_EXPORT size_t - zlistx_size (zlistx_t *self); - -// Return first item in the list, or null, leaves the cursor -CZMQ_EXPORT void * - zlistx_head (zlistx_t *self); - -// Return last item in the list, or null, leaves the cursor -CZMQ_EXPORT void * - zlistx_tail (zlistx_t *self); - -// Return the item at the head of list. If the list is empty, returns NULL. -// Leaves cursor pointing at the head item, or NULL if the list is empty. -CZMQ_EXPORT void * - zlistx_first (zlistx_t *self); - -// Return the next item. At the end of the list (or in an empty list), -// returns NULL. Use repeated zlistx_next () calls to work through the list -// from zlistx_first (). First time, acts as zlistx_first(). -CZMQ_EXPORT void * - zlistx_next (zlistx_t *self); - -// Return the previous item. At the start of the list (or in an empty list), -// returns NULL. Use repeated zlistx_prev () calls to work through the list -// backwards from zlistx_last (). First time, acts as zlistx_last(). -CZMQ_EXPORT void * - zlistx_prev (zlistx_t *self); - -// Return the item at the tail of list. If the list is empty, returns NULL. -// Leaves cursor pointing at the tail item, or NULL if the list is empty. -CZMQ_EXPORT void * - zlistx_last (zlistx_t *self); - -// Returns the value of the item at the cursor, or NULL if the cursor is -// not pointing to an item. -CZMQ_EXPORT void * - zlistx_item (zlistx_t *self); - -// Returns the handle of the item at the cursor, or NULL if the cursor is -// not pointing to an item. -CZMQ_EXPORT void * - zlistx_cursor (zlistx_t *self); - -// Returns the item associated with the given list handle, or NULL if passed -// in handle is NULL. Asserts that the passed in handle points to a list element. -CZMQ_EXPORT void * - zlistx_handle_item (void *handle); - -// Find an item in the list, searching from the start. Uses the item -// comparator, if any, else compares item values directly. Returns the -// item handle found, or NULL. Sets the cursor to the found item, if any. -CZMQ_EXPORT void * - zlistx_find (zlistx_t *self, void *item); - -// Detach an item from the list, using its handle. The item is not modified, -// and the caller is responsible for destroying it if necessary. If handle is -// null, detaches the first item on the list. Returns item that was detached, -// or null if none was. If cursor was at item, moves cursor to previous item, -// so you can detach items while iterating forwards through a list. -CZMQ_EXPORT void * - zlistx_detach (zlistx_t *self, void *handle); - -// Detach item at the cursor, if any, from the list. The item is not modified, -// and the caller is responsible for destroying it as necessary. Returns item -// that was detached, or null if none was. Moves cursor to previous item, so -// you can detach items while iterating forwards through a list. -CZMQ_EXPORT void * - zlistx_detach_cur (zlistx_t *self); - -// Delete an item, using its handle. Calls the item destructor is any is -// set. If handle is null, deletes the first item on the list. Returns 0 -// if an item was deleted, -1 if not. If cursor was at item, moves cursor -// to previous item, so you can delete items while iterating forwards -// through a list. -CZMQ_EXPORT int - zlistx_delete (zlistx_t *self, void *handle); - -// Move an item to the start of the list, via its handle. -CZMQ_EXPORT void - zlistx_move_start (zlistx_t *self, void *handle); - -// Move an item to the end of the list, via its handle. -CZMQ_EXPORT void - zlistx_move_end (zlistx_t *self, void *handle); - -// Remove all items from the list, and destroy them if the item destructor -// is set. -CZMQ_EXPORT void - zlistx_purge (zlistx_t *self); - -// Sort the list. If an item comparator was set, calls that to compare -// items, otherwise compares on item value. The sort is not stable, so may -// reorder equal items. -CZMQ_EXPORT void - zlistx_sort (zlistx_t *self); - -// Create a new node and insert it into a sorted list. Calls the item -// duplicator, if any, on the item. If low_value is true, starts searching -// from the start of the list, otherwise searches from the end. Use the item -// comparator, if any, to find where to place the new node. Returns a handle -// to the new node, or NULL if memory was exhausted. Resets the cursor to the -// list head. -CZMQ_EXPORT void * - zlistx_insert (zlistx_t *self, void *item, bool low_value); - -// Move an item, specified by handle, into position in a sorted list. Uses -// the item comparator, if any, to determine the new location. If low_value -// is true, starts searching from the start of the list, otherwise searches -// from the end. -CZMQ_EXPORT void - zlistx_reorder (zlistx_t *self, void *handle, bool low_value); - -// Make a copy of the list; items are duplicated if you set a duplicator -// for the list, otherwise not. Copying a null reference returns a null -// reference. -CZMQ_EXPORT zlistx_t * - zlistx_dup (zlistx_t *self); - -// Set a user-defined deallocator for list items; by default items are not -// freed when the list is destroyed. -CZMQ_EXPORT void - zlistx_set_destructor (zlistx_t *self, zlistx_destructor_fn destructor); - -// Set a user-defined duplicator for list items; by default items are not -// copied when the list is duplicated. -CZMQ_EXPORT void - zlistx_set_duplicator (zlistx_t *self, zlistx_duplicator_fn duplicator); - -// Set a user-defined comparator for zlistx_find and zlistx_sort; the method -// must return -1, 0, or 1 depending on whether item1 is less than, equal to, -// or greater than, item2. -CZMQ_EXPORT void - zlistx_set_comparator (zlistx_t *self, zlistx_comparator_fn comparator); - -// Self test of this class. -CZMQ_EXPORT void - zlistx_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zloop.h b/phonelibs/zmq/aarch64/include/zloop.h deleted file mode 100644 index bc58ea0530e7b3..00000000000000 --- a/phonelibs/zmq/aarch64/include/zloop.h +++ /dev/null @@ -1,168 +0,0 @@ -/* ========================================================================= - zloop - event-driven reactor - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZLOOP_H_INCLUDED__ -#define __ZLOOP_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zloop.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// Callback function for reactor socket activity -typedef int (zloop_reader_fn) ( - zloop_t *loop, zsock_t *reader, void *arg); - -// Callback function for reactor events (low-level) -typedef int (zloop_fn) ( - zloop_t *loop, zmq_pollitem_t *item, void *arg); - -// Callback for reactor timer events -typedef int (zloop_timer_fn) ( - zloop_t *loop, int timer_id, void *arg); - -// Create a new zloop reactor -CZMQ_EXPORT zloop_t * - zloop_new (void); - -// Destroy a reactor -CZMQ_EXPORT void - zloop_destroy (zloop_t **self_p); - -// Register socket reader with the reactor. When the reader has messages, -// the reactor will call the handler, passing the arg. Returns 0 if OK, -1 -// if there was an error. If you register the same socket more than once, -// each instance will invoke its corresponding handler. -CZMQ_EXPORT int - zloop_reader (zloop_t *self, zsock_t *sock, zloop_reader_fn handler, void *arg); - -// Cancel a socket reader from the reactor. If multiple readers exist for -// same socket, cancels ALL of them. -CZMQ_EXPORT void - zloop_reader_end (zloop_t *self, zsock_t *sock); - -// Configure a registered reader to ignore errors. If you do not set this, -// then readers that have errors are removed from the reactor silently. -CZMQ_EXPORT void - zloop_reader_set_tolerant (zloop_t *self, zsock_t *sock); - -// Register low-level libzmq pollitem with the reactor. When the pollitem -// is ready, will call the handler, passing the arg. Returns 0 if OK, -1 -// if there was an error. If you register the pollitem more than once, each -// instance will invoke its corresponding handler. A pollitem with -// socket=NULL and fd=0 means 'poll on FD zero'. -CZMQ_EXPORT int - zloop_poller (zloop_t *self, zmq_pollitem_t *item, zloop_fn handler, void *arg); - -// Cancel a pollitem from the reactor, specified by socket or FD. If both -// are specified, uses only socket. If multiple poll items exist for same -// socket/FD, cancels ALL of them. -CZMQ_EXPORT void - zloop_poller_end (zloop_t *self, zmq_pollitem_t *item); - -// Configure a registered poller to ignore errors. If you do not set this, -// then poller that have errors are removed from the reactor silently. -CZMQ_EXPORT void - zloop_poller_set_tolerant (zloop_t *self, zmq_pollitem_t *item); - -// Register a timer that expires after some delay and repeats some number of -// times. At each expiry, will call the handler, passing the arg. To run a -// timer forever, use 0 times. Returns a timer_id that is used to cancel the -// timer in the future. Returns -1 if there was an error. -CZMQ_EXPORT int - zloop_timer (zloop_t *self, size_t delay, size_t times, zloop_timer_fn handler, void *arg); - -// Cancel a specific timer identified by a specific timer_id (as returned by -// zloop_timer). -CZMQ_EXPORT int - zloop_timer_end (zloop_t *self, int timer_id); - -// Register a ticket timer. Ticket timers are very fast in the case where -// you use a lot of timers (thousands), and frequently remove and add them. -// The main use case is expiry timers for servers that handle many clients, -// and which reset the expiry timer for each message received from a client. -// Whereas normal timers perform poorly as the number of clients grows, the -// cost of ticket timers is constant, no matter the number of clients. You -// must set the ticket delay using zloop_set_ticket_delay before creating a -// ticket. Returns a handle to the timer that you should use in -// zloop_ticket_reset and zloop_ticket_delete. -CZMQ_EXPORT void * - zloop_ticket (zloop_t *self, zloop_timer_fn handler, void *arg); - -// Reset a ticket timer, which moves it to the end of the ticket list and -// resets its execution time. This is a very fast operation. -CZMQ_EXPORT void - zloop_ticket_reset (zloop_t *self, void *handle); - -// Delete a ticket timer. We do not actually delete the ticket here, as -// other code may still refer to the ticket. We mark as deleted, and remove -// later and safely. -CZMQ_EXPORT void - zloop_ticket_delete (zloop_t *self, void *handle); - -// Set the ticket delay, which applies to all tickets. If you lower the -// delay and there are already tickets created, the results are undefined. -CZMQ_EXPORT void - zloop_set_ticket_delay (zloop_t *self, size_t ticket_delay); - -// Set hard limit on number of timers allowed. Setting more than a small -// number of timers (10-100) can have a dramatic impact on the performance -// of the reactor. For high-volume cases, use ticket timers. If the hard -// limit is reached, the reactor stops creating new timers and logs an -// error. -CZMQ_EXPORT void - zloop_set_max_timers (zloop_t *self, size_t max_timers); - -// Set verbose tracing of reactor on/off. The default verbose setting is -// off (false). -CZMQ_EXPORT void - zloop_set_verbose (zloop_t *self, bool verbose); - -// Start the reactor. Takes control of the thread and returns when the 0MQ -// context is terminated or the process is interrupted, or any event handler -// returns -1. Event handlers may register new sockets and timers, and -// cancel sockets. Returns 0 if interrupted, -1 if canceled by a handler. -CZMQ_EXPORT int - zloop_start (zloop_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zloop_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// By default the reactor stops if the process receives a SIGINT or SIGTERM -// signal. This makes it impossible to shut-down message based architectures -// like zactors. This method lets you switch off break handling. The default -// nonstop setting is off (false). -CZMQ_EXPORT void - zloop_set_nonstop (zloop_t *self, bool nonstop); - -#endif // CZMQ_BUILD_DRAFT_API -// @end - - -// Deprecated method aliases -#define zloop_set_tolerant(s,i) zloop_poller_set_tolerant(s,i) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zmonitor.h b/phonelibs/zmq/aarch64/include/zmonitor.h deleted file mode 100644 index b490bcb1a0dfbc..00000000000000 --- a/phonelibs/zmq/aarch64/include/zmonitor.h +++ /dev/null @@ -1,73 +0,0 @@ -/* ========================================================================= - zmonitor - socket event monitor - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZMONITOR_H_INCLUDED__ -#define __ZMONITOR_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// Create new zmonitor actor instance to monitor a zsock_t socket: -// -// zactor_t *monitor = zactor_new (zmonitor, mysocket); -// -// Destroy zmonitor instance. -// -// zactor_destroy (&monitor); -// -// Enable verbose logging of commands and activity. -// -// zstr_send (monitor, "VERBOSE"); -// -// Listen to monitor event type (zero or types, ending in NULL): -// zstr_sendx (monitor, "LISTEN", type, ..., NULL); -// -// Events: -// CONNECTED -// CONNECT_DELAYED -// CONNECT_RETRIED -// LISTENING -// BIND_FAILED -// ACCEPTED -// ACCEPT_FAILED -// CLOSED -// CLOSE_FAILED -// DISCONNECTED -// MONITOR_STOPPED -// ALL -// -// Start monitor; after this, any further LISTEN commands are ignored. -// -// zstr_send (monitor, "START"); -// zsock_wait (monitor); -// -// Receive next monitor event: -// -// zmsg_t *msg = zmsg_recv (monitor); -// -// This is the zmonitor constructor as a zactor_fn; the argument can be -// a zactor_t, zsock_t, or libzmq void * socket: -CZMQ_EXPORT void - zmonitor (zsock_t *pipe, void *sock); - -// Selftest -CZMQ_EXPORT void - zmonitor_test (bool verbose); -// @end -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zmonitor_v2.h b/phonelibs/zmq/aarch64/include/zmonitor_v2.h deleted file mode 100644 index 5780e0bcb785ae..00000000000000 --- a/phonelibs/zmq/aarch64/include/zmonitor_v2.h +++ /dev/null @@ -1,56 +0,0 @@ -/* ========================================================================= - zmonitor_v2 - socket event monitor (deprecated) - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZMONITOR_V2_H_INCLUDED__ -#define __ZMONITOR_V2_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// This code needs backporting to work with ZMQ v3.2 -#if (ZMQ_VERSION_MAJOR == 4) - -// Create a new socket monitor -CZMQ_EXPORT zmonitor_t * - zmonitor_new (zctx_t *ctx, void *socket, int events); - -// Destroy a socket monitor -CZMQ_EXPORT void - zmonitor_destroy (zmonitor_t **self_p); - -// Receive a status message from the monitor; if no message arrives within -// 500 msec, or the call was interrupted, returns NULL. -CZMQ_EXPORT zmsg_t * - zmonitor_recv (zmonitor_t *self); - -// Get the ZeroMQ socket, for polling -CZMQ_EXPORT void * - zmonitor_socket (zmonitor_t *self); - -// Enable verbose tracing of commands and activity -CZMQ_EXPORT void - zmonitor_set_verbose (zmonitor_t *self, bool verbose); -#endif // ZeroMQ 4.0 or later - -// Self test of this class -CZMQ_EXPORT void - zmonitor_v2_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zmq.h b/phonelibs/zmq/aarch64/include/zmq.h deleted file mode 100644 index 5f35d1915fcd92..00000000000000 --- a/phonelibs/zmq/aarch64/include/zmq.h +++ /dev/null @@ -1,617 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . - - ************************************************************************* - NOTE to contributors. This file comprises the principal public contract - for ZeroMQ API users. Any change to this file supplied in a stable - release SHOULD not break existing applications. - In practice this means that the value of constants must not change, and - that old values may not be reused for new constants. - ************************************************************************* -*/ - -#ifndef __ZMQ_H_INCLUDED__ -#define __ZMQ_H_INCLUDED__ - -/* Version macros for compile-time API version detection */ -#define ZMQ_VERSION_MAJOR 4 -#define ZMQ_VERSION_MINOR 2 -#define ZMQ_VERSION_PATCH 0 - -#define ZMQ_MAKE_VERSION(major, minor, patch) \ - ((major) * 10000 + (minor) * 100 + (patch)) -#define ZMQ_VERSION \ - ZMQ_MAKE_VERSION(ZMQ_VERSION_MAJOR, ZMQ_VERSION_MINOR, ZMQ_VERSION_PATCH) - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined _WIN32_WCE -#include -#endif -#include -#include -#if defined _WIN32 -// Set target version to Windows Server 2008, Windows Vista or higher. -// Windows XP (0x0501) is supported but without client & server socket types. -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0600 -#endif - -#ifdef __MINGW32__ -// Require Windows XP or higher with MinGW for getaddrinfo(). -#if(_WIN32_WINNT >= 0x0600) -#else -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0600 -#endif -#endif -#include -#endif - -/* Handle DSO symbol visibility */ -#if defined _WIN32 -# if defined ZMQ_STATIC -# define ZMQ_EXPORT -# elif defined DLL_EXPORT -# define ZMQ_EXPORT __declspec(dllexport) -# else -# define ZMQ_EXPORT __declspec(dllimport) -# endif -#else -# if defined __SUNPRO_C || defined __SUNPRO_CC -# define ZMQ_EXPORT __global -# elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER -# define ZMQ_EXPORT __attribute__ ((visibility("default"))) -# else -# define ZMQ_EXPORT -# endif -#endif - -/* Define integer types needed for event interface */ -#define ZMQ_DEFINED_STDINT 1 -#if defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_OPENVMS -# include -#elif defined _MSC_VER && _MSC_VER < 1600 -# ifndef int32_t - typedef __int32 int32_t; -# endif -# ifndef uint16_t - typedef unsigned __int16 uint16_t; -# endif -# ifndef uint8_t - typedef unsigned __int8 uint8_t; -# endif -#else -# include -#endif - - -/******************************************************************************/ -/* 0MQ errors. */ -/******************************************************************************/ - -/* A number random enough not to collide with different errno ranges on */ -/* different OSes. The assumption is that error_t is at least 32-bit type. */ -#define ZMQ_HAUSNUMERO 156384712 - -/* On Windows platform some of the standard POSIX errnos are not defined. */ -#ifndef ENOTSUP -#define ENOTSUP (ZMQ_HAUSNUMERO + 1) -#endif -#ifndef EPROTONOSUPPORT -#define EPROTONOSUPPORT (ZMQ_HAUSNUMERO + 2) -#endif -#ifndef ENOBUFS -#define ENOBUFS (ZMQ_HAUSNUMERO + 3) -#endif -#ifndef ENETDOWN -#define ENETDOWN (ZMQ_HAUSNUMERO + 4) -#endif -#ifndef EADDRINUSE -#define EADDRINUSE (ZMQ_HAUSNUMERO + 5) -#endif -#ifndef EADDRNOTAVAIL -#define EADDRNOTAVAIL (ZMQ_HAUSNUMERO + 6) -#endif -#ifndef ECONNREFUSED -#define ECONNREFUSED (ZMQ_HAUSNUMERO + 7) -#endif -#ifndef EINPROGRESS -#define EINPROGRESS (ZMQ_HAUSNUMERO + 8) -#endif -#ifndef ENOTSOCK -#define ENOTSOCK (ZMQ_HAUSNUMERO + 9) -#endif -#ifndef EMSGSIZE -#define EMSGSIZE (ZMQ_HAUSNUMERO + 10) -#endif -#ifndef EAFNOSUPPORT -#define EAFNOSUPPORT (ZMQ_HAUSNUMERO + 11) -#endif -#ifndef ENETUNREACH -#define ENETUNREACH (ZMQ_HAUSNUMERO + 12) -#endif -#ifndef ECONNABORTED -#define ECONNABORTED (ZMQ_HAUSNUMERO + 13) -#endif -#ifndef ECONNRESET -#define ECONNRESET (ZMQ_HAUSNUMERO + 14) -#endif -#ifndef ENOTCONN -#define ENOTCONN (ZMQ_HAUSNUMERO + 15) -#endif -#ifndef ETIMEDOUT -#define ETIMEDOUT (ZMQ_HAUSNUMERO + 16) -#endif -#ifndef EHOSTUNREACH -#define EHOSTUNREACH (ZMQ_HAUSNUMERO + 17) -#endif -#ifndef ENETRESET -#define ENETRESET (ZMQ_HAUSNUMERO + 18) -#endif - -/* Native 0MQ error codes. */ -#define EFSM (ZMQ_HAUSNUMERO + 51) -#define ENOCOMPATPROTO (ZMQ_HAUSNUMERO + 52) -#define ETERM (ZMQ_HAUSNUMERO + 53) -#define EMTHREAD (ZMQ_HAUSNUMERO + 54) - -/* This function retrieves the errno as it is known to 0MQ library. The goal */ -/* of this function is to make the code 100% portable, including where 0MQ */ -/* compiled with certain CRT library (on Windows) is linked to an */ -/* application that uses different CRT library. */ -ZMQ_EXPORT int zmq_errno (void); - -/* Resolves system errors and 0MQ errors to human-readable string. */ -ZMQ_EXPORT const char *zmq_strerror (int errnum); - -/* Run-time API version detection */ -ZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch); - -/******************************************************************************/ -/* 0MQ infrastructure (a.k.a. context) initialisation & termination. */ -/******************************************************************************/ - -/* Context options */ -#define ZMQ_IO_THREADS 1 -#define ZMQ_MAX_SOCKETS 2 -#define ZMQ_SOCKET_LIMIT 3 -#define ZMQ_THREAD_PRIORITY 3 -#define ZMQ_THREAD_SCHED_POLICY 4 -#define ZMQ_MAX_MSGSZ 5 - -/* Default for new contexts */ -#define ZMQ_IO_THREADS_DFLT 1 -#define ZMQ_MAX_SOCKETS_DFLT 1023 -#define ZMQ_THREAD_PRIORITY_DFLT -1 -#define ZMQ_THREAD_SCHED_POLICY_DFLT -1 - -ZMQ_EXPORT void *zmq_ctx_new (void); -ZMQ_EXPORT int zmq_ctx_term (void *context); -ZMQ_EXPORT int zmq_ctx_shutdown (void *context); -ZMQ_EXPORT int zmq_ctx_set (void *context, int option, int optval); -ZMQ_EXPORT int zmq_ctx_get (void *context, int option); - -/* Old (legacy) API */ -ZMQ_EXPORT void *zmq_init (int io_threads); -ZMQ_EXPORT int zmq_term (void *context); -ZMQ_EXPORT int zmq_ctx_destroy (void *context); - - -/******************************************************************************/ -/* 0MQ message definition. */ -/******************************************************************************/ - -/* union here ensures correct alignment on architectures that require it, e.g. - * SPARC - */ -typedef union zmq_msg_t {unsigned char _ [64]; void *p; } zmq_msg_t; - -typedef void (zmq_free_fn) (void *data, void *hint); - -ZMQ_EXPORT int zmq_msg_init (zmq_msg_t *msg); -ZMQ_EXPORT int zmq_msg_init_size (zmq_msg_t *msg, size_t size); -ZMQ_EXPORT int zmq_msg_init_data (zmq_msg_t *msg, void *data, - size_t size, zmq_free_fn *ffn, void *hint); -ZMQ_EXPORT int zmq_msg_send (zmq_msg_t *msg, void *s, int flags); -ZMQ_EXPORT int zmq_msg_recv (zmq_msg_t *msg, void *s, int flags); -ZMQ_EXPORT int zmq_msg_close (zmq_msg_t *msg); -ZMQ_EXPORT int zmq_msg_move (zmq_msg_t *dest, zmq_msg_t *src); -ZMQ_EXPORT int zmq_msg_copy (zmq_msg_t *dest, zmq_msg_t *src); -ZMQ_EXPORT void *zmq_msg_data (zmq_msg_t *msg); -ZMQ_EXPORT size_t zmq_msg_size (zmq_msg_t *msg); -ZMQ_EXPORT int zmq_msg_more (zmq_msg_t *msg); -ZMQ_EXPORT int zmq_msg_get (zmq_msg_t *msg, int property); -ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int property, int optval); -ZMQ_EXPORT const char *zmq_msg_gets (zmq_msg_t *msg, const char *property); - -/******************************************************************************/ -/* 0MQ socket definition. */ -/******************************************************************************/ - -/* Socket types. */ -#define ZMQ_PAIR 0 -#define ZMQ_PUB 1 -#define ZMQ_SUB 2 -#define ZMQ_REQ 3 -#define ZMQ_REP 4 -#define ZMQ_DEALER 5 -#define ZMQ_ROUTER 6 -#define ZMQ_PULL 7 -#define ZMQ_PUSH 8 -#define ZMQ_XPUB 9 -#define ZMQ_XSUB 10 -#define ZMQ_STREAM 11 - -/* Deprecated aliases */ -#define ZMQ_XREQ ZMQ_DEALER -#define ZMQ_XREP ZMQ_ROUTER - -/* Socket options. */ -#define ZMQ_AFFINITY 4 -#define ZMQ_IDENTITY 5 -#define ZMQ_SUBSCRIBE 6 -#define ZMQ_UNSUBSCRIBE 7 -#define ZMQ_RATE 8 -#define ZMQ_RECOVERY_IVL 9 -#define ZMQ_SNDBUF 11 -#define ZMQ_RCVBUF 12 -#define ZMQ_RCVMORE 13 -#define ZMQ_FD 14 -#define ZMQ_EVENTS 15 -#define ZMQ_TYPE 16 -#define ZMQ_LINGER 17 -#define ZMQ_RECONNECT_IVL 18 -#define ZMQ_BACKLOG 19 -#define ZMQ_RECONNECT_IVL_MAX 21 -#define ZMQ_MAXMSGSIZE 22 -#define ZMQ_SNDHWM 23 -#define ZMQ_RCVHWM 24 -#define ZMQ_MULTICAST_HOPS 25 -#define ZMQ_RCVTIMEO 27 -#define ZMQ_SNDTIMEO 28 -#define ZMQ_LAST_ENDPOINT 32 -#define ZMQ_ROUTER_MANDATORY 33 -#define ZMQ_TCP_KEEPALIVE 34 -#define ZMQ_TCP_KEEPALIVE_CNT 35 -#define ZMQ_TCP_KEEPALIVE_IDLE 36 -#define ZMQ_TCP_KEEPALIVE_INTVL 37 -#define ZMQ_IMMEDIATE 39 -#define ZMQ_XPUB_VERBOSE 40 -#define ZMQ_ROUTER_RAW 41 -#define ZMQ_IPV6 42 -#define ZMQ_MECHANISM 43 -#define ZMQ_PLAIN_SERVER 44 -#define ZMQ_PLAIN_USERNAME 45 -#define ZMQ_PLAIN_PASSWORD 46 -#define ZMQ_CURVE_SERVER 47 -#define ZMQ_CURVE_PUBLICKEY 48 -#define ZMQ_CURVE_SECRETKEY 49 -#define ZMQ_CURVE_SERVERKEY 50 -#define ZMQ_PROBE_ROUTER 51 -#define ZMQ_REQ_CORRELATE 52 -#define ZMQ_REQ_RELAXED 53 -#define ZMQ_CONFLATE 54 -#define ZMQ_ZAP_DOMAIN 55 -#define ZMQ_ROUTER_HANDOVER 56 -#define ZMQ_TOS 57 -#define ZMQ_CONNECT_RID 61 -#define ZMQ_GSSAPI_SERVER 62 -#define ZMQ_GSSAPI_PRINCIPAL 63 -#define ZMQ_GSSAPI_SERVICE_PRINCIPAL 64 -#define ZMQ_GSSAPI_PLAINTEXT 65 -#define ZMQ_HANDSHAKE_IVL 66 -#define ZMQ_SOCKS_PROXY 68 -#define ZMQ_XPUB_NODROP 69 -// All options after this is for version 4.2 and still *draft* -// Subject to arbitrary change without notice -#define ZMQ_BLOCKY 70 -#define ZMQ_XPUB_MANUAL 71 -#define ZMQ_XPUB_WELCOME_MSG 72 -#define ZMQ_STREAM_NOTIFY 73 -#define ZMQ_INVERT_MATCHING 74 -#define ZMQ_HEARTBEAT_IVL 75 -#define ZMQ_HEARTBEAT_TTL 76 -#define ZMQ_HEARTBEAT_TIMEOUT 77 -#define ZMQ_XPUB_VERBOSER 78 -#define ZMQ_CONNECT_TIMEOUT 79 -#define ZMQ_TCP_MAXRT 80 -#define ZMQ_THREAD_SAFE 81 -#define ZMQ_MULTICAST_MAXTPDU 84 -#define ZMQ_VMCI_BUFFER_SIZE 85 -#define ZMQ_VMCI_BUFFER_MIN_SIZE 86 -#define ZMQ_VMCI_BUFFER_MAX_SIZE 87 -#define ZMQ_VMCI_CONNECT_TIMEOUT 88 -#define ZMQ_USE_FD 89 - -/* Message options */ -#define ZMQ_MORE 1 -#define ZMQ_SHARED 3 - -/* Send/recv options. */ -#define ZMQ_DONTWAIT 1 -#define ZMQ_SNDMORE 2 - -/* Security mechanisms */ -#define ZMQ_NULL 0 -#define ZMQ_PLAIN 1 -#define ZMQ_CURVE 2 -#define ZMQ_GSSAPI 3 - -/* RADIO-DISH protocol */ -#define ZMQ_GROUP_MAX_LENGTH 15 - -/* Deprecated options and aliases */ -#define ZMQ_TCP_ACCEPT_FILTER 38 -#define ZMQ_IPC_FILTER_PID 58 -#define ZMQ_IPC_FILTER_UID 59 -#define ZMQ_IPC_FILTER_GID 60 -#define ZMQ_IPV4ONLY 31 -#define ZMQ_DELAY_ATTACH_ON_CONNECT ZMQ_IMMEDIATE -#define ZMQ_NOBLOCK ZMQ_DONTWAIT -#define ZMQ_FAIL_UNROUTABLE ZMQ_ROUTER_MANDATORY -#define ZMQ_ROUTER_BEHAVIOR ZMQ_ROUTER_MANDATORY - -/* Deprecated Message options */ -#define ZMQ_SRCFD 2 - -/******************************************************************************/ -/* 0MQ socket events and monitoring */ -/******************************************************************************/ - -/* Socket transport events (TCP, IPC and TIPC only) */ - -#define ZMQ_EVENT_CONNECTED 0x0001 -#define ZMQ_EVENT_CONNECT_DELAYED 0x0002 -#define ZMQ_EVENT_CONNECT_RETRIED 0x0004 -#define ZMQ_EVENT_LISTENING 0x0008 -#define ZMQ_EVENT_BIND_FAILED 0x0010 -#define ZMQ_EVENT_ACCEPTED 0x0020 -#define ZMQ_EVENT_ACCEPT_FAILED 0x0040 -#define ZMQ_EVENT_CLOSED 0x0080 -#define ZMQ_EVENT_CLOSE_FAILED 0x0100 -#define ZMQ_EVENT_DISCONNECTED 0x0200 -#define ZMQ_EVENT_MONITOR_STOPPED 0x0400 -#define ZMQ_EVENT_ALL 0xFFFF - -ZMQ_EXPORT void *zmq_socket (void *, int type); -ZMQ_EXPORT int zmq_close (void *s); -ZMQ_EXPORT int zmq_setsockopt (void *s, int option, const void *optval, - size_t optvallen); -ZMQ_EXPORT int zmq_getsockopt (void *s, int option, void *optval, - size_t *optvallen); -ZMQ_EXPORT int zmq_bind (void *s, const char *addr); -ZMQ_EXPORT int zmq_connect (void *s, const char *addr); -ZMQ_EXPORT int zmq_unbind (void *s, const char *addr); -ZMQ_EXPORT int zmq_disconnect (void *s, const char *addr); -ZMQ_EXPORT int zmq_send (void *s, const void *buf, size_t len, int flags); -ZMQ_EXPORT int zmq_send_const (void *s, const void *buf, size_t len, int flags); -ZMQ_EXPORT int zmq_recv (void *s, void *buf, size_t len, int flags); -ZMQ_EXPORT int zmq_socket_monitor (void *s, const char *addr, int events); - - -/******************************************************************************/ -/* I/O multiplexing. */ -/******************************************************************************/ - -#define ZMQ_POLLIN 1 -#define ZMQ_POLLOUT 2 -#define ZMQ_POLLERR 4 -#define ZMQ_POLLPRI 8 - -typedef struct zmq_pollitem_t -{ - void *socket; -#if defined _WIN32 - SOCKET fd; -#else - int fd; -#endif - short events; - short revents; -} zmq_pollitem_t; - -#define ZMQ_POLLITEMS_DFLT 16 - -ZMQ_EXPORT int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout); - -/******************************************************************************/ -/* Message proxying */ -/******************************************************************************/ - -ZMQ_EXPORT int zmq_proxy (void *frontend, void *backend, void *capture); -ZMQ_EXPORT int zmq_proxy_steerable (void *frontend, void *backend, void *capture, void *control); - -/******************************************************************************/ -/* Probe library capabilities */ -/******************************************************************************/ - -#define ZMQ_HAS_CAPABILITIES 1 -ZMQ_EXPORT int zmq_has (const char *capability); - -/* Deprecated aliases */ -#define ZMQ_STREAMER 1 -#define ZMQ_FORWARDER 2 -#define ZMQ_QUEUE 3 - -/* Deprecated methods */ -ZMQ_EXPORT int zmq_device (int type, void *frontend, void *backend); -ZMQ_EXPORT int zmq_sendmsg (void *s, zmq_msg_t *msg, int flags); -ZMQ_EXPORT int zmq_recvmsg (void *s, zmq_msg_t *msg, int flags); -struct iovec; -ZMQ_EXPORT int zmq_sendiov (void *s, struct iovec *iov, size_t count, int flags); -ZMQ_EXPORT int zmq_recviov (void *s, struct iovec *iov, size_t *count, int flags); - -/******************************************************************************/ -/* Encryption functions */ -/******************************************************************************/ - -/* Encode data with Z85 encoding. Returns encoded data */ -ZMQ_EXPORT char *zmq_z85_encode (char *dest, const uint8_t *data, size_t size); - -/* Decode data with Z85 encoding. Returns decoded data */ -ZMQ_EXPORT uint8_t *zmq_z85_decode (uint8_t *dest, const char *string); - -/* Generate z85-encoded public and private keypair with tweetnacl/libsodium. */ -/* Returns 0 on success. */ -ZMQ_EXPORT int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key); - -/* Derive the z85-encoded public key from the z85-encoded secret key. */ -/* Returns 0 on success. */ -ZMQ_EXPORT int zmq_curve_public (char *z85_public_key, const char *z85_secret_key); - -/******************************************************************************/ -/* Atomic utility methods */ -/******************************************************************************/ - -ZMQ_EXPORT void *zmq_atomic_counter_new (void); -ZMQ_EXPORT void zmq_atomic_counter_set (void *counter, int value); -ZMQ_EXPORT int zmq_atomic_counter_inc (void *counter); -ZMQ_EXPORT int zmq_atomic_counter_dec (void *counter); -ZMQ_EXPORT int zmq_atomic_counter_value (void *counter); -ZMQ_EXPORT void zmq_atomic_counter_destroy (void **counter_p); - - -/******************************************************************************/ -/* These functions are not documented by man pages -- use at your own risk. */ -/* If you need these to be part of the formal ZMQ API, then (a) write a man */ -/* page, and (b) write a test case in tests. */ -/******************************************************************************/ - -/* Helper functions are used by perf tests so that they don't have to care */ -/* about minutiae of time-related functions on different OS platforms. */ - -/* Starts the stopwatch. Returns the handle to the watch. */ -ZMQ_EXPORT void *zmq_stopwatch_start (void); - -/* Stops the stopwatch. Returns the number of microseconds elapsed since */ -/* the stopwatch was started. */ -ZMQ_EXPORT unsigned long zmq_stopwatch_stop (void *watch_); - -/* Sleeps for specified number of seconds. */ -ZMQ_EXPORT void zmq_sleep (int seconds_); - -typedef void (zmq_thread_fn) (void*); - -/* Start a thread. Returns a handle to the thread. */ -ZMQ_EXPORT void *zmq_threadstart (zmq_thread_fn* func, void* arg); - -/* Wait for thread to complete then free up resources. */ -ZMQ_EXPORT void zmq_threadclose (void* thread); - - -/******************************************************************************/ -/* These functions are DRAFT and disabled in stable releases, and subject to */ -/* change at ANY time until declared stable. */ -/******************************************************************************/ - -#ifdef ZMQ_BUILD_DRAFT_API - -/* DRAFT Socket types. */ -#define ZMQ_SERVER 12 -#define ZMQ_CLIENT 13 -#define ZMQ_RADIO 14 -#define ZMQ_DISH 15 -#define ZMQ_GATHER 16 -#define ZMQ_SCATTER 17 -#define ZMQ_DGRAM 18 - -/* DRAFT Socket methods. */ -ZMQ_EXPORT int zmq_join (void *s, const char *group); -ZMQ_EXPORT int zmq_leave (void *s, const char *group); - -/* DRAFT Msg methods. */ -ZMQ_EXPORT int zmq_msg_set_routing_id(zmq_msg_t *msg, uint32_t routing_id); -ZMQ_EXPORT uint32_t zmq_msg_routing_id(zmq_msg_t *msg); -ZMQ_EXPORT int zmq_msg_set_group(zmq_msg_t *msg, const char *group); -ZMQ_EXPORT const char *zmq_msg_group(zmq_msg_t *msg); - -/******************************************************************************/ -/* Poller polling on sockets,fd and thread-safe sockets */ -/******************************************************************************/ - -#define ZMQ_HAVE_POLLER - -typedef struct zmq_poller_event_t -{ - void *socket; -#if defined _WIN32 - SOCKET fd; -#else - int fd; -#endif - void *user_data; - short events; -} zmq_poller_event_t; - -ZMQ_EXPORT void *zmq_poller_new (void); -ZMQ_EXPORT int zmq_poller_destroy (void **poller_p); -ZMQ_EXPORT int zmq_poller_add (void *poller, void *socket, void *user_data, short events); -ZMQ_EXPORT int zmq_poller_modify (void *poller, void *socket, short events); -ZMQ_EXPORT int zmq_poller_remove (void *poller, void *socket); -ZMQ_EXPORT int zmq_poller_wait (void *poller, zmq_poller_event_t *event, long timeout); - -#if defined _WIN32 -ZMQ_EXPORT int zmq_poller_add_fd (void *poller, SOCKET fd, void *user_data, short events); -ZMQ_EXPORT int zmq_poller_modify_fd (void *poller, SOCKET fd, short events); -ZMQ_EXPORT int zmq_poller_remove_fd (void *poller, SOCKET fd); -#else -ZMQ_EXPORT int zmq_poller_add_fd (void *poller, int fd, void *user_data, short events); -ZMQ_EXPORT int zmq_poller_modify_fd (void *poller, int fd, short events); -ZMQ_EXPORT int zmq_poller_remove_fd (void *poller, int fd); -#endif - -/******************************************************************************/ -/* Scheduling timers */ -/******************************************************************************/ - -#define ZMQ_HAVE_TIMERS - -typedef void (zmq_timer_fn)(int timer_id, void *arg); - -ZMQ_EXPORT void *zmq_timers_new (void); -ZMQ_EXPORT int zmq_timers_destroy (void **timers_p); -ZMQ_EXPORT int zmq_timers_add (void *timers, size_t interval, zmq_timer_fn handler, void *arg); -ZMQ_EXPORT int zmq_timers_cancel (void *timers, int timer_id); -ZMQ_EXPORT int zmq_timers_set_interval (void *timers, int timer_id, size_t interval); -ZMQ_EXPORT int zmq_timers_reset (void *timers, int timer_id); -ZMQ_EXPORT long zmq_timers_timeout (void *timers); -ZMQ_EXPORT int zmq_timers_execute (void *timers); - -#endif // ZMQ_BUILD_DRAFT_API - - -#undef ZMQ_EXPORT - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zmq_utils.h b/phonelibs/zmq/aarch64/include/zmq_utils.h deleted file mode 100644 index f29638d5539414..00000000000000 --- a/phonelibs/zmq/aarch64/include/zmq_utils.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/* This file is deprecated, and all its functionality provided by zmq.h */ -/* Note that -Wpedantic compilation requires GCC to avoid using its custom - extensions such as #warning, hence the trick below. Also, pragmas for - warnings or other messages are not standard, not portable, and not all - compilers even have an equivalent concept. - So in the worst case, this include file is treated as silently empty. */ - -#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER) -#if defined(__GNUC__) || defined(__GNUG__) -#pragma GCC diagnostic push -#pragma GCC diagnostic warning "-Wcpp" -#pragma GCC diagnostic ignored "-Werror" -#pragma GCC diagnostic ignored "-Wall" -#endif -#pragma message("Warning: zmq_utils.h is deprecated. All its functionality is provided by zmq.h.") -#if defined(__GNUC__) || defined(__GNUG__) -#pragma GCC diagnostic pop -#endif -#endif diff --git a/phonelibs/zmq/aarch64/include/zmsg.h b/phonelibs/zmq/aarch64/include/zmsg.h deleted file mode 100644 index c6ab16c66e953c..00000000000000 --- a/phonelibs/zmq/aarch64/include/zmsg.h +++ /dev/null @@ -1,285 +0,0 @@ -/* ========================================================================= - zmsg - working with multipart messages - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZMSG_H_INCLUDED__ -#define __ZMSG_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zmsg.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// Create a new empty message object -CZMQ_EXPORT zmsg_t * - zmsg_new (void); - -// Receive message from socket, returns zmsg_t object or NULL if the recv -// was interrupted. Does a blocking recv. If you want to not block then use -// the zloop class or zmsg_recv_nowait or zmq_poll to check for socket input -// before receiving. -CZMQ_EXPORT zmsg_t * - zmsg_recv (void *source); - -// Load/append an open file into new message, return the message. -// Returns NULL if the message could not be loaded. -CZMQ_EXPORT zmsg_t * - zmsg_load (FILE *file); - -// Decodes a serialized message frame created by zmsg_encode () and returns -// a new zmsg_t object. Returns NULL if the frame was badly formatted or -// there was insufficient memory to work. -CZMQ_EXPORT zmsg_t * - zmsg_decode (zframe_t *frame); - -// Generate a signal message encoding the given status. A signal is a short -// message carrying a 1-byte success/failure code (by convention, 0 means -// OK). Signals are encoded to be distinguishable from "normal" messages. -CZMQ_EXPORT zmsg_t * - zmsg_new_signal (byte status); - -// Destroy a message object and all frames it contains -CZMQ_EXPORT void - zmsg_destroy (zmsg_t **self_p); - -// Send message to destination socket, and destroy the message after sending -// it successfully. If the message has no frames, sends nothing but destroys -// the message anyhow. Nullifies the caller's reference to the message (as -// it is a destructor). -CZMQ_EXPORT int - zmsg_send (zmsg_t **self_p, void *dest); - -// Send message to destination socket as part of a multipart sequence, and -// destroy the message after sending it successfully. Note that after a -// zmsg_sendm, you must call zmsg_send or another method that sends a final -// message part. If the message has no frames, sends nothing but destroys -// the message anyhow. Nullifies the caller's reference to the message (as -// it is a destructor). -CZMQ_EXPORT int - zmsg_sendm (zmsg_t **self_p, void *dest); - -// Return size of message, i.e. number of frames (0 or more). -CZMQ_EXPORT size_t - zmsg_size (zmsg_t *self); - -// Return total size of all frames in message. -CZMQ_EXPORT size_t - zmsg_content_size (zmsg_t *self); - -// Push frame to the front of the message, i.e. before all other frames. -// Message takes ownership of frame, will destroy it when message is sent. -// Returns 0 on success, -1 on error. Deprecates zmsg_push, which did not -// nullify the caller's frame reference. -CZMQ_EXPORT int - zmsg_prepend (zmsg_t *self, zframe_t **frame_p); - -// Add frame to the end of the message, i.e. after all other frames. -// Message takes ownership of frame, will destroy it when message is sent. -// Returns 0 on success. Deprecates zmsg_add, which did not nullify the -// caller's frame reference. -CZMQ_EXPORT int - zmsg_append (zmsg_t *self, zframe_t **frame_p); - -// Remove first frame from message, if any. Returns frame, or NULL. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zframe_t * - zmsg_pop (zmsg_t *self); - -// Push block of memory to front of message, as a new frame. -// Returns 0 on success, -1 on error. -CZMQ_EXPORT int - zmsg_pushmem (zmsg_t *self, const void *data, size_t size); - -// Add block of memory to the end of the message, as a new frame. -// Returns 0 on success, -1 on error. -CZMQ_EXPORT int - zmsg_addmem (zmsg_t *self, const void *data, size_t size); - -// Push string as new frame to front of message. -// Returns 0 on success, -1 on error. -CZMQ_EXPORT int - zmsg_pushstr (zmsg_t *self, const char *string); - -// Push string as new frame to end of message. -// Returns 0 on success, -1 on error. -CZMQ_EXPORT int - zmsg_addstr (zmsg_t *self, const char *string); - -// Push formatted string as new frame to front of message. -// Returns 0 on success, -1 on error. -CZMQ_EXPORT int - zmsg_pushstrf (zmsg_t *self, const char *format, ...); - -// Push formatted string as new frame to end of message. -// Returns 0 on success, -1 on error. -CZMQ_EXPORT int - zmsg_addstrf (zmsg_t *self, const char *format, ...); - -// Pop frame off front of message, return as fresh string. If there were -// no more frames in the message, returns NULL. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zmsg_popstr (zmsg_t *self); - -// Push encoded message as a new frame. Message takes ownership of -// submessage, so the original is destroyed in this call. Returns 0 on -// success, -1 on error. -CZMQ_EXPORT int - zmsg_addmsg (zmsg_t *self, zmsg_t **msg_p); - -// Remove first submessage from message, if any. Returns zmsg_t, or NULL if -// decoding was not successful. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zmsg_t * - zmsg_popmsg (zmsg_t *self); - -// Remove specified frame from list, if present. Does not destroy frame. -CZMQ_EXPORT void - zmsg_remove (zmsg_t *self, zframe_t *frame); - -// Set cursor to first frame in message. Returns frame, or NULL, if the -// message is empty. Use this to navigate the frames as a list. -CZMQ_EXPORT zframe_t * - zmsg_first (zmsg_t *self); - -// Return the next frame. If there are no more frames, returns NULL. To move -// to the first frame call zmsg_first(). Advances the cursor. -CZMQ_EXPORT zframe_t * - zmsg_next (zmsg_t *self); - -// Return the last frame. If there are no frames, returns NULL. -CZMQ_EXPORT zframe_t * - zmsg_last (zmsg_t *self); - -// Save message to an open file, return 0 if OK, else -1. The message is -// saved as a series of frames, each with length and data. Note that the -// file is NOT guaranteed to be portable between operating systems, not -// versions of CZMQ. The file format is at present undocumented and liable -// to arbitrary change. -CZMQ_EXPORT int - zmsg_save (zmsg_t *self, FILE *file); - -// Serialize multipart message to a single message frame. Use this method -// to send structured messages across transports that do not support -// multipart data. Allocates and returns a new frame containing the -// serialized message. To decode a serialized message frame, use -// zmsg_decode (). -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zframe_t * - zmsg_encode (zmsg_t *self); - -// Create copy of message, as new message object. Returns a fresh zmsg_t -// object. If message is null, or memory was exhausted, returns null. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zmsg_t * - zmsg_dup (zmsg_t *self); - -// Send message to zsys log sink (may be stdout, or system facility as -// configured by zsys_set_logstream). -CZMQ_EXPORT void - zmsg_print (zmsg_t *self); - -// Return true if the two messages have the same number of frames and each -// frame in the first message is identical to the corresponding frame in the -// other message. As with zframe_eq, return false if either message is NULL. -CZMQ_EXPORT bool - zmsg_eq (zmsg_t *self, zmsg_t *other); - -// Return signal value, 0 or greater, if message is a signal, -1 if not. -CZMQ_EXPORT int - zmsg_signal (zmsg_t *self); - -// Probe the supplied object, and report if it looks like a zmsg_t. -CZMQ_EXPORT bool - zmsg_is (void *self); - -// Self test of this class. -CZMQ_EXPORT void - zmsg_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Return message routing ID, if the message came from a ZMQ_SERVER socket. -// Else returns zero. -CZMQ_EXPORT uint32_t - zmsg_routing_id (zmsg_t *self); - -// *** Draft method, for development use, may change without warning *** -// Set routing ID on message. This is used if/when the message is sent to a -// ZMQ_SERVER socket. -CZMQ_EXPORT void - zmsg_set_routing_id (zmsg_t *self, uint32_t routing_id); - -#endif // CZMQ_BUILD_DRAFT_API -// @ignore -CZMQ_EXPORT int - zmsg_pushstrf (zmsg_t *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int - zmsg_addstrf (zmsg_t *self, const char *format, ...) CHECK_PRINTF (2); -// @end - - -// DEPRECATED as over-engineered, poor style -// Pop frame off front of message, caller now owns frame -// If next frame is empty, pops and destroys that empty frame. -CZMQ_EXPORT zframe_t * - zmsg_unwrap (zmsg_t *self); - -// DEPRECATED as poor style -- callers should use zloop or zpoller -// Receive message from socket, returns zmsg_t object, or NULL either if -// there was no input waiting, or the recv was interrupted. -CZMQ_EXPORT zmsg_t * - zmsg_recv_nowait (void *source); - -// DEPRECATED as unsafe -- does not nullify frame reference. -// Push frame plus empty frame to front of message, before first frame. -// Message takes ownership of frame, will destroy it when message is sent. -CZMQ_EXPORT void - zmsg_wrap (zmsg_t *self, zframe_t *frame); - -// DEPRECATED - will be removed for next + 1 stable release -// Add frame to the front of the message, i.e. before all other frames. -// Message takes ownership of frame, will destroy it when message is sent. -// Returns 0 on success, -1 on error. -CZMQ_EXPORT int - zmsg_push (zmsg_t *self, zframe_t *frame); - -// DEPRECATED - will be removed for next stable release -CZMQ_EXPORT int - zmsg_add (zmsg_t *self, zframe_t *frame); - -// DEPRECATED as inconsistent; breaks principle that logging should all go -// to a single destination. -// Print message to open stream -// Truncates to first 10 frames, for readability. -CZMQ_EXPORT void - zmsg_fprint (zmsg_t *self, FILE *file); - -// Compiler hints -CZMQ_EXPORT int zmsg_addstrf (zmsg_t *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int zmsg_pushstrf (zmsg_t *self, const char *format, ...) CHECK_PRINTF (2); - -#ifdef __cplusplus -} -#endif - -// Deprecated method aliases -#define zmsg_dump(s) zmsg_print(s) -#define zmsg_dump_to_stream(s,F) zmsg_fprint(s,F) - -#endif diff --git a/phonelibs/zmq/aarch64/include/zmutex.h b/phonelibs/zmq/aarch64/include/zmutex.h deleted file mode 100644 index cba315999b7598..00000000000000 --- a/phonelibs/zmq/aarch64/include/zmutex.h +++ /dev/null @@ -1,55 +0,0 @@ -/* ========================================================================= - zmutex - working with mutexes - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZMUTEX_H_INCLUDED__ -#define __ZMUTEX_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// This is a deprecated class, and will be removed over time. It is -// provided in stable builds to support old applications. You should -// stop using this class, and migrate any code that is still using it. - -// Create a new mutex container -CZMQ_EXPORT zmutex_t * - zmutex_new (void); - -// Destroy a mutex container -CZMQ_EXPORT void - zmutex_destroy (zmutex_t **self_p); - -// Lock mutex -CZMQ_EXPORT void - zmutex_lock (zmutex_t *self); - -// Unlock mutex -CZMQ_EXPORT void - zmutex_unlock (zmutex_t *self); - -// Try to lock mutex -CZMQ_EXPORT int - zmutex_try_lock (zmutex_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zmutex_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zpoller.h b/phonelibs/zmq/aarch64/include/zpoller.h deleted file mode 100644 index 3756a935a64008..00000000000000 --- a/phonelibs/zmq/aarch64/include/zpoller.h +++ /dev/null @@ -1,92 +0,0 @@ -/* ========================================================================= - zpoller - trivial socket poller class - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __zpoller_H_INCLUDED__ -#define __zpoller_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zpoller.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// Create new poller, specifying zero or more readers. The list of -// readers ends in a NULL. Each reader can be a zsock_t instance, a -// zactor_t instance, a libzmq socket (void *), or a file handle. -CZMQ_EXPORT zpoller_t * - zpoller_new (void *reader, ...); - -// Destroy a poller -CZMQ_EXPORT void - zpoller_destroy (zpoller_t **self_p); - -// Add a reader to be polled. Returns 0 if OK, -1 on failure. The reader may -// be a libzmq void * socket, a zsock_t instance, or a zactor_t instance. -CZMQ_EXPORT int - zpoller_add (zpoller_t *self, void *reader); - -// Remove a reader from the poller; returns 0 if OK, -1 on failure. The reader -// must have been passed during construction, or in an zpoller_add () call. -CZMQ_EXPORT int - zpoller_remove (zpoller_t *self, void *reader); - -// Poll the registered readers for I/O, return first reader that has input. -// The reader will be a libzmq void * socket, or a zsock_t or zactor_t -// instance as specified in zpoller_new/zpoller_add. The timeout should be -// zero or greater, or -1 to wait indefinitely. Socket priority is defined -// by their order in the poll list. If you need a balanced poll, use the low -// level zmq_poll method directly. If the poll call was interrupted (SIGINT), -// or the ZMQ context was destroyed, or the timeout expired, returns NULL. -// You can test the actual exit condition by calling zpoller_expired () and -// zpoller_terminated (). The timeout is in msec. -CZMQ_EXPORT void * - zpoller_wait (zpoller_t *self, int timeout); - -// Return true if the last zpoller_wait () call ended because the timeout -// expired, without any error. -CZMQ_EXPORT bool - zpoller_expired (zpoller_t *self); - -// Return true if the last zpoller_wait () call ended because the process -// was interrupted, or the parent context was destroyed. -CZMQ_EXPORT bool - zpoller_terminated (zpoller_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zpoller_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// By default the poller stops if the process receives a SIGINT or SIGTERM -// signal. This makes it impossible to shut-down message based architectures -// like zactors. This method lets you switch off break handling. The default -// nonstop setting is off (false). -CZMQ_EXPORT void - zpoller_set_nonstop (zpoller_t *self, bool nonstop); - -#endif // CZMQ_BUILD_DRAFT_API -// @end - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/phonelibs/zmq/aarch64/include/zproc.h b/phonelibs/zmq/aarch64/include/zproc.h deleted file mode 100644 index a2e1b3dd9913c6..00000000000000 --- a/phonelibs/zmq/aarch64/include/zproc.h +++ /dev/null @@ -1,179 +0,0 @@ -/* ========================================================================= - zproc - process configuration and status - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef ZPROC_H_INCLUDED -#define ZPROC_H_INCLUDED - -#ifdef __cplusplus -extern "C" { -#endif - - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zproc.api" to make changes. -// @interface -// This is a draft class, and may change without notice. It is disabled in -// stable builds by default. If you use this in applications, please ask -// for it to be pushed to stable state. Use --enable-drafts to enable. -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Returns CZMQ version as a single 6-digit integer encoding the major -// version (x 10000), the minor version (x 100) and the patch. -CZMQ_EXPORT int - zproc_czmq_version (void); - -// *** Draft method, for development use, may change without warning *** -// Returns true if the process received a SIGINT or SIGTERM signal. -// It is good practice to use this method to exit any infinite loop -// processing messages. -CZMQ_EXPORT bool - zproc_interrupted (void); - -// *** Draft method, for development use, may change without warning *** -// Returns true if the underlying libzmq supports CURVE security. -CZMQ_EXPORT bool - zproc_has_curve (void); - -// *** Draft method, for development use, may change without warning *** -// Return current host name, for use in public tcp:// endpoints. -// If the host name is not resolvable, returns NULL. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zproc_hostname (void); - -// *** Draft method, for development use, may change without warning *** -// Move the current process into the background. The precise effect -// depends on the operating system. On POSIX boxes, moves to a specified -// working directory (if specified), closes all file handles, reopens -// stdin, stdout, and stderr to the null device, and sets the process to -// ignore SIGHUP. On Windows, does nothing. Returns 0 if OK, -1 if there -// was an error. -CZMQ_EXPORT void - zproc_daemonize (const char *workdir); - -// *** Draft method, for development use, may change without warning *** -// Drop the process ID into the lockfile, with exclusive lock, and -// switch the process to the specified group and/or user. Any of the -// arguments may be null, indicating a no-op. Returns 0 on success, -// -1 on failure. Note if you combine this with zsys_daemonize, run -// after, not before that method, or the lockfile will hold the wrong -// process ID. -CZMQ_EXPORT void - zproc_run_as (const char *lockfile, const char *group, const char *user); - -// *** Draft method, for development use, may change without warning *** -// Configure the number of I/O threads that ZeroMQ will use. A good -// rule of thumb is one thread per gigabit of traffic in or out. The -// default is 1, sufficient for most applications. If the environment -// variable ZSYS_IO_THREADS is defined, that provides the default. -// Note that this method is valid only before any socket is created. -CZMQ_EXPORT void - zproc_set_io_threads (size_t io_threads); - -// *** Draft method, for development use, may change without warning *** -// Configure the number of sockets that ZeroMQ will allow. The default -// is 1024. The actual limit depends on the system, and you can query it -// by using zsys_socket_limit (). A value of zero means "maximum". -// Note that this method is valid only before any socket is created. -CZMQ_EXPORT void - zproc_set_max_sockets (size_t max_sockets); - -// *** Draft method, for development use, may change without warning *** -// Set network interface name to use for broadcasts, particularly zbeacon. -// This lets the interface be configured for test environments where required. -// For example, on Mac OS X, zbeacon cannot bind to 255.255.255.255 which is -// the default when there is no specified interface. If the environment -// variable ZSYS_INTERFACE is set, use that as the default interface name. -// Setting the interface to "*" means "use all available interfaces". -CZMQ_EXPORT void - zproc_set_biface (const char *value); - -// *** Draft method, for development use, may change without warning *** -// Return network interface to use for broadcasts, or "" if none was set. -CZMQ_EXPORT const char * - zproc_biface (void); - -// *** Draft method, for development use, may change without warning *** -// Set log identity, which is a string that prefixes all log messages sent -// by this process. The log identity defaults to the environment variable -// ZSYS_LOGIDENT, if that is set. -CZMQ_EXPORT void - zproc_set_log_ident (const char *value); - -// *** Draft method, for development use, may change without warning *** -// Sends log output to a PUB socket bound to the specified endpoint. To -// collect such log output, create a SUB socket, subscribe to the traffic -// you care about, and connect to the endpoint. Log traffic is sent as a -// single string frame, in the same format as when sent to stdout. The -// log system supports a single sender; multiple calls to this method will -// bind the same sender to multiple endpoints. To disable the sender, call -// this method with a null argument. -CZMQ_EXPORT void - zproc_set_log_sender (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Enable or disable logging to the system facility (syslog on POSIX boxes, -// event log on Windows). By default this is disabled. -CZMQ_EXPORT void - zproc_set_log_system (bool logsystem); - -// *** Draft method, for development use, may change without warning *** -// Log error condition - highest priority -CZMQ_EXPORT void - zproc_log_error (const char *format, ...); - -// *** Draft method, for development use, may change without warning *** -// Log warning condition - high priority -CZMQ_EXPORT void - zproc_log_warning (const char *format, ...); - -// *** Draft method, for development use, may change without warning *** -// Log normal, but significant, condition - normal priority -CZMQ_EXPORT void - zproc_log_notice (const char *format, ...); - -// *** Draft method, for development use, may change without warning *** -// Log informational message - low priority -CZMQ_EXPORT void - zproc_log_info (const char *format, ...); - -// *** Draft method, for development use, may change without warning *** -// Log debug-level message - lowest priority -CZMQ_EXPORT void - zproc_log_debug (const char *format, ...); - -// *** Draft method, for development use, may change without warning *** -// Self test of this class. -CZMQ_EXPORT void - zproc_test (bool verbose); - -#endif // CZMQ_BUILD_DRAFT_API -// @ignore -CZMQ_EXPORT void - zproc_log_error (const char *format, ...) CHECK_PRINTF (1); -CZMQ_EXPORT void - zproc_log_warning (const char *format, ...) CHECK_PRINTF (1); -CZMQ_EXPORT void - zproc_log_notice (const char *format, ...) CHECK_PRINTF (1); -CZMQ_EXPORT void - zproc_log_info (const char *format, ...) CHECK_PRINTF (1); -CZMQ_EXPORT void - zproc_log_debug (const char *format, ...) CHECK_PRINTF (1); -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zproxy.h b/phonelibs/zmq/aarch64/include/zproxy.h deleted file mode 100644 index f672c5e72417a5..00000000000000 --- a/phonelibs/zmq/aarch64/include/zproxy.h +++ /dev/null @@ -1,111 +0,0 @@ -/* ========================================================================= - zproxy - run a steerable proxy in the background - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZPROXY_H_INCLUDED__ -#define __ZPROXY_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// Create new zproxy actor instance. The proxy switches messages between -// a frontend socket and a backend socket; use the FRONTEND and BACKEND -// commands to configure these: -// -// zactor_t *proxy = zactor_new (zproxy, NULL); -// -// Destroy zproxy instance. This destroys the two sockets and stops any -// message flow between them: -// -// zactor_destroy (&proxy); -// -// Note that all zproxy commands are synchronous, so your application always -// waits for a signal from the actor after each command. -// -// Enable verbose logging of commands and activity: -// -// zstr_send (proxy, "VERBOSE"); -// zsock_wait (proxy); -// -// Specify frontend socket type -- see zsock_type_str () -- and attach to -// endpoints, see zsock_attach (). Note that a proxy socket is always -// serverish: -// -// zstr_sendx (proxy, "FRONTEND", "XSUB", endpoints, NULL); -// zsock_wait (proxy); -// -// Specify backend socket type -- see zsock_type_str () -- and attach to -// endpoints, see zsock_attach (). Note that a proxy socket is always -// serverish: -// -// zstr_sendx (proxy, "BACKEND", "XPUB", endpoints, NULL); -// zsock_wait (proxy); -// -// Capture all proxied messages; these are delivered to the application -// via an inproc PULL socket that you have already bound to the specified -// endpoint: -// -// zstr_sendx (proxy, "CAPTURE", endpoint, NULL); -// zsock_wait (proxy); -// -// Pause the proxy. A paused proxy will cease processing messages, causing -// them to be queued up and potentially hit the high-water mark on the -// frontend or backend socket, causing messages to be dropped, or writing -// applications to block: -// -// zstr_sendx (proxy, "PAUSE", NULL); -// zsock_wait (proxy); -// -// Resume the proxy. Note that the proxy starts automatically as soon as it -// has a properly attached frontend and backend socket: -// -// zstr_sendx (proxy, "RESUME", NULL); -// zsock_wait (proxy); -// -// Configure an authentication domain for the "FRONTEND" or "BACKEND" proxy -// socket -- see zsock_set_zap_domain (). Call before binding socket: -// -// zstr_sendx (proxy, "DOMAIN", "FRONTEND", "global", NULL); -// zsock_wait (proxy); -// -// Configure PLAIN authentication for the "FRONTEND" or "BACKEND" proxy -// socket -- see zsock_set_plain_server (). Call before binding socket: -// -// zstr_sendx (proxy, "PLAIN", "BACKEND", NULL); -// zsock_wait (proxy); -// -// Configure CURVE authentication for the "FRONTEND" or "BACKEND" proxy -// socket -- see zsock_set_curve_server () -- specifying both the public and -// secret keys of a certificate as Z85 armored strings -- see -// zcert_public_txt () and zcert_secret_txt (). Call before binding socket: -// -// zstr_sendx (proxy, "CURVE", "FRONTEND", public_txt, secret_txt, NULL); -// zsock_wait (proxy); -// -// This is the zproxy constructor as a zactor_fn; the argument is a -// character string specifying frontend and backend socket types as two -// uppercase strings separated by a hyphen: -CZMQ_EXPORT void - zproxy (zsock_t *pipe, void *unused); - -// Selftest -CZMQ_EXPORT void - zproxy_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zproxy_v2.h b/phonelibs/zmq/aarch64/include/zproxy_v2.h deleted file mode 100644 index 4bde9515916935..00000000000000 --- a/phonelibs/zmq/aarch64/include/zproxy_v2.h +++ /dev/null @@ -1,62 +0,0 @@ -/* ========================================================================= - zproxy_v2 - run a steerable proxy in the background (deprecated) - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZPROXY_V2_H_INCLUDED__ -#define __ZPROXY_V2_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface - -// Constructor -// Create a new zproxy object. You must create the frontend and backend -// sockets, configure them, and connect or bind them, before you pass them -// to the constructor. Do NOT use the sockets again, after passing them to -// this method. -CZMQ_EXPORT zproxy_t * - zproxy_new (zctx_t *ctx, void *frontend, void *backend); - -// Destructor -// Destroy a zproxy object; note this first stops the proxy. -CZMQ_EXPORT void - zproxy_destroy (zproxy_t **self_p); - -// Copy all proxied messages to specified endpoint; if this is NULL, any -// in-progress capturing will be stopped. You must already have bound the -// endpoint to a PULL socket. -CZMQ_EXPORT void - zproxy_capture (zproxy_t *self, const char *endpoint); - -// Pauses a zproxy object; a paused proxy will cease processing messages, -// causing them to be queued up and potentially hit the high-water mark on -// the frontend socket, causing messages to be dropped, or writing -// applications to block. -CZMQ_EXPORT void - zproxy_pause (zproxy_t *self); - -// Resume a zproxy object -CZMQ_EXPORT void - zproxy_resume (zproxy_t *self); - -// Self test of this class -CZMQ_EXPORT void - zproxy_v2_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zrex.h b/phonelibs/zmq/aarch64/include/zrex.h deleted file mode 100644 index 8b50618a34837c..00000000000000 --- a/phonelibs/zmq/aarch64/include/zrex.h +++ /dev/null @@ -1,82 +0,0 @@ -/* ========================================================================= - zrex - work with regular expressions - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZREX_H_INCLUDED__ -#define __ZREX_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// Constructor. Optionally, sets an expression against which we can match -// text and capture hits. If there is an error in the expression, reports -// zrex_valid() as false and provides the error in zrex_strerror(). If you -// set a pattern, you can call zrex_matches() to test it against text. -CZMQ_EXPORT zrex_t * - zrex_new (const char *expression); - -// Destructor -CZMQ_EXPORT void - zrex_destroy (zrex_t **self_p); - -// Return true if the expression was valid and compiled without errors. -CZMQ_EXPORT bool - zrex_valid (zrex_t *self); - -// Return the error message generated during compilation of the expression. -CZMQ_EXPORT const char * - zrex_strerror (zrex_t *self); - -// Returns true if the text matches the previously compiled expression. -// Use this method to compare one expression against many strings. -CZMQ_EXPORT bool - zrex_matches (zrex_t *self, const char *text); - -// Returns true if the text matches the supplied expression. Use this -// method to compare one string against several expressions. -CZMQ_EXPORT bool - zrex_eq (zrex_t *self, const char *text, const char *expression); - -// Returns number of hits from last zrex_matches or zrex_eq. If the text -// matched, returns 1 plus the number of capture groups. If the text did -// not match, returns zero. To retrieve individual capture groups, call -// zrex_hit (). -CZMQ_EXPORT int - zrex_hits (zrex_t *self); - -// Returns the Nth capture group from the last expression match, where -// N is 0 to the value returned by zrex_hits(). Capture group 0 is the -// whole matching string. Sequence 1 is the first capture group, if any, -// and so on. -CZMQ_EXPORT const char * - zrex_hit (zrex_t *self, uint index); - -// Fetches hits into string variables provided by caller; this makes for -// nicer code than accessing hits by index. Caller should not modify nor -// free the returned values. Returns number of strings returned. This -// method starts at hit 1, i.e. first capture group, as hit 0 is always -// the original matched string. -CZMQ_EXPORT int - zrex_fetch (zrex_t *self, const char **string_p, ...); - -// Self test of this class -CZMQ_EXPORT void - zrex_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zsock.h b/phonelibs/zmq/aarch64/include/zsock.h deleted file mode 100644 index fc5c46e45e9810..00000000000000 --- a/phonelibs/zmq/aarch64/include/zsock.h +++ /dev/null @@ -1,921 +0,0 @@ -/* ========================================================================= - zsock - high-level socket API that hides libzmq contexts and sockets - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZSOCK_H_INCLUDED__ -#define __ZSOCK_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// This interface includes some smart constructors, which create sockets with -// additional set-up. In all of these, the endpoint is NULL, or starts with -// '@' (bind) or '>' (connect). Multiple endpoints are allowed, separated by -// commas. If endpoint does not start with '@' or '>', default action depends -// on socket type. - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zsock.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// Create a new socket. Returns the new socket, or NULL if the new socket -// could not be created. Note that the symbol zsock_new (and other -// constructors/destructors for zsock) are redirected to the *_checked -// variant, enabling intelligent socket leak detection. This can have -// performance implications if you use a LOT of sockets. To turn off this -// redirection behaviour, define ZSOCK_NOCHECK. -CZMQ_EXPORT zsock_t * - zsock_new (int type); - -// Create a PUB socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_pub (const char *endpoint); - -// Create a SUB socket, and optionally subscribe to some prefix string. Default -// action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_sub (const char *endpoint, const char *subscribe); - -// Create a REQ socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_req (const char *endpoint); - -// Create a REP socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_rep (const char *endpoint); - -// Create a DEALER socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_dealer (const char *endpoint); - -// Create a ROUTER socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_router (const char *endpoint); - -// Create a PUSH socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_push (const char *endpoint); - -// Create a PULL socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_pull (const char *endpoint); - -// Create an XPUB socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_xpub (const char *endpoint); - -// Create an XSUB socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_xsub (const char *endpoint); - -// Create a PAIR socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_pair (const char *endpoint); - -// Create a STREAM socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_stream (const char *endpoint); - -// Destroy the socket. You must use this for any socket created via the -// zsock_new method. -CZMQ_EXPORT void - zsock_destroy (zsock_t **self_p); - -// Bind a socket to a formatted endpoint. For tcp:// endpoints, supports -// ephemeral ports, if you specify the port number as "*". By default -// zsock uses the IANA designated range from C000 (49152) to FFFF (65535). -// To override this range, follow the "*" with "[first-last]". Either or -// both first and last may be empty. To bind to a random port within the -// range, use "!" in place of "*". -// -// Examples: -// tcp://127.0.0.1:* bind to first free port from C000 up -// tcp://127.0.0.1:! bind to random port from C000 to FFFF -// tcp://127.0.0.1:*[60000-] bind to first free port from 60000 up -// tcp://127.0.0.1:![-60000] bind to random port from C000 to 60000 -// tcp://127.0.0.1:![55000-55999] -// bind to random port from 55000 to 55999 -// -// On success, returns the actual port number used, for tcp:// endpoints, -// and 0 for other transports. On failure, returns -1. Note that when using -// ephemeral ports, a port may be reused by different services without -// clients being aware. Protocols that run on ephemeral ports should take -// this into account. -CZMQ_EXPORT int - zsock_bind (zsock_t *self, const char *format, ...); - -// Returns last bound endpoint, if any. -CZMQ_EXPORT const char * - zsock_endpoint (zsock_t *self); - -// Unbind a socket from a formatted endpoint. -// Returns 0 if OK, -1 if the endpoint was invalid or the function -// isn't supported. -CZMQ_EXPORT int - zsock_unbind (zsock_t *self, const char *format, ...); - -// Connect a socket to a formatted endpoint -// Returns 0 if OK, -1 if the endpoint was invalid. -CZMQ_EXPORT int - zsock_connect (zsock_t *self, const char *format, ...); - -// Disconnect a socket from a formatted endpoint -// Returns 0 if OK, -1 if the endpoint was invalid or the function -// isn't supported. -CZMQ_EXPORT int - zsock_disconnect (zsock_t *self, const char *format, ...); - -// Attach a socket to zero or more endpoints. If endpoints is not null, -// parses as list of ZeroMQ endpoints, separated by commas, and prefixed by -// '@' (to bind the socket) or '>' (to connect the socket). Returns 0 if all -// endpoints were valid, or -1 if there was a syntax error. If the endpoint -// does not start with '@' or '>', the serverish argument defines whether -// it is used to bind (serverish = true) or connect (serverish = false). -CZMQ_EXPORT int - zsock_attach (zsock_t *self, const char *endpoints, bool serverish); - -// Returns socket type as printable constant string. -CZMQ_EXPORT const char * - zsock_type_str (zsock_t *self); - -// Send a 'picture' message to the socket (or actor). The picture is a -// string that defines the type of each frame. This makes it easy to send -// a complex multiframe message in one call. The picture can contain any -// of these characters, each corresponding to one or two arguments: -// -// i = int (signed) -// 1 = uint8_t -// 2 = uint16_t -// 4 = uint32_t -// 8 = uint64_t -// s = char * -// b = byte *, size_t (2 arguments) -// c = zchunk_t * -// f = zframe_t * -// h = zhashx_t * -// U = zuuid_t * -// p = void * (sends the pointer value, only meaningful over inproc) -// m = zmsg_t * (sends all frames in the zmsg) -// z = sends zero-sized frame (0 arguments) -// u = uint (deprecated) -// -// Note that s, b, c, and f are encoded the same way and the choice is -// offered as a convenience to the sender, which may or may not already -// have data in a zchunk or zframe. Does not change or take ownership of -// any arguments. Returns 0 if successful, -1 if sending failed for any -// reason. -CZMQ_EXPORT int - zsock_send (void *self, const char *picture, ...); - -// Send a 'picture' message to the socket (or actor). This is a va_list -// version of zsock_send (), so please consult its documentation for the -// details. -CZMQ_EXPORT int - zsock_vsend (void *self, const char *picture, va_list argptr); - -// Receive a 'picture' message to the socket (or actor). See zsock_send for -// the format and meaning of the picture. Returns the picture elements into -// a series of pointers as provided by the caller: -// -// i = int * (stores signed integer) -// 4 = uint32_t * (stores 32-bit unsigned integer) -// 8 = uint64_t * (stores 64-bit unsigned integer) -// s = char ** (allocates new string) -// b = byte **, size_t * (2 arguments) (allocates memory) -// c = zchunk_t ** (creates zchunk) -// f = zframe_t ** (creates zframe) -// U = zuuid_t * (creates a zuuid with the data) -// h = zhashx_t ** (creates zhashx) -// p = void ** (stores pointer) -// m = zmsg_t ** (creates a zmsg with the remaing frames) -// z = null, asserts empty frame (0 arguments) -// u = uint * (stores unsigned integer, deprecated) -// -// Note that zsock_recv creates the returned objects, and the caller must -// destroy them when finished with them. The supplied pointers do not need -// to be initialized. Returns 0 if successful, or -1 if it failed to recv -// a message, in which case the pointers are not modified. When message -// frames are truncated (a short message), sets return values to zero/null. -// If an argument pointer is NULL, does not store any value (skips it). -// An 'n' picture matches an empty frame; if the message does not match, -// the method will return -1. -CZMQ_EXPORT int - zsock_recv (void *self, const char *picture, ...); - -// Receive a 'picture' message from the socket (or actor). This is a -// va_list version of zsock_recv (), so please consult its documentation -// for the details. -CZMQ_EXPORT int - zsock_vrecv (void *self, const char *picture, va_list argptr); - -// Send a binary encoded 'picture' message to the socket (or actor). This -// method is similar to zsock_send, except the arguments are encoded in a -// binary format that is compatible with zproto, and is designed to reduce -// memory allocations. The pattern argument is a string that defines the -// type of each argument. Supports these argument types: -// -// pattern C type zproto type: -// 1 uint8_t type = "number" size = "1" -// 2 uint16_t type = "number" size = "2" -// 4 uint32_t type = "number" size = "3" -// 8 uint64_t type = "number" size = "4" -// s char *, 0-255 chars type = "string" -// S char *, 0-2^32-1 chars type = "longstr" -// c zchunk_t * type = "chunk" -// f zframe_t * type = "frame" -// u zuuid_t * type = "uuid" -// m zmsg_t * type = "msg" -// p void *, sends pointer value, only over inproc -// -// Does not change or take ownership of any arguments. Returns 0 if -// successful, -1 if sending failed for any reason. -CZMQ_EXPORT int - zsock_bsend (void *self, const char *picture, ...); - -// Receive a binary encoded 'picture' message from the socket (or actor). -// This method is similar to zsock_recv, except the arguments are encoded -// in a binary format that is compatible with zproto, and is designed to -// reduce memory allocations. The pattern argument is a string that defines -// the type of each argument. See zsock_bsend for the supported argument -// types. All arguments must be pointers; this call sets them to point to -// values held on a per-socket basis. -// Note that zsock_brecv creates the returned objects, and the caller must -// destroy them when finished with them. The supplied pointers do not need -// to be initialized. Returns 0 if successful, or -1 if it failed to read -// a message. -CZMQ_EXPORT int - zsock_brecv (void *self, const char *picture, ...); - -// Set socket to use unbounded pipes (HWM=0); use this in cases when you are -// totally certain the message volume can fit in memory. This method works -// across all versions of ZeroMQ. Takes a polymorphic socket reference. -CZMQ_EXPORT void - zsock_set_unbounded (void *self); - -// Send a signal over a socket. A signal is a short message carrying a -// success/failure code (by convention, 0 means OK). Signals are encoded -// to be distinguishable from "normal" messages. Accepts a zsock_t or a -// zactor_t argument, and returns 0 if successful, -1 if the signal could -// not be sent. Takes a polymorphic socket reference. -CZMQ_EXPORT int - zsock_signal (void *self, byte status); - -// Wait on a signal. Use this to coordinate between threads, over pipe -// pairs. Blocks until the signal is received. Returns -1 on error, 0 or -// greater on success. Accepts a zsock_t or a zactor_t as argument. -// Takes a polymorphic socket reference. -CZMQ_EXPORT int - zsock_wait (void *self); - -// If there is a partial message still waiting on the socket, remove and -// discard it. This is useful when reading partial messages, to get specific -// message types. -CZMQ_EXPORT void - zsock_flush (void *self); - -// Probe the supplied object, and report if it looks like a zsock_t. -// Takes a polymorphic socket reference. -CZMQ_EXPORT bool - zsock_is (void *self); - -// Probe the supplied reference. If it looks like a zsock_t instance, return -// the underlying libzmq socket handle; else if it looks like a file -// descriptor, return NULL; else if it looks like a libzmq socket handle, -// return the supplied value. Takes a polymorphic socket reference. -CZMQ_EXPORT void * - zsock_resolve (void *self); - -// Get socket option `tos`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_tos (void *self); - -// Set socket option `tos`. -CZMQ_EXPORT void - zsock_set_tos (void *self, int tos); - -// Set socket option `router_handover`. -CZMQ_EXPORT void - zsock_set_router_handover (void *self, int router_handover); - -// Set socket option `router_mandatory`. -CZMQ_EXPORT void - zsock_set_router_mandatory (void *self, int router_mandatory); - -// Set socket option `probe_router`. -CZMQ_EXPORT void - zsock_set_probe_router (void *self, int probe_router); - -// Set socket option `req_relaxed`. -CZMQ_EXPORT void - zsock_set_req_relaxed (void *self, int req_relaxed); - -// Set socket option `req_correlate`. -CZMQ_EXPORT void - zsock_set_req_correlate (void *self, int req_correlate); - -// Set socket option `conflate`. -CZMQ_EXPORT void - zsock_set_conflate (void *self, int conflate); - -// Get socket option `zap_domain`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_zap_domain (void *self); - -// Set socket option `zap_domain`. -CZMQ_EXPORT void - zsock_set_zap_domain (void *self, const char *zap_domain); - -// Get socket option `mechanism`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_mechanism (void *self); - -// Get socket option `plain_server`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_plain_server (void *self); - -// Set socket option `plain_server`. -CZMQ_EXPORT void - zsock_set_plain_server (void *self, int plain_server); - -// Get socket option `plain_username`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_plain_username (void *self); - -// Set socket option `plain_username`. -CZMQ_EXPORT void - zsock_set_plain_username (void *self, const char *plain_username); - -// Get socket option `plain_password`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_plain_password (void *self); - -// Set socket option `plain_password`. -CZMQ_EXPORT void - zsock_set_plain_password (void *self, const char *plain_password); - -// Get socket option `curve_server`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_curve_server (void *self); - -// Set socket option `curve_server`. -CZMQ_EXPORT void - zsock_set_curve_server (void *self, int curve_server); - -// Get socket option `curve_publickey`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_curve_publickey (void *self); - -// Set socket option `curve_publickey`. -CZMQ_EXPORT void - zsock_set_curve_publickey (void *self, const char *curve_publickey); - -// Set socket option `curve_publickey` from 32-octet binary -CZMQ_EXPORT void - zsock_set_curve_publickey_bin (void *self, const byte *curve_publickey); - -// Get socket option `curve_secretkey`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_curve_secretkey (void *self); - -// Set socket option `curve_secretkey`. -CZMQ_EXPORT void - zsock_set_curve_secretkey (void *self, const char *curve_secretkey); - -// Set socket option `curve_secretkey` from 32-octet binary -CZMQ_EXPORT void - zsock_set_curve_secretkey_bin (void *self, const byte *curve_secretkey); - -// Get socket option `curve_serverkey`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_curve_serverkey (void *self); - -// Set socket option `curve_serverkey`. -CZMQ_EXPORT void - zsock_set_curve_serverkey (void *self, const char *curve_serverkey); - -// Set socket option `curve_serverkey` from 32-octet binary -CZMQ_EXPORT void - zsock_set_curve_serverkey_bin (void *self, const byte *curve_serverkey); - -// Get socket option `gssapi_server`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_gssapi_server (void *self); - -// Set socket option `gssapi_server`. -CZMQ_EXPORT void - zsock_set_gssapi_server (void *self, int gssapi_server); - -// Get socket option `gssapi_plaintext`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_gssapi_plaintext (void *self); - -// Set socket option `gssapi_plaintext`. -CZMQ_EXPORT void - zsock_set_gssapi_plaintext (void *self, int gssapi_plaintext); - -// Get socket option `gssapi_principal`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_gssapi_principal (void *self); - -// Set socket option `gssapi_principal`. -CZMQ_EXPORT void - zsock_set_gssapi_principal (void *self, const char *gssapi_principal); - -// Get socket option `gssapi_service_principal`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_gssapi_service_principal (void *self); - -// Set socket option `gssapi_service_principal`. -CZMQ_EXPORT void - zsock_set_gssapi_service_principal (void *self, const char *gssapi_service_principal); - -// Get socket option `ipv6`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_ipv6 (void *self); - -// Set socket option `ipv6`. -CZMQ_EXPORT void - zsock_set_ipv6 (void *self, int ipv6); - -// Get socket option `immediate`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_immediate (void *self); - -// Set socket option `immediate`. -CZMQ_EXPORT void - zsock_set_immediate (void *self, int immediate); - -// Set socket option `router_raw`. -CZMQ_EXPORT void - zsock_set_router_raw (void *self, int router_raw); - -// Get socket option `ipv4only`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_ipv4only (void *self); - -// Set socket option `ipv4only`. -CZMQ_EXPORT void - zsock_set_ipv4only (void *self, int ipv4only); - -// Set socket option `delay_attach_on_connect`. -CZMQ_EXPORT void - zsock_set_delay_attach_on_connect (void *self, int delay_attach_on_connect); - -// Get socket option `type`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_type (void *self); - -// Get socket option `sndhwm`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_sndhwm (void *self); - -// Set socket option `sndhwm`. -CZMQ_EXPORT void - zsock_set_sndhwm (void *self, int sndhwm); - -// Get socket option `rcvhwm`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_rcvhwm (void *self); - -// Set socket option `rcvhwm`. -CZMQ_EXPORT void - zsock_set_rcvhwm (void *self, int rcvhwm); - -// Get socket option `affinity`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_affinity (void *self); - -// Set socket option `affinity`. -CZMQ_EXPORT void - zsock_set_affinity (void *self, int affinity); - -// Set socket option `subscribe`. -CZMQ_EXPORT void - zsock_set_subscribe (void *self, const char *subscribe); - -// Set socket option `unsubscribe`. -CZMQ_EXPORT void - zsock_set_unsubscribe (void *self, const char *unsubscribe); - -// Get socket option `identity`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_identity (void *self); - -// Set socket option `identity`. -CZMQ_EXPORT void - zsock_set_identity (void *self, const char *identity); - -// Get socket option `rate`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_rate (void *self); - -// Set socket option `rate`. -CZMQ_EXPORT void - zsock_set_rate (void *self, int rate); - -// Get socket option `recovery_ivl`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_recovery_ivl (void *self); - -// Set socket option `recovery_ivl`. -CZMQ_EXPORT void - zsock_set_recovery_ivl (void *self, int recovery_ivl); - -// Get socket option `sndbuf`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_sndbuf (void *self); - -// Set socket option `sndbuf`. -CZMQ_EXPORT void - zsock_set_sndbuf (void *self, int sndbuf); - -// Get socket option `rcvbuf`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_rcvbuf (void *self); - -// Set socket option `rcvbuf`. -CZMQ_EXPORT void - zsock_set_rcvbuf (void *self, int rcvbuf); - -// Get socket option `linger`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_linger (void *self); - -// Set socket option `linger`. -CZMQ_EXPORT void - zsock_set_linger (void *self, int linger); - -// Get socket option `reconnect_ivl`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_reconnect_ivl (void *self); - -// Set socket option `reconnect_ivl`. -CZMQ_EXPORT void - zsock_set_reconnect_ivl (void *self, int reconnect_ivl); - -// Get socket option `reconnect_ivl_max`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_reconnect_ivl_max (void *self); - -// Set socket option `reconnect_ivl_max`. -CZMQ_EXPORT void - zsock_set_reconnect_ivl_max (void *self, int reconnect_ivl_max); - -// Get socket option `backlog`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_backlog (void *self); - -// Set socket option `backlog`. -CZMQ_EXPORT void - zsock_set_backlog (void *self, int backlog); - -// Get socket option `maxmsgsize`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_maxmsgsize (void *self); - -// Set socket option `maxmsgsize`. -CZMQ_EXPORT void - zsock_set_maxmsgsize (void *self, int maxmsgsize); - -// Get socket option `multicast_hops`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_multicast_hops (void *self); - -// Set socket option `multicast_hops`. -CZMQ_EXPORT void - zsock_set_multicast_hops (void *self, int multicast_hops); - -// Get socket option `rcvtimeo`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_rcvtimeo (void *self); - -// Set socket option `rcvtimeo`. -CZMQ_EXPORT void - zsock_set_rcvtimeo (void *self, int rcvtimeo); - -// Get socket option `sndtimeo`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_sndtimeo (void *self); - -// Set socket option `sndtimeo`. -CZMQ_EXPORT void - zsock_set_sndtimeo (void *self, int sndtimeo); - -// Set socket option `xpub_verbose`. -CZMQ_EXPORT void - zsock_set_xpub_verbose (void *self, int xpub_verbose); - -// Get socket option `tcp_keepalive`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_tcp_keepalive (void *self); - -// Set socket option `tcp_keepalive`. -CZMQ_EXPORT void - zsock_set_tcp_keepalive (void *self, int tcp_keepalive); - -// Get socket option `tcp_keepalive_idle`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_tcp_keepalive_idle (void *self); - -// Set socket option `tcp_keepalive_idle`. -CZMQ_EXPORT void - zsock_set_tcp_keepalive_idle (void *self, int tcp_keepalive_idle); - -// Get socket option `tcp_keepalive_cnt`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_tcp_keepalive_cnt (void *self); - -// Set socket option `tcp_keepalive_cnt`. -CZMQ_EXPORT void - zsock_set_tcp_keepalive_cnt (void *self, int tcp_keepalive_cnt); - -// Get socket option `tcp_keepalive_intvl`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_tcp_keepalive_intvl (void *self); - -// Set socket option `tcp_keepalive_intvl`. -CZMQ_EXPORT void - zsock_set_tcp_keepalive_intvl (void *self, int tcp_keepalive_intvl); - -// Get socket option `tcp_accept_filter`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_tcp_accept_filter (void *self); - -// Set socket option `tcp_accept_filter`. -CZMQ_EXPORT void - zsock_set_tcp_accept_filter (void *self, const char *tcp_accept_filter); - -// Get socket option `rcvmore`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_rcvmore (void *self); - -// Get socket option `fd`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT SOCKET - zsock_fd (void *self); - -// Get socket option `events`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_events (void *self); - -// Get socket option `last_endpoint`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_last_endpoint (void *self); - -// Self test of this class. -CZMQ_EXPORT void - zsock_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Create a SERVER socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_server (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Create a CLIENT socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_client (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Create a RADIO socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_radio (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Create a DISH socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_dish (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Create a GATHER socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_gather (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Create a SCATTER socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_scatter (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Return socket routing ID if any. This returns 0 if the socket is not -// of type ZMQ_SERVER or if no request was already received on it. -CZMQ_EXPORT uint32_t - zsock_routing_id (zsock_t *self); - -// *** Draft method, for development use, may change without warning *** -// Set routing ID on socket. The socket MUST be of type ZMQ_SERVER. -// This will be used when sending messages on the socket via the zsock API. -CZMQ_EXPORT void - zsock_set_routing_id (zsock_t *self, uint32_t routing_id); - -// *** Draft method, for development use, may change without warning *** -// Join a group for the RADIO-DISH pattern. Call only on ZMQ_DISH. -// Returns 0 if OK, -1 if failed. -CZMQ_EXPORT int - zsock_join (void *self, const char *group); - -// *** Draft method, for development use, may change without warning *** -// Leave a group for the RADIO-DISH pattern. Call only on ZMQ_DISH. -// Returns 0 if OK, -1 if failed. -CZMQ_EXPORT int - zsock_leave (void *self, const char *group); - -// *** Draft method, for development use, may change without warning *** -// Get socket option `heartbeat_ivl`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_heartbeat_ivl (void *self); - -// *** Draft method, for development use, may change without warning *** -// Set socket option `heartbeat_ivl`. -CZMQ_EXPORT void - zsock_set_heartbeat_ivl (void *self, int heartbeat_ivl); - -// *** Draft method, for development use, may change without warning *** -// Get socket option `heartbeat_ttl`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_heartbeat_ttl (void *self); - -// *** Draft method, for development use, may change without warning *** -// Set socket option `heartbeat_ttl`. -CZMQ_EXPORT void - zsock_set_heartbeat_ttl (void *self, int heartbeat_ttl); - -// *** Draft method, for development use, may change without warning *** -// Get socket option `heartbeat_timeout`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_heartbeat_timeout (void *self); - -// *** Draft method, for development use, may change without warning *** -// Set socket option `heartbeat_timeout`. -CZMQ_EXPORT void - zsock_set_heartbeat_timeout (void *self, int heartbeat_timeout); - -// *** Draft method, for development use, may change without warning *** -// Get socket option `use_fd`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_use_fd (void *self); - -// *** Draft method, for development use, may change without warning *** -// Set socket option `use_fd`. -CZMQ_EXPORT void - zsock_set_use_fd (void *self, int use_fd); - -#endif // CZMQ_BUILD_DRAFT_API -// @ignore -CZMQ_EXPORT int - zsock_bind (zsock_t *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int - zsock_unbind (zsock_t *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int - zsock_connect (zsock_t *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int - zsock_disconnect (zsock_t *self, const char *format, ...) CHECK_PRINTF (2); -// @end - - -// zsock leak detection - not a part of the official interface to zsock. This -// enables CZMQ to report socket leaks intelligently. -#if defined ZSOCK_NOCHECK - // no checking active - use the above interface methods directly. -#else -# define zsock_new(t) zsock_new_checked((t), __FILE__, __LINE__) -# define zsock_new_pub(e) zsock_new_pub_checked((e), __FILE__, __LINE__) -# define zsock_new_sub(e,s) zsock_new_sub_checked((e), (s), __FILE__, __LINE__) -# define zsock_new_req(e) zsock_new_req_checked((e), __FILE__, __LINE__) -# define zsock_new_rep(e) zsock_new_rep_checked((e), __FILE__, __LINE__) -# define zsock_new_dealer(e) zsock_new_dealer_checked((e), __FILE__, __LINE__) -# define zsock_new_router(e) zsock_new_router_checked((e), __FILE__, __LINE__) -# define zsock_new_pull(e) zsock_new_pull_checked((e), __FILE__, __LINE__) -# define zsock_new_push(e) zsock_new_push_checked((e), __FILE__, __LINE__) -# define zsock_new_xpub(e) zsock_new_xpub_checked((e), __FILE__, __LINE__) -# define zsock_new_xsub(e) zsock_new_xsub_checked((e), __FILE__, __LINE__) -# define zsock_new_pair(e) zsock_new_pair_checked((e), __FILE__, __LINE__) -# define zsock_new_stream(e) zsock_new_stream_checked((e), __FILE__, __LINE__) -# define zsock_destroy(t) zsock_destroy_checked((t), __FILE__, __LINE__) -#endif - -CZMQ_EXPORT zsock_t * - zsock_new_checked (int type, const char *filename, size_t line_nbr); - -CZMQ_EXPORT void - zsock_destroy_checked (zsock_t **self_p, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_pub_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_sub_checked (const char *endpoint, const char *subscribe, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_req_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_rep_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_dealer_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_router_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_push_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_pull_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_xpub_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_xsub_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_pair_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_stream_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_server_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_client_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_radio_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_dish_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_gather_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_scatter_checked (const char *endpoint, const char *filename, size_t line_nbr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zsocket.h b/phonelibs/zmq/aarch64/include/zsocket.h deleted file mode 100644 index a60a0d9db3e7da..00000000000000 --- a/phonelibs/zmq/aarch64/include/zsocket.h +++ /dev/null @@ -1,110 +0,0 @@ -/* ========================================================================= - zsocket - working with 0MQ sockets - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZSOCKET_H_INCLUDED__ -#define __ZSOCKET_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// This port range is defined by IANA for dynamic or private ports -// We use this when choosing a port for dynamic binding. -#define ZSOCKET_DYNFROM 0xc000 -#define ZSOCKET_DYNTO 0xffff - -// Callback function for zero-copy methods -typedef void (zsocket_free_fn) (void *data, void *arg); - -// Create a new socket within our CZMQ context, replaces zmq_socket. -// Use this to get automatic management of the socket at shutdown. -// Note: SUB sockets do not automatically subscribe to everything; you -// must set filters explicitly. -CZMQ_EXPORT void * - zsocket_new (zctx_t *self, int type); - -// Destroy a socket within our CZMQ context, replaces zmq_close. -CZMQ_EXPORT void - zsocket_destroy (zctx_t *ctx, void *self); - -// Bind a socket to a formatted endpoint. If the port is specified as -// '*', binds to any free port from ZSOCKET_DYNFROM to ZSOCKET_DYNTO -// and returns the actual port number used. Otherwise asserts that the -// bind succeeded with the specified port number. Always returns the -// port number if successful. -CZMQ_EXPORT int - zsocket_bind (void *self, const char *format, ...); - -// Unbind a socket from a formatted endpoint. -// Returns 0 if OK, -1 if the endpoint was invalid or the function -// isn't supported. -CZMQ_EXPORT int - zsocket_unbind (void *self, const char *format, ...); - -// Connect a socket to a formatted endpoint -// Returns 0 if OK, -1 if the endpoint was invalid. -CZMQ_EXPORT int - zsocket_connect (void *self, const char *format, ...); - -// Disconnect a socket from a formatted endpoint -// Returns 0 if OK, -1 if the endpoint was invalid or the function -// isn't supported. -CZMQ_EXPORT int - zsocket_disconnect (void *self, const char *format, ...); - -// Poll for input events on the socket. Returns TRUE if there is input -// ready on the socket, else FALSE. -CZMQ_EXPORT bool - zsocket_poll (void *self, int msecs); - -// Returns socket type as printable constant string -CZMQ_EXPORT const char * - zsocket_type_str (void *self); - -// Send data over a socket as a single message frame. -// Accepts these flags: ZFRAME_MORE and ZFRAME_DONTWAIT. -// Returns -1 on error, 0 on success -CZMQ_EXPORT int - zsocket_sendmem (void *self, const void *data, size_t size, int flags); - -// Send a signal over a socket. A signal is a zero-byte message. -// Signals are used primarily between threads, over pipe sockets. -// Returns -1 if there was an error sending the signal. -CZMQ_EXPORT int - zsocket_signal (void *self); - -// Wait on a signal. Use this to coordinate between threads, over -// pipe pairs. Returns -1 on error, 0 on success. -CZMQ_EXPORT int - zsocket_wait (void *self); - -// Self test of this class -CZMQ_EXPORT void - zsocket_test (bool verbose); -// @end - -// Compiler hints -CZMQ_EXPORT int zsocket_bind (void *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int zsocket_unbind (void *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int zsocket_connect (void *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int zsocket_disconnect (void *self, const char *format, ...) CHECK_PRINTF (2); - -// Emulation of widely-used 2.x socket options -CZMQ_EXPORT void zsocket_set_hwm (void *self, int hwm); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zsockopt.h b/phonelibs/zmq/aarch64/include/zsockopt.h deleted file mode 100644 index 5246986dd0b367..00000000000000 --- a/phonelibs/zmq/aarch64/include/zsockopt.h +++ /dev/null @@ -1,256 +0,0 @@ -/* ========================================================================= - zsockopt - get/set 0MQ socket options (deprecated) - - **************************************************** - * GENERATED SOURCE CODE, DO NOT EDIT!! * - * TO CHANGE THIS, EDIT src/zsockopt.gsl * - * AND RUN `gsl sockopts` in src/. * - **************************************************** - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZSOCKOPT_H_INCLUDED__ -#define __ZSOCKOPT_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -#if (ZMQ_VERSION_MAJOR == 4) -// Get socket options -CZMQ_EXPORT int zsocket_heartbeat_ivl (void *zocket); -CZMQ_EXPORT int zsocket_heartbeat_ttl (void *zocket); -CZMQ_EXPORT int zsocket_heartbeat_timeout (void *zocket); -CZMQ_EXPORT int zsocket_use_fd (void *zocket); -CZMQ_EXPORT int zsocket_tos (void *zocket); -CZMQ_EXPORT char * zsocket_zap_domain (void *zocket); -CZMQ_EXPORT int zsocket_mechanism (void *zocket); -CZMQ_EXPORT int zsocket_plain_server (void *zocket); -CZMQ_EXPORT char * zsocket_plain_username (void *zocket); -CZMQ_EXPORT char * zsocket_plain_password (void *zocket); -CZMQ_EXPORT int zsocket_curve_server (void *zocket); -CZMQ_EXPORT char * zsocket_curve_publickey (void *zocket); -CZMQ_EXPORT char * zsocket_curve_secretkey (void *zocket); -CZMQ_EXPORT char * zsocket_curve_serverkey (void *zocket); -CZMQ_EXPORT int zsocket_gssapi_server (void *zocket); -CZMQ_EXPORT int zsocket_gssapi_plaintext (void *zocket); -CZMQ_EXPORT char * zsocket_gssapi_principal (void *zocket); -CZMQ_EXPORT char * zsocket_gssapi_service_principal (void *zocket); -CZMQ_EXPORT int zsocket_ipv6 (void *zocket); -CZMQ_EXPORT int zsocket_immediate (void *zocket); -CZMQ_EXPORT int zsocket_ipv4only (void *zocket); -CZMQ_EXPORT int zsocket_type (void *zocket); -CZMQ_EXPORT int zsocket_sndhwm (void *zocket); -CZMQ_EXPORT int zsocket_rcvhwm (void *zocket); -CZMQ_EXPORT int zsocket_affinity (void *zocket); -CZMQ_EXPORT char * zsocket_identity (void *zocket); -CZMQ_EXPORT int zsocket_rate (void *zocket); -CZMQ_EXPORT int zsocket_recovery_ivl (void *zocket); -CZMQ_EXPORT int zsocket_sndbuf (void *zocket); -CZMQ_EXPORT int zsocket_rcvbuf (void *zocket); -CZMQ_EXPORT int zsocket_linger (void *zocket); -CZMQ_EXPORT int zsocket_reconnect_ivl (void *zocket); -CZMQ_EXPORT int zsocket_reconnect_ivl_max (void *zocket); -CZMQ_EXPORT int zsocket_backlog (void *zocket); -CZMQ_EXPORT int zsocket_maxmsgsize (void *zocket); -CZMQ_EXPORT int zsocket_multicast_hops (void *zocket); -CZMQ_EXPORT int zsocket_rcvtimeo (void *zocket); -CZMQ_EXPORT int zsocket_sndtimeo (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive_idle (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive_cnt (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive_intvl (void *zocket); -CZMQ_EXPORT char * zsocket_tcp_accept_filter (void *zocket); -CZMQ_EXPORT int zsocket_rcvmore (void *zocket); -CZMQ_EXPORT SOCKET zsocket_fd (void *zocket); -CZMQ_EXPORT int zsocket_events (void *zocket); -CZMQ_EXPORT char * zsocket_last_endpoint (void *zocket); - -// Set socket options -CZMQ_EXPORT void zsocket_set_heartbeat_ivl (void *zocket, int heartbeat_ivl); -CZMQ_EXPORT void zsocket_set_heartbeat_ttl (void *zocket, int heartbeat_ttl); -CZMQ_EXPORT void zsocket_set_heartbeat_timeout (void *zocket, int heartbeat_timeout); -CZMQ_EXPORT void zsocket_set_use_fd (void *zocket, int use_fd); -CZMQ_EXPORT void zsocket_set_tos (void *zocket, int tos); -CZMQ_EXPORT void zsocket_set_router_handover (void *zocket, int router_handover); -CZMQ_EXPORT void zsocket_set_router_mandatory (void *zocket, int router_mandatory); -CZMQ_EXPORT void zsocket_set_probe_router (void *zocket, int probe_router); -CZMQ_EXPORT void zsocket_set_req_relaxed (void *zocket, int req_relaxed); -CZMQ_EXPORT void zsocket_set_req_correlate (void *zocket, int req_correlate); -CZMQ_EXPORT void zsocket_set_conflate (void *zocket, int conflate); -CZMQ_EXPORT void zsocket_set_zap_domain (void *zocket, const char * zap_domain); -CZMQ_EXPORT void zsocket_set_plain_server (void *zocket, int plain_server); -CZMQ_EXPORT void zsocket_set_plain_username (void *zocket, const char * plain_username); -CZMQ_EXPORT void zsocket_set_plain_password (void *zocket, const char * plain_password); -CZMQ_EXPORT void zsocket_set_curve_server (void *zocket, int curve_server); -CZMQ_EXPORT void zsocket_set_curve_publickey (void *zocket, const char * curve_publickey); -CZMQ_EXPORT void zsocket_set_curve_publickey_bin (void *zocket, const byte *curve_publickey); -CZMQ_EXPORT void zsocket_set_curve_secretkey (void *zocket, const char * curve_secretkey); -CZMQ_EXPORT void zsocket_set_curve_secretkey_bin (void *zocket, const byte *curve_secretkey); -CZMQ_EXPORT void zsocket_set_curve_serverkey (void *zocket, const char * curve_serverkey); -CZMQ_EXPORT void zsocket_set_curve_serverkey_bin (void *zocket, const byte *curve_serverkey); -CZMQ_EXPORT void zsocket_set_gssapi_server (void *zocket, int gssapi_server); -CZMQ_EXPORT void zsocket_set_gssapi_plaintext (void *zocket, int gssapi_plaintext); -CZMQ_EXPORT void zsocket_set_gssapi_principal (void *zocket, const char * gssapi_principal); -CZMQ_EXPORT void zsocket_set_gssapi_service_principal (void *zocket, const char * gssapi_service_principal); -CZMQ_EXPORT void zsocket_set_ipv6 (void *zocket, int ipv6); -CZMQ_EXPORT void zsocket_set_immediate (void *zocket, int immediate); -CZMQ_EXPORT void zsocket_set_router_raw (void *zocket, int router_raw); -CZMQ_EXPORT void zsocket_set_ipv4only (void *zocket, int ipv4only); -CZMQ_EXPORT void zsocket_set_delay_attach_on_connect (void *zocket, int delay_attach_on_connect); -CZMQ_EXPORT void zsocket_set_sndhwm (void *zocket, int sndhwm); -CZMQ_EXPORT void zsocket_set_rcvhwm (void *zocket, int rcvhwm); -CZMQ_EXPORT void zsocket_set_affinity (void *zocket, int affinity); -CZMQ_EXPORT void zsocket_set_subscribe (void *zocket, const char * subscribe); -CZMQ_EXPORT void zsocket_set_unsubscribe (void *zocket, const char * unsubscribe); -CZMQ_EXPORT void zsocket_set_identity (void *zocket, const char * identity); -CZMQ_EXPORT void zsocket_set_rate (void *zocket, int rate); -CZMQ_EXPORT void zsocket_set_recovery_ivl (void *zocket, int recovery_ivl); -CZMQ_EXPORT void zsocket_set_sndbuf (void *zocket, int sndbuf); -CZMQ_EXPORT void zsocket_set_rcvbuf (void *zocket, int rcvbuf); -CZMQ_EXPORT void zsocket_set_linger (void *zocket, int linger); -CZMQ_EXPORT void zsocket_set_reconnect_ivl (void *zocket, int reconnect_ivl); -CZMQ_EXPORT void zsocket_set_reconnect_ivl_max (void *zocket, int reconnect_ivl_max); -CZMQ_EXPORT void zsocket_set_backlog (void *zocket, int backlog); -CZMQ_EXPORT void zsocket_set_maxmsgsize (void *zocket, int maxmsgsize); -CZMQ_EXPORT void zsocket_set_multicast_hops (void *zocket, int multicast_hops); -CZMQ_EXPORT void zsocket_set_rcvtimeo (void *zocket, int rcvtimeo); -CZMQ_EXPORT void zsocket_set_sndtimeo (void *zocket, int sndtimeo); -CZMQ_EXPORT void zsocket_set_xpub_verbose (void *zocket, int xpub_verbose); -CZMQ_EXPORT void zsocket_set_tcp_keepalive (void *zocket, int tcp_keepalive); -CZMQ_EXPORT void zsocket_set_tcp_keepalive_idle (void *zocket, int tcp_keepalive_idle); -CZMQ_EXPORT void zsocket_set_tcp_keepalive_cnt (void *zocket, int tcp_keepalive_cnt); -CZMQ_EXPORT void zsocket_set_tcp_keepalive_intvl (void *zocket, int tcp_keepalive_intvl); -CZMQ_EXPORT void zsocket_set_tcp_accept_filter (void *zocket, const char * tcp_accept_filter); -#endif - -#if (ZMQ_VERSION_MAJOR == 3) -// Get socket options -CZMQ_EXPORT int zsocket_ipv4only (void *zocket); -CZMQ_EXPORT int zsocket_type (void *zocket); -CZMQ_EXPORT int zsocket_sndhwm (void *zocket); -CZMQ_EXPORT int zsocket_rcvhwm (void *zocket); -CZMQ_EXPORT int zsocket_affinity (void *zocket); -CZMQ_EXPORT char * zsocket_identity (void *zocket); -CZMQ_EXPORT int zsocket_rate (void *zocket); -CZMQ_EXPORT int zsocket_recovery_ivl (void *zocket); -CZMQ_EXPORT int zsocket_sndbuf (void *zocket); -CZMQ_EXPORT int zsocket_rcvbuf (void *zocket); -CZMQ_EXPORT int zsocket_linger (void *zocket); -CZMQ_EXPORT int zsocket_reconnect_ivl (void *zocket); -CZMQ_EXPORT int zsocket_reconnect_ivl_max (void *zocket); -CZMQ_EXPORT int zsocket_backlog (void *zocket); -CZMQ_EXPORT int zsocket_maxmsgsize (void *zocket); -CZMQ_EXPORT int zsocket_multicast_hops (void *zocket); -CZMQ_EXPORT int zsocket_rcvtimeo (void *zocket); -CZMQ_EXPORT int zsocket_sndtimeo (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive_idle (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive_cnt (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive_intvl (void *zocket); -CZMQ_EXPORT char * zsocket_tcp_accept_filter (void *zocket); -CZMQ_EXPORT int zsocket_rcvmore (void *zocket); -CZMQ_EXPORT SOCKET zsocket_fd (void *zocket); -CZMQ_EXPORT int zsocket_events (void *zocket); -CZMQ_EXPORT char * zsocket_last_endpoint (void *zocket); - -// Set socket options -CZMQ_EXPORT void zsocket_set_router_raw (void *zocket, int router_raw); -CZMQ_EXPORT void zsocket_set_ipv4only (void *zocket, int ipv4only); -CZMQ_EXPORT void zsocket_set_delay_attach_on_connect (void *zocket, int delay_attach_on_connect); -CZMQ_EXPORT void zsocket_set_sndhwm (void *zocket, int sndhwm); -CZMQ_EXPORT void zsocket_set_rcvhwm (void *zocket, int rcvhwm); -CZMQ_EXPORT void zsocket_set_affinity (void *zocket, int affinity); -CZMQ_EXPORT void zsocket_set_subscribe (void *zocket, const char * subscribe); -CZMQ_EXPORT void zsocket_set_unsubscribe (void *zocket, const char * unsubscribe); -CZMQ_EXPORT void zsocket_set_identity (void *zocket, const char * identity); -CZMQ_EXPORT void zsocket_set_rate (void *zocket, int rate); -CZMQ_EXPORT void zsocket_set_recovery_ivl (void *zocket, int recovery_ivl); -CZMQ_EXPORT void zsocket_set_sndbuf (void *zocket, int sndbuf); -CZMQ_EXPORT void zsocket_set_rcvbuf (void *zocket, int rcvbuf); -CZMQ_EXPORT void zsocket_set_linger (void *zocket, int linger); -CZMQ_EXPORT void zsocket_set_reconnect_ivl (void *zocket, int reconnect_ivl); -CZMQ_EXPORT void zsocket_set_reconnect_ivl_max (void *zocket, int reconnect_ivl_max); -CZMQ_EXPORT void zsocket_set_backlog (void *zocket, int backlog); -CZMQ_EXPORT void zsocket_set_maxmsgsize (void *zocket, int maxmsgsize); -CZMQ_EXPORT void zsocket_set_multicast_hops (void *zocket, int multicast_hops); -CZMQ_EXPORT void zsocket_set_rcvtimeo (void *zocket, int rcvtimeo); -CZMQ_EXPORT void zsocket_set_sndtimeo (void *zocket, int sndtimeo); -CZMQ_EXPORT void zsocket_set_xpub_verbose (void *zocket, int xpub_verbose); -CZMQ_EXPORT void zsocket_set_tcp_keepalive (void *zocket, int tcp_keepalive); -CZMQ_EXPORT void zsocket_set_tcp_keepalive_idle (void *zocket, int tcp_keepalive_idle); -CZMQ_EXPORT void zsocket_set_tcp_keepalive_cnt (void *zocket, int tcp_keepalive_cnt); -CZMQ_EXPORT void zsocket_set_tcp_keepalive_intvl (void *zocket, int tcp_keepalive_intvl); -CZMQ_EXPORT void zsocket_set_tcp_accept_filter (void *zocket, const char * tcp_accept_filter); -#endif - -#if (ZMQ_VERSION_MAJOR == 2) -// Get socket options -CZMQ_EXPORT int zsocket_hwm (void *zocket); -CZMQ_EXPORT int zsocket_swap (void *zocket); -CZMQ_EXPORT int zsocket_affinity (void *zocket); -CZMQ_EXPORT char * zsocket_identity (void *zocket); -CZMQ_EXPORT int zsocket_rate (void *zocket); -CZMQ_EXPORT int zsocket_recovery_ivl (void *zocket); -CZMQ_EXPORT int zsocket_recovery_ivl_msec (void *zocket); -CZMQ_EXPORT int zsocket_mcast_loop (void *zocket); -# if (ZMQ_VERSION_MINOR == 2) -CZMQ_EXPORT int zsocket_rcvtimeo (void *zocket); -# endif -# if (ZMQ_VERSION_MINOR == 2) -CZMQ_EXPORT int zsocket_sndtimeo (void *zocket); -# endif -CZMQ_EXPORT int zsocket_sndbuf (void *zocket); -CZMQ_EXPORT int zsocket_rcvbuf (void *zocket); -CZMQ_EXPORT int zsocket_linger (void *zocket); -CZMQ_EXPORT int zsocket_reconnect_ivl (void *zocket); -CZMQ_EXPORT int zsocket_reconnect_ivl_max (void *zocket); -CZMQ_EXPORT int zsocket_backlog (void *zocket); -CZMQ_EXPORT int zsocket_type (void *zocket); -CZMQ_EXPORT int zsocket_rcvmore (void *zocket); -CZMQ_EXPORT SOCKET zsocket_fd (void *zocket); -CZMQ_EXPORT int zsocket_events (void *zocket); - -// Set socket options -CZMQ_EXPORT void zsocket_set_hwm (void *zocket, int hwm); -CZMQ_EXPORT void zsocket_set_swap (void *zocket, int swap); -CZMQ_EXPORT void zsocket_set_affinity (void *zocket, int affinity); -CZMQ_EXPORT void zsocket_set_identity (void *zocket, const char * identity); -CZMQ_EXPORT void zsocket_set_rate (void *zocket, int rate); -CZMQ_EXPORT void zsocket_set_recovery_ivl (void *zocket, int recovery_ivl); -CZMQ_EXPORT void zsocket_set_recovery_ivl_msec (void *zocket, int recovery_ivl_msec); -CZMQ_EXPORT void zsocket_set_mcast_loop (void *zocket, int mcast_loop); -# if (ZMQ_VERSION_MINOR == 2) -CZMQ_EXPORT void zsocket_set_rcvtimeo (void *zocket, int rcvtimeo); -# endif -# if (ZMQ_VERSION_MINOR == 2) -CZMQ_EXPORT void zsocket_set_sndtimeo (void *zocket, int sndtimeo); -# endif -CZMQ_EXPORT void zsocket_set_sndbuf (void *zocket, int sndbuf); -CZMQ_EXPORT void zsocket_set_rcvbuf (void *zocket, int rcvbuf); -CZMQ_EXPORT void zsocket_set_linger (void *zocket, int linger); -CZMQ_EXPORT void zsocket_set_reconnect_ivl (void *zocket, int reconnect_ivl); -CZMQ_EXPORT void zsocket_set_reconnect_ivl_max (void *zocket, int reconnect_ivl_max); -CZMQ_EXPORT void zsocket_set_backlog (void *zocket, int backlog); -CZMQ_EXPORT void zsocket_set_subscribe (void *zocket, const char * subscribe); -CZMQ_EXPORT void zsocket_set_unsubscribe (void *zocket, const char * unsubscribe); -#endif - -// Self test of this class -CZMQ_EXPORT void zsockopt_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zstr.h b/phonelibs/zmq/aarch64/include/zstr.h deleted file mode 100644 index 3d3f1a862ad7e5..00000000000000 --- a/phonelibs/zmq/aarch64/include/zstr.h +++ /dev/null @@ -1,115 +0,0 @@ -/* ========================================================================= - zstr - sending and receiving strings - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZSTR_H_INCLUDED__ -#define __ZSTR_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zstr.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// Receive C string from socket. Caller must free returned string using -// zstr_free(). Returns NULL if the context is being terminated or the -// process was interrupted. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zstr_recv (void *source); - -// Receive a series of strings (until NULL) from multipart data. -// Each string is allocated and filled with string data; if there -// are not enough frames, unallocated strings are set to NULL. -// Returns -1 if the message could not be read, else returns the -// number of strings filled, zero or more. Free each returned string -// using zstr_free(). If not enough strings are provided, remaining -// multipart frames in the message are dropped. -CZMQ_EXPORT int - zstr_recvx (void *source, char **string_p, ...); - -// Send a C string to a socket, as a frame. The string is sent without -// trailing null byte; to read this you can use zstr_recv, or a similar -// method that adds a null terminator on the received string. String -// may be NULL, which is sent as "". -CZMQ_EXPORT int - zstr_send (void *dest, const char *string); - -// Send a C string to a socket, as zstr_send(), with a MORE flag, so that -// you can send further strings in the same multi-part message. -CZMQ_EXPORT int - zstr_sendm (void *dest, const char *string); - -// Send a formatted string to a socket. Note that you should NOT use -// user-supplied strings in the format (they may contain '%' which -// will create security holes). -CZMQ_EXPORT int - zstr_sendf (void *dest, const char *format, ...); - -// Send a formatted string to a socket, as for zstr_sendf(), with a -// MORE flag, so that you can send further strings in the same multi-part -// message. -CZMQ_EXPORT int - zstr_sendfm (void *dest, const char *format, ...); - -// Send a series of strings (until NULL) as multipart data -// Returns 0 if the strings could be sent OK, or -1 on error. -CZMQ_EXPORT int - zstr_sendx (void *dest, const char *string, ...); - -// Free a provided string, and nullify the parent pointer. Safe to call on -// a null pointer. -CZMQ_EXPORT void - zstr_free (char **string_p); - -// Self test of this class. -CZMQ_EXPORT void - zstr_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Accepts a void pointer and returns a fresh character string. If source -// is null, returns an empty string. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zstr_str (void *source); - -#endif // CZMQ_BUILD_DRAFT_API -// @ignore -CZMQ_EXPORT int - zstr_sendf (void *dest, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int - zstr_sendfm (void *dest, const char *format, ...) CHECK_PRINTF (2); -// @end - - -// DEPRECATED as poor style -- callers should use zloop or zpoller -// Receive C string from socket, if socket had input ready. Caller must -// free returned string using zstr_free. Returns NULL if there was no input -// waiting, or if the context was terminated. Use zctx_interrupted to exit -// any loop that relies on this method. -CZMQ_EXPORT char * - zstr_recv_nowait (void *source); - -// Compiler hints -CZMQ_EXPORT int zstr_sendf (void *dest, const char *format, ...) CHECK_PRINTF (2); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zsys.h b/phonelibs/zmq/aarch64/include/zsys.h deleted file mode 100644 index 97f88a9555b8e0..00000000000000 --- a/phonelibs/zmq/aarch64/include/zsys.h +++ /dev/null @@ -1,386 +0,0 @@ -/* ========================================================================= - zsys - system-level methods - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZSYS_H_INCLUDED__ -#define __ZSYS_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -#define UDP_FRAME_MAX 255 // Max size of UDP frame - -// Callback for interrupt signal handler -typedef void (zsys_handler_fn) (int signal_value); - -// Initialize CZMQ zsys layer; this happens automatically when you create -// a socket or an actor; however this call lets you force initialization -// earlier, so e.g. logging is properly set-up before you start working. -// Not threadsafe, so call only from main thread. Safe to call multiple -// times. Returns global CZMQ context. -CZMQ_EXPORT void * - zsys_init (void); - -// Optionally shut down the CZMQ zsys layer; this normally happens automatically -// when the process exits; however this call lets you force a shutdown -// earlier, avoiding any potential problems with atexit() ordering, especially -// with Windows dlls. -CZMQ_EXPORT void - zsys_shutdown (void); - -// Get a new ZMQ socket, automagically creating a ZMQ context if this is -// the first time. Caller is responsible for destroying the ZMQ socket -// before process exits, to avoid a ZMQ deadlock. Note: you should not use -// this method in CZMQ apps, use zsock_new() instead. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT void * - zsys_socket (int type, const char *filename, size_t line_nbr); - -// Destroy/close a ZMQ socket. You should call this for every socket you -// create using zsys_socket(). -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT int - zsys_close (void *handle, const char *filename, size_t line_nbr); - -// Return ZMQ socket name for socket type -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT char * - zsys_sockname (int socktype); - -// Create a pipe, which consists of two PAIR sockets connected over inproc. -// The pipe is configured to use the zsys_pipehwm setting. Returns the -// frontend socket successful, NULL if failed. -CZMQ_EXPORT zsock_t * - zsys_create_pipe (zsock_t **backend_p); - -// Set interrupt handler; this saves the default handlers so that a -// zsys_handler_reset () can restore them. If you call this multiple times -// then the last handler will take affect. If handler_fn is NULL, disables -// default SIGINT/SIGTERM handling in CZMQ. -CZMQ_EXPORT void - zsys_handler_set (zsys_handler_fn *handler_fn); - -// Reset interrupt handler, call this at exit if needed -CZMQ_EXPORT void - zsys_handler_reset (void); - -// Set default interrupt handler, so Ctrl-C or SIGTERM will set -// zsys_interrupted. Idempotent; safe to call multiple times. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT void - zsys_catch_interrupts (void); - -// Return 1 if file exists, else zero -CZMQ_EXPORT bool - zsys_file_exists (const char *filename); - -// Return size of file, or -1 if not found -CZMQ_EXPORT ssize_t - zsys_file_size (const char *filename); - -// Return file modification time. Returns 0 if the file does not exist. -CZMQ_EXPORT time_t - zsys_file_modified (const char *filename); - -// Return file mode; provides at least support for the POSIX S_ISREG(m) -// and S_ISDIR(m) macros and the S_IRUSR and S_IWUSR bits, on all boxes. -// Returns a mode_t cast to int, or -1 in case of error. -CZMQ_EXPORT int - zsys_file_mode (const char *filename); - -// Delete file. Does not complain if the file is absent -CZMQ_EXPORT int - zsys_file_delete (const char *filename); - -// Check if file is 'stable' -CZMQ_EXPORT bool - zsys_file_stable (const char *filename); - -// Create a file path if it doesn't exist. The file path is treated as a -// printf format. -CZMQ_EXPORT int - zsys_dir_create (const char *pathname, ...); - -// Remove a file path if empty; the pathname is treated as printf format. -CZMQ_EXPORT int - zsys_dir_delete (const char *pathname, ...); - -// Move to a specified working directory. Returns 0 if OK, -1 if this failed. -CZMQ_EXPORT int - zsys_dir_change (const char *pathname); - -// Set private file creation mode; all files created from here will be -// readable/writable by the owner only. -CZMQ_EXPORT void - zsys_file_mode_private (void); - -// Reset default file creation mode; all files created from here will use -// process file mode defaults. -CZMQ_EXPORT void - zsys_file_mode_default (void); - -// Return the CZMQ version for run-time API detection; returns version -// number into provided fields, providing reference isn't null in each case. -CZMQ_EXPORT void - zsys_version (int *major, int *minor, int *patch); - -// Format a string using printf formatting, returning a freshly allocated -// buffer. If there was insufficient memory, returns NULL. Free the returned -// string using zstr_free(). -CZMQ_EXPORT char * - zsys_sprintf (const char *format, ...); - -// Format a string with a va_list argument, returning a freshly allocated -// buffer. If there was insufficient memory, returns NULL. Free the returned -// string using zstr_free(). -CZMQ_EXPORT char * - zsys_vprintf (const char *format, va_list argptr); - -// Create UDP beacon socket; if the routable option is true, uses -// multicast (not yet implemented), else uses broadcast. This method -// and related ones might _eventually_ be moved to a zudp class. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT SOCKET - zsys_udp_new (bool routable); - -// Close a UDP socket -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT int - zsys_udp_close (SOCKET handle); - -// Send zframe to UDP socket, return -1 if sending failed due to -// interface having disappeared (happens easily with WiFi) -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT int - zsys_udp_send (SOCKET udpsock, zframe_t *frame, inaddr_t *address, int addrlen); - -// Receive zframe from UDP socket, and set address of peer that sent it -// The peername must be a char [INET_ADDRSTRLEN] array. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT zframe_t * - zsys_udp_recv (SOCKET udpsock, char *peername, int peerlen); - -// Handle an I/O error on some socket operation; will report and die on -// fatal errors, and continue silently on "try again" errors. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT void - zsys_socket_error (const char *reason); - -// Return current host name, for use in public tcp:// endpoints. Caller gets -// a freshly allocated string, should free it using zstr_free(). If the host -// name is not resolvable, returns NULL. -CZMQ_EXPORT char * - zsys_hostname (void); - -// Move the current process into the background. The precise effect depends -// on the operating system. On POSIX boxes, moves to a specified working -// directory (if specified), closes all file handles, reopens stdin, stdout, -// and stderr to the null device, and sets the process to ignore SIGHUP. On -// Windows, does nothing. Returns 0 if OK, -1 if there was an error. -CZMQ_EXPORT int - zsys_daemonize (const char *workdir); - -// Drop the process ID into the lockfile, with exclusive lock, and switch -// the process to the specified group and/or user. Any of the arguments -// may be null, indicating a no-op. Returns 0 on success, -1 on failure. -// Note if you combine this with zsys_daemonize, run after, not before -// that method, or the lockfile will hold the wrong process ID. -CZMQ_EXPORT int - zsys_run_as (const char *lockfile, const char *group, const char *user); - -// Returns true if the underlying libzmq supports CURVE security. -// Uses a heuristic probe according to the version of libzmq being used. -CZMQ_EXPORT bool - zsys_has_curve (void); - -// Configure the number of I/O threads that ZeroMQ will use. A good -// rule of thumb is one thread per gigabit of traffic in or out. The -// default is 1, sufficient for most applications. If the environment -// variable ZSYS_IO_THREADS is defined, that provides the default. -// Note that this method is valid only before any socket is created. -CZMQ_EXPORT void - zsys_set_io_threads (size_t io_threads); - -// Configure the number of sockets that ZeroMQ will allow. The default -// is 1024. The actual limit depends on the system, and you can query it -// by using zsys_socket_limit (). A value of zero means "maximum". -// Note that this method is valid only before any socket is created. -CZMQ_EXPORT void - zsys_set_max_sockets (size_t max_sockets); - -// Return maximum number of ZeroMQ sockets that the system will support. -CZMQ_EXPORT size_t - zsys_socket_limit (void); - -// Configure the default linger timeout in msecs for new zsock instances. -// You can also set this separately on each zsock_t instance. The default -// linger time is zero, i.e. any pending messages will be dropped. If the -// environment variable ZSYS_LINGER is defined, that provides the default. -// Note that process exit will typically be delayed by the linger time. -CZMQ_EXPORT void - zsys_set_linger (size_t linger); - -// Configure the default outgoing pipe limit (HWM) for new zsock instances. -// You can also set this separately on each zsock_t instance. The default -// HWM is 1,000, on all versions of ZeroMQ. If the environment variable -// ZSYS_SNDHWM is defined, that provides the default. Note that a value of -// zero means no limit, i.e. infinite memory consumption. -CZMQ_EXPORT void - zsys_set_sndhwm (size_t sndhwm); - -// Configure the default incoming pipe limit (HWM) for new zsock instances. -// You can also set this separately on each zsock_t instance. The default -// HWM is 1,000, on all versions of ZeroMQ. If the environment variable -// ZSYS_RCVHWM is defined, that provides the default. Note that a value of -// zero means no limit, i.e. infinite memory consumption. -CZMQ_EXPORT void - zsys_set_rcvhwm (size_t rcvhwm); - -// Configure the default HWM for zactor internal pipes; this is set on both -// ends of the pipe, for outgoing messages only (sndhwm). The default HWM is -// 1,000, on all versions of ZeroMQ. If the environment var ZSYS_ACTORHWM is -// defined, that provides the default. Note that a value of zero means no -// limit, i.e. infinite memory consumption. -CZMQ_EXPORT void - zsys_set_pipehwm (size_t pipehwm); - -// Return the HWM for zactor internal pipes. -CZMQ_EXPORT size_t - zsys_pipehwm (void); - -// Configure use of IPv6 for new zsock instances. By default sockets accept -// and make only IPv4 connections. When you enable IPv6, sockets will accept -// and connect to both IPv4 and IPv6 peers. You can override the setting on -// each zsock_t instance. The default is IPv4 only (ipv6 set to 0). If the -// environment variable ZSYS_IPV6 is defined (as 1 or 0), this provides the -// default. Note: has no effect on ZMQ v2. -CZMQ_EXPORT void - zsys_set_ipv6 (int ipv6); - -// Return use of IPv6 for zsock instances. -CZMQ_EXPORT int - zsys_ipv6 (void); - -// Set network interface name to use for broadcasts, particularly zbeacon. -// This lets the interface be configured for test environments where required. -// For example, on Mac OS X, zbeacon cannot bind to 255.255.255.255 which is -// the default when there is no specified interface. If the environment -// variable ZSYS_INTERFACE is set, use that as the default interface name. -// Setting the interface to "*" means "use all available interfaces". -CZMQ_EXPORT void - zsys_set_interface (const char *value); - -// Return network interface to use for broadcasts, or "" if none was set. -CZMQ_EXPORT const char * - zsys_interface (void); - -// Set IPv6 address to use zbeacon socket, particularly for receiving zbeacon. -// This needs to be set IPv6 is enabled as IPv6 can have multiple addresses -// on a given interface. If the environment variable ZSYS_IPV6_ADDRESS is set, -// use that as the default IPv6 address. -CZMQ_EXPORT void - zsys_set_ipv6_address (const char *value); - -// Return IPv6 address to use for zbeacon reception, or "" if none was set. -CZMQ_EXPORT const char * - zsys_ipv6_address (void); - -// Set IPv6 milticast address to use for sending zbeacon messages. This needs -// to be set if IPv6 is enabled. If the environment variable -// ZSYS_IPV6_MCAST_ADDRESS is set, use that as the default IPv6 multicast -// address. -CZMQ_EXPORT void - zsys_set_ipv6_mcast_address (const char *value); - -// Return IPv6 multicast address to use for sending zbeacon, or "" if none was -// set. -CZMQ_EXPORT const char * - zsys_ipv6_mcast_address (void); - -// Configure the automatic use of pre-allocated FDs when creating new sockets. -// If 0 (default), nothing will happen. Else, when a new socket is bound, the -// system API will be used to check if an existing pre-allocated FD with a -// matching port (if TCP) or path (if IPC) exists, and if it does it will be -// set via the ZMQ_USE_FD socket option so that the library will use it -// instead of creating a new socket. -CZMQ_EXPORT void - zsys_set_auto_use_fd (int auto_use_fd); - -// Return use of automatic pre-allocated FDs for zsock instances. -CZMQ_EXPORT int - zsys_auto_use_fd (void); - -// Set log identity, which is a string that prefixes all log messages sent -// by this process. The log identity defaults to the environment variable -// ZSYS_LOGIDENT, if that is set. -CZMQ_EXPORT void - zsys_set_logident (const char *value); - -// Set stream to receive log traffic. By default, log traffic is sent to -// stdout. If you set the stream to NULL, no stream will receive the log -// traffic (it may still be sent to the system facility). -CZMQ_EXPORT void - zsys_set_logstream (FILE *stream); - -// Sends log output to a PUB socket bound to the specified endpoint. To -// collect such log output, create a SUB socket, subscribe to the traffic -// you care about, and connect to the endpoint. Log traffic is sent as a -// single string frame, in the same format as when sent to stdout. The -// log system supports a single sender; multiple calls to this method will -// bind the same sender to multiple endpoints. To disable the sender, call -// this method with a null argument. -CZMQ_EXPORT void - zsys_set_logsender (const char *endpoint); - -// Enable or disable logging to the system facility (syslog on POSIX boxes, -// event log on Windows). By default this is disabled. -CZMQ_EXPORT void - zsys_set_logsystem (bool logsystem); - -// Log error condition - highest priority -CZMQ_EXPORT void - zsys_error (const char *format, ...); - -// Log warning condition - high priority -CZMQ_EXPORT void - zsys_warning (const char *format, ...); - -// Log normal, but significant, condition - normal priority -CZMQ_EXPORT void - zsys_notice (const char *format, ...); - -// Log informational message - low priority -CZMQ_EXPORT void - zsys_info (const char *format, ...); - -// Log debug-level message - lowest priority -CZMQ_EXPORT void - zsys_debug (const char *format, ...); - -// Self test of this class -CZMQ_EXPORT void - zsys_test (bool verbose); - -// Global signal indicator, TRUE when user presses Ctrl-C or the process -// gets a SIGTERM signal. -CZMQ_EXPORT extern volatile int zsys_interrupted; -// Deprecated name for this variable -CZMQ_EXPORT extern volatile int zctx_interrupted; -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zthread.h b/phonelibs/zmq/aarch64/include/zthread.h deleted file mode 100644 index fc0602dd9ff483..00000000000000 --- a/phonelibs/zmq/aarch64/include/zthread.h +++ /dev/null @@ -1,50 +0,0 @@ -/* ========================================================================= - zthread - working with system threads (deprecated) - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZTHREAD_H_INCLUDED__ -#define __ZTHREAD_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// Detached threads follow POSIX pthreads API -typedef void *(zthread_detached_fn) (void *args); - -// Attached threads get context and pipe from parent -typedef void (zthread_attached_fn) (void *args, zctx_t *ctx, void *pipe); - -// Create a detached thread. A detached thread operates autonomously -// and is used to simulate a separate process. It gets no ctx, and no -// pipe. -CZMQ_EXPORT int - zthread_new (zthread_detached_fn *thread_fn, void *args); - -// Create an attached thread. An attached thread gets a ctx and a PAIR -// pipe back to its parent. It must monitor its pipe, and exit if the -// pipe becomes unreadable. Do not destroy the ctx, the thread does this -// automatically when it ends. -CZMQ_EXPORT void * - zthread_fork (zctx_t *ctx, zthread_attached_fn *thread_fn, void *args); - -// Self test of this class -CZMQ_EXPORT void - zthread_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/include/zuuid.h b/phonelibs/zmq/aarch64/include/zuuid.h deleted file mode 100644 index afc1104fea952b..00000000000000 --- a/phonelibs/zmq/aarch64/include/zuuid.h +++ /dev/null @@ -1,96 +0,0 @@ -/* ========================================================================= - zuuid - UUID support class - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZUUID_H_INCLUDED__ -#define __ZUUID_H_INCLUDED__ - -#define ZUUID_LEN 16 -#define ZUUID_STR_LEN (ZUUID_LEN * 2) - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zuuid.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Create a new UUID object. -CZMQ_EXPORT zuuid_t * - zuuid_new (void); - -// Create UUID object from supplied ZUUID_LEN-octet value. -CZMQ_EXPORT zuuid_t * - zuuid_new_from (const byte *source); - -// Destroy a specified UUID object. -CZMQ_EXPORT void - zuuid_destroy (zuuid_t **self_p); - -// Set UUID to new supplied ZUUID_LEN-octet value. -CZMQ_EXPORT void - zuuid_set (zuuid_t *self, const byte *source); - -// Set UUID to new supplied string value skipping '-' and '{' '}' -// optional delimiters. Return 0 if OK, else returns -1. -CZMQ_EXPORT int - zuuid_set_str (zuuid_t *self, const char *source); - -// Return UUID binary data. -CZMQ_EXPORT const byte * - zuuid_data (zuuid_t *self); - -// Return UUID binary size -CZMQ_EXPORT size_t - zuuid_size (zuuid_t *self); - -// Returns UUID as string -CZMQ_EXPORT const char * - zuuid_str (zuuid_t *self); - -// Return UUID in the canonical string format: 8-4-4-4-12, in lower -// case. Caller does not modify or free returned value. See -// http://en.wikipedia.org/wiki/Universally_unique_identifier -CZMQ_EXPORT const char * - zuuid_str_canonical (zuuid_t *self); - -// Store UUID blob in target array -CZMQ_EXPORT void - zuuid_export (zuuid_t *self, byte *target); - -// Check if UUID is same as supplied value -CZMQ_EXPORT bool - zuuid_eq (zuuid_t *self, const byte *compare); - -// Check if UUID is different from supplied value -CZMQ_EXPORT bool - zuuid_neq (zuuid_t *self, const byte *compare); - -// Make copy of UUID object; if uuid is null, or memory was exhausted, -// returns null. -CZMQ_EXPORT zuuid_t * - zuuid_dup (zuuid_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zuuid_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/aarch64/lib/libczmq.a b/phonelibs/zmq/aarch64/lib/libczmq.a deleted file mode 100644 index 2d2a251c2f453e..00000000000000 Binary files a/phonelibs/zmq/aarch64/lib/libczmq.a and /dev/null differ diff --git a/phonelibs/zmq/aarch64/lib/libczmq.la b/phonelibs/zmq/aarch64/lib/libczmq.la deleted file mode 100755 index 7eb675e692d303..00000000000000 --- a/phonelibs/zmq/aarch64/lib/libczmq.la +++ /dev/null @@ -1,41 +0,0 @@ -# libczmq.la - a libtool library file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='libczmq.so' - -# Names of this library. -library_names='libczmq.so' - -# The name of the static archive. -old_library='libczmq.a' - -# Linker flags that cannot go in dependency_libs. -inherited_linker_flags='' - -# Libraries that this one depends upon. -dependency_libs=' -L/Users/batman/src/czmq/builds/android/prefix/aarch64-linux-android-4.9/lib -L/opt/android-ndk/platforms/android-21/arch-arm64/usr/lib -L/opt/android-ndk/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a -L/Users/batman/src/libzmq/builds/android/prefix/aarch64-linux-android-4.9/lib /Users/batman/src/libzmq/builds/android/prefix/aarch64-linux-android-4.9/lib/libzmq.la -llog -lc -lgcc -ldl -lm -lgnustl_shared' - -# Names of additional weak libraries provided by this library -weak_library_names='' - -# Version information for libczmq. -current=3 -age=0 -revision=0 - -# Is this an already installed library? -installed=yes - -# Should we warn about portability when linking against -modules? -shouldnotlink=no - -# Files to dlopen/dlpreopen -dlopen='' -dlpreopen='' - -# Directory that this library needs to be installed in: -libdir='/Users/batman/src/czmq/builds/android/prefix/aarch64-linux-android-4.9/lib' diff --git a/phonelibs/zmq/aarch64/lib/libczmq.so b/phonelibs/zmq/aarch64/lib/libczmq.so deleted file mode 100755 index 6b662a197f2c93..00000000000000 Binary files a/phonelibs/zmq/aarch64/lib/libczmq.so and /dev/null differ diff --git a/phonelibs/zmq/aarch64/lib/libzmq.a b/phonelibs/zmq/aarch64/lib/libzmq.a deleted file mode 100644 index b764af7b6136e6..00000000000000 Binary files a/phonelibs/zmq/aarch64/lib/libzmq.a and /dev/null differ diff --git a/phonelibs/zmq/aarch64/lib/libzmq.la b/phonelibs/zmq/aarch64/lib/libzmq.la deleted file mode 100755 index d7d420a4bd98f2..00000000000000 --- a/phonelibs/zmq/aarch64/lib/libzmq.la +++ /dev/null @@ -1,41 +0,0 @@ -# libzmq.la - a libtool library file -# Generated by libtool (GNU libtool) 2.4.6 -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='libzmq.so' - -# Names of this library. -library_names='libzmq.so' - -# The name of the static archive. -old_library='libzmq.a' - -# Linker flags that cannot go in dependency_libs. -inherited_linker_flags='' - -# Libraries that this one depends upon. -dependency_libs=' -L/Users/batman/src/libzmq/builds/android/prefix/aarch64-linux-android-4.9/lib -L/opt/android-ndk/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a -lgnustl_shared' - -# Names of additional weak libraries provided by this library -weak_library_names='' - -# Version information for libzmq. -current=5 -age=0 -revision=0 - -# Is this an already installed library? -installed=yes - -# Should we warn about portability when linking against -modules? -shouldnotlink=no - -# Files to dlopen/dlpreopen -dlopen='' -dlpreopen='' - -# Directory that this library needs to be installed in: -libdir='/Users/batman/src/libzmq/builds/android/prefix/aarch64-linux-android-4.9/lib' diff --git a/phonelibs/zmq/aarch64/lib/libzmq.so b/phonelibs/zmq/aarch64/lib/libzmq.so deleted file mode 100755 index 909c7f43a6a5f3..00000000000000 Binary files a/phonelibs/zmq/aarch64/lib/libzmq.so and /dev/null differ diff --git a/phonelibs/zmq/arm/include/czmq.h b/phonelibs/zmq/arm/include/czmq.h deleted file mode 100644 index ba21aa3bd1efdd..00000000000000 --- a/phonelibs/zmq/arm/include/czmq.h +++ /dev/null @@ -1,31 +0,0 @@ -/* ========================================================================= - CZMQ - a high-level binding in C for ZeroMQ - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __CZMQ_H_INCLUDED__ -#define __CZMQ_H_INCLUDED__ - -// These are signatures for handler functions that customize the -// behavior of CZMQ containers. These are shared between all CZMQ -// container types. - -// -- destroy an item -typedef void (czmq_destructor) (void **item); -// -- duplicate an item -typedef void *(czmq_duplicator) (const void *item); -// - compare two items, for sorting -typedef int (czmq_comparator) (const void *item1, const void *item2); - -// Include the project library file -#include "czmq_library.h" - -#endif diff --git a/phonelibs/zmq/arm/include/czmq_library.h b/phonelibs/zmq/arm/include/czmq_library.h deleted file mode 100644 index be348db3e9a414..00000000000000 --- a/phonelibs/zmq/arm/include/czmq_library.h +++ /dev/null @@ -1,199 +0,0 @@ -/* ========================================================================= - czmq - generated layer of public API - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -################################################################################ -# THIS FILE IS 100% GENERATED BY ZPROJECT; DO NOT EDIT EXCEPT EXPERIMENTALLY # -# Read the zproject/README.md for information about making permanent changes. # -################################################################################ - ========================================================================= -*/ - -#ifndef CZMQ_LIBRARY_H_INCLUDED -#define CZMQ_LIBRARY_H_INCLUDED - -// Set up environment for the application -#include "czmq_prelude.h" - -// External dependencies -#include - -// CZMQ version macros for compile-time API detection -#define CZMQ_VERSION_MAJOR 3 -#define CZMQ_VERSION_MINOR 0 -#define CZMQ_VERSION_PATCH 3 - -#define CZMQ_MAKE_VERSION(major, minor, patch) \ - ((major) * 10000 + (minor) * 100 + (patch)) -#define CZMQ_VERSION \ - CZMQ_MAKE_VERSION(CZMQ_VERSION_MAJOR, CZMQ_VERSION_MINOR, CZMQ_VERSION_PATCH) - -#if defined (__WINDOWS__) -# if defined CZMQ_STATIC -# define CZMQ_EXPORT -# elif defined CZMQ_INTERNAL_BUILD -# if defined DLL_EXPORT -# define CZMQ_EXPORT __declspec(dllexport) -# else -# define CZMQ_EXPORT -# endif -# elif defined CZMQ_EXPORTS -# define CZMQ_EXPORT __declspec(dllexport) -# else -# define CZMQ_EXPORT __declspec(dllimport) -# endif -#else -# define CZMQ_EXPORT -#endif - -// Opaque class structures to allow forward references -// These classes are stable or legacy and built in all releases -typedef struct _zactor_t zactor_t; -#define ZACTOR_T_DEFINED -typedef struct _zarmour_t zarmour_t; -#define ZARMOUR_T_DEFINED -typedef struct _zcert_t zcert_t; -#define ZCERT_T_DEFINED -typedef struct _zcertstore_t zcertstore_t; -#define ZCERTSTORE_T_DEFINED -typedef struct _zchunk_t zchunk_t; -#define ZCHUNK_T_DEFINED -typedef struct _zclock_t zclock_t; -#define ZCLOCK_T_DEFINED -typedef struct _zconfig_t zconfig_t; -#define ZCONFIG_T_DEFINED -typedef struct _zdigest_t zdigest_t; -#define ZDIGEST_T_DEFINED -typedef struct _zdir_t zdir_t; -#define ZDIR_T_DEFINED -typedef struct _zdir_patch_t zdir_patch_t; -#define ZDIR_PATCH_T_DEFINED -typedef struct _zfile_t zfile_t; -#define ZFILE_T_DEFINED -typedef struct _zframe_t zframe_t; -#define ZFRAME_T_DEFINED -typedef struct _zhash_t zhash_t; -#define ZHASH_T_DEFINED -typedef struct _zhashx_t zhashx_t; -#define ZHASHX_T_DEFINED -typedef struct _ziflist_t ziflist_t; -#define ZIFLIST_T_DEFINED -typedef struct _zlist_t zlist_t; -#define ZLIST_T_DEFINED -typedef struct _zlistx_t zlistx_t; -#define ZLISTX_T_DEFINED -typedef struct _zloop_t zloop_t; -#define ZLOOP_T_DEFINED -typedef struct _zmsg_t zmsg_t; -#define ZMSG_T_DEFINED -typedef struct _zpoller_t zpoller_t; -#define ZPOLLER_T_DEFINED -typedef struct _zsock_t zsock_t; -#define ZSOCK_T_DEFINED -typedef struct _zstr_t zstr_t; -#define ZSTR_T_DEFINED -typedef struct _zuuid_t zuuid_t; -#define ZUUID_T_DEFINED -typedef struct _zauth_t zauth_t; -#define ZAUTH_T_DEFINED -typedef struct _zbeacon_t zbeacon_t; -#define ZBEACON_T_DEFINED -typedef struct _zgossip_t zgossip_t; -#define ZGOSSIP_T_DEFINED -typedef struct _zmonitor_t zmonitor_t; -#define ZMONITOR_T_DEFINED -typedef struct _zproxy_t zproxy_t; -#define ZPROXY_T_DEFINED -typedef struct _zrex_t zrex_t; -#define ZREX_T_DEFINED -typedef struct _zsys_t zsys_t; -#define ZSYS_T_DEFINED -typedef struct _zauth_v2_t zauth_v2_t; -#define ZAUTH_V2_T_DEFINED -typedef struct _zbeacon_v2_t zbeacon_v2_t; -#define ZBEACON_V2_T_DEFINED -typedef struct _zctx_t zctx_t; -#define ZCTX_T_DEFINED -typedef struct _zmonitor_v2_t zmonitor_v2_t; -#define ZMONITOR_V2_T_DEFINED -typedef struct _zmutex_t zmutex_t; -#define ZMUTEX_T_DEFINED -typedef struct _zproxy_v2_t zproxy_v2_t; -#define ZPROXY_V2_T_DEFINED -typedef struct _zsocket_t zsocket_t; -#define ZSOCKET_T_DEFINED -typedef struct _zsockopt_t zsockopt_t; -#define ZSOCKOPT_T_DEFINED -typedef struct _zthread_t zthread_t; -#define ZTHREAD_T_DEFINED -// Draft classes are by default not built in stable releases -#ifdef CZMQ_BUILD_DRAFT_API -typedef struct _zproc_t zproc_t; -#define ZPROC_T_DEFINED -typedef struct _ztimerset_t ztimerset_t; -#define ZTIMERSET_T_DEFINED -typedef struct _ztrie_t ztrie_t; -#define ZTRIE_T_DEFINED -#endif // CZMQ_BUILD_DRAFT_API - - -// Public classes, each with its own header file -#include "zactor.h" -#include "zarmour.h" -#include "zcert.h" -#include "zcertstore.h" -#include "zchunk.h" -#include "zclock.h" -#include "zconfig.h" -#include "zdigest.h" -#include "zdir.h" -#include "zdir_patch.h" -#include "zfile.h" -#include "zframe.h" -#include "zhash.h" -#include "zhashx.h" -#include "ziflist.h" -#include "zlist.h" -#include "zlistx.h" -#include "zloop.h" -#include "zmsg.h" -#include "zpoller.h" -#include "zsock.h" -#include "zstr.h" -#include "zuuid.h" -#include "zauth.h" -#include "zbeacon.h" -#include "zgossip.h" -#include "zmonitor.h" -#include "zproxy.h" -#include "zrex.h" -#include "zsys.h" -#include "zauth_v2.h" -#include "zbeacon_v2.h" -#include "zctx.h" -#include "zmonitor_v2.h" -#include "zmutex.h" -#include "zproxy_v2.h" -#include "zsocket.h" -#include "zsockopt.h" -#include "zthread.h" -#ifdef CZMQ_BUILD_DRAFT_API -#include "zproc.h" -#include "ztimerset.h" -#include "ztrie.h" -#endif // CZMQ_BUILD_DRAFT_API - -#endif -/* -################################################################################ -# THIS FILE IS 100% GENERATED BY ZPROJECT; DO NOT EDIT EXCEPT EXPERIMENTALLY # -# Read the zproject/README.md for information about making permanent changes. # -################################################################################ -*/ diff --git a/phonelibs/zmq/arm/include/czmq_prelude.h b/phonelibs/zmq/arm/include/czmq_prelude.h deleted file mode 100644 index e9ceb691e839ef..00000000000000 --- a/phonelibs/zmq/arm/include/czmq_prelude.h +++ /dev/null @@ -1,641 +0,0 @@ -/* ========================================================================= - czmq_prelude.h - CZMQ environment - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __CZMQ_PRELUDE_H_INCLUDED__ -#define __CZMQ_PRELUDE_H_INCLUDED__ - -//- Establish the compiler and computer system ------------------------------ -/* - * Defines zero or more of these symbols, for use in any non-portable - * code: - * - * __WINDOWS__ Microsoft C/C++ with Windows calls - * __MSDOS__ System is MS-DOS (set if __WINDOWS__ set) - * __VMS__ System is VAX/VMS or Alpha/OpenVMS - * __UNIX__ System is UNIX - * __OS2__ System is OS/2 - * - * __IS_32BIT__ OS/compiler is 32 bits - * __IS_64BIT__ OS/compiler is 64 bits - * - * When __UNIX__ is defined, we also define exactly one of these: - * - * __UTYPE_AUX Apple AUX - * __UTYPE_BEOS BeOS - * __UTYPE_BSDOS BSD/OS - * __UTYPE_DECALPHA Digital UNIX (Alpha) - * __UTYPE_IBMAIX IBM RS/6000 AIX - * __UTYPE_FREEBSD FreeBSD - * __UTYPE_HPUX HP/UX - * __UTYPE_ANDROID Android - * __UTYPE_LINUX Linux - * __UTYPE_GNU GNU/Hurd - * __UTYPE_MIPS MIPS (BSD 4.3/System V mixture) - * __UTYPE_NETBSD NetBSD - * __UTYPE_NEXT NeXT - * __UTYPE_OPENBSD OpenBSD - * __UTYPE_OSX Apple Macintosh OS X - * __UTYPE_IOS Apple iOS - * __UTYPE_QNX QNX - * __UTYPE_IRIX Silicon Graphics IRIX - * __UTYPE_SINIX SINIX-N (Siemens-Nixdorf Unix) - * __UTYPE_SUNOS SunOS - * __UTYPE_SUNSOLARIS Sun Solaris - * __UTYPE_UNIXWARE SCO UnixWare - * ... these are the ones I know about so far. - * __UTYPE_GENERIC Any other UNIX - * - * When __VMS__ is defined, we may define one or more of these: - * - * __VMS_XOPEN Supports XOPEN functions - */ - -#if (defined (__64BIT__) || defined (__x86_64__)) -# define __IS_64BIT__ // May have 64-bit OS/compiler -#else -# define __IS_32BIT__ // Else assume 32-bit OS/compiler -#endif - -#if (defined WIN32 || defined _WIN32) -# undef __WINDOWS__ -# define __WINDOWS__ -# undef __MSDOS__ -# define __MSDOS__ -#endif - -#if (defined WINDOWS || defined _WINDOWS || defined __WINDOWS__) -# undef __WINDOWS__ -# define __WINDOWS__ -# undef __MSDOS__ -# define __MSDOS__ -// Stop cheeky warnings about "deprecated" functions like fopen -# if _MSC_VER >= 1500 -# undef _CRT_SECURE_NO_DEPRECATE -# define _CRT_SECURE_NO_DEPRECATE -# pragma warning(disable: 4996) -# endif -#endif - -// MSDOS Microsoft C -// _MSC_VER Microsoft C -#if (defined (MSDOS) || defined (_MSC_VER)) -# undef __MSDOS__ -# define __MSDOS__ -# if (defined (_DEBUG) && !defined (DEBUG)) -# define DEBUG -# endif -#endif - -#if (defined (__EMX__) && defined (__i386__)) -# undef __OS2__ -# define __OS2__ -#endif - -// VMS VAX C (VAX/VMS) -// __VMS Dec C (Alpha/OpenVMS) -// __vax__ gcc -#if (defined (VMS) || defined (__VMS) || defined (__vax__)) -# undef __VMS__ -# define __VMS__ -# if (__VMS_VER >= 70000000) -# define __VMS_XOPEN -# endif -#endif - -// Try to define a __UTYPE_xxx symbol... -// unix SunOS at least -// __unix__ gcc -// _POSIX_SOURCE is various UNIX systems, maybe also VAX/VMS -#if (defined (unix) || defined (__unix__) || defined (_POSIX_SOURCE)) -# if (!defined (__VMS__)) -# undef __UNIX__ -# define __UNIX__ -# if (defined (__alpha)) // Digital UNIX is 64-bit -# undef __IS_32BIT__ -# define __IS_64BIT__ -# define __UTYPE_DECALPHA -# endif -# endif -#endif - -#if (defined (_AUX)) -# define __UTYPE_AUX -# define __UNIX__ -#elif (defined (__BEOS__)) -# define __UTYPE_BEOS -# define __UNIX__ -#elif (defined (__hpux)) -# define __UTYPE_HPUX -# define __UNIX__ -# define _INCLUDE_HPUX_SOURCE -# define _INCLUDE_XOPEN_SOURCE -# define _INCLUDE_POSIX_SOURCE -#elif (defined (_AIX) || defined (AIX)) -# define __UTYPE_IBMAIX -# define __UNIX__ -#elif (defined (BSD) || defined (bsd)) -# define __UTYPE_BSDOS -# define __UNIX__ -#elif (defined (__ANDROID__)) -# define __UTYPE_ANDROID -# define __UNIX__ -#elif (defined (LINUX) || defined (linux) || defined (__linux__)) -# define __UTYPE_LINUX -# define __UNIX__ -# ifndef __NO_CTYPE -# define __NO_CTYPE // Suppress warnings on tolower() -# endif -# ifndef _DEFAULT_SOURCE -# define _DEFAULT_SOURCE // Include stuff from 4.3 BSD Unix -# endif -#elif (defined (__GNU__)) -# define __UTYPE_GNU -# define __UNIX__ -#elif (defined (Mips)) -# define __UTYPE_MIPS -# define __UNIX__ -#elif (defined (FreeBSD) || defined (__FreeBSD__)) -# define __UTYPE_FREEBSD -# define __UNIX__ -#elif (defined (NetBSD) || defined (__NetBSD__)) -# define __UTYPE_NETBSD -# define __UNIX__ -#elif (defined (OpenBSD) || defined (__OpenBSD__)) -# define __UTYPE_OPENBSD -# define __UNIX__ -#elif (defined (APPLE) || defined (__APPLE__)) -# include -# define __UNIX__ -# if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR -# define __UTYPE_IOS -# else -# define __UTYPE_OSX -# endif -#elif (defined (NeXT)) -# define __UTYPE_NEXT -# define __UNIX__ -#elif (defined (__QNX__)) -# define __UTYPE_QNX -# define __UNIX__ -#elif (defined (sgi)) -# define __UTYPE_IRIX -# define __UNIX__ -#elif (defined (sinix)) -# define __UTYPE_SINIX -# define __UNIX__ -#elif (defined (SOLARIS) || defined (__SRV4)) -# define __UTYPE_SUNSOLARIS -# define __UNIX__ -#elif (defined (SUNOS) || defined (SUN) || defined (sun)) -# define __UTYPE_SUNOS -# define __UNIX__ -#elif (defined (__USLC__) || defined (UnixWare)) -# define __UTYPE_UNIXWARE -# define __UNIX__ -#elif (defined (__CYGWIN__)) -# define __UTYPE_CYGWIN -# define __UNIX__ -#elif (defined (__UNIX__)) -# define __UTYPE_GENERIC -#endif - -//- Always include ZeroMQ headers ------------------------------------------- - -#include "zmq.h" -#if (ZMQ_VERSION < ZMQ_MAKE_VERSION (4, 2, 0)) -# include "zmq_utils.h" -#endif - -//- Standard ANSI include files --------------------------------------------- - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//- System-specific include files ------------------------------------------- - -#if (defined (__MSDOS__)) -# if (defined (__WINDOWS__)) -# if (_WIN32_WINNT < 0x0501) -# undef _WIN32_WINNT -# define _WIN32_WINNT 0x0501 -# endif -# if (!defined (FD_SETSIZE)) -# define FD_SETSIZE 1024 // Max. filehandles/sockets -# endif -# include -# include -# include -# include -# include // For getnameinfo () -# include // For GetAdaptersAddresses () -# endif -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#if (defined (__UNIX__)) -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include // Let CZMQ build with libzmq/3.x -# include // Must come before arpa/inet.h -# if (!defined (__UTYPE_ANDROID)) && (!defined (__UTYPE_IBMAIX)) \ - && (!defined (__UTYPE_HPUX)) -# include -# endif -# if defined (__UTYPE_SUNSOLARIS) || defined (__UTYPE_SUNOS) -# include -# endif -# if (!defined (__UTYPE_BEOS)) -# include -# if (!defined (TCP_NODELAY)) -# include -# endif -# endif -# if (defined (__UTYPE_IBMAIX) || defined(__UTYPE_QNX)) -# include -# endif -# if (defined (__UTYPE_BEOS)) -# include -# endif -# if ((defined (_XOPEN_REALTIME) && (_XOPEN_REALTIME >= 1)) \ - || (defined (_POSIX_VERSION) && (_POSIX_VERSION >= 199309L))) -# include -# endif -# if (defined (__UTYPE_OSX) || defined (__UTYPE_IOS)) -# include -# include // For monotonic clocks -# endif -# if (defined (__UTYPE_OSX)) -# include // For _NSGetEnviron() -# endif -# if (defined (__UTYPE_ANDROID)) -# include -# endif -# if (defined (__UTYPE_LINUX) && defined (HAVE_LIBSYSTEMD)) -# include -# endif -#endif - -#if (defined (__VMS__)) -# if (!defined (vaxc)) -# include // Not provided by Vax C -# endif -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#if (defined (__OS2__)) -# include // Required near top -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include // Must come before arpa/inet.h -# include -# include -# if (!defined (TCP_NODELAY)) -# include -# endif -#endif - -// Add missing defines for non-POSIX systems -#ifndef S_IRUSR -# define S_IRUSR S_IREAD -#endif -#ifndef S_IWUSR -# define S_IWUSR S_IWRITE -#endif -#ifndef S_ISDIR -# define S_ISDIR(m) (((m) & S_IFDIR) != 0) -#endif -#ifndef S_ISREG -# define S_ISREG(m) (((m) & S_IFREG) != 0) -#endif - - -//- Check compiler data type sizes ------------------------------------------ - -#if (UCHAR_MAX != 0xFF) -# error "Cannot compile: must change definition of 'byte'." -#endif -#if (USHRT_MAX != 0xFFFFU) -# error "Cannot compile: must change definition of 'dbyte'." -#endif -#if (UINT_MAX != 0xFFFFFFFFU) -# error "Cannot compile: must change definition of 'qbyte'." -#endif - -//- Data types -------------------------------------------------------------- - -typedef unsigned char byte; // Single unsigned byte = 8 bits -typedef unsigned short dbyte; // Double byte = 16 bits -typedef unsigned int qbyte; // Quad byte = 32 bits -typedef struct sockaddr_in inaddr_t; // Internet socket address structure -typedef struct sockaddr_in6 in6addr_t; // Internet 6 socket address structure - -// Common structure to hold inaddr_t and in6addr_t with length -typedef struct { - union { - inaddr_t __addr; // IPv4 address - in6addr_t __addr6; // IPv6 address - } __inaddr_u; -#define ipv4addr __inaddr_u.__addr -#define ipv6addr __inaddr_u.__addr6 - int inaddrlen; -} inaddr_storage_t; - -//- Inevitable macros ------------------------------------------------------- - -#define streq(s1,s2) (!strcmp ((s1), (s2))) -#define strneq(s1,s2) (strcmp ((s1), (s2))) - -// Provide random number from 0..(num-1) -#if (defined (__WINDOWS__)) || (defined (__UTYPE_IBMAIX)) \ - || (defined (__UTYPE_HPUX)) || (defined (__UTYPE_SUNOS)) -# define randof(num) (int) ((float) (num) * rand () / (RAND_MAX + 1.0)) -#else -# define randof(num) (int) ((float) (num) * random () / (RAND_MAX + 1.0)) -#endif - -// Windows MSVS doesn't have stdbool -#if (defined (_MSC_VER)) -# if (!defined (__cplusplus) && (!defined (true))) -# define true 1 -# define false 0 - typedef char bool; -# endif -#else -# include -#endif - -//- A number of POSIX and C99 keywords and data types ----------------------- -// CZMQ uses uint for array indices; equivalent to unsigned int, but more -// convenient in code. We define it in czmq_prelude.h on systems that do -// not define it by default. - -#if (defined (__WINDOWS__)) -# if (!defined (__cplusplus) && (!defined (inline))) -# define inline __inline -# endif -# define strtoull _strtoui64 -# define atoll _atoi64 -# define srandom srand -# define TIMEZONE _timezone -# if (!defined (__MINGW32__)) -# define snprintf _snprintf -# define vsnprintf _vsnprintf -# endif - typedef unsigned long ulong; - typedef unsigned int uint; -# if (!defined (__MINGW32__)) - typedef int mode_t; -# if !defined (_SSIZE_T_DEFINED) -typedef intptr_t ssize_t; -# define _SSIZE_T_DEFINED -# endif -# endif -# if ((!defined (__MINGW32__) \ - || (defined (__MINGW32__) && defined (__IS_64BIT__))) \ - && !defined (ZMQ_DEFINED_STDINT)) - typedef __int8 int8_t; - typedef __int16 int16_t; - typedef __int32 int32_t; - typedef __int64 int64_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; - typedef unsigned __int64 uint64_t; -# endif - typedef uint32_t in_addr_t; -# if (!defined (PRId8)) -# define PRId8 "d" -# endif -# if (!defined (PRId16)) -# define PRId16 "d" -# endif -# if (!defined (PRId32)) -# define PRId32 "d" -# endif -# if (!defined (PRId64)) -# define PRId64 "I64d" -# endif -# if (!defined (PRIu8)) -# define PRIu8 "u" -# endif -# if (!defined (PRIu16)) -# define PRIu16 "u" -# endif -# if (!defined (PRIu32)) -# define PRIu32 "u" -# endif -# if (!defined (PRIu64)) -# define PRIu64 "I64u" -# endif -# if (!defined (va_copy)) - // MSVC does not support C99's va_copy so we use a regular assignment -# define va_copy(dest,src) (dest) = (src) -# endif -#elif (defined (__UTYPE_OSX)) - typedef unsigned long ulong; - typedef unsigned int uint; - // This fixes header-order dependence problem with some Linux versions -#elif (defined (__UTYPE_LINUX)) -# if (__STDC_VERSION__ >= 199901L && !defined (__USE_MISC)) - typedef unsigned int uint; -# endif -#endif - -//- Non-portable declaration specifiers ------------------------------------- - -// For thread-local storage -#if defined (__WINDOWS__) -# define CZMQ_THREADLS __declspec(thread) -#else -# define CZMQ_THREADLS __thread -#endif - -// Replacement for malloc() which asserts if we run out of heap, and -// which zeroes the allocated block. -static inline void * -safe_malloc (size_t size, const char *file, unsigned line) -{ -// printf ("%s:%u %08d\n", file, line, (int) size); - void *mem = calloc (1, size); - if (mem == NULL) { - fprintf (stderr, "FATAL ERROR at %s:%u\n", file, line); - fprintf (stderr, "OUT OF MEMORY (malloc returned NULL)\n"); - fflush (stderr); - abort (); - } - return mem; -} - -// Define _ZMALLOC_DEBUG if you need to trace memory leaks using e.g. mtrace, -// otherwise all allocations will claim to come from czmq_prelude.h. For best -// results, compile all classes so you see dangling object allocations. -// _ZMALLOC_PEDANTIC does the same thing, but its intention is to propagate -// out of memory condition back up the call stack. -#if defined _ZMALLOC_DEBUG || _ZMALLOC_PEDANTIC -# define zmalloc(size) calloc(1,(size)) -#else -# define zmalloc(size) safe_malloc((size), __FILE__, __LINE__) -#endif - -// GCC supports validating format strings for functions that act like printf -#if defined (__GNUC__) && (__GNUC__ >= 2) -# define CHECK_PRINTF(a) __attribute__((format (printf, a, a + 1))) -#else -# define CHECK_PRINTF(a) -#endif - -// Lets us write code that compiles both on Windows and normal platforms -#if !defined (__WINDOWS__) -typedef int SOCKET; -# define closesocket close -# define INVALID_SOCKET -1 -# define SOCKET_ERROR -1 -# define O_BINARY 0 -#endif - -//- Include non-portable header files based on platform.h ------------------- - -#if defined (HAVE_LINUX_WIRELESS_H) -# include -// This would normally come from net/if.h -unsigned int if_nametoindex (const char *ifname); -#else -# if defined (HAVE_NET_IF_H) -# include -# endif -# if defined (HAVE_NET_IF_MEDIA_H) -# include -# endif -#endif - -#if defined (__WINDOWS__) && !defined (HAVE_UUID) -# define HAVE_UUID 1 -#endif -#if defined (__UTYPE_OSX) && !defined (HAVE_UUID) -# define HAVE_UUID 1 -#endif -#if defined (HAVE_UUID) -# if defined (__UTYPE_FREEBSD) || defined (__UTYPE_NETBSD) -# include -# elif defined __UTYPE_HPUX -# include -# elif defined (__UNIX__) -# include -# endif -#endif - -// ZMQ compatibility macros - -#if ZMQ_VERSION_MAJOR == 4 -# define ZMQ_POLL_MSEC 1 // zmq_poll is msec - -#elif ZMQ_VERSION_MAJOR == 3 -# define ZMQ_POLL_MSEC 1 // zmq_poll is msec -# if ZMQ_VERSION_MINOR < 2 -# define zmq_ctx_new zmq_init -# endif -# define zmq_ctx_term zmq_term - -#elif ZMQ_VERSION_MAJOR == 2 -# define ZMQ_POLL_MSEC 1000 // zmq_poll is usec -# define zmq_sendmsg zmq_send // Smooth out 2.x changes -# define zmq_recvmsg zmq_recv -# define zmq_ctx_new zmq_init -# define zmq_ctx_term zmq_term -# define zmq_msg_send(m,s,f) zmq_sendmsg ((s),(m),(f)) -# define zmq_msg_recv(m,s,f) zmq_recvmsg ((s),(m),(f)) - // Older libzmq APIs may be missing some aspects of libzmq v3.0 -# ifndef ZMQ_ROUTER -# define ZMQ_ROUTER ZMQ_XREP -# endif -# ifndef ZMQ_DEALER -# define ZMQ_DEALER ZMQ_XREQ -# endif -# ifndef ZMQ_DONTWAIT -# define ZMQ_DONTWAIT ZMQ_NOBLOCK -# endif -# ifndef ZMQ_XSUB -# error "please upgrade your libzmq from http://zeromq.org" -# endif -# if ZMQ_VERSION_MINOR == 0 \ - || (ZMQ_VERSION_MINOR == 1 && ZMQ_VERSION_PATCH < 7) -# error "CZMQ requires at least libzmq/2.1.7 stable" -# endif -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zactor.h b/phonelibs/zmq/arm/include/zactor.h deleted file mode 100644 index c865c65daf1efa..00000000000000 --- a/phonelibs/zmq/arm/include/zactor.h +++ /dev/null @@ -1,76 +0,0 @@ -/* ========================================================================= - zactor - actor - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZACTOR_H_INCLUDED__ -#define __ZACTOR_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zactor.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Actors get a pipe and arguments from caller -typedef void (zactor_fn) ( - zsock_t *pipe, void *args); - -// Create a new actor passing arbitrary arguments reference. -CZMQ_EXPORT zactor_t * - zactor_new (zactor_fn task, void *args); - -// Destroy an actor. -CZMQ_EXPORT void - zactor_destroy (zactor_t **self_p); - -// Send a zmsg message to the actor, take ownership of the message -// and destroy when it has been sent. -CZMQ_EXPORT int - zactor_send (zactor_t *self, zmsg_t **msg_p); - -// Receive a zmsg message from the actor. Returns NULL if the actor -// was interrupted before the message could be received, or if there -// was a timeout on the actor. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zmsg_t * - zactor_recv (zactor_t *self); - -// Probe the supplied object, and report if it looks like a zactor_t. -CZMQ_EXPORT bool - zactor_is (void *self); - -// Probe the supplied reference. If it looks like a zactor_t instance, -// return the underlying libzmq actor handle; else if it looks like -// a libzmq actor handle, return the supplied value. -CZMQ_EXPORT void * - zactor_resolve (void *self); - -// Return the actor's zsock handle. Use this when you absolutely need -// to work with the zsock instance rather than the actor. -CZMQ_EXPORT zsock_t * - zactor_sock (zactor_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zactor_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zarmour.h b/phonelibs/zmq/arm/include/zarmour.h deleted file mode 100644 index c7f299f7afe989..00000000000000 --- a/phonelibs/zmq/arm/include/zarmour.h +++ /dev/null @@ -1,114 +0,0 @@ -/* ========================================================================= - zarmour - armoured text encoding and decoding - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZARMOUR_H_INCLUDED__ -#define __ZARMOUR_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zarmour.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -#define ZARMOUR_MODE_BASE64_STD 0 // Standard base 64 -#define ZARMOUR_MODE_BASE64_URL 1 // URL and filename friendly base 64 -#define ZARMOUR_MODE_BASE32_STD 2 // Standard base 32 -#define ZARMOUR_MODE_BASE32_HEX 3 // Extended hex base 32 -#define ZARMOUR_MODE_BASE16 4 // Standard base 16 -#define ZARMOUR_MODE_Z85 5 // Z85 from ZeroMQ RFC 32 - -// Create a new zarmour -CZMQ_EXPORT zarmour_t * - zarmour_new (void); - -// Destroy the zarmour -CZMQ_EXPORT void - zarmour_destroy (zarmour_t **self_p); - -// Encode a stream of bytes into an armoured string. Returns the armoured -// string, or NULL if there was insufficient memory available to allocate -// a new string. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zarmour_encode (zarmour_t *self, const byte *data, size_t size); - -// Decode an armoured string into a chunk. The decoded output is -// null-terminated, so it may be treated as a string, if that's what -// it was prior to encoding. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zchunk_t * - zarmour_decode (zarmour_t *self, const char *data); - -// Get the mode property. -CZMQ_EXPORT int - zarmour_mode (zarmour_t *self); - -// Get printable string for mode. -CZMQ_EXPORT const char * - zarmour_mode_str (zarmour_t *self); - -// Set the mode property. -CZMQ_EXPORT void - zarmour_set_mode (zarmour_t *self, int mode); - -// Return true if padding is turned on. -CZMQ_EXPORT bool - zarmour_pad (zarmour_t *self); - -// Turn padding on or off. Default is on. -CZMQ_EXPORT void - zarmour_set_pad (zarmour_t *self, bool pad); - -// Get the padding character. -CZMQ_EXPORT char - zarmour_pad_char (zarmour_t *self); - -// Set the padding character. -CZMQ_EXPORT void - zarmour_set_pad_char (zarmour_t *self, char pad_char); - -// Return if splitting output into lines is turned on. Default is off. -CZMQ_EXPORT bool - zarmour_line_breaks (zarmour_t *self); - -// Turn splitting output into lines on or off. -CZMQ_EXPORT void - zarmour_set_line_breaks (zarmour_t *self, bool line_breaks); - -// Get the line length used for splitting lines. -CZMQ_EXPORT size_t - zarmour_line_length (zarmour_t *self); - -// Set the line length used for splitting lines. -CZMQ_EXPORT void - zarmour_set_line_length (zarmour_t *self, size_t line_length); - -// Print properties of object -CZMQ_EXPORT void - zarmour_print (zarmour_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zarmour_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zauth.h b/phonelibs/zmq/arm/include/zauth.h deleted file mode 100644 index ca6bb913c8f5aa..00000000000000 --- a/phonelibs/zmq/arm/include/zauth.h +++ /dev/null @@ -1,100 +0,0 @@ -/* ========================================================================= - zauth - authentication for ZeroMQ security mechanisms - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZAUTH_H_INCLUDED__ -#define __ZAUTH_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -#define CURVE_ALLOW_ANY "*" - -// CZMQ v3 API (for use with zsock, not zsocket, which is deprecated). -// -// Create new zauth actor instance. This installs authentication on all -// zsock sockets. Until you add policies, all incoming NULL connections are -// allowed (classic ZeroMQ behaviour), and all PLAIN and CURVE connections -// are denied: -// -// zactor_t *auth = zactor_new (zauth, NULL); -// -// Destroy zauth instance. This removes authentication and allows all -// connections to pass, without authentication: -// -// zactor_destroy (&auth); -// -// Note that all zauth commands are synchronous, so your application always -// waits for a signal from the actor after each command. -// -// Enable verbose logging of commands and activity. Verbose logging can help -// debug non-trivial authentication policies: -// -// zstr_send (auth, "VERBOSE"); -// zsock_wait (auth); -// -// Allow (whitelist) a list of IP addresses. For NULL, all clients from -// these addresses will be accepted. For PLAIN and CURVE, they will be -// allowed to continue with authentication. You can call this method -// multiple times to whitelist more IP addresses. If you whitelist one -// or nmore addresses, any non-whitelisted addresses are treated as -// blacklisted: -// -// zstr_sendx (auth, "ALLOW", "127.0.0.1", "127.0.0.2", NULL); -// zsock_wait (auth); -// -// Deny (blacklist) a list of IP addresses. For all security mechanisms, -// this rejects the connection without any further authentication. Use -// either a whitelist, or a blacklist, not not both. If you define both -// a whitelist and a blacklist, only the whitelist takes effect: -// -// zstr_sendx (auth, "DENY", "192.168.0.1", "192.168.0.2", NULL); -// zsock_wait (auth); -// -// Configure PLAIN authentication using a plain-text password file. You can -// modify the password file at any time; zauth will reload it automatically -// if modified externally: -// -// zstr_sendx (auth, "PLAIN", filename, NULL); -// zsock_wait (auth); -// -// Configure CURVE authentication, using a directory that holds all public -// client certificates, i.e. their public keys. The certificates must be in -// zcert_save format. You can add and remove certificates in that directory -// at any time. To allow all client keys without checking, specify -// CURVE_ALLOW_ANY for the directory name: -// -// zstr_sendx (auth, "CURVE", directory, NULL); -// zsock_wait (auth); -// -// Configure GSSAPI authentication, using an underlying mechanism (usually -// Kerberos) to establish a secure context and perform mutual authentication: -// -// zstr_sendx (auth, "GSSAPI", NULL); -// zsock_wait (auth); -// -// This is the zauth constructor as a zactor_fn: -CZMQ_EXPORT void - zauth (zsock_t *pipe, void *certstore); - -// Selftest -CZMQ_EXPORT void - zauth_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zauth_v2.h b/phonelibs/zmq/arm/include/zauth_v2.h deleted file mode 100644 index bbbee86b03e62d..00000000000000 --- a/phonelibs/zmq/arm/include/zauth_v2.h +++ /dev/null @@ -1,88 +0,0 @@ -/* ========================================================================= - zauth_v2 - authentication for ZeroMQ servers (deprecated) - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZAUTH_V2_H_INCLUDED__ -#define __ZAUTH_V2_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -#ifndef CURVE_ALLOW_ANY -# define CURVE_ALLOW_ANY "*" -#endif - -// Constructor -// Install authentication for the specified context. Returns a new zauth -// object that you can use to configure authentication. Note that until you -// add policies, all incoming NULL connections are allowed (classic ZeroMQ -// behaviour), and all PLAIN and CURVE connections are denied. If there was -// an error during initialization, returns NULL. -CZMQ_EXPORT zauth_t * - zauth_new (zctx_t *ctx); - -// Destructor -CZMQ_EXPORT void - zauth_destroy (zauth_t **self_p); - -// Allow (whitelist) a single IP address. For NULL, all clients from this -// address will be accepted. For PLAIN and CURVE, they will be allowed to -// continue with authentication. You can call this method multiple times -// to whitelist multiple IP addresses. If you whitelist a single address, -// any non-whitelisted addresses are treated as blacklisted. -CZMQ_EXPORT void - zauth_allow (zauth_t *self, const char *address); - -// Deny (blacklist) a single IP address. For all security mechanisms, this -// rejects the connection without any further authentication. Use either a -// whitelist, or a blacklist, not not both. If you define both a whitelist -// and a blacklist, only the whitelist takes effect. -CZMQ_EXPORT void - zauth_deny (zauth_t *self, const char *address); - -// Configure PLAIN authentication for a given domain. PLAIN authentication -// uses a plain-text password file. To cover all domains, use "*". You can -// modify the password file at any time; it is reloaded automatically. -CZMQ_EXPORT void - zauth_configure_plain (zauth_t *self, const char *domain, const char *filename); - -// Configure CURVE authentication for a given domain. CURVE authentication -// uses a directory that holds all public client certificates, i.e. their -// public keys. The certificates must be in zcert_save () format. To cover -// all domains, use "*". You can add and remove certificates in that -// directory at any time. To allow all client keys without checking, specify -// CURVE_ALLOW_ANY for the location. -CZMQ_EXPORT void - zauth_configure_curve (zauth_t *self, const char *domain, const char *location); - -// Configure GSSAPI authentication for a given domain. GSSAPI authentication -// uses an underlying mechanism (usually Kerberos) to establish a secure -// context and perform mutual authentication. To cover all domains, use "*". -CZMQ_EXPORT void - zauth_configure_gssapi (zauth_t *self, char *domain); - -// Enable verbose tracing of commands and activity -CZMQ_EXPORT void - zauth_set_verbose (zauth_t *self, bool verbose); - -// Selftest -CZMQ_EXPORT void - zauth_v2_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zbeacon.h b/phonelibs/zmq/arm/include/zbeacon.h deleted file mode 100644 index 78917e9577e40f..00000000000000 --- a/phonelibs/zmq/arm/include/zbeacon.h +++ /dev/null @@ -1,86 +0,0 @@ -/* ========================================================================= - zbeacon - LAN discovery and presence - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZBEACON_H_INCLUDED__ -#define __ZBEACON_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// Create new zbeacon actor instance: -// -// zactor_t *beacon = zactor_new (zbeacon, NULL); -// -// Destroy zbeacon instance: -// -// zactor_destroy (&beacon); -// -// Enable verbose logging of commands and activity: -// -// zstr_send (beacon, "VERBOSE"); -// -// Configure beacon to run on specified UDP port, and return the name of -// the host, which can be used as endpoint for incoming connections. To -// force the beacon to operate on a given interface, set the environment -// variable ZSYS_INTERFACE, or call zsys_set_interface() before creating -// the beacon. If the system does not support UDP broadcasts (lacking a -// workable interface), returns an empty hostname: -// -// // Pictures: 's' = C string, 'i' = int -// zsock_send (beacon, "si", "CONFIGURE", port_number); -// char *hostname = zstr_recv (beacon); -// -// Start broadcasting a beacon at a specified interval in msec. The beacon -// data can be at most UDP_FRAME_MAX bytes; this constant is defined in -// zsys.h to be 255: -// -// // Pictures: 'b' = byte * data + size_t size -// zsock_send (beacon, "sbi", "PUBLISH", data, size, interval); -// -// Stop broadcasting the beacon: -// -// zstr_sendx (beacon, "SILENCE", NULL); -// -// Start listening to beacons from peers. The filter is used to do a prefix -// match on received beacons, to remove junk. Note that any received data -// that is identical to our broadcast beacon_data is discarded in any case. -// If the filter size is zero, we get all peer beacons: -// -// zsock_send (beacon, "sb", "SUBSCRIBE", filter_data, filter_size); -// -// Stop listening to other peers -// -// zstr_sendx (beacon, "UNSUBSCRIBE", NULL); -// -// Receive next beacon from a peer. Received beacons are always a 2-frame -// message containing the ipaddress of the sender, and then the binary -// beacon data as published by the sender: -// -// zmsg_t *msg = zmsg_recv (beacon); -// -// This is the zbeacon constructor as a zactor_fn: -CZMQ_EXPORT void - zbeacon (zsock_t *pipe, void *unused); - -// Self test of this class -CZMQ_EXPORT void - zbeacon_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zbeacon_v2.h b/phonelibs/zmq/arm/include/zbeacon_v2.h deleted file mode 100644 index 8e8f3b4cde9967..00000000000000 --- a/phonelibs/zmq/arm/include/zbeacon_v2.h +++ /dev/null @@ -1,75 +0,0 @@ -/* ========================================================================= - zbeacon - LAN discovery and presence (deprecated) - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZBEACON_V2_H_INCLUDED__ -#define __ZBEACON_V2_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// Create a new beacon on a certain UDP port. If the system does not -// support UDP broadcasts (lacking a useful interface), returns NULL. -// To force the beacon to operate on a given port, set the environment -// variable ZSYS_INTERFACE, or call zsys_set_interface() beforehand. -// If you are using the new zsock API then pass NULL as the ctx here. -CZMQ_EXPORT zbeacon_t * - zbeacon_new (zctx_t *ctx, int port_nbr); - -// Destroy a beacon -CZMQ_EXPORT void - zbeacon_destroy (zbeacon_t **self_p); - -// Return our own IP address as printable string -CZMQ_EXPORT char * - zbeacon_hostname (zbeacon_t *self); - -// Set broadcast interval in milliseconds (default is 1000 msec) -CZMQ_EXPORT void - zbeacon_set_interval (zbeacon_t *self, int interval); - -// Filter out any beacon that looks exactly like ours -CZMQ_EXPORT void - zbeacon_noecho (zbeacon_t *self); - -// Start broadcasting beacon to peers at the specified interval -CZMQ_EXPORT void - zbeacon_publish (zbeacon_t *self, byte *transmit, size_t size); - -// Stop broadcasting beacons -CZMQ_EXPORT void - zbeacon_silence (zbeacon_t *self); - -// Start listening to other peers; zero-sized filter means get everything -CZMQ_EXPORT void - zbeacon_subscribe (zbeacon_t *self, byte *filter, size_t size); - -// Stop listening to other peers -CZMQ_EXPORT void - zbeacon_unsubscribe (zbeacon_t *self); - -// Get beacon ZeroMQ socket, for polling or receiving messages -CZMQ_EXPORT void * - zbeacon_socket (zbeacon_t *self); - -// Self test of this class -CZMQ_EXPORT void - zbeacon_v2_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zcert.h b/phonelibs/zmq/arm/include/zcert.h deleted file mode 100644 index 495b579cda9317..00000000000000 --- a/phonelibs/zmq/arm/include/zcert.h +++ /dev/null @@ -1,139 +0,0 @@ -/* ========================================================================= - zcert - work with CURVE security certificates - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZCERT_H_INCLUDED__ -#define __ZCERT_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zcert.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// This class has legacy methods, which will be removed over time. You -// should not use them, and migrate any code that is still using them. -// Create and initialize a new certificate in memory -CZMQ_EXPORT zcert_t * - zcert_new (void); - -// Accepts public/secret key pair from caller -CZMQ_EXPORT zcert_t * - zcert_new_from (const byte *public_key, const byte *secret_key); - -// Load certificate from file -CZMQ_EXPORT zcert_t * - zcert_load (const char *filename); - -// Destroy a certificate in memory -CZMQ_EXPORT void - zcert_destroy (zcert_t **self_p); - -// Return public part of key pair as 32-byte binary string -CZMQ_EXPORT const byte * - zcert_public_key (zcert_t *self); - -// Return secret part of key pair as 32-byte binary string -CZMQ_EXPORT const byte * - zcert_secret_key (zcert_t *self); - -// Return public part of key pair as Z85 armored string -CZMQ_EXPORT const char * - zcert_public_txt (zcert_t *self); - -// Return secret part of key pair as Z85 armored string -CZMQ_EXPORT const char * - zcert_secret_txt (zcert_t *self); - -// Set certificate metadata from formatted string. -CZMQ_EXPORT void - zcert_set_meta (zcert_t *self, const char *name, const char *format, ...); - -// Get metadata value from certificate; if the metadata value doesn't -// exist, returns NULL. -CZMQ_EXPORT const char * - zcert_meta (zcert_t *self, const char *name); - -// Get list of metadata fields from certificate. Caller is responsible for -// destroying list. Caller should not modify the values of list items. -CZMQ_EXPORT zlist_t * - zcert_meta_keys (zcert_t *self); - -// Save full certificate (public + secret) to file for persistent storage -// This creates one public file and one secret file (filename + "_secret"). -CZMQ_EXPORT int - zcert_save (zcert_t *self, const char *filename); - -// Save public certificate only to file for persistent storage -CZMQ_EXPORT int - zcert_save_public (zcert_t *self, const char *filename); - -// Save secret certificate only to file for persistent storage -CZMQ_EXPORT int - zcert_save_secret (zcert_t *self, const char *filename); - -// Apply certificate to socket, i.e. use for CURVE security on socket. -// If certificate was loaded from public file, the secret key will be -// undefined, and this certificate will not work successfully. -CZMQ_EXPORT void - zcert_apply (zcert_t *self, void *socket); - -// Return copy of certificate; if certificate is NULL or we exhausted -// heap memory, returns NULL. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zcert_t * - zcert_dup (zcert_t *self); - -// Return true if two certificates have the same keys -CZMQ_EXPORT bool - zcert_eq (zcert_t *self, zcert_t *compare); - -// Print certificate contents to stdout -CZMQ_EXPORT void - zcert_print (zcert_t *self); - -// *** Deprecated method, slated for removal: avoid using it *** -// Print certificate contents to open stream. This method is deprecated -// and you should use the print method. -CZMQ_EXPORT void - zcert_fprint (zcert_t *self, FILE *file); - -// Self test of this class -CZMQ_EXPORT void - zcert_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Unset certificate metadata. -CZMQ_EXPORT void - zcert_unset_meta (zcert_t *self, const char *name); - -#endif // CZMQ_BUILD_DRAFT_API -// @ignore -CZMQ_EXPORT void - zcert_set_meta (zcert_t *self, const char *name, const char *format, ...) CHECK_PRINTF (3); -// @end - - -#ifdef __cplusplus -} -#endif - -// Deprecated method aliases -#define zcert_dump(s) zcert_print(s) - -#endif diff --git a/phonelibs/zmq/arm/include/zcertstore.h b/phonelibs/zmq/arm/include/zcertstore.h deleted file mode 100644 index c7f93c5a7d4604..00000000000000 --- a/phonelibs/zmq/arm/include/zcertstore.h +++ /dev/null @@ -1,100 +0,0 @@ -/* ========================================================================= - zcertstore - work with CURVE security certificate stores - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZCERTSTORE_H_INCLUDED__ -#define __ZCERTSTORE_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zcertstore.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// This class has legacy methods, which will be removed over time. You -// should not use them, and migrate any code that is still using them. -// Create a new certificate store from a disk directory, loading and -// indexing all certificates in that location. The directory itself may be -// absent, and created later, or modified at any time. The certificate store -// is automatically refreshed on any zcertstore_lookup() call. If the -// location is specified as NULL, creates a pure-memory store, which you -// can work with by inserting certificates at runtime. -CZMQ_EXPORT zcertstore_t * - zcertstore_new (const char *location); - -// Destroy a certificate store object in memory. Does not affect anything -// stored on disk. -CZMQ_EXPORT void - zcertstore_destroy (zcertstore_t **self_p); - -// Look up certificate by public key, returns zcert_t object if found, -// else returns NULL. The public key is provided in Z85 text format. -CZMQ_EXPORT zcert_t * - zcertstore_lookup (zcertstore_t *self, const char *public_key); - -// Insert certificate into certificate store in memory. Note that this -// does not save the certificate to disk. To do that, use zcert_save() -// directly on the certificate. Takes ownership of zcert_t object. -CZMQ_EXPORT void - zcertstore_insert (zcertstore_t *self, zcert_t **cert_p); - -// Print list of certificates in store to logging facility -CZMQ_EXPORT void - zcertstore_print (zcertstore_t *self); - -// *** Deprecated method, slated for removal: avoid using it *** -// Print list of certificates in store to open stream. This method is -// deprecated, and you should use the print method. -CZMQ_EXPORT void - zcertstore_fprint (zcertstore_t *self, FILE *file); - -// Self test of this class -CZMQ_EXPORT void - zcertstore_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// Loaders retrieve certificates from an arbitrary source. -typedef void (zcertstore_loader) ( - zcertstore_t *self); - -// Destructor for loader state. -typedef void (zcertstore_destructor) ( - void **self_p); - -// *** Draft method, for development use, may change without warning *** -// Override the default disk loader with a custom loader fn. -CZMQ_EXPORT void - zcertstore_set_loader (zcertstore_t *self, zcertstore_loader loader, zcertstore_destructor destructor, void *state); - -// *** Draft method, for development use, may change without warning *** -// Empty certificate hashtable. This wrapper exists to be friendly to bindings, -// which don't usually have access to struct internals. -CZMQ_EXPORT void - zcertstore_empty (zcertstore_t *self); - -#endif // CZMQ_BUILD_DRAFT_API -// @end - - -#ifdef __cplusplus -} -#endif - -// Deprecated method aliases -#define zcertstore_dump(s) zcertstore_print(s) - -#endif diff --git a/phonelibs/zmq/arm/include/zchunk.h b/phonelibs/zmq/arm/include/zchunk.h deleted file mode 100644 index 56f29b161a37e5..00000000000000 --- a/phonelibs/zmq/arm/include/zchunk.h +++ /dev/null @@ -1,163 +0,0 @@ -/* ========================================================================= - zchunk - work with memory chunks - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZCHUNK_H_INCLUDED__ -#define __ZCHUNK_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zchunk.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Create a new chunk of the specified size. If you specify the data, it -// is copied into the chunk. If you do not specify the data, the chunk is -// allocated and left empty, and you can then add data using zchunk_append. -CZMQ_EXPORT zchunk_t * - zchunk_new (const void *data, size_t size); - -// Destroy a chunk -CZMQ_EXPORT void - zchunk_destroy (zchunk_t **self_p); - -// Resizes chunk max_size as requested; chunk_cur size is set to zero -CZMQ_EXPORT void - zchunk_resize (zchunk_t *self, size_t size); - -// Return chunk cur size -CZMQ_EXPORT size_t - zchunk_size (zchunk_t *self); - -// Return chunk max size -CZMQ_EXPORT size_t - zchunk_max_size (zchunk_t *self); - -// Return chunk data -CZMQ_EXPORT byte * - zchunk_data (zchunk_t *self); - -// Set chunk data from user-supplied data; truncate if too large. Data may -// be null. Returns actual size of chunk -CZMQ_EXPORT size_t - zchunk_set (zchunk_t *self, const void *data, size_t size); - -// Fill chunk data from user-supplied octet -CZMQ_EXPORT size_t - zchunk_fill (zchunk_t *self, byte filler, size_t size); - -// Append user-supplied data to chunk, return resulting chunk size. If the -// data would exceeded the available space, it is truncated. If you want to -// grow the chunk to accommodate new data, use the zchunk_extend method. -CZMQ_EXPORT size_t - zchunk_append (zchunk_t *self, const void *data, size_t size); - -// Append user-supplied data to chunk, return resulting chunk size. If the -// data would exceeded the available space, the chunk grows in size. -CZMQ_EXPORT size_t - zchunk_extend (zchunk_t *self, const void *data, size_t size); - -// Copy as much data from 'source' into the chunk as possible; returns the -// new size of chunk. If all data from 'source' is used, returns exhausted -// on the source chunk. Source can be consumed as many times as needed until -// it is exhausted. If source was already exhausted, does not change chunk. -CZMQ_EXPORT size_t - zchunk_consume (zchunk_t *self, zchunk_t *source); - -// Returns true if the chunk was exhausted by consume methods, or if the -// chunk has a size of zero. -CZMQ_EXPORT bool - zchunk_exhausted (zchunk_t *self); - -// Read chunk from an open file descriptor -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zchunk_t * - zchunk_read (FILE *handle, size_t bytes); - -// Write chunk to an open file descriptor -CZMQ_EXPORT int - zchunk_write (zchunk_t *self, FILE *handle); - -// Try to slurp an entire file into a chunk. Will read up to maxsize of -// the file. If maxsize is 0, will attempt to read the entire file and -// fail with an assertion if that cannot fit into memory. Returns a new -// chunk containing the file data, or NULL if the file could not be read. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zchunk_t * - zchunk_slurp (const char *filename, size_t maxsize); - -// Create copy of chunk, as new chunk object. Returns a fresh zchunk_t -// object, or null if there was not enough heap memory. If chunk is null, -// returns null. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zchunk_t * - zchunk_dup (zchunk_t *self); - -// Return chunk data encoded as printable hex string. Caller must free -// string when finished with it. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zchunk_strhex (zchunk_t *self); - -// Return chunk data copied into freshly allocated string -// Caller must free string when finished with it. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zchunk_strdup (zchunk_t *self); - -// Return TRUE if chunk body is equal to string, excluding terminator -CZMQ_EXPORT bool - zchunk_streq (zchunk_t *self, const char *string); - -// Transform zchunk into a zframe that can be sent in a message. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zframe_t * - zchunk_pack (zchunk_t *self); - -// Transform a zframe into a zchunk. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zchunk_t * - zchunk_unpack (zframe_t *frame); - -// Calculate SHA1 digest for chunk, using zdigest class. -CZMQ_EXPORT const char * - zchunk_digest (zchunk_t *self); - -// Dump chunk to FILE stream, for debugging and tracing. -CZMQ_EXPORT void - zchunk_fprint (zchunk_t *self, FILE *file); - -// Dump message to stderr, for debugging and tracing. -// See zchunk_fprint for details -CZMQ_EXPORT void - zchunk_print (zchunk_t *self); - -// Probe the supplied object, and report if it looks like a zchunk_t. -CZMQ_EXPORT bool - zchunk_is (void *self); - -// Self test of this class. -CZMQ_EXPORT void - zchunk_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/phonelibs/zmq/arm/include/zclock.h b/phonelibs/zmq/arm/include/zclock.h deleted file mode 100644 index eb064162c4722a..00000000000000 --- a/phonelibs/zmq/arm/include/zclock.h +++ /dev/null @@ -1,73 +0,0 @@ -/* ========================================================================= - zclock - millisecond clocks and delays - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZCLOCK_H_INCLUDED__ -#define __ZCLOCK_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zclock.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Sleep for a number of milliseconds -CZMQ_EXPORT void - zclock_sleep (int msecs); - -// Return current system clock as milliseconds. Note that this clock can -// jump backwards (if the system clock is changed) so is unsafe to use for -// timers and time offsets. Use zclock_mono for that instead. -CZMQ_EXPORT int64_t - zclock_time (void); - -// Return current monotonic clock in milliseconds. Use this when you compute -// time offsets. The monotonic clock is not affected by system changes and -// so will never be reset backwards, unlike a system clock. -CZMQ_EXPORT int64_t - zclock_mono (void); - -// Return current monotonic clock in microseconds. Use this when you compute -// time offsets. The monotonic clock is not affected by system changes and -// so will never be reset backwards, unlike a system clock. -CZMQ_EXPORT int64_t - zclock_usecs (void); - -// Return formatted date/time as fresh string. Free using zstr_free(). -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zclock_timestr (void); - -// Self test of this class. -CZMQ_EXPORT void - zclock_test (bool verbose); - -// @end - - -// DEPRECATED in favor of zsys logging, see issue #519 -// Print formatted string to stdout, prefixed by date/time and -// terminated with a newline. -CZMQ_EXPORT void - zclock_log (const char *format, ...); - -// Compiler hints -CZMQ_EXPORT void zclock_log (const char *format, ...) CHECK_PRINTF (1); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zconfig.h b/phonelibs/zmq/arm/include/zconfig.h deleted file mode 100644 index 4ec4e1c81f03e1..00000000000000 --- a/phonelibs/zmq/arm/include/zconfig.h +++ /dev/null @@ -1,194 +0,0 @@ -/* ========================================================================= - zconfig - work with config files written in rfc.zeromq.org/spec:4/ZPL. - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZCONFIG_H_INCLUDED__ -#define __ZCONFIG_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zconfig.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// -typedef int (zconfig_fct) ( - zconfig_t *self, void *arg, int level); - -// Create new config item -CZMQ_EXPORT zconfig_t * - zconfig_new (const char *name, zconfig_t *parent); - -// Load a config tree from a specified ZPL text file; returns a zconfig_t -// reference for the root, if the file exists and is readable. Returns NULL -// if the file does not exist. -CZMQ_EXPORT zconfig_t * - zconfig_load (const char *filename); - -// Equivalent to zconfig_load, taking a format string instead of a fixed -// filename. -CZMQ_EXPORT zconfig_t * - zconfig_loadf (const char *format, ...); - -// Destroy a config item and all its children -CZMQ_EXPORT void - zconfig_destroy (zconfig_t **self_p); - -// Return name of config item -CZMQ_EXPORT char * - zconfig_name (zconfig_t *self); - -// Return value of config item -CZMQ_EXPORT char * - zconfig_value (zconfig_t *self); - -// Insert or update configuration key with value -CZMQ_EXPORT void - zconfig_put (zconfig_t *self, const char *path, const char *value); - -// Equivalent to zconfig_put, accepting a format specifier and variable -// argument list, instead of a single string value. -CZMQ_EXPORT void - zconfig_putf (zconfig_t *self, const char *path, const char *format, ...); - -// Get value for config item into a string value; leading slash is optional -// and ignored. -CZMQ_EXPORT char * - zconfig_get (zconfig_t *self, const char *path, const char *default_value); - -// Set config item name, name may be NULL -CZMQ_EXPORT void - zconfig_set_name (zconfig_t *self, const char *name); - -// Set new value for config item. The new value may be a string, a printf -// format, or NULL. Note that if string may possibly contain '%', or if it -// comes from an insecure source, you must use '%s' as the format, followed -// by the string. -CZMQ_EXPORT void - zconfig_set_value (zconfig_t *self, const char *format, ...); - -// Find our first child, if any -CZMQ_EXPORT zconfig_t * - zconfig_child (zconfig_t *self); - -// Find our first sibling, if any -CZMQ_EXPORT zconfig_t * - zconfig_next (zconfig_t *self); - -// Find a config item along a path; leading slash is optional and ignored. -CZMQ_EXPORT zconfig_t * - zconfig_locate (zconfig_t *self, const char *path); - -// Locate the last config item at a specified depth -CZMQ_EXPORT zconfig_t * - zconfig_at_depth (zconfig_t *self, int level); - -// Execute a callback for each config item in the tree; returns zero if -// successful, else -1. -CZMQ_EXPORT int - zconfig_execute (zconfig_t *self, zconfig_fct handler, void *arg); - -// Add comment to config item before saving to disk. You can add as many -// comment lines as you like. If you use a null format, all comments are -// deleted. -CZMQ_EXPORT void - zconfig_set_comment (zconfig_t *self, const char *format, ...); - -// Return comments of config item, as zlist. -CZMQ_EXPORT zlist_t * - zconfig_comments (zconfig_t *self); - -// Save a config tree to a specified ZPL text file, where a filename -// "-" means dump to standard output. -CZMQ_EXPORT int - zconfig_save (zconfig_t *self, const char *filename); - -// Equivalent to zconfig_save, taking a format string instead of a fixed -// filename. -CZMQ_EXPORT int - zconfig_savef (zconfig_t *self, const char *format, ...); - -// Report filename used during zconfig_load, or NULL if none -CZMQ_EXPORT const char * - zconfig_filename (zconfig_t *self); - -// Reload config tree from same file that it was previously loaded from. -// Returns 0 if OK, -1 if there was an error (and then does not change -// existing data). -CZMQ_EXPORT int - zconfig_reload (zconfig_t **self_p); - -// Load a config tree from a memory chunk -CZMQ_EXPORT zconfig_t * - zconfig_chunk_load (zchunk_t *chunk); - -// Save a config tree to a new memory chunk -CZMQ_EXPORT zchunk_t * - zconfig_chunk_save (zconfig_t *self); - -// Load a config tree from a null-terminated string -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zconfig_t * - zconfig_str_load (const char *string); - -// Save a config tree to a new null terminated string -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zconfig_str_save (zconfig_t *self); - -// Return true if a configuration tree was loaded from a file and that -// file has changed in since the tree was loaded. -CZMQ_EXPORT bool - zconfig_has_changed (zconfig_t *self); - -// Print the config file to open stream -CZMQ_EXPORT void - zconfig_fprint (zconfig_t *self, FILE *file); - -// Print properties of object -CZMQ_EXPORT void - zconfig_print (zconfig_t *self); - -// Self test of this class -CZMQ_EXPORT void - zconfig_test (bool verbose); - -// @ignore -CZMQ_EXPORT void - zconfig_putf (zconfig_t *self, const char *path, const char *format, ...) CHECK_PRINTF (3); -CZMQ_EXPORT void - zconfig_set_value (zconfig_t *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT void - zconfig_set_comment (zconfig_t *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int - zconfig_savef (zconfig_t *self, const char *format, ...) CHECK_PRINTF (2); -// @end - -// Self test of this class -CZMQ_EXPORT void - zconfig_test (bool verbose); - -// Compiler hints -CZMQ_EXPORT void zconfig_set_value (zconfig_t *self, const char *format, ...) CHECK_PRINTF (2); - -#ifdef __cplusplus -} -#endif - -// Deprecated method aliases -#define zconfig_dump(s) zconfig_print(s) -#define zconfig_resolve(s,p,d) zconfig_get((s),(p),(d)) - -#endif diff --git a/phonelibs/zmq/arm/include/zctx.h b/phonelibs/zmq/arm/include/zctx.h deleted file mode 100644 index 88898410dc8e99..00000000000000 --- a/phonelibs/zmq/arm/include/zctx.h +++ /dev/null @@ -1,107 +0,0 @@ -/* ========================================================================= - zctx - working with 0MQ contexts - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZCTX_H_INCLUDED__ -#define __ZCTX_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - - -// @interface -// Create new context, returns context object, replaces zmq_init -CZMQ_EXPORT zctx_t * - zctx_new (void); - -// Destroy context and all sockets in it, replaces zmq_term -CZMQ_EXPORT void - zctx_destroy (zctx_t **self_p); - -// Create new shadow context, returns context object -CZMQ_EXPORT zctx_t * - zctx_shadow (zctx_t *self); -// @end - -// Create a new context by shadowing a plain zmq context -CZMQ_EXPORT zctx_t * -zctx_shadow_zmq_ctx (void *zmqctx); - -// @interface -// Raise default I/O threads from 1, for crazy heavy applications -// The rule of thumb is one I/O thread per gigabyte of traffic in -// or out. Call this method before creating any sockets on the context, -// or calling zctx_shadow, or the setting will have no effect. -CZMQ_EXPORT void - zctx_set_iothreads (zctx_t *self, int iothreads); - -// Set msecs to flush sockets when closing them, see the ZMQ_LINGER -// man page section for more details. By default, set to zero, so -// any in-transit messages are discarded when you destroy a socket or -// a context. -CZMQ_EXPORT void - zctx_set_linger (zctx_t *self, int linger); - -// Set initial high-water mark for inter-thread pipe sockets. Note that -// this setting is separate from the default for normal sockets. You -// should change the default for pipe sockets *with care*. Too low values -// will cause blocked threads, and an infinite setting can cause memory -// exhaustion. The default, no matter the underlying ZeroMQ version, is -// 1,000. -CZMQ_EXPORT void - zctx_set_pipehwm (zctx_t *self, int pipehwm); - -// Set initial send HWM for all new normal sockets created in context. -// You can set this per-socket after the socket is created. -// The default, no matter the underlying ZeroMQ version, is 1,000. -CZMQ_EXPORT void - zctx_set_sndhwm (zctx_t *self, int sndhwm); - -// Set initial receive HWM for all new normal sockets created in context. -// You can set this per-socket after the socket is created. -// The default, no matter the underlying ZeroMQ version, is 1,000. -CZMQ_EXPORT void - zctx_set_rcvhwm (zctx_t *self, int rcvhwm); - -// Return low-level 0MQ context object, will be NULL before first socket -// is created. Use with care. -CZMQ_EXPORT void * - zctx_underlying (zctx_t *self); - -// Self test of this class -CZMQ_EXPORT void - zctx_test (bool verbose); -// @end - -// Create socket within this context, for CZMQ use only -void * - zctx__socket_new (zctx_t *self, int type); - -// Create pipe socket within this context, for CZMQ use only -void * - zctx__socket_pipe (zctx_t *self); - -// Destroy socket within this context, for CZMQ use only -void - zctx__socket_destroy (zctx_t *self, void *socket); - -// Initialize the low-level 0MQ context object, for CZMQ use only -void - zctx__initialize_underlying(zctx_t *self); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zdigest.h b/phonelibs/zmq/arm/include/zdigest.h deleted file mode 100644 index def9e860537094..00000000000000 --- a/phonelibs/zmq/arm/include/zdigest.h +++ /dev/null @@ -1,65 +0,0 @@ -/* ========================================================================= - zdigest - provides hashing functions (SHA-1 at present) - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZDIGEST_H_INCLUDED__ -#define __ZDIGEST_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zdigest.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Constructor - creates new digest object, which you use to build up a -// digest by repeatedly calling zdigest_update() on chunks of data. -CZMQ_EXPORT zdigest_t * - zdigest_new (void); - -// Destroy a digest object -CZMQ_EXPORT void - zdigest_destroy (zdigest_t **self_p); - -// Add buffer into digest calculation -CZMQ_EXPORT void - zdigest_update (zdigest_t *self, const byte *buffer, size_t length); - -// Return final digest hash data. If built without crypto support, -// returns NULL. -CZMQ_EXPORT const byte * - zdigest_data (zdigest_t *self); - -// Return final digest hash size -CZMQ_EXPORT size_t - zdigest_size (zdigest_t *self); - -// Return digest as printable hex string; caller should not modify nor -// free this string. After calling this, you may not use zdigest_update() -// on the same digest. If built without crypto support, returns NULL. -CZMQ_EXPORT char * - zdigest_string (zdigest_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zdigest_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zdir.h b/phonelibs/zmq/arm/include/zdir.h deleted file mode 100644 index 6c5551b57eead4..00000000000000 --- a/phonelibs/zmq/arm/include/zdir.h +++ /dev/null @@ -1,149 +0,0 @@ -/* ========================================================================= - zdir - work with file-system directories - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZDIR_H_INCLUDED__ -#define __ZDIR_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zdir.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Create a new directory item that loads in the full tree of the specified -// path, optionally located under some parent path. If parent is "-", then -// loads only the top-level directory, and does not use parent as a path. -CZMQ_EXPORT zdir_t * - zdir_new (const char *path, const char *parent); - -// Destroy a directory tree and all children it contains. -CZMQ_EXPORT void - zdir_destroy (zdir_t **self_p); - -// Return directory path -CZMQ_EXPORT const char * - zdir_path (zdir_t *self); - -// Return last modification time for directory. -CZMQ_EXPORT time_t - zdir_modified (zdir_t *self); - -// Return total hierarchy size, in bytes of data contained in all files -// in the directory tree. -CZMQ_EXPORT off_t - zdir_cursize (zdir_t *self); - -// Return directory count -CZMQ_EXPORT size_t - zdir_count (zdir_t *self); - -// Returns a sorted list of zfile objects; Each entry in the list is a pointer -// to a zfile_t item already allocated in the zdir tree. Do not destroy the -// original zdir tree until you are done with this list. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zlist_t * - zdir_list (zdir_t *self); - -// Remove directory, optionally including all files that it contains, at -// all levels. If force is false, will only remove the directory if empty. -// If force is true, will remove all files and all subdirectories. -CZMQ_EXPORT void - zdir_remove (zdir_t *self, bool force); - -// Calculate differences between two versions of a directory tree. -// Returns a list of zdir_patch_t patches. Either older or newer may -// be null, indicating the directory is empty/absent. If alias is set, -// generates virtual filename (minus path, plus alias). -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zlist_t * - zdir_diff (zdir_t *older, zdir_t *newer, const char *alias); - -// Return full contents of directory as a zdir_patch list. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zlist_t * - zdir_resync (zdir_t *self, const char *alias); - -// Load directory cache; returns a hash table containing the SHA-1 digests -// of every file in the tree. The cache is saved between runs in .cache. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zhash_t * - zdir_cache (zdir_t *self); - -// Print contents of directory to open stream -CZMQ_EXPORT void - zdir_fprint (zdir_t *self, FILE *file, int indent); - -// Print contents of directory to stdout -CZMQ_EXPORT void - zdir_print (zdir_t *self, int indent); - -// Create a new zdir_watch actor instance: -// -// zactor_t *watch = zactor_new (zdir_watch, NULL); -// -// Destroy zdir_watch instance: -// -// zactor_destroy (&watch); -// -// Enable verbose logging of commands and activity: -// -// zstr_send (watch, "VERBOSE"); -// -// Subscribe to changes to a directory path: -// -// zsock_send (watch, "ss", "SUBSCRIBE", "directory_path"); -// -// Unsubscribe from changes to a directory path: -// -// zsock_send (watch, "ss", "UNSUBSCRIBE", "directory_path"); -// -// Receive directory changes: -// zsock_recv (watch, "sp", &path, &patches); -// -// // Delete the received data. -// free (path); -// zlist_destroy (&patches); -CZMQ_EXPORT void - zdir_watch (zsock_t *pipe, void *unused); - -// Self test of this class. -CZMQ_EXPORT void - zdir_test (bool verbose); - -// @end - - -// Returns a sorted array of zfile objects; returns a single block of memory, -// that you destroy by calling zstr_free(). Each entry in the array is a pointer -// to a zfile_t item already allocated in the zdir tree. The array ends with -// a null pointer. Do not destroy the original zdir tree until you are done -// with this array. -CZMQ_EXPORT zfile_t ** - zdir_flatten (zdir_t *self); - -// Free a provided string, and nullify the parent pointer. Safe to call on -// a null pointer. -CZMQ_EXPORT void - zdir_flatten_free (zfile_t ***files_p); - -#ifdef __cplusplus -} -#endif - -// Deprecated method aliases -#define zdir_dump(s,i) zdir_print(s,i) - -#endif diff --git a/phonelibs/zmq/arm/include/zdir_patch.h b/phonelibs/zmq/arm/include/zdir_patch.h deleted file mode 100644 index 8d15b9aeb40c42..00000000000000 --- a/phonelibs/zmq/arm/include/zdir_patch.h +++ /dev/null @@ -1,82 +0,0 @@ -/* ========================================================================= - zdir_patch - work with directory patches - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZDIR_PATCH_H_INCLUDED__ -#define __ZDIR_PATCH_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// un-namespaced enumeration values -#define patch_create ZDIR_PATCH_CREATE -#define patch_delete ZDIR_PATCH_DELETE - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zdir_patch.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -#define ZDIR_PATCH_CREATE 1 // Creates a new file -#define ZDIR_PATCH_DELETE 2 // Delete a file - -// Create new patch -CZMQ_EXPORT zdir_patch_t * - zdir_patch_new (const char *path, zfile_t *file, int op, const char *alias); - -// Destroy a patch -CZMQ_EXPORT void - zdir_patch_destroy (zdir_patch_t **self_p); - -// Create copy of a patch. If the patch is null, or memory was exhausted, -// returns null. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zdir_patch_t * - zdir_patch_dup (zdir_patch_t *self); - -// Return patch file directory path -CZMQ_EXPORT const char * - zdir_patch_path (zdir_patch_t *self); - -// Return patch file item -CZMQ_EXPORT zfile_t * - zdir_patch_file (zdir_patch_t *self); - -// Return operation -CZMQ_EXPORT int - zdir_patch_op (zdir_patch_t *self); - -// Return patch virtual file path -CZMQ_EXPORT const char * - zdir_patch_vpath (zdir_patch_t *self); - -// Calculate hash digest for file (create only) -CZMQ_EXPORT void - zdir_patch_digest_set (zdir_patch_t *self); - -// Return hash digest for patch file -CZMQ_EXPORT const char * - zdir_patch_digest (zdir_patch_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zdir_patch_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zfile.h b/phonelibs/zmq/arm/include/zfile.h deleted file mode 100644 index 75c35774b97fd1..00000000000000 --- a/phonelibs/zmq/arm/include/zfile.h +++ /dev/null @@ -1,177 +0,0 @@ -/* ========================================================================= - zfile - helper functions for working with files. - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZFILE_H_INCLUDED__ -#define __ZFILE_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zfile.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// If file exists, populates properties. CZMQ supports portable symbolic -// links, which are files with the extension ".ln". A symbolic link is a -// text file containing one line, the filename of a target file. Reading -// data from the symbolic link actually reads from the target file. Path -// may be NULL, in which case it is not used. -CZMQ_EXPORT zfile_t * - zfile_new (const char *path, const char *name); - -// Destroy a file item -CZMQ_EXPORT void - zfile_destroy (zfile_t **self_p); - -// Duplicate a file item, returns a newly constructed item. If the file -// is null, or memory was exhausted, returns null. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zfile_t * - zfile_dup (zfile_t *self); - -// Return file name, remove path if provided -CZMQ_EXPORT const char * - zfile_filename (zfile_t *self, const char *path); - -// Refresh file properties from disk; this is not done automatically -// on access methods, otherwise it is not possible to compare directory -// snapshots. -CZMQ_EXPORT void - zfile_restat (zfile_t *self); - -// Return when the file was last modified. If you want this to reflect the -// current situation, call zfile_restat before checking this property. -CZMQ_EXPORT time_t - zfile_modified (zfile_t *self); - -// Return the last-known size of the file. If you want this to reflect the -// current situation, call zfile_restat before checking this property. -CZMQ_EXPORT off_t - zfile_cursize (zfile_t *self); - -// Return true if the file is a directory. If you want this to reflect -// any external changes, call zfile_restat before checking this property. -CZMQ_EXPORT bool - zfile_is_directory (zfile_t *self); - -// Return true if the file is a regular file. If you want this to reflect -// any external changes, call zfile_restat before checking this property. -CZMQ_EXPORT bool - zfile_is_regular (zfile_t *self); - -// Return true if the file is readable by this process. If you want this to -// reflect any external changes, call zfile_restat before checking this -// property. -CZMQ_EXPORT bool - zfile_is_readable (zfile_t *self); - -// Return true if the file is writeable by this process. If you want this -// to reflect any external changes, call zfile_restat before checking this -// property. -CZMQ_EXPORT bool - zfile_is_writeable (zfile_t *self); - -// Check if file has stopped changing and can be safely processed. -// Updates the file statistics from disk at every call. -CZMQ_EXPORT bool - zfile_is_stable (zfile_t *self); - -// Return true if the file was changed on disk since the zfile_t object -// was created, or the last zfile_restat() call made on it. -CZMQ_EXPORT bool - zfile_has_changed (zfile_t *self); - -// Remove the file from disk -CZMQ_EXPORT void - zfile_remove (zfile_t *self); - -// Open file for reading -// Returns 0 if OK, -1 if not found or not accessible -CZMQ_EXPORT int - zfile_input (zfile_t *self); - -// Open file for writing, creating directory if needed -// File is created if necessary; chunks can be written to file at any -// location. Returns 0 if OK, -1 if error. -CZMQ_EXPORT int - zfile_output (zfile_t *self); - -// Read chunk from file at specified position. If this was the last chunk, -// sets the eof property. Returns a null chunk in case of error. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zchunk_t * - zfile_read (zfile_t *self, size_t bytes, off_t offset); - -// Returns true if zfile_read() just read the last chunk in the file. -CZMQ_EXPORT bool - zfile_eof (zfile_t *self); - -// Write chunk to file at specified position -// Return 0 if OK, else -1 -CZMQ_EXPORT int - zfile_write (zfile_t *self, zchunk_t *chunk, off_t offset); - -// Read next line of text from file. Returns a pointer to the text line, -// or NULL if there was nothing more to read from the file. -CZMQ_EXPORT const char * - zfile_readln (zfile_t *self); - -// Close file, if open -CZMQ_EXPORT void - zfile_close (zfile_t *self); - -// Return file handle, if opened -CZMQ_EXPORT FILE * - zfile_handle (zfile_t *self); - -// Calculate SHA1 digest for file, using zdigest class. -CZMQ_EXPORT const char * - zfile_digest (zfile_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zfile_test (bool verbose); - -// @end - - -// @interface -// These methods are deprecated, and now moved to zsys class. -CZMQ_EXPORT bool - zfile_exists (const char *filename); -CZMQ_EXPORT ssize_t - zfile_size (const char *filename); -CZMQ_EXPORT mode_t - zfile_mode (const char *filename); -CZMQ_EXPORT int - zfile_delete (const char *filename); -CZMQ_EXPORT bool - zfile_stable (const char *filename); -CZMQ_EXPORT int - zfile_mkdir (const char *pathname); -CZMQ_EXPORT int - zfile_rmdir (const char *pathname); -CZMQ_EXPORT void - zfile_mode_private (void); -CZMQ_EXPORT void - zfile_mode_default (void); -// @end - -#ifdef __cplusplus -} -#endif - - -#endif // __ZFILE_H_INCLUDED__ diff --git a/phonelibs/zmq/arm/include/zframe.h b/phonelibs/zmq/arm/include/zframe.h deleted file mode 100644 index 728093c36ce117..00000000000000 --- a/phonelibs/zmq/arm/include/zframe.h +++ /dev/null @@ -1,176 +0,0 @@ -/* ========================================================================= - zframe - working with single message frames - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZFRAME_H_INCLUDED__ -#define __ZFRAME_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zframe.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -#define ZFRAME_MORE 1 // -#define ZFRAME_REUSE 2 // -#define ZFRAME_DONTWAIT 4 // - -// Create a new frame. If size is not null, allocates the frame data -// to the specified size. If additionally, data is not null, copies -// size octets from the specified data into the frame body. -CZMQ_EXPORT zframe_t * - zframe_new (const void *data, size_t size); - -// Create an empty (zero-sized) frame -CZMQ_EXPORT zframe_t * - zframe_new_empty (void); - -// Create a frame with a specified string content. -CZMQ_EXPORT zframe_t * - zframe_from (const char *string); - -// Receive frame from socket, returns zframe_t object or NULL if the recv -// was interrupted. Does a blocking recv, if you want to not block then use -// zpoller or zloop. -CZMQ_EXPORT zframe_t * - zframe_recv (void *source); - -// Destroy a frame -CZMQ_EXPORT void - zframe_destroy (zframe_t **self_p); - -// Send a frame to a socket, destroy frame after sending. -// Return -1 on error, 0 on success. -CZMQ_EXPORT int - zframe_send (zframe_t **self_p, void *dest, int flags); - -// Return number of bytes in frame data -CZMQ_EXPORT size_t - zframe_size (zframe_t *self); - -// Return address of frame data -CZMQ_EXPORT byte * - zframe_data (zframe_t *self); - -// Return meta data property for frame -// Caller must free string when finished with it. -CZMQ_EXPORT const char * - zframe_meta (zframe_t *self, const char *property); - -// Create a new frame that duplicates an existing frame. If frame is null, -// or memory was exhausted, returns null. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zframe_t * - zframe_dup (zframe_t *self); - -// Return frame data encoded as printable hex string, useful for 0MQ UUIDs. -// Caller must free string when finished with it. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zframe_strhex (zframe_t *self); - -// Return frame data copied into freshly allocated string -// Caller must free string when finished with it. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zframe_strdup (zframe_t *self); - -// Return TRUE if frame body is equal to string, excluding terminator -CZMQ_EXPORT bool - zframe_streq (zframe_t *self, const char *string); - -// Return frame MORE indicator (1 or 0), set when reading frame from socket -// or by the zframe_set_more() method -CZMQ_EXPORT int - zframe_more (zframe_t *self); - -// Set frame MORE indicator (1 or 0). Note this is NOT used when sending -// frame to socket, you have to specify flag explicitly. -CZMQ_EXPORT void - zframe_set_more (zframe_t *self, int more); - -// Return TRUE if two frames have identical size and data -// If either frame is NULL, equality is always false. -CZMQ_EXPORT bool - zframe_eq (zframe_t *self, zframe_t *other); - -// Set new contents for frame -CZMQ_EXPORT void - zframe_reset (zframe_t *self, const void *data, size_t size); - -// Send message to zsys log sink (may be stdout, or system facility as -// configured by zsys_set_logstream). Prefix shows before frame, if not null. -CZMQ_EXPORT void - zframe_print (zframe_t *self, const char *prefix); - -// Probe the supplied object, and report if it looks like a zframe_t. -CZMQ_EXPORT bool - zframe_is (void *self); - -// Self test of this class. -CZMQ_EXPORT void - zframe_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Return frame routing ID, if the frame came from a ZMQ_SERVER socket. -// Else returns zero. -CZMQ_EXPORT uint32_t - zframe_routing_id (zframe_t *self); - -// *** Draft method, for development use, may change without warning *** -// Set routing ID on frame. This is used if/when the frame is sent to a -// ZMQ_SERVER socket. -CZMQ_EXPORT void - zframe_set_routing_id (zframe_t *self, uint32_t routing_id); - -// *** Draft method, for development use, may change without warning *** -// Return frame group of radio-dish pattern. -CZMQ_EXPORT const char * - zframe_group (zframe_t *self); - -// *** Draft method, for development use, may change without warning *** -// Set group on frame. This is used if/when the frame is sent to a -// ZMQ_RADIO socket. -// Return -1 on error, 0 on success. -CZMQ_EXPORT int - zframe_set_group (zframe_t *self, const char *group); - -#endif // CZMQ_BUILD_DRAFT_API -// @end - - -// DEPRECATED as poor style -- callers should use zloop or zpoller -// Receive a new frame off the socket. Returns newly allocated frame, or -// NULL if there was no input waiting, or if the read was interrupted. -CZMQ_EXPORT zframe_t * - zframe_recv_nowait (void *source); - -// DEPRECATED as inconsistent; breaks principle that logging should all go -// to a single destination. -// Print contents of the frame to FILE stream. -CZMQ_EXPORT void - zframe_fprint (zframe_t *self, const char *prefix, FILE *file); - -// Deprecated method aliases -#define zframe_print_to_stream(s,p,F) zframe_fprint(s,p,F) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zgossip.h b/phonelibs/zmq/arm/include/zgossip.h deleted file mode 100644 index 647cb28c080731..00000000000000 --- a/phonelibs/zmq/arm/include/zgossip.h +++ /dev/null @@ -1,95 +0,0 @@ -/* ========================================================================= - zgossip - zgossip server - - ** WARNING ************************************************************* - THIS SOURCE FILE IS 100% GENERATED. If you edit this file, you will lose - your changes at the next build cycle. This is great for temporary printf - statements. DO NOT MAKE ANY CHANGES YOU WISH TO KEEP. The correct places - for commits are: - - * The XML model used for this code generation: zgossip.xml, or - * The code generation script that built this file: zproto_server_c - ************************************************************************ - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef ZGOSSIP_H_INCLUDED -#define ZGOSSIP_H_INCLUDED - -#include "czmq.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// To work with zgossip, use the CZMQ zactor API: -// -// Create new zgossip instance, passing logging prefix: -// -// zactor_t *zgossip = zactor_new (zgossip, "myname"); -// -// Destroy zgossip instance -// -// zactor_destroy (&zgossip); -// -// Enable verbose logging of commands and activity: -// -// zstr_send (zgossip, "VERBOSE"); -// -// Bind zgossip to specified endpoint. TCP endpoints may specify -// the port number as "*" to aquire an ephemeral port: -// -// zstr_sendx (zgossip, "BIND", endpoint, NULL); -// -// Return assigned port number, specifically when BIND was done using an -// an ephemeral port: -// -// zstr_sendx (zgossip, "PORT", NULL); -// char *command, *port_str; -// zstr_recvx (zgossip, &command, &port_str, NULL); -// assert (streq (command, "PORT")); -// -// Specify configuration file to load, overwriting any previous loaded -// configuration file or options: -// -// zstr_sendx (zgossip, "LOAD", filename, NULL); -// -// Set configuration path value: -// -// zstr_sendx (zgossip, "SET", path, value, NULL); -// -// Save configuration data to config file on disk: -// -// zstr_sendx (zgossip, "SAVE", filename, NULL); -// -// Send zmsg_t instance to zgossip: -// -// zactor_send (zgossip, &msg); -// -// Receive zmsg_t instance from zgossip: -// -// zmsg_t *msg = zactor_recv (zgossip); -// -// This is the zgossip constructor as a zactor_fn: -// -CZMQ_EXPORT void - zgossip (zsock_t *pipe, void *args); - -// Self test of this class -CZMQ_EXPORT void - zgossip_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zhash.h b/phonelibs/zmq/arm/include/zhash.h deleted file mode 100644 index 929bc2683aec36..00000000000000 --- a/phonelibs/zmq/arm/include/zhash.h +++ /dev/null @@ -1,198 +0,0 @@ -/* ========================================================================= - zhash - generic type-free hash container (simple) - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZHASH_H_INCLUDED__ -#define __ZHASH_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zhash.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has legacy methods, which will be removed over time. You -// should not use them, and migrate any code that is still using them. -// Callback function for zhash_freefn method -typedef void (zhash_free_fn) ( - void *data); - -// Callback function for zhash_foreach method. Deprecated. -typedef int (zhash_foreach_fn) ( - const char *key, void *item, void *argument); - -// Create a new, empty hash container -CZMQ_EXPORT zhash_t * - zhash_new (void); - -// Unpack binary frame into a new hash table. Packed data must follow format -// defined by zhash_pack. Hash table is set to autofree. An empty frame -// unpacks to an empty hash table. -CZMQ_EXPORT zhash_t * - zhash_unpack (zframe_t *frame); - -// Destroy a hash container and all items in it -CZMQ_EXPORT void - zhash_destroy (zhash_t **self_p); - -// Insert item into hash table with specified key and item. -// If key is already present returns -1 and leaves existing item unchanged -// Returns 0 on success. -CZMQ_EXPORT int - zhash_insert (zhash_t *self, const char *key, void *item); - -// Update item into hash table with specified key and item. -// If key is already present, destroys old item and inserts new one. -// Use free_fn method to ensure deallocator is properly called on item. -CZMQ_EXPORT void - zhash_update (zhash_t *self, const char *key, void *item); - -// Remove an item specified by key from the hash table. If there was no such -// item, this function does nothing. -CZMQ_EXPORT void - zhash_delete (zhash_t *self, const char *key); - -// Return the item at the specified key, or null -CZMQ_EXPORT void * - zhash_lookup (zhash_t *self, const char *key); - -// Reindexes an item from an old key to a new key. If there was no such -// item, does nothing. Returns 0 if successful, else -1. -CZMQ_EXPORT int - zhash_rename (zhash_t *self, const char *old_key, const char *new_key); - -// Set a free function for the specified hash table item. When the item is -// destroyed, the free function, if any, is called on that item. -// Use this when hash items are dynamically allocated, to ensure that -// you don't have memory leaks. You can pass 'free' or NULL as a free_fn. -// Returns the item, or NULL if there is no such item. -CZMQ_EXPORT void * - zhash_freefn (zhash_t *self, const char *key, zhash_free_fn free_fn); - -// Return the number of keys/items in the hash table -CZMQ_EXPORT size_t - zhash_size (zhash_t *self); - -// Make copy of hash table; if supplied table is null, returns null. -// Does not copy items themselves. Rebuilds new table so may be slow on -// very large tables. NOTE: only works with item values that are strings -// since there's no other way to know how to duplicate the item value. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zhash_t * - zhash_dup (zhash_t *self); - -// Return keys for items in table -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zlist_t * - zhash_keys (zhash_t *self); - -// Simple iterator; returns first item in hash table, in no given order, -// or NULL if the table is empty. This method is simpler to use than the -// foreach() method, which is deprecated. To access the key for this item -// use zhash_cursor(). NOTE: do NOT modify the table while iterating. -CZMQ_EXPORT void * - zhash_first (zhash_t *self); - -// Simple iterator; returns next item in hash table, in no given order, -// or NULL if the last item was already returned. Use this together with -// zhash_first() to process all items in a hash table. If you need the -// items in sorted order, use zhash_keys() and then zlist_sort(). To -// access the key for this item use zhash_cursor(). NOTE: do NOT modify -// the table while iterating. -CZMQ_EXPORT void * - zhash_next (zhash_t *self); - -// After a successful first/next method, returns the key for the item that -// was returned. This is a constant string that you may not modify or -// deallocate, and which lasts as long as the item in the hash. After an -// unsuccessful first/next, returns NULL. -CZMQ_EXPORT const char * - zhash_cursor (zhash_t *self); - -// Add a comment to hash table before saving to disk. You can add as many -// comment lines as you like. These comment lines are discarded when loading -// the file. If you use a null format, all comments are deleted. -CZMQ_EXPORT void - zhash_comment (zhash_t *self, const char *format, ...); - -// Serialize hash table to a binary frame that can be sent in a message. -// The packed format is compatible with the 'dictionary' type defined in -// http://rfc.zeromq.org/spec:35/FILEMQ, and implemented by zproto: -// -// ; A list of name/value pairs -// dictionary = dict-count *( dict-name dict-value ) -// dict-count = number-4 -// dict-value = longstr -// dict-name = string -// -// ; Strings are always length + text contents -// longstr = number-4 *VCHAR -// string = number-1 *VCHAR -// -// ; Numbers are unsigned integers in network byte order -// number-1 = 1OCTET -// number-4 = 4OCTET -// -// Comments are not included in the packed data. Item values MUST be -// strings. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zframe_t * - zhash_pack (zhash_t *self); - -// Save hash table to a text file in name=value format. Hash values must be -// printable strings; keys may not contain '=' character. Returns 0 if OK, -// else -1 if a file error occurred. -CZMQ_EXPORT int - zhash_save (zhash_t *self, const char *filename); - -// Load hash table from a text file in name=value format; hash table must -// already exist. Hash values must printable strings; keys may not contain -// '=' character. Returns 0 if OK, else -1 if a file was not readable. -CZMQ_EXPORT int - zhash_load (zhash_t *self, const char *filename); - -// When a hash table was loaded from a file by zhash_load, this method will -// reload the file if it has been modified since, and is "stable", i.e. not -// still changing. Returns 0 if OK, -1 if there was an error reloading the -// file. -CZMQ_EXPORT int - zhash_refresh (zhash_t *self); - -// Set hash for automatic value destruction -CZMQ_EXPORT void - zhash_autofree (zhash_t *self); - -// *** Deprecated method, slated for removal: avoid using it *** -// Apply function to each item in the hash table. Items are iterated in no -// defined order. Stops if callback function returns non-zero and returns -// final return code from callback function (zero = success). Deprecated. -CZMQ_EXPORT int - zhash_foreach (zhash_t *self, zhash_foreach_fn callback, void *argument); - -// Self test of this class. -CZMQ_EXPORT void - zhash_test (bool verbose); - -// @ignore -CZMQ_EXPORT void - zhash_comment (zhash_t *self, const char *format, ...) CHECK_PRINTF (2); -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zhashx.h b/phonelibs/zmq/arm/include/zhashx.h deleted file mode 100644 index 8776073156cf3c..00000000000000 --- a/phonelibs/zmq/arm/include/zhashx.h +++ /dev/null @@ -1,301 +0,0 @@ -/* ========================================================================= - zhashx - extended generic type-free hash container - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZHASHX_H_INCLUDED__ -#define __ZHASHX_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zhashx.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// This class has legacy methods, which will be removed over time. You -// should not use them, and migrate any code that is still using them. -// Destroy an item -typedef void (zhashx_destructor_fn) ( - void **item); - -// Duplicate an item -typedef void * (zhashx_duplicator_fn) ( - const void *item); - -// Compare two items, for sorting -typedef int (zhashx_comparator_fn) ( - const void *item1, const void *item2); - -// compare two items, for sorting -typedef void (zhashx_free_fn) ( - void *data); - -// compare two items, for sorting -typedef size_t (zhashx_hash_fn) ( - const void *key); - -// Serializes an item to a longstr. -// The caller takes ownership of the newly created object. -typedef char * (zhashx_serializer_fn) ( - const void *item); - -// Deserializes a longstr into an item. -// The caller takes ownership of the newly created object. -typedef void * (zhashx_deserializer_fn) ( - const char *item_str); - -// Callback function for zhashx_foreach method. -// This callback is deprecated and you should use zhashx_first/_next instead. -typedef int (zhashx_foreach_fn) ( - const char *key, void *item, void *argument); - -// Create a new, empty hash container -CZMQ_EXPORT zhashx_t * - zhashx_new (void); - -// Unpack binary frame into a new hash table. Packed data must follow format -// defined by zhashx_pack. Hash table is set to autofree. An empty frame -// unpacks to an empty hash table. -CZMQ_EXPORT zhashx_t * - zhashx_unpack (zframe_t *frame); - -// Destroy a hash container and all items in it -CZMQ_EXPORT void - zhashx_destroy (zhashx_t **self_p); - -// Insert item into hash table with specified key and item. -// If key is already present returns -1 and leaves existing item unchanged -// Returns 0 on success. -CZMQ_EXPORT int - zhashx_insert (zhashx_t *self, const void *key, void *item); - -// Update or insert item into hash table with specified key and item. If the -// key is already present, destroys old item and inserts new one. If you set -// a container item destructor, this is called on the old value. If the key -// was not already present, inserts a new item. Sets the hash cursor to the -// new item. -CZMQ_EXPORT void - zhashx_update (zhashx_t *self, const void *key, void *item); - -// Remove an item specified by key from the hash table. If there was no such -// item, this function does nothing. -CZMQ_EXPORT void - zhashx_delete (zhashx_t *self, const void *key); - -// Delete all items from the hash table. If the key destructor is -// set, calls it on every key. If the item destructor is set, calls -// it on every item. -CZMQ_EXPORT void - zhashx_purge (zhashx_t *self); - -// Return the item at the specified key, or null -CZMQ_EXPORT void * - zhashx_lookup (zhashx_t *self, const void *key); - -// Reindexes an item from an old key to a new key. If there was no such -// item, does nothing. Returns 0 if successful, else -1. -CZMQ_EXPORT int - zhashx_rename (zhashx_t *self, const void *old_key, const void *new_key); - -// Set a free function for the specified hash table item. When the item is -// destroyed, the free function, if any, is called on that item. -// Use this when hash items are dynamically allocated, to ensure that -// you don't have memory leaks. You can pass 'free' or NULL as a free_fn. -// Returns the item, or NULL if there is no such item. -CZMQ_EXPORT void * - zhashx_freefn (zhashx_t *self, const void *key, zhashx_free_fn free_fn); - -// Return the number of keys/items in the hash table -CZMQ_EXPORT size_t - zhashx_size (zhashx_t *self); - -// Return a zlistx_t containing the keys for the items in the -// table. Uses the key_duplicator to duplicate all keys and sets the -// key_destructor as destructor for the list. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zlistx_t * - zhashx_keys (zhashx_t *self); - -// Return a zlistx_t containing the values for the items in the -// table. Uses the duplicator to duplicate all items and sets the -// destructor as destructor for the list. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zlistx_t * - zhashx_values (zhashx_t *self); - -// Simple iterator; returns first item in hash table, in no given order, -// or NULL if the table is empty. This method is simpler to use than the -// foreach() method, which is deprecated. To access the key for this item -// use zhashx_cursor(). NOTE: do NOT modify the table while iterating. -CZMQ_EXPORT void * - zhashx_first (zhashx_t *self); - -// Simple iterator; returns next item in hash table, in no given order, -// or NULL if the last item was already returned. Use this together with -// zhashx_first() to process all items in a hash table. If you need the -// items in sorted order, use zhashx_keys() and then zlistx_sort(). To -// access the key for this item use zhashx_cursor(). NOTE: do NOT modify -// the table while iterating. -CZMQ_EXPORT void * - zhashx_next (zhashx_t *self); - -// After a successful first/next method, returns the key for the item that -// was returned. This is a constant string that you may not modify or -// deallocate, and which lasts as long as the item in the hash. After an -// unsuccessful first/next, returns NULL. -CZMQ_EXPORT const void * - zhashx_cursor (zhashx_t *self); - -// Add a comment to hash table before saving to disk. You can add as many -// comment lines as you like. These comment lines are discarded when loading -// the file. If you use a null format, all comments are deleted. -CZMQ_EXPORT void - zhashx_comment (zhashx_t *self, const char *format, ...); - -// Save hash table to a text file in name=value format. Hash values must be -// printable strings; keys may not contain '=' character. Returns 0 if OK, -// else -1 if a file error occurred. -CZMQ_EXPORT int - zhashx_save (zhashx_t *self, const char *filename); - -// Load hash table from a text file in name=value format; hash table must -// already exist. Hash values must printable strings; keys may not contain -// '=' character. Returns 0 if OK, else -1 if a file was not readable. -CZMQ_EXPORT int - zhashx_load (zhashx_t *self, const char *filename); - -// When a hash table was loaded from a file by zhashx_load, this method will -// reload the file if it has been modified since, and is "stable", i.e. not -// still changing. Returns 0 if OK, -1 if there was an error reloading the -// file. -CZMQ_EXPORT int - zhashx_refresh (zhashx_t *self); - -// Serialize hash table to a binary frame that can be sent in a message. -// The packed format is compatible with the 'dictionary' type defined in -// http://rfc.zeromq.org/spec:35/FILEMQ, and implemented by zproto: -// -// ; A list of name/value pairs -// dictionary = dict-count *( dict-name dict-value ) -// dict-count = number-4 -// dict-value = longstr -// dict-name = string -// -// ; Strings are always length + text contents -// longstr = number-4 *VCHAR -// string = number-1 *VCHAR -// -// ; Numbers are unsigned integers in network byte order -// number-1 = 1OCTET -// number-4 = 4OCTET -// -// Comments are not included in the packed data. Item values MUST be -// strings. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zframe_t * - zhashx_pack (zhashx_t *self); - -// Make a copy of the list; items are duplicated if you set a duplicator -// for the list, otherwise not. Copying a null reference returns a null -// reference. Note that this method's behavior changed slightly for CZMQ -// v3.x, as it does not set nor respect autofree. It does however let you -// duplicate any hash table safely. The old behavior is in zhashx_dup_v2. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zhashx_t * - zhashx_dup (zhashx_t *self); - -// Set a user-defined deallocator for hash items; by default items are not -// freed when the hash is destroyed. -CZMQ_EXPORT void - zhashx_set_destructor (zhashx_t *self, zhashx_destructor_fn destructor); - -// Set a user-defined duplicator for hash items; by default items are not -// copied when the hash is duplicated. -CZMQ_EXPORT void - zhashx_set_duplicator (zhashx_t *self, zhashx_duplicator_fn duplicator); - -// Set a user-defined deallocator for keys; by default keys are freed -// when the hash is destroyed using free(). -CZMQ_EXPORT void - zhashx_set_key_destructor (zhashx_t *self, zhashx_destructor_fn destructor); - -// Set a user-defined duplicator for keys; by default keys are duplicated -// using strdup. -CZMQ_EXPORT void - zhashx_set_key_duplicator (zhashx_t *self, zhashx_duplicator_fn duplicator); - -// Set a user-defined comparator for keys; by default keys are -// compared using strcmp. -CZMQ_EXPORT void - zhashx_set_key_comparator (zhashx_t *self, zhashx_comparator_fn comparator); - -// Set a user-defined comparator for keys; by default keys are -// compared using strcmp. -CZMQ_EXPORT void - zhashx_set_key_hasher (zhashx_t *self, zhashx_hash_fn hasher); - -// Make copy of hash table; if supplied table is null, returns null. -// Does not copy items themselves. Rebuilds new table so may be slow on -// very large tables. NOTE: only works with item values that are strings -// since there's no other way to know how to duplicate the item value. -CZMQ_EXPORT zhashx_t * - zhashx_dup_v2 (zhashx_t *self); - -// *** Deprecated method, slated for removal: avoid using it *** -// Set hash for automatic value destruction. This method is deprecated -// and you should use set_destructor instead. -CZMQ_EXPORT void - zhashx_autofree (zhashx_t *self); - -// *** Deprecated method, slated for removal: avoid using it *** -// Apply function to each item in the hash table. Items are iterated in no -// defined order. Stops if callback function returns non-zero and returns -// final return code from callback function (zero = success). This method -// is deprecated and you should use zhashx_first/_next instead. -CZMQ_EXPORT int - zhashx_foreach (zhashx_t *self, zhashx_foreach_fn callback, void *argument); - -// Self test of this class. -CZMQ_EXPORT void - zhashx_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Same as unpack but uses a user-defined deserializer function to convert -// a longstr back into item format. -CZMQ_EXPORT zhashx_t * - zhashx_unpack_own (zframe_t *frame, zhashx_deserializer_fn deserializer); - -// *** Draft method, for development use, may change without warning *** -// Same as pack but uses a user-defined serializer function to convert items -// into longstr. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zframe_t * - zhashx_pack_own (zhashx_t *self, zhashx_serializer_fn serializer); - -#endif // CZMQ_BUILD_DRAFT_API -// @ignore -CZMQ_EXPORT void - zhashx_comment (zhashx_t *self, const char *format, ...) CHECK_PRINTF (2); -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/ziflist.h b/phonelibs/zmq/arm/include/ziflist.h deleted file mode 100644 index cb2b1448025f89..00000000000000 --- a/phonelibs/zmq/arm/include/ziflist.h +++ /dev/null @@ -1,77 +0,0 @@ -/* ========================================================================= - ziflist - List of network interfaces available on system - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZIFLIST_H_INCLUDED__ -#define __ZIFLIST_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/ziflist.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Get a list of network interfaces currently defined on the system -CZMQ_EXPORT ziflist_t * - ziflist_new (void); - -// Destroy a ziflist instance -CZMQ_EXPORT void - ziflist_destroy (ziflist_t **self_p); - -// Reload network interfaces from system -CZMQ_EXPORT void - ziflist_reload (ziflist_t *self); - -// Return the number of network interfaces on system -CZMQ_EXPORT size_t - ziflist_size (ziflist_t *self); - -// Get first network interface, return NULL if there are none -CZMQ_EXPORT const char * - ziflist_first (ziflist_t *self); - -// Get next network interface, return NULL if we hit the last one -CZMQ_EXPORT const char * - ziflist_next (ziflist_t *self); - -// Return the current interface IP address as a printable string -CZMQ_EXPORT const char * - ziflist_address (ziflist_t *self); - -// Return the current interface broadcast address as a printable string -CZMQ_EXPORT const char * - ziflist_broadcast (ziflist_t *self); - -// Return the current interface network mask as a printable string -CZMQ_EXPORT const char * - ziflist_netmask (ziflist_t *self); - -// Return the list of interfaces. -CZMQ_EXPORT void - ziflist_print (ziflist_t *self); - -// Self test of this class. -CZMQ_EXPORT void - ziflist_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zlist.h b/phonelibs/zmq/arm/include/zlist.h deleted file mode 100644 index 1dcd39b9955c9e..00000000000000 --- a/phonelibs/zmq/arm/include/zlist.h +++ /dev/null @@ -1,158 +0,0 @@ -/* ========================================================================= - zlist - simple generic list container - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZLIST_H_INCLUDED__ -#define __ZLIST_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zlist.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Comparison function e.g. for sorting and removing. -typedef int (zlist_compare_fn) ( - void *item1, void *item2); - -// Callback function for zlist_freefn method -typedef void (zlist_free_fn) ( - void *data); - -// Create a new list container -CZMQ_EXPORT zlist_t * - zlist_new (void); - -// Destroy a list container -CZMQ_EXPORT void - zlist_destroy (zlist_t **self_p); - -// Return the item at the head of list. If the list is empty, returns NULL. -// Leaves cursor pointing at the head item, or NULL if the list is empty. -CZMQ_EXPORT void * - zlist_first (zlist_t *self); - -// Return the next item. If the list is empty, returns NULL. To move to -// the start of the list call zlist_first (). Advances the cursor. -CZMQ_EXPORT void * - zlist_next (zlist_t *self); - -// Return the item at the tail of list. If the list is empty, returns NULL. -// Leaves cursor pointing at the tail item, or NULL if the list is empty. -CZMQ_EXPORT void * - zlist_last (zlist_t *self); - -// Return first item in the list, or null, leaves the cursor -CZMQ_EXPORT void * - zlist_head (zlist_t *self); - -// Return last item in the list, or null, leaves the cursor -CZMQ_EXPORT void * - zlist_tail (zlist_t *self); - -// Return the current item of list. If the list is empty, returns NULL. -// Leaves cursor pointing at the current item, or NULL if the list is empty. -CZMQ_EXPORT void * - zlist_item (zlist_t *self); - -// Append an item to the end of the list, return 0 if OK or -1 if this -// failed for some reason (out of memory). Note that if a duplicator has -// been set, this method will also duplicate the item. -CZMQ_EXPORT int - zlist_append (zlist_t *self, void *item); - -// Push an item to the start of the list, return 0 if OK or -1 if this -// failed for some reason (out of memory). Note that if a duplicator has -// been set, this method will also duplicate the item. -CZMQ_EXPORT int - zlist_push (zlist_t *self, void *item); - -// Pop the item off the start of the list, if any -CZMQ_EXPORT void * - zlist_pop (zlist_t *self); - -// Checks if an item already is present. Uses compare method to determine if -// items are equal. If the compare method is NULL the check will only compare -// pointers. Returns true if item is present else false. -CZMQ_EXPORT bool - zlist_exists (zlist_t *self, void *item); - -// Remove the specified item from the list if present -CZMQ_EXPORT void - zlist_remove (zlist_t *self, void *item); - -// Make a copy of list. If the list has autofree set, the copied list will -// duplicate all items, which must be strings. Otherwise, the list will hold -// pointers back to the items in the original list. If list is null, returns -// NULL. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zlist_t * - zlist_dup (zlist_t *self); - -// Purge all items from list -CZMQ_EXPORT void - zlist_purge (zlist_t *self); - -// Return number of items in the list -CZMQ_EXPORT size_t - zlist_size (zlist_t *self); - -// Sort the list. If the compare function is null, sorts the list by -// ascending key value using a straight ASCII comparison. If you specify -// a compare function, this decides how items are sorted. The sort is not -// stable, so may reorder items with the same keys. The algorithm used is -// combsort, a compromise between performance and simplicity. -CZMQ_EXPORT void - zlist_sort (zlist_t *self, zlist_compare_fn compare); - -// Set list for automatic item destruction; item values MUST be strings. -// By default a list item refers to a value held elsewhere. When you set -// this, each time you append or push a list item, zlist will take a copy -// of the string value. Then, when you destroy the list, it will free all -// item values automatically. If you use any other technique to allocate -// list values, you must free them explicitly before destroying the list. -// The usual technique is to pop list items and destroy them, until the -// list is empty. -CZMQ_EXPORT void - zlist_autofree (zlist_t *self); - -// Sets a compare function for this list. The function compares two items. -// It returns an integer less than, equal to, or greater than zero if the -// first item is found, respectively, to be less than, to match, or be -// greater than the second item. -// This function is used for sorting, removal and exists checking. -CZMQ_EXPORT void - zlist_comparefn (zlist_t *self, zlist_compare_fn fn); - -// Set a free function for the specified list item. When the item is -// destroyed, the free function, if any, is called on that item. -// Use this when list items are dynamically allocated, to ensure that -// you don't have memory leaks. You can pass 'free' or NULL as a free_fn. -// Returns the item, or NULL if there is no such item. -CZMQ_EXPORT void * - zlist_freefn (zlist_t *self, void *item, zlist_free_fn fn, bool at_tail); - -// Self test of this class. -CZMQ_EXPORT void - zlist_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zlistx.h b/phonelibs/zmq/arm/include/zlistx.h deleted file mode 100644 index 512637cef3bff5..00000000000000 --- a/phonelibs/zmq/arm/include/zlistx.h +++ /dev/null @@ -1,205 +0,0 @@ -/* ========================================================================= - zlistx - extended generic list container - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZLISTX_H_INCLUDED__ -#define __ZLISTX_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zlistx.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Destroy an item -typedef void (zlistx_destructor_fn) ( - void **item); - -// Duplicate an item -typedef void * (zlistx_duplicator_fn) ( - const void *item); - -// Compare two items, for sorting -typedef int (zlistx_comparator_fn) ( - const void *item1, const void *item2); - -// Create a new, empty list. -CZMQ_EXPORT zlistx_t * - zlistx_new (void); - -// Destroy a list. If an item destructor was specified, all items in the -// list are automatically destroyed as well. -CZMQ_EXPORT void - zlistx_destroy (zlistx_t **self_p); - -// Add an item to the head of the list. Calls the item duplicator, if any, -// on the item. Resets cursor to list head. Returns an item handle on -// success, NULL if memory was exhausted. -CZMQ_EXPORT void * - zlistx_add_start (zlistx_t *self, void *item); - -// Add an item to the tail of the list. Calls the item duplicator, if any, -// on the item. Resets cursor to list head. Returns an item handle on -// success, NULL if memory was exhausted. -CZMQ_EXPORT void * - zlistx_add_end (zlistx_t *self, void *item); - -// Return the number of items in the list -CZMQ_EXPORT size_t - zlistx_size (zlistx_t *self); - -// Return first item in the list, or null, leaves the cursor -CZMQ_EXPORT void * - zlistx_head (zlistx_t *self); - -// Return last item in the list, or null, leaves the cursor -CZMQ_EXPORT void * - zlistx_tail (zlistx_t *self); - -// Return the item at the head of list. If the list is empty, returns NULL. -// Leaves cursor pointing at the head item, or NULL if the list is empty. -CZMQ_EXPORT void * - zlistx_first (zlistx_t *self); - -// Return the next item. At the end of the list (or in an empty list), -// returns NULL. Use repeated zlistx_next () calls to work through the list -// from zlistx_first (). First time, acts as zlistx_first(). -CZMQ_EXPORT void * - zlistx_next (zlistx_t *self); - -// Return the previous item. At the start of the list (or in an empty list), -// returns NULL. Use repeated zlistx_prev () calls to work through the list -// backwards from zlistx_last (). First time, acts as zlistx_last(). -CZMQ_EXPORT void * - zlistx_prev (zlistx_t *self); - -// Return the item at the tail of list. If the list is empty, returns NULL. -// Leaves cursor pointing at the tail item, or NULL if the list is empty. -CZMQ_EXPORT void * - zlistx_last (zlistx_t *self); - -// Returns the value of the item at the cursor, or NULL if the cursor is -// not pointing to an item. -CZMQ_EXPORT void * - zlistx_item (zlistx_t *self); - -// Returns the handle of the item at the cursor, or NULL if the cursor is -// not pointing to an item. -CZMQ_EXPORT void * - zlistx_cursor (zlistx_t *self); - -// Returns the item associated with the given list handle, or NULL if passed -// in handle is NULL. Asserts that the passed in handle points to a list element. -CZMQ_EXPORT void * - zlistx_handle_item (void *handle); - -// Find an item in the list, searching from the start. Uses the item -// comparator, if any, else compares item values directly. Returns the -// item handle found, or NULL. Sets the cursor to the found item, if any. -CZMQ_EXPORT void * - zlistx_find (zlistx_t *self, void *item); - -// Detach an item from the list, using its handle. The item is not modified, -// and the caller is responsible for destroying it if necessary. If handle is -// null, detaches the first item on the list. Returns item that was detached, -// or null if none was. If cursor was at item, moves cursor to previous item, -// so you can detach items while iterating forwards through a list. -CZMQ_EXPORT void * - zlistx_detach (zlistx_t *self, void *handle); - -// Detach item at the cursor, if any, from the list. The item is not modified, -// and the caller is responsible for destroying it as necessary. Returns item -// that was detached, or null if none was. Moves cursor to previous item, so -// you can detach items while iterating forwards through a list. -CZMQ_EXPORT void * - zlistx_detach_cur (zlistx_t *self); - -// Delete an item, using its handle. Calls the item destructor is any is -// set. If handle is null, deletes the first item on the list. Returns 0 -// if an item was deleted, -1 if not. If cursor was at item, moves cursor -// to previous item, so you can delete items while iterating forwards -// through a list. -CZMQ_EXPORT int - zlistx_delete (zlistx_t *self, void *handle); - -// Move an item to the start of the list, via its handle. -CZMQ_EXPORT void - zlistx_move_start (zlistx_t *self, void *handle); - -// Move an item to the end of the list, via its handle. -CZMQ_EXPORT void - zlistx_move_end (zlistx_t *self, void *handle); - -// Remove all items from the list, and destroy them if the item destructor -// is set. -CZMQ_EXPORT void - zlistx_purge (zlistx_t *self); - -// Sort the list. If an item comparator was set, calls that to compare -// items, otherwise compares on item value. The sort is not stable, so may -// reorder equal items. -CZMQ_EXPORT void - zlistx_sort (zlistx_t *self); - -// Create a new node and insert it into a sorted list. Calls the item -// duplicator, if any, on the item. If low_value is true, starts searching -// from the start of the list, otherwise searches from the end. Use the item -// comparator, if any, to find where to place the new node. Returns a handle -// to the new node, or NULL if memory was exhausted. Resets the cursor to the -// list head. -CZMQ_EXPORT void * - zlistx_insert (zlistx_t *self, void *item, bool low_value); - -// Move an item, specified by handle, into position in a sorted list. Uses -// the item comparator, if any, to determine the new location. If low_value -// is true, starts searching from the start of the list, otherwise searches -// from the end. -CZMQ_EXPORT void - zlistx_reorder (zlistx_t *self, void *handle, bool low_value); - -// Make a copy of the list; items are duplicated if you set a duplicator -// for the list, otherwise not. Copying a null reference returns a null -// reference. -CZMQ_EXPORT zlistx_t * - zlistx_dup (zlistx_t *self); - -// Set a user-defined deallocator for list items; by default items are not -// freed when the list is destroyed. -CZMQ_EXPORT void - zlistx_set_destructor (zlistx_t *self, zlistx_destructor_fn destructor); - -// Set a user-defined duplicator for list items; by default items are not -// copied when the list is duplicated. -CZMQ_EXPORT void - zlistx_set_duplicator (zlistx_t *self, zlistx_duplicator_fn duplicator); - -// Set a user-defined comparator for zlistx_find and zlistx_sort; the method -// must return -1, 0, or 1 depending on whether item1 is less than, equal to, -// or greater than, item2. -CZMQ_EXPORT void - zlistx_set_comparator (zlistx_t *self, zlistx_comparator_fn comparator); - -// Self test of this class. -CZMQ_EXPORT void - zlistx_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zloop.h b/phonelibs/zmq/arm/include/zloop.h deleted file mode 100644 index bc58ea0530e7b3..00000000000000 --- a/phonelibs/zmq/arm/include/zloop.h +++ /dev/null @@ -1,168 +0,0 @@ -/* ========================================================================= - zloop - event-driven reactor - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZLOOP_H_INCLUDED__ -#define __ZLOOP_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zloop.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// Callback function for reactor socket activity -typedef int (zloop_reader_fn) ( - zloop_t *loop, zsock_t *reader, void *arg); - -// Callback function for reactor events (low-level) -typedef int (zloop_fn) ( - zloop_t *loop, zmq_pollitem_t *item, void *arg); - -// Callback for reactor timer events -typedef int (zloop_timer_fn) ( - zloop_t *loop, int timer_id, void *arg); - -// Create a new zloop reactor -CZMQ_EXPORT zloop_t * - zloop_new (void); - -// Destroy a reactor -CZMQ_EXPORT void - zloop_destroy (zloop_t **self_p); - -// Register socket reader with the reactor. When the reader has messages, -// the reactor will call the handler, passing the arg. Returns 0 if OK, -1 -// if there was an error. If you register the same socket more than once, -// each instance will invoke its corresponding handler. -CZMQ_EXPORT int - zloop_reader (zloop_t *self, zsock_t *sock, zloop_reader_fn handler, void *arg); - -// Cancel a socket reader from the reactor. If multiple readers exist for -// same socket, cancels ALL of them. -CZMQ_EXPORT void - zloop_reader_end (zloop_t *self, zsock_t *sock); - -// Configure a registered reader to ignore errors. If you do not set this, -// then readers that have errors are removed from the reactor silently. -CZMQ_EXPORT void - zloop_reader_set_tolerant (zloop_t *self, zsock_t *sock); - -// Register low-level libzmq pollitem with the reactor. When the pollitem -// is ready, will call the handler, passing the arg. Returns 0 if OK, -1 -// if there was an error. If you register the pollitem more than once, each -// instance will invoke its corresponding handler. A pollitem with -// socket=NULL and fd=0 means 'poll on FD zero'. -CZMQ_EXPORT int - zloop_poller (zloop_t *self, zmq_pollitem_t *item, zloop_fn handler, void *arg); - -// Cancel a pollitem from the reactor, specified by socket or FD. If both -// are specified, uses only socket. If multiple poll items exist for same -// socket/FD, cancels ALL of them. -CZMQ_EXPORT void - zloop_poller_end (zloop_t *self, zmq_pollitem_t *item); - -// Configure a registered poller to ignore errors. If you do not set this, -// then poller that have errors are removed from the reactor silently. -CZMQ_EXPORT void - zloop_poller_set_tolerant (zloop_t *self, zmq_pollitem_t *item); - -// Register a timer that expires after some delay and repeats some number of -// times. At each expiry, will call the handler, passing the arg. To run a -// timer forever, use 0 times. Returns a timer_id that is used to cancel the -// timer in the future. Returns -1 if there was an error. -CZMQ_EXPORT int - zloop_timer (zloop_t *self, size_t delay, size_t times, zloop_timer_fn handler, void *arg); - -// Cancel a specific timer identified by a specific timer_id (as returned by -// zloop_timer). -CZMQ_EXPORT int - zloop_timer_end (zloop_t *self, int timer_id); - -// Register a ticket timer. Ticket timers are very fast in the case where -// you use a lot of timers (thousands), and frequently remove and add them. -// The main use case is expiry timers for servers that handle many clients, -// and which reset the expiry timer for each message received from a client. -// Whereas normal timers perform poorly as the number of clients grows, the -// cost of ticket timers is constant, no matter the number of clients. You -// must set the ticket delay using zloop_set_ticket_delay before creating a -// ticket. Returns a handle to the timer that you should use in -// zloop_ticket_reset and zloop_ticket_delete. -CZMQ_EXPORT void * - zloop_ticket (zloop_t *self, zloop_timer_fn handler, void *arg); - -// Reset a ticket timer, which moves it to the end of the ticket list and -// resets its execution time. This is a very fast operation. -CZMQ_EXPORT void - zloop_ticket_reset (zloop_t *self, void *handle); - -// Delete a ticket timer. We do not actually delete the ticket here, as -// other code may still refer to the ticket. We mark as deleted, and remove -// later and safely. -CZMQ_EXPORT void - zloop_ticket_delete (zloop_t *self, void *handle); - -// Set the ticket delay, which applies to all tickets. If you lower the -// delay and there are already tickets created, the results are undefined. -CZMQ_EXPORT void - zloop_set_ticket_delay (zloop_t *self, size_t ticket_delay); - -// Set hard limit on number of timers allowed. Setting more than a small -// number of timers (10-100) can have a dramatic impact on the performance -// of the reactor. For high-volume cases, use ticket timers. If the hard -// limit is reached, the reactor stops creating new timers and logs an -// error. -CZMQ_EXPORT void - zloop_set_max_timers (zloop_t *self, size_t max_timers); - -// Set verbose tracing of reactor on/off. The default verbose setting is -// off (false). -CZMQ_EXPORT void - zloop_set_verbose (zloop_t *self, bool verbose); - -// Start the reactor. Takes control of the thread and returns when the 0MQ -// context is terminated or the process is interrupted, or any event handler -// returns -1. Event handlers may register new sockets and timers, and -// cancel sockets. Returns 0 if interrupted, -1 if canceled by a handler. -CZMQ_EXPORT int - zloop_start (zloop_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zloop_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// By default the reactor stops if the process receives a SIGINT or SIGTERM -// signal. This makes it impossible to shut-down message based architectures -// like zactors. This method lets you switch off break handling. The default -// nonstop setting is off (false). -CZMQ_EXPORT void - zloop_set_nonstop (zloop_t *self, bool nonstop); - -#endif // CZMQ_BUILD_DRAFT_API -// @end - - -// Deprecated method aliases -#define zloop_set_tolerant(s,i) zloop_poller_set_tolerant(s,i) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zmonitor.h b/phonelibs/zmq/arm/include/zmonitor.h deleted file mode 100644 index b490bcb1a0dfbc..00000000000000 --- a/phonelibs/zmq/arm/include/zmonitor.h +++ /dev/null @@ -1,73 +0,0 @@ -/* ========================================================================= - zmonitor - socket event monitor - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZMONITOR_H_INCLUDED__ -#define __ZMONITOR_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// Create new zmonitor actor instance to monitor a zsock_t socket: -// -// zactor_t *monitor = zactor_new (zmonitor, mysocket); -// -// Destroy zmonitor instance. -// -// zactor_destroy (&monitor); -// -// Enable verbose logging of commands and activity. -// -// zstr_send (monitor, "VERBOSE"); -// -// Listen to monitor event type (zero or types, ending in NULL): -// zstr_sendx (monitor, "LISTEN", type, ..., NULL); -// -// Events: -// CONNECTED -// CONNECT_DELAYED -// CONNECT_RETRIED -// LISTENING -// BIND_FAILED -// ACCEPTED -// ACCEPT_FAILED -// CLOSED -// CLOSE_FAILED -// DISCONNECTED -// MONITOR_STOPPED -// ALL -// -// Start monitor; after this, any further LISTEN commands are ignored. -// -// zstr_send (monitor, "START"); -// zsock_wait (monitor); -// -// Receive next monitor event: -// -// zmsg_t *msg = zmsg_recv (monitor); -// -// This is the zmonitor constructor as a zactor_fn; the argument can be -// a zactor_t, zsock_t, or libzmq void * socket: -CZMQ_EXPORT void - zmonitor (zsock_t *pipe, void *sock); - -// Selftest -CZMQ_EXPORT void - zmonitor_test (bool verbose); -// @end -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zmonitor_v2.h b/phonelibs/zmq/arm/include/zmonitor_v2.h deleted file mode 100644 index 5780e0bcb785ae..00000000000000 --- a/phonelibs/zmq/arm/include/zmonitor_v2.h +++ /dev/null @@ -1,56 +0,0 @@ -/* ========================================================================= - zmonitor_v2 - socket event monitor (deprecated) - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZMONITOR_V2_H_INCLUDED__ -#define __ZMONITOR_V2_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// This code needs backporting to work with ZMQ v3.2 -#if (ZMQ_VERSION_MAJOR == 4) - -// Create a new socket monitor -CZMQ_EXPORT zmonitor_t * - zmonitor_new (zctx_t *ctx, void *socket, int events); - -// Destroy a socket monitor -CZMQ_EXPORT void - zmonitor_destroy (zmonitor_t **self_p); - -// Receive a status message from the monitor; if no message arrives within -// 500 msec, or the call was interrupted, returns NULL. -CZMQ_EXPORT zmsg_t * - zmonitor_recv (zmonitor_t *self); - -// Get the ZeroMQ socket, for polling -CZMQ_EXPORT void * - zmonitor_socket (zmonitor_t *self); - -// Enable verbose tracing of commands and activity -CZMQ_EXPORT void - zmonitor_set_verbose (zmonitor_t *self, bool verbose); -#endif // ZeroMQ 4.0 or later - -// Self test of this class -CZMQ_EXPORT void - zmonitor_v2_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zmq.h b/phonelibs/zmq/arm/include/zmq.h deleted file mode 100644 index 5f35d1915fcd92..00000000000000 --- a/phonelibs/zmq/arm/include/zmq.h +++ /dev/null @@ -1,617 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . - - ************************************************************************* - NOTE to contributors. This file comprises the principal public contract - for ZeroMQ API users. Any change to this file supplied in a stable - release SHOULD not break existing applications. - In practice this means that the value of constants must not change, and - that old values may not be reused for new constants. - ************************************************************************* -*/ - -#ifndef __ZMQ_H_INCLUDED__ -#define __ZMQ_H_INCLUDED__ - -/* Version macros for compile-time API version detection */ -#define ZMQ_VERSION_MAJOR 4 -#define ZMQ_VERSION_MINOR 2 -#define ZMQ_VERSION_PATCH 0 - -#define ZMQ_MAKE_VERSION(major, minor, patch) \ - ((major) * 10000 + (minor) * 100 + (patch)) -#define ZMQ_VERSION \ - ZMQ_MAKE_VERSION(ZMQ_VERSION_MAJOR, ZMQ_VERSION_MINOR, ZMQ_VERSION_PATCH) - -#ifdef __cplusplus -extern "C" { -#endif - -#if !defined _WIN32_WCE -#include -#endif -#include -#include -#if defined _WIN32 -// Set target version to Windows Server 2008, Windows Vista or higher. -// Windows XP (0x0501) is supported but without client & server socket types. -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0600 -#endif - -#ifdef __MINGW32__ -// Require Windows XP or higher with MinGW for getaddrinfo(). -#if(_WIN32_WINNT >= 0x0600) -#else -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0600 -#endif -#endif -#include -#endif - -/* Handle DSO symbol visibility */ -#if defined _WIN32 -# if defined ZMQ_STATIC -# define ZMQ_EXPORT -# elif defined DLL_EXPORT -# define ZMQ_EXPORT __declspec(dllexport) -# else -# define ZMQ_EXPORT __declspec(dllimport) -# endif -#else -# if defined __SUNPRO_C || defined __SUNPRO_CC -# define ZMQ_EXPORT __global -# elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER -# define ZMQ_EXPORT __attribute__ ((visibility("default"))) -# else -# define ZMQ_EXPORT -# endif -#endif - -/* Define integer types needed for event interface */ -#define ZMQ_DEFINED_STDINT 1 -#if defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_OPENVMS -# include -#elif defined _MSC_VER && _MSC_VER < 1600 -# ifndef int32_t - typedef __int32 int32_t; -# endif -# ifndef uint16_t - typedef unsigned __int16 uint16_t; -# endif -# ifndef uint8_t - typedef unsigned __int8 uint8_t; -# endif -#else -# include -#endif - - -/******************************************************************************/ -/* 0MQ errors. */ -/******************************************************************************/ - -/* A number random enough not to collide with different errno ranges on */ -/* different OSes. The assumption is that error_t is at least 32-bit type. */ -#define ZMQ_HAUSNUMERO 156384712 - -/* On Windows platform some of the standard POSIX errnos are not defined. */ -#ifndef ENOTSUP -#define ENOTSUP (ZMQ_HAUSNUMERO + 1) -#endif -#ifndef EPROTONOSUPPORT -#define EPROTONOSUPPORT (ZMQ_HAUSNUMERO + 2) -#endif -#ifndef ENOBUFS -#define ENOBUFS (ZMQ_HAUSNUMERO + 3) -#endif -#ifndef ENETDOWN -#define ENETDOWN (ZMQ_HAUSNUMERO + 4) -#endif -#ifndef EADDRINUSE -#define EADDRINUSE (ZMQ_HAUSNUMERO + 5) -#endif -#ifndef EADDRNOTAVAIL -#define EADDRNOTAVAIL (ZMQ_HAUSNUMERO + 6) -#endif -#ifndef ECONNREFUSED -#define ECONNREFUSED (ZMQ_HAUSNUMERO + 7) -#endif -#ifndef EINPROGRESS -#define EINPROGRESS (ZMQ_HAUSNUMERO + 8) -#endif -#ifndef ENOTSOCK -#define ENOTSOCK (ZMQ_HAUSNUMERO + 9) -#endif -#ifndef EMSGSIZE -#define EMSGSIZE (ZMQ_HAUSNUMERO + 10) -#endif -#ifndef EAFNOSUPPORT -#define EAFNOSUPPORT (ZMQ_HAUSNUMERO + 11) -#endif -#ifndef ENETUNREACH -#define ENETUNREACH (ZMQ_HAUSNUMERO + 12) -#endif -#ifndef ECONNABORTED -#define ECONNABORTED (ZMQ_HAUSNUMERO + 13) -#endif -#ifndef ECONNRESET -#define ECONNRESET (ZMQ_HAUSNUMERO + 14) -#endif -#ifndef ENOTCONN -#define ENOTCONN (ZMQ_HAUSNUMERO + 15) -#endif -#ifndef ETIMEDOUT -#define ETIMEDOUT (ZMQ_HAUSNUMERO + 16) -#endif -#ifndef EHOSTUNREACH -#define EHOSTUNREACH (ZMQ_HAUSNUMERO + 17) -#endif -#ifndef ENETRESET -#define ENETRESET (ZMQ_HAUSNUMERO + 18) -#endif - -/* Native 0MQ error codes. */ -#define EFSM (ZMQ_HAUSNUMERO + 51) -#define ENOCOMPATPROTO (ZMQ_HAUSNUMERO + 52) -#define ETERM (ZMQ_HAUSNUMERO + 53) -#define EMTHREAD (ZMQ_HAUSNUMERO + 54) - -/* This function retrieves the errno as it is known to 0MQ library. The goal */ -/* of this function is to make the code 100% portable, including where 0MQ */ -/* compiled with certain CRT library (on Windows) is linked to an */ -/* application that uses different CRT library. */ -ZMQ_EXPORT int zmq_errno (void); - -/* Resolves system errors and 0MQ errors to human-readable string. */ -ZMQ_EXPORT const char *zmq_strerror (int errnum); - -/* Run-time API version detection */ -ZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch); - -/******************************************************************************/ -/* 0MQ infrastructure (a.k.a. context) initialisation & termination. */ -/******************************************************************************/ - -/* Context options */ -#define ZMQ_IO_THREADS 1 -#define ZMQ_MAX_SOCKETS 2 -#define ZMQ_SOCKET_LIMIT 3 -#define ZMQ_THREAD_PRIORITY 3 -#define ZMQ_THREAD_SCHED_POLICY 4 -#define ZMQ_MAX_MSGSZ 5 - -/* Default for new contexts */ -#define ZMQ_IO_THREADS_DFLT 1 -#define ZMQ_MAX_SOCKETS_DFLT 1023 -#define ZMQ_THREAD_PRIORITY_DFLT -1 -#define ZMQ_THREAD_SCHED_POLICY_DFLT -1 - -ZMQ_EXPORT void *zmq_ctx_new (void); -ZMQ_EXPORT int zmq_ctx_term (void *context); -ZMQ_EXPORT int zmq_ctx_shutdown (void *context); -ZMQ_EXPORT int zmq_ctx_set (void *context, int option, int optval); -ZMQ_EXPORT int zmq_ctx_get (void *context, int option); - -/* Old (legacy) API */ -ZMQ_EXPORT void *zmq_init (int io_threads); -ZMQ_EXPORT int zmq_term (void *context); -ZMQ_EXPORT int zmq_ctx_destroy (void *context); - - -/******************************************************************************/ -/* 0MQ message definition. */ -/******************************************************************************/ - -/* union here ensures correct alignment on architectures that require it, e.g. - * SPARC - */ -typedef union zmq_msg_t {unsigned char _ [64]; void *p; } zmq_msg_t; - -typedef void (zmq_free_fn) (void *data, void *hint); - -ZMQ_EXPORT int zmq_msg_init (zmq_msg_t *msg); -ZMQ_EXPORT int zmq_msg_init_size (zmq_msg_t *msg, size_t size); -ZMQ_EXPORT int zmq_msg_init_data (zmq_msg_t *msg, void *data, - size_t size, zmq_free_fn *ffn, void *hint); -ZMQ_EXPORT int zmq_msg_send (zmq_msg_t *msg, void *s, int flags); -ZMQ_EXPORT int zmq_msg_recv (zmq_msg_t *msg, void *s, int flags); -ZMQ_EXPORT int zmq_msg_close (zmq_msg_t *msg); -ZMQ_EXPORT int zmq_msg_move (zmq_msg_t *dest, zmq_msg_t *src); -ZMQ_EXPORT int zmq_msg_copy (zmq_msg_t *dest, zmq_msg_t *src); -ZMQ_EXPORT void *zmq_msg_data (zmq_msg_t *msg); -ZMQ_EXPORT size_t zmq_msg_size (zmq_msg_t *msg); -ZMQ_EXPORT int zmq_msg_more (zmq_msg_t *msg); -ZMQ_EXPORT int zmq_msg_get (zmq_msg_t *msg, int property); -ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int property, int optval); -ZMQ_EXPORT const char *zmq_msg_gets (zmq_msg_t *msg, const char *property); - -/******************************************************************************/ -/* 0MQ socket definition. */ -/******************************************************************************/ - -/* Socket types. */ -#define ZMQ_PAIR 0 -#define ZMQ_PUB 1 -#define ZMQ_SUB 2 -#define ZMQ_REQ 3 -#define ZMQ_REP 4 -#define ZMQ_DEALER 5 -#define ZMQ_ROUTER 6 -#define ZMQ_PULL 7 -#define ZMQ_PUSH 8 -#define ZMQ_XPUB 9 -#define ZMQ_XSUB 10 -#define ZMQ_STREAM 11 - -/* Deprecated aliases */ -#define ZMQ_XREQ ZMQ_DEALER -#define ZMQ_XREP ZMQ_ROUTER - -/* Socket options. */ -#define ZMQ_AFFINITY 4 -#define ZMQ_IDENTITY 5 -#define ZMQ_SUBSCRIBE 6 -#define ZMQ_UNSUBSCRIBE 7 -#define ZMQ_RATE 8 -#define ZMQ_RECOVERY_IVL 9 -#define ZMQ_SNDBUF 11 -#define ZMQ_RCVBUF 12 -#define ZMQ_RCVMORE 13 -#define ZMQ_FD 14 -#define ZMQ_EVENTS 15 -#define ZMQ_TYPE 16 -#define ZMQ_LINGER 17 -#define ZMQ_RECONNECT_IVL 18 -#define ZMQ_BACKLOG 19 -#define ZMQ_RECONNECT_IVL_MAX 21 -#define ZMQ_MAXMSGSIZE 22 -#define ZMQ_SNDHWM 23 -#define ZMQ_RCVHWM 24 -#define ZMQ_MULTICAST_HOPS 25 -#define ZMQ_RCVTIMEO 27 -#define ZMQ_SNDTIMEO 28 -#define ZMQ_LAST_ENDPOINT 32 -#define ZMQ_ROUTER_MANDATORY 33 -#define ZMQ_TCP_KEEPALIVE 34 -#define ZMQ_TCP_KEEPALIVE_CNT 35 -#define ZMQ_TCP_KEEPALIVE_IDLE 36 -#define ZMQ_TCP_KEEPALIVE_INTVL 37 -#define ZMQ_IMMEDIATE 39 -#define ZMQ_XPUB_VERBOSE 40 -#define ZMQ_ROUTER_RAW 41 -#define ZMQ_IPV6 42 -#define ZMQ_MECHANISM 43 -#define ZMQ_PLAIN_SERVER 44 -#define ZMQ_PLAIN_USERNAME 45 -#define ZMQ_PLAIN_PASSWORD 46 -#define ZMQ_CURVE_SERVER 47 -#define ZMQ_CURVE_PUBLICKEY 48 -#define ZMQ_CURVE_SECRETKEY 49 -#define ZMQ_CURVE_SERVERKEY 50 -#define ZMQ_PROBE_ROUTER 51 -#define ZMQ_REQ_CORRELATE 52 -#define ZMQ_REQ_RELAXED 53 -#define ZMQ_CONFLATE 54 -#define ZMQ_ZAP_DOMAIN 55 -#define ZMQ_ROUTER_HANDOVER 56 -#define ZMQ_TOS 57 -#define ZMQ_CONNECT_RID 61 -#define ZMQ_GSSAPI_SERVER 62 -#define ZMQ_GSSAPI_PRINCIPAL 63 -#define ZMQ_GSSAPI_SERVICE_PRINCIPAL 64 -#define ZMQ_GSSAPI_PLAINTEXT 65 -#define ZMQ_HANDSHAKE_IVL 66 -#define ZMQ_SOCKS_PROXY 68 -#define ZMQ_XPUB_NODROP 69 -// All options after this is for version 4.2 and still *draft* -// Subject to arbitrary change without notice -#define ZMQ_BLOCKY 70 -#define ZMQ_XPUB_MANUAL 71 -#define ZMQ_XPUB_WELCOME_MSG 72 -#define ZMQ_STREAM_NOTIFY 73 -#define ZMQ_INVERT_MATCHING 74 -#define ZMQ_HEARTBEAT_IVL 75 -#define ZMQ_HEARTBEAT_TTL 76 -#define ZMQ_HEARTBEAT_TIMEOUT 77 -#define ZMQ_XPUB_VERBOSER 78 -#define ZMQ_CONNECT_TIMEOUT 79 -#define ZMQ_TCP_MAXRT 80 -#define ZMQ_THREAD_SAFE 81 -#define ZMQ_MULTICAST_MAXTPDU 84 -#define ZMQ_VMCI_BUFFER_SIZE 85 -#define ZMQ_VMCI_BUFFER_MIN_SIZE 86 -#define ZMQ_VMCI_BUFFER_MAX_SIZE 87 -#define ZMQ_VMCI_CONNECT_TIMEOUT 88 -#define ZMQ_USE_FD 89 - -/* Message options */ -#define ZMQ_MORE 1 -#define ZMQ_SHARED 3 - -/* Send/recv options. */ -#define ZMQ_DONTWAIT 1 -#define ZMQ_SNDMORE 2 - -/* Security mechanisms */ -#define ZMQ_NULL 0 -#define ZMQ_PLAIN 1 -#define ZMQ_CURVE 2 -#define ZMQ_GSSAPI 3 - -/* RADIO-DISH protocol */ -#define ZMQ_GROUP_MAX_LENGTH 15 - -/* Deprecated options and aliases */ -#define ZMQ_TCP_ACCEPT_FILTER 38 -#define ZMQ_IPC_FILTER_PID 58 -#define ZMQ_IPC_FILTER_UID 59 -#define ZMQ_IPC_FILTER_GID 60 -#define ZMQ_IPV4ONLY 31 -#define ZMQ_DELAY_ATTACH_ON_CONNECT ZMQ_IMMEDIATE -#define ZMQ_NOBLOCK ZMQ_DONTWAIT -#define ZMQ_FAIL_UNROUTABLE ZMQ_ROUTER_MANDATORY -#define ZMQ_ROUTER_BEHAVIOR ZMQ_ROUTER_MANDATORY - -/* Deprecated Message options */ -#define ZMQ_SRCFD 2 - -/******************************************************************************/ -/* 0MQ socket events and monitoring */ -/******************************************************************************/ - -/* Socket transport events (TCP, IPC and TIPC only) */ - -#define ZMQ_EVENT_CONNECTED 0x0001 -#define ZMQ_EVENT_CONNECT_DELAYED 0x0002 -#define ZMQ_EVENT_CONNECT_RETRIED 0x0004 -#define ZMQ_EVENT_LISTENING 0x0008 -#define ZMQ_EVENT_BIND_FAILED 0x0010 -#define ZMQ_EVENT_ACCEPTED 0x0020 -#define ZMQ_EVENT_ACCEPT_FAILED 0x0040 -#define ZMQ_EVENT_CLOSED 0x0080 -#define ZMQ_EVENT_CLOSE_FAILED 0x0100 -#define ZMQ_EVENT_DISCONNECTED 0x0200 -#define ZMQ_EVENT_MONITOR_STOPPED 0x0400 -#define ZMQ_EVENT_ALL 0xFFFF - -ZMQ_EXPORT void *zmq_socket (void *, int type); -ZMQ_EXPORT int zmq_close (void *s); -ZMQ_EXPORT int zmq_setsockopt (void *s, int option, const void *optval, - size_t optvallen); -ZMQ_EXPORT int zmq_getsockopt (void *s, int option, void *optval, - size_t *optvallen); -ZMQ_EXPORT int zmq_bind (void *s, const char *addr); -ZMQ_EXPORT int zmq_connect (void *s, const char *addr); -ZMQ_EXPORT int zmq_unbind (void *s, const char *addr); -ZMQ_EXPORT int zmq_disconnect (void *s, const char *addr); -ZMQ_EXPORT int zmq_send (void *s, const void *buf, size_t len, int flags); -ZMQ_EXPORT int zmq_send_const (void *s, const void *buf, size_t len, int flags); -ZMQ_EXPORT int zmq_recv (void *s, void *buf, size_t len, int flags); -ZMQ_EXPORT int zmq_socket_monitor (void *s, const char *addr, int events); - - -/******************************************************************************/ -/* I/O multiplexing. */ -/******************************************************************************/ - -#define ZMQ_POLLIN 1 -#define ZMQ_POLLOUT 2 -#define ZMQ_POLLERR 4 -#define ZMQ_POLLPRI 8 - -typedef struct zmq_pollitem_t -{ - void *socket; -#if defined _WIN32 - SOCKET fd; -#else - int fd; -#endif - short events; - short revents; -} zmq_pollitem_t; - -#define ZMQ_POLLITEMS_DFLT 16 - -ZMQ_EXPORT int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout); - -/******************************************************************************/ -/* Message proxying */ -/******************************************************************************/ - -ZMQ_EXPORT int zmq_proxy (void *frontend, void *backend, void *capture); -ZMQ_EXPORT int zmq_proxy_steerable (void *frontend, void *backend, void *capture, void *control); - -/******************************************************************************/ -/* Probe library capabilities */ -/******************************************************************************/ - -#define ZMQ_HAS_CAPABILITIES 1 -ZMQ_EXPORT int zmq_has (const char *capability); - -/* Deprecated aliases */ -#define ZMQ_STREAMER 1 -#define ZMQ_FORWARDER 2 -#define ZMQ_QUEUE 3 - -/* Deprecated methods */ -ZMQ_EXPORT int zmq_device (int type, void *frontend, void *backend); -ZMQ_EXPORT int zmq_sendmsg (void *s, zmq_msg_t *msg, int flags); -ZMQ_EXPORT int zmq_recvmsg (void *s, zmq_msg_t *msg, int flags); -struct iovec; -ZMQ_EXPORT int zmq_sendiov (void *s, struct iovec *iov, size_t count, int flags); -ZMQ_EXPORT int zmq_recviov (void *s, struct iovec *iov, size_t *count, int flags); - -/******************************************************************************/ -/* Encryption functions */ -/******************************************************************************/ - -/* Encode data with Z85 encoding. Returns encoded data */ -ZMQ_EXPORT char *zmq_z85_encode (char *dest, const uint8_t *data, size_t size); - -/* Decode data with Z85 encoding. Returns decoded data */ -ZMQ_EXPORT uint8_t *zmq_z85_decode (uint8_t *dest, const char *string); - -/* Generate z85-encoded public and private keypair with tweetnacl/libsodium. */ -/* Returns 0 on success. */ -ZMQ_EXPORT int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key); - -/* Derive the z85-encoded public key from the z85-encoded secret key. */ -/* Returns 0 on success. */ -ZMQ_EXPORT int zmq_curve_public (char *z85_public_key, const char *z85_secret_key); - -/******************************************************************************/ -/* Atomic utility methods */ -/******************************************************************************/ - -ZMQ_EXPORT void *zmq_atomic_counter_new (void); -ZMQ_EXPORT void zmq_atomic_counter_set (void *counter, int value); -ZMQ_EXPORT int zmq_atomic_counter_inc (void *counter); -ZMQ_EXPORT int zmq_atomic_counter_dec (void *counter); -ZMQ_EXPORT int zmq_atomic_counter_value (void *counter); -ZMQ_EXPORT void zmq_atomic_counter_destroy (void **counter_p); - - -/******************************************************************************/ -/* These functions are not documented by man pages -- use at your own risk. */ -/* If you need these to be part of the formal ZMQ API, then (a) write a man */ -/* page, and (b) write a test case in tests. */ -/******************************************************************************/ - -/* Helper functions are used by perf tests so that they don't have to care */ -/* about minutiae of time-related functions on different OS platforms. */ - -/* Starts the stopwatch. Returns the handle to the watch. */ -ZMQ_EXPORT void *zmq_stopwatch_start (void); - -/* Stops the stopwatch. Returns the number of microseconds elapsed since */ -/* the stopwatch was started. */ -ZMQ_EXPORT unsigned long zmq_stopwatch_stop (void *watch_); - -/* Sleeps for specified number of seconds. */ -ZMQ_EXPORT void zmq_sleep (int seconds_); - -typedef void (zmq_thread_fn) (void*); - -/* Start a thread. Returns a handle to the thread. */ -ZMQ_EXPORT void *zmq_threadstart (zmq_thread_fn* func, void* arg); - -/* Wait for thread to complete then free up resources. */ -ZMQ_EXPORT void zmq_threadclose (void* thread); - - -/******************************************************************************/ -/* These functions are DRAFT and disabled in stable releases, and subject to */ -/* change at ANY time until declared stable. */ -/******************************************************************************/ - -#ifdef ZMQ_BUILD_DRAFT_API - -/* DRAFT Socket types. */ -#define ZMQ_SERVER 12 -#define ZMQ_CLIENT 13 -#define ZMQ_RADIO 14 -#define ZMQ_DISH 15 -#define ZMQ_GATHER 16 -#define ZMQ_SCATTER 17 -#define ZMQ_DGRAM 18 - -/* DRAFT Socket methods. */ -ZMQ_EXPORT int zmq_join (void *s, const char *group); -ZMQ_EXPORT int zmq_leave (void *s, const char *group); - -/* DRAFT Msg methods. */ -ZMQ_EXPORT int zmq_msg_set_routing_id(zmq_msg_t *msg, uint32_t routing_id); -ZMQ_EXPORT uint32_t zmq_msg_routing_id(zmq_msg_t *msg); -ZMQ_EXPORT int zmq_msg_set_group(zmq_msg_t *msg, const char *group); -ZMQ_EXPORT const char *zmq_msg_group(zmq_msg_t *msg); - -/******************************************************************************/ -/* Poller polling on sockets,fd and thread-safe sockets */ -/******************************************************************************/ - -#define ZMQ_HAVE_POLLER - -typedef struct zmq_poller_event_t -{ - void *socket; -#if defined _WIN32 - SOCKET fd; -#else - int fd; -#endif - void *user_data; - short events; -} zmq_poller_event_t; - -ZMQ_EXPORT void *zmq_poller_new (void); -ZMQ_EXPORT int zmq_poller_destroy (void **poller_p); -ZMQ_EXPORT int zmq_poller_add (void *poller, void *socket, void *user_data, short events); -ZMQ_EXPORT int zmq_poller_modify (void *poller, void *socket, short events); -ZMQ_EXPORT int zmq_poller_remove (void *poller, void *socket); -ZMQ_EXPORT int zmq_poller_wait (void *poller, zmq_poller_event_t *event, long timeout); - -#if defined _WIN32 -ZMQ_EXPORT int zmq_poller_add_fd (void *poller, SOCKET fd, void *user_data, short events); -ZMQ_EXPORT int zmq_poller_modify_fd (void *poller, SOCKET fd, short events); -ZMQ_EXPORT int zmq_poller_remove_fd (void *poller, SOCKET fd); -#else -ZMQ_EXPORT int zmq_poller_add_fd (void *poller, int fd, void *user_data, short events); -ZMQ_EXPORT int zmq_poller_modify_fd (void *poller, int fd, short events); -ZMQ_EXPORT int zmq_poller_remove_fd (void *poller, int fd); -#endif - -/******************************************************************************/ -/* Scheduling timers */ -/******************************************************************************/ - -#define ZMQ_HAVE_TIMERS - -typedef void (zmq_timer_fn)(int timer_id, void *arg); - -ZMQ_EXPORT void *zmq_timers_new (void); -ZMQ_EXPORT int zmq_timers_destroy (void **timers_p); -ZMQ_EXPORT int zmq_timers_add (void *timers, size_t interval, zmq_timer_fn handler, void *arg); -ZMQ_EXPORT int zmq_timers_cancel (void *timers, int timer_id); -ZMQ_EXPORT int zmq_timers_set_interval (void *timers, int timer_id, size_t interval); -ZMQ_EXPORT int zmq_timers_reset (void *timers, int timer_id); -ZMQ_EXPORT long zmq_timers_timeout (void *timers); -ZMQ_EXPORT int zmq_timers_execute (void *timers); - -#endif // ZMQ_BUILD_DRAFT_API - - -#undef ZMQ_EXPORT - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zmq_utils.h b/phonelibs/zmq/arm/include/zmq_utils.h deleted file mode 100644 index f29638d5539414..00000000000000 --- a/phonelibs/zmq/arm/include/zmq_utils.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file - - This file is part of libzmq, the ZeroMQ core engine in C++. - - libzmq is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License (LGPL) as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - As a special exception, the Contributors give you permission to link - this library with independent modules to produce an executable, - regardless of the license terms of these independent modules, and to - copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the - terms and conditions of the license of that module. An independent - module is a module which is not derived from or based on this library. - If you modify this library, you must extend this exception to your - version of the library. - - libzmq is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -/* This file is deprecated, and all its functionality provided by zmq.h */ -/* Note that -Wpedantic compilation requires GCC to avoid using its custom - extensions such as #warning, hence the trick below. Also, pragmas for - warnings or other messages are not standard, not portable, and not all - compilers even have an equivalent concept. - So in the worst case, this include file is treated as silently empty. */ - -#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER) -#if defined(__GNUC__) || defined(__GNUG__) -#pragma GCC diagnostic push -#pragma GCC diagnostic warning "-Wcpp" -#pragma GCC diagnostic ignored "-Werror" -#pragma GCC diagnostic ignored "-Wall" -#endif -#pragma message("Warning: zmq_utils.h is deprecated. All its functionality is provided by zmq.h.") -#if defined(__GNUC__) || defined(__GNUG__) -#pragma GCC diagnostic pop -#endif -#endif diff --git a/phonelibs/zmq/arm/include/zmsg.h b/phonelibs/zmq/arm/include/zmsg.h deleted file mode 100644 index c6ab16c66e953c..00000000000000 --- a/phonelibs/zmq/arm/include/zmsg.h +++ /dev/null @@ -1,285 +0,0 @@ -/* ========================================================================= - zmsg - working with multipart messages - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZMSG_H_INCLUDED__ -#define __ZMSG_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zmsg.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// Create a new empty message object -CZMQ_EXPORT zmsg_t * - zmsg_new (void); - -// Receive message from socket, returns zmsg_t object or NULL if the recv -// was interrupted. Does a blocking recv. If you want to not block then use -// the zloop class or zmsg_recv_nowait or zmq_poll to check for socket input -// before receiving. -CZMQ_EXPORT zmsg_t * - zmsg_recv (void *source); - -// Load/append an open file into new message, return the message. -// Returns NULL if the message could not be loaded. -CZMQ_EXPORT zmsg_t * - zmsg_load (FILE *file); - -// Decodes a serialized message frame created by zmsg_encode () and returns -// a new zmsg_t object. Returns NULL if the frame was badly formatted or -// there was insufficient memory to work. -CZMQ_EXPORT zmsg_t * - zmsg_decode (zframe_t *frame); - -// Generate a signal message encoding the given status. A signal is a short -// message carrying a 1-byte success/failure code (by convention, 0 means -// OK). Signals are encoded to be distinguishable from "normal" messages. -CZMQ_EXPORT zmsg_t * - zmsg_new_signal (byte status); - -// Destroy a message object and all frames it contains -CZMQ_EXPORT void - zmsg_destroy (zmsg_t **self_p); - -// Send message to destination socket, and destroy the message after sending -// it successfully. If the message has no frames, sends nothing but destroys -// the message anyhow. Nullifies the caller's reference to the message (as -// it is a destructor). -CZMQ_EXPORT int - zmsg_send (zmsg_t **self_p, void *dest); - -// Send message to destination socket as part of a multipart sequence, and -// destroy the message after sending it successfully. Note that after a -// zmsg_sendm, you must call zmsg_send or another method that sends a final -// message part. If the message has no frames, sends nothing but destroys -// the message anyhow. Nullifies the caller's reference to the message (as -// it is a destructor). -CZMQ_EXPORT int - zmsg_sendm (zmsg_t **self_p, void *dest); - -// Return size of message, i.e. number of frames (0 or more). -CZMQ_EXPORT size_t - zmsg_size (zmsg_t *self); - -// Return total size of all frames in message. -CZMQ_EXPORT size_t - zmsg_content_size (zmsg_t *self); - -// Push frame to the front of the message, i.e. before all other frames. -// Message takes ownership of frame, will destroy it when message is sent. -// Returns 0 on success, -1 on error. Deprecates zmsg_push, which did not -// nullify the caller's frame reference. -CZMQ_EXPORT int - zmsg_prepend (zmsg_t *self, zframe_t **frame_p); - -// Add frame to the end of the message, i.e. after all other frames. -// Message takes ownership of frame, will destroy it when message is sent. -// Returns 0 on success. Deprecates zmsg_add, which did not nullify the -// caller's frame reference. -CZMQ_EXPORT int - zmsg_append (zmsg_t *self, zframe_t **frame_p); - -// Remove first frame from message, if any. Returns frame, or NULL. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zframe_t * - zmsg_pop (zmsg_t *self); - -// Push block of memory to front of message, as a new frame. -// Returns 0 on success, -1 on error. -CZMQ_EXPORT int - zmsg_pushmem (zmsg_t *self, const void *data, size_t size); - -// Add block of memory to the end of the message, as a new frame. -// Returns 0 on success, -1 on error. -CZMQ_EXPORT int - zmsg_addmem (zmsg_t *self, const void *data, size_t size); - -// Push string as new frame to front of message. -// Returns 0 on success, -1 on error. -CZMQ_EXPORT int - zmsg_pushstr (zmsg_t *self, const char *string); - -// Push string as new frame to end of message. -// Returns 0 on success, -1 on error. -CZMQ_EXPORT int - zmsg_addstr (zmsg_t *self, const char *string); - -// Push formatted string as new frame to front of message. -// Returns 0 on success, -1 on error. -CZMQ_EXPORT int - zmsg_pushstrf (zmsg_t *self, const char *format, ...); - -// Push formatted string as new frame to end of message. -// Returns 0 on success, -1 on error. -CZMQ_EXPORT int - zmsg_addstrf (zmsg_t *self, const char *format, ...); - -// Pop frame off front of message, return as fresh string. If there were -// no more frames in the message, returns NULL. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zmsg_popstr (zmsg_t *self); - -// Push encoded message as a new frame. Message takes ownership of -// submessage, so the original is destroyed in this call. Returns 0 on -// success, -1 on error. -CZMQ_EXPORT int - zmsg_addmsg (zmsg_t *self, zmsg_t **msg_p); - -// Remove first submessage from message, if any. Returns zmsg_t, or NULL if -// decoding was not successful. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zmsg_t * - zmsg_popmsg (zmsg_t *self); - -// Remove specified frame from list, if present. Does not destroy frame. -CZMQ_EXPORT void - zmsg_remove (zmsg_t *self, zframe_t *frame); - -// Set cursor to first frame in message. Returns frame, or NULL, if the -// message is empty. Use this to navigate the frames as a list. -CZMQ_EXPORT zframe_t * - zmsg_first (zmsg_t *self); - -// Return the next frame. If there are no more frames, returns NULL. To move -// to the first frame call zmsg_first(). Advances the cursor. -CZMQ_EXPORT zframe_t * - zmsg_next (zmsg_t *self); - -// Return the last frame. If there are no frames, returns NULL. -CZMQ_EXPORT zframe_t * - zmsg_last (zmsg_t *self); - -// Save message to an open file, return 0 if OK, else -1. The message is -// saved as a series of frames, each with length and data. Note that the -// file is NOT guaranteed to be portable between operating systems, not -// versions of CZMQ. The file format is at present undocumented and liable -// to arbitrary change. -CZMQ_EXPORT int - zmsg_save (zmsg_t *self, FILE *file); - -// Serialize multipart message to a single message frame. Use this method -// to send structured messages across transports that do not support -// multipart data. Allocates and returns a new frame containing the -// serialized message. To decode a serialized message frame, use -// zmsg_decode (). -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zframe_t * - zmsg_encode (zmsg_t *self); - -// Create copy of message, as new message object. Returns a fresh zmsg_t -// object. If message is null, or memory was exhausted, returns null. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT zmsg_t * - zmsg_dup (zmsg_t *self); - -// Send message to zsys log sink (may be stdout, or system facility as -// configured by zsys_set_logstream). -CZMQ_EXPORT void - zmsg_print (zmsg_t *self); - -// Return true if the two messages have the same number of frames and each -// frame in the first message is identical to the corresponding frame in the -// other message. As with zframe_eq, return false if either message is NULL. -CZMQ_EXPORT bool - zmsg_eq (zmsg_t *self, zmsg_t *other); - -// Return signal value, 0 or greater, if message is a signal, -1 if not. -CZMQ_EXPORT int - zmsg_signal (zmsg_t *self); - -// Probe the supplied object, and report if it looks like a zmsg_t. -CZMQ_EXPORT bool - zmsg_is (void *self); - -// Self test of this class. -CZMQ_EXPORT void - zmsg_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Return message routing ID, if the message came from a ZMQ_SERVER socket. -// Else returns zero. -CZMQ_EXPORT uint32_t - zmsg_routing_id (zmsg_t *self); - -// *** Draft method, for development use, may change without warning *** -// Set routing ID on message. This is used if/when the message is sent to a -// ZMQ_SERVER socket. -CZMQ_EXPORT void - zmsg_set_routing_id (zmsg_t *self, uint32_t routing_id); - -#endif // CZMQ_BUILD_DRAFT_API -// @ignore -CZMQ_EXPORT int - zmsg_pushstrf (zmsg_t *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int - zmsg_addstrf (zmsg_t *self, const char *format, ...) CHECK_PRINTF (2); -// @end - - -// DEPRECATED as over-engineered, poor style -// Pop frame off front of message, caller now owns frame -// If next frame is empty, pops and destroys that empty frame. -CZMQ_EXPORT zframe_t * - zmsg_unwrap (zmsg_t *self); - -// DEPRECATED as poor style -- callers should use zloop or zpoller -// Receive message from socket, returns zmsg_t object, or NULL either if -// there was no input waiting, or the recv was interrupted. -CZMQ_EXPORT zmsg_t * - zmsg_recv_nowait (void *source); - -// DEPRECATED as unsafe -- does not nullify frame reference. -// Push frame plus empty frame to front of message, before first frame. -// Message takes ownership of frame, will destroy it when message is sent. -CZMQ_EXPORT void - zmsg_wrap (zmsg_t *self, zframe_t *frame); - -// DEPRECATED - will be removed for next + 1 stable release -// Add frame to the front of the message, i.e. before all other frames. -// Message takes ownership of frame, will destroy it when message is sent. -// Returns 0 on success, -1 on error. -CZMQ_EXPORT int - zmsg_push (zmsg_t *self, zframe_t *frame); - -// DEPRECATED - will be removed for next stable release -CZMQ_EXPORT int - zmsg_add (zmsg_t *self, zframe_t *frame); - -// DEPRECATED as inconsistent; breaks principle that logging should all go -// to a single destination. -// Print message to open stream -// Truncates to first 10 frames, for readability. -CZMQ_EXPORT void - zmsg_fprint (zmsg_t *self, FILE *file); - -// Compiler hints -CZMQ_EXPORT int zmsg_addstrf (zmsg_t *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int zmsg_pushstrf (zmsg_t *self, const char *format, ...) CHECK_PRINTF (2); - -#ifdef __cplusplus -} -#endif - -// Deprecated method aliases -#define zmsg_dump(s) zmsg_print(s) -#define zmsg_dump_to_stream(s,F) zmsg_fprint(s,F) - -#endif diff --git a/phonelibs/zmq/arm/include/zmutex.h b/phonelibs/zmq/arm/include/zmutex.h deleted file mode 100644 index cba315999b7598..00000000000000 --- a/phonelibs/zmq/arm/include/zmutex.h +++ /dev/null @@ -1,55 +0,0 @@ -/* ========================================================================= - zmutex - working with mutexes - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZMUTEX_H_INCLUDED__ -#define __ZMUTEX_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// This is a deprecated class, and will be removed over time. It is -// provided in stable builds to support old applications. You should -// stop using this class, and migrate any code that is still using it. - -// Create a new mutex container -CZMQ_EXPORT zmutex_t * - zmutex_new (void); - -// Destroy a mutex container -CZMQ_EXPORT void - zmutex_destroy (zmutex_t **self_p); - -// Lock mutex -CZMQ_EXPORT void - zmutex_lock (zmutex_t *self); - -// Unlock mutex -CZMQ_EXPORT void - zmutex_unlock (zmutex_t *self); - -// Try to lock mutex -CZMQ_EXPORT int - zmutex_try_lock (zmutex_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zmutex_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zpoller.h b/phonelibs/zmq/arm/include/zpoller.h deleted file mode 100644 index 3756a935a64008..00000000000000 --- a/phonelibs/zmq/arm/include/zpoller.h +++ /dev/null @@ -1,92 +0,0 @@ -/* ========================================================================= - zpoller - trivial socket poller class - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __zpoller_H_INCLUDED__ -#define __zpoller_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zpoller.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// Create new poller, specifying zero or more readers. The list of -// readers ends in a NULL. Each reader can be a zsock_t instance, a -// zactor_t instance, a libzmq socket (void *), or a file handle. -CZMQ_EXPORT zpoller_t * - zpoller_new (void *reader, ...); - -// Destroy a poller -CZMQ_EXPORT void - zpoller_destroy (zpoller_t **self_p); - -// Add a reader to be polled. Returns 0 if OK, -1 on failure. The reader may -// be a libzmq void * socket, a zsock_t instance, or a zactor_t instance. -CZMQ_EXPORT int - zpoller_add (zpoller_t *self, void *reader); - -// Remove a reader from the poller; returns 0 if OK, -1 on failure. The reader -// must have been passed during construction, or in an zpoller_add () call. -CZMQ_EXPORT int - zpoller_remove (zpoller_t *self, void *reader); - -// Poll the registered readers for I/O, return first reader that has input. -// The reader will be a libzmq void * socket, or a zsock_t or zactor_t -// instance as specified in zpoller_new/zpoller_add. The timeout should be -// zero or greater, or -1 to wait indefinitely. Socket priority is defined -// by their order in the poll list. If you need a balanced poll, use the low -// level zmq_poll method directly. If the poll call was interrupted (SIGINT), -// or the ZMQ context was destroyed, or the timeout expired, returns NULL. -// You can test the actual exit condition by calling zpoller_expired () and -// zpoller_terminated (). The timeout is in msec. -CZMQ_EXPORT void * - zpoller_wait (zpoller_t *self, int timeout); - -// Return true if the last zpoller_wait () call ended because the timeout -// expired, without any error. -CZMQ_EXPORT bool - zpoller_expired (zpoller_t *self); - -// Return true if the last zpoller_wait () call ended because the process -// was interrupted, or the parent context was destroyed. -CZMQ_EXPORT bool - zpoller_terminated (zpoller_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zpoller_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// By default the poller stops if the process receives a SIGINT or SIGTERM -// signal. This makes it impossible to shut-down message based architectures -// like zactors. This method lets you switch off break handling. The default -// nonstop setting is off (false). -CZMQ_EXPORT void - zpoller_set_nonstop (zpoller_t *self, bool nonstop); - -#endif // CZMQ_BUILD_DRAFT_API -// @end - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/phonelibs/zmq/arm/include/zproc.h b/phonelibs/zmq/arm/include/zproc.h deleted file mode 100644 index a2e1b3dd9913c6..00000000000000 --- a/phonelibs/zmq/arm/include/zproc.h +++ /dev/null @@ -1,179 +0,0 @@ -/* ========================================================================= - zproc - process configuration and status - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef ZPROC_H_INCLUDED -#define ZPROC_H_INCLUDED - -#ifdef __cplusplus -extern "C" { -#endif - - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zproc.api" to make changes. -// @interface -// This is a draft class, and may change without notice. It is disabled in -// stable builds by default. If you use this in applications, please ask -// for it to be pushed to stable state. Use --enable-drafts to enable. -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Returns CZMQ version as a single 6-digit integer encoding the major -// version (x 10000), the minor version (x 100) and the patch. -CZMQ_EXPORT int - zproc_czmq_version (void); - -// *** Draft method, for development use, may change without warning *** -// Returns true if the process received a SIGINT or SIGTERM signal. -// It is good practice to use this method to exit any infinite loop -// processing messages. -CZMQ_EXPORT bool - zproc_interrupted (void); - -// *** Draft method, for development use, may change without warning *** -// Returns true if the underlying libzmq supports CURVE security. -CZMQ_EXPORT bool - zproc_has_curve (void); - -// *** Draft method, for development use, may change without warning *** -// Return current host name, for use in public tcp:// endpoints. -// If the host name is not resolvable, returns NULL. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zproc_hostname (void); - -// *** Draft method, for development use, may change without warning *** -// Move the current process into the background. The precise effect -// depends on the operating system. On POSIX boxes, moves to a specified -// working directory (if specified), closes all file handles, reopens -// stdin, stdout, and stderr to the null device, and sets the process to -// ignore SIGHUP. On Windows, does nothing. Returns 0 if OK, -1 if there -// was an error. -CZMQ_EXPORT void - zproc_daemonize (const char *workdir); - -// *** Draft method, for development use, may change without warning *** -// Drop the process ID into the lockfile, with exclusive lock, and -// switch the process to the specified group and/or user. Any of the -// arguments may be null, indicating a no-op. Returns 0 on success, -// -1 on failure. Note if you combine this with zsys_daemonize, run -// after, not before that method, or the lockfile will hold the wrong -// process ID. -CZMQ_EXPORT void - zproc_run_as (const char *lockfile, const char *group, const char *user); - -// *** Draft method, for development use, may change without warning *** -// Configure the number of I/O threads that ZeroMQ will use. A good -// rule of thumb is one thread per gigabit of traffic in or out. The -// default is 1, sufficient for most applications. If the environment -// variable ZSYS_IO_THREADS is defined, that provides the default. -// Note that this method is valid only before any socket is created. -CZMQ_EXPORT void - zproc_set_io_threads (size_t io_threads); - -// *** Draft method, for development use, may change without warning *** -// Configure the number of sockets that ZeroMQ will allow. The default -// is 1024. The actual limit depends on the system, and you can query it -// by using zsys_socket_limit (). A value of zero means "maximum". -// Note that this method is valid only before any socket is created. -CZMQ_EXPORT void - zproc_set_max_sockets (size_t max_sockets); - -// *** Draft method, for development use, may change without warning *** -// Set network interface name to use for broadcasts, particularly zbeacon. -// This lets the interface be configured for test environments where required. -// For example, on Mac OS X, zbeacon cannot bind to 255.255.255.255 which is -// the default when there is no specified interface. If the environment -// variable ZSYS_INTERFACE is set, use that as the default interface name. -// Setting the interface to "*" means "use all available interfaces". -CZMQ_EXPORT void - zproc_set_biface (const char *value); - -// *** Draft method, for development use, may change without warning *** -// Return network interface to use for broadcasts, or "" if none was set. -CZMQ_EXPORT const char * - zproc_biface (void); - -// *** Draft method, for development use, may change without warning *** -// Set log identity, which is a string that prefixes all log messages sent -// by this process. The log identity defaults to the environment variable -// ZSYS_LOGIDENT, if that is set. -CZMQ_EXPORT void - zproc_set_log_ident (const char *value); - -// *** Draft method, for development use, may change without warning *** -// Sends log output to a PUB socket bound to the specified endpoint. To -// collect such log output, create a SUB socket, subscribe to the traffic -// you care about, and connect to the endpoint. Log traffic is sent as a -// single string frame, in the same format as when sent to stdout. The -// log system supports a single sender; multiple calls to this method will -// bind the same sender to multiple endpoints. To disable the sender, call -// this method with a null argument. -CZMQ_EXPORT void - zproc_set_log_sender (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Enable or disable logging to the system facility (syslog on POSIX boxes, -// event log on Windows). By default this is disabled. -CZMQ_EXPORT void - zproc_set_log_system (bool logsystem); - -// *** Draft method, for development use, may change without warning *** -// Log error condition - highest priority -CZMQ_EXPORT void - zproc_log_error (const char *format, ...); - -// *** Draft method, for development use, may change without warning *** -// Log warning condition - high priority -CZMQ_EXPORT void - zproc_log_warning (const char *format, ...); - -// *** Draft method, for development use, may change without warning *** -// Log normal, but significant, condition - normal priority -CZMQ_EXPORT void - zproc_log_notice (const char *format, ...); - -// *** Draft method, for development use, may change without warning *** -// Log informational message - low priority -CZMQ_EXPORT void - zproc_log_info (const char *format, ...); - -// *** Draft method, for development use, may change without warning *** -// Log debug-level message - lowest priority -CZMQ_EXPORT void - zproc_log_debug (const char *format, ...); - -// *** Draft method, for development use, may change without warning *** -// Self test of this class. -CZMQ_EXPORT void - zproc_test (bool verbose); - -#endif // CZMQ_BUILD_DRAFT_API -// @ignore -CZMQ_EXPORT void - zproc_log_error (const char *format, ...) CHECK_PRINTF (1); -CZMQ_EXPORT void - zproc_log_warning (const char *format, ...) CHECK_PRINTF (1); -CZMQ_EXPORT void - zproc_log_notice (const char *format, ...) CHECK_PRINTF (1); -CZMQ_EXPORT void - zproc_log_info (const char *format, ...) CHECK_PRINTF (1); -CZMQ_EXPORT void - zproc_log_debug (const char *format, ...) CHECK_PRINTF (1); -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zproxy.h b/phonelibs/zmq/arm/include/zproxy.h deleted file mode 100644 index f672c5e72417a5..00000000000000 --- a/phonelibs/zmq/arm/include/zproxy.h +++ /dev/null @@ -1,111 +0,0 @@ -/* ========================================================================= - zproxy - run a steerable proxy in the background - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZPROXY_H_INCLUDED__ -#define __ZPROXY_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// Create new zproxy actor instance. The proxy switches messages between -// a frontend socket and a backend socket; use the FRONTEND and BACKEND -// commands to configure these: -// -// zactor_t *proxy = zactor_new (zproxy, NULL); -// -// Destroy zproxy instance. This destroys the two sockets and stops any -// message flow between them: -// -// zactor_destroy (&proxy); -// -// Note that all zproxy commands are synchronous, so your application always -// waits for a signal from the actor after each command. -// -// Enable verbose logging of commands and activity: -// -// zstr_send (proxy, "VERBOSE"); -// zsock_wait (proxy); -// -// Specify frontend socket type -- see zsock_type_str () -- and attach to -// endpoints, see zsock_attach (). Note that a proxy socket is always -// serverish: -// -// zstr_sendx (proxy, "FRONTEND", "XSUB", endpoints, NULL); -// zsock_wait (proxy); -// -// Specify backend socket type -- see zsock_type_str () -- and attach to -// endpoints, see zsock_attach (). Note that a proxy socket is always -// serverish: -// -// zstr_sendx (proxy, "BACKEND", "XPUB", endpoints, NULL); -// zsock_wait (proxy); -// -// Capture all proxied messages; these are delivered to the application -// via an inproc PULL socket that you have already bound to the specified -// endpoint: -// -// zstr_sendx (proxy, "CAPTURE", endpoint, NULL); -// zsock_wait (proxy); -// -// Pause the proxy. A paused proxy will cease processing messages, causing -// them to be queued up and potentially hit the high-water mark on the -// frontend or backend socket, causing messages to be dropped, or writing -// applications to block: -// -// zstr_sendx (proxy, "PAUSE", NULL); -// zsock_wait (proxy); -// -// Resume the proxy. Note that the proxy starts automatically as soon as it -// has a properly attached frontend and backend socket: -// -// zstr_sendx (proxy, "RESUME", NULL); -// zsock_wait (proxy); -// -// Configure an authentication domain for the "FRONTEND" or "BACKEND" proxy -// socket -- see zsock_set_zap_domain (). Call before binding socket: -// -// zstr_sendx (proxy, "DOMAIN", "FRONTEND", "global", NULL); -// zsock_wait (proxy); -// -// Configure PLAIN authentication for the "FRONTEND" or "BACKEND" proxy -// socket -- see zsock_set_plain_server (). Call before binding socket: -// -// zstr_sendx (proxy, "PLAIN", "BACKEND", NULL); -// zsock_wait (proxy); -// -// Configure CURVE authentication for the "FRONTEND" or "BACKEND" proxy -// socket -- see zsock_set_curve_server () -- specifying both the public and -// secret keys of a certificate as Z85 armored strings -- see -// zcert_public_txt () and zcert_secret_txt (). Call before binding socket: -// -// zstr_sendx (proxy, "CURVE", "FRONTEND", public_txt, secret_txt, NULL); -// zsock_wait (proxy); -// -// This is the zproxy constructor as a zactor_fn; the argument is a -// character string specifying frontend and backend socket types as two -// uppercase strings separated by a hyphen: -CZMQ_EXPORT void - zproxy (zsock_t *pipe, void *unused); - -// Selftest -CZMQ_EXPORT void - zproxy_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zproxy_v2.h b/phonelibs/zmq/arm/include/zproxy_v2.h deleted file mode 100644 index 4bde9515916935..00000000000000 --- a/phonelibs/zmq/arm/include/zproxy_v2.h +++ /dev/null @@ -1,62 +0,0 @@ -/* ========================================================================= - zproxy_v2 - run a steerable proxy in the background (deprecated) - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZPROXY_V2_H_INCLUDED__ -#define __ZPROXY_V2_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface - -// Constructor -// Create a new zproxy object. You must create the frontend and backend -// sockets, configure them, and connect or bind them, before you pass them -// to the constructor. Do NOT use the sockets again, after passing them to -// this method. -CZMQ_EXPORT zproxy_t * - zproxy_new (zctx_t *ctx, void *frontend, void *backend); - -// Destructor -// Destroy a zproxy object; note this first stops the proxy. -CZMQ_EXPORT void - zproxy_destroy (zproxy_t **self_p); - -// Copy all proxied messages to specified endpoint; if this is NULL, any -// in-progress capturing will be stopped. You must already have bound the -// endpoint to a PULL socket. -CZMQ_EXPORT void - zproxy_capture (zproxy_t *self, const char *endpoint); - -// Pauses a zproxy object; a paused proxy will cease processing messages, -// causing them to be queued up and potentially hit the high-water mark on -// the frontend socket, causing messages to be dropped, or writing -// applications to block. -CZMQ_EXPORT void - zproxy_pause (zproxy_t *self); - -// Resume a zproxy object -CZMQ_EXPORT void - zproxy_resume (zproxy_t *self); - -// Self test of this class -CZMQ_EXPORT void - zproxy_v2_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zrex.h b/phonelibs/zmq/arm/include/zrex.h deleted file mode 100644 index 8b50618a34837c..00000000000000 --- a/phonelibs/zmq/arm/include/zrex.h +++ /dev/null @@ -1,82 +0,0 @@ -/* ========================================================================= - zrex - work with regular expressions - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZREX_H_INCLUDED__ -#define __ZREX_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// Constructor. Optionally, sets an expression against which we can match -// text and capture hits. If there is an error in the expression, reports -// zrex_valid() as false and provides the error in zrex_strerror(). If you -// set a pattern, you can call zrex_matches() to test it against text. -CZMQ_EXPORT zrex_t * - zrex_new (const char *expression); - -// Destructor -CZMQ_EXPORT void - zrex_destroy (zrex_t **self_p); - -// Return true if the expression was valid and compiled without errors. -CZMQ_EXPORT bool - zrex_valid (zrex_t *self); - -// Return the error message generated during compilation of the expression. -CZMQ_EXPORT const char * - zrex_strerror (zrex_t *self); - -// Returns true if the text matches the previously compiled expression. -// Use this method to compare one expression against many strings. -CZMQ_EXPORT bool - zrex_matches (zrex_t *self, const char *text); - -// Returns true if the text matches the supplied expression. Use this -// method to compare one string against several expressions. -CZMQ_EXPORT bool - zrex_eq (zrex_t *self, const char *text, const char *expression); - -// Returns number of hits from last zrex_matches or zrex_eq. If the text -// matched, returns 1 plus the number of capture groups. If the text did -// not match, returns zero. To retrieve individual capture groups, call -// zrex_hit (). -CZMQ_EXPORT int - zrex_hits (zrex_t *self); - -// Returns the Nth capture group from the last expression match, where -// N is 0 to the value returned by zrex_hits(). Capture group 0 is the -// whole matching string. Sequence 1 is the first capture group, if any, -// and so on. -CZMQ_EXPORT const char * - zrex_hit (zrex_t *self, uint index); - -// Fetches hits into string variables provided by caller; this makes for -// nicer code than accessing hits by index. Caller should not modify nor -// free the returned values. Returns number of strings returned. This -// method starts at hit 1, i.e. first capture group, as hit 0 is always -// the original matched string. -CZMQ_EXPORT int - zrex_fetch (zrex_t *self, const char **string_p, ...); - -// Self test of this class -CZMQ_EXPORT void - zrex_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zsock.h b/phonelibs/zmq/arm/include/zsock.h deleted file mode 100644 index fc5c46e45e9810..00000000000000 --- a/phonelibs/zmq/arm/include/zsock.h +++ /dev/null @@ -1,921 +0,0 @@ -/* ========================================================================= - zsock - high-level socket API that hides libzmq contexts and sockets - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZSOCK_H_INCLUDED__ -#define __ZSOCK_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// This interface includes some smart constructors, which create sockets with -// additional set-up. In all of these, the endpoint is NULL, or starts with -// '@' (bind) or '>' (connect). Multiple endpoints are allowed, separated by -// commas. If endpoint does not start with '@' or '>', default action depends -// on socket type. - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zsock.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// Create a new socket. Returns the new socket, or NULL if the new socket -// could not be created. Note that the symbol zsock_new (and other -// constructors/destructors for zsock) are redirected to the *_checked -// variant, enabling intelligent socket leak detection. This can have -// performance implications if you use a LOT of sockets. To turn off this -// redirection behaviour, define ZSOCK_NOCHECK. -CZMQ_EXPORT zsock_t * - zsock_new (int type); - -// Create a PUB socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_pub (const char *endpoint); - -// Create a SUB socket, and optionally subscribe to some prefix string. Default -// action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_sub (const char *endpoint, const char *subscribe); - -// Create a REQ socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_req (const char *endpoint); - -// Create a REP socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_rep (const char *endpoint); - -// Create a DEALER socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_dealer (const char *endpoint); - -// Create a ROUTER socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_router (const char *endpoint); - -// Create a PUSH socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_push (const char *endpoint); - -// Create a PULL socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_pull (const char *endpoint); - -// Create an XPUB socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_xpub (const char *endpoint); - -// Create an XSUB socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_xsub (const char *endpoint); - -// Create a PAIR socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_pair (const char *endpoint); - -// Create a STREAM socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_stream (const char *endpoint); - -// Destroy the socket. You must use this for any socket created via the -// zsock_new method. -CZMQ_EXPORT void - zsock_destroy (zsock_t **self_p); - -// Bind a socket to a formatted endpoint. For tcp:// endpoints, supports -// ephemeral ports, if you specify the port number as "*". By default -// zsock uses the IANA designated range from C000 (49152) to FFFF (65535). -// To override this range, follow the "*" with "[first-last]". Either or -// both first and last may be empty. To bind to a random port within the -// range, use "!" in place of "*". -// -// Examples: -// tcp://127.0.0.1:* bind to first free port from C000 up -// tcp://127.0.0.1:! bind to random port from C000 to FFFF -// tcp://127.0.0.1:*[60000-] bind to first free port from 60000 up -// tcp://127.0.0.1:![-60000] bind to random port from C000 to 60000 -// tcp://127.0.0.1:![55000-55999] -// bind to random port from 55000 to 55999 -// -// On success, returns the actual port number used, for tcp:// endpoints, -// and 0 for other transports. On failure, returns -1. Note that when using -// ephemeral ports, a port may be reused by different services without -// clients being aware. Protocols that run on ephemeral ports should take -// this into account. -CZMQ_EXPORT int - zsock_bind (zsock_t *self, const char *format, ...); - -// Returns last bound endpoint, if any. -CZMQ_EXPORT const char * - zsock_endpoint (zsock_t *self); - -// Unbind a socket from a formatted endpoint. -// Returns 0 if OK, -1 if the endpoint was invalid or the function -// isn't supported. -CZMQ_EXPORT int - zsock_unbind (zsock_t *self, const char *format, ...); - -// Connect a socket to a formatted endpoint -// Returns 0 if OK, -1 if the endpoint was invalid. -CZMQ_EXPORT int - zsock_connect (zsock_t *self, const char *format, ...); - -// Disconnect a socket from a formatted endpoint -// Returns 0 if OK, -1 if the endpoint was invalid or the function -// isn't supported. -CZMQ_EXPORT int - zsock_disconnect (zsock_t *self, const char *format, ...); - -// Attach a socket to zero or more endpoints. If endpoints is not null, -// parses as list of ZeroMQ endpoints, separated by commas, and prefixed by -// '@' (to bind the socket) or '>' (to connect the socket). Returns 0 if all -// endpoints were valid, or -1 if there was a syntax error. If the endpoint -// does not start with '@' or '>', the serverish argument defines whether -// it is used to bind (serverish = true) or connect (serverish = false). -CZMQ_EXPORT int - zsock_attach (zsock_t *self, const char *endpoints, bool serverish); - -// Returns socket type as printable constant string. -CZMQ_EXPORT const char * - zsock_type_str (zsock_t *self); - -// Send a 'picture' message to the socket (or actor). The picture is a -// string that defines the type of each frame. This makes it easy to send -// a complex multiframe message in one call. The picture can contain any -// of these characters, each corresponding to one or two arguments: -// -// i = int (signed) -// 1 = uint8_t -// 2 = uint16_t -// 4 = uint32_t -// 8 = uint64_t -// s = char * -// b = byte *, size_t (2 arguments) -// c = zchunk_t * -// f = zframe_t * -// h = zhashx_t * -// U = zuuid_t * -// p = void * (sends the pointer value, only meaningful over inproc) -// m = zmsg_t * (sends all frames in the zmsg) -// z = sends zero-sized frame (0 arguments) -// u = uint (deprecated) -// -// Note that s, b, c, and f are encoded the same way and the choice is -// offered as a convenience to the sender, which may or may not already -// have data in a zchunk or zframe. Does not change or take ownership of -// any arguments. Returns 0 if successful, -1 if sending failed for any -// reason. -CZMQ_EXPORT int - zsock_send (void *self, const char *picture, ...); - -// Send a 'picture' message to the socket (or actor). This is a va_list -// version of zsock_send (), so please consult its documentation for the -// details. -CZMQ_EXPORT int - zsock_vsend (void *self, const char *picture, va_list argptr); - -// Receive a 'picture' message to the socket (or actor). See zsock_send for -// the format and meaning of the picture. Returns the picture elements into -// a series of pointers as provided by the caller: -// -// i = int * (stores signed integer) -// 4 = uint32_t * (stores 32-bit unsigned integer) -// 8 = uint64_t * (stores 64-bit unsigned integer) -// s = char ** (allocates new string) -// b = byte **, size_t * (2 arguments) (allocates memory) -// c = zchunk_t ** (creates zchunk) -// f = zframe_t ** (creates zframe) -// U = zuuid_t * (creates a zuuid with the data) -// h = zhashx_t ** (creates zhashx) -// p = void ** (stores pointer) -// m = zmsg_t ** (creates a zmsg with the remaing frames) -// z = null, asserts empty frame (0 arguments) -// u = uint * (stores unsigned integer, deprecated) -// -// Note that zsock_recv creates the returned objects, and the caller must -// destroy them when finished with them. The supplied pointers do not need -// to be initialized. Returns 0 if successful, or -1 if it failed to recv -// a message, in which case the pointers are not modified. When message -// frames are truncated (a short message), sets return values to zero/null. -// If an argument pointer is NULL, does not store any value (skips it). -// An 'n' picture matches an empty frame; if the message does not match, -// the method will return -1. -CZMQ_EXPORT int - zsock_recv (void *self, const char *picture, ...); - -// Receive a 'picture' message from the socket (or actor). This is a -// va_list version of zsock_recv (), so please consult its documentation -// for the details. -CZMQ_EXPORT int - zsock_vrecv (void *self, const char *picture, va_list argptr); - -// Send a binary encoded 'picture' message to the socket (or actor). This -// method is similar to zsock_send, except the arguments are encoded in a -// binary format that is compatible with zproto, and is designed to reduce -// memory allocations. The pattern argument is a string that defines the -// type of each argument. Supports these argument types: -// -// pattern C type zproto type: -// 1 uint8_t type = "number" size = "1" -// 2 uint16_t type = "number" size = "2" -// 4 uint32_t type = "number" size = "3" -// 8 uint64_t type = "number" size = "4" -// s char *, 0-255 chars type = "string" -// S char *, 0-2^32-1 chars type = "longstr" -// c zchunk_t * type = "chunk" -// f zframe_t * type = "frame" -// u zuuid_t * type = "uuid" -// m zmsg_t * type = "msg" -// p void *, sends pointer value, only over inproc -// -// Does not change or take ownership of any arguments. Returns 0 if -// successful, -1 if sending failed for any reason. -CZMQ_EXPORT int - zsock_bsend (void *self, const char *picture, ...); - -// Receive a binary encoded 'picture' message from the socket (or actor). -// This method is similar to zsock_recv, except the arguments are encoded -// in a binary format that is compatible with zproto, and is designed to -// reduce memory allocations. The pattern argument is a string that defines -// the type of each argument. See zsock_bsend for the supported argument -// types. All arguments must be pointers; this call sets them to point to -// values held on a per-socket basis. -// Note that zsock_brecv creates the returned objects, and the caller must -// destroy them when finished with them. The supplied pointers do not need -// to be initialized. Returns 0 if successful, or -1 if it failed to read -// a message. -CZMQ_EXPORT int - zsock_brecv (void *self, const char *picture, ...); - -// Set socket to use unbounded pipes (HWM=0); use this in cases when you are -// totally certain the message volume can fit in memory. This method works -// across all versions of ZeroMQ. Takes a polymorphic socket reference. -CZMQ_EXPORT void - zsock_set_unbounded (void *self); - -// Send a signal over a socket. A signal is a short message carrying a -// success/failure code (by convention, 0 means OK). Signals are encoded -// to be distinguishable from "normal" messages. Accepts a zsock_t or a -// zactor_t argument, and returns 0 if successful, -1 if the signal could -// not be sent. Takes a polymorphic socket reference. -CZMQ_EXPORT int - zsock_signal (void *self, byte status); - -// Wait on a signal. Use this to coordinate between threads, over pipe -// pairs. Blocks until the signal is received. Returns -1 on error, 0 or -// greater on success. Accepts a zsock_t or a zactor_t as argument. -// Takes a polymorphic socket reference. -CZMQ_EXPORT int - zsock_wait (void *self); - -// If there is a partial message still waiting on the socket, remove and -// discard it. This is useful when reading partial messages, to get specific -// message types. -CZMQ_EXPORT void - zsock_flush (void *self); - -// Probe the supplied object, and report if it looks like a zsock_t. -// Takes a polymorphic socket reference. -CZMQ_EXPORT bool - zsock_is (void *self); - -// Probe the supplied reference. If it looks like a zsock_t instance, return -// the underlying libzmq socket handle; else if it looks like a file -// descriptor, return NULL; else if it looks like a libzmq socket handle, -// return the supplied value. Takes a polymorphic socket reference. -CZMQ_EXPORT void * - zsock_resolve (void *self); - -// Get socket option `tos`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_tos (void *self); - -// Set socket option `tos`. -CZMQ_EXPORT void - zsock_set_tos (void *self, int tos); - -// Set socket option `router_handover`. -CZMQ_EXPORT void - zsock_set_router_handover (void *self, int router_handover); - -// Set socket option `router_mandatory`. -CZMQ_EXPORT void - zsock_set_router_mandatory (void *self, int router_mandatory); - -// Set socket option `probe_router`. -CZMQ_EXPORT void - zsock_set_probe_router (void *self, int probe_router); - -// Set socket option `req_relaxed`. -CZMQ_EXPORT void - zsock_set_req_relaxed (void *self, int req_relaxed); - -// Set socket option `req_correlate`. -CZMQ_EXPORT void - zsock_set_req_correlate (void *self, int req_correlate); - -// Set socket option `conflate`. -CZMQ_EXPORT void - zsock_set_conflate (void *self, int conflate); - -// Get socket option `zap_domain`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_zap_domain (void *self); - -// Set socket option `zap_domain`. -CZMQ_EXPORT void - zsock_set_zap_domain (void *self, const char *zap_domain); - -// Get socket option `mechanism`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_mechanism (void *self); - -// Get socket option `plain_server`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_plain_server (void *self); - -// Set socket option `plain_server`. -CZMQ_EXPORT void - zsock_set_plain_server (void *self, int plain_server); - -// Get socket option `plain_username`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_plain_username (void *self); - -// Set socket option `plain_username`. -CZMQ_EXPORT void - zsock_set_plain_username (void *self, const char *plain_username); - -// Get socket option `plain_password`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_plain_password (void *self); - -// Set socket option `plain_password`. -CZMQ_EXPORT void - zsock_set_plain_password (void *self, const char *plain_password); - -// Get socket option `curve_server`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_curve_server (void *self); - -// Set socket option `curve_server`. -CZMQ_EXPORT void - zsock_set_curve_server (void *self, int curve_server); - -// Get socket option `curve_publickey`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_curve_publickey (void *self); - -// Set socket option `curve_publickey`. -CZMQ_EXPORT void - zsock_set_curve_publickey (void *self, const char *curve_publickey); - -// Set socket option `curve_publickey` from 32-octet binary -CZMQ_EXPORT void - zsock_set_curve_publickey_bin (void *self, const byte *curve_publickey); - -// Get socket option `curve_secretkey`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_curve_secretkey (void *self); - -// Set socket option `curve_secretkey`. -CZMQ_EXPORT void - zsock_set_curve_secretkey (void *self, const char *curve_secretkey); - -// Set socket option `curve_secretkey` from 32-octet binary -CZMQ_EXPORT void - zsock_set_curve_secretkey_bin (void *self, const byte *curve_secretkey); - -// Get socket option `curve_serverkey`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_curve_serverkey (void *self); - -// Set socket option `curve_serverkey`. -CZMQ_EXPORT void - zsock_set_curve_serverkey (void *self, const char *curve_serverkey); - -// Set socket option `curve_serverkey` from 32-octet binary -CZMQ_EXPORT void - zsock_set_curve_serverkey_bin (void *self, const byte *curve_serverkey); - -// Get socket option `gssapi_server`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_gssapi_server (void *self); - -// Set socket option `gssapi_server`. -CZMQ_EXPORT void - zsock_set_gssapi_server (void *self, int gssapi_server); - -// Get socket option `gssapi_plaintext`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_gssapi_plaintext (void *self); - -// Set socket option `gssapi_plaintext`. -CZMQ_EXPORT void - zsock_set_gssapi_plaintext (void *self, int gssapi_plaintext); - -// Get socket option `gssapi_principal`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_gssapi_principal (void *self); - -// Set socket option `gssapi_principal`. -CZMQ_EXPORT void - zsock_set_gssapi_principal (void *self, const char *gssapi_principal); - -// Get socket option `gssapi_service_principal`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_gssapi_service_principal (void *self); - -// Set socket option `gssapi_service_principal`. -CZMQ_EXPORT void - zsock_set_gssapi_service_principal (void *self, const char *gssapi_service_principal); - -// Get socket option `ipv6`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_ipv6 (void *self); - -// Set socket option `ipv6`. -CZMQ_EXPORT void - zsock_set_ipv6 (void *self, int ipv6); - -// Get socket option `immediate`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_immediate (void *self); - -// Set socket option `immediate`. -CZMQ_EXPORT void - zsock_set_immediate (void *self, int immediate); - -// Set socket option `router_raw`. -CZMQ_EXPORT void - zsock_set_router_raw (void *self, int router_raw); - -// Get socket option `ipv4only`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_ipv4only (void *self); - -// Set socket option `ipv4only`. -CZMQ_EXPORT void - zsock_set_ipv4only (void *self, int ipv4only); - -// Set socket option `delay_attach_on_connect`. -CZMQ_EXPORT void - zsock_set_delay_attach_on_connect (void *self, int delay_attach_on_connect); - -// Get socket option `type`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_type (void *self); - -// Get socket option `sndhwm`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_sndhwm (void *self); - -// Set socket option `sndhwm`. -CZMQ_EXPORT void - zsock_set_sndhwm (void *self, int sndhwm); - -// Get socket option `rcvhwm`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_rcvhwm (void *self); - -// Set socket option `rcvhwm`. -CZMQ_EXPORT void - zsock_set_rcvhwm (void *self, int rcvhwm); - -// Get socket option `affinity`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_affinity (void *self); - -// Set socket option `affinity`. -CZMQ_EXPORT void - zsock_set_affinity (void *self, int affinity); - -// Set socket option `subscribe`. -CZMQ_EXPORT void - zsock_set_subscribe (void *self, const char *subscribe); - -// Set socket option `unsubscribe`. -CZMQ_EXPORT void - zsock_set_unsubscribe (void *self, const char *unsubscribe); - -// Get socket option `identity`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_identity (void *self); - -// Set socket option `identity`. -CZMQ_EXPORT void - zsock_set_identity (void *self, const char *identity); - -// Get socket option `rate`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_rate (void *self); - -// Set socket option `rate`. -CZMQ_EXPORT void - zsock_set_rate (void *self, int rate); - -// Get socket option `recovery_ivl`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_recovery_ivl (void *self); - -// Set socket option `recovery_ivl`. -CZMQ_EXPORT void - zsock_set_recovery_ivl (void *self, int recovery_ivl); - -// Get socket option `sndbuf`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_sndbuf (void *self); - -// Set socket option `sndbuf`. -CZMQ_EXPORT void - zsock_set_sndbuf (void *self, int sndbuf); - -// Get socket option `rcvbuf`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_rcvbuf (void *self); - -// Set socket option `rcvbuf`. -CZMQ_EXPORT void - zsock_set_rcvbuf (void *self, int rcvbuf); - -// Get socket option `linger`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_linger (void *self); - -// Set socket option `linger`. -CZMQ_EXPORT void - zsock_set_linger (void *self, int linger); - -// Get socket option `reconnect_ivl`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_reconnect_ivl (void *self); - -// Set socket option `reconnect_ivl`. -CZMQ_EXPORT void - zsock_set_reconnect_ivl (void *self, int reconnect_ivl); - -// Get socket option `reconnect_ivl_max`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_reconnect_ivl_max (void *self); - -// Set socket option `reconnect_ivl_max`. -CZMQ_EXPORT void - zsock_set_reconnect_ivl_max (void *self, int reconnect_ivl_max); - -// Get socket option `backlog`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_backlog (void *self); - -// Set socket option `backlog`. -CZMQ_EXPORT void - zsock_set_backlog (void *self, int backlog); - -// Get socket option `maxmsgsize`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_maxmsgsize (void *self); - -// Set socket option `maxmsgsize`. -CZMQ_EXPORT void - zsock_set_maxmsgsize (void *self, int maxmsgsize); - -// Get socket option `multicast_hops`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_multicast_hops (void *self); - -// Set socket option `multicast_hops`. -CZMQ_EXPORT void - zsock_set_multicast_hops (void *self, int multicast_hops); - -// Get socket option `rcvtimeo`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_rcvtimeo (void *self); - -// Set socket option `rcvtimeo`. -CZMQ_EXPORT void - zsock_set_rcvtimeo (void *self, int rcvtimeo); - -// Get socket option `sndtimeo`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_sndtimeo (void *self); - -// Set socket option `sndtimeo`. -CZMQ_EXPORT void - zsock_set_sndtimeo (void *self, int sndtimeo); - -// Set socket option `xpub_verbose`. -CZMQ_EXPORT void - zsock_set_xpub_verbose (void *self, int xpub_verbose); - -// Get socket option `tcp_keepalive`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_tcp_keepalive (void *self); - -// Set socket option `tcp_keepalive`. -CZMQ_EXPORT void - zsock_set_tcp_keepalive (void *self, int tcp_keepalive); - -// Get socket option `tcp_keepalive_idle`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_tcp_keepalive_idle (void *self); - -// Set socket option `tcp_keepalive_idle`. -CZMQ_EXPORT void - zsock_set_tcp_keepalive_idle (void *self, int tcp_keepalive_idle); - -// Get socket option `tcp_keepalive_cnt`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_tcp_keepalive_cnt (void *self); - -// Set socket option `tcp_keepalive_cnt`. -CZMQ_EXPORT void - zsock_set_tcp_keepalive_cnt (void *self, int tcp_keepalive_cnt); - -// Get socket option `tcp_keepalive_intvl`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_tcp_keepalive_intvl (void *self); - -// Set socket option `tcp_keepalive_intvl`. -CZMQ_EXPORT void - zsock_set_tcp_keepalive_intvl (void *self, int tcp_keepalive_intvl); - -// Get socket option `tcp_accept_filter`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_tcp_accept_filter (void *self); - -// Set socket option `tcp_accept_filter`. -CZMQ_EXPORT void - zsock_set_tcp_accept_filter (void *self, const char *tcp_accept_filter); - -// Get socket option `rcvmore`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_rcvmore (void *self); - -// Get socket option `fd`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT SOCKET - zsock_fd (void *self); - -// Get socket option `events`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_events (void *self); - -// Get socket option `last_endpoint`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zsock_last_endpoint (void *self); - -// Self test of this class. -CZMQ_EXPORT void - zsock_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Create a SERVER socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_server (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Create a CLIENT socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_client (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Create a RADIO socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_radio (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Create a DISH socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_dish (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Create a GATHER socket. Default action is bind. -CZMQ_EXPORT zsock_t * - zsock_new_gather (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Create a SCATTER socket. Default action is connect. -CZMQ_EXPORT zsock_t * - zsock_new_scatter (const char *endpoint); - -// *** Draft method, for development use, may change without warning *** -// Return socket routing ID if any. This returns 0 if the socket is not -// of type ZMQ_SERVER or if no request was already received on it. -CZMQ_EXPORT uint32_t - zsock_routing_id (zsock_t *self); - -// *** Draft method, for development use, may change without warning *** -// Set routing ID on socket. The socket MUST be of type ZMQ_SERVER. -// This will be used when sending messages on the socket via the zsock API. -CZMQ_EXPORT void - zsock_set_routing_id (zsock_t *self, uint32_t routing_id); - -// *** Draft method, for development use, may change without warning *** -// Join a group for the RADIO-DISH pattern. Call only on ZMQ_DISH. -// Returns 0 if OK, -1 if failed. -CZMQ_EXPORT int - zsock_join (void *self, const char *group); - -// *** Draft method, for development use, may change without warning *** -// Leave a group for the RADIO-DISH pattern. Call only on ZMQ_DISH. -// Returns 0 if OK, -1 if failed. -CZMQ_EXPORT int - zsock_leave (void *self, const char *group); - -// *** Draft method, for development use, may change without warning *** -// Get socket option `heartbeat_ivl`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_heartbeat_ivl (void *self); - -// *** Draft method, for development use, may change without warning *** -// Set socket option `heartbeat_ivl`. -CZMQ_EXPORT void - zsock_set_heartbeat_ivl (void *self, int heartbeat_ivl); - -// *** Draft method, for development use, may change without warning *** -// Get socket option `heartbeat_ttl`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_heartbeat_ttl (void *self); - -// *** Draft method, for development use, may change without warning *** -// Set socket option `heartbeat_ttl`. -CZMQ_EXPORT void - zsock_set_heartbeat_ttl (void *self, int heartbeat_ttl); - -// *** Draft method, for development use, may change without warning *** -// Get socket option `heartbeat_timeout`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_heartbeat_timeout (void *self); - -// *** Draft method, for development use, may change without warning *** -// Set socket option `heartbeat_timeout`. -CZMQ_EXPORT void - zsock_set_heartbeat_timeout (void *self, int heartbeat_timeout); - -// *** Draft method, for development use, may change without warning *** -// Get socket option `use_fd`. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT int - zsock_use_fd (void *self); - -// *** Draft method, for development use, may change without warning *** -// Set socket option `use_fd`. -CZMQ_EXPORT void - zsock_set_use_fd (void *self, int use_fd); - -#endif // CZMQ_BUILD_DRAFT_API -// @ignore -CZMQ_EXPORT int - zsock_bind (zsock_t *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int - zsock_unbind (zsock_t *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int - zsock_connect (zsock_t *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int - zsock_disconnect (zsock_t *self, const char *format, ...) CHECK_PRINTF (2); -// @end - - -// zsock leak detection - not a part of the official interface to zsock. This -// enables CZMQ to report socket leaks intelligently. -#if defined ZSOCK_NOCHECK - // no checking active - use the above interface methods directly. -#else -# define zsock_new(t) zsock_new_checked((t), __FILE__, __LINE__) -# define zsock_new_pub(e) zsock_new_pub_checked((e), __FILE__, __LINE__) -# define zsock_new_sub(e,s) zsock_new_sub_checked((e), (s), __FILE__, __LINE__) -# define zsock_new_req(e) zsock_new_req_checked((e), __FILE__, __LINE__) -# define zsock_new_rep(e) zsock_new_rep_checked((e), __FILE__, __LINE__) -# define zsock_new_dealer(e) zsock_new_dealer_checked((e), __FILE__, __LINE__) -# define zsock_new_router(e) zsock_new_router_checked((e), __FILE__, __LINE__) -# define zsock_new_pull(e) zsock_new_pull_checked((e), __FILE__, __LINE__) -# define zsock_new_push(e) zsock_new_push_checked((e), __FILE__, __LINE__) -# define zsock_new_xpub(e) zsock_new_xpub_checked((e), __FILE__, __LINE__) -# define zsock_new_xsub(e) zsock_new_xsub_checked((e), __FILE__, __LINE__) -# define zsock_new_pair(e) zsock_new_pair_checked((e), __FILE__, __LINE__) -# define zsock_new_stream(e) zsock_new_stream_checked((e), __FILE__, __LINE__) -# define zsock_destroy(t) zsock_destroy_checked((t), __FILE__, __LINE__) -#endif - -CZMQ_EXPORT zsock_t * - zsock_new_checked (int type, const char *filename, size_t line_nbr); - -CZMQ_EXPORT void - zsock_destroy_checked (zsock_t **self_p, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_pub_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_sub_checked (const char *endpoint, const char *subscribe, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_req_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_rep_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_dealer_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_router_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_push_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_pull_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_xpub_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_xsub_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_pair_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_stream_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_server_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_client_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_radio_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_dish_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_gather_checked (const char *endpoint, const char *filename, size_t line_nbr); - -CZMQ_EXPORT zsock_t * - zsock_new_scatter_checked (const char *endpoint, const char *filename, size_t line_nbr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zsocket.h b/phonelibs/zmq/arm/include/zsocket.h deleted file mode 100644 index a60a0d9db3e7da..00000000000000 --- a/phonelibs/zmq/arm/include/zsocket.h +++ /dev/null @@ -1,110 +0,0 @@ -/* ========================================================================= - zsocket - working with 0MQ sockets - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZSOCKET_H_INCLUDED__ -#define __ZSOCKET_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// This port range is defined by IANA for dynamic or private ports -// We use this when choosing a port for dynamic binding. -#define ZSOCKET_DYNFROM 0xc000 -#define ZSOCKET_DYNTO 0xffff - -// Callback function for zero-copy methods -typedef void (zsocket_free_fn) (void *data, void *arg); - -// Create a new socket within our CZMQ context, replaces zmq_socket. -// Use this to get automatic management of the socket at shutdown. -// Note: SUB sockets do not automatically subscribe to everything; you -// must set filters explicitly. -CZMQ_EXPORT void * - zsocket_new (zctx_t *self, int type); - -// Destroy a socket within our CZMQ context, replaces zmq_close. -CZMQ_EXPORT void - zsocket_destroy (zctx_t *ctx, void *self); - -// Bind a socket to a formatted endpoint. If the port is specified as -// '*', binds to any free port from ZSOCKET_DYNFROM to ZSOCKET_DYNTO -// and returns the actual port number used. Otherwise asserts that the -// bind succeeded with the specified port number. Always returns the -// port number if successful. -CZMQ_EXPORT int - zsocket_bind (void *self, const char *format, ...); - -// Unbind a socket from a formatted endpoint. -// Returns 0 if OK, -1 if the endpoint was invalid or the function -// isn't supported. -CZMQ_EXPORT int - zsocket_unbind (void *self, const char *format, ...); - -// Connect a socket to a formatted endpoint -// Returns 0 if OK, -1 if the endpoint was invalid. -CZMQ_EXPORT int - zsocket_connect (void *self, const char *format, ...); - -// Disconnect a socket from a formatted endpoint -// Returns 0 if OK, -1 if the endpoint was invalid or the function -// isn't supported. -CZMQ_EXPORT int - zsocket_disconnect (void *self, const char *format, ...); - -// Poll for input events on the socket. Returns TRUE if there is input -// ready on the socket, else FALSE. -CZMQ_EXPORT bool - zsocket_poll (void *self, int msecs); - -// Returns socket type as printable constant string -CZMQ_EXPORT const char * - zsocket_type_str (void *self); - -// Send data over a socket as a single message frame. -// Accepts these flags: ZFRAME_MORE and ZFRAME_DONTWAIT. -// Returns -1 on error, 0 on success -CZMQ_EXPORT int - zsocket_sendmem (void *self, const void *data, size_t size, int flags); - -// Send a signal over a socket. A signal is a zero-byte message. -// Signals are used primarily between threads, over pipe sockets. -// Returns -1 if there was an error sending the signal. -CZMQ_EXPORT int - zsocket_signal (void *self); - -// Wait on a signal. Use this to coordinate between threads, over -// pipe pairs. Returns -1 on error, 0 on success. -CZMQ_EXPORT int - zsocket_wait (void *self); - -// Self test of this class -CZMQ_EXPORT void - zsocket_test (bool verbose); -// @end - -// Compiler hints -CZMQ_EXPORT int zsocket_bind (void *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int zsocket_unbind (void *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int zsocket_connect (void *self, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int zsocket_disconnect (void *self, const char *format, ...) CHECK_PRINTF (2); - -// Emulation of widely-used 2.x socket options -CZMQ_EXPORT void zsocket_set_hwm (void *self, int hwm); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zsockopt.h b/phonelibs/zmq/arm/include/zsockopt.h deleted file mode 100644 index 5246986dd0b367..00000000000000 --- a/phonelibs/zmq/arm/include/zsockopt.h +++ /dev/null @@ -1,256 +0,0 @@ -/* ========================================================================= - zsockopt - get/set 0MQ socket options (deprecated) - - **************************************************** - * GENERATED SOURCE CODE, DO NOT EDIT!! * - * TO CHANGE THIS, EDIT src/zsockopt.gsl * - * AND RUN `gsl sockopts` in src/. * - **************************************************** - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZSOCKOPT_H_INCLUDED__ -#define __ZSOCKOPT_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -#if (ZMQ_VERSION_MAJOR == 4) -// Get socket options -CZMQ_EXPORT int zsocket_heartbeat_ivl (void *zocket); -CZMQ_EXPORT int zsocket_heartbeat_ttl (void *zocket); -CZMQ_EXPORT int zsocket_heartbeat_timeout (void *zocket); -CZMQ_EXPORT int zsocket_use_fd (void *zocket); -CZMQ_EXPORT int zsocket_tos (void *zocket); -CZMQ_EXPORT char * zsocket_zap_domain (void *zocket); -CZMQ_EXPORT int zsocket_mechanism (void *zocket); -CZMQ_EXPORT int zsocket_plain_server (void *zocket); -CZMQ_EXPORT char * zsocket_plain_username (void *zocket); -CZMQ_EXPORT char * zsocket_plain_password (void *zocket); -CZMQ_EXPORT int zsocket_curve_server (void *zocket); -CZMQ_EXPORT char * zsocket_curve_publickey (void *zocket); -CZMQ_EXPORT char * zsocket_curve_secretkey (void *zocket); -CZMQ_EXPORT char * zsocket_curve_serverkey (void *zocket); -CZMQ_EXPORT int zsocket_gssapi_server (void *zocket); -CZMQ_EXPORT int zsocket_gssapi_plaintext (void *zocket); -CZMQ_EXPORT char * zsocket_gssapi_principal (void *zocket); -CZMQ_EXPORT char * zsocket_gssapi_service_principal (void *zocket); -CZMQ_EXPORT int zsocket_ipv6 (void *zocket); -CZMQ_EXPORT int zsocket_immediate (void *zocket); -CZMQ_EXPORT int zsocket_ipv4only (void *zocket); -CZMQ_EXPORT int zsocket_type (void *zocket); -CZMQ_EXPORT int zsocket_sndhwm (void *zocket); -CZMQ_EXPORT int zsocket_rcvhwm (void *zocket); -CZMQ_EXPORT int zsocket_affinity (void *zocket); -CZMQ_EXPORT char * zsocket_identity (void *zocket); -CZMQ_EXPORT int zsocket_rate (void *zocket); -CZMQ_EXPORT int zsocket_recovery_ivl (void *zocket); -CZMQ_EXPORT int zsocket_sndbuf (void *zocket); -CZMQ_EXPORT int zsocket_rcvbuf (void *zocket); -CZMQ_EXPORT int zsocket_linger (void *zocket); -CZMQ_EXPORT int zsocket_reconnect_ivl (void *zocket); -CZMQ_EXPORT int zsocket_reconnect_ivl_max (void *zocket); -CZMQ_EXPORT int zsocket_backlog (void *zocket); -CZMQ_EXPORT int zsocket_maxmsgsize (void *zocket); -CZMQ_EXPORT int zsocket_multicast_hops (void *zocket); -CZMQ_EXPORT int zsocket_rcvtimeo (void *zocket); -CZMQ_EXPORT int zsocket_sndtimeo (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive_idle (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive_cnt (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive_intvl (void *zocket); -CZMQ_EXPORT char * zsocket_tcp_accept_filter (void *zocket); -CZMQ_EXPORT int zsocket_rcvmore (void *zocket); -CZMQ_EXPORT SOCKET zsocket_fd (void *zocket); -CZMQ_EXPORT int zsocket_events (void *zocket); -CZMQ_EXPORT char * zsocket_last_endpoint (void *zocket); - -// Set socket options -CZMQ_EXPORT void zsocket_set_heartbeat_ivl (void *zocket, int heartbeat_ivl); -CZMQ_EXPORT void zsocket_set_heartbeat_ttl (void *zocket, int heartbeat_ttl); -CZMQ_EXPORT void zsocket_set_heartbeat_timeout (void *zocket, int heartbeat_timeout); -CZMQ_EXPORT void zsocket_set_use_fd (void *zocket, int use_fd); -CZMQ_EXPORT void zsocket_set_tos (void *zocket, int tos); -CZMQ_EXPORT void zsocket_set_router_handover (void *zocket, int router_handover); -CZMQ_EXPORT void zsocket_set_router_mandatory (void *zocket, int router_mandatory); -CZMQ_EXPORT void zsocket_set_probe_router (void *zocket, int probe_router); -CZMQ_EXPORT void zsocket_set_req_relaxed (void *zocket, int req_relaxed); -CZMQ_EXPORT void zsocket_set_req_correlate (void *zocket, int req_correlate); -CZMQ_EXPORT void zsocket_set_conflate (void *zocket, int conflate); -CZMQ_EXPORT void zsocket_set_zap_domain (void *zocket, const char * zap_domain); -CZMQ_EXPORT void zsocket_set_plain_server (void *zocket, int plain_server); -CZMQ_EXPORT void zsocket_set_plain_username (void *zocket, const char * plain_username); -CZMQ_EXPORT void zsocket_set_plain_password (void *zocket, const char * plain_password); -CZMQ_EXPORT void zsocket_set_curve_server (void *zocket, int curve_server); -CZMQ_EXPORT void zsocket_set_curve_publickey (void *zocket, const char * curve_publickey); -CZMQ_EXPORT void zsocket_set_curve_publickey_bin (void *zocket, const byte *curve_publickey); -CZMQ_EXPORT void zsocket_set_curve_secretkey (void *zocket, const char * curve_secretkey); -CZMQ_EXPORT void zsocket_set_curve_secretkey_bin (void *zocket, const byte *curve_secretkey); -CZMQ_EXPORT void zsocket_set_curve_serverkey (void *zocket, const char * curve_serverkey); -CZMQ_EXPORT void zsocket_set_curve_serverkey_bin (void *zocket, const byte *curve_serverkey); -CZMQ_EXPORT void zsocket_set_gssapi_server (void *zocket, int gssapi_server); -CZMQ_EXPORT void zsocket_set_gssapi_plaintext (void *zocket, int gssapi_plaintext); -CZMQ_EXPORT void zsocket_set_gssapi_principal (void *zocket, const char * gssapi_principal); -CZMQ_EXPORT void zsocket_set_gssapi_service_principal (void *zocket, const char * gssapi_service_principal); -CZMQ_EXPORT void zsocket_set_ipv6 (void *zocket, int ipv6); -CZMQ_EXPORT void zsocket_set_immediate (void *zocket, int immediate); -CZMQ_EXPORT void zsocket_set_router_raw (void *zocket, int router_raw); -CZMQ_EXPORT void zsocket_set_ipv4only (void *zocket, int ipv4only); -CZMQ_EXPORT void zsocket_set_delay_attach_on_connect (void *zocket, int delay_attach_on_connect); -CZMQ_EXPORT void zsocket_set_sndhwm (void *zocket, int sndhwm); -CZMQ_EXPORT void zsocket_set_rcvhwm (void *zocket, int rcvhwm); -CZMQ_EXPORT void zsocket_set_affinity (void *zocket, int affinity); -CZMQ_EXPORT void zsocket_set_subscribe (void *zocket, const char * subscribe); -CZMQ_EXPORT void zsocket_set_unsubscribe (void *zocket, const char * unsubscribe); -CZMQ_EXPORT void zsocket_set_identity (void *zocket, const char * identity); -CZMQ_EXPORT void zsocket_set_rate (void *zocket, int rate); -CZMQ_EXPORT void zsocket_set_recovery_ivl (void *zocket, int recovery_ivl); -CZMQ_EXPORT void zsocket_set_sndbuf (void *zocket, int sndbuf); -CZMQ_EXPORT void zsocket_set_rcvbuf (void *zocket, int rcvbuf); -CZMQ_EXPORT void zsocket_set_linger (void *zocket, int linger); -CZMQ_EXPORT void zsocket_set_reconnect_ivl (void *zocket, int reconnect_ivl); -CZMQ_EXPORT void zsocket_set_reconnect_ivl_max (void *zocket, int reconnect_ivl_max); -CZMQ_EXPORT void zsocket_set_backlog (void *zocket, int backlog); -CZMQ_EXPORT void zsocket_set_maxmsgsize (void *zocket, int maxmsgsize); -CZMQ_EXPORT void zsocket_set_multicast_hops (void *zocket, int multicast_hops); -CZMQ_EXPORT void zsocket_set_rcvtimeo (void *zocket, int rcvtimeo); -CZMQ_EXPORT void zsocket_set_sndtimeo (void *zocket, int sndtimeo); -CZMQ_EXPORT void zsocket_set_xpub_verbose (void *zocket, int xpub_verbose); -CZMQ_EXPORT void zsocket_set_tcp_keepalive (void *zocket, int tcp_keepalive); -CZMQ_EXPORT void zsocket_set_tcp_keepalive_idle (void *zocket, int tcp_keepalive_idle); -CZMQ_EXPORT void zsocket_set_tcp_keepalive_cnt (void *zocket, int tcp_keepalive_cnt); -CZMQ_EXPORT void zsocket_set_tcp_keepalive_intvl (void *zocket, int tcp_keepalive_intvl); -CZMQ_EXPORT void zsocket_set_tcp_accept_filter (void *zocket, const char * tcp_accept_filter); -#endif - -#if (ZMQ_VERSION_MAJOR == 3) -// Get socket options -CZMQ_EXPORT int zsocket_ipv4only (void *zocket); -CZMQ_EXPORT int zsocket_type (void *zocket); -CZMQ_EXPORT int zsocket_sndhwm (void *zocket); -CZMQ_EXPORT int zsocket_rcvhwm (void *zocket); -CZMQ_EXPORT int zsocket_affinity (void *zocket); -CZMQ_EXPORT char * zsocket_identity (void *zocket); -CZMQ_EXPORT int zsocket_rate (void *zocket); -CZMQ_EXPORT int zsocket_recovery_ivl (void *zocket); -CZMQ_EXPORT int zsocket_sndbuf (void *zocket); -CZMQ_EXPORT int zsocket_rcvbuf (void *zocket); -CZMQ_EXPORT int zsocket_linger (void *zocket); -CZMQ_EXPORT int zsocket_reconnect_ivl (void *zocket); -CZMQ_EXPORT int zsocket_reconnect_ivl_max (void *zocket); -CZMQ_EXPORT int zsocket_backlog (void *zocket); -CZMQ_EXPORT int zsocket_maxmsgsize (void *zocket); -CZMQ_EXPORT int zsocket_multicast_hops (void *zocket); -CZMQ_EXPORT int zsocket_rcvtimeo (void *zocket); -CZMQ_EXPORT int zsocket_sndtimeo (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive_idle (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive_cnt (void *zocket); -CZMQ_EXPORT int zsocket_tcp_keepalive_intvl (void *zocket); -CZMQ_EXPORT char * zsocket_tcp_accept_filter (void *zocket); -CZMQ_EXPORT int zsocket_rcvmore (void *zocket); -CZMQ_EXPORT SOCKET zsocket_fd (void *zocket); -CZMQ_EXPORT int zsocket_events (void *zocket); -CZMQ_EXPORT char * zsocket_last_endpoint (void *zocket); - -// Set socket options -CZMQ_EXPORT void zsocket_set_router_raw (void *zocket, int router_raw); -CZMQ_EXPORT void zsocket_set_ipv4only (void *zocket, int ipv4only); -CZMQ_EXPORT void zsocket_set_delay_attach_on_connect (void *zocket, int delay_attach_on_connect); -CZMQ_EXPORT void zsocket_set_sndhwm (void *zocket, int sndhwm); -CZMQ_EXPORT void zsocket_set_rcvhwm (void *zocket, int rcvhwm); -CZMQ_EXPORT void zsocket_set_affinity (void *zocket, int affinity); -CZMQ_EXPORT void zsocket_set_subscribe (void *zocket, const char * subscribe); -CZMQ_EXPORT void zsocket_set_unsubscribe (void *zocket, const char * unsubscribe); -CZMQ_EXPORT void zsocket_set_identity (void *zocket, const char * identity); -CZMQ_EXPORT void zsocket_set_rate (void *zocket, int rate); -CZMQ_EXPORT void zsocket_set_recovery_ivl (void *zocket, int recovery_ivl); -CZMQ_EXPORT void zsocket_set_sndbuf (void *zocket, int sndbuf); -CZMQ_EXPORT void zsocket_set_rcvbuf (void *zocket, int rcvbuf); -CZMQ_EXPORT void zsocket_set_linger (void *zocket, int linger); -CZMQ_EXPORT void zsocket_set_reconnect_ivl (void *zocket, int reconnect_ivl); -CZMQ_EXPORT void zsocket_set_reconnect_ivl_max (void *zocket, int reconnect_ivl_max); -CZMQ_EXPORT void zsocket_set_backlog (void *zocket, int backlog); -CZMQ_EXPORT void zsocket_set_maxmsgsize (void *zocket, int maxmsgsize); -CZMQ_EXPORT void zsocket_set_multicast_hops (void *zocket, int multicast_hops); -CZMQ_EXPORT void zsocket_set_rcvtimeo (void *zocket, int rcvtimeo); -CZMQ_EXPORT void zsocket_set_sndtimeo (void *zocket, int sndtimeo); -CZMQ_EXPORT void zsocket_set_xpub_verbose (void *zocket, int xpub_verbose); -CZMQ_EXPORT void zsocket_set_tcp_keepalive (void *zocket, int tcp_keepalive); -CZMQ_EXPORT void zsocket_set_tcp_keepalive_idle (void *zocket, int tcp_keepalive_idle); -CZMQ_EXPORT void zsocket_set_tcp_keepalive_cnt (void *zocket, int tcp_keepalive_cnt); -CZMQ_EXPORT void zsocket_set_tcp_keepalive_intvl (void *zocket, int tcp_keepalive_intvl); -CZMQ_EXPORT void zsocket_set_tcp_accept_filter (void *zocket, const char * tcp_accept_filter); -#endif - -#if (ZMQ_VERSION_MAJOR == 2) -// Get socket options -CZMQ_EXPORT int zsocket_hwm (void *zocket); -CZMQ_EXPORT int zsocket_swap (void *zocket); -CZMQ_EXPORT int zsocket_affinity (void *zocket); -CZMQ_EXPORT char * zsocket_identity (void *zocket); -CZMQ_EXPORT int zsocket_rate (void *zocket); -CZMQ_EXPORT int zsocket_recovery_ivl (void *zocket); -CZMQ_EXPORT int zsocket_recovery_ivl_msec (void *zocket); -CZMQ_EXPORT int zsocket_mcast_loop (void *zocket); -# if (ZMQ_VERSION_MINOR == 2) -CZMQ_EXPORT int zsocket_rcvtimeo (void *zocket); -# endif -# if (ZMQ_VERSION_MINOR == 2) -CZMQ_EXPORT int zsocket_sndtimeo (void *zocket); -# endif -CZMQ_EXPORT int zsocket_sndbuf (void *zocket); -CZMQ_EXPORT int zsocket_rcvbuf (void *zocket); -CZMQ_EXPORT int zsocket_linger (void *zocket); -CZMQ_EXPORT int zsocket_reconnect_ivl (void *zocket); -CZMQ_EXPORT int zsocket_reconnect_ivl_max (void *zocket); -CZMQ_EXPORT int zsocket_backlog (void *zocket); -CZMQ_EXPORT int zsocket_type (void *zocket); -CZMQ_EXPORT int zsocket_rcvmore (void *zocket); -CZMQ_EXPORT SOCKET zsocket_fd (void *zocket); -CZMQ_EXPORT int zsocket_events (void *zocket); - -// Set socket options -CZMQ_EXPORT void zsocket_set_hwm (void *zocket, int hwm); -CZMQ_EXPORT void zsocket_set_swap (void *zocket, int swap); -CZMQ_EXPORT void zsocket_set_affinity (void *zocket, int affinity); -CZMQ_EXPORT void zsocket_set_identity (void *zocket, const char * identity); -CZMQ_EXPORT void zsocket_set_rate (void *zocket, int rate); -CZMQ_EXPORT void zsocket_set_recovery_ivl (void *zocket, int recovery_ivl); -CZMQ_EXPORT void zsocket_set_recovery_ivl_msec (void *zocket, int recovery_ivl_msec); -CZMQ_EXPORT void zsocket_set_mcast_loop (void *zocket, int mcast_loop); -# if (ZMQ_VERSION_MINOR == 2) -CZMQ_EXPORT void zsocket_set_rcvtimeo (void *zocket, int rcvtimeo); -# endif -# if (ZMQ_VERSION_MINOR == 2) -CZMQ_EXPORT void zsocket_set_sndtimeo (void *zocket, int sndtimeo); -# endif -CZMQ_EXPORT void zsocket_set_sndbuf (void *zocket, int sndbuf); -CZMQ_EXPORT void zsocket_set_rcvbuf (void *zocket, int rcvbuf); -CZMQ_EXPORT void zsocket_set_linger (void *zocket, int linger); -CZMQ_EXPORT void zsocket_set_reconnect_ivl (void *zocket, int reconnect_ivl); -CZMQ_EXPORT void zsocket_set_reconnect_ivl_max (void *zocket, int reconnect_ivl_max); -CZMQ_EXPORT void zsocket_set_backlog (void *zocket, int backlog); -CZMQ_EXPORT void zsocket_set_subscribe (void *zocket, const char * subscribe); -CZMQ_EXPORT void zsocket_set_unsubscribe (void *zocket, const char * unsubscribe); -#endif - -// Self test of this class -CZMQ_EXPORT void zsockopt_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zstr.h b/phonelibs/zmq/arm/include/zstr.h deleted file mode 100644 index 3d3f1a862ad7e5..00000000000000 --- a/phonelibs/zmq/arm/include/zstr.h +++ /dev/null @@ -1,115 +0,0 @@ -/* ========================================================================= - zstr - sending and receiving strings - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZSTR_H_INCLUDED__ -#define __ZSTR_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zstr.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// This class has draft methods, which may change over time. They are not -// in stable releases, by default. Use --enable-drafts to enable. -// Receive C string from socket. Caller must free returned string using -// zstr_free(). Returns NULL if the context is being terminated or the -// process was interrupted. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zstr_recv (void *source); - -// Receive a series of strings (until NULL) from multipart data. -// Each string is allocated and filled with string data; if there -// are not enough frames, unallocated strings are set to NULL. -// Returns -1 if the message could not be read, else returns the -// number of strings filled, zero or more. Free each returned string -// using zstr_free(). If not enough strings are provided, remaining -// multipart frames in the message are dropped. -CZMQ_EXPORT int - zstr_recvx (void *source, char **string_p, ...); - -// Send a C string to a socket, as a frame. The string is sent without -// trailing null byte; to read this you can use zstr_recv, or a similar -// method that adds a null terminator on the received string. String -// may be NULL, which is sent as "". -CZMQ_EXPORT int - zstr_send (void *dest, const char *string); - -// Send a C string to a socket, as zstr_send(), with a MORE flag, so that -// you can send further strings in the same multi-part message. -CZMQ_EXPORT int - zstr_sendm (void *dest, const char *string); - -// Send a formatted string to a socket. Note that you should NOT use -// user-supplied strings in the format (they may contain '%' which -// will create security holes). -CZMQ_EXPORT int - zstr_sendf (void *dest, const char *format, ...); - -// Send a formatted string to a socket, as for zstr_sendf(), with a -// MORE flag, so that you can send further strings in the same multi-part -// message. -CZMQ_EXPORT int - zstr_sendfm (void *dest, const char *format, ...); - -// Send a series of strings (until NULL) as multipart data -// Returns 0 if the strings could be sent OK, or -1 on error. -CZMQ_EXPORT int - zstr_sendx (void *dest, const char *string, ...); - -// Free a provided string, and nullify the parent pointer. Safe to call on -// a null pointer. -CZMQ_EXPORT void - zstr_free (char **string_p); - -// Self test of this class. -CZMQ_EXPORT void - zstr_test (bool verbose); - -#ifdef CZMQ_BUILD_DRAFT_API -// *** Draft method, for development use, may change without warning *** -// Accepts a void pointer and returns a fresh character string. If source -// is null, returns an empty string. -// Caller owns return value and must destroy it when done. -CZMQ_EXPORT char * - zstr_str (void *source); - -#endif // CZMQ_BUILD_DRAFT_API -// @ignore -CZMQ_EXPORT int - zstr_sendf (void *dest, const char *format, ...) CHECK_PRINTF (2); -CZMQ_EXPORT int - zstr_sendfm (void *dest, const char *format, ...) CHECK_PRINTF (2); -// @end - - -// DEPRECATED as poor style -- callers should use zloop or zpoller -// Receive C string from socket, if socket had input ready. Caller must -// free returned string using zstr_free. Returns NULL if there was no input -// waiting, or if the context was terminated. Use zctx_interrupted to exit -// any loop that relies on this method. -CZMQ_EXPORT char * - zstr_recv_nowait (void *source); - -// Compiler hints -CZMQ_EXPORT int zstr_sendf (void *dest, const char *format, ...) CHECK_PRINTF (2); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zsys.h b/phonelibs/zmq/arm/include/zsys.h deleted file mode 100644 index 97f88a9555b8e0..00000000000000 --- a/phonelibs/zmq/arm/include/zsys.h +++ /dev/null @@ -1,386 +0,0 @@ -/* ========================================================================= - zsys - system-level methods - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZSYS_H_INCLUDED__ -#define __ZSYS_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -#define UDP_FRAME_MAX 255 // Max size of UDP frame - -// Callback for interrupt signal handler -typedef void (zsys_handler_fn) (int signal_value); - -// Initialize CZMQ zsys layer; this happens automatically when you create -// a socket or an actor; however this call lets you force initialization -// earlier, so e.g. logging is properly set-up before you start working. -// Not threadsafe, so call only from main thread. Safe to call multiple -// times. Returns global CZMQ context. -CZMQ_EXPORT void * - zsys_init (void); - -// Optionally shut down the CZMQ zsys layer; this normally happens automatically -// when the process exits; however this call lets you force a shutdown -// earlier, avoiding any potential problems with atexit() ordering, especially -// with Windows dlls. -CZMQ_EXPORT void - zsys_shutdown (void); - -// Get a new ZMQ socket, automagically creating a ZMQ context if this is -// the first time. Caller is responsible for destroying the ZMQ socket -// before process exits, to avoid a ZMQ deadlock. Note: you should not use -// this method in CZMQ apps, use zsock_new() instead. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT void * - zsys_socket (int type, const char *filename, size_t line_nbr); - -// Destroy/close a ZMQ socket. You should call this for every socket you -// create using zsys_socket(). -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT int - zsys_close (void *handle, const char *filename, size_t line_nbr); - -// Return ZMQ socket name for socket type -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT char * - zsys_sockname (int socktype); - -// Create a pipe, which consists of two PAIR sockets connected over inproc. -// The pipe is configured to use the zsys_pipehwm setting. Returns the -// frontend socket successful, NULL if failed. -CZMQ_EXPORT zsock_t * - zsys_create_pipe (zsock_t **backend_p); - -// Set interrupt handler; this saves the default handlers so that a -// zsys_handler_reset () can restore them. If you call this multiple times -// then the last handler will take affect. If handler_fn is NULL, disables -// default SIGINT/SIGTERM handling in CZMQ. -CZMQ_EXPORT void - zsys_handler_set (zsys_handler_fn *handler_fn); - -// Reset interrupt handler, call this at exit if needed -CZMQ_EXPORT void - zsys_handler_reset (void); - -// Set default interrupt handler, so Ctrl-C or SIGTERM will set -// zsys_interrupted. Idempotent; safe to call multiple times. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT void - zsys_catch_interrupts (void); - -// Return 1 if file exists, else zero -CZMQ_EXPORT bool - zsys_file_exists (const char *filename); - -// Return size of file, or -1 if not found -CZMQ_EXPORT ssize_t - zsys_file_size (const char *filename); - -// Return file modification time. Returns 0 if the file does not exist. -CZMQ_EXPORT time_t - zsys_file_modified (const char *filename); - -// Return file mode; provides at least support for the POSIX S_ISREG(m) -// and S_ISDIR(m) macros and the S_IRUSR and S_IWUSR bits, on all boxes. -// Returns a mode_t cast to int, or -1 in case of error. -CZMQ_EXPORT int - zsys_file_mode (const char *filename); - -// Delete file. Does not complain if the file is absent -CZMQ_EXPORT int - zsys_file_delete (const char *filename); - -// Check if file is 'stable' -CZMQ_EXPORT bool - zsys_file_stable (const char *filename); - -// Create a file path if it doesn't exist. The file path is treated as a -// printf format. -CZMQ_EXPORT int - zsys_dir_create (const char *pathname, ...); - -// Remove a file path if empty; the pathname is treated as printf format. -CZMQ_EXPORT int - zsys_dir_delete (const char *pathname, ...); - -// Move to a specified working directory. Returns 0 if OK, -1 if this failed. -CZMQ_EXPORT int - zsys_dir_change (const char *pathname); - -// Set private file creation mode; all files created from here will be -// readable/writable by the owner only. -CZMQ_EXPORT void - zsys_file_mode_private (void); - -// Reset default file creation mode; all files created from here will use -// process file mode defaults. -CZMQ_EXPORT void - zsys_file_mode_default (void); - -// Return the CZMQ version for run-time API detection; returns version -// number into provided fields, providing reference isn't null in each case. -CZMQ_EXPORT void - zsys_version (int *major, int *minor, int *patch); - -// Format a string using printf formatting, returning a freshly allocated -// buffer. If there was insufficient memory, returns NULL. Free the returned -// string using zstr_free(). -CZMQ_EXPORT char * - zsys_sprintf (const char *format, ...); - -// Format a string with a va_list argument, returning a freshly allocated -// buffer. If there was insufficient memory, returns NULL. Free the returned -// string using zstr_free(). -CZMQ_EXPORT char * - zsys_vprintf (const char *format, va_list argptr); - -// Create UDP beacon socket; if the routable option is true, uses -// multicast (not yet implemented), else uses broadcast. This method -// and related ones might _eventually_ be moved to a zudp class. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT SOCKET - zsys_udp_new (bool routable); - -// Close a UDP socket -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT int - zsys_udp_close (SOCKET handle); - -// Send zframe to UDP socket, return -1 if sending failed due to -// interface having disappeared (happens easily with WiFi) -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT int - zsys_udp_send (SOCKET udpsock, zframe_t *frame, inaddr_t *address, int addrlen); - -// Receive zframe from UDP socket, and set address of peer that sent it -// The peername must be a char [INET_ADDRSTRLEN] array. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT zframe_t * - zsys_udp_recv (SOCKET udpsock, char *peername, int peerlen); - -// Handle an I/O error on some socket operation; will report and die on -// fatal errors, and continue silently on "try again" errors. -// *** This is for CZMQ internal use only and may change arbitrarily *** -CZMQ_EXPORT void - zsys_socket_error (const char *reason); - -// Return current host name, for use in public tcp:// endpoints. Caller gets -// a freshly allocated string, should free it using zstr_free(). If the host -// name is not resolvable, returns NULL. -CZMQ_EXPORT char * - zsys_hostname (void); - -// Move the current process into the background. The precise effect depends -// on the operating system. On POSIX boxes, moves to a specified working -// directory (if specified), closes all file handles, reopens stdin, stdout, -// and stderr to the null device, and sets the process to ignore SIGHUP. On -// Windows, does nothing. Returns 0 if OK, -1 if there was an error. -CZMQ_EXPORT int - zsys_daemonize (const char *workdir); - -// Drop the process ID into the lockfile, with exclusive lock, and switch -// the process to the specified group and/or user. Any of the arguments -// may be null, indicating a no-op. Returns 0 on success, -1 on failure. -// Note if you combine this with zsys_daemonize, run after, not before -// that method, or the lockfile will hold the wrong process ID. -CZMQ_EXPORT int - zsys_run_as (const char *lockfile, const char *group, const char *user); - -// Returns true if the underlying libzmq supports CURVE security. -// Uses a heuristic probe according to the version of libzmq being used. -CZMQ_EXPORT bool - zsys_has_curve (void); - -// Configure the number of I/O threads that ZeroMQ will use. A good -// rule of thumb is one thread per gigabit of traffic in or out. The -// default is 1, sufficient for most applications. If the environment -// variable ZSYS_IO_THREADS is defined, that provides the default. -// Note that this method is valid only before any socket is created. -CZMQ_EXPORT void - zsys_set_io_threads (size_t io_threads); - -// Configure the number of sockets that ZeroMQ will allow. The default -// is 1024. The actual limit depends on the system, and you can query it -// by using zsys_socket_limit (). A value of zero means "maximum". -// Note that this method is valid only before any socket is created. -CZMQ_EXPORT void - zsys_set_max_sockets (size_t max_sockets); - -// Return maximum number of ZeroMQ sockets that the system will support. -CZMQ_EXPORT size_t - zsys_socket_limit (void); - -// Configure the default linger timeout in msecs for new zsock instances. -// You can also set this separately on each zsock_t instance. The default -// linger time is zero, i.e. any pending messages will be dropped. If the -// environment variable ZSYS_LINGER is defined, that provides the default. -// Note that process exit will typically be delayed by the linger time. -CZMQ_EXPORT void - zsys_set_linger (size_t linger); - -// Configure the default outgoing pipe limit (HWM) for new zsock instances. -// You can also set this separately on each zsock_t instance. The default -// HWM is 1,000, on all versions of ZeroMQ. If the environment variable -// ZSYS_SNDHWM is defined, that provides the default. Note that a value of -// zero means no limit, i.e. infinite memory consumption. -CZMQ_EXPORT void - zsys_set_sndhwm (size_t sndhwm); - -// Configure the default incoming pipe limit (HWM) for new zsock instances. -// You can also set this separately on each zsock_t instance. The default -// HWM is 1,000, on all versions of ZeroMQ. If the environment variable -// ZSYS_RCVHWM is defined, that provides the default. Note that a value of -// zero means no limit, i.e. infinite memory consumption. -CZMQ_EXPORT void - zsys_set_rcvhwm (size_t rcvhwm); - -// Configure the default HWM for zactor internal pipes; this is set on both -// ends of the pipe, for outgoing messages only (sndhwm). The default HWM is -// 1,000, on all versions of ZeroMQ. If the environment var ZSYS_ACTORHWM is -// defined, that provides the default. Note that a value of zero means no -// limit, i.e. infinite memory consumption. -CZMQ_EXPORT void - zsys_set_pipehwm (size_t pipehwm); - -// Return the HWM for zactor internal pipes. -CZMQ_EXPORT size_t - zsys_pipehwm (void); - -// Configure use of IPv6 for new zsock instances. By default sockets accept -// and make only IPv4 connections. When you enable IPv6, sockets will accept -// and connect to both IPv4 and IPv6 peers. You can override the setting on -// each zsock_t instance. The default is IPv4 only (ipv6 set to 0). If the -// environment variable ZSYS_IPV6 is defined (as 1 or 0), this provides the -// default. Note: has no effect on ZMQ v2. -CZMQ_EXPORT void - zsys_set_ipv6 (int ipv6); - -// Return use of IPv6 for zsock instances. -CZMQ_EXPORT int - zsys_ipv6 (void); - -// Set network interface name to use for broadcasts, particularly zbeacon. -// This lets the interface be configured for test environments where required. -// For example, on Mac OS X, zbeacon cannot bind to 255.255.255.255 which is -// the default when there is no specified interface. If the environment -// variable ZSYS_INTERFACE is set, use that as the default interface name. -// Setting the interface to "*" means "use all available interfaces". -CZMQ_EXPORT void - zsys_set_interface (const char *value); - -// Return network interface to use for broadcasts, or "" if none was set. -CZMQ_EXPORT const char * - zsys_interface (void); - -// Set IPv6 address to use zbeacon socket, particularly for receiving zbeacon. -// This needs to be set IPv6 is enabled as IPv6 can have multiple addresses -// on a given interface. If the environment variable ZSYS_IPV6_ADDRESS is set, -// use that as the default IPv6 address. -CZMQ_EXPORT void - zsys_set_ipv6_address (const char *value); - -// Return IPv6 address to use for zbeacon reception, or "" if none was set. -CZMQ_EXPORT const char * - zsys_ipv6_address (void); - -// Set IPv6 milticast address to use for sending zbeacon messages. This needs -// to be set if IPv6 is enabled. If the environment variable -// ZSYS_IPV6_MCAST_ADDRESS is set, use that as the default IPv6 multicast -// address. -CZMQ_EXPORT void - zsys_set_ipv6_mcast_address (const char *value); - -// Return IPv6 multicast address to use for sending zbeacon, or "" if none was -// set. -CZMQ_EXPORT const char * - zsys_ipv6_mcast_address (void); - -// Configure the automatic use of pre-allocated FDs when creating new sockets. -// If 0 (default), nothing will happen. Else, when a new socket is bound, the -// system API will be used to check if an existing pre-allocated FD with a -// matching port (if TCP) or path (if IPC) exists, and if it does it will be -// set via the ZMQ_USE_FD socket option so that the library will use it -// instead of creating a new socket. -CZMQ_EXPORT void - zsys_set_auto_use_fd (int auto_use_fd); - -// Return use of automatic pre-allocated FDs for zsock instances. -CZMQ_EXPORT int - zsys_auto_use_fd (void); - -// Set log identity, which is a string that prefixes all log messages sent -// by this process. The log identity defaults to the environment variable -// ZSYS_LOGIDENT, if that is set. -CZMQ_EXPORT void - zsys_set_logident (const char *value); - -// Set stream to receive log traffic. By default, log traffic is sent to -// stdout. If you set the stream to NULL, no stream will receive the log -// traffic (it may still be sent to the system facility). -CZMQ_EXPORT void - zsys_set_logstream (FILE *stream); - -// Sends log output to a PUB socket bound to the specified endpoint. To -// collect such log output, create a SUB socket, subscribe to the traffic -// you care about, and connect to the endpoint. Log traffic is sent as a -// single string frame, in the same format as when sent to stdout. The -// log system supports a single sender; multiple calls to this method will -// bind the same sender to multiple endpoints. To disable the sender, call -// this method with a null argument. -CZMQ_EXPORT void - zsys_set_logsender (const char *endpoint); - -// Enable or disable logging to the system facility (syslog on POSIX boxes, -// event log on Windows). By default this is disabled. -CZMQ_EXPORT void - zsys_set_logsystem (bool logsystem); - -// Log error condition - highest priority -CZMQ_EXPORT void - zsys_error (const char *format, ...); - -// Log warning condition - high priority -CZMQ_EXPORT void - zsys_warning (const char *format, ...); - -// Log normal, but significant, condition - normal priority -CZMQ_EXPORT void - zsys_notice (const char *format, ...); - -// Log informational message - low priority -CZMQ_EXPORT void - zsys_info (const char *format, ...); - -// Log debug-level message - lowest priority -CZMQ_EXPORT void - zsys_debug (const char *format, ...); - -// Self test of this class -CZMQ_EXPORT void - zsys_test (bool verbose); - -// Global signal indicator, TRUE when user presses Ctrl-C or the process -// gets a SIGTERM signal. -CZMQ_EXPORT extern volatile int zsys_interrupted; -// Deprecated name for this variable -CZMQ_EXPORT extern volatile int zctx_interrupted; -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zthread.h b/phonelibs/zmq/arm/include/zthread.h deleted file mode 100644 index fc0602dd9ff483..00000000000000 --- a/phonelibs/zmq/arm/include/zthread.h +++ /dev/null @@ -1,50 +0,0 @@ -/* ========================================================================= - zthread - working with system threads (deprecated) - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZTHREAD_H_INCLUDED__ -#define __ZTHREAD_H_INCLUDED__ - -#ifdef __cplusplus -extern "C" { -#endif - -// @interface -// Detached threads follow POSIX pthreads API -typedef void *(zthread_detached_fn) (void *args); - -// Attached threads get context and pipe from parent -typedef void (zthread_attached_fn) (void *args, zctx_t *ctx, void *pipe); - -// Create a detached thread. A detached thread operates autonomously -// and is used to simulate a separate process. It gets no ctx, and no -// pipe. -CZMQ_EXPORT int - zthread_new (zthread_detached_fn *thread_fn, void *args); - -// Create an attached thread. An attached thread gets a ctx and a PAIR -// pipe back to its parent. It must monitor its pipe, and exit if the -// pipe becomes unreadable. Do not destroy the ctx, the thread does this -// automatically when it ends. -CZMQ_EXPORT void * - zthread_fork (zctx_t *ctx, zthread_attached_fn *thread_fn, void *args); - -// Self test of this class -CZMQ_EXPORT void - zthread_test (bool verbose); -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/ztimerset.h b/phonelibs/zmq/arm/include/ztimerset.h deleted file mode 100644 index 29633fafdbdd30..00000000000000 --- a/phonelibs/zmq/arm/include/ztimerset.h +++ /dev/null @@ -1,90 +0,0 @@ -/* ========================================================================= - ztimerset - timer set - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef ZTIMERSET_H_INCLUDED -#define ZTIMERSET_H_INCLUDED - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/ztimerset.api" to make changes. -// @interface -// This is a draft class, and may change without notice. It is disabled in -// stable builds by default. If you use this in applications, please ask -// for it to be pushed to stable state. Use --enable-drafts to enable. -#ifdef CZMQ_BUILD_DRAFT_API -// Callback function for timer event. -typedef void (ztimerset_fn) ( - int timer_id, void *arg); - -// *** Draft method, for development use, may change without warning *** -// Create new timer set. -CZMQ_EXPORT ztimerset_t * - ztimerset_new (void); - -// *** Draft method, for development use, may change without warning *** -// Destroy a timer set -CZMQ_EXPORT void - ztimerset_destroy (ztimerset_t **self_p); - -// *** Draft method, for development use, may change without warning *** -// Add a timer to the set. Returns timer id if OK, -1 on failure. -CZMQ_EXPORT int - ztimerset_add (ztimerset_t *self, size_t interval, ztimerset_fn handler, void *arg); - -// *** Draft method, for development use, may change without warning *** -// Cancel a timer. Returns 0 if OK, -1 on failure. -CZMQ_EXPORT int - ztimerset_cancel (ztimerset_t *self, int timer_id); - -// *** Draft method, for development use, may change without warning *** -// Set timer interval. Returns 0 if OK, -1 on failure. -// This method is slow, canceling the timer and adding a new one yield better performance. -CZMQ_EXPORT int - ztimerset_set_interval (ztimerset_t *self, int timer_id, size_t interval); - -// *** Draft method, for development use, may change without warning *** -// Reset timer to start interval counting from current time. Returns 0 if OK, -1 on failure. -// This method is slow, canceling the timer and adding a new one yield better performance. -CZMQ_EXPORT int - ztimerset_reset (ztimerset_t *self, int timer_id); - -// *** Draft method, for development use, may change without warning *** -// Return the time until the next interval. -// Should be used as timeout parameter for the zpoller wait method. -// The timeout is in msec. -CZMQ_EXPORT int - ztimerset_timeout (ztimerset_t *self); - -// *** Draft method, for development use, may change without warning *** -// Invoke callback function of all timers which their interval has elapsed. -// Should be call after zpoller wait method. -// Returns 0 if OK, -1 on failure. -CZMQ_EXPORT int - ztimerset_execute (ztimerset_t *self); - -// *** Draft method, for development use, may change without warning *** -// Self test of this class. -CZMQ_EXPORT void - ztimerset_test (bool verbose); - -#endif // CZMQ_BUILD_DRAFT_API -// @end - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/ztrie.h b/phonelibs/zmq/arm/include/ztrie.h deleted file mode 100644 index 6fd53234b1274c..00000000000000 --- a/phonelibs/zmq/arm/include/ztrie.h +++ /dev/null @@ -1,106 +0,0 @@ -/* ========================================================================= - ztrie - simple trie for tokenizable strings - - Copyright (c) 1991-2012 iMatix Corporation -- http://www.imatix.com - Copyright other contributors as noted in the AUTHORS file. - - This file is part of CZMQ, the high-level C binding for 0MQ: http://czmq.zeromq.org - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef ZTRIE_H_INCLUDED -#define ZTRIE_H_INCLUDED - -#ifdef __cplusplus -extern "C" { -#endif - - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/ztrie.api" to make changes. -// @interface -// This is a draft class, and may change without notice. It is disabled in -// stable builds by default. If you use this in applications, please ask -// for it to be pushed to stable state. Use --enable-drafts to enable. -#ifdef CZMQ_BUILD_DRAFT_API -// Callback function for ztrie_node to destroy node data. -typedef void (ztrie_destroy_data_fn) ( - void **data); - -// *** Draft method, for development use, may change without warning *** -// Creates a new ztrie. -CZMQ_EXPORT ztrie_t * - ztrie_new (char delimiter); - -// *** Draft method, for development use, may change without warning *** -// Destroy the ztrie. -CZMQ_EXPORT void - ztrie_destroy (ztrie_t **self_p); - -// *** Draft method, for development use, may change without warning *** -// Inserts a new route into the tree and attaches the data. Returns -1 -// if the route already exists, otherwise 0. This method takes ownership of -// the provided data if a destroy_data_fn is provided. -CZMQ_EXPORT int - ztrie_insert_route (ztrie_t *self, const char *path, void *data, ztrie_destroy_data_fn destroy_data_fn); - -// *** Draft method, for development use, may change without warning *** -// Removes a route from the trie and destroys its data. Returns -1 if the -// route does not exists, otherwise 0. -// the start of the list call zlist_first (). Advances the cursor. -CZMQ_EXPORT int - ztrie_remove_route (ztrie_t *self, const char *path); - -// *** Draft method, for development use, may change without warning *** -// Returns true if the path matches a route in the tree, otherwise false. -CZMQ_EXPORT bool - ztrie_matches (ztrie_t *self, const char *path); - -// *** Draft method, for development use, may change without warning *** -// Returns the data of a matched route from last ztrie_matches. If the path -// did not match, returns NULL. Do not delete the data as it's owned by -// ztrie. -CZMQ_EXPORT void * - ztrie_hit_data (ztrie_t *self); - -// *** Draft method, for development use, may change without warning *** -// Returns the count of parameters that a matched route has. -CZMQ_EXPORT size_t - ztrie_hit_parameter_count (ztrie_t *self); - -// *** Draft method, for development use, may change without warning *** -// Returns the parameters of a matched route with named regexes from last -// ztrie_matches. If the path did not match or the route did not contain any -// named regexes, returns NULL. -CZMQ_EXPORT zhashx_t * - ztrie_hit_parameters (ztrie_t *self); - -// *** Draft method, for development use, may change without warning *** -// Returns the asterisk matched part of a route, if there has been no match -// or no asterisk match, returns NULL. -CZMQ_EXPORT const char * - ztrie_hit_asterisk_match (ztrie_t *self); - -// *** Draft method, for development use, may change without warning *** -// Print the trie -CZMQ_EXPORT void - ztrie_print (ztrie_t *self); - -// *** Draft method, for development use, may change without warning *** -// Self test of this class. -CZMQ_EXPORT void - ztrie_test (bool verbose); - -#endif // CZMQ_BUILD_DRAFT_API -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/include/zuuid.h b/phonelibs/zmq/arm/include/zuuid.h deleted file mode 100644 index afc1104fea952b..00000000000000 --- a/phonelibs/zmq/arm/include/zuuid.h +++ /dev/null @@ -1,96 +0,0 @@ -/* ========================================================================= - zuuid - UUID support class - - Copyright (c) the Contributors as noted in the AUTHORS file. - This file is part of CZMQ, the high-level C binding for 0MQ: - http://czmq.zeromq.org. - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - ========================================================================= -*/ - -#ifndef __ZUUID_H_INCLUDED__ -#define __ZUUID_H_INCLUDED__ - -#define ZUUID_LEN 16 -#define ZUUID_STR_LEN (ZUUID_LEN * 2) - -#ifdef __cplusplus -extern "C" { -#endif - -// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT -// @warning Please edit the model at "api/zuuid.api" to make changes. -// @interface -// This is a stable class, and may not change except for emergencies. It -// is provided in stable builds. -// Create a new UUID object. -CZMQ_EXPORT zuuid_t * - zuuid_new (void); - -// Create UUID object from supplied ZUUID_LEN-octet value. -CZMQ_EXPORT zuuid_t * - zuuid_new_from (const byte *source); - -// Destroy a specified UUID object. -CZMQ_EXPORT void - zuuid_destroy (zuuid_t **self_p); - -// Set UUID to new supplied ZUUID_LEN-octet value. -CZMQ_EXPORT void - zuuid_set (zuuid_t *self, const byte *source); - -// Set UUID to new supplied string value skipping '-' and '{' '}' -// optional delimiters. Return 0 if OK, else returns -1. -CZMQ_EXPORT int - zuuid_set_str (zuuid_t *self, const char *source); - -// Return UUID binary data. -CZMQ_EXPORT const byte * - zuuid_data (zuuid_t *self); - -// Return UUID binary size -CZMQ_EXPORT size_t - zuuid_size (zuuid_t *self); - -// Returns UUID as string -CZMQ_EXPORT const char * - zuuid_str (zuuid_t *self); - -// Return UUID in the canonical string format: 8-4-4-4-12, in lower -// case. Caller does not modify or free returned value. See -// http://en.wikipedia.org/wiki/Universally_unique_identifier -CZMQ_EXPORT const char * - zuuid_str_canonical (zuuid_t *self); - -// Store UUID blob in target array -CZMQ_EXPORT void - zuuid_export (zuuid_t *self, byte *target); - -// Check if UUID is same as supplied value -CZMQ_EXPORT bool - zuuid_eq (zuuid_t *self, const byte *compare); - -// Check if UUID is different from supplied value -CZMQ_EXPORT bool - zuuid_neq (zuuid_t *self, const byte *compare); - -// Make copy of UUID object; if uuid is null, or memory was exhausted, -// returns null. -CZMQ_EXPORT zuuid_t * - zuuid_dup (zuuid_t *self); - -// Self test of this class. -CZMQ_EXPORT void - zuuid_test (bool verbose); - -// @end - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/phonelibs/zmq/arm/lib/libczmq.a b/phonelibs/zmq/arm/lib/libczmq.a deleted file mode 100644 index cb78e4b8296463..00000000000000 Binary files a/phonelibs/zmq/arm/lib/libczmq.a and /dev/null differ diff --git a/phonelibs/zmq/arm/lib/libczmq.so b/phonelibs/zmq/arm/lib/libczmq.so deleted file mode 100755 index 87ee937f72ae09..00000000000000 Binary files a/phonelibs/zmq/arm/lib/libczmq.so and /dev/null differ diff --git a/phonelibs/zmq/arm/lib/libzmq.a b/phonelibs/zmq/arm/lib/libzmq.a deleted file mode 100644 index cd523cd73e6ab5..00000000000000 Binary files a/phonelibs/zmq/arm/lib/libzmq.a and /dev/null differ diff --git a/phonelibs/zmq/arm/lib/libzmq.so b/phonelibs/zmq/arm/lib/libzmq.so deleted file mode 100755 index 27ec72d7bc815e..00000000000000 Binary files a/phonelibs/zmq/arm/lib/libzmq.so and /dev/null differ diff --git a/phonelibs/zmq/build.sh b/phonelibs/zmq/build.sh deleted file mode 100755 index 8c4d9a50f1f4af..00000000000000 --- a/phonelibs/zmq/build.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/sh -set -e - -# aarch64 is actually built natively and copied in... - -SED=gsed - -git clone --depth 1 -b v4.2.2 git://github.com/zeromq/libzmq.git libzmq -git clone --depth 1 -b v4.0.2 git://github.com/zeromq/czmq.git czmq - -$SED -i 's/defined .HAVE_GETIFADDRS./0/' czmq/src/ziflist.c - -LIBZMQ_ROOT=$HOME/one/phonelibs/zmq/libzmq - -export ANDROID_NDK_ROOT=/opt/android-ndk - -export ANDROID_BUILD_EXTRA_CFLAGS='-std=gnu99 -O2' -export ANDROID_BUILD_EXTRA_CXXFLAGS='-O2' - -######## arm - -export TOOLCHAIN_PATH=${ANDROID_NDK_ROOT}/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin -export TOOLCHAIN_NAME=arm-linux-androideabi-4.9 -export TOOLCHAIN_HOST=arm-linux-androideabi -export TOOLCHAIN_ARCH=arm -cd czmq/builds/android -./build.sh -cd ../../../ -cp czmq/builds/android/prefix/arm-linux-androideabi-4.9/lib/libczmq.a \ - czmq/builds/android/prefix/arm-linux-androideabi-4.9/lib/libczmq.so \ - czmq/builds/android/prefix/arm-linux-androideabi-4.9/lib/libzmq.a \ - czmq/builds/android/prefix/arm-linux-androideabi-4.9/lib/libzmq.so ./arm/lib/ -cp czmq/builds/android/prefix/arm-linux-androideabi-4.9/include/*.h ./arm/include/ - - -######## aarch64 - -(cd libzmq && patch -p0 <../build_aarch64.patch) -(cd czmq && patch -p0 <../build_aarch64.patch) - -# android-9 lacks aarch64. -$SED -i 's/android-9/android-24/' *zmq/builds/android/android_build_helper.sh -# For some reason gcc doesn't work for aarch64, but g++ does. -$SED -i 's/-lgnustl_shared/-l:libgnustl_static.a/' *zmq/builds/android/android_build_helper.sh - -export TOOLCHAIN_PATH=${ANDROID_NDK_ROOT}/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin -export TOOLCHAIN_NAME=aarch64-linux-android-4.9 -export TOOLCHAIN_HOST=aarch64-linux-android -export TOOLCHAIN_ARCH=arm64 -cd czmq/builds/android -./build.sh -cd ../../../ -cp czmq/builds/android/prefix/aarch64-linux-android-4.9/lib/libczmq.a \ - czmq/builds/android/prefix/aarch64-linux-android-4.9/lib/libczmq.so \ - czmq/builds/android/prefix/aarch64-linux-android-4.9/lib/libzmq.a \ - czmq/builds/android/prefix/aarch64-linux-android-4.9/lib/libzmq.so ./aarch64/lib/ -cp czmq/builds/android/prefix/aarch64-linux-android-4.9/include/*.h ./aarch64/include/ - -# rm -rf czmq -echo SUCCESS diff --git a/phonelibs/zmq/build_aarch64.patch b/phonelibs/zmq/build_aarch64.patch deleted file mode 100644 index d689b99c51a4c6..00000000000000 --- a/phonelibs/zmq/build_aarch64.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff --git builds/android/android_build_helper.sh builds/android/android_build_helper.sh -index 6263f70..d0b24c3 100755 ---- builds/android/android_build_helper.sh -+++ builds/android/android_build_helper.sh -@@ -202,6 +202,10 @@ function _android_build_opts_process_cxx_stl { - LDFLAGS+=" -L${ANDROID_NDK_ROOT}/sources/cxx-stl/gnu-libstdc++/4.9/libs/mips" - CPPFLAGS+=" -I${ANDROID_NDK_ROOT}/sources/cxx-stl/gnu-libstdc++/4.9/libs/mips/include" - ;; -+ arm64) -+ LDFLAGS+=" -L${ANDROID_NDK_ROOT}/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a" -+ CPPFLAGS+=" -I${ANDROID_NDK_ROOT}/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a/include" -+ ;; - *) - ANDROID_BUILD_FAIL+=("Unknown combination for ANDROID_BUILD_CXXSTL and TOOLCHAIN_ARCH") - ANDROID_BUILD_FAIL+=(" ${ANDROID_BUILD_CXXSTL}") diff --git a/phonelibs/zmq/build_linux.txt b/phonelibs/zmq/build_linux.txt deleted file mode 100644 index 54e3b2a340f33b..00000000000000 --- a/phonelibs/zmq/build_linux.txt +++ /dev/null @@ -1,7 +0,0 @@ -https://github.com/zeromq/libzmq/releases/download/v4.2.2/zeromq-4.2.2.tar.gz -./configure --prefix="this_thingy" -make -j4 -make install - -czmq -see ~/one/external/zmq/build_czmq.sh diff --git a/phonelibs/zmq/mac/lib/libczmq.a b/phonelibs/zmq/mac/lib/libczmq.a deleted file mode 100644 index 061f2afabd4937..00000000000000 Binary files a/phonelibs/zmq/mac/lib/libczmq.a and /dev/null differ diff --git a/phonelibs/zmq/mac/lib/libczmq.dylib b/phonelibs/zmq/mac/lib/libczmq.dylib deleted file mode 100644 index 50d2167e9cb8ec..00000000000000 Binary files a/phonelibs/zmq/mac/lib/libczmq.dylib and /dev/null differ diff --git a/phonelibs/zmq/mac/lib/libzmq.a b/phonelibs/zmq/mac/lib/libzmq.a deleted file mode 100644 index 3365d42e87733d..00000000000000 Binary files a/phonelibs/zmq/mac/lib/libzmq.a and /dev/null differ diff --git a/phonelibs/zmq/mac/lib/libzmq.dylib b/phonelibs/zmq/mac/lib/libzmq.dylib deleted file mode 100755 index 19b751496071c6..00000000000000 Binary files a/phonelibs/zmq/mac/lib/libzmq.dylib and /dev/null differ diff --git a/phonelibs/zmq/aarch64-linux/include/czmq.h b/phonelibs/zmq/x64/include/czmq.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/czmq.h rename to phonelibs/zmq/x64/include/czmq.h diff --git a/phonelibs/zmq/aarch64-linux/include/czmq_library.h b/phonelibs/zmq/x64/include/czmq_library.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/czmq_library.h rename to phonelibs/zmq/x64/include/czmq_library.h diff --git a/phonelibs/zmq/aarch64-linux/include/czmq_prelude.h b/phonelibs/zmq/x64/include/czmq_prelude.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/czmq_prelude.h rename to phonelibs/zmq/x64/include/czmq_prelude.h diff --git a/phonelibs/zmq/aarch64-linux/include/zactor.h b/phonelibs/zmq/x64/include/zactor.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zactor.h rename to phonelibs/zmq/x64/include/zactor.h diff --git a/phonelibs/zmq/aarch64-linux/include/zarmour.h b/phonelibs/zmq/x64/include/zarmour.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zarmour.h rename to phonelibs/zmq/x64/include/zarmour.h diff --git a/phonelibs/zmq/aarch64-linux/include/zauth.h b/phonelibs/zmq/x64/include/zauth.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zauth.h rename to phonelibs/zmq/x64/include/zauth.h diff --git a/phonelibs/zmq/aarch64-linux/include/zbeacon.h b/phonelibs/zmq/x64/include/zbeacon.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zbeacon.h rename to phonelibs/zmq/x64/include/zbeacon.h diff --git a/phonelibs/zmq/aarch64-linux/include/zcert.h b/phonelibs/zmq/x64/include/zcert.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zcert.h rename to phonelibs/zmq/x64/include/zcert.h diff --git a/phonelibs/zmq/aarch64-linux/include/zcertstore.h b/phonelibs/zmq/x64/include/zcertstore.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zcertstore.h rename to phonelibs/zmq/x64/include/zcertstore.h diff --git a/phonelibs/zmq/aarch64-linux/include/zchunk.h b/phonelibs/zmq/x64/include/zchunk.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zchunk.h rename to phonelibs/zmq/x64/include/zchunk.h diff --git a/phonelibs/zmq/aarch64-linux/include/zclock.h b/phonelibs/zmq/x64/include/zclock.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zclock.h rename to phonelibs/zmq/x64/include/zclock.h diff --git a/phonelibs/zmq/aarch64-linux/include/zconfig.h b/phonelibs/zmq/x64/include/zconfig.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zconfig.h rename to phonelibs/zmq/x64/include/zconfig.h diff --git a/phonelibs/zmq/aarch64-linux/include/zdigest.h b/phonelibs/zmq/x64/include/zdigest.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zdigest.h rename to phonelibs/zmq/x64/include/zdigest.h diff --git a/phonelibs/zmq/aarch64-linux/include/zdir.h b/phonelibs/zmq/x64/include/zdir.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zdir.h rename to phonelibs/zmq/x64/include/zdir.h diff --git a/phonelibs/zmq/aarch64-linux/include/zdir_patch.h b/phonelibs/zmq/x64/include/zdir_patch.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zdir_patch.h rename to phonelibs/zmq/x64/include/zdir_patch.h diff --git a/phonelibs/zmq/aarch64-linux/include/zfile.h b/phonelibs/zmq/x64/include/zfile.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zfile.h rename to phonelibs/zmq/x64/include/zfile.h diff --git a/phonelibs/zmq/aarch64-linux/include/zframe.h b/phonelibs/zmq/x64/include/zframe.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zframe.h rename to phonelibs/zmq/x64/include/zframe.h diff --git a/phonelibs/zmq/aarch64-linux/include/zgossip.h b/phonelibs/zmq/x64/include/zgossip.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zgossip.h rename to phonelibs/zmq/x64/include/zgossip.h diff --git a/phonelibs/zmq/aarch64-linux/include/zhash.h b/phonelibs/zmq/x64/include/zhash.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zhash.h rename to phonelibs/zmq/x64/include/zhash.h diff --git a/phonelibs/zmq/aarch64-linux/include/zhashx.h b/phonelibs/zmq/x64/include/zhashx.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zhashx.h rename to phonelibs/zmq/x64/include/zhashx.h diff --git a/phonelibs/zmq/aarch64-linux/include/ziflist.h b/phonelibs/zmq/x64/include/ziflist.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/ziflist.h rename to phonelibs/zmq/x64/include/ziflist.h diff --git a/phonelibs/zmq/aarch64-linux/include/zlist.h b/phonelibs/zmq/x64/include/zlist.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zlist.h rename to phonelibs/zmq/x64/include/zlist.h diff --git a/phonelibs/zmq/aarch64-linux/include/zlistx.h b/phonelibs/zmq/x64/include/zlistx.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zlistx.h rename to phonelibs/zmq/x64/include/zlistx.h diff --git a/phonelibs/zmq/aarch64-linux/include/zloop.h b/phonelibs/zmq/x64/include/zloop.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zloop.h rename to phonelibs/zmq/x64/include/zloop.h diff --git a/phonelibs/zmq/aarch64-linux/include/zmonitor.h b/phonelibs/zmq/x64/include/zmonitor.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zmonitor.h rename to phonelibs/zmq/x64/include/zmonitor.h diff --git a/phonelibs/zmq/aarch64-linux/include/zmq.h b/phonelibs/zmq/x64/include/zmq.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zmq.h rename to phonelibs/zmq/x64/include/zmq.h diff --git a/phonelibs/zmq/aarch64-linux/include/zmq_utils.h b/phonelibs/zmq/x64/include/zmq_utils.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zmq_utils.h rename to phonelibs/zmq/x64/include/zmq_utils.h diff --git a/phonelibs/zmq/aarch64-linux/include/zmsg.h b/phonelibs/zmq/x64/include/zmsg.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zmsg.h rename to phonelibs/zmq/x64/include/zmsg.h diff --git a/phonelibs/zmq/aarch64-linux/include/zpoller.h b/phonelibs/zmq/x64/include/zpoller.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zpoller.h rename to phonelibs/zmq/x64/include/zpoller.h diff --git a/phonelibs/zmq/x64/include/zproc.h b/phonelibs/zmq/x64/include/zproc.h new file mode 100644 index 00000000000000..4fd3fcf445c55f --- /dev/null +++ b/phonelibs/zmq/x64/include/zproc.h @@ -0,0 +1,168 @@ +/* ========================================================================= + zproc - process configuration and status + + Copyright (c) the Contributors as noted in the AUTHORS file. + This file is part of CZMQ, the high-level C binding for 0MQ: + http://czmq.zeromq.org. + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + ========================================================================= +*/ + +#ifndef ZPROC_H_INCLUDED +#define ZPROC_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + + +// @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT +// @warning Please edit the model at "api/zproc.api" to make changes. +// @interface +// This is a draft class, and may change without notice. It is disabled in +// stable builds by default. If you use this in applications, please ask +// for it to be pushed to stable state. Use --enable-drafts to enable. +#ifdef CZMQ_BUILD_DRAFT_API +// *** Draft method, for development use, may change without warning *** +// Returns CZMQ version as a single 6-digit integer encoding the major +// version (x 10000), the minor version (x 100) and the patch. +CZMQ_EXPORT int + zproc_czmq_version (void); + +// *** Draft method, for development use, may change without warning *** +// Returns true if the process received a SIGINT or SIGTERM signal. +// It is good practice to use this method to exit any infinite loop +// processing messages. +CZMQ_EXPORT bool + zproc_interrupted (void); + +// *** Draft method, for development use, may change without warning *** +// Returns true if the underlying libzmq supports CURVE security. +CZMQ_EXPORT bool + zproc_has_curve (void); + +// *** Draft method, for development use, may change without warning *** +// Return current host name, for use in public tcp:// endpoints. +// If the host name is not resolvable, returns NULL. +// Caller owns return value and must destroy it when done. +CZMQ_EXPORT char * + zproc_hostname (void); + +// *** Draft method, for development use, may change without warning *** +// Move the current process into the background. The precise effect +// depends on the operating system. On POSIX boxes, moves to a specified +// working directory (if specified), closes all file handles, reopens +// stdin, stdout, and stderr to the null device, and sets the process to +// ignore SIGHUP. On Windows, does nothing. Returns 0 if OK, -1 if there +// was an error. +CZMQ_EXPORT void + zproc_daemonize (const char *workdir); + +// *** Draft method, for development use, may change without warning *** +// Drop the process ID into the lockfile, with exclusive lock, and +// switch the process to the specified group and/or user. Any of the +// arguments may be null, indicating a no-op. Returns 0 on success, +// -1 on failure. Note if you combine this with zsys_daemonize, run +// after, not before that method, or the lockfile will hold the wrong +// process ID. +CZMQ_EXPORT void + zproc_run_as (const char *lockfile, const char *group, const char *user); + +// *** Draft method, for development use, may change without warning *** +// Configure the number of I/O threads that ZeroMQ will use. A good +// rule of thumb is one thread per gigabit of traffic in or out. The +// default is 1, sufficient for most applications. If the environment +// variable ZSYS_IO_THREADS is defined, that provides the default. +// Note that this method is valid only before any socket is created. +CZMQ_EXPORT void + zproc_set_io_threads (size_t io_threads); + +// *** Draft method, for development use, may change without warning *** +// Configure the number of sockets that ZeroMQ will allow. The default +// is 1024. The actual limit depends on the system, and you can query it +// by using zsys_socket_limit (). A value of zero means "maximum". +// Note that this method is valid only before any socket is created. +CZMQ_EXPORT void + zproc_set_max_sockets (size_t max_sockets); + +// *** Draft method, for development use, may change without warning *** +// Set network interface name to use for broadcasts, particularly zbeacon. +// This lets the interface be configured for test environments where required. +// For example, on Mac OS X, zbeacon cannot bind to 255.255.255.255 which is +// the default when there is no specified interface. If the environment +// variable ZSYS_INTERFACE is set, use that as the default interface name. +// Setting the interface to "*" means "use all available interfaces". +CZMQ_EXPORT void + zproc_set_biface (const char *value); + +// *** Draft method, for development use, may change without warning *** +// Return network interface to use for broadcasts, or "" if none was set. +CZMQ_EXPORT const char * + zproc_biface (void); + +// *** Draft method, for development use, may change without warning *** +// Set log identity, which is a string that prefixes all log messages sent +// by this process. The log identity defaults to the environment variable +// ZSYS_LOGIDENT, if that is set. +CZMQ_EXPORT void + zproc_set_log_ident (const char *value); + +// *** Draft method, for development use, may change without warning *** +// Sends log output to a PUB socket bound to the specified endpoint. To +// collect such log output, create a SUB socket, subscribe to the traffic +// you care about, and connect to the endpoint. Log traffic is sent as a +// single string frame, in the same format as when sent to stdout. The +// log system supports a single sender; multiple calls to this method will +// bind the same sender to multiple endpoints. To disable the sender, call +// this method with a null argument. +CZMQ_EXPORT void + zproc_set_log_sender (const char *endpoint); + +// *** Draft method, for development use, may change without warning *** +// Enable or disable logging to the system facility (syslog on POSIX boxes, +// event log on Windows). By default this is disabled. +CZMQ_EXPORT void + zproc_set_log_system (bool logsystem); + +// *** Draft method, for development use, may change without warning *** +// Log error condition - highest priority +CZMQ_EXPORT void + zproc_log_error (const char *format, ...) CHECK_PRINTF (1); + +// *** Draft method, for development use, may change without warning *** +// Log warning condition - high priority +CZMQ_EXPORT void + zproc_log_warning (const char *format, ...) CHECK_PRINTF (1); + +// *** Draft method, for development use, may change without warning *** +// Log normal, but significant, condition - normal priority +CZMQ_EXPORT void + zproc_log_notice (const char *format, ...) CHECK_PRINTF (1); + +// *** Draft method, for development use, may change without warning *** +// Log informational message - low priority +CZMQ_EXPORT void + zproc_log_info (const char *format, ...) CHECK_PRINTF (1); + +// *** Draft method, for development use, may change without warning *** +// Log debug-level message - lowest priority +CZMQ_EXPORT void + zproc_log_debug (const char *format, ...) CHECK_PRINTF (1); + +// *** Draft method, for development use, may change without warning *** +// Self test of this class. +CZMQ_EXPORT void + zproc_test (bool verbose); + +#endif // CZMQ_BUILD_DRAFT_API +// @end + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/phonelibs/zmq/aarch64-linux/include/zproxy.h b/phonelibs/zmq/x64/include/zproxy.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zproxy.h rename to phonelibs/zmq/x64/include/zproxy.h diff --git a/phonelibs/zmq/aarch64-linux/include/zrex.h b/phonelibs/zmq/x64/include/zrex.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zrex.h rename to phonelibs/zmq/x64/include/zrex.h diff --git a/phonelibs/zmq/aarch64-linux/include/zsock.h b/phonelibs/zmq/x64/include/zsock.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zsock.h rename to phonelibs/zmq/x64/include/zsock.h diff --git a/phonelibs/zmq/aarch64-linux/include/zstr.h b/phonelibs/zmq/x64/include/zstr.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zstr.h rename to phonelibs/zmq/x64/include/zstr.h diff --git a/phonelibs/zmq/aarch64-linux/include/zsys.h b/phonelibs/zmq/x64/include/zsys.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zsys.h rename to phonelibs/zmq/x64/include/zsys.h diff --git a/phonelibs/zmq/aarch64/include/ztimerset.h b/phonelibs/zmq/x64/include/ztimerset.h similarity index 100% rename from phonelibs/zmq/aarch64/include/ztimerset.h rename to phonelibs/zmq/x64/include/ztimerset.h diff --git a/phonelibs/zmq/aarch64/include/ztrie.h b/phonelibs/zmq/x64/include/ztrie.h similarity index 100% rename from phonelibs/zmq/aarch64/include/ztrie.h rename to phonelibs/zmq/x64/include/ztrie.h diff --git a/phonelibs/zmq/aarch64-linux/include/zuuid.h b/phonelibs/zmq/x64/include/zuuid.h similarity index 100% rename from phonelibs/zmq/aarch64-linux/include/zuuid.h rename to phonelibs/zmq/x64/include/zuuid.h diff --git a/phonelibs/zmq/x64/lib/libczmq.a b/phonelibs/zmq/x64/lib/libczmq.a new file mode 100644 index 00000000000000..9045eb980eae46 Binary files /dev/null and b/phonelibs/zmq/x64/lib/libczmq.a differ diff --git a/phonelibs/zmq/x64/lib/libczmq.la b/phonelibs/zmq/x64/lib/libczmq.la new file mode 100755 index 00000000000000..8e4a9ee3645a65 --- /dev/null +++ b/phonelibs/zmq/x64/lib/libczmq.la @@ -0,0 +1,41 @@ +# libczmq.la - a libtool library file +# Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='libczmq.so.4' + +# Names of this library. +library_names='libczmq.so.4.0.2 libczmq.so.4 libczmq.so' + +# The name of the static archive. +old_library='libczmq.a' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags=' -pthread' + +# Libraries that this one depends upon. +dependency_libs=' -L/home/batman/one/external/zmq/lib -L/usr/local/lib /home/batman/one/external/zmq/lib/libzmq.la -lrt -lpthread -ldl' + +# Names of additional weak libraries provided by this library +weak_library_names='' + +# Version information for libczmq. +current=4 +age=0 +revision=2 + +# Is this an already installed library? +installed=yes + +# Should we warn about portability when linking against -modules? +shouldnotlink=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/home/batman/one/external/zmq/lib' diff --git a/phonelibs/zmq/aarch64-linux/lib/libczmq.so b/phonelibs/zmq/x64/lib/libczmq.so similarity index 100% rename from phonelibs/zmq/aarch64-linux/lib/libczmq.so rename to phonelibs/zmq/x64/lib/libczmq.so diff --git a/phonelibs/zmq/aarch64-linux/lib/libczmq.so.4 b/phonelibs/zmq/x64/lib/libczmq.so.4 similarity index 100% rename from phonelibs/zmq/aarch64-linux/lib/libczmq.so.4 rename to phonelibs/zmq/x64/lib/libczmq.so.4 diff --git a/phonelibs/zmq/x64/lib/libczmq.so.4.0.2 b/phonelibs/zmq/x64/lib/libczmq.so.4.0.2 new file mode 100755 index 00000000000000..eaf4cce8b9c5f3 Binary files /dev/null and b/phonelibs/zmq/x64/lib/libczmq.so.4.0.2 differ diff --git a/phonelibs/zmq/x64/lib/libzmq.a b/phonelibs/zmq/x64/lib/libzmq.a new file mode 100644 index 00000000000000..28c77cc36e58ed Binary files /dev/null and b/phonelibs/zmq/x64/lib/libzmq.a differ diff --git a/phonelibs/zmq/x64/lib/libzmq.la b/phonelibs/zmq/x64/lib/libzmq.la new file mode 100644 index 00000000000000..69652b3463048a --- /dev/null +++ b/phonelibs/zmq/x64/lib/libzmq.la @@ -0,0 +1,41 @@ +# libzmq.la - a libtool library file +# Generated by libtool (GNU libtool) 2.4.6 Debian-2.4.6-0.1 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='libzmq.so.5' + +# Names of this library. +library_names='libzmq.so.5.1.2 libzmq.so.5 libzmq.so' + +# The name of the static archive. +old_library='libzmq.a' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='' + +# Libraries that this one depends upon. +dependency_libs=' -lrt -lpthread -ldl' + +# Names of additional weak libraries provided by this library +weak_library_names='' + +# Version information for libzmq. +current=6 +age=1 +revision=2 + +# Is this an already installed library? +installed=yes + +# Should we warn about portability when linking against -modules? +shouldnotlink=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/home/batman/one/external/zmq/lib' diff --git a/phonelibs/zmq/x64/lib/libzmq.lai b/phonelibs/zmq/x64/lib/libzmq.lai new file mode 100644 index 00000000000000..93c1a83dc393ff --- /dev/null +++ b/phonelibs/zmq/x64/lib/libzmq.lai @@ -0,0 +1,41 @@ +# libzmq.la - a libtool library file +# Generated by libtool (GNU libtool) 2.4.6 Debian-2.4.6-0.1 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='libzmq.so.5' + +# Names of this library. +library_names='libzmq.so.5.1.2 libzmq.so.5 libzmq.so' + +# The name of the static archive. +old_library='libzmq.a' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='' + +# Libraries that this one depends upon. +dependency_libs=' -lrt -lpthread -ldl' + +# Names of additional weak libraries provided by this library +weak_library_names='' + +# Version information for libzmq. +current=6 +age=1 +revision=2 + +# Is this an already installed library? +installed=yes + +# Should we warn about portability when linking against -modules? +shouldnotlink=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/usr/local/lib' diff --git a/phonelibs/zmq/aarch64-linux/lib/libzmq.so b/phonelibs/zmq/x64/lib/libzmq.so similarity index 100% rename from phonelibs/zmq/aarch64-linux/lib/libzmq.so rename to phonelibs/zmq/x64/lib/libzmq.so diff --git a/phonelibs/zmq/aarch64-linux/lib/libzmq.so.5 b/phonelibs/zmq/x64/lib/libzmq.so.5 similarity index 100% rename from phonelibs/zmq/aarch64-linux/lib/libzmq.so.5 rename to phonelibs/zmq/x64/lib/libzmq.so.5 diff --git a/phonelibs/zmq/x64/lib/libzmq.so.5.1.2 b/phonelibs/zmq/x64/lib/libzmq.so.5.1.2 new file mode 100755 index 00000000000000..e08e8c2dfb47d7 Binary files /dev/null and b/phonelibs/zmq/x64/lib/libzmq.so.5.1.2 differ diff --git a/phonelibs/zmq/aarch64-linux/lib/pkgconfig/libczmq.pc b/phonelibs/zmq/x64/lib/pkgconfig/libczmq.pc similarity index 92% rename from phonelibs/zmq/aarch64-linux/lib/pkgconfig/libczmq.pc rename to phonelibs/zmq/x64/lib/pkgconfig/libczmq.pc index 7740eec8c0d3b5..b6fb3dc13322f6 100644 --- a/phonelibs/zmq/aarch64-linux/lib/pkgconfig/libczmq.pc +++ b/phonelibs/zmq/x64/lib/pkgconfig/libczmq.pc @@ -3,7 +3,7 @@ # Read the zproject/README.md for information about making permanent changes. # ################################################################################ -prefix=/home/nvidia/build/zmq +prefix=/home/batman/one/external/zmq exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include @@ -16,7 +16,7 @@ Requires:libzmq Libs: -L${libdir} -lczmq Cflags: -I${includedir} -Libs.private: -lzmq -luuid +Libs.private: -L/usr/local/lib -lzmq ################################################################################ # THIS FILE IS 100% GENERATED BY ZPROJECT; DO NOT EDIT EXCEPT EXPERIMENTALLY # diff --git a/phonelibs/zmq/x64/lib/pkgconfig/libzmq.pc b/phonelibs/zmq/x64/lib/pkgconfig/libzmq.pc new file mode 100644 index 00000000000000..aba3d3a75e09e3 --- /dev/null +++ b/phonelibs/zmq/x64/lib/pkgconfig/libzmq.pc @@ -0,0 +1,10 @@ +prefix=/home/batman/one/external/zmq +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: libzmq +Description: 0MQ c++ library +Version: 4.2.2 +Libs: -L${libdir} -lzmq +Cflags: -I${includedir} diff --git a/pyextra/Flask-1.0.2-py2.7.egg-info/PKG-INFO b/pyextra/Flask-1.0.2-py2.7.egg-info/PKG-INFO deleted file mode 100644 index 59a627f61ca490..00000000000000 --- a/pyextra/Flask-1.0.2-py2.7.egg-info/PKG-INFO +++ /dev/null @@ -1,103 +0,0 @@ -Metadata-Version: 1.1 -Name: Flask -Version: 1.0.2 -Summary: A simple framework for building complex web applications. -Home-page: https://www.palletsprojects.com/p/flask/ -Author: Pallets team -Author-email: contact@palletsprojects.com -License: BSD -Description: Flask - ===== - - Flask is a lightweight `WSGI`_ web application framework. It is designed - to make getting started quick and easy, with the ability to scale up to - complex applications. It began as a simple wrapper around `Werkzeug`_ - and `Jinja`_ and has become one of the most popular Python web - application frameworks. - - Flask offers suggestions, but doesn't enforce any dependencies or - project layout. It is up to the developer to choose the tools and - libraries they want to use. There are many extensions provided by the - community that make adding new functionality easy. - - - Installing - ---------- - - Install and update using `pip`_: - - .. code-block:: text - - pip install -U Flask - - - A Simple Example - ---------------- - - .. code-block:: python - - from flask import Flask - - app = Flask(__name__) - - @app.route('/') - def hello(): - return 'Hello, World!' - - .. code-block:: text - - $ FLASK_APP=hello.py flask run - * Serving Flask app "hello" - * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) - - - Donate - ------ - - The Pallets organization develops and supports Flask and the libraries - it uses. In order to grow the community of contributors and users, and - allow the maintainers to devote more time to the projects, `please - donate today`_. - - .. _please donate today: https://psfmember.org/civicrm/contribute/transact?reset=1&id=20 - - - Links - ----- - - * Website: https://www.palletsprojects.com/p/flask/ - * Documentation: http://flask.pocoo.org/docs/ - * License: `BSD `_ - * Releases: https://pypi.org/project/Flask/ - * Code: https://github.com/pallets/flask - * Issue tracker: https://github.com/pallets/flask/issues - * Test status: - - * Linux, Mac: https://travis-ci.org/pallets/flask - * Windows: https://ci.appveyor.com/project/pallets/flask - - * Test coverage: https://codecov.io/gh/pallets/flask - - .. _WSGI: https://wsgi.readthedocs.io - .. _Werkzeug: https://www.palletsprojects.com/p/werkzeug/ - .. _Jinja: https://www.palletsprojects.com/p/jinja/ - .. _pip: https://pip.pypa.io/en/stable/quickstart/ - -Platform: any -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Web Environment -Classifier: Framework :: Flask -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: BSD License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content -Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application -Classifier: Topic :: Software Development :: Libraries :: Application Frameworks -Classifier: Topic :: Software Development :: Libraries :: Python Modules diff --git a/pyextra/Flask-1.0.2-py2.7.egg-info/SOURCES.txt b/pyextra/Flask-1.0.2-py2.7.egg-info/SOURCES.txt deleted file mode 100644 index 52f6db1918a045..00000000000000 --- a/pyextra/Flask-1.0.2-py2.7.egg-info/SOURCES.txt +++ /dev/null @@ -1,223 +0,0 @@ -AUTHORS -CHANGES.rst -LICENSE -MANIFEST.in -Makefile -README.rst -setup.cfg -setup.py -tox.ini -Flask.egg-info/PKG-INFO -Flask.egg-info/SOURCES.txt -Flask.egg-info/dependency_links.txt -Flask.egg-info/entry_points.txt -Flask.egg-info/not-zip-safe -Flask.egg-info/requires.txt -Flask.egg-info/top_level.txt -artwork/LICENSE -artwork/logo-full.svg -artwork/logo-lineart.svg -docs/Makefile -docs/advanced_foreword.rst -docs/api.rst -docs/appcontext.rst -docs/becomingbig.rst -docs/blueprints.rst -docs/changelog.rst -docs/cli.rst -docs/conf.py -docs/config.rst -docs/contents.rst.inc -docs/contributing.rst -docs/design.rst -docs/errorhandling.rst -docs/extensiondev.rst -docs/extensions.rst -docs/flaskstyle.sty -docs/foreword.rst -docs/htmlfaq.rst -docs/index.rst -docs/installation.rst -docs/latexindex.rst -docs/license.rst -docs/logging.rst -docs/logo.pdf -docs/make.bat -docs/quickstart.rst -docs/reqcontext.rst -docs/security.rst -docs/server.rst -docs/shell.rst -docs/signals.rst -docs/styleguide.rst -docs/templating.rst -docs/testing.rst -docs/unicode.rst -docs/upgrading.rst -docs/views.rst -docs/_static/debugger.png -docs/_static/flask-favicon.ico -docs/_static/flask.png -docs/_static/logo-full.png -docs/_static/no.png -docs/_static/pycharm-runconfig.png -docs/_static/touch-icon.png -docs/_static/yes.png -docs/deploying/cgi.rst -docs/deploying/fastcgi.rst -docs/deploying/index.rst -docs/deploying/mod_wsgi.rst -docs/deploying/uwsgi.rst -docs/deploying/wsgi-standalone.rst -docs/patterns/apierrors.rst -docs/patterns/appdispatch.rst -docs/patterns/appfactories.rst -docs/patterns/caching.rst -docs/patterns/celery.rst -docs/patterns/deferredcallbacks.rst -docs/patterns/distribute.rst -docs/patterns/errorpages.rst -docs/patterns/fabric.rst -docs/patterns/favicon.rst -docs/patterns/fileuploads.rst -docs/patterns/flashing.rst -docs/patterns/index.rst -docs/patterns/jquery.rst -docs/patterns/lazyloading.rst -docs/patterns/methodoverrides.rst -docs/patterns/mongokit.rst -docs/patterns/packages.rst -docs/patterns/requestchecksum.rst -docs/patterns/sqlalchemy.rst -docs/patterns/sqlite3.rst -docs/patterns/streaming.rst -docs/patterns/subclassing.rst -docs/patterns/templateinheritance.rst -docs/patterns/urlprocessors.rst -docs/patterns/viewdecorators.rst -docs/patterns/wtforms.rst -docs/tutorial/blog.rst -docs/tutorial/database.rst -docs/tutorial/deploy.rst -docs/tutorial/factory.rst -docs/tutorial/flaskr_edit.png -docs/tutorial/flaskr_index.png -docs/tutorial/flaskr_login.png -docs/tutorial/index.rst -docs/tutorial/install.rst -docs/tutorial/layout.rst -docs/tutorial/next.rst -docs/tutorial/static.rst -docs/tutorial/templates.rst -docs/tutorial/tests.rst -docs/tutorial/views.rst -examples/javascript/.gitignore -examples/javascript/LICENSE -examples/javascript/MANIFEST.in -examples/javascript/README.rst -examples/javascript/setup.cfg -examples/javascript/setup.py -examples/javascript/js_example/__init__.py -examples/javascript/js_example/views.py -examples/javascript/js_example/templates/base.html -examples/javascript/js_example/templates/fetch.html -examples/javascript/js_example/templates/jquery.html -examples/javascript/js_example/templates/plain.html -examples/javascript/tests/conftest.py -examples/javascript/tests/test_js_example.py -examples/tutorial/.gitignore -examples/tutorial/LICENSE -examples/tutorial/MANIFEST.in -examples/tutorial/README.rst -examples/tutorial/setup.cfg -examples/tutorial/setup.py -examples/tutorial/flaskr/__init__.py -examples/tutorial/flaskr/auth.py -examples/tutorial/flaskr/blog.py -examples/tutorial/flaskr/db.py -examples/tutorial/flaskr/schema.sql -examples/tutorial/flaskr/static/style.css -examples/tutorial/flaskr/templates/base.html -examples/tutorial/flaskr/templates/auth/login.html -examples/tutorial/flaskr/templates/auth/register.html -examples/tutorial/flaskr/templates/blog/create.html -examples/tutorial/flaskr/templates/blog/index.html -examples/tutorial/flaskr/templates/blog/update.html -examples/tutorial/tests/conftest.py -examples/tutorial/tests/data.sql -examples/tutorial/tests/test_auth.py -examples/tutorial/tests/test_blog.py -examples/tutorial/tests/test_db.py -examples/tutorial/tests/test_factory.py -flask/__init__.py -flask/__main__.py -flask/_compat.py -flask/app.py -flask/blueprints.py -flask/cli.py -flask/config.py -flask/ctx.py -flask/debughelpers.py -flask/globals.py -flask/helpers.py -flask/logging.py -flask/sessions.py -flask/signals.py -flask/templating.py -flask/testing.py -flask/views.py -flask/wrappers.py -flask/json/__init__.py -flask/json/tag.py -tests/conftest.py -tests/test_appctx.py -tests/test_basic.py -tests/test_blueprints.py -tests/test_cli.py -tests/test_config.py -tests/test_helpers.py -tests/test_instance_config.py -tests/test_json_tag.py -tests/test_logging.py -tests/test_regression.py -tests/test_reqctx.py -tests/test_signals.py -tests/test_subclassing.py -tests/test_templating.py -tests/test_testing.py -tests/test_user_error_handler.py -tests/test_views.py -tests/static/config.json -tests/static/index.html -tests/templates/_macro.html -tests/templates/context_template.html -tests/templates/escaping_template.html -tests/templates/mail.txt -tests/templates/non_escaping_template.txt -tests/templates/simple_template.html -tests/templates/template_filter.html -tests/templates/template_test.html -tests/templates/nested/nested.txt -tests/test_apps/.env -tests/test_apps/.flaskenv -tests/test_apps/blueprintapp/__init__.py -tests/test_apps/blueprintapp/apps/__init__.py -tests/test_apps/blueprintapp/apps/admin/__init__.py -tests/test_apps/blueprintapp/apps/admin/static/test.txt -tests/test_apps/blueprintapp/apps/admin/static/css/test.css -tests/test_apps/blueprintapp/apps/admin/templates/admin/index.html -tests/test_apps/blueprintapp/apps/frontend/__init__.py -tests/test_apps/blueprintapp/apps/frontend/templates/frontend/index.html -tests/test_apps/cliapp/__init__.py -tests/test_apps/cliapp/app.py -tests/test_apps/cliapp/factory.py -tests/test_apps/cliapp/importerrorapp.py -tests/test_apps/cliapp/message.txt -tests/test_apps/cliapp/multiapp.py -tests/test_apps/cliapp/inner1/__init__.py -tests/test_apps/cliapp/inner1/inner2/__init__.py -tests/test_apps/cliapp/inner1/inner2/flask.py -tests/test_apps/helloworld/hello.py -tests/test_apps/helloworld/wsgi.py -tests/test_apps/subdomaintestmodule/__init__.py -tests/test_apps/subdomaintestmodule/static/hello.txt \ No newline at end of file diff --git a/pyextra/Flask-1.0.2-py2.7.egg-info/entry_points.txt b/pyextra/Flask-1.0.2-py2.7.egg-info/entry_points.txt deleted file mode 100644 index 1eb025200e62eb..00000000000000 --- a/pyextra/Flask-1.0.2-py2.7.egg-info/entry_points.txt +++ /dev/null @@ -1,3 +0,0 @@ -[console_scripts] -flask = flask.cli:main - diff --git a/pyextra/Flask-1.0.2-py2.7.egg-info/installed-files.txt b/pyextra/Flask-1.0.2-py2.7.egg-info/installed-files.txt deleted file mode 100644 index 150041120d31e5..00000000000000 --- a/pyextra/Flask-1.0.2-py2.7.egg-info/installed-files.txt +++ /dev/null @@ -1,48 +0,0 @@ -../flask/testing.py -../flask/templating.py -../flask/__main__.py -../flask/sessions.py -../flask/signals.py -../flask/helpers.py -../flask/debughelpers.py -../flask/wrappers.py -../flask/app.py -../flask/ctx.py -../flask/config.py -../flask/logging.py -../flask/blueprints.py -../flask/views.py -../flask/cli.py -../flask/_compat.py -../flask/globals.py -../flask/__init__.py -../flask/json/tag.py -../flask/json/__init__.py -../flask/testing.pyc -../flask/templating.pyc -../flask/__main__.pyc -../flask/sessions.pyc -../flask/signals.pyc -../flask/helpers.pyc -../flask/debughelpers.pyc -../flask/wrappers.pyc -../flask/app.pyc -../flask/ctx.pyc -../flask/config.pyc -../flask/logging.pyc -../flask/blueprints.pyc -../flask/views.pyc -../flask/cli.pyc -../flask/_compat.pyc -../flask/globals.pyc -../flask/__init__.pyc -../flask/json/tag.pyc -../flask/json/__init__.pyc -not-zip-safe -entry_points.txt -dependency_links.txt -PKG-INFO -top_level.txt -requires.txt -SOURCES.txt -../../../../bin/flask diff --git a/pyextra/Flask-1.0.2-py2.7.egg-info/not-zip-safe b/pyextra/Flask-1.0.2-py2.7.egg-info/not-zip-safe deleted file mode 100644 index 8b137891791fe9..00000000000000 --- a/pyextra/Flask-1.0.2-py2.7.egg-info/not-zip-safe +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pyextra/Flask-1.0.2-py2.7.egg-info/requires.txt b/pyextra/Flask-1.0.2-py2.7.egg-info/requires.txt deleted file mode 100644 index f51579ea91ca2e..00000000000000 --- a/pyextra/Flask-1.0.2-py2.7.egg-info/requires.txt +++ /dev/null @@ -1,20 +0,0 @@ -Werkzeug>=0.14 -Jinja2>=2.10 -itsdangerous>=0.24 -click>=5.1 - -[dev] -pytest>=3 -coverage -tox -sphinx -pallets-sphinx-themes -sphinxcontrib-log-cabinet - -[docs] -sphinx -pallets-sphinx-themes -sphinxcontrib-log-cabinet - -[dotenv] -python-dotenv diff --git a/pyextra/Flask-1.0.2-py2.7.egg-info/top_level.txt b/pyextra/Flask-1.0.2-py2.7.egg-info/top_level.txt deleted file mode 100644 index 7e1060246fd674..00000000000000 --- a/pyextra/Flask-1.0.2-py2.7.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -flask diff --git a/pyextra/Jinja2-2.10-py2.7.egg-info/PKG-INFO b/pyextra/Jinja2-2.10-py2.7.egg-info/PKG-INFO deleted file mode 100644 index b4398d64900217..00000000000000 --- a/pyextra/Jinja2-2.10-py2.7.egg-info/PKG-INFO +++ /dev/null @@ -1,62 +0,0 @@ -Metadata-Version: 1.1 -Name: Jinja2 -Version: 2.10 -Summary: A small but fast and easy to use stand-alone template engine written in pure python. -Home-page: http://jinja.pocoo.org/ -Author: Armin Ronacher -Author-email: armin.ronacher@active-4.com -License: BSD -Description: - Jinja2 - ~~~~~~ - - Jinja2 is a template engine written in pure Python. It provides a - `Django`_ inspired non-XML syntax but supports inline expressions and - an optional `sandboxed`_ environment. - - Nutshell - -------- - - Here a small example of a Jinja template:: - - {% extends 'base.html' %} - {% block title %}Memberlist{% endblock %} - {% block content %} -

- {% endblock %} - - Philosophy - ---------- - - Application logic is for the controller but don't try to make the life - for the template designer too hard by giving him too few functionality. - - For more informations visit the new `Jinja2 webpage`_ and `documentation`_. - - .. _sandboxed: https://en.wikipedia.org/wiki/Sandbox_(computer_security) - .. _Django: https://www.djangoproject.com/ - .. _Jinja2 webpage: http://jinja.pocoo.org/ - .. _documentation: http://jinja.pocoo.org/2/documentation/ - -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Web Environment -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: BSD License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.6 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: Text Processing :: Markup :: HTML diff --git a/pyextra/Jinja2-2.10-py2.7.egg-info/SOURCES.txt b/pyextra/Jinja2-2.10-py2.7.egg-info/SOURCES.txt deleted file mode 100644 index 93158e1f63bcee..00000000000000 --- a/pyextra/Jinja2-2.10-py2.7.egg-info/SOURCES.txt +++ /dev/null @@ -1,133 +0,0 @@ -AUTHORS -CHANGES.rst -LICENSE -MANIFEST.in -README.rst -setup.cfg -setup.py -Jinja2.egg-info/PKG-INFO -Jinja2.egg-info/SOURCES.txt -Jinja2.egg-info/dependency_links.txt -Jinja2.egg-info/entry_points.txt -Jinja2.egg-info/not-zip-safe -Jinja2.egg-info/requires.txt -Jinja2.egg-info/top_level.txt -artwork/jinjalogo.svg -docs/Makefile -docs/api.rst -docs/cache_extension.py -docs/changelog.rst -docs/conf.py -docs/contents.rst.inc -docs/extensions.rst -docs/faq.rst -docs/index.rst -docs/integration.rst -docs/intro.rst -docs/jinjaext.py -docs/jinjastyle.sty -docs/latexindex.rst -docs/logo.pdf -docs/nativetypes.rst -docs/sandbox.rst -docs/switching.rst -docs/templates.rst -docs/tricks.rst -docs/_static/.ignore -docs/_static/jinja-small.png -docs/_templates/sidebarintro.html -docs/_templates/sidebarlogo.html -docs/_themes/LICENSE -docs/_themes/README -docs/_themes/jinja/layout.html -docs/_themes/jinja/relations.html -docs/_themes/jinja/theme.conf -docs/_themes/jinja/static/jinja.css_t -examples/bench.py -examples/profile.py -examples/basic/cycle.py -examples/basic/debugger.py -examples/basic/inheritance.py -examples/basic/test.py -examples/basic/test_filter_and_linestatements.py -examples/basic/test_loop_filter.py -examples/basic/translate.py -examples/basic/templates/broken.html -examples/basic/templates/subbroken.html -examples/rwbench/djangoext.py -examples/rwbench/rwbench.py -examples/rwbench/django/_form.html -examples/rwbench/django/_input_field.html -examples/rwbench/django/_textarea.html -examples/rwbench/django/index.html -examples/rwbench/django/layout.html -examples/rwbench/genshi/helpers.html -examples/rwbench/genshi/index.html -examples/rwbench/genshi/layout.html -examples/rwbench/jinja/helpers.html -examples/rwbench/jinja/index.html -examples/rwbench/jinja/layout.html -examples/rwbench/mako/helpers.html -examples/rwbench/mako/index.html -examples/rwbench/mako/layout.html -ext/djangojinja2.py -ext/inlinegettext.py -ext/jinja.el -ext/Vim/jinja.vim -ext/django2jinja/django2jinja.py -ext/django2jinja/example.py -ext/django2jinja/templates/index.html -ext/django2jinja/templates/layout.html -ext/django2jinja/templates/subtemplate.html -jinja2/__init__.py -jinja2/_compat.py -jinja2/_identifier.py -jinja2/asyncfilters.py -jinja2/asyncsupport.py -jinja2/bccache.py -jinja2/compiler.py -jinja2/constants.py -jinja2/debug.py -jinja2/defaults.py -jinja2/environment.py -jinja2/exceptions.py -jinja2/ext.py -jinja2/filters.py -jinja2/idtracking.py -jinja2/lexer.py -jinja2/loaders.py -jinja2/meta.py -jinja2/nativetypes.py -jinja2/nodes.py -jinja2/optimizer.py -jinja2/parser.py -jinja2/runtime.py -jinja2/sandbox.py -jinja2/tests.py -jinja2/utils.py -jinja2/visitor.py -tests/conftest.py -tests/test_api.py -tests/test_async.py -tests/test_asyncfilters.py -tests/test_bytecode_cache.py -tests/test_core_tags.py -tests/test_debug.py -tests/test_ext.py -tests/test_features.py -tests/test_filters.py -tests/test_idtracking.py -tests/test_imports.py -tests/test_inheritance.py -tests/test_lexnparse.py -tests/test_loader.py -tests/test_nativetypes.py -tests/test_regression.py -tests/test_security.py -tests/test_tests.py -tests/test_utils.py -tests/res/__init__.py -tests/res/templates/broken.html -tests/res/templates/syntaxerror.html -tests/res/templates/test.html -tests/res/templates/foo/test.html \ No newline at end of file diff --git a/pyextra/Jinja2-2.10-py2.7.egg-info/dependency_links.txt b/pyextra/Jinja2-2.10-py2.7.egg-info/dependency_links.txt deleted file mode 100644 index 8b137891791fe9..00000000000000 --- a/pyextra/Jinja2-2.10-py2.7.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pyextra/Jinja2-2.10-py2.7.egg-info/entry_points.txt b/pyextra/Jinja2-2.10-py2.7.egg-info/entry_points.txt deleted file mode 100644 index 32e6b753028430..00000000000000 --- a/pyextra/Jinja2-2.10-py2.7.egg-info/entry_points.txt +++ /dev/null @@ -1,4 +0,0 @@ - - [babel.extractors] - jinja2 = jinja2.ext:babel_extract[i18n] - \ No newline at end of file diff --git a/pyextra/Jinja2-2.10-py2.7.egg-info/installed-files.txt b/pyextra/Jinja2-2.10-py2.7.egg-info/installed-files.txt deleted file mode 100644 index c2af213acef197..00000000000000 --- a/pyextra/Jinja2-2.10-py2.7.egg-info/installed-files.txt +++ /dev/null @@ -1,61 +0,0 @@ -../jinja2/lexer.py -../jinja2/idtracking.py -../jinja2/_identifier.py -../jinja2/nodes.py -../jinja2/asyncfilters.py -../jinja2/loaders.py -../jinja2/defaults.py -../jinja2/meta.py -../jinja2/compiler.py -../jinja2/environment.py -../jinja2/tests.py -../jinja2/sandbox.py -../jinja2/filters.py -../jinja2/exceptions.py -../jinja2/asyncsupport.py -../jinja2/visitor.py -../jinja2/constants.py -../jinja2/utils.py -../jinja2/ext.py -../jinja2/optimizer.py -../jinja2/nativetypes.py -../jinja2/parser.py -../jinja2/runtime.py -../jinja2/debug.py -../jinja2/_compat.py -../jinja2/bccache.py -../jinja2/__init__.py -../jinja2/lexer.pyc -../jinja2/idtracking.pyc -../jinja2/_identifier.pyc -../jinja2/nodes.pyc -../jinja2/asyncfilters.pyc -../jinja2/loaders.pyc -../jinja2/defaults.pyc -../jinja2/meta.pyc -../jinja2/compiler.pyc -../jinja2/environment.pyc -../jinja2/tests.pyc -../jinja2/sandbox.pyc -../jinja2/filters.pyc -../jinja2/exceptions.pyc -../jinja2/asyncsupport.pyc -../jinja2/visitor.pyc -../jinja2/constants.pyc -../jinja2/utils.pyc -../jinja2/ext.pyc -../jinja2/optimizer.pyc -../jinja2/nativetypes.pyc -../jinja2/parser.pyc -../jinja2/runtime.pyc -../jinja2/debug.pyc -../jinja2/_compat.pyc -../jinja2/bccache.pyc -../jinja2/__init__.pyc -not-zip-safe -entry_points.txt -dependency_links.txt -PKG-INFO -top_level.txt -requires.txt -SOURCES.txt diff --git a/pyextra/Jinja2-2.10-py2.7.egg-info/not-zip-safe b/pyextra/Jinja2-2.10-py2.7.egg-info/not-zip-safe deleted file mode 100644 index 8b137891791fe9..00000000000000 --- a/pyextra/Jinja2-2.10-py2.7.egg-info/not-zip-safe +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pyextra/Jinja2-2.10-py2.7.egg-info/requires.txt b/pyextra/Jinja2-2.10-py2.7.egg-info/requires.txt deleted file mode 100644 index 1d74a32c66fb4b..00000000000000 --- a/pyextra/Jinja2-2.10-py2.7.egg-info/requires.txt +++ /dev/null @@ -1,4 +0,0 @@ -MarkupSafe>=0.23 - -[i18n] -Babel>=0.8 diff --git a/pyextra/Jinja2-2.10-py2.7.egg-info/top_level.txt b/pyextra/Jinja2-2.10-py2.7.egg-info/top_level.txt deleted file mode 100644 index 7f7afbf3bf54b3..00000000000000 --- a/pyextra/Jinja2-2.10-py2.7.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -jinja2 diff --git a/pyextra/Jinja2-2.9.6.dist-info/DESCRIPTION.rst b/pyextra/Jinja2-2.9.6.dist-info/DESCRIPTION.rst deleted file mode 100644 index 4421f046e25436..00000000000000 --- a/pyextra/Jinja2-2.9.6.dist-info/DESCRIPTION.rst +++ /dev/null @@ -1,36 +0,0 @@ -Jinja2 -~~~~~~ - -Jinja2 is a template engine written in pure Python. It provides a -`Django`_ inspired non-XML syntax but supports inline expressions and -an optional `sandboxed`_ environment. - -Nutshell --------- - -Here a small example of a Jinja template:: - - {% extends 'base.html' %} - {% block title %}Memberlist{% endblock %} - {% block content %} - - {% endblock %} - -Philosophy ----------- - -Application logic is for the controller but don't try to make the life -for the template designer too hard by giving him too few functionality. - -For more informations visit the new `Jinja2 webpage`_ and `documentation`_. - -.. _sandboxed: http://en.wikipedia.org/wiki/Sandbox_(computer_security) -.. _Django: http://www.djangoproject.com/ -.. _Jinja2 webpage: http://jinja.pocoo.org/ -.. _documentation: http://jinja.pocoo.org/2/documentation/ - - diff --git a/pyextra/Jinja2-2.9.6.dist-info/INSTALLER b/pyextra/Jinja2-2.9.6.dist-info/INSTALLER deleted file mode 100644 index a1b589e38a3204..00000000000000 --- a/pyextra/Jinja2-2.9.6.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/pyextra/Jinja2-2.9.6.dist-info/LICENSE.txt b/pyextra/Jinja2-2.9.6.dist-info/LICENSE.txt deleted file mode 100644 index 10145a264342b7..00000000000000 --- a/pyextra/Jinja2-2.9.6.dist-info/LICENSE.txt +++ /dev/null @@ -1,31 +0,0 @@ -Copyright (c) 2009 by the Jinja Team, see AUTHORS for more details. - -Some 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. - - * The names of the contributors may not 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. diff --git a/pyextra/Jinja2-2.9.6.dist-info/METADATA b/pyextra/Jinja2-2.9.6.dist-info/METADATA deleted file mode 100644 index ea69de1726d02c..00000000000000 --- a/pyextra/Jinja2-2.9.6.dist-info/METADATA +++ /dev/null @@ -1,65 +0,0 @@ -Metadata-Version: 2.0 -Name: Jinja2 -Version: 2.9.6 -Summary: A small but fast and easy to use stand-alone template engine written in pure python. -Home-page: http://jinja.pocoo.org/ -Author: Armin Ronacher -Author-email: armin.ronacher@active-4.com -License: BSD -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Web Environment -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: BSD License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.6 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: Text Processing :: Markup :: HTML -Requires-Dist: MarkupSafe (>=0.23) -Provides-Extra: i18n -Requires-Dist: Babel (>=0.8); extra == 'i18n' - -Jinja2 -~~~~~~ - -Jinja2 is a template engine written in pure Python. It provides a -`Django`_ inspired non-XML syntax but supports inline expressions and -an optional `sandboxed`_ environment. - -Nutshell --------- - -Here a small example of a Jinja template:: - - {% extends 'base.html' %} - {% block title %}Memberlist{% endblock %} - {% block content %} - - {% endblock %} - -Philosophy ----------- - -Application logic is for the controller but don't try to make the life -for the template designer too hard by giving him too few functionality. - -For more informations visit the new `Jinja2 webpage`_ and `documentation`_. - -.. _sandboxed: http://en.wikipedia.org/wiki/Sandbox_(computer_security) -.. _Django: http://www.djangoproject.com/ -.. _Jinja2 webpage: http://jinja.pocoo.org/ -.. _documentation: http://jinja.pocoo.org/2/documentation/ - - diff --git a/pyextra/Jinja2-2.9.6.dist-info/RECORD b/pyextra/Jinja2-2.9.6.dist-info/RECORD deleted file mode 100644 index 024e3899105f0d..00000000000000 --- a/pyextra/Jinja2-2.9.6.dist-info/RECORD +++ /dev/null @@ -1,59 +0,0 @@ -jinja2/__init__.py,sha256=Cx_UnJO4i_GqvKQsOu__mvGE_eMJSsBqITa26irtg5A,2565 -jinja2/_compat.py,sha256=xP60CE5Qr8FTYcDE1f54tbZLKGvMwYml4-8T7Q4KG9k,2596 -jinja2/_stringdefs.py,sha256=PYtqTmmWIhjXlFBoH-eE6fJkQvlu7nxUyQ2YlFB97VA,589381 -jinja2/asyncfilters.py,sha256=cTDPvrS8Hp_IkwsZ1m9af_lr5nHysw7uTa5gV0NmZVE,4144 -jinja2/asyncsupport.py,sha256=ZJO1Fdd9R93sDLrk6TZNuMQGgtuDmpTlENNRkLwZF7c,7765 -jinja2/bccache.py,sha256=0xoVw0R9nj3vtzPl9g-zB5BKTLFJ7FFMq2ABbn1IkCI,12793 -jinja2/compiler.py,sha256=lE5owyPwT1cGGZxWyzQtZLW7Uj1g3Vw1oVtBU8Uc_uM,62929 -jinja2/constants.py,sha256=uwwV8ZUhHhacAuz5PTwckfsbqBaqM7aKfyJL7kGX5YQ,1626 -jinja2/debug.py,sha256=UqEbKb4zofBABwvyA77Kr0-5IAQawKqC9t8ZeTIzpGU,12038 -jinja2/defaults.py,sha256=GvVEQqIRvRMCbQF2NZSr0mlEN8lxvGixU5wIIAeRe1A,1323 -jinja2/environment.py,sha256=z91L_efdYs-KNs6DBxQWDyYncOwOqn_0J4M5CfFj0Q8,50848 -jinja2/exceptions.py,sha256=_Rj-NVi98Q6AiEjYQOsP8dEIdu5AlmRHzcSNOPdWix4,4428 -jinja2/ext.py,sha256=9xq8fd_QPBIe4Z7hE1XawB7f1EDHrVZjpb2JiRTiG94,23867 -jinja2/filters.py,sha256=1OYGhyN84yVmFUIOwJNRV_StqTCfPhnRLfJTmWbEe_8,33424 -jinja2/idtracking.py,sha256=HHcCOMsQhCrrjwYAmikKqq_XetXLovCjXAThh9WbRAc,8760 -jinja2/lexer.py,sha256=W4A830e-fj12zRT6rL7H91F4D6xwED5LjR8iMxjWuVQ,28238 -jinja2/loaders.py,sha256=xiTuURKAEObyym0nU8PCIXu_Qp8fn0AJ5oIADUUm-5Q,17382 -jinja2/meta.py,sha256=fmKHxkmZYAOm9QyWWy8EMd6eefAIh234rkBMW2X4ZR8,4340 -jinja2/nodes.py,sha256=4_Ucxbkohtj4BAlpV0w_MpVmIxJNaVXDTBb4EHBA2JI,29392 -jinja2/optimizer.py,sha256=MsdlFACJ0FRdPtjmCAdt7JQ9SGrXFaDNUaslsWQaG3M,1722 -jinja2/parser.py,sha256=3tc82qO1Ovs9och_PjirbAmnWNT77n4wWjIQ8pEVKvU,35465 -jinja2/runtime.py,sha256=axkTQXg2-oc_Cm35NEMDDas3Jbq3ATxNrDOEa5v3wIw,26835 -jinja2/sandbox.py,sha256=Jx4MTxly8KvdkSWyui_kHY1_ZZ0RAQL4ojAy1KDRyK0,16707 -jinja2/tests.py,sha256=iFuUTbUYv7TFffq2aTswCRdIhQ6wyrby1YevChVPqkE,4428 -jinja2/utils.py,sha256=BIFqeXXsCUSjWx6MEwYhY6V4tXzVNs9WRXfB60MA9HY,19941 -jinja2/visitor.py,sha256=JD1H1cANA29JcntFfN5fPyqQxB4bI4wC00BzZa-XHks,3316 -Jinja2-2.9.6.dist-info/DESCRIPTION.rst,sha256=CXIS1UnPSk5_lZBS6Lb8ko-3lqGfjsiUwNBLXCTj2lc,975 -Jinja2-2.9.6.dist-info/entry_points.txt,sha256=NdzVcOrqyNyKDxD09aERj__3bFx2paZhizFDsKmVhiA,72 -Jinja2-2.9.6.dist-info/LICENSE.txt,sha256=JvzUNv3Io51EiWrAPm8d_SXjhJnEjyDYvB3Tvwqqils,1554 -Jinja2-2.9.6.dist-info/METADATA,sha256=53LSXlqC86JTyLSPsDyAOmyV4pXIzzmmZoUXz7ogytA,2172 -Jinja2-2.9.6.dist-info/metadata.json,sha256=vzvX25T4hwMOe1EIOBo9rpfiZerOB_KVLcplGG_qYtE,1394 -Jinja2-2.9.6.dist-info/RECORD,, -Jinja2-2.9.6.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7 -Jinja2-2.9.6.dist-info/WHEEL,sha256=AvR0WeTpDaxT645bl5FQxUK6NPsTls2ttpcGJg3j1Xg,110 -Jinja2-2.9.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -jinja2/_compat.pyc,, -jinja2/sandbox.pyc,, -jinja2/_stringdefs.pyc,, -jinja2/bccache.pyc,, -jinja2/runtime.pyc,, -jinja2/utils.pyc,, -jinja2/parser.pyc,, -jinja2/debug.pyc,, -jinja2/lexer.pyc,, -jinja2/defaults.pyc,, -jinja2/visitor.pyc,, -jinja2/nodes.pyc,, -jinja2/environment.pyc,, -jinja2/compiler.pyc,, -jinja2/exceptions.pyc,, -jinja2/filters.pyc,, -jinja2/__init__.pyc,, -jinja2/meta.pyc,, -jinja2/loaders.pyc,, -jinja2/ext.pyc,, -jinja2/optimizer.pyc,, -jinja2/constants.pyc,, -jinja2/tests.pyc,, -jinja2/idtracking.pyc,, diff --git a/pyextra/Jinja2-2.9.6.dist-info/WHEEL b/pyextra/Jinja2-2.9.6.dist-info/WHEEL deleted file mode 100644 index 9dff69d86102d3..00000000000000 --- a/pyextra/Jinja2-2.9.6.dist-info/WHEEL +++ /dev/null @@ -1,6 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.24.0) -Root-Is-Purelib: true -Tag: py2-none-any -Tag: py3-none-any - diff --git a/pyextra/Jinja2-2.9.6.dist-info/entry_points.txt b/pyextra/Jinja2-2.9.6.dist-info/entry_points.txt deleted file mode 100644 index 32e6b753028430..00000000000000 --- a/pyextra/Jinja2-2.9.6.dist-info/entry_points.txt +++ /dev/null @@ -1,4 +0,0 @@ - - [babel.extractors] - jinja2 = jinja2.ext:babel_extract[i18n] - \ No newline at end of file diff --git a/pyextra/Jinja2-2.9.6.dist-info/metadata.json b/pyextra/Jinja2-2.9.6.dist-info/metadata.json deleted file mode 100644 index 9bbf942f131b6b..00000000000000 --- a/pyextra/Jinja2-2.9.6.dist-info/metadata.json +++ /dev/null @@ -1 +0,0 @@ -{"license": "BSD", "name": "Jinja2", "metadata_version": "2.0", "generator": "bdist_wheel (0.24.0)", "summary": "A small but fast and easy to use stand-alone template engine written in pure python.", "run_requires": [{"requires": ["Babel (>=0.8)"], "extra": "i18n"}, {"requires": ["MarkupSafe (>=0.23)"]}], "version": "2.9.6", "extensions": {"python.details": {"project_urls": {"Home": "http://jinja.pocoo.org/"}, "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "contacts": [{"role": "author", "email": "armin.ronacher@active-4.com", "name": "Armin Ronacher"}]}, "python.exports": {"babel.extractors": {"jinja2": "jinja2.ext:babel_extract [i18n]"}}}, "classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Text Processing :: Markup :: HTML"], "extras": ["i18n"]} \ No newline at end of file diff --git a/pyextra/Jinja2-2.9.6.dist-info/top_level.txt b/pyextra/Jinja2-2.9.6.dist-info/top_level.txt deleted file mode 100644 index 7f7afbf3bf54b3..00000000000000 --- a/pyextra/Jinja2-2.9.6.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -jinja2 diff --git a/pyextra/MarkupSafe-1.0-py2.7.egg-info/PKG-INFO b/pyextra/MarkupSafe-1.0-py2.7.egg-info/PKG-INFO deleted file mode 100644 index 6f2568f66ca65e..00000000000000 --- a/pyextra/MarkupSafe-1.0-py2.7.egg-info/PKG-INFO +++ /dev/null @@ -1,133 +0,0 @@ -Metadata-Version: 1.1 -Name: MarkupSafe -Version: 1.0 -Summary: Implements a XML/HTML/XHTML Markup safe string for Python -Home-page: http://github.com/pallets/markupsafe -Author: Armin Ronacher -Author-email: armin.ronacher@active-4.com -License: BSD -Description: MarkupSafe - ========== - - Implements a unicode subclass that supports HTML strings: - - .. code-block:: python - - >>> from markupsafe import Markup, escape - >>> escape("") - Markup(u'<script>alert(document.cookie);</script>') - >>> tmpl = Markup("%s") - >>> tmpl % "Peter > Lustig" - Markup(u'Peter > Lustig') - - If you want to make an object unicode that is not yet unicode - but don't want to lose the taint information, you can use the - ``soft_unicode`` function. (On Python 3 you can also use ``soft_str`` which - is a different name for the same function). - - .. code-block:: python - - >>> from markupsafe import soft_unicode - >>> soft_unicode(42) - u'42' - >>> soft_unicode(Markup('foo')) - Markup(u'foo') - - HTML Representations - -------------------- - - Objects can customize their HTML markup equivalent by overriding - the ``__html__`` function: - - .. code-block:: python - - >>> class Foo(object): - ... def __html__(self): - ... return 'Nice' - ... - >>> escape(Foo()) - Markup(u'Nice') - >>> Markup(Foo()) - Markup(u'Nice') - - Silent Escapes - -------------- - - Since MarkupSafe 0.10 there is now also a separate escape function - called ``escape_silent`` that returns an empty string for ``None`` for - consistency with other systems that return empty strings for ``None`` - when escaping (for instance Pylons' webhelpers). - - If you also want to use this for the escape method of the Markup - object, you can create your own subclass that does that: - - .. code-block:: python - - from markupsafe import Markup, escape_silent as escape - - class SilentMarkup(Markup): - __slots__ = () - - @classmethod - def escape(cls, s): - return cls(escape(s)) - - New-Style String Formatting - --------------------------- - - Starting with MarkupSafe 0.21 new style string formats from Python 2.6 and - 3.x are now fully supported. Previously the escape behavior of those - functions was spotty at best. The new implementations operates under the - following algorithm: - - 1. if an object has an ``__html_format__`` method it is called as - replacement for ``__format__`` with the format specifier. It either - has to return a string or markup object. - 2. if an object has an ``__html__`` method it is called. - 3. otherwise the default format system of Python kicks in and the result - is HTML escaped. - - Here is how you can implement your own formatting: - - .. code-block:: python - - class User(object): - - def __init__(self, id, username): - self.id = id - self.username = username - - def __html_format__(self, format_spec): - if format_spec == 'link': - return Markup('{1}').format( - self.id, - self.__html__(), - ) - elif format_spec: - raise ValueError('Invalid format spec') - return self.__html__() - - def __html__(self): - return Markup('{0}').format(self.username) - - And to format that user: - - .. code-block:: python - - >>> user = User(1, 'foo') - >>> Markup('

User: {0:link}').format(user) - Markup(u'

User: foo') - - Markupsafe supports Python 2.6, 2.7 and Python 3.3 and higher. - -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Web Environment -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: BSD License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: Text Processing :: Markup :: HTML diff --git a/pyextra/MarkupSafe-1.0-py2.7.egg-info/SOURCES.txt b/pyextra/MarkupSafe-1.0-py2.7.egg-info/SOURCES.txt deleted file mode 100644 index 210b339ced2829..00000000000000 --- a/pyextra/MarkupSafe-1.0-py2.7.egg-info/SOURCES.txt +++ /dev/null @@ -1,18 +0,0 @@ -AUTHORS -CHANGES -LICENSE -MANIFEST.in -README.rst -setup.cfg -setup.py -tests.py -MarkupSafe.egg-info/PKG-INFO -MarkupSafe.egg-info/SOURCES.txt -MarkupSafe.egg-info/dependency_links.txt -MarkupSafe.egg-info/not-zip-safe -MarkupSafe.egg-info/top_level.txt -markupsafe/__init__.py -markupsafe/_compat.py -markupsafe/_constants.py -markupsafe/_native.py -markupsafe/_speedups.c \ No newline at end of file diff --git a/pyextra/MarkupSafe-1.0-py2.7.egg-info/dependency_links.txt b/pyextra/MarkupSafe-1.0-py2.7.egg-info/dependency_links.txt deleted file mode 100644 index 8b137891791fe9..00000000000000 --- a/pyextra/MarkupSafe-1.0-py2.7.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pyextra/MarkupSafe-1.0-py2.7.egg-info/installed-files.txt b/pyextra/MarkupSafe-1.0-py2.7.egg-info/installed-files.txt deleted file mode 100644 index 0fcc7c5405c935..00000000000000 --- a/pyextra/MarkupSafe-1.0-py2.7.egg-info/installed-files.txt +++ /dev/null @@ -1,15 +0,0 @@ -../markupsafe/__init__.py -../markupsafe/_compat.py -../markupsafe/_constants.py -../markupsafe/_native.py -../markupsafe/_speedups.c -../markupsafe/__init__.pyc -../markupsafe/_compat.pyc -../markupsafe/_constants.pyc -../markupsafe/_native.pyc -../markupsafe/_speedups.so -dependency_links.txt -not-zip-safe -PKG-INFO -SOURCES.txt -top_level.txt diff --git a/pyextra/MarkupSafe-1.0-py2.7.egg-info/not-zip-safe b/pyextra/MarkupSafe-1.0-py2.7.egg-info/not-zip-safe deleted file mode 100644 index 8b137891791fe9..00000000000000 --- a/pyextra/MarkupSafe-1.0-py2.7.egg-info/not-zip-safe +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pyextra/MarkupSafe-1.0-py2.7.egg-info/top_level.txt b/pyextra/MarkupSafe-1.0-py2.7.egg-info/top_level.txt deleted file mode 100644 index 75bf729258f9da..00000000000000 --- a/pyextra/MarkupSafe-1.0-py2.7.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -markupsafe diff --git a/pyextra/Werkzeug-0.14.1-py2.7.egg-info/PKG-INFO b/pyextra/Werkzeug-0.14.1-py2.7.egg-info/PKG-INFO deleted file mode 100644 index a0a627684d17d0..00000000000000 --- a/pyextra/Werkzeug-0.14.1-py2.7.egg-info/PKG-INFO +++ /dev/null @@ -1,104 +0,0 @@ -Metadata-Version: 1.1 -Name: Werkzeug -Version: 0.14.1 -Summary: The comprehensive WSGI web application library. -Home-page: https://www.palletsprojects.org/p/werkzeug/ -Author: Armin Ronacher -Author-email: armin.ronacher@active-4.com -License: BSD -Description: Werkzeug - ======== - - Werkzeug is a comprehensive `WSGI`_ web application library. It began as - a simple collection of various utilities for WSGI applications and has - become one of the most advanced WSGI utility libraries. - - It includes: - - * An interactive debugger that allows inspecting stack traces and source - code in the browser with an interactive interpreter for any frame in - the stack. - * A full-featured request object with objects to interact with headers, - query args, form data, files, and cookies. - * A response object that can wrap other WSGI applications and handle - streaming data. - * A routing system for matching URLs to endpoints and generating URLs - for endpoints, with an extensible system for capturing variables from - URLs. - * HTTP utilities to handle entity tags, cache control, dates, user - agents, cookies, files, and more. - * A threaded WSGI server for use while developing applications locally. - * A test client for simulating HTTP requests during testing without - requiring running a server. - - Werkzeug is Unicode aware and doesn't enforce any dependencies. It is up - to the developer to choose a template engine, database adapter, and even - how to handle requests. It can be used to build all sorts of end user - applications such as blogs, wikis, or bulletin boards. - - `Flask`_ wraps Werkzeug, using it to handle the details of WSGI while - providing more structure and patterns for defining powerful - applications. - - - Installing - ---------- - - Install and update using `pip`_: - - .. code-block:: text - - pip install -U Werkzeug - - - A Simple Example - ---------------- - - .. code-block:: python - - from werkzeug.wrappers import Request, Response - - @Request.application - def application(request): - return Response('Hello, World!') - - if __name__ == '__main__': - from werkzeug.serving import run_simple - run_simple('localhost', 4000, application) - - - Links - ----- - - * Website: https://www.palletsprojects.com/p/werkzeug/ - * Releases: https://pypi.org/project/Werkzeug/ - * Code: https://github.com/pallets/werkzeug - * Issue tracker: https://github.com/pallets/werkzeug/issues - * Test status: - - * Linux, Mac: https://travis-ci.org/pallets/werkzeug - * Windows: https://ci.appveyor.com/project/davidism/werkzeug - - * Test coverage: https://codecov.io/gh/pallets/werkzeug - - .. _WSGI: https://wsgi.readthedocs.io/en/latest/ - .. _Flask: https://www.palletsprojects.com/p/flask/ - .. _pip: https://pip.pypa.io/en/stable/quickstart/ - -Platform: any -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Web Environment -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: BSD License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.6 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content -Classifier: Topic :: Software Development :: Libraries :: Python Modules diff --git a/pyextra/Werkzeug-0.14.1-py2.7.egg-info/SOURCES.txt b/pyextra/Werkzeug-0.14.1-py2.7.egg-info/SOURCES.txt deleted file mode 100644 index 9d3b7690895811..00000000000000 --- a/pyextra/Werkzeug-0.14.1-py2.7.egg-info/SOURCES.txt +++ /dev/null @@ -1,299 +0,0 @@ -AUTHORS -CHANGES.rst -LICENSE -MANIFEST.in -Makefile -README.rst -setup.cfg -setup.py -tox.ini -Werkzeug.egg-info/PKG-INFO -Werkzeug.egg-info/SOURCES.txt -Werkzeug.egg-info/dependency_links.txt -Werkzeug.egg-info/not-zip-safe -Werkzeug.egg-info/requires.txt -Werkzeug.egg-info/top_level.txt -artwork/.DS_Store -artwork/logo.png -artwork/logo.svg -docs/.DS_Store -docs/Makefile -docs/changes.rst -docs/conf.py -docs/contents.rst.inc -docs/datastructures.rst -docs/debug.rst -docs/exceptions.rst -docs/filesystem.rst -docs/http.rst -docs/index.rst -docs/installation.rst -docs/latexindex.rst -docs/levels.rst -docs/local.rst -docs/logo.pdf -docs/make.bat -docs/makearchive.py -docs/middlewares.rst -docs/python3.rst -docs/quickstart.rst -docs/request_data.rst -docs/routing.rst -docs/serving.rst -docs/terms.rst -docs/test.rst -docs/transition.rst -docs/tutorial.rst -docs/unicode.rst -docs/urls.rst -docs/utils.rst -docs/werkzeugext.py -docs/werkzeugstyle.sty -docs/wrappers.rst -docs/wsgi.rst -docs/_static/background.png -docs/_static/codebackground.png -docs/_static/contents.png -docs/_static/debug-screenshot.png -docs/_static/favicon.ico -docs/_static/header.png -docs/_static/navigation.png -docs/_static/navigation_active.png -docs/_static/shortly.png -docs/_static/shorty-screenshot.png -docs/_static/style.css -docs/_static/werkzeug.js -docs/_static/werkzeug.png -docs/_templates/sidebarintro.html -docs/_templates/sidebarlogo.html -docs/contrib/atom.rst -docs/contrib/cache.rst -docs/contrib/fixers.rst -docs/contrib/index.rst -docs/contrib/iterio.rst -docs/contrib/lint.rst -docs/contrib/profiler.rst -docs/contrib/securecookie.rst -docs/contrib/sessions.rst -docs/contrib/wrappers.rst -docs/deployment/cgi.rst -docs/deployment/fastcgi.rst -docs/deployment/index.rst -docs/deployment/mod_wsgi.rst -docs/deployment/proxying.rst -examples/README -examples/cookieauth.py -examples/httpbasicauth.py -examples/manage-coolmagic.py -examples/manage-couchy.py -examples/manage-cupoftee.py -examples/manage-i18nurls.py -examples/manage-plnt.py -examples/manage-shorty.py -examples/manage-simplewiki.py -examples/manage-webpylike.py -examples/upload.py -examples/contrib/README -examples/contrib/securecookie.py -examples/contrib/sessions.py -examples/coolmagic/__init__.py -examples/coolmagic/application.py -examples/coolmagic/helpers.py -examples/coolmagic/utils.py -examples/coolmagic/public/style.css -examples/coolmagic/templates/layout.html -examples/coolmagic/templates/static/about.html -examples/coolmagic/templates/static/index.html -examples/coolmagic/templates/static/not_found.html -examples/coolmagic/views/__init__.py -examples/coolmagic/views/static.py -examples/couchy/README -examples/couchy/__init__.py -examples/couchy/application.py -examples/couchy/models.py -examples/couchy/utils.py -examples/couchy/views.py -examples/couchy/static/style.css -examples/couchy/templates/display.html -examples/couchy/templates/layout.html -examples/couchy/templates/list.html -examples/couchy/templates/new.html -examples/couchy/templates/not_found.html -examples/cupoftee/__init__.py -examples/cupoftee/application.py -examples/cupoftee/db.py -examples/cupoftee/network.py -examples/cupoftee/pages.py -examples/cupoftee/utils.py -examples/cupoftee/shared/content.png -examples/cupoftee/shared/down.png -examples/cupoftee/shared/favicon.ico -examples/cupoftee/shared/header.png -examples/cupoftee/shared/logo.png -examples/cupoftee/shared/style.css -examples/cupoftee/shared/up.png -examples/cupoftee/templates/layout.html -examples/cupoftee/templates/missingpage.html -examples/cupoftee/templates/search.html -examples/cupoftee/templates/server.html -examples/cupoftee/templates/serverlist.html -examples/i18nurls/__init__.py -examples/i18nurls/application.py -examples/i18nurls/urls.py -examples/i18nurls/views.py -examples/i18nurls/templates/about.html -examples/i18nurls/templates/blog.html -examples/i18nurls/templates/index.html -examples/i18nurls/templates/layout.html -examples/partial/README -examples/partial/complex_routing.py -examples/plnt/__init__.py -examples/plnt/database.py -examples/plnt/sync.py -examples/plnt/utils.py -examples/plnt/views.py -examples/plnt/webapp.py -examples/plnt/shared/style.css -examples/plnt/templates/about.html -examples/plnt/templates/index.html -examples/plnt/templates/layout.html -examples/shortly/shortly.py -examples/shortly/static/style.css -examples/shortly/templates/404.html -examples/shortly/templates/layout.html -examples/shortly/templates/new_url.html -examples/shortly/templates/short_link_details.html -examples/shorty/__init__.py -examples/shorty/application.py -examples/shorty/models.py -examples/shorty/utils.py -examples/shorty/views.py -examples/shorty/static/style.css -examples/shorty/templates/display.html -examples/shorty/templates/layout.html -examples/shorty/templates/list.html -examples/shorty/templates/new.html -examples/shorty/templates/not_found.html -examples/simplewiki/__init__.py -examples/simplewiki/actions.py -examples/simplewiki/application.py -examples/simplewiki/database.py -examples/simplewiki/specialpages.py -examples/simplewiki/utils.py -examples/simplewiki/shared/style.css -examples/simplewiki/templates/action_diff.html -examples/simplewiki/templates/action_edit.html -examples/simplewiki/templates/action_log.html -examples/simplewiki/templates/action_revert.html -examples/simplewiki/templates/action_show.html -examples/simplewiki/templates/layout.html -examples/simplewiki/templates/macros.xml -examples/simplewiki/templates/missing_action.html -examples/simplewiki/templates/page_index.html -examples/simplewiki/templates/page_missing.html -examples/simplewiki/templates/recent_changes.html -examples/webpylike/example.py -examples/webpylike/webpylike.py -tests/__init__.py -tests/conftest.py -tests/test_compat.py -tests/test_datastructures.py -tests/test_debug.py -tests/test_exceptions.py -tests/test_formparser.py -tests/test_http.py -tests/test_internal.py -tests/test_local.py -tests/test_routing.py -tests/test_security.py -tests/test_serving.py -tests/test_test.py -tests/test_urls.py -tests/test_utils.py -tests/test_wrappers.py -tests/test_wsgi.py -tests/contrib/__init__.py -tests/contrib/test_atom.py -tests/contrib/test_cache.py -tests/contrib/test_fixers.py -tests/contrib/test_iterio.py -tests/contrib/test_securecookie.py -tests/contrib/test_sessions.py -tests/contrib/test_wrappers.py -tests/contrib/cache/conftest.py -tests/contrib/cache/test_cache.py -tests/hypothesis/__init__.py -tests/hypothesis/test_urls.py -tests/multipart/__init__.py -tests/multipart/ie7_full_path_request.txt -tests/multipart/test_collect.py -tests/multipart/firefox3-2png1txt/file1.png -tests/multipart/firefox3-2png1txt/file2.png -tests/multipart/firefox3-2png1txt/request.txt -tests/multipart/firefox3-2png1txt/text.txt -tests/multipart/firefox3-2pnglongtext/file1.png -tests/multipart/firefox3-2pnglongtext/file2.png -tests/multipart/firefox3-2pnglongtext/request.txt -tests/multipart/firefox3-2pnglongtext/text.txt -tests/multipart/ie6-2png1txt/file1.png -tests/multipart/ie6-2png1txt/file2.png -tests/multipart/ie6-2png1txt/request.txt -tests/multipart/ie6-2png1txt/text.txt -tests/multipart/opera8-2png1txt/file1.png -tests/multipart/opera8-2png1txt/file2.png -tests/multipart/opera8-2png1txt/request.txt -tests/multipart/opera8-2png1txt/text.txt -tests/multipart/webkit3-2png1txt/file1.png -tests/multipart/webkit3-2png1txt/file2.png -tests/multipart/webkit3-2png1txt/request.txt -tests/multipart/webkit3-2png1txt/text.txt -tests/res/chunked.txt -tests/res/test.txt -werkzeug/__init__.py -werkzeug/_compat.py -werkzeug/_internal.py -werkzeug/_reloader.py -werkzeug/datastructures.py -werkzeug/exceptions.py -werkzeug/filesystem.py -werkzeug/formparser.py -werkzeug/http.py -werkzeug/local.py -werkzeug/posixemulation.py -werkzeug/routing.py -werkzeug/security.py -werkzeug/serving.py -werkzeug/test.py -werkzeug/testapp.py -werkzeug/urls.py -werkzeug/useragents.py -werkzeug/utils.py -werkzeug/websocket.py -werkzeug/wrappers.py -werkzeug/wsgi.py -werkzeug/contrib/__init__.py -werkzeug/contrib/atom.py -werkzeug/contrib/cache.py -werkzeug/contrib/fixers.py -werkzeug/contrib/iterio.py -werkzeug/contrib/jsrouting.py -werkzeug/contrib/limiter.py -werkzeug/contrib/lint.py -werkzeug/contrib/profiler.py -werkzeug/contrib/securecookie.py -werkzeug/contrib/sessions.py -werkzeug/contrib/testtools.py -werkzeug/contrib/wrappers.py -werkzeug/debug/__init__.py -werkzeug/debug/console.py -werkzeug/debug/repr.py -werkzeug/debug/tbtools.py -werkzeug/debug/shared/FONT_LICENSE -werkzeug/debug/shared/console.png -werkzeug/debug/shared/debugger.js -werkzeug/debug/shared/jquery.js -werkzeug/debug/shared/less.png -werkzeug/debug/shared/more.png -werkzeug/debug/shared/source.png -werkzeug/debug/shared/style.css -werkzeug/debug/shared/ubuntu.ttf \ No newline at end of file diff --git a/pyextra/Werkzeug-0.14.1-py2.7.egg-info/dependency_links.txt b/pyextra/Werkzeug-0.14.1-py2.7.egg-info/dependency_links.txt deleted file mode 100644 index 8b137891791fe9..00000000000000 --- a/pyextra/Werkzeug-0.14.1-py2.7.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pyextra/Werkzeug-0.14.1-py2.7.egg-info/installed-files.txt b/pyextra/Werkzeug-0.14.1-py2.7.egg-info/installed-files.txt deleted file mode 100644 index 105fb3c0b60939..00000000000000 --- a/pyextra/Werkzeug-0.14.1-py2.7.egg-info/installed-files.txt +++ /dev/null @@ -1,93 +0,0 @@ -../werkzeug/_reloader.py -../werkzeug/_internal.py -../werkzeug/serving.py -../werkzeug/local.py -../werkzeug/filesystem.py -../werkzeug/security.py -../werkzeug/__init__.py -../werkzeug/test.py -../werkzeug/formparser.py -../werkzeug/posixemulation.py -../werkzeug/utils.py -../werkzeug/wrappers.py -../werkzeug/routing.py -../werkzeug/http.py -../werkzeug/useragents.py -../werkzeug/exceptions.py -../werkzeug/_compat.py -../werkzeug/datastructures.py -../werkzeug/urls.py -../werkzeug/websocket.py -../werkzeug/wsgi.py -../werkzeug/testapp.py -../werkzeug/contrib/sessions.py -../werkzeug/contrib/cache.py -../werkzeug/contrib/__init__.py -../werkzeug/contrib/testtools.py -../werkzeug/contrib/wrappers.py -../werkzeug/contrib/jsrouting.py -../werkzeug/contrib/fixers.py -../werkzeug/contrib/profiler.py -../werkzeug/contrib/iterio.py -../werkzeug/contrib/atom.py -../werkzeug/contrib/securecookie.py -../werkzeug/contrib/limiter.py -../werkzeug/contrib/lint.py -../werkzeug/debug/console.py -../werkzeug/debug/tbtools.py -../werkzeug/debug/__init__.py -../werkzeug/debug/repr.py -../werkzeug/debug/shared/FONT_LICENSE -../werkzeug/debug/shared/console.png -../werkzeug/debug/shared/debugger.js -../werkzeug/debug/shared/jquery.js -../werkzeug/debug/shared/less.png -../werkzeug/debug/shared/more.png -../werkzeug/debug/shared/source.png -../werkzeug/debug/shared/style.css -../werkzeug/debug/shared/ubuntu.ttf -../werkzeug/_reloader.pyc -../werkzeug/_internal.pyc -../werkzeug/serving.pyc -../werkzeug/local.pyc -../werkzeug/filesystem.pyc -../werkzeug/security.pyc -../werkzeug/__init__.pyc -../werkzeug/test.pyc -../werkzeug/formparser.pyc -../werkzeug/posixemulation.pyc -../werkzeug/utils.pyc -../werkzeug/wrappers.pyc -../werkzeug/routing.pyc -../werkzeug/http.pyc -../werkzeug/useragents.pyc -../werkzeug/exceptions.pyc -../werkzeug/_compat.pyc -../werkzeug/datastructures.pyc -../werkzeug/urls.pyc -../werkzeug/websocket.pyc -../werkzeug/wsgi.pyc -../werkzeug/testapp.pyc -../werkzeug/contrib/sessions.pyc -../werkzeug/contrib/cache.pyc -../werkzeug/contrib/__init__.pyc -../werkzeug/contrib/testtools.pyc -../werkzeug/contrib/wrappers.pyc -../werkzeug/contrib/jsrouting.pyc -../werkzeug/contrib/fixers.pyc -../werkzeug/contrib/profiler.pyc -../werkzeug/contrib/iterio.pyc -../werkzeug/contrib/atom.pyc -../werkzeug/contrib/securecookie.pyc -../werkzeug/contrib/limiter.pyc -../werkzeug/contrib/lint.pyc -../werkzeug/debug/console.pyc -../werkzeug/debug/tbtools.pyc -../werkzeug/debug/__init__.pyc -../werkzeug/debug/repr.pyc -PKG-INFO -not-zip-safe -SOURCES.txt -requires.txt -top_level.txt -dependency_links.txt diff --git a/pyextra/Werkzeug-0.14.1-py2.7.egg-info/not-zip-safe b/pyextra/Werkzeug-0.14.1-py2.7.egg-info/not-zip-safe deleted file mode 100644 index 8b137891791fe9..00000000000000 --- a/pyextra/Werkzeug-0.14.1-py2.7.egg-info/not-zip-safe +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pyextra/Werkzeug-0.14.1-py2.7.egg-info/requires.txt b/pyextra/Werkzeug-0.14.1-py2.7.egg-info/requires.txt deleted file mode 100644 index dd8c7c51f12455..00000000000000 --- a/pyextra/Werkzeug-0.14.1-py2.7.egg-info/requires.txt +++ /dev/null @@ -1,12 +0,0 @@ - -[dev] -pytest -coverage -tox -sphinx - -[termcolor] -termcolor - -[watchdog] -watchdog diff --git a/pyextra/Werkzeug-0.14.1-py2.7.egg-info/top_level.txt b/pyextra/Werkzeug-0.14.1-py2.7.egg-info/top_level.txt deleted file mode 100644 index 6fe8da8499399d..00000000000000 --- a/pyextra/Werkzeug-0.14.1-py2.7.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -werkzeug diff --git a/pyextra/backports.ssl_match_hostname-3.7.0.1-py2.7.egg-info/PKG-INFO b/pyextra/backports.ssl_match_hostname-3.7.0.1-py2.7.egg-info/PKG-INFO deleted file mode 100644 index 035a98f8ce0f24..00000000000000 --- a/pyextra/backports.ssl_match_hostname-3.7.0.1-py2.7.egg-info/PKG-INFO +++ /dev/null @@ -1,89 +0,0 @@ -Metadata-Version: 1.1 -Name: backports.ssl-match-hostname -Version: 3.7.0.1 -Summary: The ssl.match_hostname() function from Python 3.5 -Home-page: http://bitbucket.org/brandon/backports.ssl_match_hostname -Author: Toshio Kuratomi -Author-email: toshio@fedoraproject.org -License: Python Software Foundation License -Description: - The ssl.match_hostname() function from Python 3.7 - ================================================= - - The Secure Sockets Layer is only actually *secure* - if you check the hostname in the certificate returned - by the server to which you are connecting, - and verify that it matches to hostname - that you are trying to reach. - - But the matching logic, defined in `RFC2818`_, - can be a bit tricky to implement on your own. - So the ``ssl`` package in the Standard Library of Python 3.2 - and greater now includes a ``match_hostname()`` function - for performing this check instead of requiring every application - to implement the check separately. - - This backport brings ``match_hostname()`` to users - of earlier versions of Python. - Simply make this distribution a dependency of your package, - and then use it like this:: - - from backports.ssl_match_hostname import match_hostname, CertificateError - [...] - sslsock = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_SSLv23, - cert_reqs=ssl.CERT_REQUIRED, ca_certs=...) - try: - match_hostname(sslsock.getpeercert(), hostname) - except CertificateError, ce: - ... - - Brandon Craig Rhodes is merely the packager of this distribution; - the actual code inside comes from Python 3.7 with small changes for - portability. - - - Requirements - ------------ - - * If you need to use this on Python versions earlier than 2.6 you will need to - install the `ssl module`_. From Python 2.6 upwards ``ssl`` is included in - the Python Standard Library so you do not need to install it separately. - - .. _`ssl module`:: https://pypi.python.org/pypi/ssl - - History - ------- - - * This function was introduced in python-3.2 - * It was updated for python-3.4a1 for a CVE - (backports-ssl_match_hostname-3.4.0.1) - * It was updated from RFC2818 to RFC 6125 compliance in order to fix another - security flaw for python-3.3.3 and python-3.4a5 - (backports-ssl_match_hostname-3.4.0.2) - * It was updated in python-3.5 to handle IPAddresses in ServerAltName fields - (something that backports.ssl_match_hostname will do if you also install the - ipaddress library from pypi). - * It was updated in python-3.7 to handle IPAddresses without the ipaddress library and dropped - support for partial wildcards - - .. _`ipaddress module`:: https://pypi.python.org/pypi/ipaddress - - .. _RFC2818: http://tools.ietf.org/html/rfc2818.html - -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: License :: OSI Approved :: Python Software Foundation License -Classifier: Programming Language :: Python :: 2.4 -Classifier: Programming Language :: Python :: 2.5 -Classifier: Programming Language :: Python :: 2.6 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.0 -Classifier: Programming Language :: Python :: 3.1 -Classifier: Programming Language :: Python :: 3.2 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Topic :: Security :: Cryptography diff --git a/pyextra/backports.ssl_match_hostname-3.7.0.1-py2.7.egg-info/SOURCES.txt b/pyextra/backports.ssl_match_hostname-3.7.0.1-py2.7.egg-info/SOURCES.txt deleted file mode 100644 index 95b96160996935..00000000000000 --- a/pyextra/backports.ssl_match_hostname-3.7.0.1-py2.7.egg-info/SOURCES.txt +++ /dev/null @@ -1,8 +0,0 @@ -README.txt -setup.cfg -backports/__init__.py -backports.ssl_match_hostname.egg-info/PKG-INFO -backports.ssl_match_hostname.egg-info/SOURCES.txt -backports.ssl_match_hostname.egg-info/dependency_links.txt -backports.ssl_match_hostname.egg-info/top_level.txt -backports/ssl_match_hostname/__init__.py \ No newline at end of file diff --git a/pyextra/backports.ssl_match_hostname-3.7.0.1-py2.7.egg-info/dependency_links.txt b/pyextra/backports.ssl_match_hostname-3.7.0.1-py2.7.egg-info/dependency_links.txt deleted file mode 100644 index 8b137891791fe9..00000000000000 --- a/pyextra/backports.ssl_match_hostname-3.7.0.1-py2.7.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pyextra/backports.ssl_match_hostname-3.7.0.1-py2.7.egg-info/installed-files.txt b/pyextra/backports.ssl_match_hostname-3.7.0.1-py2.7.egg-info/installed-files.txt deleted file mode 100644 index fd1aae3671ef18..00000000000000 --- a/pyextra/backports.ssl_match_hostname-3.7.0.1-py2.7.egg-info/installed-files.txt +++ /dev/null @@ -1,8 +0,0 @@ -../backports/__init__.py -../backports/__init__.pyc -../backports/ssl_match_hostname/__init__.py -../backports/ssl_match_hostname/__init__.pyc -PKG-INFO -SOURCES.txt -dependency_links.txt -top_level.txt diff --git a/pyextra/backports.ssl_match_hostname-3.7.0.1-py2.7.egg-info/top_level.txt b/pyextra/backports.ssl_match_hostname-3.7.0.1-py2.7.egg-info/top_level.txt deleted file mode 100644 index 99d2be5b64d7dc..00000000000000 --- a/pyextra/backports.ssl_match_hostname-3.7.0.1-py2.7.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -backports diff --git a/pyextra/backports/__init__.py b/pyextra/backports/__init__.py deleted file mode 100644 index 612d32836bb638..00000000000000 --- a/pyextra/backports/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# This is a Python "namespace package" http://www.python.org/dev/peps/pep-0382/ -from pkgutil import extend_path -__path__ = extend_path(__path__, __name__) diff --git a/pyextra/backports/ssl_match_hostname/__init__.py b/pyextra/backports/ssl_match_hostname/__init__.py deleted file mode 100644 index cdfef013dec186..00000000000000 --- a/pyextra/backports/ssl_match_hostname/__init__.py +++ /dev/null @@ -1,204 +0,0 @@ -"""The match_hostname() function from Python 3.7.0, essential when using SSL.""" - -import sys -import socket as _socket - -try: - # Divergence: Python-3.7+'s _ssl has this exception type but older Pythons do not - from _ssl import SSLCertVerificationError - CertificateError = SSLCertVerificationError -except: - class CertificateError(ValueError): - pass - - -__version__ = '3.7.0.1' - - -# Divergence: Added to deal with ipaddess as bytes on python2 -def _to_text(obj): - if isinstance(obj, str) and sys.version_info < (3,): - obj = unicode(obj, encoding='ascii', errors='strict') - elif sys.version_info >= (3,) and isinstance(obj, bytes): - obj = str(obj, encoding='ascii', errors='strict') - return obj - - -def _to_bytes(obj): - if isinstance(obj, str) and sys.version_info >= (3,): - obj = bytes(obj, encoding='ascii', errors='strict') - elif sys.version_info < (3,) and isinstance(obj, unicode): - obj = obj.encode('ascii', 'strict') - return obj - - -def _dnsname_match(dn, hostname): - """Matching according to RFC 6125, section 6.4.3 - - - Hostnames are compared lower case. - - For IDNA, both dn and hostname must be encoded as IDN A-label (ACE). - - Partial wildcards like 'www*.example.org', multiple wildcards, sole - wildcard or wildcards in labels other then the left-most label are not - supported and a CertificateError is raised. - - A wildcard must match at least one character. - """ - if not dn: - return False - - wildcards = dn.count('*') - # speed up common case w/o wildcards - if not wildcards: - return dn.lower() == hostname.lower() - - if wildcards > 1: - # Divergence .format() to percent formatting for Python < 2.6 - raise CertificateError( - "too many wildcards in certificate DNS name: %s" % repr(dn)) - - dn_leftmost, sep, dn_remainder = dn.partition('.') - - if '*' in dn_remainder: - # Only match wildcard in leftmost segment. - # Divergence .format() to percent formatting for Python < 2.6 - raise CertificateError( - "wildcard can only be present in the leftmost label: " - "%s." % repr(dn)) - - if not sep: - # no right side - # Divergence .format() to percent formatting for Python < 2.6 - raise CertificateError( - "sole wildcard without additional labels are not support: " - "%s." % repr(dn)) - - if dn_leftmost != '*': - # no partial wildcard matching - # Divergence .format() to percent formatting for Python < 2.6 - raise CertificateError( - "partial wildcards in leftmost label are not supported: " - "%s." % repr(dn)) - - hostname_leftmost, sep, hostname_remainder = hostname.partition('.') - if not hostname_leftmost or not sep: - # wildcard must match at least one char - return False - return dn_remainder.lower() == hostname_remainder.lower() - - -def _inet_paton(ipname): - """Try to convert an IP address to packed binary form - - Supports IPv4 addresses on all platforms and IPv6 on platforms with IPv6 - support. - """ - # inet_aton() also accepts strings like '1' - # Divergence: We make sure we have native string type for all python versions - try: - b_ipname = _to_bytes(ipname) - except UnicodeError: - raise ValueError("%s must be an all-ascii string." % repr(ipname)) - - # Set ipname in native string format - if sys.version_info < (3,): - n_ipname = b_ipname - else: - n_ipname = ipname - - if n_ipname.count('.') == 3: - try: - return _socket.inet_aton(n_ipname) - # Divergence: OSError on late python3. socket.error earlier. - # Null bytes generate ValueError on python3(we want to raise - # ValueError anyway), TypeError # earlier - except (OSError, _socket.error, TypeError): - pass - - try: - return _socket.inet_pton(_socket.AF_INET6, n_ipname) - # Divergence: OSError on late python3. socket.error earlier. - # Null bytes generate ValueError on python3(we want to raise - # ValueError anyway), TypeError # earlier - except (OSError, _socket.error, TypeError): - # Divergence .format() to percent formatting for Python < 2.6 - raise ValueError("%s is neither an IPv4 nor an IP6 " - "address." % repr(ipname)) - except AttributeError: - # AF_INET6 not available - pass - - # Divergence .format() to percent formatting for Python < 2.6 - raise ValueError("%s is not an IPv4 address." % repr(ipname)) - - -def _ipaddress_match(ipname, host_ip): - """Exact matching of IP addresses. - - RFC 6125 explicitly doesn't define an algorithm for this - (section 1.7.2 - "Out of Scope"). - """ - # OpenSSL may add a trailing newline to a subjectAltName's IP address - ip = _inet_paton(ipname.rstrip()) - return ip == host_ip - - -def match_hostname(cert, hostname): - """Verify that *cert* (in decoded format as returned by - SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 - rules are followed. - - The function matches IP addresses rather than dNSNames if hostname is a - valid ipaddress string. IPv4 addresses are supported on all platforms. - IPv6 addresses are supported on platforms with IPv6 support (AF_INET6 - and inet_pton). - - CertificateError is raised on failure. On success, the function - returns nothing. - """ - if not cert: - raise ValueError("empty or no certificate, match_hostname needs a " - "SSL socket or SSL context with either " - "CERT_OPTIONAL or CERT_REQUIRED") - try: - # Divergence: Deal with hostname as bytes - host_ip = _inet_paton(_to_text(hostname)) - except ValueError: - # Not an IP address (common case) - host_ip = None - except UnicodeError: - # Divergence: Deal with hostname as byte strings. - # IP addresses should be all ascii, so we consider it not - # an IP address if this fails - host_ip = None - dnsnames = [] - san = cert.get('subjectAltName', ()) - for key, value in san: - if key == 'DNS': - if host_ip is None and _dnsname_match(value, hostname): - return - dnsnames.append(value) - elif key == 'IP Address': - if host_ip is not None and _ipaddress_match(value, host_ip): - return - dnsnames.append(value) - if not dnsnames: - # The subject is only checked when there is no dNSName entry - # in subjectAltName - for sub in cert.get('subject', ()): - for key, value in sub: - # XXX according to RFC 2818, the most specific Common Name - # must be used. - if key == 'commonName': - if _dnsname_match(value, hostname): - return - dnsnames.append(value) - if len(dnsnames) > 1: - raise CertificateError("hostname %r " - "doesn't match either of %s" - % (hostname, ', '.join(map(repr, dnsnames)))) - elif len(dnsnames) == 1: - raise CertificateError("hostname %r " - "doesn't match %r" - % (hostname, dnsnames[0])) - else: - raise CertificateError("no appropriate commonName or " - "subjectAltName fields were found") diff --git a/pyextra/bin/flask b/pyextra/bin/flask deleted file mode 100755 index 2adb78c4a57b77..00000000000000 --- a/pyextra/bin/flask +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/local/bin/python -# EASY-INSTALL-ENTRY-SCRIPT: 'Flask==1.0.2','console_scripts','flask' -__requires__ = 'Flask==1.0.2' -import sys -from pkg_resources import load_entry_point - -if __name__ == '__main__': - sys.exit( - load_entry_point('Flask==1.0.2', 'console_scripts', 'flask')() - ) diff --git a/pyextra/bin/wsdump.py b/pyextra/bin/wsdump.py deleted file mode 100755 index 246d15050c34ed..00000000000000 --- a/pyextra/bin/wsdump.py +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/local/bin/python - -import argparse -import code -import sys -import threading -import time -import ssl - -import six -from six.moves.urllib.parse import urlparse - -import websocket - -try: - import readline -except ImportError: - pass - - -def get_encoding(): - encoding = getattr(sys.stdin, "encoding", "") - if not encoding: - return "utf-8" - else: - return encoding.lower() - - -OPCODE_DATA = (websocket.ABNF.OPCODE_TEXT, websocket.ABNF.OPCODE_BINARY) -ENCODING = get_encoding() - - -class VAction(argparse.Action): - - def __call__(self, parser, args, values, option_string=None): - if values is None: - values = "1" - try: - values = int(values) - except ValueError: - values = values.count("v") + 1 - setattr(args, self.dest, values) - - -def parse_args(): - parser = argparse.ArgumentParser(description="WebSocket Simple Dump Tool") - parser.add_argument("url", metavar="ws_url", - help="websocket url. ex. ws://echo.websocket.org/") - parser.add_argument("-p", "--proxy", - help="proxy url. ex. http://127.0.0.1:8080") - parser.add_argument("-v", "--verbose", default=0, nargs='?', action=VAction, - dest="verbose", - help="set verbose mode. If set to 1, show opcode. " - "If set to 2, enable to trace websocket module") - parser.add_argument("-n", "--nocert", action='store_true', - help="Ignore invalid SSL cert") - parser.add_argument("-r", "--raw", action="store_true", - help="raw output") - parser.add_argument("-s", "--subprotocols", nargs='*', - help="Set subprotocols") - parser.add_argument("-o", "--origin", - help="Set origin") - parser.add_argument("--eof-wait", default=0, type=int, - help="wait time(second) after 'EOF' received.") - parser.add_argument("-t", "--text", - help="Send initial text") - parser.add_argument("--timings", action="store_true", - help="Print timings in seconds") - parser.add_argument("--headers", - help="Set custom headers. Use ',' as separator") - - return parser.parse_args() - - -class RawInput: - - def raw_input(self, prompt): - if six.PY3: - line = input(prompt) - else: - line = raw_input(prompt) - - if ENCODING and ENCODING != "utf-8" and not isinstance(line, six.text_type): - line = line.decode(ENCODING).encode("utf-8") - elif isinstance(line, six.text_type): - line = line.encode("utf-8") - - return line - - -class InteractiveConsole(RawInput, code.InteractiveConsole): - - def write(self, data): - sys.stdout.write("\033[2K\033[E") - # sys.stdout.write("\n") - sys.stdout.write("\033[34m< " + data + "\033[39m") - sys.stdout.write("\n> ") - sys.stdout.flush() - - def read(self): - return self.raw_input("> ") - - -class NonInteractive(RawInput): - - def write(self, data): - sys.stdout.write(data) - sys.stdout.write("\n") - sys.stdout.flush() - - def read(self): - return self.raw_input("") - - -def main(): - start_time = time.time() - args = parse_args() - if args.verbose > 1: - websocket.enableTrace(True) - options = {} - if args.proxy: - p = urlparse(args.proxy) - options["http_proxy_host"] = p.hostname - options["http_proxy_port"] = p.port - if args.origin: - options["origin"] = args.origin - if args.subprotocols: - options["subprotocols"] = args.subprotocols - opts = {} - if args.nocert: - opts = {"cert_reqs": ssl.CERT_NONE, "check_hostname": False} - if args.headers: - options['header'] = map(str.strip, args.headers.split(',')) - ws = websocket.create_connection(args.url, sslopt=opts, **options) - if args.raw: - console = NonInteractive() - else: - console = InteractiveConsole() - print("Press Ctrl+C to quit") - - def recv(): - try: - frame = ws.recv_frame() - except websocket.WebSocketException: - return websocket.ABNF.OPCODE_CLOSE, None - if not frame: - raise websocket.WebSocketException("Not a valid frame %s" % frame) - elif frame.opcode in OPCODE_DATA: - return frame.opcode, frame.data - elif frame.opcode == websocket.ABNF.OPCODE_CLOSE: - ws.send_close() - return frame.opcode, None - elif frame.opcode == websocket.ABNF.OPCODE_PING: - ws.pong(frame.data) - return frame.opcode, frame.data - - return frame.opcode, frame.data - - def recv_ws(): - while True: - opcode, data = recv() - msg = None - if six.PY3 and opcode == websocket.ABNF.OPCODE_TEXT and isinstance(data, bytes): - data = str(data, "utf-8") - if not args.verbose and opcode in OPCODE_DATA: - msg = data - elif args.verbose: - msg = "%s: %s" % (websocket.ABNF.OPCODE_MAP.get(opcode), data) - - if msg is not None: - if args.timings: - console.write(str(time.time() - start_time) + ": " + msg) - else: - console.write(msg) - - if opcode == websocket.ABNF.OPCODE_CLOSE: - break - - thread = threading.Thread(target=recv_ws) - thread.daemon = True - thread.start() - - if args.text: - ws.send(args.text) - - while True: - try: - message = console.read() - ws.send(message) - except KeyboardInterrupt: - return - except EOFError: - time.sleep(args.eof_wait) - return - - -if __name__ == "__main__": - try: - main() - except Exception as e: - print(e) diff --git a/pyextra/click-6.7-py2.7.egg-info/PKG-INFO b/pyextra/click-6.7-py2.7.egg-info/PKG-INFO deleted file mode 100644 index bbb17b38331c58..00000000000000 --- a/pyextra/click-6.7-py2.7.egg-info/PKG-INFO +++ /dev/null @@ -1,13 +0,0 @@ -Metadata-Version: 1.1 -Name: click -Version: 6.7 -Summary: A simple wrapper around optparse for powerful command line utilities. -Home-page: http://github.com/mitsuhiko/click -Author: Armin Ronacher -Author-email: armin.ronacher@active-4.com -License: UNKNOWN -Description: UNKNOWN -Platform: UNKNOWN -Classifier: License :: OSI Approved :: BSD License -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 diff --git a/pyextra/click-6.7-py2.7.egg-info/SOURCES.txt b/pyextra/click-6.7-py2.7.egg-info/SOURCES.txt deleted file mode 100644 index 5eed4349ef6793..00000000000000 --- a/pyextra/click-6.7-py2.7.egg-info/SOURCES.txt +++ /dev/null @@ -1,114 +0,0 @@ -CHANGES -LICENSE -MANIFEST.in -Makefile -README -setup.cfg -setup.py -artwork/logo.svg -click/__init__.py -click/_bashcomplete.py -click/_compat.py -click/_termui_impl.py -click/_textwrap.py -click/_unicodefun.py -click/_winconsole.py -click/core.py -click/decorators.py -click/exceptions.py -click/formatting.py -click/globals.py -click/parser.py -click/termui.py -click/testing.py -click/types.py -click/utils.py -click.egg-info/PKG-INFO -click.egg-info/SOURCES.txt -click.egg-info/dependency_links.txt -click.egg-info/top_level.txt -docs/Makefile -docs/advanced.rst -docs/api.rst -docs/arguments.rst -docs/bashcomplete.rst -docs/changelog.rst -docs/clickdoctools.py -docs/commands.rst -docs/complex.rst -docs/conf.py -docs/contrib.rst -docs/documentation.rst -docs/exceptions.rst -docs/index.rst -docs/license.rst -docs/make.bat -docs/options.rst -docs/parameters.rst -docs/prompts.rst -docs/python3.rst -docs/quickstart.rst -docs/setuptools.rst -docs/testing.rst -docs/upgrading.rst -docs/utils.rst -docs/why.rst -docs/wincmd.rst -docs/_static/click-small.png -docs/_static/click-small@2x.png -docs/_static/click.png -docs/_static/click@2x.png -docs/_templates/sidebarintro.html -docs/_templates/sidebarlogo.html -examples/README -examples/aliases/README -examples/aliases/aliases.ini -examples/aliases/aliases.py -examples/aliases/setup.py -examples/colors/README -examples/colors/colors.py -examples/colors/setup.py -examples/complex/README -examples/complex/setup.py -examples/complex/complex/__init__.py -examples/complex/complex/cli.py -examples/complex/complex/commands/__init__.py -examples/complex/complex/commands/cmd_init.py -examples/complex/complex/commands/cmd_status.py -examples/imagepipe/.gitignore -examples/imagepipe/README -examples/imagepipe/example01.jpg -examples/imagepipe/example02.jpg -examples/imagepipe/imagepipe.py -examples/imagepipe/setup.py -examples/inout/README -examples/inout/inout.py -examples/inout/setup.py -examples/naval/README -examples/naval/naval.py -examples/naval/setup.py -examples/repo/README -examples/repo/repo.py -examples/repo/setup.py -examples/termui/README -examples/termui/setup.py -examples/termui/termui.py -examples/validation/README -examples/validation/setup.py -examples/validation/validation.py -tests/conftest.py -tests/test_arguments.py -tests/test_bashcomplete.py -tests/test_basic.py -tests/test_chain.py -tests/test_commands.py -tests/test_compat.py -tests/test_context.py -tests/test_defaults.py -tests/test_formatting.py -tests/test_imports.py -tests/test_normalization.py -tests/test_options.py -tests/test_termui.py -tests/test_testing.py -tests/test_utils.py \ No newline at end of file diff --git a/pyextra/click-6.7-py2.7.egg-info/dependency_links.txt b/pyextra/click-6.7-py2.7.egg-info/dependency_links.txt deleted file mode 100644 index 8b137891791fe9..00000000000000 --- a/pyextra/click-6.7-py2.7.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pyextra/click-6.7-py2.7.egg-info/installed-files.txt b/pyextra/click-6.7-py2.7.egg-info/installed-files.txt deleted file mode 100644 index 63d1b52c135353..00000000000000 --- a/pyextra/click-6.7-py2.7.egg-info/installed-files.txt +++ /dev/null @@ -1,38 +0,0 @@ -../click/exceptions.py -../click/testing.py -../click/decorators.py -../click/parser.py -../click/formatting.py -../click/globals.py -../click/_termui_impl.py -../click/__init__.py -../click/_compat.py -../click/_winconsole.py -../click/_unicodefun.py -../click/_textwrap.py -../click/_bashcomplete.py -../click/core.py -../click/types.py -../click/termui.py -../click/utils.py -../click/exceptions.pyc -../click/testing.pyc -../click/decorators.pyc -../click/parser.pyc -../click/formatting.pyc -../click/globals.pyc -../click/_termui_impl.pyc -../click/__init__.pyc -../click/_compat.pyc -../click/_winconsole.pyc -../click/_unicodefun.pyc -../click/_textwrap.pyc -../click/_bashcomplete.pyc -../click/core.pyc -../click/types.pyc -../click/termui.pyc -../click/utils.pyc -SOURCES.txt -top_level.txt -PKG-INFO -dependency_links.txt diff --git a/pyextra/click-6.7-py2.7.egg-info/top_level.txt b/pyextra/click-6.7-py2.7.egg-info/top_level.txt deleted file mode 100644 index dca9a909647e3b..00000000000000 --- a/pyextra/click-6.7-py2.7.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -click diff --git a/pyextra/click/__init__.py b/pyextra/click/__init__.py deleted file mode 100644 index 971e55d0a8c6de..00000000000000 --- a/pyextra/click/__init__.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8 -*- -""" - click - ~~~~~ - - Click is a simple Python module that wraps the stdlib's optparse to make - writing command line scripts fun. Unlike other modules, it's based around - a simple API that does not come with too much magic and is composable. - - In case optparse ever gets removed from the stdlib, it will be shipped by - this module. - - :copyright: (c) 2014 by Armin Ronacher. - :license: BSD, see LICENSE for more details. -""" - -# Core classes -from .core import Context, BaseCommand, Command, MultiCommand, Group, \ - CommandCollection, Parameter, Option, Argument - -# Globals -from .globals import get_current_context - -# Decorators -from .decorators import pass_context, pass_obj, make_pass_decorator, \ - command, group, argument, option, confirmation_option, \ - password_option, version_option, help_option - -# Types -from .types import ParamType, File, Path, Choice, IntRange, Tuple, \ - STRING, INT, FLOAT, BOOL, UUID, UNPROCESSED - -# Utilities -from .utils import echo, get_binary_stream, get_text_stream, open_file, \ - format_filename, get_app_dir, get_os_args - -# Terminal functions -from .termui import prompt, confirm, get_terminal_size, echo_via_pager, \ - progressbar, clear, style, unstyle, secho, edit, launch, getchar, \ - pause - -# Exceptions -from .exceptions import ClickException, UsageError, BadParameter, \ - FileError, Abort, NoSuchOption, BadOptionUsage, BadArgumentUsage, \ - MissingParameter - -# Formatting -from .formatting import HelpFormatter, wrap_text - -# Parsing -from .parser import OptionParser - - -__all__ = [ - # Core classes - 'Context', 'BaseCommand', 'Command', 'MultiCommand', 'Group', - 'CommandCollection', 'Parameter', 'Option', 'Argument', - - # Globals - 'get_current_context', - - # Decorators - 'pass_context', 'pass_obj', 'make_pass_decorator', 'command', 'group', - 'argument', 'option', 'confirmation_option', 'password_option', - 'version_option', 'help_option', - - # Types - 'ParamType', 'File', 'Path', 'Choice', 'IntRange', 'Tuple', 'STRING', - 'INT', 'FLOAT', 'BOOL', 'UUID', 'UNPROCESSED', - - # Utilities - 'echo', 'get_binary_stream', 'get_text_stream', 'open_file', - 'format_filename', 'get_app_dir', 'get_os_args', - - # Terminal functions - 'prompt', 'confirm', 'get_terminal_size', 'echo_via_pager', - 'progressbar', 'clear', 'style', 'unstyle', 'secho', 'edit', 'launch', - 'getchar', 'pause', - - # Exceptions - 'ClickException', 'UsageError', 'BadParameter', 'FileError', - 'Abort', 'NoSuchOption', 'BadOptionUsage', 'BadArgumentUsage', - 'MissingParameter', - - # Formatting - 'HelpFormatter', 'wrap_text', - - # Parsing - 'OptionParser', -] - - -# Controls if click should emit the warning about the use of unicode -# literals. -disable_unicode_literals_warning = False - - -__version__ = '6.7' diff --git a/pyextra/click/_bashcomplete.py b/pyextra/click/_bashcomplete.py deleted file mode 100644 index d9d26d28b053de..00000000000000 --- a/pyextra/click/_bashcomplete.py +++ /dev/null @@ -1,83 +0,0 @@ -import os -import re -from .utils import echo -from .parser import split_arg_string -from .core import MultiCommand, Option - - -COMPLETION_SCRIPT = ''' -%(complete_func)s() { - COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \\ - COMP_CWORD=$COMP_CWORD \\ - %(autocomplete_var)s=complete $1 ) ) - return 0 -} - -complete -F %(complete_func)s -o default %(script_names)s -''' - -_invalid_ident_char_re = re.compile(r'[^a-zA-Z0-9_]') - - -def get_completion_script(prog_name, complete_var): - cf_name = _invalid_ident_char_re.sub('', prog_name.replace('-', '_')) - return (COMPLETION_SCRIPT % { - 'complete_func': '_%s_completion' % cf_name, - 'script_names': prog_name, - 'autocomplete_var': complete_var, - }).strip() + ';' - - -def resolve_ctx(cli, prog_name, args): - ctx = cli.make_context(prog_name, args, resilient_parsing=True) - while ctx.protected_args + ctx.args and isinstance(ctx.command, MultiCommand): - a = ctx.protected_args + ctx.args - cmd = ctx.command.get_command(ctx, a[0]) - if cmd is None: - return None - ctx = cmd.make_context(a[0], a[1:], parent=ctx, resilient_parsing=True) - return ctx - - -def get_choices(cli, prog_name, args, incomplete): - ctx = resolve_ctx(cli, prog_name, args) - if ctx is None: - return - - choices = [] - if incomplete and not incomplete[:1].isalnum(): - for param in ctx.command.params: - if not isinstance(param, Option): - continue - choices.extend(param.opts) - choices.extend(param.secondary_opts) - elif isinstance(ctx.command, MultiCommand): - choices.extend(ctx.command.list_commands(ctx)) - - for item in choices: - if item.startswith(incomplete): - yield item - - -def do_complete(cli, prog_name): - cwords = split_arg_string(os.environ['COMP_WORDS']) - cword = int(os.environ['COMP_CWORD']) - args = cwords[1:cword] - try: - incomplete = cwords[cword] - except IndexError: - incomplete = '' - - for item in get_choices(cli, prog_name, args, incomplete): - echo(item) - - return True - - -def bashcomplete(cli, prog_name, complete_var, complete_instr): - if complete_instr == 'source': - echo(get_completion_script(prog_name, complete_var)) - return True - elif complete_instr == 'complete': - return do_complete(cli, prog_name) - return False diff --git a/pyextra/click/_compat.py b/pyextra/click/_compat.py deleted file mode 100644 index 2b43412c4d6026..00000000000000 --- a/pyextra/click/_compat.py +++ /dev/null @@ -1,648 +0,0 @@ -import re -import io -import os -import sys -import codecs -from weakref import WeakKeyDictionary - - -PY2 = sys.version_info[0] == 2 -WIN = sys.platform.startswith('win') -DEFAULT_COLUMNS = 80 - - -_ansi_re = re.compile('\033\[((?:\d|;)*)([a-zA-Z])') - - -def get_filesystem_encoding(): - return sys.getfilesystemencoding() or sys.getdefaultencoding() - - -def _make_text_stream(stream, encoding, errors): - if encoding is None: - encoding = get_best_encoding(stream) - if errors is None: - errors = 'replace' - return _NonClosingTextIOWrapper(stream, encoding, errors, - line_buffering=True) - - -def is_ascii_encoding(encoding): - """Checks if a given encoding is ascii.""" - try: - return codecs.lookup(encoding).name == 'ascii' - except LookupError: - return False - - -def get_best_encoding(stream): - """Returns the default stream encoding if not found.""" - rv = getattr(stream, 'encoding', None) or sys.getdefaultencoding() - if is_ascii_encoding(rv): - return 'utf-8' - return rv - - -class _NonClosingTextIOWrapper(io.TextIOWrapper): - - def __init__(self, stream, encoding, errors, **extra): - self._stream = stream = _FixupStream(stream) - io.TextIOWrapper.__init__(self, stream, encoding, errors, **extra) - - # The io module is a place where the Python 3 text behavior - # was forced upon Python 2, so we need to unbreak - # it to look like Python 2. - if PY2: - def write(self, x): - if isinstance(x, str) or is_bytes(x): - try: - self.flush() - except Exception: - pass - return self.buffer.write(str(x)) - return io.TextIOWrapper.write(self, x) - - def writelines(self, lines): - for line in lines: - self.write(line) - - def __del__(self): - try: - self.detach() - except Exception: - pass - - def isatty(self): - # https://bitbucket.org/pypy/pypy/issue/1803 - return self._stream.isatty() - - -class _FixupStream(object): - """The new io interface needs more from streams than streams - traditionally implement. As such, this fix-up code is necessary in - some circumstances. - """ - - def __init__(self, stream): - self._stream = stream - - def __getattr__(self, name): - return getattr(self._stream, name) - - def read1(self, size): - f = getattr(self._stream, 'read1', None) - if f is not None: - return f(size) - # We only dispatch to readline instead of read in Python 2 as we - # do not want cause problems with the different implementation - # of line buffering. - if PY2: - return self._stream.readline(size) - return self._stream.read(size) - - def readable(self): - x = getattr(self._stream, 'readable', None) - if x is not None: - return x() - try: - self._stream.read(0) - except Exception: - return False - return True - - def writable(self): - x = getattr(self._stream, 'writable', None) - if x is not None: - return x() - try: - self._stream.write('') - except Exception: - try: - self._stream.write(b'') - except Exception: - return False - return True - - def seekable(self): - x = getattr(self._stream, 'seekable', None) - if x is not None: - return x() - try: - self._stream.seek(self._stream.tell()) - except Exception: - return False - return True - - -if PY2: - text_type = unicode - bytes = str - raw_input = raw_input - string_types = (str, unicode) - iteritems = lambda x: x.iteritems() - range_type = xrange - - def is_bytes(x): - return isinstance(x, (buffer, bytearray)) - - _identifier_re = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$') - - # For Windows, we need to force stdout/stdin/stderr to binary if it's - # fetched for that. This obviously is not the most correct way to do - # it as it changes global state. Unfortunately, there does not seem to - # be a clear better way to do it as just reopening the file in binary - # mode does not change anything. - # - # An option would be to do what Python 3 does and to open the file as - # binary only, patch it back to the system, and then use a wrapper - # stream that converts newlines. It's not quite clear what's the - # correct option here. - # - # This code also lives in _winconsole for the fallback to the console - # emulation stream. - # - # There are also Windows environments where the `msvcrt` module is not - # available (which is why we use try-catch instead of the WIN variable - # here), such as the Google App Engine development server on Windows. In - # those cases there is just nothing we can do. - try: - import msvcrt - except ImportError: - set_binary_mode = lambda x: x - else: - def set_binary_mode(f): - try: - fileno = f.fileno() - except Exception: - pass - else: - msvcrt.setmode(fileno, os.O_BINARY) - return f - - def isidentifier(x): - return _identifier_re.search(x) is not None - - def get_binary_stdin(): - return set_binary_mode(sys.stdin) - - def get_binary_stdout(): - return set_binary_mode(sys.stdout) - - def get_binary_stderr(): - return set_binary_mode(sys.stderr) - - def get_text_stdin(encoding=None, errors=None): - rv = _get_windows_console_stream(sys.stdin, encoding, errors) - if rv is not None: - return rv - return _make_text_stream(sys.stdin, encoding, errors) - - def get_text_stdout(encoding=None, errors=None): - rv = _get_windows_console_stream(sys.stdout, encoding, errors) - if rv is not None: - return rv - return _make_text_stream(sys.stdout, encoding, errors) - - def get_text_stderr(encoding=None, errors=None): - rv = _get_windows_console_stream(sys.stderr, encoding, errors) - if rv is not None: - return rv - return _make_text_stream(sys.stderr, encoding, errors) - - def filename_to_ui(value): - if isinstance(value, bytes): - value = value.decode(get_filesystem_encoding(), 'replace') - return value -else: - import io - text_type = str - raw_input = input - string_types = (str,) - range_type = range - isidentifier = lambda x: x.isidentifier() - iteritems = lambda x: iter(x.items()) - - def is_bytes(x): - return isinstance(x, (bytes, memoryview, bytearray)) - - def _is_binary_reader(stream, default=False): - try: - return isinstance(stream.read(0), bytes) - except Exception: - return default - # This happens in some cases where the stream was already - # closed. In this case, we assume the default. - - def _is_binary_writer(stream, default=False): - try: - stream.write(b'') - except Exception: - try: - stream.write('') - return False - except Exception: - pass - return default - return True - - def _find_binary_reader(stream): - # We need to figure out if the given stream is already binary. - # This can happen because the official docs recommend detaching - # the streams to get binary streams. Some code might do this, so - # we need to deal with this case explicitly. - if _is_binary_reader(stream, False): - return stream - - buf = getattr(stream, 'buffer', None) - - # Same situation here; this time we assume that the buffer is - # actually binary in case it's closed. - if buf is not None and _is_binary_reader(buf, True): - return buf - - def _find_binary_writer(stream): - # We need to figure out if the given stream is already binary. - # This can happen because the official docs recommend detatching - # the streams to get binary streams. Some code might do this, so - # we need to deal with this case explicitly. - if _is_binary_writer(stream, False): - return stream - - buf = getattr(stream, 'buffer', None) - - # Same situation here; this time we assume that the buffer is - # actually binary in case it's closed. - if buf is not None and _is_binary_writer(buf, True): - return buf - - def _stream_is_misconfigured(stream): - """A stream is misconfigured if its encoding is ASCII.""" - # If the stream does not have an encoding set, we assume it's set - # to ASCII. This appears to happen in certain unittest - # environments. It's not quite clear what the correct behavior is - # but this at least will force Click to recover somehow. - return is_ascii_encoding(getattr(stream, 'encoding', None) or 'ascii') - - def _is_compatible_text_stream(stream, encoding, errors): - stream_encoding = getattr(stream, 'encoding', None) - stream_errors = getattr(stream, 'errors', None) - - # Perfect match. - if stream_encoding == encoding and stream_errors == errors: - return True - - # Otherwise, it's only a compatible stream if we did not ask for - # an encoding. - if encoding is None: - return stream_encoding is not None - - return False - - def _force_correct_text_reader(text_reader, encoding, errors): - if _is_binary_reader(text_reader, False): - binary_reader = text_reader - else: - # If there is no target encoding set, we need to verify that the - # reader is not actually misconfigured. - if encoding is None and not _stream_is_misconfigured(text_reader): - return text_reader - - if _is_compatible_text_stream(text_reader, encoding, errors): - return text_reader - - # If the reader has no encoding, we try to find the underlying - # binary reader for it. If that fails because the environment is - # misconfigured, we silently go with the same reader because this - # is too common to happen. In that case, mojibake is better than - # exceptions. - binary_reader = _find_binary_reader(text_reader) - if binary_reader is None: - return text_reader - - # At this point, we default the errors to replace instead of strict - # because nobody handles those errors anyways and at this point - # we're so fundamentally fucked that nothing can repair it. - if errors is None: - errors = 'replace' - return _make_text_stream(binary_reader, encoding, errors) - - def _force_correct_text_writer(text_writer, encoding, errors): - if _is_binary_writer(text_writer, False): - binary_writer = text_writer - else: - # If there is no target encoding set, we need to verify that the - # writer is not actually misconfigured. - if encoding is None and not _stream_is_misconfigured(text_writer): - return text_writer - - if _is_compatible_text_stream(text_writer, encoding, errors): - return text_writer - - # If the writer has no encoding, we try to find the underlying - # binary writer for it. If that fails because the environment is - # misconfigured, we silently go with the same writer because this - # is too common to happen. In that case, mojibake is better than - # exceptions. - binary_writer = _find_binary_writer(text_writer) - if binary_writer is None: - return text_writer - - # At this point, we default the errors to replace instead of strict - # because nobody handles those errors anyways and at this point - # we're so fundamentally fucked that nothing can repair it. - if errors is None: - errors = 'replace' - return _make_text_stream(binary_writer, encoding, errors) - - def get_binary_stdin(): - reader = _find_binary_reader(sys.stdin) - if reader is None: - raise RuntimeError('Was not able to determine binary ' - 'stream for sys.stdin.') - return reader - - def get_binary_stdout(): - writer = _find_binary_writer(sys.stdout) - if writer is None: - raise RuntimeError('Was not able to determine binary ' - 'stream for sys.stdout.') - return writer - - def get_binary_stderr(): - writer = _find_binary_writer(sys.stderr) - if writer is None: - raise RuntimeError('Was not able to determine binary ' - 'stream for sys.stderr.') - return writer - - def get_text_stdin(encoding=None, errors=None): - rv = _get_windows_console_stream(sys.stdin, encoding, errors) - if rv is not None: - return rv - return _force_correct_text_reader(sys.stdin, encoding, errors) - - def get_text_stdout(encoding=None, errors=None): - rv = _get_windows_console_stream(sys.stdout, encoding, errors) - if rv is not None: - return rv - return _force_correct_text_writer(sys.stdout, encoding, errors) - - def get_text_stderr(encoding=None, errors=None): - rv = _get_windows_console_stream(sys.stderr, encoding, errors) - if rv is not None: - return rv - return _force_correct_text_writer(sys.stderr, encoding, errors) - - def filename_to_ui(value): - if isinstance(value, bytes): - value = value.decode(get_filesystem_encoding(), 'replace') - else: - value = value.encode('utf-8', 'surrogateescape') \ - .decode('utf-8', 'replace') - return value - - -def get_streerror(e, default=None): - if hasattr(e, 'strerror'): - msg = e.strerror - else: - if default is not None: - msg = default - else: - msg = str(e) - if isinstance(msg, bytes): - msg = msg.decode('utf-8', 'replace') - return msg - - -def open_stream(filename, mode='r', encoding=None, errors='strict', - atomic=False): - # Standard streams first. These are simple because they don't need - # special handling for the atomic flag. It's entirely ignored. - if filename == '-': - if 'w' in mode: - if 'b' in mode: - return get_binary_stdout(), False - return get_text_stdout(encoding=encoding, errors=errors), False - if 'b' in mode: - return get_binary_stdin(), False - return get_text_stdin(encoding=encoding, errors=errors), False - - # Non-atomic writes directly go out through the regular open functions. - if not atomic: - if encoding is None: - return open(filename, mode), True - return io.open(filename, mode, encoding=encoding, errors=errors), True - - # Some usability stuff for atomic writes - if 'a' in mode: - raise ValueError( - 'Appending to an existing file is not supported, because that ' - 'would involve an expensive `copy`-operation to a temporary ' - 'file. Open the file in normal `w`-mode and copy explicitly ' - 'if that\'s what you\'re after.' - ) - if 'x' in mode: - raise ValueError('Use the `overwrite`-parameter instead.') - if 'w' not in mode: - raise ValueError('Atomic writes only make sense with `w`-mode.') - - # Atomic writes are more complicated. They work by opening a file - # as a proxy in the same folder and then using the fdopen - # functionality to wrap it in a Python file. Then we wrap it in an - # atomic file that moves the file over on close. - import tempfile - fd, tmp_filename = tempfile.mkstemp(dir=os.path.dirname(filename), - prefix='.__atomic-write') - - if encoding is not None: - f = io.open(fd, mode, encoding=encoding, errors=errors) - else: - f = os.fdopen(fd, mode) - - return _AtomicFile(f, tmp_filename, filename), True - - -# Used in a destructor call, needs extra protection from interpreter cleanup. -if hasattr(os, 'replace'): - _replace = os.replace - _can_replace = True -else: - _replace = os.rename - _can_replace = not WIN - - -class _AtomicFile(object): - - def __init__(self, f, tmp_filename, real_filename): - self._f = f - self._tmp_filename = tmp_filename - self._real_filename = real_filename - self.closed = False - - @property - def name(self): - return self._real_filename - - def close(self, delete=False): - if self.closed: - return - self._f.close() - if not _can_replace: - try: - os.remove(self._real_filename) - except OSError: - pass - _replace(self._tmp_filename, self._real_filename) - self.closed = True - - def __getattr__(self, name): - return getattr(self._f, name) - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, tb): - self.close(delete=exc_type is not None) - - def __repr__(self): - return repr(self._f) - - -auto_wrap_for_ansi = None -colorama = None -get_winterm_size = None - - -def strip_ansi(value): - return _ansi_re.sub('', value) - - -def should_strip_ansi(stream=None, color=None): - if color is None: - if stream is None: - stream = sys.stdin - return not isatty(stream) - return not color - - -# If we're on Windows, we provide transparent integration through -# colorama. This will make ANSI colors through the echo function -# work automatically. -if WIN: - # Windows has a smaller terminal - DEFAULT_COLUMNS = 79 - - from ._winconsole import _get_windows_console_stream - - def _get_argv_encoding(): - import locale - return locale.getpreferredencoding() - - if PY2: - def raw_input(prompt=''): - sys.stderr.flush() - if prompt: - stdout = _default_text_stdout() - stdout.write(prompt) - stdin = _default_text_stdin() - return stdin.readline().rstrip('\r\n') - - try: - import colorama - except ImportError: - pass - else: - _ansi_stream_wrappers = WeakKeyDictionary() - - def auto_wrap_for_ansi(stream, color=None): - """This function wraps a stream so that calls through colorama - are issued to the win32 console API to recolor on demand. It - also ensures to reset the colors if a write call is interrupted - to not destroy the console afterwards. - """ - try: - cached = _ansi_stream_wrappers.get(stream) - except Exception: - cached = None - if cached is not None: - return cached - strip = should_strip_ansi(stream, color) - ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip) - rv = ansi_wrapper.stream - _write = rv.write - - def _safe_write(s): - try: - return _write(s) - except: - ansi_wrapper.reset_all() - raise - - rv.write = _safe_write - try: - _ansi_stream_wrappers[stream] = rv - except Exception: - pass - return rv - - def get_winterm_size(): - win = colorama.win32.GetConsoleScreenBufferInfo( - colorama.win32.STDOUT).srWindow - return win.Right - win.Left, win.Bottom - win.Top -else: - def _get_argv_encoding(): - return getattr(sys.stdin, 'encoding', None) or get_filesystem_encoding() - - _get_windows_console_stream = lambda *x: None - - -def term_len(x): - return len(strip_ansi(x)) - - -def isatty(stream): - try: - return stream.isatty() - except Exception: - return False - - -def _make_cached_stream_func(src_func, wrapper_func): - cache = WeakKeyDictionary() - def func(): - stream = src_func() - try: - rv = cache.get(stream) - except Exception: - rv = None - if rv is not None: - return rv - rv = wrapper_func() - try: - cache[stream] = rv - except Exception: - pass - return rv - return func - - -_default_text_stdin = _make_cached_stream_func( - lambda: sys.stdin, get_text_stdin) -_default_text_stdout = _make_cached_stream_func( - lambda: sys.stdout, get_text_stdout) -_default_text_stderr = _make_cached_stream_func( - lambda: sys.stderr, get_text_stderr) - - -binary_streams = { - 'stdin': get_binary_stdin, - 'stdout': get_binary_stdout, - 'stderr': get_binary_stderr, -} - -text_streams = { - 'stdin': get_text_stdin, - 'stdout': get_text_stdout, - 'stderr': get_text_stderr, -} diff --git a/pyextra/click/_termui_impl.py b/pyextra/click/_termui_impl.py deleted file mode 100644 index 7cfd3d5c4a058b..00000000000000 --- a/pyextra/click/_termui_impl.py +++ /dev/null @@ -1,547 +0,0 @@ -""" - click._termui_impl - ~~~~~~~~~~~~~~~~~~ - - This module contains implementations for the termui module. To keep the - import time of Click down, some infrequently used functionality is placed - in this module and only imported as needed. - - :copyright: (c) 2014 by Armin Ronacher. - :license: BSD, see LICENSE for more details. -""" -import os -import sys -import time -import math -from ._compat import _default_text_stdout, range_type, PY2, isatty, \ - open_stream, strip_ansi, term_len, get_best_encoding, WIN -from .utils import echo -from .exceptions import ClickException - - -if os.name == 'nt': - BEFORE_BAR = '\r' - AFTER_BAR = '\n' -else: - BEFORE_BAR = '\r\033[?25l' - AFTER_BAR = '\033[?25h\n' - - -def _length_hint(obj): - """Returns the length hint of an object.""" - try: - return len(obj) - except (AttributeError, TypeError): - try: - get_hint = type(obj).__length_hint__ - except AttributeError: - return None - try: - hint = get_hint(obj) - except TypeError: - return None - if hint is NotImplemented or \ - not isinstance(hint, (int, long)) or \ - hint < 0: - return None - return hint - - -class ProgressBar(object): - - def __init__(self, iterable, length=None, fill_char='#', empty_char=' ', - bar_template='%(bar)s', info_sep=' ', show_eta=True, - show_percent=None, show_pos=False, item_show_func=None, - label=None, file=None, color=None, width=30): - self.fill_char = fill_char - self.empty_char = empty_char - self.bar_template = bar_template - self.info_sep = info_sep - self.show_eta = show_eta - self.show_percent = show_percent - self.show_pos = show_pos - self.item_show_func = item_show_func - self.label = label or '' - if file is None: - file = _default_text_stdout() - self.file = file - self.color = color - self.width = width - self.autowidth = width == 0 - - if length is None: - length = _length_hint(iterable) - if iterable is None: - if length is None: - raise TypeError('iterable or length is required') - iterable = range_type(length) - self.iter = iter(iterable) - self.length = length - self.length_known = length is not None - self.pos = 0 - self.avg = [] - self.start = self.last_eta = time.time() - self.eta_known = False - self.finished = False - self.max_width = None - self.entered = False - self.current_item = None - self.is_hidden = not isatty(self.file) - self._last_line = None - - def __enter__(self): - self.entered = True - self.render_progress() - return self - - def __exit__(self, exc_type, exc_value, tb): - self.render_finish() - - def __iter__(self): - if not self.entered: - raise RuntimeError('You need to use progress bars in a with block.') - self.render_progress() - return self - - def render_finish(self): - if self.is_hidden: - return - self.file.write(AFTER_BAR) - self.file.flush() - - @property - def pct(self): - if self.finished: - return 1.0 - return min(self.pos / (float(self.length) or 1), 1.0) - - @property - def time_per_iteration(self): - if not self.avg: - return 0.0 - return sum(self.avg) / float(len(self.avg)) - - @property - def eta(self): - if self.length_known and not self.finished: - return self.time_per_iteration * (self.length - self.pos) - return 0.0 - - def format_eta(self): - if self.eta_known: - t = self.eta + 1 - seconds = t % 60 - t /= 60 - minutes = t % 60 - t /= 60 - hours = t % 24 - t /= 24 - if t > 0: - days = t - return '%dd %02d:%02d:%02d' % (days, hours, minutes, seconds) - else: - return '%02d:%02d:%02d' % (hours, minutes, seconds) - return '' - - def format_pos(self): - pos = str(self.pos) - if self.length_known: - pos += '/%s' % self.length - return pos - - def format_pct(self): - return ('% 4d%%' % int(self.pct * 100))[1:] - - def format_progress_line(self): - show_percent = self.show_percent - - info_bits = [] - if self.length_known: - bar_length = int(self.pct * self.width) - bar = self.fill_char * bar_length - bar += self.empty_char * (self.width - bar_length) - if show_percent is None: - show_percent = not self.show_pos - else: - if self.finished: - bar = self.fill_char * self.width - else: - bar = list(self.empty_char * (self.width or 1)) - if self.time_per_iteration != 0: - bar[int((math.cos(self.pos * self.time_per_iteration) - / 2.0 + 0.5) * self.width)] = self.fill_char - bar = ''.join(bar) - - if self.show_pos: - info_bits.append(self.format_pos()) - if show_percent: - info_bits.append(self.format_pct()) - if self.show_eta and self.eta_known and not self.finished: - info_bits.append(self.format_eta()) - if self.item_show_func is not None: - item_info = self.item_show_func(self.current_item) - if item_info is not None: - info_bits.append(item_info) - - return (self.bar_template % { - 'label': self.label, - 'bar': bar, - 'info': self.info_sep.join(info_bits) - }).rstrip() - - def render_progress(self): - from .termui import get_terminal_size - nl = False - - if self.is_hidden: - buf = [self.label] - nl = True - else: - buf = [] - # Update width in case the terminal has been resized - if self.autowidth: - old_width = self.width - self.width = 0 - clutter_length = term_len(self.format_progress_line()) - new_width = max(0, get_terminal_size()[0] - clutter_length) - if new_width < old_width: - buf.append(BEFORE_BAR) - buf.append(' ' * self.max_width) - self.max_width = new_width - self.width = new_width - - clear_width = self.width - if self.max_width is not None: - clear_width = self.max_width - - buf.append(BEFORE_BAR) - line = self.format_progress_line() - line_len = term_len(line) - if self.max_width is None or self.max_width < line_len: - self.max_width = line_len - buf.append(line) - - buf.append(' ' * (clear_width - line_len)) - line = ''.join(buf) - - # Render the line only if it changed. - if line != self._last_line: - self._last_line = line - echo(line, file=self.file, color=self.color, nl=nl) - self.file.flush() - - def make_step(self, n_steps): - self.pos += n_steps - if self.length_known and self.pos >= self.length: - self.finished = True - - if (time.time() - self.last_eta) < 1.0: - return - - self.last_eta = time.time() - self.avg = self.avg[-6:] + [-(self.start - time.time()) / (self.pos)] - - self.eta_known = self.length_known - - def update(self, n_steps): - self.make_step(n_steps) - self.render_progress() - - def finish(self): - self.eta_known = 0 - self.current_item = None - self.finished = True - - def next(self): - if self.is_hidden: - return next(self.iter) - try: - rv = next(self.iter) - self.current_item = rv - except StopIteration: - self.finish() - self.render_progress() - raise StopIteration() - else: - self.update(1) - return rv - - if not PY2: - __next__ = next - del next - - -def pager(text, color=None): - """Decide what method to use for paging through text.""" - stdout = _default_text_stdout() - if not isatty(sys.stdin) or not isatty(stdout): - return _nullpager(stdout, text, color) - pager_cmd = (os.environ.get('PAGER', None) or '').strip() - if pager_cmd: - if WIN: - return _tempfilepager(text, pager_cmd, color) - return _pipepager(text, pager_cmd, color) - if os.environ.get('TERM') in ('dumb', 'emacs'): - return _nullpager(stdout, text, color) - if WIN or sys.platform.startswith('os2'): - return _tempfilepager(text, 'more <', color) - if hasattr(os, 'system') and os.system('(less) 2>/dev/null') == 0: - return _pipepager(text, 'less', color) - - import tempfile - fd, filename = tempfile.mkstemp() - os.close(fd) - try: - if hasattr(os, 'system') and os.system('more "%s"' % filename) == 0: - return _pipepager(text, 'more', color) - return _nullpager(stdout, text, color) - finally: - os.unlink(filename) - - -def _pipepager(text, cmd, color): - """Page through text by feeding it to another program. Invoking a - pager through this might support colors. - """ - import subprocess - env = dict(os.environ) - - # If we're piping to less we might support colors under the - # condition that - cmd_detail = cmd.rsplit('/', 1)[-1].split() - if color is None and cmd_detail[0] == 'less': - less_flags = os.environ.get('LESS', '') + ' '.join(cmd_detail[1:]) - if not less_flags: - env['LESS'] = '-R' - color = True - elif 'r' in less_flags or 'R' in less_flags: - color = True - - if not color: - text = strip_ansi(text) - - c = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, - env=env) - encoding = get_best_encoding(c.stdin) - try: - c.stdin.write(text.encode(encoding, 'replace')) - c.stdin.close() - except (IOError, KeyboardInterrupt): - pass - - # Less doesn't respect ^C, but catches it for its own UI purposes (aborting - # search or other commands inside less). - # - # That means when the user hits ^C, the parent process (click) terminates, - # but less is still alive, paging the output and messing up the terminal. - # - # If the user wants to make the pager exit on ^C, they should set - # `LESS='-K'`. It's not our decision to make. - while True: - try: - c.wait() - except KeyboardInterrupt: - pass - else: - break - - -def _tempfilepager(text, cmd, color): - """Page through text by invoking a program on a temporary file.""" - import tempfile - filename = tempfile.mktemp() - if not color: - text = strip_ansi(text) - encoding = get_best_encoding(sys.stdout) - with open_stream(filename, 'wb')[0] as f: - f.write(text.encode(encoding)) - try: - os.system(cmd + ' "' + filename + '"') - finally: - os.unlink(filename) - - -def _nullpager(stream, text, color): - """Simply print unformatted text. This is the ultimate fallback.""" - if not color: - text = strip_ansi(text) - stream.write(text) - - -class Editor(object): - - def __init__(self, editor=None, env=None, require_save=True, - extension='.txt'): - self.editor = editor - self.env = env - self.require_save = require_save - self.extension = extension - - def get_editor(self): - if self.editor is not None: - return self.editor - for key in 'VISUAL', 'EDITOR': - rv = os.environ.get(key) - if rv: - return rv - if WIN: - return 'notepad' - for editor in 'vim', 'nano': - if os.system('which %s >/dev/null 2>&1' % editor) == 0: - return editor - return 'vi' - - def edit_file(self, filename): - import subprocess - editor = self.get_editor() - if self.env: - environ = os.environ.copy() - environ.update(self.env) - else: - environ = None - try: - c = subprocess.Popen('%s "%s"' % (editor, filename), - env=environ, shell=True) - exit_code = c.wait() - if exit_code != 0: - raise ClickException('%s: Editing failed!' % editor) - except OSError as e: - raise ClickException('%s: Editing failed: %s' % (editor, e)) - - def edit(self, text): - import tempfile - - text = text or '' - if text and not text.endswith('\n'): - text += '\n' - - fd, name = tempfile.mkstemp(prefix='editor-', suffix=self.extension) - try: - if WIN: - encoding = 'utf-8-sig' - text = text.replace('\n', '\r\n') - else: - encoding = 'utf-8' - text = text.encode(encoding) - - f = os.fdopen(fd, 'wb') - f.write(text) - f.close() - timestamp = os.path.getmtime(name) - - self.edit_file(name) - - if self.require_save \ - and os.path.getmtime(name) == timestamp: - return None - - f = open(name, 'rb') - try: - rv = f.read() - finally: - f.close() - return rv.decode('utf-8-sig').replace('\r\n', '\n') - finally: - os.unlink(name) - - -def open_url(url, wait=False, locate=False): - import subprocess - - def _unquote_file(url): - try: - import urllib - except ImportError: - import urllib - if url.startswith('file://'): - url = urllib.unquote(url[7:]) - return url - - if sys.platform == 'darwin': - args = ['open'] - if wait: - args.append('-W') - if locate: - args.append('-R') - args.append(_unquote_file(url)) - null = open('/dev/null', 'w') - try: - return subprocess.Popen(args, stderr=null).wait() - finally: - null.close() - elif WIN: - if locate: - url = _unquote_file(url) - args = 'explorer /select,"%s"' % _unquote_file( - url.replace('"', '')) - else: - args = 'start %s "" "%s"' % ( - wait and '/WAIT' or '', url.replace('"', '')) - return os.system(args) - - try: - if locate: - url = os.path.dirname(_unquote_file(url)) or '.' - else: - url = _unquote_file(url) - c = subprocess.Popen(['xdg-open', url]) - if wait: - return c.wait() - return 0 - except OSError: - if url.startswith(('http://', 'https://')) and not locate and not wait: - import webbrowser - webbrowser.open(url) - return 0 - return 1 - - -def _translate_ch_to_exc(ch): - if ch == '\x03': - raise KeyboardInterrupt() - if ch == '\x04': - raise EOFError() - - -if WIN: - import msvcrt - - def getchar(echo): - rv = msvcrt.getch() - if echo: - msvcrt.putchar(rv) - _translate_ch_to_exc(rv) - if PY2: - enc = getattr(sys.stdin, 'encoding', None) - if enc is not None: - rv = rv.decode(enc, 'replace') - else: - rv = rv.decode('cp1252', 'replace') - return rv -else: - import tty - import termios - - def getchar(echo): - if not isatty(sys.stdin): - f = open('/dev/tty') - fd = f.fileno() - else: - fd = sys.stdin.fileno() - f = None - try: - old_settings = termios.tcgetattr(fd) - try: - tty.setraw(fd) - ch = os.read(fd, 32) - if echo and isatty(sys.stdout): - sys.stdout.write(ch) - finally: - termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) - sys.stdout.flush() - if f is not None: - f.close() - except termios.error: - pass - _translate_ch_to_exc(ch) - return ch.decode(get_best_encoding(sys.stdin), 'replace') diff --git a/pyextra/click/_textwrap.py b/pyextra/click/_textwrap.py deleted file mode 100644 index 7e776031eaa929..00000000000000 --- a/pyextra/click/_textwrap.py +++ /dev/null @@ -1,38 +0,0 @@ -import textwrap -from contextlib import contextmanager - - -class TextWrapper(textwrap.TextWrapper): - - def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width): - space_left = max(width - cur_len, 1) - - if self.break_long_words: - last = reversed_chunks[-1] - cut = last[:space_left] - res = last[space_left:] - cur_line.append(cut) - reversed_chunks[-1] = res - elif not cur_line: - cur_line.append(reversed_chunks.pop()) - - @contextmanager - def extra_indent(self, indent): - old_initial_indent = self.initial_indent - old_subsequent_indent = self.subsequent_indent - self.initial_indent += indent - self.subsequent_indent += indent - try: - yield - finally: - self.initial_indent = old_initial_indent - self.subsequent_indent = old_subsequent_indent - - def indent_only(self, text): - rv = [] - for idx, line in enumerate(text.splitlines()): - indent = self.initial_indent - if idx > 0: - indent = self.subsequent_indent - rv.append(indent + line) - return '\n'.join(rv) diff --git a/pyextra/click/_unicodefun.py b/pyextra/click/_unicodefun.py deleted file mode 100644 index 9e17a384eff036..00000000000000 --- a/pyextra/click/_unicodefun.py +++ /dev/null @@ -1,118 +0,0 @@ -import os -import sys -import codecs - -from ._compat import PY2 - - -# If someone wants to vendor click, we want to ensure the -# correct package is discovered. Ideally we could use a -# relative import here but unfortunately Python does not -# support that. -click = sys.modules[__name__.rsplit('.', 1)[0]] - - -def _find_unicode_literals_frame(): - import __future__ - frm = sys._getframe(1) - idx = 1 - while frm is not None: - if frm.f_globals.get('__name__', '').startswith('click.'): - frm = frm.f_back - idx += 1 - elif frm.f_code.co_flags & __future__.unicode_literals.compiler_flag: - return idx - else: - break - return 0 - - -def _check_for_unicode_literals(): - if not __debug__: - return - if not PY2 or click.disable_unicode_literals_warning: - return - bad_frame = _find_unicode_literals_frame() - if bad_frame <= 0: - return - from warnings import warn - warn(Warning('Click detected the use of the unicode_literals ' - '__future__ import. This is heavily discouraged ' - 'because it can introduce subtle bugs in your ' - 'code. You should instead use explicit u"" literals ' - 'for your unicode strings. For more information see ' - 'http://click.pocoo.org/python3/'), - stacklevel=bad_frame) - - -def _verify_python3_env(): - """Ensures that the environment is good for unicode on Python 3.""" - if PY2: - return - try: - import locale - fs_enc = codecs.lookup(locale.getpreferredencoding()).name - except Exception: - fs_enc = 'ascii' - if fs_enc != 'ascii': - return - - extra = '' - if os.name == 'posix': - import subprocess - rv = subprocess.Popen(['locale', '-a'], stdout=subprocess.PIPE, - stderr=subprocess.PIPE).communicate()[0] - good_locales = set() - has_c_utf8 = False - - # Make sure we're operating on text here. - if isinstance(rv, bytes): - rv = rv.decode('ascii', 'replace') - - for line in rv.splitlines(): - locale = line.strip() - if locale.lower().endswith(('.utf-8', '.utf8')): - good_locales.add(locale) - if locale.lower() in ('c.utf8', 'c.utf-8'): - has_c_utf8 = True - - extra += '\n\n' - if not good_locales: - extra += ( - 'Additional information: on this system no suitable UTF-8\n' - 'locales were discovered. This most likely requires resolving\n' - 'by reconfiguring the locale system.' - ) - elif has_c_utf8: - extra += ( - 'This system supports the C.UTF-8 locale which is recommended.\n' - 'You might be able to resolve your issue by exporting the\n' - 'following environment variables:\n\n' - ' export LC_ALL=C.UTF-8\n' - ' export LANG=C.UTF-8' - ) - else: - extra += ( - 'This system lists a couple of UTF-8 supporting locales that\n' - 'you can pick from. The following suitable locales where\n' - 'discovered: %s' - ) % ', '.join(sorted(good_locales)) - - bad_locale = None - for locale in os.environ.get('LC_ALL'), os.environ.get('LANG'): - if locale and locale.lower().endswith(('.utf-8', '.utf8')): - bad_locale = locale - if locale is not None: - break - if bad_locale is not None: - extra += ( - '\n\nClick discovered that you exported a UTF-8 locale\n' - 'but the locale system could not pick up from it because\n' - 'it does not exist. The exported locale is "%s" but it\n' - 'is not supported' - ) % bad_locale - - raise RuntimeError('Click will abort further execution because Python 3 ' - 'was configured to use ASCII as encoding for the ' - 'environment. Consult http://click.pocoo.org/python3/' - 'for mitigation steps.' + extra) diff --git a/pyextra/click/_winconsole.py b/pyextra/click/_winconsole.py deleted file mode 100644 index 9aed942162bbdd..00000000000000 --- a/pyextra/click/_winconsole.py +++ /dev/null @@ -1,273 +0,0 @@ -# -*- coding: utf-8 -*- -# This module is based on the excellent work by Adam Bartoš who -# provided a lot of what went into the implementation here in -# the discussion to issue1602 in the Python bug tracker. -# -# There are some general differences in regards to how this works -# compared to the original patches as we do not need to patch -# the entire interpreter but just work in our little world of -# echo and prmopt. - -import io -import os -import sys -import zlib -import time -import ctypes -import msvcrt -from click._compat import _NonClosingTextIOWrapper, text_type, PY2 -from ctypes import byref, POINTER, c_int, c_char, c_char_p, \ - c_void_p, py_object, c_ssize_t, c_ulong, windll, WINFUNCTYPE -try: - from ctypes import pythonapi - PyObject_GetBuffer = pythonapi.PyObject_GetBuffer - PyBuffer_Release = pythonapi.PyBuffer_Release -except ImportError: - pythonapi = None -from ctypes.wintypes import LPWSTR, LPCWSTR - - -c_ssize_p = POINTER(c_ssize_t) - -kernel32 = windll.kernel32 -GetStdHandle = kernel32.GetStdHandle -ReadConsoleW = kernel32.ReadConsoleW -WriteConsoleW = kernel32.WriteConsoleW -GetLastError = kernel32.GetLastError -GetCommandLineW = WINFUNCTYPE(LPWSTR)( - ('GetCommandLineW', windll.kernel32)) -CommandLineToArgvW = WINFUNCTYPE( - POINTER(LPWSTR), LPCWSTR, POINTER(c_int))( - ('CommandLineToArgvW', windll.shell32)) - - -STDIN_HANDLE = GetStdHandle(-10) -STDOUT_HANDLE = GetStdHandle(-11) -STDERR_HANDLE = GetStdHandle(-12) - - -PyBUF_SIMPLE = 0 -PyBUF_WRITABLE = 1 - -ERROR_SUCCESS = 0 -ERROR_NOT_ENOUGH_MEMORY = 8 -ERROR_OPERATION_ABORTED = 995 - -STDIN_FILENO = 0 -STDOUT_FILENO = 1 -STDERR_FILENO = 2 - -EOF = b'\x1a' -MAX_BYTES_WRITTEN = 32767 - - -class Py_buffer(ctypes.Structure): - _fields_ = [ - ('buf', c_void_p), - ('obj', py_object), - ('len', c_ssize_t), - ('itemsize', c_ssize_t), - ('readonly', c_int), - ('ndim', c_int), - ('format', c_char_p), - ('shape', c_ssize_p), - ('strides', c_ssize_p), - ('suboffsets', c_ssize_p), - ('internal', c_void_p) - ] - - if PY2: - _fields_.insert(-1, ('smalltable', c_ssize_t * 2)) - - -# On PyPy we cannot get buffers so our ability to operate here is -# serverly limited. -if pythonapi is None: - get_buffer = None -else: - def get_buffer(obj, writable=False): - buf = Py_buffer() - flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE - PyObject_GetBuffer(py_object(obj), byref(buf), flags) - try: - buffer_type = c_char * buf.len - return buffer_type.from_address(buf.buf) - finally: - PyBuffer_Release(byref(buf)) - - -class _WindowsConsoleRawIOBase(io.RawIOBase): - - def __init__(self, handle): - self.handle = handle - - def isatty(self): - io.RawIOBase.isatty(self) - return True - - -class _WindowsConsoleReader(_WindowsConsoleRawIOBase): - - def readable(self): - return True - - def readinto(self, b): - bytes_to_be_read = len(b) - if not bytes_to_be_read: - return 0 - elif bytes_to_be_read % 2: - raise ValueError('cannot read odd number of bytes from ' - 'UTF-16-LE encoded console') - - buffer = get_buffer(b, writable=True) - code_units_to_be_read = bytes_to_be_read // 2 - code_units_read = c_ulong() - - rv = ReadConsoleW(self.handle, buffer, code_units_to_be_read, - byref(code_units_read), None) - if GetLastError() == ERROR_OPERATION_ABORTED: - # wait for KeyboardInterrupt - time.sleep(0.1) - if not rv: - raise OSError('Windows error: %s' % GetLastError()) - - if buffer[0] == EOF: - return 0 - return 2 * code_units_read.value - - -class _WindowsConsoleWriter(_WindowsConsoleRawIOBase): - - def writable(self): - return True - - @staticmethod - def _get_error_message(errno): - if errno == ERROR_SUCCESS: - return 'ERROR_SUCCESS' - elif errno == ERROR_NOT_ENOUGH_MEMORY: - return 'ERROR_NOT_ENOUGH_MEMORY' - return 'Windows error %s' % errno - - def write(self, b): - bytes_to_be_written = len(b) - buf = get_buffer(b) - code_units_to_be_written = min(bytes_to_be_written, - MAX_BYTES_WRITTEN) // 2 - code_units_written = c_ulong() - - WriteConsoleW(self.handle, buf, code_units_to_be_written, - byref(code_units_written), None) - bytes_written = 2 * code_units_written.value - - if bytes_written == 0 and bytes_to_be_written > 0: - raise OSError(self._get_error_message(GetLastError())) - return bytes_written - - -class ConsoleStream(object): - - def __init__(self, text_stream, byte_stream): - self._text_stream = text_stream - self.buffer = byte_stream - - @property - def name(self): - return self.buffer.name - - def write(self, x): - if isinstance(x, text_type): - return self._text_stream.write(x) - try: - self.flush() - except Exception: - pass - return self.buffer.write(x) - - def writelines(self, lines): - for line in lines: - self.write(line) - - def __getattr__(self, name): - return getattr(self._text_stream, name) - - def isatty(self): - return self.buffer.isatty() - - def __repr__(self): - return '' % ( - self.name, - self.encoding, - ) - - -def _get_text_stdin(buffer_stream): - text_stream = _NonClosingTextIOWrapper( - io.BufferedReader(_WindowsConsoleReader(STDIN_HANDLE)), - 'utf-16-le', 'strict', line_buffering=True) - return ConsoleStream(text_stream, buffer_stream) - - -def _get_text_stdout(buffer_stream): - text_stream = _NonClosingTextIOWrapper( - _WindowsConsoleWriter(STDOUT_HANDLE), - 'utf-16-le', 'strict', line_buffering=True) - return ConsoleStream(text_stream, buffer_stream) - - -def _get_text_stderr(buffer_stream): - text_stream = _NonClosingTextIOWrapper( - _WindowsConsoleWriter(STDERR_HANDLE), - 'utf-16-le', 'strict', line_buffering=True) - return ConsoleStream(text_stream, buffer_stream) - - -if PY2: - def _hash_py_argv(): - return zlib.crc32('\x00'.join(sys.argv[1:])) - - _initial_argv_hash = _hash_py_argv() - - def _get_windows_argv(): - argc = c_int(0) - argv_unicode = CommandLineToArgvW(GetCommandLineW(), byref(argc)) - argv = [argv_unicode[i] for i in range(0, argc.value)] - - if not hasattr(sys, 'frozen'): - argv = argv[1:] - while len(argv) > 0: - arg = argv[0] - if not arg.startswith('-') or arg == '-': - break - argv = argv[1:] - if arg.startswith(('-c', '-m')): - break - - return argv[1:] - - -_stream_factories = { - 0: _get_text_stdin, - 1: _get_text_stdout, - 2: _get_text_stderr, -} - - -def _get_windows_console_stream(f, encoding, errors): - if get_buffer is not None and \ - encoding in ('utf-16-le', None) \ - and errors in ('strict', None) and \ - hasattr(f, 'isatty') and f.isatty(): - func = _stream_factories.get(f.fileno()) - if func is not None: - if not PY2: - f = getattr(f, 'buffer') - if f is None: - return None - else: - # If we are on Python 2 we need to set the stream that we - # deal with to binary mode as otherwise the exercise if a - # bit moot. The same problems apply as for - # get_binary_stdin and friends from _compat. - msvcrt.setmode(f.fileno(), os.O_BINARY) - return func(f) diff --git a/pyextra/click/core.py b/pyextra/click/core.py deleted file mode 100644 index 74564514753131..00000000000000 --- a/pyextra/click/core.py +++ /dev/null @@ -1,1744 +0,0 @@ -import errno -import os -import sys -from contextlib import contextmanager -from itertools import repeat -from functools import update_wrapper - -from .types import convert_type, IntRange, BOOL -from .utils import make_str, make_default_short_help, echo, get_os_args -from .exceptions import ClickException, UsageError, BadParameter, Abort, \ - MissingParameter -from .termui import prompt, confirm -from .formatting import HelpFormatter, join_options -from .parser import OptionParser, split_opt -from .globals import push_context, pop_context - -from ._compat import PY2, isidentifier, iteritems -from ._unicodefun import _check_for_unicode_literals, _verify_python3_env - - -_missing = object() - - -SUBCOMMAND_METAVAR = 'COMMAND [ARGS]...' -SUBCOMMANDS_METAVAR = 'COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...' - - -def _bashcomplete(cmd, prog_name, complete_var=None): - """Internal handler for the bash completion support.""" - if complete_var is None: - complete_var = '_%s_COMPLETE' % (prog_name.replace('-', '_')).upper() - complete_instr = os.environ.get(complete_var) - if not complete_instr: - return - - from ._bashcomplete import bashcomplete - if bashcomplete(cmd, prog_name, complete_var, complete_instr): - sys.exit(1) - - -def _check_multicommand(base_command, cmd_name, cmd, register=False): - if not base_command.chain or not isinstance(cmd, MultiCommand): - return - if register: - hint = 'It is not possible to add multi commands as children to ' \ - 'another multi command that is in chain mode' - else: - hint = 'Found a multi command as subcommand to a multi command ' \ - 'that is in chain mode. This is not supported' - raise RuntimeError('%s. Command "%s" is set to chain and "%s" was ' - 'added as subcommand but it in itself is a ' - 'multi command. ("%s" is a %s within a chained ' - '%s named "%s"). This restriction was supposed to ' - 'be lifted in 6.0 but the fix was flawed. This ' - 'will be fixed in Click 7.0' % ( - hint, base_command.name, cmd_name, - cmd_name, cmd.__class__.__name__, - base_command.__class__.__name__, - base_command.name)) - - -def batch(iterable, batch_size): - return list(zip(*repeat(iter(iterable), batch_size))) - - -def invoke_param_callback(callback, ctx, param, value): - code = getattr(callback, '__code__', None) - args = getattr(code, 'co_argcount', 3) - - if args < 3: - # This will become a warning in Click 3.0: - from warnings import warn - warn(Warning('Invoked legacy parameter callback "%s". The new ' - 'signature for such callbacks starting with ' - 'click 2.0 is (ctx, param, value).' - % callback), stacklevel=3) - return callback(ctx, value) - return callback(ctx, param, value) - - -@contextmanager -def augment_usage_errors(ctx, param=None): - """Context manager that attaches extra information to exceptions that - fly. - """ - try: - yield - except BadParameter as e: - if e.ctx is None: - e.ctx = ctx - if param is not None and e.param is None: - e.param = param - raise - except UsageError as e: - if e.ctx is None: - e.ctx = ctx - raise - - -def iter_params_for_processing(invocation_order, declaration_order): - """Given a sequence of parameters in the order as should be considered - for processing and an iterable of parameters that exist, this returns - a list in the correct order as they should be processed. - """ - def sort_key(item): - try: - idx = invocation_order.index(item) - except ValueError: - idx = float('inf') - return (not item.is_eager, idx) - - return sorted(declaration_order, key=sort_key) - - -class Context(object): - """The context is a special internal object that holds state relevant - for the script execution at every single level. It's normally invisible - to commands unless they opt-in to getting access to it. - - The context is useful as it can pass internal objects around and can - control special execution features such as reading data from - environment variables. - - A context can be used as context manager in which case it will call - :meth:`close` on teardown. - - .. versionadded:: 2.0 - Added the `resilient_parsing`, `help_option_names`, - `token_normalize_func` parameters. - - .. versionadded:: 3.0 - Added the `allow_extra_args` and `allow_interspersed_args` - parameters. - - .. versionadded:: 4.0 - Added the `color`, `ignore_unknown_options`, and - `max_content_width` parameters. - - :param command: the command class for this context. - :param parent: the parent context. - :param info_name: the info name for this invocation. Generally this - is the most descriptive name for the script or - command. For the toplevel script it is usually - the name of the script, for commands below it it's - the name of the script. - :param obj: an arbitrary object of user data. - :param auto_envvar_prefix: the prefix to use for automatic environment - variables. If this is `None` then reading - from environment variables is disabled. This - does not affect manually set environment - variables which are always read. - :param default_map: a dictionary (like object) with default values - for parameters. - :param terminal_width: the width of the terminal. The default is - inherit from parent context. If no context - defines the terminal width then auto - detection will be applied. - :param max_content_width: the maximum width for content rendered by - Click (this currently only affects help - pages). This defaults to 80 characters if - not overridden. In other words: even if the - terminal is larger than that, Click will not - format things wider than 80 characters by - default. In addition to that, formatters might - add some safety mapping on the right. - :param resilient_parsing: if this flag is enabled then Click will - parse without any interactivity or callback - invocation. This is useful for implementing - things such as completion support. - :param allow_extra_args: if this is set to `True` then extra arguments - at the end will not raise an error and will be - kept on the context. The default is to inherit - from the command. - :param allow_interspersed_args: if this is set to `False` then options - and arguments cannot be mixed. The - default is to inherit from the command. - :param ignore_unknown_options: instructs click to ignore options it does - not know and keeps them for later - processing. - :param help_option_names: optionally a list of strings that define how - the default help parameter is named. The - default is ``['--help']``. - :param token_normalize_func: an optional function that is used to - normalize tokens (options, choices, - etc.). This for instance can be used to - implement case insensitive behavior. - :param color: controls if the terminal supports ANSI colors or not. The - default is autodetection. This is only needed if ANSI - codes are used in texts that Click prints which is by - default not the case. This for instance would affect - help output. - """ - - def __init__(self, command, parent=None, info_name=None, obj=None, - auto_envvar_prefix=None, default_map=None, - terminal_width=None, max_content_width=None, - resilient_parsing=False, allow_extra_args=None, - allow_interspersed_args=None, - ignore_unknown_options=None, help_option_names=None, - token_normalize_func=None, color=None): - #: the parent context or `None` if none exists. - self.parent = parent - #: the :class:`Command` for this context. - self.command = command - #: the descriptive information name - self.info_name = info_name - #: the parsed parameters except if the value is hidden in which - #: case it's not remembered. - self.params = {} - #: the leftover arguments. - self.args = [] - #: protected arguments. These are arguments that are prepended - #: to `args` when certain parsing scenarios are encountered but - #: must be never propagated to another arguments. This is used - #: to implement nested parsing. - self.protected_args = [] - if obj is None and parent is not None: - obj = parent.obj - #: the user object stored. - self.obj = obj - self._meta = getattr(parent, 'meta', {}) - - #: A dictionary (-like object) with defaults for parameters. - if default_map is None \ - and parent is not None \ - and parent.default_map is not None: - default_map = parent.default_map.get(info_name) - self.default_map = default_map - - #: This flag indicates if a subcommand is going to be executed. A - #: group callback can use this information to figure out if it's - #: being executed directly or because the execution flow passes - #: onwards to a subcommand. By default it's None, but it can be - #: the name of the subcommand to execute. - #: - #: If chaining is enabled this will be set to ``'*'`` in case - #: any commands are executed. It is however not possible to - #: figure out which ones. If you require this knowledge you - #: should use a :func:`resultcallback`. - self.invoked_subcommand = None - - if terminal_width is None and parent is not None: - terminal_width = parent.terminal_width - #: The width of the terminal (None is autodetection). - self.terminal_width = terminal_width - - if max_content_width is None and parent is not None: - max_content_width = parent.max_content_width - #: The maximum width of formatted content (None implies a sensible - #: default which is 80 for most things). - self.max_content_width = max_content_width - - if allow_extra_args is None: - allow_extra_args = command.allow_extra_args - #: Indicates if the context allows extra args or if it should - #: fail on parsing. - #: - #: .. versionadded:: 3.0 - self.allow_extra_args = allow_extra_args - - if allow_interspersed_args is None: - allow_interspersed_args = command.allow_interspersed_args - #: Indicates if the context allows mixing of arguments and - #: options or not. - #: - #: .. versionadded:: 3.0 - self.allow_interspersed_args = allow_interspersed_args - - if ignore_unknown_options is None: - ignore_unknown_options = command.ignore_unknown_options - #: Instructs click to ignore options that a command does not - #: understand and will store it on the context for later - #: processing. This is primarily useful for situations where you - #: want to call into external programs. Generally this pattern is - #: strongly discouraged because it's not possibly to losslessly - #: forward all arguments. - #: - #: .. versionadded:: 4.0 - self.ignore_unknown_options = ignore_unknown_options - - if help_option_names is None: - if parent is not None: - help_option_names = parent.help_option_names - else: - help_option_names = ['--help'] - - #: The names for the help options. - self.help_option_names = help_option_names - - if token_normalize_func is None and parent is not None: - token_normalize_func = parent.token_normalize_func - - #: An optional normalization function for tokens. This is - #: options, choices, commands etc. - self.token_normalize_func = token_normalize_func - - #: Indicates if resilient parsing is enabled. In that case Click - #: will do its best to not cause any failures. - self.resilient_parsing = resilient_parsing - - # If there is no envvar prefix yet, but the parent has one and - # the command on this level has a name, we can expand the envvar - # prefix automatically. - if auto_envvar_prefix is None: - if parent is not None \ - and parent.auto_envvar_prefix is not None and \ - self.info_name is not None: - auto_envvar_prefix = '%s_%s' % (parent.auto_envvar_prefix, - self.info_name.upper()) - else: - self.auto_envvar_prefix = auto_envvar_prefix.upper() - self.auto_envvar_prefix = auto_envvar_prefix - - if color is None and parent is not None: - color = parent.color - - #: Controls if styling output is wanted or not. - self.color = color - - self._close_callbacks = [] - self._depth = 0 - - def __enter__(self): - self._depth += 1 - push_context(self) - return self - - def __exit__(self, exc_type, exc_value, tb): - self._depth -= 1 - if self._depth == 0: - self.close() - pop_context() - - @contextmanager - def scope(self, cleanup=True): - """This helper method can be used with the context object to promote - it to the current thread local (see :func:`get_current_context`). - The default behavior of this is to invoke the cleanup functions which - can be disabled by setting `cleanup` to `False`. The cleanup - functions are typically used for things such as closing file handles. - - If the cleanup is intended the context object can also be directly - used as a context manager. - - Example usage:: - - with ctx.scope(): - assert get_current_context() is ctx - - This is equivalent:: - - with ctx: - assert get_current_context() is ctx - - .. versionadded:: 5.0 - - :param cleanup: controls if the cleanup functions should be run or - not. The default is to run these functions. In - some situations the context only wants to be - temporarily pushed in which case this can be disabled. - Nested pushes automatically defer the cleanup. - """ - if not cleanup: - self._depth += 1 - try: - with self as rv: - yield rv - finally: - if not cleanup: - self._depth -= 1 - - @property - def meta(self): - """This is a dictionary which is shared with all the contexts - that are nested. It exists so that click utiltiies can store some - state here if they need to. It is however the responsibility of - that code to manage this dictionary well. - - The keys are supposed to be unique dotted strings. For instance - module paths are a good choice for it. What is stored in there is - irrelevant for the operation of click. However what is important is - that code that places data here adheres to the general semantics of - the system. - - Example usage:: - - LANG_KEY = __name__ + '.lang' - - def set_language(value): - ctx = get_current_context() - ctx.meta[LANG_KEY] = value - - def get_language(): - return get_current_context().meta.get(LANG_KEY, 'en_US') - - .. versionadded:: 5.0 - """ - return self._meta - - def make_formatter(self): - """Creates the formatter for the help and usage output.""" - return HelpFormatter(width=self.terminal_width, - max_width=self.max_content_width) - - def call_on_close(self, f): - """This decorator remembers a function as callback that should be - executed when the context tears down. This is most useful to bind - resource handling to the script execution. For instance, file objects - opened by the :class:`File` type will register their close callbacks - here. - - :param f: the function to execute on teardown. - """ - self._close_callbacks.append(f) - return f - - def close(self): - """Invokes all close callbacks.""" - for cb in self._close_callbacks: - cb() - self._close_callbacks = [] - - @property - def command_path(self): - """The computed command path. This is used for the ``usage`` - information on the help page. It's automatically created by - combining the info names of the chain of contexts to the root. - """ - rv = '' - if self.info_name is not None: - rv = self.info_name - if self.parent is not None: - rv = self.parent.command_path + ' ' + rv - return rv.lstrip() - - def find_root(self): - """Finds the outermost context.""" - node = self - while node.parent is not None: - node = node.parent - return node - - def find_object(self, object_type): - """Finds the closest object of a given type.""" - node = self - while node is not None: - if isinstance(node.obj, object_type): - return node.obj - node = node.parent - - def ensure_object(self, object_type): - """Like :meth:`find_object` but sets the innermost object to a - new instance of `object_type` if it does not exist. - """ - rv = self.find_object(object_type) - if rv is None: - self.obj = rv = object_type() - return rv - - def lookup_default(self, name): - """Looks up the default for a parameter name. This by default - looks into the :attr:`default_map` if available. - """ - if self.default_map is not None: - rv = self.default_map.get(name) - if callable(rv): - rv = rv() - return rv - - def fail(self, message): - """Aborts the execution of the program with a specific error - message. - - :param message: the error message to fail with. - """ - raise UsageError(message, self) - - def abort(self): - """Aborts the script.""" - raise Abort() - - def exit(self, code=0): - """Exits the application with a given exit code.""" - sys.exit(code) - - def get_usage(self): - """Helper method to get formatted usage string for the current - context and command. - """ - return self.command.get_usage(self) - - def get_help(self): - """Helper method to get formatted help page for the current - context and command. - """ - return self.command.get_help(self) - - def invoke(*args, **kwargs): - """Invokes a command callback in exactly the way it expects. There - are two ways to invoke this method: - - 1. the first argument can be a callback and all other arguments and - keyword arguments are forwarded directly to the function. - 2. the first argument is a click command object. In that case all - arguments are forwarded as well but proper click parameters - (options and click arguments) must be keyword arguments and Click - will fill in defaults. - - Note that before Click 3.2 keyword arguments were not properly filled - in against the intention of this code and no context was created. For - more information about this change and why it was done in a bugfix - release see :ref:`upgrade-to-3.2`. - """ - self, callback = args[:2] - ctx = self - - # It's also possible to invoke another command which might or - # might not have a callback. In that case we also fill - # in defaults and make a new context for this command. - if isinstance(callback, Command): - other_cmd = callback - callback = other_cmd.callback - ctx = Context(other_cmd, info_name=other_cmd.name, parent=self) - if callback is None: - raise TypeError('The given command does not have a ' - 'callback that can be invoked.') - - for param in other_cmd.params: - if param.name not in kwargs and param.expose_value: - kwargs[param.name] = param.get_default(ctx) - - args = args[2:] - with augment_usage_errors(self): - with ctx: - return callback(*args, **kwargs) - - def forward(*args, **kwargs): - """Similar to :meth:`invoke` but fills in default keyword - arguments from the current context if the other command expects - it. This cannot invoke callbacks directly, only other commands. - """ - self, cmd = args[:2] - - # It's also possible to invoke another command which might or - # might not have a callback. - if not isinstance(cmd, Command): - raise TypeError('Callback is not a command.') - - for param in self.params: - if param not in kwargs: - kwargs[param] = self.params[param] - - return self.invoke(cmd, **kwargs) - - -class BaseCommand(object): - """The base command implements the minimal API contract of commands. - Most code will never use this as it does not implement a lot of useful - functionality but it can act as the direct subclass of alternative - parsing methods that do not depend on the Click parser. - - For instance, this can be used to bridge Click and other systems like - argparse or docopt. - - Because base commands do not implement a lot of the API that other - parts of Click take for granted, they are not supported for all - operations. For instance, they cannot be used with the decorators - usually and they have no built-in callback system. - - .. versionchanged:: 2.0 - Added the `context_settings` parameter. - - :param name: the name of the command to use unless a group overrides it. - :param context_settings: an optional dictionary with defaults that are - passed to the context object. - """ - #: the default for the :attr:`Context.allow_extra_args` flag. - allow_extra_args = False - #: the default for the :attr:`Context.allow_interspersed_args` flag. - allow_interspersed_args = True - #: the default for the :attr:`Context.ignore_unknown_options` flag. - ignore_unknown_options = False - - def __init__(self, name, context_settings=None): - #: the name the command thinks it has. Upon registering a command - #: on a :class:`Group` the group will default the command name - #: with this information. You should instead use the - #: :class:`Context`\'s :attr:`~Context.info_name` attribute. - self.name = name - if context_settings is None: - context_settings = {} - #: an optional dictionary with defaults passed to the context. - self.context_settings = context_settings - - def get_usage(self, ctx): - raise NotImplementedError('Base commands cannot get usage') - - def get_help(self, ctx): - raise NotImplementedError('Base commands cannot get help') - - def make_context(self, info_name, args, parent=None, **extra): - """This function when given an info name and arguments will kick - off the parsing and create a new :class:`Context`. It does not - invoke the actual command callback though. - - :param info_name: the info name for this invokation. Generally this - is the most descriptive name for the script or - command. For the toplevel script it's usually - the name of the script, for commands below it it's - the name of the script. - :param args: the arguments to parse as list of strings. - :param parent: the parent context if available. - :param extra: extra keyword arguments forwarded to the context - constructor. - """ - for key, value in iteritems(self.context_settings): - if key not in extra: - extra[key] = value - ctx = Context(self, info_name=info_name, parent=parent, **extra) - with ctx.scope(cleanup=False): - self.parse_args(ctx, args) - return ctx - - def parse_args(self, ctx, args): - """Given a context and a list of arguments this creates the parser - and parses the arguments, then modifies the context as necessary. - This is automatically invoked by :meth:`make_context`. - """ - raise NotImplementedError('Base commands do not know how to parse ' - 'arguments.') - - def invoke(self, ctx): - """Given a context, this invokes the command. The default - implementation is raising a not implemented error. - """ - raise NotImplementedError('Base commands are not invokable by default') - - def main(self, args=None, prog_name=None, complete_var=None, - standalone_mode=True, **extra): - """This is the way to invoke a script with all the bells and - whistles as a command line application. This will always terminate - the application after a call. If this is not wanted, ``SystemExit`` - needs to be caught. - - This method is also available by directly calling the instance of - a :class:`Command`. - - .. versionadded:: 3.0 - Added the `standalone_mode` flag to control the standalone mode. - - :param args: the arguments that should be used for parsing. If not - provided, ``sys.argv[1:]`` is used. - :param prog_name: the program name that should be used. By default - the program name is constructed by taking the file - name from ``sys.argv[0]``. - :param complete_var: the environment variable that controls the - bash completion support. The default is - ``"__COMPLETE"`` with prog name in - uppercase. - :param standalone_mode: the default behavior is to invoke the script - in standalone mode. Click will then - handle exceptions and convert them into - error messages and the function will never - return but shut down the interpreter. If - this is set to `False` they will be - propagated to the caller and the return - value of this function is the return value - of :meth:`invoke`. - :param extra: extra keyword arguments are forwarded to the context - constructor. See :class:`Context` for more information. - """ - # If we are in Python 3, we will verify that the environment is - # sane at this point of reject further execution to avoid a - # broken script. - if not PY2: - _verify_python3_env() - else: - _check_for_unicode_literals() - - if args is None: - args = get_os_args() - else: - args = list(args) - - if prog_name is None: - prog_name = make_str(os.path.basename( - sys.argv and sys.argv[0] or __file__)) - - # Hook for the Bash completion. This only activates if the Bash - # completion is actually enabled, otherwise this is quite a fast - # noop. - _bashcomplete(self, prog_name, complete_var) - - try: - try: - with self.make_context(prog_name, args, **extra) as ctx: - rv = self.invoke(ctx) - if not standalone_mode: - return rv - ctx.exit() - except (EOFError, KeyboardInterrupt): - echo(file=sys.stderr) - raise Abort() - except ClickException as e: - if not standalone_mode: - raise - e.show() - sys.exit(e.exit_code) - except IOError as e: - if e.errno == errno.EPIPE: - sys.exit(1) - else: - raise - except Abort: - if not standalone_mode: - raise - echo('Aborted!', file=sys.stderr) - sys.exit(1) - - def __call__(self, *args, **kwargs): - """Alias for :meth:`main`.""" - return self.main(*args, **kwargs) - - -class Command(BaseCommand): - """Commands are the basic building block of command line interfaces in - Click. A basic command handles command line parsing and might dispatch - more parsing to commands nested below it. - - .. versionchanged:: 2.0 - Added the `context_settings` parameter. - - :param name: the name of the command to use unless a group overrides it. - :param context_settings: an optional dictionary with defaults that are - passed to the context object. - :param callback: the callback to invoke. This is optional. - :param params: the parameters to register with this command. This can - be either :class:`Option` or :class:`Argument` objects. - :param help: the help string to use for this command. - :param epilog: like the help string but it's printed at the end of the - help page after everything else. - :param short_help: the short help to use for this command. This is - shown on the command listing of the parent command. - :param add_help_option: by default each command registers a ``--help`` - option. This can be disabled by this parameter. - """ - - def __init__(self, name, context_settings=None, callback=None, - params=None, help=None, epilog=None, short_help=None, - options_metavar='[OPTIONS]', add_help_option=True): - BaseCommand.__init__(self, name, context_settings) - #: the callback to execute when the command fires. This might be - #: `None` in which case nothing happens. - self.callback = callback - #: the list of parameters for this command in the order they - #: should show up in the help page and execute. Eager parameters - #: will automatically be handled before non eager ones. - self.params = params or [] - self.help = help - self.epilog = epilog - self.options_metavar = options_metavar - if short_help is None and help: - short_help = make_default_short_help(help) - self.short_help = short_help - self.add_help_option = add_help_option - - def get_usage(self, ctx): - formatter = ctx.make_formatter() - self.format_usage(ctx, formatter) - return formatter.getvalue().rstrip('\n') - - def get_params(self, ctx): - rv = self.params - help_option = self.get_help_option(ctx) - if help_option is not None: - rv = rv + [help_option] - return rv - - def format_usage(self, ctx, formatter): - """Writes the usage line into the formatter.""" - pieces = self.collect_usage_pieces(ctx) - formatter.write_usage(ctx.command_path, ' '.join(pieces)) - - def collect_usage_pieces(self, ctx): - """Returns all the pieces that go into the usage line and returns - it as a list of strings. - """ - rv = [self.options_metavar] - for param in self.get_params(ctx): - rv.extend(param.get_usage_pieces(ctx)) - return rv - - def get_help_option_names(self, ctx): - """Returns the names for the help option.""" - all_names = set(ctx.help_option_names) - for param in self.params: - all_names.difference_update(param.opts) - all_names.difference_update(param.secondary_opts) - return all_names - - def get_help_option(self, ctx): - """Returns the help option object.""" - help_options = self.get_help_option_names(ctx) - if not help_options or not self.add_help_option: - return - - def show_help(ctx, param, value): - if value and not ctx.resilient_parsing: - echo(ctx.get_help(), color=ctx.color) - ctx.exit() - return Option(help_options, is_flag=True, - is_eager=True, expose_value=False, - callback=show_help, - help='Show this message and exit.') - - def make_parser(self, ctx): - """Creates the underlying option parser for this command.""" - parser = OptionParser(ctx) - parser.allow_interspersed_args = ctx.allow_interspersed_args - parser.ignore_unknown_options = ctx.ignore_unknown_options - for param in self.get_params(ctx): - param.add_to_parser(parser, ctx) - return parser - - def get_help(self, ctx): - """Formats the help into a string and returns it. This creates a - formatter and will call into the following formatting methods: - """ - formatter = ctx.make_formatter() - self.format_help(ctx, formatter) - return formatter.getvalue().rstrip('\n') - - def format_help(self, ctx, formatter): - """Writes the help into the formatter if it exists. - - This calls into the following methods: - - - :meth:`format_usage` - - :meth:`format_help_text` - - :meth:`format_options` - - :meth:`format_epilog` - """ - self.format_usage(ctx, formatter) - self.format_help_text(ctx, formatter) - self.format_options(ctx, formatter) - self.format_epilog(ctx, formatter) - - def format_help_text(self, ctx, formatter): - """Writes the help text to the formatter if it exists.""" - if self.help: - formatter.write_paragraph() - with formatter.indentation(): - formatter.write_text(self.help) - - def format_options(self, ctx, formatter): - """Writes all the options into the formatter if they exist.""" - opts = [] - for param in self.get_params(ctx): - rv = param.get_help_record(ctx) - if rv is not None: - opts.append(rv) - - if opts: - with formatter.section('Options'): - formatter.write_dl(opts) - - def format_epilog(self, ctx, formatter): - """Writes the epilog into the formatter if it exists.""" - if self.epilog: - formatter.write_paragraph() - with formatter.indentation(): - formatter.write_text(self.epilog) - - def parse_args(self, ctx, args): - parser = self.make_parser(ctx) - opts, args, param_order = parser.parse_args(args=args) - - for param in iter_params_for_processing( - param_order, self.get_params(ctx)): - value, args = param.handle_parse_result(ctx, opts, args) - - if args and not ctx.allow_extra_args and not ctx.resilient_parsing: - ctx.fail('Got unexpected extra argument%s (%s)' - % (len(args) != 1 and 's' or '', - ' '.join(map(make_str, args)))) - - ctx.args = args - return args - - def invoke(self, ctx): - """Given a context, this invokes the attached callback (if it exists) - in the right way. - """ - if self.callback is not None: - return ctx.invoke(self.callback, **ctx.params) - - -class MultiCommand(Command): - """A multi command is the basic implementation of a command that - dispatches to subcommands. The most common version is the - :class:`Group`. - - :param invoke_without_command: this controls how the multi command itself - is invoked. By default it's only invoked - if a subcommand is provided. - :param no_args_is_help: this controls what happens if no arguments are - provided. This option is enabled by default if - `invoke_without_command` is disabled or disabled - if it's enabled. If enabled this will add - ``--help`` as argument if no arguments are - passed. - :param subcommand_metavar: the string that is used in the documentation - to indicate the subcommand place. - :param chain: if this is set to `True` chaining of multiple subcommands - is enabled. This restricts the form of commands in that - they cannot have optional arguments but it allows - multiple commands to be chained together. - :param result_callback: the result callback to attach to this multi - command. - """ - allow_extra_args = True - allow_interspersed_args = False - - def __init__(self, name=None, invoke_without_command=False, - no_args_is_help=None, subcommand_metavar=None, - chain=False, result_callback=None, **attrs): - Command.__init__(self, name, **attrs) - if no_args_is_help is None: - no_args_is_help = not invoke_without_command - self.no_args_is_help = no_args_is_help - self.invoke_without_command = invoke_without_command - if subcommand_metavar is None: - if chain: - subcommand_metavar = SUBCOMMANDS_METAVAR - else: - subcommand_metavar = SUBCOMMAND_METAVAR - self.subcommand_metavar = subcommand_metavar - self.chain = chain - #: The result callback that is stored. This can be set or - #: overridden with the :func:`resultcallback` decorator. - self.result_callback = result_callback - - if self.chain: - for param in self.params: - if isinstance(param, Argument) and not param.required: - raise RuntimeError('Multi commands in chain mode cannot ' - 'have optional arguments.') - - def collect_usage_pieces(self, ctx): - rv = Command.collect_usage_pieces(self, ctx) - rv.append(self.subcommand_metavar) - return rv - - def format_options(self, ctx, formatter): - Command.format_options(self, ctx, formatter) - self.format_commands(ctx, formatter) - - def resultcallback(self, replace=False): - """Adds a result callback to the chain command. By default if a - result callback is already registered this will chain them but - this can be disabled with the `replace` parameter. The result - callback is invoked with the return value of the subcommand - (or the list of return values from all subcommands if chaining - is enabled) as well as the parameters as they would be passed - to the main callback. - - Example:: - - @click.group() - @click.option('-i', '--input', default=23) - def cli(input): - return 42 - - @cli.resultcallback() - def process_result(result, input): - return result + input - - .. versionadded:: 3.0 - - :param replace: if set to `True` an already existing result - callback will be removed. - """ - def decorator(f): - old_callback = self.result_callback - if old_callback is None or replace: - self.result_callback = f - return f - def function(__value, *args, **kwargs): - return f(old_callback(__value, *args, **kwargs), - *args, **kwargs) - self.result_callback = rv = update_wrapper(function, f) - return rv - return decorator - - def format_commands(self, ctx, formatter): - """Extra format methods for multi methods that adds all the commands - after the options. - """ - rows = [] - for subcommand in self.list_commands(ctx): - cmd = self.get_command(ctx, subcommand) - # What is this, the tool lied about a command. Ignore it - if cmd is None: - continue - - help = cmd.short_help or '' - rows.append((subcommand, help)) - - if rows: - with formatter.section('Commands'): - formatter.write_dl(rows) - - def parse_args(self, ctx, args): - if not args and self.no_args_is_help and not ctx.resilient_parsing: - echo(ctx.get_help(), color=ctx.color) - ctx.exit() - - rest = Command.parse_args(self, ctx, args) - if self.chain: - ctx.protected_args = rest - ctx.args = [] - elif rest: - ctx.protected_args, ctx.args = rest[:1], rest[1:] - - return ctx.args - - def invoke(self, ctx): - def _process_result(value): - if self.result_callback is not None: - value = ctx.invoke(self.result_callback, value, - **ctx.params) - return value - - if not ctx.protected_args: - # If we are invoked without command the chain flag controls - # how this happens. If we are not in chain mode, the return - # value here is the return value of the command. - # If however we are in chain mode, the return value is the - # return value of the result processor invoked with an empty - # list (which means that no subcommand actually was executed). - if self.invoke_without_command: - if not self.chain: - return Command.invoke(self, ctx) - with ctx: - Command.invoke(self, ctx) - return _process_result([]) - ctx.fail('Missing command.') - - # Fetch args back out - args = ctx.protected_args + ctx.args - ctx.args = [] - ctx.protected_args = [] - - # If we're not in chain mode, we only allow the invocation of a - # single command but we also inform the current context about the - # name of the command to invoke. - if not self.chain: - # Make sure the context is entered so we do not clean up - # resources until the result processor has worked. - with ctx: - cmd_name, cmd, args = self.resolve_command(ctx, args) - ctx.invoked_subcommand = cmd_name - Command.invoke(self, ctx) - sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) - with sub_ctx: - return _process_result(sub_ctx.command.invoke(sub_ctx)) - - # In chain mode we create the contexts step by step, but after the - # base command has been invoked. Because at that point we do not - # know the subcommands yet, the invoked subcommand attribute is - # set to ``*`` to inform the command that subcommands are executed - # but nothing else. - with ctx: - ctx.invoked_subcommand = args and '*' or None - Command.invoke(self, ctx) - - # Otherwise we make every single context and invoke them in a - # chain. In that case the return value to the result processor - # is the list of all invoked subcommand's results. - contexts = [] - while args: - cmd_name, cmd, args = self.resolve_command(ctx, args) - sub_ctx = cmd.make_context(cmd_name, args, parent=ctx, - allow_extra_args=True, - allow_interspersed_args=False) - contexts.append(sub_ctx) - args, sub_ctx.args = sub_ctx.args, [] - - rv = [] - for sub_ctx in contexts: - with sub_ctx: - rv.append(sub_ctx.command.invoke(sub_ctx)) - return _process_result(rv) - - def resolve_command(self, ctx, args): - cmd_name = make_str(args[0]) - original_cmd_name = cmd_name - - # Get the command - cmd = self.get_command(ctx, cmd_name) - - # If we can't find the command but there is a normalization - # function available, we try with that one. - if cmd is None and ctx.token_normalize_func is not None: - cmd_name = ctx.token_normalize_func(cmd_name) - cmd = self.get_command(ctx, cmd_name) - - # If we don't find the command we want to show an error message - # to the user that it was not provided. However, there is - # something else we should do: if the first argument looks like - # an option we want to kick off parsing again for arguments to - # resolve things like --help which now should go to the main - # place. - if cmd is None: - if split_opt(cmd_name)[0]: - self.parse_args(ctx, ctx.args) - ctx.fail('No such command "%s".' % original_cmd_name) - - return cmd_name, cmd, args[1:] - - def get_command(self, ctx, cmd_name): - """Given a context and a command name, this returns a - :class:`Command` object if it exists or returns `None`. - """ - raise NotImplementedError() - - def list_commands(self, ctx): - """Returns a list of subcommand names in the order they should - appear. - """ - return [] - - -class Group(MultiCommand): - """A group allows a command to have subcommands attached. This is the - most common way to implement nesting in Click. - - :param commands: a dictionary of commands. - """ - - def __init__(self, name=None, commands=None, **attrs): - MultiCommand.__init__(self, name, **attrs) - #: the registered subcommands by their exported names. - self.commands = commands or {} - - def add_command(self, cmd, name=None): - """Registers another :class:`Command` with this group. If the name - is not provided, the name of the command is used. - """ - name = name or cmd.name - if name is None: - raise TypeError('Command has no name.') - _check_multicommand(self, name, cmd, register=True) - self.commands[name] = cmd - - def command(self, *args, **kwargs): - """A shortcut decorator for declaring and attaching a command to - the group. This takes the same arguments as :func:`command` but - immediately registers the created command with this instance by - calling into :meth:`add_command`. - """ - def decorator(f): - cmd = command(*args, **kwargs)(f) - self.add_command(cmd) - return cmd - return decorator - - def group(self, *args, **kwargs): - """A shortcut decorator for declaring and attaching a group to - the group. This takes the same arguments as :func:`group` but - immediately registers the created command with this instance by - calling into :meth:`add_command`. - """ - def decorator(f): - cmd = group(*args, **kwargs)(f) - self.add_command(cmd) - return cmd - return decorator - - def get_command(self, ctx, cmd_name): - return self.commands.get(cmd_name) - - def list_commands(self, ctx): - return sorted(self.commands) - - -class CommandCollection(MultiCommand): - """A command collection is a multi command that merges multiple multi - commands together into one. This is a straightforward implementation - that accepts a list of different multi commands as sources and - provides all the commands for each of them. - """ - - def __init__(self, name=None, sources=None, **attrs): - MultiCommand.__init__(self, name, **attrs) - #: The list of registered multi commands. - self.sources = sources or [] - - def add_source(self, multi_cmd): - """Adds a new multi command to the chain dispatcher.""" - self.sources.append(multi_cmd) - - def get_command(self, ctx, cmd_name): - for source in self.sources: - rv = source.get_command(ctx, cmd_name) - if rv is not None: - if self.chain: - _check_multicommand(self, cmd_name, rv) - return rv - - def list_commands(self, ctx): - rv = set() - for source in self.sources: - rv.update(source.list_commands(ctx)) - return sorted(rv) - - -class Parameter(object): - """A parameter to a command comes in two versions: they are either - :class:`Option`\s or :class:`Argument`\s. Other subclasses are currently - not supported by design as some of the internals for parsing are - intentionally not finalized. - - Some settings are supported by both options and arguments. - - .. versionchanged:: 2.0 - Changed signature for parameter callback to also be passed the - parameter. In Click 2.0, the old callback format will still work, - but it will raise a warning to give you change to migrate the - code easier. - - :param param_decls: the parameter declarations for this option or - argument. This is a list of flags or argument - names. - :param type: the type that should be used. Either a :class:`ParamType` - or a Python type. The later is converted into the former - automatically if supported. - :param required: controls if this is optional or not. - :param default: the default value if omitted. This can also be a callable, - in which case it's invoked when the default is needed - without any arguments. - :param callback: a callback that should be executed after the parameter - was matched. This is called as ``fn(ctx, param, - value)`` and needs to return the value. Before Click - 2.0, the signature was ``(ctx, value)``. - :param nargs: the number of arguments to match. If not ``1`` the return - value is a tuple instead of single value. The default for - nargs is ``1`` (except if the type is a tuple, then it's - the arity of the tuple). - :param metavar: how the value is represented in the help page. - :param expose_value: if this is `True` then the value is passed onwards - to the command callback and stored on the context, - otherwise it's skipped. - :param is_eager: eager values are processed before non eager ones. This - should not be set for arguments or it will inverse the - order of processing. - :param envvar: a string or list of strings that are environment variables - that should be checked. - """ - param_type_name = 'parameter' - - def __init__(self, param_decls=None, type=None, required=False, - default=None, callback=None, nargs=None, metavar=None, - expose_value=True, is_eager=False, envvar=None): - self.name, self.opts, self.secondary_opts = \ - self._parse_decls(param_decls or (), expose_value) - - self.type = convert_type(type, default) - - # Default nargs to what the type tells us if we have that - # information available. - if nargs is None: - if self.type.is_composite: - nargs = self.type.arity - else: - nargs = 1 - - self.required = required - self.callback = callback - self.nargs = nargs - self.multiple = False - self.expose_value = expose_value - self.default = default - self.is_eager = is_eager - self.metavar = metavar - self.envvar = envvar - - @property - def human_readable_name(self): - """Returns the human readable name of this parameter. This is the - same as the name for options, but the metavar for arguments. - """ - return self.name - - def make_metavar(self): - if self.metavar is not None: - return self.metavar - metavar = self.type.get_metavar(self) - if metavar is None: - metavar = self.type.name.upper() - if self.nargs != 1: - metavar += '...' - return metavar - - def get_default(self, ctx): - """Given a context variable this calculates the default value.""" - # Otherwise go with the regular default. - if callable(self.default): - rv = self.default() - else: - rv = self.default - return self.type_cast_value(ctx, rv) - - def add_to_parser(self, parser, ctx): - pass - - def consume_value(self, ctx, opts): - value = opts.get(self.name) - if value is None: - value = ctx.lookup_default(self.name) - if value is None: - value = self.value_from_envvar(ctx) - return value - - def type_cast_value(self, ctx, value): - """Given a value this runs it properly through the type system. - This automatically handles things like `nargs` and `multiple` as - well as composite types. - """ - if self.type.is_composite: - if self.nargs <= 1: - raise TypeError('Attempted to invoke composite type ' - 'but nargs has been set to %s. This is ' - 'not supported; nargs needs to be set to ' - 'a fixed value > 1.' % self.nargs) - if self.multiple: - return tuple(self.type(x or (), self, ctx) for x in value or ()) - return self.type(value or (), self, ctx) - - def _convert(value, level): - if level == 0: - return self.type(value, self, ctx) - return tuple(_convert(x, level - 1) for x in value or ()) - return _convert(value, (self.nargs != 1) + bool(self.multiple)) - - def process_value(self, ctx, value): - """Given a value and context this runs the logic to convert the - value as necessary. - """ - # If the value we were given is None we do nothing. This way - # code that calls this can easily figure out if something was - # not provided. Otherwise it would be converted into an empty - # tuple for multiple invocations which is inconvenient. - if value is not None: - return self.type_cast_value(ctx, value) - - def value_is_missing(self, value): - if value is None: - return True - if (self.nargs != 1 or self.multiple) and value == (): - return True - return False - - def full_process_value(self, ctx, value): - value = self.process_value(ctx, value) - - if value is None: - value = self.get_default(ctx) - - if self.required and self.value_is_missing(value): - raise MissingParameter(ctx=ctx, param=self) - - return value - - def resolve_envvar_value(self, ctx): - if self.envvar is None: - return - if isinstance(self.envvar, (tuple, list)): - for envvar in self.envvar: - rv = os.environ.get(envvar) - if rv is not None: - return rv - else: - return os.environ.get(self.envvar) - - def value_from_envvar(self, ctx): - rv = self.resolve_envvar_value(ctx) - if rv is not None and self.nargs != 1: - rv = self.type.split_envvar_value(rv) - return rv - - def handle_parse_result(self, ctx, opts, args): - with augment_usage_errors(ctx, param=self): - value = self.consume_value(ctx, opts) - try: - value = self.full_process_value(ctx, value) - except Exception: - if not ctx.resilient_parsing: - raise - value = None - if self.callback is not None: - try: - value = invoke_param_callback( - self.callback, ctx, self, value) - except Exception: - if not ctx.resilient_parsing: - raise - - if self.expose_value: - ctx.params[self.name] = value - return value, args - - def get_help_record(self, ctx): - pass - - def get_usage_pieces(self, ctx): - return [] - - -class Option(Parameter): - """Options are usually optional values on the command line and - have some extra features that arguments don't have. - - All other parameters are passed onwards to the parameter constructor. - - :param show_default: controls if the default value should be shown on the - help page. Normally, defaults are not shown. - :param prompt: if set to `True` or a non empty string then the user will - be prompted for input if not set. If set to `True` the - prompt will be the option name capitalized. - :param confirmation_prompt: if set then the value will need to be confirmed - if it was prompted for. - :param hide_input: if this is `True` then the input on the prompt will be - hidden from the user. This is useful for password - input. - :param is_flag: forces this option to act as a flag. The default is - auto detection. - :param flag_value: which value should be used for this flag if it's - enabled. This is set to a boolean automatically if - the option string contains a slash to mark two options. - :param multiple: if this is set to `True` then the argument is accepted - multiple times and recorded. This is similar to ``nargs`` - in how it works but supports arbitrary number of - arguments. - :param count: this flag makes an option increment an integer. - :param allow_from_autoenv: if this is enabled then the value of this - parameter will be pulled from an environment - variable in case a prefix is defined on the - context. - :param help: the help string. - """ - param_type_name = 'option' - - def __init__(self, param_decls=None, show_default=False, - prompt=False, confirmation_prompt=False, - hide_input=False, is_flag=None, flag_value=None, - multiple=False, count=False, allow_from_autoenv=True, - type=None, help=None, **attrs): - default_is_missing = attrs.get('default', _missing) is _missing - Parameter.__init__(self, param_decls, type=type, **attrs) - - if prompt is True: - prompt_text = self.name.replace('_', ' ').capitalize() - elif prompt is False: - prompt_text = None - else: - prompt_text = prompt - self.prompt = prompt_text - self.confirmation_prompt = confirmation_prompt - self.hide_input = hide_input - - # Flags - if is_flag is None: - if flag_value is not None: - is_flag = True - else: - is_flag = bool(self.secondary_opts) - if is_flag and default_is_missing: - self.default = False - if flag_value is None: - flag_value = not self.default - self.is_flag = is_flag - self.flag_value = flag_value - if self.is_flag and isinstance(self.flag_value, bool) \ - and type is None: - self.type = BOOL - self.is_bool_flag = True - else: - self.is_bool_flag = False - - # Counting - self.count = count - if count: - if type is None: - self.type = IntRange(min=0) - if default_is_missing: - self.default = 0 - - self.multiple = multiple - self.allow_from_autoenv = allow_from_autoenv - self.help = help - self.show_default = show_default - - # Sanity check for stuff we don't support - if __debug__: - if self.nargs < 0: - raise TypeError('Options cannot have nargs < 0') - if self.prompt and self.is_flag and not self.is_bool_flag: - raise TypeError('Cannot prompt for flags that are not bools.') - if not self.is_bool_flag and self.secondary_opts: - raise TypeError('Got secondary option for non boolean flag.') - if self.is_bool_flag and self.hide_input \ - and self.prompt is not None: - raise TypeError('Hidden input does not work with boolean ' - 'flag prompts.') - if self.count: - if self.multiple: - raise TypeError('Options cannot be multiple and count ' - 'at the same time.') - elif self.is_flag: - raise TypeError('Options cannot be count and flags at ' - 'the same time.') - - def _parse_decls(self, decls, expose_value): - opts = [] - secondary_opts = [] - name = None - possible_names = [] - - for decl in decls: - if isidentifier(decl): - if name is not None: - raise TypeError('Name defined twice') - name = decl - else: - split_char = decl[:1] == '/' and ';' or '/' - if split_char in decl: - first, second = decl.split(split_char, 1) - first = first.rstrip() - if first: - possible_names.append(split_opt(first)) - opts.append(first) - second = second.lstrip() - if second: - secondary_opts.append(second.lstrip()) - else: - possible_names.append(split_opt(decl)) - opts.append(decl) - - if name is None and possible_names: - possible_names.sort(key=lambda x: len(x[0])) - name = possible_names[-1][1].replace('-', '_').lower() - if not isidentifier(name): - name = None - - if name is None: - if not expose_value: - return None, opts, secondary_opts - raise TypeError('Could not determine name for option') - - if not opts and not secondary_opts: - raise TypeError('No options defined but a name was passed (%s). ' - 'Did you mean to declare an argument instead ' - 'of an option?' % name) - - return name, opts, secondary_opts - - def add_to_parser(self, parser, ctx): - kwargs = { - 'dest': self.name, - 'nargs': self.nargs, - 'obj': self, - } - - if self.multiple: - action = 'append' - elif self.count: - action = 'count' - else: - action = 'store' - - if self.is_flag: - kwargs.pop('nargs', None) - if self.is_bool_flag and self.secondary_opts: - parser.add_option(self.opts, action=action + '_const', - const=True, **kwargs) - parser.add_option(self.secondary_opts, action=action + - '_const', const=False, **kwargs) - else: - parser.add_option(self.opts, action=action + '_const', - const=self.flag_value, - **kwargs) - else: - kwargs['action'] = action - parser.add_option(self.opts, **kwargs) - - def get_help_record(self, ctx): - any_prefix_is_slash = [] - - def _write_opts(opts): - rv, any_slashes = join_options(opts) - if any_slashes: - any_prefix_is_slash[:] = [True] - if not self.is_flag and not self.count: - rv += ' ' + self.make_metavar() - return rv - - rv = [_write_opts(self.opts)] - if self.secondary_opts: - rv.append(_write_opts(self.secondary_opts)) - - help = self.help or '' - extra = [] - if self.default is not None and self.show_default: - extra.append('default: %s' % ( - ', '.join('%s' % d for d in self.default) - if isinstance(self.default, (list, tuple)) - else self.default, )) - if self.required: - extra.append('required') - if extra: - help = '%s[%s]' % (help and help + ' ' or '', '; '.join(extra)) - - return ((any_prefix_is_slash and '; ' or ' / ').join(rv), help) - - def get_default(self, ctx): - # If we're a non boolean flag out default is more complex because - # we need to look at all flags in the same group to figure out - # if we're the the default one in which case we return the flag - # value as default. - if self.is_flag and not self.is_bool_flag: - for param in ctx.command.params: - if param.name == self.name and param.default: - return param.flag_value - return None - return Parameter.get_default(self, ctx) - - def prompt_for_value(self, ctx): - """This is an alternative flow that can be activated in the full - value processing if a value does not exist. It will prompt the - user until a valid value exists and then returns the processed - value as result. - """ - # Calculate the default before prompting anything to be stable. - default = self.get_default(ctx) - - # If this is a prompt for a flag we need to handle this - # differently. - if self.is_bool_flag: - return confirm(self.prompt, default) - - return prompt(self.prompt, default=default, - hide_input=self.hide_input, - confirmation_prompt=self.confirmation_prompt, - value_proc=lambda x: self.process_value(ctx, x)) - - def resolve_envvar_value(self, ctx): - rv = Parameter.resolve_envvar_value(self, ctx) - if rv is not None: - return rv - if self.allow_from_autoenv and \ - ctx.auto_envvar_prefix is not None: - envvar = '%s_%s' % (ctx.auto_envvar_prefix, self.name.upper()) - return os.environ.get(envvar) - - def value_from_envvar(self, ctx): - rv = self.resolve_envvar_value(ctx) - if rv is None: - return None - value_depth = (self.nargs != 1) + bool(self.multiple) - if value_depth > 0 and rv is not None: - rv = self.type.split_envvar_value(rv) - if self.multiple and self.nargs != 1: - rv = batch(rv, self.nargs) - return rv - - def full_process_value(self, ctx, value): - if value is None and self.prompt is not None \ - and not ctx.resilient_parsing: - return self.prompt_for_value(ctx) - return Parameter.full_process_value(self, ctx, value) - - -class Argument(Parameter): - """Arguments are positional parameters to a command. They generally - provide fewer features than options but can have infinite ``nargs`` - and are required by default. - - All parameters are passed onwards to the parameter constructor. - """ - param_type_name = 'argument' - - def __init__(self, param_decls, required=None, **attrs): - if required is None: - if attrs.get('default') is not None: - required = False - else: - required = attrs.get('nargs', 1) > 0 - Parameter.__init__(self, param_decls, required=required, **attrs) - if self.default is not None and self.nargs < 0: - raise TypeError('nargs=-1 in combination with a default value ' - 'is not supported.') - - @property - def human_readable_name(self): - if self.metavar is not None: - return self.metavar - return self.name.upper() - - def make_metavar(self): - if self.metavar is not None: - return self.metavar - var = self.name.upper() - if not self.required: - var = '[%s]' % var - if self.nargs != 1: - var += '...' - return var - - def _parse_decls(self, decls, expose_value): - if not decls: - if not expose_value: - return None, [], [] - raise TypeError('Could not determine name for argument') - if len(decls) == 1: - name = arg = decls[0] - name = name.replace('-', '_').lower() - elif len(decls) == 2: - name, arg = decls - else: - raise TypeError('Arguments take exactly one or two ' - 'parameter declarations, got %d' % len(decls)) - return name, [arg], [] - - def get_usage_pieces(self, ctx): - return [self.make_metavar()] - - def add_to_parser(self, parser, ctx): - parser.add_argument(dest=self.name, nargs=self.nargs, - obj=self) - - -# Circular dependency between decorators and core -from .decorators import command, group diff --git a/pyextra/click/decorators.py b/pyextra/click/decorators.py deleted file mode 100644 index 9893452650ba0a..00000000000000 --- a/pyextra/click/decorators.py +++ /dev/null @@ -1,304 +0,0 @@ -import sys -import inspect - -from functools import update_wrapper - -from ._compat import iteritems -from ._unicodefun import _check_for_unicode_literals -from .utils import echo -from .globals import get_current_context - - -def pass_context(f): - """Marks a callback as wanting to receive the current context - object as first argument. - """ - def new_func(*args, **kwargs): - return f(get_current_context(), *args, **kwargs) - return update_wrapper(new_func, f) - - -def pass_obj(f): - """Similar to :func:`pass_context`, but only pass the object on the - context onwards (:attr:`Context.obj`). This is useful if that object - represents the state of a nested system. - """ - def new_func(*args, **kwargs): - return f(get_current_context().obj, *args, **kwargs) - return update_wrapper(new_func, f) - - -def make_pass_decorator(object_type, ensure=False): - """Given an object type this creates a decorator that will work - similar to :func:`pass_obj` but instead of passing the object of the - current context, it will find the innermost context of type - :func:`object_type`. - - This generates a decorator that works roughly like this:: - - from functools import update_wrapper - - def decorator(f): - @pass_context - def new_func(ctx, *args, **kwargs): - obj = ctx.find_object(object_type) - return ctx.invoke(f, obj, *args, **kwargs) - return update_wrapper(new_func, f) - return decorator - - :param object_type: the type of the object to pass. - :param ensure: if set to `True`, a new object will be created and - remembered on the context if it's not there yet. - """ - def decorator(f): - def new_func(*args, **kwargs): - ctx = get_current_context() - if ensure: - obj = ctx.ensure_object(object_type) - else: - obj = ctx.find_object(object_type) - if obj is None: - raise RuntimeError('Managed to invoke callback without a ' - 'context object of type %r existing' - % object_type.__name__) - return ctx.invoke(f, obj, *args[1:], **kwargs) - return update_wrapper(new_func, f) - return decorator - - -def _make_command(f, name, attrs, cls): - if isinstance(f, Command): - raise TypeError('Attempted to convert a callback into a ' - 'command twice.') - try: - params = f.__click_params__ - params.reverse() - del f.__click_params__ - except AttributeError: - params = [] - help = attrs.get('help') - if help is None: - help = inspect.getdoc(f) - if isinstance(help, bytes): - help = help.decode('utf-8') - else: - help = inspect.cleandoc(help) - attrs['help'] = help - _check_for_unicode_literals() - return cls(name=name or f.__name__.lower(), - callback=f, params=params, **attrs) - - -def command(name=None, cls=None, **attrs): - """Creates a new :class:`Command` and uses the decorated function as - callback. This will also automatically attach all decorated - :func:`option`\s and :func:`argument`\s as parameters to the command. - - The name of the command defaults to the name of the function. If you - want to change that, you can pass the intended name as the first - argument. - - All keyword arguments are forwarded to the underlying command class. - - Once decorated the function turns into a :class:`Command` instance - that can be invoked as a command line utility or be attached to a - command :class:`Group`. - - :param name: the name of the command. This defaults to the function - name. - :param cls: the command class to instantiate. This defaults to - :class:`Command`. - """ - if cls is None: - cls = Command - def decorator(f): - cmd = _make_command(f, name, attrs, cls) - cmd.__doc__ = f.__doc__ - return cmd - return decorator - - -def group(name=None, **attrs): - """Creates a new :class:`Group` with a function as callback. This - works otherwise the same as :func:`command` just that the `cls` - parameter is set to :class:`Group`. - """ - attrs.setdefault('cls', Group) - return command(name, **attrs) - - -def _param_memo(f, param): - if isinstance(f, Command): - f.params.append(param) - else: - if not hasattr(f, '__click_params__'): - f.__click_params__ = [] - f.__click_params__.append(param) - - -def argument(*param_decls, **attrs): - """Attaches an argument to the command. All positional arguments are - passed as parameter declarations to :class:`Argument`; all keyword - arguments are forwarded unchanged (except ``cls``). - This is equivalent to creating an :class:`Argument` instance manually - and attaching it to the :attr:`Command.params` list. - - :param cls: the argument class to instantiate. This defaults to - :class:`Argument`. - """ - def decorator(f): - ArgumentClass = attrs.pop('cls', Argument) - _param_memo(f, ArgumentClass(param_decls, **attrs)) - return f - return decorator - - -def option(*param_decls, **attrs): - """Attaches an option to the command. All positional arguments are - passed as parameter declarations to :class:`Option`; all keyword - arguments are forwarded unchanged (except ``cls``). - This is equivalent to creating an :class:`Option` instance manually - and attaching it to the :attr:`Command.params` list. - - :param cls: the option class to instantiate. This defaults to - :class:`Option`. - """ - def decorator(f): - if 'help' in attrs: - attrs['help'] = inspect.cleandoc(attrs['help']) - OptionClass = attrs.pop('cls', Option) - _param_memo(f, OptionClass(param_decls, **attrs)) - return f - return decorator - - -def confirmation_option(*param_decls, **attrs): - """Shortcut for confirmation prompts that can be ignored by passing - ``--yes`` as parameter. - - This is equivalent to decorating a function with :func:`option` with - the following parameters:: - - def callback(ctx, param, value): - if not value: - ctx.abort() - - @click.command() - @click.option('--yes', is_flag=True, callback=callback, - expose_value=False, prompt='Do you want to continue?') - def dropdb(): - pass - """ - def decorator(f): - def callback(ctx, param, value): - if not value: - ctx.abort() - attrs.setdefault('is_flag', True) - attrs.setdefault('callback', callback) - attrs.setdefault('expose_value', False) - attrs.setdefault('prompt', 'Do you want to continue?') - attrs.setdefault('help', 'Confirm the action without prompting.') - return option(*(param_decls or ('--yes',)), **attrs)(f) - return decorator - - -def password_option(*param_decls, **attrs): - """Shortcut for password prompts. - - This is equivalent to decorating a function with :func:`option` with - the following parameters:: - - @click.command() - @click.option('--password', prompt=True, confirmation_prompt=True, - hide_input=True) - def changeadmin(password): - pass - """ - def decorator(f): - attrs.setdefault('prompt', True) - attrs.setdefault('confirmation_prompt', True) - attrs.setdefault('hide_input', True) - return option(*(param_decls or ('--password',)), **attrs)(f) - return decorator - - -def version_option(version=None, *param_decls, **attrs): - """Adds a ``--version`` option which immediately ends the program - printing out the version number. This is implemented as an eager - option that prints the version and exits the program in the callback. - - :param version: the version number to show. If not provided Click - attempts an auto discovery via setuptools. - :param prog_name: the name of the program (defaults to autodetection) - :param message: custom message to show instead of the default - (``'%(prog)s, version %(version)s'``) - :param others: everything else is forwarded to :func:`option`. - """ - if version is None: - module = sys._getframe(1).f_globals.get('__name__') - def decorator(f): - prog_name = attrs.pop('prog_name', None) - message = attrs.pop('message', '%(prog)s, version %(version)s') - - def callback(ctx, param, value): - if not value or ctx.resilient_parsing: - return - prog = prog_name - if prog is None: - prog = ctx.find_root().info_name - ver = version - if ver is None: - try: - import pkg_resources - except ImportError: - pass - else: - for dist in pkg_resources.working_set: - scripts = dist.get_entry_map().get('console_scripts') or {} - for script_name, entry_point in iteritems(scripts): - if entry_point.module_name == module: - ver = dist.version - break - if ver is None: - raise RuntimeError('Could not determine version') - echo(message % { - 'prog': prog, - 'version': ver, - }, color=ctx.color) - ctx.exit() - - attrs.setdefault('is_flag', True) - attrs.setdefault('expose_value', False) - attrs.setdefault('is_eager', True) - attrs.setdefault('help', 'Show the version and exit.') - attrs['callback'] = callback - return option(*(param_decls or ('--version',)), **attrs)(f) - return decorator - - -def help_option(*param_decls, **attrs): - """Adds a ``--help`` option which immediately ends the program - printing out the help page. This is usually unnecessary to add as - this is added by default to all commands unless suppressed. - - Like :func:`version_option`, this is implemented as eager option that - prints in the callback and exits. - - All arguments are forwarded to :func:`option`. - """ - def decorator(f): - def callback(ctx, param, value): - if value and not ctx.resilient_parsing: - echo(ctx.get_help(), color=ctx.color) - ctx.exit() - attrs.setdefault('is_flag', True) - attrs.setdefault('expose_value', False) - attrs.setdefault('help', 'Show this message and exit.') - attrs.setdefault('is_eager', True) - attrs['callback'] = callback - return option(*(param_decls or ('--help',)), **attrs)(f) - return decorator - - -# Circular dependencies between core and decorators -from .core import Command, Group, Argument, Option diff --git a/pyextra/click/exceptions.py b/pyextra/click/exceptions.py deleted file mode 100644 index 74a4542bb57f29..00000000000000 --- a/pyextra/click/exceptions.py +++ /dev/null @@ -1,201 +0,0 @@ -from ._compat import PY2, filename_to_ui, get_text_stderr -from .utils import echo - - -class ClickException(Exception): - """An exception that Click can handle and show to the user.""" - - #: The exit code for this exception - exit_code = 1 - - def __init__(self, message): - if PY2: - if message is not None: - message = message.encode('utf-8') - Exception.__init__(self, message) - self.message = message - - def format_message(self): - return self.message - - def show(self, file=None): - if file is None: - file = get_text_stderr() - echo('Error: %s' % self.format_message(), file=file) - - -class UsageError(ClickException): - """An internal exception that signals a usage error. This typically - aborts any further handling. - - :param message: the error message to display. - :param ctx: optionally the context that caused this error. Click will - fill in the context automatically in some situations. - """ - exit_code = 2 - - def __init__(self, message, ctx=None): - ClickException.__init__(self, message) - self.ctx = ctx - - def show(self, file=None): - if file is None: - file = get_text_stderr() - color = None - if self.ctx is not None: - color = self.ctx.color - echo(self.ctx.get_usage() + '\n', file=file, color=color) - echo('Error: %s' % self.format_message(), file=file, color=color) - - -class BadParameter(UsageError): - """An exception that formats out a standardized error message for a - bad parameter. This is useful when thrown from a callback or type as - Click will attach contextual information to it (for instance, which - parameter it is). - - .. versionadded:: 2.0 - - :param param: the parameter object that caused this error. This can - be left out, and Click will attach this info itself - if possible. - :param param_hint: a string that shows up as parameter name. This - can be used as alternative to `param` in cases - where custom validation should happen. If it is - a string it's used as such, if it's a list then - each item is quoted and separated. - """ - - def __init__(self, message, ctx=None, param=None, - param_hint=None): - UsageError.__init__(self, message, ctx) - self.param = param - self.param_hint = param_hint - - def format_message(self): - if self.param_hint is not None: - param_hint = self.param_hint - elif self.param is not None: - param_hint = self.param.opts or [self.param.human_readable_name] - else: - return 'Invalid value: %s' % self.message - if isinstance(param_hint, (tuple, list)): - param_hint = ' / '.join('"%s"' % x for x in param_hint) - return 'Invalid value for %s: %s' % (param_hint, self.message) - - -class MissingParameter(BadParameter): - """Raised if click required an option or argument but it was not - provided when invoking the script. - - .. versionadded:: 4.0 - - :param param_type: a string that indicates the type of the parameter. - The default is to inherit the parameter type from - the given `param`. Valid values are ``'parameter'``, - ``'option'`` or ``'argument'``. - """ - - def __init__(self, message=None, ctx=None, param=None, - param_hint=None, param_type=None): - BadParameter.__init__(self, message, ctx, param, param_hint) - self.param_type = param_type - - def format_message(self): - if self.param_hint is not None: - param_hint = self.param_hint - elif self.param is not None: - param_hint = self.param.opts or [self.param.human_readable_name] - else: - param_hint = None - if isinstance(param_hint, (tuple, list)): - param_hint = ' / '.join('"%s"' % x for x in param_hint) - - param_type = self.param_type - if param_type is None and self.param is not None: - param_type = self.param.param_type_name - - msg = self.message - if self.param is not None: - msg_extra = self.param.type.get_missing_message(self.param) - if msg_extra: - if msg: - msg += '. ' + msg_extra - else: - msg = msg_extra - - return 'Missing %s%s%s%s' % ( - param_type, - param_hint and ' %s' % param_hint or '', - msg and '. ' or '.', - msg or '', - ) - - -class NoSuchOption(UsageError): - """Raised if click attempted to handle an option that does not - exist. - - .. versionadded:: 4.0 - """ - - def __init__(self, option_name, message=None, possibilities=None, - ctx=None): - if message is None: - message = 'no such option: %s' % option_name - UsageError.__init__(self, message, ctx) - self.option_name = option_name - self.possibilities = possibilities - - def format_message(self): - bits = [self.message] - if self.possibilities: - if len(self.possibilities) == 1: - bits.append('Did you mean %s?' % self.possibilities[0]) - else: - possibilities = sorted(self.possibilities) - bits.append('(Possible options: %s)' % ', '.join(possibilities)) - return ' '.join(bits) - - -class BadOptionUsage(UsageError): - """Raised if an option is generally supplied but the use of the option - was incorrect. This is for instance raised if the number of arguments - for an option is not correct. - - .. versionadded:: 4.0 - """ - - def __init__(self, message, ctx=None): - UsageError.__init__(self, message, ctx) - - -class BadArgumentUsage(UsageError): - """Raised if an argument is generally supplied but the use of the argument - was incorrect. This is for instance raised if the number of values - for an argument is not correct. - - .. versionadded:: 6.0 - """ - - def __init__(self, message, ctx=None): - UsageError.__init__(self, message, ctx) - - -class FileError(ClickException): - """Raised if a file cannot be opened.""" - - def __init__(self, filename, hint=None): - ui_filename = filename_to_ui(filename) - if hint is None: - hint = 'unknown error' - ClickException.__init__(self, hint) - self.ui_filename = ui_filename - self.filename = filename - - def format_message(self): - return 'Could not open file %s: %s' % (self.ui_filename, self.message) - - -class Abort(RuntimeError): - """An internal signalling exception that signals Click to abort.""" diff --git a/pyextra/click/formatting.py b/pyextra/click/formatting.py deleted file mode 100644 index a3d6a4d389019c..00000000000000 --- a/pyextra/click/formatting.py +++ /dev/null @@ -1,256 +0,0 @@ -from contextlib import contextmanager -from .termui import get_terminal_size -from .parser import split_opt -from ._compat import term_len - - -# Can force a width. This is used by the test system -FORCED_WIDTH = None - - -def measure_table(rows): - widths = {} - for row in rows: - for idx, col in enumerate(row): - widths[idx] = max(widths.get(idx, 0), term_len(col)) - return tuple(y for x, y in sorted(widths.items())) - - -def iter_rows(rows, col_count): - for row in rows: - row = tuple(row) - yield row + ('',) * (col_count - len(row)) - - -def wrap_text(text, width=78, initial_indent='', subsequent_indent='', - preserve_paragraphs=False): - """A helper function that intelligently wraps text. By default, it - assumes that it operates on a single paragraph of text but if the - `preserve_paragraphs` parameter is provided it will intelligently - handle paragraphs (defined by two empty lines). - - If paragraphs are handled, a paragraph can be prefixed with an empty - line containing the ``\\b`` character (``\\x08``) to indicate that - no rewrapping should happen in that block. - - :param text: the text that should be rewrapped. - :param width: the maximum width for the text. - :param initial_indent: the initial indent that should be placed on the - first line as a string. - :param subsequent_indent: the indent string that should be placed on - each consecutive line. - :param preserve_paragraphs: if this flag is set then the wrapping will - intelligently handle paragraphs. - """ - from ._textwrap import TextWrapper - text = text.expandtabs() - wrapper = TextWrapper(width, initial_indent=initial_indent, - subsequent_indent=subsequent_indent, - replace_whitespace=False) - if not preserve_paragraphs: - return wrapper.fill(text) - - p = [] - buf = [] - indent = None - - def _flush_par(): - if not buf: - return - if buf[0].strip() == '\b': - p.append((indent or 0, True, '\n'.join(buf[1:]))) - else: - p.append((indent or 0, False, ' '.join(buf))) - del buf[:] - - for line in text.splitlines(): - if not line: - _flush_par() - indent = None - else: - if indent is None: - orig_len = term_len(line) - line = line.lstrip() - indent = orig_len - term_len(line) - buf.append(line) - _flush_par() - - rv = [] - for indent, raw, text in p: - with wrapper.extra_indent(' ' * indent): - if raw: - rv.append(wrapper.indent_only(text)) - else: - rv.append(wrapper.fill(text)) - - return '\n\n'.join(rv) - - -class HelpFormatter(object): - """This class helps with formatting text-based help pages. It's - usually just needed for very special internal cases, but it's also - exposed so that developers can write their own fancy outputs. - - At present, it always writes into memory. - - :param indent_increment: the additional increment for each level. - :param width: the width for the text. This defaults to the terminal - width clamped to a maximum of 78. - """ - - def __init__(self, indent_increment=2, width=None, max_width=None): - self.indent_increment = indent_increment - if max_width is None: - max_width = 80 - if width is None: - width = FORCED_WIDTH - if width is None: - width = max(min(get_terminal_size()[0], max_width) - 2, 50) - self.width = width - self.current_indent = 0 - self.buffer = [] - - def write(self, string): - """Writes a unicode string into the internal buffer.""" - self.buffer.append(string) - - def indent(self): - """Increases the indentation.""" - self.current_indent += self.indent_increment - - def dedent(self): - """Decreases the indentation.""" - self.current_indent -= self.indent_increment - - def write_usage(self, prog, args='', prefix='Usage: '): - """Writes a usage line into the buffer. - - :param prog: the program name. - :param args: whitespace separated list of arguments. - :param prefix: the prefix for the first line. - """ - usage_prefix = '%*s%s ' % (self.current_indent, prefix, prog) - text_width = self.width - self.current_indent - - if text_width >= (term_len(usage_prefix) + 20): - # The arguments will fit to the right of the prefix. - indent = ' ' * term_len(usage_prefix) - self.write(wrap_text(args, text_width, - initial_indent=usage_prefix, - subsequent_indent=indent)) - else: - # The prefix is too long, put the arguments on the next line. - self.write(usage_prefix) - self.write('\n') - indent = ' ' * (max(self.current_indent, term_len(prefix)) + 4) - self.write(wrap_text(args, text_width, - initial_indent=indent, - subsequent_indent=indent)) - - self.write('\n') - - def write_heading(self, heading): - """Writes a heading into the buffer.""" - self.write('%*s%s:\n' % (self.current_indent, '', heading)) - - def write_paragraph(self): - """Writes a paragraph into the buffer.""" - if self.buffer: - self.write('\n') - - def write_text(self, text): - """Writes re-indented text into the buffer. This rewraps and - preserves paragraphs. - """ - text_width = max(self.width - self.current_indent, 11) - indent = ' ' * self.current_indent - self.write(wrap_text(text, text_width, - initial_indent=indent, - subsequent_indent=indent, - preserve_paragraphs=True)) - self.write('\n') - - def write_dl(self, rows, col_max=30, col_spacing=2): - """Writes a definition list into the buffer. This is how options - and commands are usually formatted. - - :param rows: a list of two item tuples for the terms and values. - :param col_max: the maximum width of the first column. - :param col_spacing: the number of spaces between the first and - second column. - """ - rows = list(rows) - widths = measure_table(rows) - if len(widths) != 2: - raise TypeError('Expected two columns for definition list') - - first_col = min(widths[0], col_max) + col_spacing - - for first, second in iter_rows(rows, len(widths)): - self.write('%*s%s' % (self.current_indent, '', first)) - if not second: - self.write('\n') - continue - if term_len(first) <= first_col - col_spacing: - self.write(' ' * (first_col - term_len(first))) - else: - self.write('\n') - self.write(' ' * (first_col + self.current_indent)) - - text_width = max(self.width - first_col - 2, 10) - lines = iter(wrap_text(second, text_width).splitlines()) - if lines: - self.write(next(lines) + '\n') - for line in lines: - self.write('%*s%s\n' % ( - first_col + self.current_indent, '', line)) - else: - self.write('\n') - - @contextmanager - def section(self, name): - """Helpful context manager that writes a paragraph, a heading, - and the indents. - - :param name: the section name that is written as heading. - """ - self.write_paragraph() - self.write_heading(name) - self.indent() - try: - yield - finally: - self.dedent() - - @contextmanager - def indentation(self): - """A context manager that increases the indentation.""" - self.indent() - try: - yield - finally: - self.dedent() - - def getvalue(self): - """Returns the buffer contents.""" - return ''.join(self.buffer) - - -def join_options(options): - """Given a list of option strings this joins them in the most appropriate - way and returns them in the form ``(formatted_string, - any_prefix_is_slash)`` where the second item in the tuple is a flag that - indicates if any of the option prefixes was a slash. - """ - rv = [] - any_prefix_is_slash = False - for opt in options: - prefix = split_opt(opt)[0] - if prefix == '/': - any_prefix_is_slash = True - rv.append((len(prefix), opt)) - - rv.sort(key=lambda x: x[0]) - - rv = ', '.join(x[1] for x in rv) - return rv, any_prefix_is_slash diff --git a/pyextra/click/globals.py b/pyextra/click/globals.py deleted file mode 100644 index 14338e6bb8434b..00000000000000 --- a/pyextra/click/globals.py +++ /dev/null @@ -1,48 +0,0 @@ -from threading import local - - -_local = local() - - -def get_current_context(silent=False): - """Returns the current click context. This can be used as a way to - access the current context object from anywhere. This is a more implicit - alternative to the :func:`pass_context` decorator. This function is - primarily useful for helpers such as :func:`echo` which might be - interested in changing it's behavior based on the current context. - - To push the current context, :meth:`Context.scope` can be used. - - .. versionadded:: 5.0 - - :param silent: is set to `True` the return value is `None` if no context - is available. The default behavior is to raise a - :exc:`RuntimeError`. - """ - try: - return getattr(_local, 'stack')[-1] - except (AttributeError, IndexError): - if not silent: - raise RuntimeError('There is no active click context.') - - -def push_context(ctx): - """Pushes a new context to the current stack.""" - _local.__dict__.setdefault('stack', []).append(ctx) - - -def pop_context(): - """Removes the top level from the stack.""" - _local.stack.pop() - - -def resolve_color_default(color=None): - """"Internal helper to get the default value of the color flag. If a - value is passed it's returned unchanged, otherwise it's looked up from - the current context. - """ - if color is not None: - return color - ctx = get_current_context(silent=True) - if ctx is not None: - return ctx.color diff --git a/pyextra/click/parser.py b/pyextra/click/parser.py deleted file mode 100644 index 9775c9ff9b99d8..00000000000000 --- a/pyextra/click/parser.py +++ /dev/null @@ -1,426 +0,0 @@ -# -*- coding: utf-8 -*- -""" - click.parser - ~~~~~~~~~~~~ - - This module started out as largely a copy paste from the stdlib's - optparse module with the features removed that we do not need from - optparse because we implement them in Click on a higher level (for - instance type handling, help formatting and a lot more). - - The plan is to remove more and more from here over time. - - The reason this is a different module and not optparse from the stdlib - is that there are differences in 2.x and 3.x about the error messages - generated and optparse in the stdlib uses gettext for no good reason - and might cause us issues. -""" -import re -from collections import deque -from .exceptions import UsageError, NoSuchOption, BadOptionUsage, \ - BadArgumentUsage - - -def _unpack_args(args, nargs_spec): - """Given an iterable of arguments and an iterable of nargs specifications, - it returns a tuple with all the unpacked arguments at the first index - and all remaining arguments as the second. - - The nargs specification is the number of arguments that should be consumed - or `-1` to indicate that this position should eat up all the remainders. - - Missing items are filled with `None`. - """ - args = deque(args) - nargs_spec = deque(nargs_spec) - rv = [] - spos = None - - def _fetch(c): - try: - if spos is None: - return c.popleft() - else: - return c.pop() - except IndexError: - return None - - while nargs_spec: - nargs = _fetch(nargs_spec) - if nargs == 1: - rv.append(_fetch(args)) - elif nargs > 1: - x = [_fetch(args) for _ in range(nargs)] - # If we're reversed, we're pulling in the arguments in reverse, - # so we need to turn them around. - if spos is not None: - x.reverse() - rv.append(tuple(x)) - elif nargs < 0: - if spos is not None: - raise TypeError('Cannot have two nargs < 0') - spos = len(rv) - rv.append(None) - - # spos is the position of the wildcard (star). If it's not `None`, - # we fill it with the remainder. - if spos is not None: - rv[spos] = tuple(args) - args = [] - rv[spos + 1:] = reversed(rv[spos + 1:]) - - return tuple(rv), list(args) - - -def _error_opt_args(nargs, opt): - if nargs == 1: - raise BadOptionUsage('%s option requires an argument' % opt) - raise BadOptionUsage('%s option requires %d arguments' % (opt, nargs)) - - -def split_opt(opt): - first = opt[:1] - if first.isalnum(): - return '', opt - if opt[1:2] == first: - return opt[:2], opt[2:] - return first, opt[1:] - - -def normalize_opt(opt, ctx): - if ctx is None or ctx.token_normalize_func is None: - return opt - prefix, opt = split_opt(opt) - return prefix + ctx.token_normalize_func(opt) - - -def split_arg_string(string): - """Given an argument string this attempts to split it into small parts.""" - rv = [] - for match in re.finditer(r"('([^'\\]*(?:\\.[^'\\]*)*)'" - r'|"([^"\\]*(?:\\.[^"\\]*)*)"' - r'|\S+)\s*', string, re.S): - arg = match.group().strip() - if arg[:1] == arg[-1:] and arg[:1] in '"\'': - arg = arg[1:-1].encode('ascii', 'backslashreplace') \ - .decode('unicode-escape') - try: - arg = type(string)(arg) - except UnicodeError: - pass - rv.append(arg) - return rv - - -class Option(object): - - def __init__(self, opts, dest, action=None, nargs=1, const=None, obj=None): - self._short_opts = [] - self._long_opts = [] - self.prefixes = set() - - for opt in opts: - prefix, value = split_opt(opt) - if not prefix: - raise ValueError('Invalid start character for option (%s)' - % opt) - self.prefixes.add(prefix[0]) - if len(prefix) == 1 and len(value) == 1: - self._short_opts.append(opt) - else: - self._long_opts.append(opt) - self.prefixes.add(prefix) - - if action is None: - action = 'store' - - self.dest = dest - self.action = action - self.nargs = nargs - self.const = const - self.obj = obj - - @property - def takes_value(self): - return self.action in ('store', 'append') - - def process(self, value, state): - if self.action == 'store': - state.opts[self.dest] = value - elif self.action == 'store_const': - state.opts[self.dest] = self.const - elif self.action == 'append': - state.opts.setdefault(self.dest, []).append(value) - elif self.action == 'append_const': - state.opts.setdefault(self.dest, []).append(self.const) - elif self.action == 'count': - state.opts[self.dest] = state.opts.get(self.dest, 0) + 1 - else: - raise ValueError('unknown action %r' % self.action) - state.order.append(self.obj) - - -class Argument(object): - - def __init__(self, dest, nargs=1, obj=None): - self.dest = dest - self.nargs = nargs - self.obj = obj - - def process(self, value, state): - if self.nargs > 1: - holes = sum(1 for x in value if x is None) - if holes == len(value): - value = None - elif holes != 0: - raise BadArgumentUsage('argument %s takes %d values' - % (self.dest, self.nargs)) - state.opts[self.dest] = value - state.order.append(self.obj) - - -class ParsingState(object): - - def __init__(self, rargs): - self.opts = {} - self.largs = [] - self.rargs = rargs - self.order = [] - - -class OptionParser(object): - """The option parser is an internal class that is ultimately used to - parse options and arguments. It's modelled after optparse and brings - a similar but vastly simplified API. It should generally not be used - directly as the high level Click classes wrap it for you. - - It's not nearly as extensible as optparse or argparse as it does not - implement features that are implemented on a higher level (such as - types or defaults). - - :param ctx: optionally the :class:`~click.Context` where this parser - should go with. - """ - - def __init__(self, ctx=None): - #: The :class:`~click.Context` for this parser. This might be - #: `None` for some advanced use cases. - self.ctx = ctx - #: This controls how the parser deals with interspersed arguments. - #: If this is set to `False`, the parser will stop on the first - #: non-option. Click uses this to implement nested subcommands - #: safely. - self.allow_interspersed_args = True - #: This tells the parser how to deal with unknown options. By - #: default it will error out (which is sensible), but there is a - #: second mode where it will ignore it and continue processing - #: after shifting all the unknown options into the resulting args. - self.ignore_unknown_options = False - if ctx is not None: - self.allow_interspersed_args = ctx.allow_interspersed_args - self.ignore_unknown_options = ctx.ignore_unknown_options - self._short_opt = {} - self._long_opt = {} - self._opt_prefixes = set(['-', '--']) - self._args = [] - - def add_option(self, opts, dest, action=None, nargs=1, const=None, - obj=None): - """Adds a new option named `dest` to the parser. The destination - is not inferred (unlike with optparse) and needs to be explicitly - provided. Action can be any of ``store``, ``store_const``, - ``append``, ``appnd_const`` or ``count``. - - The `obj` can be used to identify the option in the order list - that is returned from the parser. - """ - if obj is None: - obj = dest - opts = [normalize_opt(opt, self.ctx) for opt in opts] - option = Option(opts, dest, action=action, nargs=nargs, - const=const, obj=obj) - self._opt_prefixes.update(option.prefixes) - for opt in option._short_opts: - self._short_opt[opt] = option - for opt in option._long_opts: - self._long_opt[opt] = option - - def add_argument(self, dest, nargs=1, obj=None): - """Adds a positional argument named `dest` to the parser. - - The `obj` can be used to identify the option in the order list - that is returned from the parser. - """ - if obj is None: - obj = dest - self._args.append(Argument(dest=dest, nargs=nargs, obj=obj)) - - def parse_args(self, args): - """Parses positional arguments and returns ``(values, args, order)`` - for the parsed options and arguments as well as the leftover - arguments if there are any. The order is a list of objects as they - appear on the command line. If arguments appear multiple times they - will be memorized multiple times as well. - """ - state = ParsingState(args) - try: - self._process_args_for_options(state) - self._process_args_for_args(state) - except UsageError: - if self.ctx is None or not self.ctx.resilient_parsing: - raise - return state.opts, state.largs, state.order - - def _process_args_for_args(self, state): - pargs, args = _unpack_args(state.largs + state.rargs, - [x.nargs for x in self._args]) - - for idx, arg in enumerate(self._args): - arg.process(pargs[idx], state) - - state.largs = args - state.rargs = [] - - def _process_args_for_options(self, state): - while state.rargs: - arg = state.rargs.pop(0) - arglen = len(arg) - # Double dashes always handled explicitly regardless of what - # prefixes are valid. - if arg == '--': - return - elif arg[:1] in self._opt_prefixes and arglen > 1: - self._process_opts(arg, state) - elif self.allow_interspersed_args: - state.largs.append(arg) - else: - state.rargs.insert(0, arg) - return - - # Say this is the original argument list: - # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] - # ^ - # (we are about to process arg(i)). - # - # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of - # [arg0, ..., arg(i-1)] (any options and their arguments will have - # been removed from largs). - # - # The while loop will usually consume 1 or more arguments per pass. - # If it consumes 1 (eg. arg is an option that takes no arguments), - # then after _process_arg() is done the situation is: - # - # largs = subset of [arg0, ..., arg(i)] - # rargs = [arg(i+1), ..., arg(N-1)] - # - # If allow_interspersed_args is false, largs will always be - # *empty* -- still a subset of [arg0, ..., arg(i-1)], but - # not a very interesting subset! - - def _match_long_opt(self, opt, explicit_value, state): - if opt not in self._long_opt: - possibilities = [word for word in self._long_opt - if word.startswith(opt)] - raise NoSuchOption(opt, possibilities=possibilities) - - option = self._long_opt[opt] - if option.takes_value: - # At this point it's safe to modify rargs by injecting the - # explicit value, because no exception is raised in this - # branch. This means that the inserted value will be fully - # consumed. - if explicit_value is not None: - state.rargs.insert(0, explicit_value) - - nargs = option.nargs - if len(state.rargs) < nargs: - _error_opt_args(nargs, opt) - elif nargs == 1: - value = state.rargs.pop(0) - else: - value = tuple(state.rargs[:nargs]) - del state.rargs[:nargs] - - elif explicit_value is not None: - raise BadOptionUsage('%s option does not take a value' % opt) - - else: - value = None - - option.process(value, state) - - def _match_short_opt(self, arg, state): - stop = False - i = 1 - prefix = arg[0] - unknown_options = [] - - for ch in arg[1:]: - opt = normalize_opt(prefix + ch, self.ctx) - option = self._short_opt.get(opt) - i += 1 - - if not option: - if self.ignore_unknown_options: - unknown_options.append(ch) - continue - raise NoSuchOption(opt) - if option.takes_value: - # Any characters left in arg? Pretend they're the - # next arg, and stop consuming characters of arg. - if i < len(arg): - state.rargs.insert(0, arg[i:]) - stop = True - - nargs = option.nargs - if len(state.rargs) < nargs: - _error_opt_args(nargs, opt) - elif nargs == 1: - value = state.rargs.pop(0) - else: - value = tuple(state.rargs[:nargs]) - del state.rargs[:nargs] - - else: - value = None - - option.process(value, state) - - if stop: - break - - # If we got any unknown options we re-combinate the string of the - # remaining options and re-attach the prefix, then report that - # to the state as new larg. This way there is basic combinatorics - # that can be achieved while still ignoring unknown arguments. - if self.ignore_unknown_options and unknown_options: - state.largs.append(prefix + ''.join(unknown_options)) - - def _process_opts(self, arg, state): - explicit_value = None - # Long option handling happens in two parts. The first part is - # supporting explicitly attached values. In any case, we will try - # to long match the option first. - if '=' in arg: - long_opt, explicit_value = arg.split('=', 1) - else: - long_opt = arg - norm_long_opt = normalize_opt(long_opt, self.ctx) - - # At this point we will match the (assumed) long option through - # the long option matching code. Note that this allows options - # like "-foo" to be matched as long options. - try: - self._match_long_opt(norm_long_opt, explicit_value, state) - except NoSuchOption: - # At this point the long option matching failed, and we need - # to try with short options. However there is a special rule - # which says, that if we have a two character options prefix - # (applies to "--foo" for instance), we do not dispatch to the - # short option code and will instead raise the no option - # error. - if arg[:2] not in self._opt_prefixes: - return self._match_short_opt(arg, state) - if not self.ignore_unknown_options: - raise - state.largs.append(arg) diff --git a/pyextra/click/termui.py b/pyextra/click/termui.py deleted file mode 100644 index d9fba52325f35b..00000000000000 --- a/pyextra/click/termui.py +++ /dev/null @@ -1,539 +0,0 @@ -import os -import sys -import struct - -from ._compat import raw_input, text_type, string_types, \ - isatty, strip_ansi, get_winterm_size, DEFAULT_COLUMNS, WIN -from .utils import echo -from .exceptions import Abort, UsageError -from .types import convert_type -from .globals import resolve_color_default - - -# The prompt functions to use. The doc tools currently override these -# functions to customize how they work. -visible_prompt_func = raw_input - -_ansi_colors = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', - 'cyan', 'white', 'reset') -_ansi_reset_all = '\033[0m' - - -def hidden_prompt_func(prompt): - import getpass - return getpass.getpass(prompt) - - -def _build_prompt(text, suffix, show_default=False, default=None): - prompt = text - if default is not None and show_default: - prompt = '%s [%s]' % (prompt, default) - return prompt + suffix - - -def prompt(text, default=None, hide_input=False, - confirmation_prompt=False, type=None, - value_proc=None, prompt_suffix=': ', - show_default=True, err=False): - """Prompts a user for input. This is a convenience function that can - be used to prompt a user for input later. - - If the user aborts the input by sending a interrupt signal, this - function will catch it and raise a :exc:`Abort` exception. - - .. versionadded:: 6.0 - Added unicode support for cmd.exe on Windows. - - .. versionadded:: 4.0 - Added the `err` parameter. - - :param text: the text to show for the prompt. - :param default: the default value to use if no input happens. If this - is not given it will prompt until it's aborted. - :param hide_input: if this is set to true then the input value will - be hidden. - :param confirmation_prompt: asks for confirmation for the value. - :param type: the type to use to check the value against. - :param value_proc: if this parameter is provided it's a function that - is invoked instead of the type conversion to - convert a value. - :param prompt_suffix: a suffix that should be added to the prompt. - :param show_default: shows or hides the default value in the prompt. - :param err: if set to true the file defaults to ``stderr`` instead of - ``stdout``, the same as with echo. - """ - result = None - - def prompt_func(text): - f = hide_input and hidden_prompt_func or visible_prompt_func - try: - # Write the prompt separately so that we get nice - # coloring through colorama on Windows - echo(text, nl=False, err=err) - return f('') - except (KeyboardInterrupt, EOFError): - # getpass doesn't print a newline if the user aborts input with ^C. - # Allegedly this behavior is inherited from getpass(3). - # A doc bug has been filed at https://bugs.python.org/issue24711 - if hide_input: - echo(None, err=err) - raise Abort() - - if value_proc is None: - value_proc = convert_type(type, default) - - prompt = _build_prompt(text, prompt_suffix, show_default, default) - - while 1: - while 1: - value = prompt_func(prompt) - if value: - break - # If a default is set and used, then the confirmation - # prompt is always skipped because that's the only thing - # that really makes sense. - elif default is not None: - return default - try: - result = value_proc(value) - except UsageError as e: - echo('Error: %s' % e.message, err=err) - continue - if not confirmation_prompt: - return result - while 1: - value2 = prompt_func('Repeat for confirmation: ') - if value2: - break - if value == value2: - return result - echo('Error: the two entered values do not match', err=err) - - -def confirm(text, default=False, abort=False, prompt_suffix=': ', - show_default=True, err=False): - """Prompts for confirmation (yes/no question). - - If the user aborts the input by sending a interrupt signal this - function will catch it and raise a :exc:`Abort` exception. - - .. versionadded:: 4.0 - Added the `err` parameter. - - :param text: the question to ask. - :param default: the default for the prompt. - :param abort: if this is set to `True` a negative answer aborts the - exception by raising :exc:`Abort`. - :param prompt_suffix: a suffix that should be added to the prompt. - :param show_default: shows or hides the default value in the prompt. - :param err: if set to true the file defaults to ``stderr`` instead of - ``stdout``, the same as with echo. - """ - prompt = _build_prompt(text, prompt_suffix, show_default, - default and 'Y/n' or 'y/N') - while 1: - try: - # Write the prompt separately so that we get nice - # coloring through colorama on Windows - echo(prompt, nl=False, err=err) - value = visible_prompt_func('').lower().strip() - except (KeyboardInterrupt, EOFError): - raise Abort() - if value in ('y', 'yes'): - rv = True - elif value in ('n', 'no'): - rv = False - elif value == '': - rv = default - else: - echo('Error: invalid input', err=err) - continue - break - if abort and not rv: - raise Abort() - return rv - - -def get_terminal_size(): - """Returns the current size of the terminal as tuple in the form - ``(width, height)`` in columns and rows. - """ - # If shutil has get_terminal_size() (Python 3.3 and later) use that - if sys.version_info >= (3, 3): - import shutil - shutil_get_terminal_size = getattr(shutil, 'get_terminal_size', None) - if shutil_get_terminal_size: - sz = shutil_get_terminal_size() - return sz.columns, sz.lines - - if get_winterm_size is not None: - return get_winterm_size() - - def ioctl_gwinsz(fd): - try: - import fcntl - import termios - cr = struct.unpack( - 'hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) - except Exception: - return - return cr - - cr = ioctl_gwinsz(0) or ioctl_gwinsz(1) or ioctl_gwinsz(2) - if not cr: - try: - fd = os.open(os.ctermid(), os.O_RDONLY) - try: - cr = ioctl_gwinsz(fd) - finally: - os.close(fd) - except Exception: - pass - if not cr or not cr[0] or not cr[1]: - cr = (os.environ.get('LINES', 25), - os.environ.get('COLUMNS', DEFAULT_COLUMNS)) - return int(cr[1]), int(cr[0]) - - -def echo_via_pager(text, color=None): - """This function takes a text and shows it via an environment specific - pager on stdout. - - .. versionchanged:: 3.0 - Added the `color` flag. - - :param text: the text to page. - :param color: controls if the pager supports ANSI colors or not. The - default is autodetection. - """ - color = resolve_color_default(color) - if not isinstance(text, string_types): - text = text_type(text) - from ._termui_impl import pager - return pager(text + '\n', color) - - -def progressbar(iterable=None, length=None, label=None, show_eta=True, - show_percent=None, show_pos=False, - item_show_func=None, fill_char='#', empty_char='-', - bar_template='%(label)s [%(bar)s] %(info)s', - info_sep=' ', width=36, file=None, color=None): - """This function creates an iterable context manager that can be used - to iterate over something while showing a progress bar. It will - either iterate over the `iterable` or `length` items (that are counted - up). While iteration happens, this function will print a rendered - progress bar to the given `file` (defaults to stdout) and will attempt - to calculate remaining time and more. By default, this progress bar - will not be rendered if the file is not a terminal. - - The context manager creates the progress bar. When the context - manager is entered the progress bar is already displayed. With every - iteration over the progress bar, the iterable passed to the bar is - advanced and the bar is updated. When the context manager exits, - a newline is printed and the progress bar is finalized on screen. - - No printing must happen or the progress bar will be unintentionally - destroyed. - - Example usage:: - - with progressbar(items) as bar: - for item in bar: - do_something_with(item) - - Alternatively, if no iterable is specified, one can manually update the - progress bar through the `update()` method instead of directly - iterating over the progress bar. The update method accepts the number - of steps to increment the bar with:: - - with progressbar(length=chunks.total_bytes) as bar: - for chunk in chunks: - process_chunk(chunk) - bar.update(chunks.bytes) - - .. versionadded:: 2.0 - - .. versionadded:: 4.0 - Added the `color` parameter. Added a `update` method to the - progressbar object. - - :param iterable: an iterable to iterate over. If not provided the length - is required. - :param length: the number of items to iterate over. By default the - progressbar will attempt to ask the iterator about its - length, which might or might not work. If an iterable is - also provided this parameter can be used to override the - length. If an iterable is not provided the progress bar - will iterate over a range of that length. - :param label: the label to show next to the progress bar. - :param show_eta: enables or disables the estimated time display. This is - automatically disabled if the length cannot be - determined. - :param show_percent: enables or disables the percentage display. The - default is `True` if the iterable has a length or - `False` if not. - :param show_pos: enables or disables the absolute position display. The - default is `False`. - :param item_show_func: a function called with the current item which - can return a string to show the current item - next to the progress bar. Note that the current - item can be `None`! - :param fill_char: the character to use to show the filled part of the - progress bar. - :param empty_char: the character to use to show the non-filled part of - the progress bar. - :param bar_template: the format string to use as template for the bar. - The parameters in it are ``label`` for the label, - ``bar`` for the progress bar and ``info`` for the - info section. - :param info_sep: the separator between multiple info items (eta etc.) - :param width: the width of the progress bar in characters, 0 means full - terminal width - :param file: the file to write to. If this is not a terminal then - only the label is printed. - :param color: controls if the terminal supports ANSI colors or not. The - default is autodetection. This is only needed if ANSI - codes are included anywhere in the progress bar output - which is not the case by default. - """ - from ._termui_impl import ProgressBar - color = resolve_color_default(color) - return ProgressBar(iterable=iterable, length=length, show_eta=show_eta, - show_percent=show_percent, show_pos=show_pos, - item_show_func=item_show_func, fill_char=fill_char, - empty_char=empty_char, bar_template=bar_template, - info_sep=info_sep, file=file, label=label, - width=width, color=color) - - -def clear(): - """Clears the terminal screen. This will have the effect of clearing - the whole visible space of the terminal and moving the cursor to the - top left. This does not do anything if not connected to a terminal. - - .. versionadded:: 2.0 - """ - if not isatty(sys.stdout): - return - # If we're on Windows and we don't have colorama available, then we - # clear the screen by shelling out. Otherwise we can use an escape - # sequence. - if WIN: - os.system('cls') - else: - sys.stdout.write('\033[2J\033[1;1H') - - -def style(text, fg=None, bg=None, bold=None, dim=None, underline=None, - blink=None, reverse=None, reset=True): - """Styles a text with ANSI styles and returns the new string. By - default the styling is self contained which means that at the end - of the string a reset code is issued. This can be prevented by - passing ``reset=False``. - - Examples:: - - click.echo(click.style('Hello World!', fg='green')) - click.echo(click.style('ATTENTION!', blink=True)) - click.echo(click.style('Some things', reverse=True, fg='cyan')) - - Supported color names: - - * ``black`` (might be a gray) - * ``red`` - * ``green`` - * ``yellow`` (might be an orange) - * ``blue`` - * ``magenta`` - * ``cyan`` - * ``white`` (might be light gray) - * ``reset`` (reset the color code only) - - .. versionadded:: 2.0 - - :param text: the string to style with ansi codes. - :param fg: if provided this will become the foreground color. - :param bg: if provided this will become the background color. - :param bold: if provided this will enable or disable bold mode. - :param dim: if provided this will enable or disable dim mode. This is - badly supported. - :param underline: if provided this will enable or disable underline. - :param blink: if provided this will enable or disable blinking. - :param reverse: if provided this will enable or disable inverse - rendering (foreground becomes background and the - other way round). - :param reset: by default a reset-all code is added at the end of the - string which means that styles do not carry over. This - can be disabled to compose styles. - """ - bits = [] - if fg: - try: - bits.append('\033[%dm' % (_ansi_colors.index(fg) + 30)) - except ValueError: - raise TypeError('Unknown color %r' % fg) - if bg: - try: - bits.append('\033[%dm' % (_ansi_colors.index(bg) + 40)) - except ValueError: - raise TypeError('Unknown color %r' % bg) - if bold is not None: - bits.append('\033[%dm' % (1 if bold else 22)) - if dim is not None: - bits.append('\033[%dm' % (2 if dim else 22)) - if underline is not None: - bits.append('\033[%dm' % (4 if underline else 24)) - if blink is not None: - bits.append('\033[%dm' % (5 if blink else 25)) - if reverse is not None: - bits.append('\033[%dm' % (7 if reverse else 27)) - bits.append(text) - if reset: - bits.append(_ansi_reset_all) - return ''.join(bits) - - -def unstyle(text): - """Removes ANSI styling information from a string. Usually it's not - necessary to use this function as Click's echo function will - automatically remove styling if necessary. - - .. versionadded:: 2.0 - - :param text: the text to remove style information from. - """ - return strip_ansi(text) - - -def secho(text, file=None, nl=True, err=False, color=None, **styles): - """This function combines :func:`echo` and :func:`style` into one - call. As such the following two calls are the same:: - - click.secho('Hello World!', fg='green') - click.echo(click.style('Hello World!', fg='green')) - - All keyword arguments are forwarded to the underlying functions - depending on which one they go with. - - .. versionadded:: 2.0 - """ - return echo(style(text, **styles), file=file, nl=nl, err=err, color=color) - - -def edit(text=None, editor=None, env=None, require_save=True, - extension='.txt', filename=None): - r"""Edits the given text in the defined editor. If an editor is given - (should be the full path to the executable but the regular operating - system search path is used for finding the executable) it overrides - the detected editor. Optionally, some environment variables can be - used. If the editor is closed without changes, `None` is returned. In - case a file is edited directly the return value is always `None` and - `require_save` and `extension` are ignored. - - If the editor cannot be opened a :exc:`UsageError` is raised. - - Note for Windows: to simplify cross-platform usage, the newlines are - automatically converted from POSIX to Windows and vice versa. As such, - the message here will have ``\n`` as newline markers. - - :param text: the text to edit. - :param editor: optionally the editor to use. Defaults to automatic - detection. - :param env: environment variables to forward to the editor. - :param require_save: if this is true, then not saving in the editor - will make the return value become `None`. - :param extension: the extension to tell the editor about. This defaults - to `.txt` but changing this might change syntax - highlighting. - :param filename: if provided it will edit this file instead of the - provided text contents. It will not use a temporary - file as an indirection in that case. - """ - from ._termui_impl import Editor - editor = Editor(editor=editor, env=env, require_save=require_save, - extension=extension) - if filename is None: - return editor.edit(text) - editor.edit_file(filename) - - -def launch(url, wait=False, locate=False): - """This function launches the given URL (or filename) in the default - viewer application for this file type. If this is an executable, it - might launch the executable in a new session. The return value is - the exit code of the launched application. Usually, ``0`` indicates - success. - - Examples:: - - click.launch('http://click.pocoo.org/') - click.launch('/my/downloaded/file', locate=True) - - .. versionadded:: 2.0 - - :param url: URL or filename of the thing to launch. - :param wait: waits for the program to stop. - :param locate: if this is set to `True` then instead of launching the - application associated with the URL it will attempt to - launch a file manager with the file located. This - might have weird effects if the URL does not point to - the filesystem. - """ - from ._termui_impl import open_url - return open_url(url, wait=wait, locate=locate) - - -# If this is provided, getchar() calls into this instead. This is used -# for unittesting purposes. -_getchar = None - - -def getchar(echo=False): - """Fetches a single character from the terminal and returns it. This - will always return a unicode character and under certain rare - circumstances this might return more than one character. The - situations which more than one character is returned is when for - whatever reason multiple characters end up in the terminal buffer or - standard input was not actually a terminal. - - Note that this will always read from the terminal, even if something - is piped into the standard input. - - .. versionadded:: 2.0 - - :param echo: if set to `True`, the character read will also show up on - the terminal. The default is to not show it. - """ - f = _getchar - if f is None: - from ._termui_impl import getchar as f - return f(echo) - - -def pause(info='Press any key to continue ...', err=False): - """This command stops execution and waits for the user to press any - key to continue. This is similar to the Windows batch "pause" - command. If the program is not run through a terminal, this command - will instead do nothing. - - .. versionadded:: 2.0 - - .. versionadded:: 4.0 - Added the `err` parameter. - - :param info: the info string to print before pausing. - :param err: if set to message goes to ``stderr`` instead of - ``stdout``, the same as with echo. - """ - if not isatty(sys.stdin) or not isatty(sys.stdout): - return - try: - if info: - echo(info, nl=False, err=err) - try: - getchar() - except (KeyboardInterrupt, EOFError): - pass - finally: - if info: - echo(err=err) diff --git a/pyextra/click/testing.py b/pyextra/click/testing.py deleted file mode 100644 index 4416c774136dc9..00000000000000 --- a/pyextra/click/testing.py +++ /dev/null @@ -1,322 +0,0 @@ -import os -import sys -import shutil -import tempfile -import contextlib - -from ._compat import iteritems, PY2 - - -# If someone wants to vendor click, we want to ensure the -# correct package is discovered. Ideally we could use a -# relative import here but unfortunately Python does not -# support that. -clickpkg = sys.modules[__name__.rsplit('.', 1)[0]] - - -if PY2: - from cStringIO import StringIO -else: - import io - from ._compat import _find_binary_reader - - -class EchoingStdin(object): - - def __init__(self, input, output): - self._input = input - self._output = output - - def __getattr__(self, x): - return getattr(self._input, x) - - def _echo(self, rv): - self._output.write(rv) - return rv - - def read(self, n=-1): - return self._echo(self._input.read(n)) - - def readline(self, n=-1): - return self._echo(self._input.readline(n)) - - def readlines(self): - return [self._echo(x) for x in self._input.readlines()] - - def __iter__(self): - return iter(self._echo(x) for x in self._input) - - def __repr__(self): - return repr(self._input) - - -def make_input_stream(input, charset): - # Is already an input stream. - if hasattr(input, 'read'): - if PY2: - return input - rv = _find_binary_reader(input) - if rv is not None: - return rv - raise TypeError('Could not find binary reader for input stream.') - - if input is None: - input = b'' - elif not isinstance(input, bytes): - input = input.encode(charset) - if PY2: - return StringIO(input) - return io.BytesIO(input) - - -class Result(object): - """Holds the captured result of an invoked CLI script.""" - - def __init__(self, runner, output_bytes, exit_code, exception, - exc_info=None): - #: The runner that created the result - self.runner = runner - #: The output as bytes. - self.output_bytes = output_bytes - #: The exit code as integer. - self.exit_code = exit_code - #: The exception that happend if one did. - self.exception = exception - #: The traceback - self.exc_info = exc_info - - @property - def output(self): - """The output as unicode string.""" - return self.output_bytes.decode(self.runner.charset, 'replace') \ - .replace('\r\n', '\n') - - def __repr__(self): - return '' % ( - self.exception and repr(self.exception) or 'okay', - ) - - -class CliRunner(object): - """The CLI runner provides functionality to invoke a Click command line - script for unittesting purposes in a isolated environment. This only - works in single-threaded systems without any concurrency as it changes the - global interpreter state. - - :param charset: the character set for the input and output data. This is - UTF-8 by default and should not be changed currently as - the reporting to Click only works in Python 2 properly. - :param env: a dictionary with environment variables for overriding. - :param echo_stdin: if this is set to `True`, then reading from stdin writes - to stdout. This is useful for showing examples in - some circumstances. Note that regular prompts - will automatically echo the input. - """ - - def __init__(self, charset=None, env=None, echo_stdin=False): - if charset is None: - charset = 'utf-8' - self.charset = charset - self.env = env or {} - self.echo_stdin = echo_stdin - - def get_default_prog_name(self, cli): - """Given a command object it will return the default program name - for it. The default is the `name` attribute or ``"root"`` if not - set. - """ - return cli.name or 'root' - - def make_env(self, overrides=None): - """Returns the environment overrides for invoking a script.""" - rv = dict(self.env) - if overrides: - rv.update(overrides) - return rv - - @contextlib.contextmanager - def isolation(self, input=None, env=None, color=False): - """A context manager that sets up the isolation for invoking of a - command line tool. This sets up stdin with the given input data - and `os.environ` with the overrides from the given dictionary. - This also rebinds some internals in Click to be mocked (like the - prompt functionality). - - This is automatically done in the :meth:`invoke` method. - - .. versionadded:: 4.0 - The ``color`` parameter was added. - - :param input: the input stream to put into sys.stdin. - :param env: the environment overrides as dictionary. - :param color: whether the output should contain color codes. The - application can still override this explicitly. - """ - input = make_input_stream(input, self.charset) - - old_stdin = sys.stdin - old_stdout = sys.stdout - old_stderr = sys.stderr - old_forced_width = clickpkg.formatting.FORCED_WIDTH - clickpkg.formatting.FORCED_WIDTH = 80 - - env = self.make_env(env) - - if PY2: - sys.stdout = sys.stderr = bytes_output = StringIO() - if self.echo_stdin: - input = EchoingStdin(input, bytes_output) - else: - bytes_output = io.BytesIO() - if self.echo_stdin: - input = EchoingStdin(input, bytes_output) - input = io.TextIOWrapper(input, encoding=self.charset) - sys.stdout = sys.stderr = io.TextIOWrapper( - bytes_output, encoding=self.charset) - - sys.stdin = input - - def visible_input(prompt=None): - sys.stdout.write(prompt or '') - val = input.readline().rstrip('\r\n') - sys.stdout.write(val + '\n') - sys.stdout.flush() - return val - - def hidden_input(prompt=None): - sys.stdout.write((prompt or '') + '\n') - sys.stdout.flush() - return input.readline().rstrip('\r\n') - - def _getchar(echo): - char = sys.stdin.read(1) - if echo: - sys.stdout.write(char) - sys.stdout.flush() - return char - - default_color = color - def should_strip_ansi(stream=None, color=None): - if color is None: - return not default_color - return not color - - old_visible_prompt_func = clickpkg.termui.visible_prompt_func - old_hidden_prompt_func = clickpkg.termui.hidden_prompt_func - old__getchar_func = clickpkg.termui._getchar - old_should_strip_ansi = clickpkg.utils.should_strip_ansi - clickpkg.termui.visible_prompt_func = visible_input - clickpkg.termui.hidden_prompt_func = hidden_input - clickpkg.termui._getchar = _getchar - clickpkg.utils.should_strip_ansi = should_strip_ansi - - old_env = {} - try: - for key, value in iteritems(env): - old_env[key] = os.environ.get(key) - if value is None: - try: - del os.environ[key] - except Exception: - pass - else: - os.environ[key] = value - yield bytes_output - finally: - for key, value in iteritems(old_env): - if value is None: - try: - del os.environ[key] - except Exception: - pass - else: - os.environ[key] = value - sys.stdout = old_stdout - sys.stderr = old_stderr - sys.stdin = old_stdin - clickpkg.termui.visible_prompt_func = old_visible_prompt_func - clickpkg.termui.hidden_prompt_func = old_hidden_prompt_func - clickpkg.termui._getchar = old__getchar_func - clickpkg.utils.should_strip_ansi = old_should_strip_ansi - clickpkg.formatting.FORCED_WIDTH = old_forced_width - - def invoke(self, cli, args=None, input=None, env=None, - catch_exceptions=True, color=False, **extra): - """Invokes a command in an isolated environment. The arguments are - forwarded directly to the command line script, the `extra` keyword - arguments are passed to the :meth:`~clickpkg.Command.main` function of - the command. - - This returns a :class:`Result` object. - - .. versionadded:: 3.0 - The ``catch_exceptions`` parameter was added. - - .. versionchanged:: 3.0 - The result object now has an `exc_info` attribute with the - traceback if available. - - .. versionadded:: 4.0 - The ``color`` parameter was added. - - :param cli: the command to invoke - :param args: the arguments to invoke - :param input: the input data for `sys.stdin`. - :param env: the environment overrides. - :param catch_exceptions: Whether to catch any other exceptions than - ``SystemExit``. - :param extra: the keyword arguments to pass to :meth:`main`. - :param color: whether the output should contain color codes. The - application can still override this explicitly. - """ - exc_info = None - with self.isolation(input=input, env=env, color=color) as out: - exception = None - exit_code = 0 - - try: - cli.main(args=args or (), - prog_name=self.get_default_prog_name(cli), **extra) - except SystemExit as e: - if e.code != 0: - exception = e - - exc_info = sys.exc_info() - - exit_code = e.code - if not isinstance(exit_code, int): - sys.stdout.write(str(exit_code)) - sys.stdout.write('\n') - exit_code = 1 - except Exception as e: - if not catch_exceptions: - raise - exception = e - exit_code = -1 - exc_info = sys.exc_info() - finally: - sys.stdout.flush() - output = out.getvalue() - - return Result(runner=self, - output_bytes=output, - exit_code=exit_code, - exception=exception, - exc_info=exc_info) - - @contextlib.contextmanager - def isolated_filesystem(self): - """A context manager that creates a temporary folder and changes - the current working directory to it for isolated filesystem tests. - """ - cwd = os.getcwd() - t = tempfile.mkdtemp() - os.chdir(t) - try: - yield t - finally: - os.chdir(cwd) - try: - shutil.rmtree(t) - except (OSError, IOError): - pass diff --git a/pyextra/click/types.py b/pyextra/click/types.py deleted file mode 100644 index 36390026dcd178..00000000000000 --- a/pyextra/click/types.py +++ /dev/null @@ -1,550 +0,0 @@ -import os -import stat - -from ._compat import open_stream, text_type, filename_to_ui, \ - get_filesystem_encoding, get_streerror, _get_argv_encoding, PY2 -from .exceptions import BadParameter -from .utils import safecall, LazyFile - - -class ParamType(object): - """Helper for converting values through types. The following is - necessary for a valid type: - - * it needs a name - * it needs to pass through None unchanged - * it needs to convert from a string - * it needs to convert its result type through unchanged - (eg: needs to be idempotent) - * it needs to be able to deal with param and context being `None`. - This can be the case when the object is used with prompt - inputs. - """ - is_composite = False - - #: the descriptive name of this type - name = None - - #: if a list of this type is expected and the value is pulled from a - #: string environment variable, this is what splits it up. `None` - #: means any whitespace. For all parameters the general rule is that - #: whitespace splits them up. The exception are paths and files which - #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on - #: Windows). - envvar_list_splitter = None - - def __call__(self, value, param=None, ctx=None): - if value is not None: - return self.convert(value, param, ctx) - - def get_metavar(self, param): - """Returns the metavar default for this param if it provides one.""" - - def get_missing_message(self, param): - """Optionally might return extra information about a missing - parameter. - - .. versionadded:: 2.0 - """ - - def convert(self, value, param, ctx): - """Converts the value. This is not invoked for values that are - `None` (the missing value). - """ - return value - - def split_envvar_value(self, rv): - """Given a value from an environment variable this splits it up - into small chunks depending on the defined envvar list splitter. - - If the splitter is set to `None`, which means that whitespace splits, - then leading and trailing whitespace is ignored. Otherwise, leading - and trailing splitters usually lead to empty items being included. - """ - return (rv or '').split(self.envvar_list_splitter) - - def fail(self, message, param=None, ctx=None): - """Helper method to fail with an invalid value message.""" - raise BadParameter(message, ctx=ctx, param=param) - - -class CompositeParamType(ParamType): - is_composite = True - - @property - def arity(self): - raise NotImplementedError() - - -class FuncParamType(ParamType): - - def __init__(self, func): - self.name = func.__name__ - self.func = func - - def convert(self, value, param, ctx): - try: - return self.func(value) - except ValueError: - try: - value = text_type(value) - except UnicodeError: - value = str(value).decode('utf-8', 'replace') - self.fail(value, param, ctx) - - -class UnprocessedParamType(ParamType): - name = 'text' - - def convert(self, value, param, ctx): - return value - - def __repr__(self): - return 'UNPROCESSED' - - -class StringParamType(ParamType): - name = 'text' - - def convert(self, value, param, ctx): - if isinstance(value, bytes): - enc = _get_argv_encoding() - try: - value = value.decode(enc) - except UnicodeError: - fs_enc = get_filesystem_encoding() - if fs_enc != enc: - try: - value = value.decode(fs_enc) - except UnicodeError: - value = value.decode('utf-8', 'replace') - return value - return value - - def __repr__(self): - return 'STRING' - - -class Choice(ParamType): - """The choice type allows a value to be checked against a fixed set of - supported values. All of these values have to be strings. - - See :ref:`choice-opts` for an example. - """ - name = 'choice' - - def __init__(self, choices): - self.choices = choices - - def get_metavar(self, param): - return '[%s]' % '|'.join(self.choices) - - def get_missing_message(self, param): - return 'Choose from %s.' % ', '.join(self.choices) - - def convert(self, value, param, ctx): - # Exact match - if value in self.choices: - return value - - # Match through normalization - if ctx is not None and \ - ctx.token_normalize_func is not None: - value = ctx.token_normalize_func(value) - for choice in self.choices: - if ctx.token_normalize_func(choice) == value: - return choice - - self.fail('invalid choice: %s. (choose from %s)' % - (value, ', '.join(self.choices)), param, ctx) - - def __repr__(self): - return 'Choice(%r)' % list(self.choices) - - -class IntParamType(ParamType): - name = 'integer' - - def convert(self, value, param, ctx): - try: - return int(value) - except (ValueError, UnicodeError): - self.fail('%s is not a valid integer' % value, param, ctx) - - def __repr__(self): - return 'INT' - - -class IntRange(IntParamType): - """A parameter that works similar to :data:`click.INT` but restricts - the value to fit into a range. The default behavior is to fail if the - value falls outside the range, but it can also be silently clamped - between the two edges. - - See :ref:`ranges` for an example. - """ - name = 'integer range' - - def __init__(self, min=None, max=None, clamp=False): - self.min = min - self.max = max - self.clamp = clamp - - def convert(self, value, param, ctx): - rv = IntParamType.convert(self, value, param, ctx) - if self.clamp: - if self.min is not None and rv < self.min: - return self.min - if self.max is not None and rv > self.max: - return self.max - if self.min is not None and rv < self.min or \ - self.max is not None and rv > self.max: - if self.min is None: - self.fail('%s is bigger than the maximum valid value ' - '%s.' % (rv, self.max), param, ctx) - elif self.max is None: - self.fail('%s is smaller than the minimum valid value ' - '%s.' % (rv, self.min), param, ctx) - else: - self.fail('%s is not in the valid range of %s to %s.' - % (rv, self.min, self.max), param, ctx) - return rv - - def __repr__(self): - return 'IntRange(%r, %r)' % (self.min, self.max) - - -class BoolParamType(ParamType): - name = 'boolean' - - def convert(self, value, param, ctx): - if isinstance(value, bool): - return bool(value) - value = value.lower() - if value in ('true', '1', 'yes', 'y'): - return True - elif value in ('false', '0', 'no', 'n'): - return False - self.fail('%s is not a valid boolean' % value, param, ctx) - - def __repr__(self): - return 'BOOL' - - -class FloatParamType(ParamType): - name = 'float' - - def convert(self, value, param, ctx): - try: - return float(value) - except (UnicodeError, ValueError): - self.fail('%s is not a valid floating point value' % - value, param, ctx) - - def __repr__(self): - return 'FLOAT' - - -class UUIDParameterType(ParamType): - name = 'uuid' - - def convert(self, value, param, ctx): - import uuid - try: - if PY2 and isinstance(value, text_type): - value = value.encode('ascii') - return uuid.UUID(value) - except (UnicodeError, ValueError): - self.fail('%s is not a valid UUID value' % value, param, ctx) - - def __repr__(self): - return 'UUID' - - -class File(ParamType): - """Declares a parameter to be a file for reading or writing. The file - is automatically closed once the context tears down (after the command - finished working). - - Files can be opened for reading or writing. The special value ``-`` - indicates stdin or stdout depending on the mode. - - By default, the file is opened for reading text data, but it can also be - opened in binary mode or for writing. The encoding parameter can be used - to force a specific encoding. - - The `lazy` flag controls if the file should be opened immediately or - upon first IO. The default is to be non lazy for standard input and - output streams as well as files opened for reading, lazy otherwise. - - Starting with Click 2.0, files can also be opened atomically in which - case all writes go into a separate file in the same folder and upon - completion the file will be moved over to the original location. This - is useful if a file regularly read by other users is modified. - - See :ref:`file-args` for more information. - """ - name = 'filename' - envvar_list_splitter = os.path.pathsep - - def __init__(self, mode='r', encoding=None, errors='strict', lazy=None, - atomic=False): - self.mode = mode - self.encoding = encoding - self.errors = errors - self.lazy = lazy - self.atomic = atomic - - def resolve_lazy_flag(self, value): - if self.lazy is not None: - return self.lazy - if value == '-': - return False - elif 'w' in self.mode: - return True - return False - - def convert(self, value, param, ctx): - try: - if hasattr(value, 'read') or hasattr(value, 'write'): - return value - - lazy = self.resolve_lazy_flag(value) - - if lazy: - f = LazyFile(value, self.mode, self.encoding, self.errors, - atomic=self.atomic) - if ctx is not None: - ctx.call_on_close(f.close_intelligently) - return f - - f, should_close = open_stream(value, self.mode, - self.encoding, self.errors, - atomic=self.atomic) - # If a context is provided, we automatically close the file - # at the end of the context execution (or flush out). If a - # context does not exist, it's the caller's responsibility to - # properly close the file. This for instance happens when the - # type is used with prompts. - if ctx is not None: - if should_close: - ctx.call_on_close(safecall(f.close)) - else: - ctx.call_on_close(safecall(f.flush)) - return f - except (IOError, OSError) as e: - self.fail('Could not open file: %s: %s' % ( - filename_to_ui(value), - get_streerror(e), - ), param, ctx) - - -class Path(ParamType): - """The path type is similar to the :class:`File` type but it performs - different checks. First of all, instead of returning an open file - handle it returns just the filename. Secondly, it can perform various - basic checks about what the file or directory should be. - - .. versionchanged:: 6.0 - `allow_dash` was added. - - :param exists: if set to true, the file or directory needs to exist for - this value to be valid. If this is not required and a - file does indeed not exist, then all further checks are - silently skipped. - :param file_okay: controls if a file is a possible value. - :param dir_okay: controls if a directory is a possible value. - :param writable: if true, a writable check is performed. - :param readable: if true, a readable check is performed. - :param resolve_path: if this is true, then the path is fully resolved - before the value is passed onwards. This means - that it's absolute and symlinks are resolved. - :param allow_dash: If this is set to `True`, a single dash to indicate - standard streams is permitted. - :param type: optionally a string type that should be used to - represent the path. The default is `None` which - means the return value will be either bytes or - unicode depending on what makes most sense given the - input data Click deals with. - """ - envvar_list_splitter = os.path.pathsep - - def __init__(self, exists=False, file_okay=True, dir_okay=True, - writable=False, readable=True, resolve_path=False, - allow_dash=False, path_type=None): - self.exists = exists - self.file_okay = file_okay - self.dir_okay = dir_okay - self.writable = writable - self.readable = readable - self.resolve_path = resolve_path - self.allow_dash = allow_dash - self.type = path_type - - if self.file_okay and not self.dir_okay: - self.name = 'file' - self.path_type = 'File' - if self.dir_okay and not self.file_okay: - self.name = 'directory' - self.path_type = 'Directory' - else: - self.name = 'path' - self.path_type = 'Path' - - def coerce_path_result(self, rv): - if self.type is not None and not isinstance(rv, self.type): - if self.type is text_type: - rv = rv.decode(get_filesystem_encoding()) - else: - rv = rv.encode(get_filesystem_encoding()) - return rv - - def convert(self, value, param, ctx): - rv = value - - is_dash = self.file_okay and self.allow_dash and rv in (b'-', '-') - - if not is_dash: - if self.resolve_path: - rv = os.path.realpath(rv) - - try: - st = os.stat(rv) - except OSError: - if not self.exists: - return self.coerce_path_result(rv) - self.fail('%s "%s" does not exist.' % ( - self.path_type, - filename_to_ui(value) - ), param, ctx) - - if not self.file_okay and stat.S_ISREG(st.st_mode): - self.fail('%s "%s" is a file.' % ( - self.path_type, - filename_to_ui(value) - ), param, ctx) - if not self.dir_okay and stat.S_ISDIR(st.st_mode): - self.fail('%s "%s" is a directory.' % ( - self.path_type, - filename_to_ui(value) - ), param, ctx) - if self.writable and not os.access(value, os.W_OK): - self.fail('%s "%s" is not writable.' % ( - self.path_type, - filename_to_ui(value) - ), param, ctx) - if self.readable and not os.access(value, os.R_OK): - self.fail('%s "%s" is not readable.' % ( - self.path_type, - filename_to_ui(value) - ), param, ctx) - - return self.coerce_path_result(rv) - - -class Tuple(CompositeParamType): - """The default behavior of Click is to apply a type on a value directly. - This works well in most cases, except for when `nargs` is set to a fixed - count and different types should be used for different items. In this - case the :class:`Tuple` type can be used. This type can only be used - if `nargs` is set to a fixed number. - - For more information see :ref:`tuple-type`. - - This can be selected by using a Python tuple literal as a type. - - :param types: a list of types that should be used for the tuple items. - """ - - def __init__(self, types): - self.types = [convert_type(ty) for ty in types] - - @property - def name(self): - return "<" + " ".join(ty.name for ty in self.types) + ">" - - @property - def arity(self): - return len(self.types) - - def convert(self, value, param, ctx): - if len(value) != len(self.types): - raise TypeError('It would appear that nargs is set to conflict ' - 'with the composite type arity.') - return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value)) - - -def convert_type(ty, default=None): - """Converts a callable or python ty into the most appropriate param - ty. - """ - guessed_type = False - if ty is None and default is not None: - if isinstance(default, tuple): - ty = tuple(map(type, default)) - else: - ty = type(default) - guessed_type = True - - if isinstance(ty, tuple): - return Tuple(ty) - if isinstance(ty, ParamType): - return ty - if ty is text_type or ty is str or ty is None: - return STRING - if ty is int: - return INT - # Booleans are only okay if not guessed. This is done because for - # flags the default value is actually a bit of a lie in that it - # indicates which of the flags is the one we want. See get_default() - # for more information. - if ty is bool and not guessed_type: - return BOOL - if ty is float: - return FLOAT - if guessed_type: - return STRING - - # Catch a common mistake - if __debug__: - try: - if issubclass(ty, ParamType): - raise AssertionError('Attempted to use an uninstantiated ' - 'parameter type (%s).' % ty) - except TypeError: - pass - return FuncParamType(ty) - - -#: A dummy parameter type that just does nothing. From a user's -#: perspective this appears to just be the same as `STRING` but internally -#: no string conversion takes place. This is necessary to achieve the -#: same bytes/unicode behavior on Python 2/3 in situations where you want -#: to not convert argument types. This is usually useful when working -#: with file paths as they can appear in bytes and unicode. -#: -#: For path related uses the :class:`Path` type is a better choice but -#: there are situations where an unprocessed type is useful which is why -#: it is is provided. -#: -#: .. versionadded:: 4.0 -UNPROCESSED = UnprocessedParamType() - -#: A unicode string parameter type which is the implicit default. This -#: can also be selected by using ``str`` as type. -STRING = StringParamType() - -#: An integer parameter. This can also be selected by using ``int`` as -#: type. -INT = IntParamType() - -#: A floating point value parameter. This can also be selected by using -#: ``float`` as type. -FLOAT = FloatParamType() - -#: A boolean parameter. This is the default for boolean flags. This can -#: also be selected by using ``bool`` as a type. -BOOL = BoolParamType() - -#: A UUID parameter. -UUID = UUIDParameterType() diff --git a/pyextra/click/utils.py b/pyextra/click/utils.py deleted file mode 100644 index eee626d3fd0153..00000000000000 --- a/pyextra/click/utils.py +++ /dev/null @@ -1,415 +0,0 @@ -import os -import sys - -from .globals import resolve_color_default - -from ._compat import text_type, open_stream, get_filesystem_encoding, \ - get_streerror, string_types, PY2, binary_streams, text_streams, \ - filename_to_ui, auto_wrap_for_ansi, strip_ansi, should_strip_ansi, \ - _default_text_stdout, _default_text_stderr, is_bytes, WIN - -if not PY2: - from ._compat import _find_binary_writer -elif WIN: - from ._winconsole import _get_windows_argv, \ - _hash_py_argv, _initial_argv_hash - - -echo_native_types = string_types + (bytes, bytearray) - - -def _posixify(name): - return '-'.join(name.split()).lower() - - -def safecall(func): - """Wraps a function so that it swallows exceptions.""" - def wrapper(*args, **kwargs): - try: - return func(*args, **kwargs) - except Exception: - pass - return wrapper - - -def make_str(value): - """Converts a value into a valid string.""" - if isinstance(value, bytes): - try: - return value.decode(get_filesystem_encoding()) - except UnicodeError: - return value.decode('utf-8', 'replace') - return text_type(value) - - -def make_default_short_help(help, max_length=45): - words = help.split() - total_length = 0 - result = [] - done = False - - for word in words: - if word[-1:] == '.': - done = True - new_length = result and 1 + len(word) or len(word) - if total_length + new_length > max_length: - result.append('...') - done = True - else: - if result: - result.append(' ') - result.append(word) - if done: - break - total_length += new_length - - return ''.join(result) - - -class LazyFile(object): - """A lazy file works like a regular file but it does not fully open - the file but it does perform some basic checks early to see if the - filename parameter does make sense. This is useful for safely opening - files for writing. - """ - - def __init__(self, filename, mode='r', encoding=None, errors='strict', - atomic=False): - self.name = filename - self.mode = mode - self.encoding = encoding - self.errors = errors - self.atomic = atomic - - if filename == '-': - self._f, self.should_close = open_stream(filename, mode, - encoding, errors) - else: - if 'r' in mode: - # Open and close the file in case we're opening it for - # reading so that we can catch at least some errors in - # some cases early. - open(filename, mode).close() - self._f = None - self.should_close = True - - def __getattr__(self, name): - return getattr(self.open(), name) - - def __repr__(self): - if self._f is not None: - return repr(self._f) - return '' % (self.name, self.mode) - - def open(self): - """Opens the file if it's not yet open. This call might fail with - a :exc:`FileError`. Not handling this error will produce an error - that Click shows. - """ - if self._f is not None: - return self._f - try: - rv, self.should_close = open_stream(self.name, self.mode, - self.encoding, - self.errors, - atomic=self.atomic) - except (IOError, OSError) as e: - from .exceptions import FileError - raise FileError(self.name, hint=get_streerror(e)) - self._f = rv - return rv - - def close(self): - """Closes the underlying file, no matter what.""" - if self._f is not None: - self._f.close() - - def close_intelligently(self): - """This function only closes the file if it was opened by the lazy - file wrapper. For instance this will never close stdin. - """ - if self.should_close: - self.close() - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, tb): - self.close_intelligently() - - def __iter__(self): - self.open() - return iter(self._f) - - -class KeepOpenFile(object): - - def __init__(self, file): - self._file = file - - def __getattr__(self, name): - return getattr(self._file, name) - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, tb): - pass - - def __repr__(self): - return repr(self._file) - - def __iter__(self): - return iter(self._file) - - -def echo(message=None, file=None, nl=True, err=False, color=None): - """Prints a message plus a newline to the given file or stdout. On - first sight, this looks like the print function, but it has improved - support for handling Unicode and binary data that does not fail no - matter how badly configured the system is. - - Primarily it means that you can print binary data as well as Unicode - data on both 2.x and 3.x to the given file in the most appropriate way - possible. This is a very carefree function as in that it will try its - best to not fail. As of Click 6.0 this includes support for unicode - output on the Windows console. - - In addition to that, if `colorama`_ is installed, the echo function will - also support clever handling of ANSI codes. Essentially it will then - do the following: - - - add transparent handling of ANSI color codes on Windows. - - hide ANSI codes automatically if the destination file is not a - terminal. - - .. _colorama: http://pypi.python.org/pypi/colorama - - .. versionchanged:: 6.0 - As of Click 6.0 the echo function will properly support unicode - output on the windows console. Not that click does not modify - the interpreter in any way which means that `sys.stdout` or the - print statement or function will still not provide unicode support. - - .. versionchanged:: 2.0 - Starting with version 2.0 of Click, the echo function will work - with colorama if it's installed. - - .. versionadded:: 3.0 - The `err` parameter was added. - - .. versionchanged:: 4.0 - Added the `color` flag. - - :param message: the message to print - :param file: the file to write to (defaults to ``stdout``) - :param err: if set to true the file defaults to ``stderr`` instead of - ``stdout``. This is faster and easier than calling - :func:`get_text_stderr` yourself. - :param nl: if set to `True` (the default) a newline is printed afterwards. - :param color: controls if the terminal supports ANSI colors or not. The - default is autodetection. - """ - if file is None: - if err: - file = _default_text_stderr() - else: - file = _default_text_stdout() - - # Convert non bytes/text into the native string type. - if message is not None and not isinstance(message, echo_native_types): - message = text_type(message) - - if nl: - message = message or u'' - if isinstance(message, text_type): - message += u'\n' - else: - message += b'\n' - - # If there is a message, and we're in Python 3, and the value looks - # like bytes, we manually need to find the binary stream and write the - # message in there. This is done separately so that most stream - # types will work as you would expect. Eg: you can write to StringIO - # for other cases. - if message and not PY2 and is_bytes(message): - binary_file = _find_binary_writer(file) - if binary_file is not None: - file.flush() - binary_file.write(message) - binary_file.flush() - return - - # ANSI-style support. If there is no message or we are dealing with - # bytes nothing is happening. If we are connected to a file we want - # to strip colors. If we are on windows we either wrap the stream - # to strip the color or we use the colorama support to translate the - # ansi codes to API calls. - if message and not is_bytes(message): - color = resolve_color_default(color) - if should_strip_ansi(file, color): - message = strip_ansi(message) - elif WIN: - if auto_wrap_for_ansi is not None: - file = auto_wrap_for_ansi(file) - elif not color: - message = strip_ansi(message) - - if message: - file.write(message) - file.flush() - - -def get_binary_stream(name): - """Returns a system stream for byte processing. This essentially - returns the stream from the sys module with the given name but it - solves some compatibility issues between different Python versions. - Primarily this function is necessary for getting binary streams on - Python 3. - - :param name: the name of the stream to open. Valid names are ``'stdin'``, - ``'stdout'`` and ``'stderr'`` - """ - opener = binary_streams.get(name) - if opener is None: - raise TypeError('Unknown standard stream %r' % name) - return opener() - - -def get_text_stream(name, encoding=None, errors='strict'): - """Returns a system stream for text processing. This usually returns - a wrapped stream around a binary stream returned from - :func:`get_binary_stream` but it also can take shortcuts on Python 3 - for already correctly configured streams. - - :param name: the name of the stream to open. Valid names are ``'stdin'``, - ``'stdout'`` and ``'stderr'`` - :param encoding: overrides the detected default encoding. - :param errors: overrides the default error mode. - """ - opener = text_streams.get(name) - if opener is None: - raise TypeError('Unknown standard stream %r' % name) - return opener(encoding, errors) - - -def open_file(filename, mode='r', encoding=None, errors='strict', - lazy=False, atomic=False): - """This is similar to how the :class:`File` works but for manual - usage. Files are opened non lazy by default. This can open regular - files as well as stdin/stdout if ``'-'`` is passed. - - If stdin/stdout is returned the stream is wrapped so that the context - manager will not close the stream accidentally. This makes it possible - to always use the function like this without having to worry to - accidentally close a standard stream:: - - with open_file(filename) as f: - ... - - .. versionadded:: 3.0 - - :param filename: the name of the file to open (or ``'-'`` for stdin/stdout). - :param mode: the mode in which to open the file. - :param encoding: the encoding to use. - :param errors: the error handling for this file. - :param lazy: can be flipped to true to open the file lazily. - :param atomic: in atomic mode writes go into a temporary file and it's - moved on close. - """ - if lazy: - return LazyFile(filename, mode, encoding, errors, atomic=atomic) - f, should_close = open_stream(filename, mode, encoding, errors, - atomic=atomic) - if not should_close: - f = KeepOpenFile(f) - return f - - -def get_os_args(): - """This returns the argument part of sys.argv in the most appropriate - form for processing. What this means is that this return value is in - a format that works for Click to process but does not necessarily - correspond well to what's actually standard for the interpreter. - - On most environments the return value is ``sys.argv[:1]`` unchanged. - However if you are on Windows and running Python 2 the return value - will actually be a list of unicode strings instead because the - default behavior on that platform otherwise will not be able to - carry all possible values that sys.argv can have. - - .. versionadded:: 6.0 - """ - # We can only extract the unicode argv if sys.argv has not been - # changed since the startup of the application. - if PY2 and WIN and _initial_argv_hash == _hash_py_argv(): - return _get_windows_argv() - return sys.argv[1:] - - -def format_filename(filename, shorten=False): - """Formats a filename for user display. The main purpose of this - function is to ensure that the filename can be displayed at all. This - will decode the filename to unicode if necessary in a way that it will - not fail. Optionally, it can shorten the filename to not include the - full path to the filename. - - :param filename: formats a filename for UI display. This will also convert - the filename into unicode without failing. - :param shorten: this optionally shortens the filename to strip of the - path that leads up to it. - """ - if shorten: - filename = os.path.basename(filename) - return filename_to_ui(filename) - - -def get_app_dir(app_name, roaming=True, force_posix=False): - r"""Returns the config folder for the application. The default behavior - is to return whatever is most appropriate for the operating system. - - To give you an idea, for an app called ``"Foo Bar"``, something like - the following folders could be returned: - - Mac OS X: - ``~/Library/Application Support/Foo Bar`` - Mac OS X (POSIX): - ``~/.foo-bar`` - Unix: - ``~/.config/foo-bar`` - Unix (POSIX): - ``~/.foo-bar`` - Win XP (roaming): - ``C:\Documents and Settings\\Local Settings\Application Data\Foo Bar`` - Win XP (not roaming): - ``C:\Documents and Settings\\Application Data\Foo Bar`` - Win 7 (roaming): - ``C:\Users\\AppData\Roaming\Foo Bar`` - Win 7 (not roaming): - ``C:\Users\\AppData\Local\Foo Bar`` - - .. versionadded:: 2.0 - - :param app_name: the application name. This should be properly capitalized - and can contain whitespace. - :param roaming: controls if the folder should be roaming or not on Windows. - Has no affect otherwise. - :param force_posix: if this is set to `True` then on any POSIX system the - folder will be stored in the home folder with a leading - dot instead of the XDG config home or darwin's - application support folder. - """ - if WIN: - key = roaming and 'APPDATA' or 'LOCALAPPDATA' - folder = os.environ.get(key) - if folder is None: - folder = os.path.expanduser('~') - return os.path.join(folder, app_name) - if force_posix: - return os.path.join(os.path.expanduser('~/.' + _posixify(app_name))) - if sys.platform == 'darwin': - return os.path.join(os.path.expanduser( - '~/Library/Application Support'), app_name) - return os.path.join( - os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config')), - _posixify(app_name)) diff --git a/pyextra/flask/__init__.py b/pyextra/flask/__init__.py deleted file mode 100644 index ded19822400ad7..00000000000000 --- a/pyextra/flask/__init__.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask - ~~~~~ - - A microframework based on Werkzeug. It's extensively documented - and follows best practice patterns. - - :copyright: © 2010 by the Pallets team. - :license: BSD, see LICENSE for more details. -""" - -__version__ = '1.0.2' - -# utilities we import from Werkzeug and Jinja2 that are unused -# in the module but are exported as public interface. -from werkzeug.exceptions import abort -from werkzeug.utils import redirect -from jinja2 import Markup, escape - -from .app import Flask, Request, Response -from .config import Config -from .helpers import url_for, flash, send_file, send_from_directory, \ - get_flashed_messages, get_template_attribute, make_response, safe_join, \ - stream_with_context -from .globals import current_app, g, request, session, _request_ctx_stack, \ - _app_ctx_stack -from .ctx import has_request_context, has_app_context, \ - after_this_request, copy_current_request_context -from .blueprints import Blueprint -from .templating import render_template, render_template_string - -# the signals -from .signals import signals_available, template_rendered, request_started, \ - request_finished, got_request_exception, request_tearing_down, \ - appcontext_tearing_down, appcontext_pushed, \ - appcontext_popped, message_flashed, before_render_template - -# We're not exposing the actual json module but a convenient wrapper around -# it. -from . import json - -# This was the only thing that Flask used to export at one point and it had -# a more generic name. -jsonify = json.jsonify - -# backwards compat, goes away in 1.0 -from .sessions import SecureCookieSession as Session -json_available = True diff --git a/pyextra/flask/__main__.py b/pyextra/flask/__main__.py deleted file mode 100644 index 4aee654374633d..00000000000000 --- a/pyextra/flask/__main__.py +++ /dev/null @@ -1,14 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.__main__ - ~~~~~~~~~~~~~~ - - Alias for flask.run for the command line. - - :copyright: © 2010 by the Pallets team. - :license: BSD, see LICENSE for more details. -""" - -if __name__ == '__main__': - from .cli import main - main(as_module=True) diff --git a/pyextra/flask/_compat.py b/pyextra/flask/_compat.py deleted file mode 100644 index a3b5b9c1c9ade6..00000000000000 --- a/pyextra/flask/_compat.py +++ /dev/null @@ -1,99 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask._compat - ~~~~~~~~~~~~~ - - Some py2/py3 compatibility support based on a stripped down - version of six so we don't have to depend on a specific version - of it. - - :copyright: © 2010 by the Pallets team. - :license: BSD, see LICENSE for more details. -""" - -import sys - -PY2 = sys.version_info[0] == 2 -_identity = lambda x: x - - -if not PY2: - text_type = str - string_types = (str,) - integer_types = (int,) - - iterkeys = lambda d: iter(d.keys()) - itervalues = lambda d: iter(d.values()) - iteritems = lambda d: iter(d.items()) - - from inspect import getfullargspec as getargspec - from io import StringIO - - def reraise(tp, value, tb=None): - if value.__traceback__ is not tb: - raise value.with_traceback(tb) - raise value - - implements_to_string = _identity - -else: - text_type = unicode - string_types = (str, unicode) - integer_types = (int, long) - - iterkeys = lambda d: d.iterkeys() - itervalues = lambda d: d.itervalues() - iteritems = lambda d: d.iteritems() - - from inspect import getargspec - from cStringIO import StringIO - - exec('def reraise(tp, value, tb=None):\n raise tp, value, tb') - - def implements_to_string(cls): - cls.__unicode__ = cls.__str__ - cls.__str__ = lambda x: x.__unicode__().encode('utf-8') - return cls - - -def with_metaclass(meta, *bases): - """Create a base class with a metaclass.""" - # This requires a bit of explanation: the basic idea is to make a - # dummy metaclass for one level of class instantiation that replaces - # itself with the actual metaclass. - class metaclass(type): - def __new__(cls, name, this_bases, d): - return meta(name, bases, d) - return type.__new__(metaclass, 'temporary_class', (), {}) - - -# Certain versions of pypy have a bug where clearing the exception stack -# breaks the __exit__ function in a very peculiar way. The second level of -# exception blocks is necessary because pypy seems to forget to check if an -# exception happened until the next bytecode instruction? -# -# Relevant PyPy bugfix commit: -# https://bitbucket.org/pypy/pypy/commits/77ecf91c635a287e88e60d8ddb0f4e9df4003301 -# According to ronan on #pypy IRC, it is released in PyPy2 2.3 and later -# versions. -# -# Ubuntu 14.04 has PyPy 2.2.1, which does exhibit this bug. -BROKEN_PYPY_CTXMGR_EXIT = False -if hasattr(sys, 'pypy_version_info'): - class _Mgr(object): - def __enter__(self): - return self - def __exit__(self, *args): - if hasattr(sys, 'exc_clear'): - # Python 3 (PyPy3) doesn't have exc_clear - sys.exc_clear() - try: - try: - with _Mgr(): - raise AssertionError() - except: - raise - except TypeError: - BROKEN_PYPY_CTXMGR_EXIT = True - except AssertionError: - pass diff --git a/pyextra/flask/app.py b/pyextra/flask/app.py deleted file mode 100644 index 87c5900348b5a2..00000000000000 --- a/pyextra/flask/app.py +++ /dev/null @@ -1,2315 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.app - ~~~~~~~~~ - - This module implements the central WSGI application object. - - :copyright: © 2010 by the Pallets team. - :license: BSD, see LICENSE for more details. -""" - -import os -import sys -import warnings -from datetime import timedelta -from functools import update_wrapper -from itertools import chain -from threading import Lock - -from werkzeug.datastructures import Headers, ImmutableDict -from werkzeug.exceptions import BadRequest, BadRequestKeyError, HTTPException, \ - InternalServerError, MethodNotAllowed, default_exceptions -from werkzeug.routing import BuildError, Map, RequestRedirect, Rule - -from . import cli, json -from ._compat import integer_types, reraise, string_types, text_type -from .config import Config, ConfigAttribute -from .ctx import AppContext, RequestContext, _AppCtxGlobals -from .globals import _request_ctx_stack, g, request, session -from .helpers import ( - _PackageBoundObject, - _endpoint_from_view_func, find_package, get_env, get_debug_flag, - get_flashed_messages, locked_cached_property, url_for, get_load_dotenv -) -from .logging import create_logger -from .sessions import SecureCookieSessionInterface -from .signals import appcontext_tearing_down, got_request_exception, \ - request_finished, request_started, request_tearing_down -from .templating import DispatchingJinjaLoader, Environment, \ - _default_template_ctx_processor -from .wrappers import Request, Response - -# a singleton sentinel value for parameter defaults -_sentinel = object() - - -def _make_timedelta(value): - if not isinstance(value, timedelta): - return timedelta(seconds=value) - return value - - -def setupmethod(f): - """Wraps a method so that it performs a check in debug mode if the - first request was already handled. - """ - def wrapper_func(self, *args, **kwargs): - if self.debug and self._got_first_request: - raise AssertionError('A setup function was called after the ' - 'first request was handled. This usually indicates a bug ' - 'in the application where a module was not imported ' - 'and decorators or other functionality was called too late.\n' - 'To fix this make sure to import all your view modules, ' - 'database models and everything related at a central place ' - 'before the application starts serving requests.') - return f(self, *args, **kwargs) - return update_wrapper(wrapper_func, f) - - -class Flask(_PackageBoundObject): - """The flask object implements a WSGI application and acts as the central - object. It is passed the name of the module or package of the - application. Once it is created it will act as a central registry for - the view functions, the URL rules, template configuration and much more. - - The name of the package is used to resolve resources from inside the - package or the folder the module is contained in depending on if the - package parameter resolves to an actual python package (a folder with - an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file). - - For more information about resource loading, see :func:`open_resource`. - - Usually you create a :class:`Flask` instance in your main module or - in the :file:`__init__.py` file of your package like this:: - - from flask import Flask - app = Flask(__name__) - - .. admonition:: About the First Parameter - - The idea of the first parameter is to give Flask an idea of what - belongs to your application. This name is used to find resources - on the filesystem, can be used by extensions to improve debugging - information and a lot more. - - So it's important what you provide there. If you are using a single - module, `__name__` is always the correct value. If you however are - using a package, it's usually recommended to hardcode the name of - your package there. - - For example if your application is defined in :file:`yourapplication/app.py` - you should create it with one of the two versions below:: - - app = Flask('yourapplication') - app = Flask(__name__.split('.')[0]) - - Why is that? The application will work even with `__name__`, thanks - to how resources are looked up. However it will make debugging more - painful. Certain extensions can make assumptions based on the - import name of your application. For example the Flask-SQLAlchemy - extension will look for the code in your application that triggered - an SQL query in debug mode. If the import name is not properly set - up, that debugging information is lost. (For example it would only - pick up SQL queries in `yourapplication.app` and not - `yourapplication.views.frontend`) - - .. versionadded:: 0.7 - The `static_url_path`, `static_folder`, and `template_folder` - parameters were added. - - .. versionadded:: 0.8 - The `instance_path` and `instance_relative_config` parameters were - added. - - .. versionadded:: 0.11 - The `root_path` parameter was added. - - .. versionadded:: 1.0 - The ``host_matching`` and ``static_host`` parameters were added. - - .. versionadded:: 1.0 - The ``subdomain_matching`` parameter was added. Subdomain - matching needs to be enabled manually now. Setting - :data:`SERVER_NAME` does not implicitly enable it. - - :param import_name: the name of the application package - :param static_url_path: can be used to specify a different path for the - static files on the web. Defaults to the name - of the `static_folder` folder. - :param static_folder: the folder with static files that should be served - at `static_url_path`. Defaults to the ``'static'`` - folder in the root path of the application. - :param static_host: the host to use when adding the static route. - Defaults to None. Required when using ``host_matching=True`` - with a ``static_folder`` configured. - :param host_matching: set ``url_map.host_matching`` attribute. - Defaults to False. - :param subdomain_matching: consider the subdomain relative to - :data:`SERVER_NAME` when matching routes. Defaults to False. - :param template_folder: the folder that contains the templates that should - be used by the application. Defaults to - ``'templates'`` folder in the root path of the - application. - :param instance_path: An alternative instance path for the application. - By default the folder ``'instance'`` next to the - package or module is assumed to be the instance - path. - :param instance_relative_config: if set to ``True`` relative filenames - for loading the config are assumed to - be relative to the instance path instead - of the application root. - :param root_path: Flask by default will automatically calculate the path - to the root of the application. In certain situations - this cannot be achieved (for instance if the package - is a Python 3 namespace package) and needs to be - manually defined. - """ - - #: The class that is used for request objects. See :class:`~flask.Request` - #: for more information. - request_class = Request - - #: The class that is used for response objects. See - #: :class:`~flask.Response` for more information. - response_class = Response - - #: The class that is used for the Jinja environment. - #: - #: .. versionadded:: 0.11 - jinja_environment = Environment - - #: The class that is used for the :data:`~flask.g` instance. - #: - #: Example use cases for a custom class: - #: - #: 1. Store arbitrary attributes on flask.g. - #: 2. Add a property for lazy per-request database connectors. - #: 3. Return None instead of AttributeError on unexpected attributes. - #: 4. Raise exception if an unexpected attr is set, a "controlled" flask.g. - #: - #: In Flask 0.9 this property was called `request_globals_class` but it - #: was changed in 0.10 to :attr:`app_ctx_globals_class` because the - #: flask.g object is now application context scoped. - #: - #: .. versionadded:: 0.10 - app_ctx_globals_class = _AppCtxGlobals - - #: The class that is used for the ``config`` attribute of this app. - #: Defaults to :class:`~flask.Config`. - #: - #: Example use cases for a custom class: - #: - #: 1. Default values for certain config options. - #: 2. Access to config values through attributes in addition to keys. - #: - #: .. versionadded:: 0.11 - config_class = Config - - #: The testing flag. Set this to ``True`` to enable the test mode of - #: Flask extensions (and in the future probably also Flask itself). - #: For example this might activate test helpers that have an - #: additional runtime cost which should not be enabled by default. - #: - #: If this is enabled and PROPAGATE_EXCEPTIONS is not changed from the - #: default it's implicitly enabled. - #: - #: This attribute can also be configured from the config with the - #: ``TESTING`` configuration key. Defaults to ``False``. - testing = ConfigAttribute('TESTING') - - #: If a secret key is set, cryptographic components can use this to - #: sign cookies and other things. Set this to a complex random value - #: when you want to use the secure cookie for instance. - #: - #: This attribute can also be configured from the config with the - #: :data:`SECRET_KEY` configuration key. Defaults to ``None``. - secret_key = ConfigAttribute('SECRET_KEY') - - #: The secure cookie uses this for the name of the session cookie. - #: - #: This attribute can also be configured from the config with the - #: ``SESSION_COOKIE_NAME`` configuration key. Defaults to ``'session'`` - session_cookie_name = ConfigAttribute('SESSION_COOKIE_NAME') - - #: A :class:`~datetime.timedelta` which is used to set the expiration - #: date of a permanent session. The default is 31 days which makes a - #: permanent session survive for roughly one month. - #: - #: This attribute can also be configured from the config with the - #: ``PERMANENT_SESSION_LIFETIME`` configuration key. Defaults to - #: ``timedelta(days=31)`` - permanent_session_lifetime = ConfigAttribute('PERMANENT_SESSION_LIFETIME', - get_converter=_make_timedelta) - - #: A :class:`~datetime.timedelta` which is used as default cache_timeout - #: for the :func:`send_file` functions. The default is 12 hours. - #: - #: This attribute can also be configured from the config with the - #: ``SEND_FILE_MAX_AGE_DEFAULT`` configuration key. This configuration - #: variable can also be set with an integer value used as seconds. - #: Defaults to ``timedelta(hours=12)`` - send_file_max_age_default = ConfigAttribute('SEND_FILE_MAX_AGE_DEFAULT', - get_converter=_make_timedelta) - - #: Enable this if you want to use the X-Sendfile feature. Keep in - #: mind that the server has to support this. This only affects files - #: sent with the :func:`send_file` method. - #: - #: .. versionadded:: 0.2 - #: - #: This attribute can also be configured from the config with the - #: ``USE_X_SENDFILE`` configuration key. Defaults to ``False``. - use_x_sendfile = ConfigAttribute('USE_X_SENDFILE') - - #: The JSON encoder class to use. Defaults to :class:`~flask.json.JSONEncoder`. - #: - #: .. versionadded:: 0.10 - json_encoder = json.JSONEncoder - - #: The JSON decoder class to use. Defaults to :class:`~flask.json.JSONDecoder`. - #: - #: .. versionadded:: 0.10 - json_decoder = json.JSONDecoder - - #: Options that are passed directly to the Jinja2 environment. - jinja_options = ImmutableDict( - extensions=['jinja2.ext.autoescape', 'jinja2.ext.with_'] - ) - - #: Default configuration parameters. - default_config = ImmutableDict({ - 'ENV': None, - 'DEBUG': None, - 'TESTING': False, - 'PROPAGATE_EXCEPTIONS': None, - 'PRESERVE_CONTEXT_ON_EXCEPTION': None, - 'SECRET_KEY': None, - 'PERMANENT_SESSION_LIFETIME': timedelta(days=31), - 'USE_X_SENDFILE': False, - 'SERVER_NAME': None, - 'APPLICATION_ROOT': '/', - 'SESSION_COOKIE_NAME': 'session', - 'SESSION_COOKIE_DOMAIN': None, - 'SESSION_COOKIE_PATH': None, - 'SESSION_COOKIE_HTTPONLY': True, - 'SESSION_COOKIE_SECURE': False, - 'SESSION_COOKIE_SAMESITE': None, - 'SESSION_REFRESH_EACH_REQUEST': True, - 'MAX_CONTENT_LENGTH': None, - 'SEND_FILE_MAX_AGE_DEFAULT': timedelta(hours=12), - 'TRAP_BAD_REQUEST_ERRORS': None, - 'TRAP_HTTP_EXCEPTIONS': False, - 'EXPLAIN_TEMPLATE_LOADING': False, - 'PREFERRED_URL_SCHEME': 'http', - 'JSON_AS_ASCII': True, - 'JSON_SORT_KEYS': True, - 'JSONIFY_PRETTYPRINT_REGULAR': False, - 'JSONIFY_MIMETYPE': 'application/json', - 'TEMPLATES_AUTO_RELOAD': None, - 'MAX_COOKIE_SIZE': 4093, - }) - - #: The rule object to use for URL rules created. This is used by - #: :meth:`add_url_rule`. Defaults to :class:`werkzeug.routing.Rule`. - #: - #: .. versionadded:: 0.7 - url_rule_class = Rule - - #: the test client that is used with when `test_client` is used. - #: - #: .. versionadded:: 0.7 - test_client_class = None - - #: The :class:`~click.testing.CliRunner` subclass, by default - #: :class:`~flask.testing.FlaskCliRunner` that is used by - #: :meth:`test_cli_runner`. Its ``__init__`` method should take a - #: Flask app object as the first argument. - #: - #: .. versionadded:: 1.0 - test_cli_runner_class = None - - #: the session interface to use. By default an instance of - #: :class:`~flask.sessions.SecureCookieSessionInterface` is used here. - #: - #: .. versionadded:: 0.8 - session_interface = SecureCookieSessionInterface() - - # TODO remove the next three attrs when Sphinx :inherited-members: works - # https://github.com/sphinx-doc/sphinx/issues/741 - - #: The name of the package or module that this app belongs to. Do not - #: change this once it is set by the constructor. - import_name = None - - #: Location of the template files to be added to the template lookup. - #: ``None`` if templates should not be added. - template_folder = None - - #: Absolute path to the package on the filesystem. Used to look up - #: resources contained in the package. - root_path = None - - def __init__( - self, - import_name, - static_url_path=None, - static_folder='static', - static_host=None, - host_matching=False, - subdomain_matching=False, - template_folder='templates', - instance_path=None, - instance_relative_config=False, - root_path=None - ): - _PackageBoundObject.__init__( - self, - import_name, - template_folder=template_folder, - root_path=root_path - ) - - if static_url_path is not None: - self.static_url_path = static_url_path - - if static_folder is not None: - self.static_folder = static_folder - - if instance_path is None: - instance_path = self.auto_find_instance_path() - elif not os.path.isabs(instance_path): - raise ValueError( - 'If an instance path is provided it must be absolute.' - ' A relative path was given instead.' - ) - - #: Holds the path to the instance folder. - #: - #: .. versionadded:: 0.8 - self.instance_path = instance_path - - #: The configuration dictionary as :class:`Config`. This behaves - #: exactly like a regular dictionary but supports additional methods - #: to load a config from files. - self.config = self.make_config(instance_relative_config) - - #: A dictionary of all view functions registered. The keys will - #: be function names which are also used to generate URLs and - #: the values are the function objects themselves. - #: To register a view function, use the :meth:`route` decorator. - self.view_functions = {} - - #: A dictionary of all registered error handlers. The key is ``None`` - #: for error handlers active on the application, otherwise the key is - #: the name of the blueprint. Each key points to another dictionary - #: where the key is the status code of the http exception. The - #: special key ``None`` points to a list of tuples where the first item - #: is the class for the instance check and the second the error handler - #: function. - #: - #: To register an error handler, use the :meth:`errorhandler` - #: decorator. - self.error_handler_spec = {} - - #: A list of functions that are called when :meth:`url_for` raises a - #: :exc:`~werkzeug.routing.BuildError`. Each function registered here - #: is called with `error`, `endpoint` and `values`. If a function - #: returns ``None`` or raises a :exc:`BuildError` the next function is - #: tried. - #: - #: .. versionadded:: 0.9 - self.url_build_error_handlers = [] - - #: A dictionary with lists of functions that will be called at the - #: beginning of each request. The key of the dictionary is the name of - #: the blueprint this function is active for, or ``None`` for all - #: requests. To register a function, use the :meth:`before_request` - #: decorator. - self.before_request_funcs = {} - - #: A list of functions that will be called at the beginning of the - #: first request to this instance. To register a function, use the - #: :meth:`before_first_request` decorator. - #: - #: .. versionadded:: 0.8 - self.before_first_request_funcs = [] - - #: A dictionary with lists of functions that should be called after - #: each request. The key of the dictionary is the name of the blueprint - #: this function is active for, ``None`` for all requests. This can for - #: example be used to close database connections. To register a function - #: here, use the :meth:`after_request` decorator. - self.after_request_funcs = {} - - #: A dictionary with lists of functions that are called after - #: each request, even if an exception has occurred. The key of the - #: dictionary is the name of the blueprint this function is active for, - #: ``None`` for all requests. These functions are not allowed to modify - #: the request, and their return values are ignored. If an exception - #: occurred while processing the request, it gets passed to each - #: teardown_request function. To register a function here, use the - #: :meth:`teardown_request` decorator. - #: - #: .. versionadded:: 0.7 - self.teardown_request_funcs = {} - - #: A list of functions that are called when the application context - #: is destroyed. Since the application context is also torn down - #: if the request ends this is the place to store code that disconnects - #: from databases. - #: - #: .. versionadded:: 0.9 - self.teardown_appcontext_funcs = [] - - #: A dictionary with lists of functions that are called before the - #: :attr:`before_request_funcs` functions. The key of the dictionary is - #: the name of the blueprint this function is active for, or ``None`` - #: for all requests. To register a function, use - #: :meth:`url_value_preprocessor`. - #: - #: .. versionadded:: 0.7 - self.url_value_preprocessors = {} - - #: A dictionary with lists of functions that can be used as URL value - #: preprocessors. The key ``None`` here is used for application wide - #: callbacks, otherwise the key is the name of the blueprint. - #: Each of these functions has the chance to modify the dictionary - #: of URL values before they are used as the keyword arguments of the - #: view function. For each function registered this one should also - #: provide a :meth:`url_defaults` function that adds the parameters - #: automatically again that were removed that way. - #: - #: .. versionadded:: 0.7 - self.url_default_functions = {} - - #: A dictionary with list of functions that are called without argument - #: to populate the template context. The key of the dictionary is the - #: name of the blueprint this function is active for, ``None`` for all - #: requests. Each returns a dictionary that the template context is - #: updated with. To register a function here, use the - #: :meth:`context_processor` decorator. - self.template_context_processors = { - None: [_default_template_ctx_processor] - } - - #: A list of shell context processor functions that should be run - #: when a shell context is created. - #: - #: .. versionadded:: 0.11 - self.shell_context_processors = [] - - #: all the attached blueprints in a dictionary by name. Blueprints - #: can be attached multiple times so this dictionary does not tell - #: you how often they got attached. - #: - #: .. versionadded:: 0.7 - self.blueprints = {} - self._blueprint_order = [] - - #: a place where extensions can store application specific state. For - #: example this is where an extension could store database engines and - #: similar things. For backwards compatibility extensions should register - #: themselves like this:: - #: - #: if not hasattr(app, 'extensions'): - #: app.extensions = {} - #: app.extensions['extensionname'] = SomeObject() - #: - #: The key must match the name of the extension module. For example in - #: case of a "Flask-Foo" extension in `flask_foo`, the key would be - #: ``'foo'``. - #: - #: .. versionadded:: 0.7 - self.extensions = {} - - #: The :class:`~werkzeug.routing.Map` for this instance. You can use - #: this to change the routing converters after the class was created - #: but before any routes are connected. Example:: - #: - #: from werkzeug.routing import BaseConverter - #: - #: class ListConverter(BaseConverter): - #: def to_python(self, value): - #: return value.split(',') - #: def to_url(self, values): - #: return ','.join(super(ListConverter, self).to_url(value) - #: for value in values) - #: - #: app = Flask(__name__) - #: app.url_map.converters['list'] = ListConverter - self.url_map = Map() - - self.url_map.host_matching = host_matching - self.subdomain_matching = subdomain_matching - - # tracks internally if the application already handled at least one - # request. - self._got_first_request = False - self._before_request_lock = Lock() - - # Add a static route using the provided static_url_path, static_host, - # and static_folder if there is a configured static_folder. - # Note we do this without checking if static_folder exists. - # For one, it might be created while the server is running (e.g. during - # development). Also, Google App Engine stores static files somewhere - if self.has_static_folder: - assert bool(static_host) == host_matching, 'Invalid static_host/host_matching combination' - self.add_url_rule( - self.static_url_path + '/', - endpoint='static', - host=static_host, - view_func=self.send_static_file - ) - - #: The click command line context for this application. Commands - #: registered here show up in the :command:`flask` command once the - #: application has been discovered. The default commands are - #: provided by Flask itself and can be overridden. - #: - #: This is an instance of a :class:`click.Group` object. - self.cli = cli.AppGroup(self.name) - - @locked_cached_property - def name(self): - """The name of the application. This is usually the import name - with the difference that it's guessed from the run file if the - import name is main. This name is used as a display name when - Flask needs the name of the application. It can be set and overridden - to change the value. - - .. versionadded:: 0.8 - """ - if self.import_name == '__main__': - fn = getattr(sys.modules['__main__'], '__file__', None) - if fn is None: - return '__main__' - return os.path.splitext(os.path.basename(fn))[0] - return self.import_name - - @property - def propagate_exceptions(self): - """Returns the value of the ``PROPAGATE_EXCEPTIONS`` configuration - value in case it's set, otherwise a sensible default is returned. - - .. versionadded:: 0.7 - """ - rv = self.config['PROPAGATE_EXCEPTIONS'] - if rv is not None: - return rv - return self.testing or self.debug - - @property - def preserve_context_on_exception(self): - """Returns the value of the ``PRESERVE_CONTEXT_ON_EXCEPTION`` - configuration value in case it's set, otherwise a sensible default - is returned. - - .. versionadded:: 0.7 - """ - rv = self.config['PRESERVE_CONTEXT_ON_EXCEPTION'] - if rv is not None: - return rv - return self.debug - - @locked_cached_property - def logger(self): - """The ``'flask.app'`` logger, a standard Python - :class:`~logging.Logger`. - - In debug mode, the logger's :attr:`~logging.Logger.level` will be set - to :data:`~logging.DEBUG`. - - If there are no handlers configured, a default handler will be added. - See :ref:`logging` for more information. - - .. versionchanged:: 1.0 - Behavior was simplified. The logger is always named - ``flask.app``. The level is only set during configuration, it - doesn't check ``app.debug`` each time. Only one format is used, - not different ones depending on ``app.debug``. No handlers are - removed, and a handler is only added if no handlers are already - configured. - - .. versionadded:: 0.3 - """ - return create_logger(self) - - @locked_cached_property - def jinja_env(self): - """The Jinja2 environment used to load templates.""" - return self.create_jinja_environment() - - @property - def got_first_request(self): - """This attribute is set to ``True`` if the application started - handling the first request. - - .. versionadded:: 0.8 - """ - return self._got_first_request - - def make_config(self, instance_relative=False): - """Used to create the config attribute by the Flask constructor. - The `instance_relative` parameter is passed in from the constructor - of Flask (there named `instance_relative_config`) and indicates if - the config should be relative to the instance path or the root path - of the application. - - .. versionadded:: 0.8 - """ - root_path = self.root_path - if instance_relative: - root_path = self.instance_path - defaults = dict(self.default_config) - defaults['ENV'] = get_env() - defaults['DEBUG'] = get_debug_flag() - return self.config_class(root_path, defaults) - - def auto_find_instance_path(self): - """Tries to locate the instance path if it was not provided to the - constructor of the application class. It will basically calculate - the path to a folder named ``instance`` next to your main file or - the package. - - .. versionadded:: 0.8 - """ - prefix, package_path = find_package(self.import_name) - if prefix is None: - return os.path.join(package_path, 'instance') - return os.path.join(prefix, 'var', self.name + '-instance') - - def open_instance_resource(self, resource, mode='rb'): - """Opens a resource from the application's instance folder - (:attr:`instance_path`). Otherwise works like - :meth:`open_resource`. Instance resources can also be opened for - writing. - - :param resource: the name of the resource. To access resources within - subfolders use forward slashes as separator. - :param mode: resource file opening mode, default is 'rb'. - """ - return open(os.path.join(self.instance_path, resource), mode) - - def _get_templates_auto_reload(self): - """Reload templates when they are changed. Used by - :meth:`create_jinja_environment`. - - This attribute can be configured with :data:`TEMPLATES_AUTO_RELOAD`. If - not set, it will be enabled in debug mode. - - .. versionadded:: 1.0 - This property was added but the underlying config and behavior - already existed. - """ - rv = self.config['TEMPLATES_AUTO_RELOAD'] - return rv if rv is not None else self.debug - - def _set_templates_auto_reload(self, value): - self.config['TEMPLATES_AUTO_RELOAD'] = value - - templates_auto_reload = property( - _get_templates_auto_reload, _set_templates_auto_reload - ) - del _get_templates_auto_reload, _set_templates_auto_reload - - def create_jinja_environment(self): - """Creates the Jinja2 environment based on :attr:`jinja_options` - and :meth:`select_jinja_autoescape`. Since 0.7 this also adds - the Jinja2 globals and filters after initialization. Override - this function to customize the behavior. - - .. versionadded:: 0.5 - .. versionchanged:: 0.11 - ``Environment.auto_reload`` set in accordance with - ``TEMPLATES_AUTO_RELOAD`` configuration option. - """ - options = dict(self.jinja_options) - - if 'autoescape' not in options: - options['autoescape'] = self.select_jinja_autoescape - - if 'auto_reload' not in options: - options['auto_reload'] = self.templates_auto_reload - - rv = self.jinja_environment(self, **options) - rv.globals.update( - url_for=url_for, - get_flashed_messages=get_flashed_messages, - config=self.config, - # request, session and g are normally added with the - # context processor for efficiency reasons but for imported - # templates we also want the proxies in there. - request=request, - session=session, - g=g - ) - rv.filters['tojson'] = json.tojson_filter - return rv - - def create_global_jinja_loader(self): - """Creates the loader for the Jinja2 environment. Can be used to - override just the loader and keeping the rest unchanged. It's - discouraged to override this function. Instead one should override - the :meth:`jinja_loader` function instead. - - The global loader dispatches between the loaders of the application - and the individual blueprints. - - .. versionadded:: 0.7 - """ - return DispatchingJinjaLoader(self) - - def select_jinja_autoescape(self, filename): - """Returns ``True`` if autoescaping should be active for the given - template name. If no template name is given, returns `True`. - - .. versionadded:: 0.5 - """ - if filename is None: - return True - return filename.endswith(('.html', '.htm', '.xml', '.xhtml')) - - def update_template_context(self, context): - """Update the template context with some commonly used variables. - This injects request, session, config and g into the template - context as well as everything template context processors want - to inject. Note that the as of Flask 0.6, the original values - in the context will not be overridden if a context processor - decides to return a value with the same key. - - :param context: the context as a dictionary that is updated in place - to add extra variables. - """ - funcs = self.template_context_processors[None] - reqctx = _request_ctx_stack.top - if reqctx is not None: - bp = reqctx.request.blueprint - if bp is not None and bp in self.template_context_processors: - funcs = chain(funcs, self.template_context_processors[bp]) - orig_ctx = context.copy() - for func in funcs: - context.update(func()) - # make sure the original values win. This makes it possible to - # easier add new variables in context processors without breaking - # existing views. - context.update(orig_ctx) - - def make_shell_context(self): - """Returns the shell context for an interactive shell for this - application. This runs all the registered shell context - processors. - - .. versionadded:: 0.11 - """ - rv = {'app': self, 'g': g} - for processor in self.shell_context_processors: - rv.update(processor()) - return rv - - #: What environment the app is running in. Flask and extensions may - #: enable behaviors based on the environment, such as enabling debug - #: mode. This maps to the :data:`ENV` config key. This is set by the - #: :envvar:`FLASK_ENV` environment variable and may not behave as - #: expected if set in code. - #: - #: **Do not enable development when deploying in production.** - #: - #: Default: ``'production'`` - env = ConfigAttribute('ENV') - - def _get_debug(self): - return self.config['DEBUG'] - - def _set_debug(self, value): - self.config['DEBUG'] = value - self.jinja_env.auto_reload = self.templates_auto_reload - - #: Whether debug mode is enabled. When using ``flask run`` to start - #: the development server, an interactive debugger will be shown for - #: unhandled exceptions, and the server will be reloaded when code - #: changes. This maps to the :data:`DEBUG` config key. This is - #: enabled when :attr:`env` is ``'development'`` and is overridden - #: by the ``FLASK_DEBUG`` environment variable. It may not behave as - #: expected if set in code. - #: - #: **Do not enable debug mode when deploying in production.** - #: - #: Default: ``True`` if :attr:`env` is ``'development'``, or - #: ``False`` otherwise. - debug = property(_get_debug, _set_debug) - del _get_debug, _set_debug - - def run(self, host=None, port=None, debug=None, - load_dotenv=True, **options): - """Runs the application on a local development server. - - Do not use ``run()`` in a production setting. It is not intended to - meet security and performance requirements for a production server. - Instead, see :ref:`deployment` for WSGI server recommendations. - - If the :attr:`debug` flag is set the server will automatically reload - for code changes and show a debugger in case an exception happened. - - If you want to run the application in debug mode, but disable the - code execution on the interactive debugger, you can pass - ``use_evalex=False`` as parameter. This will keep the debugger's - traceback screen active, but disable code execution. - - It is not recommended to use this function for development with - automatic reloading as this is badly supported. Instead you should - be using the :command:`flask` command line script's ``run`` support. - - .. admonition:: Keep in Mind - - Flask will suppress any server error with a generic error page - unless it is in debug mode. As such to enable just the - interactive debugger without the code reloading, you have to - invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``. - Setting ``use_debugger`` to ``True`` without being in debug mode - won't catch any exceptions because there won't be any to - catch. - - :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to - have the server available externally as well. Defaults to - ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable - if present. - :param port: the port of the webserver. Defaults to ``5000`` or the - port defined in the ``SERVER_NAME`` config variable if present. - :param debug: if given, enable or disable debug mode. See - :attr:`debug`. - :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` - files to set environment variables. Will also change the working - directory to the directory containing the first file found. - :param options: the options to be forwarded to the underlying Werkzeug - server. See :func:`werkzeug.serving.run_simple` for more - information. - - .. versionchanged:: 1.0 - If installed, python-dotenv will be used to load environment - variables from :file:`.env` and :file:`.flaskenv` files. - - If set, the :envvar:`FLASK_ENV` and :envvar:`FLASK_DEBUG` - environment variables will override :attr:`env` and - :attr:`debug`. - - Threaded mode is enabled by default. - - .. versionchanged:: 0.10 - The default port is now picked from the ``SERVER_NAME`` - variable. - """ - # Change this into a no-op if the server is invoked from the - # command line. Have a look at cli.py for more information. - if os.environ.get('FLASK_RUN_FROM_CLI') == 'true': - from .debughelpers import explain_ignored_app_run - explain_ignored_app_run() - return - - if get_load_dotenv(load_dotenv): - cli.load_dotenv() - - # if set, let env vars override previous values - if 'FLASK_ENV' in os.environ: - self.env = get_env() - self.debug = get_debug_flag() - elif 'FLASK_DEBUG' in os.environ: - self.debug = get_debug_flag() - - # debug passed to method overrides all other sources - if debug is not None: - self.debug = bool(debug) - - _host = '127.0.0.1' - _port = 5000 - server_name = self.config.get('SERVER_NAME') - sn_host, sn_port = None, None - - if server_name: - sn_host, _, sn_port = server_name.partition(':') - - host = host or sn_host or _host - port = int(port or sn_port or _port) - - options.setdefault('use_reloader', self.debug) - options.setdefault('use_debugger', self.debug) - options.setdefault('threaded', True) - - cli.show_server_banner(self.env, self.debug, self.name, False) - - from werkzeug.serving import run_simple - - try: - run_simple(host, port, self, **options) - finally: - # reset the first request information if the development server - # reset normally. This makes it possible to restart the server - # without reloader and that stuff from an interactive shell. - self._got_first_request = False - - def test_client(self, use_cookies=True, **kwargs): - """Creates a test client for this application. For information - about unit testing head over to :ref:`testing`. - - Note that if you are testing for assertions or exceptions in your - application code, you must set ``app.testing = True`` in order for the - exceptions to propagate to the test client. Otherwise, the exception - will be handled by the application (not visible to the test client) and - the only indication of an AssertionError or other exception will be a - 500 status code response to the test client. See the :attr:`testing` - attribute. For example:: - - app.testing = True - client = app.test_client() - - The test client can be used in a ``with`` block to defer the closing down - of the context until the end of the ``with`` block. This is useful if - you want to access the context locals for testing:: - - with app.test_client() as c: - rv = c.get('/?vodka=42') - assert request.args['vodka'] == '42' - - Additionally, you may pass optional keyword arguments that will then - be passed to the application's :attr:`test_client_class` constructor. - For example:: - - from flask.testing import FlaskClient - - class CustomClient(FlaskClient): - def __init__(self, *args, **kwargs): - self._authentication = kwargs.pop("authentication") - super(CustomClient,self).__init__( *args, **kwargs) - - app.test_client_class = CustomClient - client = app.test_client(authentication='Basic ....') - - See :class:`~flask.testing.FlaskClient` for more information. - - .. versionchanged:: 0.4 - added support for ``with`` block usage for the client. - - .. versionadded:: 0.7 - The `use_cookies` parameter was added as well as the ability - to override the client to be used by setting the - :attr:`test_client_class` attribute. - - .. versionchanged:: 0.11 - Added `**kwargs` to support passing additional keyword arguments to - the constructor of :attr:`test_client_class`. - """ - cls = self.test_client_class - if cls is None: - from flask.testing import FlaskClient as cls - return cls(self, self.response_class, use_cookies=use_cookies, **kwargs) - - def test_cli_runner(self, **kwargs): - """Create a CLI runner for testing CLI commands. - See :ref:`testing-cli`. - - Returns an instance of :attr:`test_cli_runner_class`, by default - :class:`~flask.testing.FlaskCliRunner`. The Flask app object is - passed as the first argument. - - .. versionadded:: 1.0 - """ - cls = self.test_cli_runner_class - - if cls is None: - from flask.testing import FlaskCliRunner as cls - - return cls(self, **kwargs) - - def open_session(self, request): - """Creates or opens a new session. Default implementation stores all - session data in a signed cookie. This requires that the - :attr:`secret_key` is set. Instead of overriding this method - we recommend replacing the :class:`session_interface`. - - .. deprecated: 1.0 - Will be removed in 1.1. Use ``session_interface.open_session`` - instead. - - :param request: an instance of :attr:`request_class`. - """ - - warnings.warn(DeprecationWarning( - '"open_session" is deprecated and will be removed in 1.1. Use' - ' "session_interface.open_session" instead.' - )) - return self.session_interface.open_session(self, request) - - def save_session(self, session, response): - """Saves the session if it needs updates. For the default - implementation, check :meth:`open_session`. Instead of overriding this - method we recommend replacing the :class:`session_interface`. - - .. deprecated: 1.0 - Will be removed in 1.1. Use ``session_interface.save_session`` - instead. - - :param session: the session to be saved (a - :class:`~werkzeug.contrib.securecookie.SecureCookie` - object) - :param response: an instance of :attr:`response_class` - """ - - warnings.warn(DeprecationWarning( - '"save_session" is deprecated and will be removed in 1.1. Use' - ' "session_interface.save_session" instead.' - )) - return self.session_interface.save_session(self, session, response) - - def make_null_session(self): - """Creates a new instance of a missing session. Instead of overriding - this method we recommend replacing the :class:`session_interface`. - - .. deprecated: 1.0 - Will be removed in 1.1. Use ``session_interface.make_null_session`` - instead. - - .. versionadded:: 0.7 - """ - - warnings.warn(DeprecationWarning( - '"make_null_session" is deprecated and will be removed in 1.1. Use' - ' "session_interface.make_null_session" instead.' - )) - return self.session_interface.make_null_session(self) - - @setupmethod - def register_blueprint(self, blueprint, **options): - """Register a :class:`~flask.Blueprint` on the application. Keyword - arguments passed to this method will override the defaults set on the - blueprint. - - Calls the blueprint's :meth:`~flask.Blueprint.register` method after - recording the blueprint in the application's :attr:`blueprints`. - - :param blueprint: The blueprint to register. - :param url_prefix: Blueprint routes will be prefixed with this. - :param subdomain: Blueprint routes will match on this subdomain. - :param url_defaults: Blueprint routes will use these default values for - view arguments. - :param options: Additional keyword arguments are passed to - :class:`~flask.blueprints.BlueprintSetupState`. They can be - accessed in :meth:`~flask.Blueprint.record` callbacks. - - .. versionadded:: 0.7 - """ - first_registration = False - - if blueprint.name in self.blueprints: - assert self.blueprints[blueprint.name] is blueprint, ( - 'A name collision occurred between blueprints %r and %r. Both' - ' share the same name "%s". Blueprints that are created on the' - ' fly need unique names.' % ( - blueprint, self.blueprints[blueprint.name], blueprint.name - ) - ) - else: - self.blueprints[blueprint.name] = blueprint - self._blueprint_order.append(blueprint) - first_registration = True - - blueprint.register(self, options, first_registration) - - def iter_blueprints(self): - """Iterates over all blueprints by the order they were registered. - - .. versionadded:: 0.11 - """ - return iter(self._blueprint_order) - - @setupmethod - def add_url_rule(self, rule, endpoint=None, view_func=None, - provide_automatic_options=None, **options): - """Connects a URL rule. Works exactly like the :meth:`route` - decorator. If a view_func is provided it will be registered with the - endpoint. - - Basically this example:: - - @app.route('/') - def index(): - pass - - Is equivalent to the following:: - - def index(): - pass - app.add_url_rule('/', 'index', index) - - If the view_func is not provided you will need to connect the endpoint - to a view function like so:: - - app.view_functions['index'] = index - - Internally :meth:`route` invokes :meth:`add_url_rule` so if you want - to customize the behavior via subclassing you only need to change - this method. - - For more information refer to :ref:`url-route-registrations`. - - .. versionchanged:: 0.2 - `view_func` parameter added. - - .. versionchanged:: 0.6 - ``OPTIONS`` is added automatically as method. - - :param rule: the URL rule as string - :param endpoint: the endpoint for the registered URL rule. Flask - itself assumes the name of the view function as - endpoint - :param view_func: the function to call when serving a request to the - provided endpoint - :param provide_automatic_options: controls whether the ``OPTIONS`` - method should be added automatically. This can also be controlled - by setting the ``view_func.provide_automatic_options = False`` - before adding the rule. - :param options: the options to be forwarded to the underlying - :class:`~werkzeug.routing.Rule` object. A change - to Werkzeug is handling of method options. methods - is a list of methods this rule should be limited - to (``GET``, ``POST`` etc.). By default a rule - just listens for ``GET`` (and implicitly ``HEAD``). - Starting with Flask 0.6, ``OPTIONS`` is implicitly - added and handled by the standard request handling. - """ - if endpoint is None: - endpoint = _endpoint_from_view_func(view_func) - options['endpoint'] = endpoint - methods = options.pop('methods', None) - - # if the methods are not given and the view_func object knows its - # methods we can use that instead. If neither exists, we go with - # a tuple of only ``GET`` as default. - if methods is None: - methods = getattr(view_func, 'methods', None) or ('GET',) - if isinstance(methods, string_types): - raise TypeError('Allowed methods have to be iterables of strings, ' - 'for example: @app.route(..., methods=["POST"])') - methods = set(item.upper() for item in methods) - - # Methods that should always be added - required_methods = set(getattr(view_func, 'required_methods', ())) - - # starting with Flask 0.8 the view_func object can disable and - # force-enable the automatic options handling. - if provide_automatic_options is None: - provide_automatic_options = getattr(view_func, - 'provide_automatic_options', None) - - if provide_automatic_options is None: - if 'OPTIONS' not in methods: - provide_automatic_options = True - required_methods.add('OPTIONS') - else: - provide_automatic_options = False - - # Add the required methods now. - methods |= required_methods - - rule = self.url_rule_class(rule, methods=methods, **options) - rule.provide_automatic_options = provide_automatic_options - - self.url_map.add(rule) - if view_func is not None: - old_func = self.view_functions.get(endpoint) - if old_func is not None and old_func != view_func: - raise AssertionError('View function mapping is overwriting an ' - 'existing endpoint function: %s' % endpoint) - self.view_functions[endpoint] = view_func - - def route(self, rule, **options): - """A decorator that is used to register a view function for a - given URL rule. This does the same thing as :meth:`add_url_rule` - but is intended for decorator usage:: - - @app.route('/') - def index(): - return 'Hello World' - - For more information refer to :ref:`url-route-registrations`. - - :param rule: the URL rule as string - :param endpoint: the endpoint for the registered URL rule. Flask - itself assumes the name of the view function as - endpoint - :param options: the options to be forwarded to the underlying - :class:`~werkzeug.routing.Rule` object. A change - to Werkzeug is handling of method options. methods - is a list of methods this rule should be limited - to (``GET``, ``POST`` etc.). By default a rule - just listens for ``GET`` (and implicitly ``HEAD``). - Starting with Flask 0.6, ``OPTIONS`` is implicitly - added and handled by the standard request handling. - """ - def decorator(f): - endpoint = options.pop('endpoint', None) - self.add_url_rule(rule, endpoint, f, **options) - return f - return decorator - - @setupmethod - def endpoint(self, endpoint): - """A decorator to register a function as an endpoint. - Example:: - - @app.endpoint('example.endpoint') - def example(): - return "example" - - :param endpoint: the name of the endpoint - """ - def decorator(f): - self.view_functions[endpoint] = f - return f - return decorator - - @staticmethod - def _get_exc_class_and_code(exc_class_or_code): - """Ensure that we register only exceptions as handler keys""" - if isinstance(exc_class_or_code, integer_types): - exc_class = default_exceptions[exc_class_or_code] - else: - exc_class = exc_class_or_code - - assert issubclass(exc_class, Exception) - - if issubclass(exc_class, HTTPException): - return exc_class, exc_class.code - else: - return exc_class, None - - @setupmethod - def errorhandler(self, code_or_exception): - """Register a function to handle errors by code or exception class. - - A decorator that is used to register a function given an - error code. Example:: - - @app.errorhandler(404) - def page_not_found(error): - return 'This page does not exist', 404 - - You can also register handlers for arbitrary exceptions:: - - @app.errorhandler(DatabaseError) - def special_exception_handler(error): - return 'Database connection failed', 500 - - .. versionadded:: 0.7 - Use :meth:`register_error_handler` instead of modifying - :attr:`error_handler_spec` directly, for application wide error - handlers. - - .. versionadded:: 0.7 - One can now additionally also register custom exception types - that do not necessarily have to be a subclass of the - :class:`~werkzeug.exceptions.HTTPException` class. - - :param code_or_exception: the code as integer for the handler, or - an arbitrary exception - """ - def decorator(f): - self._register_error_handler(None, code_or_exception, f) - return f - return decorator - - @setupmethod - def register_error_handler(self, code_or_exception, f): - """Alternative error attach function to the :meth:`errorhandler` - decorator that is more straightforward to use for non decorator - usage. - - .. versionadded:: 0.7 - """ - self._register_error_handler(None, code_or_exception, f) - - @setupmethod - def _register_error_handler(self, key, code_or_exception, f): - """ - :type key: None|str - :type code_or_exception: int|T<=Exception - :type f: callable - """ - if isinstance(code_or_exception, HTTPException): # old broken behavior - raise ValueError( - 'Tried to register a handler for an exception instance {0!r}.' - ' Handlers can only be registered for exception classes or' - ' HTTP error codes.'.format(code_or_exception) - ) - - try: - exc_class, code = self._get_exc_class_and_code(code_or_exception) - except KeyError: - raise KeyError( - "'{0}' is not a recognized HTTP error code. Use a subclass of" - " HTTPException with that code instead.".format(code_or_exception) - ) - - handlers = self.error_handler_spec.setdefault(key, {}).setdefault(code, {}) - handlers[exc_class] = f - - @setupmethod - def template_filter(self, name=None): - """A decorator that is used to register custom template filter. - You can specify a name for the filter, otherwise the function - name will be used. Example:: - - @app.template_filter() - def reverse(s): - return s[::-1] - - :param name: the optional name of the filter, otherwise the - function name will be used. - """ - def decorator(f): - self.add_template_filter(f, name=name) - return f - return decorator - - @setupmethod - def add_template_filter(self, f, name=None): - """Register a custom template filter. Works exactly like the - :meth:`template_filter` decorator. - - :param name: the optional name of the filter, otherwise the - function name will be used. - """ - self.jinja_env.filters[name or f.__name__] = f - - @setupmethod - def template_test(self, name=None): - """A decorator that is used to register custom template test. - You can specify a name for the test, otherwise the function - name will be used. Example:: - - @app.template_test() - def is_prime(n): - if n == 2: - return True - for i in range(2, int(math.ceil(math.sqrt(n))) + 1): - if n % i == 0: - return False - return True - - .. versionadded:: 0.10 - - :param name: the optional name of the test, otherwise the - function name will be used. - """ - def decorator(f): - self.add_template_test(f, name=name) - return f - return decorator - - @setupmethod - def add_template_test(self, f, name=None): - """Register a custom template test. Works exactly like the - :meth:`template_test` decorator. - - .. versionadded:: 0.10 - - :param name: the optional name of the test, otherwise the - function name will be used. - """ - self.jinja_env.tests[name or f.__name__] = f - - @setupmethod - def template_global(self, name=None): - """A decorator that is used to register a custom template global function. - You can specify a name for the global function, otherwise the function - name will be used. Example:: - - @app.template_global() - def double(n): - return 2 * n - - .. versionadded:: 0.10 - - :param name: the optional name of the global function, otherwise the - function name will be used. - """ - def decorator(f): - self.add_template_global(f, name=name) - return f - return decorator - - @setupmethod - def add_template_global(self, f, name=None): - """Register a custom template global function. Works exactly like the - :meth:`template_global` decorator. - - .. versionadded:: 0.10 - - :param name: the optional name of the global function, otherwise the - function name will be used. - """ - self.jinja_env.globals[name or f.__name__] = f - - @setupmethod - def before_request(self, f): - """Registers a function to run before each request. - - For example, this can be used to open a database connection, or to load - the logged in user from the session. - - The function will be called without any arguments. If it returns a - non-None value, the value is handled as if it was the return value from - the view, and further request handling is stopped. - """ - self.before_request_funcs.setdefault(None, []).append(f) - return f - - @setupmethod - def before_first_request(self, f): - """Registers a function to be run before the first request to this - instance of the application. - - The function will be called without any arguments and its return - value is ignored. - - .. versionadded:: 0.8 - """ - self.before_first_request_funcs.append(f) - return f - - @setupmethod - def after_request(self, f): - """Register a function to be run after each request. - - Your function must take one parameter, an instance of - :attr:`response_class` and return a new response object or the - same (see :meth:`process_response`). - - As of Flask 0.7 this function might not be executed at the end of the - request in case an unhandled exception occurred. - """ - self.after_request_funcs.setdefault(None, []).append(f) - return f - - @setupmethod - def teardown_request(self, f): - """Register a function to be run at the end of each request, - regardless of whether there was an exception or not. These functions - are executed when the request context is popped, even if not an - actual request was performed. - - Example:: - - ctx = app.test_request_context() - ctx.push() - ... - ctx.pop() - - When ``ctx.pop()`` is executed in the above example, the teardown - functions are called just before the request context moves from the - stack of active contexts. This becomes relevant if you are using - such constructs in tests. - - Generally teardown functions must take every necessary step to avoid - that they will fail. If they do execute code that might fail they - will have to surround the execution of these code by try/except - statements and log occurring errors. - - When a teardown function was called because of an exception it will - be passed an error object. - - The return values of teardown functions are ignored. - - .. admonition:: Debug Note - - In debug mode Flask will not tear down a request on an exception - immediately. Instead it will keep it alive so that the interactive - debugger can still access it. This behavior can be controlled - by the ``PRESERVE_CONTEXT_ON_EXCEPTION`` configuration variable. - """ - self.teardown_request_funcs.setdefault(None, []).append(f) - return f - - @setupmethod - def teardown_appcontext(self, f): - """Registers a function to be called when the application context - ends. These functions are typically also called when the request - context is popped. - - Example:: - - ctx = app.app_context() - ctx.push() - ... - ctx.pop() - - When ``ctx.pop()`` is executed in the above example, the teardown - functions are called just before the app context moves from the - stack of active contexts. This becomes relevant if you are using - such constructs in tests. - - Since a request context typically also manages an application - context it would also be called when you pop a request context. - - When a teardown function was called because of an unhandled exception - it will be passed an error object. If an :meth:`errorhandler` is - registered, it will handle the exception and the teardown will not - receive it. - - The return values of teardown functions are ignored. - - .. versionadded:: 0.9 - """ - self.teardown_appcontext_funcs.append(f) - return f - - @setupmethod - def context_processor(self, f): - """Registers a template context processor function.""" - self.template_context_processors[None].append(f) - return f - - @setupmethod - def shell_context_processor(self, f): - """Registers a shell context processor function. - - .. versionadded:: 0.11 - """ - self.shell_context_processors.append(f) - return f - - @setupmethod - def url_value_preprocessor(self, f): - """Register a URL value preprocessor function for all view - functions in the application. These functions will be called before the - :meth:`before_request` functions. - - The function can modify the values captured from the matched url before - they are passed to the view. For example, this can be used to pop a - common language code value and place it in ``g`` rather than pass it to - every view. - - The function is passed the endpoint name and values dict. The return - value is ignored. - """ - self.url_value_preprocessors.setdefault(None, []).append(f) - return f - - @setupmethod - def url_defaults(self, f): - """Callback function for URL defaults for all view functions of the - application. It's called with the endpoint and values and should - update the values passed in place. - """ - self.url_default_functions.setdefault(None, []).append(f) - return f - - def _find_error_handler(self, e): - """Return a registered error handler for an exception in this order: - blueprint handler for a specific code, app handler for a specific code, - blueprint handler for an exception class, app handler for an exception - class, or ``None`` if a suitable handler is not found. - """ - exc_class, code = self._get_exc_class_and_code(type(e)) - - for name, c in ( - (request.blueprint, code), (None, code), - (request.blueprint, None), (None, None) - ): - handler_map = self.error_handler_spec.setdefault(name, {}).get(c) - - if not handler_map: - continue - - for cls in exc_class.__mro__: - handler = handler_map.get(cls) - - if handler is not None: - return handler - - def handle_http_exception(self, e): - """Handles an HTTP exception. By default this will invoke the - registered error handlers and fall back to returning the - exception as response. - - .. versionadded:: 0.3 - """ - # Proxy exceptions don't have error codes. We want to always return - # those unchanged as errors - if e.code is None: - return e - - handler = self._find_error_handler(e) - if handler is None: - return e - return handler(e) - - def trap_http_exception(self, e): - """Checks if an HTTP exception should be trapped or not. By default - this will return ``False`` for all exceptions except for a bad request - key error if ``TRAP_BAD_REQUEST_ERRORS`` is set to ``True``. It - also returns ``True`` if ``TRAP_HTTP_EXCEPTIONS`` is set to ``True``. - - This is called for all HTTP exceptions raised by a view function. - If it returns ``True`` for any exception the error handler for this - exception is not called and it shows up as regular exception in the - traceback. This is helpful for debugging implicitly raised HTTP - exceptions. - - .. versionchanged:: 1.0 - Bad request errors are not trapped by default in debug mode. - - .. versionadded:: 0.8 - """ - if self.config['TRAP_HTTP_EXCEPTIONS']: - return True - - trap_bad_request = self.config['TRAP_BAD_REQUEST_ERRORS'] - - # if unset, trap key errors in debug mode - if ( - trap_bad_request is None and self.debug - and isinstance(e, BadRequestKeyError) - ): - return True - - if trap_bad_request: - return isinstance(e, BadRequest) - - return False - - def handle_user_exception(self, e): - """This method is called whenever an exception occurs that should be - handled. A special case are - :class:`~werkzeug.exception.HTTPException`\s which are forwarded by - this function to the :meth:`handle_http_exception` method. This - function will either return a response value or reraise the - exception with the same traceback. - - .. versionchanged:: 1.0 - Key errors raised from request data like ``form`` show the the bad - key in debug mode rather than a generic bad request message. - - .. versionadded:: 0.7 - """ - exc_type, exc_value, tb = sys.exc_info() - assert exc_value is e - # ensure not to trash sys.exc_info() at that point in case someone - # wants the traceback preserved in handle_http_exception. Of course - # we cannot prevent users from trashing it themselves in a custom - # trap_http_exception method so that's their fault then. - - # MultiDict passes the key to the exception, but that's ignored - # when generating the response message. Set an informative - # description for key errors in debug mode or when trapping errors. - if ( - (self.debug or self.config['TRAP_BAD_REQUEST_ERRORS']) - and isinstance(e, BadRequestKeyError) - # only set it if it's still the default description - and e.description is BadRequestKeyError.description - ): - e.description = "KeyError: '{0}'".format(*e.args) - - if isinstance(e, HTTPException) and not self.trap_http_exception(e): - return self.handle_http_exception(e) - - handler = self._find_error_handler(e) - - if handler is None: - reraise(exc_type, exc_value, tb) - return handler(e) - - def handle_exception(self, e): - """Default exception handling that kicks in when an exception - occurs that is not caught. In debug mode the exception will - be re-raised immediately, otherwise it is logged and the handler - for a 500 internal server error is used. If no such handler - exists, a default 500 internal server error message is displayed. - - .. versionadded:: 0.3 - """ - exc_type, exc_value, tb = sys.exc_info() - - got_request_exception.send(self, exception=e) - handler = self._find_error_handler(InternalServerError()) - - if self.propagate_exceptions: - # if we want to repropagate the exception, we can attempt to - # raise it with the whole traceback in case we can do that - # (the function was actually called from the except part) - # otherwise, we just raise the error again - if exc_value is e: - reraise(exc_type, exc_value, tb) - else: - raise e - - self.log_exception((exc_type, exc_value, tb)) - if handler is None: - return InternalServerError() - return self.finalize_request(handler(e), from_error_handler=True) - - def log_exception(self, exc_info): - """Logs an exception. This is called by :meth:`handle_exception` - if debugging is disabled and right before the handler is called. - The default implementation logs the exception as error on the - :attr:`logger`. - - .. versionadded:: 0.8 - """ - self.logger.error('Exception on %s [%s]' % ( - request.path, - request.method - ), exc_info=exc_info) - - def raise_routing_exception(self, request): - """Exceptions that are recording during routing are reraised with - this method. During debug we are not reraising redirect requests - for non ``GET``, ``HEAD``, or ``OPTIONS`` requests and we're raising - a different error instead to help debug situations. - - :internal: - """ - if not self.debug \ - or not isinstance(request.routing_exception, RequestRedirect) \ - or request.method in ('GET', 'HEAD', 'OPTIONS'): - raise request.routing_exception - - from .debughelpers import FormDataRoutingRedirect - raise FormDataRoutingRedirect(request) - - def dispatch_request(self): - """Does the request dispatching. Matches the URL and returns the - return value of the view or error handler. This does not have to - be a response object. In order to convert the return value to a - proper response object, call :func:`make_response`. - - .. versionchanged:: 0.7 - This no longer does the exception handling, this code was - moved to the new :meth:`full_dispatch_request`. - """ - req = _request_ctx_stack.top.request - if req.routing_exception is not None: - self.raise_routing_exception(req) - rule = req.url_rule - # if we provide automatic options for this URL and the - # request came with the OPTIONS method, reply automatically - if getattr(rule, 'provide_automatic_options', False) \ - and req.method == 'OPTIONS': - return self.make_default_options_response() - # otherwise dispatch to the handler for that endpoint - return self.view_functions[rule.endpoint](**req.view_args) - - def full_dispatch_request(self): - """Dispatches the request and on top of that performs request - pre and postprocessing as well as HTTP exception catching and - error handling. - - .. versionadded:: 0.7 - """ - self.try_trigger_before_first_request_functions() - try: - request_started.send(self) - rv = self.preprocess_request() - if rv is None: - rv = self.dispatch_request() - except Exception as e: - rv = self.handle_user_exception(e) - return self.finalize_request(rv) - - def finalize_request(self, rv, from_error_handler=False): - """Given the return value from a view function this finalizes - the request by converting it into a response and invoking the - postprocessing functions. This is invoked for both normal - request dispatching as well as error handlers. - - Because this means that it might be called as a result of a - failure a special safe mode is available which can be enabled - with the `from_error_handler` flag. If enabled, failures in - response processing will be logged and otherwise ignored. - - :internal: - """ - response = self.make_response(rv) - try: - response = self.process_response(response) - request_finished.send(self, response=response) - except Exception: - if not from_error_handler: - raise - self.logger.exception('Request finalizing failed with an ' - 'error while handling an error') - return response - - def try_trigger_before_first_request_functions(self): - """Called before each request and will ensure that it triggers - the :attr:`before_first_request_funcs` and only exactly once per - application instance (which means process usually). - - :internal: - """ - if self._got_first_request: - return - with self._before_request_lock: - if self._got_first_request: - return - for func in self.before_first_request_funcs: - func() - self._got_first_request = True - - def make_default_options_response(self): - """This method is called to create the default ``OPTIONS`` response. - This can be changed through subclassing to change the default - behavior of ``OPTIONS`` responses. - - .. versionadded:: 0.7 - """ - adapter = _request_ctx_stack.top.url_adapter - if hasattr(adapter, 'allowed_methods'): - methods = adapter.allowed_methods() - else: - # fallback for Werkzeug < 0.7 - methods = [] - try: - adapter.match(method='--') - except MethodNotAllowed as e: - methods = e.valid_methods - except HTTPException as e: - pass - rv = self.response_class() - rv.allow.update(methods) - return rv - - def should_ignore_error(self, error): - """This is called to figure out if an error should be ignored - or not as far as the teardown system is concerned. If this - function returns ``True`` then the teardown handlers will not be - passed the error. - - .. versionadded:: 0.10 - """ - return False - - def make_response(self, rv): - """Convert the return value from a view function to an instance of - :attr:`response_class`. - - :param rv: the return value from the view function. The view function - must return a response. Returning ``None``, or the view ending - without returning, is not allowed. The following types are allowed - for ``view_rv``: - - ``str`` (``unicode`` in Python 2) - A response object is created with the string encoded to UTF-8 - as the body. - - ``bytes`` (``str`` in Python 2) - A response object is created with the bytes as the body. - - ``tuple`` - Either ``(body, status, headers)``, ``(body, status)``, or - ``(body, headers)``, where ``body`` is any of the other types - allowed here, ``status`` is a string or an integer, and - ``headers`` is a dictionary or a list of ``(key, value)`` - tuples. If ``body`` is a :attr:`response_class` instance, - ``status`` overwrites the exiting value and ``headers`` are - extended. - - :attr:`response_class` - The object is returned unchanged. - - other :class:`~werkzeug.wrappers.Response` class - The object is coerced to :attr:`response_class`. - - :func:`callable` - The function is called as a WSGI application. The result is - used to create a response object. - - .. versionchanged:: 0.9 - Previously a tuple was interpreted as the arguments for the - response object. - """ - - status = headers = None - - # unpack tuple returns - if isinstance(rv, tuple): - len_rv = len(rv) - - # a 3-tuple is unpacked directly - if len_rv == 3: - rv, status, headers = rv - # decide if a 2-tuple has status or headers - elif len_rv == 2: - if isinstance(rv[1], (Headers, dict, tuple, list)): - rv, headers = rv - else: - rv, status = rv - # other sized tuples are not allowed - else: - raise TypeError( - 'The view function did not return a valid response tuple.' - ' The tuple must have the form (body, status, headers),' - ' (body, status), or (body, headers).' - ) - - # the body must not be None - if rv is None: - raise TypeError( - 'The view function did not return a valid response. The' - ' function either returned None or ended without a return' - ' statement.' - ) - - # make sure the body is an instance of the response class - if not isinstance(rv, self.response_class): - if isinstance(rv, (text_type, bytes, bytearray)): - # let the response class set the status and headers instead of - # waiting to do it manually, so that the class can handle any - # special logic - rv = self.response_class(rv, status=status, headers=headers) - status = headers = None - else: - # evaluate a WSGI callable, or coerce a different response - # class to the correct type - try: - rv = self.response_class.force_type(rv, request.environ) - except TypeError as e: - new_error = TypeError( - '{e}\nThe view function did not return a valid' - ' response. The return type must be a string, tuple,' - ' Response instance, or WSGI callable, but it was a' - ' {rv.__class__.__name__}.'.format(e=e, rv=rv) - ) - reraise(TypeError, new_error, sys.exc_info()[2]) - - # prefer the status if it was provided - if status is not None: - if isinstance(status, (text_type, bytes, bytearray)): - rv.status = status - else: - rv.status_code = status - - # extend existing headers with provided headers - if headers: - rv.headers.extend(headers) - - return rv - - def create_url_adapter(self, request): - """Creates a URL adapter for the given request. The URL adapter - is created at a point where the request context is not yet set - up so the request is passed explicitly. - - .. versionadded:: 0.6 - - .. versionchanged:: 0.9 - This can now also be called without a request object when the - URL adapter is created for the application context. - - .. versionchanged:: 1.0 - :data:`SERVER_NAME` no longer implicitly enables subdomain - matching. Use :attr:`subdomain_matching` instead. - """ - if request is not None: - # If subdomain matching is disabled (the default), use the - # default subdomain in all cases. This should be the default - # in Werkzeug but it currently does not have that feature. - subdomain = ((self.url_map.default_subdomain or None) - if not self.subdomain_matching else None) - return self.url_map.bind_to_environ( - request.environ, - server_name=self.config['SERVER_NAME'], - subdomain=subdomain) - # We need at the very least the server name to be set for this - # to work. - if self.config['SERVER_NAME'] is not None: - return self.url_map.bind( - self.config['SERVER_NAME'], - script_name=self.config['APPLICATION_ROOT'], - url_scheme=self.config['PREFERRED_URL_SCHEME']) - - def inject_url_defaults(self, endpoint, values): - """Injects the URL defaults for the given endpoint directly into - the values dictionary passed. This is used internally and - automatically called on URL building. - - .. versionadded:: 0.7 - """ - funcs = self.url_default_functions.get(None, ()) - if '.' in endpoint: - bp = endpoint.rsplit('.', 1)[0] - funcs = chain(funcs, self.url_default_functions.get(bp, ())) - for func in funcs: - func(endpoint, values) - - def handle_url_build_error(self, error, endpoint, values): - """Handle :class:`~werkzeug.routing.BuildError` on :meth:`url_for`. - """ - exc_type, exc_value, tb = sys.exc_info() - for handler in self.url_build_error_handlers: - try: - rv = handler(error, endpoint, values) - if rv is not None: - return rv - except BuildError as e: - # make error available outside except block (py3) - error = e - - # At this point we want to reraise the exception. If the error is - # still the same one we can reraise it with the original traceback, - # otherwise we raise it from here. - if error is exc_value: - reraise(exc_type, exc_value, tb) - raise error - - def preprocess_request(self): - """Called before the request is dispatched. Calls - :attr:`url_value_preprocessors` registered with the app and the - current blueprint (if any). Then calls :attr:`before_request_funcs` - registered with the app and the blueprint. - - If any :meth:`before_request` handler returns a non-None value, the - value is handled as if it was the return value from the view, and - further request handling is stopped. - """ - - bp = _request_ctx_stack.top.request.blueprint - - funcs = self.url_value_preprocessors.get(None, ()) - if bp is not None and bp in self.url_value_preprocessors: - funcs = chain(funcs, self.url_value_preprocessors[bp]) - for func in funcs: - func(request.endpoint, request.view_args) - - funcs = self.before_request_funcs.get(None, ()) - if bp is not None and bp in self.before_request_funcs: - funcs = chain(funcs, self.before_request_funcs[bp]) - for func in funcs: - rv = func() - if rv is not None: - return rv - - def process_response(self, response): - """Can be overridden in order to modify the response object - before it's sent to the WSGI server. By default this will - call all the :meth:`after_request` decorated functions. - - .. versionchanged:: 0.5 - As of Flask 0.5 the functions registered for after request - execution are called in reverse order of registration. - - :param response: a :attr:`response_class` object. - :return: a new response object or the same, has to be an - instance of :attr:`response_class`. - """ - ctx = _request_ctx_stack.top - bp = ctx.request.blueprint - funcs = ctx._after_request_functions - if bp is not None and bp in self.after_request_funcs: - funcs = chain(funcs, reversed(self.after_request_funcs[bp])) - if None in self.after_request_funcs: - funcs = chain(funcs, reversed(self.after_request_funcs[None])) - for handler in funcs: - response = handler(response) - if not self.session_interface.is_null_session(ctx.session): - self.session_interface.save_session(self, ctx.session, response) - return response - - def do_teardown_request(self, exc=_sentinel): - """Called after the request is dispatched and the response is - returned, right before the request context is popped. - - This calls all functions decorated with - :meth:`teardown_request`, and :meth:`Blueprint.teardown_request` - if a blueprint handled the request. Finally, the - :data:`request_tearing_down` signal is sent. - - This is called by - :meth:`RequestContext.pop() `, - which may be delayed during testing to maintain access to - resources. - - :param exc: An unhandled exception raised while dispatching the - request. Detected from the current exception information if - not passed. Passed to each teardown function. - - .. versionchanged:: 0.9 - Added the ``exc`` argument. - """ - if exc is _sentinel: - exc = sys.exc_info()[1] - funcs = reversed(self.teardown_request_funcs.get(None, ())) - bp = _request_ctx_stack.top.request.blueprint - if bp is not None and bp in self.teardown_request_funcs: - funcs = chain(funcs, reversed(self.teardown_request_funcs[bp])) - for func in funcs: - func(exc) - request_tearing_down.send(self, exc=exc) - - def do_teardown_appcontext(self, exc=_sentinel): - """Called right before the application context is popped. - - When handling a request, the application context is popped - after the request context. See :meth:`do_teardown_request`. - - This calls all functions decorated with - :meth:`teardown_appcontext`. Then the - :data:`appcontext_tearing_down` signal is sent. - - This is called by - :meth:`AppContext.pop() `. - - .. versionadded:: 0.9 - """ - if exc is _sentinel: - exc = sys.exc_info()[1] - for func in reversed(self.teardown_appcontext_funcs): - func(exc) - appcontext_tearing_down.send(self, exc=exc) - - def app_context(self): - """Create an :class:`~flask.ctx.AppContext`. Use as a ``with`` - block to push the context, which will make :data:`current_app` - point at this application. - - An application context is automatically pushed by - :meth:`RequestContext.push() ` - when handling a request, and when running a CLI command. Use - this to manually create a context outside of these situations. - - :: - - with app.app_context(): - init_db() - - See :doc:`/appcontext`. - - .. versionadded:: 0.9 - """ - return AppContext(self) - - def request_context(self, environ): - """Create a :class:`~flask.ctx.RequestContext` representing a - WSGI environment. Use a ``with`` block to push the context, - which will make :data:`request` point at this request. - - See :doc:`/reqcontext`. - - Typically you should not call this from your own code. A request - context is automatically pushed by the :meth:`wsgi_app` when - handling a request. Use :meth:`test_request_context` to create - an environment and context instead of this method. - - :param environ: a WSGI environment - """ - return RequestContext(self, environ) - - def test_request_context(self, *args, **kwargs): - """Create a :class:`~flask.ctx.RequestContext` for a WSGI - environment created from the given values. This is mostly useful - during testing, where you may want to run a function that uses - request data without dispatching a full request. - - See :doc:`/reqcontext`. - - Use a ``with`` block to push the context, which will make - :data:`request` point at the request for the created - environment. :: - - with test_request_context(...): - generate_report() - - When using the shell, it may be easier to push and pop the - context manually to avoid indentation. :: - - ctx = app.test_request_context(...) - ctx.push() - ... - ctx.pop() - - Takes the same arguments as Werkzeug's - :class:`~werkzeug.test.EnvironBuilder`, with some defaults from - the application. See the linked Werkzeug docs for most of the - available arguments. Flask-specific behavior is listed here. - - :param path: URL path being requested. - :param base_url: Base URL where the app is being served, which - ``path`` is relative to. If not given, built from - :data:`PREFERRED_URL_SCHEME`, ``subdomain``, - :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`. - :param subdomain: Subdomain name to append to - :data:`SERVER_NAME`. - :param url_scheme: Scheme to use instead of - :data:`PREFERRED_URL_SCHEME`. - :param data: The request body, either as a string or a dict of - form keys and values. - :param json: If given, this is serialized as JSON and passed as - ``data``. Also defaults ``content_type`` to - ``application/json``. - :param args: other positional arguments passed to - :class:`~werkzeug.test.EnvironBuilder`. - :param kwargs: other keyword arguments passed to - :class:`~werkzeug.test.EnvironBuilder`. - """ - from flask.testing import make_test_environ_builder - - builder = make_test_environ_builder(self, *args, **kwargs) - - try: - return self.request_context(builder.get_environ()) - finally: - builder.close() - - def wsgi_app(self, environ, start_response): - """The actual WSGI application. This is not implemented in - :meth:`__call__` so that middlewares can be applied without - losing a reference to the app object. Instead of doing this:: - - app = MyMiddleware(app) - - It's a better idea to do this instead:: - - app.wsgi_app = MyMiddleware(app.wsgi_app) - - Then you still have the original application object around and - can continue to call methods on it. - - .. versionchanged:: 0.7 - Teardown events for the request and app contexts are called - even if an unhandled error occurs. Other events may not be - called depending on when an error occurs during dispatch. - See :ref:`callbacks-and-errors`. - - :param environ: A WSGI environment. - :param start_response: A callable accepting a status code, - a list of headers, and an optional exception context to - start the response. - """ - ctx = self.request_context(environ) - error = None - try: - try: - ctx.push() - response = self.full_dispatch_request() - except Exception as e: - error = e - response = self.handle_exception(e) - except: - error = sys.exc_info()[1] - raise - return response(environ, start_response) - finally: - if self.should_ignore_error(error): - error = None - ctx.auto_pop(error) - - def __call__(self, environ, start_response): - """The WSGI server calls the Flask application object as the - WSGI application. This calls :meth:`wsgi_app` which can be - wrapped to applying middleware.""" - return self.wsgi_app(environ, start_response) - - def __repr__(self): - return '<%s %r>' % ( - self.__class__.__name__, - self.name, - ) diff --git a/pyextra/flask/blueprints.py b/pyextra/flask/blueprints.py deleted file mode 100644 index 5ce5561e4e1950..00000000000000 --- a/pyextra/flask/blueprints.py +++ /dev/null @@ -1,448 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.blueprints - ~~~~~~~~~~~~~~~~ - - Blueprints are the recommended way to implement larger or more - pluggable applications in Flask 0.7 and later. - - :copyright: © 2010 by the Pallets team. - :license: BSD, see LICENSE for more details. -""" -from functools import update_wrapper -from werkzeug.urls import url_join - -from .helpers import _PackageBoundObject, _endpoint_from_view_func - - -class BlueprintSetupState(object): - """Temporary holder object for registering a blueprint with the - application. An instance of this class is created by the - :meth:`~flask.Blueprint.make_setup_state` method and later passed - to all register callback functions. - """ - - def __init__(self, blueprint, app, options, first_registration): - #: a reference to the current application - self.app = app - - #: a reference to the blueprint that created this setup state. - self.blueprint = blueprint - - #: a dictionary with all options that were passed to the - #: :meth:`~flask.Flask.register_blueprint` method. - self.options = options - - #: as blueprints can be registered multiple times with the - #: application and not everything wants to be registered - #: multiple times on it, this attribute can be used to figure - #: out if the blueprint was registered in the past already. - self.first_registration = first_registration - - subdomain = self.options.get('subdomain') - if subdomain is None: - subdomain = self.blueprint.subdomain - - #: The subdomain that the blueprint should be active for, ``None`` - #: otherwise. - self.subdomain = subdomain - - url_prefix = self.options.get('url_prefix') - if url_prefix is None: - url_prefix = self.blueprint.url_prefix - #: The prefix that should be used for all URLs defined on the - #: blueprint. - self.url_prefix = url_prefix - - #: A dictionary with URL defaults that is added to each and every - #: URL that was defined with the blueprint. - self.url_defaults = dict(self.blueprint.url_values_defaults) - self.url_defaults.update(self.options.get('url_defaults', ())) - - def add_url_rule(self, rule, endpoint=None, view_func=None, **options): - """A helper method to register a rule (and optionally a view function) - to the application. The endpoint is automatically prefixed with the - blueprint's name. - """ - if self.url_prefix is not None: - if rule: - rule = '/'.join(( - self.url_prefix.rstrip('/'), rule.lstrip('/'))) - else: - rule = self.url_prefix - options.setdefault('subdomain', self.subdomain) - if endpoint is None: - endpoint = _endpoint_from_view_func(view_func) - defaults = self.url_defaults - if 'defaults' in options: - defaults = dict(defaults, **options.pop('defaults')) - self.app.add_url_rule(rule, '%s.%s' % (self.blueprint.name, endpoint), - view_func, defaults=defaults, **options) - - -class Blueprint(_PackageBoundObject): - """Represents a blueprint. A blueprint is an object that records - functions that will be called with the - :class:`~flask.blueprints.BlueprintSetupState` later to register functions - or other things on the main application. See :ref:`blueprints` for more - information. - - .. versionadded:: 0.7 - """ - - warn_on_modifications = False - _got_registered_once = False - - #: Blueprint local JSON decoder class to use. - #: Set to ``None`` to use the app's :class:`~flask.app.Flask.json_encoder`. - json_encoder = None - #: Blueprint local JSON decoder class to use. - #: Set to ``None`` to use the app's :class:`~flask.app.Flask.json_decoder`. - json_decoder = None - - # TODO remove the next three attrs when Sphinx :inherited-members: works - # https://github.com/sphinx-doc/sphinx/issues/741 - - #: The name of the package or module that this app belongs to. Do not - #: change this once it is set by the constructor. - import_name = None - - #: Location of the template files to be added to the template lookup. - #: ``None`` if templates should not be added. - template_folder = None - - #: Absolute path to the package on the filesystem. Used to look up - #: resources contained in the package. - root_path = None - - def __init__(self, name, import_name, static_folder=None, - static_url_path=None, template_folder=None, - url_prefix=None, subdomain=None, url_defaults=None, - root_path=None): - _PackageBoundObject.__init__(self, import_name, template_folder, - root_path=root_path) - self.name = name - self.url_prefix = url_prefix - self.subdomain = subdomain - self.static_folder = static_folder - self.static_url_path = static_url_path - self.deferred_functions = [] - if url_defaults is None: - url_defaults = {} - self.url_values_defaults = url_defaults - - def record(self, func): - """Registers a function that is called when the blueprint is - registered on the application. This function is called with the - state as argument as returned by the :meth:`make_setup_state` - method. - """ - if self._got_registered_once and self.warn_on_modifications: - from warnings import warn - warn(Warning('The blueprint was already registered once ' - 'but is getting modified now. These changes ' - 'will not show up.')) - self.deferred_functions.append(func) - - def record_once(self, func): - """Works like :meth:`record` but wraps the function in another - function that will ensure the function is only called once. If the - blueprint is registered a second time on the application, the - function passed is not called. - """ - def wrapper(state): - if state.first_registration: - func(state) - return self.record(update_wrapper(wrapper, func)) - - def make_setup_state(self, app, options, first_registration=False): - """Creates an instance of :meth:`~flask.blueprints.BlueprintSetupState` - object that is later passed to the register callback functions. - Subclasses can override this to return a subclass of the setup state. - """ - return BlueprintSetupState(self, app, options, first_registration) - - def register(self, app, options, first_registration=False): - """Called by :meth:`Flask.register_blueprint` to register all views - and callbacks registered on the blueprint with the application. Creates - a :class:`.BlueprintSetupState` and calls each :meth:`record` callback - with it. - - :param app: The application this blueprint is being registered with. - :param options: Keyword arguments forwarded from - :meth:`~Flask.register_blueprint`. - :param first_registration: Whether this is the first time this - blueprint has been registered on the application. - """ - self._got_registered_once = True - state = self.make_setup_state(app, options, first_registration) - - if self.has_static_folder: - state.add_url_rule( - self.static_url_path + '/', - view_func=self.send_static_file, endpoint='static' - ) - - for deferred in self.deferred_functions: - deferred(state) - - def route(self, rule, **options): - """Like :meth:`Flask.route` but for a blueprint. The endpoint for the - :func:`url_for` function is prefixed with the name of the blueprint. - """ - def decorator(f): - endpoint = options.pop("endpoint", f.__name__) - self.add_url_rule(rule, endpoint, f, **options) - return f - return decorator - - def add_url_rule(self, rule, endpoint=None, view_func=None, **options): - """Like :meth:`Flask.add_url_rule` but for a blueprint. The endpoint for - the :func:`url_for` function is prefixed with the name of the blueprint. - """ - if endpoint: - assert '.' not in endpoint, "Blueprint endpoints should not contain dots" - if view_func and hasattr(view_func, '__name__'): - assert '.' not in view_func.__name__, "Blueprint view function name should not contain dots" - self.record(lambda s: - s.add_url_rule(rule, endpoint, view_func, **options)) - - def endpoint(self, endpoint): - """Like :meth:`Flask.endpoint` but for a blueprint. This does not - prefix the endpoint with the blueprint name, this has to be done - explicitly by the user of this method. If the endpoint is prefixed - with a `.` it will be registered to the current blueprint, otherwise - it's an application independent endpoint. - """ - def decorator(f): - def register_endpoint(state): - state.app.view_functions[endpoint] = f - self.record_once(register_endpoint) - return f - return decorator - - def app_template_filter(self, name=None): - """Register a custom template filter, available application wide. Like - :meth:`Flask.template_filter` but for a blueprint. - - :param name: the optional name of the filter, otherwise the - function name will be used. - """ - def decorator(f): - self.add_app_template_filter(f, name=name) - return f - return decorator - - def add_app_template_filter(self, f, name=None): - """Register a custom template filter, available application wide. Like - :meth:`Flask.add_template_filter` but for a blueprint. Works exactly - like the :meth:`app_template_filter` decorator. - - :param name: the optional name of the filter, otherwise the - function name will be used. - """ - def register_template(state): - state.app.jinja_env.filters[name or f.__name__] = f - self.record_once(register_template) - - def app_template_test(self, name=None): - """Register a custom template test, available application wide. Like - :meth:`Flask.template_test` but for a blueprint. - - .. versionadded:: 0.10 - - :param name: the optional name of the test, otherwise the - function name will be used. - """ - def decorator(f): - self.add_app_template_test(f, name=name) - return f - return decorator - - def add_app_template_test(self, f, name=None): - """Register a custom template test, available application wide. Like - :meth:`Flask.add_template_test` but for a blueprint. Works exactly - like the :meth:`app_template_test` decorator. - - .. versionadded:: 0.10 - - :param name: the optional name of the test, otherwise the - function name will be used. - """ - def register_template(state): - state.app.jinja_env.tests[name or f.__name__] = f - self.record_once(register_template) - - def app_template_global(self, name=None): - """Register a custom template global, available application wide. Like - :meth:`Flask.template_global` but for a blueprint. - - .. versionadded:: 0.10 - - :param name: the optional name of the global, otherwise the - function name will be used. - """ - def decorator(f): - self.add_app_template_global(f, name=name) - return f - return decorator - - def add_app_template_global(self, f, name=None): - """Register a custom template global, available application wide. Like - :meth:`Flask.add_template_global` but for a blueprint. Works exactly - like the :meth:`app_template_global` decorator. - - .. versionadded:: 0.10 - - :param name: the optional name of the global, otherwise the - function name will be used. - """ - def register_template(state): - state.app.jinja_env.globals[name or f.__name__] = f - self.record_once(register_template) - - def before_request(self, f): - """Like :meth:`Flask.before_request` but for a blueprint. This function - is only executed before each request that is handled by a function of - that blueprint. - """ - self.record_once(lambda s: s.app.before_request_funcs - .setdefault(self.name, []).append(f)) - return f - - def before_app_request(self, f): - """Like :meth:`Flask.before_request`. Such a function is executed - before each request, even if outside of a blueprint. - """ - self.record_once(lambda s: s.app.before_request_funcs - .setdefault(None, []).append(f)) - return f - - def before_app_first_request(self, f): - """Like :meth:`Flask.before_first_request`. Such a function is - executed before the first request to the application. - """ - self.record_once(lambda s: s.app.before_first_request_funcs.append(f)) - return f - - def after_request(self, f): - """Like :meth:`Flask.after_request` but for a blueprint. This function - is only executed after each request that is handled by a function of - that blueprint. - """ - self.record_once(lambda s: s.app.after_request_funcs - .setdefault(self.name, []).append(f)) - return f - - def after_app_request(self, f): - """Like :meth:`Flask.after_request` but for a blueprint. Such a function - is executed after each request, even if outside of the blueprint. - """ - self.record_once(lambda s: s.app.after_request_funcs - .setdefault(None, []).append(f)) - return f - - def teardown_request(self, f): - """Like :meth:`Flask.teardown_request` but for a blueprint. This - function is only executed when tearing down requests handled by a - function of that blueprint. Teardown request functions are executed - when the request context is popped, even when no actual request was - performed. - """ - self.record_once(lambda s: s.app.teardown_request_funcs - .setdefault(self.name, []).append(f)) - return f - - def teardown_app_request(self, f): - """Like :meth:`Flask.teardown_request` but for a blueprint. Such a - function is executed when tearing down each request, even if outside of - the blueprint. - """ - self.record_once(lambda s: s.app.teardown_request_funcs - .setdefault(None, []).append(f)) - return f - - def context_processor(self, f): - """Like :meth:`Flask.context_processor` but for a blueprint. This - function is only executed for requests handled by a blueprint. - """ - self.record_once(lambda s: s.app.template_context_processors - .setdefault(self.name, []).append(f)) - return f - - def app_context_processor(self, f): - """Like :meth:`Flask.context_processor` but for a blueprint. Such a - function is executed each request, even if outside of the blueprint. - """ - self.record_once(lambda s: s.app.template_context_processors - .setdefault(None, []).append(f)) - return f - - def app_errorhandler(self, code): - """Like :meth:`Flask.errorhandler` but for a blueprint. This - handler is used for all requests, even if outside of the blueprint. - """ - def decorator(f): - self.record_once(lambda s: s.app.errorhandler(code)(f)) - return f - return decorator - - def url_value_preprocessor(self, f): - """Registers a function as URL value preprocessor for this - blueprint. It's called before the view functions are called and - can modify the url values provided. - """ - self.record_once(lambda s: s.app.url_value_preprocessors - .setdefault(self.name, []).append(f)) - return f - - def url_defaults(self, f): - """Callback function for URL defaults for this blueprint. It's called - with the endpoint and values and should update the values passed - in place. - """ - self.record_once(lambda s: s.app.url_default_functions - .setdefault(self.name, []).append(f)) - return f - - def app_url_value_preprocessor(self, f): - """Same as :meth:`url_value_preprocessor` but application wide. - """ - self.record_once(lambda s: s.app.url_value_preprocessors - .setdefault(None, []).append(f)) - return f - - def app_url_defaults(self, f): - """Same as :meth:`url_defaults` but application wide. - """ - self.record_once(lambda s: s.app.url_default_functions - .setdefault(None, []).append(f)) - return f - - def errorhandler(self, code_or_exception): - """Registers an error handler that becomes active for this blueprint - only. Please be aware that routing does not happen local to a - blueprint so an error handler for 404 usually is not handled by - a blueprint unless it is caused inside a view function. Another - special case is the 500 internal server error which is always looked - up from the application. - - Otherwise works as the :meth:`~flask.Flask.errorhandler` decorator - of the :class:`~flask.Flask` object. - """ - def decorator(f): - self.record_once(lambda s: s.app._register_error_handler( - self.name, code_or_exception, f)) - return f - return decorator - - def register_error_handler(self, code_or_exception, f): - """Non-decorator version of the :meth:`errorhandler` error attach - function, akin to the :meth:`~flask.Flask.register_error_handler` - application-wide function of the :class:`~flask.Flask` object but - for error handlers limited to this blueprint. - - .. versionadded:: 0.11 - """ - self.record_once(lambda s: s.app._register_error_handler( - self.name, code_or_exception, f)) diff --git a/pyextra/flask/cli.py b/pyextra/flask/cli.py deleted file mode 100644 index efc1733e29cb86..00000000000000 --- a/pyextra/flask/cli.py +++ /dev/null @@ -1,898 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.cli - ~~~~~~~~~ - - A simple command line application to run flask apps. - - :copyright: © 2010 by the Pallets team. - :license: BSD, see LICENSE for more details. -""" - -from __future__ import print_function - -import ast -import inspect -import os -import re -import ssl -import sys -import traceback -from functools import update_wrapper -from operator import attrgetter -from threading import Lock, Thread - -import click -from werkzeug.utils import import_string - -from . import __version__ -from ._compat import getargspec, iteritems, reraise, text_type -from .globals import current_app -from .helpers import get_debug_flag, get_env, get_load_dotenv - -try: - import dotenv -except ImportError: - dotenv = None - - -class NoAppException(click.UsageError): - """Raised if an application cannot be found or loaded.""" - - -def find_best_app(script_info, module): - """Given a module instance this tries to find the best possible - application in the module or raises an exception. - """ - from . import Flask - - # Search for the most common names first. - for attr_name in ('app', 'application'): - app = getattr(module, attr_name, None) - - if isinstance(app, Flask): - return app - - # Otherwise find the only object that is a Flask instance. - matches = [ - v for k, v in iteritems(module.__dict__) if isinstance(v, Flask) - ] - - if len(matches) == 1: - return matches[0] - elif len(matches) > 1: - raise NoAppException( - 'Detected multiple Flask applications in module "{module}". Use ' - '"FLASK_APP={module}:name" to specify the correct ' - 'one.'.format(module=module.__name__) - ) - - # Search for app factory functions. - for attr_name in ('create_app', 'make_app'): - app_factory = getattr(module, attr_name, None) - - if inspect.isfunction(app_factory): - try: - app = call_factory(script_info, app_factory) - - if isinstance(app, Flask): - return app - except TypeError: - if not _called_with_wrong_args(app_factory): - raise - raise NoAppException( - 'Detected factory "{factory}" in module "{module}", but ' - 'could not call it without arguments. Use ' - '"FLASK_APP=\'{module}:{factory}(args)\'" to specify ' - 'arguments.'.format( - factory=attr_name, module=module.__name__ - ) - ) - - raise NoAppException( - 'Failed to find Flask application or factory in module "{module}". ' - 'Use "FLASK_APP={module}:name to specify one.'.format( - module=module.__name__ - ) - ) - - -def call_factory(script_info, app_factory, arguments=()): - """Takes an app factory, a ``script_info` object and optionally a tuple - of arguments. Checks for the existence of a script_info argument and calls - the app_factory depending on that and the arguments provided. - """ - args_spec = getargspec(app_factory) - arg_names = args_spec.args - arg_defaults = args_spec.defaults - - if 'script_info' in arg_names: - return app_factory(*arguments, script_info=script_info) - elif arguments: - return app_factory(*arguments) - elif not arguments and len(arg_names) == 1 and arg_defaults is None: - return app_factory(script_info) - - return app_factory() - - -def _called_with_wrong_args(factory): - """Check whether calling a function raised a ``TypeError`` because - the call failed or because something in the factory raised the - error. - - :param factory: the factory function that was called - :return: true if the call failed - """ - tb = sys.exc_info()[2] - - try: - while tb is not None: - if tb.tb_frame.f_code is factory.__code__: - # in the factory, it was called successfully - return False - - tb = tb.tb_next - - # didn't reach the factory - return True - finally: - del tb - - -def find_app_by_string(script_info, module, app_name): - """Checks if the given string is a variable name or a function. If it is a - function, it checks for specified arguments and whether it takes a - ``script_info`` argument and calls the function with the appropriate - arguments. - """ - from flask import Flask - match = re.match(r'^ *([^ ()]+) *(?:\((.*?) *,? *\))? *$', app_name) - - if not match: - raise NoAppException( - '"{name}" is not a valid variable name or function ' - 'expression.'.format(name=app_name) - ) - - name, args = match.groups() - - try: - attr = getattr(module, name) - except AttributeError as e: - raise NoAppException(e.args[0]) - - if inspect.isfunction(attr): - if args: - try: - args = ast.literal_eval('({args},)'.format(args=args)) - except (ValueError, SyntaxError)as e: - raise NoAppException( - 'Could not parse the arguments in ' - '"{app_name}".'.format(e=e, app_name=app_name) - ) - else: - args = () - - try: - app = call_factory(script_info, attr, args) - except TypeError as e: - if not _called_with_wrong_args(attr): - raise - - raise NoAppException( - '{e}\nThe factory "{app_name}" in module "{module}" could not ' - 'be called with the specified arguments.'.format( - e=e, app_name=app_name, module=module.__name__ - ) - ) - else: - app = attr - - if isinstance(app, Flask): - return app - - raise NoAppException( - 'A valid Flask application was not obtained from ' - '"{module}:{app_name}".'.format( - module=module.__name__, app_name=app_name - ) - ) - - -def prepare_import(path): - """Given a filename this will try to calculate the python path, add it - to the search path and return the actual module name that is expected. - """ - path = os.path.realpath(path) - - if os.path.splitext(path)[1] == '.py': - path = os.path.splitext(path)[0] - - if os.path.basename(path) == '__init__': - path = os.path.dirname(path) - - module_name = [] - - # move up until outside package structure (no __init__.py) - while True: - path, name = os.path.split(path) - module_name.append(name) - - if not os.path.exists(os.path.join(path, '__init__.py')): - break - - if sys.path[0] != path: - sys.path.insert(0, path) - - return '.'.join(module_name[::-1]) - - -def locate_app(script_info, module_name, app_name, raise_if_not_found=True): - __traceback_hide__ = True - - try: - __import__(module_name) - except ImportError: - # Reraise the ImportError if it occurred within the imported module. - # Determine this by checking whether the trace has a depth > 1. - if sys.exc_info()[-1].tb_next: - raise NoAppException( - 'While importing "{name}", an ImportError was raised:' - '\n\n{tb}'.format(name=module_name, tb=traceback.format_exc()) - ) - elif raise_if_not_found: - raise NoAppException( - 'Could not import "{name}".'.format(name=module_name) - ) - else: - return - - module = sys.modules[module_name] - - if app_name is None: - return find_best_app(script_info, module) - else: - return find_app_by_string(script_info, module, app_name) - - -def get_version(ctx, param, value): - if not value or ctx.resilient_parsing: - return - message = 'Flask %(version)s\nPython %(python_version)s' - click.echo(message % { - 'version': __version__, - 'python_version': sys.version, - }, color=ctx.color) - ctx.exit() - - -version_option = click.Option( - ['--version'], - help='Show the flask version', - expose_value=False, - callback=get_version, - is_flag=True, - is_eager=True -) - - -class DispatchingApp(object): - """Special application that dispatches to a Flask application which - is imported by name in a background thread. If an error happens - it is recorded and shown as part of the WSGI handling which in case - of the Werkzeug debugger means that it shows up in the browser. - """ - - def __init__(self, loader, use_eager_loading=False): - self.loader = loader - self._app = None - self._lock = Lock() - self._bg_loading_exc_info = None - if use_eager_loading: - self._load_unlocked() - else: - self._load_in_background() - - def _load_in_background(self): - def _load_app(): - __traceback_hide__ = True - with self._lock: - try: - self._load_unlocked() - except Exception: - self._bg_loading_exc_info = sys.exc_info() - t = Thread(target=_load_app, args=()) - t.start() - - def _flush_bg_loading_exception(self): - __traceback_hide__ = True - exc_info = self._bg_loading_exc_info - if exc_info is not None: - self._bg_loading_exc_info = None - reraise(*exc_info) - - def _load_unlocked(self): - __traceback_hide__ = True - self._app = rv = self.loader() - self._bg_loading_exc_info = None - return rv - - def __call__(self, environ, start_response): - __traceback_hide__ = True - if self._app is not None: - return self._app(environ, start_response) - self._flush_bg_loading_exception() - with self._lock: - if self._app is not None: - rv = self._app - else: - rv = self._load_unlocked() - return rv(environ, start_response) - - -class ScriptInfo(object): - """Help object to deal with Flask applications. This is usually not - necessary to interface with as it's used internally in the dispatching - to click. In future versions of Flask this object will most likely play - a bigger role. Typically it's created automatically by the - :class:`FlaskGroup` but you can also manually create it and pass it - onwards as click object. - """ - - def __init__(self, app_import_path=None, create_app=None): - #: Optionally the import path for the Flask application. - self.app_import_path = app_import_path or os.environ.get('FLASK_APP') - #: Optionally a function that is passed the script info to create - #: the instance of the application. - self.create_app = create_app - #: A dictionary with arbitrary data that can be associated with - #: this script info. - self.data = {} - self._loaded_app = None - - def load_app(self): - """Loads the Flask app (if not yet loaded) and returns it. Calling - this multiple times will just result in the already loaded app to - be returned. - """ - __traceback_hide__ = True - - if self._loaded_app is not None: - return self._loaded_app - - app = None - - if self.create_app is not None: - app = call_factory(self, self.create_app) - else: - if self.app_import_path: - path, name = (self.app_import_path.split(':', 1) + [None])[:2] - import_name = prepare_import(path) - app = locate_app(self, import_name, name) - else: - for path in ('wsgi.py', 'app.py'): - import_name = prepare_import(path) - app = locate_app(self, import_name, None, - raise_if_not_found=False) - - if app: - break - - if not app: - raise NoAppException( - 'Could not locate a Flask application. You did not provide ' - 'the "FLASK_APP" environment variable, and a "wsgi.py" or ' - '"app.py" module was not found in the current directory.' - ) - - debug = get_debug_flag() - - # Update the app's debug flag through the descriptor so that other - # values repopulate as well. - if debug is not None: - app.debug = debug - - self._loaded_app = app - return app - - -pass_script_info = click.make_pass_decorator(ScriptInfo, ensure=True) - - -def with_appcontext(f): - """Wraps a callback so that it's guaranteed to be executed with the - script's application context. If callbacks are registered directly - to the ``app.cli`` object then they are wrapped with this function - by default unless it's disabled. - """ - @click.pass_context - def decorator(__ctx, *args, **kwargs): - with __ctx.ensure_object(ScriptInfo).load_app().app_context(): - return __ctx.invoke(f, *args, **kwargs) - return update_wrapper(decorator, f) - - -class AppGroup(click.Group): - """This works similar to a regular click :class:`~click.Group` but it - changes the behavior of the :meth:`command` decorator so that it - automatically wraps the functions in :func:`with_appcontext`. - - Not to be confused with :class:`FlaskGroup`. - """ - - def command(self, *args, **kwargs): - """This works exactly like the method of the same name on a regular - :class:`click.Group` but it wraps callbacks in :func:`with_appcontext` - unless it's disabled by passing ``with_appcontext=False``. - """ - wrap_for_ctx = kwargs.pop('with_appcontext', True) - def decorator(f): - if wrap_for_ctx: - f = with_appcontext(f) - return click.Group.command(self, *args, **kwargs)(f) - return decorator - - def group(self, *args, **kwargs): - """This works exactly like the method of the same name on a regular - :class:`click.Group` but it defaults the group class to - :class:`AppGroup`. - """ - kwargs.setdefault('cls', AppGroup) - return click.Group.group(self, *args, **kwargs) - - -class FlaskGroup(AppGroup): - """Special subclass of the :class:`AppGroup` group that supports - loading more commands from the configured Flask app. Normally a - developer does not have to interface with this class but there are - some very advanced use cases for which it makes sense to create an - instance of this. - - For information as of why this is useful see :ref:`custom-scripts`. - - :param add_default_commands: if this is True then the default run and - shell commands wil be added. - :param add_version_option: adds the ``--version`` option. - :param create_app: an optional callback that is passed the script info and - returns the loaded app. - :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` - files to set environment variables. Will also change the working - directory to the directory containing the first file found. - - .. versionchanged:: 1.0 - If installed, python-dotenv will be used to load environment variables - from :file:`.env` and :file:`.flaskenv` files. - """ - - def __init__(self, add_default_commands=True, create_app=None, - add_version_option=True, load_dotenv=True, **extra): - params = list(extra.pop('params', None) or ()) - - if add_version_option: - params.append(version_option) - - AppGroup.__init__(self, params=params, **extra) - self.create_app = create_app - self.load_dotenv = load_dotenv - - if add_default_commands: - self.add_command(run_command) - self.add_command(shell_command) - self.add_command(routes_command) - - self._loaded_plugin_commands = False - - def _load_plugin_commands(self): - if self._loaded_plugin_commands: - return - try: - import pkg_resources - except ImportError: - self._loaded_plugin_commands = True - return - - for ep in pkg_resources.iter_entry_points('flask.commands'): - self.add_command(ep.load(), ep.name) - self._loaded_plugin_commands = True - - def get_command(self, ctx, name): - self._load_plugin_commands() - - # We load built-in commands first as these should always be the - # same no matter what the app does. If the app does want to - # override this it needs to make a custom instance of this group - # and not attach the default commands. - # - # This also means that the script stays functional in case the - # application completely fails. - rv = AppGroup.get_command(self, ctx, name) - if rv is not None: - return rv - - info = ctx.ensure_object(ScriptInfo) - try: - rv = info.load_app().cli.get_command(ctx, name) - if rv is not None: - return rv - except NoAppException: - pass - - def list_commands(self, ctx): - self._load_plugin_commands() - - # The commands available is the list of both the application (if - # available) plus the builtin commands. - rv = set(click.Group.list_commands(self, ctx)) - info = ctx.ensure_object(ScriptInfo) - try: - rv.update(info.load_app().cli.list_commands(ctx)) - except Exception: - # Here we intentionally swallow all exceptions as we don't - # want the help page to break if the app does not exist. - # If someone attempts to use the command we try to create - # the app again and this will give us the error. - # However, we will not do so silently because that would confuse - # users. - traceback.print_exc() - return sorted(rv) - - def main(self, *args, **kwargs): - # Set a global flag that indicates that we were invoked from the - # command line interface. This is detected by Flask.run to make the - # call into a no-op. This is necessary to avoid ugly errors when the - # script that is loaded here also attempts to start a server. - os.environ['FLASK_RUN_FROM_CLI'] = 'true' - - if get_load_dotenv(self.load_dotenv): - load_dotenv() - - obj = kwargs.get('obj') - - if obj is None: - obj = ScriptInfo(create_app=self.create_app) - - kwargs['obj'] = obj - kwargs.setdefault('auto_envvar_prefix', 'FLASK') - return super(FlaskGroup, self).main(*args, **kwargs) - - -def _path_is_ancestor(path, other): - """Take ``other`` and remove the length of ``path`` from it. Then join it - to ``path``. If it is the original value, ``path`` is an ancestor of - ``other``.""" - return os.path.join(path, other[len(path):].lstrip(os.sep)) == other - - -def load_dotenv(path=None): - """Load "dotenv" files in order of precedence to set environment variables. - - If an env var is already set it is not overwritten, so earlier files in the - list are preferred over later files. - - Changes the current working directory to the location of the first file - found, with the assumption that it is in the top level project directory - and will be where the Python path should import local packages from. - - This is a no-op if `python-dotenv`_ is not installed. - - .. _python-dotenv: https://github.com/theskumar/python-dotenv#readme - - :param path: Load the file at this location instead of searching. - :return: ``True`` if a file was loaded. - - .. versionadded:: 1.0 - """ - if dotenv is None: - if path or os.path.exists('.env') or os.path.exists('.flaskenv'): - click.secho( - ' * Tip: There are .env files present.' - ' Do "pip install python-dotenv" to use them.', - fg='yellow') - return - - if path is not None: - return dotenv.load_dotenv(path) - - new_dir = None - - for name in ('.env', '.flaskenv'): - path = dotenv.find_dotenv(name, usecwd=True) - - if not path: - continue - - if new_dir is None: - new_dir = os.path.dirname(path) - - dotenv.load_dotenv(path) - - if new_dir and os.getcwd() != new_dir: - os.chdir(new_dir) - - return new_dir is not None # at least one file was located and loaded - - -def show_server_banner(env, debug, app_import_path, eager_loading): - """Show extra startup messages the first time the server is run, - ignoring the reloader. - """ - if os.environ.get('WERKZEUG_RUN_MAIN') == 'true': - return - - if app_import_path is not None: - message = ' * Serving Flask app "{0}"'.format(app_import_path) - - if not eager_loading: - message += ' (lazy loading)' - - click.echo(message) - - click.echo(' * Environment: {0}'.format(env)) - - if env == 'production': - click.secho( - ' WARNING: Do not use the development server in a production' - ' environment.', fg='red') - click.secho(' Use a production WSGI server instead.', dim=True) - - if debug is not None: - click.echo(' * Debug mode: {0}'.format('on' if debug else 'off')) - - -class CertParamType(click.ParamType): - """Click option type for the ``--cert`` option. Allows either an - existing file, the string ``'adhoc'``, or an import for a - :class:`~ssl.SSLContext` object. - """ - - name = 'path' - - def __init__(self): - self.path_type = click.Path( - exists=True, dir_okay=False, resolve_path=True) - - def convert(self, value, param, ctx): - try: - return self.path_type(value, param, ctx) - except click.BadParameter: - value = click.STRING(value, param, ctx).lower() - - if value == 'adhoc': - try: - import OpenSSL - except ImportError: - raise click.BadParameter( - 'Using ad-hoc certificates requires pyOpenSSL.', - ctx, param) - - return value - - obj = import_string(value, silent=True) - - if sys.version_info < (2, 7): - if obj: - return obj - else: - if isinstance(obj, ssl.SSLContext): - return obj - - raise - - -def _validate_key(ctx, param, value): - """The ``--key`` option must be specified when ``--cert`` is a file. - Modifies the ``cert`` param to be a ``(cert, key)`` pair if needed. - """ - cert = ctx.params.get('cert') - is_adhoc = cert == 'adhoc' - - if sys.version_info < (2, 7): - is_context = cert and not isinstance(cert, (text_type, bytes)) - else: - is_context = isinstance(cert, ssl.SSLContext) - - if value is not None: - if is_adhoc: - raise click.BadParameter( - 'When "--cert" is "adhoc", "--key" is not used.', - ctx, param) - - if is_context: - raise click.BadParameter( - 'When "--cert" is an SSLContext object, "--key is not used.', - ctx, param) - - if not cert: - raise click.BadParameter( - '"--cert" must also be specified.', - ctx, param) - - ctx.params['cert'] = cert, value - - else: - if cert and not (is_adhoc or is_context): - raise click.BadParameter( - 'Required when using "--cert".', - ctx, param) - - return value - - -@click.command('run', short_help='Runs a development server.') -@click.option('--host', '-h', default='127.0.0.1', - help='The interface to bind to.') -@click.option('--port', '-p', default=5000, - help='The port to bind to.') -@click.option('--cert', type=CertParamType(), - help='Specify a certificate file to use HTTPS.') -@click.option('--key', - type=click.Path(exists=True, dir_okay=False, resolve_path=True), - callback=_validate_key, expose_value=False, - help='The key file to use when specifying a certificate.') -@click.option('--reload/--no-reload', default=None, - help='Enable or disable the reloader. By default the reloader ' - 'is active if debug is enabled.') -@click.option('--debugger/--no-debugger', default=None, - help='Enable or disable the debugger. By default the debugger ' - 'is active if debug is enabled.') -@click.option('--eager-loading/--lazy-loader', default=None, - help='Enable or disable eager loading. By default eager ' - 'loading is enabled if the reloader is disabled.') -@click.option('--with-threads/--without-threads', default=True, - help='Enable or disable multithreading.') -@pass_script_info -def run_command(info, host, port, reload, debugger, eager_loading, - with_threads, cert): - """Run a local development server. - - This server is for development purposes only. It does not provide - the stability, security, or performance of production WSGI servers. - - The reloader and debugger are enabled by default if - FLASK_ENV=development or FLASK_DEBUG=1. - """ - debug = get_debug_flag() - - if reload is None: - reload = debug - - if debugger is None: - debugger = debug - - if eager_loading is None: - eager_loading = not reload - - show_server_banner(get_env(), debug, info.app_import_path, eager_loading) - app = DispatchingApp(info.load_app, use_eager_loading=eager_loading) - - from werkzeug.serving import run_simple - run_simple(host, port, app, use_reloader=reload, use_debugger=debugger, - threaded=with_threads, ssl_context=cert) - - -@click.command('shell', short_help='Runs a shell in the app context.') -@with_appcontext -def shell_command(): - """Runs an interactive Python shell in the context of a given - Flask application. The application will populate the default - namespace of this shell according to it's configuration. - - This is useful for executing small snippets of management code - without having to manually configure the application. - """ - import code - from flask.globals import _app_ctx_stack - app = _app_ctx_stack.top.app - banner = 'Python %s on %s\nApp: %s [%s]\nInstance: %s' % ( - sys.version, - sys.platform, - app.import_name, - app.env, - app.instance_path, - ) - ctx = {} - - # Support the regular Python interpreter startup script if someone - # is using it. - startup = os.environ.get('PYTHONSTARTUP') - if startup and os.path.isfile(startup): - with open(startup, 'r') as f: - eval(compile(f.read(), startup, 'exec'), ctx) - - ctx.update(app.make_shell_context()) - - code.interact(banner=banner, local=ctx) - - -@click.command('routes', short_help='Show the routes for the app.') -@click.option( - '--sort', '-s', - type=click.Choice(('endpoint', 'methods', 'rule', 'match')), - default='endpoint', - help=( - 'Method to sort routes by. "match" is the order that Flask will match ' - 'routes when dispatching a request.' - ) -) -@click.option( - '--all-methods', - is_flag=True, - help="Show HEAD and OPTIONS methods." -) -@with_appcontext -def routes_command(sort, all_methods): - """Show all registered routes with endpoints and methods.""" - - rules = list(current_app.url_map.iter_rules()) - if not rules: - click.echo('No routes were registered.') - return - - ignored_methods = set(() if all_methods else ('HEAD', 'OPTIONS')) - - if sort in ('endpoint', 'rule'): - rules = sorted(rules, key=attrgetter(sort)) - elif sort == 'methods': - rules = sorted(rules, key=lambda rule: sorted(rule.methods)) - - rule_methods = [ - ', '.join(sorted(rule.methods - ignored_methods)) for rule in rules - ] - - headers = ('Endpoint', 'Methods', 'Rule') - widths = ( - max(len(rule.endpoint) for rule in rules), - max(len(methods) for methods in rule_methods), - max(len(rule.rule) for rule in rules), - ) - widths = [max(len(h), w) for h, w in zip(headers, widths)] - row = '{{0:<{0}}} {{1:<{1}}} {{2:<{2}}}'.format(*widths) - - click.echo(row.format(*headers).strip()) - click.echo(row.format(*('-' * width for width in widths))) - - for rule, methods in zip(rules, rule_methods): - click.echo(row.format(rule.endpoint, methods, rule.rule).rstrip()) - - -cli = FlaskGroup(help="""\ -A general utility script for Flask applications. - -Provides commands from Flask, extensions, and the application. Loads the -application defined in the FLASK_APP environment variable, or from a wsgi.py -file. Setting the FLASK_ENV environment variable to 'development' will enable -debug mode. - -\b - {prefix}{cmd} FLASK_APP=hello.py - {prefix}{cmd} FLASK_ENV=development - {prefix}flask run -""".format( - cmd='export' if os.name == 'posix' else 'set', - prefix='$ ' if os.name == 'posix' else '> ' -)) - - -def main(as_module=False): - args = sys.argv[1:] - - if as_module: - this_module = 'flask' - - if sys.version_info < (2, 7): - this_module += '.cli' - - name = 'python -m ' + this_module - - # Python rewrites "python -m flask" to the path to the file in argv. - # Restore the original command so that the reloader works. - sys.argv = ['-m', this_module] + args - else: - name = None - - cli.main(args=args, prog_name=name) - - -if __name__ == '__main__': - main(as_module=True) diff --git a/pyextra/flask/config.py b/pyextra/flask/config.py deleted file mode 100644 index d6074baa8565e4..00000000000000 --- a/pyextra/flask/config.py +++ /dev/null @@ -1,265 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.config - ~~~~~~~~~~~~ - - Implements the configuration related objects. - - :copyright: © 2010 by the Pallets team. - :license: BSD, see LICENSE for more details. -""" - -import os -import types -import errno - -from werkzeug.utils import import_string -from ._compat import string_types, iteritems -from . import json - - -class ConfigAttribute(object): - """Makes an attribute forward to the config""" - - def __init__(self, name, get_converter=None): - self.__name__ = name - self.get_converter = get_converter - - def __get__(self, obj, type=None): - if obj is None: - return self - rv = obj.config[self.__name__] - if self.get_converter is not None: - rv = self.get_converter(rv) - return rv - - def __set__(self, obj, value): - obj.config[self.__name__] = value - - -class Config(dict): - """Works exactly like a dict but provides ways to fill it from files - or special dictionaries. There are two common patterns to populate the - config. - - Either you can fill the config from a config file:: - - app.config.from_pyfile('yourconfig.cfg') - - Or alternatively you can define the configuration options in the - module that calls :meth:`from_object` or provide an import path to - a module that should be loaded. It is also possible to tell it to - use the same module and with that provide the configuration values - just before the call:: - - DEBUG = True - SECRET_KEY = 'development key' - app.config.from_object(__name__) - - In both cases (loading from any Python file or loading from modules), - only uppercase keys are added to the config. This makes it possible to use - lowercase values in the config file for temporary values that are not added - to the config or to define the config keys in the same file that implements - the application. - - Probably the most interesting way to load configurations is from an - environment variable pointing to a file:: - - app.config.from_envvar('YOURAPPLICATION_SETTINGS') - - In this case before launching the application you have to set this - environment variable to the file you want to use. On Linux and OS X - use the export statement:: - - export YOURAPPLICATION_SETTINGS='/path/to/config/file' - - On windows use `set` instead. - - :param root_path: path to which files are read relative from. When the - config object is created by the application, this is - the application's :attr:`~flask.Flask.root_path`. - :param defaults: an optional dictionary of default values - """ - - def __init__(self, root_path, defaults=None): - dict.__init__(self, defaults or {}) - self.root_path = root_path - - def from_envvar(self, variable_name, silent=False): - """Loads a configuration from an environment variable pointing to - a configuration file. This is basically just a shortcut with nicer - error messages for this line of code:: - - app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS']) - - :param variable_name: name of the environment variable - :param silent: set to ``True`` if you want silent failure for missing - files. - :return: bool. ``True`` if able to load config, ``False`` otherwise. - """ - rv = os.environ.get(variable_name) - if not rv: - if silent: - return False - raise RuntimeError('The environment variable %r is not set ' - 'and as such configuration could not be ' - 'loaded. Set this variable and make it ' - 'point to a configuration file' % - variable_name) - return self.from_pyfile(rv, silent=silent) - - def from_pyfile(self, filename, silent=False): - """Updates the values in the config from a Python file. This function - behaves as if the file was imported as module with the - :meth:`from_object` function. - - :param filename: the filename of the config. This can either be an - absolute filename or a filename relative to the - root path. - :param silent: set to ``True`` if you want silent failure for missing - files. - - .. versionadded:: 0.7 - `silent` parameter. - """ - filename = os.path.join(self.root_path, filename) - d = types.ModuleType('config') - d.__file__ = filename - try: - with open(filename, mode='rb') as config_file: - exec(compile(config_file.read(), filename, 'exec'), d.__dict__) - except IOError as e: - if silent and e.errno in ( - errno.ENOENT, errno.EISDIR, errno.ENOTDIR - ): - return False - e.strerror = 'Unable to load configuration file (%s)' % e.strerror - raise - self.from_object(d) - return True - - def from_object(self, obj): - """Updates the values from the given object. An object can be of one - of the following two types: - - - a string: in this case the object with that name will be imported - - an actual object reference: that object is used directly - - Objects are usually either modules or classes. :meth:`from_object` - loads only the uppercase attributes of the module/class. A ``dict`` - object will not work with :meth:`from_object` because the keys of a - ``dict`` are not attributes of the ``dict`` class. - - Example of module-based configuration:: - - app.config.from_object('yourapplication.default_config') - from yourapplication import default_config - app.config.from_object(default_config) - - You should not use this function to load the actual configuration but - rather configuration defaults. The actual config should be loaded - with :meth:`from_pyfile` and ideally from a location not within the - package because the package might be installed system wide. - - See :ref:`config-dev-prod` for an example of class-based configuration - using :meth:`from_object`. - - :param obj: an import name or object - """ - if isinstance(obj, string_types): - obj = import_string(obj) - for key in dir(obj): - if key.isupper(): - self[key] = getattr(obj, key) - - def from_json(self, filename, silent=False): - """Updates the values in the config from a JSON file. This function - behaves as if the JSON object was a dictionary and passed to the - :meth:`from_mapping` function. - - :param filename: the filename of the JSON file. This can either be an - absolute filename or a filename relative to the - root path. - :param silent: set to ``True`` if you want silent failure for missing - files. - - .. versionadded:: 0.11 - """ - filename = os.path.join(self.root_path, filename) - - try: - with open(filename) as json_file: - obj = json.loads(json_file.read()) - except IOError as e: - if silent and e.errno in (errno.ENOENT, errno.EISDIR): - return False - e.strerror = 'Unable to load configuration file (%s)' % e.strerror - raise - return self.from_mapping(obj) - - def from_mapping(self, *mapping, **kwargs): - """Updates the config like :meth:`update` ignoring items with non-upper - keys. - - .. versionadded:: 0.11 - """ - mappings = [] - if len(mapping) == 1: - if hasattr(mapping[0], 'items'): - mappings.append(mapping[0].items()) - else: - mappings.append(mapping[0]) - elif len(mapping) > 1: - raise TypeError( - 'expected at most 1 positional argument, got %d' % len(mapping) - ) - mappings.append(kwargs.items()) - for mapping in mappings: - for (key, value) in mapping: - if key.isupper(): - self[key] = value - return True - - def get_namespace(self, namespace, lowercase=True, trim_namespace=True): - """Returns a dictionary containing a subset of configuration options - that match the specified namespace/prefix. Example usage:: - - app.config['IMAGE_STORE_TYPE'] = 'fs' - app.config['IMAGE_STORE_PATH'] = '/var/app/images' - app.config['IMAGE_STORE_BASE_URL'] = 'http://img.website.com' - image_store_config = app.config.get_namespace('IMAGE_STORE_') - - The resulting dictionary `image_store_config` would look like:: - - { - 'type': 'fs', - 'path': '/var/app/images', - 'base_url': 'http://img.website.com' - } - - This is often useful when configuration options map directly to - keyword arguments in functions or class constructors. - - :param namespace: a configuration namespace - :param lowercase: a flag indicating if the keys of the resulting - dictionary should be lowercase - :param trim_namespace: a flag indicating if the keys of the resulting - dictionary should not include the namespace - - .. versionadded:: 0.11 - """ - rv = {} - for k, v in iteritems(self): - if not k.startswith(namespace): - continue - if trim_namespace: - key = k[len(namespace):] - else: - key = k - if lowercase: - key = key.lower() - rv[key] = v - return rv - - def __repr__(self): - return '<%s %s>' % (self.__class__.__name__, dict.__repr__(self)) diff --git a/pyextra/flask/ctx.py b/pyextra/flask/ctx.py deleted file mode 100644 index 8472c920c2d6ef..00000000000000 --- a/pyextra/flask/ctx.py +++ /dev/null @@ -1,457 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.ctx - ~~~~~~~~~ - - Implements the objects required to keep the context. - - :copyright: © 2010 by the Pallets team. - :license: BSD, see LICENSE for more details. -""" - -import sys -from functools import update_wrapper - -from werkzeug.exceptions import HTTPException - -from .globals import _request_ctx_stack, _app_ctx_stack -from .signals import appcontext_pushed, appcontext_popped -from ._compat import BROKEN_PYPY_CTXMGR_EXIT, reraise - - -# a singleton sentinel value for parameter defaults -_sentinel = object() - - -class _AppCtxGlobals(object): - """A plain object. Used as a namespace for storing data during an - application context. - - Creating an app context automatically creates this object, which is - made available as the :data:`g` proxy. - - .. describe:: 'key' in g - - Check whether an attribute is present. - - .. versionadded:: 0.10 - - .. describe:: iter(g) - - Return an iterator over the attribute names. - - .. versionadded:: 0.10 - """ - - def get(self, name, default=None): - """Get an attribute by name, or a default value. Like - :meth:`dict.get`. - - :param name: Name of attribute to get. - :param default: Value to return if the attribute is not present. - - .. versionadded:: 0.10 - """ - return self.__dict__.get(name, default) - - def pop(self, name, default=_sentinel): - """Get and remove an attribute by name. Like :meth:`dict.pop`. - - :param name: Name of attribute to pop. - :param default: Value to return if the attribute is not present, - instead of raise a ``KeyError``. - - .. versionadded:: 0.11 - """ - if default is _sentinel: - return self.__dict__.pop(name) - else: - return self.__dict__.pop(name, default) - - def setdefault(self, name, default=None): - """Get the value of an attribute if it is present, otherwise - set and return a default value. Like :meth:`dict.setdefault`. - - :param name: Name of attribute to get. - :param: default: Value to set and return if the attribute is not - present. - - .. versionadded:: 0.11 - """ - return self.__dict__.setdefault(name, default) - - def __contains__(self, item): - return item in self.__dict__ - - def __iter__(self): - return iter(self.__dict__) - - def __repr__(self): - top = _app_ctx_stack.top - if top is not None: - return '' % top.app.name - return object.__repr__(self) - - -def after_this_request(f): - """Executes a function after this request. This is useful to modify - response objects. The function is passed the response object and has - to return the same or a new one. - - Example:: - - @app.route('/') - def index(): - @after_this_request - def add_header(response): - response.headers['X-Foo'] = 'Parachute' - return response - return 'Hello World!' - - This is more useful if a function other than the view function wants to - modify a response. For instance think of a decorator that wants to add - some headers without converting the return value into a response object. - - .. versionadded:: 0.9 - """ - _request_ctx_stack.top._after_request_functions.append(f) - return f - - -def copy_current_request_context(f): - """A helper function that decorates a function to retain the current - request context. This is useful when working with greenlets. The moment - the function is decorated a copy of the request context is created and - then pushed when the function is called. - - Example:: - - import gevent - from flask import copy_current_request_context - - @app.route('/') - def index(): - @copy_current_request_context - def do_some_work(): - # do some work here, it can access flask.request like you - # would otherwise in the view function. - ... - gevent.spawn(do_some_work) - return 'Regular response' - - .. versionadded:: 0.10 - """ - top = _request_ctx_stack.top - if top is None: - raise RuntimeError('This decorator can only be used at local scopes ' - 'when a request context is on the stack. For instance within ' - 'view functions.') - reqctx = top.copy() - def wrapper(*args, **kwargs): - with reqctx: - return f(*args, **kwargs) - return update_wrapper(wrapper, f) - - -def has_request_context(): - """If you have code that wants to test if a request context is there or - not this function can be used. For instance, you may want to take advantage - of request information if the request object is available, but fail - silently if it is unavailable. - - :: - - class User(db.Model): - - def __init__(self, username, remote_addr=None): - self.username = username - if remote_addr is None and has_request_context(): - remote_addr = request.remote_addr - self.remote_addr = remote_addr - - Alternatively you can also just test any of the context bound objects - (such as :class:`request` or :class:`g` for truthness):: - - class User(db.Model): - - def __init__(self, username, remote_addr=None): - self.username = username - if remote_addr is None and request: - remote_addr = request.remote_addr - self.remote_addr = remote_addr - - .. versionadded:: 0.7 - """ - return _request_ctx_stack.top is not None - - -def has_app_context(): - """Works like :func:`has_request_context` but for the application - context. You can also just do a boolean check on the - :data:`current_app` object instead. - - .. versionadded:: 0.9 - """ - return _app_ctx_stack.top is not None - - -class AppContext(object): - """The application context binds an application object implicitly - to the current thread or greenlet, similar to how the - :class:`RequestContext` binds request information. The application - context is also implicitly created if a request context is created - but the application is not on top of the individual application - context. - """ - - def __init__(self, app): - self.app = app - self.url_adapter = app.create_url_adapter(None) - self.g = app.app_ctx_globals_class() - - # Like request context, app contexts can be pushed multiple times - # but there a basic "refcount" is enough to track them. - self._refcnt = 0 - - def push(self): - """Binds the app context to the current context.""" - self._refcnt += 1 - if hasattr(sys, 'exc_clear'): - sys.exc_clear() - _app_ctx_stack.push(self) - appcontext_pushed.send(self.app) - - def pop(self, exc=_sentinel): - """Pops the app context.""" - try: - self._refcnt -= 1 - if self._refcnt <= 0: - if exc is _sentinel: - exc = sys.exc_info()[1] - self.app.do_teardown_appcontext(exc) - finally: - rv = _app_ctx_stack.pop() - assert rv is self, 'Popped wrong app context. (%r instead of %r)' \ - % (rv, self) - appcontext_popped.send(self.app) - - def __enter__(self): - self.push() - return self - - def __exit__(self, exc_type, exc_value, tb): - self.pop(exc_value) - - if BROKEN_PYPY_CTXMGR_EXIT and exc_type is not None: - reraise(exc_type, exc_value, tb) - - -class RequestContext(object): - """The request context contains all request relevant information. It is - created at the beginning of the request and pushed to the - `_request_ctx_stack` and removed at the end of it. It will create the - URL adapter and request object for the WSGI environment provided. - - Do not attempt to use this class directly, instead use - :meth:`~flask.Flask.test_request_context` and - :meth:`~flask.Flask.request_context` to create this object. - - When the request context is popped, it will evaluate all the - functions registered on the application for teardown execution - (:meth:`~flask.Flask.teardown_request`). - - The request context is automatically popped at the end of the request - for you. In debug mode the request context is kept around if - exceptions happen so that interactive debuggers have a chance to - introspect the data. With 0.4 this can also be forced for requests - that did not fail and outside of ``DEBUG`` mode. By setting - ``'flask._preserve_context'`` to ``True`` on the WSGI environment the - context will not pop itself at the end of the request. This is used by - the :meth:`~flask.Flask.test_client` for example to implement the - deferred cleanup functionality. - - You might find this helpful for unittests where you need the - information from the context local around for a little longer. Make - sure to properly :meth:`~werkzeug.LocalStack.pop` the stack yourself in - that situation, otherwise your unittests will leak memory. - """ - - def __init__(self, app, environ, request=None): - self.app = app - if request is None: - request = app.request_class(environ) - self.request = request - self.url_adapter = app.create_url_adapter(self.request) - self.flashes = None - self.session = None - - # Request contexts can be pushed multiple times and interleaved with - # other request contexts. Now only if the last level is popped we - # get rid of them. Additionally if an application context is missing - # one is created implicitly so for each level we add this information - self._implicit_app_ctx_stack = [] - - # indicator if the context was preserved. Next time another context - # is pushed the preserved context is popped. - self.preserved = False - - # remembers the exception for pop if there is one in case the context - # preservation kicks in. - self._preserved_exc = None - - # Functions that should be executed after the request on the response - # object. These will be called before the regular "after_request" - # functions. - self._after_request_functions = [] - - self.match_request() - - def _get_g(self): - return _app_ctx_stack.top.g - def _set_g(self, value): - _app_ctx_stack.top.g = value - g = property(_get_g, _set_g) - del _get_g, _set_g - - def copy(self): - """Creates a copy of this request context with the same request object. - This can be used to move a request context to a different greenlet. - Because the actual request object is the same this cannot be used to - move a request context to a different thread unless access to the - request object is locked. - - .. versionadded:: 0.10 - """ - return self.__class__(self.app, - environ=self.request.environ, - request=self.request - ) - - def match_request(self): - """Can be overridden by a subclass to hook into the matching - of the request. - """ - try: - url_rule, self.request.view_args = \ - self.url_adapter.match(return_rule=True) - self.request.url_rule = url_rule - except HTTPException as e: - self.request.routing_exception = e - - def push(self): - """Binds the request context to the current context.""" - # If an exception occurs in debug mode or if context preservation is - # activated under exception situations exactly one context stays - # on the stack. The rationale is that you want to access that - # information under debug situations. However if someone forgets to - # pop that context again we want to make sure that on the next push - # it's invalidated, otherwise we run at risk that something leaks - # memory. This is usually only a problem in test suite since this - # functionality is not active in production environments. - top = _request_ctx_stack.top - if top is not None and top.preserved: - top.pop(top._preserved_exc) - - # Before we push the request context we have to ensure that there - # is an application context. - app_ctx = _app_ctx_stack.top - if app_ctx is None or app_ctx.app != self.app: - app_ctx = self.app.app_context() - app_ctx.push() - self._implicit_app_ctx_stack.append(app_ctx) - else: - self._implicit_app_ctx_stack.append(None) - - if hasattr(sys, 'exc_clear'): - sys.exc_clear() - - _request_ctx_stack.push(self) - - # Open the session at the moment that the request context is available. - # This allows a custom open_session method to use the request context. - # Only open a new session if this is the first time the request was - # pushed, otherwise stream_with_context loses the session. - if self.session is None: - session_interface = self.app.session_interface - self.session = session_interface.open_session( - self.app, self.request - ) - - if self.session is None: - self.session = session_interface.make_null_session(self.app) - - def pop(self, exc=_sentinel): - """Pops the request context and unbinds it by doing that. This will - also trigger the execution of functions registered by the - :meth:`~flask.Flask.teardown_request` decorator. - - .. versionchanged:: 0.9 - Added the `exc` argument. - """ - app_ctx = self._implicit_app_ctx_stack.pop() - - try: - clear_request = False - if not self._implicit_app_ctx_stack: - self.preserved = False - self._preserved_exc = None - if exc is _sentinel: - exc = sys.exc_info()[1] - self.app.do_teardown_request(exc) - - # If this interpreter supports clearing the exception information - # we do that now. This will only go into effect on Python 2.x, - # on 3.x it disappears automatically at the end of the exception - # stack. - if hasattr(sys, 'exc_clear'): - sys.exc_clear() - - request_close = getattr(self.request, 'close', None) - if request_close is not None: - request_close() - clear_request = True - finally: - rv = _request_ctx_stack.pop() - - # get rid of circular dependencies at the end of the request - # so that we don't require the GC to be active. - if clear_request: - rv.request.environ['werkzeug.request'] = None - - # Get rid of the app as well if necessary. - if app_ctx is not None: - app_ctx.pop(exc) - - assert rv is self, 'Popped wrong request context. ' \ - '(%r instead of %r)' % (rv, self) - - def auto_pop(self, exc): - if self.request.environ.get('flask._preserve_context') or \ - (exc is not None and self.app.preserve_context_on_exception): - self.preserved = True - self._preserved_exc = exc - else: - self.pop(exc) - - def __enter__(self): - self.push() - return self - - def __exit__(self, exc_type, exc_value, tb): - # do not pop the request stack if we are in debug mode and an - # exception happened. This will allow the debugger to still - # access the request object in the interactive shell. Furthermore - # the context can be force kept alive for the test client. - # See flask.testing for how this works. - self.auto_pop(exc_value) - - if BROKEN_PYPY_CTXMGR_EXIT and exc_type is not None: - reraise(exc_type, exc_value, tb) - - def __repr__(self): - return '<%s \'%s\' [%s] of %s>' % ( - self.__class__.__name__, - self.request.url, - self.request.method, - self.app.name, - ) diff --git a/pyextra/flask/debughelpers.py b/pyextra/flask/debughelpers.py deleted file mode 100644 index e9765f20d0a2e4..00000000000000 --- a/pyextra/flask/debughelpers.py +++ /dev/null @@ -1,168 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.debughelpers - ~~~~~~~~~~~~~~~~~~ - - Various helpers to make the development experience better. - - :copyright: © 2010 by the Pallets team. - :license: BSD, see LICENSE for more details. -""" - -import os -from warnings import warn - -from ._compat import implements_to_string, text_type -from .app import Flask -from .blueprints import Blueprint -from .globals import _request_ctx_stack - - -class UnexpectedUnicodeError(AssertionError, UnicodeError): - """Raised in places where we want some better error reporting for - unexpected unicode or binary data. - """ - - -@implements_to_string -class DebugFilesKeyError(KeyError, AssertionError): - """Raised from request.files during debugging. The idea is that it can - provide a better error message than just a generic KeyError/BadRequest. - """ - - def __init__(self, request, key): - form_matches = request.form.getlist(key) - buf = ['You tried to access the file "%s" in the request.files ' - 'dictionary but it does not exist. The mimetype for the request ' - 'is "%s" instead of "multipart/form-data" which means that no ' - 'file contents were transmitted. To fix this error you should ' - 'provide enctype="multipart/form-data" in your form.' % - (key, request.mimetype)] - if form_matches: - buf.append('\n\nThe browser instead transmitted some file names. ' - 'This was submitted: %s' % ', '.join('"%s"' % x - for x in form_matches)) - self.msg = ''.join(buf) - - def __str__(self): - return self.msg - - -class FormDataRoutingRedirect(AssertionError): - """This exception is raised by Flask in debug mode if it detects a - redirect caused by the routing system when the request method is not - GET, HEAD or OPTIONS. Reasoning: form data will be dropped. - """ - - def __init__(self, request): - exc = request.routing_exception - buf = ['A request was sent to this URL (%s) but a redirect was ' - 'issued automatically by the routing system to "%s".' - % (request.url, exc.new_url)] - - # In case just a slash was appended we can be extra helpful - if request.base_url + '/' == exc.new_url.split('?')[0]: - buf.append(' The URL was defined with a trailing slash so ' - 'Flask will automatically redirect to the URL ' - 'with the trailing slash if it was accessed ' - 'without one.') - - buf.append(' Make sure to directly send your %s-request to this URL ' - 'since we can\'t make browsers or HTTP clients redirect ' - 'with form data reliably or without user interaction.' % - request.method) - buf.append('\n\nNote: this exception is only raised in debug mode') - AssertionError.__init__(self, ''.join(buf).encode('utf-8')) - - -def attach_enctype_error_multidict(request): - """Since Flask 0.8 we're monkeypatching the files object in case a - request is detected that does not use multipart form data but the files - object is accessed. - """ - oldcls = request.files.__class__ - class newcls(oldcls): - def __getitem__(self, key): - try: - return oldcls.__getitem__(self, key) - except KeyError: - if key not in request.form: - raise - raise DebugFilesKeyError(request, key) - newcls.__name__ = oldcls.__name__ - newcls.__module__ = oldcls.__module__ - request.files.__class__ = newcls - - -def _dump_loader_info(loader): - yield 'class: %s.%s' % (type(loader).__module__, type(loader).__name__) - for key, value in sorted(loader.__dict__.items()): - if key.startswith('_'): - continue - if isinstance(value, (tuple, list)): - if not all(isinstance(x, (str, text_type)) for x in value): - continue - yield '%s:' % key - for item in value: - yield ' - %s' % item - continue - elif not isinstance(value, (str, text_type, int, float, bool)): - continue - yield '%s: %r' % (key, value) - - -def explain_template_loading_attempts(app, template, attempts): - """This should help developers understand what failed""" - info = ['Locating template "%s":' % template] - total_found = 0 - blueprint = None - reqctx = _request_ctx_stack.top - if reqctx is not None and reqctx.request.blueprint is not None: - blueprint = reqctx.request.blueprint - - for idx, (loader, srcobj, triple) in enumerate(attempts): - if isinstance(srcobj, Flask): - src_info = 'application "%s"' % srcobj.import_name - elif isinstance(srcobj, Blueprint): - src_info = 'blueprint "%s" (%s)' % (srcobj.name, - srcobj.import_name) - else: - src_info = repr(srcobj) - - info.append('% 5d: trying loader of %s' % ( - idx + 1, src_info)) - - for line in _dump_loader_info(loader): - info.append(' %s' % line) - - if triple is None: - detail = 'no match' - else: - detail = 'found (%r)' % (triple[1] or '') - total_found += 1 - info.append(' -> %s' % detail) - - seems_fishy = False - if total_found == 0: - info.append('Error: the template could not be found.') - seems_fishy = True - elif total_found > 1: - info.append('Warning: multiple loaders returned a match for the template.') - seems_fishy = True - - if blueprint is not None and seems_fishy: - info.append(' The template was looked up from an endpoint that ' - 'belongs to the blueprint "%s".' % blueprint) - info.append(' Maybe you did not place a template in the right folder?') - info.append(' See http://flask.pocoo.org/docs/blueprints/#templates') - - app.logger.info('\n'.join(info)) - - -def explain_ignored_app_run(): - if os.environ.get('WERKZEUG_RUN_MAIN') != 'true': - warn(Warning('Silently ignoring app.run() because the ' - 'application is run from the flask command line ' - 'executable. Consider putting app.run() behind an ' - 'if __name__ == "__main__" guard to silence this ' - 'warning.'), stacklevel=3) diff --git a/pyextra/flask/globals.py b/pyextra/flask/globals.py deleted file mode 100644 index 7d50a6f6d4052f..00000000000000 --- a/pyextra/flask/globals.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.globals - ~~~~~~~~~~~~~ - - Defines all the global objects that are proxies to the current - active context. - - :copyright: © 2010 by the Pallets team. - :license: BSD, see LICENSE for more details. -""" - -from functools import partial -from werkzeug.local import LocalStack, LocalProxy - - -_request_ctx_err_msg = '''\ -Working outside of request context. - -This typically means that you attempted to use functionality that needed -an active HTTP request. Consult the documentation on testing for -information about how to avoid this problem.\ -''' -_app_ctx_err_msg = '''\ -Working outside of application context. - -This typically means that you attempted to use functionality that needed -to interface with the current application object in some way. To solve -this, set up an application context with app.app_context(). See the -documentation for more information.\ -''' - - -def _lookup_req_object(name): - top = _request_ctx_stack.top - if top is None: - raise RuntimeError(_request_ctx_err_msg) - return getattr(top, name) - - -def _lookup_app_object(name): - top = _app_ctx_stack.top - if top is None: - raise RuntimeError(_app_ctx_err_msg) - return getattr(top, name) - - -def _find_app(): - top = _app_ctx_stack.top - if top is None: - raise RuntimeError(_app_ctx_err_msg) - return top.app - - -# context locals -_request_ctx_stack = LocalStack() -_app_ctx_stack = LocalStack() -current_app = LocalProxy(_find_app) -request = LocalProxy(partial(_lookup_req_object, 'request')) -session = LocalProxy(partial(_lookup_req_object, 'session')) -g = LocalProxy(partial(_lookup_app_object, 'g')) diff --git a/pyextra/flask/helpers.py b/pyextra/flask/helpers.py deleted file mode 100644 index df0b91fc55ee0e..00000000000000 --- a/pyextra/flask/helpers.py +++ /dev/null @@ -1,1044 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.helpers - ~~~~~~~~~~~~~ - - Implements various helpers. - - :copyright: © 2010 by the Pallets team. - :license: BSD, see LICENSE for more details. -""" - -import os -import socket -import sys -import pkgutil -import posixpath -import mimetypes -from time import time -from zlib import adler32 -from threading import RLock -import unicodedata -from werkzeug.routing import BuildError -from functools import update_wrapper - -from werkzeug.urls import url_quote -from werkzeug.datastructures import Headers, Range -from werkzeug.exceptions import BadRequest, NotFound, \ - RequestedRangeNotSatisfiable - -from werkzeug.wsgi import wrap_file -from jinja2 import FileSystemLoader - -from .signals import message_flashed -from .globals import session, _request_ctx_stack, _app_ctx_stack, \ - current_app, request -from ._compat import string_types, text_type, PY2 - -# sentinel -_missing = object() - - -# what separators does this operating system provide that are not a slash? -# this is used by the send_from_directory function to ensure that nobody is -# able to access files from outside the filesystem. -_os_alt_seps = list(sep for sep in [os.path.sep, os.path.altsep] - if sep not in (None, '/')) - - -def get_env(): - """Get the environment the app is running in, indicated by the - :envvar:`FLASK_ENV` environment variable. The default is - ``'production'``. - """ - return os.environ.get('FLASK_ENV') or 'production' - - -def get_debug_flag(): - """Get whether debug mode should be enabled for the app, indicated - by the :envvar:`FLASK_DEBUG` environment variable. The default is - ``True`` if :func:`.get_env` returns ``'development'``, or ``False`` - otherwise. - """ - val = os.environ.get('FLASK_DEBUG') - - if not val: - return get_env() == 'development' - - return val.lower() not in ('0', 'false', 'no') - - -def get_load_dotenv(default=True): - """Get whether the user has disabled loading dotenv files by setting - :envvar:`FLASK_SKIP_DOTENV`. The default is ``True``, load the - files. - - :param default: What to return if the env var isn't set. - """ - val = os.environ.get('FLASK_SKIP_DOTENV') - - if not val: - return default - - return val.lower() in ('0', 'false', 'no') - - -def _endpoint_from_view_func(view_func): - """Internal helper that returns the default endpoint for a given - function. This always is the function name. - """ - assert view_func is not None, 'expected view func if endpoint ' \ - 'is not provided.' - return view_func.__name__ - - -def stream_with_context(generator_or_function): - """Request contexts disappear when the response is started on the server. - This is done for efficiency reasons and to make it less likely to encounter - memory leaks with badly written WSGI middlewares. The downside is that if - you are using streamed responses, the generator cannot access request bound - information any more. - - This function however can help you keep the context around for longer:: - - from flask import stream_with_context, request, Response - - @app.route('/stream') - def streamed_response(): - @stream_with_context - def generate(): - yield 'Hello ' - yield request.args['name'] - yield '!' - return Response(generate()) - - Alternatively it can also be used around a specific generator:: - - from flask import stream_with_context, request, Response - - @app.route('/stream') - def streamed_response(): - def generate(): - yield 'Hello ' - yield request.args['name'] - yield '!' - return Response(stream_with_context(generate())) - - .. versionadded:: 0.9 - """ - try: - gen = iter(generator_or_function) - except TypeError: - def decorator(*args, **kwargs): - gen = generator_or_function(*args, **kwargs) - return stream_with_context(gen) - return update_wrapper(decorator, generator_or_function) - - def generator(): - ctx = _request_ctx_stack.top - if ctx is None: - raise RuntimeError('Attempted to stream with context but ' - 'there was no context in the first place to keep around.') - with ctx: - # Dummy sentinel. Has to be inside the context block or we're - # not actually keeping the context around. - yield None - - # The try/finally is here so that if someone passes a WSGI level - # iterator in we're still running the cleanup logic. Generators - # don't need that because they are closed on their destruction - # automatically. - try: - for item in gen: - yield item - finally: - if hasattr(gen, 'close'): - gen.close() - - # The trick is to start the generator. Then the code execution runs until - # the first dummy None is yielded at which point the context was already - # pushed. This item is discarded. Then when the iteration continues the - # real generator is executed. - wrapped_g = generator() - next(wrapped_g) - return wrapped_g - - -def make_response(*args): - """Sometimes it is necessary to set additional headers in a view. Because - views do not have to return response objects but can return a value that - is converted into a response object by Flask itself, it becomes tricky to - add headers to it. This function can be called instead of using a return - and you will get a response object which you can use to attach headers. - - If view looked like this and you want to add a new header:: - - def index(): - return render_template('index.html', foo=42) - - You can now do something like this:: - - def index(): - response = make_response(render_template('index.html', foo=42)) - response.headers['X-Parachutes'] = 'parachutes are cool' - return response - - This function accepts the very same arguments you can return from a - view function. This for example creates a response with a 404 error - code:: - - response = make_response(render_template('not_found.html'), 404) - - The other use case of this function is to force the return value of a - view function into a response which is helpful with view - decorators:: - - response = make_response(view_function()) - response.headers['X-Parachutes'] = 'parachutes are cool' - - Internally this function does the following things: - - - if no arguments are passed, it creates a new response argument - - if one argument is passed, :meth:`flask.Flask.make_response` - is invoked with it. - - if more than one argument is passed, the arguments are passed - to the :meth:`flask.Flask.make_response` function as tuple. - - .. versionadded:: 0.6 - """ - if not args: - return current_app.response_class() - if len(args) == 1: - args = args[0] - return current_app.make_response(args) - - -def url_for(endpoint, **values): - """Generates a URL to the given endpoint with the method provided. - - Variable arguments that are unknown to the target endpoint are appended - to the generated URL as query arguments. If the value of a query argument - is ``None``, the whole pair is skipped. In case blueprints are active - you can shortcut references to the same blueprint by prefixing the - local endpoint with a dot (``.``). - - This will reference the index function local to the current blueprint:: - - url_for('.index') - - For more information, head over to the :ref:`Quickstart `. - - To integrate applications, :class:`Flask` has a hook to intercept URL build - errors through :attr:`Flask.url_build_error_handlers`. The `url_for` - function results in a :exc:`~werkzeug.routing.BuildError` when the current - app does not have a URL for the given endpoint and values. When it does, the - :data:`~flask.current_app` calls its :attr:`~Flask.url_build_error_handlers` if - it is not ``None``, which can return a string to use as the result of - `url_for` (instead of `url_for`'s default to raise the - :exc:`~werkzeug.routing.BuildError` exception) or re-raise the exception. - An example:: - - def external_url_handler(error, endpoint, values): - "Looks up an external URL when `url_for` cannot build a URL." - # This is an example of hooking the build_error_handler. - # Here, lookup_url is some utility function you've built - # which looks up the endpoint in some external URL registry. - url = lookup_url(endpoint, **values) - if url is None: - # External lookup did not have a URL. - # Re-raise the BuildError, in context of original traceback. - exc_type, exc_value, tb = sys.exc_info() - if exc_value is error: - raise exc_type, exc_value, tb - else: - raise error - # url_for will use this result, instead of raising BuildError. - return url - - app.url_build_error_handlers.append(external_url_handler) - - Here, `error` is the instance of :exc:`~werkzeug.routing.BuildError`, and - `endpoint` and `values` are the arguments passed into `url_for`. Note - that this is for building URLs outside the current application, and not for - handling 404 NotFound errors. - - .. versionadded:: 0.10 - The `_scheme` parameter was added. - - .. versionadded:: 0.9 - The `_anchor` and `_method` parameters were added. - - .. versionadded:: 0.9 - Calls :meth:`Flask.handle_build_error` on - :exc:`~werkzeug.routing.BuildError`. - - :param endpoint: the endpoint of the URL (name of the function) - :param values: the variable arguments of the URL rule - :param _external: if set to ``True``, an absolute URL is generated. Server - address can be changed via ``SERVER_NAME`` configuration variable which - defaults to `localhost`. - :param _scheme: a string specifying the desired URL scheme. The `_external` - parameter must be set to ``True`` or a :exc:`ValueError` is raised. The default - behavior uses the same scheme as the current request, or - ``PREFERRED_URL_SCHEME`` from the :ref:`app configuration ` if no - request context is available. As of Werkzeug 0.10, this also can be set - to an empty string to build protocol-relative URLs. - :param _anchor: if provided this is added as anchor to the URL. - :param _method: if provided this explicitly specifies an HTTP method. - """ - appctx = _app_ctx_stack.top - reqctx = _request_ctx_stack.top - - if appctx is None: - raise RuntimeError( - 'Attempted to generate a URL without the application context being' - ' pushed. This has to be executed when application context is' - ' available.' - ) - - # If request specific information is available we have some extra - # features that support "relative" URLs. - if reqctx is not None: - url_adapter = reqctx.url_adapter - blueprint_name = request.blueprint - - if endpoint[:1] == '.': - if blueprint_name is not None: - endpoint = blueprint_name + endpoint - else: - endpoint = endpoint[1:] - - external = values.pop('_external', False) - - # Otherwise go with the url adapter from the appctx and make - # the URLs external by default. - else: - url_adapter = appctx.url_adapter - - if url_adapter is None: - raise RuntimeError( - 'Application was not able to create a URL adapter for request' - ' independent URL generation. You might be able to fix this by' - ' setting the SERVER_NAME config variable.' - ) - - external = values.pop('_external', True) - - anchor = values.pop('_anchor', None) - method = values.pop('_method', None) - scheme = values.pop('_scheme', None) - appctx.app.inject_url_defaults(endpoint, values) - - # This is not the best way to deal with this but currently the - # underlying Werkzeug router does not support overriding the scheme on - # a per build call basis. - old_scheme = None - if scheme is not None: - if not external: - raise ValueError('When specifying _scheme, _external must be True') - old_scheme = url_adapter.url_scheme - url_adapter.url_scheme = scheme - - try: - try: - rv = url_adapter.build(endpoint, values, method=method, - force_external=external) - finally: - if old_scheme is not None: - url_adapter.url_scheme = old_scheme - except BuildError as error: - # We need to inject the values again so that the app callback can - # deal with that sort of stuff. - values['_external'] = external - values['_anchor'] = anchor - values['_method'] = method - values['_scheme'] = scheme - return appctx.app.handle_url_build_error(error, endpoint, values) - - if anchor is not None: - rv += '#' + url_quote(anchor) - return rv - - -def get_template_attribute(template_name, attribute): - """Loads a macro (or variable) a template exports. This can be used to - invoke a macro from within Python code. If you for example have a - template named :file:`_cider.html` with the following contents: - - .. sourcecode:: html+jinja - - {% macro hello(name) %}Hello {{ name }}!{% endmacro %} - - You can access this from Python code like this:: - - hello = get_template_attribute('_cider.html', 'hello') - return hello('World') - - .. versionadded:: 0.2 - - :param template_name: the name of the template - :param attribute: the name of the variable of macro to access - """ - return getattr(current_app.jinja_env.get_template(template_name).module, - attribute) - - -def flash(message, category='message'): - """Flashes a message to the next request. In order to remove the - flashed message from the session and to display it to the user, - the template has to call :func:`get_flashed_messages`. - - .. versionchanged:: 0.3 - `category` parameter added. - - :param message: the message to be flashed. - :param category: the category for the message. The following values - are recommended: ``'message'`` for any kind of message, - ``'error'`` for errors, ``'info'`` for information - messages and ``'warning'`` for warnings. However any - kind of string can be used as category. - """ - # Original implementation: - # - # session.setdefault('_flashes', []).append((category, message)) - # - # This assumed that changes made to mutable structures in the session are - # always in sync with the session object, which is not true for session - # implementations that use external storage for keeping their keys/values. - flashes = session.get('_flashes', []) - flashes.append((category, message)) - session['_flashes'] = flashes - message_flashed.send(current_app._get_current_object(), - message=message, category=category) - - -def get_flashed_messages(with_categories=False, category_filter=[]): - """Pulls all flashed messages from the session and returns them. - Further calls in the same request to the function will return - the same messages. By default just the messages are returned, - but when `with_categories` is set to ``True``, the return value will - be a list of tuples in the form ``(category, message)`` instead. - - Filter the flashed messages to one or more categories by providing those - categories in `category_filter`. This allows rendering categories in - separate html blocks. The `with_categories` and `category_filter` - arguments are distinct: - - * `with_categories` controls whether categories are returned with message - text (``True`` gives a tuple, where ``False`` gives just the message text). - * `category_filter` filters the messages down to only those matching the - provided categories. - - See :ref:`message-flashing-pattern` for examples. - - .. versionchanged:: 0.3 - `with_categories` parameter added. - - .. versionchanged:: 0.9 - `category_filter` parameter added. - - :param with_categories: set to ``True`` to also receive categories. - :param category_filter: whitelist of categories to limit return values - """ - flashes = _request_ctx_stack.top.flashes - if flashes is None: - _request_ctx_stack.top.flashes = flashes = session.pop('_flashes') \ - if '_flashes' in session else [] - if category_filter: - flashes = list(filter(lambda f: f[0] in category_filter, flashes)) - if not with_categories: - return [x[1] for x in flashes] - return flashes - - -def send_file(filename_or_fp, mimetype=None, as_attachment=False, - attachment_filename=None, add_etags=True, - cache_timeout=None, conditional=False, last_modified=None): - """Sends the contents of a file to the client. This will use the - most efficient method available and configured. By default it will - try to use the WSGI server's file_wrapper support. Alternatively - you can set the application's :attr:`~Flask.use_x_sendfile` attribute - to ``True`` to directly emit an ``X-Sendfile`` header. This however - requires support of the underlying webserver for ``X-Sendfile``. - - By default it will try to guess the mimetype for you, but you can - also explicitly provide one. For extra security you probably want - to send certain files as attachment (HTML for instance). The mimetype - guessing requires a `filename` or an `attachment_filename` to be - provided. - - ETags will also be attached automatically if a `filename` is provided. You - can turn this off by setting `add_etags=False`. - - If `conditional=True` and `filename` is provided, this method will try to - upgrade the response stream to support range requests. This will allow - the request to be answered with partial content response. - - Please never pass filenames to this function from user sources; - you should use :func:`send_from_directory` instead. - - .. versionadded:: 0.2 - - .. versionadded:: 0.5 - The `add_etags`, `cache_timeout` and `conditional` parameters were - added. The default behavior is now to attach etags. - - .. versionchanged:: 0.7 - mimetype guessing and etag support for file objects was - deprecated because it was unreliable. Pass a filename if you are - able to, otherwise attach an etag yourself. This functionality - will be removed in Flask 1.0 - - .. versionchanged:: 0.9 - cache_timeout pulls its default from application config, when None. - - .. versionchanged:: 0.12 - The filename is no longer automatically inferred from file objects. If - you want to use automatic mimetype and etag support, pass a filepath via - `filename_or_fp` or `attachment_filename`. - - .. versionchanged:: 0.12 - The `attachment_filename` is preferred over `filename` for MIME-type - detection. - - .. versionchanged:: 1.0 - UTF-8 filenames, as specified in `RFC 2231`_, are supported. - - .. _RFC 2231: https://tools.ietf.org/html/rfc2231#section-4 - - :param filename_or_fp: the filename of the file to send. - This is relative to the :attr:`~Flask.root_path` - if a relative path is specified. - Alternatively a file object might be provided in - which case ``X-Sendfile`` might not work and fall - back to the traditional method. Make sure that the - file pointer is positioned at the start of data to - send before calling :func:`send_file`. - :param mimetype: the mimetype of the file if provided. If a file path is - given, auto detection happens as fallback, otherwise an - error will be raised. - :param as_attachment: set to ``True`` if you want to send this file with - a ``Content-Disposition: attachment`` header. - :param attachment_filename: the filename for the attachment if it - differs from the file's filename. - :param add_etags: set to ``False`` to disable attaching of etags. - :param conditional: set to ``True`` to enable conditional responses. - - :param cache_timeout: the timeout in seconds for the headers. When ``None`` - (default), this value is set by - :meth:`~Flask.get_send_file_max_age` of - :data:`~flask.current_app`. - :param last_modified: set the ``Last-Modified`` header to this value, - a :class:`~datetime.datetime` or timestamp. - If a file was passed, this overrides its mtime. - """ - mtime = None - fsize = None - if isinstance(filename_or_fp, string_types): - filename = filename_or_fp - if not os.path.isabs(filename): - filename = os.path.join(current_app.root_path, filename) - file = None - if attachment_filename is None: - attachment_filename = os.path.basename(filename) - else: - file = filename_or_fp - filename = None - - if mimetype is None: - if attachment_filename is not None: - mimetype = mimetypes.guess_type(attachment_filename)[0] \ - or 'application/octet-stream' - - if mimetype is None: - raise ValueError( - 'Unable to infer MIME-type because no filename is available. ' - 'Please set either `attachment_filename`, pass a filepath to ' - '`filename_or_fp` or set your own MIME-type via `mimetype`.' - ) - - headers = Headers() - if as_attachment: - if attachment_filename is None: - raise TypeError('filename unavailable, required for ' - 'sending as attachment') - - try: - attachment_filename = attachment_filename.encode('latin-1') - except UnicodeEncodeError: - filenames = { - 'filename': unicodedata.normalize( - 'NFKD', attachment_filename).encode('latin-1', 'ignore'), - 'filename*': "UTF-8''%s" % url_quote(attachment_filename), - } - else: - filenames = {'filename': attachment_filename} - - headers.add('Content-Disposition', 'attachment', **filenames) - - if current_app.use_x_sendfile and filename: - if file is not None: - file.close() - headers['X-Sendfile'] = filename - fsize = os.path.getsize(filename) - headers['Content-Length'] = fsize - data = None - else: - if file is None: - file = open(filename, 'rb') - mtime = os.path.getmtime(filename) - fsize = os.path.getsize(filename) - headers['Content-Length'] = fsize - data = wrap_file(request.environ, file) - - rv = current_app.response_class(data, mimetype=mimetype, headers=headers, - direct_passthrough=True) - - if last_modified is not None: - rv.last_modified = last_modified - elif mtime is not None: - rv.last_modified = mtime - - rv.cache_control.public = True - if cache_timeout is None: - cache_timeout = current_app.get_send_file_max_age(filename) - if cache_timeout is not None: - rv.cache_control.max_age = cache_timeout - rv.expires = int(time() + cache_timeout) - - if add_etags and filename is not None: - from warnings import warn - - try: - rv.set_etag('%s-%s-%s' % ( - os.path.getmtime(filename), - os.path.getsize(filename), - adler32( - filename.encode('utf-8') if isinstance(filename, text_type) - else filename - ) & 0xffffffff - )) - except OSError: - warn('Access %s failed, maybe it does not exist, so ignore etags in ' - 'headers' % filename, stacklevel=2) - - if conditional: - try: - rv = rv.make_conditional(request, accept_ranges=True, - complete_length=fsize) - except RequestedRangeNotSatisfiable: - if file is not None: - file.close() - raise - # make sure we don't send x-sendfile for servers that - # ignore the 304 status code for x-sendfile. - if rv.status_code == 304: - rv.headers.pop('x-sendfile', None) - return rv - - -def safe_join(directory, *pathnames): - """Safely join `directory` and zero or more untrusted `pathnames` - components. - - Example usage:: - - @app.route('/wiki/') - def wiki_page(filename): - filename = safe_join(app.config['WIKI_FOLDER'], filename) - with open(filename, 'rb') as fd: - content = fd.read() # Read and process the file content... - - :param directory: the trusted base directory. - :param pathnames: the untrusted pathnames relative to that directory. - :raises: :class:`~werkzeug.exceptions.NotFound` if one or more passed - paths fall out of its boundaries. - """ - - parts = [directory] - - for filename in pathnames: - if filename != '': - filename = posixpath.normpath(filename) - - if ( - any(sep in filename for sep in _os_alt_seps) - or os.path.isabs(filename) - or filename == '..' - or filename.startswith('../') - ): - raise NotFound() - - parts.append(filename) - - return posixpath.join(*parts) - - -def send_from_directory(directory, filename, **options): - """Send a file from a given directory with :func:`send_file`. This - is a secure way to quickly expose static files from an upload folder - or something similar. - - Example usage:: - - @app.route('/uploads/') - def download_file(filename): - return send_from_directory(app.config['UPLOAD_FOLDER'], - filename, as_attachment=True) - - .. admonition:: Sending files and Performance - - It is strongly recommended to activate either ``X-Sendfile`` support in - your webserver or (if no authentication happens) to tell the webserver - to serve files for the given path on its own without calling into the - web application for improved performance. - - .. versionadded:: 0.5 - - :param directory: the directory where all the files are stored. - :param filename: the filename relative to that directory to - download. - :param options: optional keyword arguments that are directly - forwarded to :func:`send_file`. - """ - filename = safe_join(directory, filename) - if not os.path.isabs(filename): - filename = os.path.join(current_app.root_path, filename) - try: - if not os.path.isfile(filename): - raise NotFound() - except (TypeError, ValueError): - raise BadRequest() - options.setdefault('conditional', True) - return send_file(filename, **options) - - -def get_root_path(import_name): - """Returns the path to a package or cwd if that cannot be found. This - returns the path of a package or the folder that contains a module. - - Not to be confused with the package path returned by :func:`find_package`. - """ - # Module already imported and has a file attribute. Use that first. - mod = sys.modules.get(import_name) - if mod is not None and hasattr(mod, '__file__'): - return os.path.dirname(os.path.abspath(mod.__file__)) - - # Next attempt: check the loader. - loader = pkgutil.get_loader(import_name) - - # Loader does not exist or we're referring to an unloaded main module - # or a main module without path (interactive sessions), go with the - # current working directory. - if loader is None or import_name == '__main__': - return os.getcwd() - - # For .egg, zipimporter does not have get_filename until Python 2.7. - # Some other loaders might exhibit the same behavior. - if hasattr(loader, 'get_filename'): - filepath = loader.get_filename(import_name) - else: - # Fall back to imports. - __import__(import_name) - mod = sys.modules[import_name] - filepath = getattr(mod, '__file__', None) - - # If we don't have a filepath it might be because we are a - # namespace package. In this case we pick the root path from the - # first module that is contained in our package. - if filepath is None: - raise RuntimeError('No root path can be found for the provided ' - 'module "%s". This can happen because the ' - 'module came from an import hook that does ' - 'not provide file name information or because ' - 'it\'s a namespace package. In this case ' - 'the root path needs to be explicitly ' - 'provided.' % import_name) - - # filepath is import_name.py for a module, or __init__.py for a package. - return os.path.dirname(os.path.abspath(filepath)) - - -def _matching_loader_thinks_module_is_package(loader, mod_name): - """Given the loader that loaded a module and the module this function - attempts to figure out if the given module is actually a package. - """ - # If the loader can tell us if something is a package, we can - # directly ask the loader. - if hasattr(loader, 'is_package'): - return loader.is_package(mod_name) - # importlib's namespace loaders do not have this functionality but - # all the modules it loads are packages, so we can take advantage of - # this information. - elif (loader.__class__.__module__ == '_frozen_importlib' and - loader.__class__.__name__ == 'NamespaceLoader'): - return True - # Otherwise we need to fail with an error that explains what went - # wrong. - raise AttributeError( - ('%s.is_package() method is missing but is required by Flask of ' - 'PEP 302 import hooks. If you do not use import hooks and ' - 'you encounter this error please file a bug against Flask.') % - loader.__class__.__name__) - - -def find_package(import_name): - """Finds a package and returns the prefix (or None if the package is - not installed) as well as the folder that contains the package or - module as a tuple. The package path returned is the module that would - have to be added to the pythonpath in order to make it possible to - import the module. The prefix is the path below which a UNIX like - folder structure exists (lib, share etc.). - """ - root_mod_name = import_name.split('.')[0] - loader = pkgutil.get_loader(root_mod_name) - if loader is None or import_name == '__main__': - # import name is not found, or interactive/main module - package_path = os.getcwd() - else: - # For .egg, zipimporter does not have get_filename until Python 2.7. - if hasattr(loader, 'get_filename'): - filename = loader.get_filename(root_mod_name) - elif hasattr(loader, 'archive'): - # zipimporter's loader.archive points to the .egg or .zip - # archive filename is dropped in call to dirname below. - filename = loader.archive - else: - # At least one loader is missing both get_filename and archive: - # Google App Engine's HardenedModulesHook - # - # Fall back to imports. - __import__(import_name) - filename = sys.modules[import_name].__file__ - package_path = os.path.abspath(os.path.dirname(filename)) - - # In case the root module is a package we need to chop of the - # rightmost part. This needs to go through a helper function - # because of python 3.3 namespace packages. - if _matching_loader_thinks_module_is_package( - loader, root_mod_name): - package_path = os.path.dirname(package_path) - - site_parent, site_folder = os.path.split(package_path) - py_prefix = os.path.abspath(sys.prefix) - if package_path.startswith(py_prefix): - return py_prefix, package_path - elif site_folder.lower() == 'site-packages': - parent, folder = os.path.split(site_parent) - # Windows like installations - if folder.lower() == 'lib': - base_dir = parent - # UNIX like installations - elif os.path.basename(parent).lower() == 'lib': - base_dir = os.path.dirname(parent) - else: - base_dir = site_parent - return base_dir, package_path - return None, package_path - - -class locked_cached_property(object): - """A decorator that converts a function into a lazy property. The - function wrapped is called the first time to retrieve the result - and then that calculated result is used the next time you access - the value. Works like the one in Werkzeug but has a lock for - thread safety. - """ - - def __init__(self, func, name=None, doc=None): - self.__name__ = name or func.__name__ - self.__module__ = func.__module__ - self.__doc__ = doc or func.__doc__ - self.func = func - self.lock = RLock() - - def __get__(self, obj, type=None): - if obj is None: - return self - with self.lock: - value = obj.__dict__.get(self.__name__, _missing) - if value is _missing: - value = self.func(obj) - obj.__dict__[self.__name__] = value - return value - - -class _PackageBoundObject(object): - #: The name of the package or module that this app belongs to. Do not - #: change this once it is set by the constructor. - import_name = None - - #: Location of the template files to be added to the template lookup. - #: ``None`` if templates should not be added. - template_folder = None - - #: Absolute path to the package on the filesystem. Used to look up - #: resources contained in the package. - root_path = None - - def __init__(self, import_name, template_folder=None, root_path=None): - self.import_name = import_name - self.template_folder = template_folder - - if root_path is None: - root_path = get_root_path(self.import_name) - - self.root_path = root_path - self._static_folder = None - self._static_url_path = None - - def _get_static_folder(self): - if self._static_folder is not None: - return os.path.join(self.root_path, self._static_folder) - - def _set_static_folder(self, value): - self._static_folder = value - - static_folder = property( - _get_static_folder, _set_static_folder, - doc='The absolute path to the configured static folder.' - ) - del _get_static_folder, _set_static_folder - - def _get_static_url_path(self): - if self._static_url_path is not None: - return self._static_url_path - - if self.static_folder is not None: - return '/' + os.path.basename(self.static_folder) - - def _set_static_url_path(self, value): - self._static_url_path = value - - static_url_path = property( - _get_static_url_path, _set_static_url_path, - doc='The URL prefix that the static route will be registered for.' - ) - del _get_static_url_path, _set_static_url_path - - @property - def has_static_folder(self): - """This is ``True`` if the package bound object's container has a - folder for static files. - - .. versionadded:: 0.5 - """ - return self.static_folder is not None - - @locked_cached_property - def jinja_loader(self): - """The Jinja loader for this package bound object. - - .. versionadded:: 0.5 - """ - if self.template_folder is not None: - return FileSystemLoader(os.path.join(self.root_path, - self.template_folder)) - - def get_send_file_max_age(self, filename): - """Provides default cache_timeout for the :func:`send_file` functions. - - By default, this function returns ``SEND_FILE_MAX_AGE_DEFAULT`` from - the configuration of :data:`~flask.current_app`. - - Static file functions such as :func:`send_from_directory` use this - function, and :func:`send_file` calls this function on - :data:`~flask.current_app` when the given cache_timeout is ``None``. If a - cache_timeout is given in :func:`send_file`, that timeout is used; - otherwise, this method is called. - - This allows subclasses to change the behavior when sending files based - on the filename. For example, to set the cache timeout for .js files - to 60 seconds:: - - class MyFlask(flask.Flask): - def get_send_file_max_age(self, name): - if name.lower().endswith('.js'): - return 60 - return flask.Flask.get_send_file_max_age(self, name) - - .. versionadded:: 0.9 - """ - return total_seconds(current_app.send_file_max_age_default) - - def send_static_file(self, filename): - """Function used internally to send static files from the static - folder to the browser. - - .. versionadded:: 0.5 - """ - if not self.has_static_folder: - raise RuntimeError('No static folder for this object') - # Ensure get_send_file_max_age is called in all cases. - # Here, we ensure get_send_file_max_age is called for Blueprints. - cache_timeout = self.get_send_file_max_age(filename) - return send_from_directory(self.static_folder, filename, - cache_timeout=cache_timeout) - - def open_resource(self, resource, mode='rb'): - """Opens a resource from the application's resource folder. To see - how this works, consider the following folder structure:: - - /myapplication.py - /schema.sql - /static - /style.css - /templates - /layout.html - /index.html - - If you want to open the :file:`schema.sql` file you would do the - following:: - - with app.open_resource('schema.sql') as f: - contents = f.read() - do_something_with(contents) - - :param resource: the name of the resource. To access resources within - subfolders use forward slashes as separator. - :param mode: resource file opening mode, default is 'rb'. - """ - if mode not in ('r', 'rb'): - raise ValueError('Resources can only be opened for reading') - return open(os.path.join(self.root_path, resource), mode) - - -def total_seconds(td): - """Returns the total seconds from a timedelta object. - - :param timedelta td: the timedelta to be converted in seconds - - :returns: number of seconds - :rtype: int - """ - return td.days * 60 * 60 * 24 + td.seconds - - -def is_ip(value): - """Determine if the given string is an IP address. - - Python 2 on Windows doesn't provide ``inet_pton``, so this only - checks IPv4 addresses in that environment. - - :param value: value to check - :type value: str - - :return: True if string is an IP address - :rtype: bool - """ - if PY2 and os.name == 'nt': - try: - socket.inet_aton(value) - return True - except socket.error: - return False - - for family in (socket.AF_INET, socket.AF_INET6): - try: - socket.inet_pton(family, value) - except socket.error: - pass - else: - return True - - return False diff --git a/pyextra/flask/json/__init__.py b/pyextra/flask/json/__init__.py deleted file mode 100644 index fbe6b92f0a3712..00000000000000 --- a/pyextra/flask/json/__init__.py +++ /dev/null @@ -1,327 +0,0 @@ -# -*- coding: utf-8 -*- -""" -flask.json -~~~~~~~~~~ - -:copyright: © 2010 by the Pallets team. -:license: BSD, see LICENSE for more details. -""" -import codecs -import io -import uuid -from datetime import date, datetime -from flask.globals import current_app, request -from flask._compat import text_type, PY2 - -from werkzeug.http import http_date -from jinja2 import Markup - -# Use the same json implementation as itsdangerous on which we -# depend anyways. -from itsdangerous import json as _json - - -# Figure out if simplejson escapes slashes. This behavior was changed -# from one version to another without reason. -_slash_escape = '\\/' not in _json.dumps('/') - - -__all__ = ['dump', 'dumps', 'load', 'loads', 'htmlsafe_dump', - 'htmlsafe_dumps', 'JSONDecoder', 'JSONEncoder', - 'jsonify'] - - -def _wrap_reader_for_text(fp, encoding): - if isinstance(fp.read(0), bytes): - fp = io.TextIOWrapper(io.BufferedReader(fp), encoding) - return fp - - -def _wrap_writer_for_text(fp, encoding): - try: - fp.write('') - except TypeError: - fp = io.TextIOWrapper(fp, encoding) - return fp - - -class JSONEncoder(_json.JSONEncoder): - """The default Flask JSON encoder. This one extends the default simplejson - encoder by also supporting ``datetime`` objects, ``UUID`` as well as - ``Markup`` objects which are serialized as RFC 822 datetime strings (same - as the HTTP date format). In order to support more data types override the - :meth:`default` method. - """ - - def default(self, o): - """Implement this method in a subclass such that it returns a - serializable object for ``o``, or calls the base implementation (to - raise a :exc:`TypeError`). - - For example, to support arbitrary iterators, you could implement - default like this:: - - def default(self, o): - try: - iterable = iter(o) - except TypeError: - pass - else: - return list(iterable) - return JSONEncoder.default(self, o) - """ - if isinstance(o, datetime): - return http_date(o.utctimetuple()) - if isinstance(o, date): - return http_date(o.timetuple()) - if isinstance(o, uuid.UUID): - return str(o) - if hasattr(o, '__html__'): - return text_type(o.__html__()) - return _json.JSONEncoder.default(self, o) - - -class JSONDecoder(_json.JSONDecoder): - """The default JSON decoder. This one does not change the behavior from - the default simplejson decoder. Consult the :mod:`json` documentation - for more information. This decoder is not only used for the load - functions of this module but also :attr:`~flask.Request`. - """ - - -def _dump_arg_defaults(kwargs): - """Inject default arguments for dump functions.""" - if current_app: - bp = current_app.blueprints.get(request.blueprint) if request else None - kwargs.setdefault( - 'cls', - bp.json_encoder if bp and bp.json_encoder - else current_app.json_encoder - ) - - if not current_app.config['JSON_AS_ASCII']: - kwargs.setdefault('ensure_ascii', False) - - kwargs.setdefault('sort_keys', current_app.config['JSON_SORT_KEYS']) - else: - kwargs.setdefault('sort_keys', True) - kwargs.setdefault('cls', JSONEncoder) - - -def _load_arg_defaults(kwargs): - """Inject default arguments for load functions.""" - if current_app: - bp = current_app.blueprints.get(request.blueprint) if request else None - kwargs.setdefault( - 'cls', - bp.json_decoder if bp and bp.json_decoder - else current_app.json_decoder - ) - else: - kwargs.setdefault('cls', JSONDecoder) - - -def detect_encoding(data): - """Detect which UTF codec was used to encode the given bytes. - - The latest JSON standard (:rfc:`8259`) suggests that only UTF-8 is - accepted. Older documents allowed 8, 16, or 32. 16 and 32 can be big - or little endian. Some editors or libraries may prepend a BOM. - - :param data: Bytes in unknown UTF encoding. - :return: UTF encoding name - """ - head = data[:4] - - if head[:3] == codecs.BOM_UTF8: - return 'utf-8-sig' - - if b'\x00' not in head: - return 'utf-8' - - if head in (codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE): - return 'utf-32' - - if head[:2] in (codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE): - return 'utf-16' - - if len(head) == 4: - if head[:3] == b'\x00\x00\x00': - return 'utf-32-be' - - if head[::2] == b'\x00\x00': - return 'utf-16-be' - - if head[1:] == b'\x00\x00\x00': - return 'utf-32-le' - - if head[1::2] == b'\x00\x00': - return 'utf-16-le' - - if len(head) == 2: - return 'utf-16-be' if head.startswith(b'\x00') else 'utf-16-le' - - return 'utf-8' - - -def dumps(obj, **kwargs): - """Serialize ``obj`` to a JSON formatted ``str`` by using the application's - configured encoder (:attr:`~flask.Flask.json_encoder`) if there is an - application on the stack. - - This function can return ``unicode`` strings or ascii-only bytestrings by - default which coerce into unicode strings automatically. That behavior by - default is controlled by the ``JSON_AS_ASCII`` configuration variable - and can be overridden by the simplejson ``ensure_ascii`` parameter. - """ - _dump_arg_defaults(kwargs) - encoding = kwargs.pop('encoding', None) - rv = _json.dumps(obj, **kwargs) - if encoding is not None and isinstance(rv, text_type): - rv = rv.encode(encoding) - return rv - - -def dump(obj, fp, **kwargs): - """Like :func:`dumps` but writes into a file object.""" - _dump_arg_defaults(kwargs) - encoding = kwargs.pop('encoding', None) - if encoding is not None: - fp = _wrap_writer_for_text(fp, encoding) - _json.dump(obj, fp, **kwargs) - - -def loads(s, **kwargs): - """Unserialize a JSON object from a string ``s`` by using the application's - configured decoder (:attr:`~flask.Flask.json_decoder`) if there is an - application on the stack. - """ - _load_arg_defaults(kwargs) - if isinstance(s, bytes): - encoding = kwargs.pop('encoding', None) - if encoding is None: - encoding = detect_encoding(s) - s = s.decode(encoding) - return _json.loads(s, **kwargs) - - -def load(fp, **kwargs): - """Like :func:`loads` but reads from a file object. - """ - _load_arg_defaults(kwargs) - if not PY2: - fp = _wrap_reader_for_text(fp, kwargs.pop('encoding', None) or 'utf-8') - return _json.load(fp, **kwargs) - - -def htmlsafe_dumps(obj, **kwargs): - """Works exactly like :func:`dumps` but is safe for use in `` - - - - -

-''' -FOOTER = u'''\ - -
- -
-
-

Console Locked

-

- The console is locked and needs to be unlocked by entering the PIN. - You can find the PIN printed out on the standard output of your - shell that runs the server. -

-

PIN: - - -

-
-
- - -''' - -PAGE_HTML = HEADER + u'''\ -

%(exception_type)s

-
-

%(exception)s

-
-

Traceback (most recent call last)

-%(summary)s -
-
-

- - This is the Copy/Paste friendly version of the traceback. You can also paste this traceback into - a gist: - -

- -
-
-
- The debugger caught an exception in your WSGI application. You can now - look at the traceback which led to the error. - If you enable JavaScript you can also use additional features such as code - execution (if the evalex feature is enabled), automatic pasting of the - exceptions and much more. -
-''' + FOOTER + ''' - -''' - -CONSOLE_HTML = HEADER + u'''\ -

Interactive Console

-
-In this console you can execute Python expressions in the context of the -application. The initial namespace was created by the debugger automatically. -
-
The Console requires JavaScript.
-''' + FOOTER - -SUMMARY_HTML = u'''\ -
- %(title)s -
    %(frames)s
- %(description)s -
-''' - -FRAME_HTML = u'''\ -
-

File "%(filename)s", - line %(lineno)s, - in %(function_name)s

-
%(lines)s
-
-''' - -SOURCE_LINE_HTML = u'''\ - - %(lineno)s - %(code)s - -''' - - -def render_console_html(secret, evalex_trusted=True): - return CONSOLE_HTML % { - 'evalex': 'true', - 'evalex_trusted': evalex_trusted and 'true' or 'false', - 'console': 'true', - 'title': 'Console', - 'secret': secret, - 'traceback_id': -1 - } - - -def get_current_traceback(ignore_system_exceptions=False, - show_hidden_frames=False, skip=0): - """Get the current exception info as `Traceback` object. Per default - calling this method will reraise system exceptions such as generator exit, - system exit or others. This behavior can be disabled by passing `False` - to the function as first parameter. - """ - exc_type, exc_value, tb = sys.exc_info() - if ignore_system_exceptions and exc_type in system_exceptions: - raise - for x in range_type(skip): - if tb.tb_next is None: - break - tb = tb.tb_next - tb = Traceback(exc_type, exc_value, tb) - if not show_hidden_frames: - tb.filter_hidden_frames() - return tb - - -class Line(object): - """Helper for the source renderer.""" - __slots__ = ('lineno', 'code', 'in_frame', 'current') - - def __init__(self, lineno, code): - self.lineno = lineno - self.code = code - self.in_frame = False - self.current = False - - def classes(self): - rv = ['line'] - if self.in_frame: - rv.append('in-frame') - if self.current: - rv.append('current') - return rv - classes = property(classes) - - def render(self): - return SOURCE_LINE_HTML % { - 'classes': u' '.join(self.classes), - 'lineno': self.lineno, - 'code': escape(self.code) - } - - -class Traceback(object): - """Wraps a traceback.""" - - def __init__(self, exc_type, exc_value, tb): - self.exc_type = exc_type - self.exc_value = exc_value - if not isinstance(exc_type, str): - exception_type = exc_type.__name__ - if exc_type.__module__ not in ('__builtin__', 'exceptions'): - exception_type = exc_type.__module__ + '.' + exception_type - else: - exception_type = exc_type - self.exception_type = exception_type - - # we only add frames to the list that are not hidden. This follows - # the the magic variables as defined by paste.exceptions.collector - self.frames = [] - while tb: - self.frames.append(Frame(exc_type, exc_value, tb)) - tb = tb.tb_next - - def filter_hidden_frames(self): - """Remove the frames according to the paste spec.""" - if not self.frames: - return - - new_frames = [] - hidden = False - for frame in self.frames: - hide = frame.hide - if hide in ('before', 'before_and_this'): - new_frames = [] - hidden = False - if hide == 'before_and_this': - continue - elif hide in ('reset', 'reset_and_this'): - hidden = False - if hide == 'reset_and_this': - continue - elif hide in ('after', 'after_and_this'): - hidden = True - if hide == 'after_and_this': - continue - elif hide or hidden: - continue - new_frames.append(frame) - - # if we only have one frame and that frame is from the codeop - # module, remove it. - if len(new_frames) == 1 and self.frames[0].module == 'codeop': - del self.frames[:] - - # if the last frame is missing something went terrible wrong :( - elif self.frames[-1] in new_frames: - self.frames[:] = new_frames - - def is_syntax_error(self): - """Is it a syntax error?""" - return isinstance(self.exc_value, SyntaxError) - is_syntax_error = property(is_syntax_error) - - def exception(self): - """String representation of the exception.""" - buf = traceback.format_exception_only(self.exc_type, self.exc_value) - rv = ''.join(buf).strip() - return rv.decode('utf-8', 'replace') if PY2 else rv - exception = property(exception) - - def log(self, logfile=None): - """Log the ASCII traceback into a file object.""" - if logfile is None: - logfile = sys.stderr - tb = self.plaintext.rstrip() + u'\n' - if PY2: - tb = tb.encode('utf-8', 'replace') - logfile.write(tb) - - def paste(self): - """Create a paste and return the paste id.""" - data = json.dumps({ - 'description': 'Werkzeug Internal Server Error', - 'public': False, - 'files': { - 'traceback.txt': { - 'content': self.plaintext - } - } - }).encode('utf-8') - try: - from urllib2 import urlopen - except ImportError: - from urllib.request import urlopen - rv = urlopen('https://api.github.com/gists', data=data) - resp = json.loads(rv.read().decode('utf-8')) - rv.close() - return { - 'url': resp['html_url'], - 'id': resp['id'] - } - - def render_summary(self, include_title=True): - """Render the traceback for the interactive console.""" - title = '' - frames = [] - classes = ['traceback'] - if not self.frames: - classes.append('noframe-traceback') - - if include_title: - if self.is_syntax_error: - title = u'Syntax Error' - else: - title = u'Traceback (most recent call last):' - - for frame in self.frames: - frames.append(u'%s' % ( - frame.info and u' title="%s"' % escape(frame.info) or u'', - frame.render() - )) - - if self.is_syntax_error: - description_wrapper = u'
%s
' - else: - description_wrapper = u'
%s
' - - return SUMMARY_HTML % { - 'classes': u' '.join(classes), - 'title': title and u'

%s

' % title or u'', - 'frames': u'\n'.join(frames), - 'description': description_wrapper % escape(self.exception) - } - - def render_full(self, evalex=False, secret=None, - evalex_trusted=True): - """Render the Full HTML page with the traceback info.""" - exc = escape(self.exception) - return PAGE_HTML % { - 'evalex': evalex and 'true' or 'false', - 'evalex_trusted': evalex_trusted and 'true' or 'false', - 'console': 'false', - 'title': exc, - 'exception': exc, - 'exception_type': escape(self.exception_type), - 'summary': self.render_summary(include_title=False), - 'plaintext': escape(self.plaintext), - 'plaintext_cs': re.sub('-{2,}', '-', self.plaintext), - 'traceback_id': self.id, - 'secret': secret - } - - def generate_plaintext_traceback(self): - """Like the plaintext attribute but returns a generator""" - yield u'Traceback (most recent call last):' - for frame in self.frames: - yield u' File "%s", line %s, in %s' % ( - frame.filename, - frame.lineno, - frame.function_name - ) - yield u' ' + frame.current_line.strip() - yield self.exception - - def plaintext(self): - return u'\n'.join(self.generate_plaintext_traceback()) - plaintext = cached_property(plaintext) - - id = property(lambda x: id(x)) - - -class Frame(object): - - """A single frame in a traceback.""" - - def __init__(self, exc_type, exc_value, tb): - self.lineno = tb.tb_lineno - self.function_name = tb.tb_frame.f_code.co_name - self.locals = tb.tb_frame.f_locals - self.globals = tb.tb_frame.f_globals - - fn = inspect.getsourcefile(tb) or inspect.getfile(tb) - if fn[-4:] in ('.pyo', '.pyc'): - fn = fn[:-1] - # if it's a file on the file system resolve the real filename. - if os.path.isfile(fn): - fn = os.path.realpath(fn) - self.filename = to_unicode(fn, get_filesystem_encoding()) - self.module = self.globals.get('__name__') - self.loader = self.globals.get('__loader__') - self.code = tb.tb_frame.f_code - - # support for paste's traceback extensions - self.hide = self.locals.get('__traceback_hide__', False) - info = self.locals.get('__traceback_info__') - if info is not None: - try: - info = text_type(info) - except UnicodeError: - info = str(info).decode('utf-8', 'replace') - self.info = info - - def render(self): - """Render a single frame in a traceback.""" - return FRAME_HTML % { - 'id': self.id, - 'filename': escape(self.filename), - 'lineno': self.lineno, - 'function_name': escape(self.function_name), - 'lines': self.render_line_context(), - } - - def render_line_context(self): - before, current, after = self.get_context_lines() - rv = [] - - def render_line(line, cls): - line = line.expandtabs().rstrip() - stripped_line = line.strip() - prefix = len(line) - len(stripped_line) - rv.append( - '
%s%s
' % ( - cls, ' ' * prefix, escape(stripped_line) or ' ')) - - for line in before: - render_line(line, 'before') - render_line(current, 'current') - for line in after: - render_line(line, 'after') - - return '\n'.join(rv) - - def get_annotated_lines(self): - """Helper function that returns lines with extra information.""" - lines = [Line(idx + 1, x) for idx, x in enumerate(self.sourcelines)] - - # find function definition and mark lines - if hasattr(self.code, 'co_firstlineno'): - lineno = self.code.co_firstlineno - 1 - while lineno > 0: - if _funcdef_re.match(lines[lineno].code): - break - lineno -= 1 - try: - offset = len(inspect.getblock([x.code + '\n' for x - in lines[lineno:]])) - except TokenError: - offset = 0 - for line in lines[lineno:lineno + offset]: - line.in_frame = True - - # mark current line - try: - lines[self.lineno - 1].current = True - except IndexError: - pass - - return lines - - def eval(self, code, mode='single'): - """Evaluate code in the context of the frame.""" - if isinstance(code, string_types): - if PY2 and isinstance(code, unicode): # noqa - code = UTF8_COOKIE + code.encode('utf-8') - code = compile(code, '', mode) - return eval(code, self.globals, self.locals) - - @cached_property - def sourcelines(self): - """The sourcecode of the file as list of unicode strings.""" - # get sourcecode from loader or file - source = None - if self.loader is not None: - try: - if hasattr(self.loader, 'get_source'): - source = self.loader.get_source(self.module) - elif hasattr(self.loader, 'get_source_by_code'): - source = self.loader.get_source_by_code(self.code) - except Exception: - # we munch the exception so that we don't cause troubles - # if the loader is broken. - pass - - if source is None: - try: - f = open(to_native(self.filename, get_filesystem_encoding()), - mode='rb') - except IOError: - return [] - try: - source = f.read() - finally: - f.close() - - # already unicode? return right away - if isinstance(source, text_type): - return source.splitlines() - - # yes. it should be ascii, but we don't want to reject too many - # characters in the debugger if something breaks - charset = 'utf-8' - if source.startswith(UTF8_COOKIE): - source = source[3:] - else: - for idx, match in enumerate(_line_re.finditer(source)): - match = _coding_re.search(match.group()) - if match is not None: - charset = match.group(1) - break - if idx > 1: - break - - # on broken cookies we fall back to utf-8 too - charset = to_native(charset) - try: - codecs.lookup(charset) - except LookupError: - charset = 'utf-8' - - return source.decode(charset, 'replace').splitlines() - - def get_context_lines(self, context=5): - before = self.sourcelines[self.lineno - context - 1:self.lineno - 1] - past = self.sourcelines[self.lineno:self.lineno + context] - return ( - before, - self.current_line, - past, - ) - - @property - def current_line(self): - try: - return self.sourcelines[self.lineno - 1] - except IndexError: - return u'' - - @cached_property - def console(self): - return Console(self.globals, self.locals) - - id = property(lambda x: id(x)) diff --git a/pyextra/werkzeug/exceptions.py b/pyextra/werkzeug/exceptions.py deleted file mode 100644 index 1d68185a9b7be1..00000000000000 --- a/pyextra/werkzeug/exceptions.py +++ /dev/null @@ -1,719 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.exceptions - ~~~~~~~~~~~~~~~~~~~ - - This module implements a number of Python exceptions you can raise from - within your views to trigger a standard non-200 response. - - - Usage Example - ------------- - - :: - - from werkzeug.wrappers import BaseRequest - from werkzeug.wsgi import responder - from werkzeug.exceptions import HTTPException, NotFound - - def view(request): - raise NotFound() - - @responder - def application(environ, start_response): - request = BaseRequest(environ) - try: - return view(request) - except HTTPException as e: - return e - - - As you can see from this example those exceptions are callable WSGI - applications. Because of Python 2.4 compatibility those do not extend - from the response objects but only from the python exception class. - - As a matter of fact they are not Werkzeug response objects. However you - can get a response object by calling ``get_response()`` on a HTTP - exception. - - Keep in mind that you have to pass an environment to ``get_response()`` - because some errors fetch additional information from the WSGI - environment. - - If you want to hook in a different exception page to say, a 404 status - code, you can add a second except for a specific subclass of an error:: - - @responder - def application(environ, start_response): - request = BaseRequest(environ) - try: - return view(request) - except NotFound, e: - return not_found(request) - except HTTPException, e: - return e - - - :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -import sys - -# Because of bootstrapping reasons we need to manually patch ourselves -# onto our parent module. -import werkzeug -werkzeug.exceptions = sys.modules[__name__] - -from werkzeug._internal import _get_environ -from werkzeug._compat import iteritems, integer_types, text_type, \ - implements_to_string - -from werkzeug.wrappers import Response - - -@implements_to_string -class HTTPException(Exception): - - """ - Baseclass for all HTTP exceptions. This exception can be called as WSGI - application to render a default error page or you can catch the subclasses - of it independently and render nicer error messages. - """ - - code = None - description = None - - def __init__(self, description=None, response=None): - Exception.__init__(self) - if description is not None: - self.description = description - self.response = response - - @classmethod - def wrap(cls, exception, name=None): - """This method returns a new subclass of the exception provided that - also is a subclass of `BadRequest`. - """ - class newcls(cls, exception): - - def __init__(self, arg=None, *args, **kwargs): - cls.__init__(self, *args, **kwargs) - exception.__init__(self, arg) - newcls.__module__ = sys._getframe(1).f_globals.get('__name__') - newcls.__name__ = name or cls.__name__ + exception.__name__ - return newcls - - @property - def name(self): - """The status name.""" - return HTTP_STATUS_CODES.get(self.code, 'Unknown Error') - - def get_description(self, environ=None): - """Get the description.""" - return u'

%s

' % escape(self.description) - - def get_body(self, environ=None): - """Get the HTML body.""" - return text_type(( - u'\n' - u'%(code)s %(name)s\n' - u'

%(name)s

\n' - u'%(description)s\n' - ) % { - 'code': self.code, - 'name': escape(self.name), - 'description': self.get_description(environ) - }) - - def get_headers(self, environ=None): - """Get a list of headers.""" - return [('Content-Type', 'text/html')] - - def get_response(self, environ=None): - """Get a response object. If one was passed to the exception - it's returned directly. - - :param environ: the optional environ for the request. This - can be used to modify the response depending - on how the request looked like. - :return: a :class:`Response` object or a subclass thereof. - """ - if self.response is not None: - return self.response - if environ is not None: - environ = _get_environ(environ) - headers = self.get_headers(environ) - return Response(self.get_body(environ), self.code, headers) - - def __call__(self, environ, start_response): - """Call the exception as WSGI application. - - :param environ: the WSGI environment. - :param start_response: the response callable provided by the WSGI - server. - """ - response = self.get_response(environ) - return response(environ, start_response) - - def __str__(self): - code = self.code if self.code is not None else '???' - return '%s %s: %s' % (code, self.name, self.description) - - def __repr__(self): - code = self.code if self.code is not None else '???' - return "<%s '%s: %s'>" % (self.__class__.__name__, code, self.name) - - -class BadRequest(HTTPException): - - """*400* `Bad Request` - - Raise if the browser sends something to the application the application - or server cannot handle. - """ - code = 400 - description = ( - 'The browser (or proxy) sent a request that this server could ' - 'not understand.' - ) - - -class ClientDisconnected(BadRequest): - - """Internal exception that is raised if Werkzeug detects a disconnected - client. Since the client is already gone at that point attempting to - send the error message to the client might not work and might ultimately - result in another exception in the server. Mainly this is here so that - it is silenced by default as far as Werkzeug is concerned. - - Since disconnections cannot be reliably detected and are unspecified - by WSGI to a large extent this might or might not be raised if a client - is gone. - - .. versionadded:: 0.8 - """ - - -class SecurityError(BadRequest): - - """Raised if something triggers a security error. This is otherwise - exactly like a bad request error. - - .. versionadded:: 0.9 - """ - - -class BadHost(BadRequest): - - """Raised if the submitted host is badly formatted. - - .. versionadded:: 0.11.2 - """ - - -class Unauthorized(HTTPException): - - """*401* `Unauthorized` - - Raise if the user is not authorized. Also used if you want to use HTTP - basic auth. - """ - code = 401 - description = ( - 'The server could not verify that you are authorized to access ' - 'the URL requested. You either supplied the wrong credentials (e.g. ' - 'a bad password), or your browser doesn\'t understand how to supply ' - 'the credentials required.' - ) - - -class Forbidden(HTTPException): - - """*403* `Forbidden` - - Raise if the user doesn't have the permission for the requested resource - but was authenticated. - """ - code = 403 - description = ( - 'You don\'t have the permission to access the requested resource. ' - 'It is either read-protected or not readable by the server.' - ) - - -class NotFound(HTTPException): - - """*404* `Not Found` - - Raise if a resource does not exist and never existed. - """ - code = 404 - description = ( - 'The requested URL was not found on the server. ' - 'If you entered the URL manually please check your spelling and ' - 'try again.' - ) - - -class MethodNotAllowed(HTTPException): - - """*405* `Method Not Allowed` - - Raise if the server used a method the resource does not handle. For - example `POST` if the resource is view only. Especially useful for REST. - - The first argument for this exception should be a list of allowed methods. - Strictly speaking the response would be invalid if you don't provide valid - methods in the header which you can do with that list. - """ - code = 405 - description = 'The method is not allowed for the requested URL.' - - def __init__(self, valid_methods=None, description=None): - """Takes an optional list of valid http methods - starting with werkzeug 0.3 the list will be mandatory.""" - HTTPException.__init__(self, description) - self.valid_methods = valid_methods - - def get_headers(self, environ): - headers = HTTPException.get_headers(self, environ) - if self.valid_methods: - headers.append(('Allow', ', '.join(self.valid_methods))) - return headers - - -class NotAcceptable(HTTPException): - - """*406* `Not Acceptable` - - Raise if the server can't return any content conforming to the - `Accept` headers of the client. - """ - code = 406 - - description = ( - 'The resource identified by the request is only capable of ' - 'generating response entities which have content characteristics ' - 'not acceptable according to the accept headers sent in the ' - 'request.' - ) - - -class RequestTimeout(HTTPException): - - """*408* `Request Timeout` - - Raise to signalize a timeout. - """ - code = 408 - description = ( - 'The server closed the network connection because the browser ' - 'didn\'t finish the request within the specified time.' - ) - - -class Conflict(HTTPException): - - """*409* `Conflict` - - Raise to signal that a request cannot be completed because it conflicts - with the current state on the server. - - .. versionadded:: 0.7 - """ - code = 409 - description = ( - 'A conflict happened while processing the request. The resource ' - 'might have been modified while the request was being processed.' - ) - - -class Gone(HTTPException): - - """*410* `Gone` - - Raise if a resource existed previously and went away without new location. - """ - code = 410 - description = ( - 'The requested URL is no longer available on this server and there ' - 'is no forwarding address. If you followed a link from a foreign ' - 'page, please contact the author of this page.' - ) - - -class LengthRequired(HTTPException): - - """*411* `Length Required` - - Raise if the browser submitted data but no ``Content-Length`` header which - is required for the kind of processing the server does. - """ - code = 411 - description = ( - 'A request with this method requires a valid Content-' - 'Length header.' - ) - - -class PreconditionFailed(HTTPException): - - """*412* `Precondition Failed` - - Status code used in combination with ``If-Match``, ``If-None-Match``, or - ``If-Unmodified-Since``. - """ - code = 412 - description = ( - 'The precondition on the request for the URL failed positive ' - 'evaluation.' - ) - - -class RequestEntityTooLarge(HTTPException): - - """*413* `Request Entity Too Large` - - The status code one should return if the data submitted exceeded a given - limit. - """ - code = 413 - description = ( - 'The data value transmitted exceeds the capacity limit.' - ) - - -class RequestURITooLarge(HTTPException): - - """*414* `Request URI Too Large` - - Like *413* but for too long URLs. - """ - code = 414 - description = ( - 'The length of the requested URL exceeds the capacity limit ' - 'for this server. The request cannot be processed.' - ) - - -class UnsupportedMediaType(HTTPException): - - """*415* `Unsupported Media Type` - - The status code returned if the server is unable to handle the media type - the client transmitted. - """ - code = 415 - description = ( - 'The server does not support the media type transmitted in ' - 'the request.' - ) - - -class RequestedRangeNotSatisfiable(HTTPException): - - """*416* `Requested Range Not Satisfiable` - - The client asked for an invalid part of the file. - - .. versionadded:: 0.7 - """ - code = 416 - description = ( - 'The server cannot provide the requested range.' - ) - - def __init__(self, length=None, units="bytes", description=None): - """Takes an optional `Content-Range` header value based on ``length`` - parameter. - """ - HTTPException.__init__(self, description) - self.length = length - self.units = units - - def get_headers(self, environ): - headers = HTTPException.get_headers(self, environ) - if self.length is not None: - headers.append( - ('Content-Range', '%s */%d' % (self.units, self.length))) - return headers - - -class ExpectationFailed(HTTPException): - - """*417* `Expectation Failed` - - The server cannot meet the requirements of the Expect request-header. - - .. versionadded:: 0.7 - """ - code = 417 - description = ( - 'The server could not meet the requirements of the Expect header' - ) - - -class ImATeapot(HTTPException): - - """*418* `I'm a teapot` - - The server should return this if it is a teapot and someone attempted - to brew coffee with it. - - .. versionadded:: 0.7 - """ - code = 418 - description = ( - 'This server is a teapot, not a coffee machine' - ) - - -class UnprocessableEntity(HTTPException): - - """*422* `Unprocessable Entity` - - Used if the request is well formed, but the instructions are otherwise - incorrect. - """ - code = 422 - description = ( - 'The request was well-formed but was unable to be followed ' - 'due to semantic errors.' - ) - - -class Locked(HTTPException): - - """*423* `Locked` - - Used if the resource that is being accessed is locked. - """ - code = 423 - description = ( - 'The resource that is being accessed is locked.' - ) - - -class PreconditionRequired(HTTPException): - - """*428* `Precondition Required` - - The server requires this request to be conditional, typically to prevent - the lost update problem, which is a race condition between two or more - clients attempting to update a resource through PUT or DELETE. By requiring - each client to include a conditional header ("If-Match" or "If-Unmodified- - Since") with the proper value retained from a recent GET request, the - server ensures that each client has at least seen the previous revision of - the resource. - """ - code = 428 - description = ( - 'This request is required to be conditional; try using "If-Match" ' - 'or "If-Unmodified-Since".' - ) - - -class TooManyRequests(HTTPException): - - """*429* `Too Many Requests` - - The server is limiting the rate at which this user receives responses, and - this request exceeds that rate. (The server may use any convenient method - to identify users and their request rates). The server may include a - "Retry-After" header to indicate how long the user should wait before - retrying. - """ - code = 429 - description = ( - 'This user has exceeded an allotted request count. Try again later.' - ) - - -class RequestHeaderFieldsTooLarge(HTTPException): - - """*431* `Request Header Fields Too Large` - - The server refuses to process the request because the header fields are too - large. One or more individual fields may be too large, or the set of all - headers is too large. - """ - code = 431 - description = ( - 'One or more header fields exceeds the maximum size.' - ) - - -class UnavailableForLegalReasons(HTTPException): - - """*451* `Unavailable For Legal Reasons` - - This status code indicates that the server is denying access to the - resource as a consequence of a legal demand. - """ - code = 451 - description = ( - 'Unavailable for legal reasons.' - ) - - -class InternalServerError(HTTPException): - - """*500* `Internal Server Error` - - Raise if an internal server error occurred. This is a good fallback if an - unknown error occurred in the dispatcher. - """ - code = 500 - description = ( - 'The server encountered an internal error and was unable to ' - 'complete your request. Either the server is overloaded or there ' - 'is an error in the application.' - ) - - -class NotImplemented(HTTPException): - - """*501* `Not Implemented` - - Raise if the application does not support the action requested by the - browser. - """ - code = 501 - description = ( - 'The server does not support the action requested by the ' - 'browser.' - ) - - -class BadGateway(HTTPException): - - """*502* `Bad Gateway` - - If you do proxying in your application you should return this status code - if you received an invalid response from the upstream server it accessed - in attempting to fulfill the request. - """ - code = 502 - description = ( - 'The proxy server received an invalid response from an upstream ' - 'server.' - ) - - -class ServiceUnavailable(HTTPException): - - """*503* `Service Unavailable` - - Status code you should return if a service is temporarily unavailable. - """ - code = 503 - description = ( - 'The server is temporarily unable to service your request due to ' - 'maintenance downtime or capacity problems. Please try again ' - 'later.' - ) - - -class GatewayTimeout(HTTPException): - - """*504* `Gateway Timeout` - - Status code you should return if a connection to an upstream server - times out. - """ - code = 504 - description = ( - 'The connection to an upstream server timed out.' - ) - - -class HTTPVersionNotSupported(HTTPException): - - """*505* `HTTP Version Not Supported` - - The server does not support the HTTP protocol version used in the request. - """ - code = 505 - description = ( - 'The server does not support the HTTP protocol version used in the ' - 'request.' - ) - - -default_exceptions = {} -__all__ = ['HTTPException'] - - -def _find_exceptions(): - for name, obj in iteritems(globals()): - try: - is_http_exception = issubclass(obj, HTTPException) - except TypeError: - is_http_exception = False - if not is_http_exception or obj.code is None: - continue - __all__.append(obj.__name__) - old_obj = default_exceptions.get(obj.code, None) - if old_obj is not None and issubclass(obj, old_obj): - continue - default_exceptions[obj.code] = obj -_find_exceptions() -del _find_exceptions - - -class Aborter(object): - - """ - When passed a dict of code -> exception items it can be used as - callable that raises exceptions. If the first argument to the - callable is an integer it will be looked up in the mapping, if it's - a WSGI application it will be raised in a proxy exception. - - The rest of the arguments are forwarded to the exception constructor. - """ - - def __init__(self, mapping=None, extra=None): - if mapping is None: - mapping = default_exceptions - self.mapping = dict(mapping) - if extra is not None: - self.mapping.update(extra) - - def __call__(self, code, *args, **kwargs): - if not args and not kwargs and not isinstance(code, integer_types): - raise HTTPException(response=code) - if code not in self.mapping: - raise LookupError('no exception for %r' % code) - raise self.mapping[code](*args, **kwargs) - - -def abort(status, *args, **kwargs): - ''' - Raises an :py:exc:`HTTPException` for the given status code or WSGI - application:: - - abort(404) # 404 Not Found - abort(Response('Hello World')) - - Can be passed a WSGI application or a status code. If a status code is - given it's looked up in the list of exceptions and will raise that - exception, if passed a WSGI application it will wrap it in a proxy WSGI - exception and raise that:: - - abort(404) - abort(Response('Hello World')) - - ''' - return _aborter(status, *args, **kwargs) - -_aborter = Aborter() - - -#: an exception that is used internally to signal both a key error and a -#: bad request. Used by a lot of the datastructures. -BadRequestKeyError = BadRequest.wrap(KeyError) - - -# imported here because of circular dependencies of werkzeug.utils -from werkzeug.utils import escape -from werkzeug.http import HTTP_STATUS_CODES diff --git a/pyextra/werkzeug/filesystem.py b/pyextra/werkzeug/filesystem.py deleted file mode 100644 index 62467465553477..00000000000000 --- a/pyextra/werkzeug/filesystem.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.filesystem - ~~~~~~~~~~~~~~~~~~~ - - Various utilities for the local filesystem. - - :copyright: (c) 2015 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" - -import codecs -import sys -import warnings - -# We do not trust traditional unixes. -has_likely_buggy_unicode_filesystem = \ - sys.platform.startswith('linux') or 'bsd' in sys.platform - - -def _is_ascii_encoding(encoding): - """ - Given an encoding this figures out if the encoding is actually ASCII (which - is something we don't actually want in most cases). This is necessary - because ASCII comes under many names such as ANSI_X3.4-1968. - """ - if encoding is None: - return False - try: - return codecs.lookup(encoding).name == 'ascii' - except LookupError: - return False - - -class BrokenFilesystemWarning(RuntimeWarning, UnicodeWarning): - '''The warning used by Werkzeug to signal a broken filesystem. Will only be - used once per runtime.''' - - -_warned_about_filesystem_encoding = False - - -def get_filesystem_encoding(): - """ - Returns the filesystem encoding that should be used. Note that this is - different from the Python understanding of the filesystem encoding which - might be deeply flawed. Do not use this value against Python's unicode APIs - because it might be different. See :ref:`filesystem-encoding` for the exact - behavior. - - The concept of a filesystem encoding in generally is not something you - should rely on. As such if you ever need to use this function except for - writing wrapper code reconsider. - """ - global _warned_about_filesystem_encoding - rv = sys.getfilesystemencoding() - if has_likely_buggy_unicode_filesystem and not rv \ - or _is_ascii_encoding(rv): - if not _warned_about_filesystem_encoding: - warnings.warn( - 'Detected a misconfigured UNIX filesystem: Will use UTF-8 as ' - 'filesystem encoding instead of {0!r}'.format(rv), - BrokenFilesystemWarning) - _warned_about_filesystem_encoding = True - return 'utf-8' - return rv diff --git a/pyextra/werkzeug/formparser.py b/pyextra/werkzeug/formparser.py deleted file mode 100644 index c56859e905d65b..00000000000000 --- a/pyextra/werkzeug/formparser.py +++ /dev/null @@ -1,534 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.formparser - ~~~~~~~~~~~~~~~~~~~ - - This module implements the form parsing. It supports url-encoded forms - as well as non-nested multipart uploads. - - :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -import re -import codecs - -# there are some platforms where SpooledTemporaryFile is not available. -# In that case we need to provide a fallback. -try: - from tempfile import SpooledTemporaryFile -except ImportError: - from tempfile import TemporaryFile - SpooledTemporaryFile = None - -from itertools import chain, repeat, tee -from functools import update_wrapper - -from werkzeug._compat import to_native, text_type, BytesIO -from werkzeug.urls import url_decode_stream -from werkzeug.wsgi import make_line_iter, \ - get_input_stream, get_content_length -from werkzeug.datastructures import Headers, FileStorage, MultiDict -from werkzeug.http import parse_options_header - - -#: an iterator that yields empty strings -_empty_string_iter = repeat('') - -#: a regular expression for multipart boundaries -_multipart_boundary_re = re.compile('^[ -~]{0,200}[!-~]$') - -#: supported http encodings that are also available in python we support -#: for multipart messages. -_supported_multipart_encodings = frozenset(['base64', 'quoted-printable']) - - -def default_stream_factory(total_content_length, filename, content_type, - content_length=None): - """The stream factory that is used per default.""" - max_size = 1024 * 500 - if SpooledTemporaryFile is not None: - return SpooledTemporaryFile(max_size=max_size, mode='wb+') - if total_content_length is None or total_content_length > max_size: - return TemporaryFile('wb+') - return BytesIO() - - -def parse_form_data(environ, stream_factory=None, charset='utf-8', - errors='replace', max_form_memory_size=None, - max_content_length=None, cls=None, - silent=True): - """Parse the form data in the environ and return it as tuple in the form - ``(stream, form, files)``. You should only call this method if the - transport method is `POST`, `PUT`, or `PATCH`. - - If the mimetype of the data transmitted is `multipart/form-data` the - files multidict will be filled with `FileStorage` objects. If the - mimetype is unknown the input stream is wrapped and returned as first - argument, else the stream is empty. - - This is a shortcut for the common usage of :class:`FormDataParser`. - - Have a look at :ref:`dealing-with-request-data` for more details. - - .. versionadded:: 0.5 - The `max_form_memory_size`, `max_content_length` and - `cls` parameters were added. - - .. versionadded:: 0.5.1 - The optional `silent` flag was added. - - :param environ: the WSGI environment to be used for parsing. - :param stream_factory: An optional callable that returns a new read and - writeable file descriptor. This callable works - the same as :meth:`~BaseResponse._get_file_stream`. - :param charset: The character set for URL and url encoded form data. - :param errors: The encoding error behavior. - :param max_form_memory_size: the maximum number of bytes to be accepted for - in-memory stored form data. If the data - exceeds the value specified an - :exc:`~exceptions.RequestEntityTooLarge` - exception is raised. - :param max_content_length: If this is provided and the transmitted data - is longer than this value an - :exc:`~exceptions.RequestEntityTooLarge` - exception is raised. - :param cls: an optional dict class to use. If this is not specified - or `None` the default :class:`MultiDict` is used. - :param silent: If set to False parsing errors will not be caught. - :return: A tuple in the form ``(stream, form, files)``. - """ - return FormDataParser(stream_factory, charset, errors, - max_form_memory_size, max_content_length, - cls, silent).parse_from_environ(environ) - - -def exhaust_stream(f): - """Helper decorator for methods that exhausts the stream on return.""" - - def wrapper(self, stream, *args, **kwargs): - try: - return f(self, stream, *args, **kwargs) - finally: - exhaust = getattr(stream, 'exhaust', None) - if exhaust is not None: - exhaust() - else: - while 1: - chunk = stream.read(1024 * 64) - if not chunk: - break - return update_wrapper(wrapper, f) - - -class FormDataParser(object): - - """This class implements parsing of form data for Werkzeug. By itself - it can parse multipart and url encoded form data. It can be subclassed - and extended but for most mimetypes it is a better idea to use the - untouched stream and expose it as separate attributes on a request - object. - - .. versionadded:: 0.8 - - :param stream_factory: An optional callable that returns a new read and - writeable file descriptor. This callable works - the same as :meth:`~BaseResponse._get_file_stream`. - :param charset: The character set for URL and url encoded form data. - :param errors: The encoding error behavior. - :param max_form_memory_size: the maximum number of bytes to be accepted for - in-memory stored form data. If the data - exceeds the value specified an - :exc:`~exceptions.RequestEntityTooLarge` - exception is raised. - :param max_content_length: If this is provided and the transmitted data - is longer than this value an - :exc:`~exceptions.RequestEntityTooLarge` - exception is raised. - :param cls: an optional dict class to use. If this is not specified - or `None` the default :class:`MultiDict` is used. - :param silent: If set to False parsing errors will not be caught. - """ - - def __init__(self, stream_factory=None, charset='utf-8', - errors='replace', max_form_memory_size=None, - max_content_length=None, cls=None, - silent=True): - if stream_factory is None: - stream_factory = default_stream_factory - self.stream_factory = stream_factory - self.charset = charset - self.errors = errors - self.max_form_memory_size = max_form_memory_size - self.max_content_length = max_content_length - if cls is None: - cls = MultiDict - self.cls = cls - self.silent = silent - - def get_parse_func(self, mimetype, options): - return self.parse_functions.get(mimetype) - - def parse_from_environ(self, environ): - """Parses the information from the environment as form data. - - :param environ: the WSGI environment to be used for parsing. - :return: A tuple in the form ``(stream, form, files)``. - """ - content_type = environ.get('CONTENT_TYPE', '') - content_length = get_content_length(environ) - mimetype, options = parse_options_header(content_type) - return self.parse(get_input_stream(environ), mimetype, - content_length, options) - - def parse(self, stream, mimetype, content_length, options=None): - """Parses the information from the given stream, mimetype, - content length and mimetype parameters. - - :param stream: an input stream - :param mimetype: the mimetype of the data - :param content_length: the content length of the incoming data - :param options: optional mimetype parameters (used for - the multipart boundary for instance) - :return: A tuple in the form ``(stream, form, files)``. - """ - if self.max_content_length is not None and \ - content_length is not None and \ - content_length > self.max_content_length: - raise exceptions.RequestEntityTooLarge() - if options is None: - options = {} - - parse_func = self.get_parse_func(mimetype, options) - if parse_func is not None: - try: - return parse_func(self, stream, mimetype, - content_length, options) - except ValueError: - if not self.silent: - raise - - return stream, self.cls(), self.cls() - - @exhaust_stream - def _parse_multipart(self, stream, mimetype, content_length, options): - parser = MultiPartParser(self.stream_factory, self.charset, self.errors, - max_form_memory_size=self.max_form_memory_size, - cls=self.cls) - boundary = options.get('boundary') - if boundary is None: - raise ValueError('Missing boundary') - if isinstance(boundary, text_type): - boundary = boundary.encode('ascii') - form, files = parser.parse(stream, boundary, content_length) - return stream, form, files - - @exhaust_stream - def _parse_urlencoded(self, stream, mimetype, content_length, options): - if self.max_form_memory_size is not None and \ - content_length is not None and \ - content_length > self.max_form_memory_size: - raise exceptions.RequestEntityTooLarge() - form = url_decode_stream(stream, self.charset, - errors=self.errors, cls=self.cls) - return stream, form, self.cls() - - #: mapping of mimetypes to parsing functions - parse_functions = { - 'multipart/form-data': _parse_multipart, - 'application/x-www-form-urlencoded': _parse_urlencoded, - 'application/x-url-encoded': _parse_urlencoded - } - - -def is_valid_multipart_boundary(boundary): - """Checks if the string given is a valid multipart boundary.""" - return _multipart_boundary_re.match(boundary) is not None - - -def _line_parse(line): - """Removes line ending characters and returns a tuple (`stripped_line`, - `is_terminated`). - """ - if line[-2:] in ['\r\n', b'\r\n']: - return line[:-2], True - elif line[-1:] in ['\r', '\n', b'\r', b'\n']: - return line[:-1], True - return line, False - - -def parse_multipart_headers(iterable): - """Parses multipart headers from an iterable that yields lines (including - the trailing newline symbol). The iterable has to be newline terminated. - - The iterable will stop at the line where the headers ended so it can be - further consumed. - - :param iterable: iterable of strings that are newline terminated - """ - result = [] - for line in iterable: - line = to_native(line) - line, line_terminated = _line_parse(line) - if not line_terminated: - raise ValueError('unexpected end of line in multipart header') - if not line: - break - elif line[0] in ' \t' and result: - key, value = result[-1] - result[-1] = (key, value + '\n ' + line[1:]) - else: - parts = line.split(':', 1) - if len(parts) == 2: - result.append((parts[0].strip(), parts[1].strip())) - - # we link the list to the headers, no need to create a copy, the - # list was not shared anyways. - return Headers(result) - - -_begin_form = 'begin_form' -_begin_file = 'begin_file' -_cont = 'cont' -_end = 'end' - - -class MultiPartParser(object): - - def __init__(self, stream_factory=None, charset='utf-8', errors='replace', - max_form_memory_size=None, cls=None, buffer_size=64 * 1024): - self.charset = charset - self.errors = errors - self.max_form_memory_size = max_form_memory_size - self.stream_factory = default_stream_factory if stream_factory is None else stream_factory - self.cls = MultiDict if cls is None else cls - - # make sure the buffer size is divisible by four so that we can base64 - # decode chunk by chunk - assert buffer_size % 4 == 0, 'buffer size has to be divisible by 4' - # also the buffer size has to be at least 1024 bytes long or long headers - # will freak out the system - assert buffer_size >= 1024, 'buffer size has to be at least 1KB' - - self.buffer_size = buffer_size - - def _fix_ie_filename(self, filename): - """Internet Explorer 6 transmits the full file name if a file is - uploaded. This function strips the full path if it thinks the - filename is Windows-like absolute. - """ - if filename[1:3] == ':\\' or filename[:2] == '\\\\': - return filename.split('\\')[-1] - return filename - - def _find_terminator(self, iterator): - """The terminator might have some additional newlines before it. - There is at least one application that sends additional newlines - before headers (the python setuptools package). - """ - for line in iterator: - if not line: - break - line = line.strip() - if line: - return line - return b'' - - def fail(self, message): - raise ValueError(message) - - def get_part_encoding(self, headers): - transfer_encoding = headers.get('content-transfer-encoding') - if transfer_encoding is not None and \ - transfer_encoding in _supported_multipart_encodings: - return transfer_encoding - - def get_part_charset(self, headers): - # Figure out input charset for current part - content_type = headers.get('content-type') - if content_type: - mimetype, ct_params = parse_options_header(content_type) - return ct_params.get('charset', self.charset) - return self.charset - - def start_file_streaming(self, filename, headers, total_content_length): - if isinstance(filename, bytes): - filename = filename.decode(self.charset, self.errors) - filename = self._fix_ie_filename(filename) - content_type = headers.get('content-type') - try: - content_length = int(headers['content-length']) - except (KeyError, ValueError): - content_length = 0 - container = self.stream_factory(total_content_length, content_type, - filename, content_length) - return filename, container - - def in_memory_threshold_reached(self, bytes): - raise exceptions.RequestEntityTooLarge() - - def validate_boundary(self, boundary): - if not boundary: - self.fail('Missing boundary') - if not is_valid_multipart_boundary(boundary): - self.fail('Invalid boundary: %s' % boundary) - if len(boundary) > self.buffer_size: # pragma: no cover - # this should never happen because we check for a minimum size - # of 1024 and boundaries may not be longer than 200. The only - # situation when this happens is for non debug builds where - # the assert is skipped. - self.fail('Boundary longer than buffer size') - - def parse_lines(self, file, boundary, content_length, cap_at_buffer=True): - """Generate parts of - ``('begin_form', (headers, name))`` - ``('begin_file', (headers, name, filename))`` - ``('cont', bytestring)`` - ``('end', None)`` - - Always obeys the grammar - parts = ( begin_form cont* end | - begin_file cont* end )* - """ - next_part = b'--' + boundary - last_part = next_part + b'--' - - iterator = chain(make_line_iter(file, limit=content_length, - buffer_size=self.buffer_size, - cap_at_buffer=cap_at_buffer), - _empty_string_iter) - - terminator = self._find_terminator(iterator) - - if terminator == last_part: - return - elif terminator != next_part: - self.fail('Expected boundary at start of multipart data') - - while terminator != last_part: - headers = parse_multipart_headers(iterator) - - disposition = headers.get('content-disposition') - if disposition is None: - self.fail('Missing Content-Disposition header') - disposition, extra = parse_options_header(disposition) - transfer_encoding = self.get_part_encoding(headers) - name = extra.get('name') - - # Accept filename* to support non-ascii filenames as per rfc2231 - filename = extra.get('filename') or extra.get('filename*') - - # if no content type is given we stream into memory. A list is - # used as a temporary container. - if filename is None: - yield _begin_form, (headers, name) - - # otherwise we parse the rest of the headers and ask the stream - # factory for something we can write in. - else: - yield _begin_file, (headers, name, filename) - - buf = b'' - for line in iterator: - if not line: - self.fail('unexpected end of stream') - - if line[:2] == b'--': - terminator = line.rstrip() - if terminator in (next_part, last_part): - break - - if transfer_encoding is not None: - if transfer_encoding == 'base64': - transfer_encoding = 'base64_codec' - try: - line = codecs.decode(line, transfer_encoding) - except Exception: - self.fail('could not decode transfer encoded chunk') - - # we have something in the buffer from the last iteration. - # this is usually a newline delimiter. - if buf: - yield _cont, buf - buf = b'' - - # If the line ends with windows CRLF we write everything except - # the last two bytes. In all other cases however we write - # everything except the last byte. If it was a newline, that's - # fine, otherwise it does not matter because we will write it - # the next iteration. this ensures we do not write the - # final newline into the stream. That way we do not have to - # truncate the stream. However we do have to make sure that - # if something else than a newline is in there we write it - # out. - if line[-2:] == b'\r\n': - buf = b'\r\n' - cutoff = -2 - else: - buf = line[-1:] - cutoff = -1 - yield _cont, line[:cutoff] - - else: # pragma: no cover - raise ValueError('unexpected end of part') - - # if we have a leftover in the buffer that is not a newline - # character we have to flush it, otherwise we will chop of - # certain values. - if buf not in (b'', b'\r', b'\n', b'\r\n'): - yield _cont, buf - - yield _end, None - - def parse_parts(self, file, boundary, content_length): - """Generate ``('file', (name, val))`` and - ``('form', (name, val))`` parts. - """ - in_memory = 0 - - for ellt, ell in self.parse_lines(file, boundary, content_length): - if ellt == _begin_file: - headers, name, filename = ell - is_file = True - guard_memory = False - filename, container = self.start_file_streaming( - filename, headers, content_length) - _write = container.write - - elif ellt == _begin_form: - headers, name = ell - is_file = False - container = [] - _write = container.append - guard_memory = self.max_form_memory_size is not None - - elif ellt == _cont: - _write(ell) - # if we write into memory and there is a memory size limit we - # count the number of bytes in memory and raise an exception if - # there is too much data in memory. - if guard_memory: - in_memory += len(ell) - if in_memory > self.max_form_memory_size: - self.in_memory_threshold_reached(in_memory) - - elif ellt == _end: - if is_file: - container.seek(0) - yield ('file', - (name, FileStorage(container, filename, name, - headers=headers))) - else: - part_charset = self.get_part_charset(headers) - yield ('form', - (name, b''.join(container).decode( - part_charset, self.errors))) - - def parse(self, file, boundary, content_length): - formstream, filestream = tee( - self.parse_parts(file, boundary, content_length), 2) - form = (p[1] for p in formstream if p[0] == 'form') - files = (p[1] for p in filestream if p[0] == 'file') - return self.cls(form), self.cls(files) - - -from werkzeug import exceptions diff --git a/pyextra/werkzeug/http.py b/pyextra/werkzeug/http.py deleted file mode 100644 index 22197221c8fa3b..00000000000000 --- a/pyextra/werkzeug/http.py +++ /dev/null @@ -1,1158 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.http - ~~~~~~~~~~~~~ - - Werkzeug comes with a bunch of utilities that help Werkzeug to deal with - HTTP data. Most of the classes and functions provided by this module are - used by the wrappers, but they are useful on their own, too, especially if - the response and request objects are not used. - - This covers some of the more HTTP centric features of WSGI, some other - utilities such as cookie handling are documented in the `werkzeug.utils` - module. - - - :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -import re -import warnings -from time import time, gmtime -try: - from email.utils import parsedate_tz -except ImportError: # pragma: no cover - from email.Utils import parsedate_tz -try: - from urllib.request import parse_http_list as _parse_list_header - from urllib.parse import unquote_to_bytes as _unquote -except ImportError: # pragma: no cover - from urllib2 import parse_http_list as _parse_list_header, \ - unquote as _unquote -from datetime import datetime, timedelta -from hashlib import md5 -import base64 - -from werkzeug._internal import _cookie_quote, _make_cookie_domain, \ - _cookie_parse_impl -from werkzeug._compat import to_unicode, iteritems, text_type, \ - string_types, try_coerce_native, to_bytes, PY2, \ - integer_types - - -_cookie_charset = 'latin1' -# for explanation of "media-range", etc. see Sections 5.3.{1,2} of RFC 7231 -_accept_re = re.compile( - r'''( # media-range capturing-parenthesis - [^\s;,]+ # type/subtype - (?:[ \t]*;[ \t]* # ";" - (?: # parameter non-capturing-parenthesis - [^\s;,q][^\s;,]* # token that doesn't start with "q" - | # or - q[^\s;,=][^\s;,]* # token that is more than just "q" - ) - )* # zero or more parameters - ) # end of media-range - (?:[ \t]*;[ \t]*q= # weight is a "q" parameter - (\d*(?:\.\d+)?) # qvalue capturing-parentheses - [^,]* # "extension" accept params: who cares? - )? # accept params are optional - ''', re.VERBOSE) -_token_chars = frozenset("!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - '^_`abcdefghijklmnopqrstuvwxyz|~') -_etag_re = re.compile(r'([Ww]/)?(?:"(.*?)"|(.*?))(?:\s*,\s*|$)') -_unsafe_header_chars = set('()<>@,;:\"/[]?={} \t') -_option_header_piece_re = re.compile(r''' - ;\s* - (?P - "[^"\\]*(?:\\.[^"\\]*)*" # quoted string - | - [^\s;,=*]+ # token - ) - \s* - (?: # optionally followed by =value - (?: # equals sign, possibly with encoding - \*\s*=\s* # * indicates extended notation - (?P[^\s]+?) - '(?P[^\s]*?)' - | - =\s* # basic notation - ) - (?P - "[^"\\]*(?:\\.[^"\\]*)*" # quoted string - | - [^;,]+ # token - )? - )? - \s* -''', flags=re.VERBOSE) -_option_header_start_mime_type = re.compile(r',\s*([^;,\s]+)([;,]\s*.+)?') - -_entity_headers = frozenset([ - 'allow', 'content-encoding', 'content-language', 'content-length', - 'content-location', 'content-md5', 'content-range', 'content-type', - 'expires', 'last-modified' -]) -_hop_by_hop_headers = frozenset([ - 'connection', 'keep-alive', 'proxy-authenticate', - 'proxy-authorization', 'te', 'trailer', 'transfer-encoding', - 'upgrade' -]) - - -HTTP_STATUS_CODES = { - 100: 'Continue', - 101: 'Switching Protocols', - 102: 'Processing', - 200: 'OK', - 201: 'Created', - 202: 'Accepted', - 203: 'Non Authoritative Information', - 204: 'No Content', - 205: 'Reset Content', - 206: 'Partial Content', - 207: 'Multi Status', - 226: 'IM Used', # see RFC 3229 - 300: 'Multiple Choices', - 301: 'Moved Permanently', - 302: 'Found', - 303: 'See Other', - 304: 'Not Modified', - 305: 'Use Proxy', - 307: 'Temporary Redirect', - 400: 'Bad Request', - 401: 'Unauthorized', - 402: 'Payment Required', # unused - 403: 'Forbidden', - 404: 'Not Found', - 405: 'Method Not Allowed', - 406: 'Not Acceptable', - 407: 'Proxy Authentication Required', - 408: 'Request Timeout', - 409: 'Conflict', - 410: 'Gone', - 411: 'Length Required', - 412: 'Precondition Failed', - 413: 'Request Entity Too Large', - 414: 'Request URI Too Long', - 415: 'Unsupported Media Type', - 416: 'Requested Range Not Satisfiable', - 417: 'Expectation Failed', - 418: 'I\'m a teapot', # see RFC 2324 - 422: 'Unprocessable Entity', - 423: 'Locked', - 424: 'Failed Dependency', - 426: 'Upgrade Required', - 428: 'Precondition Required', # see RFC 6585 - 429: 'Too Many Requests', - 431: 'Request Header Fields Too Large', - 449: 'Retry With', # proprietary MS extension - 451: 'Unavailable For Legal Reasons', - 500: 'Internal Server Error', - 501: 'Not Implemented', - 502: 'Bad Gateway', - 503: 'Service Unavailable', - 504: 'Gateway Timeout', - 505: 'HTTP Version Not Supported', - 507: 'Insufficient Storage', - 510: 'Not Extended' -} - - -def wsgi_to_bytes(data): - """coerce wsgi unicode represented bytes to real ones - - """ - if isinstance(data, bytes): - return data - return data.encode('latin1') # XXX: utf8 fallback? - - -def bytes_to_wsgi(data): - assert isinstance(data, bytes), 'data must be bytes' - if isinstance(data, str): - return data - else: - return data.decode('latin1') - - -def quote_header_value(value, extra_chars='', allow_token=True): - """Quote a header value if necessary. - - .. versionadded:: 0.5 - - :param value: the value to quote. - :param extra_chars: a list of extra characters to skip quoting. - :param allow_token: if this is enabled token values are returned - unchanged. - """ - if isinstance(value, bytes): - value = bytes_to_wsgi(value) - value = str(value) - if allow_token: - token_chars = _token_chars | set(extra_chars) - if set(value).issubset(token_chars): - return value - return '"%s"' % value.replace('\\', '\\\\').replace('"', '\\"') - - -def unquote_header_value(value, is_filename=False): - r"""Unquotes a header value. (Reversal of :func:`quote_header_value`). - This does not use the real unquoting but what browsers are actually - using for quoting. - - .. versionadded:: 0.5 - - :param value: the header value to unquote. - """ - if value and value[0] == value[-1] == '"': - # this is not the real unquoting, but fixing this so that the - # RFC is met will result in bugs with internet explorer and - # probably some other browsers as well. IE for example is - # uploading files with "C:\foo\bar.txt" as filename - value = value[1:-1] - - # if this is a filename and the starting characters look like - # a UNC path, then just return the value without quotes. Using the - # replace sequence below on a UNC path has the effect of turning - # the leading double slash into a single slash and then - # _fix_ie_filename() doesn't work correctly. See #458. - if not is_filename or value[:2] != '\\\\': - return value.replace('\\\\', '\\').replace('\\"', '"') - return value - - -def dump_options_header(header, options): - """The reverse function to :func:`parse_options_header`. - - :param header: the header to dump - :param options: a dict of options to append. - """ - segments = [] - if header is not None: - segments.append(header) - for key, value in iteritems(options): - if value is None: - segments.append(key) - else: - segments.append('%s=%s' % (key, quote_header_value(value))) - return '; '.join(segments) - - -def dump_header(iterable, allow_token=True): - """Dump an HTTP header again. This is the reversal of - :func:`parse_list_header`, :func:`parse_set_header` and - :func:`parse_dict_header`. This also quotes strings that include an - equals sign unless you pass it as dict of key, value pairs. - - >>> dump_header({'foo': 'bar baz'}) - 'foo="bar baz"' - >>> dump_header(('foo', 'bar baz')) - 'foo, "bar baz"' - - :param iterable: the iterable or dict of values to quote. - :param allow_token: if set to `False` tokens as values are disallowed. - See :func:`quote_header_value` for more details. - """ - if isinstance(iterable, dict): - items = [] - for key, value in iteritems(iterable): - if value is None: - items.append(key) - else: - items.append('%s=%s' % ( - key, - quote_header_value(value, allow_token=allow_token) - )) - else: - items = [quote_header_value(x, allow_token=allow_token) - for x in iterable] - return ', '.join(items) - - -def parse_list_header(value): - """Parse lists as described by RFC 2068 Section 2. - - In particular, parse comma-separated lists where the elements of - the list may include quoted-strings. A quoted-string could - contain a comma. A non-quoted string could have quotes in the - middle. Quotes are removed automatically after parsing. - - It basically works like :func:`parse_set_header` just that items - may appear multiple times and case sensitivity is preserved. - - The return value is a standard :class:`list`: - - >>> parse_list_header('token, "quoted value"') - ['token', 'quoted value'] - - To create a header from the :class:`list` again, use the - :func:`dump_header` function. - - :param value: a string with a list header. - :return: :class:`list` - """ - result = [] - for item in _parse_list_header(value): - if item[:1] == item[-1:] == '"': - item = unquote_header_value(item[1:-1]) - result.append(item) - return result - - -def parse_dict_header(value, cls=dict): - """Parse lists of key, value pairs as described by RFC 2068 Section 2 and - convert them into a python dict (or any other mapping object created from - the type with a dict like interface provided by the `cls` argument): - - >>> d = parse_dict_header('foo="is a fish", bar="as well"') - >>> type(d) is dict - True - >>> sorted(d.items()) - [('bar', 'as well'), ('foo', 'is a fish')] - - If there is no value for a key it will be `None`: - - >>> parse_dict_header('key_without_value') - {'key_without_value': None} - - To create a header from the :class:`dict` again, use the - :func:`dump_header` function. - - .. versionchanged:: 0.9 - Added support for `cls` argument. - - :param value: a string with a dict header. - :param cls: callable to use for storage of parsed results. - :return: an instance of `cls` - """ - result = cls() - if not isinstance(value, text_type): - # XXX: validate - value = bytes_to_wsgi(value) - for item in _parse_list_header(value): - if '=' not in item: - result[item] = None - continue - name, value = item.split('=', 1) - if value[:1] == value[-1:] == '"': - value = unquote_header_value(value[1:-1]) - result[name] = value - return result - - -def parse_options_header(value, multiple=False): - """Parse a ``Content-Type`` like header into a tuple with the content - type and the options: - - >>> parse_options_header('text/html; charset=utf8') - ('text/html', {'charset': 'utf8'}) - - This should not be used to parse ``Cache-Control`` like headers that use - a slightly different format. For these headers use the - :func:`parse_dict_header` function. - - .. versionadded:: 0.5 - - :param value: the header to parse. - :param multiple: Whether try to parse and return multiple MIME types - :return: (mimetype, options) or (mimetype, options, mimetype, options, …) - if multiple=True - """ - if not value: - return '', {} - - result = [] - - value = "," + value.replace("\n", ",") - while value: - match = _option_header_start_mime_type.match(value) - if not match: - break - result.append(match.group(1)) # mimetype - options = {} - # Parse options - rest = match.group(2) - while rest: - optmatch = _option_header_piece_re.match(rest) - if not optmatch: - break - option, encoding, _, option_value = optmatch.groups() - option = unquote_header_value(option) - if option_value is not None: - option_value = unquote_header_value( - option_value, - option == 'filename') - if encoding is not None: - option_value = _unquote(option_value).decode(encoding) - options[option] = option_value - rest = rest[optmatch.end():] - result.append(options) - if multiple is False: - return tuple(result) - value = rest - - return tuple(result) if result else ('', {}) - - -def parse_accept_header(value, cls=None): - """Parses an HTTP Accept-* header. This does not implement a complete - valid algorithm but one that supports at least value and quality - extraction. - - Returns a new :class:`Accept` object (basically a list of ``(value, quality)`` - tuples sorted by the quality with some additional accessor methods). - - The second parameter can be a subclass of :class:`Accept` that is created - with the parsed values and returned. - - :param value: the accept header string to be parsed. - :param cls: the wrapper class for the return value (can be - :class:`Accept` or a subclass thereof) - :return: an instance of `cls`. - """ - if cls is None: - cls = Accept - - if not value: - return cls(None) - - result = [] - for match in _accept_re.finditer(value): - quality = match.group(2) - if not quality: - quality = 1 - else: - quality = max(min(float(quality), 1), 0) - result.append((match.group(1), quality)) - return cls(result) - - -def parse_cache_control_header(value, on_update=None, cls=None): - """Parse a cache control header. The RFC differs between response and - request cache control, this method does not. It's your responsibility - to not use the wrong control statements. - - .. versionadded:: 0.5 - The `cls` was added. If not specified an immutable - :class:`~werkzeug.datastructures.RequestCacheControl` is returned. - - :param value: a cache control header to be parsed. - :param on_update: an optional callable that is called every time a value - on the :class:`~werkzeug.datastructures.CacheControl` - object is changed. - :param cls: the class for the returned object. By default - :class:`~werkzeug.datastructures.RequestCacheControl` is used. - :return: a `cls` object. - """ - if cls is None: - cls = RequestCacheControl - if not value: - return cls(None, on_update) - return cls(parse_dict_header(value), on_update) - - -def parse_set_header(value, on_update=None): - """Parse a set-like header and return a - :class:`~werkzeug.datastructures.HeaderSet` object: - - >>> hs = parse_set_header('token, "quoted value"') - - The return value is an object that treats the items case-insensitively - and keeps the order of the items: - - >>> 'TOKEN' in hs - True - >>> hs.index('quoted value') - 1 - >>> hs - HeaderSet(['token', 'quoted value']) - - To create a header from the :class:`HeaderSet` again, use the - :func:`dump_header` function. - - :param value: a set header to be parsed. - :param on_update: an optional callable that is called every time a - value on the :class:`~werkzeug.datastructures.HeaderSet` - object is changed. - :return: a :class:`~werkzeug.datastructures.HeaderSet` - """ - if not value: - return HeaderSet(None, on_update) - return HeaderSet(parse_list_header(value), on_update) - - -def parse_authorization_header(value): - """Parse an HTTP basic/digest authorization header transmitted by the web - browser. The return value is either `None` if the header was invalid or - not given, otherwise an :class:`~werkzeug.datastructures.Authorization` - object. - - :param value: the authorization header to parse. - :return: a :class:`~werkzeug.datastructures.Authorization` object or `None`. - """ - if not value: - return - value = wsgi_to_bytes(value) - try: - auth_type, auth_info = value.split(None, 1) - auth_type = auth_type.lower() - except ValueError: - return - if auth_type == b'basic': - try: - username, password = base64.b64decode(auth_info).split(b':', 1) - except Exception: - return - return Authorization('basic', {'username': bytes_to_wsgi(username), - 'password': bytes_to_wsgi(password)}) - elif auth_type == b'digest': - auth_map = parse_dict_header(auth_info) - for key in 'username', 'realm', 'nonce', 'uri', 'response': - if key not in auth_map: - return - if 'qop' in auth_map: - if not auth_map.get('nc') or not auth_map.get('cnonce'): - return - return Authorization('digest', auth_map) - - -def parse_www_authenticate_header(value, on_update=None): - """Parse an HTTP WWW-Authenticate header into a - :class:`~werkzeug.datastructures.WWWAuthenticate` object. - - :param value: a WWW-Authenticate header to parse. - :param on_update: an optional callable that is called every time a value - on the :class:`~werkzeug.datastructures.WWWAuthenticate` - object is changed. - :return: a :class:`~werkzeug.datastructures.WWWAuthenticate` object. - """ - if not value: - return WWWAuthenticate(on_update=on_update) - try: - auth_type, auth_info = value.split(None, 1) - auth_type = auth_type.lower() - except (ValueError, AttributeError): - return WWWAuthenticate(value.strip().lower(), on_update=on_update) - return WWWAuthenticate(auth_type, parse_dict_header(auth_info), - on_update) - - -def parse_if_range_header(value): - """Parses an if-range header which can be an etag or a date. Returns - a :class:`~werkzeug.datastructures.IfRange` object. - - .. versionadded:: 0.7 - """ - if not value: - return IfRange() - date = parse_date(value) - if date is not None: - return IfRange(date=date) - # drop weakness information - return IfRange(unquote_etag(value)[0]) - - -def parse_range_header(value, make_inclusive=True): - """Parses a range header into a :class:`~werkzeug.datastructures.Range` - object. If the header is missing or malformed `None` is returned. - `ranges` is a list of ``(start, stop)`` tuples where the ranges are - non-inclusive. - - .. versionadded:: 0.7 - """ - if not value or '=' not in value: - return None - - ranges = [] - last_end = 0 - units, rng = value.split('=', 1) - units = units.strip().lower() - - for item in rng.split(','): - item = item.strip() - if '-' not in item: - return None - if item.startswith('-'): - if last_end < 0: - return None - try: - begin = int(item) - except ValueError: - return None - end = None - last_end = -1 - elif '-' in item: - begin, end = item.split('-', 1) - begin = begin.strip() - end = end.strip() - if not begin.isdigit(): - return None - begin = int(begin) - if begin < last_end or last_end < 0: - return None - if end: - if not end.isdigit(): - return None - end = int(end) + 1 - if begin >= end: - return None - else: - end = None - last_end = end - ranges.append((begin, end)) - - return Range(units, ranges) - - -def parse_content_range_header(value, on_update=None): - """Parses a range header into a - :class:`~werkzeug.datastructures.ContentRange` object or `None` if - parsing is not possible. - - .. versionadded:: 0.7 - - :param value: a content range header to be parsed. - :param on_update: an optional callable that is called every time a value - on the :class:`~werkzeug.datastructures.ContentRange` - object is changed. - """ - if value is None: - return None - try: - units, rangedef = (value or '').strip().split(None, 1) - except ValueError: - return None - - if '/' not in rangedef: - return None - rng, length = rangedef.split('/', 1) - if length == '*': - length = None - elif length.isdigit(): - length = int(length) - else: - return None - - if rng == '*': - return ContentRange(units, None, None, length, on_update=on_update) - elif '-' not in rng: - return None - - start, stop = rng.split('-', 1) - try: - start = int(start) - stop = int(stop) + 1 - except ValueError: - return None - - if is_byte_range_valid(start, stop, length): - return ContentRange(units, start, stop, length, on_update=on_update) - - -def quote_etag(etag, weak=False): - """Quote an etag. - - :param etag: the etag to quote. - :param weak: set to `True` to tag it "weak". - """ - if '"' in etag: - raise ValueError('invalid etag') - etag = '"%s"' % etag - if weak: - etag = 'W/' + etag - return etag - - -def unquote_etag(etag): - """Unquote a single etag: - - >>> unquote_etag('W/"bar"') - ('bar', True) - >>> unquote_etag('"bar"') - ('bar', False) - - :param etag: the etag identifier to unquote. - :return: a ``(etag, weak)`` tuple. - """ - if not etag: - return None, None - etag = etag.strip() - weak = False - if etag.startswith(('W/', 'w/')): - weak = True - etag = etag[2:] - if etag[:1] == etag[-1:] == '"': - etag = etag[1:-1] - return etag, weak - - -def parse_etags(value): - """Parse an etag header. - - :param value: the tag header to parse - :return: an :class:`~werkzeug.datastructures.ETags` object. - """ - if not value: - return ETags() - strong = [] - weak = [] - end = len(value) - pos = 0 - while pos < end: - match = _etag_re.match(value, pos) - if match is None: - break - is_weak, quoted, raw = match.groups() - if raw == '*': - return ETags(star_tag=True) - elif quoted: - raw = quoted - if is_weak: - weak.append(raw) - else: - strong.append(raw) - pos = match.end() - return ETags(strong, weak) - - -def generate_etag(data): - """Generate an etag for some data.""" - return md5(data).hexdigest() - - -def parse_date(value): - """Parse one of the following date formats into a datetime object: - - .. sourcecode:: text - - Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 - Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 - Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format - - If parsing fails the return value is `None`. - - :param value: a string with a supported date format. - :return: a :class:`datetime.datetime` object. - """ - if value: - t = parsedate_tz(value.strip()) - if t is not None: - try: - year = t[0] - # unfortunately that function does not tell us if two digit - # years were part of the string, or if they were prefixed - # with two zeroes. So what we do is to assume that 69-99 - # refer to 1900, and everything below to 2000 - if year >= 0 and year <= 68: - year += 2000 - elif year >= 69 and year <= 99: - year += 1900 - return datetime(*((year,) + t[1:7])) - \ - timedelta(seconds=t[-1] or 0) - except (ValueError, OverflowError): - return None - - -def _dump_date(d, delim): - """Used for `http_date` and `cookie_date`.""" - if d is None: - d = gmtime() - elif isinstance(d, datetime): - d = d.utctimetuple() - elif isinstance(d, (integer_types, float)): - d = gmtime(d) - return '%s, %02d%s%s%s%s %02d:%02d:%02d GMT' % ( - ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')[d.tm_wday], - d.tm_mday, delim, - ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec')[d.tm_mon - 1], - delim, str(d.tm_year), d.tm_hour, d.tm_min, d.tm_sec - ) - - -def cookie_date(expires=None): - """Formats the time to ensure compatibility with Netscape's cookie - standard. - - Accepts a floating point number expressed in seconds since the epoch in, a - datetime object or a timetuple. All times in UTC. The :func:`parse_date` - function can be used to parse such a date. - - Outputs a string in the format ``Wdy, DD-Mon-YYYY HH:MM:SS GMT``. - - :param expires: If provided that date is used, otherwise the current. - """ - return _dump_date(expires, '-') - - -def http_date(timestamp=None): - """Formats the time to match the RFC1123 date format. - - Accepts a floating point number expressed in seconds since the epoch in, a - datetime object or a timetuple. All times in UTC. The :func:`parse_date` - function can be used to parse such a date. - - Outputs a string in the format ``Wdy, DD Mon YYYY HH:MM:SS GMT``. - - :param timestamp: If provided that date is used, otherwise the current. - """ - return _dump_date(timestamp, ' ') - - -def parse_age(value=None): - """Parses a base-10 integer count of seconds into a timedelta. - - If parsing fails, the return value is `None`. - - :param value: a string consisting of an integer represented in base-10 - :return: a :class:`datetime.timedelta` object or `None`. - """ - if not value: - return None - try: - seconds = int(value) - except ValueError: - return None - if seconds < 0: - return None - try: - return timedelta(seconds=seconds) - except OverflowError: - return None - - -def dump_age(age=None): - """Formats the duration as a base-10 integer. - - :param age: should be an integer number of seconds, - a :class:`datetime.timedelta` object, or, - if the age is unknown, `None` (default). - """ - if age is None: - return - if isinstance(age, timedelta): - # do the equivalent of Python 2.7's timedelta.total_seconds(), - # but disregarding fractional seconds - age = age.seconds + (age.days * 24 * 3600) - - age = int(age) - if age < 0: - raise ValueError('age cannot be negative') - - return str(age) - - -def is_resource_modified(environ, etag=None, data=None, last_modified=None, - ignore_if_range=True): - """Convenience method for conditional requests. - - :param environ: the WSGI environment of the request to be checked. - :param etag: the etag for the response for comparison. - :param data: or alternatively the data of the response to automatically - generate an etag using :func:`generate_etag`. - :param last_modified: an optional date of the last modification. - :param ignore_if_range: If `False`, `If-Range` header will be taken into - account. - :return: `True` if the resource was modified, otherwise `False`. - """ - if etag is None and data is not None: - etag = generate_etag(data) - elif data is not None: - raise TypeError('both data and etag given') - if environ['REQUEST_METHOD'] not in ('GET', 'HEAD'): - return False - - unmodified = False - if isinstance(last_modified, string_types): - last_modified = parse_date(last_modified) - - # ensure that microsecond is zero because the HTTP spec does not transmit - # that either and we might have some false positives. See issue #39 - if last_modified is not None: - last_modified = last_modified.replace(microsecond=0) - - if_range = None - if not ignore_if_range and 'HTTP_RANGE' in environ: - # http://tools.ietf.org/html/rfc7233#section-3.2 - # A server MUST ignore an If-Range header field received in a request - # that does not contain a Range header field. - if_range = parse_if_range_header(environ.get('HTTP_IF_RANGE')) - - if if_range is not None and if_range.date is not None: - modified_since = if_range.date - else: - modified_since = parse_date(environ.get('HTTP_IF_MODIFIED_SINCE')) - - if modified_since and last_modified and last_modified <= modified_since: - unmodified = True - - if etag: - etag, _ = unquote_etag(etag) - if if_range is not None and if_range.etag is not None: - unmodified = parse_etags(if_range.etag).contains(etag) - else: - if_none_match = parse_etags(environ.get('HTTP_IF_NONE_MATCH')) - if if_none_match: - # http://tools.ietf.org/html/rfc7232#section-3.2 - # "A recipient MUST use the weak comparison function when comparing - # entity-tags for If-None-Match" - unmodified = if_none_match.contains_weak(etag) - - # https://tools.ietf.org/html/rfc7232#section-3.1 - # "Origin server MUST use the strong comparison function when - # comparing entity-tags for If-Match" - if_match = parse_etags(environ.get('HTTP_IF_MATCH')) - if if_match: - unmodified = not if_match.is_strong(etag) - - return not unmodified - - -def remove_entity_headers(headers, allowed=('expires', 'content-location')): - """Remove all entity headers from a list or :class:`Headers` object. This - operation works in-place. `Expires` and `Content-Location` headers are - by default not removed. The reason for this is :rfc:`2616` section - 10.3.5 which specifies some entity headers that should be sent. - - .. versionchanged:: 0.5 - added `allowed` parameter. - - :param headers: a list or :class:`Headers` object. - :param allowed: a list of headers that should still be allowed even though - they are entity headers. - """ - allowed = set(x.lower() for x in allowed) - headers[:] = [(key, value) for key, value in headers if - not is_entity_header(key) or key.lower() in allowed] - - -def remove_hop_by_hop_headers(headers): - """Remove all HTTP/1.1 "Hop-by-Hop" headers from a list or - :class:`Headers` object. This operation works in-place. - - .. versionadded:: 0.5 - - :param headers: a list or :class:`Headers` object. - """ - headers[:] = [(key, value) for key, value in headers if - not is_hop_by_hop_header(key)] - - -def is_entity_header(header): - """Check if a header is an entity header. - - .. versionadded:: 0.5 - - :param header: the header to test. - :return: `True` if it's an entity header, `False` otherwise. - """ - return header.lower() in _entity_headers - - -def is_hop_by_hop_header(header): - """Check if a header is an HTTP/1.1 "Hop-by-Hop" header. - - .. versionadded:: 0.5 - - :param header: the header to test. - :return: `True` if it's an HTTP/1.1 "Hop-by-Hop" header, `False` otherwise. - """ - return header.lower() in _hop_by_hop_headers - - -def parse_cookie(header, charset='utf-8', errors='replace', cls=None): - """Parse a cookie. Either from a string or WSGI environ. - - Per default encoding errors are ignored. If you want a different behavior - you can set `errors` to ``'replace'`` or ``'strict'``. In strict mode a - :exc:`HTTPUnicodeError` is raised. - - .. versionchanged:: 0.5 - This function now returns a :class:`TypeConversionDict` instead of a - regular dict. The `cls` parameter was added. - - :param header: the header to be used to parse the cookie. Alternatively - this can be a WSGI environment. - :param charset: the charset for the cookie values. - :param errors: the error behavior for the charset decoding. - :param cls: an optional dict class to use. If this is not specified - or `None` the default :class:`TypeConversionDict` is - used. - """ - if isinstance(header, dict): - header = header.get('HTTP_COOKIE', '') - elif header is None: - header = '' - - # If the value is an unicode string it's mangled through latin1. This - # is done because on PEP 3333 on Python 3 all headers are assumed latin1 - # which however is incorrect for cookies, which are sent in page encoding. - # As a result we - if isinstance(header, text_type): - header = header.encode('latin1', 'replace') - - if cls is None: - cls = TypeConversionDict - - def _parse_pairs(): - for key, val in _cookie_parse_impl(header): - key = to_unicode(key, charset, errors, allow_none_charset=True) - val = to_unicode(val, charset, errors, allow_none_charset=True) - yield try_coerce_native(key), val - - return cls(_parse_pairs()) - - -def dump_cookie(key, value='', max_age=None, expires=None, path='/', - domain=None, secure=False, httponly=False, - charset='utf-8', sync_expires=True, max_size=4093, - samesite=None): - """Creates a new Set-Cookie header without the ``Set-Cookie`` prefix - The parameters are the same as in the cookie Morsel object in the - Python standard library but it accepts unicode data, too. - - On Python 3 the return value of this function will be a unicode - string, on Python 2 it will be a native string. In both cases the - return value is usually restricted to ascii as the vast majority of - values are properly escaped, but that is no guarantee. If a unicode - string is returned it's tunneled through latin1 as required by - PEP 3333. - - The return value is not ASCII safe if the key contains unicode - characters. This is technically against the specification but - happens in the wild. It's strongly recommended to not use - non-ASCII values for the keys. - - :param max_age: should be a number of seconds, or `None` (default) if - the cookie should last only as long as the client's - browser session. Additionally `timedelta` objects - are accepted, too. - :param expires: should be a `datetime` object or unix timestamp. - :param path: limits the cookie to a given path, per default it will - span the whole domain. - :param domain: Use this if you want to set a cross-domain cookie. For - example, ``domain=".example.com"`` will set a cookie - that is readable by the domain ``www.example.com``, - ``foo.example.com`` etc. Otherwise, a cookie will only - be readable by the domain that set it. - :param secure: The cookie will only be available via HTTPS - :param httponly: disallow JavaScript to access the cookie. This is an - extension to the cookie standard and probably not - supported by all browsers. - :param charset: the encoding for unicode values. - :param sync_expires: automatically set expires if max_age is defined - but expires not. - :param max_size: Warn if the final header value exceeds this size. The - default, 4093, should be safely `supported by most browsers - `_. Set to 0 to disable this check. - :param samesite: Limits the scope of the cookie such that it will only - be attached to requests if those requests are "same-site". - - .. _`cookie`: http://browsercookielimits.squawky.net/ - """ - key = to_bytes(key, charset) - value = to_bytes(value, charset) - - if path is not None: - path = iri_to_uri(path, charset) - domain = _make_cookie_domain(domain) - if isinstance(max_age, timedelta): - max_age = (max_age.days * 60 * 60 * 24) + max_age.seconds - if expires is not None: - if not isinstance(expires, string_types): - expires = cookie_date(expires) - elif max_age is not None and sync_expires: - expires = to_bytes(cookie_date(time() + max_age)) - - samesite = samesite.title() if samesite else None - if samesite not in ('Strict', 'Lax', None): - raise ValueError("invalid SameSite value; must be 'Strict', 'Lax' or None") - - buf = [key + b'=' + _cookie_quote(value)] - - # XXX: In theory all of these parameters that are not marked with `None` - # should be quoted. Because stdlib did not quote it before I did not - # want to introduce quoting there now. - for k, v, q in ((b'Domain', domain, True), - (b'Expires', expires, False,), - (b'Max-Age', max_age, False), - (b'Secure', secure, None), - (b'HttpOnly', httponly, None), - (b'Path', path, False), - (b'SameSite', samesite, False)): - if q is None: - if v: - buf.append(k) - continue - - if v is None: - continue - - tmp = bytearray(k) - if not isinstance(v, (bytes, bytearray)): - v = to_bytes(text_type(v), charset) - if q: - v = _cookie_quote(v) - tmp += b'=' + v - buf.append(bytes(tmp)) - - # The return value will be an incorrectly encoded latin1 header on - # Python 3 for consistency with the headers object and a bytestring - # on Python 2 because that's how the API makes more sense. - rv = b'; '.join(buf) - if not PY2: - rv = rv.decode('latin1') - - # Warn if the final value of the cookie is less than the limit. If the - # cookie is too large, then it may be silently ignored, which can be quite - # hard to debug. - cookie_size = len(rv) - - if max_size and cookie_size > max_size: - value_size = len(value) - warnings.warn( - 'The "{key}" cookie is too large: the value was {value_size} bytes' - ' but the header required {extra_size} extra bytes. The final size' - ' was {cookie_size} bytes but the limit is {max_size} bytes.' - ' Browsers may silently ignore cookies larger than this.'.format( - key=key, - value_size=value_size, - extra_size=cookie_size - value_size, - cookie_size=cookie_size, - max_size=max_size - ), - stacklevel=2 - ) - - return rv - - -def is_byte_range_valid(start, stop, length): - """Checks if a given byte content range is valid for the given length. - - .. versionadded:: 0.7 - """ - if (start is None) != (stop is None): - return False - elif start is None: - return length is None or length >= 0 - elif length is None: - return 0 <= start < stop - elif start >= stop: - return False - return 0 <= start < length - - -# circular dependency fun -from werkzeug.datastructures import Accept, HeaderSet, ETags, Authorization, \ - WWWAuthenticate, TypeConversionDict, IfRange, Range, ContentRange, \ - RequestCacheControl - - -# DEPRECATED -# backwards compatible imports -from werkzeug.datastructures import ( # noqa - MIMEAccept, CharsetAccept, LanguageAccept, Headers -) -from werkzeug.urls import iri_to_uri diff --git a/pyextra/werkzeug/local.py b/pyextra/werkzeug/local.py deleted file mode 100644 index e6d7478a0fd070..00000000000000 --- a/pyextra/werkzeug/local.py +++ /dev/null @@ -1,420 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.local - ~~~~~~~~~~~~~~ - - This module implements context-local objects. - - :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -import copy -from functools import update_wrapper -from werkzeug.wsgi import ClosingIterator -from werkzeug._compat import PY2, implements_bool - -# since each thread has its own greenlet we can just use those as identifiers -# for the context. If greenlets are not available we fall back to the -# current thread ident depending on where it is. -try: - from greenlet import getcurrent as get_ident -except ImportError: - try: - from thread import get_ident - except ImportError: - from _thread import get_ident - - -def release_local(local): - """Releases the contents of the local for the current context. - This makes it possible to use locals without a manager. - - Example:: - - >>> loc = Local() - >>> loc.foo = 42 - >>> release_local(loc) - >>> hasattr(loc, 'foo') - False - - With this function one can release :class:`Local` objects as well - as :class:`LocalStack` objects. However it is not possible to - release data held by proxies that way, one always has to retain - a reference to the underlying local object in order to be able - to release it. - - .. versionadded:: 0.6.1 - """ - local.__release_local__() - - -class Local(object): - __slots__ = ('__storage__', '__ident_func__') - - def __init__(self): - object.__setattr__(self, '__storage__', {}) - object.__setattr__(self, '__ident_func__', get_ident) - - def __iter__(self): - return iter(self.__storage__.items()) - - def __call__(self, proxy): - """Create a proxy for a name.""" - return LocalProxy(self, proxy) - - def __release_local__(self): - self.__storage__.pop(self.__ident_func__(), None) - - def __getattr__(self, name): - try: - return self.__storage__[self.__ident_func__()][name] - except KeyError: - raise AttributeError(name) - - def __setattr__(self, name, value): - ident = self.__ident_func__() - storage = self.__storage__ - try: - storage[ident][name] = value - except KeyError: - storage[ident] = {name: value} - - def __delattr__(self, name): - try: - del self.__storage__[self.__ident_func__()][name] - except KeyError: - raise AttributeError(name) - - -class LocalStack(object): - - """This class works similar to a :class:`Local` but keeps a stack - of objects instead. This is best explained with an example:: - - >>> ls = LocalStack() - >>> ls.push(42) - >>> ls.top - 42 - >>> ls.push(23) - >>> ls.top - 23 - >>> ls.pop() - 23 - >>> ls.top - 42 - - They can be force released by using a :class:`LocalManager` or with - the :func:`release_local` function but the correct way is to pop the - item from the stack after using. When the stack is empty it will - no longer be bound to the current context (and as such released). - - By calling the stack without arguments it returns a proxy that resolves to - the topmost item on the stack. - - .. versionadded:: 0.6.1 - """ - - def __init__(self): - self._local = Local() - - def __release_local__(self): - self._local.__release_local__() - - def _get__ident_func__(self): - return self._local.__ident_func__ - - def _set__ident_func__(self, value): - object.__setattr__(self._local, '__ident_func__', value) - __ident_func__ = property(_get__ident_func__, _set__ident_func__) - del _get__ident_func__, _set__ident_func__ - - def __call__(self): - def _lookup(): - rv = self.top - if rv is None: - raise RuntimeError('object unbound') - return rv - return LocalProxy(_lookup) - - def push(self, obj): - """Pushes a new item to the stack""" - rv = getattr(self._local, 'stack', None) - if rv is None: - self._local.stack = rv = [] - rv.append(obj) - return rv - - def pop(self): - """Removes the topmost item from the stack, will return the - old value or `None` if the stack was already empty. - """ - stack = getattr(self._local, 'stack', None) - if stack is None: - return None - elif len(stack) == 1: - release_local(self._local) - return stack[-1] - else: - return stack.pop() - - @property - def top(self): - """The topmost item on the stack. If the stack is empty, - `None` is returned. - """ - try: - return self._local.stack[-1] - except (AttributeError, IndexError): - return None - - -class LocalManager(object): - - """Local objects cannot manage themselves. For that you need a local - manager. You can pass a local manager multiple locals or add them later - by appending them to `manager.locals`. Every time the manager cleans up, - it will clean up all the data left in the locals for this context. - - The `ident_func` parameter can be added to override the default ident - function for the wrapped locals. - - .. versionchanged:: 0.6.1 - Instead of a manager the :func:`release_local` function can be used - as well. - - .. versionchanged:: 0.7 - `ident_func` was added. - """ - - def __init__(self, locals=None, ident_func=None): - if locals is None: - self.locals = [] - elif isinstance(locals, Local): - self.locals = [locals] - else: - self.locals = list(locals) - if ident_func is not None: - self.ident_func = ident_func - for local in self.locals: - object.__setattr__(local, '__ident_func__', ident_func) - else: - self.ident_func = get_ident - - def get_ident(self): - """Return the context identifier the local objects use internally for - this context. You cannot override this method to change the behavior - but use it to link other context local objects (such as SQLAlchemy's - scoped sessions) to the Werkzeug locals. - - .. versionchanged:: 0.7 - You can pass a different ident function to the local manager that - will then be propagated to all the locals passed to the - constructor. - """ - return self.ident_func() - - def cleanup(self): - """Manually clean up the data in the locals for this context. Call - this at the end of the request or use `make_middleware()`. - """ - for local in self.locals: - release_local(local) - - def make_middleware(self, app): - """Wrap a WSGI application so that cleaning up happens after - request end. - """ - def application(environ, start_response): - return ClosingIterator(app(environ, start_response), self.cleanup) - return application - - def middleware(self, func): - """Like `make_middleware` but for decorating functions. - - Example usage:: - - @manager.middleware - def application(environ, start_response): - ... - - The difference to `make_middleware` is that the function passed - will have all the arguments copied from the inner application - (name, docstring, module). - """ - return update_wrapper(self.make_middleware(func), func) - - def __repr__(self): - return '<%s storages: %d>' % ( - self.__class__.__name__, - len(self.locals) - ) - - -@implements_bool -class LocalProxy(object): - - """Acts as a proxy for a werkzeug local. Forwards all operations to - a proxied object. The only operations not supported for forwarding - are right handed operands and any kind of assignment. - - Example usage:: - - from werkzeug.local import Local - l = Local() - - # these are proxies - request = l('request') - user = l('user') - - - from werkzeug.local import LocalStack - _response_local = LocalStack() - - # this is a proxy - response = _response_local() - - Whenever something is bound to l.user / l.request the proxy objects - will forward all operations. If no object is bound a :exc:`RuntimeError` - will be raised. - - To create proxies to :class:`Local` or :class:`LocalStack` objects, - call the object as shown above. If you want to have a proxy to an - object looked up by a function, you can (as of Werkzeug 0.6.1) pass - a function to the :class:`LocalProxy` constructor:: - - session = LocalProxy(lambda: get_current_request().session) - - .. versionchanged:: 0.6.1 - The class can be instantiated with a callable as well now. - """ - __slots__ = ('__local', '__dict__', '__name__', '__wrapped__') - - def __init__(self, local, name=None): - object.__setattr__(self, '_LocalProxy__local', local) - object.__setattr__(self, '__name__', name) - if callable(local) and not hasattr(local, '__release_local__'): - # "local" is a callable that is not an instance of Local or - # LocalManager: mark it as a wrapped function. - object.__setattr__(self, '__wrapped__', local) - - def _get_current_object(self): - """Return the current object. This is useful if you want the real - object behind the proxy at a time for performance reasons or because - you want to pass the object into a different context. - """ - if not hasattr(self.__local, '__release_local__'): - return self.__local() - try: - return getattr(self.__local, self.__name__) - except AttributeError: - raise RuntimeError('no object bound to %s' % self.__name__) - - @property - def __dict__(self): - try: - return self._get_current_object().__dict__ - except RuntimeError: - raise AttributeError('__dict__') - - def __repr__(self): - try: - obj = self._get_current_object() - except RuntimeError: - return '<%s unbound>' % self.__class__.__name__ - return repr(obj) - - def __bool__(self): - try: - return bool(self._get_current_object()) - except RuntimeError: - return False - - def __unicode__(self): - try: - return unicode(self._get_current_object()) # noqa - except RuntimeError: - return repr(self) - - def __dir__(self): - try: - return dir(self._get_current_object()) - except RuntimeError: - return [] - - def __getattr__(self, name): - if name == '__members__': - return dir(self._get_current_object()) - return getattr(self._get_current_object(), name) - - def __setitem__(self, key, value): - self._get_current_object()[key] = value - - def __delitem__(self, key): - del self._get_current_object()[key] - - if PY2: - __getslice__ = lambda x, i, j: x._get_current_object()[i:j] - - def __setslice__(self, i, j, seq): - self._get_current_object()[i:j] = seq - - def __delslice__(self, i, j): - del self._get_current_object()[i:j] - - __setattr__ = lambda x, n, v: setattr(x._get_current_object(), n, v) - __delattr__ = lambda x, n: delattr(x._get_current_object(), n) - __str__ = lambda x: str(x._get_current_object()) - __lt__ = lambda x, o: x._get_current_object() < o - __le__ = lambda x, o: x._get_current_object() <= o - __eq__ = lambda x, o: x._get_current_object() == o - __ne__ = lambda x, o: x._get_current_object() != o - __gt__ = lambda x, o: x._get_current_object() > o - __ge__ = lambda x, o: x._get_current_object() >= o - __cmp__ = lambda x, o: cmp(x._get_current_object(), o) # noqa - __hash__ = lambda x: hash(x._get_current_object()) - __call__ = lambda x, *a, **kw: x._get_current_object()(*a, **kw) - __len__ = lambda x: len(x._get_current_object()) - __getitem__ = lambda x, i: x._get_current_object()[i] - __iter__ = lambda x: iter(x._get_current_object()) - __contains__ = lambda x, i: i in x._get_current_object() - __add__ = lambda x, o: x._get_current_object() + o - __sub__ = lambda x, o: x._get_current_object() - o - __mul__ = lambda x, o: x._get_current_object() * o - __floordiv__ = lambda x, o: x._get_current_object() // o - __mod__ = lambda x, o: x._get_current_object() % o - __divmod__ = lambda x, o: x._get_current_object().__divmod__(o) - __pow__ = lambda x, o: x._get_current_object() ** o - __lshift__ = lambda x, o: x._get_current_object() << o - __rshift__ = lambda x, o: x._get_current_object() >> o - __and__ = lambda x, o: x._get_current_object() & o - __xor__ = lambda x, o: x._get_current_object() ^ o - __or__ = lambda x, o: x._get_current_object() | o - __div__ = lambda x, o: x._get_current_object().__div__(o) - __truediv__ = lambda x, o: x._get_current_object().__truediv__(o) - __neg__ = lambda x: -(x._get_current_object()) - __pos__ = lambda x: +(x._get_current_object()) - __abs__ = lambda x: abs(x._get_current_object()) - __invert__ = lambda x: ~(x._get_current_object()) - __complex__ = lambda x: complex(x._get_current_object()) - __int__ = lambda x: int(x._get_current_object()) - __long__ = lambda x: long(x._get_current_object()) # noqa - __float__ = lambda x: float(x._get_current_object()) - __oct__ = lambda x: oct(x._get_current_object()) - __hex__ = lambda x: hex(x._get_current_object()) - __index__ = lambda x: x._get_current_object().__index__() - __coerce__ = lambda x, o: x._get_current_object().__coerce__(x, o) - __enter__ = lambda x: x._get_current_object().__enter__() - __exit__ = lambda x, *a, **kw: x._get_current_object().__exit__(*a, **kw) - __radd__ = lambda x, o: o + x._get_current_object() - __rsub__ = lambda x, o: o - x._get_current_object() - __rmul__ = lambda x, o: o * x._get_current_object() - __rdiv__ = lambda x, o: o / x._get_current_object() - if PY2: - __rtruediv__ = lambda x, o: x._get_current_object().__rtruediv__(o) - else: - __rtruediv__ = __rdiv__ - __rfloordiv__ = lambda x, o: o // x._get_current_object() - __rmod__ = lambda x, o: o % x._get_current_object() - __rdivmod__ = lambda x, o: x._get_current_object().__rdivmod__(o) - __copy__ = lambda x: copy.copy(x._get_current_object()) - __deepcopy__ = lambda x, memo: copy.deepcopy(x._get_current_object(), memo) diff --git a/pyextra/werkzeug/posixemulation.py b/pyextra/werkzeug/posixemulation.py deleted file mode 100644 index 8fd6314f28a2b7..00000000000000 --- a/pyextra/werkzeug/posixemulation.py +++ /dev/null @@ -1,106 +0,0 @@ -# -*- coding: utf-8 -*- -r""" - werkzeug.posixemulation - ~~~~~~~~~~~~~~~~~~~~~~~ - - Provides a POSIX emulation for some features that are relevant to - web applications. The main purpose is to simplify support for - systems such as Windows NT that are not 100% POSIX compatible. - - Currently this only implements a :func:`rename` function that - follows POSIX semantics. Eg: if the target file already exists it - will be replaced without asking. - - This module was introduced in 0.6.1 and is not a public interface. - It might become one in later versions of Werkzeug. - - :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -import sys -import os -import errno -import time -import random - -from ._compat import to_unicode -from .filesystem import get_filesystem_encoding - - -can_rename_open_file = False -if os.name == 'nt': # pragma: no cover - _rename = lambda src, dst: False - _rename_atomic = lambda src, dst: False - - try: - import ctypes - - _MOVEFILE_REPLACE_EXISTING = 0x1 - _MOVEFILE_WRITE_THROUGH = 0x8 - _MoveFileEx = ctypes.windll.kernel32.MoveFileExW - - def _rename(src, dst): - src = to_unicode(src, get_filesystem_encoding()) - dst = to_unicode(dst, get_filesystem_encoding()) - if _rename_atomic(src, dst): - return True - retry = 0 - rv = False - while not rv and retry < 100: - rv = _MoveFileEx(src, dst, _MOVEFILE_REPLACE_EXISTING | - _MOVEFILE_WRITE_THROUGH) - if not rv: - time.sleep(0.001) - retry += 1 - return rv - - # new in Vista and Windows Server 2008 - _CreateTransaction = ctypes.windll.ktmw32.CreateTransaction - _CommitTransaction = ctypes.windll.ktmw32.CommitTransaction - _MoveFileTransacted = ctypes.windll.kernel32.MoveFileTransactedW - _CloseHandle = ctypes.windll.kernel32.CloseHandle - can_rename_open_file = True - - def _rename_atomic(src, dst): - ta = _CreateTransaction(None, 0, 0, 0, 0, 1000, 'Werkzeug rename') - if ta == -1: - return False - try: - retry = 0 - rv = False - while not rv and retry < 100: - rv = _MoveFileTransacted(src, dst, None, None, - _MOVEFILE_REPLACE_EXISTING | - _MOVEFILE_WRITE_THROUGH, ta) - if rv: - rv = _CommitTransaction(ta) - break - else: - time.sleep(0.001) - retry += 1 - return rv - finally: - _CloseHandle(ta) - except Exception: - pass - - def rename(src, dst): - # Try atomic or pseudo-atomic rename - if _rename(src, dst): - return - # Fall back to "move away and replace" - try: - os.rename(src, dst) - except OSError as e: - if e.errno != errno.EEXIST: - raise - old = "%s-%08x" % (dst, random.randint(0, sys.maxint)) - os.rename(dst, old) - os.rename(src, dst) - try: - os.unlink(old) - except Exception: - pass -else: - rename = os.rename - can_rename_open_file = True diff --git a/pyextra/werkzeug/routing.py b/pyextra/werkzeug/routing.py deleted file mode 100644 index 2e4e2f42c1c264..00000000000000 --- a/pyextra/werkzeug/routing.py +++ /dev/null @@ -1,1792 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.routing - ~~~~~~~~~~~~~~~~ - - When it comes to combining multiple controller or view functions (however - you want to call them) you need a dispatcher. A simple way would be - applying regular expression tests on the ``PATH_INFO`` and calling - registered callback functions that return the value then. - - This module implements a much more powerful system than simple regular - expression matching because it can also convert values in the URLs and - build URLs. - - Here a simple example that creates an URL map for an application with - two subdomains (www and kb) and some URL rules: - - >>> m = Map([ - ... # Static URLs - ... Rule('/', endpoint='static/index'), - ... Rule('/about', endpoint='static/about'), - ... Rule('/help', endpoint='static/help'), - ... # Knowledge Base - ... Subdomain('kb', [ - ... Rule('/', endpoint='kb/index'), - ... Rule('/browse/', endpoint='kb/browse'), - ... Rule('/browse//', endpoint='kb/browse'), - ... Rule('/browse//', endpoint='kb/browse') - ... ]) - ... ], default_subdomain='www') - - If the application doesn't use subdomains it's perfectly fine to not set - the default subdomain and not use the `Subdomain` rule factory. The endpoint - in the rules can be anything, for example import paths or unique - identifiers. The WSGI application can use those endpoints to get the - handler for that URL. It doesn't have to be a string at all but it's - recommended. - - Now it's possible to create a URL adapter for one of the subdomains and - build URLs: - - >>> c = m.bind('example.com') - >>> c.build("kb/browse", dict(id=42)) - 'http://kb.example.com/browse/42/' - >>> c.build("kb/browse", dict()) - 'http://kb.example.com/browse/' - >>> c.build("kb/browse", dict(id=42, page=3)) - 'http://kb.example.com/browse/42/3' - >>> c.build("static/about") - '/about' - >>> c.build("static/index", force_external=True) - 'http://www.example.com/' - - >>> c = m.bind('example.com', subdomain='kb') - >>> c.build("static/about") - 'http://www.example.com/about' - - The first argument to bind is the server name *without* the subdomain. - Per default it will assume that the script is mounted on the root, but - often that's not the case so you can provide the real mount point as - second argument: - - >>> c = m.bind('example.com', '/applications/example') - - The third argument can be the subdomain, if not given the default - subdomain is used. For more details about binding have a look at the - documentation of the `MapAdapter`. - - And here is how you can match URLs: - - >>> c = m.bind('example.com') - >>> c.match("/") - ('static/index', {}) - >>> c.match("/about") - ('static/about', {}) - >>> c = m.bind('example.com', '/', 'kb') - >>> c.match("/") - ('kb/index', {}) - >>> c.match("/browse/42/23") - ('kb/browse', {'id': 42, 'page': 23}) - - If matching fails you get a `NotFound` exception, if the rule thinks - it's a good idea to redirect (for example because the URL was defined - to have a slash at the end but the request was missing that slash) it - will raise a `RequestRedirect` exception. Both are subclasses of the - `HTTPException` so you can use those errors as responses in the - application. - - If matching succeeded but the URL rule was incompatible to the given - method (for example there were only rules for `GET` and `HEAD` and - routing system tried to match a `POST` request) a `MethodNotAllowed` - exception is raised. - - - :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -import difflib -import re -import uuid -import posixpath - -from pprint import pformat -from threading import Lock - -from werkzeug.urls import url_encode, url_quote, url_join -from werkzeug.utils import redirect, format_string -from werkzeug.exceptions import HTTPException, NotFound, MethodNotAllowed, \ - BadHost -from werkzeug._internal import _get_environ, _encode_idna -from werkzeug._compat import itervalues, iteritems, to_unicode, to_bytes, \ - text_type, string_types, native_string_result, \ - implements_to_string, wsgi_decoding_dance -from werkzeug.datastructures import ImmutableDict, MultiDict -from werkzeug.utils import cached_property - - -_rule_re = re.compile(r''' - (?P[^<]*) # static rule data - < - (?: - (?P[a-zA-Z_][a-zA-Z0-9_]*) # converter name - (?:\((?P.*?)\))? # converter arguments - \: # variable delimiter - )? - (?P[a-zA-Z_][a-zA-Z0-9_]*) # variable name - > -''', re.VERBOSE) -_simple_rule_re = re.compile(r'<([^>]+)>') -_converter_args_re = re.compile(r''' - ((?P\w+)\s*=\s*)? - (?P - True|False| - \d+.\d+| - \d+.| - \d+| - [\w\d_.]+| - [urUR]?(?P"[^"]*?"|'[^']*') - )\s*, -''', re.VERBOSE | re.UNICODE) - - -_PYTHON_CONSTANTS = { - 'None': None, - 'True': True, - 'False': False -} - - -def _pythonize(value): - if value in _PYTHON_CONSTANTS: - return _PYTHON_CONSTANTS[value] - for convert in int, float: - try: - return convert(value) - except ValueError: - pass - if value[:1] == value[-1:] and value[0] in '"\'': - value = value[1:-1] - return text_type(value) - - -def parse_converter_args(argstr): - argstr += ',' - args = [] - kwargs = {} - - for item in _converter_args_re.finditer(argstr): - value = item.group('stringval') - if value is None: - value = item.group('value') - value = _pythonize(value) - if not item.group('name'): - args.append(value) - else: - name = item.group('name') - kwargs[name] = value - - return tuple(args), kwargs - - -def parse_rule(rule): - """Parse a rule and return it as generator. Each iteration yields tuples - in the form ``(converter, arguments, variable)``. If the converter is - `None` it's a static url part, otherwise it's a dynamic one. - - :internal: - """ - pos = 0 - end = len(rule) - do_match = _rule_re.match - used_names = set() - while pos < end: - m = do_match(rule, pos) - if m is None: - break - data = m.groupdict() - if data['static']: - yield None, None, data['static'] - variable = data['variable'] - converter = data['converter'] or 'default' - if variable in used_names: - raise ValueError('variable name %r used twice.' % variable) - used_names.add(variable) - yield converter, data['args'] or None, variable - pos = m.end() - if pos < end: - remaining = rule[pos:] - if '>' in remaining or '<' in remaining: - raise ValueError('malformed url rule: %r' % rule) - yield None, None, remaining - - -class RoutingException(Exception): - - """Special exceptions that require the application to redirect, notifying - about missing urls, etc. - - :internal: - """ - - -class RequestRedirect(HTTPException, RoutingException): - - """Raise if the map requests a redirect. This is for example the case if - `strict_slashes` are activated and an url that requires a trailing slash. - - The attribute `new_url` contains the absolute destination url. - """ - code = 301 - - def __init__(self, new_url): - RoutingException.__init__(self, new_url) - self.new_url = new_url - - def get_response(self, environ): - return redirect(self.new_url, self.code) - - -class RequestSlash(RoutingException): - - """Internal exception.""" - - -class RequestAliasRedirect(RoutingException): - - """This rule is an alias and wants to redirect to the canonical URL.""" - - def __init__(self, matched_values): - self.matched_values = matched_values - - -@implements_to_string -class BuildError(RoutingException, LookupError): - - """Raised if the build system cannot find a URL for an endpoint with the - values provided. - """ - - def __init__(self, endpoint, values, method, adapter=None): - LookupError.__init__(self, endpoint, values, method) - self.endpoint = endpoint - self.values = values - self.method = method - self.adapter = adapter - - @cached_property - def suggested(self): - return self.closest_rule(self.adapter) - - def closest_rule(self, adapter): - def _score_rule(rule): - return sum([ - 0.98 * difflib.SequenceMatcher( - None, rule.endpoint, self.endpoint - ).ratio(), - 0.01 * bool(set(self.values or ()).issubset(rule.arguments)), - 0.01 * bool(rule.methods and self.method in rule.methods) - ]) - - if adapter and adapter.map._rules: - return max(adapter.map._rules, key=_score_rule) - - def __str__(self): - message = [] - message.append('Could not build url for endpoint %r' % self.endpoint) - if self.method: - message.append(' (%r)' % self.method) - if self.values: - message.append(' with values %r' % sorted(self.values.keys())) - message.append('.') - if self.suggested: - if self.endpoint == self.suggested.endpoint: - if self.method and self.method not in self.suggested.methods: - message.append(' Did you mean to use methods %r?' % sorted( - self.suggested.methods - )) - missing_values = self.suggested.arguments.union( - set(self.suggested.defaults or ()) - ) - set(self.values.keys()) - if missing_values: - message.append( - ' Did you forget to specify values %r?' % - sorted(missing_values) - ) - else: - message.append( - ' Did you mean %r instead?' % self.suggested.endpoint - ) - return u''.join(message) - - -class ValidationError(ValueError): - - """Validation error. If a rule converter raises this exception the rule - does not match the current URL and the next URL is tried. - """ - - -class RuleFactory(object): - - """As soon as you have more complex URL setups it's a good idea to use rule - factories to avoid repetitive tasks. Some of them are builtin, others can - be added by subclassing `RuleFactory` and overriding `get_rules`. - """ - - def get_rules(self, map): - """Subclasses of `RuleFactory` have to override this method and return - an iterable of rules.""" - raise NotImplementedError() - - -class Subdomain(RuleFactory): - - """All URLs provided by this factory have the subdomain set to a - specific domain. For example if you want to use the subdomain for - the current language this can be a good setup:: - - url_map = Map([ - Rule('/', endpoint='#select_language'), - Subdomain('', [ - Rule('/', endpoint='index'), - Rule('/about', endpoint='about'), - Rule('/help', endpoint='help') - ]) - ]) - - All the rules except for the ``'#select_language'`` endpoint will now - listen on a two letter long subdomain that holds the language code - for the current request. - """ - - def __init__(self, subdomain, rules): - self.subdomain = subdomain - self.rules = rules - - def get_rules(self, map): - for rulefactory in self.rules: - for rule in rulefactory.get_rules(map): - rule = rule.empty() - rule.subdomain = self.subdomain - yield rule - - -class Submount(RuleFactory): - - """Like `Subdomain` but prefixes the URL rule with a given string:: - - url_map = Map([ - Rule('/', endpoint='index'), - Submount('/blog', [ - Rule('/', endpoint='blog/index'), - Rule('/entry/', endpoint='blog/show') - ]) - ]) - - Now the rule ``'blog/show'`` matches ``/blog/entry/``. - """ - - def __init__(self, path, rules): - self.path = path.rstrip('/') - self.rules = rules - - def get_rules(self, map): - for rulefactory in self.rules: - for rule in rulefactory.get_rules(map): - rule = rule.empty() - rule.rule = self.path + rule.rule - yield rule - - -class EndpointPrefix(RuleFactory): - - """Prefixes all endpoints (which must be strings for this factory) with - another string. This can be useful for sub applications:: - - url_map = Map([ - Rule('/', endpoint='index'), - EndpointPrefix('blog/', [Submount('/blog', [ - Rule('/', endpoint='index'), - Rule('/entry/', endpoint='show') - ])]) - ]) - """ - - def __init__(self, prefix, rules): - self.prefix = prefix - self.rules = rules - - def get_rules(self, map): - for rulefactory in self.rules: - for rule in rulefactory.get_rules(map): - rule = rule.empty() - rule.endpoint = self.prefix + rule.endpoint - yield rule - - -class RuleTemplate(object): - - """Returns copies of the rules wrapped and expands string templates in - the endpoint, rule, defaults or subdomain sections. - - Here a small example for such a rule template:: - - from werkzeug.routing import Map, Rule, RuleTemplate - - resource = RuleTemplate([ - Rule('/$name/', endpoint='$name.list'), - Rule('/$name/', endpoint='$name.show') - ]) - - url_map = Map([resource(name='user'), resource(name='page')]) - - When a rule template is called the keyword arguments are used to - replace the placeholders in all the string parameters. - """ - - def __init__(self, rules): - self.rules = list(rules) - - def __call__(self, *args, **kwargs): - return RuleTemplateFactory(self.rules, dict(*args, **kwargs)) - - -class RuleTemplateFactory(RuleFactory): - - """A factory that fills in template variables into rules. Used by - `RuleTemplate` internally. - - :internal: - """ - - def __init__(self, rules, context): - self.rules = rules - self.context = context - - def get_rules(self, map): - for rulefactory in self.rules: - for rule in rulefactory.get_rules(map): - new_defaults = subdomain = None - if rule.defaults: - new_defaults = {} - for key, value in iteritems(rule.defaults): - if isinstance(value, string_types): - value = format_string(value, self.context) - new_defaults[key] = value - if rule.subdomain is not None: - subdomain = format_string(rule.subdomain, self.context) - new_endpoint = rule.endpoint - if isinstance(new_endpoint, string_types): - new_endpoint = format_string(new_endpoint, self.context) - yield Rule( - format_string(rule.rule, self.context), - new_defaults, - subdomain, - rule.methods, - rule.build_only, - new_endpoint, - rule.strict_slashes - ) - - -@implements_to_string -class Rule(RuleFactory): - - """A Rule represents one URL pattern. There are some options for `Rule` - that change the way it behaves and are passed to the `Rule` constructor. - Note that besides the rule-string all arguments *must* be keyword arguments - in order to not break the application on Werkzeug upgrades. - - `string` - Rule strings basically are just normal URL paths with placeholders in - the format ```` where the converter and the - arguments are optional. If no converter is defined the `default` - converter is used which means `string` in the normal configuration. - - URL rules that end with a slash are branch URLs, others are leaves. - If you have `strict_slashes` enabled (which is the default), all - branch URLs that are matched without a trailing slash will trigger a - redirect to the same URL with the missing slash appended. - - The converters are defined on the `Map`. - - `endpoint` - The endpoint for this rule. This can be anything. A reference to a - function, a string, a number etc. The preferred way is using a string - because the endpoint is used for URL generation. - - `defaults` - An optional dict with defaults for other rules with the same endpoint. - This is a bit tricky but useful if you want to have unique URLs:: - - url_map = Map([ - Rule('/all/', defaults={'page': 1}, endpoint='all_entries'), - Rule('/all/page/', endpoint='all_entries') - ]) - - If a user now visits ``http://example.com/all/page/1`` he will be - redirected to ``http://example.com/all/``. If `redirect_defaults` is - disabled on the `Map` instance this will only affect the URL - generation. - - `subdomain` - The subdomain rule string for this rule. If not specified the rule - only matches for the `default_subdomain` of the map. If the map is - not bound to a subdomain this feature is disabled. - - Can be useful if you want to have user profiles on different subdomains - and all subdomains are forwarded to your application:: - - url_map = Map([ - Rule('/', subdomain='', endpoint='user/homepage'), - Rule('/stats', subdomain='', endpoint='user/stats') - ]) - - `methods` - A sequence of http methods this rule applies to. If not specified, all - methods are allowed. For example this can be useful if you want different - endpoints for `POST` and `GET`. If methods are defined and the path - matches but the method matched against is not in this list or in the - list of another rule for that path the error raised is of the type - `MethodNotAllowed` rather than `NotFound`. If `GET` is present in the - list of methods and `HEAD` is not, `HEAD` is added automatically. - - .. versionchanged:: 0.6.1 - `HEAD` is now automatically added to the methods if `GET` is - present. The reason for this is that existing code often did not - work properly in servers not rewriting `HEAD` to `GET` - automatically and it was not documented how `HEAD` should be - treated. This was considered a bug in Werkzeug because of that. - - `strict_slashes` - Override the `Map` setting for `strict_slashes` only for this rule. If - not specified the `Map` setting is used. - - `build_only` - Set this to True and the rule will never match but will create a URL - that can be build. This is useful if you have resources on a subdomain - or folder that are not handled by the WSGI application (like static data) - - `redirect_to` - If given this must be either a string or callable. In case of a - callable it's called with the url adapter that triggered the match and - the values of the URL as keyword arguments and has to return the target - for the redirect, otherwise it has to be a string with placeholders in - rule syntax:: - - def foo_with_slug(adapter, id): - # ask the database for the slug for the old id. this of - # course has nothing to do with werkzeug. - return 'foo/' + Foo.get_slug_for_id(id) - - url_map = Map([ - Rule('/foo/', endpoint='foo'), - Rule('/some/old/url/', redirect_to='foo/'), - Rule('/other/old/url/', redirect_to=foo_with_slug) - ]) - - When the rule is matched the routing system will raise a - `RequestRedirect` exception with the target for the redirect. - - Keep in mind that the URL will be joined against the URL root of the - script so don't use a leading slash on the target URL unless you - really mean root of that domain. - - `alias` - If enabled this rule serves as an alias for another rule with the same - endpoint and arguments. - - `host` - If provided and the URL map has host matching enabled this can be - used to provide a match rule for the whole host. This also means - that the subdomain feature is disabled. - - .. versionadded:: 0.7 - The `alias` and `host` parameters were added. - """ - - def __init__(self, string, defaults=None, subdomain=None, methods=None, - build_only=False, endpoint=None, strict_slashes=None, - redirect_to=None, alias=False, host=None): - if not string.startswith('/'): - raise ValueError('urls must start with a leading slash') - self.rule = string - self.is_leaf = not string.endswith('/') - - self.map = None - self.strict_slashes = strict_slashes - self.subdomain = subdomain - self.host = host - self.defaults = defaults - self.build_only = build_only - self.alias = alias - if methods is None: - self.methods = None - else: - if isinstance(methods, str): - raise TypeError('param `methods` should be `Iterable[str]`, not `str`') - self.methods = set([x.upper() for x in methods]) - if 'HEAD' not in self.methods and 'GET' in self.methods: - self.methods.add('HEAD') - self.endpoint = endpoint - self.redirect_to = redirect_to - - if defaults: - self.arguments = set(map(str, defaults)) - else: - self.arguments = set() - self._trace = self._converters = self._regex = self._argument_weights = None - - def empty(self): - """ - Return an unbound copy of this rule. - - This can be useful if want to reuse an already bound URL for another - map. See ``get_empty_kwargs`` to override what keyword arguments are - provided to the new copy. - """ - return type(self)(self.rule, **self.get_empty_kwargs()) - - def get_empty_kwargs(self): - """ - Provides kwargs for instantiating empty copy with empty() - - Use this method to provide custom keyword arguments to the subclass of - ``Rule`` when calling ``some_rule.empty()``. Helpful when the subclass - has custom keyword arguments that are needed at instantiation. - - Must return a ``dict`` that will be provided as kwargs to the new - instance of ``Rule``, following the initial ``self.rule`` value which - is always provided as the first, required positional argument. - """ - defaults = None - if self.defaults: - defaults = dict(self.defaults) - return dict(defaults=defaults, subdomain=self.subdomain, - methods=self.methods, build_only=self.build_only, - endpoint=self.endpoint, strict_slashes=self.strict_slashes, - redirect_to=self.redirect_to, alias=self.alias, - host=self.host) - - def get_rules(self, map): - yield self - - def refresh(self): - """Rebinds and refreshes the URL. Call this if you modified the - rule in place. - - :internal: - """ - self.bind(self.map, rebind=True) - - def bind(self, map, rebind=False): - """Bind the url to a map and create a regular expression based on - the information from the rule itself and the defaults from the map. - - :internal: - """ - if self.map is not None and not rebind: - raise RuntimeError('url rule %r already bound to map %r' % - (self, self.map)) - self.map = map - if self.strict_slashes is None: - self.strict_slashes = map.strict_slashes - if self.subdomain is None: - self.subdomain = map.default_subdomain - self.compile() - - def get_converter(self, variable_name, converter_name, args, kwargs): - """Looks up the converter for the given parameter. - - .. versionadded:: 0.9 - """ - if converter_name not in self.map.converters: - raise LookupError('the converter %r does not exist' % converter_name) - return self.map.converters[converter_name](self.map, *args, **kwargs) - - def compile(self): - """Compiles the regular expression and stores it.""" - assert self.map is not None, 'rule not bound' - - if self.map.host_matching: - domain_rule = self.host or '' - else: - domain_rule = self.subdomain or '' - - self._trace = [] - self._converters = {} - self._static_weights = [] - self._argument_weights = [] - regex_parts = [] - - def _build_regex(rule): - index = 0 - for converter, arguments, variable in parse_rule(rule): - if converter is None: - regex_parts.append(re.escape(variable)) - self._trace.append((False, variable)) - for part in variable.split('/'): - if part: - self._static_weights.append((index, -len(part))) - else: - if arguments: - c_args, c_kwargs = parse_converter_args(arguments) - else: - c_args = () - c_kwargs = {} - convobj = self.get_converter( - variable, converter, c_args, c_kwargs) - regex_parts.append('(?P<%s>%s)' % (variable, convobj.regex)) - self._converters[variable] = convobj - self._trace.append((True, variable)) - self._argument_weights.append(convobj.weight) - self.arguments.add(str(variable)) - index = index + 1 - - _build_regex(domain_rule) - regex_parts.append('\\|') - self._trace.append((False, '|')) - _build_regex(self.is_leaf and self.rule or self.rule.rstrip('/')) - if not self.is_leaf: - self._trace.append((False, '/')) - - if self.build_only: - return - regex = r'^%s%s$' % ( - u''.join(regex_parts), - (not self.is_leaf or not self.strict_slashes) and - '(?/?)' or '' - ) - self._regex = re.compile(regex, re.UNICODE) - - def match(self, path, method=None): - """Check if the rule matches a given path. Path is a string in the - form ``"subdomain|/path"`` and is assembled by the map. If - the map is doing host matching the subdomain part will be the host - instead. - - If the rule matches a dict with the converted values is returned, - otherwise the return value is `None`. - - :internal: - """ - if not self.build_only: - m = self._regex.search(path) - if m is not None: - groups = m.groupdict() - # we have a folder like part of the url without a trailing - # slash and strict slashes enabled. raise an exception that - # tells the map to redirect to the same url but with a - # trailing slash - if self.strict_slashes and not self.is_leaf and \ - not groups.pop('__suffix__') and \ - (method is None or self.methods is None or - method in self.methods): - raise RequestSlash() - # if we are not in strict slashes mode we have to remove - # a __suffix__ - elif not self.strict_slashes: - del groups['__suffix__'] - - result = {} - for name, value in iteritems(groups): - try: - value = self._converters[name].to_python(value) - except ValidationError: - return - result[str(name)] = value - if self.defaults: - result.update(self.defaults) - - if self.alias and self.map.redirect_defaults: - raise RequestAliasRedirect(result) - - return result - - def build(self, values, append_unknown=True): - """Assembles the relative url for that rule and the subdomain. - If building doesn't work for some reasons `None` is returned. - - :internal: - """ - tmp = [] - add = tmp.append - processed = set(self.arguments) - for is_dynamic, data in self._trace: - if is_dynamic: - try: - add(self._converters[data].to_url(values[data])) - except ValidationError: - return - processed.add(data) - else: - add(url_quote(to_bytes(data, self.map.charset), safe='/:|+')) - domain_part, url = (u''.join(tmp)).split(u'|', 1) - - if append_unknown: - query_vars = MultiDict(values) - for key in processed: - if key in query_vars: - del query_vars[key] - - if query_vars: - url += u'?' + url_encode(query_vars, charset=self.map.charset, - sort=self.map.sort_parameters, - key=self.map.sort_key) - - return domain_part, url - - def provides_defaults_for(self, rule): - """Check if this rule has defaults for a given rule. - - :internal: - """ - return not self.build_only and self.defaults and \ - self.endpoint == rule.endpoint and self != rule and \ - self.arguments == rule.arguments - - def suitable_for(self, values, method=None): - """Check if the dict of values has enough data for url generation. - - :internal: - """ - # if a method was given explicitly and that method is not supported - # by this rule, this rule is not suitable. - if method is not None and self.methods is not None \ - and method not in self.methods: - return False - - defaults = self.defaults or () - - # all arguments required must be either in the defaults dict or - # the value dictionary otherwise it's not suitable - for key in self.arguments: - if key not in defaults and key not in values: - return False - - # in case defaults are given we ensure taht either the value was - # skipped or the value is the same as the default value. - if defaults: - for key, value in iteritems(defaults): - if key in values and value != values[key]: - return False - - return True - - def match_compare_key(self): - """The match compare key for sorting. - - Current implementation: - - 1. rules without any arguments come first for performance - reasons only as we expect them to match faster and some - common ones usually don't have any arguments (index pages etc.) - 2. rules with more static parts come first so the second argument - is the negative length of the number of the static weights. - 3. we order by static weights, which is a combination of index - and length - 4. The more complex rules come first so the next argument is the - negative length of the number of argument weights. - 5. lastly we order by the actual argument weights. - - :internal: - """ - return bool(self.arguments), -len(self._static_weights), self._static_weights,\ - -len(self._argument_weights), self._argument_weights - - def build_compare_key(self): - """The build compare key for sorting. - - :internal: - """ - return self.alias and 1 or 0, -len(self.arguments), \ - -len(self.defaults or ()) - - def __eq__(self, other): - return self.__class__ is other.__class__ and \ - self._trace == other._trace - - __hash__ = None - - def __ne__(self, other): - return not self.__eq__(other) - - def __str__(self): - return self.rule - - @native_string_result - def __repr__(self): - if self.map is None: - return u'<%s (unbound)>' % self.__class__.__name__ - tmp = [] - for is_dynamic, data in self._trace: - if is_dynamic: - tmp.append(u'<%s>' % data) - else: - tmp.append(data) - return u'<%s %s%s -> %s>' % ( - self.__class__.__name__, - repr((u''.join(tmp)).lstrip(u'|')).lstrip(u'u'), - self.methods is not None - and u' (%s)' % u', '.join(self.methods) - or u'', - self.endpoint - ) - - -class BaseConverter(object): - - """Base class for all converters.""" - regex = '[^/]+' - weight = 100 - - def __init__(self, map): - self.map = map - - def to_python(self, value): - return value - - def to_url(self, value): - return url_quote(value, charset=self.map.charset) - - -class UnicodeConverter(BaseConverter): - - """This converter is the default converter and accepts any string but - only one path segment. Thus the string can not include a slash. - - This is the default validator. - - Example:: - - Rule('/pages/'), - Rule('/') - - :param map: the :class:`Map`. - :param minlength: the minimum length of the string. Must be greater - or equal 1. - :param maxlength: the maximum length of the string. - :param length: the exact length of the string. - """ - - def __init__(self, map, minlength=1, maxlength=None, length=None): - BaseConverter.__init__(self, map) - if length is not None: - length = '{%d}' % int(length) - else: - if maxlength is None: - maxlength = '' - else: - maxlength = int(maxlength) - length = '{%s,%s}' % ( - int(minlength), - maxlength - ) - self.regex = '[^/]' + length - - -class AnyConverter(BaseConverter): - - """Matches one of the items provided. Items can either be Python - identifiers or strings:: - - Rule('/') - - :param map: the :class:`Map`. - :param items: this function accepts the possible items as positional - arguments. - """ - - def __init__(self, map, *items): - BaseConverter.__init__(self, map) - self.regex = '(?:%s)' % '|'.join([re.escape(x) for x in items]) - - -class PathConverter(BaseConverter): - - """Like the default :class:`UnicodeConverter`, but it also matches - slashes. This is useful for wikis and similar applications:: - - Rule('/') - Rule('//edit') - - :param map: the :class:`Map`. - """ - regex = '[^/].*?' - weight = 200 - - -class NumberConverter(BaseConverter): - - """Baseclass for `IntegerConverter` and `FloatConverter`. - - :internal: - """ - weight = 50 - - def __init__(self, map, fixed_digits=0, min=None, max=None): - BaseConverter.__init__(self, map) - self.fixed_digits = fixed_digits - self.min = min - self.max = max - - def to_python(self, value): - if (self.fixed_digits and len(value) != self.fixed_digits): - raise ValidationError() - value = self.num_convert(value) - if (self.min is not None and value < self.min) or \ - (self.max is not None and value > self.max): - raise ValidationError() - return value - - def to_url(self, value): - value = self.num_convert(value) - if self.fixed_digits: - value = ('%%0%sd' % self.fixed_digits) % value - return str(value) - - -class IntegerConverter(NumberConverter): - - """This converter only accepts integer values:: - - Rule('/page/') - - This converter does not support negative values. - - :param map: the :class:`Map`. - :param fixed_digits: the number of fixed digits in the URL. If you set - this to ``4`` for example, the application will - only match if the url looks like ``/0001/``. The - default is variable length. - :param min: the minimal value. - :param max: the maximal value. - """ - regex = r'\d+' - num_convert = int - - -class FloatConverter(NumberConverter): - - """This converter only accepts floating point values:: - - Rule('/probability/') - - This converter does not support negative values. - - :param map: the :class:`Map`. - :param min: the minimal value. - :param max: the maximal value. - """ - regex = r'\d+\.\d+' - num_convert = float - - def __init__(self, map, min=None, max=None): - NumberConverter.__init__(self, map, 0, min, max) - - -class UUIDConverter(BaseConverter): - - """This converter only accepts UUID strings:: - - Rule('/object/') - - .. versionadded:: 0.10 - - :param map: the :class:`Map`. - """ - regex = r'[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-' \ - r'[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}' - - def to_python(self, value): - return uuid.UUID(value) - - def to_url(self, value): - return str(value) - - -#: the default converter mapping for the map. -DEFAULT_CONVERTERS = { - 'default': UnicodeConverter, - 'string': UnicodeConverter, - 'any': AnyConverter, - 'path': PathConverter, - 'int': IntegerConverter, - 'float': FloatConverter, - 'uuid': UUIDConverter, -} - - -class Map(object): - - """The map class stores all the URL rules and some configuration - parameters. Some of the configuration values are only stored on the - `Map` instance since those affect all rules, others are just defaults - and can be overridden for each rule. Note that you have to specify all - arguments besides the `rules` as keyword arguments! - - :param rules: sequence of url rules for this map. - :param default_subdomain: The default subdomain for rules without a - subdomain defined. - :param charset: charset of the url. defaults to ``"utf-8"`` - :param strict_slashes: Take care of trailing slashes. - :param redirect_defaults: This will redirect to the default rule if it - wasn't visited that way. This helps creating - unique URLs. - :param converters: A dict of converters that adds additional converters - to the list of converters. If you redefine one - converter this will override the original one. - :param sort_parameters: If set to `True` the url parameters are sorted. - See `url_encode` for more details. - :param sort_key: The sort key function for `url_encode`. - :param encoding_errors: the error method to use for decoding - :param host_matching: if set to `True` it enables the host matching - feature and disables the subdomain one. If - enabled the `host` parameter to rules is used - instead of the `subdomain` one. - - .. versionadded:: 0.5 - `sort_parameters` and `sort_key` was added. - - .. versionadded:: 0.7 - `encoding_errors` and `host_matching` was added. - """ - - #: .. versionadded:: 0.6 - #: a dict of default converters to be used. - default_converters = ImmutableDict(DEFAULT_CONVERTERS) - - def __init__(self, rules=None, default_subdomain='', charset='utf-8', - strict_slashes=True, redirect_defaults=True, - converters=None, sort_parameters=False, sort_key=None, - encoding_errors='replace', host_matching=False): - self._rules = [] - self._rules_by_endpoint = {} - self._remap = True - self._remap_lock = Lock() - - self.default_subdomain = default_subdomain - self.charset = charset - self.encoding_errors = encoding_errors - self.strict_slashes = strict_slashes - self.redirect_defaults = redirect_defaults - self.host_matching = host_matching - - self.converters = self.default_converters.copy() - if converters: - self.converters.update(converters) - - self.sort_parameters = sort_parameters - self.sort_key = sort_key - - for rulefactory in rules or (): - self.add(rulefactory) - - def is_endpoint_expecting(self, endpoint, *arguments): - """Iterate over all rules and check if the endpoint expects - the arguments provided. This is for example useful if you have - some URLs that expect a language code and others that do not and - you want to wrap the builder a bit so that the current language - code is automatically added if not provided but endpoints expect - it. - - :param endpoint: the endpoint to check. - :param arguments: this function accepts one or more arguments - as positional arguments. Each one of them is - checked. - """ - self.update() - arguments = set(arguments) - for rule in self._rules_by_endpoint[endpoint]: - if arguments.issubset(rule.arguments): - return True - return False - - def iter_rules(self, endpoint=None): - """Iterate over all rules or the rules of an endpoint. - - :param endpoint: if provided only the rules for that endpoint - are returned. - :return: an iterator - """ - self.update() - if endpoint is not None: - return iter(self._rules_by_endpoint[endpoint]) - return iter(self._rules) - - def add(self, rulefactory): - """Add a new rule or factory to the map and bind it. Requires that the - rule is not bound to another map. - - :param rulefactory: a :class:`Rule` or :class:`RuleFactory` - """ - for rule in rulefactory.get_rules(self): - rule.bind(self) - self._rules.append(rule) - self._rules_by_endpoint.setdefault(rule.endpoint, []).append(rule) - self._remap = True - - def bind(self, server_name, script_name=None, subdomain=None, - url_scheme='http', default_method='GET', path_info=None, - query_args=None): - """Return a new :class:`MapAdapter` with the details specified to the - call. Note that `script_name` will default to ``'/'`` if not further - specified or `None`. The `server_name` at least is a requirement - because the HTTP RFC requires absolute URLs for redirects and so all - redirect exceptions raised by Werkzeug will contain the full canonical - URL. - - If no path_info is passed to :meth:`match` it will use the default path - info passed to bind. While this doesn't really make sense for - manual bind calls, it's useful if you bind a map to a WSGI - environment which already contains the path info. - - `subdomain` will default to the `default_subdomain` for this map if - no defined. If there is no `default_subdomain` you cannot use the - subdomain feature. - - .. versionadded:: 0.7 - `query_args` added - - .. versionadded:: 0.8 - `query_args` can now also be a string. - """ - server_name = server_name.lower() - if self.host_matching: - if subdomain is not None: - raise RuntimeError('host matching enabled and a ' - 'subdomain was provided') - elif subdomain is None: - subdomain = self.default_subdomain - if script_name is None: - script_name = '/' - try: - server_name = _encode_idna(server_name) - except UnicodeError: - raise BadHost() - return MapAdapter(self, server_name, script_name, subdomain, - url_scheme, path_info, default_method, query_args) - - def bind_to_environ(self, environ, server_name=None, subdomain=None): - """Like :meth:`bind` but you can pass it an WSGI environment and it - will fetch the information from that dictionary. Note that because of - limitations in the protocol there is no way to get the current - subdomain and real `server_name` from the environment. If you don't - provide it, Werkzeug will use `SERVER_NAME` and `SERVER_PORT` (or - `HTTP_HOST` if provided) as used `server_name` with disabled subdomain - feature. - - If `subdomain` is `None` but an environment and a server name is - provided it will calculate the current subdomain automatically. - Example: `server_name` is ``'example.com'`` and the `SERVER_NAME` - in the wsgi `environ` is ``'staging.dev.example.com'`` the calculated - subdomain will be ``'staging.dev'``. - - If the object passed as environ has an environ attribute, the value of - this attribute is used instead. This allows you to pass request - objects. Additionally `PATH_INFO` added as a default of the - :class:`MapAdapter` so that you don't have to pass the path info to - the match method. - - .. versionchanged:: 0.5 - previously this method accepted a bogus `calculate_subdomain` - parameter that did not have any effect. It was removed because - of that. - - .. versionchanged:: 0.8 - This will no longer raise a ValueError when an unexpected server - name was passed. - - :param environ: a WSGI environment. - :param server_name: an optional server name hint (see above). - :param subdomain: optionally the current subdomain (see above). - """ - environ = _get_environ(environ) - - if 'HTTP_HOST' in environ: - wsgi_server_name = environ['HTTP_HOST'] - - if environ['wsgi.url_scheme'] == 'http' \ - and wsgi_server_name.endswith(':80'): - wsgi_server_name = wsgi_server_name[:-3] - elif environ['wsgi.url_scheme'] == 'https' \ - and wsgi_server_name.endswith(':443'): - wsgi_server_name = wsgi_server_name[:-4] - else: - wsgi_server_name = environ['SERVER_NAME'] - - if (environ['wsgi.url_scheme'], environ['SERVER_PORT']) not \ - in (('https', '443'), ('http', '80')): - wsgi_server_name += ':' + environ['SERVER_PORT'] - - wsgi_server_name = wsgi_server_name.lower() - - if server_name is None: - server_name = wsgi_server_name - else: - server_name = server_name.lower() - - if subdomain is None and not self.host_matching: - cur_server_name = wsgi_server_name.split('.') - real_server_name = server_name.split('.') - offset = -len(real_server_name) - if cur_server_name[offset:] != real_server_name: - # This can happen even with valid configs if the server was - # accesssed directly by IP address under some situations. - # Instead of raising an exception like in Werkzeug 0.7 or - # earlier we go by an invalid subdomain which will result - # in a 404 error on matching. - subdomain = '' - else: - subdomain = '.'.join(filter(None, cur_server_name[:offset])) - - def _get_wsgi_string(name): - val = environ.get(name) - if val is not None: - return wsgi_decoding_dance(val, self.charset) - - script_name = _get_wsgi_string('SCRIPT_NAME') - path_info = _get_wsgi_string('PATH_INFO') - query_args = _get_wsgi_string('QUERY_STRING') - return Map.bind(self, server_name, script_name, - subdomain, environ['wsgi.url_scheme'], - environ['REQUEST_METHOD'], path_info, - query_args=query_args) - - def update(self): - """Called before matching and building to keep the compiled rules - in the correct order after things changed. - """ - if not self._remap: - return - - with self._remap_lock: - if not self._remap: - return - - self._rules.sort(key=lambda x: x.match_compare_key()) - for rules in itervalues(self._rules_by_endpoint): - rules.sort(key=lambda x: x.build_compare_key()) - self._remap = False - - def __repr__(self): - rules = self.iter_rules() - return '%s(%s)' % (self.__class__.__name__, pformat(list(rules))) - - -class MapAdapter(object): - - """Returned by :meth:`Map.bind` or :meth:`Map.bind_to_environ` and does - the URL matching and building based on runtime information. - """ - - def __init__(self, map, server_name, script_name, subdomain, - url_scheme, path_info, default_method, query_args=None): - self.map = map - self.server_name = to_unicode(server_name) - script_name = to_unicode(script_name) - if not script_name.endswith(u'/'): - script_name += u'/' - self.script_name = script_name - self.subdomain = to_unicode(subdomain) - self.url_scheme = to_unicode(url_scheme) - self.path_info = to_unicode(path_info) - self.default_method = to_unicode(default_method) - self.query_args = query_args - - def dispatch(self, view_func, path_info=None, method=None, - catch_http_exceptions=False): - """Does the complete dispatching process. `view_func` is called with - the endpoint and a dict with the values for the view. It should - look up the view function, call it, and return a response object - or WSGI application. http exceptions are not caught by default - so that applications can display nicer error messages by just - catching them by hand. If you want to stick with the default - error messages you can pass it ``catch_http_exceptions=True`` and - it will catch the http exceptions. - - Here a small example for the dispatch usage:: - - from werkzeug.wrappers import Request, Response - from werkzeug.wsgi import responder - from werkzeug.routing import Map, Rule - - def on_index(request): - return Response('Hello from the index') - - url_map = Map([Rule('/', endpoint='index')]) - views = {'index': on_index} - - @responder - def application(environ, start_response): - request = Request(environ) - urls = url_map.bind_to_environ(environ) - return urls.dispatch(lambda e, v: views[e](request, **v), - catch_http_exceptions=True) - - Keep in mind that this method might return exception objects, too, so - use :class:`Response.force_type` to get a response object. - - :param view_func: a function that is called with the endpoint as - first argument and the value dict as second. Has - to dispatch to the actual view function with this - information. (see above) - :param path_info: the path info to use for matching. Overrides the - path info specified on binding. - :param method: the HTTP method used for matching. Overrides the - method specified on binding. - :param catch_http_exceptions: set to `True` to catch any of the - werkzeug :class:`HTTPException`\s. - """ - try: - try: - endpoint, args = self.match(path_info, method) - except RequestRedirect as e: - return e - return view_func(endpoint, args) - except HTTPException as e: - if catch_http_exceptions: - return e - raise - - def match(self, path_info=None, method=None, return_rule=False, - query_args=None): - """The usage is simple: you just pass the match method the current - path info as well as the method (which defaults to `GET`). The - following things can then happen: - - - you receive a `NotFound` exception that indicates that no URL is - matching. A `NotFound` exception is also a WSGI application you - can call to get a default page not found page (happens to be the - same object as `werkzeug.exceptions.NotFound`) - - - you receive a `MethodNotAllowed` exception that indicates that there - is a match for this URL but not for the current request method. - This is useful for RESTful applications. - - - you receive a `RequestRedirect` exception with a `new_url` - attribute. This exception is used to notify you about a request - Werkzeug requests from your WSGI application. This is for example the - case if you request ``/foo`` although the correct URL is ``/foo/`` - You can use the `RequestRedirect` instance as response-like object - similar to all other subclasses of `HTTPException`. - - - you get a tuple in the form ``(endpoint, arguments)`` if there is - a match (unless `return_rule` is True, in which case you get a tuple - in the form ``(rule, arguments)``) - - If the path info is not passed to the match method the default path - info of the map is used (defaults to the root URL if not defined - explicitly). - - All of the exceptions raised are subclasses of `HTTPException` so they - can be used as WSGI responses. They will all render generic error or - redirect pages. - - Here is a small example for matching: - - >>> m = Map([ - ... Rule('/', endpoint='index'), - ... Rule('/downloads/', endpoint='downloads/index'), - ... Rule('/downloads/', endpoint='downloads/show') - ... ]) - >>> urls = m.bind("example.com", "/") - >>> urls.match("/", "GET") - ('index', {}) - >>> urls.match("/downloads/42") - ('downloads/show', {'id': 42}) - - And here is what happens on redirect and missing URLs: - - >>> urls.match("/downloads") - Traceback (most recent call last): - ... - RequestRedirect: http://example.com/downloads/ - >>> urls.match("/missing") - Traceback (most recent call last): - ... - NotFound: 404 Not Found - - :param path_info: the path info to use for matching. Overrides the - path info specified on binding. - :param method: the HTTP method used for matching. Overrides the - method specified on binding. - :param return_rule: return the rule that matched instead of just the - endpoint (defaults to `False`). - :param query_args: optional query arguments that are used for - automatic redirects as string or dictionary. It's - currently not possible to use the query arguments - for URL matching. - - .. versionadded:: 0.6 - `return_rule` was added. - - .. versionadded:: 0.7 - `query_args` was added. - - .. versionchanged:: 0.8 - `query_args` can now also be a string. - """ - self.map.update() - if path_info is None: - path_info = self.path_info - else: - path_info = to_unicode(path_info, self.map.charset) - if query_args is None: - query_args = self.query_args - method = (method or self.default_method).upper() - - path = u'%s|%s' % ( - self.map.host_matching and self.server_name or self.subdomain, - path_info and '/%s' % path_info.lstrip('/') - ) - - have_match_for = set() - for rule in self.map._rules: - try: - rv = rule.match(path, method) - except RequestSlash: - raise RequestRedirect(self.make_redirect_url( - url_quote(path_info, self.map.charset, - safe='/:|+') + '/', query_args)) - except RequestAliasRedirect as e: - raise RequestRedirect(self.make_alias_redirect_url( - path, rule.endpoint, e.matched_values, method, query_args)) - if rv is None: - continue - if rule.methods is not None and method not in rule.methods: - have_match_for.update(rule.methods) - continue - - if self.map.redirect_defaults: - redirect_url = self.get_default_redirect(rule, method, rv, - query_args) - if redirect_url is not None: - raise RequestRedirect(redirect_url) - - if rule.redirect_to is not None: - if isinstance(rule.redirect_to, string_types): - def _handle_match(match): - value = rv[match.group(1)] - return rule._converters[match.group(1)].to_url(value) - redirect_url = _simple_rule_re.sub(_handle_match, - rule.redirect_to) - else: - redirect_url = rule.redirect_to(self, **rv) - raise RequestRedirect(str(url_join('%s://%s%s%s' % ( - self.url_scheme or 'http', - self.subdomain and self.subdomain + '.' or '', - self.server_name, - self.script_name - ), redirect_url))) - - if return_rule: - return rule, rv - else: - return rule.endpoint, rv - - if have_match_for: - raise MethodNotAllowed(valid_methods=list(have_match_for)) - raise NotFound() - - def test(self, path_info=None, method=None): - """Test if a rule would match. Works like `match` but returns `True` - if the URL matches, or `False` if it does not exist. - - :param path_info: the path info to use for matching. Overrides the - path info specified on binding. - :param method: the HTTP method used for matching. Overrides the - method specified on binding. - """ - try: - self.match(path_info, method) - except RequestRedirect: - pass - except HTTPException: - return False - return True - - def allowed_methods(self, path_info=None): - """Returns the valid methods that match for a given path. - - .. versionadded:: 0.7 - """ - try: - self.match(path_info, method='--') - except MethodNotAllowed as e: - return e.valid_methods - except HTTPException as e: - pass - return [] - - def get_host(self, domain_part): - """Figures out the full host name for the given domain part. The - domain part is a subdomain in case host matching is disabled or - a full host name. - """ - if self.map.host_matching: - if domain_part is None: - return self.server_name - return to_unicode(domain_part, 'ascii') - subdomain = domain_part - if subdomain is None: - subdomain = self.subdomain - else: - subdomain = to_unicode(subdomain, 'ascii') - return (subdomain and subdomain + u'.' or u'') + self.server_name - - def get_default_redirect(self, rule, method, values, query_args): - """A helper that returns the URL to redirect to if it finds one. - This is used for default redirecting only. - - :internal: - """ - assert self.map.redirect_defaults - for r in self.map._rules_by_endpoint[rule.endpoint]: - # every rule that comes after this one, including ourself - # has a lower priority for the defaults. We order the ones - # with the highest priority up for building. - if r is rule: - break - if r.provides_defaults_for(rule) and \ - r.suitable_for(values, method): - values.update(r.defaults) - domain_part, path = r.build(values) - return self.make_redirect_url( - path, query_args, domain_part=domain_part) - - def encode_query_args(self, query_args): - if not isinstance(query_args, string_types): - query_args = url_encode(query_args, self.map.charset) - return query_args - - def make_redirect_url(self, path_info, query_args=None, domain_part=None): - """Creates a redirect URL. - - :internal: - """ - suffix = '' - if query_args: - suffix = '?' + self.encode_query_args(query_args) - return str('%s://%s/%s%s' % ( - self.url_scheme or 'http', - self.get_host(domain_part), - posixpath.join(self.script_name[:-1].lstrip('/'), - path_info.lstrip('/')), - suffix - )) - - def make_alias_redirect_url(self, path, endpoint, values, method, query_args): - """Internally called to make an alias redirect URL.""" - url = self.build(endpoint, values, method, append_unknown=False, - force_external=True) - if query_args: - url += '?' + self.encode_query_args(query_args) - assert url != path, 'detected invalid alias setting. No canonical ' \ - 'URL found' - return url - - def _partial_build(self, endpoint, values, method, append_unknown): - """Helper for :meth:`build`. Returns subdomain and path for the - rule that accepts this endpoint, values and method. - - :internal: - """ - # in case the method is none, try with the default method first - if method is None: - rv = self._partial_build(endpoint, values, self.default_method, - append_unknown) - if rv is not None: - return rv - - # default method did not match or a specific method is passed, - # check all and go with first result. - for rule in self.map._rules_by_endpoint.get(endpoint, ()): - if rule.suitable_for(values, method): - rv = rule.build(values, append_unknown) - if rv is not None: - return rv - - def build(self, endpoint, values=None, method=None, force_external=False, - append_unknown=True): - """Building URLs works pretty much the other way round. Instead of - `match` you call `build` and pass it the endpoint and a dict of - arguments for the placeholders. - - The `build` function also accepts an argument called `force_external` - which, if you set it to `True` will force external URLs. Per default - external URLs (include the server name) will only be used if the - target URL is on a different subdomain. - - >>> m = Map([ - ... Rule('/', endpoint='index'), - ... Rule('/downloads/', endpoint='downloads/index'), - ... Rule('/downloads/', endpoint='downloads/show') - ... ]) - >>> urls = m.bind("example.com", "/") - >>> urls.build("index", {}) - '/' - >>> urls.build("downloads/show", {'id': 42}) - '/downloads/42' - >>> urls.build("downloads/show", {'id': 42}, force_external=True) - 'http://example.com/downloads/42' - - Because URLs cannot contain non ASCII data you will always get - bytestrings back. Non ASCII characters are urlencoded with the - charset defined on the map instance. - - Additional values are converted to unicode and appended to the URL as - URL querystring parameters: - - >>> urls.build("index", {'q': 'My Searchstring'}) - '/?q=My+Searchstring' - - When processing those additional values, lists are furthermore - interpreted as multiple values (as per - :py:class:`werkzeug.datastructures.MultiDict`): - - >>> urls.build("index", {'q': ['a', 'b', 'c']}) - '/?q=a&q=b&q=c' - - If a rule does not exist when building a `BuildError` exception is - raised. - - The build method accepts an argument called `method` which allows you - to specify the method you want to have an URL built for if you have - different methods for the same endpoint specified. - - .. versionadded:: 0.6 - the `append_unknown` parameter was added. - - :param endpoint: the endpoint of the URL to build. - :param values: the values for the URL to build. Unhandled values are - appended to the URL as query parameters. - :param method: the HTTP method for the rule if there are different - URLs for different methods on the same endpoint. - :param force_external: enforce full canonical external URLs. If the URL - scheme is not provided, this will generate - a protocol-relative URL. - :param append_unknown: unknown parameters are appended to the generated - URL as query string argument. Disable this - if you want the builder to ignore those. - """ - self.map.update() - if values: - if isinstance(values, MultiDict): - valueiter = iteritems(values, multi=True) - else: - valueiter = iteritems(values) - values = dict((k, v) for k, v in valueiter if v is not None) - else: - values = {} - - rv = self._partial_build(endpoint, values, method, append_unknown) - if rv is None: - raise BuildError(endpoint, values, method, self) - domain_part, path = rv - - host = self.get_host(domain_part) - - # shortcut this. - if not force_external and ( - (self.map.host_matching and host == self.server_name) or - (not self.map.host_matching and domain_part == self.subdomain) - ): - return str(url_join(self.script_name, './' + path.lstrip('/'))) - return str('%s//%s%s/%s' % ( - self.url_scheme + ':' if self.url_scheme else '', - host, - self.script_name[:-1], - path.lstrip('/') - )) diff --git a/pyextra/werkzeug/security.py b/pyextra/werkzeug/security.py deleted file mode 100644 index d4c5c9f487b8ce..00000000000000 --- a/pyextra/werkzeug/security.py +++ /dev/null @@ -1,270 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.security - ~~~~~~~~~~~~~~~~~ - - Security related helpers such as secure password hashing tools. - - :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -import os -import hmac -import hashlib -import posixpath -import codecs -from struct import Struct -from random import SystemRandom -from operator import xor -from itertools import starmap - -from werkzeug._compat import range_type, PY2, text_type, izip, to_bytes, \ - string_types, to_native - - -SALT_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' -DEFAULT_PBKDF2_ITERATIONS = 50000 - - -_pack_int = Struct('>I').pack -_builtin_safe_str_cmp = getattr(hmac, 'compare_digest', None) -_sys_rng = SystemRandom() -_os_alt_seps = list(sep for sep in [os.path.sep, os.path.altsep] - if sep not in (None, '/')) - - -def _find_hashlib_algorithms(): - algos = getattr(hashlib, 'algorithms', None) - if algos is None: - algos = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512') - rv = {} - for algo in algos: - func = getattr(hashlib, algo, None) - if func is not None: - rv[algo] = func - return rv -_hash_funcs = _find_hashlib_algorithms() - - -def pbkdf2_hex(data, salt, iterations=DEFAULT_PBKDF2_ITERATIONS, - keylen=None, hashfunc=None): - """Like :func:`pbkdf2_bin`, but returns a hex-encoded string. - - .. versionadded:: 0.9 - - :param data: the data to derive. - :param salt: the salt for the derivation. - :param iterations: the number of iterations. - :param keylen: the length of the resulting key. If not provided, - the digest size will be used. - :param hashfunc: the hash function to use. This can either be the - string name of a known hash function, or a function - from the hashlib module. Defaults to sha256. - """ - rv = pbkdf2_bin(data, salt, iterations, keylen, hashfunc) - return to_native(codecs.encode(rv, 'hex_codec')) - - -_has_native_pbkdf2 = hasattr(hashlib, 'pbkdf2_hmac') - - -def pbkdf2_bin(data, salt, iterations=DEFAULT_PBKDF2_ITERATIONS, - keylen=None, hashfunc=None): - """Returns a binary digest for the PBKDF2 hash algorithm of `data` - with the given `salt`. It iterates `iterations` times and produces a - key of `keylen` bytes. By default, SHA-256 is used as hash function; - a different hashlib `hashfunc` can be provided. - - .. versionadded:: 0.9 - - :param data: the data to derive. - :param salt: the salt for the derivation. - :param iterations: the number of iterations. - :param keylen: the length of the resulting key. If not provided - the digest size will be used. - :param hashfunc: the hash function to use. This can either be the - string name of a known hash function or a function - from the hashlib module. Defaults to sha256. - """ - if isinstance(hashfunc, string_types): - hashfunc = _hash_funcs[hashfunc] - elif not hashfunc: - hashfunc = hashlib.sha256 - data = to_bytes(data) - salt = to_bytes(salt) - - # If we're on Python with pbkdf2_hmac we can try to use it for - # compatible digests. - if _has_native_pbkdf2: - _test_hash = hashfunc() - if hasattr(_test_hash, 'name') and \ - _test_hash.name in _hash_funcs: - return hashlib.pbkdf2_hmac(_test_hash.name, - data, salt, iterations, - keylen) - - mac = hmac.HMAC(data, None, hashfunc) - if not keylen: - keylen = mac.digest_size - - def _pseudorandom(x, mac=mac): - h = mac.copy() - h.update(x) - return bytearray(h.digest()) - buf = bytearray() - for block in range_type(1, -(-keylen // mac.digest_size) + 1): - rv = u = _pseudorandom(salt + _pack_int(block)) - for i in range_type(iterations - 1): - u = _pseudorandom(bytes(u)) - rv = bytearray(starmap(xor, izip(rv, u))) - buf.extend(rv) - return bytes(buf[:keylen]) - - -def safe_str_cmp(a, b): - """This function compares strings in somewhat constant time. This - requires that the length of at least one string is known in advance. - - Returns `True` if the two strings are equal, or `False` if they are not. - - .. versionadded:: 0.7 - """ - if isinstance(a, text_type): - a = a.encode('utf-8') - if isinstance(b, text_type): - b = b.encode('utf-8') - - if _builtin_safe_str_cmp is not None: - return _builtin_safe_str_cmp(a, b) - - if len(a) != len(b): - return False - - rv = 0 - if PY2: - for x, y in izip(a, b): - rv |= ord(x) ^ ord(y) - else: - for x, y in izip(a, b): - rv |= x ^ y - - return rv == 0 - - -def gen_salt(length): - """Generate a random string of SALT_CHARS with specified ``length``.""" - if length <= 0: - raise ValueError('Salt length must be positive') - return ''.join(_sys_rng.choice(SALT_CHARS) for _ in range_type(length)) - - -def _hash_internal(method, salt, password): - """Internal password hash helper. Supports plaintext without salt, - unsalted and salted passwords. In case salted passwords are used - hmac is used. - """ - if method == 'plain': - return password, method - - if isinstance(password, text_type): - password = password.encode('utf-8') - - if method.startswith('pbkdf2:'): - args = method[7:].split(':') - if len(args) not in (1, 2): - raise ValueError('Invalid number of arguments for PBKDF2') - method = args.pop(0) - iterations = args and int(args[0] or 0) or DEFAULT_PBKDF2_ITERATIONS - is_pbkdf2 = True - actual_method = 'pbkdf2:%s:%d' % (method, iterations) - else: - is_pbkdf2 = False - actual_method = method - - hash_func = _hash_funcs.get(method) - if hash_func is None: - raise TypeError('invalid method %r' % method) - - if is_pbkdf2: - if not salt: - raise ValueError('Salt is required for PBKDF2') - rv = pbkdf2_hex(password, salt, iterations, - hashfunc=hash_func) - elif salt: - if isinstance(salt, text_type): - salt = salt.encode('utf-8') - rv = hmac.HMAC(salt, password, hash_func).hexdigest() - else: - h = hash_func() - h.update(password) - rv = h.hexdigest() - return rv, actual_method - - -def generate_password_hash(password, method='pbkdf2:sha256', salt_length=8): - """Hash a password with the given method and salt with a string of - the given length. The format of the string returned includes the method - that was used so that :func:`check_password_hash` can check the hash. - - The format for the hashed string looks like this:: - - method$salt$hash - - This method can **not** generate unsalted passwords but it is possible - to set param method='plain' in order to enforce plaintext passwords. - If a salt is used, hmac is used internally to salt the password. - - If PBKDF2 is wanted it can be enabled by setting the method to - ``pbkdf2:method:iterations`` where iterations is optional:: - - pbkdf2:sha256:80000$salt$hash - pbkdf2:sha256$salt$hash - - :param password: the password to hash. - :param method: the hash method to use (one that hashlib supports). Can - optionally be in the format ``pbkdf2:[:iterations]`` - to enable PBKDF2. - :param salt_length: the length of the salt in letters. - """ - salt = method != 'plain' and gen_salt(salt_length) or '' - h, actual_method = _hash_internal(method, salt, password) - return '%s$%s$%s' % (actual_method, salt, h) - - -def check_password_hash(pwhash, password): - """check a password against a given salted and hashed password value. - In order to support unsalted legacy passwords this method supports - plain text passwords, md5 and sha1 hashes (both salted and unsalted). - - Returns `True` if the password matched, `False` otherwise. - - :param pwhash: a hashed string like returned by - :func:`generate_password_hash`. - :param password: the plaintext password to compare against the hash. - """ - if pwhash.count('$') < 2: - return False - method, salt, hashval = pwhash.split('$', 2) - return safe_str_cmp(_hash_internal(method, salt, password)[0], hashval) - - -def safe_join(directory, *pathnames): - """Safely join `directory` and one or more untrusted `pathnames`. If this - cannot be done, this function returns ``None``. - - :param directory: the base directory. - :param pathnames: the untrusted pathnames relative to that directory. - """ - parts = [directory] - for filename in pathnames: - if filename != '': - filename = posixpath.normpath(filename) - for sep in _os_alt_seps: - if sep in filename: - return None - if os.path.isabs(filename) or \ - filename == '..' or \ - filename.startswith('../'): - return None - parts.append(filename) - return posixpath.join(*parts) diff --git a/pyextra/werkzeug/serving.py b/pyextra/werkzeug/serving.py deleted file mode 100644 index 902f1aa1c62d3a..00000000000000 --- a/pyextra/werkzeug/serving.py +++ /dev/null @@ -1,862 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.serving - ~~~~~~~~~~~~~~~~ - - There are many ways to serve a WSGI application. While you're developing - it you usually don't want a full blown webserver like Apache but a simple - standalone one. From Python 2.5 onwards there is the `wsgiref`_ server in - the standard library. If you're using older versions of Python you can - download the package from the cheeseshop. - - However there are some caveats. Sourcecode won't reload itself when - changed and each time you kill the server using ``^C`` you get an - `KeyboardInterrupt` error. While the latter is easy to solve the first - one can be a pain in the ass in some situations. - - The easiest way is creating a small ``start-myproject.py`` that runs the - application:: - - #!/usr/bin/env python - # -*- coding: utf-8 -*- - from myproject import make_app - from werkzeug.serving import run_simple - - app = make_app(...) - run_simple('localhost', 8080, app, use_reloader=True) - - You can also pass it a `extra_files` keyword argument with a list of - additional files (like configuration files) you want to observe. - - For bigger applications you should consider using `click` - (http://click.pocoo.org) instead of a simple start file. - - - :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -from __future__ import with_statement - -import io -import os -import socket -import sys -import signal - - -can_fork = hasattr(os, "fork") - - -try: - import termcolor -except ImportError: - termcolor = None - -try: - import ssl -except ImportError: - class _SslDummy(object): - def __getattr__(self, name): - raise RuntimeError('SSL support unavailable') - ssl = _SslDummy() - - -def _get_openssl_crypto_module(): - try: - from OpenSSL import crypto - except ImportError: - raise TypeError('Using ad-hoc certificates requires the pyOpenSSL ' - 'library.') - else: - return crypto - - -try: - import SocketServer as socketserver - from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler -except ImportError: - import socketserver - from http.server import HTTPServer, BaseHTTPRequestHandler - -ThreadingMixIn = socketserver.ThreadingMixIn - -if can_fork: - ForkingMixIn = socketserver.ForkingMixIn -else: - class ForkingMixIn(object): - pass - -# important: do not use relative imports here or python -m will break -import werkzeug -from werkzeug._internal import _log -from werkzeug._compat import PY2, WIN, reraise, wsgi_encoding_dance -from werkzeug.urls import url_parse, url_unquote -from werkzeug.exceptions import InternalServerError - - -LISTEN_QUEUE = 128 -can_open_by_fd = not WIN and hasattr(socket, 'fromfd') - - -class DechunkedInput(io.RawIOBase): - """An input stream that handles Transfer-Encoding 'chunked'""" - - def __init__(self, rfile): - self._rfile = rfile - self._done = False - self._len = 0 - - def readable(self): - return True - - def read_chunk_len(self): - try: - line = self._rfile.readline().decode('latin1') - _len = int(line.strip(), 16) - except ValueError: - raise IOError('Invalid chunk header') - if _len < 0: - raise IOError('Negative chunk length not allowed') - return _len - - def readinto(self, buf): - read = 0 - while not self._done and read < len(buf): - if self._len == 0: - # This is the first chunk or we fully consumed the previous - # one. Read the next length of the next chunk - self._len = self.read_chunk_len() - - if self._len == 0: - # Found the final chunk of size 0. The stream is now exhausted, - # but there is still a final newline that should be consumed - self._done = True - - if self._len > 0: - # There is data (left) in this chunk, so append it to the - # buffer. If this operation fully consumes the chunk, this will - # reset self._len to 0. - n = min(len(buf), self._len) - buf[read:read + n] = self._rfile.read(n) - self._len -= n - read += n - - if self._len == 0: - # Skip the terminating newline of a chunk that has been fully - # consumed. This also applies to the 0-sized final chunk - terminator = self._rfile.readline() - if terminator not in (b'\n', b'\r\n', b'\r'): - raise IOError('Missing chunk terminating newline') - - return read - - -class WSGIRequestHandler(BaseHTTPRequestHandler, object): - - """A request handler that implements WSGI dispatching.""" - - @property - def server_version(self): - return 'Werkzeug/' + werkzeug.__version__ - - def make_environ(self): - request_url = url_parse(self.path) - - def shutdown_server(): - self.server.shutdown_signal = True - - url_scheme = self.server.ssl_context is None and 'http' or 'https' - path_info = url_unquote(request_url.path) - - environ = { - 'wsgi.version': (1, 0), - 'wsgi.url_scheme': url_scheme, - 'wsgi.input': self.rfile, - 'wsgi.errors': sys.stderr, - 'wsgi.multithread': self.server.multithread, - 'wsgi.multiprocess': self.server.multiprocess, - 'wsgi.run_once': False, - 'werkzeug.server.shutdown': shutdown_server, - 'SERVER_SOFTWARE': self.server_version, - 'REQUEST_METHOD': self.command, - 'SCRIPT_NAME': '', - 'PATH_INFO': wsgi_encoding_dance(path_info), - 'QUERY_STRING': wsgi_encoding_dance(request_url.query), - 'REMOTE_ADDR': self.address_string(), - 'REMOTE_PORT': self.port_integer(), - 'SERVER_NAME': self.server.server_address[0], - 'SERVER_PORT': str(self.server.server_address[1]), - 'SERVER_PROTOCOL': self.request_version - } - - for key, value in self.headers.items(): - key = key.upper().replace('-', '_') - if key not in ('CONTENT_TYPE', 'CONTENT_LENGTH'): - key = 'HTTP_' + key - environ[key] = value - - if environ.get('HTTP_TRANSFER_ENCODING', '').strip().lower() == 'chunked': - environ['wsgi.input_terminated'] = True - environ['wsgi.input'] = DechunkedInput(environ['wsgi.input']) - - if request_url.scheme and request_url.netloc: - environ['HTTP_HOST'] = request_url.netloc - - return environ - - def run_wsgi(self): - if self.headers.get('Expect', '').lower().strip() == '100-continue': - self.wfile.write(b'HTTP/1.1 100 Continue\r\n\r\n') - - self.environ = environ = self.make_environ() - headers_set = [] - headers_sent = [] - - def write(data): - assert headers_set, 'write() before start_response' - if not headers_sent: - status, response_headers = headers_sent[:] = headers_set - try: - code, msg = status.split(None, 1) - except ValueError: - code, msg = status, "" - code = int(code) - self.send_response(code, msg) - header_keys = set() - for key, value in response_headers: - self.send_header(key, value) - key = key.lower() - header_keys.add(key) - if not ('content-length' in header_keys or - environ['REQUEST_METHOD'] == 'HEAD' or - code < 200 or code in (204, 304)): - self.close_connection = True - self.send_header('Connection', 'close') - if 'server' not in header_keys: - self.send_header('Server', self.version_string()) - if 'date' not in header_keys: - self.send_header('Date', self.date_time_string()) - self.end_headers() - - assert isinstance(data, bytes), 'applications must write bytes' - self.wfile.write(data) - self.wfile.flush() - - def start_response(status, response_headers, exc_info=None): - if exc_info: - try: - if headers_sent: - reraise(*exc_info) - finally: - exc_info = None - elif headers_set: - raise AssertionError('Headers already set') - headers_set[:] = [status, response_headers] - return write - - def execute(app): - application_iter = app(environ, start_response) - try: - for data in application_iter: - write(data) - if not headers_sent: - write(b'') - finally: - if hasattr(application_iter, 'close'): - application_iter.close() - application_iter = None - - try: - execute(self.server.app) - except (socket.error, socket.timeout) as e: - self.connection_dropped(e, environ) - except Exception: - if self.server.passthrough_errors: - raise - from werkzeug.debug.tbtools import get_current_traceback - traceback = get_current_traceback(ignore_system_exceptions=True) - try: - # if we haven't yet sent the headers but they are set - # we roll back to be able to set them again. - if not headers_sent: - del headers_set[:] - execute(InternalServerError()) - except Exception: - pass - self.server.log('error', 'Error on request:\n%s', - traceback.plaintext) - - def handle(self): - """Handles a request ignoring dropped connections.""" - rv = None - try: - rv = BaseHTTPRequestHandler.handle(self) - except (socket.error, socket.timeout) as e: - self.connection_dropped(e) - except Exception: - if self.server.ssl_context is None or not is_ssl_error(): - raise - if self.server.shutdown_signal: - self.initiate_shutdown() - return rv - - def initiate_shutdown(self): - """A horrible, horrible way to kill the server for Python 2.6 and - later. It's the best we can do. - """ - # Windows does not provide SIGKILL, go with SIGTERM then. - sig = getattr(signal, 'SIGKILL', signal.SIGTERM) - # reloader active - if os.environ.get('WERKZEUG_RUN_MAIN') == 'true': - os.kill(os.getpid(), sig) - # python 2.7 - self.server._BaseServer__shutdown_request = True - # python 2.6 - self.server._BaseServer__serving = False - - def connection_dropped(self, error, environ=None): - """Called if the connection was closed by the client. By default - nothing happens. - """ - - def handle_one_request(self): - """Handle a single HTTP request.""" - self.raw_requestline = self.rfile.readline() - if not self.raw_requestline: - self.close_connection = 1 - elif self.parse_request(): - return self.run_wsgi() - - def send_response(self, code, message=None): - """Send the response header and log the response code.""" - self.log_request(code) - if message is None: - message = code in self.responses and self.responses[code][0] or '' - if self.request_version != 'HTTP/0.9': - hdr = "%s %d %s\r\n" % (self.protocol_version, code, message) - self.wfile.write(hdr.encode('ascii')) - - def version_string(self): - return BaseHTTPRequestHandler.version_string(self).strip() - - def address_string(self): - if getattr(self, 'environ', None): - return self.environ['REMOTE_ADDR'] - else: - return self.client_address[0] - - def port_integer(self): - return self.client_address[1] - - def log_request(self, code='-', size='-'): - msg = self.requestline - code = str(code) - - if termcolor: - color = termcolor.colored - - if code[0] == '1': # 1xx - Informational - msg = color(msg, attrs=['bold']) - elif code[0] == '2': # 2xx - Success - msg = color(msg, color='white') - elif code == '304': # 304 - Resource Not Modified - msg = color(msg, color='cyan') - elif code[0] == '3': # 3xx - Redirection - msg = color(msg, color='green') - elif code == '404': # 404 - Resource Not Found - msg = color(msg, color='yellow') - elif code[0] == '4': # 4xx - Client Error - msg = color(msg, color='red', attrs=['bold']) - else: # 5xx, or any other response - msg = color(msg, color='magenta', attrs=['bold']) - - self.log('info', '"%s" %s %s', msg, code, size) - - def log_error(self, *args): - self.log('error', *args) - - def log_message(self, format, *args): - self.log('info', format, *args) - - def log(self, type, message, *args): - _log(type, '%s - - [%s] %s\n' % (self.address_string(), - self.log_date_time_string(), - message % args)) - - -#: backwards compatible name if someone is subclassing it -BaseRequestHandler = WSGIRequestHandler - - -def generate_adhoc_ssl_pair(cn=None): - from random import random - crypto = _get_openssl_crypto_module() - - # pretty damn sure that this is not actually accepted by anyone - if cn is None: - cn = '*' - - cert = crypto.X509() - cert.set_serial_number(int(random() * sys.maxsize)) - cert.gmtime_adj_notBefore(0) - cert.gmtime_adj_notAfter(60 * 60 * 24 * 365) - - subject = cert.get_subject() - subject.CN = cn - subject.O = 'Dummy Certificate' # noqa: E741 - - issuer = cert.get_issuer() - issuer.CN = 'Untrusted Authority' - issuer.O = 'Self-Signed' # noqa: E741 - - pkey = crypto.PKey() - pkey.generate_key(crypto.TYPE_RSA, 2048) - cert.set_pubkey(pkey) - cert.sign(pkey, 'sha256') - - return cert, pkey - - -def make_ssl_devcert(base_path, host=None, cn=None): - """Creates an SSL key for development. This should be used instead of - the ``'adhoc'`` key which generates a new cert on each server start. - It accepts a path for where it should store the key and cert and - either a host or CN. If a host is given it will use the CN - ``*.host/CN=host``. - - For more information see :func:`run_simple`. - - .. versionadded:: 0.9 - - :param base_path: the path to the certificate and key. The extension - ``.crt`` is added for the certificate, ``.key`` is - added for the key. - :param host: the name of the host. This can be used as an alternative - for the `cn`. - :param cn: the `CN` to use. - """ - from OpenSSL import crypto - if host is not None: - cn = '*.%s/CN=%s' % (host, host) - cert, pkey = generate_adhoc_ssl_pair(cn=cn) - - cert_file = base_path + '.crt' - pkey_file = base_path + '.key' - - with open(cert_file, 'wb') as f: - f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) - with open(pkey_file, 'wb') as f: - f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)) - - return cert_file, pkey_file - - -def generate_adhoc_ssl_context(): - """Generates an adhoc SSL context for the development server.""" - crypto = _get_openssl_crypto_module() - import tempfile - import atexit - - cert, pkey = generate_adhoc_ssl_pair() - cert_handle, cert_file = tempfile.mkstemp() - pkey_handle, pkey_file = tempfile.mkstemp() - atexit.register(os.remove, pkey_file) - atexit.register(os.remove, cert_file) - - os.write(cert_handle, crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) - os.write(pkey_handle, crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)) - os.close(cert_handle) - os.close(pkey_handle) - ctx = load_ssl_context(cert_file, pkey_file) - return ctx - - -def load_ssl_context(cert_file, pkey_file=None, protocol=None): - """Loads SSL context from cert/private key files and optional protocol. - Many parameters are directly taken from the API of - :py:class:`ssl.SSLContext`. - - :param cert_file: Path of the certificate to use. - :param pkey_file: Path of the private key to use. If not given, the key - will be obtained from the certificate file. - :param protocol: One of the ``PROTOCOL_*`` constants in the stdlib ``ssl`` - module. Defaults to ``PROTOCOL_SSLv23``. - """ - if protocol is None: - protocol = ssl.PROTOCOL_SSLv23 - ctx = _SSLContext(protocol) - ctx.load_cert_chain(cert_file, pkey_file) - return ctx - - -class _SSLContext(object): - - '''A dummy class with a small subset of Python3's ``ssl.SSLContext``, only - intended to be used with and by Werkzeug.''' - - def __init__(self, protocol): - self._protocol = protocol - self._certfile = None - self._keyfile = None - self._password = None - - def load_cert_chain(self, certfile, keyfile=None, password=None): - self._certfile = certfile - self._keyfile = keyfile or certfile - self._password = password - - def wrap_socket(self, sock, **kwargs): - return ssl.wrap_socket(sock, keyfile=self._keyfile, - certfile=self._certfile, - ssl_version=self._protocol, **kwargs) - - -def is_ssl_error(error=None): - """Checks if the given error (or the current one) is an SSL error.""" - exc_types = (ssl.SSLError,) - try: - from OpenSSL.SSL import Error - exc_types += (Error,) - except ImportError: - pass - - if error is None: - error = sys.exc_info()[1] - return isinstance(error, exc_types) - - -def select_ip_version(host, port): - """Returns AF_INET4 or AF_INET6 depending on where to connect to.""" - # disabled due to problems with current ipv6 implementations - # and various operating systems. Probably this code also is - # not supposed to work, but I can't come up with any other - # ways to implement this. - # try: - # info = socket.getaddrinfo(host, port, socket.AF_UNSPEC, - # socket.SOCK_STREAM, 0, - # socket.AI_PASSIVE) - # if info: - # return info[0][0] - # except socket.gaierror: - # pass - if ':' in host and hasattr(socket, 'AF_INET6'): - return socket.AF_INET6 - return socket.AF_INET - - -def get_sockaddr(host, port, family): - """Returns a fully qualified socket address, that can properly used by - socket.bind""" - try: - res = socket.getaddrinfo(host, port, family, - socket.SOCK_STREAM, socket.SOL_TCP) - except socket.gaierror: - return (host, port) - return res[0][4] - - -class BaseWSGIServer(HTTPServer, object): - - """Simple single-threaded, single-process WSGI server.""" - multithread = False - multiprocess = False - request_queue_size = LISTEN_QUEUE - - def __init__(self, host, port, app, handler=None, - passthrough_errors=False, ssl_context=None, fd=None): - if handler is None: - handler = WSGIRequestHandler - - self.address_family = select_ip_version(host, port) - - if fd is not None: - real_sock = socket.fromfd(fd, self.address_family, - socket.SOCK_STREAM) - port = 0 - HTTPServer.__init__(self, get_sockaddr(host, int(port), - self.address_family), handler) - self.app = app - self.passthrough_errors = passthrough_errors - self.shutdown_signal = False - self.host = host - self.port = self.socket.getsockname()[1] - - # Patch in the original socket. - if fd is not None: - self.socket.close() - self.socket = real_sock - self.server_address = self.socket.getsockname() - - if ssl_context is not None: - if isinstance(ssl_context, tuple): - ssl_context = load_ssl_context(*ssl_context) - if ssl_context == 'adhoc': - ssl_context = generate_adhoc_ssl_context() - # If we are on Python 2 the return value from socket.fromfd - # is an internal socket object but what we need for ssl wrap - # is the wrapper around it :( - sock = self.socket - if PY2 and not isinstance(sock, socket.socket): - sock = socket.socket(sock.family, sock.type, sock.proto, sock) - self.socket = ssl_context.wrap_socket(sock, server_side=True) - self.ssl_context = ssl_context - else: - self.ssl_context = None - - def log(self, type, message, *args): - _log(type, message, *args) - - def serve_forever(self): - self.shutdown_signal = False - try: - HTTPServer.serve_forever(self) - except KeyboardInterrupt: - pass - finally: - self.server_close() - - def handle_error(self, request, client_address): - if self.passthrough_errors: - raise - return HTTPServer.handle_error(self, request, client_address) - - def get_request(self): - con, info = self.socket.accept() - return con, info - - -class ThreadedWSGIServer(ThreadingMixIn, BaseWSGIServer): - - """A WSGI server that does threading.""" - multithread = True - daemon_threads = True - - -class ForkingWSGIServer(ForkingMixIn, BaseWSGIServer): - - """A WSGI server that does forking.""" - multiprocess = True - - def __init__(self, host, port, app, processes=40, handler=None, - passthrough_errors=False, ssl_context=None, fd=None): - if not can_fork: - raise ValueError('Your platform does not support forking.') - BaseWSGIServer.__init__(self, host, port, app, handler, - passthrough_errors, ssl_context, fd) - self.max_children = processes - - -def make_server(host=None, port=None, app=None, threaded=False, processes=1, - request_handler=None, passthrough_errors=False, - ssl_context=None, fd=None): - """Create a new server instance that is either threaded, or forks - or just processes one request after another. - """ - if threaded and processes > 1: - raise ValueError("cannot have a multithreaded and " - "multi process server.") - elif threaded: - return ThreadedWSGIServer(host, port, app, request_handler, - passthrough_errors, ssl_context, fd=fd) - elif processes > 1: - return ForkingWSGIServer(host, port, app, processes, request_handler, - passthrough_errors, ssl_context, fd=fd) - else: - return BaseWSGIServer(host, port, app, request_handler, - passthrough_errors, ssl_context, fd=fd) - - -def is_running_from_reloader(): - """Checks if the application is running from within the Werkzeug - reloader subprocess. - - .. versionadded:: 0.10 - """ - return os.environ.get('WERKZEUG_RUN_MAIN') == 'true' - - -def run_simple(hostname, port, application, use_reloader=False, - use_debugger=False, use_evalex=True, - extra_files=None, reloader_interval=1, - reloader_type='auto', threaded=False, - processes=1, request_handler=None, static_files=None, - passthrough_errors=False, ssl_context=None): - """Start a WSGI application. Optional features include a reloader, - multithreading and fork support. - - This function has a command-line interface too:: - - python -m werkzeug.serving --help - - .. versionadded:: 0.5 - `static_files` was added to simplify serving of static files as well - as `passthrough_errors`. - - .. versionadded:: 0.6 - support for SSL was added. - - .. versionadded:: 0.8 - Added support for automatically loading a SSL context from certificate - file and private key. - - .. versionadded:: 0.9 - Added command-line interface. - - .. versionadded:: 0.10 - Improved the reloader and added support for changing the backend - through the `reloader_type` parameter. See :ref:`reloader` - for more information. - - :param hostname: The host for the application. eg: ``'localhost'`` - :param port: The port for the server. eg: ``8080`` - :param application: the WSGI application to execute - :param use_reloader: should the server automatically restart the python - process if modules were changed? - :param use_debugger: should the werkzeug debugging system be used? - :param use_evalex: should the exception evaluation feature be enabled? - :param extra_files: a list of files the reloader should watch - additionally to the modules. For example configuration - files. - :param reloader_interval: the interval for the reloader in seconds. - :param reloader_type: the type of reloader to use. The default is - auto detection. Valid values are ``'stat'`` and - ``'watchdog'``. See :ref:`reloader` for more - information. - :param threaded: should the process handle each request in a separate - thread? - :param processes: if greater than 1 then handle each request in a new process - up to this maximum number of concurrent processes. - :param request_handler: optional parameter that can be used to replace - the default one. You can use this to replace it - with a different - :class:`~BaseHTTPServer.BaseHTTPRequestHandler` - subclass. - :param static_files: a list or dict of paths for static files. This works - exactly like :class:`SharedDataMiddleware`, it's actually - just wrapping the application in that middleware before - serving. - :param passthrough_errors: set this to `True` to disable the error catching. - This means that the server will die on errors but - it can be useful to hook debuggers in (pdb etc.) - :param ssl_context: an SSL context for the connection. Either an - :class:`ssl.SSLContext`, a tuple in the form - ``(cert_file, pkey_file)``, the string ``'adhoc'`` if - the server should automatically create one, or ``None`` - to disable SSL (which is the default). - """ - if not isinstance(port, int): - raise TypeError('port must be an integer') - if use_debugger: - from werkzeug.debug import DebuggedApplication - application = DebuggedApplication(application, use_evalex) - if static_files: - from werkzeug.wsgi import SharedDataMiddleware - application = SharedDataMiddleware(application, static_files) - - def log_startup(sock): - display_hostname = hostname not in ('', '*') and hostname or 'localhost' - if ':' in display_hostname: - display_hostname = '[%s]' % display_hostname - quit_msg = '(Press CTRL+C to quit)' - port = sock.getsockname()[1] - _log('info', ' * Running on %s://%s:%d/ %s', - ssl_context is None and 'http' or 'https', - display_hostname, port, quit_msg) - - def inner(): - try: - fd = int(os.environ['WERKZEUG_SERVER_FD']) - except (LookupError, ValueError): - fd = None - srv = make_server(hostname, port, application, threaded, - processes, request_handler, - passthrough_errors, ssl_context, - fd=fd) - if fd is None: - log_startup(srv.socket) - srv.serve_forever() - - if use_reloader: - # If we're not running already in the subprocess that is the - # reloader we want to open up a socket early to make sure the - # port is actually available. - if os.environ.get('WERKZEUG_RUN_MAIN') != 'true': - if port == 0 and not can_open_by_fd: - raise ValueError('Cannot bind to a random port with enabled ' - 'reloader if the Python interpreter does ' - 'not support socket opening by fd.') - - # Create and destroy a socket so that any exceptions are - # raised before we spawn a separate Python interpreter and - # lose this ability. - address_family = select_ip_version(hostname, port) - s = socket.socket(address_family, socket.SOCK_STREAM) - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - s.bind(get_sockaddr(hostname, port, address_family)) - if hasattr(s, 'set_inheritable'): - s.set_inheritable(True) - - # If we can open the socket by file descriptor, then we can just - # reuse this one and our socket will survive the restarts. - if can_open_by_fd: - os.environ['WERKZEUG_SERVER_FD'] = str(s.fileno()) - s.listen(LISTEN_QUEUE) - log_startup(s) - else: - s.close() - - # Do not use relative imports, otherwise "python -m werkzeug.serving" - # breaks. - from werkzeug._reloader import run_with_reloader - run_with_reloader(inner, extra_files, reloader_interval, - reloader_type) - else: - inner() - - -def run_with_reloader(*args, **kwargs): - # People keep using undocumented APIs. Do not use this function - # please, we do not guarantee that it continues working. - from werkzeug._reloader import run_with_reloader - return run_with_reloader(*args, **kwargs) - - -def main(): - '''A simple command-line interface for :py:func:`run_simple`.''' - - # in contrast to argparse, this works at least under Python < 2.7 - import optparse - from werkzeug.utils import import_string - - parser = optparse.OptionParser( - usage='Usage: %prog [options] app_module:app_object') - parser.add_option('-b', '--bind', dest='address', - help='The hostname:port the app should listen on.') - parser.add_option('-d', '--debug', dest='use_debugger', - action='store_true', default=False, - help='Use Werkzeug\'s debugger.') - parser.add_option('-r', '--reload', dest='use_reloader', - action='store_true', default=False, - help='Reload Python process if modules change.') - options, args = parser.parse_args() - - hostname, port = None, None - if options.address: - address = options.address.split(':') - hostname = address[0] - if len(address) > 1: - port = address[1] - - if len(args) != 1: - sys.stdout.write('No application supplied, or too much. See --help\n') - sys.exit(1) - app = import_string(args[0]) - - run_simple( - hostname=(hostname or '127.0.0.1'), port=int(port or 5000), - application=app, use_reloader=options.use_reloader, - use_debugger=options.use_debugger - ) - -if __name__ == '__main__': - main() diff --git a/pyextra/werkzeug/test.py b/pyextra/werkzeug/test.py deleted file mode 100644 index acd21793df7133..00000000000000 --- a/pyextra/werkzeug/test.py +++ /dev/null @@ -1,948 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.test - ~~~~~~~~~~~~~ - - This module implements a client to WSGI applications for testing. - - :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -import sys -import mimetypes -from time import time -from random import random -from itertools import chain -from tempfile import TemporaryFile -from io import BytesIO - -try: - from urllib2 import Request as U2Request -except ImportError: - from urllib.request import Request as U2Request -try: - from http.cookiejar import CookieJar -except ImportError: # Py2 - from cookielib import CookieJar - -from werkzeug._compat import iterlists, iteritems, itervalues, to_bytes, \ - string_types, text_type, reraise, wsgi_encoding_dance, \ - make_literal_wrapper -from werkzeug._internal import _empty_stream, _get_environ -from werkzeug.wrappers import BaseRequest -from werkzeug.urls import url_encode, url_fix, iri_to_uri, url_unquote, \ - url_unparse, url_parse -from werkzeug.wsgi import get_host, get_current_url, ClosingIterator -from werkzeug.utils import dump_cookie, get_content_type -from werkzeug.datastructures import FileMultiDict, MultiDict, \ - CombinedMultiDict, Headers, FileStorage, CallbackDict -from werkzeug.http import dump_options_header, parse_options_header - - -def stream_encode_multipart(values, use_tempfile=True, threshold=1024 * 500, - boundary=None, charset='utf-8'): - """Encode a dict of values (either strings or file descriptors or - :class:`FileStorage` objects.) into a multipart encoded string stored - in a file descriptor. - """ - if boundary is None: - boundary = '---------------WerkzeugFormPart_%s%s' % (time(), random()) - _closure = [BytesIO(), 0, False] - - if use_tempfile: - def write_binary(string): - stream, total_length, on_disk = _closure - if on_disk: - stream.write(string) - else: - length = len(string) - if length + _closure[1] <= threshold: - stream.write(string) - else: - new_stream = TemporaryFile('wb+') - new_stream.write(stream.getvalue()) - new_stream.write(string) - _closure[0] = new_stream - _closure[2] = True - _closure[1] = total_length + length - else: - write_binary = _closure[0].write - - def write(string): - write_binary(string.encode(charset)) - - if not isinstance(values, MultiDict): - values = MultiDict(values) - - for key, values in iterlists(values): - for value in values: - write('--%s\r\nContent-Disposition: form-data; name="%s"' % - (boundary, key)) - reader = getattr(value, 'read', None) - if reader is not None: - filename = getattr(value, 'filename', - getattr(value, 'name', None)) - content_type = getattr(value, 'content_type', None) - if content_type is None: - content_type = filename and \ - mimetypes.guess_type(filename)[0] or \ - 'application/octet-stream' - if filename is not None: - write('; filename="%s"\r\n' % filename) - else: - write('\r\n') - write('Content-Type: %s\r\n\r\n' % content_type) - while 1: - chunk = reader(16384) - if not chunk: - break - write_binary(chunk) - else: - if not isinstance(value, string_types): - value = str(value) - - value = to_bytes(value, charset) - write('\r\n\r\n') - write_binary(value) - write('\r\n') - write('--%s--\r\n' % boundary) - - length = int(_closure[0].tell()) - _closure[0].seek(0) - return _closure[0], length, boundary - - -def encode_multipart(values, boundary=None, charset='utf-8'): - """Like `stream_encode_multipart` but returns a tuple in the form - (``boundary``, ``data``) where data is a bytestring. - """ - stream, length, boundary = stream_encode_multipart( - values, use_tempfile=False, boundary=boundary, charset=charset) - return boundary, stream.read() - - -def File(fd, filename=None, mimetype=None): - """Backwards compat.""" - from warnings import warn - warn(DeprecationWarning('werkzeug.test.File is deprecated, use the ' - 'EnvironBuilder or FileStorage instead')) - return FileStorage(fd, filename=filename, content_type=mimetype) - - -class _TestCookieHeaders(object): - - """A headers adapter for cookielib - """ - - def __init__(self, headers): - self.headers = headers - - def getheaders(self, name): - headers = [] - name = name.lower() - for k, v in self.headers: - if k.lower() == name: - headers.append(v) - return headers - - def get_all(self, name, default=None): - rv = [] - for k, v in self.headers: - if k.lower() == name.lower(): - rv.append(v) - return rv or default or [] - - -class _TestCookieResponse(object): - - """Something that looks like a httplib.HTTPResponse, but is actually just an - adapter for our test responses to make them available for cookielib. - """ - - def __init__(self, headers): - self.headers = _TestCookieHeaders(headers) - - def info(self): - return self.headers - - -class _TestCookieJar(CookieJar): - - """A cookielib.CookieJar modified to inject and read cookie headers from - and to wsgi environments, and wsgi application responses. - """ - - def inject_wsgi(self, environ): - """Inject the cookies as client headers into the server's wsgi - environment. - """ - cvals = [] - for cookie in self: - cvals.append('%s=%s' % (cookie.name, cookie.value)) - if cvals: - environ['HTTP_COOKIE'] = '; '.join(cvals) - - def extract_wsgi(self, environ, headers): - """Extract the server's set-cookie headers as cookies into the - cookie jar. - """ - self.extract_cookies( - _TestCookieResponse(headers), - U2Request(get_current_url(environ)), - ) - - -def _iter_data(data): - """Iterates over a `dict` or :class:`MultiDict` yielding all keys and - values. - This is used to iterate over the data passed to the - :class:`EnvironBuilder`. - """ - if isinstance(data, MultiDict): - for key, values in iterlists(data): - for value in values: - yield key, value - else: - for key, values in iteritems(data): - if isinstance(values, list): - for value in values: - yield key, value - else: - yield key, values - - -class EnvironBuilder(object): - - """This class can be used to conveniently create a WSGI environment - for testing purposes. It can be used to quickly create WSGI environments - or request objects from arbitrary data. - - The signature of this class is also used in some other places as of - Werkzeug 0.5 (:func:`create_environ`, :meth:`BaseResponse.from_values`, - :meth:`Client.open`). Because of this most of the functionality is - available through the constructor alone. - - Files and regular form data can be manipulated independently of each - other with the :attr:`form` and :attr:`files` attributes, but are - passed with the same argument to the constructor: `data`. - - `data` can be any of these values: - - - a `str` or `bytes` object: The object is converted into an - :attr:`input_stream`, the :attr:`content_length` is set and you have to - provide a :attr:`content_type`. - - a `dict` or :class:`MultiDict`: The keys have to be strings. The values - have to be either any of the following objects, or a list of any of the - following objects: - - - a :class:`file`-like object: These are converted into - :class:`FileStorage` objects automatically. - - a `tuple`: The :meth:`~FileMultiDict.add_file` method is called - with the key and the unpacked `tuple` items as positional - arguments. - - a `str`: The string is set as form data for the associated key. - - a file-like object: The object content is loaded in memory and then - handled like a regular `str` or a `bytes`. - - .. versionadded:: 0.6 - `path` and `base_url` can now be unicode strings that are encoded using - the :func:`iri_to_uri` function. - - :param path: the path of the request. In the WSGI environment this will - end up as `PATH_INFO`. If the `query_string` is not defined - and there is a question mark in the `path` everything after - it is used as query string. - :param base_url: the base URL is a URL that is used to extract the WSGI - URL scheme, host (server name + server port) and the - script root (`SCRIPT_NAME`). - :param query_string: an optional string or dict with URL parameters. - :param method: the HTTP method to use, defaults to `GET`. - :param input_stream: an optional input stream. Do not specify this and - `data`. As soon as an input stream is set you can't - modify :attr:`args` and :attr:`files` unless you - set the :attr:`input_stream` to `None` again. - :param content_type: The content type for the request. As of 0.5 you - don't have to provide this when specifying files - and form data via `data`. - :param content_length: The content length for the request. You don't - have to specify this when providing data via - `data`. - :param errors_stream: an optional error stream that is used for - `wsgi.errors`. Defaults to :data:`stderr`. - :param multithread: controls `wsgi.multithread`. Defaults to `False`. - :param multiprocess: controls `wsgi.multiprocess`. Defaults to `False`. - :param run_once: controls `wsgi.run_once`. Defaults to `False`. - :param headers: an optional list or :class:`Headers` object of headers. - :param data: a string or dict of form data or a file-object. - See explanation above. - :param environ_base: an optional dict of environment defaults. - :param environ_overrides: an optional dict of environment overrides. - :param charset: the charset used to encode unicode data. - """ - - #: the server protocol to use. defaults to HTTP/1.1 - server_protocol = 'HTTP/1.1' - - #: the wsgi version to use. defaults to (1, 0) - wsgi_version = (1, 0) - - #: the default request class for :meth:`get_request` - request_class = BaseRequest - - def __init__(self, path='/', base_url=None, query_string=None, - method='GET', input_stream=None, content_type=None, - content_length=None, errors_stream=None, multithread=False, - multiprocess=False, run_once=False, headers=None, data=None, - environ_base=None, environ_overrides=None, charset='utf-8', - mimetype=None): - path_s = make_literal_wrapper(path) - if query_string is None and path_s('?') in path: - path, query_string = path.split(path_s('?'), 1) - self.charset = charset - self.path = iri_to_uri(path) - if base_url is not None: - base_url = url_fix(iri_to_uri(base_url, charset), charset) - self.base_url = base_url - if isinstance(query_string, (bytes, text_type)): - self.query_string = query_string - else: - if query_string is None: - query_string = MultiDict() - elif not isinstance(query_string, MultiDict): - query_string = MultiDict(query_string) - self.args = query_string - self.method = method - if headers is None: - headers = Headers() - elif not isinstance(headers, Headers): - headers = Headers(headers) - self.headers = headers - if content_type is not None: - self.content_type = content_type - if errors_stream is None: - errors_stream = sys.stderr - self.errors_stream = errors_stream - self.multithread = multithread - self.multiprocess = multiprocess - self.run_once = run_once - self.environ_base = environ_base - self.environ_overrides = environ_overrides - self.input_stream = input_stream - self.content_length = content_length - self.closed = False - - if data: - if input_stream is not None: - raise TypeError('can\'t provide input stream and data') - if hasattr(data, 'read'): - data = data.read() - if isinstance(data, text_type): - data = data.encode(self.charset) - if isinstance(data, bytes): - self.input_stream = BytesIO(data) - if self.content_length is None: - self.content_length = len(data) - else: - for key, value in _iter_data(data): - if isinstance(value, (tuple, dict)) or \ - hasattr(value, 'read'): - self._add_file_from_data(key, value) - else: - self.form.setlistdefault(key).append(value) - - if mimetype is not None: - self.mimetype = mimetype - - def _add_file_from_data(self, key, value): - """Called in the EnvironBuilder to add files from the data dict.""" - if isinstance(value, tuple): - self.files.add_file(key, *value) - elif isinstance(value, dict): - from warnings import warn - warn(DeprecationWarning('it\'s no longer possible to pass dicts ' - 'as `data`. Use tuples or FileStorage ' - 'objects instead'), stacklevel=2) - value = dict(value) - mimetype = value.pop('mimetype', None) - if mimetype is not None: - value['content_type'] = mimetype - self.files.add_file(key, **value) - else: - self.files.add_file(key, value) - - def _get_base_url(self): - return url_unparse((self.url_scheme, self.host, - self.script_root, '', '')).rstrip('/') + '/' - - def _set_base_url(self, value): - if value is None: - scheme = 'http' - netloc = 'localhost' - script_root = '' - else: - scheme, netloc, script_root, qs, anchor = url_parse(value) - if qs or anchor: - raise ValueError('base url must not contain a query string ' - 'or fragment') - self.script_root = script_root.rstrip('/') - self.host = netloc - self.url_scheme = scheme - - base_url = property(_get_base_url, _set_base_url, doc=''' - The base URL is a URL that is used to extract the WSGI - URL scheme, host (server name + server port) and the - script root (`SCRIPT_NAME`).''') - del _get_base_url, _set_base_url - - def _get_content_type(self): - ct = self.headers.get('Content-Type') - if ct is None and not self._input_stream: - if self._files: - return 'multipart/form-data' - elif self._form: - return 'application/x-www-form-urlencoded' - return None - return ct - - def _set_content_type(self, value): - if value is None: - self.headers.pop('Content-Type', None) - else: - self.headers['Content-Type'] = value - - content_type = property(_get_content_type, _set_content_type, doc=''' - The content type for the request. Reflected from and to the - :attr:`headers`. Do not set if you set :attr:`files` or - :attr:`form` for auto detection.''') - del _get_content_type, _set_content_type - - def _get_content_length(self): - return self.headers.get('Content-Length', type=int) - - def _get_mimetype(self): - ct = self.content_type - if ct: - return ct.split(';')[0].strip() - - def _set_mimetype(self, value): - self.content_type = get_content_type(value, self.charset) - - def _get_mimetype_params(self): - def on_update(d): - self.headers['Content-Type'] = \ - dump_options_header(self.mimetype, d) - d = parse_options_header(self.headers.get('content-type', ''))[1] - return CallbackDict(d, on_update) - - mimetype = property(_get_mimetype, _set_mimetype, doc=''' - The mimetype (content type without charset etc.) - - .. versionadded:: 0.14 - ''') - mimetype_params = property(_get_mimetype_params, doc=''' - The mimetype parameters as dict. For example if the content - type is ``text/html; charset=utf-8`` the params would be - ``{'charset': 'utf-8'}``. - - .. versionadded:: 0.14 - ''') - del _get_mimetype, _set_mimetype, _get_mimetype_params - - def _set_content_length(self, value): - if value is None: - self.headers.pop('Content-Length', None) - else: - self.headers['Content-Length'] = str(value) - - content_length = property(_get_content_length, _set_content_length, doc=''' - The content length as integer. Reflected from and to the - :attr:`headers`. Do not set if you set :attr:`files` or - :attr:`form` for auto detection.''') - del _get_content_length, _set_content_length - - def form_property(name, storage, doc): - key = '_' + name - - def getter(self): - if self._input_stream is not None: - raise AttributeError('an input stream is defined') - rv = getattr(self, key) - if rv is None: - rv = storage() - setattr(self, key, rv) - - return rv - - def setter(self, value): - self._input_stream = None - setattr(self, key, value) - return property(getter, setter, doc=doc) - - form = form_property('form', MultiDict, doc=''' - A :class:`MultiDict` of form values.''') - files = form_property('files', FileMultiDict, doc=''' - A :class:`FileMultiDict` of uploaded files. You can use the - :meth:`~FileMultiDict.add_file` method to add new files to the - dict.''') - del form_property - - def _get_input_stream(self): - return self._input_stream - - def _set_input_stream(self, value): - self._input_stream = value - self._form = self._files = None - - input_stream = property(_get_input_stream, _set_input_stream, doc=''' - An optional input stream. If you set this it will clear - :attr:`form` and :attr:`files`.''') - del _get_input_stream, _set_input_stream - - def _get_query_string(self): - if self._query_string is None: - if self._args is not None: - return url_encode(self._args, charset=self.charset) - return '' - return self._query_string - - def _set_query_string(self, value): - self._query_string = value - self._args = None - - query_string = property(_get_query_string, _set_query_string, doc=''' - The query string. If you set this to a string :attr:`args` will - no longer be available.''') - del _get_query_string, _set_query_string - - def _get_args(self): - if self._query_string is not None: - raise AttributeError('a query string is defined') - if self._args is None: - self._args = MultiDict() - return self._args - - def _set_args(self, value): - self._query_string = None - self._args = value - - args = property(_get_args, _set_args, doc=''' - The URL arguments as :class:`MultiDict`.''') - del _get_args, _set_args - - @property - def server_name(self): - """The server name (read-only, use :attr:`host` to set)""" - return self.host.split(':', 1)[0] - - @property - def server_port(self): - """The server port as integer (read-only, use :attr:`host` to set)""" - pieces = self.host.split(':', 1) - if len(pieces) == 2 and pieces[1].isdigit(): - return int(pieces[1]) - elif self.url_scheme == 'https': - return 443 - return 80 - - def __del__(self): - try: - self.close() - except Exception: - pass - - def close(self): - """Closes all files. If you put real :class:`file` objects into the - :attr:`files` dict you can call this method to automatically close - them all in one go. - """ - if self.closed: - return - try: - files = itervalues(self.files) - except AttributeError: - files = () - for f in files: - try: - f.close() - except Exception: - pass - self.closed = True - - def get_environ(self): - """Return the built environ.""" - input_stream = self.input_stream - content_length = self.content_length - - mimetype = self.mimetype - content_type = self.content_type - - if input_stream is not None: - start_pos = input_stream.tell() - input_stream.seek(0, 2) - end_pos = input_stream.tell() - input_stream.seek(start_pos) - content_length = end_pos - start_pos - elif mimetype == 'multipart/form-data': - values = CombinedMultiDict([self.form, self.files]) - input_stream, content_length, boundary = \ - stream_encode_multipart(values, charset=self.charset) - content_type = mimetype + '; boundary="%s"' % boundary - elif mimetype == 'application/x-www-form-urlencoded': - # XXX: py2v3 review - values = url_encode(self.form, charset=self.charset) - values = values.encode('ascii') - content_length = len(values) - input_stream = BytesIO(values) - else: - input_stream = _empty_stream - - result = {} - if self.environ_base: - result.update(self.environ_base) - - def _path_encode(x): - return wsgi_encoding_dance(url_unquote(x, self.charset), self.charset) - - qs = wsgi_encoding_dance(self.query_string) - - result.update({ - 'REQUEST_METHOD': self.method, - 'SCRIPT_NAME': _path_encode(self.script_root), - 'PATH_INFO': _path_encode(self.path), - 'QUERY_STRING': qs, - 'SERVER_NAME': self.server_name, - 'SERVER_PORT': str(self.server_port), - 'HTTP_HOST': self.host, - 'SERVER_PROTOCOL': self.server_protocol, - 'CONTENT_TYPE': content_type or '', - 'CONTENT_LENGTH': str(content_length or '0'), - 'wsgi.version': self.wsgi_version, - 'wsgi.url_scheme': self.url_scheme, - 'wsgi.input': input_stream, - 'wsgi.errors': self.errors_stream, - 'wsgi.multithread': self.multithread, - 'wsgi.multiprocess': self.multiprocess, - 'wsgi.run_once': self.run_once - }) - for key, value in self.headers.to_wsgi_list(): - result['HTTP_%s' % key.upper().replace('-', '_')] = value - if self.environ_overrides: - result.update(self.environ_overrides) - return result - - def get_request(self, cls=None): - """Returns a request with the data. If the request class is not - specified :attr:`request_class` is used. - - :param cls: The request wrapper to use. - """ - if cls is None: - cls = self.request_class - return cls(self.get_environ()) - - -class ClientRedirectError(Exception): - - """ - If a redirect loop is detected when using follow_redirects=True with - the :cls:`Client`, then this exception is raised. - """ - - -class Client(object): - - """This class allows to send requests to a wrapped application. - - The response wrapper can be a class or factory function that takes - three arguments: app_iter, status and headers. The default response - wrapper just returns a tuple. - - Example:: - - class ClientResponse(BaseResponse): - ... - - client = Client(MyApplication(), response_wrapper=ClientResponse) - - The use_cookies parameter indicates whether cookies should be stored and - sent for subsequent requests. This is True by default, but passing False - will disable this behaviour. - - If you want to request some subdomain of your application you may set - `allow_subdomain_redirects` to `True` as if not no external redirects - are allowed. - - .. versionadded:: 0.5 - `use_cookies` is new in this version. Older versions did not provide - builtin cookie support. - - .. versionadded:: 0.14 - The `mimetype` parameter was added. - """ - - def __init__(self, application, response_wrapper=None, use_cookies=True, - allow_subdomain_redirects=False): - self.application = application - self.response_wrapper = response_wrapper - if use_cookies: - self.cookie_jar = _TestCookieJar() - else: - self.cookie_jar = None - self.allow_subdomain_redirects = allow_subdomain_redirects - - def set_cookie(self, server_name, key, value='', max_age=None, - expires=None, path='/', domain=None, secure=None, - httponly=False, charset='utf-8'): - """Sets a cookie in the client's cookie jar. The server name - is required and has to match the one that is also passed to - the open call. - """ - assert self.cookie_jar is not None, 'cookies disabled' - header = dump_cookie(key, value, max_age, expires, path, domain, - secure, httponly, charset) - environ = create_environ(path, base_url='http://' + server_name) - headers = [('Set-Cookie', header)] - self.cookie_jar.extract_wsgi(environ, headers) - - def delete_cookie(self, server_name, key, path='/', domain=None): - """Deletes a cookie in the test client.""" - self.set_cookie(server_name, key, expires=0, max_age=0, - path=path, domain=domain) - - def run_wsgi_app(self, environ, buffered=False): - """Runs the wrapped WSGI app with the given environment.""" - if self.cookie_jar is not None: - self.cookie_jar.inject_wsgi(environ) - rv = run_wsgi_app(self.application, environ, buffered=buffered) - if self.cookie_jar is not None: - self.cookie_jar.extract_wsgi(environ, rv[2]) - return rv - - def resolve_redirect(self, response, new_location, environ, buffered=False): - """Resolves a single redirect and triggers the request again - directly on this redirect client. - """ - scheme, netloc, script_root, qs, anchor = url_parse(new_location) - base_url = url_unparse((scheme, netloc, '', '', '')).rstrip('/') + '/' - - cur_server_name = netloc.split(':', 1)[0].split('.') - real_server_name = get_host(environ).rsplit(':', 1)[0].split('.') - if cur_server_name == ['']: - # this is a local redirect having autocorrect_location_header=False - cur_server_name = real_server_name - base_url = EnvironBuilder(environ).base_url - - if self.allow_subdomain_redirects: - allowed = cur_server_name[-len(real_server_name):] == real_server_name - else: - allowed = cur_server_name == real_server_name - - if not allowed: - raise RuntimeError('%r does not support redirect to ' - 'external targets' % self.__class__) - - status_code = int(response[1].split(None, 1)[0]) - if status_code == 307: - method = environ['REQUEST_METHOD'] - else: - method = 'GET' - - # For redirect handling we temporarily disable the response - # wrapper. This is not threadsafe but not a real concern - # since the test client must not be shared anyways. - old_response_wrapper = self.response_wrapper - self.response_wrapper = None - try: - return self.open(path=script_root, base_url=base_url, - query_string=qs, as_tuple=True, - buffered=buffered, method=method) - finally: - self.response_wrapper = old_response_wrapper - - def open(self, *args, **kwargs): - """Takes the same arguments as the :class:`EnvironBuilder` class with - some additions: You can provide a :class:`EnvironBuilder` or a WSGI - environment as only argument instead of the :class:`EnvironBuilder` - arguments and two optional keyword arguments (`as_tuple`, `buffered`) - that change the type of the return value or the way the application is - executed. - - .. versionchanged:: 0.5 - If a dict is provided as file in the dict for the `data` parameter - the content type has to be called `content_type` now instead of - `mimetype`. This change was made for consistency with - :class:`werkzeug.FileWrapper`. - - The `follow_redirects` parameter was added to :func:`open`. - - Additional parameters: - - :param as_tuple: Returns a tuple in the form ``(environ, result)`` - :param buffered: Set this to True to buffer the application run. - This will automatically close the application for - you as well. - :param follow_redirects: Set this to True if the `Client` should - follow HTTP redirects. - """ - as_tuple = kwargs.pop('as_tuple', False) - buffered = kwargs.pop('buffered', False) - follow_redirects = kwargs.pop('follow_redirects', False) - environ = None - if not kwargs and len(args) == 1: - if isinstance(args[0], EnvironBuilder): - environ = args[0].get_environ() - elif isinstance(args[0], dict): - environ = args[0] - if environ is None: - builder = EnvironBuilder(*args, **kwargs) - try: - environ = builder.get_environ() - finally: - builder.close() - - response = self.run_wsgi_app(environ, buffered=buffered) - - # handle redirects - redirect_chain = [] - while 1: - status_code = int(response[1].split(None, 1)[0]) - if status_code not in (301, 302, 303, 305, 307) \ - or not follow_redirects: - break - new_location = response[2]['location'] - new_redirect_entry = (new_location, status_code) - if new_redirect_entry in redirect_chain: - raise ClientRedirectError('loop detected') - redirect_chain.append(new_redirect_entry) - environ, response = self.resolve_redirect(response, new_location, - environ, - buffered=buffered) - - if self.response_wrapper is not None: - response = self.response_wrapper(*response) - if as_tuple: - return environ, response - return response - - def get(self, *args, **kw): - """Like open but method is enforced to GET.""" - kw['method'] = 'GET' - return self.open(*args, **kw) - - def patch(self, *args, **kw): - """Like open but method is enforced to PATCH.""" - kw['method'] = 'PATCH' - return self.open(*args, **kw) - - def post(self, *args, **kw): - """Like open but method is enforced to POST.""" - kw['method'] = 'POST' - return self.open(*args, **kw) - - def head(self, *args, **kw): - """Like open but method is enforced to HEAD.""" - kw['method'] = 'HEAD' - return self.open(*args, **kw) - - def put(self, *args, **kw): - """Like open but method is enforced to PUT.""" - kw['method'] = 'PUT' - return self.open(*args, **kw) - - def delete(self, *args, **kw): - """Like open but method is enforced to DELETE.""" - kw['method'] = 'DELETE' - return self.open(*args, **kw) - - def options(self, *args, **kw): - """Like open but method is enforced to OPTIONS.""" - kw['method'] = 'OPTIONS' - return self.open(*args, **kw) - - def trace(self, *args, **kw): - """Like open but method is enforced to TRACE.""" - kw['method'] = 'TRACE' - return self.open(*args, **kw) - - def __repr__(self): - return '<%s %r>' % ( - self.__class__.__name__, - self.application - ) - - -def create_environ(*args, **kwargs): - """Create a new WSGI environ dict based on the values passed. The first - parameter should be the path of the request which defaults to '/'. The - second one can either be an absolute path (in that case the host is - localhost:80) or a full path to the request with scheme, netloc port and - the path to the script. - - This accepts the same arguments as the :class:`EnvironBuilder` - constructor. - - .. versionchanged:: 0.5 - This function is now a thin wrapper over :class:`EnvironBuilder` which - was added in 0.5. The `headers`, `environ_base`, `environ_overrides` - and `charset` parameters were added. - """ - builder = EnvironBuilder(*args, **kwargs) - try: - return builder.get_environ() - finally: - builder.close() - - -def run_wsgi_app(app, environ, buffered=False): - """Return a tuple in the form (app_iter, status, headers) of the - application output. This works best if you pass it an application that - returns an iterator all the time. - - Sometimes applications may use the `write()` callable returned - by the `start_response` function. This tries to resolve such edge - cases automatically. But if you don't get the expected output you - should set `buffered` to `True` which enforces buffering. - - If passed an invalid WSGI application the behavior of this function is - undefined. Never pass non-conforming WSGI applications to this function. - - :param app: the application to execute. - :param buffered: set to `True` to enforce buffering. - :return: tuple in the form ``(app_iter, status, headers)`` - """ - environ = _get_environ(environ) - response = [] - buffer = [] - - def start_response(status, headers, exc_info=None): - if exc_info is not None: - reraise(*exc_info) - response[:] = [status, headers] - return buffer.append - - app_rv = app(environ, start_response) - close_func = getattr(app_rv, 'close', None) - app_iter = iter(app_rv) - - # when buffering we emit the close call early and convert the - # application iterator into a regular list - if buffered: - try: - app_iter = list(app_iter) - finally: - if close_func is not None: - close_func() - - # otherwise we iterate the application iter until we have a response, chain - # the already received data with the already collected data and wrap it in - # a new `ClosingIterator` if we need to restore a `close` callable from the - # original return value. - else: - while not response: - buffer.append(next(app_iter)) - if buffer: - app_iter = chain(buffer, app_iter) - if close_func is not None and app_iter is not app_rv: - app_iter = ClosingIterator(app_iter, close_func) - - return app_iter, response[0], Headers(response[1]) diff --git a/pyextra/werkzeug/testapp.py b/pyextra/werkzeug/testapp.py deleted file mode 100644 index 595555a09b00af..00000000000000 --- a/pyextra/werkzeug/testapp.py +++ /dev/null @@ -1,230 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.testapp - ~~~~~~~~~~~~~~~~ - - Provide a small test application that can be used to test a WSGI server - and check it for WSGI compliance. - - :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -import os -import sys -import werkzeug -from textwrap import wrap -from werkzeug.wrappers import BaseRequest as Request, BaseResponse as Response -from werkzeug.utils import escape -import base64 - -logo = Response(base64.b64decode(''' -R0lGODlhoACgAOMIAAEDACwpAEpCAGdgAJaKAM28AOnVAP3rAP///////// -//////////////////////yH5BAEKAAgALAAAAACgAKAAAAT+EMlJq704680R+F0ojmRpnuj0rWnrv -nB8rbRs33gu0bzu/0AObxgsGn3D5HHJbCUFyqZ0ukkSDlAidctNFg7gbI9LZlrBaHGtzAae0eloe25 -7w9EDOX2fst/xenyCIn5/gFqDiVVDV4aGeYiKkhSFjnCQY5OTlZaXgZp8nJ2ekaB0SQOjqphrpnOiq -ncEn65UsLGytLVmQ6m4sQazpbtLqL/HwpnER8bHyLrLOc3Oz8PRONPU1crXN9na263dMt/g4SzjMeX -m5yDpLqgG7OzJ4u8lT/P69ej3JPn69kHzN2OIAHkB9RUYSFCFQYQJFTIkCDBiwoXWGnowaLEjRm7+G -p9A7Hhx4rUkAUaSLJlxHMqVMD/aSycSZkyTplCqtGnRAM5NQ1Ly5OmzZc6gO4d6DGAUKA+hSocWYAo -SlM6oUWX2O/o0KdaVU5vuSQLAa0ADwQgMEMB2AIECZhVSnTno6spgbtXmHcBUrQACcc2FrTrWS8wAf -78cMFBgwIBgbN+qvTt3ayikRBk7BoyGAGABAdYyfdzRQGV3l4coxrqQ84GpUBmrdR3xNIDUPAKDBSA -ADIGDhhqTZIWaDcrVX8EsbNzbkvCOxG8bN5w8ly9H8jyTJHC6DFndQydbguh2e/ctZJFXRxMAqqPVA -tQH5E64SPr1f0zz7sQYjAHg0In+JQ11+N2B0XXBeeYZgBZFx4tqBToiTCPv0YBgQv8JqA6BEf6RhXx -w1ENhRBnWV8ctEX4Ul2zc3aVGcQNC2KElyTDYyYUWvShdjDyMOGMuFjqnII45aogPhz/CodUHFwaDx -lTgsaOjNyhGWJQd+lFoAGk8ObghI0kawg+EV5blH3dr+digkYuAGSaQZFHFz2P/cTaLmhF52QeSb45 -Jwxd+uSVGHlqOZpOeJpCFZ5J+rkAkFjQ0N1tah7JJSZUFNsrkeJUJMIBi8jyaEKIhKPomnC91Uo+NB -yyaJ5umnnpInIFh4t6ZSpGaAVmizqjpByDegYl8tPE0phCYrhcMWSv+uAqHfgH88ak5UXZmlKLVJhd -dj78s1Fxnzo6yUCrV6rrDOkluG+QzCAUTbCwf9SrmMLzK6p+OPHx7DF+bsfMRq7Ec61Av9i6GLw23r -idnZ+/OO0a99pbIrJkproCQMA17OPG6suq3cca5ruDfXCCDoS7BEdvmJn5otdqscn+uogRHHXs8cbh -EIfYaDY1AkrC0cqwcZpnM6ludx72x0p7Fo/hZAcpJDjax0UdHavMKAbiKltMWCF3xxh9k25N/Viud8 -ba78iCvUkt+V6BpwMlErmcgc502x+u1nSxJSJP9Mi52awD1V4yB/QHONsnU3L+A/zR4VL/indx/y64 -gqcj+qgTeweM86f0Qy1QVbvmWH1D9h+alqg254QD8HJXHvjQaGOqEqC22M54PcftZVKVSQG9jhkv7C -JyTyDoAJfPdu8v7DRZAxsP/ky9MJ3OL36DJfCFPASC3/aXlfLOOON9vGZZHydGf8LnxYJuuVIbl83y -Az5n/RPz07E+9+zw2A2ahz4HxHo9Kt79HTMx1Q7ma7zAzHgHqYH0SoZWyTuOLMiHwSfZDAQTn0ajk9 -YQqodnUYjByQZhZak9Wu4gYQsMyEpIOAOQKze8CmEF45KuAHTvIDOfHJNipwoHMuGHBnJElUoDmAyX -c2Qm/R8Ah/iILCCJOEokGowdhDYc/yoL+vpRGwyVSCWFYZNljkhEirGXsalWcAgOdeAdoXcktF2udb -qbUhjWyMQxYO01o6KYKOr6iK3fE4MaS+DsvBsGOBaMb0Y6IxADaJhFICaOLmiWTlDAnY1KzDG4ambL -cWBA8mUzjJsN2KjSaSXGqMCVXYpYkj33mcIApyhQf6YqgeNAmNvuC0t4CsDbSshZJkCS1eNisKqlyG -cF8G2JeiDX6tO6Mv0SmjCa3MFb0bJaGPMU0X7c8XcpvMaOQmCajwSeY9G0WqbBmKv34DsMIEztU6Y2 -KiDlFdt6jnCSqx7Dmt6XnqSKaFFHNO5+FmODxMCWBEaco77lNDGXBM0ECYB/+s7nKFdwSF5hgXumQe -EZ7amRg39RHy3zIjyRCykQh8Zo2iviRKyTDn/zx6EefptJj2Cw+Ep2FSc01U5ry4KLPYsTyWnVGnvb -UpyGlhjBUljyjHhWpf8OFaXwhp9O4T1gU9UeyPPa8A2l0p1kNqPXEVRm1AOs1oAGZU596t6SOR2mcB -Oco1srWtkaVrMUzIErrKri85keKqRQYX9VX0/eAUK1hrSu6HMEX3Qh2sCh0q0D2CtnUqS4hj62sE/z -aDs2Sg7MBS6xnQeooc2R2tC9YrKpEi9pLXfYXp20tDCpSP8rKlrD4axprb9u1Df5hSbz9QU0cRpfgn -kiIzwKucd0wsEHlLpe5yHXuc6FrNelOl7pY2+11kTWx7VpRu97dXA3DO1vbkhcb4zyvERYajQgAADs -='''), mimetype='image/png') - - -TEMPLATE = u'''\ - -WSGI Information - -
- -

WSGI Information

-

- This page displays all available information about the WSGI server and - the underlying Python interpreter. -

Python Interpreter

- - - - - - -
Python Version - %(python_version)s -
Platform - %(platform)s [%(os)s] -
API Version - %(api_version)s -
Byteorder - %(byteorder)s -
Werkzeug Version - %(werkzeug_version)s -
-

WSGI Environment

- %(wsgi_env)s
-

Installed Eggs

-

- The following python packages were installed on the system as - Python eggs: -

    %(python_eggs)s
-

System Path

-

- The following paths are the current contents of the load path. The - following entries are looked up for Python packages. Note that not - all items in this path are folders. Gray and underlined items are - entries pointing to invalid resources or used by custom import hooks - such as the zip importer. -

- Items with a bright background were expanded for display from a relative - path. If you encounter such paths in the output you might want to check - your setup as relative paths are usually problematic in multithreaded - environments. -

    %(sys_path)s
-
-''' - - -def iter_sys_path(): - if os.name == 'posix': - def strip(x): - prefix = os.path.expanduser('~') - if x.startswith(prefix): - x = '~' + x[len(prefix):] - return x - else: - strip = lambda x: x - - cwd = os.path.abspath(os.getcwd()) - for item in sys.path: - path = os.path.join(cwd, item or os.path.curdir) - yield strip(os.path.normpath(path)), \ - not os.path.isdir(path), path != item - - -def render_testapp(req): - try: - import pkg_resources - except ImportError: - eggs = () - else: - eggs = sorted(pkg_resources.working_set, - key=lambda x: x.project_name.lower()) - python_eggs = [] - for egg in eggs: - try: - version = egg.version - except (ValueError, AttributeError): - version = 'unknown' - python_eggs.append('
  • %s [%s]' % ( - escape(egg.project_name), - escape(version) - )) - - wsgi_env = [] - sorted_environ = sorted(req.environ.items(), - key=lambda x: repr(x[0]).lower()) - for key, value in sorted_environ: - wsgi_env.append('%s%s' % ( - escape(str(key)), - ' '.join(wrap(escape(repr(value)))) - )) - - sys_path = [] - for item, virtual, expanded in iter_sys_path(): - class_ = [] - if virtual: - class_.append('virtual') - if expanded: - class_.append('exp') - sys_path.append('%s' % ( - class_ and ' class="%s"' % ' '.join(class_) or '', - escape(item) - )) - - return (TEMPLATE % { - 'python_version': '
    '.join(escape(sys.version).splitlines()), - 'platform': escape(sys.platform), - 'os': escape(os.name), - 'api_version': sys.api_version, - 'byteorder': sys.byteorder, - 'werkzeug_version': werkzeug.__version__, - 'python_eggs': '\n'.join(python_eggs), - 'wsgi_env': '\n'.join(wsgi_env), - 'sys_path': '\n'.join(sys_path) - }).encode('utf-8') - - -def test_app(environ, start_response): - """Simple test application that dumps the environment. You can use - it to check if Werkzeug is working properly: - - .. sourcecode:: pycon - - >>> from werkzeug.serving import run_simple - >>> from werkzeug.testapp import test_app - >>> run_simple('localhost', 3000, test_app) - * Running on http://localhost:3000/ - - The application displays important information from the WSGI environment, - the Python interpreter and the installed libraries. - """ - req = Request(environ, populate_request=False) - if req.args.get('resource') == 'logo': - response = logo - else: - response = Response(render_testapp(req), mimetype='text/html') - return response(environ, start_response) - - -if __name__ == '__main__': - from werkzeug.serving import run_simple - run_simple('localhost', 5000, test_app, use_reloader=True) diff --git a/pyextra/werkzeug/urls.py b/pyextra/werkzeug/urls.py deleted file mode 100644 index 5bd9a40d899248..00000000000000 --- a/pyextra/werkzeug/urls.py +++ /dev/null @@ -1,1007 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.urls - ~~~~~~~~~~~~~ - - ``werkzeug.urls`` used to provide several wrapper functions for Python 2 - urlparse, whose main purpose were to work around the behavior of the Py2 - stdlib and its lack of unicode support. While this was already a somewhat - inconvenient situation, it got even more complicated because Python 3's - ``urllib.parse`` actually does handle unicode properly. In other words, - this module would wrap two libraries with completely different behavior. So - now this module contains a 2-and-3-compatible backport of Python 3's - ``urllib.parse``, which is mostly API-compatible. - - :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -import os -import re -from werkzeug._compat import text_type, PY2, to_unicode, \ - to_native, implements_to_string, try_coerce_native, \ - normalize_string_tuple, make_literal_wrapper, \ - fix_tuple_repr -from werkzeug._internal import _encode_idna, _decode_idna -from werkzeug.datastructures import MultiDict, iter_multi_items -from collections import namedtuple - - -# A regular expression for what a valid schema looks like -_scheme_re = re.compile(r'^[a-zA-Z0-9+-.]+$') - -# Characters that are safe in any part of an URL. -_always_safe = (b'abcdefghijklmnopqrstuvwxyz' - b'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.-+') - -_hexdigits = '0123456789ABCDEFabcdef' -_hextobyte = dict( - ((a + b).encode(), int(a + b, 16)) - for a in _hexdigits for b in _hexdigits -) -_bytetohex = [ - ('%%%02X' % char).encode('ascii') for char in range(256) -] - - -_URLTuple = fix_tuple_repr(namedtuple( - '_URLTuple', - ['scheme', 'netloc', 'path', 'query', 'fragment'] -)) - - -class BaseURL(_URLTuple): - - '''Superclass of :py:class:`URL` and :py:class:`BytesURL`.''' - __slots__ = () - - def replace(self, **kwargs): - """Return an URL with the same values, except for those parameters - given new values by whichever keyword arguments are specified.""" - return self._replace(**kwargs) - - @property - def host(self): - """The host part of the URL if available, otherwise `None`. The - host is either the hostname or the IP address mentioned in the - URL. It will not contain the port. - """ - return self._split_host()[0] - - @property - def ascii_host(self): - """Works exactly like :attr:`host` but will return a result that - is restricted to ASCII. If it finds a netloc that is not ASCII - it will attempt to idna decode it. This is useful for socket - operations when the URL might include internationalized characters. - """ - rv = self.host - if rv is not None and isinstance(rv, text_type): - try: - rv = _encode_idna(rv) - except UnicodeError: - rv = rv.encode('ascii', 'ignore') - return to_native(rv, 'ascii', 'ignore') - - @property - def port(self): - """The port in the URL as an integer if it was present, `None` - otherwise. This does not fill in default ports. - """ - try: - rv = int(to_native(self._split_host()[1])) - if 0 <= rv <= 65535: - return rv - except (ValueError, TypeError): - pass - - @property - def auth(self): - """The authentication part in the URL if available, `None` - otherwise. - """ - return self._split_netloc()[0] - - @property - def username(self): - """The username if it was part of the URL, `None` otherwise. - This undergoes URL decoding and will always be a unicode string. - """ - rv = self._split_auth()[0] - if rv is not None: - return _url_unquote_legacy(rv) - - @property - def raw_username(self): - """The username if it was part of the URL, `None` otherwise. - Unlike :attr:`username` this one is not being decoded. - """ - return self._split_auth()[0] - - @property - def password(self): - """The password if it was part of the URL, `None` otherwise. - This undergoes URL decoding and will always be a unicode string. - """ - rv = self._split_auth()[1] - if rv is not None: - return _url_unquote_legacy(rv) - - @property - def raw_password(self): - """The password if it was part of the URL, `None` otherwise. - Unlike :attr:`password` this one is not being decoded. - """ - return self._split_auth()[1] - - def decode_query(self, *args, **kwargs): - """Decodes the query part of the URL. Ths is a shortcut for - calling :func:`url_decode` on the query argument. The arguments and - keyword arguments are forwarded to :func:`url_decode` unchanged. - """ - return url_decode(self.query, *args, **kwargs) - - def join(self, *args, **kwargs): - """Joins this URL with another one. This is just a convenience - function for calling into :meth:`url_join` and then parsing the - return value again. - """ - return url_parse(url_join(self, *args, **kwargs)) - - def to_url(self): - """Returns a URL string or bytes depending on the type of the - information stored. This is just a convenience function - for calling :meth:`url_unparse` for this URL. - """ - return url_unparse(self) - - def decode_netloc(self): - """Decodes the netloc part into a string.""" - rv = _decode_idna(self.host or '') - - if ':' in rv: - rv = '[%s]' % rv - port = self.port - if port is not None: - rv = '%s:%d' % (rv, port) - auth = ':'.join(filter(None, [ - _url_unquote_legacy(self.raw_username or '', '/:%@'), - _url_unquote_legacy(self.raw_password or '', '/:%@'), - ])) - if auth: - rv = '%s@%s' % (auth, rv) - return rv - - def to_uri_tuple(self): - """Returns a :class:`BytesURL` tuple that holds a URI. This will - encode all the information in the URL properly to ASCII using the - rules a web browser would follow. - - It's usually more interesting to directly call :meth:`iri_to_uri` which - will return a string. - """ - return url_parse(iri_to_uri(self).encode('ascii')) - - def to_iri_tuple(self): - """Returns a :class:`URL` tuple that holds a IRI. This will try - to decode as much information as possible in the URL without - losing information similar to how a web browser does it for the - URL bar. - - It's usually more interesting to directly call :meth:`uri_to_iri` which - will return a string. - """ - return url_parse(uri_to_iri(self)) - - def get_file_location(self, pathformat=None): - """Returns a tuple with the location of the file in the form - ``(server, location)``. If the netloc is empty in the URL or - points to localhost, it's represented as ``None``. - - The `pathformat` by default is autodetection but needs to be set - when working with URLs of a specific system. The supported values - are ``'windows'`` when working with Windows or DOS paths and - ``'posix'`` when working with posix paths. - - If the URL does not point to to a local file, the server and location - are both represented as ``None``. - - :param pathformat: The expected format of the path component. - Currently ``'windows'`` and ``'posix'`` are - supported. Defaults to ``None`` which is - autodetect. - """ - if self.scheme != 'file': - return None, None - - path = url_unquote(self.path) - host = self.netloc or None - - if pathformat is None: - if os.name == 'nt': - pathformat = 'windows' - else: - pathformat = 'posix' - - if pathformat == 'windows': - if path[:1] == '/' and path[1:2].isalpha() and path[2:3] in '|:': - path = path[1:2] + ':' + path[3:] - windows_share = path[:3] in ('\\' * 3, '/' * 3) - import ntpath - path = ntpath.normpath(path) - # Windows shared drives are represented as ``\\host\\directory``. - # That results in a URL like ``file://///host/directory``, and a - # path like ``///host/directory``. We need to special-case this - # because the path contains the hostname. - if windows_share and host is None: - parts = path.lstrip('\\').split('\\', 1) - if len(parts) == 2: - host, path = parts - else: - host = parts[0] - path = '' - elif pathformat == 'posix': - import posixpath - path = posixpath.normpath(path) - else: - raise TypeError('Invalid path format %s' % repr(pathformat)) - - if host in ('127.0.0.1', '::1', 'localhost'): - host = None - - return host, path - - def _split_netloc(self): - if self._at in self.netloc: - return self.netloc.split(self._at, 1) - return None, self.netloc - - def _split_auth(self): - auth = self._split_netloc()[0] - if not auth: - return None, None - if self._colon not in auth: - return auth, None - return auth.split(self._colon, 1) - - def _split_host(self): - rv = self._split_netloc()[1] - if not rv: - return None, None - - if not rv.startswith(self._lbracket): - if self._colon in rv: - return rv.split(self._colon, 1) - return rv, None - - idx = rv.find(self._rbracket) - if idx < 0: - return rv, None - - host = rv[1:idx] - rest = rv[idx + 1:] - if rest.startswith(self._colon): - return host, rest[1:] - return host, None - - -@implements_to_string -class URL(BaseURL): - - """Represents a parsed URL. This behaves like a regular tuple but - also has some extra attributes that give further insight into the - URL. - """ - __slots__ = () - _at = '@' - _colon = ':' - _lbracket = '[' - _rbracket = ']' - - def __str__(self): - return self.to_url() - - def encode_netloc(self): - """Encodes the netloc part to an ASCII safe URL as bytes.""" - rv = self.ascii_host or '' - if ':' in rv: - rv = '[%s]' % rv - port = self.port - if port is not None: - rv = '%s:%d' % (rv, port) - auth = ':'.join(filter(None, [ - url_quote(self.raw_username or '', 'utf-8', 'strict', '/:%'), - url_quote(self.raw_password or '', 'utf-8', 'strict', '/:%'), - ])) - if auth: - rv = '%s@%s' % (auth, rv) - return to_native(rv) - - def encode(self, charset='utf-8', errors='replace'): - """Encodes the URL to a tuple made out of bytes. The charset is - only being used for the path, query and fragment. - """ - return BytesURL( - self.scheme.encode('ascii'), - self.encode_netloc(), - self.path.encode(charset, errors), - self.query.encode(charset, errors), - self.fragment.encode(charset, errors) - ) - - -class BytesURL(BaseURL): - - """Represents a parsed URL in bytes.""" - __slots__ = () - _at = b'@' - _colon = b':' - _lbracket = b'[' - _rbracket = b']' - - def __str__(self): - return self.to_url().decode('utf-8', 'replace') - - def encode_netloc(self): - """Returns the netloc unchanged as bytes.""" - return self.netloc - - def decode(self, charset='utf-8', errors='replace'): - """Decodes the URL to a tuple made out of strings. The charset is - only being used for the path, query and fragment. - """ - return URL( - self.scheme.decode('ascii'), - self.decode_netloc(), - self.path.decode(charset, errors), - self.query.decode(charset, errors), - self.fragment.decode(charset, errors) - ) - - -def _unquote_to_bytes(string, unsafe=''): - if isinstance(string, text_type): - string = string.encode('utf-8') - if isinstance(unsafe, text_type): - unsafe = unsafe.encode('utf-8') - unsafe = frozenset(bytearray(unsafe)) - bits = iter(string.split(b'%')) - result = bytearray(next(bits, b'')) - for item in bits: - try: - char = _hextobyte[item[:2]] - if char in unsafe: - raise KeyError() - result.append(char) - result.extend(item[2:]) - except KeyError: - result.extend(b'%') - result.extend(item) - return bytes(result) - - -def _url_encode_impl(obj, charset, encode_keys, sort, key): - iterable = iter_multi_items(obj) - if sort: - iterable = sorted(iterable, key=key) - for key, value in iterable: - if value is None: - continue - if not isinstance(key, bytes): - key = text_type(key).encode(charset) - if not isinstance(value, bytes): - value = text_type(value).encode(charset) - yield url_quote_plus(key) + '=' + url_quote_plus(value) - - -def _url_unquote_legacy(value, unsafe=''): - try: - return url_unquote(value, charset='utf-8', - errors='strict', unsafe=unsafe) - except UnicodeError: - return url_unquote(value, charset='latin1', unsafe=unsafe) - - -def url_parse(url, scheme=None, allow_fragments=True): - """Parses a URL from a string into a :class:`URL` tuple. If the URL - is lacking a scheme it can be provided as second argument. Otherwise, - it is ignored. Optionally fragments can be stripped from the URL - by setting `allow_fragments` to `False`. - - The inverse of this function is :func:`url_unparse`. - - :param url: the URL to parse. - :param scheme: the default schema to use if the URL is schemaless. - :param allow_fragments: if set to `False` a fragment will be removed - from the URL. - """ - s = make_literal_wrapper(url) - is_text_based = isinstance(url, text_type) - - if scheme is None: - scheme = s('') - netloc = query = fragment = s('') - i = url.find(s(':')) - if i > 0 and _scheme_re.match(to_native(url[:i], errors='replace')): - # make sure "iri" is not actually a port number (in which case - # "scheme" is really part of the path) - rest = url[i + 1:] - if not rest or any(c not in s('0123456789') for c in rest): - # not a port number - scheme, url = url[:i].lower(), rest - - if url[:2] == s('//'): - delim = len(url) - for c in s('/?#'): - wdelim = url.find(c, 2) - if wdelim >= 0: - delim = min(delim, wdelim) - netloc, url = url[2:delim], url[delim:] - if (s('[') in netloc and s(']') not in netloc) or \ - (s(']') in netloc and s('[') not in netloc): - raise ValueError('Invalid IPv6 URL') - - if allow_fragments and s('#') in url: - url, fragment = url.split(s('#'), 1) - if s('?') in url: - url, query = url.split(s('?'), 1) - - result_type = is_text_based and URL or BytesURL - return result_type(scheme, netloc, url, query, fragment) - - -def url_quote(string, charset='utf-8', errors='strict', safe='/:', unsafe=''): - """URL encode a single string with a given encoding. - - :param s: the string to quote. - :param charset: the charset to be used. - :param safe: an optional sequence of safe characters. - :param unsafe: an optional sequence of unsafe characters. - - .. versionadded:: 0.9.2 - The `unsafe` parameter was added. - """ - if not isinstance(string, (text_type, bytes, bytearray)): - string = text_type(string) - if isinstance(string, text_type): - string = string.encode(charset, errors) - if isinstance(safe, text_type): - safe = safe.encode(charset, errors) - if isinstance(unsafe, text_type): - unsafe = unsafe.encode(charset, errors) - safe = frozenset(bytearray(safe) + _always_safe) - frozenset(bytearray(unsafe)) - rv = bytearray() - for char in bytearray(string): - if char in safe: - rv.append(char) - else: - rv.extend(_bytetohex[char]) - return to_native(bytes(rv)) - - -def url_quote_plus(string, charset='utf-8', errors='strict', safe=''): - """URL encode a single string with the given encoding and convert - whitespace to "+". - - :param s: The string to quote. - :param charset: The charset to be used. - :param safe: An optional sequence of safe characters. - """ - return url_quote(string, charset, errors, safe + ' ', '+').replace(' ', '+') - - -def url_unparse(components): - """The reverse operation to :meth:`url_parse`. This accepts arbitrary - as well as :class:`URL` tuples and returns a URL as a string. - - :param components: the parsed URL as tuple which should be converted - into a URL string. - """ - scheme, netloc, path, query, fragment = \ - normalize_string_tuple(components) - s = make_literal_wrapper(scheme) - url = s('') - - # We generally treat file:///x and file:/x the same which is also - # what browsers seem to do. This also allows us to ignore a schema - # register for netloc utilization or having to differenciate between - # empty and missing netloc. - if netloc or (scheme and path.startswith(s('/'))): - if path and path[:1] != s('/'): - path = s('/') + path - url = s('//') + (netloc or s('')) + path - elif path: - url += path - if scheme: - url = scheme + s(':') + url - if query: - url = url + s('?') + query - if fragment: - url = url + s('#') + fragment - return url - - -def url_unquote(string, charset='utf-8', errors='replace', unsafe=''): - """URL decode a single string with a given encoding. If the charset - is set to `None` no unicode decoding is performed and raw bytes - are returned. - - :param s: the string to unquote. - :param charset: the charset of the query string. If set to `None` - no unicode decoding will take place. - :param errors: the error handling for the charset decoding. - """ - rv = _unquote_to_bytes(string, unsafe) - if charset is not None: - rv = rv.decode(charset, errors) - return rv - - -def url_unquote_plus(s, charset='utf-8', errors='replace'): - """URL decode a single string with the given `charset` and decode "+" to - whitespace. - - Per default encoding errors are ignored. If you want a different behavior - you can set `errors` to ``'replace'`` or ``'strict'``. In strict mode a - :exc:`HTTPUnicodeError` is raised. - - :param s: The string to unquote. - :param charset: the charset of the query string. If set to `None` - no unicode decoding will take place. - :param errors: The error handling for the `charset` decoding. - """ - if isinstance(s, text_type): - s = s.replace(u'+', u' ') - else: - s = s.replace(b'+', b' ') - return url_unquote(s, charset, errors) - - -def url_fix(s, charset='utf-8'): - r"""Sometimes you get an URL by a user that just isn't a real URL because - it contains unsafe characters like ' ' and so on. This function can fix - some of the problems in a similar way browsers handle data entered by the - user: - - >>> url_fix(u'http://de.wikipedia.org/wiki/Elf (Begriffskl\xe4rung)') - 'http://de.wikipedia.org/wiki/Elf%20(Begriffskl%C3%A4rung)' - - :param s: the string with the URL to fix. - :param charset: The target charset for the URL if the url was given as - unicode string. - """ - # First step is to switch to unicode processing and to convert - # backslashes (which are invalid in URLs anyways) to slashes. This is - # consistent with what Chrome does. - s = to_unicode(s, charset, 'replace').replace('\\', '/') - - # For the specific case that we look like a malformed windows URL - # we want to fix this up manually: - if s.startswith('file://') and s[7:8].isalpha() and s[8:10] in (':/', '|/'): - s = 'file:///' + s[7:] - - url = url_parse(s) - path = url_quote(url.path, charset, safe='/%+$!*\'(),') - qs = url_quote_plus(url.query, charset, safe=':&%=+$!*\'(),') - anchor = url_quote_plus(url.fragment, charset, safe=':&%=+$!*\'(),') - return to_native(url_unparse((url.scheme, url.encode_netloc(), - path, qs, anchor))) - - -def uri_to_iri(uri, charset='utf-8', errors='replace'): - r""" - Converts a URI in a given charset to a IRI. - - Examples for URI versus IRI: - - >>> uri_to_iri(b'http://xn--n3h.net/') - u'http://\u2603.net/' - >>> uri_to_iri(b'http://%C3%BCser:p%C3%A4ssword@xn--n3h.net/p%C3%A5th') - u'http://\xfcser:p\xe4ssword@\u2603.net/p\xe5th' - - Query strings are left unchanged: - - >>> uri_to_iri('/?foo=24&x=%26%2f') - u'/?foo=24&x=%26%2f' - - .. versionadded:: 0.6 - - :param uri: The URI to convert. - :param charset: The charset of the URI. - :param errors: The error handling on decode. - """ - if isinstance(uri, tuple): - uri = url_unparse(uri) - uri = url_parse(to_unicode(uri, charset)) - path = url_unquote(uri.path, charset, errors, '%/;?') - query = url_unquote(uri.query, charset, errors, '%;/?:@&=+,$#') - fragment = url_unquote(uri.fragment, charset, errors, '%;/?:@&=+,$#') - return url_unparse((uri.scheme, uri.decode_netloc(), - path, query, fragment)) - - -def iri_to_uri(iri, charset='utf-8', errors='strict', safe_conversion=False): - r""" - Converts any unicode based IRI to an acceptable ASCII URI. Werkzeug always - uses utf-8 URLs internally because this is what browsers and HTTP do as - well. In some places where it accepts an URL it also accepts a unicode IRI - and converts it into a URI. - - Examples for IRI versus URI: - - >>> iri_to_uri(u'http://☃.net/') - 'http://xn--n3h.net/' - >>> iri_to_uri(u'http://üser:pässword@☃.net/påth') - 'http://%C3%BCser:p%C3%A4ssword@xn--n3h.net/p%C3%A5th' - - There is a general problem with IRI and URI conversion with some - protocols that appear in the wild that are in violation of the URI - specification. In places where Werkzeug goes through a forced IRI to - URI conversion it will set the `safe_conversion` flag which will - not perform a conversion if the end result is already ASCII. This - can mean that the return value is not an entirely correct URI but - it will not destroy such invalid URLs in the process. - - As an example consider the following two IRIs:: - - magnet:?xt=uri:whatever - itms-services://?action=download-manifest - - The internal representation after parsing of those URLs is the same - and there is no way to reconstruct the original one. If safe - conversion is enabled however this function becomes a noop for both of - those strings as they both can be considered URIs. - - .. versionadded:: 0.6 - - .. versionchanged:: 0.9.6 - The `safe_conversion` parameter was added. - - :param iri: The IRI to convert. - :param charset: The charset for the URI. - :param safe_conversion: indicates if a safe conversion should take place. - For more information see the explanation above. - """ - if isinstance(iri, tuple): - iri = url_unparse(iri) - - if safe_conversion: - try: - native_iri = to_native(iri) - ascii_iri = to_native(iri).encode('ascii') - if ascii_iri.split() == [ascii_iri]: - return native_iri - except UnicodeError: - pass - - iri = url_parse(to_unicode(iri, charset, errors)) - - netloc = iri.encode_netloc() - path = url_quote(iri.path, charset, errors, '/:~+%') - query = url_quote(iri.query, charset, errors, '%&[]:;$*()+,!?*/=') - fragment = url_quote(iri.fragment, charset, errors, '=%&[]:;$()+,!?*/') - - return to_native(url_unparse((iri.scheme, netloc, - path, query, fragment))) - - -def url_decode(s, charset='utf-8', decode_keys=False, include_empty=True, - errors='replace', separator='&', cls=None): - """ - Parse a querystring and return it as :class:`MultiDict`. There is a - difference in key decoding on different Python versions. On Python 3 - keys will always be fully decoded whereas on Python 2, keys will - remain bytestrings if they fit into ASCII. On 2.x keys can be forced - to be unicode by setting `decode_keys` to `True`. - - If the charset is set to `None` no unicode decoding will happen and - raw bytes will be returned. - - Per default a missing value for a key will default to an empty key. If - you don't want that behavior you can set `include_empty` to `False`. - - Per default encoding errors are ignored. If you want a different behavior - you can set `errors` to ``'replace'`` or ``'strict'``. In strict mode a - `HTTPUnicodeError` is raised. - - .. versionchanged:: 0.5 - In previous versions ";" and "&" could be used for url decoding. - This changed in 0.5 where only "&" is supported. If you want to - use ";" instead a different `separator` can be provided. - - The `cls` parameter was added. - - :param s: a string with the query string to decode. - :param charset: the charset of the query string. If set to `None` - no unicode decoding will take place. - :param decode_keys: Used on Python 2.x to control whether keys should - be forced to be unicode objects. If set to `True` - then keys will be unicode in all cases. Otherwise, - they remain `str` if they fit into ASCII. - :param include_empty: Set to `False` if you don't want empty values to - appear in the dict. - :param errors: the decoding error behavior. - :param separator: the pair separator to be used, defaults to ``&`` - :param cls: an optional dict class to use. If this is not specified - or `None` the default :class:`MultiDict` is used. - """ - if cls is None: - cls = MultiDict - if isinstance(s, text_type) and not isinstance(separator, text_type): - separator = separator.decode(charset or 'ascii') - elif isinstance(s, bytes) and not isinstance(separator, bytes): - separator = separator.encode(charset or 'ascii') - return cls(_url_decode_impl(s.split(separator), charset, decode_keys, - include_empty, errors)) - - -def url_decode_stream(stream, charset='utf-8', decode_keys=False, - include_empty=True, errors='replace', separator='&', - cls=None, limit=None, return_iterator=False): - """Works like :func:`url_decode` but decodes a stream. The behavior - of stream and limit follows functions like - :func:`~werkzeug.wsgi.make_line_iter`. The generator of pairs is - directly fed to the `cls` so you can consume the data while it's - parsed. - - .. versionadded:: 0.8 - - :param stream: a stream with the encoded querystring - :param charset: the charset of the query string. If set to `None` - no unicode decoding will take place. - :param decode_keys: Used on Python 2.x to control whether keys should - be forced to be unicode objects. If set to `True`, - keys will be unicode in all cases. Otherwise, they - remain `str` if they fit into ASCII. - :param include_empty: Set to `False` if you don't want empty values to - appear in the dict. - :param errors: the decoding error behavior. - :param separator: the pair separator to be used, defaults to ``&`` - :param cls: an optional dict class to use. If this is not specified - or `None` the default :class:`MultiDict` is used. - :param limit: the content length of the URL data. Not necessary if - a limited stream is provided. - :param return_iterator: if set to `True` the `cls` argument is ignored - and an iterator over all decoded pairs is - returned - """ - from werkzeug.wsgi import make_chunk_iter - if return_iterator: - cls = lambda x: x - elif cls is None: - cls = MultiDict - pair_iter = make_chunk_iter(stream, separator, limit) - return cls(_url_decode_impl(pair_iter, charset, decode_keys, - include_empty, errors)) - - -def _url_decode_impl(pair_iter, charset, decode_keys, include_empty, errors): - for pair in pair_iter: - if not pair: - continue - s = make_literal_wrapper(pair) - equal = s('=') - if equal in pair: - key, value = pair.split(equal, 1) - else: - if not include_empty: - continue - key = pair - value = s('') - key = url_unquote_plus(key, charset, errors) - if charset is not None and PY2 and not decode_keys: - key = try_coerce_native(key) - yield key, url_unquote_plus(value, charset, errors) - - -def url_encode(obj, charset='utf-8', encode_keys=False, sort=False, key=None, - separator=b'&'): - """URL encode a dict/`MultiDict`. If a value is `None` it will not appear - in the result string. Per default only values are encoded into the target - charset strings. If `encode_keys` is set to ``True`` unicode keys are - supported too. - - If `sort` is set to `True` the items are sorted by `key` or the default - sorting algorithm. - - .. versionadded:: 0.5 - `sort`, `key`, and `separator` were added. - - :param obj: the object to encode into a query string. - :param charset: the charset of the query string. - :param encode_keys: set to `True` if you have unicode keys. (Ignored on - Python 3.x) - :param sort: set to `True` if you want parameters to be sorted by `key`. - :param separator: the separator to be used for the pairs. - :param key: an optional function to be used for sorting. For more details - check out the :func:`sorted` documentation. - """ - separator = to_native(separator, 'ascii') - return separator.join(_url_encode_impl(obj, charset, encode_keys, sort, key)) - - -def url_encode_stream(obj, stream=None, charset='utf-8', encode_keys=False, - sort=False, key=None, separator=b'&'): - """Like :meth:`url_encode` but writes the results to a stream - object. If the stream is `None` a generator over all encoded - pairs is returned. - - .. versionadded:: 0.8 - - :param obj: the object to encode into a query string. - :param stream: a stream to write the encoded object into or `None` if - an iterator over the encoded pairs should be returned. In - that case the separator argument is ignored. - :param charset: the charset of the query string. - :param encode_keys: set to `True` if you have unicode keys. (Ignored on - Python 3.x) - :param sort: set to `True` if you want parameters to be sorted by `key`. - :param separator: the separator to be used for the pairs. - :param key: an optional function to be used for sorting. For more details - check out the :func:`sorted` documentation. - """ - separator = to_native(separator, 'ascii') - gen = _url_encode_impl(obj, charset, encode_keys, sort, key) - if stream is None: - return gen - for idx, chunk in enumerate(gen): - if idx: - stream.write(separator) - stream.write(chunk) - - -def url_join(base, url, allow_fragments=True): - """Join a base URL and a possibly relative URL to form an absolute - interpretation of the latter. - - :param base: the base URL for the join operation. - :param url: the URL to join. - :param allow_fragments: indicates whether fragments should be allowed. - """ - if isinstance(base, tuple): - base = url_unparse(base) - if isinstance(url, tuple): - url = url_unparse(url) - - base, url = normalize_string_tuple((base, url)) - s = make_literal_wrapper(base) - - if not base: - return url - if not url: - return base - - bscheme, bnetloc, bpath, bquery, bfragment = \ - url_parse(base, allow_fragments=allow_fragments) - scheme, netloc, path, query, fragment = \ - url_parse(url, bscheme, allow_fragments) - if scheme != bscheme: - return url - if netloc: - return url_unparse((scheme, netloc, path, query, fragment)) - netloc = bnetloc - - if path[:1] == s('/'): - segments = path.split(s('/')) - elif not path: - segments = bpath.split(s('/')) - if not query: - query = bquery - else: - segments = bpath.split(s('/'))[:-1] + path.split(s('/')) - - # If the rightmost part is "./" we want to keep the slash but - # remove the dot. - if segments[-1] == s('.'): - segments[-1] = s('') - - # Resolve ".." and "." - segments = [segment for segment in segments if segment != s('.')] - while 1: - i = 1 - n = len(segments) - 1 - while i < n: - if segments[i] == s('..') and \ - segments[i - 1] not in (s(''), s('..')): - del segments[i - 1:i + 1] - break - i += 1 - else: - break - - # Remove trailing ".." if the URL is absolute - unwanted_marker = [s(''), s('..')] - while segments[:2] == unwanted_marker: - del segments[1] - - path = s('/').join(segments) - return url_unparse((scheme, netloc, path, query, fragment)) - - -class Href(object): - - """Implements a callable that constructs URLs with the given base. The - function can be called with any number of positional and keyword - arguments which than are used to assemble the URL. Works with URLs - and posix paths. - - Positional arguments are appended as individual segments to - the path of the URL: - - >>> href = Href('/foo') - >>> href('bar', 23) - '/foo/bar/23' - >>> href('foo', bar=23) - '/foo/foo?bar=23' - - If any of the arguments (positional or keyword) evaluates to `None` it - will be skipped. If no keyword arguments are given the last argument - can be a :class:`dict` or :class:`MultiDict` (or any other dict subclass), - otherwise the keyword arguments are used for the query parameters, cutting - off the first trailing underscore of the parameter name: - - >>> href(is_=42) - '/foo?is=42' - >>> href({'foo': 'bar'}) - '/foo?foo=bar' - - Combining of both methods is not allowed: - - >>> href({'foo': 'bar'}, bar=42) - Traceback (most recent call last): - ... - TypeError: keyword arguments and query-dicts can't be combined - - Accessing attributes on the href object creates a new href object with - the attribute name as prefix: - - >>> bar_href = href.bar - >>> bar_href("blub") - '/foo/bar/blub' - - If `sort` is set to `True` the items are sorted by `key` or the default - sorting algorithm: - - >>> href = Href("/", sort=True) - >>> href(a=1, b=2, c=3) - '/?a=1&b=2&c=3' - - .. versionadded:: 0.5 - `sort` and `key` were added. - """ - - def __init__(self, base='./', charset='utf-8', sort=False, key=None): - if not base: - base = './' - self.base = base - self.charset = charset - self.sort = sort - self.key = key - - def __getattr__(self, name): - if name[:2] == '__': - raise AttributeError(name) - base = self.base - if base[-1:] != '/': - base += '/' - return Href(url_join(base, name), self.charset, self.sort, self.key) - - def __call__(self, *path, **query): - if path and isinstance(path[-1], dict): - if query: - raise TypeError('keyword arguments and query-dicts ' - 'can\'t be combined') - query, path = path[-1], path[:-1] - elif query: - query = dict([(k.endswith('_') and k[:-1] or k, v) - for k, v in query.items()]) - path = '/'.join([to_unicode(url_quote(x, self.charset), 'ascii') - for x in path if x is not None]).lstrip('/') - rv = self.base - if path: - if not rv.endswith('/'): - rv += '/' - rv = url_join(rv, './' + path) - if query: - rv += '?' + to_unicode(url_encode(query, self.charset, sort=self.sort, - key=self.key), 'ascii') - return to_native(rv) diff --git a/pyextra/werkzeug/useragents.py b/pyextra/werkzeug/useragents.py deleted file mode 100644 index 4d7d41f1cf4ebc..00000000000000 --- a/pyextra/werkzeug/useragents.py +++ /dev/null @@ -1,212 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.useragents - ~~~~~~~~~~~~~~~~~~~ - - This module provides a helper to inspect user agent strings. This module - is far from complete but should work for most of the currently available - browsers. - - - :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -import re - - -class UserAgentParser(object): - - """A simple user agent parser. Used by the `UserAgent`.""" - - platforms = ( - ('cros', 'chromeos'), - ('iphone|ios', 'iphone'), - ('ipad', 'ipad'), - (r'darwin|mac|os\s*x', 'macos'), - ('win', 'windows'), - (r'android', 'android'), - ('netbsd', 'netbsd'), - ('openbsd', 'openbsd'), - ('freebsd', 'freebsd'), - ('dragonfly', 'dragonflybsd'), - ('(sun|i86)os', 'solaris'), - (r'x11|lin(\b|ux)?', 'linux'), - (r'nintendo\s+wii', 'wii'), - ('irix', 'irix'), - ('hp-?ux', 'hpux'), - ('aix', 'aix'), - ('sco|unix_sv', 'sco'), - ('bsd', 'bsd'), - ('amiga', 'amiga'), - ('blackberry|playbook', 'blackberry'), - ('symbian', 'symbian') - ) - browsers = ( - ('googlebot', 'google'), - ('msnbot', 'msn'), - ('yahoo', 'yahoo'), - ('ask jeeves', 'ask'), - (r'aol|america\s+online\s+browser', 'aol'), - ('opera', 'opera'), - ('edge', 'edge'), - ('chrome', 'chrome'), - ('seamonkey', 'seamonkey'), - ('firefox|firebird|phoenix|iceweasel', 'firefox'), - ('galeon', 'galeon'), - ('safari|version', 'safari'), - ('webkit', 'webkit'), - ('camino', 'camino'), - ('konqueror', 'konqueror'), - ('k-meleon', 'kmeleon'), - ('netscape', 'netscape'), - (r'msie|microsoft\s+internet\s+explorer|trident/.+? rv:', 'msie'), - ('lynx', 'lynx'), - ('links', 'links'), - ('Baiduspider', 'baidu'), - ('bingbot', 'bing'), - ('mozilla', 'mozilla') - ) - - _browser_version_re = r'(?:%s)[/\sa-z(]*(\d+[.\da-z]+)?' - _language_re = re.compile( - r'(?:;\s*|\s+)(\b\w{2}\b(?:-\b\w{2}\b)?)\s*;|' - r'(?:\(|\[|;)\s*(\b\w{2}\b(?:-\b\w{2}\b)?)\s*(?:\]|\)|;)' - ) - - def __init__(self): - self.platforms = [(b, re.compile(a, re.I)) for a, b in self.platforms] - self.browsers = [(b, re.compile(self._browser_version_re % a, re.I)) - for a, b in self.browsers] - - def __call__(self, user_agent): - for platform, regex in self.platforms: - match = regex.search(user_agent) - if match is not None: - break - else: - platform = None - for browser, regex in self.browsers: - match = regex.search(user_agent) - if match is not None: - version = match.group(1) - break - else: - browser = version = None - match = self._language_re.search(user_agent) - if match is not None: - language = match.group(1) or match.group(2) - else: - language = None - return platform, browser, version, language - - -class UserAgent(object): - - """Represents a user agent. Pass it a WSGI environment or a user agent - string and you can inspect some of the details from the user agent - string via the attributes. The following attributes exist: - - .. attribute:: string - - the raw user agent string - - .. attribute:: platform - - the browser platform. The following platforms are currently - recognized: - - - `aix` - - `amiga` - - `android` - - `blackberry` - - `bsd` - - `chromeos` - - `dragonflybsd` - - `freebsd` - - `hpux` - - `ipad` - - `iphone` - - `irix` - - `linux` - - `macos` - - `netbsd` - - `openbsd` - - `sco` - - `solaris` - - `symbian` - - `wii` - - `windows` - - .. attribute:: browser - - the name of the browser. The following browsers are currently - recognized: - - - `aol` * - - `ask` * - - `baidu` * - - `bing` * - - `camino` - - `chrome` - - `firefox` - - `galeon` - - `google` * - - `kmeleon` - - `konqueror` - - `links` - - `lynx` - - `mozilla` - - `msie` - - `msn` - - `netscape` - - `opera` - - `safari` - - `seamonkey` - - `webkit` - - `yahoo` * - - (Browsers marked with a star (``*``) are crawlers.) - - .. attribute:: version - - the version of the browser - - .. attribute:: language - - the language of the browser - """ - - _parser = UserAgentParser() - - def __init__(self, environ_or_string): - if isinstance(environ_or_string, dict): - environ_or_string = environ_or_string.get('HTTP_USER_AGENT', '') - self.string = environ_or_string - self.platform, self.browser, self.version, self.language = \ - self._parser(environ_or_string) - - def to_header(self): - return self.string - - def __str__(self): - return self.string - - def __nonzero__(self): - return bool(self.browser) - - __bool__ = __nonzero__ - - def __repr__(self): - return '<%s %r/%s>' % ( - self.__class__.__name__, - self.browser, - self.version - ) - - -# conceptionally this belongs in this module but because we want to lazily -# load the user agent module (which happens in wrappers.py) we have to import -# it afterwards. The class itself has the module set to this module so -# pickle, inspect and similar modules treat the object as if it was really -# implemented here. -from werkzeug.wrappers import UserAgentMixin # noqa diff --git a/pyextra/werkzeug/utils.py b/pyextra/werkzeug/utils.py deleted file mode 100644 index 918e7e5b60170b..00000000000000 --- a/pyextra/werkzeug/utils.py +++ /dev/null @@ -1,628 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.utils - ~~~~~~~~~~~~~~ - - This module implements various utilities for WSGI applications. Most of - them are used by the request and response wrappers but especially for - middleware development it makes sense to use them without the wrappers. - - :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -import re -import os -import sys -import pkgutil -try: - from html.entities import name2codepoint -except ImportError: - from htmlentitydefs import name2codepoint - -from werkzeug._compat import unichr, text_type, string_types, iteritems, \ - reraise, PY2 -from werkzeug._internal import _DictAccessorProperty, \ - _parse_signature, _missing - - -_format_re = re.compile(r'\$(?:(%s)|\{(%s)\})' % (('[a-zA-Z_][a-zA-Z0-9_]*',) * 2)) -_entity_re = re.compile(r'&([^;]+);') -_filename_ascii_strip_re = re.compile(r'[^A-Za-z0-9_.-]') -_windows_device_files = ('CON', 'AUX', 'COM1', 'COM2', 'COM3', 'COM4', 'LPT1', - 'LPT2', 'LPT3', 'PRN', 'NUL') - - -class cached_property(property): - - """A decorator that converts a function into a lazy property. The - function wrapped is called the first time to retrieve the result - and then that calculated result is used the next time you access - the value:: - - class Foo(object): - - @cached_property - def foo(self): - # calculate something important here - return 42 - - The class has to have a `__dict__` in order for this property to - work. - """ - - # implementation detail: A subclass of python's builtin property - # decorator, we override __get__ to check for a cached value. If one - # choses to invoke __get__ by hand the property will still work as - # expected because the lookup logic is replicated in __get__ for - # manual invocation. - - def __init__(self, func, name=None, doc=None): - self.__name__ = name or func.__name__ - self.__module__ = func.__module__ - self.__doc__ = doc or func.__doc__ - self.func = func - - def __set__(self, obj, value): - obj.__dict__[self.__name__] = value - - def __get__(self, obj, type=None): - if obj is None: - return self - value = obj.__dict__.get(self.__name__, _missing) - if value is _missing: - value = self.func(obj) - obj.__dict__[self.__name__] = value - return value - - -class environ_property(_DictAccessorProperty): - - """Maps request attributes to environment variables. This works not only - for the Werzeug request object, but also any other class with an - environ attribute: - - >>> class Test(object): - ... environ = {'key': 'value'} - ... test = environ_property('key') - >>> var = Test() - >>> var.test - 'value' - - If you pass it a second value it's used as default if the key does not - exist, the third one can be a converter that takes a value and converts - it. If it raises :exc:`ValueError` or :exc:`TypeError` the default value - is used. If no default value is provided `None` is used. - - Per default the property is read only. You have to explicitly enable it - by passing ``read_only=False`` to the constructor. - """ - - read_only = True - - def lookup(self, obj): - return obj.environ - - -class header_property(_DictAccessorProperty): - - """Like `environ_property` but for headers.""" - - def lookup(self, obj): - return obj.headers - - -class HTMLBuilder(object): - - """Helper object for HTML generation. - - Per default there are two instances of that class. The `html` one, and - the `xhtml` one for those two dialects. The class uses keyword parameters - and positional parameters to generate small snippets of HTML. - - Keyword parameters are converted to XML/SGML attributes, positional - arguments are used as children. Because Python accepts positional - arguments before keyword arguments it's a good idea to use a list with the - star-syntax for some children: - - >>> html.p(class_='foo', *[html.a('foo', href='foo.html'), ' ', - ... html.a('bar', href='bar.html')]) - u'

    foo bar

    ' - - This class works around some browser limitations and can not be used for - arbitrary SGML/XML generation. For that purpose lxml and similar - libraries exist. - - Calling the builder escapes the string passed: - - >>> html.p(html("")) - u'

    <foo>

    ' - """ - - _entity_re = re.compile(r'&([^;]+);') - _entities = name2codepoint.copy() - _entities['apos'] = 39 - _empty_elements = set([ - 'area', 'base', 'basefont', 'br', 'col', 'command', 'embed', 'frame', - 'hr', 'img', 'input', 'keygen', 'isindex', 'link', 'meta', 'param', - 'source', 'wbr' - ]) - _boolean_attributes = set([ - 'selected', 'checked', 'compact', 'declare', 'defer', 'disabled', - 'ismap', 'multiple', 'nohref', 'noresize', 'noshade', 'nowrap' - ]) - _plaintext_elements = set(['textarea']) - _c_like_cdata = set(['script', 'style']) - - def __init__(self, dialect): - self._dialect = dialect - - def __call__(self, s): - return escape(s) - - def __getattr__(self, tag): - if tag[:2] == '__': - raise AttributeError(tag) - - def proxy(*children, **arguments): - buffer = '<' + tag - for key, value in iteritems(arguments): - if value is None: - continue - if key[-1] == '_': - key = key[:-1] - if key in self._boolean_attributes: - if not value: - continue - if self._dialect == 'xhtml': - value = '="' + key + '"' - else: - value = '' - else: - value = '="' + escape(value) + '"' - buffer += ' ' + key + value - if not children and tag in self._empty_elements: - if self._dialect == 'xhtml': - buffer += ' />' - else: - buffer += '>' - return buffer - buffer += '>' - - children_as_string = ''.join([text_type(x) for x in children - if x is not None]) - - if children_as_string: - if tag in self._plaintext_elements: - children_as_string = escape(children_as_string) - elif tag in self._c_like_cdata and self._dialect == 'xhtml': - children_as_string = '/**/' - buffer += children_as_string + '' - return buffer - return proxy - - def __repr__(self): - return '<%s for %r>' % ( - self.__class__.__name__, - self._dialect - ) - - -html = HTMLBuilder('html') -xhtml = HTMLBuilder('xhtml') - - -def get_content_type(mimetype, charset): - """Returns the full content type string with charset for a mimetype. - - If the mimetype represents text the charset will be appended as charset - parameter, otherwise the mimetype is returned unchanged. - - :param mimetype: the mimetype to be used as content type. - :param charset: the charset to be appended in case it was a text mimetype. - :return: the content type. - """ - if mimetype.startswith('text/') or \ - mimetype == 'application/xml' or \ - (mimetype.startswith('application/') and - mimetype.endswith('+xml')): - mimetype += '; charset=' + charset - return mimetype - - -def format_string(string, context): - """String-template format a string: - - >>> format_string('$foo and ${foo}s', dict(foo=42)) - '42 and 42s' - - This does not do any attribute lookup etc. For more advanced string - formattings have a look at the `werkzeug.template` module. - - :param string: the format string. - :param context: a dict with the variables to insert. - """ - def lookup_arg(match): - x = context[match.group(1) or match.group(2)] - if not isinstance(x, string_types): - x = type(string)(x) - return x - return _format_re.sub(lookup_arg, string) - - -def secure_filename(filename): - r"""Pass it a filename and it will return a secure version of it. This - filename can then safely be stored on a regular file system and passed - to :func:`os.path.join`. The filename returned is an ASCII only string - for maximum portability. - - On windows systems the function also makes sure that the file is not - named after one of the special device files. - - >>> secure_filename("My cool movie.mov") - 'My_cool_movie.mov' - >>> secure_filename("../../../etc/passwd") - 'etc_passwd' - >>> secure_filename(u'i contain cool \xfcml\xe4uts.txt') - 'i_contain_cool_umlauts.txt' - - The function might return an empty filename. It's your responsibility - to ensure that the filename is unique and that you generate random - filename if the function returned an empty one. - - .. versionadded:: 0.5 - - :param filename: the filename to secure - """ - if isinstance(filename, text_type): - from unicodedata import normalize - filename = normalize('NFKD', filename).encode('ascii', 'ignore') - if not PY2: - filename = filename.decode('ascii') - for sep in os.path.sep, os.path.altsep: - if sep: - filename = filename.replace(sep, ' ') - filename = str(_filename_ascii_strip_re.sub('', '_'.join( - filename.split()))).strip('._') - - # on nt a couple of special files are present in each folder. We - # have to ensure that the target file is not such a filename. In - # this case we prepend an underline - if os.name == 'nt' and filename and \ - filename.split('.')[0].upper() in _windows_device_files: - filename = '_' + filename - - return filename - - -def escape(s, quote=None): - """Replace special characters "&", "<", ">" and (") to HTML-safe sequences. - - There is a special handling for `None` which escapes to an empty string. - - .. versionchanged:: 0.9 - `quote` is now implicitly on. - - :param s: the string to escape. - :param quote: ignored. - """ - if s is None: - return '' - elif hasattr(s, '__html__'): - return text_type(s.__html__()) - elif not isinstance(s, string_types): - s = text_type(s) - if quote is not None: - from warnings import warn - warn(DeprecationWarning('quote parameter is implicit now'), stacklevel=2) - s = s.replace('&', '&').replace('<', '<') \ - .replace('>', '>').replace('"', """) - return s - - -def unescape(s): - """The reverse function of `escape`. This unescapes all the HTML - entities, not only the XML entities inserted by `escape`. - - :param s: the string to unescape. - """ - def handle_match(m): - name = m.group(1) - if name in HTMLBuilder._entities: - return unichr(HTMLBuilder._entities[name]) - try: - if name[:2] in ('#x', '#X'): - return unichr(int(name[2:], 16)) - elif name.startswith('#'): - return unichr(int(name[1:])) - except ValueError: - pass - return u'' - return _entity_re.sub(handle_match, s) - - -def redirect(location, code=302, Response=None): - """Returns a response object (a WSGI application) that, if called, - redirects the client to the target location. Supported codes are 301, - 302, 303, 305, and 307. 300 is not supported because it's not a real - redirect and 304 because it's the answer for a request with a request - with defined If-Modified-Since headers. - - .. versionadded:: 0.6 - The location can now be a unicode string that is encoded using - the :func:`iri_to_uri` function. - - .. versionadded:: 0.10 - The class used for the Response object can now be passed in. - - :param location: the location the response should redirect to. - :param code: the redirect status code. defaults to 302. - :param class Response: a Response class to use when instantiating a - response. The default is :class:`werkzeug.wrappers.Response` if - unspecified. - """ - if Response is None: - from werkzeug.wrappers import Response - - display_location = escape(location) - if isinstance(location, text_type): - # Safe conversion is necessary here as we might redirect - # to a broken URI scheme (for instance itms-services). - from werkzeug.urls import iri_to_uri - location = iri_to_uri(location, safe_conversion=True) - response = Response( - '\n' - 'Redirecting...\n' - '

    Redirecting...

    \n' - '

    You should be redirected automatically to target URL: ' - '%s. If not click the link.' % - (escape(location), display_location), code, mimetype='text/html') - response.headers['Location'] = location - return response - - -def append_slash_redirect(environ, code=301): - """Redirects to the same URL but with a slash appended. The behavior - of this function is undefined if the path ends with a slash already. - - :param environ: the WSGI environment for the request that triggers - the redirect. - :param code: the status code for the redirect. - """ - new_path = environ['PATH_INFO'].strip('/') + '/' - query_string = environ.get('QUERY_STRING') - if query_string: - new_path += '?' + query_string - return redirect(new_path, code) - - -def import_string(import_name, silent=False): - """Imports an object based on a string. This is useful if you want to - use import paths as endpoints or something similar. An import path can - be specified either in dotted notation (``xml.sax.saxutils.escape``) - or with a colon as object delimiter (``xml.sax.saxutils:escape``). - - If `silent` is True the return value will be `None` if the import fails. - - :param import_name: the dotted name for the object to import. - :param silent: if set to `True` import errors are ignored and - `None` is returned instead. - :return: imported object - """ - # force the import name to automatically convert to strings - # __import__ is not able to handle unicode strings in the fromlist - # if the module is a package - import_name = str(import_name).replace(':', '.') - try: - try: - __import__(import_name) - except ImportError: - if '.' not in import_name: - raise - else: - return sys.modules[import_name] - - module_name, obj_name = import_name.rsplit('.', 1) - try: - module = __import__(module_name, None, None, [obj_name]) - except ImportError: - # support importing modules not yet set up by the parent module - # (or package for that matter) - module = import_string(module_name) - - try: - return getattr(module, obj_name) - except AttributeError as e: - raise ImportError(e) - - except ImportError as e: - if not silent: - reraise( - ImportStringError, - ImportStringError(import_name, e), - sys.exc_info()[2]) - - -def find_modules(import_path, include_packages=False, recursive=False): - """Finds all the modules below a package. This can be useful to - automatically import all views / controllers so that their metaclasses / - function decorators have a chance to register themselves on the - application. - - Packages are not returned unless `include_packages` is `True`. This can - also recursively list modules but in that case it will import all the - packages to get the correct load path of that module. - - :param import_path: the dotted name for the package to find child modules. - :param include_packages: set to `True` if packages should be returned, too. - :param recursive: set to `True` if recursion should happen. - :return: generator - """ - module = import_string(import_path) - path = getattr(module, '__path__', None) - if path is None: - raise ValueError('%r is not a package' % import_path) - basename = module.__name__ + '.' - for importer, modname, ispkg in pkgutil.iter_modules(path): - modname = basename + modname - if ispkg: - if include_packages: - yield modname - if recursive: - for item in find_modules(modname, include_packages, True): - yield item - else: - yield modname - - -def validate_arguments(func, args, kwargs, drop_extra=True): - """Checks if the function accepts the arguments and keyword arguments. - Returns a new ``(args, kwargs)`` tuple that can safely be passed to - the function without causing a `TypeError` because the function signature - is incompatible. If `drop_extra` is set to `True` (which is the default) - any extra positional or keyword arguments are dropped automatically. - - The exception raised provides three attributes: - - `missing` - A set of argument names that the function expected but where - missing. - - `extra` - A dict of keyword arguments that the function can not handle but - where provided. - - `extra_positional` - A list of values that where given by positional argument but the - function cannot accept. - - This can be useful for decorators that forward user submitted data to - a view function:: - - from werkzeug.utils import ArgumentValidationError, validate_arguments - - def sanitize(f): - def proxy(request): - data = request.values.to_dict() - try: - args, kwargs = validate_arguments(f, (request,), data) - except ArgumentValidationError: - raise BadRequest('The browser failed to transmit all ' - 'the data expected.') - return f(*args, **kwargs) - return proxy - - :param func: the function the validation is performed against. - :param args: a tuple of positional arguments. - :param kwargs: a dict of keyword arguments. - :param drop_extra: set to `False` if you don't want extra arguments - to be silently dropped. - :return: tuple in the form ``(args, kwargs)``. - """ - parser = _parse_signature(func) - args, kwargs, missing, extra, extra_positional = parser(args, kwargs)[:5] - if missing: - raise ArgumentValidationError(tuple(missing)) - elif (extra or extra_positional) and not drop_extra: - raise ArgumentValidationError(None, extra, extra_positional) - return tuple(args), kwargs - - -def bind_arguments(func, args, kwargs): - """Bind the arguments provided into a dict. When passed a function, - a tuple of arguments and a dict of keyword arguments `bind_arguments` - returns a dict of names as the function would see it. This can be useful - to implement a cache decorator that uses the function arguments to build - the cache key based on the values of the arguments. - - :param func: the function the arguments should be bound for. - :param args: tuple of positional arguments. - :param kwargs: a dict of keyword arguments. - :return: a :class:`dict` of bound keyword arguments. - """ - args, kwargs, missing, extra, extra_positional, \ - arg_spec, vararg_var, kwarg_var = _parse_signature(func)(args, kwargs) - values = {} - for (name, has_default, default), value in zip(arg_spec, args): - values[name] = value - if vararg_var is not None: - values[vararg_var] = tuple(extra_positional) - elif extra_positional: - raise TypeError('too many positional arguments') - if kwarg_var is not None: - multikw = set(extra) & set([x[0] for x in arg_spec]) - if multikw: - raise TypeError('got multiple values for keyword argument ' + - repr(next(iter(multikw)))) - values[kwarg_var] = extra - elif extra: - raise TypeError('got unexpected keyword argument ' + - repr(next(iter(extra)))) - return values - - -class ArgumentValidationError(ValueError): - - """Raised if :func:`validate_arguments` fails to validate""" - - def __init__(self, missing=None, extra=None, extra_positional=None): - self.missing = set(missing or ()) - self.extra = extra or {} - self.extra_positional = extra_positional or [] - ValueError.__init__(self, 'function arguments invalid. (' - '%d missing, %d additional)' % ( - len(self.missing), - len(self.extra) + len(self.extra_positional) - )) - - -class ImportStringError(ImportError): - - """Provides information about a failed :func:`import_string` attempt.""" - - #: String in dotted notation that failed to be imported. - import_name = None - #: Wrapped exception. - exception = None - - def __init__(self, import_name, exception): - self.import_name = import_name - self.exception = exception - - msg = ( - 'import_string() failed for %r. Possible reasons are:\n\n' - '- missing __init__.py in a package;\n' - '- package or module path not included in sys.path;\n' - '- duplicated package or module name taking precedence in ' - 'sys.path;\n' - '- missing module, class, function or variable;\n\n' - 'Debugged import:\n\n%s\n\n' - 'Original exception:\n\n%s: %s') - - name = '' - tracked = [] - for part in import_name.replace(':', '.').split('.'): - name += (name and '.') + part - imported = import_string(name, silent=True) - if imported: - tracked.append((name, getattr(imported, '__file__', None))) - else: - track = ['- %r found in %r.' % (n, i) for n, i in tracked] - track.append('- %r not found.' % name) - msg = msg % (import_name, '\n'.join(track), - exception.__class__.__name__, str(exception)) - break - - ImportError.__init__(self, msg) - - def __repr__(self): - return '<%s(%r, %r)>' % (self.__class__.__name__, self.import_name, - self.exception) - - -# DEPRECATED -# these objects were previously in this module as well. we import -# them here for backwards compatibility with old pickles. -from werkzeug.datastructures import ( # noqa - MultiDict, CombinedMultiDict, Headers, EnvironHeaders) -from werkzeug.http import parse_cookie, dump_cookie # noqa diff --git a/pyextra/werkzeug/websocket.py b/pyextra/werkzeug/websocket.py deleted file mode 100644 index 764698b70337ea..00000000000000 --- a/pyextra/werkzeug/websocket.py +++ /dev/null @@ -1,337 +0,0 @@ -import re -import errno -import socket -import struct -import collections - -from base64 import b64decode, b64encode -from hashlib import sha1 - - -WS_KEY = b'258EAFA5-E914-47DA-95CA-C5AB0DC85B11' - - -def pack_message(message): - """Pack the message inside ``00`` and ``FF`` - As per the dataframing section (5.3) for the websocket spec - """ - if isinstance(message, unicode): - message = message.encode('utf-8') - elif not isinstance(message, str): - message = str(message) - packed = "\x00%s\xFF" % message - return packed - - -def encode_hybi(buf, opcode, base64=False): - """ Encode a HyBi style WebSocket frame. - Optional opcode: - 0x0 - continuation - 0x1 - text frame (base64 encode buf) - 0x2 - binary frame (use raw buf) - 0x8 - connection close - 0x9 - ping - 0xA - pong - """ - if base64: - buf = b64encode(buf) - b1 = 0x80 | (opcode & 0x0f) # FIN + opcode - payload_len = len(buf) - if payload_len <= 125: - header = struct.pack('>BB', b1, payload_len) - elif payload_len > 125 and payload_len < 65536: - header = struct.pack('>BBH', b1, 126, payload_len) - elif payload_len >= 65536: - header = struct.pack('>BBQ', b1, 127, payload_len) - return header + buf, len(header), 0 - - -def decode_hybi(buf, base64=False): - """Decode HyBi style WebSocket packets.""" - f = {'fin' : 0, - 'opcode' : 0, - 'mask' : 0, - 'hlen' : 2, - 'length' : 0, - 'payload' : None, - 'left' : 0, - 'close_code' : None, - 'close_reason' : None} - - blen = len(buf) - f['left'] = blen - - if blen < f['hlen']: - return f # Incomplete frame header - - b1, b2 = struct.unpack_from(">BB", buf) - f['opcode'] = b1 & 0x0f - f['fin'] = (b1 & 0x80) >> 7 - has_mask = (b2 & 0x80) >> 7 - - f['length'] = b2 & 0x7f - - if f['length'] == 126: - f['hlen'] = 4 - if blen < f['hlen']: - return f # Incomplete frame header - (f['length'],) = struct.unpack_from('>xxH', buf) - elif f['length'] == 127: - f['hlen'] = 10 - if blen < f['hlen']: - return f # Incomplete frame header - (f['length'],) = struct.unpack_from('>xxQ', buf) - - full_len = f['hlen'] + has_mask * 4 + f['length'] - - if blen < full_len: # Incomplete frame - return f # Incomplete frame header - - # Number of bytes that are part of the next frame(s) - f['left'] = blen - full_len - - # Process 1 frame - if has_mask: - # unmask payload - f['mask'] = buf[f['hlen']:f['hlen']+4] - b = c = '' - if f['length'] >= 4: - data = struct.unpack('= 2: - f['close_code'] = struct.unpack_from(">H", f['payload']) - if f['length'] > 3: - f['close_reason'] = f['payload'][2:] - - return f - - -class WebSocketWSGI(object): - - def __init__(self, handler): - self.handler = handler - - def verify_client(self, ws): - pass - - def __call__(self, environ, start_response): - if not (environ.get('HTTP_CONNECTION').find('Upgrade') != -1 and - environ['HTTP_UPGRADE'].lower() == 'websocket'): - # need to check a few more things here for true compliance - start_response('400 Bad Request', [('Connection','close')]) - return [] - - sock = environ['gunicorn.socket'] - - ws = WebSocket(sock, environ) - - handshake_reply = ("HTTP/1.1 101 Switching Protocols\r\n" - "Upgrade: websocket\r\n" - "Connection: Upgrade\r\n") - - path = environ['PATH_INFO'] - key = environ.get('HTTP_SEC_WEBSOCKET_KEY') - if key: - ws_key = b64decode(key) - if len(ws_key) != 16: - start_response('400 Bad Request', [('Connection','close')]) - return [] - - protocols = [] - subprotocols = environ.get('HTTP_SEC_WEBSOCKET_PROTOCOL') - ws_protocols = [] - if subprotocols: - for s in subprotocols.split(','): - s = s.strip() - if s in protocols: - ws_protocols.append(s) - if ws_protocols: - handshake_reply += 'Sec-WebSocket-Protocol: %s\r\n' % ', '.join(ws_protocols) - - exts = [] - extensions = environ.get('HTTP_SEC_WEBSOCKET_EXTENSIONS') - ws_extensions = [] - if extensions: - for ext in extensions.split(','): - ext = ext.strip() - if ext in exts: - ws_extensions.append(ext) - if ws_extensions: - handshake_reply += 'Sec-WebSocket-Extensions: %s\r\n' % ', '.join(ws_extensions) - - handshake_reply += ( - "Sec-WebSocket-Origin: %s\r\n" - "Sec-WebSocket-Location: ws://%s%s\r\n" - "Sec-WebSocket-Version: %s\r\n" - "Sec-WebSocket-Accept: %s\r\n\r\n" - % ( - environ.get('HTTP_ORIGIN'), - environ.get('HTTP_HOST'), - path, - ws.version, - b64encode(sha1(key + WS_KEY).digest()) - )) - - else: - - handshake_reply += ( - "WebSocket-Origin: %s\r\n" - "WebSocket-Location: ws://%s%s\r\n\r\n" % ( - environ.get('HTTP_ORIGIN'), - environ.get('HTTP_HOST'), - path)) - - sock.sendall(handshake_reply) - - try: - self.handler(ws) - except socket.error as e: - if e[0] != errno.EPIPE: - raise - - # use this undocumented feature of grainbows to ensure that it - # doesn't barf on the fact that we didn't call start_response - return ALREADY_HANDLED - - -class WebSocket(object): - - def __init__(self, sock, environ, version=76): - self._socket = sock - try: - version = int(environ.get('HTTP_SEC_WEBSOCKET_VERSION')) - except (ValueError, TypeError): - version = 76 - self.version = version - self.closed = False - self.accepted = False - self._buf = b'' - self._msgs = collections.deque() - - def _parse_messages(self): - """ Parses for messages in the buffer *buf*. It is assumed that - the buffer contains the start character for a message, but that it - may contain only part of the rest of the message. - Returns an array of messages, and the buffer remainder that - didn't contain any full messages.""" - msgs = [] - end_idx = 0 - buf = self._buf - while buf: - if self.version in (7, 8, 13): - frame = decode_hybi(buf, base64=False) - - if frame['payload'] == None: - break - else: - if frame['opcode'] == 0x8: # connection close - self.closed = True - break - else: - msgs.append(frame['payload']); - if frame['left']: - buf = buf[-frame['left']:] - else: - buf = b'' - - else: - frame_type = ord(buf[0]) - if frame_type == 0: - # Normal message. - end_idx = buf.find("\xFF") - if end_idx == -1: #pragma NO COVER - break - msgs.append(buf[1:end_idx].decode('utf-8', 'replace')) - buf = buf[end_idx+1:] - elif frame_type == 255: - # Closing handshake. - assert ord(buf[1]) == 0, "Unexpected closing handshake: %r" % buf - self.closed = True - break - else: - raise ValueError("Don't understand how to parse this type of message: %r" % buf) - self._buf = buf - return msgs - - def send(self, message): - """Send a message to the browser. - *message* should be convertable to a string; unicode objects should be - encodable as utf-8. Raises socket.error with errno of 32 - (broken pipe) if the socket has already been closed by the client. - """ - if self.version in (7, 8, 13): - packed, lenhead, lentail = encode_hybi( - message, opcode=0x01, base64=False) - else: - packed = pack_message(message) - self._socket.sendall(packed) - - def wait(self): - """Waits for and deserializes messages. - Returns a single message; the oldest not yet processed. If the client - has already closed the connection, returns None. This is different - from normal socket behavior because the empty string is a valid - websocket message.""" - while not self._msgs: - # Websocket might be closed already. - if self.closed: - return None - # no parsed messages, must mean buf needs more data - delta = self._socket.recv(8096) - if delta == '': - return None - self._buf += delta - msgs = self._parse_messages() - self._msgs.extend(msgs) - return self._msgs.popleft() - - def _send_closing_frame(self, ignore_send_errors=False): - """Sends the closing frame to the client, if required.""" - if self.version in (7, 8, 13) and not self.closed: - msg = '' - #if code != None: - # msg = struct.pack(">H%ds" % (len(reason)), code) - - buf, h, t = encode_hybi(msg, opcode=0x08, base64=False) - self._socket.sendall(buf) - self.closed = True - - elif self.version == 76 and not self.closed: - try: - self._socket.sendall("\xff\x00") - except socket.error: - # Sometimes, like when the remote side cuts off the connection, - # we don't care about this. - if not ignore_send_errors: #pragma NO COVER - raise - self.closed = True - - def close(self): - """Forcibly close the websocket; generally it is preferable to - return from the handler method.""" - self._send_closing_frame() - self._socket.shutdown(True) - self._socket.close() diff --git a/pyextra/werkzeug/wrappers.py b/pyextra/werkzeug/wrappers.py deleted file mode 100644 index 92dfa5dacc0dcb..00000000000000 --- a/pyextra/werkzeug/wrappers.py +++ /dev/null @@ -1,2028 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.wrappers - ~~~~~~~~~~~~~~~~~ - - The wrappers are simple request and response objects which you can - subclass to do whatever you want them to do. The request object contains - the information transmitted by the client (webbrowser) and the response - object contains all the information sent back to the browser. - - An important detail is that the request object is created with the WSGI - environ and will act as high-level proxy whereas the response object is an - actual WSGI application. - - Like everything else in Werkzeug these objects will work correctly with - unicode data. Incoming form data parsed by the response object will be - decoded into an unicode object if possible and if it makes sense. - - - :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -from functools import update_wrapper -from datetime import datetime, timedelta -from warnings import warn - -from werkzeug.http import HTTP_STATUS_CODES, \ - parse_accept_header, parse_cache_control_header, parse_etags, \ - parse_date, generate_etag, is_resource_modified, unquote_etag, \ - quote_etag, parse_set_header, parse_authorization_header, \ - parse_www_authenticate_header, remove_entity_headers, \ - parse_options_header, dump_options_header, http_date, \ - parse_if_range_header, parse_cookie, dump_cookie, \ - parse_range_header, parse_content_range_header, dump_header, \ - parse_age, dump_age -from werkzeug.urls import url_decode, iri_to_uri, url_join -from werkzeug.formparser import FormDataParser, default_stream_factory -from werkzeug.utils import cached_property, environ_property, \ - header_property, get_content_type -from werkzeug.wsgi import get_current_url, get_host, \ - ClosingIterator, get_input_stream, get_content_length, _RangeWrapper -from werkzeug.datastructures import MultiDict, CombinedMultiDict, Headers, \ - EnvironHeaders, ImmutableMultiDict, ImmutableTypeConversionDict, \ - ImmutableList, MIMEAccept, CharsetAccept, LanguageAccept, \ - ResponseCacheControl, RequestCacheControl, CallbackDict, \ - ContentRange, iter_multi_items -from werkzeug._internal import _get_environ -from werkzeug._compat import to_bytes, string_types, text_type, \ - integer_types, wsgi_decoding_dance, wsgi_get_bytes, \ - to_unicode, to_native, BytesIO - - -def _run_wsgi_app(*args): - """This function replaces itself to ensure that the test module is not - imported unless required. DO NOT USE! - """ - global _run_wsgi_app - from werkzeug.test import run_wsgi_app as _run_wsgi_app - return _run_wsgi_app(*args) - - -def _warn_if_string(iterable): - """Helper for the response objects to check if the iterable returned - to the WSGI server is not a string. - """ - if isinstance(iterable, string_types): - warn(Warning('response iterable was set to a string. This appears ' - 'to work but means that the server will send the ' - 'data to the client char, by char. This is almost ' - 'never intended behavior, use response.data to assign ' - 'strings to the response object.'), stacklevel=2) - - -def _assert_not_shallow(request): - if request.shallow: - raise RuntimeError('A shallow request tried to consume ' - 'form data. If you really want to do ' - 'that, set `shallow` to False.') - - -def _iter_encoded(iterable, charset): - for item in iterable: - if isinstance(item, text_type): - yield item.encode(charset) - else: - yield item - - -def _clean_accept_ranges(accept_ranges): - if accept_ranges is True: - return "bytes" - elif accept_ranges is False: - return "none" - elif isinstance(accept_ranges, text_type): - return to_native(accept_ranges) - raise ValueError("Invalid accept_ranges value") - - -class BaseRequest(object): - - """Very basic request object. This does not implement advanced stuff like - entity tag parsing or cache controls. The request object is created with - the WSGI environment as first argument and will add itself to the WSGI - environment as ``'werkzeug.request'`` unless it's created with - `populate_request` set to False. - - There are a couple of mixins available that add additional functionality - to the request object, there is also a class called `Request` which - subclasses `BaseRequest` and all the important mixins. - - It's a good idea to create a custom subclass of the :class:`BaseRequest` - and add missing functionality either via mixins or direct implementation. - Here an example for such subclasses:: - - from werkzeug.wrappers import BaseRequest, ETagRequestMixin - - class Request(BaseRequest, ETagRequestMixin): - pass - - Request objects are **read only**. As of 0.5 modifications are not - allowed in any place. Unlike the lower level parsing functions the - request object will use immutable objects everywhere possible. - - Per default the request object will assume all the text data is `utf-8` - encoded. Please refer to `the unicode chapter `_ for more - details about customizing the behavior. - - Per default the request object will be added to the WSGI - environment as `werkzeug.request` to support the debugging system. - If you don't want that, set `populate_request` to `False`. - - If `shallow` is `True` the environment is initialized as shallow - object around the environ. Every operation that would modify the - environ in any way (such as consuming form data) raises an exception - unless the `shallow` attribute is explicitly set to `False`. This - is useful for middlewares where you don't want to consume the form - data by accident. A shallow request is not populated to the WSGI - environment. - - .. versionchanged:: 0.5 - read-only mode was enforced by using immutables classes for all - data. - """ - - #: the charset for the request, defaults to utf-8 - charset = 'utf-8' - - #: the error handling procedure for errors, defaults to 'replace' - encoding_errors = 'replace' - - #: the maximum content length. This is forwarded to the form data - #: parsing function (:func:`parse_form_data`). When set and the - #: :attr:`form` or :attr:`files` attribute is accessed and the - #: parsing fails because more than the specified value is transmitted - #: a :exc:`~werkzeug.exceptions.RequestEntityTooLarge` exception is raised. - #: - #: Have a look at :ref:`dealing-with-request-data` for more details. - #: - #: .. versionadded:: 0.5 - max_content_length = None - - #: the maximum form field size. This is forwarded to the form data - #: parsing function (:func:`parse_form_data`). When set and the - #: :attr:`form` or :attr:`files` attribute is accessed and the - #: data in memory for post data is longer than the specified value a - #: :exc:`~werkzeug.exceptions.RequestEntityTooLarge` exception is raised. - #: - #: Have a look at :ref:`dealing-with-request-data` for more details. - #: - #: .. versionadded:: 0.5 - max_form_memory_size = None - - #: the class to use for `args` and `form`. The default is an - #: :class:`~werkzeug.datastructures.ImmutableMultiDict` which supports - #: multiple values per key. alternatively it makes sense to use an - #: :class:`~werkzeug.datastructures.ImmutableOrderedMultiDict` which - #: preserves order or a :class:`~werkzeug.datastructures.ImmutableDict` - #: which is the fastest but only remembers the last key. It is also - #: possible to use mutable structures, but this is not recommended. - #: - #: .. versionadded:: 0.6 - parameter_storage_class = ImmutableMultiDict - - #: the type to be used for list values from the incoming WSGI environment. - #: By default an :class:`~werkzeug.datastructures.ImmutableList` is used - #: (for example for :attr:`access_list`). - #: - #: .. versionadded:: 0.6 - list_storage_class = ImmutableList - - #: the type to be used for dict values from the incoming WSGI environment. - #: By default an - #: :class:`~werkzeug.datastructures.ImmutableTypeConversionDict` is used - #: (for example for :attr:`cookies`). - #: - #: .. versionadded:: 0.6 - dict_storage_class = ImmutableTypeConversionDict - - #: The form data parser that shoud be used. Can be replaced to customize - #: the form date parsing. - form_data_parser_class = FormDataParser - - #: Optionally a list of hosts that is trusted by this request. By default - #: all hosts are trusted which means that whatever the client sends the - #: host is will be accepted. - #: - #: This is the recommended setup as a webserver should manually be set up - #: to only route correct hosts to the application, and remove the - #: `X-Forwarded-Host` header if it is not being used (see - #: :func:`werkzeug.wsgi.get_host`). - #: - #: .. versionadded:: 0.9 - trusted_hosts = None - - #: Indicates whether the data descriptor should be allowed to read and - #: buffer up the input stream. By default it's enabled. - #: - #: .. versionadded:: 0.9 - disable_data_descriptor = False - - def __init__(self, environ, populate_request=True, shallow=False): - self.environ = environ - if populate_request and not shallow: - self.environ['werkzeug.request'] = self - self.shallow = shallow - - def __repr__(self): - # make sure the __repr__ even works if the request was created - # from an invalid WSGI environment. If we display the request - # in a debug session we don't want the repr to blow up. - args = [] - try: - args.append("'%s'" % to_native(self.url, self.url_charset)) - args.append('[%s]' % self.method) - except Exception: - args.append('(invalid WSGI environ)') - - return '<%s %s>' % ( - self.__class__.__name__, - ' '.join(args) - ) - - @property - def url_charset(self): - """The charset that is assumed for URLs. Defaults to the value - of :attr:`charset`. - - .. versionadded:: 0.6 - """ - return self.charset - - @classmethod - def from_values(cls, *args, **kwargs): - """Create a new request object based on the values provided. If - environ is given missing values are filled from there. This method is - useful for small scripts when you need to simulate a request from an URL. - Do not use this method for unittesting, there is a full featured client - object (:class:`Client`) that allows to create multipart requests, - support for cookies etc. - - This accepts the same options as the - :class:`~werkzeug.test.EnvironBuilder`. - - .. versionchanged:: 0.5 - This method now accepts the same arguments as - :class:`~werkzeug.test.EnvironBuilder`. Because of this the - `environ` parameter is now called `environ_overrides`. - - :return: request object - """ - from werkzeug.test import EnvironBuilder - charset = kwargs.pop('charset', cls.charset) - kwargs['charset'] = charset - builder = EnvironBuilder(*args, **kwargs) - try: - return builder.get_request(cls) - finally: - builder.close() - - @classmethod - def application(cls, f): - """Decorate a function as responder that accepts the request as first - argument. This works like the :func:`responder` decorator but the - function is passed the request object as first argument and the - request object will be closed automatically:: - - @Request.application - def my_wsgi_app(request): - return Response('Hello World!') - - As of Werkzeug 0.14 HTTP exceptions are automatically caught and - converted to responses instead of failing. - - :param f: the WSGI callable to decorate - :return: a new WSGI callable - """ - #: return a callable that wraps the -2nd argument with the request - #: and calls the function with all the arguments up to that one and - #: the request. The return value is then called with the latest - #: two arguments. This makes it possible to use this decorator for - #: both methods and standalone WSGI functions. - from werkzeug.exceptions import HTTPException - - def application(*args): - request = cls(args[-2]) - with request: - try: - resp = f(*args[:-2] + (request,)) - except HTTPException as e: - resp = e.get_response(args[-2]) - return resp(*args[-2:]) - - return update_wrapper(application, f) - - def _get_file_stream(self, total_content_length, content_type, filename=None, - content_length=None): - """Called to get a stream for the file upload. - - This must provide a file-like class with `read()`, `readline()` - and `seek()` methods that is both writeable and readable. - - The default implementation returns a temporary file if the total - content length is higher than 500KB. Because many browsers do not - provide a content length for the files only the total content - length matters. - - :param total_content_length: the total content length of all the - data in the request combined. This value - is guaranteed to be there. - :param content_type: the mimetype of the uploaded file. - :param filename: the filename of the uploaded file. May be `None`. - :param content_length: the length of this file. This value is usually - not provided because webbrowsers do not provide - this value. - """ - return default_stream_factory( - total_content_length=total_content_length, - content_type=content_type, - filename=filename, - content_length=content_length) - - @property - def want_form_data_parsed(self): - """Returns True if the request method carries content. As of - Werkzeug 0.9 this will be the case if a content type is transmitted. - - .. versionadded:: 0.8 - """ - return bool(self.environ.get('CONTENT_TYPE')) - - def make_form_data_parser(self): - """Creates the form data parser. Instantiates the - :attr:`form_data_parser_class` with some parameters. - - .. versionadded:: 0.8 - """ - return self.form_data_parser_class(self._get_file_stream, - self.charset, - self.encoding_errors, - self.max_form_memory_size, - self.max_content_length, - self.parameter_storage_class) - - def _load_form_data(self): - """Method used internally to retrieve submitted data. After calling - this sets `form` and `files` on the request object to multi dicts - filled with the incoming form data. As a matter of fact the input - stream will be empty afterwards. You can also call this method to - force the parsing of the form data. - - .. versionadded:: 0.8 - """ - # abort early if we have already consumed the stream - if 'form' in self.__dict__: - return - - _assert_not_shallow(self) - - if self.want_form_data_parsed: - content_type = self.environ.get('CONTENT_TYPE', '') - content_length = get_content_length(self.environ) - mimetype, options = parse_options_header(content_type) - parser = self.make_form_data_parser() - data = parser.parse(self._get_stream_for_parsing(), - mimetype, content_length, options) - else: - data = (self.stream, self.parameter_storage_class(), - self.parameter_storage_class()) - - # inject the values into the instance dict so that we bypass - # our cached_property non-data descriptor. - d = self.__dict__ - d['stream'], d['form'], d['files'] = data - - def _get_stream_for_parsing(self): - """This is the same as accessing :attr:`stream` with the difference - that if it finds cached data from calling :meth:`get_data` first it - will create a new stream out of the cached data. - - .. versionadded:: 0.9.3 - """ - cached_data = getattr(self, '_cached_data', None) - if cached_data is not None: - return BytesIO(cached_data) - return self.stream - - def close(self): - """Closes associated resources of this request object. This - closes all file handles explicitly. You can also use the request - object in a with statement which will automatically close it. - - .. versionadded:: 0.9 - """ - files = self.__dict__.get('files') - for key, value in iter_multi_items(files or ()): - value.close() - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, tb): - self.close() - - @cached_property - def stream(self): - """ - If the incoming form data was not encoded with a known mimetype - the data is stored unmodified in this stream for consumption. Most - of the time it is a better idea to use :attr:`data` which will give - you that data as a string. The stream only returns the data once. - - Unlike :attr:`input_stream` this stream is properly guarded that you - can't accidentally read past the length of the input. Werkzeug will - internally always refer to this stream to read data which makes it - possible to wrap this object with a stream that does filtering. - - .. versionchanged:: 0.9 - This stream is now always available but might be consumed by the - form parser later on. Previously the stream was only set if no - parsing happened. - """ - _assert_not_shallow(self) - return get_input_stream(self.environ) - - input_stream = environ_property('wsgi.input', """ - The WSGI input stream. - - In general it's a bad idea to use this one because you can easily read past - the boundary. Use the :attr:`stream` instead. - """) - - @cached_property - def args(self): - """The parsed URL parameters (the part in the URL after the question - mark). - - By default an - :class:`~werkzeug.datastructures.ImmutableMultiDict` - is returned from this function. This can be changed by setting - :attr:`parameter_storage_class` to a different type. This might - be necessary if the order of the form data is important. - """ - return url_decode(wsgi_get_bytes(self.environ.get('QUERY_STRING', '')), - self.url_charset, errors=self.encoding_errors, - cls=self.parameter_storage_class) - - @cached_property - def data(self): - """ - Contains the incoming request data as string in case it came with - a mimetype Werkzeug does not handle. - """ - - if self.disable_data_descriptor: - raise AttributeError('data descriptor is disabled') - # XXX: this should eventually be deprecated. - - # We trigger form data parsing first which means that the descriptor - # will not cache the data that would otherwise be .form or .files - # data. This restores the behavior that was there in Werkzeug - # before 0.9. New code should use :meth:`get_data` explicitly as - # this will make behavior explicit. - return self.get_data(parse_form_data=True) - - def get_data(self, cache=True, as_text=False, parse_form_data=False): - """This reads the buffered incoming data from the client into one - bytestring. By default this is cached but that behavior can be - changed by setting `cache` to `False`. - - Usually it's a bad idea to call this method without checking the - content length first as a client could send dozens of megabytes or more - to cause memory problems on the server. - - Note that if the form data was already parsed this method will not - return anything as form data parsing does not cache the data like - this method does. To implicitly invoke form data parsing function - set `parse_form_data` to `True`. When this is done the return value - of this method will be an empty string if the form parser handles - the data. This generally is not necessary as if the whole data is - cached (which is the default) the form parser will used the cached - data to parse the form data. Please be generally aware of checking - the content length first in any case before calling this method - to avoid exhausting server memory. - - If `as_text` is set to `True` the return value will be a decoded - unicode string. - - .. versionadded:: 0.9 - """ - rv = getattr(self, '_cached_data', None) - if rv is None: - if parse_form_data: - self._load_form_data() - rv = self.stream.read() - if cache: - self._cached_data = rv - if as_text: - rv = rv.decode(self.charset, self.encoding_errors) - return rv - - @cached_property - def form(self): - """The form parameters. By default an - :class:`~werkzeug.datastructures.ImmutableMultiDict` - is returned from this function. This can be changed by setting - :attr:`parameter_storage_class` to a different type. This might - be necessary if the order of the form data is important. - - Please keep in mind that file uploads will not end up here, but instead - in the :attr:`files` attribute. - - .. versionchanged:: 0.9 - - Previous to Werkzeug 0.9 this would only contain form data for POST - and PUT requests. - """ - self._load_form_data() - return self.form - - @cached_property - def values(self): - """A :class:`werkzeug.datastructures.CombinedMultiDict` that combines - :attr:`args` and :attr:`form`.""" - args = [] - for d in self.args, self.form: - if not isinstance(d, MultiDict): - d = MultiDict(d) - args.append(d) - return CombinedMultiDict(args) - - @cached_property - def files(self): - """:class:`~werkzeug.datastructures.MultiDict` object containing - all uploaded files. Each key in :attr:`files` is the name from the - ````. Each value in :attr:`files` is a - Werkzeug :class:`~werkzeug.datastructures.FileStorage` object. - - It basically behaves like a standard file object you know from Python, - with the difference that it also has a - :meth:`~werkzeug.datastructures.FileStorage.save` function that can - store the file on the filesystem. - - Note that :attr:`files` will only contain data if the request method was - POST, PUT or PATCH and the ``

    `` that posted to the request had - ``enctype="multipart/form-data"``. It will be empty otherwise. - - See the :class:`~werkzeug.datastructures.MultiDict` / - :class:`~werkzeug.datastructures.FileStorage` documentation for - more details about the used data structure. - """ - self._load_form_data() - return self.files - - @cached_property - def cookies(self): - """A :class:`dict` with the contents of all cookies transmitted with - the request.""" - return parse_cookie(self.environ, self.charset, - self.encoding_errors, - cls=self.dict_storage_class) - - @cached_property - def headers(self): - """The headers from the WSGI environ as immutable - :class:`~werkzeug.datastructures.EnvironHeaders`. - """ - return EnvironHeaders(self.environ) - - @cached_property - def path(self): - """Requested path as unicode. This works a bit like the regular path - info in the WSGI environment but will always include a leading slash, - even if the URL root is accessed. - """ - raw_path = wsgi_decoding_dance(self.environ.get('PATH_INFO') or '', - self.charset, self.encoding_errors) - return '/' + raw_path.lstrip('/') - - @cached_property - def full_path(self): - """Requested path as unicode, including the query string.""" - return self.path + u'?' + to_unicode(self.query_string, self.url_charset) - - @cached_property - def script_root(self): - """The root path of the script without the trailing slash.""" - raw_path = wsgi_decoding_dance(self.environ.get('SCRIPT_NAME') or '', - self.charset, self.encoding_errors) - return raw_path.rstrip('/') - - @cached_property - def url(self): - """The reconstructed current URL as IRI. - See also: :attr:`trusted_hosts`. - """ - return get_current_url(self.environ, - trusted_hosts=self.trusted_hosts) - - @cached_property - def base_url(self): - """Like :attr:`url` but without the querystring - See also: :attr:`trusted_hosts`. - """ - return get_current_url(self.environ, strip_querystring=True, - trusted_hosts=self.trusted_hosts) - - @cached_property - def url_root(self): - """The full URL root (with hostname), this is the application - root as IRI. - See also: :attr:`trusted_hosts`. - """ - return get_current_url(self.environ, True, - trusted_hosts=self.trusted_hosts) - - @cached_property - def host_url(self): - """Just the host with scheme as IRI. - See also: :attr:`trusted_hosts`. - """ - return get_current_url(self.environ, host_only=True, - trusted_hosts=self.trusted_hosts) - - @cached_property - def host(self): - """Just the host including the port if available. - See also: :attr:`trusted_hosts`. - """ - return get_host(self.environ, trusted_hosts=self.trusted_hosts) - - query_string = environ_property( - 'QUERY_STRING', '', read_only=True, - load_func=wsgi_get_bytes, doc='The URL parameters as raw bytestring.') - method = environ_property( - 'REQUEST_METHOD', 'GET', read_only=True, - load_func=lambda x: x.upper(), - doc="The request method. (For example ``'GET'`` or ``'POST'``).") - - @cached_property - def access_route(self): - """If a forwarded header exists this is a list of all ip addresses - from the client ip to the last proxy server. - """ - if 'HTTP_X_FORWARDED_FOR' in self.environ: - addr = self.environ['HTTP_X_FORWARDED_FOR'].split(',') - return self.list_storage_class([x.strip() for x in addr]) - elif 'REMOTE_ADDR' in self.environ: - return self.list_storage_class([self.environ['REMOTE_ADDR']]) - return self.list_storage_class() - - @property - def remote_addr(self): - """The remote address of the client.""" - return self.environ.get('REMOTE_ADDR') - - remote_user = environ_property('REMOTE_USER', doc=''' - If the server supports user authentication, and the script is - protected, this attribute contains the username the user has - authenticated as.''') - - scheme = environ_property('wsgi.url_scheme', doc=''' - URL scheme (http or https). - - .. versionadded:: 0.7''') - - @property - def is_xhr(self): - """True if the request was triggered via a JavaScript XMLHttpRequest. - This only works with libraries that support the ``X-Requested-With`` - header and set it to "XMLHttpRequest". Libraries that do that are - prototype, jQuery and Mochikit and probably some more. - - .. deprecated:: 0.13 - ``X-Requested-With`` is not standard and is unreliable. - """ - warn(DeprecationWarning( - 'Request.is_xhr is deprecated. Given that the X-Requested-With ' - 'header is not a part of any spec, it is not reliable' - ), stacklevel=2) - return self.environ.get( - 'HTTP_X_REQUESTED_WITH', '' - ).lower() == 'xmlhttprequest' - - is_secure = property(lambda x: x.environ['wsgi.url_scheme'] == 'https', - doc='`True` if the request is secure.') - is_multithread = environ_property('wsgi.multithread', doc=''' - boolean that is `True` if the application is served by - a multithreaded WSGI server.''') - is_multiprocess = environ_property('wsgi.multiprocess', doc=''' - boolean that is `True` if the application is served by - a WSGI server that spawns multiple processes.''') - is_run_once = environ_property('wsgi.run_once', doc=''' - boolean that is `True` if the application will be executed only - once in a process lifetime. This is the case for CGI for example, - but it's not guaranteed that the execution only happens one time.''') - - -class BaseResponse(object): - - """Base response class. The most important fact about a response object - is that it's a regular WSGI application. It's initialized with a couple - of response parameters (headers, body, status code etc.) and will start a - valid WSGI response when called with the environ and start response - callable. - - Because it's a WSGI application itself processing usually ends before the - actual response is sent to the server. This helps debugging systems - because they can catch all the exceptions before responses are started. - - Here a small example WSGI application that takes advantage of the - response objects:: - - from werkzeug.wrappers import BaseResponse as Response - - def index(): - return Response('Index page') - - def application(environ, start_response): - path = environ.get('PATH_INFO') or '/' - if path == '/': - response = index() - else: - response = Response('Not Found', status=404) - return response(environ, start_response) - - Like :class:`BaseRequest` which object is lacking a lot of functionality - implemented in mixins. This gives you a better control about the actual - API of your response objects, so you can create subclasses and add custom - functionality. A full featured response object is available as - :class:`Response` which implements a couple of useful mixins. - - To enforce a new type of already existing responses you can use the - :meth:`force_type` method. This is useful if you're working with different - subclasses of response objects and you want to post process them with a - known interface. - - Per default the response object will assume all the text data is `utf-8` - encoded. Please refer to `the unicode chapter `_ for more - details about customizing the behavior. - - Response can be any kind of iterable or string. If it's a string it's - considered being an iterable with one item which is the string passed. - Headers can be a list of tuples or a - :class:`~werkzeug.datastructures.Headers` object. - - Special note for `mimetype` and `content_type`: For most mime types - `mimetype` and `content_type` work the same, the difference affects - only 'text' mimetypes. If the mimetype passed with `mimetype` is a - mimetype starting with `text/`, the charset parameter of the response - object is appended to it. In contrast the `content_type` parameter is - always added as header unmodified. - - .. versionchanged:: 0.5 - the `direct_passthrough` parameter was added. - - :param response: a string or response iterable. - :param status: a string with a status or an integer with the status code. - :param headers: a list of headers or a - :class:`~werkzeug.datastructures.Headers` object. - :param mimetype: the mimetype for the response. See notice above. - :param content_type: the content type for the response. See notice above. - :param direct_passthrough: if set to `True` :meth:`iter_encoded` is not - called before iteration which makes it - possible to pass special iterators through - unchanged (see :func:`wrap_file` for more - details.) - """ - - #: the charset of the response. - charset = 'utf-8' - - #: the default status if none is provided. - default_status = 200 - - #: the default mimetype if none is provided. - default_mimetype = 'text/plain' - - #: if set to `False` accessing properties on the response object will - #: not try to consume the response iterator and convert it into a list. - #: - #: .. versionadded:: 0.6.2 - #: - #: That attribute was previously called `implicit_seqence_conversion`. - #: (Notice the typo). If you did use this feature, you have to adapt - #: your code to the name change. - implicit_sequence_conversion = True - - #: Should this response object correct the location header to be RFC - #: conformant? This is true by default. - #: - #: .. versionadded:: 0.8 - autocorrect_location_header = True - - #: Should this response object automatically set the content-length - #: header if possible? This is true by default. - #: - #: .. versionadded:: 0.8 - automatically_set_content_length = True - - #: Warn if a cookie header exceeds this size. The default, 4093, should be - #: safely `supported by most browsers `_. A cookie larger than - #: this size will still be sent, but it may be ignored or handled - #: incorrectly by some browsers. Set to 0 to disable this check. - #: - #: .. versionadded:: 0.13 - #: - #: .. _`cookie`: http://browsercookielimits.squawky.net/ - max_cookie_size = 4093 - - def __init__(self, response=None, status=None, headers=None, - mimetype=None, content_type=None, direct_passthrough=False): - if isinstance(headers, Headers): - self.headers = headers - elif not headers: - self.headers = Headers() - else: - self.headers = Headers(headers) - - if content_type is None: - if mimetype is None and 'content-type' not in self.headers: - mimetype = self.default_mimetype - if mimetype is not None: - mimetype = get_content_type(mimetype, self.charset) - content_type = mimetype - if content_type is not None: - self.headers['Content-Type'] = content_type - if status is None: - status = self.default_status - if isinstance(status, integer_types): - self.status_code = status - else: - self.status = status - - self.direct_passthrough = direct_passthrough - self._on_close = [] - - # we set the response after the headers so that if a class changes - # the charset attribute, the data is set in the correct charset. - if response is None: - self.response = [] - elif isinstance(response, (text_type, bytes, bytearray)): - self.set_data(response) - else: - self.response = response - - def call_on_close(self, func): - """Adds a function to the internal list of functions that should - be called as part of closing down the response. Since 0.7 this - function also returns the function that was passed so that this - can be used as a decorator. - - .. versionadded:: 0.6 - """ - self._on_close.append(func) - return func - - def __repr__(self): - if self.is_sequence: - body_info = '%d bytes' % sum(map(len, self.iter_encoded())) - else: - body_info = 'streamed' if self.is_streamed else 'likely-streamed' - return '<%s %s [%s]>' % ( - self.__class__.__name__, - body_info, - self.status - ) - - @classmethod - def force_type(cls, response, environ=None): - """Enforce that the WSGI response is a response object of the current - type. Werkzeug will use the :class:`BaseResponse` internally in many - situations like the exceptions. If you call :meth:`get_response` on an - exception you will get back a regular :class:`BaseResponse` object, even - if you are using a custom subclass. - - This method can enforce a given response type, and it will also - convert arbitrary WSGI callables into response objects if an environ - is provided:: - - # convert a Werkzeug response object into an instance of the - # MyResponseClass subclass. - response = MyResponseClass.force_type(response) - - # convert any WSGI application into a response object - response = MyResponseClass.force_type(response, environ) - - This is especially useful if you want to post-process responses in - the main dispatcher and use functionality provided by your subclass. - - Keep in mind that this will modify response objects in place if - possible! - - :param response: a response object or wsgi application. - :param environ: a WSGI environment object. - :return: a response object. - """ - if not isinstance(response, BaseResponse): - if environ is None: - raise TypeError('cannot convert WSGI application into ' - 'response objects without an environ') - response = BaseResponse(*_run_wsgi_app(response, environ)) - response.__class__ = cls - return response - - @classmethod - def from_app(cls, app, environ, buffered=False): - """Create a new response object from an application output. This - works best if you pass it an application that returns a generator all - the time. Sometimes applications may use the `write()` callable - returned by the `start_response` function. This tries to resolve such - edge cases automatically. But if you don't get the expected output - you should set `buffered` to `True` which enforces buffering. - - :param app: the WSGI application to execute. - :param environ: the WSGI environment to execute against. - :param buffered: set to `True` to enforce buffering. - :return: a response object. - """ - return cls(*_run_wsgi_app(app, environ, buffered)) - - def _get_status_code(self): - return self._status_code - - def _set_status_code(self, code): - self._status_code = code - try: - self._status = '%d %s' % (code, HTTP_STATUS_CODES[code].upper()) - except KeyError: - self._status = '%d UNKNOWN' % code - status_code = property(_get_status_code, _set_status_code, - doc='The HTTP Status code as number') - del _get_status_code, _set_status_code - - def _get_status(self): - return self._status - - def _set_status(self, value): - try: - self._status = to_native(value) - except AttributeError: - raise TypeError('Invalid status argument') - - try: - self._status_code = int(self._status.split(None, 1)[0]) - except ValueError: - self._status_code = 0 - self._status = '0 %s' % self._status - except IndexError: - raise ValueError('Empty status argument') - status = property(_get_status, _set_status, doc='The HTTP Status code') - del _get_status, _set_status - - def get_data(self, as_text=False): - """The string representation of the request body. Whenever you call - this property the request iterable is encoded and flattened. This - can lead to unwanted behavior if you stream big data. - - This behavior can be disabled by setting - :attr:`implicit_sequence_conversion` to `False`. - - If `as_text` is set to `True` the return value will be a decoded - unicode string. - - .. versionadded:: 0.9 - """ - self._ensure_sequence() - rv = b''.join(self.iter_encoded()) - if as_text: - rv = rv.decode(self.charset) - return rv - - def set_data(self, value): - """Sets a new string as response. The value set must either by a - unicode or bytestring. If a unicode string is set it's encoded - automatically to the charset of the response (utf-8 by default). - - .. versionadded:: 0.9 - """ - # if an unicode string is set, it's encoded directly so that we - # can set the content length - if isinstance(value, text_type): - value = value.encode(self.charset) - else: - value = bytes(value) - self.response = [value] - if self.automatically_set_content_length: - self.headers['Content-Length'] = str(len(value)) - - data = property(get_data, set_data, doc=''' - A descriptor that calls :meth:`get_data` and :meth:`set_data`. This - should not be used and will eventually get deprecated. - ''') - - def calculate_content_length(self): - """Returns the content length if available or `None` otherwise.""" - try: - self._ensure_sequence() - except RuntimeError: - return None - return sum(len(x) for x in self.iter_encoded()) - - def _ensure_sequence(self, mutable=False): - """This method can be called by methods that need a sequence. If - `mutable` is true, it will also ensure that the response sequence - is a standard Python list. - - .. versionadded:: 0.6 - """ - if self.is_sequence: - # if we need a mutable object, we ensure it's a list. - if mutable and not isinstance(self.response, list): - self.response = list(self.response) - return - if self.direct_passthrough: - raise RuntimeError('Attempted implicit sequence conversion ' - 'but the response object is in direct ' - 'passthrough mode.') - if not self.implicit_sequence_conversion: - raise RuntimeError('The response object required the iterable ' - 'to be a sequence, but the implicit ' - 'conversion was disabled. Call ' - 'make_sequence() yourself.') - self.make_sequence() - - def make_sequence(self): - """Converts the response iterator in a list. By default this happens - automatically if required. If `implicit_sequence_conversion` is - disabled, this method is not automatically called and some properties - might raise exceptions. This also encodes all the items. - - .. versionadded:: 0.6 - """ - if not self.is_sequence: - # if we consume an iterable we have to ensure that the close - # method of the iterable is called if available when we tear - # down the response - close = getattr(self.response, 'close', None) - self.response = list(self.iter_encoded()) - if close is not None: - self.call_on_close(close) - - def iter_encoded(self): - """Iter the response encoded with the encoding of the response. - If the response object is invoked as WSGI application the return - value of this method is used as application iterator unless - :attr:`direct_passthrough` was activated. - """ - if __debug__: - _warn_if_string(self.response) - # Encode in a separate function so that self.response is fetched - # early. This allows us to wrap the response with the return - # value from get_app_iter or iter_encoded. - return _iter_encoded(self.response, self.charset) - - def set_cookie(self, key, value='', max_age=None, expires=None, - path='/', domain=None, secure=False, httponly=False, - samesite=None): - """Sets a cookie. The parameters are the same as in the cookie `Morsel` - object in the Python standard library but it accepts unicode data, too. - - A warning is raised if the size of the cookie header exceeds - :attr:`max_cookie_size`, but the header will still be set. - - :param key: the key (name) of the cookie to be set. - :param value: the value of the cookie. - :param max_age: should be a number of seconds, or `None` (default) if - the cookie should last only as long as the client's - browser session. - :param expires: should be a `datetime` object or UNIX timestamp. - :param path: limits the cookie to a given path, per default it will - span the whole domain. - :param domain: if you want to set a cross-domain cookie. For example, - ``domain=".example.com"`` will set a cookie that is - readable by the domain ``www.example.com``, - ``foo.example.com`` etc. Otherwise, a cookie will only - be readable by the domain that set it. - :param secure: If `True`, the cookie will only be available via HTTPS - :param httponly: disallow JavaScript to access the cookie. This is an - extension to the cookie standard and probably not - supported by all browsers. - :param samesite: Limits the scope of the cookie such that it will only - be attached to requests if those requests are - "same-site". - """ - self.headers.add('Set-Cookie', dump_cookie( - key, - value=value, - max_age=max_age, - expires=expires, - path=path, - domain=domain, - secure=secure, - httponly=httponly, - charset=self.charset, - max_size=self.max_cookie_size, - samesite=samesite - )) - - def delete_cookie(self, key, path='/', domain=None): - """Delete a cookie. Fails silently if key doesn't exist. - - :param key: the key (name) of the cookie to be deleted. - :param path: if the cookie that should be deleted was limited to a - path, the path has to be defined here. - :param domain: if the cookie that should be deleted was limited to a - domain, that domain has to be defined here. - """ - self.set_cookie(key, expires=0, max_age=0, path=path, domain=domain) - - @property - def is_streamed(self): - """If the response is streamed (the response is not an iterable with - a length information) this property is `True`. In this case streamed - means that there is no information about the number of iterations. - This is usually `True` if a generator is passed to the response object. - - This is useful for checking before applying some sort of post - filtering that should not take place for streamed responses. - """ - try: - len(self.response) - except (TypeError, AttributeError): - return True - return False - - @property - def is_sequence(self): - """If the iterator is buffered, this property will be `True`. A - response object will consider an iterator to be buffered if the - response attribute is a list or tuple. - - .. versionadded:: 0.6 - """ - return isinstance(self.response, (tuple, list)) - - def close(self): - """Close the wrapped response if possible. You can also use the object - in a with statement which will automatically close it. - - .. versionadded:: 0.9 - Can now be used in a with statement. - """ - if hasattr(self.response, 'close'): - self.response.close() - for func in self._on_close: - func() - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, tb): - self.close() - - def freeze(self): - """Call this method if you want to make your response object ready for - being pickled. This buffers the generator if there is one. It will - also set the `Content-Length` header to the length of the body. - - .. versionchanged:: 0.6 - The `Content-Length` header is now set. - """ - # we explicitly set the length to a list of the *encoded* response - # iterator. Even if the implicit sequence conversion is disabled. - self.response = list(self.iter_encoded()) - self.headers['Content-Length'] = str(sum(map(len, self.response))) - - def get_wsgi_headers(self, environ): - """This is automatically called right before the response is started - and returns headers modified for the given environment. It returns a - copy of the headers from the response with some modifications applied - if necessary. - - For example the location header (if present) is joined with the root - URL of the environment. Also the content length is automatically set - to zero here for certain status codes. - - .. versionchanged:: 0.6 - Previously that function was called `fix_headers` and modified - the response object in place. Also since 0.6, IRIs in location - and content-location headers are handled properly. - - Also starting with 0.6, Werkzeug will attempt to set the content - length if it is able to figure it out on its own. This is the - case if all the strings in the response iterable are already - encoded and the iterable is buffered. - - :param environ: the WSGI environment of the request. - :return: returns a new :class:`~werkzeug.datastructures.Headers` - object. - """ - headers = Headers(self.headers) - location = None - content_location = None - content_length = None - status = self.status_code - - # iterate over the headers to find all values in one go. Because - # get_wsgi_headers is used each response that gives us a tiny - # speedup. - for key, value in headers: - ikey = key.lower() - if ikey == u'location': - location = value - elif ikey == u'content-location': - content_location = value - elif ikey == u'content-length': - content_length = value - - # make sure the location header is an absolute URL - if location is not None: - old_location = location - if isinstance(location, text_type): - # Safe conversion is necessary here as we might redirect - # to a broken URI scheme (for instance itms-services). - location = iri_to_uri(location, safe_conversion=True) - - if self.autocorrect_location_header: - current_url = get_current_url(environ, root_only=True) - if isinstance(current_url, text_type): - current_url = iri_to_uri(current_url) - location = url_join(current_url, location) - if location != old_location: - headers['Location'] = location - - # make sure the content location is a URL - if content_location is not None and \ - isinstance(content_location, text_type): - headers['Content-Location'] = iri_to_uri(content_location) - - if status in (304, 412): - remove_entity_headers(headers) - - # if we can determine the content length automatically, we - # should try to do that. But only if this does not involve - # flattening the iterator or encoding of unicode strings in - # the response. We however should not do that if we have a 304 - # response. - if self.automatically_set_content_length and \ - self.is_sequence and content_length is None and \ - status not in (204, 304) and \ - not (100 <= status < 200): - try: - content_length = sum(len(to_bytes(x, 'ascii')) - for x in self.response) - except UnicodeError: - # aha, something non-bytestringy in there, too bad, we - # can't safely figure out the length of the response. - pass - else: - headers['Content-Length'] = str(content_length) - - return headers - - def get_app_iter(self, environ): - """Returns the application iterator for the given environ. Depending - on the request method and the current status code the return value - might be an empty response rather than the one from the response. - - If the request method is `HEAD` or the status code is in a range - where the HTTP specification requires an empty response, an empty - iterable is returned. - - .. versionadded:: 0.6 - - :param environ: the WSGI environment of the request. - :return: a response iterable. - """ - status = self.status_code - if environ['REQUEST_METHOD'] == 'HEAD' or \ - 100 <= status < 200 or status in (204, 304, 412): - iterable = () - elif self.direct_passthrough: - if __debug__: - _warn_if_string(self.response) - return self.response - else: - iterable = self.iter_encoded() - return ClosingIterator(iterable, self.close) - - def get_wsgi_response(self, environ): - """Returns the final WSGI response as tuple. The first item in - the tuple is the application iterator, the second the status and - the third the list of headers. The response returned is created - specially for the given environment. For example if the request - method in the WSGI environment is ``'HEAD'`` the response will - be empty and only the headers and status code will be present. - - .. versionadded:: 0.6 - - :param environ: the WSGI environment of the request. - :return: an ``(app_iter, status, headers)`` tuple. - """ - headers = self.get_wsgi_headers(environ) - app_iter = self.get_app_iter(environ) - return app_iter, self.status, headers.to_wsgi_list() - - def __call__(self, environ, start_response): - """Process this response as WSGI application. - - :param environ: the WSGI environment. - :param start_response: the response callable provided by the WSGI - server. - :return: an application iterator - """ - app_iter, status, headers = self.get_wsgi_response(environ) - start_response(status, headers) - return app_iter - - -class AcceptMixin(object): - - """A mixin for classes with an :attr:`~BaseResponse.environ` attribute - to get all the HTTP accept headers as - :class:`~werkzeug.datastructures.Accept` objects (or subclasses - thereof). - """ - - @cached_property - def accept_mimetypes(self): - """List of mimetypes this client supports as - :class:`~werkzeug.datastructures.MIMEAccept` object. - """ - return parse_accept_header(self.environ.get('HTTP_ACCEPT'), MIMEAccept) - - @cached_property - def accept_charsets(self): - """List of charsets this client supports as - :class:`~werkzeug.datastructures.CharsetAccept` object. - """ - return parse_accept_header(self.environ.get('HTTP_ACCEPT_CHARSET'), - CharsetAccept) - - @cached_property - def accept_encodings(self): - """List of encodings this client accepts. Encodings in a HTTP term - are compression encodings such as gzip. For charsets have a look at - :attr:`accept_charset`. - """ - return parse_accept_header(self.environ.get('HTTP_ACCEPT_ENCODING')) - - @cached_property - def accept_languages(self): - """List of languages this client accepts as - :class:`~werkzeug.datastructures.LanguageAccept` object. - - .. versionchanged 0.5 - In previous versions this was a regular - :class:`~werkzeug.datastructures.Accept` object. - """ - return parse_accept_header(self.environ.get('HTTP_ACCEPT_LANGUAGE'), - LanguageAccept) - - -class ETagRequestMixin(object): - - """Add entity tag and cache descriptors to a request object or object with - a WSGI environment available as :attr:`~BaseRequest.environ`. This not - only provides access to etags but also to the cache control header. - """ - - @cached_property - def cache_control(self): - """A :class:`~werkzeug.datastructures.RequestCacheControl` object - for the incoming cache control headers. - """ - cache_control = self.environ.get('HTTP_CACHE_CONTROL') - return parse_cache_control_header(cache_control, None, - RequestCacheControl) - - @cached_property - def if_match(self): - """An object containing all the etags in the `If-Match` header. - - :rtype: :class:`~werkzeug.datastructures.ETags` - """ - return parse_etags(self.environ.get('HTTP_IF_MATCH')) - - @cached_property - def if_none_match(self): - """An object containing all the etags in the `If-None-Match` header. - - :rtype: :class:`~werkzeug.datastructures.ETags` - """ - return parse_etags(self.environ.get('HTTP_IF_NONE_MATCH')) - - @cached_property - def if_modified_since(self): - """The parsed `If-Modified-Since` header as datetime object.""" - return parse_date(self.environ.get('HTTP_IF_MODIFIED_SINCE')) - - @cached_property - def if_unmodified_since(self): - """The parsed `If-Unmodified-Since` header as datetime object.""" - return parse_date(self.environ.get('HTTP_IF_UNMODIFIED_SINCE')) - - @cached_property - def if_range(self): - """The parsed `If-Range` header. - - .. versionadded:: 0.7 - - :rtype: :class:`~werkzeug.datastructures.IfRange` - """ - return parse_if_range_header(self.environ.get('HTTP_IF_RANGE')) - - @cached_property - def range(self): - """The parsed `Range` header. - - .. versionadded:: 0.7 - - :rtype: :class:`~werkzeug.datastructures.Range` - """ - return parse_range_header(self.environ.get('HTTP_RANGE')) - - -class UserAgentMixin(object): - - """Adds a `user_agent` attribute to the request object which contains the - parsed user agent of the browser that triggered the request as a - :class:`~werkzeug.useragents.UserAgent` object. - """ - - @cached_property - def user_agent(self): - """The current user agent.""" - from werkzeug.useragents import UserAgent - return UserAgent(self.environ) - - -class AuthorizationMixin(object): - - """Adds an :attr:`authorization` property that represents the parsed - value of the `Authorization` header as - :class:`~werkzeug.datastructures.Authorization` object. - """ - - @cached_property - def authorization(self): - """The `Authorization` object in parsed form.""" - header = self.environ.get('HTTP_AUTHORIZATION') - return parse_authorization_header(header) - - -class StreamOnlyMixin(object): - - """If mixed in before the request object this will change the bahavior - of it to disable handling of form parsing. This disables the - :attr:`files`, :attr:`form` attributes and will just provide a - :attr:`stream` attribute that however is always available. - - .. versionadded:: 0.9 - """ - - disable_data_descriptor = True - want_form_data_parsed = False - - -class ETagResponseMixin(object): - - """Adds extra functionality to a response object for etag and cache - handling. This mixin requires an object with at least a `headers` - object that implements a dict like interface similar to - :class:`~werkzeug.datastructures.Headers`. - - If you want the :meth:`freeze` method to automatically add an etag, you - have to mixin this method before the response base class. The default - response class does not do that. - """ - - @property - def cache_control(self): - """The Cache-Control general-header field is used to specify - directives that MUST be obeyed by all caching mechanisms along the - request/response chain. - """ - def on_update(cache_control): - if not cache_control and 'cache-control' in self.headers: - del self.headers['cache-control'] - elif cache_control: - self.headers['Cache-Control'] = cache_control.to_header() - return parse_cache_control_header(self.headers.get('cache-control'), - on_update, - ResponseCacheControl) - - def _wrap_response(self, start, length): - """Wrap existing Response in case of Range Request context.""" - if self.status_code == 206: - self.response = _RangeWrapper(self.response, start, length) - - def _is_range_request_processable(self, environ): - """Return ``True`` if `Range` header is present and if underlying - resource is considered unchanged when compared with `If-Range` header. - """ - return ( - 'HTTP_IF_RANGE' not in environ - or not is_resource_modified( - environ, self.headers.get('etag'), None, - self.headers.get('last-modified'), ignore_if_range=False - ) - ) and 'HTTP_RANGE' in environ - - def _process_range_request(self, environ, complete_length=None, accept_ranges=None): - """Handle Range Request related headers (RFC7233). If `Accept-Ranges` - header is valid, and Range Request is processable, we set the headers - as described by the RFC, and wrap the underlying response in a - RangeWrapper. - - Returns ``True`` if Range Request can be fulfilled, ``False`` otherwise. - - :raises: :class:`~werkzeug.exceptions.RequestedRangeNotSatisfiable` - if `Range` header could not be parsed or satisfied. - """ - from werkzeug.exceptions import RequestedRangeNotSatisfiable - if accept_ranges is None: - return False - self.headers['Accept-Ranges'] = accept_ranges - if not self._is_range_request_processable(environ) or complete_length is None: - return False - parsed_range = parse_range_header(environ.get('HTTP_RANGE')) - if parsed_range is None: - raise RequestedRangeNotSatisfiable(complete_length) - range_tuple = parsed_range.range_for_length(complete_length) - content_range_header = parsed_range.to_content_range_header(complete_length) - if range_tuple is None or content_range_header is None: - raise RequestedRangeNotSatisfiable(complete_length) - content_length = range_tuple[1] - range_tuple[0] - # Be sure not to send 206 response - # if requested range is the full content. - if content_length != complete_length: - self.headers['Content-Length'] = content_length - self.content_range = content_range_header - self.status_code = 206 - self._wrap_response(range_tuple[0], content_length) - return True - return False - - def make_conditional(self, request_or_environ, accept_ranges=False, - complete_length=None): - """Make the response conditional to the request. This method works - best if an etag was defined for the response already. The `add_etag` - method can be used to do that. If called without etag just the date - header is set. - - This does nothing if the request method in the request or environ is - anything but GET or HEAD. - - For optimal performance when handling range requests, it's recommended - that your response data object implements `seekable`, `seek` and `tell` - methods as described by :py:class:`io.IOBase`. Objects returned by - :meth:`~werkzeug.wsgi.wrap_file` automatically implement those methods. - - It does not remove the body of the response because that's something - the :meth:`__call__` function does for us automatically. - - Returns self so that you can do ``return resp.make_conditional(req)`` - but modifies the object in-place. - - :param request_or_environ: a request object or WSGI environment to be - used to make the response conditional - against. - :param accept_ranges: This parameter dictates the value of - `Accept-Ranges` header. If ``False`` (default), - the header is not set. If ``True``, it will be set - to ``"bytes"``. If ``None``, it will be set to - ``"none"``. If it's a string, it will use this - value. - :param complete_length: Will be used only in valid Range Requests. - It will set `Content-Range` complete length - value and compute `Content-Length` real value. - This parameter is mandatory for successful - Range Requests completion. - :raises: :class:`~werkzeug.exceptions.RequestedRangeNotSatisfiable` - if `Range` header could not be parsed or satisfied. - """ - environ = _get_environ(request_or_environ) - if environ['REQUEST_METHOD'] in ('GET', 'HEAD'): - # if the date is not in the headers, add it now. We however - # will not override an already existing header. Unfortunately - # this header will be overriden by many WSGI servers including - # wsgiref. - if 'date' not in self.headers: - self.headers['Date'] = http_date() - accept_ranges = _clean_accept_ranges(accept_ranges) - is206 = self._process_range_request(environ, complete_length, accept_ranges) - if not is206 and not is_resource_modified( - environ, self.headers.get('etag'), None, - self.headers.get('last-modified') - ): - if parse_etags(environ.get('HTTP_IF_MATCH')): - self.status_code = 412 - else: - self.status_code = 304 - if self.automatically_set_content_length and 'content-length' not in self.headers: - length = self.calculate_content_length() - if length is not None: - self.headers['Content-Length'] = length - return self - - def add_etag(self, overwrite=False, weak=False): - """Add an etag for the current response if there is none yet.""" - if overwrite or 'etag' not in self.headers: - self.set_etag(generate_etag(self.get_data()), weak) - - def set_etag(self, etag, weak=False): - """Set the etag, and override the old one if there was one.""" - self.headers['ETag'] = quote_etag(etag, weak) - - def get_etag(self): - """Return a tuple in the form ``(etag, is_weak)``. If there is no - ETag the return value is ``(None, None)``. - """ - return unquote_etag(self.headers.get('ETag')) - - def freeze(self, no_etag=False): - """Call this method if you want to make your response object ready for - pickeling. This buffers the generator if there is one. This also - sets the etag unless `no_etag` is set to `True`. - """ - if not no_etag: - self.add_etag() - super(ETagResponseMixin, self).freeze() - - accept_ranges = header_property('Accept-Ranges', doc=''' - The `Accept-Ranges` header. Even though the name would indicate - that multiple values are supported, it must be one string token only. - - The values ``'bytes'`` and ``'none'`` are common. - - .. versionadded:: 0.7''') - - def _get_content_range(self): - def on_update(rng): - if not rng: - del self.headers['content-range'] - else: - self.headers['Content-Range'] = rng.to_header() - rv = parse_content_range_header(self.headers.get('content-range'), - on_update) - # always provide a content range object to make the descriptor - # more user friendly. It provides an unset() method that can be - # used to remove the header quickly. - if rv is None: - rv = ContentRange(None, None, None, on_update=on_update) - return rv - - def _set_content_range(self, value): - if not value: - del self.headers['content-range'] - elif isinstance(value, string_types): - self.headers['Content-Range'] = value - else: - self.headers['Content-Range'] = value.to_header() - content_range = property(_get_content_range, _set_content_range, doc=''' - The `Content-Range` header as - :class:`~werkzeug.datastructures.ContentRange` object. Even if the - header is not set it wil provide such an object for easier - manipulation. - - .. versionadded:: 0.7''') - del _get_content_range, _set_content_range - - -class ResponseStream(object): - - """A file descriptor like object used by the :class:`ResponseStreamMixin` to - represent the body of the stream. It directly pushes into the response - iterable of the response object. - """ - - mode = 'wb+' - - def __init__(self, response): - self.response = response - self.closed = False - - def write(self, value): - if self.closed: - raise ValueError('I/O operation on closed file') - self.response._ensure_sequence(mutable=True) - self.response.response.append(value) - self.response.headers.pop('Content-Length', None) - return len(value) - - def writelines(self, seq): - for item in seq: - self.write(item) - - def close(self): - self.closed = True - - def flush(self): - if self.closed: - raise ValueError('I/O operation on closed file') - - def isatty(self): - if self.closed: - raise ValueError('I/O operation on closed file') - return False - - def tell(self): - self.response._ensure_sequence() - return sum(map(len, self.response.response)) - - @property - def encoding(self): - return self.response.charset - - -class ResponseStreamMixin(object): - - """Mixin for :class:`BaseRequest` subclasses. Classes that inherit from - this mixin will automatically get a :attr:`stream` property that provides - a write-only interface to the response iterable. - """ - - @cached_property - def stream(self): - """The response iterable as write-only stream.""" - return ResponseStream(self) - - -class CommonRequestDescriptorsMixin(object): - - """A mixin for :class:`BaseRequest` subclasses. Request objects that - mix this class in will automatically get descriptors for a couple of - HTTP headers with automatic type conversion. - - .. versionadded:: 0.5 - """ - - content_type = environ_property('CONTENT_TYPE', doc=''' - The Content-Type entity-header field indicates the media type of - the entity-body sent to the recipient or, in the case of the HEAD - method, the media type that would have been sent had the request - been a GET.''') - - @cached_property - def content_length(self): - """The Content-Length entity-header field indicates the size of the - entity-body in bytes or, in the case of the HEAD method, the size of - the entity-body that would have been sent had the request been a - GET. - """ - return get_content_length(self.environ) - - content_encoding = environ_property('HTTP_CONTENT_ENCODING', doc=''' - The Content-Encoding entity-header field is used as a modifier to the - media-type. When present, its value indicates what additional content - codings have been applied to the entity-body, and thus what decoding - mechanisms must be applied in order to obtain the media-type - referenced by the Content-Type header field. - - .. versionadded:: 0.9''') - content_md5 = environ_property('HTTP_CONTENT_MD5', doc=''' - The Content-MD5 entity-header field, as defined in RFC 1864, is an - MD5 digest of the entity-body for the purpose of providing an - end-to-end message integrity check (MIC) of the entity-body. (Note: - a MIC is good for detecting accidental modification of the - entity-body in transit, but is not proof against malicious attacks.) - - .. versionadded:: 0.9''') - referrer = environ_property('HTTP_REFERER', doc=''' - The Referer[sic] request-header field allows the client to specify, - for the server's benefit, the address (URI) of the resource from which - the Request-URI was obtained (the "referrer", although the header - field is misspelled).''') - date = environ_property('HTTP_DATE', None, parse_date, doc=''' - The Date general-header field represents the date and time at which - the message was originated, having the same semantics as orig-date - in RFC 822.''') - max_forwards = environ_property('HTTP_MAX_FORWARDS', None, int, doc=''' - The Max-Forwards request-header field provides a mechanism with the - TRACE and OPTIONS methods to limit the number of proxies or gateways - that can forward the request to the next inbound server.''') - - def _parse_content_type(self): - if not hasattr(self, '_parsed_content_type'): - self._parsed_content_type = \ - parse_options_header(self.environ.get('CONTENT_TYPE', '')) - - @property - def mimetype(self): - """Like :attr:`content_type`, but without parameters (eg, without - charset, type etc.) and always lowercase. For example if the content - type is ``text/HTML; charset=utf-8`` the mimetype would be - ``'text/html'``. - """ - self._parse_content_type() - return self._parsed_content_type[0].lower() - - @property - def mimetype_params(self): - """The mimetype parameters as dict. For example if the content - type is ``text/html; charset=utf-8`` the params would be - ``{'charset': 'utf-8'}``. - """ - self._parse_content_type() - return self._parsed_content_type[1] - - @cached_property - def pragma(self): - """The Pragma general-header field is used to include - implementation-specific directives that might apply to any recipient - along the request/response chain. All pragma directives specify - optional behavior from the viewpoint of the protocol; however, some - systems MAY require that behavior be consistent with the directives. - """ - return parse_set_header(self.environ.get('HTTP_PRAGMA', '')) - - -class CommonResponseDescriptorsMixin(object): - - """A mixin for :class:`BaseResponse` subclasses. Response objects that - mix this class in will automatically get descriptors for a couple of - HTTP headers with automatic type conversion. - """ - - def _get_mimetype(self): - ct = self.headers.get('content-type') - if ct: - return ct.split(';')[0].strip() - - def _set_mimetype(self, value): - self.headers['Content-Type'] = get_content_type(value, self.charset) - - def _get_mimetype_params(self): - def on_update(d): - self.headers['Content-Type'] = \ - dump_options_header(self.mimetype, d) - d = parse_options_header(self.headers.get('content-type', ''))[1] - return CallbackDict(d, on_update) - - mimetype = property(_get_mimetype, _set_mimetype, doc=''' - The mimetype (content type without charset etc.)''') - mimetype_params = property(_get_mimetype_params, doc=''' - The mimetype parameters as dict. For example if the content - type is ``text/html; charset=utf-8`` the params would be - ``{'charset': 'utf-8'}``. - - .. versionadded:: 0.5 - ''') - location = header_property('Location', doc=''' - The Location response-header field is used to redirect the recipient - to a location other than the Request-URI for completion of the request - or identification of a new resource.''') - age = header_property('Age', None, parse_age, dump_age, doc=''' - The Age response-header field conveys the sender's estimate of the - amount of time since the response (or its revalidation) was - generated at the origin server. - - Age values are non-negative decimal integers, representing time in - seconds.''') - content_type = header_property('Content-Type', doc=''' - The Content-Type entity-header field indicates the media type of the - entity-body sent to the recipient or, in the case of the HEAD method, - the media type that would have been sent had the request been a GET. - ''') - content_length = header_property('Content-Length', None, int, str, doc=''' - The Content-Length entity-header field indicates the size of the - entity-body, in decimal number of OCTETs, sent to the recipient or, - in the case of the HEAD method, the size of the entity-body that would - have been sent had the request been a GET.''') - content_location = header_property('Content-Location', doc=''' - The Content-Location entity-header field MAY be used to supply the - resource location for the entity enclosed in the message when that - entity is accessible from a location separate from the requested - resource's URI.''') - content_encoding = header_property('Content-Encoding', doc=''' - The Content-Encoding entity-header field is used as a modifier to the - media-type. When present, its value indicates what additional content - codings have been applied to the entity-body, and thus what decoding - mechanisms must be applied in order to obtain the media-type - referenced by the Content-Type header field.''') - content_md5 = header_property('Content-MD5', doc=''' - The Content-MD5 entity-header field, as defined in RFC 1864, is an - MD5 digest of the entity-body for the purpose of providing an - end-to-end message integrity check (MIC) of the entity-body. (Note: - a MIC is good for detecting accidental modification of the - entity-body in transit, but is not proof against malicious attacks.) - ''') - date = header_property('Date', None, parse_date, http_date, doc=''' - The Date general-header field represents the date and time at which - the message was originated, having the same semantics as orig-date - in RFC 822.''') - expires = header_property('Expires', None, parse_date, http_date, doc=''' - The Expires entity-header field gives the date/time after which the - response is considered stale. A stale cache entry may not normally be - returned by a cache.''') - last_modified = header_property('Last-Modified', None, parse_date, - http_date, doc=''' - The Last-Modified entity-header field indicates the date and time at - which the origin server believes the variant was last modified.''') - - def _get_retry_after(self): - value = self.headers.get('retry-after') - if value is None: - return - elif value.isdigit(): - return datetime.utcnow() + timedelta(seconds=int(value)) - return parse_date(value) - - def _set_retry_after(self, value): - if value is None: - if 'retry-after' in self.headers: - del self.headers['retry-after'] - return - elif isinstance(value, datetime): - value = http_date(value) - else: - value = str(value) - self.headers['Retry-After'] = value - - retry_after = property(_get_retry_after, _set_retry_after, doc=''' - The Retry-After response-header field can be used with a 503 (Service - Unavailable) response to indicate how long the service is expected - to be unavailable to the requesting client. - - Time in seconds until expiration or date.''') - - def _set_property(name, doc=None): - def fget(self): - def on_update(header_set): - if not header_set and name in self.headers: - del self.headers[name] - elif header_set: - self.headers[name] = header_set.to_header() - return parse_set_header(self.headers.get(name), on_update) - - def fset(self, value): - if not value: - del self.headers[name] - elif isinstance(value, string_types): - self.headers[name] = value - else: - self.headers[name] = dump_header(value) - return property(fget, fset, doc=doc) - - vary = _set_property('Vary', doc=''' - The Vary field value indicates the set of request-header fields that - fully determines, while the response is fresh, whether a cache is - permitted to use the response to reply to a subsequent request - without revalidation.''') - content_language = _set_property('Content-Language', doc=''' - The Content-Language entity-header field describes the natural - language(s) of the intended audience for the enclosed entity. Note - that this might not be equivalent to all the languages used within - the entity-body.''') - allow = _set_property('Allow', doc=''' - The Allow entity-header field lists the set of methods supported - by the resource identified by the Request-URI. The purpose of this - field is strictly to inform the recipient of valid methods - associated with the resource. An Allow header field MUST be - present in a 405 (Method Not Allowed) response.''') - - del _set_property, _get_mimetype, _set_mimetype, _get_retry_after, \ - _set_retry_after - - -class WWWAuthenticateMixin(object): - - """Adds a :attr:`www_authenticate` property to a response object.""" - - @property - def www_authenticate(self): - """The `WWW-Authenticate` header in a parsed form.""" - def on_update(www_auth): - if not www_auth and 'www-authenticate' in self.headers: - del self.headers['www-authenticate'] - elif www_auth: - self.headers['WWW-Authenticate'] = www_auth.to_header() - header = self.headers.get('www-authenticate') - return parse_www_authenticate_header(header, on_update) - - -class Request(BaseRequest, AcceptMixin, ETagRequestMixin, - UserAgentMixin, AuthorizationMixin, - CommonRequestDescriptorsMixin): - - """Full featured request object implementing the following mixins: - - - :class:`AcceptMixin` for accept header parsing - - :class:`ETagRequestMixin` for etag and cache control handling - - :class:`UserAgentMixin` for user agent introspection - - :class:`AuthorizationMixin` for http auth handling - - :class:`CommonRequestDescriptorsMixin` for common headers - """ - - -class PlainRequest(StreamOnlyMixin, Request): - - """A request object without special form parsing capabilities. - - .. versionadded:: 0.9 - """ - - -class Response(BaseResponse, ETagResponseMixin, ResponseStreamMixin, - CommonResponseDescriptorsMixin, - WWWAuthenticateMixin): - - """Full featured response object implementing the following mixins: - - - :class:`ETagResponseMixin` for etag and cache control handling - - :class:`ResponseStreamMixin` to add support for the `stream` property - - :class:`CommonResponseDescriptorsMixin` for various HTTP descriptors - - :class:`WWWAuthenticateMixin` for HTTP authentication support - """ diff --git a/pyextra/werkzeug/wsgi.py b/pyextra/werkzeug/wsgi.py deleted file mode 100644 index c30021a7b6ae51..00000000000000 --- a/pyextra/werkzeug/wsgi.py +++ /dev/null @@ -1,1364 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.wsgi - ~~~~~~~~~~~~~ - - This module implements WSGI related helpers. - - :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -import io -try: - import httplib -except ImportError: - from http import client as httplib -import mimetypes -import os -import posixpath -import re -import socket -from datetime import datetime -from functools import partial, update_wrapper -from itertools import chain -from time import mktime, time -from zlib import adler32 - -from werkzeug._compat import BytesIO, PY2, implements_iterator, iteritems, \ - make_literal_wrapper, string_types, text_type, to_bytes, to_unicode, \ - try_coerce_native, wsgi_get_bytes -from werkzeug._internal import _empty_stream, _encode_idna -from werkzeug.filesystem import get_filesystem_encoding -from werkzeug.http import http_date, is_resource_modified, \ - is_hop_by_hop_header -from werkzeug.urls import uri_to_iri, url_join, url_parse, url_quote -from werkzeug.datastructures import EnvironHeaders - - -def responder(f): - """Marks a function as responder. Decorate a function with it and it - will automatically call the return value as WSGI application. - - Example:: - - @responder - def application(environ, start_response): - return Response('Hello World!') - """ - return update_wrapper(lambda *a: f(*a)(*a[-2:]), f) - - -def get_current_url(environ, root_only=False, strip_querystring=False, - host_only=False, trusted_hosts=None): - """A handy helper function that recreates the full URL as IRI for the - current request or parts of it. Here's an example: - - >>> from werkzeug.test import create_environ - >>> env = create_environ("/?param=foo", "http://localhost/script") - >>> get_current_url(env) - 'http://localhost/script/?param=foo' - >>> get_current_url(env, root_only=True) - 'http://localhost/script/' - >>> get_current_url(env, host_only=True) - 'http://localhost/' - >>> get_current_url(env, strip_querystring=True) - 'http://localhost/script/' - - This optionally it verifies that the host is in a list of trusted hosts. - If the host is not in there it will raise a - :exc:`~werkzeug.exceptions.SecurityError`. - - Note that the string returned might contain unicode characters as the - representation is an IRI not an URI. If you need an ASCII only - representation you can use the :func:`~werkzeug.urls.iri_to_uri` - function: - - >>> from werkzeug.urls import iri_to_uri - >>> iri_to_uri(get_current_url(env)) - 'http://localhost/script/?param=foo' - - :param environ: the WSGI environment to get the current URL from. - :param root_only: set `True` if you only want the root URL. - :param strip_querystring: set to `True` if you don't want the querystring. - :param host_only: set to `True` if the host URL should be returned. - :param trusted_hosts: a list of trusted hosts, see :func:`host_is_trusted` - for more information. - """ - tmp = [environ['wsgi.url_scheme'], '://', get_host(environ, trusted_hosts)] - cat = tmp.append - if host_only: - return uri_to_iri(''.join(tmp) + '/') - cat(url_quote(wsgi_get_bytes(environ.get('SCRIPT_NAME', ''))).rstrip('/')) - cat('/') - if not root_only: - cat(url_quote(wsgi_get_bytes(environ.get('PATH_INFO', '')).lstrip(b'/'))) - if not strip_querystring: - qs = get_query_string(environ) - if qs: - cat('?' + qs) - return uri_to_iri(''.join(tmp)) - - -def host_is_trusted(hostname, trusted_list): - """Checks if a host is trusted against a list. This also takes care - of port normalization. - - .. versionadded:: 0.9 - - :param hostname: the hostname to check - :param trusted_list: a list of hostnames to check against. If a - hostname starts with a dot it will match against - all subdomains as well. - """ - if not hostname: - return False - - if isinstance(trusted_list, string_types): - trusted_list = [trusted_list] - - def _normalize(hostname): - if ':' in hostname: - hostname = hostname.rsplit(':', 1)[0] - return _encode_idna(hostname) - - try: - hostname = _normalize(hostname) - except UnicodeError: - return False - for ref in trusted_list: - if ref.startswith('.'): - ref = ref[1:] - suffix_match = True - else: - suffix_match = False - try: - ref = _normalize(ref) - except UnicodeError: - return False - if ref == hostname: - return True - if suffix_match and hostname.endswith(b'.' + ref): - return True - return False - - -def get_host(environ, trusted_hosts=None): - """Return the real host for the given WSGI environment. This first checks - the `X-Forwarded-Host` header, then the normal `Host` header, and finally - the `SERVER_NAME` environment variable (using the first one it finds). - - Optionally it verifies that the host is in a list of trusted hosts. - If the host is not in there it will raise a - :exc:`~werkzeug.exceptions.SecurityError`. - - :param environ: the WSGI environment to get the host of. - :param trusted_hosts: a list of trusted hosts, see :func:`host_is_trusted` - for more information. - """ - if 'HTTP_X_FORWARDED_HOST' in environ: - rv = environ['HTTP_X_FORWARDED_HOST'].split(',', 1)[0].strip() - elif 'HTTP_HOST' in environ: - rv = environ['HTTP_HOST'] - else: - rv = environ['SERVER_NAME'] - if (environ['wsgi.url_scheme'], environ['SERVER_PORT']) not \ - in (('https', '443'), ('http', '80')): - rv += ':' + environ['SERVER_PORT'] - if trusted_hosts is not None: - if not host_is_trusted(rv, trusted_hosts): - from werkzeug.exceptions import SecurityError - raise SecurityError('Host "%s" is not trusted' % rv) - return rv - - -def get_content_length(environ): - """Returns the content length from the WSGI environment as - integer. If it's not available or chunked transfer encoding is used, - ``None`` is returned. - - .. versionadded:: 0.9 - - :param environ: the WSGI environ to fetch the content length from. - """ - if environ.get('HTTP_TRANSFER_ENCODING', '') == 'chunked': - return None - - content_length = environ.get('CONTENT_LENGTH') - if content_length is not None: - try: - return max(0, int(content_length)) - except (ValueError, TypeError): - pass - - -def get_input_stream(environ, safe_fallback=True): - """Returns the input stream from the WSGI environment and wraps it - in the most sensible way possible. The stream returned is not the - raw WSGI stream in most cases but one that is safe to read from - without taking into account the content length. - - If content length is not set, the stream will be empty for safety reasons. - If the WSGI server supports chunked or infinite streams, it should set - the ``wsgi.input_terminated`` value in the WSGI environ to indicate that. - - .. versionadded:: 0.9 - - :param environ: the WSGI environ to fetch the stream from. - :param safe_fallback: use an empty stream as a safe fallback when the - content length is not set. Disabling this allows infinite streams, - which can be a denial-of-service risk. - """ - stream = environ['wsgi.input'] - content_length = get_content_length(environ) - - # A wsgi extension that tells us if the input is terminated. In - # that case we return the stream unchanged as we know we can safely - # read it until the end. - if environ.get('wsgi.input_terminated'): - return stream - - # If the request doesn't specify a content length, returning the stream is - # potentially dangerous because it could be infinite, malicious or not. If - # safe_fallback is true, return an empty stream instead for safety. - if content_length is None: - return safe_fallback and _empty_stream or stream - - # Otherwise limit the stream to the content length - return LimitedStream(stream, content_length) - - -def get_query_string(environ): - """Returns the `QUERY_STRING` from the WSGI environment. This also takes - care about the WSGI decoding dance on Python 3 environments as a - native string. The string returned will be restricted to ASCII - characters. - - .. versionadded:: 0.9 - - :param environ: the WSGI environment object to get the query string from. - """ - qs = wsgi_get_bytes(environ.get('QUERY_STRING', '')) - # QUERY_STRING really should be ascii safe but some browsers - # will send us some unicode stuff (I am looking at you IE). - # In that case we want to urllib quote it badly. - return try_coerce_native(url_quote(qs, safe=':&%=+$!*\'(),')) - - -def get_path_info(environ, charset='utf-8', errors='replace'): - """Returns the `PATH_INFO` from the WSGI environment and properly - decodes it. This also takes care about the WSGI decoding dance - on Python 3 environments. if the `charset` is set to `None` a - bytestring is returned. - - .. versionadded:: 0.9 - - :param environ: the WSGI environment object to get the path from. - :param charset: the charset for the path info, or `None` if no - decoding should be performed. - :param errors: the decoding error handling. - """ - path = wsgi_get_bytes(environ.get('PATH_INFO', '')) - return to_unicode(path, charset, errors, allow_none_charset=True) - - -def get_script_name(environ, charset='utf-8', errors='replace'): - """Returns the `SCRIPT_NAME` from the WSGI environment and properly - decodes it. This also takes care about the WSGI decoding dance - on Python 3 environments. if the `charset` is set to `None` a - bytestring is returned. - - .. versionadded:: 0.9 - - :param environ: the WSGI environment object to get the path from. - :param charset: the charset for the path, or `None` if no - decoding should be performed. - :param errors: the decoding error handling. - """ - path = wsgi_get_bytes(environ.get('SCRIPT_NAME', '')) - return to_unicode(path, charset, errors, allow_none_charset=True) - - -def pop_path_info(environ, charset='utf-8', errors='replace'): - """Removes and returns the next segment of `PATH_INFO`, pushing it onto - `SCRIPT_NAME`. Returns `None` if there is nothing left on `PATH_INFO`. - - If the `charset` is set to `None` a bytestring is returned. - - If there are empty segments (``'/foo//bar``) these are ignored but - properly pushed to the `SCRIPT_NAME`: - - >>> env = {'SCRIPT_NAME': '/foo', 'PATH_INFO': '/a/b'} - >>> pop_path_info(env) - 'a' - >>> env['SCRIPT_NAME'] - '/foo/a' - >>> pop_path_info(env) - 'b' - >>> env['SCRIPT_NAME'] - '/foo/a/b' - - .. versionadded:: 0.5 - - .. versionchanged:: 0.9 - The path is now decoded and a charset and encoding - parameter can be provided. - - :param environ: the WSGI environment that is modified. - """ - path = environ.get('PATH_INFO') - if not path: - return None - - script_name = environ.get('SCRIPT_NAME', '') - - # shift multiple leading slashes over - old_path = path - path = path.lstrip('/') - if path != old_path: - script_name += '/' * (len(old_path) - len(path)) - - if '/' not in path: - environ['PATH_INFO'] = '' - environ['SCRIPT_NAME'] = script_name + path - rv = wsgi_get_bytes(path) - else: - segment, path = path.split('/', 1) - environ['PATH_INFO'] = '/' + path - environ['SCRIPT_NAME'] = script_name + segment - rv = wsgi_get_bytes(segment) - - return to_unicode(rv, charset, errors, allow_none_charset=True) - - -def peek_path_info(environ, charset='utf-8', errors='replace'): - """Returns the next segment on the `PATH_INFO` or `None` if there - is none. Works like :func:`pop_path_info` without modifying the - environment: - - >>> env = {'SCRIPT_NAME': '/foo', 'PATH_INFO': '/a/b'} - >>> peek_path_info(env) - 'a' - >>> peek_path_info(env) - 'a' - - If the `charset` is set to `None` a bytestring is returned. - - .. versionadded:: 0.5 - - .. versionchanged:: 0.9 - The path is now decoded and a charset and encoding - parameter can be provided. - - :param environ: the WSGI environment that is checked. - """ - segments = environ.get('PATH_INFO', '').lstrip('/').split('/', 1) - if segments: - return to_unicode(wsgi_get_bytes(segments[0]), - charset, errors, allow_none_charset=True) - - -def extract_path_info(environ_or_baseurl, path_or_url, charset='utf-8', - errors='replace', collapse_http_schemes=True): - """Extracts the path info from the given URL (or WSGI environment) and - path. The path info returned is a unicode string, not a bytestring - suitable for a WSGI environment. The URLs might also be IRIs. - - If the path info could not be determined, `None` is returned. - - Some examples: - - >>> extract_path_info('http://example.com/app', '/app/hello') - u'/hello' - >>> extract_path_info('http://example.com/app', - ... 'https://example.com/app/hello') - u'/hello' - >>> extract_path_info('http://example.com/app', - ... 'https://example.com/app/hello', - ... collapse_http_schemes=False) is None - True - - Instead of providing a base URL you can also pass a WSGI environment. - - .. versionadded:: 0.6 - - :param environ_or_baseurl: a WSGI environment dict, a base URL or - base IRI. This is the root of the - application. - :param path_or_url: an absolute path from the server root, a - relative path (in which case it's the path info) - or a full URL. Also accepts IRIs and unicode - parameters. - :param charset: the charset for byte data in URLs - :param errors: the error handling on decode - :param collapse_http_schemes: if set to `False` the algorithm does - not assume that http and https on the - same server point to the same - resource. - """ - def _normalize_netloc(scheme, netloc): - parts = netloc.split(u'@', 1)[-1].split(u':', 1) - if len(parts) == 2: - netloc, port = parts - if (scheme == u'http' and port == u'80') or \ - (scheme == u'https' and port == u'443'): - port = None - else: - netloc = parts[0] - port = None - if port is not None: - netloc += u':' + port - return netloc - - # make sure whatever we are working on is a IRI and parse it - path = uri_to_iri(path_or_url, charset, errors) - if isinstance(environ_or_baseurl, dict): - environ_or_baseurl = get_current_url(environ_or_baseurl, - root_only=True) - base_iri = uri_to_iri(environ_or_baseurl, charset, errors) - base_scheme, base_netloc, base_path = url_parse(base_iri)[:3] - cur_scheme, cur_netloc, cur_path, = \ - url_parse(url_join(base_iri, path))[:3] - - # normalize the network location - base_netloc = _normalize_netloc(base_scheme, base_netloc) - cur_netloc = _normalize_netloc(cur_scheme, cur_netloc) - - # is that IRI even on a known HTTP scheme? - if collapse_http_schemes: - for scheme in base_scheme, cur_scheme: - if scheme not in (u'http', u'https'): - return None - else: - if not (base_scheme in (u'http', u'https') and - base_scheme == cur_scheme): - return None - - # are the netlocs compatible? - if base_netloc != cur_netloc: - return None - - # are we below the application path? - base_path = base_path.rstrip(u'/') - if not cur_path.startswith(base_path): - return None - - return u'/' + cur_path[len(base_path):].lstrip(u'/') - - -class ProxyMiddleware(object): - """This middleware routes some requests to the provided WSGI app and - proxies some requests to an external server. This is not something that - can generally be done on the WSGI layer and some HTTP requests will not - tunnel through correctly (for instance websocket requests cannot be - proxied through WSGI). As a result this is only really useful for some - basic requests that can be forwarded. - - Example configuration:: - - app = ProxyMiddleware(app, { - '/static/': { - 'target': 'http://127.0.0.1:5001/', - } - }) - - For each host options can be specified. The following options are - supported: - - ``target``: - the target URL to dispatch to - ``remove_prefix``: - if set to `True` the prefix is chopped off the URL before - dispatching it to the server. - ``host``: - When set to ``''`` which is the default the host header is - automatically rewritten to the URL of the target. If set to `None` - then the host header is unmodified from the client request. Any - other value overwrites the host header with that value. - ``headers``: - An optional dictionary of headers that should be sent with the - request to the target host. - ``ssl_context``: - In case this is an HTTPS target host then an SSL context can be - provided here (:class:`ssl.SSLContext`). This can be used for instance - to disable SSL verification. - - In this case everything below ``'/static/'`` is proxied to the server on - port 5001. The host header is automatically rewritten and so are request - URLs (eg: the leading `/static/` prefix here gets chopped off). - - .. versionadded:: 0.14 - """ - - def __init__(self, app, targets, chunk_size=2 << 13, timeout=10): - def _set_defaults(opts): - opts.setdefault('remove_prefix', False) - opts.setdefault('host', '') - opts.setdefault('headers', {}) - opts.setdefault('ssl_context', None) - return opts - self.app = app - self.targets = dict(('/%s/' % k.strip('/'), _set_defaults(v)) - for k, v in iteritems(targets)) - self.chunk_size = chunk_size - self.timeout = timeout - - def proxy_to(self, opts, path, prefix): - target = url_parse(opts['target']) - - def application(environ, start_response): - headers = list(EnvironHeaders(environ).items()) - headers[:] = [(k, v) for k, v in headers - if not is_hop_by_hop_header(k) and - k.lower() not in ('content-length', 'host')] - headers.append(('Connection', 'close')) - if opts['host'] == '': - headers.append(('Host', target.ascii_host)) - elif opts['host'] is None: - headers.append(('Host', environ['HTTP_HOST'])) - else: - headers.append(('Host', opts['host'])) - headers.extend(opts['headers'].items()) - - remote_path = path - if opts['remove_prefix']: - remote_path = '%s/%s' % ( - target.path.rstrip('/'), - remote_path[len(prefix):].lstrip('/') - ) - - content_length = environ.get('CONTENT_LENGTH') - chunked = False - if content_length not in ('', None): - headers.append(('Content-Length', content_length)) - elif content_length is not None: - headers.append(('Transfer-Encoding', 'chunked')) - chunked = True - - try: - if target.scheme == 'http': - con = httplib.HTTPConnection( - target.ascii_host, target.port or 80, - timeout=self.timeout) - elif target.scheme == 'https': - con = httplib.HTTPSConnection( - target.ascii_host, target.port or 443, - timeout=self.timeout, - context=opts['ssl_context']) - con.connect() - con.putrequest(environ['REQUEST_METHOD'], url_quote(remote_path), - skip_host=True) - - for k, v in headers: - if k.lower() == 'connection': - v = 'close' - con.putheader(k, v) - con.endheaders() - - stream = get_input_stream(environ) - while 1: - data = stream.read(self.chunk_size) - if not data: - break - if chunked: - con.send(b'%x\r\n%s\r\n' % (len(data), data)) - else: - con.send(data) - - resp = con.getresponse() - except socket.error: - from werkzeug.exceptions import BadGateway - return BadGateway()(environ, start_response) - - start_response('%d %s' % (resp.status, resp.reason), - [(k.title(), v) for k, v in resp.getheaders() - if not is_hop_by_hop_header(k)]) - - def read(): - while 1: - try: - data = resp.read(self.chunk_size) - except socket.error: - break - if not data: - break - yield data - return read() - return application - - def __call__(self, environ, start_response): - path = environ['PATH_INFO'] - app = self.app - for prefix, opts in iteritems(self.targets): - if path.startswith(prefix): - app = self.proxy_to(opts, path, prefix) - break - return app(environ, start_response) - - -class SharedDataMiddleware(object): - - """A WSGI middleware that provides static content for development - environments or simple server setups. Usage is quite simple:: - - import os - from werkzeug.wsgi import SharedDataMiddleware - - app = SharedDataMiddleware(app, { - '/shared': os.path.join(os.path.dirname(__file__), 'shared') - }) - - The contents of the folder ``./shared`` will now be available on - ``http://example.com/shared/``. This is pretty useful during development - because a standalone media server is not required. One can also mount - files on the root folder and still continue to use the application because - the shared data middleware forwards all unhandled requests to the - application, even if the requests are below one of the shared folders. - - If `pkg_resources` is available you can also tell the middleware to serve - files from package data:: - - app = SharedDataMiddleware(app, { - '/shared': ('myapplication', 'shared_files') - }) - - This will then serve the ``shared_files`` folder in the `myapplication` - Python package. - - The optional `disallow` parameter can be a list of :func:`~fnmatch.fnmatch` - rules for files that are not accessible from the web. If `cache` is set to - `False` no caching headers are sent. - - Currently the middleware does not support non ASCII filenames. If the - encoding on the file system happens to be the encoding of the URI it may - work but this could also be by accident. We strongly suggest using ASCII - only file names for static files. - - The middleware will guess the mimetype using the Python `mimetype` - module. If it's unable to figure out the charset it will fall back - to `fallback_mimetype`. - - .. versionchanged:: 0.5 - The cache timeout is configurable now. - - .. versionadded:: 0.6 - The `fallback_mimetype` parameter was added. - - :param app: the application to wrap. If you don't want to wrap an - application you can pass it :exc:`NotFound`. - :param exports: a list or dict of exported files and folders. - :param disallow: a list of :func:`~fnmatch.fnmatch` rules. - :param fallback_mimetype: the fallback mimetype for unknown files. - :param cache: enable or disable caching headers. - :param cache_timeout: the cache timeout in seconds for the headers. - """ - - def __init__(self, app, exports, disallow=None, cache=True, - cache_timeout=60 * 60 * 12, fallback_mimetype='text/plain'): - self.app = app - self.exports = [] - self.cache = cache - self.cache_timeout = cache_timeout - if hasattr(exports, 'items'): - exports = iteritems(exports) - for key, value in exports: - if isinstance(value, tuple): - loader = self.get_package_loader(*value) - elif isinstance(value, string_types): - if os.path.isfile(value): - loader = self.get_file_loader(value) - else: - loader = self.get_directory_loader(value) - else: - raise TypeError('unknown def %r' % value) - self.exports.append((key, loader)) - if disallow is not None: - from fnmatch import fnmatch - self.is_allowed = lambda x: not fnmatch(x, disallow) - self.fallback_mimetype = fallback_mimetype - - def is_allowed(self, filename): - """Subclasses can override this method to disallow the access to - certain files. However by providing `disallow` in the constructor - this method is overwritten. - """ - return True - - def _opener(self, filename): - return lambda: ( - open(filename, 'rb'), - datetime.utcfromtimestamp(os.path.getmtime(filename)), - int(os.path.getsize(filename)) - ) - - def get_file_loader(self, filename): - return lambda x: (os.path.basename(filename), self._opener(filename)) - - def get_package_loader(self, package, package_path): - from pkg_resources import DefaultProvider, ResourceManager, \ - get_provider - loadtime = datetime.utcnow() - provider = get_provider(package) - manager = ResourceManager() - filesystem_bound = isinstance(provider, DefaultProvider) - - def loader(path): - if path is None: - return None, None - path = posixpath.join(package_path, path) - if not provider.has_resource(path): - return None, None - basename = posixpath.basename(path) - if filesystem_bound: - return basename, self._opener( - provider.get_resource_filename(manager, path)) - s = provider.get_resource_string(manager, path) - return basename, lambda: ( - BytesIO(s), - loadtime, - len(s) - ) - return loader - - def get_directory_loader(self, directory): - def loader(path): - if path is not None: - path = os.path.join(directory, path) - else: - path = directory - if os.path.isfile(path): - return os.path.basename(path), self._opener(path) - return None, None - return loader - - def generate_etag(self, mtime, file_size, real_filename): - if not isinstance(real_filename, bytes): - real_filename = real_filename.encode(get_filesystem_encoding()) - return 'wzsdm-%d-%s-%s' % ( - mktime(mtime.timetuple()), - file_size, - adler32(real_filename) & 0xffffffff - ) - - def __call__(self, environ, start_response): - cleaned_path = get_path_info(environ) - if PY2: - cleaned_path = cleaned_path.encode(get_filesystem_encoding()) - # sanitize the path for non unix systems - cleaned_path = cleaned_path.strip('/') - for sep in os.sep, os.altsep: - if sep and sep != '/': - cleaned_path = cleaned_path.replace(sep, '/') - path = '/' + '/'.join(x for x in cleaned_path.split('/') - if x and x != '..') - file_loader = None - for search_path, loader in self.exports: - if search_path == path: - real_filename, file_loader = loader(None) - if file_loader is not None: - break - if not search_path.endswith('/'): - search_path += '/' - if path.startswith(search_path): - real_filename, file_loader = loader(path[len(search_path):]) - if file_loader is not None: - break - if file_loader is None or not self.is_allowed(real_filename): - return self.app(environ, start_response) - - guessed_type = mimetypes.guess_type(real_filename) - mime_type = guessed_type[0] or self.fallback_mimetype - f, mtime, file_size = file_loader() - - headers = [('Date', http_date())] - if self.cache: - timeout = self.cache_timeout - etag = self.generate_etag(mtime, file_size, real_filename) - headers += [ - ('Etag', '"%s"' % etag), - ('Cache-Control', 'max-age=%d, public' % timeout) - ] - if not is_resource_modified(environ, etag, last_modified=mtime): - f.close() - start_response('304 Not Modified', headers) - return [] - headers.append(('Expires', http_date(time() + timeout))) - else: - headers.append(('Cache-Control', 'public')) - - headers.extend(( - ('Content-Type', mime_type), - ('Content-Length', str(file_size)), - ('Last-Modified', http_date(mtime)) - )) - start_response('200 OK', headers) - return wrap_file(environ, f) - - -class DispatcherMiddleware(object): - - """Allows one to mount middlewares or applications in a WSGI application. - This is useful if you want to combine multiple WSGI applications:: - - app = DispatcherMiddleware(app, { - '/app2': app2, - '/app3': app3 - }) - """ - - def __init__(self, app, mounts=None): - self.app = app - self.mounts = mounts or {} - - def __call__(self, environ, start_response): - script = environ.get('PATH_INFO', '') - path_info = '' - while '/' in script: - if script in self.mounts: - app = self.mounts[script] - break - script, last_item = script.rsplit('/', 1) - path_info = '/%s%s' % (last_item, path_info) - else: - app = self.mounts.get(script, self.app) - original_script_name = environ.get('SCRIPT_NAME', '') - environ['SCRIPT_NAME'] = original_script_name + script - environ['PATH_INFO'] = path_info - return app(environ, start_response) - - -@implements_iterator -class ClosingIterator(object): - - """The WSGI specification requires that all middlewares and gateways - respect the `close` callback of an iterator. Because it is useful to add - another close action to a returned iterator and adding a custom iterator - is a boring task this class can be used for that:: - - return ClosingIterator(app(environ, start_response), [cleanup_session, - cleanup_locals]) - - If there is just one close function it can be passed instead of the list. - - A closing iterator is not needed if the application uses response objects - and finishes the processing if the response is started:: - - try: - return response(environ, start_response) - finally: - cleanup_session() - cleanup_locals() - """ - - def __init__(self, iterable, callbacks=None): - iterator = iter(iterable) - self._next = partial(next, iterator) - if callbacks is None: - callbacks = [] - elif callable(callbacks): - callbacks = [callbacks] - else: - callbacks = list(callbacks) - iterable_close = getattr(iterator, 'close', None) - if iterable_close: - callbacks.insert(0, iterable_close) - self._callbacks = callbacks - - def __iter__(self): - return self - - def __next__(self): - return self._next() - - def close(self): - for callback in self._callbacks: - callback() - - -def wrap_file(environ, file, buffer_size=8192): - """Wraps a file. This uses the WSGI server's file wrapper if available - or otherwise the generic :class:`FileWrapper`. - - .. versionadded:: 0.5 - - If the file wrapper from the WSGI server is used it's important to not - iterate over it from inside the application but to pass it through - unchanged. If you want to pass out a file wrapper inside a response - object you have to set :attr:`~BaseResponse.direct_passthrough` to `True`. - - More information about file wrappers are available in :pep:`333`. - - :param file: a :class:`file`-like object with a :meth:`~file.read` method. - :param buffer_size: number of bytes for one iteration. - """ - return environ.get('wsgi.file_wrapper', FileWrapper)(file, buffer_size) - - -@implements_iterator -class FileWrapper(object): - - """This class can be used to convert a :class:`file`-like object into - an iterable. It yields `buffer_size` blocks until the file is fully - read. - - You should not use this class directly but rather use the - :func:`wrap_file` function that uses the WSGI server's file wrapper - support if it's available. - - .. versionadded:: 0.5 - - If you're using this object together with a :class:`BaseResponse` you have - to use the `direct_passthrough` mode. - - :param file: a :class:`file`-like object with a :meth:`~file.read` method. - :param buffer_size: number of bytes for one iteration. - """ - - def __init__(self, file, buffer_size=8192): - self.file = file - self.buffer_size = buffer_size - - def close(self): - if hasattr(self.file, 'close'): - self.file.close() - - def seekable(self): - if hasattr(self.file, 'seekable'): - return self.file.seekable() - if hasattr(self.file, 'seek'): - return True - return False - - def seek(self, *args): - if hasattr(self.file, 'seek'): - self.file.seek(*args) - - def tell(self): - if hasattr(self.file, 'tell'): - return self.file.tell() - return None - - def __iter__(self): - return self - - def __next__(self): - data = self.file.read(self.buffer_size) - if data: - return data - raise StopIteration() - - -@implements_iterator -class _RangeWrapper(object): - # private for now, but should we make it public in the future ? - - """This class can be used to convert an iterable object into - an iterable that will only yield a piece of the underlying content. - It yields blocks until the underlying stream range is fully read. - The yielded blocks will have a size that can't exceed the original - iterator defined block size, but that can be smaller. - - If you're using this object together with a :class:`BaseResponse` you have - to use the `direct_passthrough` mode. - - :param iterable: an iterable object with a :meth:`__next__` method. - :param start_byte: byte from which read will start. - :param byte_range: how many bytes to read. - """ - - def __init__(self, iterable, start_byte=0, byte_range=None): - self.iterable = iter(iterable) - self.byte_range = byte_range - self.start_byte = start_byte - self.end_byte = None - if byte_range is not None: - self.end_byte = self.start_byte + self.byte_range - self.read_length = 0 - self.seekable = hasattr(iterable, 'seekable') and iterable.seekable() - self.end_reached = False - - def __iter__(self): - return self - - def _next_chunk(self): - try: - chunk = next(self.iterable) - self.read_length += len(chunk) - return chunk - except StopIteration: - self.end_reached = True - raise - - def _first_iteration(self): - chunk = None - if self.seekable: - self.iterable.seek(self.start_byte) - self.read_length = self.iterable.tell() - contextual_read_length = self.read_length - else: - while self.read_length <= self.start_byte: - chunk = self._next_chunk() - if chunk is not None: - chunk = chunk[self.start_byte - self.read_length:] - contextual_read_length = self.start_byte - return chunk, contextual_read_length - - def _next(self): - if self.end_reached: - raise StopIteration() - chunk = None - contextual_read_length = self.read_length - if self.read_length == 0: - chunk, contextual_read_length = self._first_iteration() - if chunk is None: - chunk = self._next_chunk() - if self.end_byte is not None and self.read_length >= self.end_byte: - self.end_reached = True - return chunk[:self.end_byte - contextual_read_length] - return chunk - - def __next__(self): - chunk = self._next() - if chunk: - return chunk - self.end_reached = True - raise StopIteration() - - def close(self): - if hasattr(self.iterable, 'close'): - self.iterable.close() - - -def _make_chunk_iter(stream, limit, buffer_size): - """Helper for the line and chunk iter functions.""" - if isinstance(stream, (bytes, bytearray, text_type)): - raise TypeError('Passed a string or byte object instead of ' - 'true iterator or stream.') - if not hasattr(stream, 'read'): - for item in stream: - if item: - yield item - return - if not isinstance(stream, LimitedStream) and limit is not None: - stream = LimitedStream(stream, limit) - _read = stream.read - while 1: - item = _read(buffer_size) - if not item: - break - yield item - - -def make_line_iter(stream, limit=None, buffer_size=10 * 1024, - cap_at_buffer=False): - """Safely iterates line-based over an input stream. If the input stream - is not a :class:`LimitedStream` the `limit` parameter is mandatory. - - This uses the stream's :meth:`~file.read` method internally as opposite - to the :meth:`~file.readline` method that is unsafe and can only be used - in violation of the WSGI specification. The same problem applies to the - `__iter__` function of the input stream which calls :meth:`~file.readline` - without arguments. - - If you need line-by-line processing it's strongly recommended to iterate - over the input stream using this helper function. - - .. versionchanged:: 0.8 - This function now ensures that the limit was reached. - - .. versionadded:: 0.9 - added support for iterators as input stream. - - .. versionadded:: 0.11.10 - added support for the `cap_at_buffer` parameter. - - :param stream: the stream or iterate to iterate over. - :param limit: the limit in bytes for the stream. (Usually - content length. Not necessary if the `stream` - is a :class:`LimitedStream`. - :param buffer_size: The optional buffer size. - :param cap_at_buffer: if this is set chunks are split if they are longer - than the buffer size. Internally this is implemented - that the buffer size might be exhausted by a factor - of two however. - """ - _iter = _make_chunk_iter(stream, limit, buffer_size) - - first_item = next(_iter, '') - if not first_item: - return - - s = make_literal_wrapper(first_item) - empty = s('') - cr = s('\r') - lf = s('\n') - crlf = s('\r\n') - - _iter = chain((first_item,), _iter) - - def _iter_basic_lines(): - _join = empty.join - buffer = [] - while 1: - new_data = next(_iter, '') - if not new_data: - break - new_buf = [] - buf_size = 0 - for item in chain(buffer, new_data.splitlines(True)): - new_buf.append(item) - buf_size += len(item) - if item and item[-1:] in crlf: - yield _join(new_buf) - new_buf = [] - elif cap_at_buffer and buf_size >= buffer_size: - rv = _join(new_buf) - while len(rv) >= buffer_size: - yield rv[:buffer_size] - rv = rv[buffer_size:] - new_buf = [rv] - buffer = new_buf - if buffer: - yield _join(buffer) - - # This hackery is necessary to merge 'foo\r' and '\n' into one item - # of 'foo\r\n' if we were unlucky and we hit a chunk boundary. - previous = empty - for item in _iter_basic_lines(): - if item == lf and previous[-1:] == cr: - previous += item - item = empty - if previous: - yield previous - previous = item - if previous: - yield previous - - -def make_chunk_iter(stream, separator, limit=None, buffer_size=10 * 1024, - cap_at_buffer=False): - """Works like :func:`make_line_iter` but accepts a separator - which divides chunks. If you want newline based processing - you should use :func:`make_line_iter` instead as it - supports arbitrary newline markers. - - .. versionadded:: 0.8 - - .. versionadded:: 0.9 - added support for iterators as input stream. - - .. versionadded:: 0.11.10 - added support for the `cap_at_buffer` parameter. - - :param stream: the stream or iterate to iterate over. - :param separator: the separator that divides chunks. - :param limit: the limit in bytes for the stream. (Usually - content length. Not necessary if the `stream` - is otherwise already limited). - :param buffer_size: The optional buffer size. - :param cap_at_buffer: if this is set chunks are split if they are longer - than the buffer size. Internally this is implemented - that the buffer size might be exhausted by a factor - of two however. - """ - _iter = _make_chunk_iter(stream, limit, buffer_size) - - first_item = next(_iter, '') - if not first_item: - return - - _iter = chain((first_item,), _iter) - if isinstance(first_item, text_type): - separator = to_unicode(separator) - _split = re.compile(r'(%s)' % re.escape(separator)).split - _join = u''.join - else: - separator = to_bytes(separator) - _split = re.compile(b'(' + re.escape(separator) + b')').split - _join = b''.join - - buffer = [] - while 1: - new_data = next(_iter, '') - if not new_data: - break - chunks = _split(new_data) - new_buf = [] - buf_size = 0 - for item in chain(buffer, chunks): - if item == separator: - yield _join(new_buf) - new_buf = [] - buf_size = 0 - else: - buf_size += len(item) - new_buf.append(item) - - if cap_at_buffer and buf_size >= buffer_size: - rv = _join(new_buf) - while len(rv) >= buffer_size: - yield rv[:buffer_size] - rv = rv[buffer_size:] - new_buf = [rv] - buf_size = len(rv) - - buffer = new_buf - if buffer: - yield _join(buffer) - - -@implements_iterator -class LimitedStream(io.IOBase): - - """Wraps a stream so that it doesn't read more than n bytes. If the - stream is exhausted and the caller tries to get more bytes from it - :func:`on_exhausted` is called which by default returns an empty - string. The return value of that function is forwarded - to the reader function. So if it returns an empty string - :meth:`read` will return an empty string as well. - - The limit however must never be higher than what the stream can - output. Otherwise :meth:`readlines` will try to read past the - limit. - - .. admonition:: Note on WSGI compliance - - calls to :meth:`readline` and :meth:`readlines` are not - WSGI compliant because it passes a size argument to the - readline methods. Unfortunately the WSGI PEP is not safely - implementable without a size argument to :meth:`readline` - because there is no EOF marker in the stream. As a result - of that the use of :meth:`readline` is discouraged. - - For the same reason iterating over the :class:`LimitedStream` - is not portable. It internally calls :meth:`readline`. - - We strongly suggest using :meth:`read` only or using the - :func:`make_line_iter` which safely iterates line-based - over a WSGI input stream. - - :param stream: the stream to wrap. - :param limit: the limit for the stream, must not be longer than - what the string can provide if the stream does not - end with `EOF` (like `wsgi.input`) - """ - - def __init__(self, stream, limit): - self._read = stream.read - self._readline = stream.readline - self._pos = 0 - self.limit = limit - - def __iter__(self): - return self - - @property - def is_exhausted(self): - """If the stream is exhausted this attribute is `True`.""" - return self._pos >= self.limit - - def on_exhausted(self): - """This is called when the stream tries to read past the limit. - The return value of this function is returned from the reading - function. - """ - # Read null bytes from the stream so that we get the - # correct end of stream marker. - return self._read(0) - - def on_disconnect(self): - """What should happen if a disconnect is detected? The return - value of this function is returned from read functions in case - the client went away. By default a - :exc:`~werkzeug.exceptions.ClientDisconnected` exception is raised. - """ - from werkzeug.exceptions import ClientDisconnected - raise ClientDisconnected() - - def exhaust(self, chunk_size=1024 * 64): - """Exhaust the stream. This consumes all the data left until the - limit is reached. - - :param chunk_size: the size for a chunk. It will read the chunk - until the stream is exhausted and throw away - the results. - """ - to_read = self.limit - self._pos - chunk = chunk_size - while to_read > 0: - chunk = min(to_read, chunk) - self.read(chunk) - to_read -= chunk - - def read(self, size=None): - """Read `size` bytes or if size is not provided everything is read. - - :param size: the number of bytes read. - """ - if self._pos >= self.limit: - return self.on_exhausted() - if size is None or size == -1: # -1 is for consistence with file - size = self.limit - to_read = min(self.limit - self._pos, size) - try: - read = self._read(to_read) - except (IOError, ValueError): - return self.on_disconnect() - if to_read and len(read) != to_read: - return self.on_disconnect() - self._pos += len(read) - return read - - def readline(self, size=None): - """Reads one line from the stream.""" - if self._pos >= self.limit: - return self.on_exhausted() - if size is None: - size = self.limit - self._pos - else: - size = min(size, self.limit - self._pos) - try: - line = self._readline(size) - except (ValueError, IOError): - return self.on_disconnect() - if size and not line: - return self.on_disconnect() - self._pos += len(line) - return line - - def readlines(self, size=None): - """Reads a file into a list of strings. It calls :meth:`readline` - until the file is read to the end. It does support the optional - `size` argument if the underlaying stream supports it for - `readline`. - """ - last_pos = self._pos - result = [] - if size is not None: - end = min(self.limit, last_pos + size) - else: - end = self.limit - while 1: - if size is not None: - size -= last_pos - self._pos - if self._pos >= end: - break - result.append(self.readline(size)) - if size is not None: - last_pos = self._pos - return result - - def tell(self): - """Returns the position of the stream. - - .. versionadded:: 0.9 - """ - return self._pos - - def __next__(self): - line = self.readline() - if not line: - raise StopIteration() - return line - - def readable(self): - return True diff --git a/requirements_openpilot.txt b/requirements_openpilot.txt deleted file mode 100644 index 48b2ddb3115ca0..00000000000000 --- a/requirements_openpilot.txt +++ /dev/null @@ -1,68 +0,0 @@ -# This are the packages installed on the EON --e git+https://github.com/commaai/le_python.git@5eef8f5be5929d33973e1b10e686fa0cdcd6792f#egg=Logentries --e git+https://github.com/commaai/python-overpy.git@f86529af402d4642e1faeb146671c40284007323#egg=overpy -Cython==0.27.3 -Flask==1.0.2 -#PyGObject==3.28.2 This is installed on the EON, but requires a ton of dependencies to install -PyYAML==3.12 -appdirs==1.4.0 -atomicwrites==1.1.5 -attrs==16.0.0 -bitstring==3.1.5 -capnpy==0.4.2 -certifi==2016.8.31 -cffi==1.11.5 -contextlib2==0.5.4 -crc16==0.1.1 -crcmod==1.7 -cryptography==1.4 -cycler==0.10.0 -decorator==4.0.10 -docopt==0.6.2 -enum34==1.1.6 -evdev==0.6.1 -fastcluster==1.1.20 -filterpy==1.2.4 -ipaddress==1.0.16 -json-rpc==1.12.1 -libusb1==1.5.0 -lmdb==0.92 -mpmath==1.0.0 -nose==1.3.7 -numpy==1.11.1 -pause==0.1.2 -py==1.4.31 -pyOpenSSL==16.0.0 -pyasn1-modules==0.0.8 -pyasn1==0.1.9 -pycapnp==0.6.3 -pycparser==2.18 -pycrypto==2.6.1 -pyflakes==1.6.0 -pyopencl==2016.1 -pyparsing==2.1.10 -#pypcap==1.1.5 needs extra dependencies and is not used -pyproj==1.9.5.1 -pypytools==0.4.3 -pyserial==3.1.1 -pytest==2.9.2 -python-dateutil==2.6.0 -pytools==2016.2.1 -pytz==2016.10 -pyyaml==3.12 -pyzmq==15.4.0 -raven==5.23.0 -recordclass==0.4.1 -requests==2.10.0 -scipy==0.19.1 -service-identity==16.0.0 -setproctitle==1.1.10 -simplejson==3.8.2 -six==1.10.0 -smbus-cffi==0.5.1 -smbus2==0.2.0 -sympy==1.1.1 -tqdm==4.23.1 -ujson==1.35 -v4l2==0.2 -websocket_client==0.55.0 diff --git a/run_docker_tests.sh b/run_docker_tests.sh index a153aac73b53c5..caf6299a6310ff 100755 --- a/run_docker_tests.sh +++ b/run_docker_tests.sh @@ -1,8 +1,19 @@ #!/bin/bash set -e +SETUP="cd /tmp/openpilot && make -C cereal && " + docker build -t tmppilot -f Dockerfile.openpilot . -docker run --rm \ - -v "$(pwd)"/selfdrive/test/tests/plant/out:/tmp/openpilot/selfdrive/test/tests/plant/out \ - tmppilot /bin/sh -c 'cd /tmp/openpilot/selfdrive/test/tests/plant && OPTEST=1 ./test_longitudinal.py' + +docker run --rm tmppilot /bin/sh -c "$SETUP cd /tmp/openpilot/selfdrive/test/ && ./test_fingerprints.py" +docker run --rm tmppilot /bin/sh -c 'cd /tmp/openpilot/ && flake8 --select=F $(find . -iname "*.py" | grep -vi "^\./pyextra.*" | grep -vi "^\./panda" | grep -vi "^\./tools")' +docker run --rm tmppilot /bin/sh -c 'cd /tmp/openpilot/ && pylint $(find . -iname "*.py" | grep -vi "^\./pyextra.*" | grep -vi "^\./panda" | grep -vi "^\./tools"); exit $(($? & 3))' +docker run --rm tmppilot /bin/sh -c "$SETUP python -m unittest discover common" +docker run --rm tmppilot /bin/sh -c "$SETUP make -C selfdrive/can -j4 && python -m unittest discover selfdrive/can" +docker run --rm tmppilot /bin/sh -c "$SETUP python -m unittest discover selfdrive/boardd" +docker run --rm tmppilot /bin/sh -c "$SETUP make -C selfdrive/can -j4 && python -m unittest discover selfdrive/controls" +docker run --rm tmppilot /bin/sh -c "$SETUP python -m unittest discover selfdrive/loggerd" +docker run --rm -v "$(pwd)"/selfdrive/test/longitudinal_maneuvers/out:/tmp/openpilot/selfdrive/test/longitudinal_maneuvers/out tmppilot /bin/sh -c "$SETUP make -C selfdrive/can -j4 && cd /tmp/openpilot/selfdrive/test/longitudinal_maneuvers && OPTEST=1 ./test_longitudinal.py" +docker run --rm tmppilot /bin/sh -c "$SETUP make -C selfdrive/can -j4 && cd /tmp/openpilot/selfdrive/test/process_replay/ && ./test_processes.py" +docker run --rm tmppilot /bin/sh -c "$SETUP make -C selfdrive/can -j4 && mkdir -p /data/params && cd /tmp/openpilot/selfdrive/test/ && ./test_car_models.py" diff --git a/selfdrive/assets/Roboto-Bold.ttf b/selfdrive/assets/Roboto-Bold.ttf deleted file mode 100644 index a355c27cde02b1..00000000000000 Binary files a/selfdrive/assets/Roboto-Bold.ttf and /dev/null differ diff --git a/selfdrive/assets/courbd.ttf b/selfdrive/assets/fonts/courbd.ttf similarity index 100% rename from selfdrive/assets/courbd.ttf rename to selfdrive/assets/fonts/courbd.ttf diff --git a/selfdrive/assets/OpenSans-Bold.ttf b/selfdrive/assets/fonts/opensans_bold.ttf similarity index 100% rename from selfdrive/assets/OpenSans-Bold.ttf rename to selfdrive/assets/fonts/opensans_bold.ttf diff --git a/selfdrive/assets/OpenSans-Regular.ttf b/selfdrive/assets/fonts/opensans_regular.ttf similarity index 100% rename from selfdrive/assets/OpenSans-Regular.ttf rename to selfdrive/assets/fonts/opensans_regular.ttf diff --git a/selfdrive/assets/OpenSans-SemiBold.ttf b/selfdrive/assets/fonts/opensans_semibold.ttf similarity index 100% rename from selfdrive/assets/OpenSans-SemiBold.ttf rename to selfdrive/assets/fonts/opensans_semibold.ttf diff --git a/selfdrive/assets/sounds/disengaged.wav b/selfdrive/assets/sounds/disengaged.wav index 958e08fd85b3e6..3aa8e51e690420 100644 Binary files a/selfdrive/assets/sounds/disengaged.wav and b/selfdrive/assets/sounds/disengaged.wav differ diff --git a/selfdrive/assets/sounds/engaged.wav b/selfdrive/assets/sounds/engaged.wav index c6c088e01c8b73..1451f937f32879 100644 Binary files a/selfdrive/assets/sounds/engaged.wav and b/selfdrive/assets/sounds/engaged.wav differ diff --git a/selfdrive/assets/sounds/error.wav b/selfdrive/assets/sounds/error.wav index 1ff0c540d26ab0..e805181aeb6374 100644 Binary files a/selfdrive/assets/sounds/error.wav and b/selfdrive/assets/sounds/error.wav differ diff --git a/selfdrive/assets/sounds/warning_1.wav b/selfdrive/assets/sounds/warning_1.wav index 67b8d76fe804fa..43ca74cc5cbfa2 100644 Binary files a/selfdrive/assets/sounds/warning_1.wav and b/selfdrive/assets/sounds/warning_1.wav differ diff --git a/selfdrive/assets/sounds/warning_2.wav b/selfdrive/assets/sounds/warning_2.wav index 8e1b1d7d9161a7..e9709d9fdb7b26 100644 Binary files a/selfdrive/assets/sounds/warning_2.wav and b/selfdrive/assets/sounds/warning_2.wav differ diff --git a/selfdrive/assets/sounds/warning_repeat.wav b/selfdrive/assets/sounds/warning_repeat.wav new file mode 100644 index 00000000000000..fbde4f933cf32d Binary files /dev/null and b/selfdrive/assets/sounds/warning_repeat.wav differ diff --git a/selfdrive/athena/athenad.py b/selfdrive/athena/athenad.py old mode 100755 new mode 100644 index f6f9ef231acb2d..d3b98e71314798 --- a/selfdrive/athena/athenad.py +++ b/selfdrive/athena/athenad.py @@ -1,28 +1,37 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python3.7 import json import os +import io import random +import re +import select +import subprocess +import socket import time import threading import traceback -import zmq -import Queue +import base64 +import requests +import queue +from functools import partial from jsonrpc import JSONRPCResponseManager, dispatcher -from websocket import create_connection, WebSocketTimeoutException +from websocket import create_connection, WebSocketTimeoutException, ABNF +from selfdrive.loggerd.config import ROOT -import selfdrive.crash as crash import selfdrive.messaging as messaging +from common.api import Api from common.params import Params from selfdrive.services import service_list from selfdrive.swaglog import cloudlog -from selfdrive.version import version, dirty +from functools import reduce ATHENA_HOST = os.getenv('ATHENA_HOST', 'wss://athena.comma.ai') HANDLER_THREADS = os.getenv('HANDLER_THREADS', 4) +LOCAL_PORT_WHITELIST = set([8022]) dispatcher["echo"] = lambda s: s -payload_queue = Queue.Queue() -response_queue = Queue.Queue() +payload_queue = queue.Queue() +response_queue = queue.Queue() def handle_long_poll(ws): end_event = threading.Event() @@ -32,10 +41,11 @@ def handle_long_poll(ws): threading.Thread(target=ws_send, args=(ws, end_event)) ] + [ threading.Thread(target=jsonrpc_handler, args=(end_event,)) - for x in xrange(HANDLER_THREADS) + for x in range(HANDLER_THREADS) ] - map(lambda thread: thread.start(), threads) + for thread in threads: + thread.start() try: while not end_event.is_set(): time.sleep(0.1) @@ -47,12 +57,13 @@ def handle_long_poll(ws): thread.join() def jsonrpc_handler(end_event): + dispatcher["startLocalProxy"] = partial(startLocalProxy, end_event) while not end_event.is_set(): try: data = payload_queue.get(timeout=1) response = JSONRPCResponseManager.handle(data, dispatcher) response_queue.put_nowait(response) - except Queue.Empty: + except queue.Empty: pass except Exception as e: cloudlog.exception("athena jsonrpc handler failed") @@ -63,14 +74,143 @@ def jsonrpc_handler(end_event): # TODO: add service to, for example, start visiond and take a picture @dispatcher.add_method def getMessage(service=None, timeout=1000): - context = zmq.Context() if service is None or service not in service_list: raise Exception("invalid service") - socket = messaging.sub_sock(context, service_list[service].port) - socket.setsockopt(zmq.RCVTIMEO, timeout) + socket = messaging.sub_sock(service) + socket.setTimeout(timeout) ret = messaging.recv_one(socket) return ret.to_dict() +@dispatcher.add_method +def listDataDirectory(): + files = [os.path.relpath(os.path.join(dp, f), ROOT) for dp, dn, fn in os.walk(ROOT) for f in fn] + return files + +@dispatcher.add_method +def uploadFileToUrl(fn, url, headers): + if len(fn) == 0 or fn[0] == '/' or '..' in fn: + return 500 + with open(os.path.join(ROOT, fn), "rb") as f: + ret = requests.put(url, data=f, headers=headers, timeout=10) + return ret.status_code + +def startLocalProxy(global_end_event, remote_ws_uri, local_port): + try: + if local_port not in LOCAL_PORT_WHITELIST: + raise Exception("Requested local port not whitelisted") + + params = Params() + dongle_id = params.get("DongleId").decode('utf8') + identity_token = Api(dongle_id).get_token() + ws = create_connection(remote_ws_uri, + cookie="jwt=" + identity_token, + enable_multithread=True) + + ssock, csock = socket.socketpair() + local_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + local_sock.connect(('127.0.0.1', local_port)) + local_sock.setblocking(0) + + proxy_end_event = threading.Event() + threads = [ + threading.Thread(target=ws_proxy_recv, args=(ws, local_sock, ssock, proxy_end_event, global_end_event)), + threading.Thread(target=ws_proxy_send, args=(ws, local_sock, csock, proxy_end_event)) + ] + for thread in threads: + thread.start() + + return {"success": 1} + except Exception as e: + traceback.print_exc() + raise e + +@dispatcher.add_method +def getPublicKey(): + if not os.path.isfile('/persist/comma/id_rsa.pub'): + return None + + with open('/persist/comma/id_rsa.pub', 'r') as f: + return f.read() + +@dispatcher.add_method +def getSshAuthorizedKeys(): + return Params().get("GithubSshKeys", encoding='utf8') or '' + +@dispatcher.add_method +def getSimInfo(): + sim_state = subprocess.check_output(['getprop', 'gsm.sim.state'], encoding='utf8').strip().split(',') # pylint: disable=unexpected-keyword-arg + network_type = subprocess.check_output(['getprop', 'gsm.network.type'], encoding='utf8').strip().split(',') # pylint: disable=unexpected-keyword-arg + mcc_mnc = subprocess.check_output(['getprop', 'gsm.sim.operator.numeric'], encoding='utf8').strip() or None # pylint: disable=unexpected-keyword-arg + + sim_id_aidl_out = subprocess.check_output(['service', 'call', 'iphonesubinfo', '11'], encoding='utf8') # pylint: disable=unexpected-keyword-arg + sim_id_aidl_lines = sim_id_aidl_out.split('\n') + if len(sim_id_aidl_lines) > 3: + sim_id_lines = sim_id_aidl_lines[1:4] + sim_id_fragments = [re.search(r"'([0-9\.]+)'", line).group(1) for line in sim_id_lines] + sim_id = reduce(lambda frag1, frag2: frag1.replace('.', '') + frag2.replace('.', ''), sim_id_fragments) + else: + sim_id = None + + return { + 'sim_id': sim_id, + 'mcc_mnc': mcc_mnc, + 'network_type': network_type, + 'sim_state': sim_state + } + +@dispatcher.add_method +def takeSnapshot(): + from selfdrive.visiond.snapshot.snapshot import snapshot, jpeg_write + ret = snapshot() + if ret is not None: + def b64jpeg(x): + if x is not None: + f = io.BytesIO() + jpeg_write(f, x) + return base64.b64encode(f.getvalue()).decode("utf-8") + else: + return None + return {'jpegBack': b64jpeg(ret[0]), + 'jpegFront': b64jpeg(ret[1])} + else: + raise Exception("not available while visiond is started") + +def ws_proxy_recv(ws, local_sock, ssock, end_event, global_end_event): + while not (end_event.is_set() or global_end_event.is_set()): + try: + data = ws.recv() + local_sock.sendall(data) + except WebSocketTimeoutException: + pass + except Exception: + cloudlog.exception("athenad.ws_proxy_recv.exception") + traceback.print_exc() + break + + ssock.close() + end_event.set() + +def ws_proxy_send(ws, local_sock, signal_sock, end_event): + while not end_event.is_set(): + try: + r, _, _ = select.select((local_sock, signal_sock), (), ()) + if r: + if r[0].fileno() == signal_sock.fileno(): + # got end signal from ws_proxy_recv + end_event.set() + break + data = local_sock.recv(4096) + if not data: + # local_sock is dead + end_event.set() + break + + ws.send(data, ABNF.OPCODE_BINARY) + except Exception: + cloudlog.exception("athenad.ws_proxy_send.exception") + traceback.print_exc() + end_event.set() + def ws_recv(ws, end_event): while not end_event.is_set(): try: @@ -79,6 +219,7 @@ def ws_recv(ws, end_event): except WebSocketTimeoutException: pass except Exception: + cloudlog.exception("athenad.ws_recv.exception") traceback.print_exc() end_event.set() @@ -87,9 +228,10 @@ def ws_send(ws, end_event): try: response = response_queue.get(timeout=1) ws.send(response.json) - except Queue.Empty: + except queue.Empty: pass except Exception: + cloudlog.exception("athenad.ws_send.exception") traceback.print_exc() end_event.set() @@ -98,27 +240,25 @@ def backoff(retries): def main(gctx=None): params = Params() - dongle_id = params.get("DongleId") - access_token = params.get("AccessToken") - ws_uri = ATHENA_HOST + "/ws/" + dongle_id + dongle_id = params.get("DongleId").decode('utf-8') + ws_uri = ATHENA_HOST + "/ws/v2/" + dongle_id - crash.bind_user(id=dongle_id) - crash.bind_extra(version=version, dirty=dirty, is_eon=True) - crash.install() + api = Api(dongle_id) conn_retries = 0 while 1: try: - print("connecting to %s" % ws_uri) ws = create_connection(ws_uri, - cookie="jwt=" + access_token, + cookie="jwt=" + api.get_token(), enable_multithread=True) + cloudlog.event("athenad.main.connected_ws", ws_uri=ws_uri) ws.settimeout(1) conn_retries = 0 handle_long_poll(ws) except (KeyboardInterrupt, SystemExit): break except Exception: + cloudlog.exception("athenad.main.exception") conn_retries += 1 traceback.print_exc() diff --git a/selfdrive/athena/manage_athenad.py b/selfdrive/athena/manage_athenad.py new file mode 100644 index 00000000000000..034bfac5cb0dad --- /dev/null +++ b/selfdrive/athena/manage_athenad.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 + +import time +from multiprocessing import Process + +import selfdrive.crash as crash +from common.params import Params +from selfdrive.manager import launcher +from selfdrive.swaglog import cloudlog +from selfdrive.version import version, dirty + +ATHENA_MGR_PID_PARAM = "AthenadPid" + +def main(): + params = Params() + dongle_id = params.get("DongleId").decode('utf-8') + cloudlog.bind_global(dongle_id=dongle_id, version=version, dirty=dirty, is_eon=True) + crash.bind_user(id=dongle_id) + crash.bind_extra(version=version, dirty=dirty, is_eon=True) + crash.install() + + try: + while 1: + cloudlog.info("starting athena daemon") + proc = Process(name='athenad', target=launcher, args=('selfdrive.athena.athenad',)) + proc.start() + proc.join() + cloudlog.event("athenad exited", exitcode=proc.exitcode) + time.sleep(5) + except: + cloudlog.exception("manage_athenad.exception") + finally: + params.delete(ATHENA_MGR_PID_PARAM) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/selfdrive/boardd/Makefile b/selfdrive/boardd/Makefile index 893edde545b848..f9d0155c6f27f1 100644 --- a/selfdrive/boardd/Makefile +++ b/selfdrive/boardd/Makefile @@ -16,14 +16,12 @@ WARN_FLAGS = -Werror=implicit-function-declaration \ CFLAGS = -std=gnu11 -g -fPIC -I../ -I../../ -O2 $(WARN_FLAGS) CXXFLAGS = -std=c++11 -g -fPIC -I../ -I../../ -O2 $(WARN_FLAGS) -ZMQ_FLAGS = -I$(PHONELIBS)/zmq/aarch64/include -ZMQ_LIBS = -L$(PHONELIBS)/zmq/aarch64/lib \ - -l:libczmq.a -l:libzmq.a \ - -lgnustl_shared +MESSAGING_FLAGS = -I$(BASEDIR)/selfdrive/messaging +MESSAGING_LIBS = $(BASEDIR)/selfdrive/messaging/messaging.a JSON_FLAGS = -I$(PHONELIBS)/json/src -EXTRA_LIBS = -lusb +EXTRA_LIBS = -lusb-1.0 # ifeq ($(OS),GNU/Linux) # # for Drive PX2 @@ -31,10 +29,15 @@ EXTRA_LIBS = -lusb # CEREAL_LIBS = -lcapnp -lkj -lcapnp_c # EXTRA_LIBS = -lusb-1.0 -lpthread # endif +ifeq ($(ARCH),aarch64) +CFLAGS += -mcpu=cortex-a57 +CXXFLAGS += -mcpu=cortex-a57 +EXTRA_LIBS += -lgnustl_shared +endif + ifeq ($(ARCH),x86_64) -ZMQ_LIBS = -L$(BASEDIR)/external/zmq/lib/ \ - -l:libczmq.a -l:libzmq.a +ZMQ_FLAGS = -I$(PHONELIBS)/zmq/aarch64/include EXTRA_LIBS = -lusb-1.0 -lpthread CXXFLAGS += -I/usr/include/libusb-1.0 CFLAGS += -I/usr/include/libusb-1.0 @@ -46,6 +49,7 @@ all: boardd include ../common/cereal.mk OBJS = boardd.o \ + can_list_to_can_capnp.o \ ../common/swaglog.o \ ../common/params.o \ ../common/util.o \ @@ -54,24 +58,33 @@ OBJS = boardd.o \ DEPS := $(OBJS:.o=.d) -boardd: $(OBJS) +boardd: $(OBJS) $(MESSAGING_LIBS) @echo "[ LINK ] $@" $(CXX) -fPIC -o '$@' $^ \ $(CEREAL_LIBS) \ - $(ZMQ_LIBS) \ $(EXTRA_LIBS) boardd.o: boardd.cc @echo "[ CXX ] $@" - $(CXX) $(CXXFLAGS) \ + $(CXX) $(CXXFLAGS) -MMD \ -I$(PHONELIBS)/android_system_core/include \ $(CEREAL_CFLAGS) \ $(CEREAL_CXXFLAGS) \ $(ZMQ_FLAGS) \ + $(MESSAGING_FLAGS) \ -I../ \ -I../../ \ -c -o '$@' '$<' + +boardd_api_impl.so: libcan_list_to_can_capnp.a boardd_api_impl.pyx boardd_setup.py + python3 boardd_setup.py build_ext --inplace + rm -rf build + rm -f boardd_api_impl.cpp + +libcan_list_to_can_capnp.a: can_list_to_can_capnp.o $(CEREAL_OBJS) + ar rcsD '$@' $^ + %.o: %.c @echo "[ CC ] $@" $(CC) $(CFLAGS) -MMD \ @@ -81,8 +94,17 @@ boardd.o: boardd.cc $(JSON_FLAGS) \ -c -o '$@' '$<' +%.o: %.cc + @echo "[ CC ] $@" + $(CXX) $(CXXFLAGS) -MMD \ + -Iinclude -I.. -I../.. \ + $(CEREAL_CXXFLAGS) \ + $(ZMQ_FLAGS) \ + $(MESSAGING_FLAGS) \ + -c -o '$@' '$<' + .PHONY: clean clean: - rm -f boardd $(OBJS) $(DEPS) + rm -f boardd libcan_list_to_can_capnp.a boardd_api_impl.so $(OBJS) $(DEPS) -include $(DEPS) diff --git a/selfdrive/boardd/boardd.cc b/selfdrive/boardd/boardd.cc index dd89d4d6d48bda..b94bf3a3ed23f4 100644 --- a/selfdrive/boardd/boardd.cc +++ b/selfdrive/boardd/boardd.cc @@ -1,11 +1,12 @@ #include +#include #include #include #include #include #include #include -#include +#include #include #include #include @@ -14,16 +15,17 @@ #include #include -#include -#include +#include #include #include "cereal/gen/cpp/log.capnp.h" #include "cereal/gen/cpp/car.capnp.h" +#include "common/messaging.h" #include "common/params.h" #include "common/swaglog.h" #include "common/timing.h" +#include "messaging.hpp" #include @@ -31,26 +33,19 @@ #define RECV_SIZE (0x1000) #define TIMEOUT 0 -#define SAFETY_NOOUTPUT 0 -#define SAFETY_HONDA 1 -#define SAFETY_TOYOTA 2 -#define SAFETY_ELM327 0xE327 -#define SAFETY_GM 3 -#define SAFETY_HONDA_BOSCH 4 -#define SAFETY_FORD 5 -#define SAFETY_CADILLAC 6 -#define SAFETY_HYUNDAI 7 -#define SAFETY_TESLA 8 -#define SAFETY_CHRYSLER 9 -#define SAFETY_SUBARU 10 -#define SAFETY_TOYOTA_IPAS 0x1335 -#define SAFETY_TOYOTA_NOLIMITS 0x1336 -#define SAFETY_ALLOUTPUT 0x1337 -#define SAFETY_ELM327 0xE327 - namespace { -volatile int do_exit = 0; +volatile sig_atomic_t do_exit = 0; + +struct __attribute__((packed)) timestamp_t { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t weekday; + uint8_t hour; + uint8_t minute; + uint8_t second; +}; libusb_context *ctx = NULL; libusb_device_handle *dev_handle; @@ -59,7 +54,12 @@ pthread_mutex_t usb_lock; bool spoofing_started = false; bool fake_send = false; bool loopback_can = false; -bool is_grey_panda = false; +cereal::HealthData::HwType hw_type = cereal::HealthData::HwType::UNKNOWN; +bool is_pigeon = false; +const uint32_t NO_IGNITION_CNT_MAX = 2 * 60 * 60 * 24 * 3; // turn off charge after 3 days +uint32_t no_ignition_cnt = 0; +bool connected_once = false; +bool ignition_last = false; pthread_t safety_setter_thread_handle = -1; pthread_t pigeon_thread_handle = -1; @@ -69,6 +69,27 @@ void pigeon_init(); void *pigeon_thread(void *crap); void *safety_setter_thread(void *s) { + char *value_vin; + size_t value_vin_sz = 0; + + // switch to no_output when CarVin param is read + while (1) { + if (do_exit) return NULL; + const int result = read_db_value(NULL, "CarVin", &value_vin, &value_vin_sz); + if (value_vin_sz > 0) { + // sanity check VIN format + assert(value_vin_sz == 17); + break; + } + usleep(100*1000); + } + LOGW("got CarVin %s", value_vin); + + // VIN query done, stop listening to OBDII + pthread_mutex_lock(&usb_lock); + libusb_control_transfer(dev_handle, 0x40, 0xdc, (uint16_t)(cereal::CarParams::SafetyModel::NO_OUTPUT), 0, NULL, 0, TIMEOUT); + pthread_mutex_unlock(&usb_lock); + char *value; size_t value_sz = 0; @@ -85,59 +106,24 @@ void *safety_setter_thread(void *s) { // format for board, make copy due to alignment issues, will be freed on out of scope auto amsg = kj::heapArray((value_sz / sizeof(capnp::word)) + 1); memcpy(amsg.begin(), value, value_sz); + free(value); capnp::FlatArrayMessageReader cmsg(amsg); cereal::CarParams::Reader car_params = cmsg.getRoot(); - auto safety_model = car_params.getSafetyModel(); + int safety_model = int(car_params.getSafetyModel()); auto safety_param = car_params.getSafetyParam(); LOGW("setting safety model: %d with param %d", safety_model, safety_param); - int safety_setting = 0; - switch (safety_model) { - case (int)cereal::CarParams::SafetyModels::NO_OUTPUT: - safety_setting = SAFETY_NOOUTPUT; - break; - case (int)cereal::CarParams::SafetyModels::HONDA: - safety_setting = SAFETY_HONDA; - break; - case (int)cereal::CarParams::SafetyModels::TOYOTA: - safety_setting = SAFETY_TOYOTA; - break; - case (int)cereal::CarParams::SafetyModels::ELM327: - safety_setting = SAFETY_ELM327; - break; - case (int)cereal::CarParams::SafetyModels::GM: - safety_setting = SAFETY_GM; - break; - case (int)cereal::CarParams::SafetyModels::HONDA_BOSCH: - safety_setting = SAFETY_HONDA_BOSCH; - break; - case (int)cereal::CarParams::SafetyModels::FORD: - safety_setting = SAFETY_FORD; - break; - case (int)cereal::CarParams::SafetyModels::CADILLAC: - safety_setting = SAFETY_CADILLAC; - break; - case (int)cereal::CarParams::SafetyModels::HYUNDAI: - safety_setting = SAFETY_HYUNDAI; - break; - case (int)cereal::CarParams::SafetyModels::CHRYSLER: - safety_setting = SAFETY_CHRYSLER; - break; - case (int)cereal::CarParams::SafetyModels::SUBARU: - safety_setting = SAFETY_SUBARU; - break; - default: - LOGE("unknown safety model: %d", safety_model); - } - pthread_mutex_lock(&usb_lock); // set in the mutex to avoid race safety_setter_thread_handle = -1; - libusb_control_transfer(dev_handle, 0x40, 0xdc, safety_setting, safety_param, NULL, 0, TIMEOUT); + // set if long_control is allowed by openpilot. Hardcoded to True for now + libusb_control_transfer(dev_handle, 0x40, 0xdf, 1, 0, NULL, 0, TIMEOUT); + + libusb_control_transfer(dev_handle, 0x40, 0xdc, safety_model, safety_param, NULL, 0, TIMEOUT); pthread_mutex_unlock(&usb_lock); @@ -147,7 +133,15 @@ void *safety_setter_thread(void *s) { // must be called before threads or with mutex bool usb_connect() { int err; - unsigned char is_pigeon[1] = {0}; + unsigned char hw_query[1] = {0}; + unsigned char fw_ver_buf[64]; + unsigned char serial_buf[16]; + const char *fw_ver; + const char *serial; + int fw_ver_sz = 0; + int serial_sz = 0; + + ignition_last = false; dev_handle = libusb_open_device_with_vid_pid(ctx, 0xbbaa, 0xddcc); if (dev_handle == NULL) { goto fail; } @@ -162,33 +156,46 @@ bool usb_connect() { libusb_control_transfer(dev_handle, 0xc0, 0xe5, 1, 0, NULL, 0, TIMEOUT); } - // power off ESP - libusb_control_transfer(dev_handle, 0xc0, 0xd9, 0, 0, NULL, 0, TIMEOUT); + // get panda fw + err = libusb_control_transfer(dev_handle, 0xc0, 0xd6, 0, 0, fw_ver_buf, 64, TIMEOUT); + if (err > 0) { + fw_ver = (const char *)fw_ver_buf; + fw_ver_sz = err; + write_db_value(NULL, "PandaFirmware", fw_ver, fw_ver_sz); + printf("panda fw: %.*s\n", fw_ver_sz, fw_ver); + } + else { goto fail; } - // power on charging (may trigger a reconnection, should be okay) - #ifndef __x86_64__ - libusb_control_transfer(dev_handle, 0xc0, 0xe6, 1, 0, NULL, 0, TIMEOUT); - #else - LOGW("not enabling charging on x86_64"); - #endif + // get panda serial + err = libusb_control_transfer(dev_handle, 0xc0, 0xd0, 0, 0, serial_buf, 16, TIMEOUT); - // no output is the default - if (getenv("RECVMOCK")) { - libusb_control_transfer(dev_handle, 0x40, 0xdc, SAFETY_ELM327, 0, NULL, 0, TIMEOUT); - } else { - libusb_control_transfer(dev_handle, 0x40, 0xdc, SAFETY_NOOUTPUT, 0, NULL, 0, TIMEOUT); + if (err > 0) { + serial = (const char *)serial_buf; + serial_sz = strnlen(serial, err); + write_db_value(NULL, "PandaDongleId", serial, serial_sz); + printf("panda serial: %.*s\n", serial_sz, serial); } + else { goto fail; } - if (safety_setter_thread_handle == -1) { - err = pthread_create(&safety_setter_thread_handle, NULL, safety_setter_thread, NULL); - assert(err == 0); + // power off ESP + libusb_control_transfer(dev_handle, 0xc0, 0xd9, 0, 0, NULL, 0, TIMEOUT); + + // power on charging, only the first time. Panda can also change mode and it causes a brief disconneciton +#ifndef __x86_64__ + if (!connected_once) { + libusb_control_transfer(dev_handle, 0xc0, 0xe6, (uint16_t)(cereal::HealthData::UsbPowerMode::CDP), 0, NULL, 0, TIMEOUT); } +#endif + connected_once = true; - libusb_control_transfer(dev_handle, 0xc0, 0xc1, 0, 0, is_pigeon, 1, TIMEOUT); + libusb_control_transfer(dev_handle, 0xc0, 0xc1, 0, 0, hw_query, 1, TIMEOUT); - if (is_pigeon[0]) { - LOGW("grey panda detected"); - is_grey_panda = true; + hw_type = (cereal::HealthData::HwType)(hw_query[0]); + is_pigeon = (hw_type == cereal::HealthData::HwType::GREY_PANDA) || + (hw_type == cereal::HealthData::HwType::BLACK_PANDA) || + (hw_type == cereal::HealthData::HwType::UNO); + if (is_pigeon) { + LOGW("panda with gps detected"); pigeon_needs_init = true; if (pigeon_thread_handle == -1) { err = pthread_create(&pigeon_thread_handle, NULL, pigeon_thread, NULL); @@ -196,6 +203,38 @@ bool usb_connect() { } } + if (hw_type == cereal::HealthData::HwType::UNO){ + // Get time from system + time_t rawtime; + time(&rawtime); + + struct tm * sys_time = gmtime(&rawtime); + + // Get time from RTC + timestamp_t rtc_time; + libusb_control_transfer(dev_handle, 0xc0, 0xa0, 0, 0, (unsigned char*)&rtc_time, sizeof(rtc_time), TIMEOUT); + + //printf("System: %d-%d-%d\t%d:%d:%d\n", 1900 + sys_time->tm_year, 1 + sys_time->tm_mon, sys_time->tm_mday, sys_time->tm_hour, sys_time->tm_min, sys_time->tm_sec); + //printf("RTC: %d-%d-%d\t%d:%d:%d\n", rtc_time.year, rtc_time.month, rtc_time.day, rtc_time.hour, rtc_time.minute, rtc_time.second); + + // Update system time from RTC if it looks off, and RTC time is good + if (1900 + sys_time->tm_year < 2019 && rtc_time.year >= 2019){ + LOGE("System time wrong, setting from RTC"); + + struct tm new_time = { 0 }; + new_time.tm_year = rtc_time.year - 1900; + new_time.tm_mon = rtc_time.month - 1; + new_time.tm_mday = rtc_time.day; + new_time.tm_hour = rtc_time.hour; + new_time.tm_min = rtc_time.minute; + new_time.tm_sec = rtc_time.second; + + setenv("TZ","UTC",1); + const struct timeval tv = {mktime(&new_time), 0}; + settimeofday(&tv, 0); + } + } + return true; fail: return false; @@ -216,12 +255,14 @@ void handle_usb_issue(int err, const char func[]) { // TODO: check other errors, is simply retrying okay? } -void can_recv(void *s) { +void can_recv(PubSocket *publisher) { int err; uint32_t data[RECV_SIZE/4]; int recv; uint32_t f1, f2; + uint64_t start_time = nanos_since_boot(); + // do recv pthread_mutex_lock(&usb_lock); @@ -244,12 +285,13 @@ void can_recv(void *s) { // create message capnp::MallocMessageBuilder msg; cereal::Event::Builder event = msg.initRoot(); - event.setLogMonoTime(nanos_since_boot()); + event.setLogMonoTime(start_time); + size_t num_msg = recv / 0x10; - auto canData = event.initCan(recv/0x10); + auto canData = event.initCan(num_msg); // populate message - for (int i = 0; i<(recv/0x10); i++) { + for (int i = 0; i < num_msg; i++) { if (data[i*4] & 4) { // extended canData[i].setAddress(data[i*4] >> 3); @@ -267,21 +309,27 @@ void can_recv(void *s) { // send to can auto words = capnp::messageToFlatArray(msg); auto bytes = words.asBytes(); - zmq_send(s, bytes.begin(), bytes.size(), 0); + publisher->send((char*)bytes.begin(), bytes.size()); } -void can_health(void *s) { +void can_health(PubSocket *publisher) { int cnt; + int err; - // copied from board/main.c + // copied from panda/board/main.c struct __attribute__((packed)) health { uint32_t voltage; uint32_t current; - uint8_t started; + uint32_t can_send_errs; + uint32_t can_fwd_errs; + uint32_t gmlan_send_errs; + uint8_t ignition_line; + uint8_t ignition_can; uint8_t controls_allowed; uint8_t gas_interceptor_detected; - uint8_t started_signal_detected; - uint8_t started_alt; + uint8_t car_harness_status; + uint8_t usb_power_mode; + uint8_t safety_model; } health; // recv from board @@ -289,11 +337,80 @@ void can_health(void *s) { do { cnt = libusb_control_transfer(dev_handle, 0xc0, 0xd2, 0, 0, (unsigned char*)&health, sizeof(health), TIMEOUT); - if (cnt != sizeof(health)) { handle_usb_issue(cnt, __func__); } + if (cnt != sizeof(health)) { + handle_usb_issue(cnt, __func__); + } } while(cnt != sizeof(health)); pthread_mutex_unlock(&usb_lock); + bool ignition = ((health.ignition_line != 0) || (health.ignition_can != 0)); + + if (!ignition) { + no_ignition_cnt += 1; + } else { + no_ignition_cnt = 0; + } + +#ifndef __x86_64__ + if ((no_ignition_cnt > NO_IGNITION_CNT_MAX) && (health.usb_power_mode == (uint8_t)(cereal::HealthData::UsbPowerMode::CDP))) { + printf("TURN OFF CHARGING!\n"); + pthread_mutex_lock(&usb_lock); + libusb_control_transfer(dev_handle, 0xc0, 0xe6, (uint16_t)(cereal::HealthData::UsbPowerMode::CLIENT), 0, NULL, 0, TIMEOUT); + pthread_mutex_unlock(&usb_lock); + } +#endif + + // clear VIN, CarParams, and set new safety on car start + if (ignition && !ignition_last) { + + int result = delete_db_value(NULL, "CarVin"); + assert((result == 0) || (result == ERR_NO_VALUE)); + result = delete_db_value(NULL, "CarParams"); + assert((result == 0) || (result == ERR_NO_VALUE)); + + // diagnostic only is the default, needed for VIN query + pthread_mutex_lock(&usb_lock); + libusb_control_transfer(dev_handle, 0x40, 0xdc, (uint16_t)(cereal::CarParams::SafetyModel::ELM327), 0, NULL, 0, TIMEOUT); + pthread_mutex_unlock(&usb_lock); + + if (safety_setter_thread_handle == -1) { + err = pthread_create(&safety_setter_thread_handle, NULL, safety_setter_thread, NULL); + assert(err == 0); + } + } + + // Get fan RPM + uint16_t fan_speed_rpm = 0; + + pthread_mutex_lock(&usb_lock); + int sz = libusb_control_transfer(dev_handle, 0xc0, 0xb2, 0, 0, (unsigned char*)&fan_speed_rpm, sizeof(fan_speed_rpm), TIMEOUT); + pthread_mutex_unlock(&usb_lock); + + // Write to rtc once per minute when no ignition present + if ((hw_type == cereal::HealthData::HwType::UNO) && !ignition && (no_ignition_cnt % 120 == 1)){ + // Get time from system + time_t rawtime; + time(&rawtime); + + struct tm * sys_time = gmtime(&rawtime); + + // Write time to RTC if it looks reasonable + if (1900 + sys_time->tm_year >= 2019){ + pthread_mutex_lock(&usb_lock); + libusb_control_transfer(dev_handle, 0x40, 0xa1, (uint16_t)(1900 + sys_time->tm_year), 0, NULL, 0, TIMEOUT); + libusb_control_transfer(dev_handle, 0x40, 0xa2, (uint16_t)(1 + sys_time->tm_mon), 0, NULL, 0, TIMEOUT); + libusb_control_transfer(dev_handle, 0x40, 0xa3, (uint16_t)sys_time->tm_mday, 0, NULL, 0, TIMEOUT); + // libusb_control_transfer(dev_handle, 0x40, 0xa4, (uint16_t)(1 + sys_time->tm_wday), 0, NULL, 0, TIMEOUT); + libusb_control_transfer(dev_handle, 0x40, 0xa5, (uint16_t)sys_time->tm_hour, 0, NULL, 0, TIMEOUT); + libusb_control_transfer(dev_handle, 0x40, 0xa6, (uint16_t)sys_time->tm_min, 0, NULL, 0, TIMEOUT); + libusb_control_transfer(dev_handle, 0x40, 0xa7, (uint16_t)sys_time->tm_sec, 0, NULL, 0, TIMEOUT); + pthread_mutex_unlock(&usb_lock); + } + } + + ignition_last = ignition; + // create message capnp::MallocMessageBuilder msg; cereal::Event::Builder event = msg.initRoot(); @@ -304,40 +421,50 @@ void can_health(void *s) { healthData.setVoltage(health.voltage); healthData.setCurrent(health.current); if (spoofing_started) { - healthData.setStarted(1); + healthData.setIgnitionLine(1); } else { - healthData.setStarted(health.started); + healthData.setIgnitionLine(health.ignition_line); } + healthData.setIgnitionCan(health.ignition_can); healthData.setControlsAllowed(health.controls_allowed); healthData.setGasInterceptorDetected(health.gas_interceptor_detected); - healthData.setStartedSignalDetected(health.started_signal_detected); - healthData.setIsGreyPanda(is_grey_panda); + healthData.setHasGps(is_pigeon); + healthData.setCanSendErrs(health.can_send_errs); + healthData.setCanFwdErrs(health.can_fwd_errs); + healthData.setGmlanSendErrs(health.gmlan_send_errs); + healthData.setHwType(hw_type); + healthData.setUsbPowerMode(cereal::HealthData::UsbPowerMode(health.usb_power_mode)); + healthData.setSafetyModel(cereal::CarParams::SafetyModel(health.safety_model)); + healthData.setFanSpeedRpm(fan_speed_rpm); // send to health auto words = capnp::messageToFlatArray(msg); auto bytes = words.asBytes(); - zmq_send(s, bytes.begin(), bytes.size(), 0); + publisher->send((char*)bytes.begin(), bytes.size()); + + pthread_mutex_lock(&usb_lock); + + // send heartbeat back to panda + libusb_control_transfer(dev_handle, 0x40, 0xf3, 1, 0, NULL, 0, TIMEOUT); + + pthread_mutex_unlock(&usb_lock); } -void can_send(void *s) { +void can_send(SubSocket *subscriber) { int err; // recv from sendcan - zmq_msg_t msg; - zmq_msg_init(&msg); - err = zmq_msg_recv(&msg, s, 0); - assert(err >= 0); + Message * msg = subscriber->receive(); - // format for board, make copy due to alignment issues, will be freed on out of scope - auto amsg = kj::heapArray((zmq_msg_size(&msg) / sizeof(capnp::word)) + 1); - memcpy(amsg.begin(), zmq_msg_data(&msg), zmq_msg_size(&msg)); + auto amsg = kj::heapArray((msg->getSize() / sizeof(capnp::word)) + 1); + memcpy(amsg.begin(), msg->getData(), msg->getSize()); capnp::FlatArrayMessageReader cmsg(amsg); cereal::Event::Reader event = cmsg.getRoot(); if (nanos_since_boot() - event.getLogMonoTime() > 1e9) { //Older than 1 second. Dont send. - zmq_msg_close(&msg); + delete msg; return; } int msg_count = event.getCan().size(); @@ -360,7 +487,7 @@ void can_send(void *s) { } // release msg - zmq_msg_close(&msg); + delete msg; // send to board int sent; @@ -379,66 +506,23 @@ void can_send(void *s) { free(send); } - // **** threads **** -void *thermal_thread(void *crap) { - int err; - LOGD("start thermal thread"); - - // thermal = 8005 - void *context = zmq_ctx_new(); - void *subscriber = zmq_socket(context, ZMQ_SUB); - zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0); - zmq_connect(subscriber, "tcp://127.0.0.1:8005"); - - // run as fast as messages come in - while (!do_exit) { - // recv from thermal - zmq_msg_t msg; - zmq_msg_init(&msg); - err = zmq_msg_recv(&msg, subscriber, 0); - assert(err >= 0); - - // format for board, make copy due to alignment issues, will be freed on out of scope - // copied from send thread... - auto amsg = kj::heapArray((zmq_msg_size(&msg) / sizeof(capnp::word)) + 1); - memcpy(amsg.begin(), zmq_msg_data(&msg), zmq_msg_size(&msg)); - - capnp::FlatArrayMessageReader cmsg(amsg); - cereal::Event::Reader event = cmsg.getRoot(); - - uint16_t target_fan_speed = event.getThermal().getFanSpeed(); - //LOGW("setting fan speed %d", target_fan_speed); - - pthread_mutex_lock(&usb_lock); - libusb_control_transfer(dev_handle, 0xc0, 0xd3, target_fan_speed, 0, NULL, 0, TIMEOUT); - pthread_mutex_unlock(&usb_lock); - - zmq_msg_close(&msg); - } - - // turn the fan off when we exit - libusb_control_transfer(dev_handle, 0xc0, 0xd3, 0, 0, NULL, 0, TIMEOUT); - - return NULL; -} - void *can_send_thread(void *crap) { LOGD("start send thread"); // sendcan = 8017 - void *context = zmq_ctx_new(); - void *subscriber = zmq_socket(context, ZMQ_SUB); - zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0); - zmq_connect(subscriber, "tcp://127.0.0.1:8017"); + Context * context = Context::create(); + SubSocket * subscriber = SubSocket::create(context, "sendcan"); + // drain sendcan to delete any stale messages from previous runs - zmq_msg_t msg; - zmq_msg_init(&msg); - int err = 0; - while(err >= 0) { - err = zmq_msg_recv(&msg, subscriber, ZMQ_DONTWAIT); + while (true){ + Message * msg = subscriber->receive(true); + if (msg == NULL){ + break; + } + delete msg; } // run as fast as messages come in @@ -452,35 +536,108 @@ void *can_recv_thread(void *crap) { LOGD("start recv thread"); // can = 8006 - void *context = zmq_ctx_new(); - void *publisher = zmq_socket(context, ZMQ_PUB); - zmq_bind(publisher, "tcp://*:8006"); + Context * c = Context::create(); + PubSocket * publisher = PubSocket::create(c, "can"); + + // run at 100hz + const uint64_t dt = 10000000ULL; + uint64_t next_frame_time = nanos_since_boot() + dt; - // run at ~200hz while (!do_exit) { can_recv(publisher); - // 5ms - usleep(5*1000); + + uint64_t cur_time = nanos_since_boot(); + int64_t remaining = next_frame_time - cur_time; + if (remaining > 0){ + useconds_t sleep = remaining / 1000; + usleep(sleep); + } else { + LOGW("missed cycle"); + next_frame_time = cur_time; + } + + next_frame_time += dt; } return NULL; } void *can_health_thread(void *crap) { LOGD("start health thread"); - // health = 8011 - void *context = zmq_ctx_new(); - void *publisher = zmq_socket(context, ZMQ_PUB); - zmq_bind(publisher, "tcp://*:8011"); + Context * c = Context::create(); + PubSocket * publisher = PubSocket::create(c, "health"); - // run at 1hz + // run at 2hz while (!do_exit) { can_health(publisher); - usleep(1000*1000); + usleep(500*1000); } return NULL; } +void *hardware_control_thread(void *crap) { + LOGD("start hardware control thread"); + Context * c = Context::create(); + SubSocket * thermal_sock = SubSocket::create(c, "thermal"); + SubSocket * driver_monitoring_sock = SubSocket::create(c, "driverMonitoring"); + + Poller * poller = Poller::create({thermal_sock, driver_monitoring_sock}); + + // Wait for hardware type to be set. + while (hw_type == cereal::HealthData::HwType::UNKNOWN){ + usleep(100*1000); + } + // Only control fan speed on UNO + if (hw_type != cereal::HealthData::HwType::UNO) return NULL; + + + uint16_t prev_fan_speed = 999; + uint16_t prev_ir_pwr = 999; + + while (!do_exit) { + for (auto sock : poller->poll(1000)){ + Message * msg = sock->receive(); + if (msg == NULL) continue; + + auto amsg = kj::heapArray((msg->getSize() / sizeof(capnp::word)) + 1); + memcpy(amsg.begin(), msg->getData(), msg->getSize()); + + delete msg; + + capnp::FlatArrayMessageReader cmsg(amsg); + cereal::Event::Reader event = cmsg.getRoot(); + + auto type = event.which(); + if(type == cereal::Event::THERMAL){ + uint16_t fan_speed = event.getThermal().getFanSpeed(); + if (fan_speed != prev_fan_speed){ + pthread_mutex_lock(&usb_lock); + libusb_control_transfer(dev_handle, 0x40, 0xb1, fan_speed, 0, NULL, 0, TIMEOUT); + pthread_mutex_unlock(&usb_lock); + + prev_fan_speed = fan_speed; + } + } else if (type == cereal::Event::DRIVER_MONITORING){ + uint16_t ir_pwr = 100.0 * event.getDriverMonitoring().getIrPwr(); + + if (ir_pwr != prev_ir_pwr){ + pthread_mutex_lock(&usb_lock); + libusb_control_transfer(dev_handle, 0x40, 0xb0, ir_pwr, 0, NULL, 0, TIMEOUT); + pthread_mutex_unlock(&usb_lock); + + prev_ir_pwr = ir_pwr; + } + } + } + } + + delete poller; + delete thermal_sock; + delete c; + + return NULL; +} + #define pigeon_send(x) _pigeon_send(x, sizeof(x)-1) void hexdump(unsigned char *d, int l) { @@ -528,7 +685,7 @@ void pigeon_set_baud(int baud) { void pigeon_init() { usleep(1000*1000); - LOGW("grey panda start"); + LOGW("panda GPS start"); // power off pigeon pigeon_set_power(0); @@ -569,10 +726,10 @@ void pigeon_init() { pigeon_send("\xB5\x62\x06\x01\x03\x00\x02\x15\x01\x22\x70"); pigeon_send("\xB5\x62\x06\x01\x03\x00\x02\x13\x01\x20\x6C"); - LOGW("grey panda is ready to fly"); + LOGW("panda GPS on"); } -static void pigeon_publish_raw(void *publisher, unsigned char *dat, int alen) { +static void pigeon_publish_raw(PubSocket *publisher, unsigned char *dat, int alen) { // create message capnp::MallocMessageBuilder msg; cereal::Event::Builder event = msg.initRoot(); @@ -583,15 +740,14 @@ static void pigeon_publish_raw(void *publisher, unsigned char *dat, int alen) { // send to ubloxRaw auto words = capnp::messageToFlatArray(msg); auto bytes = words.asBytes(); - zmq_send(publisher, bytes.begin(), bytes.size(), 0); + publisher->send((char*)bytes.begin(), bytes.size()); } void *pigeon_thread(void *crap) { // ubloxRaw = 8042 - void *context = zmq_ctx_new(); - void *publisher = zmq_socket(context, ZMQ_PUB); - zmq_bind(publisher, "tcp://*:8042"); + Context * context = Context::create(); + PubSocket * publisher = PubSocket::create(context, "ubloxRaw"); // run at ~100hz unsigned char dat[0x1000]; @@ -614,7 +770,7 @@ void *pigeon_thread(void *crap) { } if (alen > 0) { if (dat[0] == (char)0x00){ - LOGW("received invalid ublox message, resetting pigeon"); + LOGW("received invalid ublox message, resetting panda GPS"); pigeon_init(); } else { pigeon_publish_raw(publisher, dat, alen); @@ -685,16 +841,13 @@ int main() { can_recv_thread, NULL); assert(err == 0); - pthread_t thermal_thread_handle; - err = pthread_create(&thermal_thread_handle, NULL, - thermal_thread, NULL); + pthread_t hardware_control_thread_handle; + err = pthread_create(&hardware_control_thread_handle, NULL, + hardware_control_thread, NULL); assert(err == 0); // join threads - err = pthread_join(thermal_thread_handle, NULL); - assert(err == 0); - err = pthread_join(can_recv_thread_handle, NULL); assert(err == 0); diff --git a/selfdrive/boardd/boardd.py b/selfdrive/boardd/boardd.py old mode 100755 new mode 100644 index fb045bb3aafdc2..d3bcb1471054d3 --- a/selfdrive/boardd/boardd.py +++ b/selfdrive/boardd/boardd.py @@ -1,49 +1,13 @@ -#!/usr/bin/env python - -# This file is not used by OpenPilot. Only boardd.cc is used. -# The python version is slower, but has more options for development. - -# TODO: merge the extra functionalities of this file (like MOCK) in boardd.c and -# delete this python version of boardd - +# pylint: skip-file import os -import struct -import zmq -import time +import subprocess -import selfdrive.messaging as messaging -from common.realtime import Ratekeeper -from selfdrive.services import service_list -from selfdrive.swaglog import cloudlog +# Cython +boardd_api_dir = os.path.dirname(os.path.abspath(__file__)) +subprocess.check_call(["make", "boardd_api_impl.so"], cwd=boardd_api_dir) +from selfdrive.boardd.boardd_api_impl import can_list_to_can_capnp +assert can_list_to_can_capnp -# USB is optional -try: - import usb1 - from usb1 import USBErrorIO, USBErrorOverflow #pylint: disable=no-name-in-module -except Exception: - pass - -SAFETY_NOOUTPUT = 0 -SAFETY_HONDA = 1 -SAFETY_TOYOTA = 2 -SAFETY_CHRYSLER = 9 -SAFETY_TOYOTA_NOLIMITS = 0x1336 -SAFETY_ALLOUTPUT = 0x1337 - -# *** serialization functions *** -def can_list_to_can_capnp(can_msgs, msgtype='can'): - dat = messaging.new_message() - dat.init(msgtype, len(can_msgs)) - for i, can_msg in enumerate(can_msgs): - if msgtype == 'sendcan': - cc = dat.sendcan[i] - else: - cc = dat.can[i] - cc.address = can_msg[0] - cc.busTime = can_msg[1] - cc.dat = str(can_msg[2]) - cc.src = can_msg[3] - return dat def can_capnp_to_can_list(can, src_filter=None): ret = [] @@ -51,202 +15,3 @@ def can_capnp_to_can_list(can, src_filter=None): if src_filter is None or msg.src in src_filter: ret.append((msg.address, msg.busTime, msg.dat, msg.src)) return ret - -# *** can driver *** -def can_health(): - while 1: - try: - dat = handle.controlRead(usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE, 0xd2, 0, 0, 0x10) - break - except (USBErrorIO, USBErrorOverflow): - cloudlog.exception("CAN: BAD HEALTH, RETRYING") - v, i, started = struct.unpack("IIB", dat[0:9]) - # TODO: units - return {"voltage": v, "current": i, "started": bool(started)} - -def __parse_can_buffer(dat): - ret = [] - for j in range(0, len(dat), 0x10): - ddat = dat[j:j+0x10] - f1, f2 = struct.unpack("II", ddat[0:8]) - ret.append((f1 >> 21, f2>>16, ddat[8:8+(f2&0xF)], (f2>>4)&0xF)) - return ret - -def can_send_many(arr): - snds = [] - for addr, _, dat, alt in arr: - if addr < 0x800: # only support 11 bit addr - snd = struct.pack("II", ((addr << 21) | 1), len(dat) | (alt << 4)) + dat - snd = snd.ljust(0x10, '\x00') - snds.append(snd) - while 1: - try: - handle.bulkWrite(3, ''.join(snds)) - break - except (USBErrorIO, USBErrorOverflow): - cloudlog.exception("CAN: BAD SEND MANY, RETRYING") - -def can_recv(): - dat = "" - while 1: - try: - dat = handle.bulkRead(1, 0x10*256) - break - except (USBErrorIO, USBErrorOverflow): - cloudlog.exception("CAN: BAD RECV, RETRYING") - return __parse_can_buffer(dat) - -def can_init(): - global handle, context - handle = None - cloudlog.info("attempting can init") - - context = usb1.USBContext() - #context.setDebug(9) - - for device in context.getDeviceList(skip_on_error=True): - if device.getVendorID() == 0xbbaa and device.getProductID() == 0xddcc: - handle = device.open() - handle.claimInterface(0) - handle.controlWrite(0x40, 0xdc, SAFETY_ALLOUTPUT, 0, b'') - - if handle is None: - cloudlog.warn("CAN NOT FOUND") - exit(-1) - - cloudlog.info("got handle") - cloudlog.info("can init done") - -def boardd_mock_loop(): - context = zmq.Context() - can_init() - handle.controlWrite(0x40, 0xdc, SAFETY_ALLOUTPUT, 0, b'') - - logcan = messaging.sub_sock(context, service_list['can'].port) - sendcan = messaging.pub_sock(context, service_list['sendcan'].port) - - while 1: - tsc = messaging.drain_sock(logcan, wait_for_one=True) - snds = map(lambda x: can_capnp_to_can_list(x.can), tsc) - snd = [] - for s in snds: - snd += s - snd = filter(lambda x: x[-1] <= 1, snd) - can_send_many(snd) - - # recv @ 100hz - can_msgs = can_recv() - print("sent %d got %d" % (len(snd), len(can_msgs))) - m = can_list_to_can_capnp(can_msgs) - sendcan.send(m.to_bytes()) - -def boardd_test_loop(): - can_init() - cnt = 0 - while 1: - can_send_many([[0xbb,0,"\xaa\xaa\xaa\xaa",0], [0xaa,0,"\xaa\xaa\xaa\xaa"+struct.pack("!I", cnt),1]]) - #can_send_many([[0xaa,0,"\xaa\xaa\xaa\xaa",0]]) - #can_send_many([[0xaa,0,"\xaa\xaa\xaa\xaa",1]]) - # recv @ 100hz - can_msgs = can_recv() - print("got %d" % (len(can_msgs))) - time.sleep(0.01) - cnt += 1 - -# *** main loop *** -def boardd_loop(rate=200): - rk = Ratekeeper(rate) - context = zmq.Context() - - can_init() - - # *** publishes can and health - logcan = messaging.pub_sock(context, service_list['can'].port) - health_sock = messaging.pub_sock(context, service_list['health'].port) - - # *** subscribes to can send - sendcan = messaging.sub_sock(context, service_list['sendcan'].port) - - # drain sendcan to delete any stale messages from previous runs - messaging.drain_sock(sendcan) - - while 1: - # health packet @ 1hz - if (rk.frame%rate) == 0: - health = can_health() - msg = messaging.new_message() - msg.init('health') - - # store the health to be logged - msg.health.voltage = health['voltage'] - msg.health.current = health['current'] - msg.health.started = health['started'] - msg.health.controlsAllowed = True - - health_sock.send(msg.to_bytes()) - - # recv @ 100hz - can_msgs = can_recv() - - # publish to logger - # TODO: refactor for speed - if len(can_msgs) > 0: - dat = can_list_to_can_capnp(can_msgs) - logcan.send(dat.to_bytes()) - - # send can if we have a packet - tsc = messaging.recv_sock(sendcan) - if tsc is not None: - can_send_many(can_capnp_to_can_list(tsc.sendcan)) - - rk.keep_time() - -# *** main loop *** -def boardd_proxy_loop(rate=200, address="192.168.2.251"): - rk = Ratekeeper(rate) - context = zmq.Context() - - can_init() - - # *** subscribes can - logcan = messaging.sub_sock(context, service_list['can'].port, addr=address) - # *** publishes to can send - sendcan = messaging.pub_sock(context, service_list['sendcan'].port) - - # drain sendcan to delete any stale messages from previous runs - messaging.drain_sock(sendcan) - - while 1: - # recv @ 100hz - can_msgs = can_recv() - #for m in can_msgs: - # print "R:",hex(m[0]), str(m[2]).encode("hex") - - # publish to logger - # TODO: refactor for speed - if len(can_msgs) > 0: - dat = can_list_to_can_capnp(can_msgs, "sendcan") - sendcan.send(dat.to_bytes()) - - # send can if we have a packet - tsc = messaging.recv_sock(logcan) - if tsc is not None: - cl = can_capnp_to_can_list(tsc.can) - #for m in cl: - # print "S:",hex(m[0]), str(m[2]).encode("hex") - can_send_many(cl) - - rk.keep_time() - -def main(gctx=None): - if os.getenv("MOCK") is not None: - boardd_mock_loop() - elif os.getenv("PROXY") is not None: - boardd_proxy_loop() - elif os.getenv("BOARDTEST") is not None: - boardd_test_loop() - else: - boardd_loop() - -if __name__ == "__main__": - main() diff --git a/selfdrive/boardd/boardd_api_impl.pyx b/selfdrive/boardd/boardd_api_impl.pyx new file mode 100644 index 00000000000000..3f50fbaab6c5ca --- /dev/null +++ b/selfdrive/boardd/boardd_api_impl.pyx @@ -0,0 +1,26 @@ +# distutils: language = c++ +# cython: language_level=3 +from libcpp.vector cimport vector +from libcpp.string cimport string +from libcpp cimport bool + +cdef struct can_frame: + long address + string dat + long busTime + long src + +cdef extern void can_list_to_can_capnp_cpp(const vector[can_frame] &can_list, string &out, bool sendCan, bool valid) + +def can_list_to_can_capnp(can_msgs, msgtype='can', valid=True): + cdef vector[can_frame] can_list + cdef can_frame f + for can_msg in can_msgs: + f.address = can_msg[0] + f.busTime = can_msg[1] + f.dat = can_msg[2] + f.src = can_msg[3] + can_list.push_back(f) + cdef string out + can_list_to_can_capnp_cpp(can_list, out, msgtype == 'sendcan', valid) + return out diff --git a/selfdrive/boardd/boardd_setup.py b/selfdrive/boardd/boardd_setup.py new file mode 100644 index 00000000000000..887a1b71053f22 --- /dev/null +++ b/selfdrive/boardd/boardd_setup.py @@ -0,0 +1,29 @@ +import subprocess +from distutils.core import Extension, setup # pylint: disable=import-error,no-name-in-module + +from Cython.Build import cythonize + +from common.cython_hacks import BuildExtWithoutPlatformSuffix + +PHONELIBS = '../../phonelibs' + +ARCH = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() # pylint: disable=unexpected-keyword-arg +ARCH_DIR = 'x64' if ARCH == "x86_64" else 'aarch64' + +setup(name='Boardd API Implementation', + cmdclass={'build_ext': BuildExtWithoutPlatformSuffix}, + ext_modules=cythonize( + Extension( + "boardd_api_impl", + libraries=[':libcan_list_to_can_capnp.a', ':libcapnp.a', ':libcapnp.a', ':libkj.a'], + library_dirs=[ + './', + PHONELIBS + '/capnp-cpp/' + ARCH_DIR + '/lib/', + PHONELIBS + '/capnp-c/' + ARCH_DIR + '/lib/' + ], + sources=['boardd_api_impl.pyx'], + language="c++", + extra_compile_args=["-std=c++11"], + ) + ) +) diff --git a/selfdrive/boardd/can_list_to_can_capnp.cc b/selfdrive/boardd/can_list_to_can_capnp.cc new file mode 100644 index 00000000000000..8ba9d3d5609d9c --- /dev/null +++ b/selfdrive/boardd/can_list_to_can_capnp.cc @@ -0,0 +1,37 @@ +#include +#include +#include +#include "common/timing.h" +#include +#include "cereal/gen/cpp/log.capnp.h" +#include "cereal/gen/cpp/car.capnp.h" + +typedef struct { + long address; + std::string dat; + long busTime; + long src; +} can_frame; + +extern "C" { + +void can_list_to_can_capnp_cpp(const std::vector &can_list, std::string &out, bool sendCan, bool valid) { + capnp::MallocMessageBuilder msg; + cereal::Event::Builder event = msg.initRoot(); + event.setLogMonoTime(nanos_since_boot()); + event.setValid(valid); + + auto canData = sendCan ? event.initSendcan(can_list.size()) : event.initCan(can_list.size()); + int j = 0; + for (auto it = can_list.begin(); it != can_list.end(); it++, j++) { + canData[j].setAddress(it->address); + canData[j].setBusTime(it->busTime); + canData[j].setDat(kj::arrayPtr((uint8_t*)it->dat.data(), it->dat.size())); + canData[j].setSrc(it->src); + } + auto words = capnp::messageToFlatArray(msg); + auto bytes = words.asBytes(); + out.append((const char *)bytes.begin(), bytes.size()); +} + +} diff --git a/pyextra/jsonrpc/tests/test_backend_django/__init__.py b/selfdrive/boardd/tests/__init__.py similarity index 100% rename from pyextra/jsonrpc/tests/test_backend_django/__init__.py rename to selfdrive/boardd/tests/__init__.py diff --git a/selfdrive/boardd/tests/boardd_old.py b/selfdrive/boardd/tests/boardd_old.py new file mode 100755 index 00000000000000..f963004423ab98 --- /dev/null +++ b/selfdrive/boardd/tests/boardd_old.py @@ -0,0 +1,246 @@ +#!/usr/bin/env python3 + +# This file is not used by OpenPilot. Only boardd.cc is used. +# The python version is slower, but has more options for development. + +# TODO: merge the extra functionalities of this file (like MOCK) in boardd.c and +# delete this python version of boardd + +import os +import struct +import time + +import selfdrive.messaging as messaging +from common.realtime import Ratekeeper +from selfdrive.swaglog import cloudlog +from selfdrive.boardd.boardd import can_capnp_to_can_list +from cereal import car + +SafetyModel = car.CarParams.SafetyModel + +# USB is optional +try: + import usb1 + from usb1 import USBErrorIO, USBErrorOverflow #pylint: disable=no-name-in-module +except Exception: + pass + +# *** serialization functions *** +def can_list_to_can_capnp(can_msgs, msgtype='can'): + dat = messaging.new_message() + dat.init(msgtype, len(can_msgs)) + for i, can_msg in enumerate(can_msgs): + if msgtype == 'sendcan': + cc = dat.sendcan[i] + else: + cc = dat.can[i] + cc.address = can_msg[0] + cc.busTime = can_msg[1] + cc.dat = bytes(can_msg[2]) + cc.src = can_msg[3] + return dat + + +# *** can driver *** +def can_health(): + while 1: + try: + dat = handle.controlRead(usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE, 0xd2, 0, 0, 0x16) + break + except (USBErrorIO, USBErrorOverflow): + cloudlog.exception("CAN: BAD HEALTH, RETRYING") + v, i = struct.unpack("II", dat[0:8]) + ign_line, ign_can = struct.unpack("BB", dat[20:22]) + return {"voltage": v, "current": i, "ignition_line": bool(ign_line), "ignition_can": bool(ign_can)} + +def __parse_can_buffer(dat): + ret = [] + for j in range(0, len(dat), 0x10): + ddat = dat[j:j+0x10] + f1, f2 = struct.unpack("II", ddat[0:8]) + ret.append((f1 >> 21, f2>>16, ddat[8:8+(f2&0xF)], (f2>>4)&0xFF)) + return ret + +def can_send_many(arr): + snds = [] + for addr, _, dat, alt in arr: + if addr < 0x800: # only support 11 bit addr + snd = struct.pack("II", ((addr << 21) | 1), len(dat) | (alt << 4)) + dat + snd = snd.ljust(0x10, b'\x00') + snds.append(snd) + while 1: + try: + handle.bulkWrite(3, b''.join(snds)) + break + except (USBErrorIO, USBErrorOverflow): + cloudlog.exception("CAN: BAD SEND MANY, RETRYING") + +def can_recv(): + dat = b"" + while 1: + try: + dat = handle.bulkRead(1, 0x10*256) + break + except (USBErrorIO, USBErrorOverflow): + cloudlog.exception("CAN: BAD RECV, RETRYING") + return __parse_can_buffer(dat) + +def can_init(): + global handle, context + handle = None + cloudlog.info("attempting can init") + + context = usb1.USBContext() + #context.setDebug(9) + + for device in context.getDeviceList(skip_on_error=True): + if device.getVendorID() == 0xbbaa and device.getProductID() == 0xddcc: + handle = device.open() + handle.claimInterface(0) + handle.controlWrite(0x40, 0xdc, SafetyModel.allOutput, 0, b'') + + if handle is None: + cloudlog.warning("CAN NOT FOUND") + exit(-1) + + cloudlog.info("got handle") + cloudlog.info("can init done") + +def boardd_mock_loop(): + can_init() + handle.controlWrite(0x40, 0xdc, SafetyModel.allOutput, 0, b'') + + logcan = messaging.sub_sock('can') + sendcan = messaging.pub_sock('sendcan') + + while 1: + tsc = messaging.drain_sock(logcan, wait_for_one=True) + snds = map(lambda x: can_capnp_to_can_list(x.can), tsc) + snd = [] + for s in snds: + snd += s + snd = list(filter(lambda x: x[-1] <= 2, snd)) + snd_0 = len(list(filter(lambda x: x[-1] == 0, snd))) + snd_1 = len(list(filter(lambda x: x[-1] == 1, snd))) + snd_2 = len(list(filter(lambda x: x[-1] == 2, snd))) + can_send_many(snd) + + # recv @ 100hz + can_msgs = can_recv() + got_0 = len(list(filter(lambda x: x[-1] == 0+0x80, can_msgs))) + got_1 = len(list(filter(lambda x: x[-1] == 1+0x80, can_msgs))) + got_2 = len(list(filter(lambda x: x[-1] == 2+0x80, can_msgs))) + print("sent %3d (%3d/%3d/%3d) got %3d (%3d/%3d/%3d)" % + (len(snd), snd_0, snd_1, snd_2, len(can_msgs), got_0, got_1, got_2)) + m = can_list_to_can_capnp(can_msgs, msgtype='sendcan') + sendcan.send(m.to_bytes()) + +def boardd_test_loop(): + can_init() + cnt = 0 + while 1: + can_send_many([[0xbb,0,"\xaa\xaa\xaa\xaa",0], [0xaa,0,"\xaa\xaa\xaa\xaa"+struct.pack("!I", cnt),1]]) + #can_send_many([[0xaa,0,"\xaa\xaa\xaa\xaa",0]]) + #can_send_many([[0xaa,0,"\xaa\xaa\xaa\xaa",1]]) + # recv @ 100hz + can_msgs = can_recv() + print("got %d" % (len(can_msgs))) + time.sleep(0.01) + cnt += 1 + +# *** main loop *** +def boardd_loop(rate=100): + rk = Ratekeeper(rate) + + can_init() + + # *** publishes can and health + logcan = messaging.pub_sock('can') + health_sock = messaging.pub_sock('health') + + # *** subscribes to can send + sendcan = messaging.sub_sock('sendcan') + + # drain sendcan to delete any stale messages from previous runs + messaging.drain_sock(sendcan) + + while 1: + # health packet @ 2hz + if (rk.frame % (rate // 2)) == 0: + health = can_health() + msg = messaging.new_message() + msg.init('health') + + # store the health to be logged + msg.health.voltage = health['voltage'] + msg.health.current = health['current'] + msg.health.ignitionLine = health['ignition_line'] + msg.health.ignitionCan = health['ignition_can'] + msg.health.controlsAllowed = True + + health_sock.send(msg.to_bytes()) + + # recv @ 100hz + can_msgs = can_recv() + + # publish to logger + # TODO: refactor for speed + if len(can_msgs) > 0: + dat = can_list_to_can_capnp(can_msgs).to_bytes() + logcan.send(dat) + + # send can if we have a packet + tsc = messaging.recv_sock(sendcan) + if tsc is not None: + can_send_many(can_capnp_to_can_list(tsc.sendcan)) + + rk.keep_time() + +# *** main loop *** +def boardd_proxy_loop(rate=100, address="192.168.2.251"): + rk = Ratekeeper(rate) + + can_init() + + # *** subscribes can + logcan = messaging.sub_sock('can', addr=address) + # *** publishes to can send + sendcan = messaging.pub_sock('sendcan') + + # drain sendcan to delete any stale messages from previous runs + messaging.drain_sock(sendcan) + + while 1: + # recv @ 100hz + can_msgs = can_recv() + #for m in can_msgs: + # print("R: {0} {1}".format(hex(m[0]), str(m[2]).encode("hex"))) + + # publish to logger + # TODO: refactor for speed + if len(can_msgs) > 0: + dat = can_list_to_can_capnp(can_msgs, "sendcan") + sendcan.send(dat) + + # send can if we have a packet + tsc = messaging.recv_sock(logcan) + if tsc is not None: + cl = can_capnp_to_can_list(tsc.can) + #for m in cl: + # print("S: {0} {1}".format(hex(m[0]), str(m[2]).encode("hex"))) + can_send_many(cl) + + rk.keep_time() + +def main(gctx=None): + if os.getenv("MOCK") is not None: + boardd_mock_loop() + elif os.getenv("PROXY") is not None: + boardd_proxy_loop() + elif os.getenv("BOARDTEST") is not None: + boardd_test_loop() + else: + boardd_loop() + +if __name__ == "__main__": + main() diff --git a/selfdrive/boardd/tests/fuzzer.py b/selfdrive/boardd/tests/fuzzer.py new file mode 100755 index 00000000000000..bb58f8b5e07a53 --- /dev/null +++ b/selfdrive/boardd/tests/fuzzer.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +from __future__ import print_function +import time +import random + +from boardd_old import can_init, can_recv, can_send_many, can_health + +if __name__ == "__main__": + can_init() + while 1: + c = random.randint(0, 3) + if c == 0: + print(can_recv()) + elif c == 1: + print(can_health()) + elif c == 2: + many = [[0x123, 0, "abcdef", 0]] * random.randint(1, 10) + can_send_many(many) + elif c == 3: + time.sleep(random.randint(0, 100) / 1000.0) diff --git a/selfdrive/boardd/tests/replay_many.py b/selfdrive/boardd/tests/replay_many.py new file mode 100755 index 00000000000000..cd94806a87c5a9 --- /dev/null +++ b/selfdrive/boardd/tests/replay_many.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +import sys +import time +import signal +import traceback +from panda import Panda +from multiprocessing import Pool + +import selfdrive.messaging as messaging +from selfdrive.boardd.boardd import can_capnp_to_can_list + +def initializer(): + """Ignore CTRL+C in the worker process. + source: https://stackoverflow.com/a/44869451 """ + signal.signal(signal.SIGINT, signal.SIG_IGN) + +def send_thread(serial): + try: + panda = Panda(serial) + panda.set_safety_mode(Panda.SAFETY_ALLOUTPUT) + panda.set_can_loopback(False) + + can_sock = messaging.sub_sock('can') + + while True: + # Send messages one bus 0 and 1 + tsc = messaging.recv_one(can_sock) + snd = can_capnp_to_can_list(tsc.can) + snd = list(filter(lambda x: x[-1] <= 2, snd)) + panda.can_send_many(snd) + + # Drain panda message buffer + panda.can_recv() + except Exception: + traceback.print_exc() + + +if __name__ == "__main__": + serials = Panda.list() + num_pandas = len(serials) + + if num_pandas == 0: + print("No pandas found. Exiting") + sys.exit(1) + else: + print("%d pandas found. Starting broadcast" % num_pandas) + + pool = Pool(num_pandas, initializer=initializer) + pool.map_async(send_thread, serials) + + while True: + try: + time.sleep(10) + except KeyboardInterrupt: + pool.terminate() + pool.join() + raise diff --git a/selfdrive/boardd/tests/test_boardd_api.py b/selfdrive/boardd/tests/test_boardd_api.py new file mode 100644 index 00000000000000..f41e1e3571049d --- /dev/null +++ b/selfdrive/boardd/tests/test_boardd_api.py @@ -0,0 +1,77 @@ +import random +import numpy as np + +import selfdrive.boardd.tests.boardd_old as boardd_old +import selfdrive.boardd.boardd as boardd + +from common.realtime import sec_since_boot +from cereal import log +import unittest + + +def generate_random_can_data_list(): + can_list = [] + cnt = random.randint(1, 64) + for j in range(cnt): + can_data = np.random.bytes(random.randint(1, 8)) + can_list.append([random.randint(0, 128), random.randint(0, 128), can_data, random.randint(0, 128)]) + return can_list, cnt + + +class TestBoarddApiMethods(unittest.TestCase): + def test_correctness(self): + for i in range(1000): + can_list, _ = generate_random_can_data_list() + + # Sendcan + # Old API + m_old = boardd_old.can_list_to_can_capnp(can_list, 'sendcan').to_bytes() + # new API + m = boardd.can_list_to_can_capnp(can_list, 'sendcan') + + ev_old = log.Event.from_bytes(m_old) + ev = log.Event.from_bytes(m) + + self.assertEqual(ev_old.which(), ev.which()) + self.assertEqual(len(ev.sendcan), len(ev_old.sendcan)) + for i in range(len(ev.sendcan)): + attrs = ['address', 'busTime', 'dat', 'src'] + for attr in attrs: + self.assertEqual(getattr(ev.sendcan[i], attr, 'new'), getattr(ev_old.sendcan[i], attr, 'old')) + + # Can + m_old = boardd_old.can_list_to_can_capnp(can_list, 'can').to_bytes() + # new API + m = boardd.can_list_to_can_capnp(can_list, 'can') + + ev_old = log.Event.from_bytes(m_old) + ev = log.Event.from_bytes(m) + self.assertEqual(ev_old.which(), ev.which()) + self.assertEqual(len(ev.can), len(ev_old.can)) + for i in range(len(ev.can)): + attrs = ['address', 'busTime', 'dat', 'src'] + for attr in attrs: + self.assertEqual(getattr(ev.can[i], attr, 'new'), getattr(ev_old.can[i], attr, 'old')) + + def test_performance(self): + can_list, cnt = generate_random_can_data_list() + recursions = 1000 + + n1 = sec_since_boot() + for i in range(recursions): + boardd_old.can_list_to_can_capnp(can_list, 'sendcan').to_bytes() + n2 = sec_since_boot() + elapsed_old = n2 - n1 + + # print('Old API, elapsed time: {} secs'.format(elapsed_old)) + n1 = sec_since_boot() + for i in range(recursions): + boardd.can_list_to_can_capnp(can_list) + n2 = sec_since_boot() + elapsed_new = n2 - n1 + # print('New API, elapsed time: {} secs'.format(elapsed_new)) + self.assertTrue(elapsed_new < elapsed_old / 2) + + +if __name__ == '__main__': + unittest.main() diff --git a/selfdrive/boardd/tests/test_boardd_loopback.py b/selfdrive/boardd/tests/test_boardd_loopback.py new file mode 100755 index 00000000000000..fefb3bf254c001 --- /dev/null +++ b/selfdrive/boardd/tests/test_boardd_loopback.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +"""Run boardd with the BOARDD_LOOPBACK envvar before running this test.""" + +import os +import random +import time + +from selfdrive.boardd.boardd import can_list_to_can_capnp +from selfdrive.messaging import drain_sock, pub_sock, sub_sock + +def get_test_string(): + return b"test"+os.urandom(10) + +BUS = 0 + +def main(): + rcv = sub_sock('can') # port 8006 + snd = pub_sock('sendcan') # port 8017 + time.sleep(0.3) # wait to bind before send/recv + + for i in range(10): + print("Loop %d" % i) + at = random.randint(1024, 2000) + st = get_test_string()[0:8] + snd.send(can_list_to_can_capnp([[at, 0, st, 0]], msgtype='sendcan').to_bytes()) + time.sleep(0.1) + res = drain_sock(rcv, True) + assert len(res) == 1 + + res = res[0].can + assert len(res) == 2 + + msg0, msg1 = res + + assert msg0.dat == st + assert msg1.dat == st + + assert msg0.address == at + assert msg1.address == at + + assert msg0.src == 0x80 | BUS + assert msg1.src == BUS + + print("Success") + +if __name__ == "__main__": + main() diff --git a/selfdrive/can/Makefile b/selfdrive/can/Makefile index b140aa5f87e2a1..cc1175b8c1413f 100644 --- a/selfdrive/can/Makefile +++ b/selfdrive/can/Makefile @@ -16,30 +16,28 @@ WARN_FLAGS = -Werror=implicit-function-declaration \ CFLAGS = -std=gnu11 -g -fPIC -O2 $(WARN_FLAGS) CXXFLAGS = -std=c++11 -g -fPIC -O2 $(WARN_FLAGS) +LDFLAGS = -ifeq ($(UNAME_S),Darwin) - ZMQ_LIBS = -L/usr/local/lib -lzmq -else ifeq ($(OPTEST),1) - ZMQ_LIBS = -lzmq -else ifeq ($(UNAME_M),x86_64) - EXTERNAL := ../../external - ZMQ_FLAGS = -I$(EXTERNAL)/zmq/include - ZMQ_LIBS = -L$(EXTERNAL)/zmq/lib -l:libzmq.a -else ifeq ($(UNAME_M),aarch64) - ZMQ_FLAGS = -I$(PHONELIBS)/zmq/aarch64/include - ZMQ_LIBS = -L$(PHONELIBS)/zmq/aarch64/lib -l:libzmq.a - CXXFLAGS += -lgnustl_shared +ifeq ($(ARCH),aarch64) +CFLAGS += -mcpu=cortex-a57 +CXXFLAGS += -mcpu=cortex-a57 endif -OPENDBC_PATH := $(shell python -c 'import opendbc; print opendbc.DBC_PATH') +OBJDIR = obj -DBC_SOURCES := $(wildcard $(OPENDBC_PATH)/*.dbc) +OPENDBC_PATH := $(shell python3 -c 'import opendbc; print(opendbc.DBC_PATH)') + +DBC_SOURCES := $(sort $(wildcard $(OPENDBC_PATH)/*.dbc)) +DBC_OBJS := $(patsubst $(OPENDBC_PATH)/%.dbc,$(OBJDIR)/%.o,$(DBC_SOURCES)) DBC_CCS := $(patsubst $(OPENDBC_PATH)/%.dbc,dbc_out/%.cc,$(DBC_SOURCES)) +.SECONDARY: $(DBC_CCS) + +LIBDBC_OBJS := $(OBJDIR)/dbc.o $(OBJDIR)/parser.o $(OBJDIR)/packer.o $(OBJDIR)/common.o CWD := $(shell pwd) .PHONY: all -all: libdbc.so +all: $(OBJDIR) libdbc.so parser_pyx.so include ../common/cereal.mk @@ -49,22 +47,51 @@ libdbc.so:: ../../cereal/gen/cpp/log.capnp.h ../../cereal/gen/cpp/log.capnp.h: cd ../../cereal && make -libdbc.so:: dbc.cc parser.cc packer.cc $(DBC_CCS) +libdbc.so:: $(LIBDBC_OBJS) $(DBC_OBJS) + @echo "[ LINK ] $@" $(CXX) -fPIC -shared -o '$@' $^ \ - -I. \ - -I../.. \ - $(CXXFLAGS) \ - $(ZMQ_FLAGS) \ - $(ZMQ_LIBS) \ - $(CEREAL_CXXFLAGS) \ - $(CEREAL_LIBS) - -dbc_out/%.cc: $(OPENDBC_PATH)/%.dbc process_dbc.py dbc_template.cc - PYTHONPATH=$(PYTHONPATH):$(CWD)/../../pyextra ./process_dbc.py '$<' '$@' - -.PHONY: clean + -I. -I../.. \ + $(CXXFLAGS) \ + $(LDFLAGS) \ + $(CEREAL_CXXFLAGS) \ + $(CEREAL_LIBS) + +packer_impl.so: packer_impl.pyx packer_setup.py + python3 packer_setup.py build_ext --inplace + rm -rf build + rm -f packer_impl.cpp + +parser_pyx.so: libdbc.so parser_pyx_setup.py parser_pyx.pyx common.pxd + python3 parser_pyx_setup.py build_ext --inplace + rm -rf build + rm -f parser_pyx.cpp + +$(OBJDIR)/%.o: %.cc + @echo "[ CXX ] $@" + $(CXX) -fPIC -c -o '$@' $^ \ + -I. -I../.. \ + $(CXXFLAGS) \ + $(CEREAL_CXXFLAGS) \ + +$(OBJDIR)/%.o: dbc_out/%.cc + @echo "[ CXX ] $@" + $(CXX) -fPIC -c -o '$@' $^ \ + -I. -I../.. \ + $(CXXFLAGS) \ + $(CEREAL_CXXFLAGS) \ + +dbc_out/%.cc: process_dbc.py dbc_template.cc $(OPENDBC_PATH)/%.dbc + @echo "[ DBC GEN ] $@" + ./process_dbc.py $(OPENDBC_PATH) '$@' + +$(OBJDIR): + mkdir -p $@ + +.PHONY: clean $(OBJDIR) clean: rm -rf libdbc.so* rm -f dbc_out/*.cc rm -f dbcs.txt rm -f dbcs.csv + rm -f *.so + rm -rf $(OBJDIR)/* diff --git a/selfdrive/can/can_define.py b/selfdrive/can/can_define.py new file mode 100644 index 00000000000000..eb708869f09963 --- /dev/null +++ b/selfdrive/can/can_define.py @@ -0,0 +1,39 @@ +from collections import defaultdict +from selfdrive.can.libdbc_py import libdbc, ffi + +class CANDefine(): + def __init__(self, dbc_name): + self.dv = defaultdict(dict) + self.dbc_name = dbc_name + self.dbc = libdbc.dbc_lookup(dbc_name.encode('utf8')) + + num_vals = self.dbc[0].num_vals + + self.address_to_msg_name = {} + num_msgs = self.dbc[0].num_msgs + for i in range(num_msgs): + msg = self.dbc[0].msgs[i] + name = ffi.string(msg.name).decode('utf8') + address = msg.address + self.address_to_msg_name[address] = name + + for i in range(num_vals): + val = self.dbc[0].vals[i] + + sgname = ffi.string(val.name).decode('utf8') + address = val.address + def_val = ffi.string(val.def_val).decode('utf8') + + #separate definition/value pairs + def_val = def_val.split() + values = [int(v) for v in def_val[::2]] + defs = def_val[1::2] + + if address not in self.dv: + self.dv[address] = {} + msgname = self.address_to_msg_name[address] + self.dv[msgname] = {} + + # two ways to lookup: address or msg name + self.dv[address][sgname] = dict(zip(values, defs)) + self.dv[msgname][sgname] = self.dv[address][sgname] diff --git a/selfdrive/can/common.cc b/selfdrive/can/common.cc new file mode 100644 index 00000000000000..5a131eb6c757af --- /dev/null +++ b/selfdrive/can/common.cc @@ -0,0 +1,165 @@ +#include "common.h" + +unsigned int honda_checksum(unsigned int address, uint64_t d, int l) { + d >>= ((8-l)*8); // remove padding + d >>= 4; // remove checksum + + int s = 0; + while (address) { s += (address & 0xF); address >>= 4; } + while (d) { s += (d & 0xF); d >>= 4; } + s = 8-s; + s &= 0xF; + + return s; +} + +unsigned int toyota_checksum(unsigned int address, uint64_t d, int l) { + d >>= ((8-l)*8); // remove padding + d >>= 8; // remove checksum + + unsigned int s = l; + while (address) { s += address & 0xff; address >>= 8; } + while (d) { s += d & 0xff; d >>= 8; } + + return s & 0xFF; +} + +// Static lookup table for fast computation of CRC8 poly 0x2F, aka 8H2F/AUTOSAR +uint8_t crc8_lut_8h2f[256]; + +void gen_crc_lookup_table(uint8_t poly, uint8_t crc_lut[]) { + uint8_t crc; + int i, j; + + for (i = 0; i < 256; i++) { + crc = i; + for (j = 0; j < 8; j++) { + if ((crc & 0x80) != 0) + crc = (uint8_t)((crc << 1) ^ poly); + else + crc <<= 1; + } + crc_lut[i] = crc; + } +} + +void init_crc_lookup_tables() { + // At init time, set up static lookup tables for fast CRC computation. + + gen_crc_lookup_table(0x2F, crc8_lut_8h2f); // CRC-8 8H2F/AUTOSAR for Volkswagen +} + +unsigned int volkswagen_crc(unsigned int address, uint64_t d, int l) { + // Volkswagen uses standard CRC8 8H2F/AUTOSAR, but they compute it with + // a magic variable padding byte tacked onto the end of the payload. + // https://www.autosar.org/fileadmin/user_upload/standards/classic/4-3/AUTOSAR_SWS_CRCLibrary.pdf + + uint8_t *dat = (uint8_t *)&d; + uint8_t crc = 0xFF; // Standard init value for CRC8 8H2F/AUTOSAR + + // CRC the payload first, skipping over the first byte where the CRC lives. + for (int i = 1; i < l; i++) { + crc ^= dat[i]; + crc = crc8_lut_8h2f[crc]; + } + + // Look up and apply the magic final CRC padding byte, which permutes by CAN + // address, and additionally (for SOME addresses) by the message counter. + uint8_t counter = dat[1] & 0x0F; + switch(address) { + case 0x86: // LWI_01 Steering Angle + crc ^= (uint8_t[]){0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86}[counter]; + break; + case 0x9F: // EPS_01 Electric Power Steering + crc ^= (uint8_t[]){0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5}[counter]; + break; + case 0xAD: // Getriebe_11 Automatic Gearbox + crc ^= (uint8_t[]){0x3F,0x69,0x39,0xDC,0x94,0xF9,0x14,0x64,0xD8,0x6A,0x34,0xCE,0xA2,0x55,0xB5,0x2C}[counter]; + break; + case 0xFD: // ESP_21 Electronic Stability Program + crc ^= (uint8_t[]){0xB4,0xEF,0xF8,0x49,0x1E,0xE5,0xC2,0xC0,0x97,0x19,0x3C,0xC9,0xF1,0x98,0xD6,0x61}[counter]; + break; + case 0x106: // ESP_05 Electronic Stability Program + crc ^= (uint8_t[]){0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07}[counter]; + break; + case 0x117: // ACC_10 Automatic Cruise Control + crc ^= (uint8_t[]){0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC}[counter]; + break; + case 0x122: // ACC_06 Automatic Cruise Control + crc ^= (uint8_t[]){0x37,0x7D,0xF3,0xA9,0x18,0x46,0x6D,0x4D,0x3D,0x71,0x92,0x9C,0xE5,0x32,0x10,0xB9}[counter]; + break; + case 0x126: // HCA_01 Heading Control Assist + crc ^= (uint8_t[]){0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA}[counter]; + break; + case 0x12B: // GRA_ACC_01 Steering wheel controls for ACC + crc ^= (uint8_t[]){0x6A,0x38,0xB4,0x27,0x22,0xEF,0xE1,0xBB,0xF8,0x80,0x84,0x49,0xC7,0x9E,0x1E,0x2B}[counter]; + break; + case 0x187: // EV_Gearshift "Gear" selection data for EVs with no gearbox + crc ^= (uint8_t[]){0x7F,0xED,0x17,0xC2,0x7C,0xEB,0x44,0x21,0x01,0xFA,0xDB,0x15,0x4A,0x6B,0x23,0x05}[counter]; + break; + case 0x30C: // ACC_02 Automatic Cruise Control + crc ^= (uint8_t[]){0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F}[counter]; + break; + case 0x3C0: // Klemmen_Status_01 ignition and starting status + crc ^= (uint8_t[]){0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3}[counter]; + break; + case 0x65D: // ESP_20 Electronic Stability Program + crc ^= (uint8_t[]){0xAC,0xB3,0xAB,0xEB,0x7A,0xE1,0x3B,0xF7,0x73,0xBA,0x7C,0x9E,0x06,0x5F,0x02,0xD9}[counter]; + break; + default: // As-yet undefined CAN message, CRC check expected to fail + printf("Attempt to CRC check undefined Volkswagen message 0x%02X\n", address); + crc ^= (uint8_t[]){0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}[counter]; + break; + } + crc = crc8_lut_8h2f[crc]; + + return crc ^ 0xFF; // Return after standard final XOR for CRC8 8H2F/AUTOSAR +} + + +unsigned int pedal_checksum(uint64_t d, int l) { + uint8_t crc = 0xFF; + uint8_t poly = 0xD5; // standard crc8 + + d >>= ((8-l)*8); // remove padding + d >>= 8; // remove checksum + + uint8_t *dat = (uint8_t *)&d; + + int i, j; + for (i = 0; i < l - 1; i++) { + crc ^= dat[i]; + for (j = 0; j < 8; j++) { + if ((crc & 0x80) != 0) { + crc = (uint8_t)((crc << 1) ^ poly); + } + else { + crc <<= 1; + } + } + } + return crc; +} + + +uint64_t read_u64_be(const uint8_t* v) { + return (((uint64_t)v[0] << 56) + | ((uint64_t)v[1] << 48) + | ((uint64_t)v[2] << 40) + | ((uint64_t)v[3] << 32) + | ((uint64_t)v[4] << 24) + | ((uint64_t)v[5] << 16) + | ((uint64_t)v[6] << 8) + | (uint64_t)v[7]); +} + +uint64_t read_u64_le(const uint8_t* v) { + return ((uint64_t)v[0] + | ((uint64_t)v[1] << 8) + | ((uint64_t)v[2] << 16) + | ((uint64_t)v[3] << 24) + | ((uint64_t)v[4] << 32) + | ((uint64_t)v[5] << 40) + | ((uint64_t)v[6] << 48) + | ((uint64_t)v[7] << 56)); +} diff --git a/selfdrive/can/common.h b/selfdrive/can/common.h index 4f097228432543..a496c3918b91ad 100644 --- a/selfdrive/can/common.h +++ b/selfdrive/can/common.h @@ -1,90 +1,59 @@ -#ifndef SELFDRIVE_CAN_COMMON_H -#define SELFDRIVE_CAN_COMMON_H +#pragma once -#include -#include -#include +#include +#include -#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) +#include "common_dbc.h" +#include +#include "cereal/gen/cpp/log.capnp.h" +#define MAX_BAD_COUNTER 5 +// Helper functions unsigned int honda_checksum(unsigned int address, uint64_t d, int l); unsigned int toyota_checksum(unsigned int address, uint64_t d, int l); -unsigned int pedal_checksum(unsigned int address, uint64_t d, int l); - -struct SignalPackValue { - const char* name; - double value; -}; - - -struct SignalParseOptions { +void init_crc_lookup_tables(); +unsigned int volkswagen_crc(unsigned int address, uint64_t d, int l); +unsigned int pedal_checksum(uint64_t d, int l); +uint64_t read_u64_be(const uint8_t* v); +uint64_t read_u64_le(const uint8_t* v); + +class MessageState { +public: uint32_t address; - const char* name; - double default_value; -}; + unsigned int size; -struct MessageParseOptions { - uint32_t address; - int check_frequency; -}; + std::vector parse_sigs; + std::vector vals; -struct SignalValue { - uint32_t address; uint16_t ts; - const char* name; - double value; -}; + uint64_t seen; + uint64_t check_threshold; + uint8_t counter; + uint8_t counter_fail; -enum SignalType { - DEFAULT, - HONDA_CHECKSUM, - HONDA_COUNTER, - TOYOTA_CHECKSUM, - PEDAL_CHECKSUM, - PEDAL_COUNTER, + bool parse(uint64_t sec, uint16_t ts_, uint8_t * dat); + bool update_counter_generic(int64_t v, int cnt_size); }; -struct Signal { - const char* name; - int b1, b2, bo; - bool is_signed; - double factor, offset; - bool is_little_endian; - SignalType type; -}; +class CANParser { +private: + const int bus; -struct Msg { - const char* name; - uint32_t address; - unsigned int size; - size_t num_sigs; - const Signal *sigs; -}; - -struct Val { - const char* name; - uint32_t address; - const char* def_val; - const Signal *sigs; -}; - -struct DBC { - const char* name; - size_t num_msgs; - const Msg *msgs; - const Val *vals; - size_t num_vals; -}; + const DBC *dbc = NULL; + std::unordered_map message_states; -const DBC* dbc_lookup(const std::string& dbc_name); +public: + bool can_valid = false; + uint64_t last_sec = 0; -void dbc_register(const DBC* dbc); + CANParser(int abus, const std::string& dbc_name, + const std::vector &options, + const std::vector &sigoptions); + void UpdateCans(uint64_t sec, const capnp::List::Reader& cans); + void UpdateValid(uint64_t sec); + void update_string(std::string data); + std::vector query_latest(); -#define dbc_init(dbc) \ -static void __attribute__((constructor)) do_dbc_init_ ## dbc(void) { \ - dbc_register(&dbc); \ -} - -#endif +}; diff --git a/selfdrive/can/common.pxd b/selfdrive/can/common.pxd new file mode 100644 index 00000000000000..54c6e444fdfcd8 --- /dev/null +++ b/selfdrive/can/common.pxd @@ -0,0 +1,71 @@ +# distutils: language = c++ +#cython: language_level=3 + +from libc.stdint cimport uint32_t, uint64_t, uint16_t +from libcpp.vector cimport vector +from libcpp.map cimport map +from libcpp.string cimport string +from libcpp.unordered_set cimport unordered_set +from libcpp cimport bool + + +cdef extern from "common.h": + + ctypedef enum SignalType: + DEFAULT, + HONDA_CHECKSUM, + HONDA_COUNTER, + TOYOTA_CHECKSUM, + PEDAL_CHECKSUM, + PEDAL_COUNTER + + cdef struct Signal: + const char* name + int b1, b2, bo + bool is_signed + double factor, offset + SignalType type + + cdef struct Msg: + const char* name + uint32_t address + unsigned int size + size_t num_sigs + const Signal *sigs + + cdef struct Val: + const char* name + uint32_t address + const char* def_val + const Signal *sigs + + cdef struct DBC: + const char* name + size_t num_msgs + const Msg *msgs + const Val *vals + size_t num_vals + + cdef struct SignalParseOptions: + uint32_t address + const char* name + double default_value + + + cdef struct MessageParseOptions: + uint32_t address + int check_frequency + + cdef struct SignalValue: + uint32_t address + uint16_t ts + const char* name + double value + + cdef const DBC* dbc_lookup(const string); + + cdef cppclass CANParser: + bool can_valid + CANParser(int, string, vector[MessageParseOptions], vector[SignalParseOptions]) + void update_string(string) + vector[SignalValue] query_latest() diff --git a/selfdrive/can/common_dbc.h b/selfdrive/can/common_dbc.h new file mode 100644 index 00000000000000..ae6f443ec90cd3 --- /dev/null +++ b/selfdrive/can/common_dbc.h @@ -0,0 +1,82 @@ +#pragma once + +#include +#include +#include + +#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) + +struct SignalPackValue { + const char* name; + double value; +}; + +struct SignalParseOptions { + uint32_t address; + const char* name; + double default_value; +}; + +struct MessageParseOptions { + uint32_t address; + int check_frequency; +}; + +struct SignalValue { + uint32_t address; + uint16_t ts; + const char* name; + double value; +}; + +enum SignalType { + DEFAULT, + HONDA_CHECKSUM, + HONDA_COUNTER, + TOYOTA_CHECKSUM, + PEDAL_CHECKSUM, + PEDAL_COUNTER, + VOLKSWAGEN_CHECKSUM, + VOLKSWAGEN_COUNTER, +}; + +struct Signal { + const char* name; + int b1, b2, bo; + bool is_signed; + double factor, offset; + bool is_little_endian; + SignalType type; +}; + +struct Msg { + const char* name; + uint32_t address; + unsigned int size; + size_t num_sigs; + const Signal *sigs; +}; + +struct Val { + const char* name; + uint32_t address; + const char* def_val; + const Signal *sigs; +}; + +struct DBC { + const char* name; + size_t num_msgs; + const Msg *msgs; + const Val *vals; + size_t num_vals; +}; + +const DBC* dbc_lookup(const std::string& dbc_name); + +void dbc_register(const DBC* dbc); + +#define dbc_init(dbc) \ +static void __attribute__((constructor)) do_dbc_init_ ## dbc(void) { \ + dbc_register(&dbc); \ +} diff --git a/selfdrive/can/dbc.cc b/selfdrive/can/dbc.cc index 95d5e4d791394a..6587de7fe0163a 100644 --- a/selfdrive/can/dbc.cc +++ b/selfdrive/can/dbc.cc @@ -1,7 +1,6 @@ -#include #include -#include "common.h" +#include "common_dbc.h" namespace { diff --git a/selfdrive/can/dbc_template.cc b/selfdrive/can/dbc_template.cc index 776403b22f03ff..d916eeada06a43 100644 --- a/selfdrive/can/dbc_template.cc +++ b/selfdrive/can/dbc_template.cc @@ -1,6 +1,4 @@ -#include - -#include "common.h" +#include "common_dbc.h" namespace { @@ -27,6 +25,10 @@ const Signal sigs_{{address}}[] = { .type = SignalType::HONDA_COUNTER, {% elif checksum_type == "toyota" and sig.name == "CHECKSUM" %} .type = SignalType::TOYOTA_CHECKSUM, + {% elif checksum_type == "volkswagen" and sig.name == "CHECKSUM" %} + .type = SignalType::VOLKSWAGEN_CHECKSUM, + {% elif checksum_type == "volkswagen" and sig.name == "COUNTER" %} + .type = SignalType::VOLKSWAGEN_COUNTER, {% elif address in [512, 513] and sig.name == "CHECKSUM_PEDAL" %} .type = SignalType::PEDAL_CHECKSUM, {% elif address in [512, 513] and sig.name == "COUNTER_PEDAL" %} diff --git a/selfdrive/can/libdbc_py.py b/selfdrive/can/libdbc_py.py index cf712cf634ee89..92093f9316896e 100644 --- a/selfdrive/can/libdbc_py.py +++ b/selfdrive/can/libdbc_py.py @@ -5,7 +5,7 @@ can_dir = os.path.dirname(os.path.abspath(__file__)) libdbc_fn = os.path.join(can_dir, "libdbc.so") -subprocess.check_call(["make"], cwd=can_dir) +subprocess.check_call(["make", "-j3"], cwd=can_dir) # don't use all the cores to avoid overheating ffi = FFI() ffi.cdef(""" @@ -41,6 +41,8 @@ TOYOTA_CHECKSUM, PEDAL_CHECKSUM, PEDAL_COUNTER, + VOLKSWAGEN_CHECKSUM, + VOLKSWAGEN_COUNTER, } SignalType; typedef struct { @@ -77,12 +79,11 @@ void* can_init(int bus, const char* dbc_name, size_t num_message_options, const MessageParseOptions* message_options, - size_t num_signal_options, const SignalParseOptions* signal_options, bool sendcan, - const char* tcp_addr); + size_t num_signal_options, const SignalParseOptions* signal_options); -void can_update(void* can, uint64_t sec, bool wait); +void can_update_string(void *can, const char* dat, int len); -size_t can_query(void* can, uint64_t sec, bool *out_can_valid, size_t out_values_size, SignalValue* out_values); +size_t can_query_latest(void* can, bool *out_can_valid, size_t out_values_size, SignalValue* out_values); const DBC* dbc_lookup(const char* dbc_name); diff --git a/selfdrive/can/packer.cc b/selfdrive/can/packer.cc index 17171f15503048..c658e56731f3f3 100644 --- a/selfdrive/can/packer.cc +++ b/selfdrive/can/packer.cc @@ -1,6 +1,4 @@ #include -#include -#include #include #include #include @@ -51,6 +49,7 @@ namespace { signal_lookup[std::make_pair(msg->address, std::string(sig->name))] = *sig; } } + init_crc_lookup_tables(); } uint64_t pack(uint32_t address, const std::vector &signals, int counter) { @@ -82,23 +81,28 @@ namespace { } auto sig = sig_it->second; - if (sig.type != SignalType::HONDA_COUNTER){ + if ((sig.type != SignalType::HONDA_COUNTER) && (sig.type != SignalType::VOLKSWAGEN_COUNTER)) { WARN("COUNTER signal type not valid\n"); } ret = set_value(ret, sig, counter); } - auto sig_it = signal_lookup.find(std::make_pair(address, "CHECKSUM")); - if (sig_it != signal_lookup.end()) { - auto sig = sig_it->second; - if (sig.type == SignalType::HONDA_CHECKSUM){ + auto sig_it_checksum = signal_lookup.find(std::make_pair(address, "CHECKSUM")); + if (sig_it_checksum != signal_lookup.end()) { + auto sig = sig_it_checksum->second; + if (sig.type == SignalType::HONDA_CHECKSUM) { unsigned int chksm = honda_checksum(address, ret, message_lookup[address].size); ret = set_value(ret, sig, chksm); - } - else if (sig.type == SignalType::TOYOTA_CHECKSUM){ + } else if (sig.type == SignalType::TOYOTA_CHECKSUM) { unsigned int chksm = toyota_checksum(address, ret, message_lookup[address].size); ret = set_value(ret, sig, chksm); + } else if (sig.type == SignalType::VOLKSWAGEN_CHECKSUM) { + // FIXME: Hackish fix for an endianness issue. The message is in reverse byte order + // until later in the pack process. Checksums can be run backwards, CRCs not so much. + // The correct fix is unclear but this works for the moment. + unsigned int chksm = volkswagen_crc(address, ReverseBytes(ret), message_lookup[address].size); + ret = set_value(ret, sig, chksm); } else { //WARN("CHECKSUM signal type not valid\n"); } @@ -108,7 +112,6 @@ namespace { } - private: const DBC *dbc = NULL; std::map, Signal> signal_lookup; @@ -129,4 +132,8 @@ extern "C" { return cp->pack(address, std::vector(vals, vals+num_vals), counter); } + uint64_t canpack_pack_vector(void* inst, uint32_t address, const std::vector &signals, int counter) { + CANPacker *cp = (CANPacker*)inst; + return cp->pack(address, signals, counter); + } } diff --git a/selfdrive/can/packer.py b/selfdrive/can/packer.py index cc669e60c6a23c..ccb537c9565036 100644 --- a/selfdrive/can/packer.py +++ b/selfdrive/can/packer.py @@ -1,67 +1,9 @@ -import struct -from selfdrive.can.libdbc_py import libdbc, ffi +# pylint: skip-file +import os +import subprocess +can_dir = os.path.dirname(os.path.abspath(__file__)) +subprocess.check_call(["make", "-j3", "packer_impl.so"], cwd=can_dir) # don't use all the cores to avoid overheating -class CANPacker(object): - def __init__(self, dbc_name): - self.packer = libdbc.canpack_init(dbc_name) - self.dbc = libdbc.dbc_lookup(dbc_name) - self.sig_names = {} - self.name_to_address_and_size = {} - - num_msgs = self.dbc[0].num_msgs - for i in range(num_msgs): - msg = self.dbc[0].msgs[i] - - name = ffi.string(msg.name) - address = msg.address - self.name_to_address_and_size[name] = (address, msg.size) - self.name_to_address_and_size[address] = (address, msg.size) - - def pack(self, addr, values, counter): - values_thing = [] - for name, value in values.iteritems(): - if name not in self.sig_names: - self.sig_names[name] = ffi.new("char[]", name) - - values_thing.append({ - 'name': self.sig_names[name], - 'value': value - }) - - values_c = ffi.new("SignalPackValue[]", values_thing) - - return libdbc.canpack_pack(self.packer, addr, len(values_thing), values_c, counter) - - def pack_bytes(self, addr, values, counter=-1): - addr, size = self.name_to_address_and_size[addr] - - val = self.pack(addr, values, counter) - r = struct.pack(">Q", val) - return addr, r[:size] - - def make_can_msg(self, addr, bus, values, counter=-1): - addr, msg = self.pack_bytes(addr, values, counter) - return [addr, 0, msg, bus] - - -if __name__ == "__main__": - ## little endian test - cp = CANPacker("hyundai_santa_fe_2019_ccan") - s = cp.pack_bytes(0x340, { - "CR_Lkas_StrToqReq": -0.06, - #"CF_Lkas_FcwBasReq": 1, - "CF_Lkas_MsgCount": 7, - "CF_Lkas_HbaSysState": 0, - #"CF_Lkas_Chksum": 3, - }) - s = cp.pack_bytes(0x340, { - "CF_Lkas_MsgCount": 1, - }) - # big endian test - #cp = CANPacker("honda_civic_touring_2016_can_generated") - #s = cp.pack_bytes(0xe4, { - # "STEER_TORQUE": -2, - #}) - print [hex(ord(v)) for v in s[1]] - print(s[1].encode("hex")) +from selfdrive.can.packer_impl import CANPacker +assert CANPacker diff --git a/selfdrive/can/packer_impl.pyx b/selfdrive/can/packer_impl.pyx new file mode 100644 index 00000000000000..d7c6119b753874 --- /dev/null +++ b/selfdrive/can/packer_impl.pyx @@ -0,0 +1,124 @@ +# distutils: language = c++ +# cython: c_string_encoding=ascii, language_level=3 + +from libc.stdint cimport uint32_t, uint64_t +from libcpp.vector cimport vector +from libcpp.map cimport map +from libcpp.string cimport string +from libcpp cimport bool +from posix.dlfcn cimport dlopen, dlsym, RTLD_LAZY +import os +import subprocess + +cdef struct SignalPackValue: + const char* name + double value + +ctypedef enum SignalType: + DEFAULT, + HONDA_CHECKSUM, + HONDA_COUNTER, + TOYOTA_CHECKSUM, + PEDAL_CHECKSUM, + PEDAL_COUNTER, + VOLKSWAGEN_CHECKSUM, + VOLKSWAGEN_COUNTER + +cdef struct Signal: + const char* name + int b1, b2, bo + bool is_signed + double factor, offset + SignalType type + + + +cdef struct Msg: + const char* name + uint32_t address + unsigned int size + size_t num_sigs + const Signal *sigs + +cdef struct Val: + const char* name + uint32_t address + const char* def_val + const Signal *sigs + +cdef struct DBC: + const char* name + size_t num_msgs + const Msg *msgs + const Val *vals + size_t num_vals + +ctypedef void * (*canpack_init_func)(const char* dbc_name) +ctypedef uint64_t (*canpack_pack_vector_func)(void* inst, uint32_t address, const vector[SignalPackValue] &signals, int counter) +ctypedef const DBC * (*dbc_lookup_func)(const char* dbc_name) + + +cdef class CANPacker(): + cdef void *packer + cdef const DBC *dbc + cdef map[string, (int, int)] name_to_address_and_size + cdef map[int, int] address_to_size + cdef canpack_init_func canpack_init + cdef canpack_pack_vector_func canpack_pack_vector + cdef dbc_lookup_func dbc_lookup + + def __init__(self, dbc_name): + can_dir = os.path.dirname(os.path.abspath(__file__)) + libdbc_fn = os.path.join(can_dir, "libdbc.so") + libdbc_fn = str(libdbc_fn).encode('utf8') + subprocess.check_call(["make"], cwd=can_dir) + + cdef void *libdbc = dlopen(libdbc_fn, RTLD_LAZY) + self.canpack_init = dlsym(libdbc, 'canpack_init') + self.canpack_pack_vector = dlsym(libdbc, 'canpack_pack_vector') + self.dbc_lookup = dlsym(libdbc, 'dbc_lookup') + + self.packer = self.canpack_init(dbc_name) + self.dbc = self.dbc_lookup(dbc_name) + num_msgs = self.dbc[0].num_msgs + for i in range(num_msgs): + msg = self.dbc[0].msgs[i] + self.name_to_address_and_size[string(msg.name)] = (msg.address, msg.size) + self.address_to_size[msg.address] = msg.size + + cdef uint64_t pack(self, addr, values, counter): + cdef vector[SignalPackValue] values_thing + cdef SignalPackValue spv + + names = [] + + for name, value in values.iteritems(): + n = name.encode('utf8') + names.append(n) # TODO: find better way to keep reference to temp string arround + + spv.name = n + spv.value = value + values_thing.push_back(spv) + + return self.canpack_pack_vector(self.packer, addr, values_thing, counter) + + cdef inline uint64_t ReverseBytes(self, uint64_t x): + return (((x & 0xff00000000000000ull) >> 56) | + ((x & 0x00ff000000000000ull) >> 40) | + ((x & 0x0000ff0000000000ull) >> 24) | + ((x & 0x000000ff00000000ull) >> 8) | + ((x & 0x00000000ff000000ull) << 8) | + ((x & 0x0000000000ff0000ull) << 24) | + ((x & 0x000000000000ff00ull) << 40) | + ((x & 0x00000000000000ffull) << 56)) + + cpdef make_can_msg(self, name_or_addr, bus, values, counter=-1): + cdef int addr, size + if type(name_or_addr) == int: + addr = name_or_addr + size = self.address_to_size[name_or_addr] + else: + addr, size = self.name_to_address_and_size[name_or_addr.encode('utf8')] + cdef uint64_t val = self.pack(addr, values, counter) + val = self.ReverseBytes(val) + return [addr, 0, (&val)[:size], bus] diff --git a/selfdrive/can/packer_setup.py b/selfdrive/can/packer_setup.py new file mode 100644 index 00000000000000..8b25e605802841 --- /dev/null +++ b/selfdrive/can/packer_setup.py @@ -0,0 +1,9 @@ +from distutils.core import Extension, setup # pylint: disable=import-error,no-name-in-module + +from Cython.Build import cythonize + +from common.cython_hacks import BuildExtWithoutPlatformSuffix + +setup(name='CAN Packer API Implementation', + cmdclass={'build_ext': BuildExtWithoutPlatformSuffix}, + ext_modules=cythonize(Extension("packer_impl", ["packer_impl.pyx"], language="c++", extra_compile_args=["-std=c++11"]))) diff --git a/selfdrive/can/parser.cc b/selfdrive/can/parser.cc index b6845b47db2ad9..4d2dc32e2af919 100644 --- a/selfdrive/can/parser.cc +++ b/selfdrive/can/parser.cc @@ -1,5 +1,3 @@ -#include -#include #include #include @@ -7,16 +5,7 @@ #include #include #include - -#include -#include #include -#include - -#include - -#include -#include "cereal/gen/cpp/log.capnp.h" #include "common.h" @@ -25,502 +14,227 @@ #define INFO printf -#define MAX_BAD_COUNTER 5 - -unsigned int honda_checksum(unsigned int address, uint64_t d, int l) { - d >>= ((8-l)*8); // remove padding - d >>= 4; // remove checksum - - int s = 0; - while (address) { s += (address & 0xF); address >>= 4; } - while (d) { s += (d & 0xF); d >>= 4; } - s = 8-s; - s &= 0xF; - - return s; -} +bool MessageState::parse(uint64_t sec, uint16_t ts_, uint8_t * dat) { + uint64_t dat_le = read_u64_le(dat); + uint64_t dat_be = read_u64_be(dat); -unsigned int toyota_checksum(unsigned int address, uint64_t d, int l) { - d >>= ((8-l)*8); // remove padding - d >>= 8; // remove checksum + for (int i=0; i < parse_sigs.size(); i++) { + auto& sig = parse_sigs[i]; + int64_t tmp; - unsigned int s = l; - while (address) { s += address & 0xff; address >>= 8; } - while (d) { s += d & 0xff; d >>= 8; } - - return s & 0xFF; -} - -unsigned int pedal_checksum(unsigned int address, uint64_t d, int l) { - uint8_t crc = 0xFF; - uint8_t poly = 0xD5; // standard crc8 + if (sig.is_little_endian){ + tmp = (dat_le >> sig.b1) & ((1ULL << sig.b2)-1); + } else { + tmp = (dat_be >> sig.bo) & ((1ULL << sig.b2)-1); + } - d >>= ((8-l)*8); // remove padding - d >>= 8; // remove checksum + if (sig.is_signed) { + tmp -= (tmp >> (sig.b2-1)) ? (1ULL << sig.b2) : 0; //signed + } - uint8_t *dat = (uint8_t *)&d; + DEBUG("parse 0x%X %s -> %lld\n", address, sig.name, tmp); - int i, j; - for (i = 0; i < l - 1; i++) { - crc ^= dat[i]; - for (j = 0; j < 8; j++) { - if ((crc & 0x80) != 0) { - crc = (uint8_t)((crc << 1) ^ poly); + if (sig.type == SignalType::HONDA_CHECKSUM) { + if (honda_checksum(address, dat_be, size) != tmp) { + INFO("0x%X CHECKSUM FAIL\n", address); + return false; } - else { - crc <<= 1; + } else if (sig.type == SignalType::HONDA_COUNTER) { + if (!update_counter_generic(tmp, sig.b2)) { + return false; } - } - } - return crc; -} - -namespace { - -uint64_t read_u64_be(const uint8_t* v) { - return (((uint64_t)v[0] << 56) - | ((uint64_t)v[1] << 48) - | ((uint64_t)v[2] << 40) - | ((uint64_t)v[3] << 32) - | ((uint64_t)v[4] << 24) - | ((uint64_t)v[5] << 16) - | ((uint64_t)v[6] << 8) - | (uint64_t)v[7]); -} - -uint64_t read_u64_le(const uint8_t* v) { - return ((uint64_t)v[0] - | ((uint64_t)v[1] << 8) - | ((uint64_t)v[2] << 16) - | ((uint64_t)v[3] << 24) - | ((uint64_t)v[4] << 32) - | ((uint64_t)v[5] << 40) - | ((uint64_t)v[6] << 48) - | ((uint64_t)v[7] << 56)); -} - - -struct MessageState { - uint32_t address; - unsigned int size; - - std::vector parse_sigs; - std::vector vals; - - uint16_t ts; - uint64_t seen; - uint64_t check_threshold; - - uint8_t counter; - uint8_t counter_fail; - - bool parse(uint64_t sec, uint16_t ts_, uint64_t dat) { - for (int i=0; i < parse_sigs.size(); i++) { - auto& sig = parse_sigs[i]; - int64_t tmp; - - if (sig.is_little_endian){ - tmp = (dat >> sig.b1) & ((1ULL << sig.b2)-1); - } else { - tmp = (dat >> sig.bo) & ((1ULL << sig.b2)-1); + } else if (sig.type == SignalType::TOYOTA_CHECKSUM) { + if (toyota_checksum(address, dat_be, size) != tmp) { + INFO("0x%X CHECKSUM FAIL\n", address); + return false; } - - if (sig.is_signed) { - tmp -= (tmp >> (sig.b2-1)) ? (1ULL << sig.b2) : 0; //signed + } else if (sig.type == SignalType::VOLKSWAGEN_CHECKSUM) { + if (volkswagen_crc(address, dat_le, size) != tmp) { + INFO("0x%X CRC FAIL\n", address); + return false; } - - DEBUG("parse %X %s -> %lld\n", address, sig.name, tmp); - - if (sig.type == SignalType::HONDA_CHECKSUM) { - if (honda_checksum(address, dat, size) != tmp) { - INFO("%X CHECKSUM FAIL\n", address); - return false; - } - } else if (sig.type == SignalType::HONDA_COUNTER) { - if (!update_counter_generic(tmp, sig.b2)) { - return false; - } - } else if (sig.type == SignalType::TOYOTA_CHECKSUM) { - if (toyota_checksum(address, dat, size) != tmp) { - INFO("%X CHECKSUM FAIL\n", address); - return false; - } - } else if (sig.type == SignalType::PEDAL_CHECKSUM) { - if (pedal_checksum(address, dat, size) != tmp) { - INFO("%X PEDAL CHECKSUM FAIL\n", address); - return false; - } - } else if (sig.type == SignalType::PEDAL_COUNTER) { + } else if (sig.type == SignalType::VOLKSWAGEN_COUNTER) { if (!update_counter_generic(tmp, sig.b2)) { - return false; - } + INFO("0x%X CHECKSUM FAIL\n", address); + return false; } - - vals[i] = tmp * sig.factor + sig.offset; - } - ts = ts_; - seen = sec; - - return true; - } - - - bool update_counter_generic(int64_t v, int cnt_size) { - uint8_t old_counter = counter; - counter = v; - if (((old_counter+1) & ((1 << cnt_size) -1)) != v) { - counter_fail += 1; - if (counter_fail > 1) { - INFO("%X COUNTER FAIL %d -- %d vs %d\n", address, counter_fail, old_counter, (int)v); + } else if (sig.type == SignalType::PEDAL_CHECKSUM) { + if (pedal_checksum(dat_be, size) != tmp) { + INFO("0x%X PEDAL CHECKSUM FAIL\n", address); + return false; } - if (counter_fail >= MAX_BAD_COUNTER) { + } else if (sig.type == SignalType::PEDAL_COUNTER) { + if (!update_counter_generic(tmp, sig.b2)) { return false; } - } else if (counter_fail > 0) { - counter_fail--; } - return true; + + vals[i] = tmp * sig.factor + sig.offset; } + ts = ts_; + seen = sec; -}; + return true; +} -class CANParser { - public: - CANParser(int abus, const std::string& dbc_name, - const std::vector &options, - const std::vector &sigoptions, - bool sendcan, const std::string& tcp_addr) - : bus(abus) { - // connect to can on 8006 - context = zmq_ctx_new(); - subscriber = zmq_socket(context, ZMQ_SUB); - zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0); +bool MessageState::update_counter_generic(int64_t v, int cnt_size) { + uint8_t old_counter = counter; + counter = v; + if (((old_counter+1) & ((1 << cnt_size) -1)) != v) { + counter_fail += 1; + if (counter_fail > 1) { + INFO("%X COUNTER FAIL %d -- %d vs %d\n", address, counter_fail, old_counter, (int)v); + } + if (counter_fail >= MAX_BAD_COUNTER) { + return false; + } + } else if (counter_fail > 0) { + counter_fail--; + } + return true; +} - std::string tcp_addr_str; - if (sendcan) { - tcp_addr_str = "tcp://" + tcp_addr + ":8017"; - } else { - tcp_addr_str = "tcp://" + tcp_addr + ":8006"; - } - const char *tcp_addr_char = tcp_addr_str.c_str(); +CANParser::CANParser(int abus, const std::string& dbc_name, + const std::vector &options, + const std::vector &sigoptions) + : bus(abus) { - zmq_connect(subscriber, tcp_addr_char); + dbc = dbc_lookup(dbc_name); + assert(dbc); + init_crc_lookup_tables(); - // drain sendcan to delete any stale messages from previous runs - zmq_msg_t msgDrain; - zmq_msg_init(&msgDrain); - int err = 0; - while(err >= 0) { - err = zmq_msg_recv(&msgDrain, subscriber, ZMQ_DONTWAIT); - } + for (const auto& op : options) { + MessageState state = { + .address = op.address, + // .check_frequency = op.check_frequency, + }; - dbc = dbc_lookup(dbc_name); - assert(dbc); + // msg is not valid if a message isn't received for 10 consecutive steps + if (op.check_frequency > 0) { + state.check_threshold = (1000000000ULL / op.check_frequency) * 10; + } - for (const auto& op : options) { - MessageState state = { - .address = op.address, - // .check_frequency = op.check_frequency, - }; - // msg is not valid if a message isn't received for 10 consecutive steps - if (op.check_frequency > 0) { - state.check_threshold = (1000000000ULL / op.check_frequency) * 10; + const Msg* msg = NULL; + for (int i=0; inum_msgs; i++) { + if (dbc->msgs[i].address == op.address) { + msg = &dbc->msgs[i]; + break; } + } + if (!msg) { + fprintf(stderr, "CANParser: could not find message 0x%X in dnc %s\n", op.address, dbc_name.c_str()); + assert(false); + } + state.size = msg->size; - const Msg* msg = NULL; - for (int i=0; inum_msgs; i++) { - if (dbc->msgs[i].address == op.address) { - msg = &dbc->msgs[i]; - break; - } - } - if (!msg) { - fprintf(stderr, "CANParser: could not find message 0x%X in dnc %s\n", op.address, dbc_name.c_str()); - assert(false); + // track checksums and counters for this message + for (int i=0; inum_sigs; i++) { + const Signal *sig = &msg->sigs[i]; + if (sig->type != SignalType::DEFAULT) { + state.parse_sigs.push_back(*sig); + state.vals.push_back(0); } + } - state.size = msg->size; + // track requested signals for this message + for (const auto& sigop : sigoptions) { + if (sigop.address != op.address) continue; - // track checksums and counters for this message for (int i=0; inum_sigs; i++) { const Signal *sig = &msg->sigs[i]; - if (sig->type != SignalType::DEFAULT) { + if (strcmp(sig->name, sigop.name) == 0 + && sig->type == SignalType::DEFAULT) { state.parse_sigs.push_back(*sig); - state.vals.push_back(0); - } - } - - // track requested signals for this message - for (const auto& sigop : sigoptions) { - if (sigop.address != op.address) continue; - - for (int i=0; inum_sigs; i++) { - const Signal *sig = &msg->sigs[i]; - if (strcmp(sig->name, sigop.name) == 0 - && sig->type == SignalType::DEFAULT) { - state.parse_sigs.push_back(*sig); - state.vals.push_back(sigop.default_value); - break; - } + state.vals.push_back(sigop.default_value); + break; } - } - message_states[state.address] = state; } - } - - void UpdateCans(uint64_t sec, const capnp::List::Reader& cans) { - int msg_count = cans.size(); - uint64_t p; - - DEBUG("got %d messages\n", msg_count); - // parse the messages - for (int i = 0; i < msg_count; i++) { - auto cmsg = cans[i]; - if (cmsg.getSrc() != bus) { - // DEBUG("skip %d: wrong bus\n", cmsg.getAddress()); - continue; - } - auto state_it = message_states.find(cmsg.getAddress()); - if (state_it == message_states.end()) { - // DEBUG("skip %d: not specified\n", cmsg.getAddress()); - continue; - } + message_states[state.address] = state; + } +} - if (cmsg.getDat().size() > 8) continue; //shouldnt ever happen - uint8_t dat[8] = {0}; - memcpy(dat, cmsg.getDat().begin(), cmsg.getDat().size()); - - // Assumes all signals in the message are of the same type (little or big endian) - // TODO: allow signals within the same message to have different endianess - auto& sig = message_states[cmsg.getAddress()].parse_sigs[0]; - if (sig.is_little_endian) { - p = read_u64_le(dat); - } else { - p = read_u64_be(dat); - } +void CANParser::UpdateCans(uint64_t sec, const capnp::List::Reader& cans) { + int msg_count = cans.size(); + uint64_t p; - DEBUG(" proc %X: %llx\n", cmsg.getAddress(), p); + DEBUG("got %d messages\n", msg_count); - state_it->second.parse(sec, cmsg.getBusTime(), p); + // parse the messages + for (int i = 0; i < msg_count; i++) { + auto cmsg = cans[i]; + if (cmsg.getSrc() != bus) { + // DEBUG("skip %d: wrong bus\n", cmsg.getAddress()); + continue; } - } - - void UpdateValid(uint64_t sec) { - can_valid = true; - for (const auto& kv : message_states) { - const auto& state = kv.second; - if (state.check_threshold > 0 && (sec - state.seen) > state.check_threshold) { - if (state.seen > 0) { - DEBUG("%X TIMEOUT\n", state.address); - } - can_valid = false; + auto state_it = message_states.find(cmsg.getAddress()); + if (state_it == message_states.end()) { + // DEBUG("skip %d: not specified\n", cmsg.getAddress()); + continue; } - } - } - - void update(uint64_t sec, bool wait) { - int err; - - // recv from can - zmq_msg_t msg; - zmq_msg_init(&msg); - - // multiple recv is fine - bool first = wait; - while (1) { - if (first) { - err = zmq_msg_recv(&msg, subscriber, 0); - first = false; - } else { - err = zmq_msg_recv(&msg, subscriber, ZMQ_DONTWAIT); - } - if (err < 0) break; - - // format for board, make copy due to alignment issues, will be freed on out of scope - auto amsg = kj::heapArray((zmq_msg_size(&msg) / sizeof(capnp::word)) + 1); - memcpy(amsg.begin(), zmq_msg_data(&msg), zmq_msg_size(&msg)); - // extract the messages - capnp::FlatArrayMessageReader cmsg(amsg); - cereal::Event::Reader event = cmsg.getRoot(); + if (cmsg.getDat().size() > 8) continue; //shouldnt ever happen + uint8_t dat[8] = {0}; + memcpy(dat, cmsg.getDat().begin(), cmsg.getDat().size()); - auto cans = event.getCan(); - - UpdateCans(sec, cans); + state_it->second.parse(sec, cmsg.getBusTime(), dat); } +} - UpdateValid(sec); - - zmq_msg_close(&msg); - } - - std::vector query(uint64_t sec) { - std::vector ret; - - for (const auto& kv : message_states) { - const auto& state = kv.second; - if (sec != 0 && state.seen != sec) continue; - - for (int i=0; i 0 && (sec - state.seen) > state.check_threshold) { + if (state.seen > 0) { + DEBUG("%X TIMEOUT\n", state.address); } + can_valid = false; } - - return ret; } +} - bool can_valid = false; - - private: - const int bus; - // zmq vars - void *context = NULL; - void *subscriber = NULL; +void CANParser::update_string(std::string data) { + // format for board, make copy due to alignment issues, will be freed on out of scope + auto amsg = kj::heapArray((data.length() / sizeof(capnp::word)) + 1); + memcpy(amsg.begin(), data.data(), data.length()); - const DBC *dbc = NULL; - std::unordered_map message_states; -}; + // extract the messages + capnp::FlatArrayMessageReader cmsg(amsg); + cereal::Event::Reader event = cmsg.getRoot(); -} + last_sec = event.getLogMonoTime(); -extern "C" { - -void* can_init(int bus, const char* dbc_name, - size_t num_message_options, const MessageParseOptions* message_options, - size_t num_signal_options, const SignalParseOptions* signal_options, - bool sendcan, const char* tcp_addr) { - CANParser* ret = new CANParser(bus, std::string(dbc_name), - (message_options ? std::vector(message_options, message_options+num_message_options) - : std::vector{}), - (signal_options ? std::vector(signal_options, signal_options+num_signal_options) - : std::vector{}), sendcan, std::string(tcp_addr)); - return (void*)ret; -} + auto cans = event.getCan(); + UpdateCans(last_sec, cans); -void can_update(void* can, uint64_t sec, bool wait) { - CANParser* cp = (CANParser*)can; - cp->update(sec, wait); + UpdateValid(last_sec); } -size_t can_query(void* can, uint64_t sec, bool *out_can_valid, size_t out_values_size, SignalValue* out_values) { - CANParser* cp = (CANParser*)can; - - if (out_can_valid) { - *out_can_valid = cp->can_valid; - } - const std::vector values = cp->query(sec); - if (out_values) { - std::copy(values.begin(), values.begin()+std::min(out_values_size, values.size()), out_values); - } - return values.size(); -}; +std::vector CANParser::query_latest() { + std::vector ret; -} + for (const auto& kv : message_states) { + const auto& state = kv.second; + if (last_sec != 0 && state.seen != last_sec) continue; -#ifdef TEST - -int main(int argc, char** argv) { - CANParser cp(0, "honda_civic_touring_2016_can", - std::vector{ - // address, check_frequency - {0x14a, 100}, - {0x158, 100}, - {0x17c, 100}, - {0x191, 100}, - {0x1a4, 50}, - {0x326, 10}, - {0x1b0, 50}, - {0x1d0, 50}, - {0x305, 10}, - {0x324, 10}, - {0x405, 3}, - {0x18f, 0}, - {0x130, 0}, - {0x296, 0}, - {0x30c, 0}, - }, - std::vector{ - // sig_name, sig_address, default - {0x158, "XMISSION_SPEED", 0}, - {0x1d0, "WHEEL_SPEED_FL", 0}, - {0x1d0, "WHEEL_SPEED_FR", 0}, - {0x1d0, "WHEEL_SPEED_RL", 0}, - {0x14a, "STEER_ANGLE", 0}, - {0x18f, "STEER_TORQUE_SENSOR", 0}, - {0x191, "GEAR", 0}, - {0x1b0, "WHEELS_MOVING", 1}, - {0x405, "DOOR_OPEN_FL", 1}, - {0x405, "DOOR_OPEN_FR", 1}, - {0x405, "DOOR_OPEN_RL", 1}, - {0x405, "DOOR_OPEN_RR", 1}, - {0x324, "CRUISE_SPEED_PCM", 0}, - {0x305, "SEATBELT_DRIVER_LAMP", 1}, - {0x305, "SEATBELT_DRIVER_LATCHED", 0}, - {0x17c, "BRAKE_PRESSED", 0}, - {0x130, "CAR_GAS", 0}, - {0x296, "CRUISE_BUTTONS", 0}, - {0x1a4, "ESP_DISABLED", 1}, - {0x30c, "HUD_LEAD", 0}, - {0x1a4, "USER_BRAKE", 0}, - {0x18f, "STEER_STATUS", 5}, - {0x1d0, "WHEEL_SPEED_RR", 0}, - {0x1b0, "BRAKE_ERROR_1", 1}, - {0x1b0, "BRAKE_ERROR_2", 1}, - {0x191, "GEAR_SHIFTER", 0}, - {0x326, "MAIN_ON", 0}, - {0x17c, "ACC_STATUS", 0}, - {0x17c, "PEDAL_GAS", 0}, - {0x296, "CRUISE_SETTING", 0}, - {0x326, "LEFT_BLINKER", 0}, - {0x326, "RIGHT_BLINKER", 0}, - {0x324, "COUNTER", 0}, - {0x17c, "ENGINE_RPM", 0}, - }); - - - - const std::string log_fn = "dats.bin"; - - int log_fd = open(log_fn.c_str(), O_RDONLY, 0); - assert(log_fd >= 0); - - off_t log_size = lseek(log_fd, 0, SEEK_END); - lseek(log_fd, 0, SEEK_SET); - - void* log_data = mmap(NULL, log_size, PROT_READ, MAP_PRIVATE, log_fd, 0); - assert(log_data); - - auto words = kj::arrayPtr((const capnp::word*)log_data, log_size/sizeof(capnp::word)); - while (words.size() > 0) { - capnp::FlatArrayMessageReader reader(words); - - auto evt = reader.getRoot(); - auto cans = evt.getCan(); - - cp.UpdateCans(0, cans); - - words = kj::arrayPtr(reader.getEnd(), words.end()); + for (int i=0; iself.address_to_msg_name[cv.address].c_str() + cv_name = cv.name + + self.vl[cv.address][cv_name] = cv.value + self.ts[cv.address][cv_name] = cv.ts + + self.vl[name][cv_name] = cv.value + self.ts[name][cv_name] = cv.ts + + updated_val.insert(cv.address) + + return updated_val + + def update_string(self, dat): + self.can.update_string(dat) + return self.update_vl() + + def update_strings(self, strings): + updated_vals = set() + + for s in strings: + updated_val = self.update_string(s) + updated_vals.update(updated_val) + + return updated_vals diff --git a/selfdrive/can/parser_pyx_setup.py b/selfdrive/can/parser_pyx_setup.py new file mode 100644 index 00000000000000..a024c7a640f27a --- /dev/null +++ b/selfdrive/can/parser_pyx_setup.py @@ -0,0 +1,35 @@ +import os +import subprocess +from distutils.core import Extension, setup # pylint: disable=import-error,no-name-in-module + +from Cython.Build import cythonize + +from common.basedir import BASEDIR +from common.cython_hacks import BuildExtWithoutPlatformSuffix + +sourcefiles = ['parser_pyx.pyx'] +extra_compile_args = ["-std=c++11"] +ARCH = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() # pylint: disable=unexpected-keyword-arg + +if ARCH == "aarch64": + extra_compile_args += ["-Wno-deprecated-register"] + +setup(name='CAN parser', + cmdclass={'build_ext': BuildExtWithoutPlatformSuffix}, + ext_modules=cythonize( + Extension( + "parser_pyx", + language="c++", + sources=sourcefiles, + extra_compile_args=extra_compile_args, + include_dirs=[ + BASEDIR, + os.path.join(BASEDIR, 'phonelibs', 'capnp-cpp/include'), + ], + extra_link_args=[ + os.path.join(BASEDIR, 'selfdrive', 'can', 'libdbc.so'), + ], + ) + ), + nthreads=4, +) diff --git a/selfdrive/can/plant_can_parser.py b/selfdrive/can/plant_can_parser.py index 44939747cee521..37ea3353744a60 100644 --- a/selfdrive/can/plant_can_parser.py +++ b/selfdrive/can/plant_can_parser.py @@ -7,7 +7,7 @@ from common.realtime import sec_since_boot from common.dbc import dbc -class CANParser(object): +class CANParser(): def __init__(self, dbc_f, signals, checks=None): ### input: # dbc_f : dbc file @@ -21,7 +21,7 @@ def __init__(self, dbc_f, signals, checks=None): # - frequency is the frequency at which health should be monitored. checks = [] if checks is None else checks - self.msgs_ck = set([check[0] for check in checks]) + self.msgs_ck = {check[0] for check in checks} self.frqs = dict(checks) self.can_valid = False # start with False CAN assumption # list of received msg we want to monitor counter and checksum for @@ -73,12 +73,12 @@ def update_can(self, can_recv): self.ck[msg] = True if "CHECKSUM" in out.keys() and msg in self.msgs_ck: # remove checksum (half byte) - ck_portion = cdat[:-1] + chr(ord(cdat[-1]) & 0xF0) + ck_portion = cdat[:-1] + (cdat[-1] & 0xF0).to_bytes(1, 'little') # recalculate checksum msg_vl = fix(ck_portion, msg) # compare recalculated vs received checksum if msg_vl != cdat: - print "CHECKSUM FAIL: " + hex(msg) + print("CHECKSUM FAIL: {0}".format(hex(msg))) self.ck[msg] = False self.ok[msg] = False # counter check @@ -87,13 +87,13 @@ def update_can(self, can_recv): cn = out["COUNTER"] # check counter validity if it's a relevant message if cn != ((self.cn[msg] + 1) % 4) and msg in self.msgs_ck and "COUNTER" in out.keys(): - #print hex(msg), "FAILED COUNTER!" + #print("FAILED COUNTER: {0}".format(hex(msg)() self.cn_vl[msg] += 1 # counter check failed else: self.cn_vl[msg] -= 1 # counter check passed # message status is invalid if we received too many wrong counter values if self.cn_vl[msg] >= cn_vl_max: - print "COUNTER WRONG: " + hex(msg) + print("COUNTER WRONG: {0}".format(hex(msg))) self.ok[msg] = False # update msg time stamps and counter value @@ -118,7 +118,7 @@ def update_can(self, can_recv): self.can_valid = True if False in self.ok.values(): - #print "CAN INVALID!" + #print("CAN INVALID!") self.can_valid = False return msgs_upd diff --git a/selfdrive/can/process_dbc.py b/selfdrive/can/process_dbc.py index 810947c8ef18d3..c1da3ce45c35db 100755 --- a/selfdrive/can/process_dbc.py +++ b/selfdrive/can/process_dbc.py @@ -1,4 +1,5 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 +from __future__ import print_function import os import sys @@ -7,62 +8,98 @@ from collections import Counter from common.dbc import dbc -if len(sys.argv) != 3: - print "usage: %s dbc_path struct_path" % (sys.argv[0],) - sys.exit(0) - -dbc_fn = sys.argv[1] -out_fn = sys.argv[2] - -template_fn = os.path.join(os.path.dirname(__file__), "dbc_template.cc") - -can_dbc = dbc(dbc_fn) - -with open(template_fn, "r") as template_f: - template = jinja2.Template(template_f.read(), trim_blocks=True, lstrip_blocks=True) - -msgs = [(address, msg_name, msg_size, sorted(msg_sigs, key=lambda s: s.name not in ("COUNTER", "CHECKSUM"))) # process counter and checksums first - for address, ((msg_name, msg_size), msg_sigs) in sorted(can_dbc.msgs.iteritems()) if msg_sigs] - -def_vals = {a: set(b) for a,b in can_dbc.def_vals.items()} #remove duplicates -def_vals = [(address, sig) for address, sig in sorted(def_vals.iteritems())] - -if can_dbc.name.startswith("honda") or can_dbc.name.startswith("acura"): - checksum_type = "honda" - checksum_size = 4 -elif can_dbc.name.startswith("toyota") or can_dbc.name.startswith("lexus"): - checksum_type = "toyota" - checksum_size = 8 -else: - checksum_type = None - -for address, msg_name, msg_size, sigs in msgs: - for sig in sigs: - if checksum_type is not None and sig.name == "CHECKSUM": - if sig.size != checksum_size: - sys.exit("CHECKSUM is not %d bits longs %s" % (checksum_size, msg_name)) - if checksum_type == "honda" and sig.start_bit % 8 != 3: - sys.exit("CHECKSUM starts at wrong bit %s" % msg_name) - if checksum_type == "toyota" and sig.start_bit % 8 != 7: - sys.exit("CHECKSUM starts at wrong bit %s" % msg_name) - if checksum_type == "honda" and sig.name == "COUNTER": - if sig.size != 2: - sys.exit("COUNTER is not 2 bits longs %s" % msg_name) - if sig.start_bit % 8 != 5: - sys.exit("COUNTER starts at wrong bit %s" % msg_name) - if address in [0x200, 0x201]: - if sig.name == "COUNTER_PEDAL" and sig.size != 4: - sys.exit("PEDAL COUNTER is not 4 bits longs %s" % msg_name) - if sig.name == "CHECKSUM_PEDAL" and sig.size != 8: - sys.exit("PEDAL CHECKSUM is not 8 bits longs %s" % msg_name) - -# Fail on duplicate message names -c = Counter([msg_name for address, msg_name, msg_size, sigs in msgs]) -for name, count in c.items(): - if count > 1: - sys.exit("Duplicate message name in DBC file %s" % name) - -parser_code = template.render(dbc=can_dbc, checksum_type=checksum_type, msgs=msgs, def_vals=def_vals, len=len) - -with open(out_fn, "w") as out_f: - out_f.write(parser_code) +def main(): + if len(sys.argv) != 3: + print("usage: %s dbc_directory output_filename" % (sys.argv[0],)) + sys.exit(0) + + dbc_dir = sys.argv[1] + out_fn = sys.argv[2] + + dbc_name = os.path.split(out_fn)[-1].replace('.cc', '') + + template_fn = os.path.join(os.path.dirname(__file__), "dbc_template.cc") + + with open(template_fn, "r") as template_f: + template = jinja2.Template(template_f.read(), trim_blocks=True, lstrip_blocks=True) + + can_dbc = dbc(os.path.join(dbc_dir, dbc_name + '.dbc')) + + msgs = [(address, msg_name, msg_size, sorted(msg_sigs, key=lambda s: s.name not in ("COUNTER", "CHECKSUM"))) # process counter and checksums first + for address, ((msg_name, msg_size), msg_sigs) in sorted(can_dbc.msgs.items()) if msg_sigs] + + def_vals = {a: set(b) for a,b in can_dbc.def_vals.items()} #remove duplicates + def_vals = sorted(def_vals.items()) + + if can_dbc.name.startswith(("honda_", "acura_")): + checksum_type = "honda" + checksum_size = 4 + counter_size = 2 + checksum_start_bit = 3 + counter_start_bit = 5 + little_endian = False + elif can_dbc.name.startswith(("toyota_", "lexus_")): + checksum_type = "toyota" + checksum_size = 8 + counter_size = None + checksum_start_bit = 7 + counter_start_bit = None + little_endian = False + elif can_dbc.name.startswith(("vw_", "volkswagen_", "audi_", "seat_", "skoda_")): + checksum_type = "volkswagen" + checksum_size = 8 + counter_size = 4 + checksum_start_bit = 0 + counter_start_bit = 0 + little_endian = True + else: + checksum_type = None + checksum_size = None + counter_size = None + checksum_start_bit = None + counter_start_bit = None + little_endian = None + + # sanity checks on expected COUNTER and CHECKSUM rules, as packer and parser auto-compute those signals + for address, msg_name, msg_size, sigs in msgs: + dbc_msg_name = dbc_name + " " + msg_name + for sig in sigs: + if checksum_type is not None: + # checksum rules + if sig.name == "CHECKSUM": + if sig.size != checksum_size: + sys.exit("%s: CHECKSUM is not %d bits long" % (dbc_msg_name, checksum_size)) + if sig.start_bit % 8 != checksum_start_bit: + sys.exit("%s: CHECKSUM starts at wrong bit" % dbc_msg_name) + if little_endian != sig.is_little_endian: + sys.exit("%s: CHECKSUM has wrong endianess" % dbc_msg_name) + # counter rules + if sig.name == "COUNTER": + if counter_size is not None and sig.size != counter_size: + sys.exit("%s: COUNTER is not %d bits long" % (dbc_msg_name, counter_size)) + if counter_start_bit is not None and sig.start_bit % 8 != counter_start_bit: + print(counter_start_bit, sig.start_bit) + sys.exit("%s: COUNTER starts at wrong bit" % dbc_msg_name) + if little_endian != sig.is_little_endian: + sys.exit("%s: COUNTER has wrong endianess" % dbc_msg_name) + # pedal rules + if address in [0x200, 0x201]: + if sig.name == "COUNTER_PEDAL" and sig.size != 4: + sys.exit("%s: PEDAL COUNTER is not 4 bits long" % dbc_msg_name) + if sig.name == "CHECKSUM_PEDAL" and sig.size != 8: + sys.exit("%s: PEDAL CHECKSUM is not 8 bits long" % dbc_msg_name) + + # Fail on duplicate message names + c = Counter([msg_name for address, msg_name, msg_size, sigs in msgs]) + for name, count in c.items(): + if count > 1: + sys.exit("%s: Duplicate message name in DBC file %s" % (dbc_name, name)) + + parser_code = template.render(dbc=can_dbc, checksum_type=checksum_type, msgs=msgs, def_vals=def_vals, len=len) + + + with open(out_fn, "w") as out_f: + out_f.write(parser_code) + +if __name__ == '__main__': + main() diff --git a/pyextra/jsonrpc/tests/test_backend_flask/__init__.py b/selfdrive/can/tests/__init__.py similarity index 100% rename from pyextra/jsonrpc/tests/test_backend_flask/__init__.py rename to selfdrive/can/tests/__init__.py diff --git a/selfdrive/can/tests/test_packer_parser.py b/selfdrive/can/tests/test_packer_parser.py new file mode 100644 index 00000000000000..9b8a886c465590 --- /dev/null +++ b/selfdrive/can/tests/test_packer_parser.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 + +import unittest + +from selfdrive.can.parser import CANParser +from selfdrive.can.packer import CANPacker + +from selfdrive.boardd.boardd import can_list_to_can_capnp + +from selfdrive.car.honda.interface import CarInterface as HondaInterface +from selfdrive.car.honda.values import CAR as HONDA_CAR +from selfdrive.car.honda.values import DBC as HONDA_DBC + +from selfdrive.car.subaru.interface import CarInterface as SubaruInterface +from selfdrive.car.subaru.values import CAR as SUBARU_CAR +from selfdrive.car.subaru.values import DBC as SUBARU_DBC + +class TestCanParserPacker(unittest.TestCase): + def test_civic(self): + CP = HondaInterface.get_params(HONDA_CAR.CIVIC) + + signals = [ + ("STEER_TORQUE", "STEERING_CONTROL", 0), + ("STEER_TORQUE_REQUEST", "STEERING_CONTROL", 0), + ] + checks = [] + + parser = CANParser(HONDA_DBC[CP.carFingerprint]['pt'], signals, checks, 0) + packer = CANPacker(HONDA_DBC[CP.carFingerprint]['pt']) + + idx = 0 + + for steer in range(0, 255): + for active in [1, 0]: + values = { + "STEER_TORQUE": steer, + "STEER_TORQUE_REQUEST": active, + } + + msgs = packer.make_can_msg("STEERING_CONTROL", 0, values, idx) + bts = can_list_to_can_capnp([msgs]) + + parser.update_string(bts) + + self.assertAlmostEqual(parser.vl["STEERING_CONTROL"]["STEER_TORQUE"], steer) + self.assertAlmostEqual(parser.vl["STEERING_CONTROL"]["STEER_TORQUE_REQUEST"], active) + self.assertAlmostEqual(parser.vl["STEERING_CONTROL"]["COUNTER"], idx % 4) + + idx += 1 + + def test_subaru(self): + # Subuaru is little endian + CP = SubaruInterface.get_params(SUBARU_CAR.IMPREZA) + + signals = [ + ("Counter", "ES_LKAS", 0), + ("LKAS_Output", "ES_LKAS", 0), + ("LKAS_Request", "ES_LKAS", 0), + ("SET_1", "ES_LKAS", 0), + + ] + + checks = [] + + parser = CANParser(SUBARU_DBC[CP.carFingerprint]['pt'], signals, checks, 0) + packer = CANPacker(SUBARU_DBC[CP.carFingerprint]['pt']) + + idx = 0 + + for steer in range(0, 255): + for active in [1, 0]: + values = { + "Counter": idx, + "LKAS_Output": steer, + "LKAS_Request": active, + "SET_1": 1 + } + + msgs = packer.make_can_msg("ES_LKAS", 0, values) + bts = can_list_to_can_capnp([msgs]) + parser.update_string(bts) + + self.assertAlmostEqual(parser.vl["ES_LKAS"]["LKAS_Output"], steer) + self.assertAlmostEqual(parser.vl["ES_LKAS"]["LKAS_Request"], active) + self.assertAlmostEqual(parser.vl["ES_LKAS"]["SET_1"], 1) + self.assertAlmostEqual(parser.vl["ES_LKAS"]["Counter"], idx % 16) + + idx += 1 + + +if __name__ == "__main__": + unittest.main() diff --git a/selfdrive/car/__init__.py b/selfdrive/car/__init__.py index 255b20806cce36..b0232daf44aede 100644 --- a/selfdrive/car/__init__.py +++ b/selfdrive/car/__init__.py @@ -1,6 +1,39 @@ # functions common among cars from common.numpy_fast import clip +# kg of standard extra cargo to count for drive, gas, etc... +STD_CARGO_KG = 136. + +def gen_empty_fingerprint(): + return {i: {} for i in range(0, 4)} + +# FIXME: hardcoding honda civic 2016 touring params so they can be used to +# scale unknown params for other cars +class CivicParams: + MASS = 1326. + STD_CARGO_KG + WHEELBASE = 2.70 + CENTER_TO_FRONT = WHEELBASE * 0.4 + CENTER_TO_REAR = WHEELBASE - CENTER_TO_FRONT + ROTATIONAL_INERTIA = 2500 + TIRE_STIFFNESS_FRONT = 192150 + TIRE_STIFFNESS_REAR = 202500 + +# TODO: get actual value, for now starting with reasonable value for +# civic and scaling by mass and wheelbase +def scale_rot_inertia(mass, wheelbase): + return CivicParams.ROTATIONAL_INERTIA * mass * wheelbase ** 2 / (CivicParams.MASS * CivicParams.WHEELBASE ** 2) + +# TODO: start from empirically derived lateral slip stiffness for the civic and scale by +# mass and CG position, so all cars will have approximately similar dyn behaviors +def scale_tire_stiffness(mass, wheelbase, center_to_front, tire_stiffness_factor=1.0): + center_to_rear = wheelbase - center_to_front + tire_stiffness_front = (CivicParams.TIRE_STIFFNESS_FRONT * tire_stiffness_factor) * mass / CivicParams.MASS * \ + (center_to_rear / wheelbase) / (CivicParams.CENTER_TO_REAR / CivicParams.WHEELBASE) + + tire_stiffness_rear = (CivicParams.TIRE_STIFFNESS_REAR * tire_stiffness_factor) * mass / CivicParams.MASS * \ + (center_to_front / wheelbase) / (CivicParams.CENTER_TO_FRONT / CivicParams.WHEELBASE) + + return tire_stiffness_front, tire_stiffness_rear def dbc_dict(pt_dbc, radar_dbc, chassis_dbc=None): return {'pt': pt_dbc, 'radar': radar_dbc, 'chassis': chassis_dbc} @@ -23,11 +56,10 @@ def apply_std_steer_torque_limits(apply_torque, apply_torque_last, driver_torque apply_torque = clip(apply_torque, apply_torque_last - LIMITS.STEER_DELTA_UP, min(apply_torque_last + LIMITS.STEER_DELTA_DOWN, LIMITS.STEER_DELTA_UP)) - return int(round(apply_torque)) + return int(round(float(apply_torque))) def apply_toyota_steer_torque_limits(apply_torque, apply_torque_last, motor_torque, LIMITS): - # limits due to comparison of commanded torque VS motor reported torque max_lim = min(max(motor_torque + LIMITS.STEER_ERROR_MAX, LIMITS.STEER_ERROR_MAX), LIMITS.STEER_MAX) min_lim = max(min(motor_torque - LIMITS.STEER_ERROR_MAX, -LIMITS.STEER_ERROR_MAX), -LIMITS.STEER_MAX) @@ -44,7 +76,7 @@ def apply_toyota_steer_torque_limits(apply_torque, apply_torque_last, motor_torq apply_torque_last - LIMITS.STEER_DELTA_UP, min(apply_torque_last + LIMITS.STEER_DELTA_DOWN, LIMITS.STEER_DELTA_UP)) - return int(round(apply_torque)) + return int(round(float(apply_torque))) def crc8_pedal(data): @@ -76,8 +108,19 @@ def create_gas_command(packer, gas_amount, idx): dat = packer.make_can_msg("GAS_COMMAND", 0, values)[2] - dat = [ord(i) for i in dat] checksum = crc8_pedal(dat[:-1]) values["CHECKSUM_PEDAL"] = checksum return packer.make_can_msg("GAS_COMMAND", 0, values) + + +def is_ecu_disconnected(fingerprint, fingerprint_list, ecu_fingerprint, car, ecu): + # check if a stock ecu is disconnected by looking for specific CAN msgs in the fingerprint + # return True if the reference car fingerprint contains the ecu fingerprint msg and + # fingerprint does not contains messages normally sent by a given ecu + ecu_in_car = False + for car_finger in fingerprint_list[car]: + if any(msg in car_finger for msg in ecu_fingerprint[ecu]): + ecu_in_car = True + + return ecu_in_car and not any(msg in fingerprint for msg in ecu_fingerprint[ecu]) diff --git a/selfdrive/car/car_helpers.py b/selfdrive/car/car_helpers.py index 58cde11bdf293c..bc7d9676f5ea30 100644 --- a/selfdrive/car/car_helpers.py +++ b/selfdrive/car/car_helpers.py @@ -1,20 +1,32 @@ import os -import time +from common.params import Params from common.basedir import BASEDIR -from common.realtime import sec_since_boot -from common.fingerprints import eliminate_incompatible_cars, all_known_cars +from selfdrive.car.fingerprints import eliminate_incompatible_cars, all_known_cars +from selfdrive.car.vin import get_vin, VIN_UNKNOWN from selfdrive.swaglog import cloudlog import selfdrive.messaging as messaging +from selfdrive.car import gen_empty_fingerprint -def load_interfaces(x): +def get_startup_alert(car_recognized, controller_available): + alert = 'startup' + if not car_recognized: + alert = 'startupNoCar' + elif car_recognized and not controller_available: + alert = 'startupNoControl' + return alert + + +def load_interfaces(brand_names): ret = {} - for interface in x: - try: - imp = __import__('selfdrive.car.%s.interface' % interface, fromlist=['CarInterface']).CarInterface - except ImportError: - imp = None - for car in x[interface]: - ret[car] = imp + for brand_name in brand_names: + path = ('selfdrive.car.%s' % brand_name) + CarInterface = __import__(path + '.interface', fromlist=['CarInterface']).CarInterface + if os.path.exists(BASEDIR + '/' + path.replace('.', '/') + '/carcontroller.py'): + CarController = __import__(path + '.carcontroller', fromlist=['CarController']).CarController + else: + CarController = None + for model_name in brand_names[brand_name]: + ret[model_name] = (CarInterface, CarController) return ret @@ -22,87 +34,92 @@ def _get_interface_names(): # read all the folders in selfdrive/car and return a dict where: # - keys are all the car names that which we have an interface for # - values are lists of spefic car models for a given car - interface_names = {} + brand_names = {} for car_folder in [x[0] for x in os.walk(BASEDIR + '/selfdrive/car')]: try: - car_name = car_folder.split('/')[-1] - model_names = __import__('selfdrive.car.%s.values' % car_name, fromlist=['CAR']).CAR + brand_name = car_folder.split('/')[-1] + model_names = __import__('selfdrive.car.%s.values' % brand_name, fromlist=['CAR']).CAR model_names = [getattr(model_names, c) for c in model_names.__dict__.keys() if not c.startswith("__")] - interface_names[car_name] = model_names + brand_names[brand_name] = model_names except (ImportError, IOError): pass - return interface_names + return brand_names # imports from directory selfdrive/car// interfaces = load_interfaces(_get_interface_names()) +def only_toyota_left(candidate_cars): + return all(("TOYOTA" in c or "LEXUS" in c) for c in candidate_cars) and len(candidate_cars) > 0 # BOUNTY: every added fingerprint in selfdrive/car/*/values.py is a $100 coupon code on shop.comma.ai # **** for use live only **** -def fingerprint(logcan, timeout): - if os.getenv("SIMULATOR2") is not None: - return ("simulator2", None) - elif os.getenv("SIMULATOR") is not None: - return ("simulator", None) - - cloudlog.warning("waiting for fingerprint...") - candidate_cars = all_known_cars() - finger = {} - st = None - st_passive = sec_since_boot() # only relevant when passive - can_seen = False - while 1: - for a in messaging.drain_sock(logcan): - for can in a.can: - can_seen = True - # ignore everything not on bus 0 and with more than 11 bits, - # which are ussually sporadic and hard to include in fingerprints - if can.src == 0 and can.address < 0x800: - finger[can.address] = len(can.dat) - candidate_cars = eliminate_incompatible_cars(can, candidate_cars) - - if st is None and can_seen: - st = sec_since_boot() # start time - ts = sec_since_boot() - # if we only have one car choice and the time_fingerprint since we got our first - # message has elapsed, exit. Toyota needs higher time_fingerprint, since DSU does not - # broadcast immediately - if len(candidate_cars) == 1 and st is not None: - # TODO: better way to decide to wait more if Toyota - time_fingerprint = 1.0 if ("TOYOTA" in candidate_cars[0] or "LEXUS" in candidate_cars[0]) else 0.1 - if (ts-st) > time_fingerprint: - break - - # bail if no cars left or we've been waiting too long - elif len(candidate_cars) == 0 or (timeout and (ts - st_passive) > timeout): - return None, finger - - time.sleep(0.01) - - cloudlog.warning("fingerprinted %s", candidate_cars[0]) - return (candidate_cars[0], finger) - - -def get_car(logcan, sendcan=None, passive=True): - # TODO: timeout only useful for replays so controlsd can start before unlogger - timeout = 2. if passive else None - candidate, fingerprints = fingerprint(logcan, timeout) +def fingerprint(logcan, sendcan, has_relay): + + if has_relay: + # Vin query only reliably works thorugh OBDII + vin = get_vin(logcan, sendcan, 1) + else: + vin = VIN_UNKNOWN + + cloudlog.warning("VIN %s", vin) + Params().put("CarVin", vin) + + finger = gen_empty_fingerprint() + candidate_cars = {i: all_known_cars() for i in [0, 1]} # attempt fingerprint on both bus 0 and 1 + frame = 0 + frame_fingerprint = 10 # 0.1s + car_fingerprint = None + done = False + + while not done: + a = messaging.get_one_can(logcan) + + for can in a.can: + # need to independently try to fingerprint both bus 0 and 1 to work + # for the combo black_panda and honda_bosch. Ignore extended messages + # and VIN query response. + # Include bus 2 for toyotas to disambiguate cars using camera messages + # (ideally should be done for all cars but we can't for Honda Bosch) + if can.src in range(0, 4): + finger[can.src][can.address] = len(can.dat) + for b in candidate_cars: + if (can.src == b or (only_toyota_left(candidate_cars[b]) and can.src == 2)) and \ + can.address < 0x800 and can.address not in [0x7df, 0x7e0, 0x7e8]: + candidate_cars[b] = eliminate_incompatible_cars(can, candidate_cars[b]) + + # if we only have one car choice and the time since we got our first + # message has elapsed, exit + for b in candidate_cars: + # Toyota needs higher time to fingerprint, since DSU does not broadcast immediately + if only_toyota_left(candidate_cars[b]): + frame_fingerprint = 100 # 1s + if len(candidate_cars[b]) == 1: + if frame > frame_fingerprint: + # fingerprint done + car_fingerprint = candidate_cars[b][0] + + # bail if no cars left or we've been waiting for more than 2s + failed = all(len(cc) == 0 for cc in candidate_cars.values()) or frame > 200 + succeeded = car_fingerprint is not None + done = failed or succeeded + + frame += 1 + + cloudlog.warning("fingerprinted %s", car_fingerprint) + return car_fingerprint, finger, vin + + +def get_car(logcan, sendcan, has_relay=False): + + candidate, fingerprints, vin = fingerprint(logcan, sendcan, has_relay) if candidate is None: cloudlog.warning("car doesn't match any fingerprints: %r", fingerprints) - if passive: - candidate = "mock" - else: - return None, None - - interface_cls = interfaces[candidate] - - if interface_cls is None: - cloudlog.warning("car matched %s, but interface wasn't available or failed to import" % candidate) - return None, None + candidate = "mock" - params = interface_cls.get_params(candidate, fingerprints) + CarInterface, CarController = interfaces[candidate] + car_params = CarInterface.get_params(candidate, fingerprints, vin, has_relay) - return interface_cls(params, sendcan), params + return CarInterface(car_params, CarController), car_params diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index 83c2ecc32c743c..ed92b1427dcde1 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -1,23 +1,10 @@ -from cereal import car -from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car import apply_toyota_steer_torque_limits from selfdrive.car.chrysler.chryslercan import create_lkas_hud, create_lkas_command, \ - create_wheel_buttons, create_lkas_heartbit, \ - create_chimes -from selfdrive.car.chrysler.values import ECU + create_wheel_buttons +from selfdrive.car.chrysler.values import ECU, CAR, SteerLimitParams from selfdrive.can.packer import CANPacker -AudibleAlert = car.CarControl.HUDControl.AudibleAlert -LOUD_ALERTS = [AudibleAlert.chimeWarning1, AudibleAlert.chimeWarning2, AudibleAlert.chimeWarningRepeat] - -class SteerLimitParams: - STEER_MAX = 261 # 262 faults - STEER_DELTA_UP = 3 # 3 is stock. 100 is fine. 200 is too much it seems - STEER_DELTA_DOWN = 3 # no faults on the way down it seems - STEER_ERROR_MAX = 80 - - -class CarController(object): +class CarController(): def __init__(self, dbc_name, car_fingerprint, enable_camera): self.braking = False # redundant safety check with the board @@ -28,7 +15,7 @@ def __init__(self, dbc_name, car_fingerprint, enable_camera): self.hud_count = 0 self.car_fingerprint = car_fingerprint self.alert_active = False - self.send_chime = False + self.gone_fast_yet = False self.fake_ecus = set() if enable_camera: @@ -37,12 +24,11 @@ def __init__(self, dbc_name, car_fingerprint, enable_camera): self.packer = CANPacker(dbc_name) - def update(self, sendcan, enabled, CS, frame, actuators, - pcm_cancel_cmd, hud_alert, audible_alert): - + def update(self, enabled, CS, actuators, pcm_cancel_cmd, hud_alert): # this seems needed to avoid steering faults and to force the sync with the EPS counter + frame = CS.lkas_counter if self.prev_frame == frame: - return + return [] # *** compute control surfaces *** # steer torque @@ -51,6 +37,11 @@ def update(self, sendcan, enabled, CS, frame, actuators, CS.steer_torque_motor, SteerLimitParams) moving_fast = CS.v_ego > CS.CP.minSteerSpeed # for status message + if CS.v_ego > (CS.CP.minSteerSpeed - 0.5): # for command high bit + self.gone_fast_yet = True + elif self.car_fingerprint in (CAR.PACIFICA_2019_HYBRID, CAR.JEEP_CHEROKEE_2019): + if CS.v_ego < (CS.CP.minSteerSpeed - 3.0): + self.gone_fast_yet = False # < 14.5m/s stock turns off this bit, but fine down to 13.5 lkas_active = moving_fast and enabled if not lkas_active: @@ -58,38 +49,29 @@ def update(self, sendcan, enabled, CS, frame, actuators, self.apply_steer_last = apply_steer - if audible_alert in LOUD_ALERTS: - self.send_chime = True - can_sends = [] #*** control msgs *** - if self.send_chime: - new_msg = create_chimes(AudibleAlert) - can_sends.append(new_msg) - if audible_alert not in LOUD_ALERTS: - self.send_chime = False - if pcm_cancel_cmd: # TODO: would be better to start from frame_2b3 new_msg = create_wheel_buttons(self.ccframe) can_sends.append(new_msg) + # LKAS_HEARTBIT is forwarded by Panda so no need to send it here. # frame is 100Hz (0.01s period) - if (self.ccframe % 10 == 0): # 0.1s period - new_msg = create_lkas_heartbit(self.car_fingerprint) - can_sends.append(new_msg) - if (self.ccframe % 25 == 0): # 0.25s period - new_msg = create_lkas_hud(self.packer, CS.gear_shifter, lkas_active, hud_alert, self.car_fingerprint, - self.hud_count) - can_sends.append(new_msg) - self.hud_count += 1 - - new_msg = create_lkas_command(self.packer, int(apply_steer), frame) + if (CS.lkas_car_model != -1): + new_msg = create_lkas_hud( + self.packer, CS.gear_shifter, lkas_active, hud_alert, + self.hud_count, CS.lkas_car_model) + can_sends.append(new_msg) + self.hud_count += 1 + + new_msg = create_lkas_command(self.packer, int(apply_steer), self.gone_fast_yet, frame) can_sends.append(new_msg) self.ccframe += 1 self.prev_frame = frame - sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan').to_bytes()) + + return can_sends diff --git a/selfdrive/car/chrysler/carstate.py b/selfdrive/car/chrysler/carstate.py index a6344027dfa275..93b354e0f8de93 100644 --- a/selfdrive/car/chrysler/carstate.py +++ b/selfdrive/car/chrysler/carstate.py @@ -1,21 +1,22 @@ +from cereal import car from selfdrive.can.parser import CANParser from selfdrive.car.chrysler.values import DBC, STEER_THRESHOLD from common.kalman.simple_kalman import KF1D -import numpy as np +GearShifter = car.CarState.GearShifter def parse_gear_shifter(can_gear): if can_gear == 0x1: - return "park" + return GearShifter.park elif can_gear == 0x2: - return "reverse" + return GearShifter.reverse elif can_gear == 0x3: - return "neutral" + return GearShifter.neutral elif can_gear == 0x4: - return "drive" + return GearShifter.drive elif can_gear == 0x5: - return "low" - return "unknown" + return GearShifter.low + return GearShifter.unknown def get_can_parser(CP): @@ -28,7 +29,7 @@ def get_can_parser(CP): ("DOOR_OPEN_RL", "DOORS", 0), ("DOOR_OPEN_RR", "DOORS", 0), ("BRAKE_PRESSED_2", "BRAKE_2", 0), - ("ACCEL_PEDAL", "ACCEL_PEDAL_MSG", 0), + ("ACCEL_134", "ACCEL_GAS_134", 0), ("SPEED_LEFT", "SPEED_1", 0), ("SPEED_RIGHT", "SPEED_1", 0), ("WHEEL_SPEED_FL", "WHEEL_SPEEDS", 0), @@ -63,8 +64,20 @@ def get_can_parser(CP): return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) +def get_camera_parser(CP): + signals = [ + # sig_name, sig_address, default + # TODO read in all the other values + ("COUNTER", "LKAS_COMMAND", -1), + ("CAR_MODEL", "LKAS_HUD", -1), + ("LKAS_STATUS_OK", "LKAS_HEARTBIT", -1) + ] + checks = [] -class CarState(object): + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2) + + +class CarState(): def __init__(self, CP): self.CP = CP @@ -78,16 +91,14 @@ def __init__(self, CP): dt = 0.01 # Q = np.matrix([[10.0, 0.0], [0.0, 100.0]]) # R = 1e3 - self.v_ego_kf = KF1D(x0=np.matrix([[0.0], [0.0]]), - A=np.matrix([[1.0, dt], [0.0, 1.0]]), - C=np.matrix([1.0, 0.0]), - K=np.matrix([[0.12287673], [0.29666309]])) + self.v_ego_kf = KF1D(x0=[[0.0], [0.0]], + A=[[1.0, dt], [0.0, 1.0]], + C=[1.0, 0.0], + K=[[0.12287673], [0.29666309]]) self.v_ego = 0.0 - def update(self, cp): - # copy can_valid - self.can_valid = cp.can_valid + def update(self, cp, cp_cam): # update prevs, update must run once per loop self.prev_left_blinker_on = self.left_blinker_on @@ -103,7 +114,7 @@ def update(self, cp): self.seatbelt = (cp.vl["SEATBELT_STATUS"]['SEATBELT_DRIVER_UNLATCHED'] == 0) self.brake_pressed = cp.vl["BRAKE_2"]['BRAKE_PRESSED_2'] == 5 # human-only - self.pedal_gas = cp.vl["ACCEL_PEDAL_MSG"]['ACCEL_PEDAL'] + self.pedal_gas = cp.vl["ACCEL_GAS_134"]['ACCEL_134'] self.car_gas = self.pedal_gas self.esp_disabled = (cp.vl["TRACTION_BUTTON"]['TRACTION_OFF'] == 1) @@ -115,7 +126,7 @@ def update(self, cp): # Kalman filter if abs(v_wheel - self.v_ego) > 2.0: # Prevent large accelerations when car starts at non zero speed - self.v_ego_kf.x = np.matrix([[v_wheel], [0.0]]) + self.v_ego_kf.x = [[v_wheel], [0.0]] self.v_ego_raw = v_wheel v_ego_x = self.v_ego_kf.update(v_wheel) @@ -142,3 +153,7 @@ def update(self, cp): self.pcm_acc_status = self.main_on self.generic_toggle = bool(cp.vl["STEERING_LEVERS"]['HIGH_BEAM_FLASH']) + + self.lkas_counter = cp_cam.vl["LKAS_COMMAND"]['COUNTER'] + self.lkas_car_model = cp_cam.vl["LKAS_HUD"]['CAR_MODEL'] + self.lkas_status_ok = cp_cam.vl["LKAS_HEARTBIT"]['LKAS_STATUS_OK'] diff --git a/selfdrive/car/chrysler/chryslercan.py b/selfdrive/car/chrysler/chryslercan.py index e17ee362316617..047ae82580b27d 100644 --- a/selfdrive/car/chrysler/chryslercan.py +++ b/selfdrive/car/chrysler/chryslercan.py @@ -1,17 +1,8 @@ from cereal import car -from selfdrive.car.chrysler.values import CAR +GearShifter = car.CarState.GearShifter VisualAlert = car.CarControl.HUDControl.VisualAlert -AudibleAlert = car.CarControl.HUDControl.AudibleAlert - -MODEL_TO_CONSTANT = { - CAR.PACIFICA_2017_HYBRID: 0, - CAR.PACIFICA_2018: 0x64, - CAR.PACIFICA_2018_HYBRID: 0xa8, - CAR.PACIFICA_2019_HYBRID: 0x68, - CAR.JEEP_CHEROKEE: 0xa4, - } def calc_checksum(data): """This function does not want the checksum byte in the input data. @@ -21,8 +12,8 @@ def calc_checksum(data): end_index = len(data) index = 0 checksum = 0xFF - temp_chk = 0; - bit_sum = 0; + temp_chk = 0 + bit_sum = 0 if(end_index <= index): return False for index in range(0, end_index): @@ -31,7 +22,7 @@ def calc_checksum(data): iterate = 8 while(iterate > 0): iterate -= 1 - bit_sum = curr & shift; + bit_sum = curr & shift temp_chk = checksum & 0x80 if (bit_sum != 0): bit_sum = 0x1C @@ -53,31 +44,23 @@ def calc_checksum(data): def make_can_msg(addr, dat): return [addr, 0, dat, 0] -def create_lkas_heartbit(car_fingerprint): - # LKAS_HEARTBIT (729) Lane-keeping heartbeat. - msg = '0000000820'.decode('hex') # 2017 - return make_can_msg(0x2d9, msg) -def create_lkas_hud(packer, gear, lkas_active, hud_alert, car_fingerprint, hud_count): +def create_lkas_hud(packer, gear, lkas_active, hud_alert, hud_count, lkas_car_model): # LKAS_HUD 0x2a6 (678) Controls what lane-keeping icon is displayed. if hud_alert == VisualAlert.steerRequired: - msg = '0000000300000000'.decode('hex') + msg = b'\x00\x00\x00\x03\x00\x00\x00\x00' return make_can_msg(0x2a6, msg) - color = 0 # default values are for park or neutral - lines = 0 + color = 1 # default values are for park or neutral in 2017 are 0 0, but trying 1 1 for 2019 + lines = 1 alerts = 0 - if hud_count < (3 *4): # first 3 seconds, 4Hz - lines = 1 + if hud_count < (1 *4): # first 3 seconds, 4Hz alerts = 1 - elif hud_count < (6 * 4): # next 3 seconds, 4Hz - lines = 1 - alerts = 0 # CAR.PACIFICA_2018_HYBRID and CAR.PACIFICA_2019_HYBRID # had color = 1 and lines = 1 but trying 2017 hybrid style for now. - if gear in ('drive', 'reverse', 'low'): + if gear in (GearShifter.drive, GearShifter.reverse, GearShifter.low): if lkas_active: color = 2 # control active, display green. lines = 6 @@ -87,7 +70,7 @@ def create_lkas_hud(packer, gear, lkas_active, hud_alert, car_fingerprint, hud_c values = { "LKAS_ICON_COLOR": color, # byte 0, last 2 bits - "CAR_MODEL": MODEL_TO_CONSTANT[car_fingerprint], # byte 1 + "CAR_MODEL": lkas_car_model, # byte 1 "LKAS_LANE_LINES": lines, # byte 2, last 4 bits "LKAS_ALERTS": alerts, # byte 3, last 4 bits } @@ -95,35 +78,26 @@ def create_lkas_hud(packer, gear, lkas_active, hud_alert, car_fingerprint, hud_c return packer.make_can_msg("LKAS_HUD", 0, values) # 0x2a6 -def create_lkas_command(packer, apply_steer, frame): - # LKAS_COMMAND (658) Lane-keeping signal to turn the wheel. +def create_lkas_command(packer, apply_steer, moving_fast, frame): + # LKAS_COMMAND 0x292 (658) Lane-keeping signal to turn the wheel. values = { "LKAS_STEERING_TORQUE": apply_steer, - "LKAS_HIGH_TORQUE": 1, + "LKAS_HIGH_TORQUE": int(moving_fast), "COUNTER": frame % 0x10, } dat = packer.make_can_msg("LKAS_COMMAND", 0, values)[2] - dat = [ord(i) for i in dat][:-1] + dat = dat[:-1] checksum = calc_checksum(dat) values["CHECKSUM"] = checksum return packer.make_can_msg("LKAS_COMMAND", 0, values) -def create_chimes(audible_alert): - # '0050' nothing, chime '4f55' - if audible_alert == AudibleAlert.none: - msg = '0050'.decode('hex') - else: - msg = '4f55'.decode('hex') - return make_can_msg(0x339, msg) - - def create_wheel_buttons(frame): # WHEEL_BUTTONS (571) Message sent to cancel ACC. - start = [0x01] # acc cancel set + start = b"\x01" # acc cancel set counter = (frame % 10) << 4 - dat = start + [counter] - dat = dat + [calc_checksum(dat)] - return make_can_msg(0x23b, str(bytearray(dat))) + dat = start + counter.to_bytes(1, 'little') + dat = dat + calc_checksum(dat).to_bytes(1, 'little') + return make_can_msg(0x23b, dat) diff --git a/selfdrive/car/chrysler/chryslercan_test.py b/selfdrive/car/chrysler/chryslercan_test.py deleted file mode 100644 index 2edfff9f2af2fc..00000000000000 --- a/selfdrive/car/chrysler/chryslercan_test.py +++ /dev/null @@ -1,47 +0,0 @@ -import chryslercan -from values import CAR -from selfdrive.can.packer import CANPacker - -from cereal import car -VisualAlert = car.CarControl.HUDControl.VisualAlert -AudibleAlert = car.CarControl.HUDControl.AudibleAlert - -import unittest - - -class TestChryslerCan(unittest.TestCase): - - def test_checksum(self): - self.assertEqual(0x75, chryslercan.calc_checksum([0x01, 0x20])) - self.assertEqual(0xcc, chryslercan.calc_checksum([0x14, 0, 0, 0, 0x20])) - - def test_heartbit(self): - self.assertEqual( - [0x2d9, 0, '0000000820'.decode('hex'), 0], - chryslercan.create_lkas_heartbit(CAR.PACIFICA_2017_HYBRID)) - - def test_hud(self): - packer = CANPacker('chrysler_pacifica_2017_hybrid') - self.assertEqual( - [0x2a6, 0, '0000010100000000'.decode('hex'), 0], - chryslercan.create_lkas_hud(packer, - 'park', False, False, CAR.PACIFICA_2017_HYBRID, 1)) - self.assertEqual( - [0x2a6, 0, '0000010000000000'.decode('hex'), 0], - chryslercan.create_lkas_hud(packer, - 'park', False, False, CAR.PACIFICA_2017_HYBRID, 5*4)) - self.assertEqual( - [0x2a6, 0, '0000000000000000'.decode('hex'), 0], - chryslercan.create_lkas_hud(packer, - 'park', False, False, CAR.PACIFICA_2017_HYBRID, 99999)) - self.assertEqual( - [0x2a6, 0, '0200060000000000'.decode('hex'), 0], - chryslercan.create_lkas_hud(packer, - 'drive', True, False, CAR.PACIFICA_2017_HYBRID, 99999)) - self.assertEqual( - [0x2a6, 0, '0264060000000000'.decode('hex'), 0], - chryslercan.create_lkas_hud(packer, - 'drive', True, False, CAR.PACIFICA_2018, 99999)) - -if __name__ == '__main__': - unittest.main() diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index ac797616bc32ab..8a3cd750a42d36 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -1,25 +1,21 @@ -#!/usr/bin/env python -from common.realtime import sec_since_boot +#!/usr/bin/env python3 from cereal import car from selfdrive.config import Conversions as CV from selfdrive.controls.lib.drive_helpers import EventTypes as ET, create_event from selfdrive.controls.lib.vehicle_model import VehicleModel -from selfdrive.car.chrysler.carstate import CarState, get_can_parser -from selfdrive.car.chrysler.values import ECU, check_ecu_msgs, CAR +from selfdrive.car.chrysler.carstate import CarState, get_can_parser, get_camera_parser +from selfdrive.car.chrysler.values import ECU, ECU_FINGERPRINT, CAR, FINGERPRINTS +from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint +from selfdrive.car.interfaces import CarInterfaceBase -try: - from selfdrive.car.chrysler.carcontroller import CarController -except ImportError: - CarController = None +GearShifter = car.CarState.GearShifter +ButtonType = car.CarState.ButtonEvent.Type - -class CarInterface(object): - def __init__(self, CP, sendcan=None): +class CarInterface(CarInterfaceBase): + def __init__(self, CP, CarController): self.CP = CP self.VM = VehicleModel(CP) - self.frame = 0 - self.can_invalid_count = 0 self.gas_pressed_prev = False self.brake_pressed_prev = False self.cruise_enabled_prev = False @@ -27,12 +23,11 @@ def __init__(self, CP, sendcan=None): # *** init the major players *** self.CS = CarState(CP) - self.cp = get_can_parser(CP) + self.cp_cam = get_camera_parser(CP) - # sending if read only is False - if sendcan is not None: - self.sendcan = sendcan + self.CC = None + if CarController is not None: self.CC = CarController(self.cp.dbc_name, CP.carFingerprint, CP.enableCamera) @staticmethod @@ -40,72 +35,51 @@ def compute_gb(accel, speed): return float(accel) / 3.0 @staticmethod - def calc_accel_override(a_ego, a_target, v_ego, v_target): - return 1.0 - - @staticmethod - def get_params(candidate, fingerprint): - - # kg of standard extra cargo to count for drive, gas, etc... - std_cargo = 136 + def get_params(candidate, fingerprint=gen_empty_fingerprint(), vin="", has_relay=False): ret = car.CarParams.new_message() ret.carName = "chrysler" ret.carFingerprint = candidate + ret.carVin = vin + ret.isPandaBlack = has_relay - ret.safetyModel = car.CarParams.SafetyModels.chrysler + ret.safetyModel = car.CarParams.SafetyModel.chrysler # pedal ret.enableCruise = True - # FIXME: hardcoding honda civic 2016 touring params so they can be used to - # scale unknown params for other cars - mass_civic = 2923./2.205 + std_cargo - wheelbase_civic = 2.70 - centerToFront_civic = wheelbase_civic * 0.4 - centerToRear_civic = wheelbase_civic - centerToFront_civic - rotationalInertia_civic = 2500 - tireStiffnessFront_civic = 85400 * 2.0 - tireStiffnessRear_civic = 90000 * 2.0 - # Speed conversion: 20, 45 mph - ret.steerKpBP, ret.steerKiBP = [[9., 20.], [9., 20.]] ret.wheelbase = 3.089 # in meters for Pacifica Hybrid 2017 ret.steerRatio = 16.2 # Pacifica Hybrid 2017 - ret.mass = 2858 + std_cargo # kg curb weight Pacifica Hybrid 2017 - ret.steerKpV, ret.steerKiV = [[0.15,0.30], [0.03,0.05]] - ret.steerKf = 0.00006 # full torque for 10 deg at 80mph means 0.00007818594 + ret.mass = 2858. + STD_CARGO_KG # kg curb weight Pacifica Hybrid 2017 + ret.lateralTuning.pid.kpBP, ret.lateralTuning.pid.kiBP = [[9., 20.], [9., 20.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.15,0.30], [0.03,0.05]] + ret.lateralTuning.pid.kf = 0.00006 # full torque for 10 deg at 80mph means 0.00007818594 ret.steerActuatorDelay = 0.1 ret.steerRateCost = 0.7 - if candidate == CAR.JEEP_CHEROKEE: + if candidate in (CAR.JEEP_CHEROKEE, CAR.JEEP_CHEROKEE_2019): ret.wheelbase = 2.91 # in meters ret.steerRatio = 12.7 ret.steerActuatorDelay = 0.2 # in seconds ret.centerToFront = ret.wheelbase * 0.44 - ret.longPidDeadzoneBP = [0., 9.] - ret.longPidDeadzoneV = [0., .15] ret.minSteerSpeed = 3.8 # m/s ret.minEnableSpeed = -1. # enable is done by stock ACC, so ignore this + if candidate in (CAR.PACIFICA_2019_HYBRID, CAR.JEEP_CHEROKEE_2019): + ret.minSteerSpeed = 17.5 # m/s 17 on the way up, 13 on the way down once engaged. + # TODO allow 2019 cars to steer down to 13 m/s if already engaged. - centerToRear = ret.wheelbase - ret.centerToFront # TODO: get actual value, for now starting with reasonable value for # civic and scaling by mass and wheelbase - ret.rotationalInertia = rotationalInertia_civic * \ - ret.mass * ret.wheelbase**2 / (mass_civic * wheelbase_civic**2) + ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) # TODO: start from empirically derived lateral slip stiffness for the civic and scale by # mass and CG position, so all cars will have approximately similar dyn behaviors - ret.tireStiffnessFront = tireStiffnessFront_civic * \ - ret.mass / mass_civic * \ - (centerToRear / ret.wheelbase) / (centerToRear_civic / wheelbase_civic) - ret.tireStiffnessRear = tireStiffnessRear_civic * \ - ret.mass / mass_civic * \ - (ret.centerToFront / ret.wheelbase) / (centerToFront_civic / wheelbase_civic) + ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront) # no rear steering, at least on the listed cars above ret.steerRatioRear = 0. @@ -118,33 +92,36 @@ def get_params(candidate, fingerprint): ret.brakeMaxBP = [5., 20.] ret.brakeMaxV = [1., 0.8] - ret.enableCamera = not check_ecu_msgs(fingerprint, ECU.CAM) - print "ECU Camera Simulated: ", ret.enableCamera + ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, ECU.CAM) or has_relay + print("ECU Camera Simulated: {0}".format(ret.enableCamera)) ret.openpilotLongitudinalControl = False ret.steerLimitAlert = True ret.stoppingControl = False ret.startAccel = 0.0 - ret.longitudinalKpBP = [0., 5., 35.] - ret.longitudinalKpV = [3.6, 2.4, 1.5] - ret.longitudinalKiBP = [0., 35.] - ret.longitudinalKiV = [0.54, 0.36] + ret.longitudinalTuning.deadzoneBP = [0., 9.] + ret.longitudinalTuning.deadzoneV = [0., .15] + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kpV = [3.6, 2.4, 1.5] + ret.longitudinalTuning.kiBP = [0., 35.] + ret.longitudinalTuning.kiV = [0.54, 0.36] return ret # returns a car.CarState - def update(self, c): + def update(self, c, can_strings): # ******************* do can recv ******************* - canMonoTimes = [] + self.cp.update_strings(can_strings) + self.cp_cam.update_strings(can_strings) - self.cp.update(int(sec_since_boot() * 1e9), False) - - self.CS.update(self.cp) + self.CS.update(self.cp, self.cp_cam) # create message ret = car.CarState.new_message() + ret.canValid = self.cp.can_valid and self.cp_cam.can_valid + # speeds ret.vEgo = self.CS.v_ego ret.vEgoRaw = self.CS.v_ego_raw @@ -180,8 +157,6 @@ def update(self, c): ret.cruiseState.speed = self.CS.v_cruise_pcm * CV.KPH_TO_MS ret.cruiseState.available = self.CS.main_on ret.cruiseState.speedOffset = 0. - # ignore standstill in hybrid rav4, since pcm allows to restart without - # receiving any special command ret.cruiseState.standstill = False # TODO: button presses @@ -189,13 +164,13 @@ def update(self, c): if self.CS.left_blinker_on != self.CS.prev_left_blinker_on: be = car.CarState.ButtonEvent.new_message() - be.type = 'leftBlinker' + be.type = ButtonType.leftBlinker be.pressed = self.CS.left_blinker_on != 0 buttonEvents.append(be) if self.CS.right_blinker_on != self.CS.prev_right_blinker_on: be = car.CarState.ButtonEvent.new_message() - be.type = 'rightBlinker' + be.type = ButtonType.rightBlinker be.pressed = self.CS.right_blinker_on != 0 buttonEvents.append(be) @@ -208,16 +183,12 @@ def update(self, c): self.low_speed_alert = (ret.vEgo < self.CP.minSteerSpeed) ret.genericToggle = self.CS.generic_toggle + #ret.lkasCounter = self.CS.lkas_counter + #ret.lkasCarModel = self.CS.lkas_car_model # events events = [] - if not self.CS.can_valid: - self.can_invalid_count += 1 - if self.can_invalid_count >= 5: - events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) - else: - self.can_invalid_count = 0 - if not (ret.gearShifter in ('drive', 'low')): + if not (ret.gearShifter in (GearShifter.drive, GearShifter.low)): events.append(create_event('wrongGear', [ET.NO_ENTRY, ET.SOFT_DISABLE])) if ret.doorOpen: events.append(create_event('doorOpen', [ET.NO_ENTRY, ET.SOFT_DISABLE])) @@ -227,7 +198,7 @@ def update(self, c): events.append(create_event('espDisabled', [ET.NO_ENTRY, ET.SOFT_DISABLE])) if not self.CS.main_on: events.append(create_event('wrongCarMode', [ET.NO_ENTRY, ET.USER_DISABLE])) - if ret.gearShifter == 'reverse': + if ret.gearShifter == GearShifter.reverse: events.append(create_event('reverseGear', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) if self.CS.steer_error: events.append(create_event('steerUnavailable', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE, ET.PERMANENT])) @@ -246,7 +217,6 @@ def update(self, c): events.append(create_event('belowSteerSpeed', [ET.WARNING])) ret.events = events - ret.canMonoTimes = canMonoTimes self.gas_pressed_prev = ret.gasPressed self.brake_pressed_prev = ret.brakePressed @@ -259,11 +229,8 @@ def update(self, c): def apply(self, c): if (self.CS.frame == -1): - return False # if we haven't seen a frame 220, then do not update. + return [] # if we haven't seen a frame 220, then do not update. - self.frame = self.CS.frame - self.CC.update(self.sendcan, c.enabled, self.CS, self.frame, - c.actuators, c.cruiseControl.cancel, c.hudControl.visualAlert, - c.hudControl.audibleAlert) + can_sends = self.CC.update(c.enabled, self.CS, c.actuators, c.cruiseControl.cancel, c.hudControl.visualAlert) - return False + return can_sends diff --git a/selfdrive/car/chrysler/radar_interface.py b/selfdrive/car/chrysler/radar_interface.py index 60eaa4566a8819..3130c2ca719999 100755 --- a/selfdrive/car/chrysler/radar_interface.py +++ b/selfdrive/car/chrysler/radar_interface.py @@ -1,19 +1,15 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import os from selfdrive.can.parser import CANParser from cereal import car -from common.realtime import sec_since_boot -import zmq -from selfdrive.services import service_list -import selfdrive.messaging as messaging +from selfdrive.car.interfaces import RadarInterfaceBase - -RADAR_MSGS_C = range(0x2c2, 0x2d4+2, 2) # c_ messages 706,...,724 -RADAR_MSGS_D = range(0x2a2, 0x2b4+2, 2) # d_ messages +RADAR_MSGS_C = list(range(0x2c2, 0x2d4+2, 2)) # c_ messages 706,...,724 +RADAR_MSGS_D = list(range(0x2a2, 0x2b4+2, 2)) # d_ messages LAST_MSG = max(RADAR_MSGS_C + RADAR_MSGS_D) NUMBER_MSGS = len(RADAR_MSGS_C) + len(RADAR_MSGS_D) -def _create_radard_can_parser(): +def _create_radar_can_parser(): dbc_f = 'chrysler_pacifica_2017_hybrid_private_fusion.dbc' msg_n = len(RADAR_MSGS_C) # list of [(signal name, message name or number, initial values), (...)] @@ -25,63 +21,58 @@ def _create_radard_can_parser(): # The factor and offset are applied by the dbc parsing library, so the # default values should be after the factor/offset are applied. - signals = zip(['LONG_DIST'] * msg_n + + signals = list(zip(['LONG_DIST'] * msg_n + ['LAT_DIST'] * msg_n + ['REL_SPEED'] * msg_n, RADAR_MSGS_C * 2 + # LONG_DIST, LAT_DIST RADAR_MSGS_D, # REL_SPEED [0] * msg_n + # LONG_DIST [-1000] * msg_n + # LAT_DIST - [-146.278] * msg_n) # REL_SPEED set to 0, factor/offset to this + [-146.278] * msg_n)) # REL_SPEED set to 0, factor/offset to this # TODO what are the checks actually used for? # honda only checks the last message, # toyota checks all the messages. Which do we want? - checks = zip(RADAR_MSGS_C + + checks = list(zip(RADAR_MSGS_C + RADAR_MSGS_D, [20]*msg_n + # 20Hz (0.05s) - [20]*msg_n) # 20Hz (0.05s) + [20]*msg_n)) # 20Hz (0.05s) return CANParser(os.path.splitext(dbc_f)[0], signals, checks, 1) def _address_to_track(address): if address in RADAR_MSGS_C: - return (address - RADAR_MSGS_C[0]) / 2 + return (address - RADAR_MSGS_C[0]) // 2 if address in RADAR_MSGS_D: - return (address - RADAR_MSGS_D[0]) / 2 + return (address - RADAR_MSGS_D[0]) // 2 raise ValueError("radar received unexpected address %d" % address) -class RadarInterface(object): +class RadarInterface(RadarInterfaceBase): def __init__(self, CP): self.pts = {} - self.delay = 0.0 # Delay of radar #TUNE - self.rcp = _create_radard_can_parser() - context = zmq.Context() - self.logcan = messaging.sub_sock(context, service_list['can'].port) - - def update(self): - canMonoTimes = [] + self.delay = 0 # Delay of radar #TUNE + self.rcp = _create_radar_can_parser() + self.updated_messages = set() + self.trigger_msg = LAST_MSG - updated_messages = set() # set of message IDs (sig_addresses) we've seen + def update(self, can_strings): + vls = self.rcp.update_strings(can_strings) + self.updated_messages.update(vls) - while 1: - tm = int(sec_since_boot() * 1e9) - updated_messages.update(self.rcp.update(tm, True)) - if LAST_MSG in updated_messages: - break + if self.trigger_msg not in self.updated_messages: + return None - ret = car.RadarState.new_message() + ret = car.RadarData.new_message() errors = [] if not self.rcp.can_valid: - errors.append("commIssue") + errors.append("canError") ret.errors = errors - ret.canMonoTimes = canMonoTimes - for ii in updated_messages: # ii should be the message ID as a number + for ii in self.updated_messages: # ii should be the message ID as a number cpt = self.rcp.vl[ii] trackId = _address_to_track(ii) if trackId not in self.pts: - self.pts[trackId] = car.RadarState.RadarPoint.new_message() + self.pts[trackId] = car.RadarData.RadarPoint.new_message() self.pts[trackId].trackId = trackId self.pts[trackId].aRel = float('nan') self.pts[trackId].yvRel = float('nan') @@ -97,11 +88,6 @@ def update(self): # We want a list, not a dictionary. Filter out LONG_DIST==0 because that means it's not valid. ret.points = [x for x in self.pts.values() if x.dRel != 0] - return ret -if __name__ == "__main__": - RI = RadarInterface(None) - while 1: - ret = RI.update() - print(chr(27) + "[2J") # clear screen - print ret + self.updated_messages.clear() + return ret diff --git a/selfdrive/car/chrysler/run_tests.sh b/selfdrive/car/chrysler/run_tests.sh deleted file mode 100755 index 1dcc8b2acf0bbf..00000000000000 --- a/selfdrive/car/chrysler/run_tests.sh +++ /dev/null @@ -1 +0,0 @@ -PYTHONPATH=`realpath ../../../` python chryslercan_test.py diff --git a/selfdrive/car/chrysler/test_chryslercan.py b/selfdrive/car/chrysler/test_chryslercan.py new file mode 100644 index 00000000000000..292fec5222ef86 --- /dev/null +++ b/selfdrive/car/chrysler/test_chryslercan.py @@ -0,0 +1,61 @@ +import unittest + +from cereal import car +from selfdrive.can.packer import CANPacker +from selfdrive.car.chrysler import chryslercan + +VisualAlert = car.CarControl.HUDControl.VisualAlert +GearShifter = car.CarState.GearShifter + + + +class TestChryslerCan(unittest.TestCase): + + def test_checksum(self): + self.assertEqual(0x75, chryslercan.calc_checksum(b"\x01\x20")) + self.assertEqual(0xcc, chryslercan.calc_checksum(b"\x14\x00\x00\x00\x20")) + + def test_hud(self): + packer = CANPacker('chrysler_pacifica_2017_hybrid') + self.assertEqual( + [0x2a6, 0, b'\x01\x00\x01\x01\x00\x00\x00\x00', 0], + chryslercan.create_lkas_hud( + packer, + GearShifter.park, False, False, 1, 0)) + self.assertEqual( + [0x2a6, 0, b'\x01\x00\x01\x00\x00\x00\x00\x00', 0], + chryslercan.create_lkas_hud( + packer, + GearShifter.park, False, False, 5*4, 0)) + self.assertEqual( + [0x2a6, 0, b'\x01\x00\x01\x00\x00\x00\x00\x00', 0], + chryslercan.create_lkas_hud( + packer, + GearShifter.park, False, False, 99999, 0)) + self.assertEqual( + [0x2a6, 0, b'\x02\x00\x06\x00\x00\x00\x00\x00', 0], + chryslercan.create_lkas_hud( + packer, + GearShifter.drive, True, False, 99999, 0)) + self.assertEqual( + [0x2a6, 0, b'\x02\x64\x06\x00\x00\x00\x00\x00', 0], + chryslercan.create_lkas_hud( + packer, + GearShifter.drive, True, False, 99999, 0x64)) + + def test_command(self): + packer = CANPacker('chrysler_pacifica_2017_hybrid') + self.assertEqual( + [0x292, 0, b'\x14\x00\x00\x00\x10\x86', 0], + chryslercan.create_lkas_command( + packer, + 0, True, 1)) + self.assertEqual( + [0x292, 0, b'\x04\x00\x00\x00\x80\x83', 0], + chryslercan.create_lkas_command( + packer, + 0, False, 8)) + + +if __name__ == '__main__': + unittest.main() diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index 6e3a24b8fde249..ebd7cad8753cb1 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -1,11 +1,20 @@ from selfdrive.car import dbc_dict +class SteerLimitParams: + STEER_MAX = 261 # 262 faults + STEER_DELTA_UP = 3 # 3 is stock. 100 is fine. 200 is too much it seems + STEER_DELTA_DOWN = 3 # no faults on the way down it seems + STEER_ERROR_MAX = 80 + + + class CAR: PACIFICA_2017_HYBRID = "CHRYSLER PACIFICA HYBRID 2017" PACIFICA_2018_HYBRID = "CHRYSLER PACIFICA HYBRID 2018" PACIFICA_2019_HYBRID = "CHRYSLER PACIFICA HYBRID 2019" - PACIFICA_2018 = "CHRYSLER PACIFICA 2018" + PACIFICA_2018 = "CHRYSLER PACIFICA 2018" # Also covers Pacifica 2017. JEEP_CHEROKEE = "JEEP GRAND CHEROKEE V6 2018" # Also covers Tailhawk 2017. + JEEP_CHEROKEE_2019 = "JEEP GRAND CHEROKEE 2019" # Unique can messages: # Only the hybrids have 270: 8 @@ -23,28 +32,35 @@ class CAR: {168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 515: 7, 516: 7, 517: 7, 518: 7, 520: 8, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 4, 571: 3, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 701: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 746: 5, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 908: 8, 924: 3, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 956: 8, 958: 8, 959: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8, 1216: 8, 1218: 8, 1220: 8, 1225: 8, 1235: 8, 1242: 8, 1246: 8, 1250: 8, 1284: 8, 1537: 8, 1538: 8, 1562: 8, 1568: 8, 1856: 8, 1858: 8, 1860: 8, 1865: 8, 1875: 8, 1882: 8, 1886: 8, 1890: 8, 1892: 8, 2016: 8, 2024: 8}, ], CAR.PACIFICA_2018: [ - {55: 8, 257: 5, 258: 8, 264: 8, 268: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 528: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 746: 5, 752: 2, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 924: 8, 926: 3, 937: 8, 947: 8, 948: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1098: 8, 1100: 8}, - + {55: 8, 257: 5, 258: 8, 264: 8, 268: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 516: 7, 517: 7, 520: 8, 524: 8, 526: 6, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 656: 4, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 746: 5, 752: 2, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 924: 8, 926: 3, 937: 8, 947: 8, 948: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1098: 8, 1100: 8, 1537: 8, 1538: 8, 1562: 8}, + {55: 8, 257: 5, 258: 8, 264: 8, 268: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 516: 7, 517: 7, 520: 8, 524: 8, 526: 6, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 4, 571: 3, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 656: 4, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 746: 5, 752: 2, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 924: 3, 926: 3, 937: 8, 947: 8, 948: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1098: 8, 1100: 8, 1537: 8, 1538: 8, 1562: 8}, ], CAR.PACIFICA_2018_HYBRID: [ - {68: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 528: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 660: 8, 669: 3, 671: 8, 672: 8, 680: 8, 701: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 746: 5, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8}, - {168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 528: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 660: 8, 669: 3, 671: 8, 672: 8, 680: 8, 701: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 746: 5, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8}, + {68: 8, 168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 528: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 680: 8, 701: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 746: 5, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8}, + # based on 9ae7821dc4e92455|2019-07-01--16-42-55 + {168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 515: 7, 516: 7, 517: 7, 518: 7, 520: 8, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 701: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 746: 5, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8, 1216: 8, 1218: 8, 1220: 8, 1225: 8, 1235: 8, 1242: 8, 1246: 8, 1250: 8, 1251: 8, 1252: 8, 1258: 8, 1259: 8, 1260: 8, 1262: 8, 1284: 8, 1537: 8, 1538: 8, 1562: 8, 1568: 8, 1856: 8, 1858: 8, 1860: 8, 1865: 8, 1875: 8, 1882: 8, 1886: 8, 1890: 8, 1891: 8, 1892: 8, 1898: 8, 1899: 8, 1900: 8, 1902: 8, 2016: 8, 2018: 8, 2019: 8, 2020: 8, 2023: 8, 2024: 8, 2026: 8, 2027: 8, 2028: 8, 2031: 8}, ], CAR.PACIFICA_2019_HYBRID: [ - {168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 515: 7, 516: 7, 517: 7, 518: 7, 520: 8, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 660: 8, 669: 3, 671: 8, 672: 8, 680: 8, 701: 8, 703: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 746: 5, 752: 2, 754: 8, 760: 8, 764: 8, 766: 8, 770:8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 906: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 962: 8, 969: 4, 973: 8, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8, 1538: 8}, + {168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 515: 7, 516: 7, 517: 7, 518: 7, 520: 8, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 680: 8, 701: 8, 703: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 746: 5, 752: 2, 754: 8, 760: 8, 764: 8, 766: 8, 770:8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 906: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 962: 8, 969: 4, 973: 8, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8, 1538: 8}, # Based on 0607d2516fc2148f|2019-02-13--23-03-16 { 168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 528: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 701: 8, 703: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 746: 5, 752: 2, 754: 8, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 906: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 962: 8, 969: 4, 973: 8, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8, 1537: 8 + }, + # Based on 3c7ce223e3571b54|2019-05-11--20-16-14 + { + 168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 528: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 701: 8, 703: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 746: 5, 752: 2, 754: 8, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 906: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 962: 8, 969: 4, 973: 8, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8, 1562: 8, 1570: 8 } ], CAR.JEEP_CHEROKEE: [ # JEEP GRAND CHEROKEE V6 2018 - {55: 8, 168: 8, 181: 8, 256: 4, 257: 5, 258: 8, 264: 8, 268: 8, 272: 6, 273: 6, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 4, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 656: 4, 658: 6, 660: 8, 671: 8, 672: 8, 676: 8, 678: 8, 680: 8, 683: 8, 684: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 738: 8, 746: 5, 752: 2, 754: 8, 760: 8, 761: 8, 764: 8, 766: 8, 773: 8, 776: 8, 779: 8, 782: 8, 783: 8, 784: 8, 785: 8, 788: 3, 792: 8, 799: 8, 800: 8, 804: 8, 806: 2, 808: 8, 810: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 831: 6, 832: 8, 838: 2, 844: 5, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 906: 8, 924: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 968: 8, 969: 4, 970: 8, 973: 8, 974: 5, 976: 8, 977: 4, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8}, + {55: 8, 168: 8, 181: 8, 256: 4, 257: 5, 258: 8, 264: 8, 268: 8, 272: 6, 273: 6, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 4, 571: 3, 579: 8, 584: 8, 608: 8, 618: 8, 624: 8, 625: 8, 632: 8, 639: 8, 656: 4, 658: 6, 660: 8, 671: 8, 672: 8, 676: 8, 678: 8, 680: 8, 683: 8, 684: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 738: 8, 746: 5, 752: 2, 754: 8, 760: 8, 761: 8, 764: 8, 766: 8, 773: 8, 776: 8, 779: 8, 782: 8, 783: 8, 784: 8, 785: 8, 788: 3, 792: 8, 799: 8, 800: 8, 804: 8, 806: 2, 808: 8, 810: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 831: 6, 832: 8, 838: 2, 844: 5, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 906: 8, 924: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 956: 8, 968: 8, 969: 4, 970: 8, 973: 8, 974: 5, 976: 8, 977: 4, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8}, # Jeep Grand Cherokee 2017 Trailhawk - {257: 5, 258: 8, 264: 8, 268: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 4, 571: 3, 584: 8, 608: 8, 618: 8, 624: 8, 625: 8, 632: 8, 639: 8, 660: 8, 671: 8, 672: 8, 680: 8, 684: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 746: 5, 752: 2, 760: 8, 761: 8, 764: 8, 766: 8, 773: 8, 776: 8, 779: 8, 783: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 806: 2, 808: 8, 810: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 831: 6, 832: 8, 838: 2, 844: 5, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 924: 3, 937: 8, 947: 8, 948: 8, 969: 4, 974: 5, 977: 4, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8}, + {257: 5, 258: 8, 264: 8, 268: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 4, 571: 3, 584: 8, 608: 8, 618: 8, 624: 8, 625: 8, 632: 8, 639: 8, 658: 6, 660: 8, 671: 8, 672: 8, 680: 8, 684: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 746: 5, 752: 2, 760: 8, 761: 8, 764: 8, 766: 8, 773: 8, 776: 8, 779: 8, 783: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 806: 2, 808: 8, 810: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 831: 6, 832: 8, 838: 2, 844: 5, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 924: 3, 937: 8, 947: 8, 948: 8, 969: 4, 974: 5, 977: 4, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8}, + ], + CAR.JEEP_CHEROKEE_2019: [ # Jeep Grand Cherokee 2019 from Switzerland # 530: 8 is so far only in this Jeep. - {55: 8, 181: 8, 256: 4, 257: 5, 258: 8, 264: 8, 268: 8, 272: 6, 273: 6, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 530: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 618: 8, 624: 8, 625: 8, 632: 8, 639: 8, 660: 8, 671: 8, 672: 8, 676: 8, 680: 8, 683: 8, 684: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 738: 8, 746: 5, 752: 2, 754: 8, 760: 8, 761: 8, 764: 8, 773: 8, 776: 8, 779: 8, 782: 8, 783: 8, 784: 8, 792: 8, 799: 8, 804: 8, 806: 2, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 831: 6, 832: 8, 838: 2, 844: 5, 848: 8, 853: 8, 856: 4, 860: 6, 882: 8, 897: 8, 906: 8, 924: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 968: 8, 969: 4, 970: 8, 973: 8, 974: 5, 977: 4, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8}, + {55: 8, 181: 8, 256: 4, 257: 5, 258: 8, 264: 8, 268: 8, 272: 6, 273: 6, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 530: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 618: 8, 624: 8, 625: 8, 632: 8, 639: 8, 658: 6, 660: 8, 671: 8, 672: 8, 676: 8, 680: 8, 683: 8, 684: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 738: 8, 746: 5, 752: 2, 754: 8, 760: 8, 761: 8, 764: 8, 773: 8, 776: 8, 779: 8, 782: 8, 783: 8, 784: 8, 792: 8, 799: 8, 804: 8, 806: 2, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 831: 6, 832: 8, 838: 2, 844: 5, 848: 8, 853: 8, 856: 4, 860: 6, 882: 8, 897: 8, 906: 8, 924: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 968: 8, 969: 4, 970: 8, 973: 8, 974: 5, 977: 4, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8}, ], } @@ -65,6 +81,9 @@ class CAR: CAR.JEEP_CHEROKEE: dbc_dict( # Same DBC file works. 'chrysler_pacifica_2017_hybrid', # 'pt' 'chrysler_pacifica_2017_hybrid_private_fusion'), # 'radar' + CAR.JEEP_CHEROKEE_2019: dbc_dict( # Same DBC file works. + 'chrysler_pacifica_2017_hybrid', # 'pt' + 'chrysler_pacifica_2017_hybrid_private_fusion'), # 'radar' } STEER_THRESHOLD = 120 @@ -75,10 +94,5 @@ class ECU: ECU_FINGERPRINT = { - ECU.CAM: 0x2d9, # steer torque cmd + ECU.CAM: [0x292], # lkas cmd } - - -def check_ecu_msgs(fingerprint, ecu): - # return True if fingerprint contains messages normally sent by a given ecu - return ECU_FINGERPRINT[ecu] in fingerprint diff --git a/common/fingerprints.py b/selfdrive/car/fingerprints.py similarity index 94% rename from common/fingerprints.py rename to selfdrive/car/fingerprints.py index d4845f8d416a0a..0e29e6c1e71139 100644 --- a/common/fingerprints.py +++ b/selfdrive/car/fingerprints.py @@ -4,7 +4,7 @@ def get_fingerprint_list(): # read all the folders in selfdrive/car and return a dict where: # - keys are all the car models for which we have a fingerprint - # - values are lists dicts of messages that constitute the unique + # - values are lists dicts of messages that constitute the unique # CAN fingerprint of each car model and all its variants fingerprints = {} for car_folder in [x[0] for x in os.walk(BASEDIR + '/selfdrive/car')]: @@ -28,10 +28,8 @@ def get_fingerprint_list(): def is_valid_for_fingerprint(msg, car_fingerprint): adr = msg.address - bus = msg.src # ignore addresses that are more than 11 bits - return (adr in car_fingerprint and car_fingerprint[adr] == len(msg.dat)) or \ - bus != 0 or adr >= 0x800 + return (adr in car_fingerprint and car_fingerprint[adr] == len(msg.dat)) or adr >= 0x800 def eliminate_incompatible_cars(msg, candidate_cars): @@ -61,4 +59,4 @@ def eliminate_incompatible_cars(msg, candidate_cars): def all_known_cars(): """Returns a list of all known car strings.""" - return _FINGERPRINTS.keys() + return list(_FINGERPRINTS.keys()) diff --git a/selfdrive/car/ford/carcontroller.py b/selfdrive/car/ford/carcontroller.py new file mode 100644 index 00000000000000..b466f03ea04964 --- /dev/null +++ b/selfdrive/car/ford/carcontroller.py @@ -0,0 +1,87 @@ +from cereal import car +from selfdrive.car.ford.fordcan import make_can_msg, create_steer_command, create_lkas_ui, \ + spam_cancel_button +from selfdrive.can.packer import CANPacker + + +MAX_STEER_DELTA = 1 +TOGGLE_DEBUG = False + +class CarController(): + def __init__(self, dbc_name, enable_camera, vehicle_model): + self.packer = CANPacker(dbc_name) + self.enable_camera = enable_camera + self.enabled_last = False + self.main_on_last = False + self.vehicle_model = vehicle_model + self.generic_toggle_last = 0 + self.steer_alert_last = False + self.lkas_action = 0 + + def update(self, enabled, CS, frame, actuators, visual_alert, pcm_cancel): + + can_sends = [] + steer_alert = visual_alert == car.CarControl.HUDControl.VisualAlert.steerRequired + + apply_steer = actuators.steer + + if self.enable_camera: + + if pcm_cancel: + #print "CANCELING!!!!" + can_sends.append(spam_cancel_button(self.packer)) + + if (frame % 3) == 0: + + curvature = self.vehicle_model.calc_curvature(actuators.steerAngle*3.1415/180., CS.v_ego) + + # The use of the toggle below is handy for trying out the various LKAS modes + if TOGGLE_DEBUG: + self.lkas_action += int(CS.generic_toggle and not self.generic_toggle_last) + self.lkas_action &= 0xf + else: + self.lkas_action = 5 # 4 and 5 seem the best. 8 and 9 seem to aggressive and laggy + + can_sends.append(create_steer_command(self.packer, apply_steer, enabled, + CS.lkas_state, CS.angle_steers, curvature, self.lkas_action)) + self.generic_toggle_last = CS.generic_toggle + + if (frame % 100) == 0: + + can_sends.append(make_can_msg(973, b'\x00\x00\x00\x00\x00\x00\x00\x00', 0, False)) + #can_sends.append(make_can_msg(984, '\x00\x00\x00\x00\x80\x45\x60\x30', 0, False)) + + if (frame % 100) == 0 or (self.enabled_last != enabled) or (self.main_on_last != CS.main_on) or \ + (self.steer_alert_last != steer_alert): + can_sends.append(create_lkas_ui(self.packer, CS.main_on, enabled, steer_alert)) + + if (frame % 200) == 0: + can_sends.append(make_can_msg(1875, b'\x80\xb0\x55\x55\x78\x90\x00\x00', 1, False)) + + if (frame % 10) == 0: + + can_sends.append(make_can_msg(1648, b'\x00\x00\x00\x40\x00\x00\x50\x00', 1, False)) + can_sends.append(make_can_msg(1649, b'\x10\x10\xf1\x70\x04\x00\x00\x00', 1, False)) + + can_sends.append(make_can_msg(1664, b'\x00\x00\x03\xe8\x00\x01\xa9\xb2', 1, False)) + can_sends.append(make_can_msg(1674, b'\x08\x00\x00\xff\x0c\xfb\x6a\x08', 1, False)) + can_sends.append(make_can_msg(1675, b'\x00\x00\x3b\x60\x37\x00\x00\x00', 1, False)) + can_sends.append(make_can_msg(1690, b'\x70\x00\x00\x55\x86\x1c\xe0\x00', 1, False)) + + can_sends.append(make_can_msg(1910, b'\x06\x4b\x06\x4b\x42\xd3\x11\x30', 1, False)) + can_sends.append(make_can_msg(1911, b'\x48\x53\x37\x54\x48\x53\x37\x54', 1, False)) + can_sends.append(make_can_msg(1912, b'\x31\x34\x47\x30\x38\x31\x43\x42', 1, False)) + can_sends.append(make_can_msg(1913, b'\x31\x34\x47\x30\x38\x32\x43\x42', 1, False)) + can_sends.append(make_can_msg(1969, b'\xf4\x40\x00\x00\x00\x00\x00\x00', 1, False)) + can_sends.append(make_can_msg(1971, b'\x0b\xc0\x00\x00\x00\x00\x00\x00', 1, False)) + + static_msgs = range(1653, 1658) + for addr in static_msgs: + cnt = (frame % 10) + 1 + can_sends.append(make_can_msg(addr, (cnt<<4).to_bytes(1, 'little') + b'\x00\x00\x00\x00\x00\x00\x00', 1, False)) + + self.enabled_last = enabled + self.main_on_last = CS.main_on + self.steer_alert_last = steer_alert + + return can_sends diff --git a/selfdrive/car/ford/carstate.py b/selfdrive/car/ford/carstate.py index 5a8f1f142c5d34..b6ddf4525981f3 100644 --- a/selfdrive/car/ford/carstate.py +++ b/selfdrive/car/ford/carstate.py @@ -1,8 +1,8 @@ from selfdrive.can.parser import CANParser +from common.numpy_fast import mean from selfdrive.config import Conversions as CV from selfdrive.car.ford.values import DBC from common.kalman.simple_kalman import KF1D -import numpy as np WHEEL_RADIUS = 0.33 @@ -32,7 +32,7 @@ def get_can_parser(CP): return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) -class CarState(object): +class CarState(): def __init__(self, CP): self.CP = CP @@ -46,16 +46,13 @@ def __init__(self, CP): dt = 0.01 # Q = np.matrix([[10.0, 0.0], [0.0, 100.0]]) # R = 1e3 - self.v_ego_kf = KF1D(x0=np.matrix([[0.0], [0.0]]), - A=np.matrix([[1.0, dt], [0.0, 1.0]]), - C=np.matrix([1.0, 0.0]), - K=np.matrix([[0.12287673], [0.29666309]])) + self.v_ego_kf = KF1D(x0=[[0.0], [0.0]], + A=[[1.0, dt], [0.0, 1.0]], + C=[1.0, 0.0], + K=[[0.12287673], [0.29666309]]) self.v_ego = 0.0 def update(self, cp): - # copy can_valid - self.can_valid = cp.can_valid - # update prevs, update must run once per loop self.prev_left_blinker_on = self.left_blinker_on self.prev_right_blinker_on = self.right_blinker_on @@ -65,11 +62,11 @@ def update(self, cp): self.v_wheel_fr = cp.vl["WheelSpeed_CG1"]['WhlRl_W_Meas'] * WHEEL_RADIUS self.v_wheel_rl = cp.vl["WheelSpeed_CG1"]['WhlFr_W_Meas'] * WHEEL_RADIUS self.v_wheel_rr = cp.vl["WheelSpeed_CG1"]['WhlFl_W_Meas'] * WHEEL_RADIUS - v_wheel = float(np.mean([self.v_wheel_fl, self.v_wheel_fr, self.v_wheel_rl, self.v_wheel_rr])) + v_wheel = mean([self.v_wheel_fl, self.v_wheel_fr, self.v_wheel_rl, self.v_wheel_rr]) # Kalman filter if abs(v_wheel - self.v_ego) > 2.0: # Prevent large accelerations when car starts at non zero speed - self.v_ego_kf.x = np.matrix([[v_wheel], [0.0]]) + self.v_ego_kf.x = [[v_wheel], [0.0]] self.v_ego_raw = v_wheel v_ego_x = self.v_ego_kf.update(v_wheel) diff --git a/selfdrive/car/ford/fordcan.py b/selfdrive/car/ford/fordcan.py new file mode 100644 index 00000000000000..a55f2989648dea --- /dev/null +++ b/selfdrive/car/ford/fordcan.py @@ -0,0 +1,54 @@ +from common.numpy_fast import clip +from selfdrive.car.ford.values import MAX_ANGLE + + +def make_can_msg(addr, dat, alt, cks=False): + return [addr, 0, dat, alt] + + +def create_steer_command(packer, angle_cmd, enabled, lkas_state, angle_steers, curvature, lkas_action): + """Creates a CAN message for the Ford Steer Command.""" + + #if enabled and lkas available: + if enabled and lkas_state in [2,3]: #and (frame % 500) >= 3: + action = lkas_action + else: + action = 0xf + angle_cmd = angle_steers/MAX_ANGLE + + angle_cmd = clip(angle_cmd * MAX_ANGLE, - MAX_ANGLE, MAX_ANGLE) + + values = { + "Lkas_Action": action, + "Lkas_Alert": 0xf, # no alerts + "Lane_Curvature": clip(curvature, -0.01, 0.01), # is it just for debug? + #"Lane_Curvature": 0, # is it just for debug? + "Steer_Angle_Req": angle_cmd + } + return packer.make_can_msg("Lane_Keep_Assist_Control", 0, values) + + +def create_lkas_ui(packer, main_on, enabled, steer_alert): + """Creates a CAN message for the Ford Steer Ui.""" + + if not main_on: + lines = 0xf + elif enabled: + lines = 0x3 + else: + lines = 0x6 + + values = { + "Set_Me_X80": 0x80, + "Set_Me_X45": 0x45, + "Set_Me_X30": 0x30, + "Lines_Hud": lines, + "Hands_Warning_W_Chime": steer_alert, + } + return packer.make_can_msg("Lane_Keep_Assist_Ui", 0, values) + +def spam_cancel_button(packer): + values = { + "Cancel": 1 + } + return packer.make_can_msg("Steering_Buttons", 0, values) diff --git a/selfdrive/car/ford/interface.py b/selfdrive/car/ford/interface.py index 0e29ea62620814..a05144c133d347 100755 --- a/selfdrive/car/ford/interface.py +++ b/selfdrive/car/ford/interface.py @@ -1,26 +1,21 @@ -#!/usr/bin/env python -from common.realtime import sec_since_boot +#!/usr/bin/env python3 from cereal import car from selfdrive.swaglog import cloudlog from selfdrive.config import Conversions as CV from selfdrive.controls.lib.drive_helpers import EventTypes as ET, create_event from selfdrive.controls.lib.vehicle_model import VehicleModel from selfdrive.car.ford.carstate import CarState, get_can_parser -from selfdrive.car.ford.fordcan import MAX_ANGLE +from selfdrive.car.ford.values import MAX_ANGLE, ECU, ECU_FINGERPRINT, FINGERPRINTS +from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint +from selfdrive.car.interfaces import CarInterfaceBase -try: - from selfdrive.car.ford.carcontroller import CarController -except ImportError: - CarController = None - -class CarInterface(object): - def __init__(self, CP, sendcan=None): +class CarInterface(CarInterfaceBase): + def __init__(self, CP, CarController): self.CP = CP self.VM = VehicleModel(CP) self.frame = 0 - self.can_invalid_count = 0 self.gas_pressed_prev = False self.brake_pressed_prev = False self.cruise_enabled_prev = False @@ -30,9 +25,8 @@ def __init__(self, CP, sendcan=None): self.cp = get_can_parser(CP) - # sending if read only is False - if sendcan is not None: - self.sendcan = sendcan + self.CC = None + if CarController is not None: self.CC = CarController(self.cp.dbc_name, CP.enableCamera, self.VM) @staticmethod @@ -40,71 +34,44 @@ def compute_gb(accel, speed): return float(accel) / 3.0 @staticmethod - def calc_accel_override(a_ego, a_target, v_ego, v_target): - return 1.0 - - @staticmethod - def get_params(candidate, fingerprint): - - # kg of standard extra cargo to count for drive, gas, etc... - std_cargo = 136 + def get_params(candidate, fingerprint=gen_empty_fingerprint(), vin="", has_relay=False): ret = car.CarParams.new_message() ret.carName = "ford" ret.carFingerprint = candidate + ret.carVin = vin + ret.isPandaBlack = has_relay - ret.safetyModel = car.CarParams.SafetyModels.ford + ret.safetyModel = car.CarParams.SafetyModel.ford + ret.dashcamOnly = True # pedal ret.enableCruise = True - # FIXME: hardcoding honda civic 2016 touring params so they can be used to - # scale unknown params for other cars - mass_civic = 2923. * CV.LB_TO_KG + std_cargo - wheelbase_civic = 2.70 - centerToFront_civic = wheelbase_civic * 0.4 - centerToRear_civic = wheelbase_civic - centerToFront_civic - rotationalInertia_civic = 2500 - tireStiffnessFront_civic = 85400 - tireStiffnessRear_civic = 90000 - - ret.steerKiBP, ret.steerKpBP = [[0.], [0.]] ret.wheelbase = 2.85 ret.steerRatio = 14.8 - ret.mass = 3045. * CV.LB_TO_KG + std_cargo - ret.steerKpV, ret.steerKiV = [[0.01], [0.005]] # TODO: tune this - ret.steerKf = 1. / MAX_ANGLE # MAX Steer angle to normalize FF + ret.mass = 3045. * CV.LB_TO_KG + STD_CARGO_KG + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.01], [0.005]] # TODO: tune this + ret.lateralTuning.pid.kf = 1. / MAX_ANGLE # MAX Steer angle to normalize FF ret.steerActuatorDelay = 0.1 # Default delay, not measured yet ret.steerRateCost = 1.0 - - f = 1.2 - tireStiffnessFront_civic *= f - tireStiffnessRear_civic *= f - ret.centerToFront = ret.wheelbase * 0.44 - - ret.longPidDeadzoneBP = [0., 9.] - ret.longPidDeadzoneV = [0., .15] + tire_stiffness_factor = 0.5328 # min speed to enable ACC. if car can do stop and go, then set enabling speed # to a negative value, so it won't matter. ret.minEnableSpeed = -1. - centerToRear = ret.wheelbase - ret.centerToFront # TODO: get actual value, for now starting with reasonable value for # civic and scaling by mass and wheelbase - ret.rotationalInertia = rotationalInertia_civic * \ - ret.mass * ret.wheelbase**2 / (mass_civic * wheelbase_civic**2) + ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) # TODO: start from empirically derived lateral slip stiffness for the civic and scale by # mass and CG position, so all cars will have approximately similar dyn behaviors - ret.tireStiffnessFront = tireStiffnessFront_civic * \ - ret.mass / mass_civic * \ - (centerToRear / ret.wheelbase) / (centerToRear_civic / wheelbase_civic) - ret.tireStiffnessRear = tireStiffnessRear_civic * \ - ret.mass / mass_civic * \ - (ret.centerToFront / ret.wheelbase) / (centerToFront_civic / wheelbase_civic) + ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, + tire_stiffness_factor=tire_stiffness_factor) # no rear steering, at least on the listed cars above ret.steerRatioRear = 0. @@ -118,33 +85,35 @@ def get_params(candidate, fingerprint): ret.brakeMaxBP = [5., 20.] ret.brakeMaxV = [1., 0.8] - ret.enableCamera = not any(x for x in [970, 973, 984] if x in fingerprint) + ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, ECU.CAM) or has_relay ret.openpilotLongitudinalControl = False - cloudlog.warn("ECU Camera Simulated: %r", ret.enableCamera) + cloudlog.warning("ECU Camera Simulated: %r", ret.enableCamera) ret.steerLimitAlert = False ret.stoppingControl = False ret.startAccel = 0.0 - ret.longitudinalKpBP = [0., 5., 35.] - ret.longitudinalKpV = [3.6, 2.4, 1.5] - ret.longitudinalKiBP = [0., 35.] - ret.longitudinalKiV = [0.54, 0.36] + ret.longitudinalTuning.deadzoneBP = [0., 9.] + ret.longitudinalTuning.deadzoneV = [0., .15] + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kpV = [3.6, 2.4, 1.5] + ret.longitudinalTuning.kiBP = [0., 35.] + ret.longitudinalTuning.kiV = [0.54, 0.36] return ret # returns a car.CarState - def update(self, c): + def update(self, c, can_strings): # ******************* do can recv ******************* - canMonoTimes = [] - - self.cp.update(int(sec_since_boot() * 1e9), False) + self.cp.update_strings(can_strings) self.CS.update(self.cp) # create message ret = car.CarState.new_message() + ret.canValid = self.cp.can_valid + # speeds ret.vEgo = self.CS.v_ego ret.vEgoRaw = self.CS.v_ego_raw @@ -172,12 +141,6 @@ def update(self, c): # events events = [] - if not self.CS.can_valid: - self.can_invalid_count += 1 - if self.can_invalid_count >= 5: - events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) - else: - self.can_invalid_count = 0 if self.CS.steer_error: events.append(create_event('steerUnavailable', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE, ET.PERMANENT])) @@ -200,7 +163,6 @@ def update(self, c): events.append(create_event('steerTempUnavailableMute', [ET.WARNING])) ret.events = events - ret.canMonoTimes = canMonoTimes self.gas_pressed_prev = ret.gasPressed self.brake_pressed_prev = ret.brakePressed @@ -212,8 +174,8 @@ def update(self, c): # to be called @ 100hz def apply(self, c): - self.CC.update(self.sendcan, c.enabled, self.CS, self.frame, c.actuators, - c.hudControl.visualAlert, c.cruiseControl.cancel) + can_sends = self.CC.update(c.enabled, self.CS, self.frame, c.actuators, + c.hudControl.visualAlert, c.cruiseControl.cancel) self.frame += 1 - return False + return can_sends diff --git a/selfdrive/car/ford/radar_interface.py b/selfdrive/car/ford/radar_interface.py index 2acea9d7084949..2538a185de05d0 100755 --- a/selfdrive/car/ford/radar_interface.py +++ b/selfdrive/car/ford/radar_interface.py @@ -1,60 +1,50 @@ -#!/usr/bin/env python -import os -import numpy as np -from selfdrive.can.parser import CANParser +#!/usr/bin/env python3 from cereal import car -from common.realtime import sec_since_boot -import zmq -from selfdrive.services import service_list -import selfdrive.messaging as messaging - +from selfdrive.can.parser import CANParser +from selfdrive.car.ford.values import DBC +from selfdrive.config import Conversions as CV +from selfdrive.car.interfaces import RadarInterfaceBase -RADAR_MSGS = range(0x500, 0x540) +RADAR_MSGS = list(range(0x500, 0x540)) -def _create_radard_can_parser(): - dbc_f = 'ford_fusion_2018_adas.dbc' +def _create_radar_can_parser(car_fingerprint): + dbc_f = DBC[car_fingerprint]['radar'] msg_n = len(RADAR_MSGS) - signals = zip(['X_Rel'] * msg_n + ['Angle'] * msg_n + ['V_Rel'] * msg_n, - RADAR_MSGS * 3, - [0] * msg_n + [0] * msg_n + [0] * msg_n) - checks = zip(RADAR_MSGS, [20]*msg_n) + signals = list(zip(['X_Rel'] * msg_n + ['Angle'] * msg_n + ['V_Rel'] * msg_n, + RADAR_MSGS * 3, + [0] * msg_n + [0] * msg_n + [0] * msg_n)) + checks = list(zip(RADAR_MSGS, [20]*msg_n)) - return CANParser(os.path.splitext(dbc_f)[0], signals, checks, 1) + return CANParser(dbc_f, signals, checks, 1) -class RadarInterface(object): +class RadarInterface(RadarInterfaceBase): def __init__(self, CP): # radar self.pts = {} self.validCnt = {key: 0 for key in RADAR_MSGS} self.track_id = 0 - self.delay = 0.0 # Delay of radar + self.delay = 0 # Delay of radar - # Nidec - self.rcp = _create_radard_can_parser() + self.rcp = _create_radar_can_parser(CP.carFingerprint) + self.trigger_msg = 0x53f + self.updated_messages = set() - context = zmq.Context() - self.logcan = messaging.sub_sock(context, service_list['can'].port) + def update(self, can_strings): + vls = self.rcp.update_strings(can_strings) + self.updated_messages.update(vls) - def update(self): - canMonoTimes = [] + if self.trigger_msg not in self.updated_messages: + return None - updated_messages = set() - while 1: - tm = int(sec_since_boot() * 1e9) - updated_messages.update(self.rcp.update(tm, True)) - # TODO: do not hardcode last msg - if 0x53f in updated_messages: - break - ret = car.RadarState.new_message() + ret = car.RadarData.new_message() errors = [] if not self.rcp.can_valid: - errors.append("commIssue") + errors.append("canError") ret.errors = errors - ret.canMonoTimes = canMonoTimes - for ii in updated_messages: + for ii in sorted(self.updated_messages): cpt = self.rcp.vl[ii] if cpt['X_Rel'] > 0.00001: @@ -69,11 +59,11 @@ def update(self): # radar point only valid if there have been enough valid measurements if self.validCnt[ii] > 0: if ii not in self.pts: - self.pts[ii] = car.RadarState.RadarPoint.new_message() + self.pts[ii] = car.RadarData.RadarPoint.new_message() self.pts[ii].trackId = self.track_id self.track_id += 1 self.pts[ii].dRel = cpt['X_Rel'] # from front of car - self.pts[ii].yRel = cpt['X_Rel'] * cpt['Angle'] * np.pi / 180. # in car frame's y axis, left is positive + self.pts[ii].yRel = cpt['X_Rel'] * cpt['Angle'] * CV.DEG_TO_RAD # in car frame's y axis, left is positive self.pts[ii].vRel = cpt['V_Rel'] self.pts[ii].aRel = float('nan') self.pts[ii].yvRel = float('nan') @@ -82,12 +72,6 @@ def update(self): if ii in self.pts: del self.pts[ii] - ret.points = self.pts.values() + ret.points = list(self.pts.values()) + self.updated_messages.clear() return ret - -if __name__ == "__main__": - RI = RadarInterface(None) - while 1: - ret = RI.update() - print(chr(27) + "[2J") - print ret diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py index b8890107fcc52b..a3fb576a3b704c 100644 --- a/selfdrive/car/ford/values.py +++ b/selfdrive/car/ford/values.py @@ -1,12 +1,21 @@ from selfdrive.car import dbc_dict +MAX_ANGLE = 87. # make sure we never command the extremes (0xfff) which cause latching fault + class CAR: FUSION = "FORD FUSION 2018" FINGERPRINTS = { CAR.FUSION: [{ 71: 8, 74: 8, 75: 8, 76: 8, 90: 8, 92: 8, 93: 8, 118: 8, 119: 8, 120: 8, 125: 8, 129: 8, 130: 8, 131: 8, 132: 8, 133: 8, 145: 8, 146: 8, 357: 8, 359: 8, 360: 8, 361: 8, 376: 8, 390: 8, 391: 8, 392: 8, 394: 8, 512: 8, 514: 8, 516: 8, 531: 8, 532: 8, 534: 8, 535: 8, 560: 8, 578: 8, 604: 8, 613: 8, 673: 8, 827: 8, 848: 8, 934: 8, 935: 8, 936: 8, 947: 8, 963: 8, 970: 8, 972: 8, 973: 8, 984: 8, 992: 8, 994: 8, 997: 8, 998: 8, 1003: 8, 1034: 8, 1045: 8, 1046: 8, 1053: 8, 1054: 8, 1058: 8, 1059: 8, 1068: 8, 1072: 8, 1073: 8, 1082: 8, 1107: 8, 1108: 8, 1109: 8, 1110: 8, 1200: 8, 1427: 8, 1430: 8, 1438: 8, 1459: 8 - }], + }], +} + +class ECU: + CAM = 0 + +ECU_FINGERPRINT = { + ECU.CAM: [970, 973, 984] } DBC = { diff --git a/selfdrive/car/gm/carcontroller.py b/selfdrive/car/gm/carcontroller.py index b242bc57b7914f..c4647c8228d9cd 100644 --- a/selfdrive/car/gm/carcontroller.py +++ b/selfdrive/car/gm/carcontroller.py @@ -1,12 +1,14 @@ +from cereal import car +from common.realtime import DT_CTRL from common.numpy_fast import interp -from common.realtime import sec_since_boot from selfdrive.config import Conversions as CV -from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car import apply_std_steer_torque_limits from selfdrive.car.gm import gmcan from selfdrive.car.gm.values import DBC, SUPERCRUISE_CARS from selfdrive.can.packer import CANPacker +VisualAlert = car.CarControl.HUDControl.VisualAlert + class CarControllerParams(): def __init__(self, car_fingerprint): @@ -46,7 +48,7 @@ def __init__(self, car_fingerprint): def actuator_hystereses(final_pedal, pedal_steady): # hyst params... TODO: move these to VehicleParams - pedal_hyst_gap = 0.01 # don't change pedal command for small oscilalitons within this value + pedal_hyst_gap = 0.01 # don't change pedal command for small oscillations within this value # for small pedal oscillations within pedal_hyst_gap, don't change the pedal command if final_pedal == 0.: @@ -59,16 +61,20 @@ def actuator_hystereses(final_pedal, pedal_steady): return final_pedal, pedal_steady +def process_hud_alert(hud_alert): + # initialize to no alert + steer = 0 + if hud_alert == VisualAlert.steerRequired: + steer = 1 + return steer -class CarController(object): - def __init__(self, canbus, car_fingerprint, allow_controls): +class CarController(): + def __init__(self, canbus, car_fingerprint): self.pedal_steady = 0. - self.start_time = sec_since_boot() - self.chime = 0 + self.start_time = 0. self.steer_idx = 0 self.apply_steer_last = 0 self.car_fingerprint = car_fingerprint - self.allow_controls = allow_controls self.lka_icon_status_last = (False, False) # Setup detection helper. Routes commands to @@ -79,13 +85,8 @@ def __init__(self, canbus, car_fingerprint, allow_controls): self.packer_pt = CANPacker(DBC[car_fingerprint]['pt']) self.packer_ch = CANPacker(DBC[car_fingerprint]['chassis']) - def update(self, sendcan, enabled, CS, frame, actuators, \ - hud_v_cruise, hud_show_lanes, hud_show_car, chime, chime_cnt): - """ Controls thread """ - - # Sanity check. - if not self.allow_controls: - return + def update(self, enabled, CS, frame, actuators, \ + hud_v_cruise, hud_show_lanes, hud_show_car, hud_alert): P = self.params @@ -93,6 +94,9 @@ def update(self, sendcan, enabled, CS, frame, actuators, \ can_sends = [] canbus = self.canbus + alert_out = process_hud_alert(hud_alert) + steer = alert_out + ### STEER ### if (frame % P.STEER_STEP) == 0: @@ -104,7 +108,7 @@ def update(self, sendcan, enabled, CS, frame, actuators, \ apply_steer = 0 self.apply_steer_last = apply_steer - idx = (frame / P.STEER_STEP) % 4 + idx = (frame // P.STEER_STEP) % 4 if self.car_fingerprint in SUPERCRUISE_CARS: can_sends += gmcan.create_steering_control_ct6(self.packer_pt, @@ -134,7 +138,7 @@ def update(self, sendcan, enabled, CS, frame, actuators, \ # Gas/regen and brakes - all at 25Hz if (frame % 4) == 0: - idx = (frame / 4) % 4 + idx = (frame // 4) % 4 at_full_stop = enabled and CS.standstill near_stop = enabled and (CS.v_ego < P.NEAR_STOP_BRAKE_PHASE) @@ -150,16 +154,16 @@ def update(self, sendcan, enabled, CS, frame, actuators, \ # Radar needs to know current speed and yaw rate (50hz), # and that ADAS is alive (10hz) time_and_headlights_step = 10 - tt = sec_since_boot() + tt = frame * DT_CTRL if frame % time_and_headlights_step == 0: - idx = (frame / time_and_headlights_step) % 4 + idx = (frame // time_and_headlights_step) % 4 can_sends.append(gmcan.create_adas_time_status(canbus.obstacle, int((tt - self.start_time) * 60), idx)) can_sends.append(gmcan.create_adas_headlights_status(canbus.obstacle)) speed_and_accelerometer_step = 2 if frame % speed_and_accelerometer_step == 0: - idx = (frame / speed_and_accelerometer_step) % 4 + idx = (frame // speed_and_accelerometer_step) % 4 can_sends.append(gmcan.create_adas_steering_status(canbus.obstacle, idx)) can_sends.append(gmcan.create_adas_accelerometer_speed_status(canbus.obstacle, CS.v_ego, idx)) @@ -175,24 +179,7 @@ def update(self, sendcan, enabled, CS, frame, actuators, \ lka_icon_status = (lka_active, lka_critical) if frame % P.CAMERA_KEEPALIVE_STEP == 0 \ or lka_icon_status != self.lka_icon_status_last: - can_sends.append(gmcan.create_lka_icon_command(canbus.sw_gmlan, lka_active, lka_critical)) + can_sends.append(gmcan.create_lka_icon_command(canbus.sw_gmlan, lka_active, lka_critical, steer)) self.lka_icon_status_last = lka_icon_status - # Send chimes - if self.chime != chime: - duration = 0x3c - - # There is no 'repeat forever' chime command - # TODO: Manage periodic re-issuing of chime command - # and chime cancellation - if chime_cnt == -1: - chime_cnt = 10 - - if chime != 0: - can_sends.append(gmcan.create_chime_command(canbus.sw_gmlan, chime, duration, chime_cnt)) - - # If canceling a repeated chime, cancel command must be - # issued for the same chime type and duration - self.chime = chime - - sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan').to_bytes()) + return can_sends diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index ae97a38b9ceede..7da8d6527257c6 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -1,5 +1,5 @@ -import numpy as np from cereal import car +from common.numpy_fast import mean from common.kalman.simple_kalman import KF1D from selfdrive.config import Conversions as CV from selfdrive.can.parser import CANParser @@ -49,7 +49,8 @@ def get_powertrain_can_parser(CP, canbus): return CANParser(DBC[CP.carFingerprint]['pt'], signals, [], canbus.powertrain) -class CarState(object): + +class CarState(): def __init__(self, CP, canbus): self.CP = CP # initialize can parser @@ -63,15 +64,13 @@ def __init__(self, CP, canbus): # vEgo kalman filter dt = 0.01 - self.v_ego_kf = KF1D(x0=np.matrix([[0.], [0.]]), - A=np.matrix([[1., dt], [0., 1.]]), - C=np.matrix([1., 0.]), - K=np.matrix([[0.12287673], [0.29666309]])) + self.v_ego_kf = KF1D(x0=[[0.], [0.]], + A=[[1., dt], [0., 1.]], + C=[1., 0.], + K=[[0.12287673], [0.29666309]]) self.v_ego = 0. def update(self, pt_cp): - - self.can_valid = pt_cp.can_valid self.prev_cruise_buttons = self.cruise_buttons self.cruise_buttons = pt_cp.vl["ASCMSteeringButton"]['ACCButtons'] @@ -79,7 +78,7 @@ def update(self, pt_cp): self.v_wheel_fr = pt_cp.vl["EBCMWheelSpdFront"]['FRWheelSpd'] * CV.KPH_TO_MS self.v_wheel_rl = pt_cp.vl["EBCMWheelSpdRear"]['RLWheelSpd'] * CV.KPH_TO_MS self.v_wheel_rr = pt_cp.vl["EBCMWheelSpdRear"]['RRWheelSpd'] * CV.KPH_TO_MS - v_wheel = float(np.mean([self.v_wheel_fl, self.v_wheel_fr, self.v_wheel_rl, self.v_wheel_rr])) + v_wheel = mean([self.v_wheel_fl, self.v_wheel_fr, self.v_wheel_rl, self.v_wheel_rr]) if abs(v_wheel - self.v_ego) > 2.0: # Prevent large accelerations when car starts at non zero speed self.v_ego_kf.x = [[v_wheel], [0.0]] @@ -117,7 +116,6 @@ def update(self, pt_cp): self.steer_error = False self.brake_error = False - self.can_valid = True self.prev_left_blinker_on = self.left_blinker_on self.prev_right_blinker_on = self.right_blinker_on diff --git a/selfdrive/car/gm/gmcan.py b/selfdrive/car/gm/gmcan.py index 910cb1d95604ce..ada05658ba7b28 100644 --- a/selfdrive/car/gm/gmcan.py +++ b/selfdrive/car/gm/gmcan.py @@ -24,7 +24,7 @@ def create_steering_control_ct6(packer, canbus, apply_steer, v_ego, idx, enabled dat = packer.make_can_msg("ASCMLKASteeringCmd", 0, values)[2] # the checksum logic is weird values['LKASteeringCmdChecksum'] = (0x2a + - sum([ord(i) for i in dat][:4]) + + sum(dat[:4]) + values['LKASMode']) & 0x3ff # pack again with checksum dat = packer.make_can_msg("ASCMLKASteeringCmd", 0, values)[2] @@ -36,7 +36,7 @@ def create_steering_control_ct6(packer, canbus, apply_steer, v_ego, idx, enabled def create_adas_keepalive(bus): - dat = "\x00\x00\x00\x00\x00\x00\x00" + dat = b"\x00\x00\x00\x00\x00\x00\x00" return [[0x409, 0, dat, bus], [0x40a, 0, dat, bus]] def create_gas_regen_command(packer, bus, throttle, idx, acc_engaged, at_full_stop): @@ -52,9 +52,9 @@ def create_gas_regen_command(packer, bus, throttle, idx, acc_engaged, at_full_st } dat = packer.make_can_msg("ASCMGasRegenCmd", bus, values)[2] - values["GasRegenChecksum"] = (((0xff - ord(dat[1])) & 0xff) << 16) | \ - (((0xff - ord(dat[2])) & 0xff) << 8) | \ - ((0x100 - ord(dat[3]) - idx) & 0xff) + values["GasRegenChecksum"] = (((0xff -dat[1]) & 0xff) << 16) | \ + (((0xff - dat[2]) & 0xff) << 8) | \ + ((0x100 - dat[3] - idx) & 0xff) return packer.make_can_msg("ASCMGasRegenCmd", bus, values) @@ -106,13 +106,13 @@ def create_adas_time_status(bus, tt, idx): chksum = 0x1000 - dat[0] - dat[1] - dat[2] - dat[3] chksum = chksum & 0xfff dat += [0x40 + (chksum >> 8), chksum & 0xff, 0x12] - return [0xa1, 0, "".join(map(chr, dat)), bus] + return [0xa1, 0, bytes(dat), bus] def create_adas_steering_status(bus, idx): dat = [idx << 6, 0xf0, 0x20, 0, 0, 0] chksum = 0x60 + sum(dat) dat += [chksum >> 8, chksum & 0xff] - return [0x306, 0, "".join(map(chr, dat)), bus] + return [0x306, 0, bytes(dat), bus] def create_adas_accelerometer_speed_status(bus, speed_ms, idx): spd = int(speed_ms * 16) & 0xfff @@ -125,23 +125,24 @@ def create_adas_accelerometer_speed_status(bus, speed_ms, idx): dat = [0x08, spd >> 4, ((spd & 0xf) << 4) | (accel >> 8), accel & 0xff, 0] chksum = 0x62 + far_range_mode + (idx << 2) + dat[0] + dat[1] + dat[2] + dat[3] + dat[4] dat += [(idx << 5) + (far_range_mode << 4) + (near_range_mode << 3) + (chksum >> 8), chksum & 0xff] - return [0x308, 0, "".join(map(chr, dat)), bus] + return [0x308, 0, bytes(dat), bus] def create_adas_headlights_status(bus): - return [0x310, 0, "\x42\x04", bus] + return [0x310, 0, b"\x42\x04", bus] -def create_chime_command(bus, chime_type, duration, repeat_cnt): - dat = [chime_type, duration, repeat_cnt, 0xff, 0] - return [0x10400060, 0, "".join(map(chr, dat)), bus] - -def create_lka_icon_command(bus, active, critical): - if active: +def create_lka_icon_command(bus, active, critical, steer): + if active and steer == 1: + if critical: + dat = b"\x50\xc0\x14" + else: + dat = b"\x50\x40\x18" + elif active: if critical: - dat = "\x40\xc0\x14" + dat = b"\x40\xc0\x14" else: - dat = "\x40\x40\x18" + dat = b"\x40\x40\x18" else: - dat = "\x00\x00\x00" + dat = b"\x00\x00\x00" return [0x104c006c, 0, dat, bus] # TODO: WIP diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 83e90c3c7d7fcb..213f7676520d2b 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -1,32 +1,30 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from cereal import car -from common.realtime import sec_since_boot from selfdrive.config import Conversions as CV from selfdrive.controls.lib.drive_helpers import create_event, EventTypes as ET from selfdrive.controls.lib.vehicle_model import VehicleModel -from selfdrive.car.gm.values import DBC, CAR, STOCK_CONTROL_MSGS, AUDIO_HUD, SUPERCRUISE_CARS +from selfdrive.car.gm.values import DBC, CAR, ECU, ECU_FINGERPRINT, \ + SUPERCRUISE_CARS, AccState, FINGERPRINTS from selfdrive.car.gm.carstate import CarState, CruiseButtons, get_powertrain_can_parser +from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint +from selfdrive.car.interfaces import CarInterfaceBase -try: - from selfdrive.car.gm.carcontroller import CarController -except ImportError: - CarController = None +ButtonType = car.CarState.ButtonEvent.Type -class CanBus(object): +class CanBus(CarInterfaceBase): def __init__(self): self.powertrain = 0 self.obstacle = 1 self.chassis = 2 self.sw_gmlan = 3 -class CarInterface(object): - def __init__(self, CP, sendcan=None): +class CarInterface(CarInterfaceBase): + def __init__(self, CP, CarController): self.CP = CP self.frame = 0 self.gas_pressed_prev = False self.brake_pressed_prev = False - self.can_invalid_count = 0 self.acc_active_prev = 0 # *** init the major players *** @@ -36,42 +34,39 @@ def __init__(self, CP, sendcan=None): self.pt_cp = get_powertrain_can_parser(CP, canbus) self.ch_cp_dbc_name = DBC[CP.carFingerprint]['chassis'] - # sending if read only is False - if sendcan is not None: - self.sendcan = sendcan - self.CC = CarController(canbus, CP.carFingerprint, CP.enableCamera) + self.CC = None + if CarController is not None: + self.CC = CarController(canbus, CP.carFingerprint) @staticmethod def compute_gb(accel, speed): return float(accel) / 4.0 @staticmethod - def calc_accel_override(a_ego, a_target, v_ego, v_target): - return 1.0 - - @staticmethod - def get_params(candidate, fingerprint): + def get_params(candidate, fingerprint=gen_empty_fingerprint(), vin="", has_relay=False): ret = car.CarParams.new_message() ret.carName = "gm" ret.carFingerprint = candidate + ret.carVin = vin + ret.isPandaBlack = has_relay ret.enableCruise = False # Presence of a camera on the object bus is ok. - # Have to go passive if ASCM is online (ACC-enabled cars), + # Have to go to read_only if ASCM is online (ACC-enabled cars), # or camera is on powertrain bus (LKA cars without ACC). - ret.enableCamera = not any(x for x in STOCK_CONTROL_MSGS[candidate] if x in fingerprint) + ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, ECU.CAM) or \ + has_relay or \ + candidate == CAR.CADILLAC_CT6 ret.openpilotLongitudinalControl = ret.enableCamera - - std_cargo = 136 + tire_stiffness_factor = 0.444 # not optimized yet if candidate == CAR.VOLT: # supports stop and go, but initial engage must be above 18mph (which include conservatism) ret.minEnableSpeed = 18 * CV.MPH_TO_MS - # kg of standard extra cargo to count for driver, gas, etc... - ret.mass = 1607 + std_cargo - ret.safetyModel = car.CarParams.SafetyModels.gm + ret.mass = 1607. + STD_CARGO_KG + ret.safetyModel = car.CarParams.SafetyModel.gm ret.wheelbase = 2.69 ret.steerRatio = 15.7 ret.steerRatioRear = 0. @@ -80,28 +75,27 @@ def get_params(candidate, fingerprint): elif candidate == CAR.MALIBU: # supports stop and go, but initial engage must be above 18mph (which include conservatism) ret.minEnableSpeed = 18 * CV.MPH_TO_MS - ret.mass = 1496 + std_cargo - ret.safetyModel = car.CarParams.SafetyModels.gm + ret.mass = 1496. + STD_CARGO_KG + ret.safetyModel = car.CarParams.SafetyModel.gm ret.wheelbase = 2.83 ret.steerRatio = 15.8 ret.steerRatioRear = 0. ret.centerToFront = ret.wheelbase * 0.4 # wild guess elif candidate == CAR.HOLDEN_ASTRA: - # kg of standard extra cargo to count for driver, gas, etc... - ret.mass = 1363 + std_cargo + ret.mass = 1363. + STD_CARGO_KG ret.wheelbase = 2.662 # Remaining parameters copied from Volt for now ret.centerToFront = ret.wheelbase * 0.4 ret.minEnableSpeed = 18 * CV.MPH_TO_MS - ret.safetyModel = car.CarParams.SafetyModels.gm + ret.safetyModel = car.CarParams.SafetyModel.gm ret.steerRatio = 15.7 ret.steerRatioRear = 0. elif candidate == CAR.ACADIA: - ret.minEnableSpeed = -1 # engage speed is decided by pcm - ret.mass = 4353. * CV.LB_TO_KG + std_cargo - ret.safetyModel = car.CarParams.SafetyModels.gm + ret.minEnableSpeed = -1. # engage speed is decided by pcm + ret.mass = 4353. * CV.LB_TO_KG + STD_CARGO_KG + ret.safetyModel = car.CarParams.SafetyModel.gm ret.wheelbase = 2.86 ret.steerRatio = 14.4 #end to end is 13.46 ret.steerRatioRear = 0. @@ -109,8 +103,8 @@ def get_params(candidate, fingerprint): elif candidate == CAR.BUICK_REGAL: ret.minEnableSpeed = 18 * CV.MPH_TO_MS - ret.mass = 3779. * CV.LB_TO_KG + std_cargo # (3849+3708)/2 - ret.safetyModel = car.CarParams.SafetyModels.gm + ret.mass = 3779. * CV.LB_TO_KG + STD_CARGO_KG # (3849+3708)/2 + ret.safetyModel = car.CarParams.SafetyModel.gm ret.wheelbase = 2.83 #111.4 inches in meters ret.steerRatio = 14.4 # guess for tourx ret.steerRatioRear = 0. @@ -118,8 +112,8 @@ def get_params(candidate, fingerprint): elif candidate == CAR.CADILLAC_ATS: ret.minEnableSpeed = 18 * CV.MPH_TO_MS - ret.mass = 1601 + std_cargo - ret.safetyModel = car.CarParams.SafetyModels.gm + ret.mass = 1601. + STD_CARGO_KG + ret.safetyModel = car.CarParams.SafetyModel.gm ret.wheelbase = 2.78 ret.steerRatio = 15.3 ret.steerRatioRear = 0. @@ -127,60 +121,42 @@ def get_params(candidate, fingerprint): elif candidate == CAR.CADILLAC_CT6: # engage speed is decided by pcm - ret.minEnableSpeed = -1 - # kg of standard extra cargo to count for driver, gas, etc... - ret.mass = 4016. * CV.LB_TO_KG + std_cargo - ret.safetyModel = car.CarParams.SafetyModels.cadillac + ret.minEnableSpeed = -1. + ret.mass = 4016. * CV.LB_TO_KG + STD_CARGO_KG + ret.safetyModel = car.CarParams.SafetyModel.cadillac ret.wheelbase = 3.11 ret.steerRatio = 14.6 # it's 16.3 without rear active steering ret.steerRatioRear = 0. # TODO: there is RAS on this car! ret.centerToFront = ret.wheelbase * 0.465 - # hardcoding honda civic 2016 touring params so they can be used to - # scale unknown params for other cars - mass_civic = 2923. * CV.LB_TO_KG + std_cargo - wheelbase_civic = 2.70 - centerToFront_civic = wheelbase_civic * 0.4 - centerToRear_civic = wheelbase_civic - centerToFront_civic - rotationalInertia_civic = 2500 - tireStiffnessFront_civic = 85400 - tireStiffnessRear_civic = 90000 - - centerToRear = ret.wheelbase - ret.centerToFront # TODO: get actual value, for now starting with reasonable value for # civic and scaling by mass and wheelbase - ret.rotationalInertia = rotationalInertia_civic * \ - ret.mass * ret.wheelbase**2 / (mass_civic * wheelbase_civic**2) + ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) # TODO: start from empirically derived lateral slip stiffness for the civic and scale by # mass and CG position, so all cars will have approximately similar dyn behaviors - ret.tireStiffnessFront = tireStiffnessFront_civic * \ - ret.mass / mass_civic * \ - (centerToRear / ret.wheelbase) / (centerToRear_civic / wheelbase_civic) - ret.tireStiffnessRear = tireStiffnessRear_civic * \ - ret.mass / mass_civic * \ - (ret.centerToFront / ret.wheelbase) / (centerToFront_civic / wheelbase_civic) - + ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, + tire_stiffness_factor=tire_stiffness_factor) # same tuning for Volt and CT6 for now - ret.steerKiBP, ret.steerKpBP = [[0.], [0.]] - ret.steerKpV, ret.steerKiV = [[0.2], [0.00]] - ret.steerKf = 0.00004 # full torque for 20 deg at 80mph means 0.00007818594 + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.00]] + ret.lateralTuning.pid.kf = 0.00004 # full torque for 20 deg at 80mph means 0.00007818594 - ret.steerMaxBP = [0.] # m/s + ret.steerMaxBP = [0.] # m/s ret.steerMaxV = [1.] ret.gasMaxBP = [0.] ret.gasMaxV = [.5] ret.brakeMaxBP = [0.] ret.brakeMaxV = [1.] - ret.longPidDeadzoneBP = [0.] - ret.longPidDeadzoneV = [0.] - ret.longitudinalKpBP = [5., 35.] - ret.longitudinalKpV = [2.4, 1.5] - ret.longitudinalKiBP = [0.] - ret.longitudinalKiV = [0.36] + ret.longitudinalTuning.kpBP = [5., 35.] + ret.longitudinalTuning.kpV = [2.4, 1.5] + ret.longitudinalTuning.kiBP = [0.] + ret.longitudinalTuning.kiV = [0.36] + ret.longitudinalTuning.deadzoneBP = [0.] + ret.longitudinalTuning.deadzoneV = [0.] ret.steerLimitAlert = True @@ -194,14 +170,16 @@ def get_params(candidate, fingerprint): return ret # returns a car.CarState - def update(self, c): + def update(self, c, can_strings): + self.pt_cp.update_strings(can_strings) - self.pt_cp.update(int(sec_since_boot() * 1e9), False) self.CS.update(self.pt_cp) # create message ret = car.CarState.new_message() + ret.canValid = self.pt_cp.can_valid + # speeds ret.vEgo = self.CS.v_ego ret.aEgo = self.CS.a_ego @@ -231,7 +209,7 @@ def update(self, c): # cruise state ret.cruiseState.available = bool(self.CS.main_on) - cruiseEnabled = self.CS.pcm_acc_status != 0 + cruiseEnabled = self.CS.pcm_acc_status != AccState.OFF ret.cruiseState.enabled = cruiseEnabled ret.cruiseState.standstill = self.CS.pcm_acc_status == 4 @@ -246,19 +224,19 @@ def update(self, c): # blinkers if self.CS.left_blinker_on != self.CS.prev_left_blinker_on: be = car.CarState.ButtonEvent.new_message() - be.type = 'leftBlinker' + be.type = ButtonType.leftBlinker be.pressed = self.CS.left_blinker_on buttonEvents.append(be) if self.CS.right_blinker_on != self.CS.prev_right_blinker_on: be = car.CarState.ButtonEvent.new_message() - be.type = 'rightBlinker' + be.type = ButtonType.rightBlinker be.pressed = self.CS.right_blinker_on buttonEvents.append(be) if self.CS.cruise_buttons != self.CS.prev_cruise_buttons: be = car.CarState.ButtonEvent.new_message() - be.type = 'unknown' + be.type = ButtonType.unknown if self.CS.cruise_buttons != CruiseButtons.UNPRESS: be.pressed = True but = self.CS.cruise_buttons @@ -267,24 +245,18 @@ def update(self, c): but = self.CS.prev_cruise_buttons if but == CruiseButtons.RES_ACCEL: if not (cruiseEnabled and self.CS.standstill): - be.type = 'accelCruise' # Suppress resume button if we're resuming from stop so we don't adjust speed. + be.type = ButtonType.accelCruise # Suppress resume button if we're resuming from stop so we don't adjust speed. elif but == CruiseButtons.DECEL_SET: - be.type = 'decelCruise' + be.type = ButtonType.decelCruise elif but == CruiseButtons.CANCEL: - be.type = 'cancel' + be.type = ButtonType.cancel elif but == CruiseButtons.MAIN: - be.type = 'altButton3' + be.type = ButtonType.altButton3 buttonEvents.append(be) ret.buttonEvents = buttonEvents events = [] - if not self.CS.can_valid: - self.can_invalid_count += 1 - if self.can_invalid_count >= 5: - events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) - else: - self.can_invalid_count = 0 if self.CS.steer_error: events.append(create_event('steerUnavailable', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE, ET.PERMANENT])) if self.CS.steer_not_allowed: @@ -323,14 +295,16 @@ def update(self, c): events.append(create_event('pedalPressed', [ET.PRE_ENABLE])) if ret.cruiseState.standstill: events.append(create_event('resumeRequired', [ET.WARNING])) + if self.CS.pcm_acc_status == AccState.FAULTED: + events.append(create_event('controlsFailed', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) # handle button presses for b in ret.buttonEvents: # do enable on both accel and decel buttons - if b.type in ["accelCruise", "decelCruise"] and not b.pressed: + if b.type in [ButtonType.accelCruise, ButtonType.decelCruise] and not b.pressed: events.append(create_event('buttonEnable', [ET.ENABLE])) # do disable on button down - if b.type == "cancel" and b.pressed: + if b.type == ButtonType.cancel and b.pressed: events.append(create_event('buttonCancel', [ET.USER_DISABLE])) ret.events = events @@ -350,16 +324,14 @@ def apply(self, c): if hud_v_cruise > 70: hud_v_cruise = 0 - chime, chime_count = AUDIO_HUD[c.hudControl.audibleAlert.raw] - # For Openpilot, "enabled" includes pre-enable. # In GM, PCM faults out if ACC command overlaps user gas. enabled = c.enabled and not self.CS.user_gas_pressed - self.CC.update(self.sendcan, enabled, self.CS, self.frame, \ - c.actuators, - hud_v_cruise, c.hudControl.lanesVisible, \ - c.hudControl.leadVisible, \ - chime, chime_count) + can_sends = self.CC.update(enabled, self.CS, self.frame, \ + c.actuators, + hud_v_cruise, c.hudControl.lanesVisible, \ + c.hudControl.leadVisible, c.hudControl.visualAlert) self.frame += 1 + return can_sends diff --git a/selfdrive/car/gm/radar_interface.py b/selfdrive/car/gm/radar_interface.py index 6af0d3f8fae843..1fb39c5c439921 100755 --- a/selfdrive/car/gm/radar_interface.py +++ b/selfdrive/car/gm/radar_interface.py @@ -1,15 +1,13 @@ -#!/usr/bin/env python -import zmq +#!/usr/bin/env python3 +from __future__ import print_function import math import time -import numpy as np from cereal import car from selfdrive.can.parser import CANParser from selfdrive.car.gm.interface import CanBus from selfdrive.car.gm.values import DBC, CAR -from common.realtime import sec_since_boot -from selfdrive.services import service_list -import selfdrive.messaging as messaging +from selfdrive.config import Conversions as CV +from selfdrive.car.interfaces import RadarInterfaceBase RADAR_HEADER_MSG = 1120 SLOT_1_MSG = RADAR_HEADER_MSG + 1 @@ -19,13 +17,13 @@ # messages that are present in DBC LAST_RADAR_MSG = RADAR_HEADER_MSG + NUM_SLOTS -def create_radard_can_parser(canbus, car_fingerprint): +def create_radar_can_parser(canbus, car_fingerprint): dbc_f = DBC[car_fingerprint]['radar'] if car_fingerprint in (CAR.VOLT, CAR.MALIBU, CAR.HOLDEN_ASTRA, CAR.ACADIA, CAR.CADILLAC_ATS): # C1A-ARS3-A by Continental - radar_targets = range(SLOT_1_MSG, SLOT_1_MSG + NUM_SLOTS) - signals = zip(['FLRRNumValidTargets', + radar_targets = list(range(SLOT_1_MSG, SLOT_1_MSG + NUM_SLOTS)) + signals = list(zip(['FLRRNumValidTargets', 'FLRRSnsrBlckd', 'FLRRYawRtPlsblityFlt', 'FLRRHWFltPrsntInt', 'FLRRAntTngFltPrsnt', 'FLRRAlgnFltPrsnt', 'FLRRSnstvFltPrsntInt'] + @@ -36,7 +34,7 @@ def create_radard_can_parser(canbus, car_fingerprint): [0] * 7 + [0.0] * NUM_SLOTS + [0.0] * NUM_SLOTS + [0.0] * NUM_SLOTS + [0.0] * NUM_SLOTS + - [0.0] * NUM_SLOTS + [0] * NUM_SLOTS) + [0.0] * NUM_SLOTS + [0] * NUM_SLOTS)) checks = [] @@ -44,41 +42,39 @@ def create_radard_can_parser(canbus, car_fingerprint): else: return None -class RadarInterface(object): +class RadarInterface(RadarInterfaceBase): def __init__(self, CP): # radar self.pts = {} - self.delay = 0.0 # Delay of radar + self.delay = 0 # Delay of radar canbus = CanBus() - print "Using %d as obstacle CAN bus ID" % canbus.obstacle - self.rcp = create_radard_can_parser(canbus, CP.carFingerprint) + print("Using %d as obstacle CAN bus ID" % canbus.obstacle) + self.rcp = create_radar_can_parser(canbus, CP.carFingerprint) - context = zmq.Context() - self.logcan = messaging.sub_sock(context, service_list['can'].port) + self.trigger_msg = LAST_RADAR_MSG + self.updated_messages = set() - def update(self): - updated_messages = set() - ret = car.RadarState.new_message() - while 1: + def update(self, can_strings): + if self.rcp is None: + time.sleep(0.05) # nothing to do + return car.RadarData.new_message() - if self.rcp is None: - time.sleep(0.05) # nothing to do - return ret + vls = self.rcp.update_strings(can_strings) + self.updated_messages.update(vls) - tm = int(sec_since_boot() * 1e9) - updated_messages.update(self.rcp.update(tm, True)) - if LAST_RADAR_MSG in updated_messages: - break + if self.trigger_msg not in self.updated_messages: + return None + ret = car.RadarData.new_message() header = self.rcp.vl[RADAR_HEADER_MSG] fault = header['FLRRSnsrBlckd'] or header['FLRRSnstvFltPrsntInt'] or \ header['FLRRYawRtPlsblityFlt'] or header['FLRRHWFltPrsntInt'] or \ header['FLRRAntTngFltPrsnt'] or header['FLRRAlgnFltPrsnt'] errors = [] if not self.rcp.can_valid: - errors.append("commIssue") + errors.append("canError") if fault: errors.append("fault") ret.errors = errors @@ -88,7 +84,7 @@ def update(self): # Not all radar messages describe targets, # no need to monitor all of the self.rcp.msgs_upd - for ii in updated_messages: + for ii in self.updated_messages: if ii == RADAR_HEADER_MSG: continue @@ -101,27 +97,20 @@ def update(self): targetId = cpt['TrkObjectID'] currentTargets.add(targetId) if targetId not in self.pts: - self.pts[targetId] = car.RadarState.RadarPoint.new_message() + self.pts[targetId] = car.RadarData.RadarPoint.new_message() self.pts[targetId].trackId = targetId distance = cpt['TrkRange'] self.pts[targetId].dRel = distance # from front of car # From driver's pov, left is positive - deg_to_rad = np.pi/180. - self.pts[targetId].yRel = math.sin(deg_to_rad * cpt['TrkAzimuth']) * distance + self.pts[targetId].yRel = math.sin(cpt['TrkAzimuth'] * CV.DEG_TO_RAD) * distance self.pts[targetId].vRel = cpt['TrkRangeRate'] self.pts[targetId].aRel = float('nan') self.pts[targetId].yvRel = float('nan') - for oldTarget in self.pts.keys(): + for oldTarget in list(self.pts.keys()): if not oldTarget in currentTargets: del self.pts[oldTarget] - ret.points = self.pts.values() + ret.points = list(self.pts.values()) + self.updated_messages.clear() return ret - -if __name__ == "__main__": - RI = RadarInterface(None) - while 1: - ret = RI.update() - print(chr(27) + "[2J") - print ret diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index f6aa0658fff354..126ae9e40b0cac 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -1,8 +1,6 @@ from cereal import car from selfdrive.car import dbc_dict -AudibleAlert = car.CarControl.HUDControl.AudibleAlert - class CAR: HOLDEN_ASTRA = "HOLDEN ASTRA RS-V BK 2017" VOLT = "CHEVROLET VOLT PREMIER 2017" @@ -21,24 +19,11 @@ class CruiseButtons: MAIN = 5 CANCEL = 6 -# Car chimes, beeps, blinker sounds etc -class CM: - TOCK = 0x81 - TICK = 0x82 - LOW_BEEP = 0x84 - HIGH_BEEP = 0x85 - LOW_CHIME = 0x86 - HIGH_CHIME = 0x87 - -AUDIO_HUD = { - AudibleAlert.none: (0, 0), - AudibleAlert.chimeEngage: (CM.HIGH_CHIME, 1), - AudibleAlert.chimeDisengage: (CM.HIGH_CHIME, 1), - AudibleAlert.chimeError: (CM.LOW_CHIME, 2), - AudibleAlert.chimePrompt: (CM.LOW_CHIME, 1), - AudibleAlert.chimeWarning1: (CM.LOW_CHIME, 2), - AudibleAlert.chimeWarning2: (CM.LOW_CHIME, -1), - AudibleAlert.chimeWarningRepeat: (CM.LOW_CHIME, -1)} +class AccState: + OFF = 0 + ACTIVE = 1 + FAULTED = 3 + STANDSTILL = 4 def is_eps_status_ok(eps_status, car_fingerprint): valid_eps_status = [] @@ -63,12 +48,12 @@ def parse_gear_shifter(can_gear): FINGERPRINTS = { # Astra BK MY17, ASCM unplugged CAR.HOLDEN_ASTRA: [{ - 190: 8, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 8, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 386: 8, 388: 8, 393: 8, 398: 8, 401: 8, 413: 8, 417: 8, 419: 8, 422: 1, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 8, 455: 7, 456: 8, 458: 5, 479: 8, 481: 7, 485: 8, 489: 8, 497: 8, 499: 3, 500: 8, 501: 8, 508: 8, 528: 5, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 647: 5, 707: 8, 723: 8, 753: 5, 761: 7, 806: 1, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 961: 8, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1009: 8, 1011: 6, 1017: 8, 1019: 3, 1020: 8, 1105: 6, 1217: 8, 1221: 5, 1225: 8, 1233: 8, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 8, 1280: 4, 1300: 8, 1328: 4, 1417: 8, 1906: 7, 1907: 7, 1908: 7, 1912: 7, 1919: 7, + 190: 8, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 8, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 393: 8, 398: 8, 401: 8, 413: 8, 417: 8, 419: 8, 422: 1, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 8, 455: 7, 456: 8, 458: 5, 479: 8, 481: 7, 485: 8, 489: 8, 497: 8, 499: 3, 500: 8, 501: 8, 508: 8, 528: 5, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 647: 5, 707: 8, 715: 8, 723: 8, 753: 5, 761: 7, 806: 1, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 961: 8, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1009: 8, 1011: 6, 1017: 8, 1019: 3, 1020: 8, 1105: 6, 1217: 8, 1221: 5, 1225: 8, 1233: 8, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 8, 1280: 4, 1300: 8, 1328: 4, 1417: 8, 1906: 7, 1907: 7, 1908: 7, 1912: 7, 1919: 7, }], CAR.VOLT: [ # Volt Premier w/ ACC 2017 { - 170: 8, 171: 8, 189: 7, 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 288: 5, 289: 8, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 386: 8, 388: 8, 389: 2, 390: 7, 417: 7, 419: 1, 426: 7, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 528: 4, 532: 6, 546: 7, 550: 8, 554: 3, 558: 8, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 566: 5, 567: 3, 568: 1, 573: 1, 577: 8, 647: 3, 707: 8, 711: 6, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 961: 8, 969: 8, 977: 8, 979: 7, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1017: 8, 1019: 2, 1020: 8, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1273: 3, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1601: 8, 1905: 7, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1922: 7, 1927: 7, 1928: 7, 2016: 8, 2020: 8, 2024: 8, 2028: 8 + 170: 8, 171: 8, 189: 7, 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 288: 5, 289: 8, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 389: 2, 390: 7, 417: 7, 419: 1, 426: 7, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 528: 4, 532: 6, 546: 7, 550: 8, 554: 3, 558: 8, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 566: 5, 567: 3, 568: 1, 573: 1, 577: 8, 647: 3, 707: 8, 711: 6, 715: 8, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 961: 8, 969: 8, 977: 8, 979: 7, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1017: 8, 1019: 2, 1020: 8, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1273: 3, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1601: 8, 1905: 7, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1922: 7, 1927: 7, 1928: 7, 2016: 8, 2020: 8, 2024: 8, 2028: 8 }, # Volt Premier w/ ACC 2018 { @@ -101,14 +86,11 @@ def parse_gear_shifter(can_gear): STEER_THRESHOLD = 1.0 -STOCK_CONTROL_MSGS = { - CAR.HOLDEN_ASTRA: [384, 715], - CAR.VOLT: [384, 715], # 384 = "ASCMLKASteeringCmd", 715 = "ASCMGasRegenCmd" - CAR.MALIBU: [384, 715], # 384 = "ASCMLKASteeringCmd", 715 = "ASCMGasRegenCmd" - CAR.ACADIA: [384, 715], # 384 = "ASCMLKASteeringCmd", 715 = "ASCMGasRegenCmd" - CAR.CADILLAC_ATS: [384, 715], # 384 = "ASCMLKASteeringCmd", 715 = "ASCMGasRegenCmd" - CAR.BUICK_REGAL: [384, 715], # 384 = "ASCMLKASteeringCmd", 715 = "ASCMGasRegenCmd" - CAR.CADILLAC_CT6: [], # CT6 does not require ASCMs to be disconnected +class ECU: + CAM = 0 + +ECU_FINGERPRINT = { + ECU.CAM: [384, 715] # 384 = "ASCMLKASteeringCmd", 715 = "ASCMGasRegenCmd" } DBC = { diff --git a/selfdrive/car/honda/carcontroller.py b/selfdrive/car/honda/carcontroller.py index 08c0235fd436d9..1058e2f21a972c 100644 --- a/selfdrive/car/honda/carcontroller.py +++ b/selfdrive/car/honda/carcontroller.py @@ -1,6 +1,5 @@ from collections import namedtuple -from common.realtime import sec_since_boot -from selfdrive.boardd.boardd import can_list_to_can_capnp +from common.realtime import DT_CTRL from selfdrive.controls.lib.drive_helpers import rate_limit from common.numpy_fast import clip from selfdrive.car import create_gas_command @@ -8,13 +7,14 @@ from selfdrive.car.honda.values import AH, CruiseButtons, CAR from selfdrive.can.packer import CANPacker + def actuator_hystereses(brake, braking, brake_steady, v_ego, car_fingerprint): # hyst params brake_hyst_on = 0.02 # to activate brakes exceed this value brake_hyst_off = 0.005 # to deactivate brakes below this value - brake_hyst_gap = 0.01 # don't change brake command for small ocilalitons within this value + brake_hyst_gap = 0.01 # don't change brake command for small oscillations within this value - #*** histeresis logic to avoid brake blinking. go above 0.1 to trigger + #*** hysteresis logic to avoid brake blinking. go above 0.1 to trigger if (brake < brake_hyst_on and not braking) or brake < brake_hyst_off: brake = 0. braking = brake > 0. @@ -34,15 +34,14 @@ def actuator_hystereses(brake, braking, brake_steady, v_ego, car_fingerprint): return brake, braking, brake_steady -def brake_pump_hysteresys(apply_brake, apply_brake_last, last_pump_ts): - ts = sec_since_boot() +def brake_pump_hysteresis(apply_brake, apply_brake_last, last_pump_ts, ts): pump_on = False # reset pump timer if: # - there is an increment in brake request # - we are applying steady state brakes and we haven't been running the pump # for more than 20s (to prevent pressure bleeding) - if apply_brake > apply_brake_last or (ts - last_pump_ts > 20 and apply_brake > 0): + if apply_brake > apply_brake_last or (ts - last_pump_ts > 20. and apply_brake > 0): last_pump_ts = ts # once the pump is on, run it for at least 0.2s @@ -71,29 +70,22 @@ def process_hud_alert(hud_alert): HUDData = namedtuple("HUDData", ["pcm_accel", "v_cruise", "mini_car", "car", "X4", - "lanes", "beep", "chime", "fcw", "acc_alert", "steer_required"]) + "lanes", "fcw", "acc_alert", "steer_required"]) -class CarController(object): - def __init__(self, dbc_name, enable_camera=True): +class CarController(): + def __init__(self, dbc_name): self.braking = False self.brake_steady = 0. self.brake_last = 0. self.apply_brake_last = 0 - self.last_pump_ts = 0 - self.enable_camera = enable_camera + self.last_pump_ts = 0. self.packer = CANPacker(dbc_name) self.new_radar_config = False - def update(self, sendcan, enabled, CS, frame, actuators, \ + def update(self, enabled, CS, frame, actuators, \ pcm_speed, pcm_override, pcm_cancel_cmd, pcm_accel, \ - hud_v_cruise, hud_show_lanes, hud_show_car, \ - hud_alert, snd_beep, snd_chime): - - """ Controls thread """ - - if not self.enable_camera: - return + hud_v_cruise, hud_show_lanes, hud_show_car, hud_alert): # *** apply brake hysteresis *** brake, self.braking, self.brake_steady = actuator_hystereses(actuators.brake, self.braking, self.brake_steady, CS.v_ego, CS.CP.carFingerprint) @@ -120,24 +112,21 @@ def update(self, sendcan, enabled, CS, frame, actuators, \ else: hud_car = 0 - # For lateral control-only, send chimes as a beep since we don't send 0x1fa - if CS.CP.radarOffCan: - snd_beep = snd_beep if snd_beep != 0 else snd_chime - - #print chime, alert_id, hud_alert fcw_display, steer_required, acc_alert = process_hud_alert(hud_alert) hud = HUDData(int(pcm_accel), int(round(hud_v_cruise)), 1, hud_car, - 0xc1, hud_lanes, int(snd_beep), snd_chime, fcw_display, acc_alert, steer_required) + 0xc1, hud_lanes, fcw_display, acc_alert, steer_required) # **** process the car messages **** # *** compute control surfaces *** - BRAKE_MAX = 1024/4 + BRAKE_MAX = 1024//4 if CS.CP.carFingerprint in (CAR.ACURA_ILX): STEER_MAX = 0xF00 elif CS.CP.carFingerprint in (CAR.CRV, CAR.ACURA_RDX): STEER_MAX = 0x3e8 # CR-V only uses 12-bits and requires a lower value (max value from energee) + elif CS.CP.carFingerprint in (CAR.ODYSSEY_CHN): + STEER_MAX = 0x7FFF else: STEER_MAX = 0x1000 @@ -154,27 +143,28 @@ def update(self, sendcan, enabled, CS, frame, actuators, \ # Send steering command. idx = frame % 4 can_sends.append(hondacan.create_steering_control(self.packer, apply_steer, - lkas_active, CS.CP.carFingerprint, idx)) + lkas_active, CS.CP.carFingerprint, idx, CS.CP.isPandaBlack)) # Send dashboard UI commands. if (frame % 10) == 0: - idx = (frame/10) % 4 - can_sends.extend(hondacan.create_ui_commands(self.packer, pcm_speed, hud, CS.CP.carFingerprint, idx)) + idx = (frame//10) % 4 + can_sends.extend(hondacan.create_ui_commands(self.packer, pcm_speed, hud, CS.CP.carFingerprint, CS.is_metric, idx, CS.CP.isPandaBlack)) if CS.CP.radarOffCan: # If using stock ACC, spam cancel command to kill gas when OP disengages. if pcm_cancel_cmd: - can_sends.append(hondacan.spam_buttons_command(self.packer, CruiseButtons.CANCEL, idx)) + can_sends.append(hondacan.spam_buttons_command(self.packer, CruiseButtons.CANCEL, idx, CS.CP.carFingerprint, CS.CP.isPandaBlack)) elif CS.stopped: - can_sends.append(hondacan.spam_buttons_command(self.packer, CruiseButtons.RES_ACCEL, idx)) + can_sends.append(hondacan.spam_buttons_command(self.packer, CruiseButtons.RES_ACCEL, idx, CS.CP.carFingerprint, CS.CP.isPandaBlack)) else: # Send gas and brake commands. if (frame % 2) == 0: - idx = frame / 2 - pump_on, self.last_pump_ts = brake_pump_hysteresys(apply_brake, self.apply_brake_last, self.last_pump_ts) + idx = frame // 2 + ts = frame * DT_CTRL + pump_on, self.last_pump_ts = brake_pump_hysteresis(apply_brake, self.apply_brake_last, self.last_pump_ts, ts) can_sends.append(hondacan.create_brake_command(self.packer, apply_brake, pump_on, - pcm_override, pcm_cancel_cmd, hud.chime, hud.fcw, idx)) + pcm_override, pcm_cancel_cmd, hud.fcw, idx, CS.CP.carFingerprint, CS.CP.isPandaBlack)) self.apply_brake_last = apply_brake if CS.CP.enableGasInterceptor: @@ -182,4 +172,4 @@ def update(self, sendcan, enabled, CS, frame, actuators, \ # This prevents unexpected pedal range rescaling can_sends.append(create_gas_command(self.packer, apply_gas, idx)) - sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan').to_bytes()) + return can_sends diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index f4c7cade8c0b99..792542167ba359 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -1,13 +1,18 @@ +from cereal import car +from collections import defaultdict from common.numpy_fast import interp from common.kalman.simple_kalman import KF1D -from selfdrive.can.parser import CANParser, CANDefine +from selfdrive.can.can_define import CANDefine +from selfdrive.can.parser import CANParser from selfdrive.config import Conversions as CV from selfdrive.car.honda.values import CAR, DBC, STEER_THRESHOLD, SPEED_FACTOR, HONDA_BOSCH +GearShifter = car.CarState.GearShifter + def parse_gear_shifter(gear, vals): - val_to_capnp = {'P': 'park', 'R': 'reverse', 'N': 'neutral', - 'D': 'drive', 'S': 'sport', 'L': 'low'} + val_to_capnp = {'P': GearShifter.park, 'R': GearShifter.reverse, 'N': GearShifter.neutral, + 'D': GearShifter.drive, 'S': GearShifter.sport, 'L': GearShifter.low} try: return val_to_capnp[vals[gear]] except KeyError: @@ -37,6 +42,7 @@ def get_can_signals(CP): ("STEER_ANGLE", "STEERING_SENSORS", 0), ("STEER_ANGLE_RATE", "STEERING_SENSORS", 0), ("STEER_TORQUE_SENSOR", "STEER_STATUS", 0), + ("STEER_TORQUE_MOTOR", "STEER_STATUS", 0), ("LEFT_BLINKER", "SCM_FEEDBACK", 0), ("RIGHT_BLINKER", "SCM_FEEDBACK", 0), ("GEAR", "GEARBOX", 0), @@ -46,7 +52,6 @@ def get_can_signals(CP): ("BRAKE_SWITCH", "POWERTRAIN_DATA", 0), ("CRUISE_BUTTONS", "SCM_BUTTONS", 0), ("ESP_DISABLED", "VSA_STATUS", 1), - ("HUD_LEAD", "ACC_HUD", 0), ("USER_BRAKE", "VSA_STATUS", 0), ("BRAKE_HOLD_ACTIVE", "VSA_STATUS", 0), ("STEER_STATUS", "STEER_STATUS", 5), @@ -60,22 +65,40 @@ def get_can_signals(CP): ("ENGINE_DATA", 100), ("WHEEL_SPEEDS", 50), ("STEERING_SENSORS", 100), - ("SCM_FEEDBACK", 10), - ("GEARBOX", 100), ("SEATBELT_STATUS", 10), ("CRUISE", 10), ("POWERTRAIN_DATA", 100), ("VSA_STATUS", 50), - ("SCM_BUTTONS", 25), ] + if CP.carFingerprint == CAR.ODYSSEY_CHN: + checks += [ + ("SCM_FEEDBACK", 25), + ("SCM_BUTTONS", 50), + ] + else: + checks += [ + ("SCM_FEEDBACK", 10), + ("SCM_BUTTONS", 25), + ] + + if CP.carFingerprint == CAR.CRV_HYBRID: + checks += [ + ("GEARBOX", 50), + ] + else: + checks += [ + ("GEARBOX", 100), + ] + if CP.radarOffCan: # Civic is only bosch to use the same brake message as other hondas. - if CP.carFingerprint not in (CAR.ACCORDH, CAR.CIVIC_BOSCH): + if CP.carFingerprint not in (CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CRV_HYBRID): signals += [("BRAKE_PRESSED", "BRAKE_MODULE", 0)] checks += [("BRAKE_MODULE", 50)] signals += [("CAR_GAS", "GAS_PEDAL_2", 0), ("MAIN_ON", "SCM_FEEDBACK", 0), + ("CRUISE_CONTROL_LABEL", "ACC_HUD", 0), ("EPB_STATE", "EPB_STATUS", 0), ("CRUISE_SPEED", "ACC_HUD", 0)] checks += [("GAS_PEDAL_2", 100)] @@ -85,11 +108,17 @@ def get_can_signals(CP): ("BRAKE_ERROR_2", "STANDSTILL", 1), ("CRUISE_SPEED_PCM", "CRUISE", 0), ("CRUISE_SPEED_OFFSET", "CRUISE_PARAMS", 0)] - checks += [("CRUISE_PARAMS", 50), - ("STANDSTILL", 50)] + checks += [("STANDSTILL", 50)] + + if CP.carFingerprint == CAR.ODYSSEY_CHN: + checks += [("CRUISE_PARAMS", 10)] + else: + checks += [("CRUISE_PARAMS", 50)] - if CP.carFingerprint in (CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH): + if CP.carFingerprint in (CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CRV_HYBRID): signals += [("DRIVERS_DOOR_OPEN", "SCM_FEEDBACK", 1)] + elif CP.carFingerprint == CAR.ODYSSEY_CHN: + signals += [("DRIVERS_DOOR_OPEN", "SCM_BUTTONS", 1)] else: signals += [("DOOR_OPEN_FL", "DOORS_STATUS", 1), ("DOOR_OPEN_FR", "DOORS_STATUS", 1), @@ -101,12 +130,17 @@ def get_can_signals(CP): if CP.carFingerprint == CAR.CIVIC: signals += [("CAR_GAS", "GAS_PEDAL_2", 0), ("MAIN_ON", "SCM_FEEDBACK", 0), + ("IMPERIAL_UNIT", "HUD_SETTING", 0), ("EPB_STATE", "EPB_STATUS", 0)] elif CP.carFingerprint == CAR.ACURA_ILX: signals += [("CAR_GAS", "GAS_PEDAL_2", 0), ("MAIN_ON", "SCM_BUTTONS", 0)] elif CP.carFingerprint in (CAR.CRV, CAR.ACURA_RDX, CAR.PILOT_2019, CAR.RIDGELINE): signals += [("MAIN_ON", "SCM_BUTTONS", 0)] + elif CP.carFingerprint == CAR.FIT: + signals += [("CAR_GAS", "GAS_PEDAL_2", 0), + ("MAIN_ON", "SCM_BUTTONS", 0), + ("BRAKE_HOLD_ACTIVE", "VSA_STATUS", 0)] elif CP.carFingerprint == CAR.ODYSSEY: signals += [("MAIN_ON", "SCM_FEEDBACK", 0), ("EPB_STATE", "EPB_STATUS", 0)] @@ -114,10 +148,15 @@ def get_can_signals(CP): elif CP.carFingerprint == CAR.PILOT: signals += [("MAIN_ON", "SCM_BUTTONS", 0), ("CAR_GAS", "GAS_PEDAL_2", 0)] + elif CP.carFingerprint == CAR.ODYSSEY_CHN: + signals += [("MAIN_ON", "SCM_BUTTONS", 0), + ("EPB_STATE", "EPB_STATUS", 0)] + checks += [("EPB_STATUS", 50)] # add gas interceptor reading if we are using it if CP.enableGasInterceptor: signals.append(("INTERCEPTOR_GAS", "GAS_SENSOR", 0)) + signals.append(("INTERCEPTOR_GAS2", "GAS_SENSOR", 0)) checks.append(("GAS_SENSOR", 50)) return signals, checks @@ -125,25 +164,27 @@ def get_can_signals(CP): def get_can_parser(CP): signals, checks = get_can_signals(CP) - return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) + bus_pt = 1 if CP.isPandaBlack and CP.carFingerprint in HONDA_BOSCH else 0 + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, bus_pt) + def get_cam_can_parser(CP): signals = [] - # all hondas except CRV and RDX use 0xe4 for steering + # all hondas except CRV, RDX and 2019 Odyssey@China use 0xe4 for steering checks = [(0xe4, 100)] - if CP.carFingerprint in [CAR.CRV, CAR.ACURA_RDX]: + if CP.carFingerprint in [CAR.CRV, CAR.ACURA_RDX, CAR.ODYSSEY_CHN]: checks = [(0x194, 100)] - cam_bus = 1 if CP.carFingerprint in HONDA_BOSCH else 2 - - return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, cam_bus) + bus_cam = 1 if CP.carFingerprint in HONDA_BOSCH and not CP.isPandaBlack else 2 + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, bus_cam) -class CarState(object): +class CarState(): def __init__(self, CP): self.CP = CP self.can_define = CANDefine(DBC[CP.carFingerprint]['pt']) self.shifter_values = self.can_define.dv["GEARBOX"]["GEAR_SHIFTER"] + self.steer_status_values = defaultdict(lambda: "UNKNOWN", self.can_define.dv["STEER_STATUS"]["STEER_STATUS"]) self.user_gas, self.user_gas_pressed = 0., 0 self.brake_switch_prev = 0 @@ -157,6 +198,7 @@ def __init__(self, CP): self.left_blinker_on = 0 self.right_blinker_on = 0 + self.cruise_mode = 0 self.stopped = 0 # vEgo kalman filter @@ -165,16 +207,12 @@ def __init__(self, CP): # R = 1e3 self.v_ego_kf = KF1D(x0=[[0.0], [0.0]], A=[[1.0, dt], [0.0, 1.0]], - C=[[1.0, 0.0]], + C=[1.0, 0.0], K=[[0.12287673], [0.29666309]]) self.v_ego = 0.0 def update(self, cp, cp_cam): - # copy can_valid on buses 0 and 2 - self.can_valid = cp.can_valid - self.cam_can_valid = cp_cam.can_valid - # car params v_weight_v = [0., 1.] # don't trust smooth speed at low values to avoid premature zero snapping v_weight_bp = [1., 6.] # smooth blending, below ~0.6m/s the smooth speed snaps to zero @@ -188,21 +226,25 @@ def update(self, cp, cp_cam): self.prev_right_blinker_on = self.right_blinker_on # ******************* parse out can ******************* - - if self.CP.carFingerprint in (CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH): # TODO: find wheels moving bit in dbc + if self.CP.carFingerprint in (CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CRV_HYBRID): # TODO: find wheels moving bit in dbc self.standstill = cp.vl["ENGINE_DATA"]['XMISSION_SPEED'] < 0.1 self.door_all_closed = not cp.vl["SCM_FEEDBACK"]['DRIVERS_DOOR_OPEN'] + elif self.CP.carFingerprint == CAR.ODYSSEY_CHN: + self.standstill = cp.vl["ENGINE_DATA"]['XMISSION_SPEED'] < 0.1 + self.door_all_closed = not cp.vl["SCM_BUTTONS"]['DRIVERS_DOOR_OPEN'] else: self.standstill = not cp.vl["STANDSTILL"]['WHEELS_MOVING'] self.door_all_closed = not any([cp.vl["DOORS_STATUS"]['DOOR_OPEN_FL'], cp.vl["DOORS_STATUS"]['DOOR_OPEN_FR'], cp.vl["DOORS_STATUS"]['DOOR_OPEN_RL'], cp.vl["DOORS_STATUS"]['DOOR_OPEN_RR']]) self.seatbelt = not cp.vl["SEATBELT_STATUS"]['SEATBELT_DRIVER_LAMP'] and cp.vl["SEATBELT_STATUS"]['SEATBELT_DRIVER_LATCHED'] - # 2 = temporary; 3 = TBD; 4 = temporary, hit a bump; 5 = (permanent); 6 = temporary; 7 = (permanent) - # TODO: Use values from DBC to parse this field - self.steer_error = cp.vl["STEER_STATUS"]['STEER_STATUS'] not in [0, 2, 3, 4, 6] - self.steer_not_allowed = cp.vl["STEER_STATUS"]['STEER_STATUS'] != 0 - self.steer_warning = cp.vl["STEER_STATUS"]['STEER_STATUS'] not in [0, 3] # 3 is low speed lockout, not worth a warning + steer_status = self.steer_status_values[cp.vl["STEER_STATUS"]['STEER_STATUS']] + self.steer_error = steer_status not in ['NORMAL', 'NO_TORQUE_ALERT_1', 'NO_TORQUE_ALERT_2', 'LOW_SPEED_LOCKOUT', 'TMP_FAULT'] + # NO_TORQUE_ALERT_2 can be caused by bump OR steering nudge from driver + self.steer_not_allowed = steer_status not in ['NORMAL', 'NO_TORQUE_ALERT_2'] + # LOW_SPEED_LOCKOUT is not worth a warning + self.steer_warning = steer_status not in ['NORMAL', 'LOW_SPEED_LOCKOUT', 'NO_TORQUE_ALERT_2'] + if self.CP.radarOffCan: self.brake_error = 0 else: @@ -233,7 +275,7 @@ def update(self, cp, cp_cam): # this is a hack for the interceptor. This is now only used in the simulation # TODO: Replace tests by toyota so this can go away if self.CP.enableGasInterceptor: - self.user_gas = cp.vl["GAS_SENSOR"]['INTERCEPTOR_GAS'] + self.user_gas = (cp.vl["GAS_SENSOR"]['INTERCEPTOR_GAS'] + cp.vl["GAS_SENSOR"]['INTERCEPTOR_GAS2']) / 2. self.user_gas_pressed = self.user_gas > 0 # this works because interceptor read < 0 when pedal position is 0. Once calibrated, this will change self.gear = 0 if self.CP.carFingerprint == CAR.CIVIC else cp.vl["GEARBOX"]['GEAR'] @@ -248,9 +290,12 @@ def update(self, cp, cp_cam): self.right_blinker_on = cp.vl["SCM_FEEDBACK"]['RIGHT_BLINKER'] self.brake_hold = cp.vl["VSA_STATUS"]['BRAKE_HOLD_ACTIVE'] - if self.CP.carFingerprint in (CAR.CIVIC, CAR.ODYSSEY, CAR.CRV_5G, CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH): + if self.CP.carFingerprint in (CAR.CIVIC, CAR.ODYSSEY, CAR.CRV_5G, CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CRV_HYBRID): self.park_brake = cp.vl["EPB_STATUS"]['EPB_STATE'] != 0 self.main_on = cp.vl["SCM_FEEDBACK"]['MAIN_ON'] + elif self.CP.carFingerprint == CAR.ODYSSEY_CHN: + self.park_brake = cp.vl["EPB_STATUS"]['EPB_STATE'] != 0 + self.main_on = cp.vl["SCM_BUTTONS"]['MAIN_ON'] else: self.park_brake = 0 # TODO self.main_on = cp.vl["SCM_BUTTONS"]['MAIN_ON'] @@ -260,20 +305,22 @@ def update(self, cp, cp_cam): self.pedal_gas = cp.vl["POWERTRAIN_DATA"]['PEDAL_GAS'] # crv doesn't include cruise control - if self.CP.carFingerprint in (CAR.CRV, CAR.ODYSSEY, CAR.ACURA_RDX, CAR.RIDGELINE, CAR.PILOT_2019): + if self.CP.carFingerprint in (CAR.CRV, CAR.ODYSSEY, CAR.ACURA_RDX, CAR.RIDGELINE, CAR.PILOT_2019, CAR.ODYSSEY_CHN): self.car_gas = self.pedal_gas else: self.car_gas = cp.vl["GAS_PEDAL_2"]['CAR_GAS'] self.steer_torque_driver = cp.vl["STEER_STATUS"]['STEER_TORQUE_SENSOR'] + self.steer_torque_motor = cp.vl["STEER_STATUS"]['STEER_TORQUE_MOTOR'] self.steer_override = abs(self.steer_torque_driver) > STEER_THRESHOLD[self.CP.carFingerprint] self.brake_switch = cp.vl["POWERTRAIN_DATA"]['BRAKE_SWITCH'] if self.CP.radarOffCan: + self.cruise_mode = cp.vl["ACC_HUD"]['CRUISE_CONTROL_LABEL'] self.stopped = cp.vl["ACC_HUD"]['CRUISE_SPEED'] == 252. self.cruise_speed_offset = calc_cruise_offset(0, self.v_ego) - if self.CP.carFingerprint in (CAR.CIVIC_BOSCH, CAR.ACCORDH): + if self.CP.carFingerprint in (CAR.CIVIC_BOSCH, CAR.ACCORDH, CAR.CRV_HYBRID): self.brake_switch = cp.vl["POWERTRAIN_DATA"]['BRAKE_SWITCH'] self.brake_pressed = cp.vl["POWERTRAIN_DATA"]['BRAKE_PRESSED'] or \ (self.brake_switch and self.brake_switch_prev and \ @@ -299,26 +346,11 @@ def update(self, cp, cp_cam): self.user_brake = cp.vl["VSA_STATUS"]['USER_BRAKE'] self.pcm_acc_status = cp.vl["POWERTRAIN_DATA"]['ACC_STATUS'] - self.hud_lead = cp.vl["ACC_HUD"]['HUD_LEAD'] # Gets rid of Pedal Grinding noise when brake is pressed at slow speeds for some models - # TODO: this should be ok for all cars. Verify it. if self.CP.carFingerprint in (CAR.PILOT, CAR.PILOT_2019, CAR.RIDGELINE): if self.user_brake > 0.05: self.brake_pressed = 1 -# carstate standalone tester -if __name__ == '__main__': - import zmq - context = zmq.Context() - - class CarParams(object): - def __init__(self): - self.carFingerprint = "HONDA CIVIC 2016 TOURING" - self.enableGasInterceptor = 0 - CP = CarParams() - CS = CarState(CP) - - # while 1: - # CS.update() - # time.sleep(0.01) + # TODO: discover the CAN msg that has the imperial unit bit for all other cars + self.is_metric = not cp.vl["HUD_SETTING"]['IMPERIAL_UNIT'] if self.CP.carFingerprint in (CAR.CIVIC) else False diff --git a/selfdrive/car/honda/hondacan.py b/selfdrive/car/honda/hondacan.py index 435360d65f8d95..c6b9a12e8362c7 100644 --- a/selfdrive/car/honda/hondacan.py +++ b/selfdrive/car/honda/hondacan.py @@ -6,7 +6,6 @@ def can_cksum(mm): s = 0 for c in mm: - c = ord(c) s += (c>>4) s += c & 0xF s = 8-s @@ -15,11 +14,19 @@ def can_cksum(mm): def fix(msg, addr): - msg2 = msg[0:-1] + chr(ord(msg[-1]) | can_cksum(struct.pack("I", addr)+msg)) + msg2 = msg[0:-1] + (msg[-1] | can_cksum(struct.pack("I", addr)+msg)).to_bytes(1, 'little') return msg2 -def create_brake_command(packer, apply_brake, pump_on, pcm_override, pcm_cancel_cmd, chime, fcw, idx): +def get_pt_bus(car_fingerprint, has_relay): + return 1 if car_fingerprint in HONDA_BOSCH and has_relay else 0 + + +def get_lkas_cmd_bus(car_fingerprint, has_relay): + return 2 if car_fingerprint in HONDA_BOSCH and not has_relay else 0 + + +def create_brake_command(packer, apply_brake, pump_on, pcm_override, pcm_cancel_cmd, fcw, idx, car_fingerprint, has_relay): # TODO: do we loose pressure if we keep pump off for long? brakelights = apply_brake > 0 brake_rq = apply_brake > 0 @@ -32,69 +39,71 @@ def create_brake_command(packer, apply_brake, pump_on, pcm_override, pcm_cancel_ "CRUISE_FAULT_CMD": pcm_fault_cmd, "CRUISE_CANCEL_CMD": pcm_cancel_cmd, "COMPUTER_BRAKE_REQUEST": brake_rq, - "SET_ME_0X80": 0x80, + "SET_ME_1": 1, "BRAKE_LIGHTS": brakelights, - "CHIME": chime, + "CHIME": 0, # TODO: Why are there two bits for fcw? According to dbc file the first bit should also work "FCW": fcw << 1, + "AEB_REQ_1": 0, + "AEB_REQ_2": 0, + "AEB_STATUS": 0, } - return packer.make_can_msg("BRAKE_COMMAND", 0, values, idx) + bus = get_pt_bus(car_fingerprint, has_relay) + return packer.make_can_msg("BRAKE_COMMAND", bus, values, idx) -def create_steering_control(packer, apply_steer, lkas_active, car_fingerprint, idx): +def create_steering_control(packer, apply_steer, lkas_active, car_fingerprint, idx, has_relay): values = { "STEER_TORQUE": apply_steer if lkas_active else 0, "STEER_TORQUE_REQUEST": lkas_active, } - # Set bus 2 for accord and new crv. - bus = 2 if car_fingerprint in HONDA_BOSCH else 0 + bus = get_lkas_cmd_bus(car_fingerprint, has_relay) return packer.make_can_msg("STEERING_CONTROL", bus, values, idx) -def create_ui_commands(packer, pcm_speed, hud, car_fingerprint, idx): +def create_ui_commands(packer, pcm_speed, hud, car_fingerprint, is_metric, idx, has_relay): commands = [] - bus = 0 + bus_pt = get_pt_bus(car_fingerprint, has_relay) + bus_lkas = get_lkas_cmd_bus(car_fingerprint, has_relay) - # Bosch sends commands to bus 2. - if car_fingerprint in HONDA_BOSCH: - bus = 2 - else: + if car_fingerprint not in HONDA_BOSCH: acc_hud_values = { 'PCM_SPEED': pcm_speed * CV.MS_TO_KPH, 'PCM_GAS': hud.pcm_accel, 'CRUISE_SPEED': hud.v_cruise, 'ENABLE_MINI_CAR': hud.mini_car, 'HUD_LEAD': hud.car, - 'SET_ME_X03': 0x03, - 'SET_ME_X03_2': 0x03, - 'SET_ME_X01': 0x01, + 'HUD_DISTANCE': 3, # max distance setting on display + 'IMPERIAL_UNIT': int(not is_metric), + 'SET_ME_X01_2': 1, + 'SET_ME_X01': 1, } - commands.append(packer.make_can_msg("ACC_HUD", 0, acc_hud_values, idx)) + commands.append(packer.make_can_msg("ACC_HUD", bus_pt, acc_hud_values, idx)) lkas_hud_values = { 'SET_ME_X41': 0x41, 'SET_ME_X48': 0x48, 'STEERING_REQUIRED': hud.steer_required, 'SOLID_LANES': hud.lanes, - 'BEEP': hud.beep, + 'BEEP': 0, } - commands.append(packer.make_can_msg('LKAS_HUD', bus, lkas_hud_values, idx)) + commands.append(packer.make_can_msg('LKAS_HUD', bus_lkas, lkas_hud_values, idx)) if car_fingerprint in (CAR.CIVIC, CAR.ODYSSEY): - radar_hud_values = { 'ACC_ALERTS': hud.acc_alert, 'LEAD_SPEED': 0x1fe, # What are these magic values 'LEAD_STATE': 0x7, 'LEAD_DISTANCE': 0x1e, } - commands.append(packer.make_can_msg('RADAR_HUD', 0, radar_hud_values, idx)) + commands.append(packer.make_can_msg('RADAR_HUD', bus_pt, radar_hud_values, idx)) return commands -def spam_buttons_command(packer, button_val, idx): +def spam_buttons_command(packer, button_val, idx, car_fingerprint, has_relay): values = { 'CRUISE_BUTTONS': button_val, 'CRUISE_SETTING': 0, } - return packer.make_can_msg("SCM_BUTTONS", 0, values, idx) + bus = get_pt_bus(car_fingerprint, has_relay) + return packer.make_can_msg("SCM_BUTTONS", bus, values, idx) diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index 3acd2c7415345d..3c2ecfa8ddd4f8 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -1,29 +1,22 @@ -#!/usr/bin/env python -import os +#!/usr/bin/env python3 import numpy as np from cereal import car from common.numpy_fast import clip, interp -from common.realtime import sec_since_boot +from common.realtime import DT_CTRL from selfdrive.swaglog import cloudlog from selfdrive.config import Conversions as CV from selfdrive.controls.lib.drive_helpers import create_event, EventTypes as ET, get_events from selfdrive.controls.lib.vehicle_model import VehicleModel from selfdrive.car.honda.carstate import CarState, get_can_parser, get_cam_can_parser -from selfdrive.car.honda.values import CruiseButtons, CAR, HONDA_BOSCH, AUDIO_HUD, VISUAL_HUD -from selfdrive.controls.lib.planner import _A_CRUISE_MAX_V_FOLLOWING +from selfdrive.car.honda.values import CruiseButtons, CAR, HONDA_BOSCH, VISUAL_HUD, ECU, ECU_FINGERPRINT, FINGERPRINTS +from selfdrive.car import STD_CARGO_KG, CivicParams, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint +from selfdrive.controls.lib.planner import _A_CRUISE_MAX_V +from selfdrive.car.interfaces import CarInterfaceBase -try: - from selfdrive.car.honda.carcontroller import CarController -except ImportError: - CarController = None - - -# msgs sent for steering controller by camera module on can 0. -# those messages are mutually exclusive on CRV and non-CRV cars -CAMERA_MSGS = [0xe4, 0x194] - -A_ACC_MAX = max(_A_CRUISE_MAX_V_FOLLOWING) +A_ACC_MAX = max(_A_CRUISE_MAX_V) +ButtonType = car.CarState.ButtonEvent.Type +GearShifter = car.CarState.GearShifter def compute_gb_honda(accel, speed): creep_brake = 0.0 @@ -79,8 +72,8 @@ def _compute_gb_acura(accel, speed): return _compute_gb_acura -class CarInterface(object): - def __init__(self, CP, sendcan=None): +class CarInterface(CarInterfaceBase): + def __init__(self, CP, CarController): self.CP = CP self.frame = 0 @@ -88,8 +81,6 @@ def __init__(self, CP, sendcan=None): self.last_enable_sent = 0 self.gas_pressed_prev = False self.brake_pressed_prev = False - self.can_invalid_count = 0 - self.cam_can_invalid_count = 0 self.cp = get_can_parser(CP) self.cp_cam = get_cam_can_parser(CP) @@ -98,10 +89,9 @@ def __init__(self, CP, sendcan=None): self.CS = CarState(CP) self.VM = VehicleModel(CP) - # sending if read only is False - if sendcan is not None: - self.sendcan = sendcan - self.CC = CarController(self.cp.dbc_name, CP.enableCamera) + self.CC = None + if CarController is not None: + self.CC = CarController(self.cp.dbc_name) if self.CS.CP.carFingerprint == CAR.ACURA_ILX: self.compute_gb = get_compute_gb_acura() @@ -141,41 +131,31 @@ def calc_accel_override(a_ego, a_target, v_ego, v_target): return float(max(max_accel, a_target / A_ACC_MAX)) * min(speedLimiter, accelLimiter) @staticmethod - def get_params(candidate, fingerprint): + def get_params(candidate, fingerprint=gen_empty_fingerprint(), vin="", has_relay=False): ret = car.CarParams.new_message() ret.carName = "honda" ret.carFingerprint = candidate + ret.carVin = vin + ret.isPandaBlack = has_relay if candidate in HONDA_BOSCH: - ret.safetyModel = car.CarParams.SafetyModels.hondaBosch - ret.enableCamera = True + ret.safetyModel = car.CarParams.SafetyModel.hondaBosch + rdr_bus = 0 if has_relay else 2 + ret.enableCamera = is_ecu_disconnected(fingerprint[rdr_bus], FINGERPRINTS, ECU_FINGERPRINT, candidate, ECU.CAM) or has_relay ret.radarOffCan = True ret.openpilotLongitudinalControl = False else: - ret.safetyModel = car.CarParams.SafetyModels.honda - ret.enableCamera = not any(x for x in CAMERA_MSGS if x in fingerprint) - ret.enableGasInterceptor = 0x201 in fingerprint + ret.safetyModel = car.CarParams.SafetyModel.honda + ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, ECU.CAM) or has_relay + ret.enableGasInterceptor = 0x201 in fingerprint[0] ret.openpilotLongitudinalControl = ret.enableCamera - cloudlog.warn("ECU Camera Simulated: %r", ret.enableCamera) - cloudlog.warn("ECU Gas Interceptor: %r", ret.enableGasInterceptor) + cloudlog.warning("ECU Camera Simulated: %r", ret.enableCamera) + cloudlog.warning("ECU Gas Interceptor: %r", ret.enableGasInterceptor) ret.enableCruise = not ret.enableGasInterceptor - # kg of standard extra cargo to count for drive, gas, etc... - std_cargo = 136 - - # FIXME: hardcoding honda civic 2016 touring params so they can be used to - # scale unknown params for other cars - mass_civic = 2923 * CV.LB_TO_KG + std_cargo - wheelbase_civic = 2.70 - centerToFront_civic = wheelbase_civic * 0.4 - centerToRear_civic = wheelbase_civic - centerToFront_civic - rotationalInertia_civic = 2500 - tireStiffnessFront_civic = 192150 - tireStiffnessRear_civic = 202500 - # Optimized car params: tire_stiffness_factor and steerRatio are a result of a vehicle # model optimization process. Certain Hondas have an extra steering sensor at the bottom # of the steering rack, which improves controls quality as it removes the steering column @@ -183,134 +163,169 @@ def get_params(candidate, fingerprint): # Tire stiffness factor fictitiously lower if it includes the steering column torsion effect. # For modeling details, see p.198-200 in "The Science of Vehicle Dynamics (2014), M. Guiggiani" - ret.steerKiBP, ret.steerKpBP = [[0.], [0.]] - - ret.steerKf = 0.00006 # conservative feed-forward + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] + ret.lateralTuning.pid.kf = 0.00006 # conservative feed-forward if candidate in [CAR.CIVIC, CAR.CIVIC_BOSCH]: stop_and_go = True - ret.mass = mass_civic - ret.wheelbase = wheelbase_civic - ret.centerToFront = centerToFront_civic - ret.steerRatio = 14.63 # 10.93 is end-to-end spec + ret.mass = CivicParams.MASS + ret.wheelbase = CivicParams.WHEELBASE + ret.centerToFront = CivicParams.CENTER_TO_FRONT + ret.steerRatio = 15.38 # 10.93 is end-to-end spec tire_stiffness_factor = 1. - # Civic at comma has modified steering FW, so different tuning for the Neo in that car - is_fw_modified = os.getenv("DONGLE_ID") in ['99c94dc769b5d96e'] - ret.steerKpV, ret.steerKiV = [[0.4], [0.12]] if is_fw_modified else [[0.8], [0.24]] - if is_fw_modified: - tire_stiffness_factor = 0.9 - ret.steerKf = 0.00004 - ret.longitudinalKpBP = [0., 5., 35.] - ret.longitudinalKpV = [3.6, 2.4, 1.5] - ret.longitudinalKiBP = [0., 35.] - ret.longitudinalKiV = [0.54, 0.36] + + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kpV = [3.6, 2.4, 1.5] + ret.longitudinalTuning.kiBP = [0., 35.] + ret.longitudinalTuning.kiV = [0.54, 0.36] elif candidate in (CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH): stop_and_go = True if not candidate == CAR.ACCORDH: # Hybrid uses same brake msg as hatch ret.safetyParam = 1 # Accord and CRV 5G use an alternate user brake msg - ret.mass = 3279. * CV.LB_TO_KG + std_cargo + ret.mass = 3279. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.83 ret.centerToFront = ret.wheelbase * 0.39 - ret.steerRatio = 15.96 # 11.82 is spec end-to-end + ret.steerRatio = 16.33 # 11.82 is spec end-to-end tire_stiffness_factor = 0.8467 - ret.steerKpV, ret.steerKiV = [[0.6], [0.18]] - ret.longitudinalKpBP = [0., 5., 35.] - ret.longitudinalKpV = [1.2, 0.8, 0.5] - ret.longitudinalKiBP = [0., 35.] - ret.longitudinalKiV = [0.18, 0.12] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.18]] + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kpV = [1.2, 0.8, 0.5] + ret.longitudinalTuning.kiBP = [0., 35.] + ret.longitudinalTuning.kiV = [0.18, 0.12] elif candidate == CAR.ACURA_ILX: stop_and_go = False - ret.mass = 3095 * CV.LB_TO_KG + std_cargo + ret.mass = 3095. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.67 ret.centerToFront = ret.wheelbase * 0.37 ret.steerRatio = 18.61 # 15.3 is spec end-to-end tire_stiffness_factor = 0.72 - ret.steerKpV, ret.steerKiV = [[0.8], [0.24]] - ret.longitudinalKpBP = [0., 5., 35.] - ret.longitudinalKpV = [1.2, 0.8, 0.5] - ret.longitudinalKiBP = [0., 35.] - ret.longitudinalKiV = [0.18, 0.12] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kpV = [1.2, 0.8, 0.5] + ret.longitudinalTuning.kiBP = [0., 35.] + ret.longitudinalTuning.kiV = [0.18, 0.12] elif candidate == CAR.CRV: stop_and_go = False - ret.mass = 3572 * CV.LB_TO_KG + std_cargo + ret.mass = 3572. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.62 ret.centerToFront = ret.wheelbase * 0.41 - ret.steerRatio = 15.3 # as spec + ret.steerRatio = 16.89 # as spec tire_stiffness_factor = 0.444 # not optimized yet - ret.steerKpV, ret.steerKiV = [[0.8], [0.24]] - ret.longitudinalKpBP = [0., 5., 35.] - ret.longitudinalKpV = [1.2, 0.8, 0.5] - ret.longitudinalKiBP = [0., 35.] - ret.longitudinalKiV = [0.18, 0.12] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kpV = [1.2, 0.8, 0.5] + ret.longitudinalTuning.kiBP = [0., 35.] + ret.longitudinalTuning.kiV = [0.18, 0.12] elif candidate == CAR.CRV_5G: stop_and_go = True ret.safetyParam = 1 # Accord and CRV 5G use an alternate user brake msg - ret.mass = 3410. * CV.LB_TO_KG + std_cargo + ret.mass = 3410. * CV.LB_TO_KG + STD_CARGO_KG + ret.wheelbase = 2.66 + ret.centerToFront = ret.wheelbase * 0.41 + ret.steerRatio = 16.0 # 12.3 is spec end-to-end + tire_stiffness_factor = 0.677 + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.18]] + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kpV = [1.2, 0.8, 0.5] + ret.longitudinalTuning.kiBP = [0., 35.] + ret.longitudinalTuning.kiV = [0.18, 0.12] + + elif candidate == CAR.CRV_HYBRID: + stop_and_go = True + ret.safetyParam = 1 # Accord and CRV 5G use an alternate user brake msg + ret.mass = 1667. + STD_CARGO_KG # mean of 4 models in kg ret.wheelbase = 2.66 ret.centerToFront = ret.wheelbase * 0.41 ret.steerRatio = 16.0 # 12.3 is spec end-to-end tire_stiffness_factor = 0.677 - ret.steerKpV, ret.steerKiV = [[0.6], [0.18]] - ret.longitudinalKpBP = [0., 5., 35.] - ret.longitudinalKpV = [1.2, 0.8, 0.5] - ret.longitudinalKiBP = [0., 35.] - ret.longitudinalKiV = [0.18, 0.12] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.18]] + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kpV = [1.2, 0.8, 0.5] + ret.longitudinalTuning.kiBP = [0., 35.] + ret.longitudinalTuning.kiV = [0.18, 0.12] + + elif candidate == CAR.FIT: + stop_and_go = False + ret.mass = 2644. * CV.LB_TO_KG + STD_CARGO_KG + ret.wheelbase = 2.53 + ret.centerToFront = ret.wheelbase * 0.39 + ret.steerRatio = 13.06 + tire_stiffness_factor = 0.75 # not optimized yet + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.06]] + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kpV = [1.2, 0.8, 0.5] + ret.longitudinalTuning.kiBP = [0., 35.] + ret.longitudinalTuning.kiV = [0.18, 0.12] elif candidate == CAR.ACURA_RDX: stop_and_go = False - ret.mass = 3935 * CV.LB_TO_KG + std_cargo + ret.mass = 3935. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.68 ret.centerToFront = ret.wheelbase * 0.38 ret.steerRatio = 15.0 # as spec tire_stiffness_factor = 0.444 # not optimized yet - ret.steerKpV, ret.steerKiV = [[0.8], [0.24]] - ret.longitudinalKpBP = [0., 5., 35.] - ret.longitudinalKpV = [1.2, 0.8, 0.5] - ret.longitudinalKiBP = [0., 35.] - ret.longitudinalKiV = [0.18, 0.12] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kpV = [1.2, 0.8, 0.5] + ret.longitudinalTuning.kiBP = [0., 35.] + ret.longitudinalTuning.kiV = [0.18, 0.12] elif candidate == CAR.ODYSSEY: stop_and_go = False - ret.mass = 4471 * CV.LB_TO_KG + std_cargo + ret.mass = 4471. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 3.00 ret.centerToFront = ret.wheelbase * 0.41 ret.steerRatio = 14.35 # as spec tire_stiffness_factor = 0.82 - ret.steerKpV, ret.steerKiV = [[0.45], [0.135]] - ret.longitudinalKpBP = [0., 5., 35.] - ret.longitudinalKpV = [1.2, 0.8, 0.5] - ret.longitudinalKiBP = [0., 35.] - ret.longitudinalKiV = [0.18, 0.12] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.45], [0.135]] + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kpV = [1.2, 0.8, 0.5] + ret.longitudinalTuning.kiBP = [0., 35.] + ret.longitudinalTuning.kiV = [0.18, 0.12] + + elif candidate == CAR.ODYSSEY_CHN: + stop_and_go = False + ret.mass = 1849.2 + STD_CARGO_KG # mean of 4 models in kg + ret.wheelbase = 2.90 # spec + ret.centerToFront = ret.wheelbase * 0.41 # from CAR.ODYSSEY + ret.steerRatio = 14.35 # from CAR.ODYSSEY + tire_stiffness_factor = 0.82 # from CAR.ODYSSEY + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.45], [0.135]] + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kpV = [1.2, 0.8, 0.5] + ret.longitudinalTuning.kiBP = [0., 35.] + ret.longitudinalTuning.kiV = [0.18, 0.12] elif candidate in (CAR.PILOT, CAR.PILOT_2019): stop_and_go = False - ret.mass = 4303 * CV.LB_TO_KG + std_cargo - ret.wheelbase = 2.81 - ret.centerToFront = ret.wheelbase * 0.41 - ret.steerRatio = 16.0 # as spec + ret.mass = 4204. * CV.LB_TO_KG + STD_CARGO_KG # average weight + ret.wheelbase = 2.82 + ret.centerToFront = ret.wheelbase * 0.428 # average weight distribution + ret.steerRatio = 17.25 # as spec tire_stiffness_factor = 0.444 # not optimized yet - ret.steerKpV, ret.steerKiV = [[0.38], [0.11]] - ret.longitudinalKpBP = [0., 5., 35.] - ret.longitudinalKpV = [1.2, 0.8, 0.5] - ret.longitudinalKiBP = [0., 35.] - ret.longitudinalKiV = [0.18, 0.12] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.38], [0.11]] + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kpV = [1.2, 0.8, 0.5] + ret.longitudinalTuning.kiBP = [0., 35.] + ret.longitudinalTuning.kiV = [0.18, 0.12] elif candidate == CAR.RIDGELINE: stop_and_go = False - ret.mass = 4515 * CV.LB_TO_KG + std_cargo + ret.mass = 4515. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 3.18 ret.centerToFront = ret.wheelbase * 0.41 ret.steerRatio = 15.59 # as spec tire_stiffness_factor = 0.444 # not optimized yet - ret.steerKpV, ret.steerKiV = [[0.38], [0.11]] - ret.longitudinalKpBP = [0., 5., 35.] - ret.longitudinalKpV = [1.2, 0.8, 0.5] - ret.longitudinalKiBP = [0., 35.] - ret.longitudinalKiV = [0.18, 0.12] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.38], [0.11]] + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kpV = [1.2, 0.8, 0.5] + ret.longitudinalTuning.kiBP = [0., 35.] + ret.longitudinalTuning.kiV = [0.18, 0.12] else: raise ValueError("unsupported car %s" % candidate) @@ -322,20 +337,14 @@ def get_params(candidate, fingerprint): # conflict with PCM acc ret.minEnableSpeed = -1. if (stop_and_go or ret.enableGasInterceptor) else 25.5 * CV.MPH_TO_MS - centerToRear = ret.wheelbase - ret.centerToFront # TODO: get actual value, for now starting with reasonable value for # civic and scaling by mass and wheelbase - ret.rotationalInertia = rotationalInertia_civic * \ - ret.mass * ret.wheelbase**2 / (mass_civic * wheelbase_civic**2) + ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) # TODO: start from empirically derived lateral slip stiffness for the civic and scale by # mass and CG position, so all cars will have approximately similar dyn behaviors - ret.tireStiffnessFront = (tireStiffnessFront_civic * tire_stiffness_factor) * \ - ret.mass / mass_civic * \ - (centerToRear / ret.wheelbase) / (centerToRear_civic / wheelbase_civic) - ret.tireStiffnessRear = (tireStiffnessRear_civic * tire_stiffness_factor) * \ - ret.mass / mass_civic * \ - (ret.centerToFront / ret.wheelbase) / (centerToFront_civic / wheelbase_civic) + ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, + tire_stiffness_factor=tire_stiffness_factor) # no rear steering, at least on the listed cars above ret.steerRatioRear = 0. @@ -349,8 +358,8 @@ def get_params(candidate, fingerprint): ret.brakeMaxBP = [5., 20.] # m/s ret.brakeMaxV = [1., 0.8] # max brake allowed - ret.longPidDeadzoneBP = [0.] - ret.longPidDeadzoneV = [0.] + ret.longitudinalTuning.deadzoneBP = [0.] + ret.longitudinalTuning.deadzoneV = [0.] ret.stoppingControl = True ret.steerLimitAlert = True @@ -362,18 +371,18 @@ def get_params(candidate, fingerprint): return ret # returns a car.CarState - def update(self, c): + def update(self, c, can_strings): # ******************* do can recv ******************* - canMonoTimes = [] - - self.cp.update(int(sec_since_boot() * 1e9), False) - self.cp_cam.update(int(sec_since_boot() * 1e9), False) + self.cp.update_strings(can_strings) + self.cp_cam.update_strings(can_strings) self.CS.update(self.cp, self.cp_cam) # create message ret = car.CarState.new_message() + ret.canValid = self.cp.can_valid + # speeds ret.vEgo = self.CS.v_ego ret.aEgo = self.CS.a_ego @@ -408,12 +417,13 @@ def update(self, c): ret.gearShifter = self.CS.gear_shifter ret.steeringTorque = self.CS.steer_torque_driver + ret.steeringTorqueEps = self.CS.steer_torque_motor ret.steeringPressed = self.CS.steer_override # cruise state ret.cruiseState.enabled = self.CS.pcm_acc_status != 0 ret.cruiseState.speed = self.CS.v_cruise_pcm * CV.KPH_TO_MS - ret.cruiseState.available = bool(self.CS.main_on) + ret.cruiseState.available = bool(self.CS.main_on) and not bool(self.CS.cruise_mode) ret.cruiseState.speedOffset = self.CS.cruise_speed_offset ret.cruiseState.standstill = False @@ -427,19 +437,19 @@ def update(self, c): if self.CS.left_blinker_on != self.CS.prev_left_blinker_on: be = car.CarState.ButtonEvent.new_message() - be.type = 'leftBlinker' + be.type = ButtonType.leftBlinker be.pressed = self.CS.left_blinker_on != 0 buttonEvents.append(be) if self.CS.right_blinker_on != self.CS.prev_right_blinker_on: be = car.CarState.ButtonEvent.new_message() - be.type = 'rightBlinker' + be.type = ButtonType.rightBlinker be.pressed = self.CS.right_blinker_on != 0 buttonEvents.append(be) if self.CS.cruise_buttons != self.CS.prev_cruise_buttons: be = car.CarState.ButtonEvent.new_message() - be.type = 'unknown' + be.type = ButtonType.unknown if self.CS.cruise_buttons != 0: be.pressed = True but = self.CS.cruise_buttons @@ -447,18 +457,18 @@ def update(self, c): be.pressed = False but = self.CS.prev_cruise_buttons if but == CruiseButtons.RES_ACCEL: - be.type = 'accelCruise' + be.type = ButtonType.accelCruise elif but == CruiseButtons.DECEL_SET: - be.type = 'decelCruise' + be.type = ButtonType.decelCruise elif but == CruiseButtons.CANCEL: - be.type = 'cancel' + be.type = ButtonType.cancel elif but == CruiseButtons.MAIN: - be.type = 'altButton3' + be.type = ButtonType.altButton3 buttonEvents.append(be) if self.CS.cruise_setting != self.CS.prev_cruise_setting: be = car.CarState.ButtonEvent.new_message() - be.type = 'unknown' + be.type = ButtonType.unknown if self.CS.cruise_setting != 0: be.pressed = True but = self.CS.cruise_setting @@ -466,37 +476,23 @@ def update(self, c): be.pressed = False but = self.CS.prev_cruise_setting if but == 1: - be.type = 'altButton1' + be.type = ButtonType.altButton1 # TODO: more buttons? buttonEvents.append(be) ret.buttonEvents = buttonEvents # events - # TODO: event names aren't checked at compile time. - # Maybe there is a way to use capnp enums directly events = [] - if not self.CS.can_valid: - self.can_invalid_count += 1 - if self.can_invalid_count >= 5: - events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) - else: - self.can_invalid_count = 0 - - if not self.CS.cam_can_valid and self.CP.enableCamera: - self.cam_can_invalid_count += 1 - # wait 1.0s before throwing the alert to avoid it popping when you turn off the car - if self.cam_can_invalid_count >= 100 and self.CS.CP.carFingerprint not in HONDA_BOSCH: - events.append(create_event('invalidGiraffeHonda', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE, ET.PERMANENT])) - else: - self.cam_can_invalid_count = 0 - + # wait 1.0s before throwing the alert to avoid it popping when you turn off the car + if self.cp_cam.can_invalid_cnt >= 100 and self.CS.CP.carFingerprint not in HONDA_BOSCH and self.CP.enableCamera: + events.append(create_event('invalidGiraffeHonda', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE, ET.PERMANENT])) if self.CS.steer_error: events.append(create_event('steerUnavailable', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE, ET.PERMANENT])) elif self.CS.steer_warning: events.append(create_event('steerTempUnavailable', [ET.WARNING])) if self.CS.brake_error: events.append(create_event('brakeUnavailable', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE, ET.PERMANENT])) - if not ret.gearShifter == 'drive': + if not ret.gearShifter == GearShifter.drive: events.append(create_event('wrongGear', [ET.NO_ENTRY, ET.SOFT_DISABLE])) if ret.doorOpen: events.append(create_event('doorOpen', [ET.NO_ENTRY, ET.SOFT_DISABLE])) @@ -504,9 +500,9 @@ def update(self, c): events.append(create_event('seatbeltNotLatched', [ET.NO_ENTRY, ET.SOFT_DISABLE])) if self.CS.esp_disabled: events.append(create_event('espDisabled', [ET.NO_ENTRY, ET.SOFT_DISABLE])) - if not self.CS.main_on: + if not self.CS.main_on or self.CS.cruise_mode: events.append(create_event('wrongCarMode', [ET.NO_ENTRY, ET.USER_DISABLE])) - if ret.gearShifter == 'reverse': + if ret.gearShifter == GearShifter.reverse: events.append(create_event('reverseGear', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) if self.CS.brake_hold and self.CS.CP.carFingerprint not in HONDA_BOSCH: events.append(create_event('brakeHold', [ET.NO_ENTRY, ET.USER_DISABLE])) @@ -535,13 +531,13 @@ def update(self, c): if self.CS.CP.minEnableSpeed > 0 and ret.vEgo < 0.001: events.append(create_event('manualRestart', [ET.WARNING])) - cur_time = sec_since_boot() + cur_time = self.frame * DT_CTRL enable_pressed = False # handle button presses for b in ret.buttonEvents: # do enable on both accel and decel buttons - if b.type in ["accelCruise", "decelCruise"] and not b.pressed: + if b.type in [ButtonType.accelCruise, ButtonType.decelCruise] and not b.pressed: self.last_enable_pressed = cur_time enable_pressed = True @@ -564,7 +560,6 @@ def update(self, c): events.append(create_event('buttonEnable', [ET.ENABLE])) ret.events = events - ret.canMonoTimes = canMonoTimes # update previous brake/gas pressed self.gas_pressed_prev = ret.gasPressed @@ -582,21 +577,19 @@ def apply(self, c): hud_v_cruise = 255 hud_alert = VISUAL_HUD[c.hudControl.visualAlert.raw] - snd_beep, snd_chime = AUDIO_HUD[c.hudControl.audibleAlert.raw] pcm_accel = int(clip(c.cruiseControl.accelOverride, 0, 1) * 0xc6) - self.CC.update(self.sendcan, c.enabled, self.CS, self.frame, - c.actuators, - c.cruiseControl.speedOverride, - c.cruiseControl.override, - c.cruiseControl.cancel, - pcm_accel, - hud_v_cruise, - c.hudControl.lanesVisible, - hud_show_car=c.hudControl.leadVisible, - hud_alert=hud_alert, - snd_beep=snd_beep, - snd_chime=snd_chime) + can_sends = self.CC.update(c.enabled, self.CS, self.frame, + c.actuators, + c.cruiseControl.speedOverride, + c.cruiseControl.override, + c.cruiseControl.cancel, + pcm_accel, + hud_v_cruise, + c.hudControl.lanesVisible, + hud_show_car=c.hudControl.leadVisible, + hud_alert=hud_alert) self.frame += 1 + return can_sends diff --git a/selfdrive/car/honda/radar_interface.py b/selfdrive/car/honda/radar_interface.py index 7d30265c2f471e..2415e95a35f734 100755 --- a/selfdrive/car/honda/radar_interface.py +++ b/selfdrive/car/honda/radar_interface.py @@ -1,28 +1,25 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import os -import zmq import time from cereal import car from selfdrive.can.parser import CANParser -from common.realtime import sec_since_boot -from selfdrive.services import service_list -import selfdrive.messaging as messaging - +from common.realtime import DT_RDR +from selfdrive.car.interfaces import RadarInterfaceBase def _create_nidec_can_parser(): dbc_f = 'acura_ilx_2016_nidec.dbc' - radar_messages = [0x400] + range(0x430, 0x43A) + range(0x440, 0x446) - signals = zip(['RADAR_STATE'] + + radar_messages = [0x400] + list(range(0x430, 0x43A)) + list(range(0x440, 0x446)) + signals = list(zip(['RADAR_STATE'] + ['LONG_DIST'] * 16 + ['NEW_TRACK'] * 16 + ['LAT_DIST'] * 16 + ['REL_SPEED'] * 16, [0x400] + radar_messages[1:] * 4, - [0] + [255] * 16 + [1] * 16 + [0] * 16 + [0] * 16) - checks = zip([0x445], [20]) - - return CANParser(os.path.splitext(dbc_f)[0], signals, checks, 1) + [0] + [255] * 16 + [1] * 16 + [0] * 16 + [0] * 16)) + checks = list(zip([0x445], [20])) + fn = os.path.splitext(dbc_f)[0].encode('utf8') + return CANParser(fn, signals, checks, 1) -class RadarInterface(object): +class RadarInterface(RadarInterfaceBase): def __init__(self, CP): # radar self.pts = {} @@ -31,33 +28,36 @@ def __init__(self, CP): self.radar_wrong_config = False self.radar_off_can = CP.radarOffCan - self.delay = 0.1 # Delay of radar + self.delay = int(0.1 / DT_RDR) # 0.1s delay of radar # Nidec self.rcp = _create_nidec_can_parser() + self.trigger_msg = 0x445 + self.updated_messages = set() - context = zmq.Context() - self.logcan = messaging.sub_sock(context, service_list['can'].port) - - def update(self): - canMonoTimes = [] - - updated_messages = set() - ret = car.RadarState.new_message() - + def update(self, can_strings): # in Bosch radar and we are only steering for now, so sleep 0.05s to keep # radard at 20Hz and return no points if self.radar_off_can: - time.sleep(0.05) - return ret + if 'NO_RADAR_SLEEP' not in os.environ: + time.sleep(0.05) + return car.RadarData.new_message() + + vls = self.rcp.update_strings(can_strings) + self.updated_messages.update(vls) - while 1: - tm = int(sec_since_boot() * 1e9) - updated_messages.update(self.rcp.update(tm, True)) - if 0x445 in updated_messages: - break + if self.trigger_msg not in self.updated_messages: + return None - for ii in updated_messages: + rr = self._update(self.updated_messages) + self.updated_messages.clear() + return rr + + + def _update(self, updated_messages): + ret = car.RadarData.new_message() + + for ii in sorted(updated_messages): cpt = self.rcp.vl[ii] if ii == 0x400: # check for radar faults @@ -65,7 +65,7 @@ def update(self): self.radar_wrong_config = cpt['RADAR_STATE'] == 0x69 elif cpt['LONG_DIST'] < 255: if ii not in self.pts or cpt['NEW_TRACK']: - self.pts[ii] = car.RadarState.RadarPoint.new_message() + self.pts[ii] = car.RadarData.RadarPoint.new_message() self.pts[ii].trackId = self.track_id self.track_id += 1 self.pts[ii].dRel = cpt['LONG_DIST'] # from front of car @@ -80,25 +80,13 @@ def update(self): errors = [] if not self.rcp.can_valid: - errors.append("commIssue") + errors.append("canError") if self.radar_fault: errors.append("fault") if self.radar_wrong_config: errors.append("wrongConfig") ret.errors = errors - ret.canMonoTimes = canMonoTimes - ret.points = self.pts.values() + ret.points = list(self.pts.values()) return ret - - -if __name__ == "__main__": - class CarParams: - radarOffCan = False - - RI = RadarInterface(CarParams) - while 1: - ret = RI.update() - print(chr(27) + "[2J") - print ret diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index 56302551f93f32..90dfd4eab32a9f 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -1,7 +1,6 @@ from cereal import car from selfdrive.car import dbc_dict -AudibleAlert = car.CarControl.HUDControl.AudibleAlert VisualAlert = car.CarControl.HUDControl.VisualAlert # Car button codes @@ -11,31 +10,6 @@ class CruiseButtons: CANCEL = 2 MAIN = 1 -#car chimes: enumeration from dbc file. Chimes are for alerts and warnings -class CM: - MUTE = 0 - SINGLE = 3 - DOUBLE = 4 - REPEATED = 1 - CONTINUOUS = 2 - -#car beeps: enumeration from dbc file. Beeps are for engage and disengage -class BP: - MUTE = 0 - SINGLE = 3 - TRIPLE = 2 - REPEATED = 1 - -AUDIO_HUD = { - AudibleAlert.none: (BP.MUTE, CM.MUTE), - AudibleAlert.chimeEngage: (BP.SINGLE, CM.MUTE), - AudibleAlert.chimeDisengage: (BP.SINGLE, CM.MUTE), - AudibleAlert.chimeError: (BP.MUTE, CM.DOUBLE), - AudibleAlert.chimePrompt: (BP.MUTE, CM.SINGLE), - AudibleAlert.chimeWarning1: (BP.MUTE, CM.DOUBLE), - AudibleAlert.chimeWarning2: (BP.MUTE, CM.REPEATED), - AudibleAlert.chimeWarningRepeat: (BP.MUTE, CM.REPEATED)} - class AH: #[alert_idx, value] # See dbc files for info on values" @@ -56,6 +30,9 @@ class AH: VisualAlert.seatbeltUnbuckled: AH.SEATBELT, VisualAlert.speedTooHigh: AH.SPEED_TOO_HIGH} +class ECU: + CAM = 0 + class CAR: ACCORD = "HONDA ACCORD 2018 SPORT 2T" ACCORD_15 = "HONDA ACCORD 2018 LX 1.5T" @@ -65,12 +42,18 @@ class CAR: ACURA_ILX = "ACURA ILX 2016 ACURAWATCH PLUS" CRV = "HONDA CR-V 2016 TOURING" CRV_5G = "HONDA CR-V 2017 EX" + CRV_HYBRID = "HONDA CR-V 2019 HYBRID" + FIT = "HONDA FIT 2018 EX" ODYSSEY = "HONDA ODYSSEY 2018 EX-L" + ODYSSEY_CHN = "HONDA ODYSSEY 2019 EXCLUSIVE CHN" ACURA_RDX = "ACURA RDX 2018 ACURAWATCH PLUS" PILOT = "HONDA PILOT 2017 TOURING" PILOT_2019 = "HONDA PILOT 2019 ELITE" RIDGELINE = "HONDA RIDGELINE 2017 BLACK EDITION" +# diag message that in some Nidec cars only appear with 1s freq if VIN query is performed +DIAG_MSGS = {1600: 5, 1601: 8} + FINGERPRINTS = { CAR.ACCORD: [{ 148: 8, 228: 5, 304: 8, 330: 8, 344: 8, 380: 8, 399: 7, 419: 8, 420: 8, 427: 3, 432: 7, 441: 5, 446: 3, 450: 8, 464: 8, 477: 8, 479: 8, 495: 8, 545: 6, 662: 4, 773: 7, 777: 8, 780: 8, 804: 8, 806: 8, 808: 8, 829: 5, 862: 8, 884: 8, 891: 8, 927: 8, 929: 8, 1302: 8, 1600: 5, 1601: 8, 1652: 8 @@ -92,14 +75,21 @@ class CAR: 57: 3, 148: 8, 228: 5, 304: 8, 330: 8, 344: 8, 380: 8, 399: 7, 401: 8, 420: 8, 427: 3, 428: 8, 432: 7, 450: 8, 464: 8, 470: 2, 476: 7, 487: 4, 490: 8, 493: 5, 506: 8, 512: 6, 513: 6, 545: 6, 597: 8, 662: 4, 773: 7, 777: 8, 780: 8, 795: 8, 800: 8, 804: 8, 806: 8, 808: 8, 829: 5, 862: 8, 884: 8, 891: 8, 892: 8, 927: 8, 929: 8, 985: 3, 1024: 5, 1027: 5, 1029: 8, 1036: 8, 1039: 8, 1108: 8, 1302: 8, 1322: 5, 1361: 5, 1365: 5, 1424: 5, 1633: 8, }], CAR.CIVIC_BOSCH: [{ - # 2017 Civic Hatchback EX and 2019 Civic Sedan Touring Canadian - 57: 3, 148: 8, 228: 5, 304: 8, 330: 8, 344: 8, 380: 8, 399: 7, 401: 8, 420: 8, 427: 3, 428: 8, 432: 7, 441: 5, 450: 8, 464: 8, 470: 2, 476: 7, 477: 8, 479: 8, 490: 8, 493: 5, 495: 8, 506: 8, 545: 6, 597: 8, 662: 4, 773: 7, 777: 8, 780: 8, 795: 8, 800: 8, 804: 8, 806: 8, 808: 8, 829: 5, 862: 8, 884: 8, 891: 8, 892: 8, 927: 8, 929: 8, 985: 3, 1024: 5, 1027: 5, 1029: 8, 1036: 8, 1039: 8, 1108: 8, 1302: 8, 1322: 5, 1361: 5, 1365: 5, 1424: 5, 1600: 5, 1601: 8, 1633: 8, + # 2017 Civic Hatchback EX, 2019 Civic Sedan Touring Canadian, and 2018 Civic Hatchback Executive Premium 1.0L CVT European + 57: 3, 148: 8, 228: 5, 304: 8, 330: 8, 344: 8, 380: 8, 399: 7, 401: 8, 420: 8, 427: 3, 428: 8, 432: 7, 441: 5, 450: 8, 460: 3, 464: 8, 470: 2, 476: 7, 477: 8, 479: 8, 490: 8, 493: 5, 495: 8, 506: 8, 545: 6, 597: 8, 662: 4, 773: 7, 777: 8, 780: 8, 795: 8, 800: 8, 804: 8, 806: 8, 808: 8, 829: 5, 862: 8, 884: 8, 891: 8, 892: 8, 927: 8, 929: 8, 985: 3, 1024: 5, 1027: 5, 1029: 8, 1036: 8, 1039: 8, 1108: 8, 1302: 8, 1322: 5, 1361: 5, 1365: 5, 1424: 5, 1600: 5, 1601: 8, 1625: 5, 1629: 5, 1633: 8, }], CAR.CRV: [{ 57: 3, 145: 8, 316: 8, 340: 8, 342: 6, 344: 8, 380: 8, 398: 3, 399: 6, 401: 8, 404: 4, 420: 8, 422: 8, 426: 8, 432: 7, 464: 8, 474: 5, 476: 4, 487: 4, 490: 8, 493: 3, 506: 8, 507: 1, 512: 6, 513: 6, 542: 7, 545: 4, 597: 8, 660: 8, 661: 4, 773: 7, 777: 8, 780: 8, 800: 8, 804: 8, 808: 8, 829: 5, 882: 2, 884: 7, 888: 8, 891: 8, 892: 8, 923: 2, 929: 8, 983: 8, 985: 3, 1024: 5, 1027: 5, 1029: 8, 1033: 5, 1036: 8, 1039: 8, 1057: 5, 1064: 7, 1108: 8, 1125: 8, 1296: 8, 1365: 5, 1424: 5, 1600: 5, 1601: 8, }], + # msg 1115 has seen with len 2 and 4, so ignore it CAR.CRV_5G: [{ - 57: 3, 148: 8, 199: 4, 228: 5, 231: 5, 232: 7, 304: 8, 330: 8, 340: 8, 344: 8, 380: 8, 399: 7, 401: 8, 420: 8, 423: 2, 427: 3, 428: 8, 432: 7, 441: 5, 446: 3, 450: 8, 464: 8, 467: 2, 469: 3, 470: 2, 474: 8, 476: 7, 477: 8, 479: 8, 490: 8, 493: 5, 495: 8, 507: 1, 545: 6, 597: 8, 661: 4, 662: 4, 773: 7, 777: 8, 780: 8, 795: 8, 800: 8, 804: 8, 806: 8, 808: 8, 814: 4, 815: 8, 817: 4, 825: 4, 829: 5, 862: 8, 881: 8, 882: 4, 884: 8, 888: 8, 891: 8, 927: 8, 918: 7, 929: 8, 983: 8, 985: 3, 1024: 5, 1027: 5, 1029: 8, 1036: 8, 1039: 8, 1064: 7, 1108: 8, 1092: 1, 1115: 4, 1125: 8, 1127: 2, 1296: 8, 1302: 8, 1322: 5, 1361: 5, 1365: 5, 1424: 5, 1600: 5, 1601: 8, 1618: 5, 1633: 8, 1670: 5 + 57: 3, 148: 8, 199: 4, 228: 5, 231: 5, 232: 7, 304: 8, 330: 8, 340: 8, 344: 8, 380: 8, 399: 7, 401: 8, 420: 8, 423: 2, 427: 3, 428: 8, 432: 7, 441: 5, 446: 3, 450: 8, 464: 8, 467: 2, 469: 3, 470: 2, 474: 8, 476: 7, 477: 8, 479: 8, 490: 8, 493: 5, 495: 8, 507: 1, 545: 6, 597: 8, 661: 4, 662: 4, 773: 7, 777: 8, 780: 8, 795: 8, 800: 8, 804: 8, 806: 8, 808: 8, 814: 4, 815: 8, 817: 4, 825: 4, 829: 5, 862: 8, 881: 8, 882: 4, 884: 8, 888: 8, 891: 8, 927: 8, 918: 7, 929: 8, 983: 8, 985: 3, 1024: 5, 1027: 5, 1029: 8, 1036: 8, 1039: 8, 1064: 7, 1108: 8, 1092: 1, 1125: 8, 1127: 2, 1296: 8, 1302: 8, 1322: 5, 1361: 5, 1365: 5, 1424: 5, 1600: 5, 1601: 8, 1618: 5, 1633: 8, 1670: 5 + }], + CAR.CRV_HYBRID: [{ + 57: 3, 148: 8, 228: 5, 304: 8, 330: 8, 344: 8, 380: 8, 387: 8, 388: 8, 399: 7, 408: 6, 415: 6, 419: 8, 420: 8, 427: 3, 428: 8, 432: 7, 441: 5, 450: 8, 464: 8, 477: 8, 479: 8, 490: 8, 495: 8, 525: 8, 531: 8, 545: 6, 662: 4, 773: 7, 777: 8, 780: 8, 804: 8, 806: 8, 808: 8, 814: 4, 829: 5, 833: 6, 862: 8, 884: 8, 891: 8, 927: 8, 929: 8, 930: 8, 931: 8, 1302: 8, 1361: 5, 1365: 5, 1600: 5, 1601: 8, 1626: 5, 1627: 5 + }], + CAR.FIT: [{ + 57: 3, 145: 8, 228: 5, 304: 8, 342: 6, 344: 8, 380: 8, 399: 7, 401: 8, 420: 8, 422: 8, 427: 3, 428: 8, 432: 7, 464: 8, 487: 4, 490: 8, 506: 8, 597: 8, 660: 8, 661: 4, 773: 7, 777: 8, 780: 8, 800: 8, 804: 8, 808: 8, 829: 5, 862: 8, 884: 7, 892: 8, 929: 8, 985: 3, 1024: 5, 1027: 5, 1029: 8, 1036: 8, 1039: 8, 1108: 8, 1322: 5, 1361: 5, 1365: 5, 1424: 5, 1600: 5, 1601: 8 }], # 2018 Odyssey w/ Added Comma Pedal Support (512L & 513L) CAR.ODYSSEY: [{ @@ -109,16 +99,20 @@ class CAR: { 57: 3, 148: 8, 228: 5, 229: 4, 304: 8, 342: 6, 344: 8, 380: 8, 399: 7, 411: 5, 419: 8, 420: 8, 427: 3, 432: 7, 440: 8, 450: 8, 463: 8, 464: 8, 476: 4, 490: 8, 506: 8, 507: 1, 542: 7, 545: 6, 597: 8, 662: 4, 773: 7, 777: 8, 780: 8, 795: 8, 800: 8, 804: 8, 806: 8, 808: 8, 817: 4, 819: 7, 821: 5, 825: 4, 829: 5, 837: 5, 856: 7, 862: 8, 871: 8, 881: 8, 882: 4, 884: 8, 891: 8, 892: 8, 905: 8, 923: 2, 927: 8, 929: 8, 963: 8, 965: 8, 966: 8, 967: 8, 983: 8, 985: 3, 1029: 8, 1036: 8, 1052: 8, 1064: 7, 1088: 8, 1089: 8, 1092: 1, 1108: 8, 1110: 8, 1125: 8, 1296: 8, 1302: 8, 1600: 5, 1601: 8, 1612: 5, 1613: 5, 1614: 5, 1616: 5, 1619: 5, 1623: 5, 1668: 5 }], + CAR.ODYSSEY_CHN: [{ + 57: 3, 145: 8, 316: 8, 342: 6, 344: 8, 380: 8, 398: 3, 399: 7, 401: 8, 404: 4, 411: 5, 420: 8, 422: 8, 423: 2, 426: 8, 432: 7, 450: 8, 464: 8, 490: 8, 506: 8, 507: 1, 512: 6, 513: 6, 597: 8, 610: 8, 611: 8, 612: 8, 617: 8, 660: 8, 661: 4, 773: 7, 780: 8, 804: 8, 808: 8, 829: 5, 862: 8, 884: 7, 892: 8, 923: 2, 929: 8, 1030: 5, 1137: 8, 1302: 8, 1348: 5, 1361: 5, 1365: 5, 1600: 5, 1601: 8, 1639: 8 + }], # 2017 Pilot Touring AND 2016 Pilot EX-L w/ Added Comma Pedal Support (512L & 513L) CAR.PILOT: [{ 57: 3, 145: 8, 228: 5, 229: 4, 308: 5, 316: 8, 334: 8, 339: 7, 342: 6, 344: 8, 379: 8, 380: 8, 392: 6, 399: 7, 419: 8, 420: 8, 422: 8, 425: 8, 426: 8, 427: 3, 432: 7, 463: 8, 464: 8, 476: 4, 490: 8, 506: 8, 507: 1, 512: 6, 513: 6, 538: 3, 542: 7, 545: 5, 546: 3, 597: 8, 660: 8, 773: 7, 777: 8, 780: 8, 795: 8, 800: 8, 804: 8, 808: 8, 819: 7, 821: 5, 829: 5, 837: 5, 856: 7, 871: 8, 882: 2, 884: 7, 891: 8, 892: 8, 923: 2, 929: 8, 963: 8, 965: 8, 966: 8, 967: 8, 983: 8, 985: 3, 1027: 5, 1029: 8, 1036: 8, 1039: 8, 1064: 7, 1088: 8, 1089: 8, 1108: 8, 1125: 8, 1296: 8, 1424: 5, 1600: 5, 1601: 8, 1612: 5, 1613: 5, 1616: 5, 1618: 5, 1668: 5 }], + # this fingerprint also includes the Passport 2019 CAR.PILOT_2019: [{ - 57: 3, 145: 8, 228: 5, 308: 5, 316: 8, 334: 8, 342: 6, 344: 8, 379: 8, 380: 8, 399: 7, 411: 5, 419: 8, 420: 8, 422: 8, 425: 8, 426: 8, 427: 3, 432: 7, 463: 8, 464: 8, 476: 4, 490: 8, 506: 8, 538: 3, 542: 7, 545: 5, 546: 3, 597: 8, 660: 8, 773: 7, 777: 8, 780: 8, 795: 8, 800: 8, 804: 8, 808: 8, 817: 4, 819: 7, 821: 5, 825: 4, 829: 5, 837: 5, 856: 7, 871: 8, 881: 8, 882: 2, 884: 7, 891: 8, 892: 8, 923: 2, 927: 8, 929: 8, 983: 8, 985: 3, 1029: 8, 1052: 8, 1064: 7, 1088: 8, 1089: 8, 1092: 1, 1108: 8, 1110: 8, 1125: 8, 1296: 8, 1424: 5, 1445: 8, 1600: 5, 1601: 8, 1612: 5, 1613: 5, 1614: 5, 1615: 8, 1616: 5, 1617: 8, 1618: 5, 1623: 5, 1668: 5 + 57: 3, 145: 8, 228: 5, 308: 5, 316: 8, 334: 8, 342: 6, 344: 8, 379: 8, 380: 8, 399: 7, 411: 5, 419: 8, 420: 8, 422: 8, 425: 8, 426: 8, 427: 3, 432: 7, 463: 8, 464: 8, 476: 4, 490: 8, 506: 8, 512: 6, 513: 6, 538: 3, 542: 7, 545: 5, 546: 3, 597: 8, 660: 8, 773: 7, 777: 8, 780: 8, 795: 8, 800: 8, 804: 8, 808: 8, 817: 4, 819: 7, 821: 5, 825: 4, 829: 5, 837: 5, 856: 7, 871: 8, 881: 8, 882: 2, 884: 7, 891: 8, 892: 8, 923: 2, 927: 8, 929: 8, 983: 8, 985: 3, 1029: 8, 1052: 8, 1064: 7, 1088: 8, 1089: 8, 1092: 1, 1108: 8, 1110: 8, 1125: 8, 1296: 8, 1424: 5, 1445: 8, 1600: 5, 1601: 8, 1612: 5, 1613: 5, 1614: 5, 1615: 8, 1616: 5, 1617: 8, 1618: 5, 1623: 5, 1668: 5 }, # 2019 Pilot EX-L { - 57: 3, 145: 8, 228: 5, 229: 4, 308: 5, 316: 8, 339: 7, 342: 6, 344: 8, 380: 8, 392: 6, 399: 7, 411: 5, 419: 8, 420: 8, 422: 8, 425: 8, 426: 8, 427: 3, 432: 7, 464: 8, 476: 4, 490: 8, 506: 8, 542: 7, 545: 5, 546: 3, 597: 8, 660: 8, 773: 7, 777: 8, 780: 8, 795: 8, 800: 8, 804: 8, 808: 8, 817: 4, 819: 7, 821: 5, 829: 5, 871: 8, 881: 8, 882: 2, 884: 7, 891: 8, 892: 8, 923: 2, 927: 8, 929: 8, 963: 8, 965: 8, 966: 8, 967: 8, 983: 8, 985: 3, 1027: 5, 1029: 8, 1039: 8, 1064: 7, 1088: 8, 1089: 8, 1092: 1, 1108: 8, 1125: 8, 1296: 8, 1424: 5, 1445: 8, 1600: 5, 1601: 8, 1612: 5, 1613: 5, 1616: 5, 1617: 8, 1618: 5, 1623: 5, 1668: 5 + 57: 3, 145: 8, 228: 5, 229: 4, 308: 5, 316: 8, 339: 7, 342: 6, 344: 8, 380: 8, 392: 6, 399: 7, 411: 5, 419: 8, 420: 8, 422: 8, 425: 8, 426: 8, 427: 3, 432: 7, 464: 8, 476: 4, 490: 8, 506: 8, 512: 6, 513: 6, 542: 7, 545: 5, 546: 3, 597: 8, 660: 8, 773: 7, 777: 8, 780: 8, 795: 8, 800: 8, 804: 8, 808: 8, 817: 4, 819: 7, 821: 5, 829: 5, 871: 8, 881: 8, 882: 2, 884: 7, 891: 8, 892: 8, 923: 2, 927: 8, 929: 8, 963: 8, 965: 8, 966: 8, 967: 8, 983: 8, 985: 3, 1027: 5, 1029: 8, 1039: 8, 1064: 7, 1088: 8, 1089: 8, 1092: 1, 1108: 8, 1125: 8, 1296: 8, 1424: 5, 1445: 8, 1600: 5, 1601: 8, 1612: 5, 1613: 5, 1616: 5, 1617: 8, 1618: 5, 1623: 5, 1668: 5 }], # Ridgeline w/ Added Comma Pedal Support (512L & 513L) CAR.RIDGELINE: [{ @@ -126,10 +120,16 @@ class CAR: }, # 2019 Ridgeline { - 57: 3, 145: 8, 229: 4, 308: 5, 316: 8, 339: 7, 342: 6, 344: 8, 380: 8, 392: 6, 399: 7, 419: 8, 420: 8, 422:8, 425: 8, 426: 8, 427: 3, 432: 7, 464: 8, 476: 4, 490: 8, 545: 5, 546: 3, 597: 8, 660: 8, 773: 7, 777: 8, 795: 8, 800: 8, 804: 8, 808: 8, 819: 7, 821: 5, 871: 8, 882: 2, 884: 7, 892: 8, 923: 2, 929: 8, 963: 8, 965: 8, 966: 8, 967: 8, 983: 8, 985: 3, 1027: 5, 1029: 8, 1036: 8, 1039: 8, 1064: 7, 1088: 8, 1089: 8, 1092: 1, 1108: 8, 1125: 8, 1296: 8, 1365: 5, 424: 5, 1613: 5, 1616: 5, 1618: 5, 1623: 5, 1668: 5 + 57: 3, 145: 8, 228: 5, 229: 4, 308: 5, 316: 8, 339: 7, 342: 6, 344: 8, 380: 8, 392: 6, 399: 7, 419: 8, 420: 8, 422:8, 425: 8, 426: 8, 427: 3, 432: 7, 464: 8, 476: 4, 490: 8, 545: 5, 546: 3, 597: 8, 660: 8, 773: 7, 777: 8, 795: 8, 800: 8, 804: 8, 808: 8, 819: 7, 821: 5, 871: 8, 882: 2, 884: 7, 892: 8, 923: 2, 929: 8, 963: 8, 965: 8, 966: 8, 967: 8, 983: 8, 985: 3, 1027: 5, 1029: 8, 1036: 8, 1039: 8, 1064: 7, 1088: 8, 1089: 8, 1092: 1, 1108: 8, 1125: 8, 1296: 8, 1365: 5, 424: 5, 1613: 5, 1616: 5, 1618: 5, 1623: 5, 1668: 5 }] } +# add DIAG_MSGS to fingerprints +for c in FINGERPRINTS: + for f, _ in enumerate(FINGERPRINTS[c]): + for d in DIAG_MSGS: + FINGERPRINTS[c][f][d] = DIAG_MSGS[d] + DBC = { CAR.ACCORD: dbc_dict('honda_accord_s2t_2018_can_generated', None), CAR.ACCORD_15: dbc_dict('honda_accord_lx15t_2018_can_generated', None), @@ -140,7 +140,10 @@ class CAR: CAR.CIVIC_BOSCH: dbc_dict('honda_civic_hatchback_ex_2017_can_generated', None), CAR.CRV: dbc_dict('honda_crv_touring_2016_can_generated', 'acura_ilx_2016_nidec'), CAR.CRV_5G: dbc_dict('honda_crv_ex_2017_can_generated', None), + CAR.CRV_HYBRID: dbc_dict('honda_crv_hybrid_2019_can_generated', None), + CAR.FIT: dbc_dict('honda_fit_ex_2018_can_generated', 'acura_ilx_2016_nidec'), CAR.ODYSSEY: dbc_dict('honda_odyssey_exl_2018_generated', 'acura_ilx_2016_nidec'), + CAR.ODYSSEY_CHN: dbc_dict('honda_odyssey_extreme_edition_2018_china_can_generated', 'acura_ilx_2016_nidec'), CAR.PILOT: dbc_dict('honda_pilot_touring_2017_can_generated', 'acura_ilx_2016_nidec'), CAR.PILOT_2019: dbc_dict('honda_pilot_touring_2017_can_generated', 'acura_ilx_2016_nidec'), CAR.RIDGELINE: dbc_dict('honda_ridgeline_black_edition_2017_can_generated', 'acura_ilx_2016_nidec'), @@ -156,7 +159,10 @@ class CAR: CAR.CIVIC_BOSCH: 1200, CAR.CRV: 1200, CAR.CRV_5G: 1200, + CAR.CRV_HYBRID: 1200, + CAR.FIT: 1200, CAR.ODYSSEY: 1200, + CAR.ODYSSEY_CHN: 1200, CAR.PILOT: 1200, CAR.PILOT_2019: 1200, CAR.RIDGELINE: 1200, @@ -172,11 +178,19 @@ class CAR: CAR.CIVIC_BOSCH: 1., CAR.CRV: 1.025, CAR.CRV_5G: 1.025, + CAR.CRV_HYBRID: 1.025, + CAR.FIT: 1., CAR.ODYSSEY: 1., + CAR.ODYSSEY_CHN: 1., CAR.PILOT: 1., CAR.PILOT_2019: 1., CAR.RIDGELINE: 1., } -# TODO: get these from dbc file -HONDA_BOSCH = [CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CRV_5G] +# msgs sent for steering controller by camera module on can 0. +# those messages are mutually exclusive on CRV and non-CRV cars +ECU_FINGERPRINT = { + ECU.CAM: [0xE4, 0x194], # steer torque cmd +} + +HONDA_BOSCH = [CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CRV_5G, CAR.CRV_HYBRID] diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py index 627e27b4c4b012..3942ad73dbca24 100644 --- a/selfdrive/car/hyundai/carcontroller.py +++ b/selfdrive/car/hyundai/carcontroller.py @@ -1,40 +1,59 @@ +from cereal import car from selfdrive.car import apply_std_steer_torque_limits -from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car.hyundai.hyundaican import create_lkas11, create_lkas12, \ create_1191, create_1156, \ create_clu11 -from selfdrive.car.hyundai.values import Buttons +from selfdrive.car.hyundai.values import CAR, Buttons, SteerLimitParams from selfdrive.can.packer import CANPacker -# Steer torque limits +VisualAlert = car.CarControl.HUDControl.VisualAlert -class SteerLimitParams: - STEER_MAX = 255 # 409 is the max, 255 is stock - STEER_DELTA_UP = 3 - STEER_DELTA_DOWN = 7 - STEER_DRIVER_ALLOWANCE = 50 - STEER_DRIVER_MULTIPLIER = 2 - STEER_DRIVER_FACTOR = 1 +def process_hud_alert(enabled, fingerprint, visual_alert, left_line, + right_line, left_lane_depart, right_lane_depart): -class CarController(object): - def __init__(self, dbc_name, car_fingerprint, enable_camera): + hud_alert = 0 + if visual_alert == VisualAlert.steerRequired: + hud_alert = 3 + + # initialize to no line visible + lane_visible = 1 + if left_line and right_line: + if enabled: + lane_visible = 3 + else: + lane_visible = 4 + elif left_line: + lane_visible = 5 + elif right_line: + lane_visible = 6 + + # initialize to no warnings + left_lane_warning = 0 + right_lane_warning = 0 + if left_lane_depart: + left_lane_warning = 1 if fingerprint in [CAR.GENESIS , CAR.GENESIS_G90, CAR.GENESIS_G80] else 2 + if right_lane_depart: + right_lane_warning = 1 if fingerprint in [CAR.GENESIS , CAR.GENESIS_G90, CAR.GENESIS_G80] else 2 + + return hud_alert, lane_visible, left_lane_warning, right_lane_warning + +class CarController(): + def __init__(self, dbc_name, car_fingerprint): self.apply_steer_last = 0 self.car_fingerprint = car_fingerprint self.lkas11_cnt = 0 - self.cnt = 0 - self.last_resume_cnt = 0 - self.enable_camera = enable_camera + self.clu11_cnt = 0 + self.last_resume_frame = 0 + self.last_lead_distance = 0 # True when giraffe switch 2 is low and we need to replace all the camera messages # otherwise we forward the camera msgs and we just replace the lkas cmd signals self.camera_disconnected = False self.packer = CANPacker(dbc_name) - def update(self, sendcan, enabled, CS, actuators, pcm_cancel_cmd, hud_alert): - - if not self.enable_camera: - return + def update(self, enabled, CS, frame, actuators, pcm_cancel_cmd, visual_alert, + left_line, right_line, left_lane_depart, right_lane_depart): ### Steering Torque apply_steer = actuators.steer * SteerLimitParams.STEER_MAX @@ -48,29 +67,47 @@ def update(self, sendcan, enabled, CS, actuators, pcm_cancel_cmd, hud_alert): self.apply_steer_last = apply_steer + hud_alert, lane_visible, left_lane_warning, right_lane_warning =\ + process_hud_alert(enabled, self.car_fingerprint, visual_alert, + left_line, right_line,left_lane_depart, right_lane_depart) + can_sends = [] - self.lkas11_cnt = self.cnt % 0x10 - self.clu11_cnt = self.cnt % 0x10 + self.lkas11_cnt = frame % 0x10 if self.camera_disconnected: - if (self.cnt % 10) == 0: + if (frame % 10) == 0: can_sends.append(create_lkas12()) - if (self.cnt % 50) == 0: + if (frame % 50) == 0: can_sends.append(create_1191()) - if (self.cnt % 7) == 0: + if (frame % 7) == 0: can_sends.append(create_1156()) can_sends.append(create_lkas11(self.packer, self.car_fingerprint, apply_steer, steer_req, self.lkas11_cnt, - enabled, CS.lkas11, hud_alert, keep_stock=(not self.camera_disconnected))) + enabled, CS.lkas11, hud_alert, lane_visible, left_lane_depart, right_lane_depart, + keep_stock=(not self.camera_disconnected))) if pcm_cancel_cmd: - can_sends.append(create_clu11(self.packer, CS.clu11, Buttons.CANCEL)) - elif CS.stopped and (self.cnt - self.last_resume_cnt) > 5: - self.last_resume_cnt = self.cnt - can_sends.append(create_clu11(self.packer, CS.clu11, Buttons.RES_ACCEL)) - - ### Send messages to canbus - sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan').to_bytes()) - - self.cnt += 1 + self.clu11_cnt = frame % 0x10 + can_sends.append(create_clu11(self.packer, CS.clu11, Buttons.CANCEL, self.clu11_cnt)) + + if CS.stopped: + # run only first time when the car stopped + if self.last_lead_distance == 0: + # get the lead distance from the Radar + self.last_lead_distance = CS.lead_distance + self.clu11_cnt = 0 + # when lead car starts moving, create 6 RES msgs + elif CS.lead_distance > self.last_lead_distance and (frame - self.last_resume_frame) > 5: + can_sends.append(create_clu11(self.packer, CS.clu11, Buttons.RES_ACCEL, self.clu11_cnt)) + self.clu11_cnt += 1 + # interval after 6 msgs + if self.clu11_cnt > 5: + self.last_resume_frame = frame + self.clu11_cnt = 0 + # reset lead distnce after the car starts moving + elif self.last_lead_distance != 0: + self.last_lead_distance = 0 + + + return can_sends diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index bd3e63740c1646..661b4275818b6e 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -1,9 +1,10 @@ -from selfdrive.car.hyundai.values import DBC, STEER_THRESHOLD +from cereal import car +from selfdrive.car.hyundai.values import DBC, STEER_THRESHOLD, FEATURES from selfdrive.can.parser import CANParser from selfdrive.config import Conversions as CV from common.kalman.simple_kalman import KF1D -import numpy as np +GearShifter = car.CarState.GearShifter def get_can_parser(CP): @@ -32,7 +33,7 @@ def get_can_parser(CP): ("CYL_PRES", "ESP12", 0), ("CF_Clu_CruiseSwState", "CLU11", 0), - ("CF_Clu_CruiseSwMain" , "CLU11", 0), + ("CF_Clu_CruiseSwMain", "CLU11", 0), ("CF_Clu_SldMainSW", "CLU11", 0), ("CF_Clu_ParityBit1", "CLU11", 0), ("CF_Clu_VanzDecimal" , "CLU11", 0), @@ -44,14 +45,6 @@ def get_can_parser(CP): ("CF_Clu_AmpInfo", "CLU11", 0), ("CF_Clu_AliveCnt1", "CLU11", 0), - ("CF_Clu_InhibitD", "CLU15", 0), - ("CF_Clu_InhibitP", "CLU15", 0), - ("CF_Clu_InhibitN", "CLU15", 0), - ("CF_Clu_InhibitR", "CLU15", 0), - - ("CF_Lvr_Gear","LVR12",0), - ("CUR_GR", "TCU12",0), - ("ACCEnable", "TCS13", 0), ("ACC_REQ", "TCS13", 0), ("DriverBraking", "TCS13", 0), @@ -69,12 +62,9 @@ def get_can_parser(CP): ("CF_Mdps_FailStat", "MDPS12", 0), ("CR_Mdps_OutTq", "MDPS12", 0), - ("VSetDis", "SCC11", 0), - ("SCCInfoDisplay", "SCC11", 0), - ("ACCMode", "SCC12", 1), - ("SAS_Angle", "SAS11", 0), ("SAS_Speed", "SAS11", 0), + ] checks = [ @@ -85,17 +75,50 @@ def get_can_parser(CP): ("TCS13", 50), ("CLU11", 50), ("ESP12", 100), - ("EMS12", 100), ("CGW1", 10), ("CGW4", 5), ("WHL_SPD11", 50), - ("SCC11", 50), - ("SCC12", 50), ("SAS11", 100) ] - + if CP.carFingerprint not in FEATURES["non_scc"]: + signals += [ + ("MainMode_ACC", "SCC11", 0), + ("VSetDis", "SCC11", 0), + ("SCCInfoDisplay", "SCC11", 0), + ("ACC_ObjDist", "SCC11", 0), + ("ACCMode", "SCC12", 1), + ] + checks += [ + ("SCC11", 50), + ("SCC12", 50), + ] + else: + signals += [ + ("CRUISE_LAMP_M", "EMS16", 0), + ("CF_Lvr_CruiseSet", "LVR12", 0), + ] + if CP.carFingerprint in FEATURES["use_cluster_gears"]: + signals += [ + ("CF_Clu_InhibitD", "CLU15", 0), + ("CF_Clu_InhibitP", "CLU15", 0), + ("CF_Clu_InhibitN", "CLU15", 0), + ("CF_Clu_InhibitR", "CLU15", 0), + ] + elif CP.carFingerprint in FEATURES["use_tcu_gears"]: + signals += [ + ("CUR_GR", "TCU12",0), + ] + elif CP.carFingerprint in FEATURES["use_new_gears"]: + signals += [ + ("Gear_Signal", "NEW11", 0), + ] + else: + signals += [ + ("CF_Lvr_Gear","LVR12",0), + ] return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) + def get_camera_parser(CP): signals = [ @@ -121,7 +144,8 @@ def get_camera_parser(CP): return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2) -class CarState(object): + +class CarState(): def __init__(self, CP): self.CP = CP @@ -133,20 +157,18 @@ def __init__(self, CP): dt = 0.01 # Q = np.matrix([[10.0, 0.0], [0.0, 100.0]]) # R = 1e3 - self.v_ego_kf = KF1D(x0=np.matrix([[0.0], [0.0]]), - A=np.matrix([[1.0, dt], [0.0, 1.0]]), - C=np.matrix([1.0, 0.0]), - K=np.matrix([[0.12287673], [0.29666309]])) + self.v_ego_kf = KF1D(x0=[[0.0], [0.0]], + A=[[1.0, dt], [0.0, 1.0]], + C=[1.0, 0.0], + K=[[0.12287673], [0.29666309]]) self.v_ego = 0.0 self.left_blinker_on = 0 self.left_blinker_flash = 0 self.right_blinker_on = 0 self.right_blinker_flash = 0 + self.no_radar = self.CP.carFingerprint in FEATURES["non_scc"] def update(self, cp, cp_cam): - # copy can_valid - self.can_valid = cp.can_valid - # update prevs, update must run once per Loop self.prev_left_blinker_on = self.left_blinker_on self.prev_right_blinker_on = self.right_blinker_on @@ -156,10 +178,12 @@ def update(self, cp, cp_cam): self.brake_pressed = cp.vl["TCS13"]['DriverBraking'] self.esp_disabled = cp.vl["TCS15"]['ESC_Off_Step'] - self.park_brake = cp.vl["CGW1"]['CF_Gway_ParkBrakeSw'] - self.main_on = True - self.acc_active = cp.vl["SCC12"]['ACCMode'] != 0 + + self.main_on = (cp.vl["SCC11"]["MainMode_ACC"] != 0) if not self.no_radar else \ + cp.vl['EMS16']['CRUISE_LAMP_M'] + self.acc_active = (cp.vl["SCC12"]['ACCMode'] != 0) if not self.no_radar else \ + (cp.vl["LVR12"]['CF_Lvr_CruiseSet'] != 0) self.pcm_acc_status = int(self.acc_active) # calc best v_ego estimate, by averaging two opposite corners @@ -173,7 +197,7 @@ def update(self, cp, cp_cam): # Kalman filter, even though Hyundai raw wheel speed is heaviliy filtered by default if abs(v_wheel - self.v_ego) > 2.0: # Prevent large accelerations when car starts at non zero speed - self.v_ego_kf.x = np.matrix([[v_wheel], [0.0]]) + self.v_ego_kf.x = [[v_wheel], [0.0]] self.v_ego_raw = v_wheel v_ego_x = self.v_ego_kf.update(v_wheel) @@ -181,13 +205,13 @@ def update(self, cp, cp_cam): self.a_ego = float(v_ego_x[1]) is_set_speed_in_mph = int(cp.vl["CLU11"]["CF_Clu_SPEED_UNIT"]) speed_conv = CV.MPH_TO_MS if is_set_speed_in_mph else CV.KPH_TO_MS - self.cruise_set_speed = cp.vl["SCC11"]['VSetDis'] * speed_conv + self.cruise_set_speed = cp.vl["SCC11"]['VSetDis'] * speed_conv if not self.no_radar else \ + (cp.vl["LVR12"]["CF_Lvr_CruiseSet"] * speed_conv) self.standstill = not v_wheel > 0.1 self.angle_steers = cp.vl["SAS11"]['SAS_Angle'] self.angle_steers_rate = cp.vl["SAS11"]['SAS_Speed'] self.yaw_rate = cp.vl["ESP12"]['YAW_RATE'] - self.main_on = True self.left_blinker_on = cp.vl["CGW1"]['CF_Gway_TSigLHSw'] self.left_blinker_flash = cp.vl["CGW1"]['CF_Gway_TurnSigLh'] self.right_blinker_on = cp.vl["CGW1"]['CF_Gway_TSigRHSw'] @@ -198,7 +222,8 @@ def update(self, cp, cp_cam): self.brake_error = 0 self.steer_torque_driver = cp.vl["MDPS11"]['CR_Mdps_DrvTq'] self.steer_torque_motor = cp.vl["MDPS12"]['CR_Mdps_OutTq'] - self.stopped = cp.vl["SCC11"]['SCCInfoDisplay'] == 4. + self.stopped = cp.vl["SCC11"]['SCCInfoDisplay'] == 4. if not self.no_radar else False + self.lead_distance = cp.vl["SCC11"]['ACC_ObjDist'] if not self.no_radar else 0 self.user_brake = 0 @@ -210,41 +235,57 @@ def update(self, cp, cp_cam): self.pedal_gas = cp.vl["EMS12"]['TPS'] self.car_gas = cp.vl["EMS12"]['TPS'] + # Gear Selection via Cluster - For those Kia/Hyundai which are not fully discovered, we can use the Cluster Indicator for Gear Selection, as this seems to be standard over all cars, but is not the preferred method. + if self.car_fingerprint in FEATURES["use_cluster_gears"]: + if cp.vl["CLU15"]["CF_Clu_InhibitD"] == 1: + self.gear_shifter = GearShifter.drive + elif cp.vl["CLU15"]["CF_Clu_InhibitN"] == 1: + self.gear_shifter = GearShifter.neutral + elif cp.vl["CLU15"]["CF_Clu_InhibitP"] == 1: + self.gear_shifter = GearShifter.park + elif cp.vl["CLU15"]["CF_Clu_InhibitR"] == 1: + self.gear_shifter = GearShifter.reverse + else: + self.gear_shifter = GearShifter.unknown + # Gear Selecton via TCU12 + elif self.car_fingerprint in FEATURES["use_tcu_gears"]: + gear = cp.vl["TCU12"]["CUR_GR"] + if gear == 0: + self.gear_shifter = GearShifter.park + elif gear == 14: + self.gear_shifter = GearShifter.reverse + elif gear > 0 and gear < 9: # unaware of anything over 8 currently + self.gear_shifter = GearShifter.drive + else: + self.gear_shifter = GearShifter.unknown + # Gear Selecton - This is only compatible with optima hybrid 2017 + elif self.car_fingerprint in FEATURES["use_new_gears"]: + gear = cp.vl["NEW11"]["Gear_Signal"] + if gear == 5: + self.gear_shifter = GearShifter.drive + elif gear == 6: + self.gear_shifter = GearShifter.neutral + elif gear == 0: + self.gear_shifter = GearShifter.park + elif gear == 7: + self.gear_shifter = GearShifter.reverse + else: + self.gear_shifter = GearShifter.unknown # Gear Selecton - This is not compatible with all Kia/Hyundai's, But is the best way for those it is compatible with - gear = cp.vl["LVR12"]["CF_Lvr_Gear"] - if gear == 5: - self.gear_shifter = "drive" - elif gear == 6: - self.gear_shifter = "neutral" - elif gear == 0: - self.gear_shifter = "park" - elif gear == 7: - self.gear_shifter = "reverse" else: - self.gear_shifter = "unknown" + gear = cp.vl["LVR12"]["CF_Lvr_Gear"] + if gear == 5: + self.gear_shifter = GearShifter.drive + elif gear == 6: + self.gear_shifter = GearShifter.neutral + elif gear == 0: + self.gear_shifter = GearShifter.park + elif gear == 7: + self.gear_shifter = GearShifter.reverse + else: + self.gear_shifter = GearShifter.unknown - # Gear Selection via Cluster - For those Kia/Hyundai which are not fully discovered, we can use the Cluster Indicator for Gear Selection, as this seems to be standard over all cars, but is not the preferred method. - if cp.vl["CLU15"]["CF_Clu_InhibitD"] == 1: - self.gear_shifter_cluster = "drive" - elif cp.vl["CLU15"]["CF_Clu_InhibitN"] == 1: - self.gear_shifter_cluster = "neutral" - elif cp.vl["CLU15"]["CF_Clu_InhibitP"] == 1: - self.gear_shifter_cluster = "park" - elif cp.vl["CLU15"]["CF_Clu_InhibitR"] == 1: - self.gear_shifter_cluster = "reverse" - else: - self.gear_shifter_cluster = "unknown" - # Gear Selecton via TCU12 - gear2 = cp.vl["TCU12"]["CUR_GR"] - if gear2 == 0: - self.gear_tcu = "park" - elif gear2 == 14: - self.gear_tcu = "reverse" - elif gear2 > 0 and gear2 < 9: # unaware of anything over 8 currently - self.gear_tcu = "drive" - else: - self.gear_tcu = "unknown" # save the entire LKAS11 and CLU11 self.lkas11 = cp_cam.vl["LKAS11"] diff --git a/selfdrive/car/hyundai/hyundaican.py b/selfdrive/car/hyundai/hyundaican.py index 5a895497a1865f..342ec7b0bc9ec9 100644 --- a/selfdrive/car/hyundai/hyundaican.py +++ b/selfdrive/car/hyundai/hyundaican.py @@ -1,18 +1,19 @@ import crcmod -from selfdrive.car.hyundai.values import CHECKSUM +from selfdrive.car.hyundai.values import CAR, CHECKSUM hyundai_checksum = crcmod.mkCrcFun(0x11D, initCrc=0xFD, rev=False, xorOut=0xdf) def make_can_msg(addr, dat, alt): return [addr, 0, dat, alt] -def create_lkas11(packer, car_fingerprint, apply_steer, steer_req, cnt, enabled, lkas11, hud_alert, keep_stock=False): +def create_lkas11(packer, car_fingerprint, apply_steer, steer_req, cnt, enabled, lkas11, hud_alert, + lane_visible, left_lane_depart, right_lane_depart, keep_stock=False): values = { - "CF_Lkas_Icon": 3 if enabled else 0, - "CF_Lkas_LdwsSysState": 3 if steer_req else 1, + "CF_Lkas_Bca_R": 3 if enabled else 0, + "CF_Lkas_LdwsSysState": lane_visible, "CF_Lkas_SysWarning": hud_alert, - "CF_Lkas_LdwsLHWarning": lkas11["CF_Lkas_LdwsLHWarning"] if keep_stock else 0, - "CF_Lkas_LdwsRHWarning": lkas11["CF_Lkas_LdwsRHWarning"] if keep_stock else 0, + "CF_Lkas_LdwsLHWarning": left_lane_depart, + "CF_Lkas_LdwsRHWarning": right_lane_depart, "CF_Lkas_HbaLamp": lkas11["CF_Lkas_HbaLamp"] if keep_stock else 0, "CF_Lkas_FcwBasReq": lkas11["CF_Lkas_FcwBasReq"] if keep_stock else 0, "CR_Lkas_StrToqReq": apply_steer, @@ -30,19 +31,24 @@ def create_lkas11(packer, car_fingerprint, apply_steer, steer_req, cnt, enabled, "CF_Lkas_LdwsOpt_USM": lkas11["CF_Lkas_LdwsOpt_USM"] if keep_stock else 3, } + if car_fingerprint == CAR.GENESIS: + values["CF_Lkas_Bca_R"] = 2 + values["CF_Lkas_HbaSysState"] = lkas11["CF_Lkas_HbaSysState"] if keep_stock else 0 + values["CF_Lkas_HbaOpt"] = lkas11["CF_Lkas_HbaOpt"] if keep_stock else 1 + values["CF_Lkas_FcwOpt_USM"] = lkas11["CF_Lkas_FcwOpt_USM"] if keep_stock else 2 + values["CF_Lkas_LdwsOpt_USM"] = lkas11["CF_Lkas_LdwsOpt_USM"] if keep_stock else 0 + dat = packer.make_can_msg("LKAS11", 0, values)[2] if car_fingerprint in CHECKSUM["crc8"]: # CRC Checksum as seen on 2019 Hyundai Santa Fe - dat = dat[:6] + dat[7] + dat = dat[:6] + dat[7:8] checksum = hyundai_checksum(dat) elif car_fingerprint in CHECKSUM["6B"]: # Checksum of first 6 Bytes, as seen on 2018 Kia Sorento - dat = [ord(i) for i in dat] checksum = sum(dat[:6]) % 256 - elif car_fingerprint in CHECKSUM["7B"]: + else: # Checksum of first 6 Bytes and last Byte as seen on 2018 Kia Stinger - dat = [ord(i) for i in dat] checksum = (sum(dat[:6]) + dat[7]) % 256 values["CF_Lkas_Chksum"] = checksum @@ -50,17 +56,17 @@ def create_lkas11(packer, car_fingerprint, apply_steer, steer_req, cnt, enabled, return packer.make_can_msg("LKAS11", 0, values) def create_lkas12(): - return make_can_msg(1342, "\x00\x00\x00\x00\x60\x05", 0) + return make_can_msg(1342, b"\x00\x00\x00\x00\x60\x05", 0) def create_1191(): - return make_can_msg(1191, "\x01\x00", 0) + return make_can_msg(1191, b"\x01\x00", 0) def create_1156(): - return make_can_msg(1156, "\x08\x20\xfe\x3f\x00\xe0\xfd\x3f", 0) + return make_can_msg(1156, b"\x08\x20\xfe\x3f\x00\xe0\xfd\x3f", 0) -def create_clu11(packer, clu11, button): +def create_clu11(packer, clu11, button, cnt): values = { "CF_Clu_CruiseSwState": button, "CF_Clu_CruiseSwMain": clu11["CF_Clu_CruiseSwMain"], @@ -73,7 +79,7 @@ def create_clu11(packer, clu11, button): "CF_Clu_RheostatLevel": clu11["CF_Clu_RheostatLevel"], "CF_Clu_CluInfo": clu11["CF_Clu_CluInfo"], "CF_Clu_AmpInfo": clu11["CF_Clu_AmpInfo"], - "CF_Clu_AliveCnt1": 0, + "CF_Clu_AliveCnt1": cnt, } return packer.make_can_msg("CLU11", 0, values) diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index d7fc2bd394774e..a7c30c04bc7737 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -1,29 +1,24 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from cereal import car -from common.realtime import sec_since_boot from selfdrive.config import Conversions as CV from selfdrive.controls.lib.drive_helpers import EventTypes as ET, create_event from selfdrive.controls.lib.vehicle_model import VehicleModel from selfdrive.car.hyundai.carstate import CarState, get_can_parser, get_camera_parser -from selfdrive.car.hyundai.values import CAMERA_MSGS, CAR, get_hud_alerts, FEATURES +from selfdrive.car.hyundai.values import ECU, ECU_FINGERPRINT, CAR, FINGERPRINTS +from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint +from selfdrive.car.interfaces import CarInterfaceBase -try: - from selfdrive.car.hyundai.carcontroller import CarController -except ImportError: - CarController = None +GearShifter = car.CarState.GearShifter +ButtonType = car.CarState.ButtonEvent.Type - -class CarInterface(object): - def __init__(self, CP, sendcan=None): +class CarInterface(CarInterfaceBase): + def __init__(self, CP, CarController): self.CP = CP self.VM = VehicleModel(CP) - self.idx = 0 - self.lanes = 0 - self.lkas_request = 0 + self.frame = 0 self.gas_pressed_prev = False self.brake_pressed_prev = False - self.can_invalid_count = 0 self.cruise_enabled_prev = False self.low_speed_alert = False @@ -32,124 +27,140 @@ def __init__(self, CP, sendcan=None): self.cp = get_can_parser(CP) self.cp_cam = get_camera_parser(CP) - # sending if read only is False - if sendcan is not None: - self.sendcan = sendcan - self.CC = CarController(self.cp.dbc_name, CP.carFingerprint, CP.enableCamera) + self.CC = None + if CarController is not None: + self.CC = CarController(self.cp.dbc_name, CP.carFingerprint) @staticmethod def compute_gb(accel, speed): return float(accel) / 3.0 @staticmethod - def calc_accel_override(a_ego, a_target, v_ego, v_target): - return 1.0 - - @staticmethod - def get_params(candidate, fingerprint): - - # kg of standard extra cargo to count for drive, gas, etc... - std_cargo = 136 + def get_params(candidate, fingerprint=gen_empty_fingerprint(), vin="", has_relay=False): ret = car.CarParams.new_message() ret.carName = "hyundai" ret.carFingerprint = candidate - ret.radarOffCan = True - ret.safetyModel = car.CarParams.SafetyModels.hyundai + ret.carVin = vin + ret.isPandaBlack = has_relay + ret.safetyModel = car.CarParams.SafetyModel.hyundai ret.enableCruise = True # stock acc - # FIXME: hardcoding honda civic 2016 touring params so they can be used to - # scale unknown params for other cars - mass_civic = 2923 * CV.LB_TO_KG + std_cargo - wheelbase_civic = 2.70 - centerToFront_civic = wheelbase_civic * 0.4 - centerToRear_civic = wheelbase_civic - centerToFront_civic - rotationalInertia_civic = 2500 - tireStiffnessFront_civic = 192150 - tireStiffnessRear_civic = 202500 - ret.steerActuatorDelay = 0.1 # Default delay + ret.steerRateCost = 0.5 tire_stiffness_factor = 1. - if candidate == CAR.SANTA_FE: - ret.steerKf = 0.00005 - ret.steerRateCost = 0.5 - ret.mass = 3982 * CV.LB_TO_KG + std_cargo + if candidate in [CAR.SANTA_FE, CAR.SANTA_FE_1]: + ret.lateralTuning.pid.kf = 0.00005 + ret.mass = 3982. * CV.LB_TO_KG + STD_CARGO_KG ret.wheelbase = 2.766 - # Values from optimizer ret.steerRatio = 16.55 # 13.8 is spec end-to-end tire_stiffness_factor = 0.82 - - ret.steerKiBP, ret.steerKpBP = [[9., 22.], [9., 22.]] - ret.steerKpV, ret.steerKiV = [[0.2, 0.35], [0.05, 0.09]] + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[9., 22.], [9., 22.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2, 0.35], [0.05, 0.09]] ret.minSteerSpeed = 0. elif candidate == CAR.KIA_SORENTO: - ret.steerKf = 0.00005 - ret.mass = 1985 + std_cargo + ret.lateralTuning.pid.kf = 0.00005 + ret.mass = 1985. + STD_CARGO_KG ret.wheelbase = 2.78 ret.steerRatio = 14.4 * 1.1 # 10% higher at the center seems reasonable - ret.steerKiBP, ret.steerKpBP = [[0.], [0.]] - ret.steerKpV, ret.steerKiV = [[0.25], [0.05]] + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] ret.minSteerSpeed = 0. - elif candidate == CAR.ELANTRA: - ret.steerKf = 0.00006 - ret.mass = 1275 + std_cargo + elif candidate in [CAR.ELANTRA, CAR.ELANTRA_GT_I30]: + ret.lateralTuning.pid.kf = 0.00006 + ret.mass = 1275. + STD_CARGO_KG ret.wheelbase = 2.7 ret.steerRatio = 13.73 #Spec tire_stiffness_factor = 0.385 - ret.steerKiBP, ret.steerKpBP = [[0.], [0.]] - ret.steerKpV, ret.steerKiV = [[0.25], [0.05]] + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] ret.minSteerSpeed = 32 * CV.MPH_TO_MS elif candidate == CAR.GENESIS: - ret.steerKf = 0.00005 - ret.mass = 2060 + std_cargo + ret.lateralTuning.pid.kf = 0.00005 + ret.mass = 2060. + STD_CARGO_KG ret.wheelbase = 3.01 ret.steerRatio = 16.5 - ret.steerKiBP, ret.steerKpBP = [[0.], [0.]] - ret.steerKpV, ret.steerKiV = [[0.16], [0.01]] - ret.minSteerSpeed = 35 * CV.MPH_TO_MS - elif candidate == CAR.KIA_OPTIMA: - ret.steerKf = 0.00005 - ret.mass = 3558 * CV.LB_TO_KG + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.16], [0.01]] + ret.minSteerSpeed = 60 * CV.KPH_TO_MS + elif candidate in [CAR.GENESIS_G90, CAR.GENESIS_G80]: + ret.mass = 2200 + ret.wheelbase = 3.15 + ret.steerRatio = 12.069 + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.16], [0.01]] + elif candidate in [CAR.KIA_OPTIMA, CAR.KIA_OPTIMA_H]: + ret.lateralTuning.pid.kf = 0.00005 + ret.mass = 3558. * CV.LB_TO_KG ret.wheelbase = 2.80 ret.steerRatio = 13.75 tire_stiffness_factor = 0.5 - ret.steerKiBP, ret.steerKpBP = [[0.], [0.]] - ret.steerKpV, ret.steerKiV = [[0.25], [0.05]] + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] elif candidate == CAR.KIA_STINGER: - ret.steerKf = 0.00005 - ret.mass = 1825 + std_cargo + ret.lateralTuning.pid.kf = 0.00005 + ret.mass = 1825. + STD_CARGO_KG ret.wheelbase = 2.78 ret.steerRatio = 14.4 * 1.15 # 15% higher at the center seems reasonable - ret.steerKiBP, ret.steerKpBP = [[0.], [0.]] - ret.steerKpV, ret.steerKiV = [[0.25], [0.05]] + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] ret.minSteerSpeed = 0. + elif candidate == CAR.KONA: + ret.lateralTuning.pid.kf = 0.00006 + ret.mass = 1275. + STD_CARGO_KG + ret.wheelbase = 2.7 + ret.steerRatio = 13.73 #Spec + tire_stiffness_factor = 0.385 + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] + elif candidate == CAR.IONIQ: + ret.lateralTuning.pid.kf = 0.00006 + ret.mass = 1275. + STD_CARGO_KG + ret.wheelbase = 2.7 + ret.steerRatio = 13.73 #Spec + tire_stiffness_factor = 0.385 + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] + elif candidate == CAR.IONIQ_EV_LTD: + ret.lateralTuning.pid.kf = 0.00006 + ret.mass = 1490. + STD_CARGO_KG #weight per hyundai site https://www.hyundaiusa.com/ioniq-electric/specifications.aspx + ret.wheelbase = 2.7 + ret.steerRatio = 13.73 #Spec + tire_stiffness_factor = 0.385 + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] + ret.minSteerSpeed = 32 * CV.MPH_TO_MS + elif candidate == CAR.KIA_FORTE: + ret.lateralTuning.pid.kf = 0.00005 + ret.mass = 3558. * CV.LB_TO_KG + ret.wheelbase = 2.80 + ret.steerRatio = 13.75 + tire_stiffness_factor = 0.5 + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.25], [0.05]] + ret.minEnableSpeed = -1. # enable is done by stock ACC, so ignore this - ret.longitudinalKpBP = [0.] - ret.longitudinalKpV = [0.] - ret.longitudinalKiBP = [0.] - ret.longitudinalKiV = [0.] + ret.longitudinalTuning.kpBP = [0.] + ret.longitudinalTuning.kpV = [0.] + ret.longitudinalTuning.kiBP = [0.] + ret.longitudinalTuning.kiV = [0.] + ret.longitudinalTuning.deadzoneBP = [0.] + ret.longitudinalTuning.deadzoneV = [0.] ret.centerToFront = ret.wheelbase * 0.4 - centerToRear = ret.wheelbase - ret.centerToFront - # TODO: get actual value, for now starting with reasonable value for # civic and scaling by mass and wheelbase - ret.rotationalInertia = rotationalInertia_civic * \ - ret.mass * ret.wheelbase**2 / (mass_civic * wheelbase_civic**2) + ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) # TODO: start from empirically derived lateral slip stiffness for the civic and scale by # mass and CG position, so all cars will have approximately similar dyn behaviors - ret.tireStiffnessFront = (tireStiffnessFront_civic * tire_stiffness_factor) * \ - ret.mass / mass_civic * \ - (centerToRear / ret.wheelbase) / (centerToRear_civic / wheelbase_civic) - ret.tireStiffnessRear = (tireStiffnessRear_civic * tire_stiffness_factor) * \ - ret.mass / mass_civic * \ - (ret.centerToFront / ret.wheelbase) / (centerToFront_civic / wheelbase_civic) + ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, + tire_stiffness_factor=tire_stiffness_factor) # no rear steering, at least on the listed cars above @@ -163,10 +174,8 @@ def get_params(candidate, fingerprint): ret.gasMaxV = [1.] ret.brakeMaxBP = [0.] ret.brakeMaxV = [1.] - ret.longPidDeadzoneBP = [0.] - ret.longPidDeadzoneV = [0.] - ret.enableCamera = not any(x for x in CAMERA_MSGS if x in fingerprint) + ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, ECU.CAM) or has_relay ret.openpilotLongitudinalControl = False ret.steerLimitAlert = False @@ -176,14 +185,17 @@ def get_params(candidate, fingerprint): return ret # returns a car.CarState - def update(self, c): + def update(self, c, can_strings): # ******************* do can recv ******************* - canMonoTimes = [] - self.cp.update(int(sec_since_boot() * 1e9), False) - self.cp_cam.update(int(sec_since_boot() * 1e9), False) + self.cp.update_strings(can_strings) + self.cp_cam.update_strings(can_strings) + self.CS.update(self.cp, self.cp_cam) # create message ret = car.CarState.new_message() + + ret.canValid = self.cp.can_valid # TODO: check cp_cam validity + # speeds ret.vEgo = self.CS.v_ego ret.vEgoRaw = self.CS.v_ego_raw @@ -196,12 +208,7 @@ def update(self, c): ret.wheelSpeeds.rr = self.CS.v_wheel_rr # gear shifter - if self.CP.carFingerprint in FEATURES["use_cluster_gears"]: - ret.gearShifter = self.CS.gear_shifter_cluster - elif self.CP.carFingerprint in FEATURES["use_tcu_gears"]: - ret.gearShifter = self.CS.gear_tcu - else: - ret.gearShifter = self.CS.gear_shifter + ret.gearShifter = self.CS.gear_shifter # gas pedal ret.gas = self.CS.car_gas @@ -233,13 +240,13 @@ def update(self, c): if self.CS.left_blinker_on != self.CS.prev_left_blinker_on: be = car.CarState.ButtonEvent.new_message() - be.type = 'leftBlinker' + be.type = ButtonType.leftBlinker be.pressed = self.CS.left_blinker_on != 0 buttonEvents.append(be) if self.CS.right_blinker_on != self.CS.prev_right_blinker_on: be = car.CarState.ButtonEvent.new_message() - be.type = 'rightBlinker' + be.type = ButtonType.rightBlinker be.pressed = self.CS.right_blinker_on != 0 buttonEvents.append(be) @@ -250,22 +257,14 @@ def update(self, c): ret.doorOpen = not self.CS.door_all_closed ret.seatbeltUnlatched = not self.CS.seatbelt - # low speed steer alert hysteresis logic (only for cars with steer cut off above 10 m/s) - if ret.vEgo < (self.CP.minSteerSpeed + 2.) and self.CP.minSteerSpeed > 10.: - self.low_speed_alert = True - if ret.vEgo > (self.CP.minSteerSpeed + 4.): + if ret.vEgo < (self.CP.minSteerSpeed + 0.2) and self.CP.minSteerSpeed > 10.: + self.low_speed_alert = True + if ret.vEgo > (self.CP.minSteerSpeed + 0.7): self.low_speed_alert = False - # events events = [] - if not self.CS.can_valid: - self.can_invalid_count += 1 - if self.can_invalid_count >= 5: - events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) - else: - self.can_invalid_count = 0 - if not ret.gearShifter == 'drive': + if not ret.gearShifter == GearShifter.drive: events.append(create_event('wrongGear', [ET.NO_ENTRY, ET.SOFT_DISABLE])) if ret.doorOpen: events.append(create_event('doorOpen', [ET.NO_ENTRY, ET.SOFT_DISABLE])) @@ -275,12 +274,11 @@ def update(self, c): events.append(create_event('espDisabled', [ET.NO_ENTRY, ET.SOFT_DISABLE])) if not self.CS.main_on: events.append(create_event('wrongCarMode', [ET.NO_ENTRY, ET.USER_DISABLE])) - if ret.gearShifter == 'reverse': + if ret.gearShifter == GearShifter.reverse: events.append(create_event('reverseGear', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) if self.CS.steer_error: events.append(create_event('steerTempUnavailable', [ET.NO_ENTRY, ET.WARNING])) - # enable request in prius is simple, as we activate when Toyota is active (rising edge) if ret.cruiseState.enabled and not self.cruise_enabled_prev: events.append(create_event('pcmEnable', [ET.ENABLE])) elif not ret.cruiseState.enabled: @@ -298,7 +296,6 @@ def update(self, c): events.append(create_event('belowSteerSpeed', [ET.WARNING])) ret.events = events - ret.canMonoTimes = canMonoTimes self.gas_pressed_prev = ret.gasPressed self.brake_pressed_prev = ret.brakePressed @@ -307,10 +304,13 @@ def update(self, c): return ret.as_reader() def apply(self, c): - - hud_alert = get_hud_alerts(c.hudControl.visualAlert, c.hudControl.audibleAlert) - - self.CC.update(self.sendcan, c.enabled, self.CS, c.actuators, - c.cruiseControl.cancel, hud_alert) - - return False + + # Fix for Genesis hard fault when steer request sent while the speed is low + enable = 0 if self.CS.v_ego < self.CP.minSteerSpeed and self.CP.carFingerprint == CAR.GENESIS else c.enabled + + can_sends = self.CC.update(enable, self.CS, self.frame, c.actuators, + c.cruiseControl.cancel, c.hudControl.visualAlert, c.hudControl.leftLaneVisible, + c.hudControl.rightLaneVisible, c.hudControl.leftLaneDepart, c.hudControl.rightLaneDepart) + + self.frame += 1 + return can_sends diff --git a/selfdrive/car/hyundai/radar_interface.py b/selfdrive/car/hyundai/radar_interface.py index 96159fd87d9535..5b16c99319a35a 100644 --- a/selfdrive/car/hyundai/radar_interface.py +++ b/selfdrive/car/hyundai/radar_interface.py @@ -1,24 +1,77 @@ -#!/usr/bin/env python -from cereal import car +#!/usr/bin/env python3 +import os import time +from cereal import car +from selfdrive.can.parser import CANParser +from selfdrive.car.interfaces import RadarInterfaceBase +from selfdrive.car.hyundai.values import DBC, FEATURES + +def get_radar_can_parser(CP): + signals = [ + # sig_name, sig_address, default + ("ACC_ObjStatus", "SCC11", 0), + ("ACC_ObjLatPos", "SCC11", 0), + ("ACC_ObjDist", "SCC11", 0), + ("ACC_ObjRelSpd", "SCC11", 0), + ] + checks = [ + # address, frequency + ("SCC11", 50), + ] + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) -class RadarInterface(object): +class RadarInterface(RadarInterfaceBase): def __init__(self, CP): # radar self.pts = {} - self.delay = 0.1 + self.delay = 0 # Delay of radar + self.rcp = get_radar_can_parser(CP) + self.updated_messages = set() + self.trigger_msg = 0x420 + self.track_id = 0 + self.no_radar = CP.carFingerprint in FEATURES["non_scc"] - def update(self): + def update(self, can_strings): + if self.no_radar: + if 'NO_RADAR_SLEEP' not in os.environ: + time.sleep(0.05) # radard runs on RI updates - ret = car.RadarState.new_message() - time.sleep(0.05) # radard runs on RI updates + return car.RadarData.new_message() + + vls = self.rcp.update_strings(can_strings) + self.updated_messages.update(vls) - return ret + if self.trigger_msg not in self.updated_messages: + return None + + rr = self._update(self.updated_messages) + self.updated_messages.clear() -if __name__ == "__main__": - RI = RadarInterface(None) - while 1: - ret = RI.update() - print(chr(27) + "[2J") - print ret + return rr + + + def _update(self, updated_messages): + ret = car.RadarData.new_message() + cpt = self.rcp.vl + errors = [] + if not self.rcp.can_valid: + errors.append("canError") + ret.errors = errors + + valid = cpt["SCC11"]['ACC_ObjStatus'] + if valid: + for ii in range(2): + if ii not in self.pts: + self.pts[ii] = car.RadarData.RadarPoint.new_message() + self.pts[ii].trackId = self.track_id + self.track_id += 1 + self.pts[ii].dRel = cpt["SCC11"]['ACC_ObjDist'] # from front of car + self.pts[ii].yRel = -cpt["SCC11"]['ACC_ObjLatPos'] # in car frame's y axis, left is negative + self.pts[ii].vRel = cpt["SCC11"]['ACC_ObjRelSpd'] + self.pts[ii].aRel = float('nan') + self.pts[ii].yvRel = float('nan') + self.pts[ii].measured = True + + ret.points = list(self.pts.values()) + return ret diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 1756976e94aa13..266b2d49ef47c6 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -1,22 +1,31 @@ -from cereal import car from selfdrive.car import dbc_dict -VisualAlert = car.CarControl.HUDControl.VisualAlert -AudibleAlert = car.CarControl.HUDControl.AudibleAlert +# Steer torque limits -def get_hud_alerts(visual_alert, audible_alert): - if visual_alert == VisualAlert.steerRequired: - return 4 if audible_alert != AudibleAlert.none else 5 - else: - return 0 +class SteerLimitParams: + STEER_MAX = 255 # 409 is the max, 255 is stock + STEER_DELTA_UP = 3 + STEER_DELTA_DOWN = 7 + STEER_DRIVER_ALLOWANCE = 50 + STEER_DRIVER_MULTIPLIER = 2 + STEER_DRIVER_FACTOR = 1 class CAR: ELANTRA = "HYUNDAI ELANTRA LIMITED ULTIMATE 2017" GENESIS = "HYUNDAI GENESIS 2018" - KIA_OPTIMA = "KIA OPTIMA SX 2019" + KIA_OPTIMA = "KIA OPTIMA SX 2019 & 2016" + KIA_OPTIMA_H = "KIA OPTIMA HYBRID 2017 & SPORTS 2019" KIA_SORENTO = "KIA SORENTO GT LINE 2018" KIA_STINGER = "KIA STINGER GT2 2018" SANTA_FE = "HYUNDAI SANTA FE LIMITED 2019" + SANTA_FE_1 = "HYUNDAI SANTA FE has no scc" + KONA = "HYUNDAI KONA 2019" + GENESIS_G90 = "GENESIS G90 2017" + GENESIS_G80 = "GENESIS G80 2017" + IONIQ = "HYUNDAI IONIQ HYBRID 2017 PREMIUM" + IONIQ_EV_LTD = "HYUNDAI IONIQ ELECTRIC 2019 LIMITED" + KIA_FORTE = "KIA FORTE E 2018" + ELANTRA_GT_I30 = "HYUNDAI I30 N LINE 2019 & GT 2018 DCT" class Buttons: NONE = 0 @@ -26,16 +35,22 @@ class Buttons: FINGERPRINTS = { CAR.ELANTRA: [{ - 66: 8, 67: 8, 68: 8, 127: 8, 273: 8, 274: 8, 275: 8, 339: 8, 356: 4, 399: 8, 512: 6, 544: 8, 593: 8, 608: 8, 688: 5, 790: 8, 809: 8, 897: 8, 899: 8, 902: 8, 903: 8, 905: 8, 909: 8, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1170: 8, 1265: 4, 1280: 1, 1282: 4, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1314: 8, 1322: 8, 1345: 8, 1349: 8, 1351: 8, 1353: 8, 1363: 8, 1366: 8, 1367: 8, 1369: 8, 1407: 8, 1415: 8, 1419: 8, 1425: 2, 1427: 6, 1440: 8, 1456: 4, 1472: 8, 1486: 8, 1487: 8, 1491: 8, 1530: 8, 1532: 5, 2001: 8, 2003: 8, 2004: 8, 2009: 8, 2012: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8 + 66: 8, 67: 8, 68: 8, 127: 8, 273: 8, 274: 8, 275: 8, 339: 8, 356: 4, 399: 8, 512: 6, 544: 8, 593: 8, 608: 8, 688: 5, 790: 8, 809: 8, 897: 8, 832: 8, 899: 8, 902: 8, 903: 8, 905: 8, 909: 8, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1170: 8, 1265: 4, 1280: 1, 1282: 4, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1314: 8, 1322: 8, 1345: 8, 1349: 8, 1351: 8, 1353: 8, 1363: 8, 1366: 8, 1367: 8, 1369: 8, 1407: 8, 1415: 8, 1419: 8, 1425: 2, 1427: 6, 1440: 8, 1456: 4, 1472: 8, 1486: 8, 1487: 8, 1491: 8, 1530: 8, 1532: 5, 2001: 8, 2003: 8, 2004: 8, 2009: 8, 2012: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8 }], CAR.GENESIS: [{ 67: 8, 68: 8, 304: 8, 320: 8, 339: 8, 356: 4, 544: 7, 593: 8, 608: 8, 688: 5, 809: 8, 832: 8, 854: 7, 870: 7, 871: 8, 872: 5, 897: 8, 902: 8, 903: 6, 916: 8, 1024: 2, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1107: 5, 1136: 8, 1151: 6, 1168: 7, 1170: 8, 1173: 8, 1184: 8, 1265: 4, 1280: 1, 1287: 4, 1292: 8, 1312: 8, 1322: 8, 1331: 8, 1332: 8, 1333: 8, 1334: 8, 1335: 8, 1342: 6, 1345: 8, 1363: 8, 1369: 8, 1370: 8, 1371: 8, 1378: 4, 1384: 5, 1407: 8, 1419: 8, 1427: 6, 1434: 2, 1456: 4 }, { 67: 8, 68: 8, 304: 8, 320: 8, 339: 8, 356: 4, 544: 7, 593: 8, 608: 8, 688: 5, 809: 8, 832: 8, 854: 7, 870: 7, 871: 8, 872: 5, 897: 8, 902: 8, 903: 6, 916: 8, 1024: 2, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1107: 5, 1136: 8, 1151: 6, 1168: 7, 1170: 8, 1173: 8, 1184: 8, 1265: 4, 1280: 1, 1281: 3, 1287: 4, 1292: 8, 1312: 8, 1322: 8, 1331: 8, 1332: 8, 1333: 8, 1334: 8, 1335: 8, 1345: 8, 1363: 8, 1369: 8, 1370: 8, 1378: 4, 1379: 8, 1384: 5, 1407: 8, 1419: 8, 1427: 6, 1434: 2, 1456: 4 + }, + { + 67: 8, 68: 8, 304: 8, 320: 8, 339: 8, 356: 4, 544: 7, 593: 8, 608: 8, 688: 5, 809: 8, 854: 7, 870: 7, 871: 8, 872: 5, 897: 8, 902: 8, 903: 6, 912: 7, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1107: 5, 1136: 8, 1151: 6, 1168: 7, 1170: 8, 1173: 8, 1184: 8, 1265: 4, 1268: 8, 1280: 1, 1281: 3, 1287: 4, 1292: 8, 1312: 8, 1322: 8, 1331: 8, 1332: 8, 1333: 8, 1334: 8, 1335: 8, 1345: 8, 1363: 8, 1369: 8, 1370: 8, 1371: 8, 1378: 4, 1384: 5, 1407: 8, 1419: 8, 1427: 6, 1434: 2, 1437: 8, 1456: 4 }], CAR.KIA_OPTIMA: [{ 64: 8, 66: 8, 67: 8, 68: 8, 127: 8, 273: 8, 274: 8, 275: 8, 339: 8, 356: 4, 399: 8, 447: 8, 512: 6, 544: 8, 593: 8, 608: 8, 688: 5, 790: 8, 809: 8, 832: 8, 884: 8, 897: 8, 899: 8, 902: 8, 903: 6, 909: 8, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1151: 6, 1168: 7, 1170: 8, 1186: 2, 1191: 2, 1253: 8, 1254: 8, 1255: 8, 1265: 4, 1280: 1, 1282: 4, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1331: 8, 1332: 8, 1333: 8, 1342: 6, 1345: 8, 1348: 8, 1349: 8, 1351: 8, 1353: 8, 1363: 8, 1365: 8, 1366: 8, 1367: 8, 1369: 8, 1407: 8, 1414: 3, 1415: 8, 1419: 8, 1425: 2, 1427: 6, 1440: 8, 1456: 4, 1470: 8, 1472: 8, 1486: 8, 1487: 8, 1491: 8, 1530: 8, 1532: 5, 1952: 8, 1960: 8, 1988: 8, 1996: 8, 2001: 8, 2004: 8, 2008: 8, 2009: 8, 2012: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8 + }, + { + 64: 8, 66: 8, 67: 8, 68: 8, 127: 8, 128: 8, 129: 8, 273: 8, 274: 8, 275: 8, 339: 8, 354: 3, 356: 4, 399: 8, 512: 6, 544: 8, 593: 8, 608: 8, 688: 5, 790: 8, 809: 8, 832: 8, 897: 8, 899: 8, 902: 8, 903: 6, 912: 7, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1151: 6, 1168: 7, 1170: 8, 1265: 4, 1268: 8, 1280: 1, 1282: 4, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1331: 8, 1332: 8, 1333: 8, 1342: 6, 1345: 8, 1348: 8, 1349: 8, 1351: 8, 1353: 8, 1356: 8, 1363: 8, 1365: 8, 1366: 8, 1367: 8, 1369: 8, 1407: 8, 1419: 8, 1425: 2, 1427: 6, 1440: 8, 1456: 4, 1470: 8, 1472: 8, 1491: 8, 1492: 8 }], CAR.KIA_SORENTO: [{ 67: 8, 68: 8, 127: 8, 304: 8, 320: 8, 339: 8, 356: 4, 544: 8, 593: 8, 608: 8, 688: 5, 809: 8, 832: 8, 854: 7, 870: 7, 871: 8, 872: 8, 897: 8, 902: 8, 903: 8, 916: 8, 1040: 8, 1042: 8, 1056: 8, 1057: 8, 1064: 8, 1078: 4, 1107: 5, 1136: 8, 1151: 6, 1168: 7, 1170: 8, 1173: 8, 1265: 4, 1280: 1, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1331: 8, 1332: 8, 1333: 8, 1342: 6, 1345: 8, 1348: 8, 1363: 8, 1369: 8, 1370: 8, 1371: 8, 1384: 8, 1407: 8, 1411: 8, 1419: 8, 1425: 2, 1427: 6, 1444: 8, 1456: 4, 1470: 8, 1489: 1 @@ -48,30 +63,86 @@ class Buttons: }, { 67: 8, 127: 8, 304: 8, 320: 8, 339: 8, 356: 4, 544: 8, 593: 8, 608: 8, 688: 6, 764: 8, 809: 8, 854: 7, 870: 7, 871: 8, 872: 8, 897: 8, 902: 8, 903: 8, 905: 8, 909: 8, 916: 8, 1040: 8, 1042: 8, 1056: 8, 1057: 8, 1064: 8, 1078: 4, 1107: 5, 1136: 8, 1151: 6, 1155: 8, 1162: 8, 1164: 8, 1168: 7, 1170: 8, 1173: 8, 1180: 8, 1183: 8, 1186: 2, 1227: 8, 1265: 4, 1280: 1, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1345: 8, 1348: 8, 1363: 8, 1369: 8, 1371: 8, 1378: 8, 1384: 8, 1407: 8, 1414: 3, 1419: 8, 1427: 6, 1456: 4, 1470: 8, 1988: 8, 2000: 8, 2004: 8, 2008: 8, 2012: 8 - } - ], + }], + CAR.SANTA_FE_1: [{ + 67: 8, 68: 8, 80: 4, 160: 8, 161: 8, 272: 8, 288: 4, 339: 8, 356: 8, 357: 8, 399: 8, 497: 8,544: 8, 608: 8, 672: 8, 688: 5, 704: 1, 790: 8, 809: 8, 848: 8, 880: 8, 898: 8, 900: 8, 901: 8, 904: 8, 1056: 8, 1064: 8, 1065: 8, 1072: 8, 1075: 8, 1087: 8, 1088: 8, 1151: 8, 1200: 8, 1201: 8, 1232: 4, 1264: 8, 1265: 8, 1266: 8, 1296: 8, 1306: 8, 1312: 8, 1322: 8, 1331: 8, 1332: 8, 1333: 8, 1348: 8, 1349: 8, 1369: 8, 1370: 8, 1371: 8, 1407: 8, 1415: 8, 1419: 8, 1440: 8, 1442: 4, 1461: 8, 1470: 8 + }], + CAR.GENESIS_G90: [{ + 67: 8, 68: 8, 127: 8, 304: 8, 320: 8, 339: 8, 356: 4, 358: 6, 359: 8, 544: 8, 593: 8, 608: 8, 688: 5, 809: 8, 854: 7, 870: 7, 871: 8, 872: 8, 897: 8, 902: 8, 903: 8, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1107: 5, 1136: 8, 1151: 6, 1162: 4, 1168: 7, 1170: 8, 1173: 8, 1184: 8, 1265: 4, 1280: 1, 1281: 3, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1345: 8, 1348: 8, 1363: 8, 1369: 8, 1370: 8, 1371: 8, 1378: 4, 1384: 8, 1407: 8, 1419: 8, 1425: 2, 1427: 6, 1434: 2, 1456: 4, 1470: 8, 1988: 8, 2000: 8, 2003: 8, 2004: 8, 2005: 8, 2008: 8, 2011: 8, 2012: 8, 2013: 8 + }], + CAR.IONIQ: [{ + 68: 8, 127: 8, 304: 8, 320: 8, 339: 8, 352: 8, 356: 4, 544: 8, 576: 8, 593: 8, 688: 5, 881: 8, 882: 8, 897: 8, 902: 8, 903: 8, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1136: 6, 1173: 8, 1225: 8, 1265: 4, 1280: 1, 1287: 4, 1290: 8, 1291: 8, 1292: 8, 1294: 8, 1322: 8, 1345: 8, 1348: 8, 1355: 8, 1363: 8, 1369: 8, 1407: 8, 1419: 8, 1427: 6, 1429: 8, 1430: 8, 1448: 8, 1456: 4, 1470:8, 1476: 8, 1535: 8 + }], + CAR.IONIQ_EV_LTD: [{ + 127: 8, 304: 8, 320: 8, 339: 8, 352: 8, 356: 4, 544: 7, 593: 8, 688: 5, 832: 8, 881: 8, 882: 8, 897: 8, 902: 8, 903: 8, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1136: 8, 1151: 6, 1168: 7, 1173: 8, 1265: 4, 1280: 1, 1287: 4, 1290: 8, 1291: 8, 1292: 8, 1294: 8, 1322: 8, 1342: 6, 1345: 8, 1348: 8, 1355: 8, 1363: 8, 1369: 8, 1407: 8, 1419: 8, 1425: 2, 1426: 8, 1427: 6, 1429: 8, 1430: 8, 1456: 4, 1470: 8, 1507: 8, 1535: 8 + }], + CAR.GENESIS_G80: [{ + 67: 8, 68: 8, 127: 8, 304: 8, 320: 8, 339: 8, 356: 4, 358: 6, 544: 8, 593: 8, 608: 8, 688: 5, 809: 8, 832: 8, 854: 7, 870: 7, 871: 8, 872: 8, 897: 8, 902: 8, 903: 8, 916: 8, 1024: 2, 1040: 8, 1042: 8, 1056: 8, 1057: 8, 1078: 4, 1107: 5, 1136: 8, 1151: 6, 1156: 8, 1168: 7, 1170: 8, 1173: 8, 1184: 8, 1191: 2, 1265: 4, 1280: 1, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1342: 6, 1345: 8, 1348: 8, 1363: 8, 1369: 8, 1370: 8, 1371: 8, 1378: 4, 1384: 8, 1407: 8, 1419: 8, 1425: 2, 1427: 6, 1434: 2, 1456: 4, 1470: 8 + }], + CAR.KONA: [{ + 67: 8, 127: 8, 304: 8, 320: 8, 339: 8, 354: 3, 356: 4, 544: 8, 593: 8, 608: 8, 688: 5, 809: 8, 832: 8, 854: 7, 870: 7, 871: 8, 872: 8, 897: 8, 902: 8, 903: 8, 909: 8, 916: 8, 1040: 8, 1078: 4, 1107: 5, 1136: 8, 1156: 8, 1170: 8, 1173: 8, 1191: 2, 1265: 4, 1280: 1, 1287: 4, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1342: 6, 1345: 8, 1348: 8, 1363: 8, 1369: 8, 1384: 8, 1394: 8,1407: 8, 1414: 3, 1419: 8, 1427: 6, 1456: 4, 1470: 8, 2004: 8, 2009: 8, 2012: 8 + }, + { + 127: 8, 304: 8, 320: 8, 339: 8, 352: 8, 356: 4, 544: 8, 593: 8, 688: 5, 881: 8, 882: 8, 897: 8, 902: 8, 903: 8, 916: 8, 1040: 8, 1042: 8, 1078: 4, 1136: 8, 1151: 6, 1168: 7, 1173: 8, 1183: 8, 1225: 8, 1265: 4, 1280: 1, 1287: 4, 1291: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1345: 8, 1348: 8, 1355: 8, 1363: 8, 1369: 8, 1407: 8, 1426: 8, 1427: 6, 1429: 8, 1430: 8, 1456: 4, 1470: 8, 1473: 8, 1507: 8, 1535: 8 + }, + { + 67: 8, 127: 8, 304: 8, 320: 8, 339: 8, 354: 3, 356: 4, 544: 8, 593: 8, 608: 8, 688: 5, 809: 8, 832: 8, 854: 7, 870: 7, 871: 8, 872: 8, 897: 8, 902: 8, 903: 8, 909: 8, 916: 8, 1040: 8, 1064: 8, 1078: 4, 1107: 5, 1136: 8, 1151: 6, 1156: 8, 1170: 8, 1173: 8, 1186: 2, 1191: 2, 1265: 4, 1280: 1, 1287: 4, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1342: 6, 1345: 8, 1348: 8, 1363: 8, 1369: 8, 1384: 8, 1394: 8, 1407: 8, 1414: 3, 1419: 8, 1427: 6, 1456: 4, 1470: 8, 1988: 8, 1990: 8, 1998: 8, 2001: 8, 2004: 8, 2009: 8, 2012: 8, 2015: 8 + }], + CAR.KIA_FORTE: [{ + 67: 8, 127: 8, 304: 8, 320: 8, 339: 8, 356: 4, 544: 8, 593: 8, 608: 8, 688: 5, 809: 8, 832: 8, 854: 7, 870: 7, 871: 8, 872: 8, 897: 8, 902: 8, 903: 8, 909: 8, 916: 8, 1040: 8, 1042: 8, 1078: 4, 1107: 5, 1136: 8, 1156: 8, 1170: 8, 1173: 8, 1191: 2, 1225: 8, 1265: 4, 1280: 4, 1287: 4, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1342: 6, 1345: 8, 1348: 8, 1363: 8, 1369: 8, 1384: 8, 1394: 8, 1407: 8, 1427: 6, 1456: 4, 1470: 8 + }], + CAR.KIA_OPTIMA_H: [{ + 68: 8, 127: 8, 304: 8, 320: 8, 339: 8, 352: 8, 356: 4, 544: 8, 593: 8, 688: 5, 832: 8, 881: 8, 882: 8, 897: 8, 902: 8, 903: 6, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1136: 6, 1151: 6, 1168: 7, 1173: 8, 1236: 2, 1265: 4, 1280: 1, 1287: 4, 1290: 8, 1291: 8, 1292: 8, 1322: 8, 1331: 8, 1332: 8, 1333: 8, 1342: 6, 1345: 8, 1348: 8, 1355: 8, 1363: 8, 1369: 8, 1371: 8, 1407: 8, 1419: 8, 1427: 6, 1429: 8, 1430: 8, 1448: 8, 1456: 4, 1470: 8, 1476: 8, 1535: 8 + }, + { + 68: 8, 127: 8, 304: 8, 320: 8, 339: 8, 352: 8, 356: 4, 544: 8, 576: 8, 593: 8, 688: 5, 881: 8, 882: 8, 897: 8, 902: 8, 903: 8, 909: 8, 912: 7, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1136: 6, 1151: 6, 1168: 7, 1173: 8, 1180: 8, 1186: 2, 1191: 2, 1265: 4, 1268: 8, 1280: 1, 1287: 4, 1290: 8, 1291: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1342: 6, 1345: 8, 1348: 8, 1355: 8, 1363: 8, 1369: 8, 1371: 8, 1407: 8, 1419: 8, 1420: 8, 1425: 2, 1427: 6, 1429: 8, 1430: 8, 1448: 8, 1456: 4, 1470: 8, 1476: 8, 1535: 8 + }], + CAR.ELANTRA_GT_I30: [{ + 66: 8, 67: 8, 68: 8, 127: 8, 128: 8, 129: 8, 273: 8, 274: 8, 275: 8, 339: 8, 354: 3, 356: 4, 399: 8, 512: 6, 544: 8, 593: 8, 608: 8, 688: 5, 790: 8, 809: 8, 884: 8, 897: 8, 899: 8, 902: 8, 903: 8, 905: 8, 909: 8, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1151: 6, 1168: 7, 1170: 8, 1193: 8, 1265: 4, 1280: 1, 1282: 4, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1345: 8, 1348: 8, 1349: 8, 1351: 8, 1353: 8, 1356: 8, 1363: 8, 1365: 8, 1366: 8, 1367: 8, 1369: 8, 1407: 8, 1414: 3, 1415: 8, 1427: 6, 1440: 8, 1456: 4, 1470: 8, 1486: 8, 1487: 8, 1491: 8, 1530: 8, 1952: 8, 1960: 8, 1988: 8, 2000: 8, 2001: 8, 2005: 8, 2008: 8, 2009: 8, 2013: 8, 2017: 8, 2025: 8 + }, + { + 66: 8, 67: 8, 68: 8, 127: 8, 128: 8, 129: 8, 273: 8, 274: 8, 275: 8, 339: 8, 354: 3, 356: 4, 399: 8, 512: 6, 544: 8, 593: 8, 608: 8, 688: 5, 790: 8, 809: 8, 832: 8, 897: 8, 899: 8, 902: 8, 903: 8, 905: 8, 909: 8, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1151: 6, 1168: 7, 1170: 8, 1265: 4, 1280: 1, 1282: 4, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1342: 6, 1345: 8, 1348: 8, 1349: 8, 1351: 8, 1353: 8, 1356: 8, 1363: 8, 1366: 8, 1367: 8, 1369: 8, 1407: 8, 1414: 3, 1415: 8, 1419: 8, 1440: 8, 1456: 4, 1470: 8, 1486: 8, 1487: 8, 1491: 8, 1530: 8 + }, + { + 66: 8, 67: 8, 68: 8, 127: 8, 128: 8, 129: 8, 273: 8, 274: 8, 275: 8, 339: 8, 354: 3, 356: 4, 399: 8, 512: 6, 544: 8, 593: 8, 608: 8, 688: 5, 790: 8, 809: 8, 832: 8, 897: 8, 899: 8, 902: 8, 903: 8, 905: 8, 909: 8, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1151: 6, 1168: 7, 1170: 8, 1265: 4, 1280: 1, 1282: 4, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1342: 6, 1345: 8, 1348: 8, 1349: 8, 1351: 8, 1353: 8, 1356: 8, 1363: 8, 1366: 8, 1367: 8, 1369: 8, 1407: 8, 1414: 3, 1419: 8, 1427: 6, 1440: 8, 1456: 4, 1470: 8, 1486: 8, 1487: 8, 1491: 8, 1960: 8, 1990: 8, 1998: 8, 2000: 8, 2001: 8, 2004: 8, 2005: 8, 2008: 8, 2009: 8, 2012: 8, 2013: 8, 2015: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8 + }], } -CAMERA_MSGS = [832, 1156, 1191, 1342] +class ECU: + CAM = 0 + +ECU_FINGERPRINT = { + ECU.CAM: [832, 1156, 1191, 1342] +} CHECKSUM = { - "crc8": [CAR.SANTA_FE], + "crc8": [CAR.SANTA_FE, CAR.SANTA_FE_1], "6B": [CAR.KIA_SORENTO, CAR.GENESIS], - "7B": [CAR.KIA_STINGER, CAR.ELANTRA, CAR.KIA_OPTIMA], } FEATURES = { - "use_cluster_gears": [CAR.ELANTRA], # Use Cluster for Gear Selection, rather than Transmission - "use_tcu_gears": [CAR.KIA_OPTIMA], # Use TCU Message for Gear Selection + "use_cluster_gears": [CAR.ELANTRA, CAR.KONA, CAR.ELANTRA_GT_I30], # Use Cluster for Gear Selection, rather than Transmission + "use_tcu_gears": [CAR.KIA_OPTIMA], # Use TCU Message for Gear Selection + "use_new_gears": [CAR.KIA_OPTIMA_H, CAR.IONIQ_EV_LTD], # Use TCU Message for Gear Selection + "non_scc": [CAR.IONIQ, CAR.KONA, CAR.KIA_FORTE, CAR.SANTA_FE_1], # Car without SCC } DBC = { CAR.ELANTRA: dbc_dict('hyundai_kia_generic', None), CAR.GENESIS: dbc_dict('hyundai_kia_generic', None), CAR.KIA_OPTIMA: dbc_dict('hyundai_kia_generic', None), + CAR.KIA_OPTIMA_H: dbc_dict('hyundai_kia_generic', None), CAR.KIA_SORENTO: dbc_dict('hyundai_kia_generic', None), CAR.KIA_STINGER: dbc_dict('hyundai_kia_generic', None), CAR.SANTA_FE: dbc_dict('hyundai_kia_generic', None), + CAR.SANTA_FE_1: dbc_dict('hyundai_kia_generic', None), + CAR.GENESIS_G90: dbc_dict('hyundai_kia_generic', None), + CAR.GENESIS_G80: dbc_dict('hyundai_kia_generic', None), + CAR.IONIQ: dbc_dict('hyundai_kia_generic', None), + CAR.IONIQ_EV_LTD: dbc_dict('hyundai_kia_generic', None), + CAR.KONA: dbc_dict('hyundai_kia_generic', None), + CAR.KIA_FORTE: dbc_dict('hyundai_kia_generic', None), + CAR.ELANTRA_GT_I30: dbc_dict('hyundai_kia_generic', None), } STEER_THRESHOLD = 100 diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py new file mode 100644 index 00000000000000..0c7c2c81dc9d77 --- /dev/null +++ b/selfdrive/car/interfaces.py @@ -0,0 +1,43 @@ +import os +import time +from cereal import car +from selfdrive.car import gen_empty_fingerprint + +# generic car and radar interfaces + +class CarInterfaceBase(): + def __init__(self, CP, CarController): + pass + + @staticmethod + def calc_accel_override(a_ego, a_target, v_ego, v_target): + return 1. + + @staticmethod + def compute_gb(accel, speed): + raise NotImplementedError + + @staticmethod + def get_params(candidate, fingerprint=gen_empty_fingerprint(), vin="", has_relay=False): + raise NotImplementedError + + # returns a car.CarState, pass in car.CarControl + def update(self, c, can_strings): + raise NotImplementedError + + # return sendcan, pass in a car.CarControl + def apply(self, c): + raise NotImplementedError + +class RadarInterfaceBase(): + def __init__(self, CP): + self.pts = {} + self.delay = 0 + + def update(self, can_strings): + ret = car.RadarData.new_message() + + if 'NO_RADAR_SLEEP' not in os.environ: + time.sleep(0.05) # radard runs on RI updates + + return ret diff --git a/selfdrive/car/mock/interface.py b/selfdrive/car/mock/interface.py index 3a5e05257c4a90..a46b93aa61cda8 100755 --- a/selfdrive/car/mock/interface.py +++ b/selfdrive/car/mock/interface.py @@ -1,10 +1,10 @@ -#!/usr/bin/env python -import zmq +#!/usr/bin/env python3 from cereal import car from selfdrive.config import Conversions as CV -from selfdrive.services import service_list from selfdrive.swaglog import cloudlog import selfdrive.messaging as messaging +from selfdrive.car import gen_empty_fingerprint +from selfdrive.car.interfaces import CarInterfaceBase # mocked car interface to work with chffrplus TS = 0.01 # 100Hz @@ -13,17 +13,16 @@ LPG = 2 * 3.1415 * YAW_FR * TS / (1 + 2 * 3.1415 * YAW_FR * TS) -class CarInterface(object): - def __init__(self, CP, sendcan=None): - +class CarInterface(CarInterfaceBase): + def __init__(self, CP, CarController): self.CP = CP + self.CC = CarController cloudlog.debug("Using Mock Car Interface") - context = zmq.Context() # TODO: subscribe to phone sensor - self.sensor = messaging.sub_sock(context, service_list['sensorEvents'].port) - self.gps = messaging.sub_sock(context, service_list['gpsLocation'].port) + self.sensor = messaging.sub_sock('sensorEvents') + self.gps = messaging.sub_sock('gpsLocation') self.speed = 0. self.prev_speed = 0. @@ -35,18 +34,14 @@ def compute_gb(accel, speed): return accel @staticmethod - def calc_accel_override(a_ego, a_target, v_ego, v_target): - return 1.0 - - @staticmethod - def get_params(candidate, fingerprint): + def get_params(candidate, fingerprint=gen_empty_fingerprint(), vin="", has_relay=False): ret = car.CarParams.new_message() ret.carName = "mock" ret.carFingerprint = candidate - ret.safetyModel = car.CarParams.SafetyModels.noOutput + ret.safetyModel = car.CarParams.SafetyModel.noOutput ret.openpilotLongitudinalControl = False # FIXME: hardcoding honda civic 2016 touring params so they can be used to @@ -56,8 +51,6 @@ def get_params(candidate, fingerprint): ret.wheelbase = 2.70 ret.centerToFront = ret.wheelbase * 0.5 ret.steerRatio = 13. # reasonable - ret.longPidDeadzoneBP = [0.] - ret.longPidDeadzoneV = [0.] ret.tireStiffnessFront = 1e6 # very stiff to neglect slip ret.tireStiffnessRear = 1e6 # very stiff to neglect slip ret.steerRatioRear = 0. @@ -69,17 +62,18 @@ def get_params(candidate, fingerprint): ret.brakeMaxBP = [0.] ret.brakeMaxV = [0.] - ret.longitudinalKpBP = [0.] - ret.longitudinalKpV = [0.] - ret.longitudinalKiBP = [0.] - ret.longitudinalKiV = [0.] + ret.longitudinalTuning.kpBP = [0.] + ret.longitudinalTuning.kpV = [0.] + ret.longitudinalTuning.kiBP = [0.] + ret.longitudinalTuning.kiV = [0.] + ret.longitudinalTuning.deadzoneBP = [0.] + ret.longitudinalTuning.deadzoneV = [0.] ret.steerActuatorDelay = 0. return ret # returns a car.CarState - def update(self, c): - + def update(self, c, can_strings): # get basic data from phone and gps since CAN isn't connected sensors = messaging.recv_sock(self.sensor) if sensors is not None: @@ -120,4 +114,4 @@ def update(self, c): def apply(self, c): # in mock no carcontrols - return False + return [] diff --git a/selfdrive/car/mock/radar_interface.py b/selfdrive/car/mock/radar_interface.py index ec042d1794a7ec..b2f76511360320 100755 --- a/selfdrive/car/mock/radar_interface.py +++ b/selfdrive/car/mock/radar_interface.py @@ -1,24 +1,5 @@ -#!/usr/bin/env python -from cereal import car -import time +#!/usr/bin/env python3 +from selfdrive.car.interfaces import RadarInterfaceBase - -class RadarInterface(object): - def __init__(self, CP): - # radar - self.pts = {} - self.delay = 0.1 - - def update(self): - - ret = car.RadarState.new_message() - time.sleep(0.05) # radard runs on RI updates - - return ret - -if __name__ == "__main__": - RI = RadarInterface(None) - while 1: - ret = RI.update() - print(chr(27) + "[2J") - print ret +class RadarInterface(RadarInterfaceBase): + pass diff --git a/selfdrive/car/subaru/carcontroller.py b/selfdrive/car/subaru/carcontroller.py new file mode 100644 index 00000000000000..e7b9b7d94de20a --- /dev/null +++ b/selfdrive/car/subaru/carcontroller.py @@ -0,0 +1,71 @@ +#from common.numpy_fast import clip +from selfdrive.car import apply_std_steer_torque_limits +from selfdrive.car.subaru import subarucan +from selfdrive.car.subaru.values import DBC +from selfdrive.can.packer import CANPacker + + +class CarControllerParams(): + def __init__(self, car_fingerprint): + self.STEER_MAX = 2047 # max_steer 4095 + self.STEER_STEP = 2 # how often we update the steer cmd + self.STEER_DELTA_UP = 50 # torque increase per refresh, 0.8s to max + self.STEER_DELTA_DOWN = 70 # torque decrease per refresh + self.STEER_DRIVER_ALLOWANCE = 60 # allowed driver torque before start limiting + self.STEER_DRIVER_MULTIPLIER = 10 # weight driver torque heavily + self.STEER_DRIVER_FACTOR = 1 # from dbc + + + +class CarController(): + def __init__(self, car_fingerprint): + self.lkas_active = False + self.steer_idx = 0 + self.apply_steer_last = 0 + self.car_fingerprint = car_fingerprint + self.es_distance_cnt = -1 + self.es_lkas_cnt = -1 + + # Setup detection helper. Routes commands to + # an appropriate CAN bus number. + self.params = CarControllerParams(car_fingerprint) + self.packer = CANPacker(DBC[car_fingerprint]['pt']) + + def update(self, enabled, CS, frame, actuators, pcm_cancel_cmd, visual_alert, left_line, right_line): + """ Controls thread """ + + P = self.params + + # Send CAN commands. + can_sends = [] + + ### STEER ### + + if (frame % P.STEER_STEP) == 0: + + final_steer = actuators.steer if enabled else 0. + apply_steer = int(round(final_steer * P.STEER_MAX)) + + # limits due to driver torque + + apply_steer = int(round(apply_steer)) + apply_steer = apply_std_steer_torque_limits(apply_steer, self.apply_steer_last, CS.steer_torque_driver, P) + + lkas_enabled = enabled and not CS.steer_not_allowed + + if not lkas_enabled: + apply_steer = 0 + + can_sends.append(subarucan.create_steering_control(self.packer, CS.CP.carFingerprint, apply_steer, frame, P.STEER_STEP)) + + self.apply_steer_last = apply_steer + + if self.es_distance_cnt != CS.es_distance_msg["Counter"]: + can_sends.append(subarucan.create_es_distance(self.packer, CS.es_distance_msg, pcm_cancel_cmd)) + self.es_distance_cnt = CS.es_distance_msg["Counter"] + + if self.es_lkas_cnt != CS.es_lkas_msg["Counter"]: + can_sends.append(subarucan.create_es_lkas(self.packer, CS.es_lkas_msg, visual_alert, left_line, right_line)) + self.es_lkas_cnt = CS.es_lkas_msg["Counter"] + + return can_sends diff --git a/selfdrive/car/subaru/carstate.py b/selfdrive/car/subaru/carstate.py index e12f5f957f26ff..f0256de3d0675b 100644 --- a/selfdrive/car/subaru/carstate.py +++ b/selfdrive/car/subaru/carstate.py @@ -1,4 +1,4 @@ -import numpy as np +import copy from common.kalman.simple_kalman import KF1D from selfdrive.config import Conversions as CV from selfdrive.can.parser import CANParser @@ -25,6 +25,7 @@ def get_powertrain_can_parser(CP): ("DOOR_OPEN_FL", "BodyInfo", 1), ("DOOR_OPEN_RR", "BodyInfo", 1), ("DOOR_OPEN_RL", "BodyInfo", 1), + ("Units", "Dash_State", 1), ] checks = [ @@ -32,13 +33,56 @@ def get_powertrain_can_parser(CP): ("Dashlights", 10), ("CruiseControl", 20), ("Wheel_Speeds", 50), - ("Steering_Torque", 100), + ("Steering_Torque", 50), ("BodyInfo", 10), ] return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) -class CarState(object): + +def get_camera_can_parser(CP): + signals = [ + ("Cruise_Set_Speed", "ES_DashStatus", 0), + + ("Counter", "ES_Distance", 0), + ("Signal1", "ES_Distance", 0), + ("Signal2", "ES_Distance", 0), + ("Main", "ES_Distance", 0), + ("Signal3", "ES_Distance", 0), + + ("Checksum", "ES_LKAS_State", 0), + ("Counter", "ES_LKAS_State", 0), + ("Keep_Hands_On_Wheel", "ES_LKAS_State", 0), + ("Empty_Box", "ES_LKAS_State", 0), + ("Signal1", "ES_LKAS_State", 0), + ("LKAS_ACTIVE", "ES_LKAS_State", 0), + ("Signal2", "ES_LKAS_State", 0), + ("Backward_Speed_Limit_Menu", "ES_LKAS_State", 0), + ("LKAS_ENABLE_3", "ES_LKAS_State", 0), + ("Signal3", "ES_LKAS_State", 0), + ("LKAS_ENABLE_2", "ES_LKAS_State", 0), + ("Signal4", "ES_LKAS_State", 0), + ("LKAS_Left_Line_Visible", "ES_LKAS_State", 0), + ("Signal6", "ES_LKAS_State", 0), + ("LKAS_Right_Line_Visible", "ES_LKAS_State", 0), + ("Signal7", "ES_LKAS_State", 0), + ("FCW_Cont_Beep", "ES_LKAS_State", 0), + ("FCW_Repeated_Beep", "ES_LKAS_State", 0), + ("Throttle_Management_Activated", "ES_LKAS_State", 0), + ("Traffic_light_Ahead", "ES_LKAS_State", 0), + ("Right_Depart", "ES_LKAS_State", 0), + ("Signal5", "ES_LKAS_State", 0), + + ] + + checks = [ + ("ES_DashStatus", 10), + ] + + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2) + + +class CarState(): def __init__(self, CP): # initialize can parser self.CP = CP @@ -54,15 +98,14 @@ def __init__(self, CP): # vEgo kalman filter dt = 0.01 - self.v_ego_kf = KF1D(x0=np.matrix([[0.], [0.]]), - A=np.matrix([[1., dt], [0., 1.]]), - C=np.matrix([1., 0.]), - K=np.matrix([[0.12287673], [0.29666309]])) + self.v_ego_kf = KF1D(x0=[[0.], [0.]], + A=[[1., dt], [0., 1.]], + C=[1., 0.], + K=[[0.12287673], [0.29666309]]) self.v_ego = 0. - def update(self, cp): + def update(self, cp, cp_cam): - self.can_valid = True self.pedal_gas = cp.vl["Throttle"]['Throttle_Pedal'] self.brake_pressure = cp.vl["Brake_Pedal"]['Brake_Pedal'] self.user_gas_pressed = self.pedal_gas > 0 @@ -74,10 +117,15 @@ def update(self, cp): self.v_wheel_rl = cp.vl["Wheel_Speeds"]['RL'] * CV.KPH_TO_MS self.v_wheel_rr = cp.vl["Wheel_Speeds"]['RR'] * CV.KPH_TO_MS + self.v_cruise_pcm = cp_cam.vl["ES_DashStatus"]['Cruise_Set_Speed'] + # 1 = imperial, 6 = metric + if cp.vl["Dash_State"]['Units'] == 1: + self.v_cruise_pcm *= CV.MPH_TO_KPH + v_wheel = (self.v_wheel_fl + self.v_wheel_fr + self.v_wheel_rl + self.v_wheel_rr) / 4. - # Kalman filter, even though Hyundai raw wheel speed is heaviliy filtered by default + # Kalman filter, even though Subaru raw wheel speed is heaviliy filtered by default if abs(v_wheel - self.v_ego) > 2.0: # Prevent large accelerations when car starts at non zero speed - self.v_ego_kf.x = np.matrix([[v_wheel], [0.0]]) + self.v_ego_kf.x = [[v_wheel], [0.0]] self.v_ego_raw = v_wheel v_ego_x = self.v_ego_kf.update(v_wheel) @@ -101,4 +149,5 @@ def update(self, cp): cp.vl["BodyInfo"]['DOOR_OPEN_FR'], cp.vl["BodyInfo"]['DOOR_OPEN_FL']]) - + self.es_distance_msg = copy.copy(cp_cam.vl["ES_Distance"]) + self.es_lkas_msg = copy.copy(cp_cam.vl["ES_LKAS_State"]) diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py index 93a1ac62b2ddda..e2195b00a19ca1 100644 --- a/selfdrive/car/subaru/interface.py +++ b/selfdrive/car/subaru/interface.py @@ -1,34 +1,33 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 from cereal import car -from common.realtime import sec_since_boot from selfdrive.config import Conversions as CV from selfdrive.controls.lib.drive_helpers import create_event, EventTypes as ET from selfdrive.controls.lib.vehicle_model import VehicleModel from selfdrive.car.subaru.values import CAR -from selfdrive.car.subaru.carstate import CarState, get_powertrain_can_parser +from selfdrive.car.subaru.carstate import CarState, get_powertrain_can_parser, get_camera_can_parser +from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint +from selfdrive.car.interfaces import CarInterfaceBase -try: - from selfdrive.car.subaru.carcontroller import CarController -except ImportError: - CarController = None +ButtonType = car.CarState.ButtonEvent.Type - -class CarInterface(object): - def __init__(self, CP, sendcan=None): +class CarInterface(CarInterfaceBase): + def __init__(self, CP, CarController): self.CP = CP self.frame = 0 - self.can_invalid_count = 0 self.acc_active_prev = 0 + self.gas_pressed_prev = False # *** init the major players *** self.CS = CarState(CP) self.VM = VehicleModel(CP) self.pt_cp = get_powertrain_can_parser(CP) + self.cam_cp = get_camera_can_parser(CP) + + self.gas_pressed_prev = False - # sending if read only is False - if sendcan is not None: - self.sendcan = sendcan + self.CC = None + if CarController is not None: self.CC = CarController(CP.carFingerprint) @staticmethod @@ -36,34 +35,34 @@ def compute_gb(accel, speed): return float(accel) / 4.0 @staticmethod - def calc_accel_override(a_ego, a_target, v_ego, v_target): - return 1.0 - - @staticmethod - def get_params(candidate, fingerprint): + def get_params(candidate, fingerprint=gen_empty_fingerprint(), vin="", has_relay=False): ret = car.CarParams.new_message() ret.carName = "subaru" + ret.radarOffCan = True ret.carFingerprint = candidate - ret.safetyModel = car.CarParams.SafetyModels.subaru + ret.carVin = vin + ret.isPandaBlack = has_relay + ret.safetyModel = car.CarParams.SafetyModel.subaru - ret.enableCruise = False + ret.enableCruise = True ret.steerLimitAlert = True + + # force openpilot to fake the stock camera, since car harness is not supported yet and old style giraffe (with switches) + # was never released ret.enableCamera = True - std_cargo = 136 ret.steerRateCost = 0.7 if candidate in [CAR.IMPREZA]: - ret.mass = 1568 + std_cargo + ret.mass = 1568. + STD_CARGO_KG ret.wheelbase = 2.67 ret.centerToFront = ret.wheelbase * 0.5 ret.steerRatio = 15 - tire_stiffness_factor = 1.0 ret.steerActuatorDelay = 0.4 # end-to-end angle controller - ret.steerKf = 0.00005 - ret.steerKiBP, ret.steerKpBP = [[0., 20.], [0., 20.]] - ret.steerKpV, ret.steerKiV = [[0.2, 0.3], [0.02, 0.03]] + ret.lateralTuning.pid.kf = 0.00005 + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0., 20.], [0., 20.]] + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2, 0.3], [0.02, 0.03]] ret.steerMaxBP = [0.] # m/s ret.steerMaxV = [1.] @@ -76,51 +75,37 @@ def get_params(candidate, fingerprint): ret.gasMaxV = [0.] ret.brakeMaxBP = [0.] ret.brakeMaxV = [0.] - ret.longPidDeadzoneBP = [0.] - ret.longPidDeadzoneV = [0.] - ret.longitudinalKpBP = [0.] - ret.longitudinalKpV = [0.] - ret.longitudinalKiBP = [0.] - ret.longitudinalKiV = [0.] + ret.longitudinalTuning.deadzoneBP = [0.] + ret.longitudinalTuning.deadzoneV = [0.] + ret.longitudinalTuning.kpBP = [0.] + ret.longitudinalTuning.kpV = [0.] + ret.longitudinalTuning.kiBP = [0.] + ret.longitudinalTuning.kiV = [0.] # end from gm - # hardcoding honda civic 2016 touring params so they can be used to - # scale unknown params for other cars - mass_civic = 2923./2.205 + std_cargo - wheelbase_civic = 2.70 - centerToFront_civic = wheelbase_civic * 0.4 - centerToRear_civic = wheelbase_civic - centerToFront_civic - rotationalInertia_civic = 2500 - tireStiffnessFront_civic = 192150 - tireStiffnessRear_civic = 202500 - centerToRear = ret.wheelbase - ret.centerToFront - # TODO: get actual value, for now starting with reasonable value for # civic and scaling by mass and wheelbase - ret.rotationalInertia = rotationalInertia_civic * \ - ret.mass * ret.wheelbase**2 / (mass_civic * wheelbase_civic**2) + ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) # TODO: start from empirically derived lateral slip stiffness for the civic and scale by # mass and CG position, so all cars will have approximately similar dyn behaviors - ret.tireStiffnessFront = (tireStiffnessFront_civic * tire_stiffness_factor) * \ - ret.mass / mass_civic * \ - (centerToRear / ret.wheelbase) / (centerToRear_civic / wheelbase_civic) - ret.tireStiffnessRear = (tireStiffnessRear_civic * tire_stiffness_factor) * \ - ret.mass / mass_civic * \ - (ret.centerToFront / ret.wheelbase) / (centerToFront_civic / wheelbase_civic) + ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront) return ret # returns a car.CarState - def update(self, c): + def update(self, c, can_strings): + self.pt_cp.update_strings(can_strings) + self.cam_cp.update_strings(can_strings) - self.pt_cp.update(int(sec_since_boot() * 1e9), False) - self.CS.update(self.pt_cp) + self.CS.update(self.pt_cp, self.cam_cp) # create message ret = car.CarState.new_message() + ret.canValid = self.pt_cp.can_valid and self.cam_cp.can_valid + # speeds ret.vEgo = self.CS.v_ego ret.aEgo = self.CS.a_ego @@ -140,66 +125,71 @@ def update(self, c): ret.steeringPressed = self.CS.steer_override ret.steeringTorque = self.CS.steer_torque_driver + ret.gas = self.CS.pedal_gas / 255. + ret.gasPressed = self.CS.user_gas_pressed + # cruise state + ret.cruiseState.enabled = bool(self.CS.acc_active) + ret.cruiseState.speed = self.CS.v_cruise_pcm * CV.KPH_TO_MS ret.cruiseState.available = bool(self.CS.main_on) + ret.cruiseState.speedOffset = 0. + ret.leftBlinker = self.CS.left_blinker_on ret.rightBlinker = self.CS.right_blinker_on ret.seatbeltUnlatched = self.CS.seatbelt_unlatched + ret.doorOpen = self.CS.door_open buttonEvents = [] # blinkers if self.CS.left_blinker_on != self.CS.prev_left_blinker_on: be = car.CarState.ButtonEvent.new_message() - be.type = 'leftBlinker' + be.type = ButtonType.leftBlinker be.pressed = self.CS.left_blinker_on buttonEvents.append(be) if self.CS.right_blinker_on != self.CS.prev_right_blinker_on: be = car.CarState.ButtonEvent.new_message() - be.type = 'rightBlinker' + be.type = ButtonType.rightBlinker be.pressed = self.CS.right_blinker_on buttonEvents.append(be) be = car.CarState.ButtonEvent.new_message() - be.type = 'accelCruise' + be.type = ButtonType.accelCruise buttonEvents.append(be) events = [] - if not self.CS.can_valid: - self.can_invalid_count += 1 - if self.can_invalid_count >= 5: - events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) - else: - self.can_invalid_count = 0 - if ret.seatbeltUnlatched: events.append(create_event('seatbeltNotLatched', [ET.NO_ENTRY, ET.SOFT_DISABLE])) + if ret.doorOpen: + events.append(create_event('doorOpen', [ET.NO_ENTRY, ET.SOFT_DISABLE])) + if self.CS.acc_active and not self.acc_active_prev: events.append(create_event('pcmEnable', [ET.ENABLE])) if not self.CS.acc_active: events.append(create_event('pcmDisable', [ET.USER_DISABLE])) - ## handle button presses - #for b in ret.buttonEvents: - # # do enable on both accel and decel buttons - # if b.type in ["accelCruise", "decelCruise"] and not b.pressed: - # events.append(create_event('buttonEnable', [ET.ENABLE])) - # # do disable on button down - # if b.type == "cancel" and b.pressed: - # events.append(create_event('buttonCancel', [ET.USER_DISABLE])) + # disable on gas pedal rising edge + if (ret.gasPressed and not self.gas_pressed_prev): + events.append(create_event('pedalPressed', [ET.NO_ENTRY, ET.USER_DISABLE])) + + if ret.gasPressed: + events.append(create_event('pedalPressed', [ET.PRE_ENABLE])) ret.events = events # update previous brake/gas pressed + self.gas_pressed_prev = ret.gasPressed self.acc_active_prev = self.CS.acc_active - # cast to reader so it can't be modified return ret.as_reader() def apply(self, c): - self.CC.update(self.sendcan, c.enabled, self.CS, self.frame, c.actuators) + can_sends = self.CC.update(c.enabled, self.CS, self.frame, c.actuators, + c.cruiseControl.cancel, c.hudControl.visualAlert, + c.hudControl.leftLaneVisible, c.hudControl.rightLaneVisible) self.frame += 1 + return can_sends diff --git a/selfdrive/car/subaru/radar_interface.py b/selfdrive/car/subaru/radar_interface.py index 96159fd87d9535..b2f76511360320 100644 --- a/selfdrive/car/subaru/radar_interface.py +++ b/selfdrive/car/subaru/radar_interface.py @@ -1,24 +1,5 @@ -#!/usr/bin/env python -from cereal import car -import time +#!/usr/bin/env python3 +from selfdrive.car.interfaces import RadarInterfaceBase - -class RadarInterface(object): - def __init__(self, CP): - # radar - self.pts = {} - self.delay = 0.1 - - def update(self): - - ret = car.RadarState.new_message() - time.sleep(0.05) # radard runs on RI updates - - return ret - -if __name__ == "__main__": - RI = RadarInterface(None) - while 1: - ret = RI.update() - print(chr(27) + "[2J") - print ret +class RadarInterface(RadarInterfaceBase): + pass diff --git a/selfdrive/car/subaru/subarucan.py b/selfdrive/car/subaru/subarucan.py new file mode 100644 index 00000000000000..96abfaafb3d698 --- /dev/null +++ b/selfdrive/car/subaru/subarucan.py @@ -0,0 +1,56 @@ +import copy +from cereal import car +from selfdrive.car.subaru.values import CAR + +VisualAlert = car.CarControl.HUDControl.VisualAlert + +def subaru_checksum(packer, values, addr): + dat = packer.make_can_msg(addr, 0, values)[2] + return (sum(dat[1:]) + (addr >> 8) + addr) & 0xff + +def create_steering_control(packer, car_fingerprint, apply_steer, frame, steer_step): + + if car_fingerprint == CAR.IMPREZA: + #counts from 0 to 15 then back to 0 + 16 for enable bit + idx = ((frame // steer_step) % 16) + + values = { + "Counter": idx, + "LKAS_Output": apply_steer, + "LKAS_Request": 1 if apply_steer != 0 else 0, + "SET_1": 1 + } + values["Checksum"] = subaru_checksum(packer, values, 0x122) + + return packer.make_can_msg("ES_LKAS", 0, values) + +def create_steering_status(packer, car_fingerprint, apply_steer, frame, steer_step): + + if car_fingerprint == CAR.IMPREZA: + values = {} + values["Checksum"] = subaru_checksum(packer, {}, 0x322) + + return packer.make_can_msg("ES_LKAS_State", 0, values) + +def create_es_distance(packer, es_distance_msg, pcm_cancel_cmd): + + values = copy.copy(es_distance_msg) + if pcm_cancel_cmd: + values["Main"] = 1 + + values["Checksum"] = subaru_checksum(packer, values, 545) + + return packer.make_can_msg("ES_Distance", 0, values) + +def create_es_lkas(packer, es_lkas_msg, visual_alert, left_line, right_line): + + values = copy.copy(es_lkas_msg) + if visual_alert == VisualAlert.steerRequired: + values["Keep_Hands_On_Wheel"] = 1 + + values["LKAS_Left_Line_Visible"] = int(left_line) + values["LKAS_Right_Line_Visible"] = int(right_line) + + values["Checksum"] = subaru_checksum(packer, values, 802) + + return packer.make_can_msg("ES_LKAS_State", 0, values) diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index 18b89295648731..7292a135c06c1c 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -6,6 +6,10 @@ class CAR: FINGERPRINTS = { CAR.IMPREZA: [{ 2: 8, 64: 8, 65: 8, 72: 8, 73: 8, 280: 8, 281: 8, 290: 8, 312: 8, 313: 8, 314: 8, 315: 8, 316: 8, 326: 8, 544: 8, 545: 8, 546: 8, 552: 8, 554: 8, 557: 8, 576: 8, 577: 8, 722: 8, 801: 8, 802: 8, 805: 8, 808: 8, 816: 8, 826: 8, 837: 8, 838: 8, 839: 8, 842: 8, 912: 8, 915: 8, 940: 8, 1614: 8, 1617: 8, 1632: 8, 1650: 8, 1657: 8, 1658: 8, 1677: 8, 1697: 8, 1722: 8, 1743: 8, 1759: 8, 1786: 5, 1787: 5, 1788: 8, 1809: 8, 1813: 8, 1817: 8, 1821: 8, 1840: 8, 1848: 8, 1924: 8, 1932: 8, 1952: 8, 1960: 8 + }, + # Crosstrek 2018 (same platform as Impreza) + { + 2: 8, 64: 8, 65: 8, 72: 8, 73: 8, 256: 8, 280: 8, 281: 8, 290: 8, 312: 8, 313: 8, 314: 8, 315: 8, 316: 8, 326: 8, 372: 8, 544: 8, 545: 8, 546: 8, 554: 8, 557: 8, 576: 8, 577: 8, 722: 8, 801: 8, 802: 8, 805: 8, 808: 8, 811: 8, 826: 8, 837: 8, 838: 8, 839: 8, 842: 8, 912: 8, 915: 8, 940: 8, 1614: 8, 1617: 8, 1632: 8, 1650: 8, 1657: 8, 1658: 8, 1677: 8, 1697: 8, 1759: 8, 1786: 5, 1787: 5, 1788: 8 }], } @@ -13,6 +17,13 @@ class CAR: CAR.IMPREZA: 80, } +class ECU: + CAM = 0 + +ECU_FINGERPRINT = { + ECU.CAM: [290, 356], # steer torque cmd +} + DBC = { CAR.IMPREZA: dbc_dict('subaru_global_2017', None), } diff --git a/selfdrive/car/toyota/carcontroller.py b/selfdrive/car/toyota/carcontroller.py index cdd1bde51b5a3d..ae37ec463dee6f 100644 --- a/selfdrive/car/toyota/carcontroller.py +++ b/selfdrive/car/toyota/carcontroller.py @@ -1,17 +1,15 @@ from cereal import car from common.numpy_fast import clip, interp -from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car import apply_toyota_steer_torque_limits from selfdrive.car import create_gas_command -from selfdrive.car.toyota.toyotacan import make_can_msg, create_video_target,\ +from selfdrive.car.toyota.toyotacan import make_can_msg, \ create_steer_command, create_ui_command, \ create_ipas_steer_command, create_accel_command, \ - create_fcw_command -from selfdrive.car.toyota.values import ECU, STATIC_MSGS + create_acc_cancel_command, create_fcw_command +from selfdrive.car.toyota.values import CAR, ECU, STATIC_MSGS, TSS2_CAR, SteerLimitParams from selfdrive.can.packer import CANPacker VisualAlert = car.CarControl.HUDControl.VisualAlert -AudibleAlert = car.CarControl.HUDControl.AudibleAlert # Accel limits ACCEL_HYST_GAP = 0.02 # don't change accel command for small oscilalitons within this value @@ -19,12 +17,6 @@ ACCEL_MIN = -3.0 # 3 m/s2 ACCEL_SCALE = max(ACCEL_MAX, -ACCEL_MIN) -# Steer torque limits -class SteerLimitParams: - STEER_MAX = 1500 - STEER_DELTA_UP = 10 # 1.5s time to peak torque - STEER_DELTA_DOWN = 25 # always lower than 45 otherwise the Rav4 faults (Prius seems ok with 50) - STEER_ERROR_MAX = 350 # max delta between torque cmd and torque motor # Steer angle limits (tested at the Crows Landing track and considered ok) ANGLE_MAX_BP = [0., 5.] @@ -54,25 +46,17 @@ def accel_hysteresis(accel, accel_steady, enabled): return accel, accel_steady -def process_hud_alert(hud_alert, audible_alert): +def process_hud_alert(hud_alert): # initialize to no alert steer = 0 fcw = 0 - sound1 = 0 - sound2 = 0 if hud_alert == VisualAlert.fcw: fcw = 1 elif hud_alert == VisualAlert.steerRequired: steer = 1 - if audible_alert == AudibleAlert.chimeWarningRepeat: - sound1 = 1 - elif audible_alert != AudibleAlert.none: - # TODO: find a way to send single chimes - sound2 = 1 - - return steer, fcw, sound1, sound2 + return steer, fcw def ipas_state_transition(steer_angle_enabled, enabled, ipas_active, ipas_reset_counter): @@ -99,7 +83,7 @@ def ipas_state_transition(steer_angle_enabled, enabled, ipas_active, ipas_reset_ return False, 0 -class CarController(object): +class CarController(): def __init__(self, dbc_name, car_fingerprint, enable_camera, enable_dsu, enable_apg): self.braking = False # redundant safety check with the board @@ -124,8 +108,8 @@ def __init__(self, dbc_name, car_fingerprint, enable_camera, enable_dsu, enable_ self.packer = CANPacker(dbc_name) - def update(self, sendcan, enabled, CS, frame, actuators, - pcm_cancel_cmd, hud_alert, audible_alert, forwarding_camera, left_line, right_line, lead): + def update(self, enabled, CS, frame, actuators, pcm_cancel_cmd, hud_alert, + left_line, right_line, lead, left_lane_depart, right_lane_depart): # *** compute control surfaces *** @@ -161,7 +145,7 @@ def update(self, sendcan, enabled, CS, frame, actuators, self.steer_angle_enabled, self.ipas_reset_counter = \ ipas_state_transition(self.steer_angle_enabled, enabled, CS.ipas_active, self.ipas_reset_counter) - #print self.steer_angle_enabled, self.ipas_reset_counter, CS.ipas_active + #print("{0} {1} {2}".format(self.steer_angle_enabled, self.ipas_reset_counter, CS.ipas_active)) # steer angle if self.steer_angle_enabled and CS.ipas_active: @@ -198,7 +182,7 @@ def update(self, sendcan, enabled, CS, frame, actuators, can_sends = [] #*** control msgs *** - #print "steer", apply_steer, min_lim, max_lim, CS.steer_torque_motor + #print("steer {0} {1} {2} {3}".format(apply_steer, min_lim, max_lim, CS.steer_torque_motor) # toyota can trace shows this message at 42Hz, with counter adding alternatively 1 and 2; # sending it at 100Hz seem to allow a higher rate limit, as the rate limit seems imposed @@ -218,7 +202,11 @@ def update(self, sendcan, enabled, CS, frame, actuators, # accel cmd comes from DSU, but we can spam can to cancel the system even if we are using lat only control if (frame % 3 == 0 and ECU.DSU in self.fake_ecus) or (pcm_cancel_cmd and ECU.CAM in self.fake_ecus): lead = lead or CS.v_ego < 12. # at low speed we always assume the lead is present do ACC can be engaged - if ECU.DSU in self.fake_ecus: + + # Lexus IS uses a different cancellation message + if pcm_cancel_cmd and CS.CP.carFingerprint == CAR.LEXUS_IS: + can_sends.append(create_acc_cancel_command(self.packer)) + elif ECU.DSU in self.fake_ecus: can_sends.append(create_accel_command(self.packer, apply_accel, pcm_cancel_cmd, self.standstill_req, lead)) else: can_sends.append(create_accel_command(self.packer, 0, pcm_cancel_cmd, False, lead)) @@ -226,17 +214,13 @@ def update(self, sendcan, enabled, CS, frame, actuators, if (frame % 2 == 0) and (CS.CP.enableGasInterceptor): # send exactly zero if apply_gas is zero. Interceptor will send the max between read value and apply_gas. # This prevents unexpected pedal range rescaling - can_sends.append(create_gas_command(self.packer, apply_gas, frame/2)) - - if frame % 10 == 0 and ECU.CAM in self.fake_ecus and not forwarding_camera: - for addr in TARGET_IDS: - can_sends.append(create_video_target(frame/10, addr)) + can_sends.append(create_gas_command(self.packer, apply_gas, frame//2)) # ui mesg is at 100Hz but we send asap if: # - there is something to display # - there is something to stop displaying - alert_out = process_hud_alert(hud_alert, audible_alert) - steer, fcw, sound1, sound2 = alert_out + alert_out = process_hud_alert(hud_alert) + steer, fcw = alert_out if (any(alert_out) and not self.alert_active) or \ (not any(alert_out) and self.alert_active): @@ -245,29 +229,20 @@ def update(self, sendcan, enabled, CS, frame, actuators, else: send_ui = False + # disengage msg causes a bad fault sound so play a good sound instead + if pcm_cancel_cmd: + send_ui = True + if (frame % 100 == 0 or send_ui) and ECU.CAM in self.fake_ecus: - can_sends.append(create_ui_command(self.packer, steer, sound1, sound2, left_line, right_line)) + can_sends.append(create_ui_command(self.packer, steer, pcm_cancel_cmd, left_line, right_line, left_lane_depart, right_lane_depart)) - if frame % 100 == 0 and ECU.DSU in self.fake_ecus: + if frame % 100 == 0 and ECU.DSU in self.fake_ecus and self.car_fingerprint not in TSS2_CAR: can_sends.append(create_fcw_command(self.packer, fcw)) #*** static msgs *** for (addr, ecu, cars, bus, fr_step, vl) in STATIC_MSGS: - if frame % fr_step == 0 and ecu in self.fake_ecus and self.car_fingerprint in cars and not (ecu == ECU.CAM and forwarding_camera): - # special cases - if fr_step == 5 and ecu == ECU.CAM and bus == 1: - cnt = (((frame / 5) % 7) + 1) << 5 - vl = chr(cnt) + vl - elif addr in (0x489, 0x48a) and bus == 0: - # add counter for those 2 messages (last 4 bits) - cnt = ((frame/100)%0xf) + 1 - if addr == 0x48a: - # 0x48a has a 8 preceding the counter - cnt += 1 << 7 - vl += chr(cnt) - + if frame % fr_step == 0 and ecu in self.fake_ecus and self.car_fingerprint in cars: can_sends.append(make_can_msg(addr, vl, bus, False)) - - sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan').to_bytes()) + return can_sends diff --git a/selfdrive/car/toyota/carstate.py b/selfdrive/car/toyota/carstate.py index 02debc47bf8484..fc0260ef562408 100644 --- a/selfdrive/car/toyota/carstate.py +++ b/selfdrive/car/toyota/carstate.py @@ -1,23 +1,28 @@ -import numpy as np +from cereal import car +from common.numpy_fast import mean from common.kalman.simple_kalman import KF1D -from selfdrive.can.parser import CANParser, CANDefine +from selfdrive.can.can_define import CANDefine +from selfdrive.can.parser import CANParser from selfdrive.config import Conversions as CV -from selfdrive.car.toyota.values import CAR, DBC, STEER_THRESHOLD +from selfdrive.car.toyota.values import CAR, DBC, STEER_THRESHOLD, TSS2_CAR, NO_DSU_CAR + +GearShifter = car.CarState.GearShifter def parse_gear_shifter(gear, vals): - val_to_capnp = {'P': 'park', 'R': 'reverse', 'N': 'neutral', - 'D': 'drive', 'B': 'brake'} + val_to_capnp = {'P': GearShifter.park, 'R': GearShifter.reverse, 'N': GearShifter.neutral, + 'D': GearShifter.drive, 'B': GearShifter.brake} try: return val_to_capnp[vals[gear]] except KeyError: - return "unknown" + return GearShifter.unknown def get_can_parser(CP): signals = [ # sig_name, sig_address, default + ("STEER_ANGLE", "STEER_ANGLE_SENSOR", 0), ("GEAR", "GEAR_PACKET", 0), ("BRAKE_PRESSED", "BRAKE_MODULE", 0), ("GAS_PEDAL", "GAS_PEDAL", 0), @@ -31,15 +36,10 @@ def get_can_parser(CP): ("DOOR_OPEN_RR", "SEATS_DOORS", 1), ("SEATBELT_DRIVER_UNLATCHED", "SEATS_DOORS", 1), ("TC_DISABLED", "ESP_CONTROL", 1), - ("STEER_ANGLE", "STEER_ANGLE_SENSOR", 0), ("STEER_FRACTION", "STEER_ANGLE_SENSOR", 0), ("STEER_RATE", "STEER_ANGLE_SENSOR", 0), - ("GAS_RELEASED", "PCM_CRUISE", 0), ("CRUISE_ACTIVE", "PCM_CRUISE", 0), ("CRUISE_STATE", "PCM_CRUISE", 0), - ("MAIN_ON", "PCM_CRUISE_2", 0), - ("SET_SPEED", "PCM_CRUISE_2", 0), - ("LOW_SPEED_LOCKOUT", "PCM_CRUISE_2", 0), ("STEER_TORQUE_DRIVER", "STEER_TORQUE_SENSOR", 0), ("STEER_TORQUE_EPS", "STEER_TORQUE_SENSOR", 0), ("TURN_SIGNALS", "STEERING_LEVERS", 3), # 3 is no blinkers @@ -55,18 +55,31 @@ def get_can_parser(CP): ("WHEEL_SPEEDS", 80), ("STEER_ANGLE_SENSOR", 80), ("PCM_CRUISE", 33), - ("PCM_CRUISE_2", 33), ("STEER_TORQUE_SENSOR", 50), ("EPS_STATUS", 25), ] + if CP.carFingerprint == CAR.LEXUS_IS: + signals.append(("MAIN_ON", "DSU_CRUISE", 0)) + signals.append(("SET_SPEED", "DSU_CRUISE", 0)) + checks.append(("DSU_CRUISE", 5)) + else: + signals.append(("MAIN_ON", "PCM_CRUISE_2", 0)) + signals.append(("SET_SPEED", "PCM_CRUISE_2", 0)) + signals.append(("LOW_SPEED_LOCKOUT", "PCM_CRUISE_2", 0)) + checks.append(("PCM_CRUISE_2", 33)) + + if CP.carFingerprint in NO_DSU_CAR: + signals += [("STEER_ANGLE", "STEER_TORQUE_SENSOR", 0)] + if CP.carFingerprint == CAR.PRIUS: signals += [("STATE", "AUTOPARK_STATUS", 0)] # add gas interceptor reading if we are using it if CP.enableGasInterceptor: - signals.append(("INTERCEPTOR_GAS", "GAS_SENSOR", 0)) - checks.append(("GAS_SENSOR", 50)) + signals.append(("INTERCEPTOR_GAS", "GAS_SENSOR", 0)) + signals.append(("INTERCEPTOR_GAS2", "GAS_SENSOR", 0)) + checks.append(("GAS_SENSOR", 50)) return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) @@ -81,7 +94,7 @@ def get_cam_can_parser(CP): return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2) -class CarState(object): +class CarState(): def __init__(self, CP): self.CP = CP @@ -89,6 +102,8 @@ def __init__(self, CP): self.shifter_values = self.can_define.dv["GEAR_PACKET"]['GEAR'] self.left_blinker_on = 0 self.right_blinker_on = 0 + self.angle_offset = 0. + self.init_angle_offset = False # initialize can parser self.car_fingerprint = CP.carFingerprint @@ -97,17 +112,13 @@ def __init__(self, CP): dt = 0.01 # Q = np.matrix([[10.0, 0.0], [0.0, 100.0]]) # R = 1e3 - self.v_ego_kf = KF1D(x0=np.matrix([[0.0], [0.0]]), - A=np.matrix([[1.0, dt], [0.0, 1.0]]), - C=np.matrix([1.0, 0.0]), - K=np.matrix([[0.12287673], [0.29666309]])) + self.v_ego_kf = KF1D(x0=[[0.0], [0.0]], + A=[[1.0, dt], [0.0, 1.0]], + C=[1.0, 0.0], + K=[[0.12287673], [0.29666309]]) self.v_ego = 0.0 - def update(self, cp, cp_cam): - # copy can_valid - self.can_valid = cp.can_valid - self.cam_can_valid = cp_cam.can_valid - + def update(self, cp): # update prevs, update must run once per loop self.prev_left_blinker_on = self.left_blinker_on self.prev_right_blinker_on = self.right_blinker_on @@ -118,7 +129,7 @@ def update(self, cp, cp_cam): self.brake_pressed = cp.vl["BRAKE_MODULE"]['BRAKE_PRESSED'] if self.CP.enableGasInterceptor: - self.pedal_gas = cp.vl["GAS_SENSOR"]['INTERCEPTOR_GAS'] + self.pedal_gas = (cp.vl["GAS_SENSOR"]['INTERCEPTOR_GAS'] + cp.vl["GAS_SENSOR"]['INTERCEPTOR_GAS2']) / 2. else: self.pedal_gas = cp.vl["GAS_PEDAL"]['GAS_PEDAL'] self.car_gas = self.pedal_gas @@ -129,11 +140,11 @@ def update(self, cp, cp_cam): self.v_wheel_fr = cp.vl["WHEEL_SPEEDS"]['WHEEL_SPEED_FR'] * CV.KPH_TO_MS self.v_wheel_rl = cp.vl["WHEEL_SPEEDS"]['WHEEL_SPEED_RL'] * CV.KPH_TO_MS self.v_wheel_rr = cp.vl["WHEEL_SPEEDS"]['WHEEL_SPEED_RR'] * CV.KPH_TO_MS - v_wheel = float(np.mean([self.v_wheel_fl, self.v_wheel_fr, self.v_wheel_rl, self.v_wheel_rr])) + v_wheel = mean([self.v_wheel_fl, self.v_wheel_fr, self.v_wheel_rl, self.v_wheel_rr]) # Kalman filter if abs(v_wheel - self.v_ego) > 2.0: # Prevent large accelerations when car starts at non zero speed - self.v_ego_kf.x = np.matrix([[v_wheel], [0.0]]) + self.v_ego_kf.x = [[v_wheel], [0.0]] self.v_ego_raw = v_wheel v_ego_x = self.v_ego_kf.update(v_wheel) @@ -141,11 +152,25 @@ def update(self, cp, cp_cam): self.a_ego = float(v_ego_x[1]) self.standstill = not v_wheel > 0.001 - self.angle_steers = cp.vl["STEER_ANGLE_SENSOR"]['STEER_ANGLE'] + cp.vl["STEER_ANGLE_SENSOR"]['STEER_FRACTION'] + if self.CP.carFingerprint in TSS2_CAR: + self.angle_steers = cp.vl["STEER_TORQUE_SENSOR"]['STEER_ANGLE'] + elif self.CP.carFingerprint in NO_DSU_CAR: + # cp.vl["STEER_TORQUE_SENSOR"]['STEER_ANGLE'] is zeroed to where the steering angle is at start. + # need to apply an offset as soon as the steering angle measurements are both received + self.angle_steers = cp.vl["STEER_TORQUE_SENSOR"]['STEER_ANGLE'] - self.angle_offset + angle_wheel = cp.vl["STEER_ANGLE_SENSOR"]['STEER_ANGLE'] + cp.vl["STEER_ANGLE_SENSOR"]['STEER_FRACTION'] + if abs(angle_wheel) > 1e-3 and abs(self.angle_steers) > 1e-3 and not self.init_angle_offset: + self.init_angle_offset = True + self.angle_offset = self.angle_steers - angle_wheel + else: + self.angle_steers = cp.vl["STEER_ANGLE_SENSOR"]['STEER_ANGLE'] + cp.vl["STEER_ANGLE_SENSOR"]['STEER_FRACTION'] self.angle_steers_rate = cp.vl["STEER_ANGLE_SENSOR"]['STEER_RATE'] can_gear = int(cp.vl["GEAR_PACKET"]['GEAR']) self.gear_shifter = parse_gear_shifter(can_gear, self.shifter_values) - self.main_on = cp.vl["PCM_CRUISE_2"]['MAIN_ON'] + if self.CP.carFingerprint == CAR.LEXUS_IS: + self.main_on = cp.vl["DSU_CRUISE"]['MAIN_ON'] + else: + self.main_on = cp.vl["PCM_CRUISE_2"]['MAIN_ON'] self.left_blinker_on = cp.vl["STEERING_LEVERS"]['TURN_SIGNALS'] == 1 self.right_blinker_on = cp.vl["STEERING_LEVERS"]['TURN_SIGNALS'] == 2 @@ -160,11 +185,14 @@ def update(self, cp, cp_cam): self.steer_override = abs(self.steer_torque_driver) > STEER_THRESHOLD self.user_brake = 0 - self.v_cruise_pcm = cp.vl["PCM_CRUISE_2"]['SET_SPEED'] + if self.CP.carFingerprint == CAR.LEXUS_IS: + self.v_cruise_pcm = cp.vl["DSU_CRUISE"]['SET_SPEED'] + self.low_speed_lockout = False + else: + self.v_cruise_pcm = cp.vl["PCM_CRUISE_2"]['SET_SPEED'] + self.low_speed_lockout = cp.vl["PCM_CRUISE_2"]['LOW_SPEED_LOCKOUT'] == 2 self.pcm_acc_status = cp.vl["PCM_CRUISE"]['CRUISE_STATE'] self.pcm_acc_active = bool(cp.vl["PCM_CRUISE"]['CRUISE_ACTIVE']) - self.gas_pressed = not cp.vl["PCM_CRUISE"]['GAS_RELEASED'] - self.low_speed_lockout = cp.vl["PCM_CRUISE_2"]['LOW_SPEED_LOCKOUT'] == 2 self.brake_lights = bool(cp.vl["ESP_CONTROL"]['BRAKE_LIGHTS_ACC'] or self.brake_pressed) if self.CP.carFingerprint == CAR.PRIUS: self.generic_toggle = cp.vl["AUTOPARK_STATUS"]['STATE'] != 0 diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index 8b6cb0a0129844..a351590ca1fc68 100755 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -1,29 +1,25 @@ -#!/usr/bin/env python -from common.realtime import sec_since_boot +#!/usr/bin/env python3 from cereal import car from selfdrive.config import Conversions as CV from selfdrive.controls.lib.drive_helpers import EventTypes as ET, create_event from selfdrive.controls.lib.vehicle_model import VehicleModel from selfdrive.car.toyota.carstate import CarState, get_can_parser, get_cam_can_parser -from selfdrive.car.toyota.values import ECU, check_ecu_msgs, CAR +from selfdrive.car.toyota.values import ECU, ECU_FINGERPRINT, CAR, NO_STOP_TIMER_CAR, TSS2_CAR, FINGERPRINTS +from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, is_ecu_disconnected, gen_empty_fingerprint from selfdrive.swaglog import cloudlog +from selfdrive.car.interfaces import CarInterfaceBase -try: - from selfdrive.car.toyota.carcontroller import CarController -except ImportError: - CarController = None +ButtonType = car.CarState.ButtonEvent.Type +GearShifter = car.CarState.GearShifter - -class CarInterface(object): - def __init__(self, CP, sendcan=None): +class CarInterface(CarInterfaceBase): + def __init__(self, CP, CarController): self.CP = CP self.VM = VehicleModel(CP) self.frame = 0 self.gas_pressed_prev = False self.brake_pressed_prev = False - self.can_invalid_count = 0 - self.cam_can_valid_count = 0 self.cruise_enabled_prev = False # *** init the major players *** @@ -32,11 +28,8 @@ def __init__(self, CP, sendcan=None): self.cp = get_can_parser(CP) self.cp_cam = get_cam_can_parser(CP) - self.forwarding_camera = False - - # sending if read only is False - if sendcan is not None: - self.sendcan = sendcan + self.CC = None + if CarController is not None: self.CC = CarController(self.cp.dbc_name, CP.carFingerprint, CP.enableCamera, CP.enableDsu, CP.enableApgs) @staticmethod @@ -44,137 +37,204 @@ def compute_gb(accel, speed): return float(accel) / 3.0 @staticmethod - def calc_accel_override(a_ego, a_target, v_ego, v_target): - return 1.0 - - @staticmethod - def get_params(candidate, fingerprint): - - # kg of standard extra cargo to count for drive, gas, etc... - std_cargo = 136 + def get_params(candidate, fingerprint=gen_empty_fingerprint(), vin="", has_relay=False): ret = car.CarParams.new_message() ret.carName = "toyota" ret.carFingerprint = candidate + ret.carVin = vin + ret.isPandaBlack = has_relay - ret.safetyModel = car.CarParams.SafetyModels.toyota + ret.safetyModel = car.CarParams.SafetyModel.toyota # pedal ret.enableCruise = not ret.enableGasInterceptor - # FIXME: hardcoding honda civic 2016 touring params so they can be used to - # scale unknown params for other cars - mass_civic = 2923 * CV.LB_TO_KG + std_cargo - wheelbase_civic = 2.70 - centerToFront_civic = wheelbase_civic * 0.4 - centerToRear_civic = wheelbase_civic - centerToFront_civic - rotationalInertia_civic = 2500 - tireStiffnessFront_civic = 192150 - tireStiffnessRear_civic = 202500 - - ret.steerKiBP, ret.steerKpBP = [[0.], [0.]] ret.steerActuatorDelay = 0.12 # Default delay, Prius has larger delay + if candidate not in [CAR.PRIUS, CAR.RAV4, CAR.RAV4H]: # These cars use LQR/INDI + ret.lateralTuning.init('pid') + ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] + if candidate == CAR.PRIUS: stop_and_go = True ret.safetyParam = 66 # see conversion factor for STEER_TORQUE_EPS in dbc file ret.wheelbase = 2.70 - ret.steerRatio = 15.00 # unknown end-to-end spec + ret.steerRatio = 15.74 # unknown end-to-end spec tire_stiffness_factor = 0.6371 # hand-tune - ret.mass = 3045 * CV.LB_TO_KG + std_cargo - ret.steerKpV, ret.steerKiV = [[0.4], [0.01]] - ret.steerKf = 0.00006 # full torque for 10 deg at 80mph means 0.00007818594 - # TODO: Prius seem to have very laggy actuators. Understand if it is lag or hysteresis - ret.steerActuatorDelay = 0.25 + ret.mass = 3045. * CV.LB_TO_KG + STD_CARGO_KG + + ret.lateralTuning.init('indi') + ret.lateralTuning.indi.innerLoopGain = 4.0 + ret.lateralTuning.indi.outerLoopGain = 3.0 + ret.lateralTuning.indi.timeConstant = 1.0 + ret.lateralTuning.indi.actuatorEffectiveness = 1.0 + + # TODO: Determine if this is better than INDI + # ret.lateralTuning.init('lqr') + # ret.lateralTuning.lqr.scale = 1500.0 + # ret.lateralTuning.lqr.ki = 0.01 + + # ret.lateralTuning.lqr.a = [0., 1., -0.22619643, 1.21822268] + # ret.lateralTuning.lqr.b = [-1.92006585e-04, 3.95603032e-05] + # ret.lateralTuning.lqr.c = [1., 0.] + # ret.lateralTuning.lqr.k = [-110.73572306, 451.22718255] + # ret.lateralTuning.lqr.l = [0.03233671, 0.03185757] + # ret.lateralTuning.lqr.dcGain = 0.002237852961363602 + + ret.steerActuatorDelay = 0.5 elif candidate in [CAR.RAV4, CAR.RAV4H]: stop_and_go = True if (candidate in CAR.RAV4H) else False - ret.safetyParam = 73 # see conversion factor for STEER_TORQUE_EPS in dbc file + ret.safetyParam = 73 ret.wheelbase = 2.65 - ret.steerRatio = 16.30 # 14.5 is spec end-to-end + ret.steerRatio = 16.88 # 14.5 is spec end-to-end tire_stiffness_factor = 0.5533 - ret.mass = 3650 * CV.LB_TO_KG + std_cargo # mean between normal and hybrid - ret.steerKpV, ret.steerKiV = [[0.6], [0.05]] - ret.steerKf = 0.00006 # full torque for 10 deg at 80mph means 0.00007818594 + ret.mass = 3650. * CV.LB_TO_KG + STD_CARGO_KG # mean between normal and hybrid + ret.lateralTuning.init('lqr') + + ret.lateralTuning.lqr.scale = 1500.0 + ret.lateralTuning.lqr.ki = 0.05 + + ret.lateralTuning.lqr.a = [0., 1., -0.22619643, 1.21822268] + ret.lateralTuning.lqr.b = [-1.92006585e-04, 3.95603032e-05] + ret.lateralTuning.lqr.c = [1., 0.] + ret.lateralTuning.lqr.k = [-110.73572306, 451.22718255] + ret.lateralTuning.lqr.l = [0.3233671, 0.3185757] + ret.lateralTuning.lqr.dcGain = 0.002237852961363602 elif candidate == CAR.COROLLA: stop_and_go = False - ret.safetyParam = 100 # see conversion factor for STEER_TORQUE_EPS in dbc file + ret.safetyParam = 100 ret.wheelbase = 2.70 - ret.steerRatio = 17.8 - tire_stiffness_factor = 0.444 - ret.mass = 2860 * CV.LB_TO_KG + std_cargo # mean between normal and hybrid - ret.steerKpV, ret.steerKiV = [[0.2], [0.05]] - ret.steerKf = 0.00003 # full torque for 20 deg at 80mph means 0.00007818594 + ret.steerRatio = 18.27 + tire_stiffness_factor = 0.444 # not optimized yet + ret.mass = 2860. * CV.LB_TO_KG + STD_CARGO_KG # mean between normal and hybrid + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.05]] + ret.lateralTuning.pid.kf = 0.00003 # full torque for 20 deg at 80mph means 0.00007818594 elif candidate == CAR.LEXUS_RXH: stop_and_go = True - ret.safetyParam = 100 # see conversion factor for STEER_TORQUE_EPS in dbc file + ret.safetyParam = 73 ret.wheelbase = 2.79 ret.steerRatio = 16. # 14.8 is spec end-to-end tire_stiffness_factor = 0.444 # not optimized yet - ret.mass = 4481 * CV.LB_TO_KG + std_cargo # mean between min and max - ret.steerKpV, ret.steerKiV = [[0.6], [0.1]] - ret.steerKf = 0.00006 # full torque for 10 deg at 80mph means 0.00007818594 + ret.mass = 4481. * CV.LB_TO_KG + STD_CARGO_KG # mean between min and max + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.1]] + ret.lateralTuning.pid.kf = 0.00006 # full torque for 10 deg at 80mph means 0.00007818594 elif candidate in [CAR.CHR, CAR.CHRH]: stop_and_go = True - ret.safetyParam = 100 + ret.safetyParam = 73 ret.wheelbase = 2.63906 ret.steerRatio = 13.6 tire_stiffness_factor = 0.7933 - ret.mass = 3300. * CV.LB_TO_KG + std_cargo - ret.steerKpV, ret.steerKiV = [[0.723], [0.0428]] - ret.steerKf = 0.00006 + ret.mass = 3300. * CV.LB_TO_KG + STD_CARGO_KG + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.723], [0.0428]] + ret.lateralTuning.pid.kf = 0.00006 elif candidate in [CAR.CAMRY, CAR.CAMRYH]: stop_and_go = True - ret.safetyParam = 100 + ret.safetyParam = 73 ret.wheelbase = 2.82448 ret.steerRatio = 13.7 tire_stiffness_factor = 0.7933 - ret.mass = 3400 * CV.LB_TO_KG + std_cargo #mean between normal and hybrid - ret.steerKpV, ret.steerKiV = [[0.6], [0.1]] - ret.steerKf = 0.00006 + ret.mass = 3400. * CV.LB_TO_KG + STD_CARGO_KG #mean between normal and hybrid + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.1]] + ret.lateralTuning.pid.kf = 0.00006 elif candidate in [CAR.HIGHLANDER, CAR.HIGHLANDERH]: stop_and_go = True - ret.safetyParam = 100 + ret.safetyParam = 73 ret.wheelbase = 2.78 ret.steerRatio = 16.0 - tire_stiffness_factor = 0.444 # not optimized yet - ret.mass = 4607 * CV.LB_TO_KG + std_cargo #mean between normal and hybrid limited - ret.steerKpV, ret.steerKiV = [[0.6], [0.05]] - ret.steerKf = 0.00006 + tire_stiffness_factor = 0.8 + ret.mass = 4607. * CV.LB_TO_KG + STD_CARGO_KG #mean between normal and hybrid limited + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.18], [0.015]] # community tuning + ret.lateralTuning.pid.kf = 0.00012 # community tuning - ret.steerRateCost = 1. - ret.centerToFront = ret.wheelbase * 0.44 + elif candidate == CAR.AVALON: + stop_and_go = False + ret.safetyParam = 73 + ret.wheelbase = 2.82 + ret.steerRatio = 14.8 #Found at https://pressroom.toyota.com/releases/2016+avalon+product+specs.download + tire_stiffness_factor = 0.7983 + ret.mass = 3505. * CV.LB_TO_KG + STD_CARGO_KG # mean between normal and hybrid + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.17], [0.03]] + ret.lateralTuning.pid.kf = 0.00006 + + elif candidate == CAR.RAV4_TSS2: + stop_and_go = True + ret.safetyParam = 73 + ret.wheelbase = 2.68986 + ret.steerRatio = 14.3 + tire_stiffness_factor = 0.7933 + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.1]] + ret.mass = 3370. * CV.LB_TO_KG + STD_CARGO_KG + ret.lateralTuning.pid.kf = 0.00007818594 - ret.longPidDeadzoneBP = [0., 9.] - ret.longPidDeadzoneV = [0., .15] + elif candidate in [CAR.COROLLA_TSS2, CAR.COROLLAH_TSS2]: + stop_and_go = True + ret.safetyParam = 73 + ret.wheelbase = 2.63906 + ret.steerRatio = 13.9 + tire_stiffness_factor = 0.444 # not optimized yet + ret.mass = 3060. * CV.LB_TO_KG + STD_CARGO_KG + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.1]] + ret.lateralTuning.pid.kf = 0.00007818594 - #detect the Pedal address - ret.enableGasInterceptor = 0x201 in fingerprint + elif candidate in [CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2]: + stop_and_go = True + ret.safetyParam = 73 + ret.wheelbase = 2.8702 + ret.steerRatio = 16.0 # not optimized + tire_stiffness_factor = 0.444 # not optimized yet + ret.mass = 3704. * CV.LB_TO_KG + STD_CARGO_KG + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.1]] + ret.lateralTuning.pid.kf = 0.00007818594 - # min speed to enable ACC. if car can do stop and go, then set enabling speed - # to a negative value, so it won't matter. - ret.minEnableSpeed = -1. if (stop_and_go or ret.enableGasInterceptor) else 19. * CV.MPH_TO_MS + elif candidate == CAR.SIENNA: + stop_and_go = True + ret.safetyParam = 73 + ret.wheelbase = 3.03 + ret.steerRatio = 16.0 + tire_stiffness_factor = 0.444 + ret.mass = 4590. * CV.LB_TO_KG + STD_CARGO_KG + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.3], [0.05]] + ret.lateralTuning.pid.kf = 0.00007818594 + + elif candidate == CAR.LEXUS_IS: + stop_and_go = False + ret.safetyParam = 77 + ret.wheelbase = 2.79908 + ret.steerRatio = 13.3 + tire_stiffness_factor = 0.444 + ret.mass = 3736.8 * CV.LB_TO_KG + STD_CARGO_KG + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.3], [0.05]] + ret.lateralTuning.pid.kf = 0.00006 + + elif candidate == CAR.LEXUS_CTH: + stop_and_go = True + ret.safetyParam = 100 + ret.wheelbase = 2.60 + ret.steerRatio = 18.6 + tire_stiffness_factor = 0.517 + ret.mass = 3108 * CV.LB_TO_KG + STD_CARGO_KG # mean between min and max + ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.3], [0.05]] + ret.lateralTuning.pid.kf = 0.00007 + + ret.steerRateCost = 1. + ret.centerToFront = ret.wheelbase * 0.44 - centerToRear = ret.wheelbase - ret.centerToFront # TODO: get actual value, for now starting with reasonable value for # civic and scaling by mass and wheelbase - ret.rotationalInertia = rotationalInertia_civic * \ - ret.mass * ret.wheelbase**2 / (mass_civic * wheelbase_civic**2) + ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) # TODO: start from empirically derived lateral slip stiffness for the civic and scale by # mass and CG position, so all cars will have approximately similar dyn behaviors - ret.tireStiffnessFront = (tireStiffnessFront_civic * tire_stiffness_factor) * \ - ret.mass / mass_civic * \ - (centerToRear / ret.wheelbase) / (centerToRear_civic / wheelbase_civic) - ret.tireStiffnessRear = (tireStiffnessRear_civic * tire_stiffness_factor) * \ - ret.mass / mass_civic * \ - (ret.centerToFront / ret.wheelbase) / (centerToFront_civic / wheelbase_civic) + ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, + tire_stiffness_factor=tire_stiffness_factor) # no rear steering, at least on the listed cars above ret.steerRatioRear = 0. @@ -183,53 +243,58 @@ def get_params(candidate, fingerprint): # steer, gas, brake limitations VS speed ret.steerMaxBP = [16. * CV.KPH_TO_MS, 45. * CV.KPH_TO_MS] # breakpoints at 1 and 40 kph ret.steerMaxV = [1., 1.] # 2/3rd torque allowed above 45 kph - ret.brakeMaxBP = [5., 20.] - ret.brakeMaxV = [1., 0.8] + ret.brakeMaxBP = [0.] + ret.brakeMaxV = [1.] - ret.enableCamera = not check_ecu_msgs(fingerprint, ECU.CAM) - ret.enableDsu = not check_ecu_msgs(fingerprint, ECU.DSU) - ret.enableApgs = False #not check_ecu_msgs(fingerprint, ECU.APGS) + ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, ECU.CAM) or has_relay + ret.enableDsu = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, ECU.DSU) or (has_relay and candidate in TSS2_CAR) + ret.enableApgs = False # is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, ECU.APGS) + ret.enableGasInterceptor = 0x201 in fingerprint[0] ret.openpilotLongitudinalControl = ret.enableCamera and ret.enableDsu - cloudlog.warn("ECU Camera Simulated: %r", ret.enableCamera) - cloudlog.warn("ECU DSU Simulated: %r", ret.enableDsu) - cloudlog.warn("ECU APGS Simulated: %r", ret.enableApgs) - cloudlog.warn("ECU Gas Interceptor: %r", ret.enableGasInterceptor) + cloudlog.warning("ECU Camera Simulated: %r", ret.enableCamera) + cloudlog.warning("ECU DSU Simulated: %r", ret.enableDsu) + cloudlog.warning("ECU APGS Simulated: %r", ret.enableApgs) + cloudlog.warning("ECU Gas Interceptor: %r", ret.enableGasInterceptor) + + # min speed to enable ACC. if car can do stop and go, then set enabling speed + # to a negative value, so it won't matter. + ret.minEnableSpeed = -1. if (stop_and_go or ret.enableGasInterceptor) else 19. * CV.MPH_TO_MS ret.steerLimitAlert = False - ret.longitudinalKpBP = [0., 5., 35.] - ret.longitudinalKiBP = [0., 35.] + + ret.longitudinalTuning.deadzoneBP = [0., 9.] + ret.longitudinalTuning.deadzoneV = [0., .15] + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kiBP = [0., 35.] ret.stoppingControl = False ret.startAccel = 0.0 if ret.enableGasInterceptor: ret.gasMaxBP = [0., 9., 35] ret.gasMaxV = [0.2, 0.5, 0.7] - ret.longitudinalKpV = [1.2, 0.8, 0.5] - ret.longitudinalKiV = [0.18, 0.12] + ret.longitudinalTuning.kpV = [1.2, 0.8, 0.5] + ret.longitudinalTuning.kiV = [0.18, 0.12] else: ret.gasMaxBP = [0.] ret.gasMaxV = [0.5] - ret.longitudinalKpV = [3.6, 2.4, 1.5] - ret.longitudinalKiV = [0.54, 0.36] + ret.longitudinalTuning.kpV = [3.6, 2.4, 1.5] + ret.longitudinalTuning.kiV = [0.54, 0.36] return ret # returns a car.CarState - def update(self, c): + def update(self, c, can_strings): # ******************* do can recv ******************* - canMonoTimes = [] - - self.cp.update(int(sec_since_boot() * 1e9), False) - - # run the cam can update for 10s as we just need to know if the camera is alive - if self.frame < 1000: - self.cp_cam.update(int(sec_since_boot() * 1e9), False) + self.cp.update_strings(can_strings) + self.cp_cam.update_strings(can_strings) - self.CS.update(self.cp, self.cp_cam) + self.CS.update(self.cp) # create message ret = car.CarState.new_message() + ret.canValid = self.cp.can_valid + # speeds ret.vEgo = self.CS.v_ego ret.vEgoRaw = self.CS.v_ego_raw @@ -262,6 +327,7 @@ def update(self, c): ret.steeringRate = self.CS.angle_steers_rate ret.steeringTorque = self.CS.steer_torque_driver + ret.steeringTorqueEps = self.CS.steer_torque_motor ret.steeringPressed = self.CS.steer_override # cruise state @@ -270,7 +336,7 @@ def update(self, c): ret.cruiseState.available = bool(self.CS.main_on) ret.cruiseState.speedOffset = 0. - if self.CP.carFingerprint in [CAR.RAV4H, CAR.HIGHLANDERH, CAR.HIGHLANDER] or self.CP.enableGasInterceptor: + if self.CP.carFingerprint in NO_STOP_TIMER_CAR or self.CP.enableGasInterceptor: # ignore standstill in hybrid vehicles, since pcm allows to restart without # receiving any special command # also if interceptor is detected @@ -281,13 +347,13 @@ def update(self, c): buttonEvents = [] if self.CS.left_blinker_on != self.CS.prev_left_blinker_on: be = car.CarState.ButtonEvent.new_message() - be.type = 'leftBlinker' + be.type = ButtonType.leftBlinker be.pressed = self.CS.left_blinker_on != 0 buttonEvents.append(be) if self.CS.right_blinker_on != self.CS.prev_right_blinker_on: be = car.CarState.ButtonEvent.new_message() - be.type = 'rightBlinker' + be.type = ButtonType.rightBlinker be.pressed = self.CS.right_blinker_on != 0 buttonEvents.append(be) @@ -302,19 +368,10 @@ def update(self, c): # events events = [] - if not self.CS.can_valid: - self.can_invalid_count += 1 - if self.can_invalid_count >= 5: - events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) - else: - self.can_invalid_count = 0 - - if self.CS.cam_can_valid: - self.cam_can_valid_count += 1 - if self.cam_can_valid_count >= 5: - self.forwarding_camera = True - if not ret.gearShifter == 'drive' and self.CP.enableDsu: + if self.cp_cam.can_invalid_cnt >= 100 and self.CP.enableCamera: + events.append(create_event('invalidGiraffeToyota', [ET.PERMANENT, ET.NO_ENTRY])) + if not ret.gearShifter == GearShifter.drive and self.CP.enableDsu: events.append(create_event('wrongGear', [ET.NO_ENTRY, ET.SOFT_DISABLE])) if ret.doorOpen: events.append(create_event('doorOpen', [ET.NO_ENTRY, ET.SOFT_DISABLE])) @@ -324,7 +381,7 @@ def update(self, c): events.append(create_event('espDisabled', [ET.NO_ENTRY, ET.SOFT_DISABLE])) if not self.CS.main_on and self.CP.enableDsu: events.append(create_event('wrongCarMode', [ET.NO_ENTRY, ET.USER_DISABLE])) - if ret.gearShifter == 'reverse' and self.CP.enableDsu: + if ret.gearShifter == GearShifter.reverse and self.CP.enableDsu: events.append(create_event('reverseGear', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) if self.CS.steer_error: events.append(create_event('steerTempUnavailable', [ET.NO_ENTRY, ET.WARNING])) @@ -354,7 +411,6 @@ def update(self, c): events.append(create_event('pedalPressed', [ET.PRE_ENABLE])) ret.events = events - ret.canMonoTimes = canMonoTimes self.gas_pressed_prev = ret.gasPressed self.brake_pressed_prev = ret.brakePressed @@ -366,10 +422,11 @@ def update(self, c): # to be called @ 100hz def apply(self, c): - self.CC.update(self.sendcan, c.enabled, self.CS, self.frame, - c.actuators, c.cruiseControl.cancel, c.hudControl.visualAlert, - c.hudControl.audibleAlert, self.forwarding_camera, - c.hudControl.leftLaneVisible, c.hudControl.rightLaneVisible, c.hudControl.leadVisible) + can_sends = self.CC.update(c.enabled, self.CS, self.frame, + c.actuators, c.cruiseControl.cancel, + c.hudControl.visualAlert, c.hudControl.leftLaneVisible, + c.hudControl.rightLaneVisible, c.hudControl.leadVisible, + c.hudControl.leftLaneDepart, c.hudControl.rightLaneDepart) self.frame += 1 - return False + return can_sends diff --git a/selfdrive/car/toyota/radar_interface.py b/selfdrive/car/toyota/radar_interface.py index 9711f1393ff566..a24a911a44f857 100755 --- a/selfdrive/car/toyota/radar_interface.py +++ b/selfdrive/car/toyota/radar_interface.py @@ -1,73 +1,83 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import os -import zmq import time from selfdrive.can.parser import CANParser from cereal import car -from common.realtime import sec_since_boot -from selfdrive.services import service_list -import selfdrive.messaging as messaging -from selfdrive.car.toyota.values import NO_DSU_CAR +from selfdrive.car.toyota.values import NO_DSU_CAR, DBC, TSS2_CAR +from selfdrive.car.interfaces import RadarInterfaceBase +def _create_radar_can_parser(car_fingerprint): + dbc_f = DBC[car_fingerprint]['radar'] -RADAR_A_MSGS = list(range(0x210, 0x220)) -RADAR_B_MSGS = list(range(0x220, 0x230)) - -def _create_radard_can_parser(): - dbc_f = 'toyota_prius_2017_adas.dbc' + if car_fingerprint in TSS2_CAR: + RADAR_A_MSGS = list(range(0x180, 0x190)) + RADAR_B_MSGS = list(range(0x190, 0x1a0)) + else: + RADAR_A_MSGS = list(range(0x210, 0x220)) + RADAR_B_MSGS = list(range(0x220, 0x230)) msg_a_n = len(RADAR_A_MSGS) msg_b_n = len(RADAR_B_MSGS) - signals = zip(['LONG_DIST'] * msg_a_n + ['NEW_TRACK'] * msg_a_n + ['LAT_DIST'] * msg_a_n + + signals = list(zip(['LONG_DIST'] * msg_a_n + ['NEW_TRACK'] * msg_a_n + ['LAT_DIST'] * msg_a_n + ['REL_SPEED'] * msg_a_n + ['VALID'] * msg_a_n + ['SCORE'] * msg_b_n, RADAR_A_MSGS * 5 + RADAR_B_MSGS, - [255] * msg_a_n + [1] * msg_a_n + [0] * msg_a_n + [0] * msg_a_n + [0] * msg_a_n + [0] * msg_b_n) + [255] * msg_a_n + [1] * msg_a_n + [0] * msg_a_n + [0] * msg_a_n + [0] * msg_a_n + [0] * msg_b_n)) - checks = zip(RADAR_A_MSGS + RADAR_B_MSGS, [20]*(msg_a_n + msg_b_n)) + checks = list(zip(RADAR_A_MSGS + RADAR_B_MSGS, [20]*(msg_a_n + msg_b_n))) return CANParser(os.path.splitext(dbc_f)[0], signals, checks, 1) - -class RadarInterface(object): +class RadarInterface(RadarInterfaceBase): def __init__(self, CP): # radar self.pts = {} - self.valid_cnt = {key: 0 for key in RADAR_A_MSGS} self.track_id = 0 - self.delay = 0.0 # Delay of radar + self.delay = 0 # Delay of radar - self.rcp = _create_radard_can_parser() - self.no_dsu_car = CP.carFingerprint in NO_DSU_CAR + if CP.carFingerprint in TSS2_CAR: + self.RADAR_A_MSGS = list(range(0x180, 0x190)) + self.RADAR_B_MSGS = list(range(0x190, 0x1a0)) + else: + self.RADAR_A_MSGS = list(range(0x210, 0x220)) + self.RADAR_B_MSGS = list(range(0x220, 0x230)) - context = zmq.Context() - self.logcan = messaging.sub_sock(context, service_list['can'].port) + self.valid_cnt = {key: 0 for key in self.RADAR_A_MSGS} - def update(self): + self.rcp = _create_radar_can_parser(CP.carFingerprint) + self.trigger_msg = self.RADAR_B_MSGS[-1] + self.updated_messages = set() - ret = car.RadarState.new_message() - if self.no_dsu_car: - # TODO: make a adas dbc file for dsu-less models + # No radar dbc for cars without DSU which are not TSS 2.0 + # TODO: make a adas dbc file for dsu-less models + self.no_radar = CP.carFingerprint in NO_DSU_CAR and CP.carFingerprint not in TSS2_CAR + + def update(self, can_strings): + if self.no_radar: time.sleep(0.05) - return ret + return car.RadarData.new_message() + + vls = self.rcp.update_strings(can_strings) + self.updated_messages.update(vls) - canMonoTimes = [] - updated_messages = set() - while 1: - tm = int(sec_since_boot() * 1e9) - updated_messages.update(self.rcp.update(tm, True)) - if RADAR_B_MSGS[-1] in updated_messages: - break + if self.trigger_msg not in self.updated_messages: + return None + rr = self._update(self.updated_messages) + self.updated_messages.clear() + + return rr + + def _update(self, updated_messages): + ret = car.RadarData.new_message() errors = [] if not self.rcp.can_valid: - errors.append("commIssue") + errors.append("canError") ret.errors = errors - ret.canMonoTimes = canMonoTimes - for ii in updated_messages: - if ii in RADAR_A_MSGS: + for ii in sorted(updated_messages): + if ii in self.RADAR_A_MSGS: cpt = self.rcp.vl[ii] if cpt['LONG_DIST'] >=255 or cpt['NEW_TRACK']: @@ -83,7 +93,7 @@ def update(self): # radar point only valid if it's a valid measurement and score is above 50 if cpt['VALID'] or (score > 50 and cpt['LONG_DIST'] < 255 and self.valid_cnt[ii] > 0): if ii not in self.pts or cpt['NEW_TRACK']: - self.pts[ii] = car.RadarState.RadarPoint.new_message() + self.pts[ii] = car.RadarData.RadarPoint.new_message() self.pts[ii].trackId = self.track_id self.track_id += 1 self.pts[ii].dRel = cpt['LONG_DIST'] # from front of car @@ -96,12 +106,5 @@ def update(self): if ii in self.pts: del self.pts[ii] - ret.points = self.pts.values() + ret.points = list(self.pts.values()) return ret - -if __name__ == "__main__": - RI = RadarInterface(None) - while 1: - ret = RI.update() - print(chr(27) + "[2J") - print(ret) diff --git a/selfdrive/car/toyota/toyotacan.py b/selfdrive/car/toyota/toyotacan.py index 720c0ef60a8a25..92d1c2ea26d0a8 100644 --- a/selfdrive/car/toyota/toyotacan.py +++ b/selfdrive/car/toyota/toyotacan.py @@ -10,7 +10,7 @@ def fix(msg, addr): checksum = idh + idl + len(msg) + 1 for d_byte in msg: - checksum += ord(d_byte) + checksum += d_byte #return msg + chr(checksum & 0xFF) return msg + struct.pack("B", checksum & 0xFF) @@ -22,12 +22,6 @@ def make_can_msg(addr, dat, alt, cks=False): return [addr, 0, dat, alt] -def create_video_target(frame, addr): - counter = frame & 0xff - msg = struct.pack("!BBBBBBB", counter, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00) - return make_can_msg(addr, msg, 1, True) - - def create_ipas_steer_command(packer, steer, enabled, apgs_enabled): """Creates a CAN message for the Toyota Steer Command.""" if steer < 0: @@ -64,6 +58,22 @@ def create_steer_command(packer, steer, steer_req, raw_cnt): return packer.make_can_msg("STEERING_LKA", 0, values) +def create_lta_steer_command(packer, steer, steer_req, raw_cnt, angle): + """Creates a CAN message for the Toyota LTA Steer Command.""" + + values = { + "COUNTER": raw_cnt, + "SETME_X3": 3, + "PERCENTAGE" : 100, + "SETME_X64": 0x64, + "ANGLE": angle, + "STEER_ANGLE_CMD": steer, + "STEER_REQUEST": steer_req, + "BIT": 0, + } + return packer.make_can_msg("STEERING_LTA", 0, values) + + def create_accel_command(packer, accel, pcm_cancel, standstill_req, lead): # TODO: find the exact canceling bit that does not create a chime values = { @@ -79,6 +89,18 @@ def create_accel_command(packer, accel, pcm_cancel, standstill_req, lead): return packer.make_can_msg("ACC_CONTROL", 0, values) +def create_acc_cancel_command(packer): + values = { + "GAS_RELEASED": 0, + "CRUISE_ACTIVE": 0, + "STANDSTILL_ON": 0, + "ACCEL_NET": 0, + "CRUISE_STATE": 0, + "CANCEL_REQ": 1, + } + return packer.make_can_msg("PCM_CRUISE", 0, values) + + def create_fcw_command(packer, fcw): values = { "FCW": fcw, @@ -89,18 +111,19 @@ def create_fcw_command(packer, fcw): return packer.make_can_msg("ACC_HUD", 0, values) -def create_ui_command(packer, steer, sound1, sound2, left_line, right_line): +def create_ui_command(packer, steer, chime, left_line, right_line, left_lane_depart, right_lane_depart): values = { - "RIGHT_LINE": 1 if right_line else 2, - "LEFT_LINE": 1 if left_line else 2, + "RIGHT_LINE": 3 if right_lane_depart else 1 if right_line else 2, + "LEFT_LINE": 3 if left_lane_depart else 1 if left_line else 2, + "BARRIERS" : 3 if left_lane_depart or right_lane_depart else 0, "SET_ME_X0C": 0x0c, "SET_ME_X2C": 0x2c, "SET_ME_X38": 0x38, "SET_ME_X02": 0x02, "SET_ME_X01": 1, "SET_ME_X01_2": 1, - "REPEATED_BEEPS": sound1, - "TWO_BEEPS": sound2, + "REPEATED_BEEPS": 0, + "TWO_BEEPS": chime, "LDA_ALERT": steer, } return packer.make_can_msg("LKAS_HUD", 0, values) diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 2f3f44448a5332..dae175db02095b 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -1,5 +1,12 @@ from selfdrive.car import dbc_dict +# Steer torque limits +class SteerLimitParams: + STEER_MAX = 1500 + STEER_DELTA_UP = 10 # 1.5s time to peak torque + STEER_DELTA_DOWN = 25 # always lower than 45 otherwise the Rav4 faults (Prius seems ok with 50) + STEER_ERROR_MAX = 350 # max delta between torque cmd and torque motor + class CAR: PRIUS = "TOYOTA PRIUS 2017" RAV4H = "TOYOTA RAV4 HYBRID 2017" @@ -12,6 +19,15 @@ class CAR: CAMRYH = "TOYOTA CAMRY HYBRID 2018" HIGHLANDER = "TOYOTA HIGHLANDER 2017" HIGHLANDERH = "TOYOTA HIGHLANDER HYBRID 2018" + AVALON = "TOYOTA AVALON 2016" + RAV4_TSS2 = "TOYOTA RAV4 2019" + COROLLA_TSS2 = "TOYOTA COROLLA TSS2 2019" + COROLLAH_TSS2 = "TOYOTA COROLLA HYBRID TSS2 2019" + LEXUS_ES_TSS2 = "LEXUS ES 2019" + LEXUS_ESH_TSS2 = "LEXUS ES 300H 2019" + SIENNA = "TOYOTA SIENNA XLE 2018" + LEXUS_IS = "LEXUS IS300 2018" + LEXUS_CTH = "LEXUS CT 200H 2018" class ECU: @@ -22,61 +38,41 @@ class ECU: # addr: (ecu, cars, bus, 1/freq*100, vl) STATIC_MSGS = [ - (0x130, ECU.CAM, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH), 1, 100, '\x00\x00\x00\x00\x00\x00\x38'), - (0x240, ECU.CAM, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH), 1, 5, '\x00\x10\x01\x00\x10\x01\x00'), - (0x241, ECU.CAM, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH), 1, 5, '\x00\x10\x01\x00\x10\x01\x00'), - (0x244, ECU.CAM, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH), 1, 5, '\x00\x10\x01\x00\x10\x01\x00'), - (0x245, ECU.CAM, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH), 1, 5, '\x00\x10\x01\x00\x10\x01\x00'), - (0x248, ECU.CAM, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH), 1, 5, '\x00\x00\x00\x00\x00\x00\x01'), - (0x367, ECU.CAM, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH), 0, 40, '\x06\x00'), - (0x414, ECU.CAM, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH), 0, 100, '\x00\x00\x00\x00\x00\x00\x17\x00'), - (0x466, ECU.CAM, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.HIGHLANDER, CAR.HIGHLANDERH), 1, 100, '\x20\x20\xAD'), - (0x466, ECU.CAM, (CAR.COROLLA), 1, 100, '\x24\x20\xB1'), - (0x489, ECU.CAM, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH), 0, 100, '\x00\x00\x00\x00\x00\x00\x00'), - (0x48a, ECU.CAM, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH), 0, 100, '\x00\x00\x00\x00\x00\x00\x00'), - (0x48b, ECU.CAM, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH), 0, 100, '\x66\x06\x08\x0a\x02\x00\x00\x00'), - (0x4d3, ECU.CAM, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA), 0, 100, '\x1C\x00\x00\x01\x00\x00\x00\x00'), - - (0x128, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA), 1, 3, '\xf4\x01\x90\x83\x00\x37'), - (0x128, ECU.DSU, (CAR.HIGHLANDER, CAR.HIGHLANDERH), 1, 3, '\x03\x00\x20\x00\x00\x52'), - (0x141, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH), 1, 2, '\x00\x00\x00\x46'), - (0x160, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH), 1, 7, '\x00\x00\x08\x12\x01\x31\x9c\x51'), - (0x161, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA), 1, 7, '\x00\x1e\x00\x00\x00\x80\x07'), - (0X161, ECU.DSU, (CAR.HIGHLANDERH, CAR.HIGHLANDER), 1, 7, '\x00\x1e\x00\xd4\x00\x00\x5b'), - (0x283, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH), 0, 3, '\x00\x00\x00\x00\x00\x00\x8c'), - (0x2E6, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH), 0, 3, '\xff\xf8\x00\x08\x7f\xe0\x00\x4e'), - (0x2E7, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH), 0, 3, '\xa8\x9c\x31\x9c\x00\x00\x00\x02'), - (0x33E, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH), 0, 20, '\x0f\xff\x26\x40\x00\x1f\x00'), - (0x344, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH), 0, 5, '\x00\x00\x01\x00\x00\x00\x00\x50'), - (0x365, ECU.DSU, (CAR.PRIUS, CAR.LEXUS_RXH, CAR.HIGHLANDERH), 0, 20, '\x00\x00\x00\x80\x03\x00\x08'), - (0x365, ECU.DSU, (CAR.RAV4, CAR.RAV4H, CAR.COROLLA, CAR.HIGHLANDER), 0, 20, '\x00\x00\x00\x80\xfc\x00\x08'), - (0x366, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.HIGHLANDERH), 0, 20, '\x00\x00\x4d\x82\x40\x02\x00'), - (0x366, ECU.DSU, (CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER), 0, 20, '\x00\x72\x07\xff\x09\xfe\x00'), - (0x470, ECU.DSU, (CAR.PRIUS, CAR.LEXUS_RXH), 1, 100, '\x00\x00\x02\x7a'), - (0x470, ECU.DSU, (CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.RAV4H), 1, 100, '\x00\x00\x01\x79'), - (0x4CB, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDERH, CAR.HIGHLANDER), 0, 100, '\x0c\x00\x00\x00\x00\x00\x00\x00'), + (0x128, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.AVALON), 1, 3, b'\xf4\x01\x90\x83\x00\x37'), + (0x128, ECU.DSU, (CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.SIENNA, CAR.LEXUS_CTH), 1, 3, b'\x03\x00\x20\x00\x00\x52'), + (0x141, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH), 1, 2, b'\x00\x00\x00\x46'), + (0x160, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH), 1, 7, b'\x00\x00\x08\x12\x01\x31\x9c\x51'), + (0x161, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.AVALON), 1, 7, b'\x00\x1e\x00\x00\x00\x80\x07'), + (0X161, ECU.DSU, (CAR.HIGHLANDERH, CAR.HIGHLANDER, CAR.SIENNA, CAR.LEXUS_CTH), 1, 7, b'\x00\x1e\x00\xd4\x00\x00\x5b'), + (0x283, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH), 0, 3, b'\x00\x00\x00\x00\x00\x00\x8c'), + (0x2E6, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH), 0, 3, b'\xff\xf8\x00\x08\x7f\xe0\x00\x4e'), + (0x2E7, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH), 0, 3, b'\xa8\x9c\x31\x9c\x00\x00\x00\x02'), + (0x33E, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH), 0, 20, b'\x0f\xff\x26\x40\x00\x1f\x00'), + (0x344, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH), 0, 5, b'\x00\x00\x01\x00\x00\x00\x00\x50'), + (0x365, ECU.DSU, (CAR.PRIUS, CAR.LEXUS_RXH, CAR.HIGHLANDERH), 0, 20, b'\x00\x00\x00\x80\x03\x00\x08'), + (0x365, ECU.DSU, (CAR.RAV4, CAR.RAV4H, CAR.COROLLA, CAR.HIGHLANDER, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH), 0, 20, b'\x00\x00\x00\x80\xfc\x00\x08'), + (0x366, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.HIGHLANDERH), 0, 20, b'\x00\x00\x4d\x82\x40\x02\x00'), + (0x366, ECU.DSU, (CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH), 0, 20, b'\x00\x72\x07\xff\x09\xfe\x00'), + (0x470, ECU.DSU, (CAR.PRIUS, CAR.LEXUS_RXH), 1, 100, b'\x00\x00\x02\x7a'), + (0x470, ECU.DSU, (CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.RAV4H, CAR.SIENNA, CAR.LEXUS_CTH), 1, 100, b'\x00\x00\x01\x79'), + (0x4CB, ECU.DSU, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDERH, CAR.HIGHLANDER, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH), 0, 100, b'\x0c\x00\x00\x00\x00\x00\x00\x00'), - (0x292, ECU.APGS, (CAR.PRIUS), 0, 3, '\x00\x00\x00\x00\x00\x00\x00\x9e'), - (0x32E, ECU.APGS, (CAR.PRIUS), 0, 20, '\x00\x00\x00\x00\x00\x00\x00\x00'), - (0x396, ECU.APGS, (CAR.PRIUS), 0, 100, '\xBD\x00\x00\x00\x60\x0F\x02\x00'), - (0x43A, ECU.APGS, (CAR.PRIUS), 0, 100, '\x84\x00\x00\x00\x00\x00\x00\x00'), - (0x43B, ECU.APGS, (CAR.PRIUS), 0, 100, '\x00\x00\x00\x00\x00\x00\x00\x00'), - (0x497, ECU.APGS, (CAR.PRIUS), 0, 100, '\x00\x00\x00\x00\x00\x00\x00\x00'), - (0x4CC, ECU.APGS, (CAR.PRIUS), 0, 100, '\x0D\x00\x00\x00\x00\x00\x00\x00'), + (0x292, ECU.APGS, (CAR.PRIUS), 0, 3, b'\x00\x00\x00\x00\x00\x00\x00\x9e'), + (0x32E, ECU.APGS, (CAR.PRIUS), 0, 20, b'\x00\x00\x00\x00\x00\x00\x00\x00'), + (0x396, ECU.APGS, (CAR.PRIUS), 0, 100, b'\xBD\x00\x00\x00\x60\x0F\x02\x00'), + (0x43A, ECU.APGS, (CAR.PRIUS), 0, 100, b'\x84\x00\x00\x00\x00\x00\x00\x00'), + (0x43B, ECU.APGS, (CAR.PRIUS), 0, 100, b'\x00\x00\x00\x00\x00\x00\x00\x00'), + (0x497, ECU.APGS, (CAR.PRIUS), 0, 100, b'\x00\x00\x00\x00\x00\x00\x00\x00'), + (0x4CC, ECU.APGS, (CAR.PRIUS), 0, 100, b'\x0D\x00\x00\x00\x00\x00\x00\x00'), ] ECU_FINGERPRINT = { - ECU.CAM: 0x2e4, # steer torque cmd - ECU.DSU: 0x343, # accel cmd - ECU.APGS: 0x835, # angle cmd + ECU.CAM: [0x2e4], # steer torque cmd + ECU.DSU: [0x343], # accel cmd + ECU.APGS: [0x835], # angle cmd } -def check_ecu_msgs(fingerprint, ecu): - # return True if fingerprint contains messages normally sent by a given ecu - return ECU_FINGERPRINT[ecu] in fingerprint - - FINGERPRINTS = { CAR.RAV4: [{ 36: 8, 37: 8, 170: 8, 180: 8, 186: 4, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 512: 6, 513: 6, 547: 8, 548: 8, 552: 4, 562: 4, 608: 8, 610: 5, 643: 7, 705: 8, 725: 2, 740: 5, 800: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 897: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 3, 918: 7, 921: 8, 933: 8, 944: 8, 945: 8, 951: 8, 955: 4, 956: 8, 979: 2, 998: 5, 999: 7, 1000: 8, 1001: 8, 1005: 2, 1008: 2, 1014: 8, 1017: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1059: 1, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1227: 8, 1228: 8, 1235: 8, 1237: 8, 1263: 8, 1264: 8, 1279: 8, 1408: 8, 1409: 8, 1410: 8, 1552: 8, 1553: 8, 1554: 8, 1555: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1596: 8, 1597: 8, 1600: 8, 1656: 8, 1664: 8, 1728: 8, 1745: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8, 2015: 8, 2024: 8 @@ -86,22 +82,35 @@ def check_ecu_msgs(fingerprint, ecu): }, # Chinese RAV4 { - 36: 8, 37: 8, 170: 8, 180: 8, 186: 4, 355: 5, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 547: 8, 548: 8, 552: 4, 562: 4, 608: 8, 610: 5, 643: 7, 705: 8, 725: 2, 740: 5, 742: 8, 743: 8, 800: 8, 830: 7, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 897: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 3, 921: 8, 922: 8, 933: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 979: 2, 998: 5, 999: 7, 1000: 8, 1001: 8, 1008: 2, 1017: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1059: 1, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1207: 8, 1227: 8, 1235: 8, 1263: 8, 1279: 8, 1552: 8, 1553: 8, 1554: 8, 1555: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1596: 8, 1597: 8, 1600: 8, 1664: 8, 1728: 8, 1745: 8, 1779: 8 + 36: 8, 37: 8, 170: 8, 180: 8, 186: 4, 355: 5, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 512: 6, 513: 6, 547: 8, 548: 8, 552: 4, 562: 4, 608: 8, 610: 5, 643: 7, 705: 8, 725: 2, 740: 5, 742: 8, 743: 8, 800: 8, 830: 7, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 897: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 3, 921: 8, 922: 8, 933: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 979: 2, 998: 5, 999: 7, 1000: 8, 1001: 8, 1008: 2, 1017: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1059: 1, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1207: 8, 1227: 8, 1235: 8, 1263: 8, 1279: 8, 1552: 8, 1553: 8, 1554: 8, 1555: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1596: 8, 1597: 8, 1600: 8, 1664: 8, 1728: 8, 1745: 8, 1779: 8 }], CAR.PRIUS: [{ # with ipas 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 512: 6, 513: 6, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 8, 614: 8, 643: 7, 658: 8, 713: 8, 740: 5, 742: 8, 743: 8, 800: 8, 810: 2, 814: 8, 824: 2, 829: 2, 830: 7, 835: 8, 836: 8, 845: 5, 863: 8, 869: 7, 870: 7, 871: 2,898: 8, 900: 6, 902: 6, 905: 8, 913: 8, 918: 8, 921: 8, 933: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 974: 8, 975: 5, 993: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1005: 2, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1057: 8, 1059: 1, 1071: 8, 1076: 8, 1077: 8, 1082: 8, 1083: 8, 1084: 8, 1085: 8, 1086: 8, 1114: 8, 1132: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1175: 8, 1227: 8, 1228: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1595: 8, 1777: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + }, + #2019 LE + { + 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 8, 614: 8, 643: 7, 658: 8, 713: 8, 740: 5, 742: 8, 743: 8, 800: 8, 810: 2, 814: 8, 829: 2, 830: 7, 835: 8, 836: 8, 863: 8, 865: 8, 869: 7, 870: 7, 871: 2, 896: 8, 898: 8, 900: 6, 902: 6, 905: 8, 918: 8, 921: 8, 933: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 975: 5, 993: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1057: 8, 1059: 1, 1071: 8, 1076: 8, 1077: 8, 1082: 8, 1083: 8, 1084: 8, 1085: 8, 1086: 8, 1114: 8, 1132: 8, 1161: 8, 1162: 8, 1163: 8, 1175: 8, 1227: 8, 1228: 8, 1235: 8, 1237: 8, 1279: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1592: 8, 1595: 8, 1777: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + }, + #2020 Prius Prime Limited + { + 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 8, 614: 8, 643: 7, 658: 8, 713: 8, 740: 5, 742: 8, 743: 8, 800: 8, 810: 2, 814: 8, 824: 2, 829: 2, 830: 7, 835: 8, 836: 8, 863: 8, 865: 8, 869: 7, 870: 7, 871: 2, 896: 8, 898: 8, 900: 6, 902: 6, 905: 8, 913: 8, 918: 8, 921: 8, 933: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 974: 8, 975: 5, 993: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1057: 8, 1059: 1, 1071: 8, 1076: 8, 1077: 8, 1082: 8, 1083: 8, 1084: 8, 1085: 8, 1086: 8, 1114: 8, 1132: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1175: 8, 1227: 8, 1228: 8, 1235: 8, 1237: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1592: 8, 1595: 8, 1649: 8, 1777: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8, 2015: 8, 2024: 8, 2026: 8, 2027: 8, 2029: 8, 2030: 8, 2031: 8 }], #Corolla w/ added Pedal Support (512L and 513L) CAR.COROLLA: [{ 36: 8, 37: 8, 170: 8, 180: 8, 186: 4, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 512: 6, 513: 6, 547: 8, 548: 8, 552: 4, 608: 8, 610: 5, 643: 7, 705: 8, 740: 5, 800: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 897: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 2, 921: 8, 933: 8, 944: 8, 945: 8, 951: 8, 955: 4, 956: 8, 979: 2, 992: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1017: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1059: 1, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1196: 8, 1227: 8, 1235: 8, 1279: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1596: 8, 1597: 8, 1600: 8, 1664: 8, 1728: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8, 2016: 8, 2017: 8, 2018: 8, 2019: 8, 2020: 8, 2021: 8, 2022: 8, 2023: 8, 2024: 8 }], CAR.LEXUS_RXH: [{ - 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 5, 643: 7, 658: 8, 713: 8, 740: 5, 742: 8, 743: 8, 800: 8, 810: 2, 812: 3, 814: 8, 830: 7, 835: 8, 836: 8, 845: 5, 863: 8, 869: 7, 870: 7, 871: 2, 898: 8, 900: 6, 902: 6, 905: 8, 913: 8, 918: 8, 921: 8, 933: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 975: 6, 993: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1005: 2, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1063: 8, 1071: 8, 1077: 8, 1082: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1227: 8, 1228: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1575: 8, 1595: 8, 1777: 8, 1779: 8, 1808: 8, 1810: 8, 1816: 8, 1818: 8, 1840: 8, 1848: 8, 1904: 8, 1912: 8, 1940: 8, 1941: 8, 1948: 8, 1949: 8, 1952: 8, 1956: 8, 1960: 8, 1964: 8, 1986: 8, 1990: 8, 1994: 8, 1998: 8, 2004: 8, 2012: 8 + 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 512: 6, 513:6, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 5, 643: 7, 658: 8, 713: 8, 740: 5, 742: 8, 743: 8, 800: 8, 810: 2, 812: 3, 814: 8, 830: 7, 835: 8, 836: 8, 845: 5, 863: 8, 869: 7, 870: 7, 871: 2, 898: 8, 900: 6, 902: 6, 905: 8, 913: 8, 918: 8, 921: 8, 933: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 975: 6, 993: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1005: 2, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1063: 8, 1071: 8, 1077: 8, 1082: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1227: 8, 1228: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1575: 8, 1595: 8, 1777: 8, 1779: 8, 1808: 8, 1810: 8, 1816: 8, 1818: 8, 1840: 8, 1848: 8, 1904: 8, 1912: 8, 1940: 8, 1941: 8, 1948: 8, 1949: 8, 1952: 8, 1956: 8, 1960: 8, 1964: 8, 1986: 8, 1990: 8, 1994: 8, 1998: 8, 2004: 8, 2012: 8 + }, + # RX450HL + # TODO: get proper fingerprint in stock mode + { + 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 512: 6, 513: 6, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 5, 643: 7, 658: 8, 713: 8, 740: 5, 742: 8, 743: 8, 800: 8, 810: 2, 812: 3, 814: 8, 830: 7, 835: 8, 836: 8, 863: 8, 865: 8, 869: 7, 870: 7, 898: 8, 900: 6, 902: 6, 905: 8, 918: 8, 921: 8, 933: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 975: 6, 993: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1005: 2, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1056: 8, 1057: 8, 1059: 1, 1063: 8, 1071: 8, 1076: 8, 1077: 8, 1082: 8, 1114: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1227: 8, 1228: 8, 1237: 8, 1264: 8, 1279: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1575: 8, 1592: 8, 1594: 8, 1595: 8, 1649: 8, 1777: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 }, - # RX450HL + # RX540H 2019 with color hud { - 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 5, 643: 7, 658: 8, 713: 8, 742: 8, 743: 8, 800: 8, 810: 2, 812: 3, 814: 8, 830: 7, 835: 8, 836: 8, 863: 8, 865: 8, 869: 7, 870: 7, 898: 8, 900: 6, 902: 6, 905: 8, 918: 8, 921: 8, 933: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 975: 6, 993: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1005: 2, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1056: 8, 1057: 8, 1059: 1, 1063: 8, 1071: 8, 1076: 8, 1077: 8, 1082: 8, 1114: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1227: 8, 1228: 8, 1237: 8, 1264: 8, 1279: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1575: 8, 1592: 8, 1594: 8, 1595: 8, 1649: 8, 1777: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 512: 6, 513: 6, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 5, 643: 7, 658: 8, 713: 8, 740: 5, 742: 8, 743: 8, 800: 8, 810: 2, 812: 3, 814: 8, 818: 8, 819: 8, 820: 8, 821: 8, 822: 8, 830: 7, 835: 8, 836: 8, 845: 5, 863: 8, 865: 8, 869: 7, 870: 7, 871: 2, 898: 8, 900: 6, 902: 6, 905: 8, 913: 8, 918: 8, 921: 8, 933: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 975: 6, 993: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1057: 8, 1059: 1, 1063: 8, 1071: 8, 1076: 8, 1077: 8, 1082: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1227: 8, 1228: 8, 1235: 8, 1237: 8, 1263: 8, 1264: 8, 1279: 8, 1349: 8, 1350: 8, 1351: 8, 1413: 8, 1414: 8, 1415: 8, 1416: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1575: 8, 1592: 8, 1594: 8, 1595: 8, 1649: 8, 1777: 8, 1779: 8, 1808: 8, 1810: 8, 1816: 8, 1818: 8, 1904: 8, 1912: 8, 1952: 8, 1960: 8, 1990: 8, 1998: 8 }], CAR.CHR: [{ 36: 8, 37: 8, 170: 8, 180: 8, 186: 4, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 608: 8, 610: 8, 614: 8, 643: 7, 658: 8, 705: 8, 740: 5, 800: 8, 810: 2, 812: 8, 814: 8, 830: 7, 835: 8, 836: 8, 845: 5, 869: 7, 870: 7, 871: 2, 898: 8, 913: 8, 918: 8, 921: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 1014: 8, 1017: 8, 1020: 8, 1021: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1082: 8, 1083: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1175: 8, 1228: 8, 1235: 8, 1237: 8, 1279: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1595: 8, 1745: 8, 1779: 8 @@ -115,44 +124,117 @@ def check_ecu_msgs(fingerprint, ecu): 36: 8, 37: 8, 119: 6, 170: 8, 180: 8, 186: 4, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 608: 8, 610: 8, 643: 7, 658: 8, 705: 8, 728: 8, 740: 5, 761: 8, 764: 8, 800: 8, 810: 2, 812: 8, 814: 8, 818: 8, 822: 8, 824: 8, 830: 7, 835: 8, 836: 8, 869: 7, 870: 7, 871: 2, 888: 8, 889: 8, 891: 8, 898: 8, 900: 6, 902: 6, 905: 8, 918: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 983: 8, 984: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1011: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1076: 8, 1077: 8, 1082: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1228: 8, 1235: 8, 1237: 8, 1263: 8, 1264: 8, 1279: 8, 1412: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1595: 8, 1745: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1808: 8, 1816: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 }, #XSE and SE + # TODO: get proper fingerprint in stock mode { - 36: 8, 37: 8, 114: 5, 119: 6, 120: 4, 170: 8, 180: 8, 186: 4, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 608: 8, 610: 8, 643: 7, 658: 8, 705: 8, 728: 8, 761: 8, 764: 8, 800: 8, 810: 2, 812: 8, 814: 8, 818: 8, 822: 8, 824: 8, 830: 7, 835: 8, 836: 8, 869: 7, 870: 7, 888: 8, 889: 8, 891: 8, 898: 8, 900: 6, 902: 6, 905: 8, 918: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 983: 8, 984: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1011: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1056: 8, 1059: 1, 1076: 8, 1077: 8, 1082: 8, 1114: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1228: 8, 1237: 8, 1263: 8, 1264: 8, 1279: 8, 1412: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1595: 8, 1745: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1808: 8, 1816: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + 36: 8, 37: 8, 114: 5, 119: 6, 120: 4, 170: 8, 180: 8, 186: 4, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 608: 8, 610: 8, 643: 7, 658: 8, 705: 8, 728: 8, 740: 5, 761: 8, 764: 8, 800: 8, 810: 2, 812: 8, 814: 8, 818: 8, 822: 8, 824: 8, 830: 7, 835: 8, 836: 8, 869: 7, 870: 7, 888: 8, 889: 8, 891: 8, 898: 8, 900: 6, 902: 6, 905: 8, 918: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 983: 8, 984: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1011: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1056: 8, 1059: 1, 1076: 8, 1077: 8, 1082: 8, 1114: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1228: 8, 1237: 8, 1263: 8, 1264: 8, 1279: 8, 1412: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1595: 8, 1745: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1808: 8, 1816: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 }], CAR.CAMRYH: [ - #LE and LE with Blindspot Monitor + #SE, LE and LE with Blindspot Monitor { - 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 8, 643: 7, 713: 8, 728: 8, 740: 5, 761: 8, 764: 8, 800: 8, 810: 2, 812: 8, 818: 8, 824: 8, 829: 2, 830: 7, 835: 8, 836: 8, 869: 7, 870: 7, 871: 2, 889: 8, 898: 8, 900: 6, 902: 6, 905: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 975: 5, 983: 8, 984: 8, 993: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1011: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1057: 8, 1059: 1, 1071: 8, 1076: 8, 1077: 8, 1084: 8, 1085: 8, 1086: 8, 1114: 8, 1132: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1595: 8, 1745: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1808: 8, 1810: 8, 1816: 8, 1818: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 - }, + 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 8, 643: 7, 713: 8, 728: 8, 740: 5, 761: 8, 764: 8, 800: 8, 810: 2, 812: 8, 818: 8, 824: 8, 829: 2, 830: 7, 835: 8, 836: 8, 865: 8, 869: 7, 870: 7, 871: 2, 889: 8, 896: 8, 898: 8, 900: 6, 902: 6, 905: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 975: 5, 983: 8, 984: 8, 993: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1011: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1057: 8, 1059: 1, 1071: 8, 1076: 8, 1077: 8, 1084: 8, 1085: 8, 1086: 8, 1114: 8, 1132: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1592: 8, 1594: 8, 1595: 8, 1649: 8, 1745: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1808: 8, 1810: 8, 1816: 8, 1818: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + }, #SL { 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 8, 643: 7, 713: 8, 728: 8, 740: 5, 761: 8, 764: 8, 800: 8, 810: 2, 812: 8, 818: 8, 824: 8, 829: 2, 830: 7, 835: 8, 836: 8, 869: 7, 870: 7, 871: 2, 888: 8, 889: 8, 898: 8, 900: 6, 902: 6, 905: 8, 913: 8, 918: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 975: 5, 993: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1057: 8, 1059: 1, 1071: 8, 1076: 8, 1077: 8, 1084: 8, 1085: 8, 1086: 8, 1114: 8, 1132: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1228: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1595: 8, 1745: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + }, + #XLE + { + 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 8, 643: 7, 658: 8, 713: 8, 728: 8, 740: 5, 761: 8, 764: 8, 800: 8, 810: 2, 812: 8, 814: 8, 818: 8, 824: 8, 829: 2, 830: 7, 835: 8, 836: 8, 869: 7, 870: 7, 871: 2, 888: 8, 889: 8, 898: 8, 900: 6, 902: 6, 905: 8, 918: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 975: 5, 983: 8, 984: 8, 993: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1011: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1057: 8, 1059: 1, 1071: 8, 1076: 8, 1077: 8, 1082: 8, 1084: 8, 1085: 8, 1086: 8, 1114: 8, 1132: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1228: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1595: 8, 1745: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 }], CAR.HIGHLANDER: [{ - 36: 8, 37: 8, 114: 5, 119: 6, 120: 4, 170: 8, 180: 8, 186: 4, 238: 4, 355: 5, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 545: 5, 550: 8, 552: 4, 608: 8, 610: 5, 643: 7, 705: 8, 725: 2, 740: 5, 800: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 3, 921: 8, 922: 8, 933: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 979: 2, 998: 5, 999: 7, 1000: 8, 1001: 8, 1008: 2, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1059: 1, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1182: 8, 1183: 8, 1189: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1197: 8, 1198: 8, 1199: 8, 1206: 8, 1207: 8, 1212: 8, 1227: 8, 1235: 8, 1237: 8, 1279: 8, 1408: 8, 1409: 8, 1410: 8, 1552: 8, 1553: 8, 1554: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1599: 8, 1656: 8, 1666: 8, 1667: 8, 1728: 8, 1745: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + 36: 8, 37: 8, 114: 5, 119: 6, 120: 4, 170: 8, 180: 8, 186: 4, 238: 4, 355: 5, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 545: 5, 550: 8, 552: 4, 608: 8, 610: 5, 643: 7, 705: 8, 725: 2, 740: 5, 800: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 3, 921: 8, 922: 8, 933: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 979: 2, 998: 5, 999: 7, 1000: 8, 1001: 8, 1008: 2, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1059: 1, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1182: 8, 1183: 8, 1189: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1197: 8, 1198: 8, 1199: 8, 1206: 8, 1207: 8, 1212: 8, 1227: 8, 1235: 8, 1237: 8, 1279: 8, 1408: 8, 1409: 8, 1410: 8, 1552: 8, 1553: 8, 1554: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1599: 8, 1656: 8, 1666: 8, 1667: 8, 1728: 8, 1745: 8, 1779: 8, 1872: 8, 1880: 8, 1904: 8, 1912: 8, 1984: 8, 1988: 8, 1992: 8, 1996: 8, 1990: 8, 1998: 8 + }, + # 2019 Highlander XLE + { + 36: 8, 37: 8, 114: 5, 119: 6, 120: 4, 170: 8, 180: 8, 186: 4, 238: 4, 355: 5, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 545: 5, 550: 8, 552: 4, 608: 8, 610: 5, 643: 7, 705: 8, 725: 2, 740: 5, 800: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 3, 921: 8, 922: 8, 933: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 979: 2, 992: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1008: 2, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1059: 1, 1076: 8, 1077: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1182: 8, 1183: 8, 1189: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1197: 8, 1198: 8, 1199: 8, 1206: 8, 1207: 8, 1212: 8, 1227: 8, 1235: 8, 1237: 8, 1279: 8, 1408: 8, 1409: 8, 1410: 8, 1552: 8, 1553: 8, 1554: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1599: 8, 1656: 8, 1728: 8, 1745: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 }, # 2017 Highlander Limited { 36: 8, 37: 8, 114: 5, 119: 6, 120: 4, 170: 8, 180: 8, 186: 4, 238: 4, 355: 5, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 545: 5, 550: 8, 552: 4, 608: 8, 610: 5, 643: 7, 705: 8, 725: 2, 740: 5, 800: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 3, 918: 7, 921: 8, 922: 8, 933: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 979: 2, 998: 5, 999: 7, 1000: 8, 1001: 8, 1005: 2, 1008: 2, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1059: 1, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1182: 8, 1183: 8, 1189: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1197: 8, 1198: 8, 1199: 8, 1206: 8, 1207: 8, 1212: 8, 1227: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1408: 8, 1409: 8, 1410: 8, 1552: 8, 1553: 8, 1554: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1599: 8, 1656: 8, 1728: 8, 1745: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 }], CAR.HIGHLANDERH: [{ - 36: 8, 37: 8, 170: 8, 180: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 581: 5, 608: 8, 610: 5, 643: 7, 713: 8, 740: 5, 800: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 897: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 3, 918: 7, 921: 8, 933: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 3, 955: 8, 956: 8, 979: 2, 998: 5, 999: 7, 1000: 8, 1001: 8, 1005: 2, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1059: 1, 1112: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1184: 8, 1185: 8, 1186: 8, 1189: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1197: 8, 1198: 8, 1199: 8, 1206: 8, 1212: 8, 1227: 8, 1232: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1552: 8, 1553: 8, 1554: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1599: 8, 1656: 8, 1728: 8, 1745: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + 36: 8, 37: 8, 170: 8, 180: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 581: 5, 608: 8, 610: 5, 643: 7, 713: 8, 740: 5, 800: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 897: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 3, 918: 7, 921: 8, 933: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 3, 955: 8, 956: 8, 979: 2, 998: 5, 999: 7, 1000: 8, 1001: 8, 1005: 2, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1059: 1, 1112: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1184: 8, 1185: 8, 1186: 8, 1189: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1197: 8, 1198: 8, 1199: 8, 1206: 8, 1212: 8, 1227: 8, 1232: 8, 1235: 8, 1237: 8, 1263: 8, 1264: 8, 1279: 8, 1552: 8, 1553: 8, 1554: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1599: 8, 1656: 8, 1728: 8, 1745: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + }, + { + # 2019 Highlander Hybrid Limited Platinum + 36: 8, 37: 8, 170: 8, 180: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 581: 5, 608: 8, 610: 5, 643: 7, 713: 8, 740: 5, 800: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 897: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 3, 918: 7, 921: 8, 933: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 3, 955: 8, 956: 8, 979: 2, 992: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1057: 8, 1059: 1, 1076: 8, 1077: 8, 1112: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1184: 8, 1185: 8, 1186: 8, 1189: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1197: 8, 1198: 8, 1199: 8, 1206: 8, 1212: 8, 1227: 8, 1232: 8, 1235: 8, 1237: 8, 1263: 8, 1279: 8, 1552: 8, 1553: 8, 1554: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1599: 8, 1656: 8, 1666: 8, 1667: 8, 1728: 8, 1745: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + }], + CAR.AVALON: [{ + 36: 8, 37: 8, 170: 8, 180: 8, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 547: 8, 550: 8, 552: 4, 562: 6, 608: 8, 610: 5, 643: 7, 705: 8, 740: 5, 800: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 897: 8, 905: 8, 911: 1, 916: 2, 921: 8, 933: 6, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 979: 2, 1005: 2, 1014: 8, 1017: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1200: 8, 1201: 8, 1202: 8, 1203: 8, 1206: 8, 1227: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1552: 8, 1553: 8, 1554: 8, 1555: 8, 1556: 8, 1557: 8, 1558: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1596: 8, 1597: 8, 1664: 8, 1728: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + }], + CAR.RAV4_TSS2: [ + # LE + { + 36: 8, 37: 8, 170: 8, 180: 8, 186: 4, 355: 5, 401: 8, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 565: 8, 608: 8, 610: 8, 643: 7, 705: 8, 728: 8, 740: 5, 742: 8, 743: 8, 761: 8, 764: 8, 765: 8, 800: 8, 810: 2, 812: 8, 824: 8, 829: 2, 830: 7, 835: 8, 836: 8, 865: 8, 869: 7, 870: 7, 871: 2, 877: 8, 881: 8, 882: 8, 885: 8, 896: 8, 898: 8, 900: 6, 902: 6, 905: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1063: 8, 1076: 8, 1077: 8,1114: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1172: 8, 1235: 8, 1279: 8, 1541: 8, 1552: 8, 1553:8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1592: 8, 1594: 8, 1595: 8, 1649: 8, 1745: 8, 1775: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + }, + # XLE, Limited, and AWD + { + 36: 8, 37: 8, 170: 8, 180: 8, 186: 4, 401: 8, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 565: 8, 608: 8, 610: 8, 643: 7, 658: 8, 705: 8, 728: 8, 740: 5, 742: 8, 743: 8, 761: 8, 764: 8, 765: 8, 800: 8, 810: 2, 812: 8, 814: 8, 818: 8, 822: 8, 824: 8, 829: 2, 830: 7, 835: 8, 836: 8, 865: 8, 869: 7, 870: 7, 871: 2, 877: 8, 881: 8, 882: 8, 885: 8, 889: 8, 891: 8, 896: 8, 898: 8, 900: 6, 902: 6, 905: 8, 918: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 987: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1063: 8, 1076: 8, 1077: 8, 1082: 8, 1084: 8, 1085: 8, 1086: 8, 1114: 8, 1132: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1172: 8, 1228: 8, 1235: 8, 1237: 8, 1263: 8, 1264: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1592: 8, 1594: 8, 1595: 8, 1649: 8, 1696: 8, 1745: 8, 1775: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8, 2015: 8, 2016: 8, 2024: 8 + }], + CAR.COROLLA_TSS2: [ + # hatch 2019+ and sedan 2020+ + { + 36: 8, 37: 8, 114: 5, 170: 8, 180: 8, 186: 4, 401: 8, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 608: 8, 610: 8, 643: 7, 705: 8, 728: 8, 740: 5, 742: 8, 743: 8, 761: 8, 764: 8, 765: 8, 800: 8, 810: 2, 812: 8, 824: 8, 829: 2, 830: 7, 835: 8, 836: 8, 865: 8, 869: 7, 870: 7, 871: 2, 877: 8, 881: 8, 896: 8, 898: 8, 900: 6, 902: 6, 905: 8, 913: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1076: 8, 1077: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1172: 8, 1235: 8, 1237: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1592: 8, 1595: 8, 1649: 8, 1745: 8, 1775: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1808: 8, 1809: 8, 1816: 8, 1817: 8, 1840: 8, 1848: 8, 1904: 8, 1912: 8, 1940: 8, 1941: 8, 1948: 8, 1949: 8, 1952: 8, 1960: 8, 1981: 8, 1986: 8, 1990: 8, 1994: 8, 1998: 8, 2004: 8 + }], + CAR.COROLLAH_TSS2: [ + # 2019 Taiwan Altis Hybrid + { + 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 401: 8, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 8, 643: 7, 713: 8, 728: 8, 740: 5, 742: 8, 743: 8, 761: 8, 765: 8, 800: 8, 810: 2, 829: 2, 830: 7, 835: 8, 836: 8, 865: 8, 869: 7, 870: 7, 871: 2, 877: 8, 881: 8, 885: 8, 896: 8, 898: 8, 918: 7, 921: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 975: 5, 987: 8, 993: 8, 1002: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1057: 8, 1059: 1, 1071: 8, 1082: 8, 1112: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1172: 8, 1235: 8, 1237: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1592: 8, 1594: 8, 1595: 8, 1745: 8, 1775: 8, 1779: 8 + }], + CAR.LEXUS_ES_TSS2: [{ + 36: 8, 37: 8, 114: 5, 119: 6, 120: 4, 170: 8, 180: 8, 186: 4, 401: 8, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 608: 8, 610: 8, 643: 7, 658: 8, 705: 8, 728: 8, 740: 5, 761: 8, 764: 8, 765: 8, 800: 8, 810: 2, 812: 8, 814: 8, 818: 8, 824: 8, 830: 7, 835: 8, 836: 8, 865: 8, 869: 7, 870: 7, 871: 2, 877: 8, 881: 8, 882: 8, 885: 8, 889: 8, 896: 8, 898: 8, 900: 6, 902: 6, 905: 8, 913: 8, 918: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 987: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1076: 8, 1077: 8, 1082: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1172: 8, 1228: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1575: 8, 1592: 8, 1594: 8, 1595: 8, 1649: 8, 1696: 8, 1775: 8, 1777: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1904: 8, 1912: 8 + }], + CAR.LEXUS_ESH_TSS2: [ + { + 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 401: 8, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 8, 643: 7, 658: 8, 713: 8, 728: 8, 740: 5, 742: 8, 743: 8, 744: 8, 761: 8, 764: 8, 765: 8, 800: 8, 810: 2, 812: 8, 814: 8, 818: 8, 824: 8, 829: 2, 830: 7, 835: 8, 836: 8, 863: 8, 865: 8, 869: 7, 870: 7, 871: 2, 877: 8, 881: 8, 882: 8, 885: 8, 889: 8, 896: 8, 898: 8, 900: 6, 902: 6, 905: 8, 913: 8, 918: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 975: 5, 987: 8, 993: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1056: 8, 1057: 8, 1059: 1, 1071: 8, 1076: 8, 1077: 8, 1082: 8, 1084: 8, 1085: 8, 1086: 8, 1114: 8, 1132: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1172: 8, 1228: 8, 1235: 8, 1264: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1575: 8, 1592: 8, 1594: 8, 1595: 8, 1649: 8, 1696: 8, 1775: 8, 1777: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + }], + CAR.SIENNA: [ + { + 36: 8, 37: 8, 114: 5, 119: 6, 120: 4, 170: 8, 180: 8, 186: 4, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 545: 5, 548: 8, 550: 8, 552: 4, 562: 4, 608: 8, 610: 5, 643: 7, 705: 8, 725: 2, 740: 5, 764: 8, 800: 8, 824: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 888: 8, 896: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 1, 918: 7, 921: 8, 933: 8, 944: 6, 945: 8, 951: 8, 955: 8, 956: 8, 979: 2, 992: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1008: 2, 1014: 8, 1017: 8, 1041: 8, 1042: 8, 1043: 8, 1056: 8, 1059: 1, 1076: 8, 1077: 8, 1114: 8, 1160: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1182: 8, 1183: 8, 1191: 8, 1192: 8, 1196: 8, 1197: 8, 1198: 8, 1199: 8, 1200: 8, 1201: 8, 1202: 8, 1203: 8, 1212: 8, 1227: 8, 1228: 8, 1235: 8, 1237: 8, 1279: 8, 1552: 8, 1553: 8, 1555: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1656: 8, 1664: 8, 1666: 8, 1667: 8, 1728: 8, 1745: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + }, + # XLE AWD 2018 + { + 36: 8, 37: 8, 114: 5, 119: 6, 120: 4, 170: 8, 180: 8, 186: 4, 238: 4, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 545: 5, 548: 8, 550: 8, 552: 4, 562: 4, 608: 8, 610: 5, 643: 7, 705: 8, 725: 2, 740: 5, 764: 8, 800: 8, 824: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 1, 921: 8, 933: 8, 944: 6, 945: 8, 951: 8, 955: 8, 956: 8, 979: 2, 992: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1008: 2, 1014: 8, 1017: 8, 1041: 8, 1042: 8, 1043: 8, 1056: 8, 1059: 1, 1076: 8, 1077: 8, 1114: 8, 1160: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1182: 8, 1183: 8, 1191: 8, 1192: 8, 1196: 8, 1197: 8, 1198: 8, 1199: 8, 1200: 8, 1201: 8, 1202: 8, 1203: 8, 1212: 8, 1227: 8, 1235: 8, 1237: 8, 1279: 8, 1552: 8, 1553: 8, 1555: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1656: 8, 1664: 8, 1666: 8, 1667: 8, 1728: 8, 1745: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + }], + CAR.LEXUS_IS: [ + # IS300 2018 + { + 36: 8, 37: 8, 114: 5, 119: 6, 120: 4, 170: 8, 180: 8, 186: 4, 238: 4, 400: 6, 426: 6, 452: 8, 464: 8, 466: 8, 467: 5, 544: 4, 550: 8, 552: 4, 608: 8, 610: 5, 643: 7, 705: 8, 740: 5, 800: 8, 836: 8, 845: 5, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 897: 8, 900: 6, 902: 6, 905: 8, 911: 8, 913: 8, 916: 3, 918: 7, 921: 8, 933: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 979: 2, 992: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1005: 2, 1008: 2, 1009: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1059: 1, 1112: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1168: 1, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1182: 8, 1183: 8, 1184: 8, 1185: 8, 1186: 8, 1187: 8, 1189: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1197: 8, 1198: 8, 1199: 8, 1206: 8, 1208: 8, 1212: 8, 1227: 8, 1235: 8, 1237: 8, 1279: 8, 1408: 8, 1409: 8, 1410: 8, 1552: 8, 1553: 8, 1554: 8, 1555: 8, 1556: 8, 1557: 8, 1561: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1575: 8, 1584: 8, 1589: 8, 1590: 8, 1592: 8, 1593: 8, 1595: 8, 1599: 8, 1648: 8, 1666: 8, 1667: 8, 1728: 8, 1745: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + }, + # IS300H 2017 + { + 36: 8, 37: 8, 170: 8, 180: 8, 295: 8, 296: 8, 400: 6, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 581: 5, 608: 8, 610: 5, 643: 7, 713: 8, 740: 5, 800: 8, 836: 8, 845: 5, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 897: 8, 900: 6, 902: 6, 905: 8, 911: 8, 913: 8, 916: 3, 918: 7, 921: 7, 933: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 3, 955: 8, 956: 8, 979: 2, 992: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1009: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1057: 8, 1059: 1, 1112: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1168: 1, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1184: 8, 1185: 8, 1186: 8, 1187: 8, 1189: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1197: 8, 1198: 8, 1199: 8, 1206: 8, 1208: 8, 1212: 8, 1227: 8, 1232: 8, 1235: 8, 1279: 8, 1408: 8, 1409: 8, 1410: 8, 1552: 8, 1553: 8, 1554: 8, 1555: 8, 1556: 8, 1557: 8, 1561: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1575: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1599: 8, 1728: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 }], + CAR.LEXUS_CTH: [{ + 36: 8, 37: 8, 170: 8, 180: 8, 288: 8, 426: 6, 452: 8, 466: 8, 467: 8, 548: 8, 552: 4, 560: 7, 581: 5, 608: 8, 610: 5, 643: 7, 713: 8, 740: 5, 800: 8, 810: 2, 832: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 897: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 1, 921: 8, 933: 8, 944: 6, 945: 8, 950: 8, 951: 8, 953: 3, 955: 4, 956: 8, 979: 2, 992: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1017: 8, 1041: 8, 1042: 8, 1043: 8, 1056: 8, 1057: 8, 1059: 1, 1076: 8, 1077: 8, 1114: 8, 1116: 8, 1160: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1184: 8, 1185: 8, 1186: 8, 1190: 8, 1191: 8, 1192: 8, 1227: 8, 1235: 8, 1279: 8, 1552: 8, 1553: 8, 1554: 8, 1555: 8, 1556: 8, 1557: 8, 1558: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1575: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1664: 8, 1728: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + }] } STEER_THRESHOLD = 100 DBC = { - CAR.RAV4H: dbc_dict('toyota_rav4_hybrid_2017_pt_generated', 'toyota_prius_2017_adas'), - CAR.RAV4: dbc_dict('toyota_rav4_2017_pt_generated', 'toyota_prius_2017_adas'), - CAR.PRIUS: dbc_dict('toyota_prius_2017_pt_generated', 'toyota_prius_2017_adas'), - CAR.COROLLA: dbc_dict('toyota_corolla_2017_pt_generated', 'toyota_prius_2017_adas'), - CAR.LEXUS_RXH: dbc_dict('lexus_rx_hybrid_2017_pt_generated', 'toyota_prius_2017_adas'), - CAR.CHR: dbc_dict('toyota_chr_2018_pt_generated', 'toyota_prius_2017_adas'), - CAR.CHRH: dbc_dict('toyota_chr_hybrid_2018_pt_generated', 'toyota_prius_2017_adas'), - CAR.CAMRY: dbc_dict('toyota_chr_2018_pt_generated', 'toyota_prius_2017_adas'), - CAR.CAMRYH: dbc_dict('toyota_camry_hybrid_2018_pt_generated', 'toyota_prius_2017_adas'), - CAR.HIGHLANDER: dbc_dict('toyota_highlander_2017_pt_generated', 'toyota_prius_2017_adas'), - CAR.HIGHLANDERH: dbc_dict('toyota_highlander_hybrid_2018_pt_generated', 'toyota_prius_2017_adas'), + CAR.RAV4H: dbc_dict('toyota_rav4_hybrid_2017_pt_generated', 'toyota_adas'), + CAR.RAV4: dbc_dict('toyota_rav4_2017_pt_generated', 'toyota_adas'), + CAR.PRIUS: dbc_dict('toyota_prius_2017_pt_generated', 'toyota_adas'), + CAR.COROLLA: dbc_dict('toyota_corolla_2017_pt_generated', 'toyota_adas'), + CAR.LEXUS_RXH: dbc_dict('lexus_rx_hybrid_2017_pt_generated', 'toyota_adas'), + CAR.CHR: dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'), + CAR.CHRH: dbc_dict('toyota_nodsu_hybrid_pt_generated', 'toyota_adas'), + CAR.CAMRY: dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'), + CAR.CAMRYH: dbc_dict('toyota_camry_hybrid_2018_pt_generated', 'toyota_adas'), + CAR.HIGHLANDER: dbc_dict('toyota_highlander_2017_pt_generated', 'toyota_adas'), + CAR.HIGHLANDERH: dbc_dict('toyota_highlander_hybrid_2018_pt_generated', 'toyota_adas'), + CAR.AVALON: dbc_dict('toyota_avalon_2017_pt_generated', 'toyota_adas'), + CAR.RAV4_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), + CAR.COROLLA_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), + CAR.COROLLAH_TSS2: dbc_dict('toyota_nodsu_hybrid_pt_generated', 'toyota_tss2_adas'), + CAR.LEXUS_ES_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), + CAR.LEXUS_ESH_TSS2: dbc_dict('toyota_nodsu_hybrid_pt_generated', 'toyota_tss2_adas'), + CAR.SIENNA: dbc_dict('toyota_sienna_xle_2018_pt_generated', 'toyota_adas'), + CAR.LEXUS_IS: dbc_dict('lexus_is_2018_pt_generated', 'toyota_adas'), + CAR.LEXUS_CTH: dbc_dict('lexus_ct200h_2018_pt_generated', 'toyota_adas'), } -NO_DSU_CAR = [CAR.CHR, CAR.CHRH, CAR.CAMRY, CAR.CAMRYH] +NO_DSU_CAR = [CAR.CHR, CAR.CHRH, CAR.CAMRY, CAR.CAMRYH, CAR.RAV4_TSS2, CAR.COROLLA_TSS2, CAR.COROLLAH_TSS2, CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2] +TSS2_CAR = [CAR.RAV4_TSS2, CAR.COROLLA_TSS2, CAR.COROLLAH_TSS2, CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2] +NO_STOP_TIMER_CAR = [CAR.RAV4H, CAR.HIGHLANDERH, CAR.HIGHLANDER, CAR.RAV4_TSS2, CAR.COROLLA_TSS2, CAR.COROLLAH_TSS2, CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2, CAR.SIENNA] # no resume button press required diff --git a/selfdrive/car/vin.py b/selfdrive/car/vin.py new file mode 100755 index 00000000000000..eac0316db4d33e --- /dev/null +++ b/selfdrive/car/vin.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +import selfdrive.messaging as messaging +from selfdrive.boardd.boardd import can_list_to_can_capnp + +VIN_UNKNOWN = "0" * 17 + +# sanity checks on response messages from vin query +def is_vin_response_valid(can_dat, step, cnt): + if len(can_dat) != 8: + # ISO-TP meesages are all 8 bytes + return False + + if step == 0: + # VIN does not fit in a single message and it's 20 bytes of data + if can_dat[0] != 0x10 or can_dat[1] != 0x14: + return False + + if step == 1 and cnt == 0: + # first response after a CONTINUE query is sent + if can_dat[0] != 0x21: + return False + + if step == 1 and cnt == 1: + # second response after a CONTINUE query is sent + if can_dat[0] != 0x22: + return False + + return True + + +class VinQuery(): + def __init__(self, bus): + self.bus = bus + # works on standard 11-bit addresses for diagnostic. Tested on Toyota and Subaru; + # Honda uses the extended 29-bit addresses, and unfortunately only works from OBDII + self.query_ext_msgs = [[0x18DB33F1, 0, b'\x02\x09\x02'.ljust(8, b"\x00"), bus], + [0x18DA10f1, 0, b'\x30'.ljust(8, b"\x00"), bus]] + self.query_nor_msgs = [[0x7df, 0, b'\x02\x09\x02'.ljust(8, b"\x00"), bus], + [0x7e0, 0, b'\x30'.ljust(8, b"\x00"), bus]] + + self.cnts = [1, 2] # number of messages to wait for at each iteration + self.step = 0 + self.cnt = 0 + self.responded = False + self.never_responded = True + self.dat = b"" + self.vin = VIN_UNKNOWN + + def check_response(self, msg): + # have we got a VIN query response? + if msg.src == self.bus and msg.address in [0x18daf110, 0x7e8]: + self.never_responded = False + # basic sanity checks on ISO-TP response + if is_vin_response_valid(msg.dat, self.step, self.cnt): + self.dat += bytes(msg.dat[2:]) if self.step == 0 else bytes(msg.dat[1:]) + self.cnt += 1 + if self.cnt == self.cnts[self.step]: + self.responded = True + self.step += 1 + + def send_query(self, sendcan): + # keep sending VIN qury if ECU isn't responsing. + # sendcan is probably not ready due to the zmq slow joiner syndrome + if self.never_responded or (self.responded and self.step < len(self.cnts)): + sendcan.send(can_list_to_can_capnp([self.query_ext_msgs[self.step]], msgtype='sendcan')) + sendcan.send(can_list_to_can_capnp([self.query_nor_msgs[self.step]], msgtype='sendcan')) + self.responded = False + self.cnt = 0 + + def get_vin(self): + # only report vin if procedure is finished + if self.step == len(self.cnts) and self.cnt == self.cnts[-1]: + self.vin = self.dat[3:].decode('utf8') + return self.vin + + +def get_vin(logcan, sendcan, bus, query_time=1.): + vin_query = VinQuery(bus) + frame = 0 + + # 1s max of VIN query time + while frame < query_time * 100: + a = messaging.get_one_can(logcan) + + for can in a.can: + vin_query.check_response(can) + + vin_query.send_query(sendcan) + frame += 1 + + return vin_query.get_vin() + + +if __name__ == "__main__": + logcan = messaging.sub_sock('can') + sendcan = messaging.pub_sock('sendcan') + print(get_vin(logcan, sendcan, 0)) diff --git a/pyextra/Flask-1.0.2-py2.7.egg-info/dependency_links.txt b/selfdrive/car/volkswagen/__init__.py similarity index 100% rename from pyextra/Flask-1.0.2-py2.7.egg-info/dependency_links.txt rename to selfdrive/car/volkswagen/__init__.py diff --git a/selfdrive/car/volkswagen/carcontroller.py b/selfdrive/car/volkswagen/carcontroller.py new file mode 100644 index 00000000000000..4ec662dce4c6bf --- /dev/null +++ b/selfdrive/car/volkswagen/carcontroller.py @@ -0,0 +1,188 @@ +from cereal import car +from selfdrive.car import apply_std_steer_torque_limits +from selfdrive.car.volkswagen import volkswagencan +from selfdrive.car.volkswagen.values import DBC, MQB_LDW_MESSAGES, BUTTON_STATES, CarControllerParams +from selfdrive.can.packer import CANPacker + +VisualAlert = car.CarControl.HUDControl.VisualAlert + + +class CarController(): + def __init__(self, canbus, car_fingerprint): + self.apply_steer_last = 0 + self.car_fingerprint = car_fingerprint + + # Setup detection helper. Routes commands to an appropriate CAN bus number. + self.canbus = canbus + self.packer_gw = CANPacker(DBC[car_fingerprint]['pt']) + + self.hcaSameTorqueCount = 0 + self.hcaEnabledFrameCount = 0 + self.graButtonStatesToSend = None + self.graMsgSentCount = 0 + self.graMsgStartFramePrev = 0 + self.graMsgBusCounterPrev = 0 + + def update(self, enabled, CS, frame, actuators, visual_alert, audible_alert, leftLaneVisible, rightLaneVisible): + """ Controls thread """ + + P = CarControllerParams + + # Send CAN commands. + can_sends = [] + canbus = self.canbus + + #-------------------------------------------------------------------------- + # # + # Prepare HCA_01 Heading Control Assist messages with steering torque. # + # # + #-------------------------------------------------------------------------- + + # The factory camera sends at 50Hz while steering and 1Hz when not. When + # OP is active, Panda filters HCA_01 from the factory camera and OP emits + # HCA_01 at 50Hz. Rate switching creates some confusion in Cabana and + # doesn't seem to add value at this time. The rack will accept HCA_01 at + # 100Hz if we want to control at finer resolution in the future. + if frame % P.HCA_STEP == 0: + + # FAULT AVOIDANCE: HCA must not be enabled at standstill. Also stop + # commanding HCA if there's a fault, so the steering rack recovers. + if enabled and not (CS.standstill or CS.steeringFault): + + # FAULT AVOIDANCE: Requested HCA torque must not exceed 3.0 Nm. This + # is inherently handled by scaling to STEER_MAX. The rack doesn't seem + # to care about up/down rate, but we have some evidence it may do its + # own rate limiting, and matching OP helps for accurate tuning. + apply_steer = int(round(actuators.steer * P.STEER_MAX)) + apply_steer = apply_std_steer_torque_limits(apply_steer, self.apply_steer_last, CS.steeringTorque, P) + + # FAULT AVOIDANCE: HCA must not be enabled for >360 seconds. Sending + # a single frame with HCA disabled is an effective workaround. + if apply_steer == 0: + # We can usually reset the timer for free, just by disabling HCA + # when apply_steer is exactly zero, which happens by chance during + # many steer torque direction changes. This could be expanded with + # a small dead-zone to capture all zero crossings, but not seeing a + # major need at this time. + hcaEnabled = False + self.hcaEnabledFrameCount = 0 + else: + self.hcaEnabledFrameCount += 1 + if self.hcaEnabledFrameCount >= 118 * (100 / P.HCA_STEP): # 118s + # The Kansas I-70 Crosswind Problem: if we truly do need to steer + # in one direction for > 360 seconds, we have to disable HCA for a + # frame while actively steering. Testing shows we can just set the + # disabled flag, and keep sending non-zero torque, which keeps the + # Panda torque rate limiting safety happy. Do so 3x within the 360 + # second window for safety and redundancy. + hcaEnabled = False + self.hcaEnabledFrameCount = 0 + else: + hcaEnabled = True + # FAULT AVOIDANCE: HCA torque must not be static for > 6 seconds. + # This is to detect the sending camera being stuck or frozen. OP + # can trip this on a curve if steering is saturated. Avoid this by + # reducing torque 0.01 Nm for one frame. Do so 3x within the 6 + # second period for safety and redundancy. + if self.apply_steer_last == apply_steer: + self.hcaSameTorqueCount += 1 + if self.hcaSameTorqueCount > 1.9 * (100 / P.HCA_STEP): # 1.9s + apply_steer -= (1, -1)[apply_steer < 0] + self.hcaSameTorqueCount = 0 + else: + self.hcaSameTorqueCount = 0 + + else: + # Continue sending HCA_01 messages, with the enable flags turned off. + hcaEnabled = False + apply_steer = 0 + + self.apply_steer_last = apply_steer + idx = (frame / P.HCA_STEP) % 16 + can_sends.append(volkswagencan.create_mqb_steering_control(self.packer_gw, canbus.gateway, apply_steer, + idx, hcaEnabled)) + + #-------------------------------------------------------------------------- + # # + # Prepare LDW_02 HUD messages with lane borders, confidence levels, and # + # the LKAS status LED. # + # # + #-------------------------------------------------------------------------- + + # The factory camera emits this message at 10Hz. When OP is active, Panda + # filters LDW_02 from the factory camera and OP emits LDW_02 at 10Hz. + + if frame % P.LDW_STEP == 0: + hcaEnabled = True if enabled and not CS.standstill else False + + if visual_alert == VisualAlert.steerRequired: + hud_alert = MQB_LDW_MESSAGES["laneAssistTakeOverSilent"] + else: + hud_alert = MQB_LDW_MESSAGES["none"] + + can_sends.append(volkswagencan.create_mqb_hud_control(self.packer_gw, canbus.gateway, hcaEnabled, + CS.steeringPressed, hud_alert, leftLaneVisible, + rightLaneVisible)) + + #-------------------------------------------------------------------------- + # # + # Prepare GRA_ACC_01 ACC control messages with button press events. # + # # + #-------------------------------------------------------------------------- + + # The car sends this message at 33hz. OP sends it on-demand only for + # virtual button presses. + # + # First create any virtual button press event needed by openpilot, to sync + # stock ACC with OP disengagement, or to auto-resume from stop. + + if frame > self.graMsgStartFramePrev + P.GRA_VBP_STEP: + if not enabled and CS.accEnabled: + # Cancel ACC if it's engaged with OP disengaged. + self.graButtonStatesToSend = BUTTON_STATES.copy() + self.graButtonStatesToSend["cancel"] = True + elif enabled and CS.standstill: + # Blip the Resume button if we're engaged at standstill. + # FIXME: This is a naive implementation, improve with visiond or radar input. + # A subset of MQBs like to "creep" too aggressively with this implementation. + self.graButtonStatesToSend = BUTTON_STATES.copy() + self.graButtonStatesToSend["resumeCruise"] = True + + # OP/Panda can see this message but can't filter it when integrated at the + # R242 LKAS camera. It could do so if integrated at the J533 gateway, but + # we need a generalized solution that works for either. The message is + # counter-protected, so we need to time our transmissions very precisely + # to achieve fast and fault-free switching between message flows accepted + # at the J428 ACC radar. + # + # Example message flow on the bus, frequency of 33Hz (GRA_ACC_STEP): + # + # CAR: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 + # EON: 3 4 5 6 7 8 9 A B C D E F 0 1 2 GG^ + # + # If OP needs to send a button press, it waits to see a GRA_ACC_01 message + # counter change, and then immediately follows up with the next increment. + # The OP message will be sent within about 1ms of the car's message, which + # is about 2ms before the car's next message is expected. OP sends for an + # arbitrary duration of 16 messages / ~0.5 sec, in lockstep with each new + # message from the car. + # + # Because OP's counter is synced to the car, J428 immediately accepts the + # OP messages as valid. Further messages from the car get discarded as + # duplicates without a fault. When OP stops sending, the extra time gap + # (GG) to the next valid car message is less than 1 * GRA_ACC_STEP. J428 + # tolerates the gap just fine and control returns to the car immediately. + + if CS.graMsgBusCounter != self.graMsgBusCounterPrev: + self.graMsgBusCounterPrev = CS.graMsgBusCounter + if self.graButtonStatesToSend is not None: + if self.graMsgSentCount == 0: + self.graMsgStartFramePrev = frame + idx = (CS.graMsgBusCounter + 1) % 16 + can_sends.append(volkswagencan.create_mqb_acc_buttons_control(self.packer_gw, canbus.extended, self.graButtonStatesToSend, CS, idx)) + self.graMsgSentCount += 1 + if self.graMsgSentCount >= 16: + self.graButtonStatesToSend = None + self.graMsgSentCount = 0 + + return can_sends diff --git a/selfdrive/car/volkswagen/carstate.py b/selfdrive/car/volkswagen/carstate.py new file mode 100644 index 00000000000000..a39cbae8c57af0 --- /dev/null +++ b/selfdrive/car/volkswagen/carstate.py @@ -0,0 +1,229 @@ +import numpy as np +from cereal import car +from common.kalman.simple_kalman import KF1D +from selfdrive.config import Conversions as CV +from selfdrive.can.parser import CANParser +from selfdrive.can.can_define import CANDefine +from selfdrive.car.volkswagen.values import DBC, BUTTON_STATES +from selfdrive.car.volkswagen.carcontroller import CarControllerParams + +GEAR = car.CarState.GearShifter + +def get_mqb_gateway_can_parser(CP, canbus): + # this function generates lists for signal, messages and initial values + signals = [ + # sig_name, sig_address, default + ("LWI_Lenkradwinkel", "LWI_01", 0), # Absolute steering angle + ("LWI_VZ_Lenkradwinkel", "LWI_01", 0), # Steering angle sign + ("LWI_Lenkradw_Geschw", "LWI_01", 0), # Absolute steering rate + ("LWI_VZ_Lenkradw_Geschw", "LWI_01", 0), # Steering rate sign + ("ESP_VL_Radgeschw_02", "ESP_19", 0), # ABS wheel speed, front left + ("ESP_VR_Radgeschw_02", "ESP_19", 0), # ABS wheel speed, front right + ("ESP_HL_Radgeschw_02", "ESP_19", 0), # ABS wheel speed, rear left + ("ESP_HR_Radgeschw_02", "ESP_19", 0), # ABS wheel speed, rear right + ("ESP_Gierrate", "ESP_02", 0), # Absolute yaw rate + ("ESP_VZ_Gierrate", "ESP_02", 0), # Yaw rate sign + ("ZV_FT_offen", "Gateway_72", 0), # Door open, driver + ("ZV_BT_offen", "Gateway_72", 0), # Door open, passenger + ("ZV_HFS_offen", "Gateway_72", 0), # Door open, rear left + ("ZV_HBFS_offen", "Gateway_72", 0), # Door open, rear right + ("ZV_HD_offen", "Gateway_72", 0), # Trunk or hatch open + ("BH_Blinker_li", "Gateway_72", 0), # Left turn signal on + ("BH_Blinker_re", "Gateway_72", 0), # Right turn signal on + ("GE_Fahrstufe", "Getriebe_11", 0), # Auto trans gear selector position + ("AB_Gurtschloss_FA", "Airbag_02", 0), # Seatbelt status, driver + ("AB_Gurtschloss_BF", "Airbag_02", 0), # Seatbelt status, passenger + ("ESP_Fahrer_bremst", "ESP_05", 0), # Brake pedal pressed + ("ESP_Status_Bremsdruck", "ESP_05", 0), # Brakes applied + ("ESP_Bremsdruck", "ESP_05", 0), # Brake pressure applied + ("MO_Fahrpedalrohwert_01", "Motor_20", 0), # Accelerator pedal value + ("MO_Kuppl_schalter", "Motor_14", 0), # Clutch switch + ("Driver_Strain", "EPS_01", 0), # Absolute driver torque input + ("Driver_Strain_VZ", "EPS_01", 0), # Driver torque input sign + ("HCA_Ready", "EPS_01", 0), # Steering rack HCA support configured + ("ESP_Tastung_passiv", "ESP_21", 0), # Stability control disabled + ("KBI_MFA_v_Einheit_02", "Einheiten_01", 0), # MPH vs KMH speed display + ("KBI_Handbremse", "Kombi_01", 0), # Manual handbrake applied + ("TSK_Fahrzeugmasse_02", "Motor_16", 0), # Estimated vehicle mass from drivetrain coordinator + ("GRA_Hauptschalter", "GRA_ACC_01", 0), # ACC button, on/off + ("GRA_Abbrechen", "GRA_ACC_01", 0), # ACC button, cancel + ("GRA_Tip_Setzen", "GRA_ACC_01", 0), # ACC button, set + ("GRA_Tip_Hoch", "GRA_ACC_01", 0), # ACC button, increase or accel + ("GRA_Tip_Runter", "GRA_ACC_01", 0), # ACC button, decrease or decel + ("GRA_Tip_Wiederaufnahme", "GRA_ACC_01", 0), # ACC button, resume + ("GRA_Verstellung_Zeitluecke", "GRA_ACC_01", 0), # ACC button, time gap adj + ("GRA_Typ_Hauptschalter", "GRA_ACC_01", 0), # ACC main button type + ("GRA_Tip_Stufe_2", "GRA_ACC_01", 0), # unknown related to stalk type + ("GRA_ButtonTypeInfo", "GRA_ACC_01", 0), # unknown related to stalk type + ("COUNTER", "GRA_ACC_01", 0), # GRA_ACC_01 CAN message counter + ] + + checks = [ + # sig_address, frequency + ("LWI_01", 100), # From J500 Steering Assist with integrated sensors + ("EPS_01", 100), # From J500 Steering Assist with integrated sensors + ("ESP_19", 100), # From J104 ABS/ESP controller + ("ESP_05", 50), # From J104 ABS/ESP controller + ("ESP_21", 50), # From J104 ABS/ESP controller + ("Motor_20", 50), # From J623 Engine control module + ("GRA_ACC_01", 33), # From J??? steering wheel control buttons + ("Getriebe_11", 20), # From J743 Auto transmission control module + ("Gateway_72", 10), # From J533 CAN gateway (aggregated data) + ("Motor_14", 10), # From J623 Engine control module + ("Airbag_02", 5), # From J234 Airbag control module + ("Kombi_01", 2), # From J285 Instrument cluster + ("Motor_16", 2), # From J623 Engine control module + ("Einheiten_01", 1), # From J??? not known if gateway, cluster, or BCM + ] + + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, canbus.gateway) + +def get_mqb_extended_can_parser(CP, canbus): + + signals = [ + # sig_name, sig_address, default + ("ACC_Status_ACC", "ACC_06", 0), # ACC engagement status + ("ACC_Typ", "ACC_06", 0), # ACC type (follow to stop, stop&go) + ("SetSpeed", "ACC_02", 0), # ACC set speed + ] + + checks = [ + # sig_address, frequency + ("ACC_06", 50), # From J428 ACC radar control module + ("ACC_02", 17), # From J428 ACC radar control module + ] + + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, canbus.extended) + +def parse_gear_shifter(gear, vals): + # Return mapping of gearshift position to selected gear. + + val_to_capnp = {'P': GEAR.park, 'R': GEAR.reverse, 'N': GEAR.neutral, + 'D': GEAR.drive, 'E': GEAR.eco, 'S': GEAR.sport, 'T': GEAR.manumatic} + try: + return val_to_capnp[vals[gear]] + except KeyError: + return "unknown" + +class CarState(): + def __init__(self, CP, canbus): + # initialize can parser + self.CP = CP + self.car_fingerprint = CP.carFingerprint + self.can_define = CANDefine(DBC[CP.carFingerprint]['pt']) + + self.shifter_values = self.can_define.dv["Getriebe_11"]['GE_Fahrstufe'] + + self.buttonStates = BUTTON_STATES.copy() + + # vEgo Kalman filter + dt = 0.01 + self.v_ego_kf = KF1D(x0=[[0.], [0.]], + A=[[1., dt], [0., 1.]], + C=[1., 0.], + K=[[0.12287673], [0.29666309]]) + + def update(self, gw_cp, ex_cp): + # Update vehicle speed and acceleration from ABS wheel speeds. + self.wheelSpeedFL = gw_cp.vl["ESP_19"]['ESP_VL_Radgeschw_02'] * CV.KPH_TO_MS + self.wheelSpeedFR = gw_cp.vl["ESP_19"]['ESP_VR_Radgeschw_02'] * CV.KPH_TO_MS + self.wheelSpeedRL = gw_cp.vl["ESP_19"]['ESP_HL_Radgeschw_02'] * CV.KPH_TO_MS + self.wheelSpeedRR = gw_cp.vl["ESP_19"]['ESP_HR_Radgeschw_02'] * CV.KPH_TO_MS + + self.vEgoRaw = float(np.mean([self.wheelSpeedFL, self.wheelSpeedFR, self.wheelSpeedRL, self.wheelSpeedRR])) + v_ego_x = self.v_ego_kf.update(self.vEgoRaw) + self.vEgo = float(v_ego_x[0]) + self.aEgo = float(v_ego_x[1]) + self.standstill = self.vEgoRaw < 0.1 + + # Update steering angle, rate, yaw rate, and driver input torque. VW send + # the sign/direction in a separate signal so they must be recombined. + self.steeringAngle = gw_cp.vl["LWI_01"]['LWI_Lenkradwinkel'] * (1,-1)[int(gw_cp.vl["LWI_01"]['LWI_VZ_Lenkradwinkel'])] + self.steeringRate = gw_cp.vl["LWI_01"]['LWI_Lenkradw_Geschw'] * (1,-1)[int(gw_cp.vl["LWI_01"]['LWI_VZ_Lenkradwinkel'])] + self.steeringTorque = gw_cp.vl["EPS_01"]['Driver_Strain'] * (1,-1)[int(gw_cp.vl["EPS_01"]['Driver_Strain_VZ'])] + self.steeringPressed = abs(self.steeringTorque) > CarControllerParams.STEER_DRIVER_ALLOWANCE + self.yawRate = gw_cp.vl["ESP_02"]['ESP_Gierrate'] * (1,-1)[int(gw_cp.vl["ESP_02"]['ESP_VZ_Gierrate'])] * CV.DEG_TO_RAD + + # Update gas, brakes, and gearshift. + self.gas = gw_cp.vl["Motor_20"]['MO_Fahrpedalrohwert_01'] / 100.0 + self.gasPressed = self.gas > 0 + self.brake = gw_cp.vl["ESP_05"]['ESP_Bremsdruck'] / 250.0 # FIXME: this is pressure in Bar, not sure what OP expects + self.brakePressed = bool(gw_cp.vl["ESP_05"]['ESP_Fahrer_bremst']) + self.brakeLights = bool(gw_cp.vl["ESP_05"]['ESP_Status_Bremsdruck']) + + # Update gear and/or clutch position data. + can_gear_shifter = int(gw_cp.vl["Getriebe_11"]['GE_Fahrstufe']) + self.gearShifter = parse_gear_shifter(can_gear_shifter, self.shifter_values) + + # Update door and trunk/hatch lid open status. + self.doorOpen = any([gw_cp.vl["Gateway_72"]['ZV_FT_offen'], + gw_cp.vl["Gateway_72"]['ZV_BT_offen'], + gw_cp.vl["Gateway_72"]['ZV_HFS_offen'], + gw_cp.vl["Gateway_72"]['ZV_HBFS_offen'], + gw_cp.vl["Gateway_72"]['ZV_HD_offen']]) + + # Update seatbelt fastened status. + self.seatbeltUnlatched = False if gw_cp.vl["Airbag_02"]["AB_Gurtschloss_FA"] == 3 else True + + # 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 gw_cp.vl["Einheiten_01"]["KBI_MFA_v_Einheit_02"] + + # Update ACC radar status. + accStatus = ex_cp.vl["ACC_06"]['ACC_Status_ACC'] + if accStatus == 1: + # ACC okay but disabled + self.accFault = False + self.accAvailable = False + self.accEnabled = False + elif accStatus == 2: + # ACC okay and enabled, but not currently engaged + self.accFault = False + self.accAvailable = True + self.accEnabled = False + elif accStatus in [3, 4, 5]: + # ACC okay and enabled, currently engaged and regulating speed (3) or engaged with driver accelerating (4) or overrun (5) + self.accFault = False + self.accAvailable = True + self.accEnabled = True + else: + # ACC fault of some sort. Seen statuses 6 or 7 for CAN comms disruptions, visibility issues, etc. + self.accFault = True + self.accAvailable = False + self.accEnabled = False + + # Update ACC setpoint. When the setpoint is zero or there's an error, the + # radar sends a set-speed of ~90.69 m/s / 203mph. + self.accSetSpeed = ex_cp.vl["ACC_02"]['SetSpeed'] + if self.accSetSpeed > 90: self.accSetSpeed = 0 + + # Update control button states for turn signals and ACC controls. + self.buttonStates["leftBlinker"] = bool(gw_cp.vl["Gateway_72"]['BH_Blinker_li']) + self.buttonStates["leftBlinker"] = bool(gw_cp.vl["Gateway_72"]['BH_Blinker_re']) + self.buttonStates["accelCruise"] = bool(gw_cp.vl["GRA_ACC_01"]['GRA_Tip_Hoch']) + self.buttonStates["decelCruise"] = bool(gw_cp.vl["GRA_ACC_01"]['GRA_Tip_Runter']) + self.buttonStates["cancel"] = bool(gw_cp.vl["GRA_ACC_01"]['GRA_Abbrechen']) + self.buttonStates["setCruise"] = bool(gw_cp.vl["GRA_ACC_01"]['GRA_Tip_Setzen']) + self.buttonStates["resumeCruise"] = bool(gw_cp.vl["GRA_ACC_01"]['GRA_Tip_Wiederaufnahme']) + self.buttonStates["gapAdjustCruise"] = bool(gw_cp.vl["GRA_ACC_01"]['GRA_Verstellung_Zeitluecke']) + + # Read ACC hardware button type configuration info that has to pass thru + # to the radar. Ends up being different for steering wheel buttons vs + # third stalk type controls. + self.graHauptschalter = gw_cp.vl["GRA_ACC_01"]['GRA_Hauptschalter'] + self.graTypHauptschalter = gw_cp.vl["GRA_ACC_01"]['GRA_Typ_Hauptschalter'] + self.graButtonTypeInfo = gw_cp.vl["GRA_ACC_01"]['GRA_ButtonTypeInfo'] + self.graTipStufe2 = gw_cp.vl["GRA_ACC_01"]['GRA_Tip_Stufe_2'] + # Pick up the GRA_ACC_01 CAN message counter so we can sync to it for + # later cruise-control button spamming. + self.graMsgBusCounter = gw_cp.vl["GRA_ACC_01"]['COUNTER'] + + # Check to make sure the electric power steering rack is configured to + # accept and respond to HCA_01 messages and has not encountered a fault. + self.steeringFault = not gw_cp.vl["EPS_01"]["HCA_Ready"] + + # Additional safety checks performed in CarInterface. + self.parkingBrakeSet = bool(gw_cp.vl["Kombi_01"]['KBI_Handbremse']) # FIXME: need to include an EPB check as well + self.stabilityControlDisabled = gw_cp.vl["ESP_21"]['ESP_Tastung_passiv'] + diff --git a/selfdrive/car/volkswagen/interface.py b/selfdrive/car/volkswagen/interface.py new file mode 100644 index 00000000000000..272c86bece9402 --- /dev/null +++ b/selfdrive/car/volkswagen/interface.py @@ -0,0 +1,242 @@ +from cereal import car +from selfdrive.config import Conversions as CV +from selfdrive.controls.lib.drive_helpers import create_event, EventTypes as ET +from selfdrive.controls.lib.vehicle_model import VehicleModel +from selfdrive.car.volkswagen.values import CAR, BUTTON_STATES +from selfdrive.car.volkswagen.carstate import CarState, get_mqb_gateway_can_parser, get_mqb_extended_can_parser +from common.params import Params +from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint +from selfdrive.car.interfaces import CarInterfaceBase + +GEAR = car.CarState.GearShifter + +class CANBUS: + gateway = 0 + extended = 2 + +class CarInterface(CarInterfaceBase): + def __init__(self, CP, CarController): + self.CP = CP + self.CC = None + + self.frame = 0 + + self.gasPressedPrev = False + self.brakePressedPrev = False + self.cruiseStateEnabledPrev = False + self.displayMetricUnitsPrev = None + self.buttonStatesPrev = BUTTON_STATES.copy() + + # *** init the major players *** + self.CS = CarState(CP, CANBUS) + self.VM = VehicleModel(CP) + self.gw_cp = get_mqb_gateway_can_parser(CP, CANBUS) + self.ex_cp = get_mqb_extended_can_parser(CP, CANBUS) + + # sending if read only is False + if CarController is not None: + self.CC = CarController(CANBUS, CP.carFingerprint) + + @staticmethod + def compute_gb(accel, speed): + return float(accel) / 4.0 + + @staticmethod + def get_params(candidate, fingerprint=gen_empty_fingerprint(), vin="", has_relay=False): + ret = car.CarParams.new_message() + + ret.carFingerprint = candidate + ret.isPandaBlack = has_relay + ret.carVin = vin + + if candidate == CAR.GOLF: + # Set common MQB parameters that will apply globally + ret.carName = "volkswagen" + ret.safetyModel = car.CarParams.SafetyModel.volkswagen + ret.enableCruise = True # Stock ACC still controls acceleration and braking + ret.openpilotLongitudinalControl = False + ret.steerControlType = car.CarParams.SteerControlType.torque + # Steer torque is strongly rate limit and max value is decently high. Off to avoid false positives + ret.steerLimitAlert = False + + # Additional common MQB parameters that may be overridden per-vehicle + ret.steerRateCost = 0.5 + ret.steerActuatorDelay = 0.05 # Hopefully all MQB racks are similar here + ret.steerMaxBP = [0.] # m/s + ret.steerMaxV = [1.] + + # As a starting point for speed-adjusted lateral tuning, use the example + # map speed breakpoints from a VW Tiguan (SSP 399 page 9). It's unclear + # whether the driver assist map breakpoints have any direct bearing on + # HCA assist torque, but if they're good breakpoints for the driver, + # they're probably good breakpoints for HCA as well. OP won't be driving + # 250kph/155mph but it provides interpolation scaling above 100kmh/62mph. + ret.lateralTuning.pid.kpBP = [0., 15 * CV.KPH_TO_MS, 50 * CV.KPH_TO_MS] + ret.lateralTuning.pid.kiBP = [0., 15 * CV.KPH_TO_MS, 50 * CV.KPH_TO_MS] + + # FIXME: Per-vehicle parameters need to be reintegrated. + # For the time being, per-vehicle stuff is being archived since we + # can't auto-detect very well yet. Now that tuning is figured out, + # averaged params should work reasonably on a range of cars. Owners + # can tweak here, as needed, until we have car type auto-detection. + + ret.mass = 1700 + STD_CARGO_KG + ret.wheelbase = 2.75 + ret.centerToFront = ret.wheelbase * 0.45 + ret.steerRatio = 15.6 + ret.lateralTuning.pid.kf = 0.00006 + ret.lateralTuning.pid.kpV = [0.15, 0.25, 0.60] + ret.lateralTuning.pid.kiV = [0.05, 0.05, 0.05] + tire_stiffness_factor = 0.6 + + ret.enableCamera = True # Stock camera detection doesn't apply to VW + ret.transmissionType = car.CarParams.TransmissionType.automatic + ret.steerRatioRear = 0. + + # No support for OP longitudinal control on Volkswagen at this time. + ret.gasMaxBP = [0.] + ret.gasMaxV = [0.] + ret.brakeMaxBP = [0.] + ret.brakeMaxV = [0.] + ret.longitudinalTuning.deadzoneBP = [0.] + ret.longitudinalTuning.deadzoneV = [0.] + ret.longitudinalTuning.kpBP = [0.] + ret.longitudinalTuning.kpV = [0.] + ret.longitudinalTuning.kiBP = [0.] + ret.longitudinalTuning.kiV = [0.] + + # TODO: get actual value, for now starting with reasonable value for + # civic and scaling by mass and wheelbase + ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) + + # TODO: start from empirically derived lateral slip stiffness for the civic and scale by + # mass and CG position, so all cars will have approximately similar dyn behaviors + ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, + tire_stiffness_factor=tire_stiffness_factor) + + return ret + + # returns a car.CarState + def update(self, c, can_strings): + canMonoTimes = [] + events = [] + buttonEvents = [] + params = Params() + ret = car.CarState.new_message() + + # Process the most recent CAN message traffic, and check for validity + self.gw_cp.update_strings(can_strings) + self.ex_cp.update_strings(can_strings) + self.CS.update(self.gw_cp, self.ex_cp) + ret.canValid = self.gw_cp.can_valid and self.ex_cp.can_valid + + # Wheel and vehicle speed, yaw rate + ret.wheelSpeeds.fl = self.CS.wheelSpeedFL + ret.wheelSpeeds.fr = self.CS.wheelSpeedFR + ret.wheelSpeeds.rl = self.CS.wheelSpeedRL + ret.wheelSpeeds.rr = self.CS.wheelSpeedRR + ret.vEgoRaw = self.CS.vEgoRaw + ret.vEgo = self.CS.vEgo + ret.aEgo = self.CS.aEgo + ret.standstill = self.CS.standstill + + # Steering wheel position, movement, yaw rate, and driver input + ret.steeringAngle = self.CS.steeringAngle + ret.steeringRate = self.CS.steeringRate + ret.steeringTorque = self.CS.steeringTorque + ret.steeringPressed = self.CS.steeringPressed + ret.yawRate = self.CS.yawRate + + # Gas, brakes and shifting + ret.gas = self.CS.gas + ret.gasPressed = self.CS.gasPressed + ret.brake = self.CS.brake + ret.brakePressed = self.CS.brakePressed + ret.brakeLights = self.CS.brakeLights + ret.gearShifter = self.CS.gearShifter + + # Doors open, seatbelt unfastened + ret.doorOpen = self.CS.doorOpen + ret.seatbeltUnlatched = self.CS.seatbeltUnlatched + + # Update the EON metric configuration to match the car at first startup, + # or if there's been a change. + if self.CS.displayMetricUnits != self.displayMetricUnitsPrev: + params.put("IsMetric", "1" if self.CS.displayMetricUnits else "0") + + # Blinker switch updates + ret.leftBlinker = self.CS.buttonStates["leftBlinker"] + ret.rightBlinker = self.CS.buttonStates["rightBlinker"] + + # ACC cruise state + ret.cruiseState.available = self.CS.accAvailable + ret.cruiseState.enabled = self.CS.accEnabled + ret.cruiseState.speed = self.CS.accSetSpeed + + # Check for and process state-change events (button press or release) from + # the turn stalk switch or ACC steering wheel/control stalk buttons. + for button in self.CS.buttonStates: + if self.CS.buttonStates[button] != self.buttonStatesPrev[button]: + be = car.CarState.ButtonEvent.new_message() + be.type = button + be.pressed = self.CS.buttonStates[button] + buttonEvents.append(be) + + # Vehicle operation safety checks and events + if ret.doorOpen: + events.append(create_event('doorOpen', [ET.NO_ENTRY, ET.SOFT_DISABLE])) + if ret.seatbeltUnlatched: + events.append(create_event('seatbeltNotLatched', [ET.NO_ENTRY, ET.SOFT_DISABLE])) + if ret.gearShifter == GEAR.reverse: + events.append(create_event('reverseGear', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) + if not ret.gearShifter in [GEAR.drive, GEAR.eco, GEAR.sport]: + events.append(create_event('wrongGear', [ET.NO_ENTRY, ET.SOFT_DISABLE])) + if self.CS.stabilityControlDisabled: + events.append(create_event('espDisabled', [ET.NO_ENTRY, ET.SOFT_DISABLE])) + if self.CS.parkingBrakeSet: + events.append(create_event('parkBrake', [ET.NO_ENTRY, ET.USER_DISABLE])) + + # Vehicle health safety checks and events + if self.CS.accFault: + events.append(create_event('radarFault', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) + if self.CS.steeringFault: + events.append(create_event('steerTempUnavailable', [ET.NO_ENTRY, ET.WARNING])) + + # Per the Comma safety model, disable on pedals rising edge or when brake + # is pressed and speed isn't zero. + if (ret.gasPressed and not self.gasPressedPrev) or \ + (ret.brakePressed and (not self.brakePressedPrev or not ret.standstill)): + events.append(create_event('pedalPressed', [ET.NO_ENTRY, ET.USER_DISABLE])) + if ret.gasPressed: + events.append(create_event('pedalPressed', [ET.PRE_ENABLE])) + + # Engagement and longitudinal control using stock ACC. Make sure OP is + # disengaged if stock ACC is disengaged. + if not ret.cruiseState.enabled: + events.append(create_event('pcmDisable', [ET.USER_DISABLE])) + # Attempt OP engagement only on rising edge of stock ACC engagement. + elif not self.cruiseStateEnabledPrev: + events.append(create_event('pcmEnable', [ET.ENABLE])) + + ret.events = events + ret.buttonEvents = buttonEvents + ret.canMonoTimes = canMonoTimes + + # update previous car states + self.gasPressedPrev = ret.gasPressed + self.brakePressedPrev = ret.brakePressed + self.cruiseStateEnabledPrev = ret.cruiseState.enabled + self.displayMetricUnitsPrev = self.CS.displayMetricUnits + self.buttonStatesPrev = self.CS.buttonStates.copy() + + # cast to reader so it can't be modified + return ret.as_reader() + + def apply(self, c): + can_sends = self.CC.update(c.enabled, self.CS, self.frame, c.actuators, + c.hudControl.visualAlert, + c.hudControl.audibleAlert, + c.hudControl.leftLaneVisible, + c.hudControl.rightLaneVisible) + self.frame += 1 + return can_sends diff --git a/selfdrive/car/volkswagen/radar_interface.py b/selfdrive/car/volkswagen/radar_interface.py new file mode 100644 index 00000000000000..b2f76511360320 --- /dev/null +++ b/selfdrive/car/volkswagen/radar_interface.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 +from selfdrive.car.interfaces import RadarInterfaceBase + +class RadarInterface(RadarInterfaceBase): + pass diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py new file mode 100644 index 00000000000000..6a1106076c384f --- /dev/null +++ b/selfdrive/car/volkswagen/values.py @@ -0,0 +1,63 @@ +from selfdrive.car import dbc_dict + +class CarControllerParams: + HCA_STEP = 2 # HCA_01 message frequency 50Hz + LDW_STEP = 10 # LDW_02 message frequency 10Hz + GRA_ACC_STEP = 3 # GRA_ACC_01 message frequency 33Hz + + GRA_VBP_STEP = 100 # Send ACC virtual button presses once a second + GRA_VBP_COUNT = 16 # Send VBP messages for ~0.5s (GRA_ACC_STEP * 16) + + # Observed documented MQB limits: 3.00 Nm max, rate of change 5.00 Nm/sec. + # Limiting both torque and rate-of-change based on real-world testing and + # Comma's safety requirements for minimum time to lane departure. + STEER_MAX = 250 # Max heading control assist torque 2.50 Nm + STEER_DELTA_UP = 4 # Max HCA reached in 1.25s (STEER_MAX / (50Hz * 1.25)) + STEER_DELTA_DOWN = 10 # Min HCA reached in 0.60s (STEER_MAX / (50Hz * 0.60)) + STEER_DRIVER_ALLOWANCE = 80 + STEER_DRIVER_MULTIPLIER = 3 # weight driver torque heavily + STEER_DRIVER_FACTOR = 1 # from dbc + +BUTTON_STATES = { + "leftBlinker": False, + "rightBlinker": False, + "accelCruise": False, + "decelCruise": False, + "cancel": False, + "setCruise": False, + "resumeCruise": False, + "gapAdjustCruise": False +} + +MQB_LDW_MESSAGES = { + "none": 0, # Nothing to display + "laneAssistUnavailChime": 1, # "Lane Assist currently not available." with chime + "laneAssistUnavailNoSensorChime": 3, # "Lane Assist not available. No sensor view." with chime + "laneAssistTakeOverUrgent": 4, # "Lane Assist: Please Take Over Steering" with urgent beep + "emergencyAssistUrgent": 6, # "Emergency Assist: Please Take Over Steering" with urgent beep + "laneAssistTakeOverChime": 7, # "Lane Assist: Please Take Over Steering" with chime + "laneAssistTakeOverSilent": 8, # "Lane Assist: Please Take Over Steering" silent + "emergencyAssistChangingLanes": 9, # "Emergency Assist: Changing lanes..." with urgent beep + "laneAssistDeactivated": 10, # "Lane Assist deactivated." silent with persistent icon afterward +} + +class CAR: + GOLF = "Volkswagen Golf" + +FINGERPRINTS = { + CAR.GOLF: [ + # 76b83eb0245de90e|2019-10-21--17-40-42 - jyoung8607 car + {64: 8, 134: 8, 159: 8, 173: 8, 178: 8, 253: 8, 257: 8, 260: 8, 262: 8, 264: 8, 278: 8, 279: 8, 283: 8, 286: 8, 288: 8, 289: 8, 290: 8, 294: 8, 299: 8, 302: 8, 346: 8, 385: 8, 418: 8, 427: 8, 668: 8, 679: 8, 681: 8, 695: 8, 779: 8, 780: 8, 783: 8, 792: 8, 795: 8, 804: 8, 806: 8, 807: 8, 808: 8, 809: 8, 870: 8, 896: 8, 897: 8, 898: 8, 901: 8, 917: 8, 919: 8, 949: 8, 958: 8, 960: 4, 981: 8, 987: 8, 988: 8, 991: 8, 997: 8, 1000: 8, 1019: 8, 1120: 8, 1122: 8, 1123: 8, 1124: 8, 1153: 8, 1162: 8, 1175: 8, 1312: 8, 1385: 8, 1413: 8, 1440: 5, 1514: 8, 1515: 8, 1520: 8, 1600: 8, 1601: 8, 1603: 8, 1605: 8, 1624: 8, 1626: 8, 1629: 8, 1631: 8, 1646: 8, 1648: 8, 1712: 6, 1714: 8, 1716: 8, 1717: 8, 1719: 8, 1720: 8, 1721: 8 + }], +} + +class ECU: + CAM = 0 + +ECU_FINGERPRINT = { + ECU.CAM: [294, 919], # HCA_01 Heading Control Assist, LDW_02 Lane Departure Warning +} + +DBC = { + CAR.GOLF: dbc_dict('vw_mqb_2010', None), +} diff --git a/selfdrive/car/volkswagen/volkswagencan.py b/selfdrive/car/volkswagen/volkswagencan.py new file mode 100644 index 00000000000000..34f19003d89b04 --- /dev/null +++ b/selfdrive/car/volkswagen/volkswagencan.py @@ -0,0 +1,52 @@ +# CAN controls for MQB platform Volkswagen, Audi, Skoda and SEAT. +# PQ35/PQ46/NMS, and any future MLB, to come later. + +def create_mqb_steering_control(packer, bus, apply_steer, idx, lkas_enabled): + values = { + "SET_ME_0X3": 0x3, + "Assist_Torque": abs(apply_steer), + "Assist_Requested": lkas_enabled, + "Assist_VZ": 1 if apply_steer < 0 else 0, + "HCA_Available": 1, + "HCA_Standby": not lkas_enabled, + "HCA_Active": lkas_enabled, + "SET_ME_0XFE": 0xFE, + "SET_ME_0X07": 0x07, + } + return packer.make_can_msg("HCA_01", bus, values, idx) + +def create_mqb_hud_control(packer, bus, hca_enabled, steering_pressed, hud_alert, leftLaneVisible, rightLaneVisible): + + if hca_enabled: + leftlanehud = 3 if leftLaneVisible else 1 + rightlanehud = 3 if rightLaneVisible else 1 + else: + leftlanehud = 2 if leftLaneVisible else 1 + rightlanehud = 2 if rightLaneVisible else 1 + + values = { + "LDW_Unknown": 2, # FIXME: possible speed or attention relationship + "Kombi_Lamp_Orange": 1 if hca_enabled and steering_pressed else 0, + "Kombi_Lamp_Green": 1 if hca_enabled and not steering_pressed else 0, + "Left_Lane_Status": leftlanehud, + "Right_Lane_Status": rightlanehud, + "Alert_Message": hud_alert, + } + return packer.make_can_msg("LDW_02", bus, values) + +def create_mqb_acc_buttons_control(packer, bus, buttonStatesToSend, CS, idx): + values = { + "GRA_Hauptschalter": CS.graHauptschalter, + "GRA_Abbrechen": buttonStatesToSend["cancel"], + "GRA_Tip_Setzen": buttonStatesToSend["setCruise"], + "GRA_Tip_Hoch": buttonStatesToSend["accelCruise"], + "GRA_Tip_Runter": buttonStatesToSend["decelCruise"], + "GRA_Tip_Wiederaufnahme": buttonStatesToSend["resumeCruise"], + "GRA_Verstellung_Zeitluecke": 3 if buttonStatesToSend["gapAdjustCruise"] else 0, + "GRA_Typ_Hauptschalter": CS.graTypHauptschalter, + "GRA_Codierung": 2, + "GRA_Tip_Stufe_2": CS.graTipStufe2, + "GRA_ButtonTypeInfo": CS.graButtonTypeInfo + } + + return packer.make_can_msg("GRA_ACC_01", bus, values, idx) diff --git a/selfdrive/common/cereal.mk b/selfdrive/common/cereal.mk index 46f23be551a9d6..ed05efc08caa3e 100644 --- a/selfdrive/common/cereal.mk +++ b/selfdrive/common/cereal.mk @@ -1,23 +1,15 @@ UNAME_M ?= $(shell uname -m) UNAME_S ?= $(shell uname -s) - - +ifeq ($(UNAME_S),Darwin) CEREAL_CFLAGS = -I$(PHONELIBS)/capnp-c/include - -ifeq ($(OPTEST),1) - -CEREAL_LIBS = -lcapnp -lkj - -else ifeq ($(UNAME_S),Darwin) - CEREAL_CXXFLAGS = -I$(PHONELIBS)/capnp-cpp/mac/include CEREAL_LIBS = $(PHONELIBS)/capnp-cpp/mac/lib/libcapnp.a \ $(PHONELIBS)/capnp-cpp/mac/lib/libkj.a \ $(PHONELIBS)/capnp-c/mac/lib/libcapnp_c.a else ifeq ($(UNAME_M),x86_64) - +CEREAL_CFLAGS = -I$(PHONELIBS)/capnp-c/include CEREAL_CXXFLAGS = -I$(PHONELIBS)/capnp-cpp/include ifeq ($(CEREAL_LIBS),) CEREAL_LIBS = -L$(PHONELIBS)/capnp-cpp/x64/lib/ \ @@ -27,13 +19,10 @@ endif else -CEREAL_CXXFLAGS = -I$(PHONELIBS)/capnp-cpp/include +#CEREAL_CXXFLAGS = -I$(PHONELIBS)/capnp-cpp/include ifeq ($(CEREAL_LIBS),) - CEREAL_LIBS = -L$(PHONELIBS)/capnp-cpp/aarch64/lib/ \ - -L$(PHONELIBS)/capnp-c/aarch64/lib/ \ - -l:libcapn.a -l:libcapnp.a -l:libkj.a + CEREAL_LIBS = -l:libcapn.a -l:libcapnp.a -l:libkj.a endif - endif CEREAL_OBJS = ../../cereal/gen/c/log.capnp.o ../../cereal/gen/c/car.capnp.o diff --git a/selfdrive/common/cqueue.c b/selfdrive/common/cqueue.c new file mode 100644 index 00000000000000..fe2c6f4ebff1ae --- /dev/null +++ b/selfdrive/common/cqueue.c @@ -0,0 +1,52 @@ +#include +#include +#include + +#include "cqueue.h" + +void queue_init(Queue *q) { + memset(q, 0, sizeof(*q)); + TAILQ_INIT(&q->q); + pthread_mutex_init(&q->lock, NULL); + pthread_cond_init(&q->cv, NULL); +} + +void* queue_pop(Queue *q) { + pthread_mutex_lock(&q->lock); + while (TAILQ_EMPTY(&q->q)) { + pthread_cond_wait(&q->cv, &q->lock); + } + QueueEntry *entry = TAILQ_FIRST(&q->q); + TAILQ_REMOVE(&q->q, entry, entries); + pthread_mutex_unlock(&q->lock); + + void* r = entry->data; + free(entry); + return r; +} + +void* queue_try_pop(Queue *q) { + pthread_mutex_lock(&q->lock); + + void* r = NULL; + if (!TAILQ_EMPTY(&q->q)) { + QueueEntry *entry = TAILQ_FIRST(&q->q); + TAILQ_REMOVE(&q->q, entry, entries); + r = entry->data; + free(entry); + } + + pthread_mutex_unlock(&q->lock); + return r; +} + +void queue_push(Queue *q, void *data) { + QueueEntry *entry = calloc(1, sizeof(QueueEntry)); + assert(entry); + entry->data = data; + + pthread_mutex_lock(&q->lock); + TAILQ_INSERT_TAIL(&q->q, entry, entries); + pthread_cond_signal(&q->cv); + pthread_mutex_unlock(&q->lock); +} diff --git a/selfdrive/common/cqueue.h b/selfdrive/common/cqueue.h new file mode 100644 index 00000000000000..f2613660b21405 --- /dev/null +++ b/selfdrive/common/cqueue.h @@ -0,0 +1,33 @@ +#ifndef COMMON_CQUEUE_H +#define COMMON_CQUEUE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// a blocking queue + +typedef struct QueueEntry { + TAILQ_ENTRY(QueueEntry) entries; + void *data; +} QueueEntry; + +typedef struct Queue { + TAILQ_HEAD(queue, QueueEntry) q; + pthread_mutex_t lock; + pthread_cond_t cv; +} Queue; + +void queue_init(Queue *q); +void* queue_pop(Queue *q); +void* queue_try_pop(Queue *q); +void queue_push(Queue *q, void *data); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/selfdrive/common/messaging.h b/selfdrive/common/messaging.h new file mode 100644 index 00000000000000..725129508fd268 --- /dev/null +++ b/selfdrive/common/messaging.h @@ -0,0 +1,15 @@ +// the c version of selfdrive/messaging.py + +#include + +// TODO: refactor to take in service instead of endpoint? +void *sub_sock(void *ctx, const char *endpoint) { + void* sock = zmq_socket(ctx, ZMQ_SUB); + assert(sock); + zmq_setsockopt(sock, ZMQ_SUBSCRIBE, "", 0); + int reconnect_ivl = 500; + zmq_setsockopt(sock, ZMQ_RECONNECT_IVL_MAX, &reconnect_ivl, sizeof(reconnect_ivl)); + zmq_connect(sock, endpoint); + return sock; +} + diff --git a/selfdrive/common/modeldata.h b/selfdrive/common/modeldata.h index c3f48930f29e36..6c0cd006f67aaa 100644 --- a/selfdrive/common/modeldata.h +++ b/selfdrive/common/modeldata.h @@ -1,18 +1,28 @@ #ifndef MODELDATA_H #define MODELDATA_H -#define MODEL_PATH_DISTANCE 50 +#define MODEL_PATH_DISTANCE 192 +#define POLYFIT_DEGREE 4 +#define SPEED_PERCENTILES 10 typedef struct PathData { float points[MODEL_PATH_DISTANCE]; float prob; float std; + float stds[MODEL_PATH_DISTANCE]; + float poly[POLYFIT_DEGREE]; } PathData; typedef struct LeadData { float dist; float prob; float std; + float rel_y; + float rel_y_std; + float rel_v; + float rel_v_std; + float rel_a; + float rel_a_std; } LeadData; typedef struct ModelData { @@ -20,6 +30,8 @@ typedef struct ModelData { PathData left_lane; PathData right_lane; LeadData lead; + LeadData lead_future; + float speed[SPEED_PERCENTILES]; } ModelData; #endif diff --git a/selfdrive/common/mutex.h b/selfdrive/common/mutex.h new file mode 100644 index 00000000000000..ef0135935736f4 --- /dev/null +++ b/selfdrive/common/mutex.h @@ -0,0 +1,13 @@ +#ifndef COMMON_MUTEX_H +#define COMMON_MUTEX_H + +#include + +static inline void mutex_init_reentrant(pthread_mutex_t *mutex) { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(mutex, &attr); +} + +#endif diff --git a/selfdrive/common/params.cc b/selfdrive/common/params.cc index 7bbcf5fad11c60..6e0e8b186f33ba 100644 --- a/selfdrive/common/params.cc +++ b/selfdrive/common/params.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -16,6 +17,7 @@ #include "common/util.h" #include "common/utilpp.h" + namespace { template @@ -28,8 +30,42 @@ static const char* default_params_path = null_coalesce( } // namespace +static int fsync_dir(const char* path){ + int result = 0; + int fd = open(path, O_RDONLY); + + if (fd < 0){ + result = -1; + goto cleanup; + } + + result = fsync(fd); + if (result < 0) { + goto cleanup; + } + + cleanup: + int result_close = 0; + if (fd >= 0){ + result_close = close(fd); + } + + if (result_close < 0) { + return result_close; + } else { + return result; + } +} + int write_db_value(const char* params_path, const char* key, const char* value, size_t value_size) { + // Information about safely and atomically writing a file: https://lwn.net/Articles/457667/ + // 1) Create temp file + // 2) Write data to temp file + // 3) fsync() the temp file + // 4) rename the temp file to the real name + // 5) fsync() the containing directory + int lock_fd = -1; int tmp_fd = -1; int result; @@ -55,12 +91,14 @@ int write_db_value(const char* params_path, const char* key, const char* value, goto cleanup; } + // Build lock path result = snprintf(path, sizeof(path), "%s/.lock", params_path); if (result < 0) { goto cleanup; } lock_fd = open(path, 0); + // Build key path result = snprintf(path, sizeof(path), "%s/d/%s", params_path, key); if (result < 0) { goto cleanup; @@ -72,6 +110,12 @@ int write_db_value(const char* params_path, const char* key, const char* value, goto cleanup; } + // change permissions to 0666 for apks + result = fchmod(tmp_fd, 0666); + if (result < 0) { + goto cleanup; + } + // fsync to force persist the changes. result = fsync(tmp_fd); if (result < 0) { @@ -80,6 +124,20 @@ int write_db_value(const char* params_path, const char* key, const char* value, // Move temp into place. result = rename(tmp_path, path); + if (result < 0) { + goto cleanup; + } + + // fsync parent directory + result = snprintf(path, sizeof(path), "%s/d", params_path); + if (result < 0) { + goto cleanup; + } + + result = fsync_dir(path); + if (result < 0) { + goto cleanup; + } cleanup: // Release lock. @@ -95,6 +153,60 @@ int write_db_value(const char* params_path, const char* key, const char* value, return result; } +int delete_db_value(const char* params_path, const char* key) { + int lock_fd = -1; + int result; + char path[1024]; + + if (params_path == NULL) { + params_path = default_params_path; + } + + // Build lock path, and open lockfile + result = snprintf(path, sizeof(path), "%s/.lock", params_path); + if (result < 0) { + goto cleanup; + } + lock_fd = open(path, 0); + + // Take lock. + result = flock(lock_fd, LOCK_EX); + if (result < 0) { + goto cleanup; + } + + // Build key path + result = snprintf(path, sizeof(path), "%s/d/%s", params_path, key); + if (result < 0) { + goto cleanup; + } + + // Delete value. + result = remove(path); + if (result != 0) { + result = ERR_NO_VALUE; + goto cleanup; + } + + // fsync parent directory + result = snprintf(path, sizeof(path), "%s/d", params_path); + if (result < 0) { + goto cleanup; + } + + result = fsync_dir(path); + if (result < 0) { + goto cleanup; + } + +cleanup: + // Release lock. + if (lock_fd >= 0) { + close(lock_fd); + } + return result; +} + int read_db_value(const char* params_path, const char* key, char** value, size_t* value_sz) { int lock_fd = -1; @@ -184,6 +296,9 @@ int read_db_all(const char* params_path, std::map *par while ((de = readdir(d))) { if (!isalnum(de->d_name[0])) continue; std::string key = std::string(de->d_name); + + if (key == "AccessToken") continue; + std::string value = util::read_file(util::string_format("%s/%s", key_path.c_str(), key.c_str())); (*params)[key] = value; diff --git a/selfdrive/common/params.h b/selfdrive/common/params.h index 299dcccd0a412d..6dcd36145e0d28 100644 --- a/selfdrive/common/params.h +++ b/selfdrive/common/params.h @@ -7,6 +7,8 @@ extern "C" { #endif +#define ERR_NO_VALUE -33 + int write_db_value(const char* params_path, const char* key, const char* value, size_t value_size); @@ -23,6 +25,10 @@ int write_db_value(const char* params_path, const char* key, const char* value, int read_db_value(const char* params_path, const char* key, char** value, size_t* value_sz); +// Delete a value from the params database. +// Inputs are the same as read_db_value, without value and value_sz. +int delete_db_value(const char* params_path, const char* key); + // Reads a value from the params database, blocking until successful. // Inputs are the same as read_db_value. void read_db_value_blocking(const char* params_path, const char* key, diff --git a/selfdrive/common/spinner.c b/selfdrive/common/spinner.c new file mode 100644 index 00000000000000..abae7cc1352009 --- /dev/null +++ b/selfdrive/common/spinner.c @@ -0,0 +1,184 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "nanovg.h" +#define NANOVG_GLES3_IMPLEMENTATION +#include "nanovg_gl.h" +#include "nanovg_gl_utils.h" + +#include "framebuffer.h" +#include "spinner.h" + +#define SPINTEXT_LENGTH 128 + +// external resources linked in +extern const unsigned char _binary_opensans_semibold_ttf_start[]; +extern const unsigned char _binary_opensans_semibold_ttf_end[]; + +extern const unsigned char _binary_img_spinner_track_png_start[]; +extern const unsigned char _binary_img_spinner_track_png_end[]; + +extern const unsigned char _binary_img_spinner_comma_png_start[]; +extern const unsigned char _binary_img_spinner_comma_png_end[]; + +bool stdin_input_available() { + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + fd_set fds; + FD_ZERO(&fds); + FD_SET(STDIN_FILENO, &fds); + select(STDIN_FILENO+1, &fds, NULL, NULL, &timeout); + return (FD_ISSET(0, &fds)); +} + +int spin(int argc, char** argv) { + int err; + + bool draw_progress = false; + float progress_val = 0.0; + + char spintext[SPINTEXT_LENGTH]; + spintext[0] = 0; + + const char* spintext_arg = NULL; + if (argc >= 2) { + strncpy(spintext, argv[1], SPINTEXT_LENGTH); + } + + // spinner + int fb_w, fb_h; + EGLDisplay display; + EGLSurface surface; + FramebufferState *fb = framebuffer_init("spinner", 0x00001000, false, + &display, &surface, &fb_w, &fb_h); + assert(fb); + + NVGcontext *vg = nvgCreateGLES3(NVG_ANTIALIAS | NVG_STENCIL_STROKES); + assert(vg); + + int font = nvgCreateFontMem(vg, "Bold", (unsigned char*)_binary_opensans_semibold_ttf_start, _binary_opensans_semibold_ttf_end-_binary_opensans_semibold_ttf_start, 0); + assert(font >= 0); + + int spinner_img = nvgCreateImageMem(vg, 0, (unsigned char*)_binary_img_spinner_track_png_start, _binary_img_spinner_track_png_end - _binary_img_spinner_track_png_start); + assert(spinner_img >= 0); + int spinner_img_s = 360; + int spinner_img_x = ((fb_w/2)-(spinner_img_s/2)); + int spinner_img_y = 260; + int spinner_img_xc = (fb_w/2); + int spinner_img_yc = (fb_h/2)-100; + int spinner_comma_img = nvgCreateImageMem(vg, 0, (unsigned char*)_binary_img_spinner_comma_png_start, _binary_img_spinner_comma_png_end - _binary_img_spinner_comma_png_start); + assert(spinner_comma_img >= 0); + + for (int cnt = 0; ; cnt++) { + // Check stdin for new text + if (stdin_input_available()){ + fgets(spintext, SPINTEXT_LENGTH, stdin); + spintext[strcspn(spintext, "\n")] = 0; + + // Check if number (update progress bar) + size_t len = strlen(spintext); + bool is_number = len > 0; + for (int i = 0; i < len; i++){ + if (!isdigit(spintext[i])){ + is_number = false; + break; + } + } + + if (is_number) { + progress_val = (float)(atoi(spintext)) / 100.0; + progress_val = fmin(1.0, progress_val); + progress_val = fmax(0.0, progress_val); + } + + draw_progress = is_number; + } + + glClearColor(0.1, 0.1, 0.1, 1.0); + glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + nvgBeginFrame(vg, fb_w, fb_h, 1.0f); + + // background + nvgBeginPath(vg); + NVGpaint bg = nvgLinearGradient(vg, fb_w, 0, fb_w, fb_h, + nvgRGBA(0, 0, 0, 175), nvgRGBA(0, 0, 0, 255)); + nvgFillPaint(vg, bg); + nvgRect(vg, 0, 0, fb_w, fb_h); + nvgFill(vg); + + // spin track + nvgSave(vg); + nvgTranslate(vg, spinner_img_xc, spinner_img_yc); + nvgRotate(vg, (3.75*M_PI * cnt/120.0)); + nvgTranslate(vg, -spinner_img_xc, -spinner_img_yc); + NVGpaint spinner_imgPaint = nvgImagePattern(vg, spinner_img_x, spinner_img_y, + spinner_img_s, spinner_img_s, 0, spinner_img, 0.6f); + nvgBeginPath(vg); + nvgFillPaint(vg, spinner_imgPaint); + nvgRect(vg, spinner_img_x, spinner_img_y, spinner_img_s, spinner_img_s); + nvgFill(vg); + nvgRestore(vg); + + // comma + NVGpaint comma_imgPaint = nvgImagePattern(vg, spinner_img_x, spinner_img_y, + spinner_img_s, spinner_img_s, 0, spinner_comma_img, 1.0f); + nvgBeginPath(vg); + nvgFillPaint(vg, comma_imgPaint); + nvgRect(vg, spinner_img_x, spinner_img_y, spinner_img_s, spinner_img_s); + nvgFill(vg); + + if (draw_progress){ + // draw progress bar + int progress_width = 1000; + int progress_x = fb_w/2-progress_width/2; + int progress_y = 775; + int progress_height = 25; + + NVGpaint paint = nvgBoxGradient( + vg, progress_x + 1, progress_y + 1, + progress_width - 2, progress_height, 3, 4, nvgRGB(27, 27, 27), nvgRGB(27, 27, 27)); + nvgBeginPath(vg); + nvgRoundedRect(vg, progress_x, progress_y, progress_width, progress_height, 12); + nvgFillPaint(vg, paint); + nvgFill(vg); + + int bar_pos = ((progress_width - 2) * progress_val); + + paint = nvgBoxGradient( + vg, progress_x, progress_y, + bar_pos+1.5f, progress_height-1, 3, 4, + nvgRGB(245, 245, 245), nvgRGB(105, 105, 105)); + + nvgBeginPath(vg); + nvgRoundedRect( + vg, progress_x+1, progress_y+1, + bar_pos, progress_height-2, 12); + nvgFillPaint(vg, paint); + nvgFill(vg); + } else { + // message + nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_TOP); + nvgFontSize(vg, 96.0f); + nvgText(vg, fb_w/2, (fb_h*2/3)+24, spintext, NULL); + } + + nvgEndFrame(vg); + eglSwapBuffers(display, surface); + assert(glGetError() == GL_NO_ERROR); + } + + return 0; +} diff --git a/selfdrive/common/spinner.h b/selfdrive/common/spinner.h new file mode 100644 index 00000000000000..fd35dcc7d48c31 --- /dev/null +++ b/selfdrive/common/spinner.h @@ -0,0 +1,14 @@ +#ifndef COMMON_SPINNER_H +#define COMMON_SPINNER_H + +#ifdef __cplusplus +extern "C" { +#endif + +int spin(int argc, char** argv); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/selfdrive/common/touch.c b/selfdrive/common/touch.c index f21fac8f07afd5..4527cb53201e67 100644 --- a/selfdrive/common/touch.c +++ b/selfdrive/common/touch.c @@ -69,14 +69,15 @@ int touch_poll(TouchState *s, int* out_x, int* out_y, int timeout) { return -1; } - switch (event.type) { + switch (event.type) { case EV_ABS: if (event.code == ABS_MT_POSITION_X) { s->last_x = event.value; } else if (event.code == ABS_MT_POSITION_Y) { s->last_y = event.value; + } else if (event.code == ABS_MT_TRACKING_ID && event.value != -1) { + up = true; } - up = true; break; default: break; @@ -90,3 +91,30 @@ int touch_poll(TouchState *s, int* out_x, int* out_y, int timeout) { return up; } +int touch_read(TouchState *s, int* out_x, int* out_y) { + assert(out_x && out_y); + struct input_event event; + int err = read(s->fd, &event, sizeof(event)); + if (err < sizeof(event)) { + return -1; + } + bool up = false; + switch (event.type) { + case EV_ABS: + if (event.code == ABS_MT_POSITION_X) { + s->last_x = event.value; + } else if (event.code == ABS_MT_POSITION_Y) { + s->last_y = event.value; + } + up = true; + break; + default: + break; + } + if (up) { + // adjust for flippening + *out_x = s->last_y; + *out_y = 1080 - s->last_x; + } + return up; +} diff --git a/selfdrive/common/touch.h b/selfdrive/common/touch.h index c2bb6dfeced30c..c48f66b9827214 100644 --- a/selfdrive/common/touch.h +++ b/selfdrive/common/touch.h @@ -12,6 +12,7 @@ typedef struct TouchState { void touch_init(TouchState *s); int touch_poll(TouchState *s, int *out_x, int *out_y, int timeout); +int touch_read(TouchState *s, int* out_x, int* out_y); #ifdef __cplusplus } diff --git a/selfdrive/common/util.c b/selfdrive/common/util.c index 6f8f0a9a6cf186..01b8a0b6d92c80 100644 --- a/selfdrive/common/util.c +++ b/selfdrive/common/util.c @@ -26,6 +26,7 @@ void* read_file(const char* path, size_t* out_len) { fclose(f); if (num_read != 1) { + free(buf); return NULL; } diff --git a/selfdrive/common/util.h b/selfdrive/common/util.h index 65dde16e24082e..b3ca916941654d 100644 --- a/selfdrive/common/util.h +++ b/selfdrive/common/util.h @@ -1,6 +1,7 @@ #ifndef COMMON_UTIL_H #define COMMON_UTIL_H +#include #ifndef __cplusplus diff --git a/selfdrive/common/utilpp.h b/selfdrive/common/utilpp.h index e374c5c256f772..6a68b5fba2d1d7 100644 --- a/selfdrive/common/utilpp.h +++ b/selfdrive/common/utilpp.h @@ -18,7 +18,7 @@ inline bool starts_with(std::string s, std::string prefix) { template inline std::string string_format( const std::string& format, Args ... args ) { size_t size = snprintf( nullptr, 0, format.c_str(), args ... ) + 1; - std::unique_ptr buf( new char[ size ] ); + std::unique_ptr buf( new char[ size ] ); snprintf( buf.get(), size, format.c_str(), args ... ); return std::string( buf.get(), buf.get() + size - 1 ); } @@ -32,7 +32,7 @@ inline std::string read_file(std::string fn) { inline std::string tohex(const uint8_t* buf, size_t buf_size) { std::unique_ptr hexbuf(new char[buf_size*2+1]); - for (int i=0; isize % img->stride) == 0); assert((img->stride % img->bpp) == 0); @@ -87,13 +87,14 @@ EGLClientBuffer visionimg_to_egl(const VisionImg *img) { GraphicBuffer* gb = new GraphicBuffer(img->width, img->height, (PixelFormat)format, GraphicBuffer::USAGE_HW_TEXTURE, img->stride/img->bpp, hnd, false); - + // GraphicBuffer is ref counted by EGLClientBuffer(ANativeWindowBuffer), no need and not possible to release. + *pph = hnd; return (EGLClientBuffer) gb->getNativeBuffer(); } -GLuint visionimg_to_gl(const VisionImg *img) { +GLuint visionimg_to_gl(const VisionImg *img, EGLImageKHR *pkhr, void **pph) { - EGLClientBuffer buf = visionimg_to_egl(img); + EGLClientBuffer buf = visionimg_to_egl(img, pph); EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); assert(display != EGL_NO_DISPLAY); @@ -107,8 +108,15 @@ GLuint visionimg_to_gl(const VisionImg *img) { glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); - + *pkhr = image; return tex; } +void visionimg_destroy_gl(EGLImageKHR khr, void *ph) { + EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + assert(display != EGL_NO_DISPLAY); + eglDestroyImageKHR(display, khr); + delete (private_handle_t*)ph; +} + #endif diff --git a/selfdrive/common/visionimg.h b/selfdrive/common/visionimg.h index 9fabb6054f6dd3..74b0f3137d1b8c 100644 --- a/selfdrive/common/visionimg.h +++ b/selfdrive/common/visionimg.h @@ -27,8 +27,9 @@ void visionimg_compute_aligned_width_and_height(int width, int height, int *alig VisionImg visionimg_alloc_rgb24(int width, int height, VisionBuf *out_buf); #ifdef QCOM -EGLClientBuffer visionimg_to_egl(const VisionImg *img); -GLuint visionimg_to_gl(const VisionImg *img); +EGLClientBuffer visionimg_to_egl(const VisionImg *img, void **pph); +GLuint visionimg_to_gl(const VisionImg *img, EGLImageKHR *pkhr, void **pph); +void visionimg_destroy_gl(EGLImageKHR khr, void *ph); #endif #ifdef __cplusplus diff --git a/selfdrive/config.py b/selfdrive/config.py index 751a84e285f52c..6c2296273ad087 100644 --- a/selfdrive/config.py +++ b/selfdrive/config.py @@ -17,7 +17,8 @@ class Conversions: LB_TO_KG = 0.453592 -RADAR_TO_CENTER = 2.7 # RADAR is ~ 2.7m ahead from center of car +RADAR_TO_CENTER = 2.7 # (deprecated) RADAR is ~ 2.7m ahead from center of car +RADAR_TO_CAMERA = 1.52 # RADAR is ~ 1.5m ahead from center of mesh frame class UIParams: lidar_x, lidar_y, lidar_zoom = 384, 960, 6 diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index b5d699bdaabfa4..1550116617297f 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -1,32 +1,36 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 +import os import gc -import zmq -import json +import capnp from cereal import car, log from common.numpy_fast import clip -from common.realtime import sec_since_boot, set_realtime_priority, Ratekeeper +from common.realtime import sec_since_boot, set_realtime_priority, Ratekeeper, DT_CTRL from common.profiler import Profiler -from common.params import Params +from common.params import Params, put_nonblocking import selfdrive.messaging as messaging from selfdrive.config import Conversions as CV -from selfdrive.services import service_list -from selfdrive.car.car_helpers import get_car -from selfdrive.controls.lib.drive_helpers import learn_angle_model_bias, \ - get_events, \ +from selfdrive.boardd.boardd import can_list_to_can_capnp +from selfdrive.car.car_helpers import get_car, get_startup_alert +from selfdrive.controls.lib.lane_planner import CAMERA_OFFSET +from selfdrive.controls.lib.drive_helpers import get_events, \ create_event, \ EventTypes as ET, \ update_v_cruise, \ initialize_v_cruise from selfdrive.controls.lib.longcontrol import LongControl, STARTING_TARGET_SPEED -from selfdrive.controls.lib.latcontrol import LatControl +from selfdrive.controls.lib.latcontrol_pid import LatControlPID +from selfdrive.controls.lib.latcontrol_indi import LatControlINDI +from selfdrive.controls.lib.latcontrol_lqr import LatControlLQR from selfdrive.controls.lib.alertmanager import AlertManager from selfdrive.controls.lib.vehicle_model import VehicleModel -from selfdrive.controls.lib.driver_monitor import DriverStatus -from selfdrive.controls.lib.planner import _DT_MPC +from selfdrive.controls.lib.driver_monitor import DriverStatus, MAX_TERMINAL_ALERTS +from selfdrive.controls.lib.planner import LON_MPC_STEP +from selfdrive.controls.lib.gps_helpers import is_rhd_region from selfdrive.locationd.calibration_helpers import Calibration, Filter ThermalStatus = log.ThermalData.ThermalStatus -State = log.Live100Data.ControlState +State = log.ControlsState.OpenpilotState +HwType = log.HealthData.HwType def isActive(state): @@ -38,41 +42,37 @@ def isEnabled(state): """Check if openpilot is engaged""" return (isActive(state) or state == State.preEnabled) +def events_to_bytes(events): + # optimization when comparing capnp structs: str() or tree traverse are much slower + ret = [] + for e in events: + if isinstance(e, capnp.lib.capnp._DynamicStructReader): + e = e.as_builder() + ret.append(e.to_bytes()) + return ret -def data_sample(CI, CC, plan_sock, path_plan_sock, thermal, calibration, health, driver_monitor, - poller, cal_status, cal_perc, overtemp, free_space, low_battery, - driver_status, state, mismatch_counter, params, plan, path_plan): + +def data_sample(CI, CC, sm, can_sock, cal_status, cal_perc, overtemp, free_space, low_battery, + driver_status, state, mismatch_counter, params): """Receive data from sockets and create events for battery, temperature and disk space""" # Update carstate from CAN and create events - CS = CI.update(CC) + can_strs = messaging.drain_sock_raw(can_sock, wait_for_one=True) + CS = CI.update(CC, can_strs) + + sm.update(0) + events = list(CS.events) enabled = isEnabled(state) - # Receive from sockets - td = None - cal = None - hh = None - dm = None - - for socket, event in poller.poll(0): - if socket is thermal: - td = messaging.recv_one(socket) - elif socket is calibration: - cal = messaging.recv_one(socket) - elif socket is health: - hh = messaging.recv_one(socket) - elif socket is driver_monitor: - dm = messaging.recv_one(socket) - elif socket is plan_sock: - plan = messaging.recv_one(socket) - elif socket is path_plan_sock: - path_plan = messaging.recv_one(socket) - - if td is not None: - overtemp = td.thermal.thermalStatus >= ThermalStatus.red - free_space = td.thermal.freeSpace < 0.07 # under 7% of space free no enable allowed - low_battery = td.thermal.batteryPercent < 1 # at zero percent battery, OP should not be allowed + # Check for CAN timeout + if not can_strs: + events.append(create_event('canError', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) + + if sm.updated['thermal']: + overtemp = sm['thermal'].thermalStatus >= ThermalStatus.red + free_space = sm['thermal'].freeSpace < 0.07 # under 7% of space free no enable allowed + low_battery = sm['thermal'].batteryPercent < 1 and sm['thermal'].chargingError # at zero percent battery, while discharging, OP should not allowed # Create events for battery, temperature and disk space if low_battery: @@ -82,39 +82,54 @@ def data_sample(CI, CC, plan_sock, path_plan_sock, thermal, calibration, health, if free_space: events.append(create_event('outOfSpace', [ET.NO_ENTRY])) + # GPS coords RHD parsing, once every restart + if sm.updated['gpsLocation'] and not driver_status.is_rhd_region_checked: + is_rhd = is_rhd_region(sm['gpsLocation'].latitude, sm['gpsLocation'].longitude) + driver_status.is_rhd_region = is_rhd + driver_status.is_rhd_region_checked = True + put_nonblocking("IsRHD", "1" if is_rhd else "0") + # Handle calibration - if cal is not None: - cal_status = cal.liveCalibration.calStatus - cal_perc = cal.liveCalibration.calPerc + if sm.updated['liveCalibration']: + cal_status = sm['liveCalibration'].calStatus + cal_perc = sm['liveCalibration'].calPerc + cal_rpy = [0,0,0] if cal_status != Calibration.CALIBRATED: if cal_status == Calibration.UNCALIBRATED: events.append(create_event('calibrationIncomplete', [ET.NO_ENTRY, ET.SOFT_DISABLE, ET.PERMANENT])) else: events.append(create_event('calibrationInvalid', [ET.NO_ENTRY, ET.SOFT_DISABLE])) + else: + rpy = sm['liveCalibration'].rpyCalib + if len(rpy) == 3: + cal_rpy = rpy # When the panda and controlsd do not agree on controls_allowed # we want to disengage openpilot. However the status from the panda goes through - # another socket than the CAN messages, therefore one can arrive earlier than the other. + # another socket other than the CAN messages and one can arrive earlier than the other. # Therefore we allow a mismatch for two samples, then we trigger the disengagement. if not enabled: mismatch_counter = 0 - if hh is not None: - controls_allowed = hh.health.controlsAllowed + if sm.updated['health']: + controls_allowed = sm['health'].controlsAllowed if not controls_allowed and enabled: mismatch_counter += 1 if mismatch_counter >= 2: events.append(create_event('controlsMismatch', [ET.IMMEDIATE_DISABLE])) # Driver monitoring - if dm is not None: - driver_status.get_pose(dm.driverMonitoring, params) + if sm.updated['driverMonitoring']: + driver_status.get_pose(sm['driverMonitoring'], cal_rpy, CS.vEgo, enabled) - return CS, events, cal_status, cal_perc, overtemp, free_space, low_battery, mismatch_counter, plan, path_plan + if driver_status.terminal_alert_cnt >= MAX_TERMINAL_ALERTS: + events.append(create_event("tooDistracted", [ET.NO_ENTRY])) + return CS, events, cal_status, cal_perc, overtemp, free_space, low_battery, mismatch_counter -def state_transition(CS, CP, state, events, soft_disable_timer, v_cruise_kph, AM): + +def state_transition(frame, CS, CP, state, events, soft_disable_timer, v_cruise_kph, AM): """Compute conditional state transitions and execute actions on state transitions""" enabled = isEnabled(state) @@ -135,43 +150,43 @@ def state_transition(CS, CP, state, events, soft_disable_timer, v_cruise_kph, AM if get_events(events, [ET.ENABLE]): if get_events(events, [ET.NO_ENTRY]): for e in get_events(events, [ET.NO_ENTRY]): - AM.add(str(e) + "NoEntry", enabled) + AM.add(frame, str(e) + "NoEntry", enabled) else: if get_events(events, [ET.PRE_ENABLE]): state = State.preEnabled else: state = State.enabled - AM.add("enable", enabled) + AM.add(frame, "enable", enabled) v_cruise_kph = initialize_v_cruise(CS.vEgo, CS.buttonEvents, v_cruise_kph_last) # ENABLED elif state == State.enabled: if get_events(events, [ET.USER_DISABLE]): state = State.disabled - AM.add("disable", enabled) + AM.add(frame, "disable", enabled) elif get_events(events, [ET.IMMEDIATE_DISABLE]): state = State.disabled for e in get_events(events, [ET.IMMEDIATE_DISABLE]): - AM.add(e, enabled) + AM.add(frame, e, enabled) elif get_events(events, [ET.SOFT_DISABLE]): state = State.softDisabling soft_disable_timer = 300 # 3s for e in get_events(events, [ET.SOFT_DISABLE]): - AM.add(e, enabled) + AM.add(frame, e, enabled) # SOFT DISABLING elif state == State.softDisabling: if get_events(events, [ET.USER_DISABLE]): state = State.disabled - AM.add("disable", enabled) + AM.add(frame, "disable", enabled) elif get_events(events, [ET.IMMEDIATE_DISABLE]): state = State.disabled for e in get_events(events, [ET.IMMEDIATE_DISABLE]): - AM.add(e, enabled) + AM.add(frame, e, enabled) elif not get_events(events, [ET.SOFT_DISABLE]): # no more soft disabling condition, so go back to ENABLED @@ -179,7 +194,7 @@ def state_transition(CS, CP, state, events, soft_disable_timer, v_cruise_kph, AM elif get_events(events, [ET.SOFT_DISABLE]) and soft_disable_timer > 0: for e in get_events(events, [ET.SOFT_DISABLE]): - AM.add(e, enabled) + AM.add(frame, e, enabled) elif soft_disable_timer <= 0: state = State.disabled @@ -188,12 +203,12 @@ def state_transition(CS, CP, state, events, soft_disable_timer, v_cruise_kph, AM elif state == State.preEnabled: if get_events(events, [ET.USER_DISABLE]): state = State.disabled - AM.add("disable", enabled) + AM.add(frame, "disable", enabled) elif get_events(events, [ET.IMMEDIATE_DISABLE, ET.SOFT_DISABLE]): state = State.disabled for e in get_events(events, [ET.IMMEDIATE_DISABLE, ET.SOFT_DISABLE]): - AM.add(e, enabled) + AM.add(frame, e, enabled) elif not get_events(events, [ET.PRE_ENABLE]): state = State.enabled @@ -201,8 +216,8 @@ def state_transition(CS, CP, state, events, soft_disable_timer, v_cruise_kph, AM return state, soft_disable_timer, v_cruise_kph, v_cruise_kph_last -def state_control(plan, path_plan, CS, CP, state, events, v_cruise_kph, v_cruise_kph_last, AM, rk, - driver_status, LaC, LoC, VM, angle_model_bias, passive, is_metric, cal_perc): +def state_control(frame, rcv_frame, plan, path_plan, CS, CP, state, events, v_cruise_kph, v_cruise_kph_last, + AM, rk, driver_status, LaC, LoC, read_only, is_metric, cal_perc): """Given the state, this function returns an actuators packet""" actuators = car.CarControl.Actuators.new_message() @@ -220,7 +235,7 @@ def state_control(plan, path_plan, CS, CP, state, events, v_cruise_kph, v_cruise # send FCW alert if triggered by planner if plan.fcw: - AM.add("fcw", enabled) + AM.add(frame, "fcw", enabled) # State specific actions @@ -237,32 +252,23 @@ def state_control(plan, path_plan, CS, CP, state, events, v_cruise_kph, v_cruise extra_text = str(int(round(CP.minSteerSpeed * CV.MS_TO_KPH))) + " kph" else: extra_text = str(int(round(CP.minSteerSpeed * CV.MS_TO_MPH))) + " mph" - AM.add(e, enabled, extra_text_2=extra_text) - - # Run angle offset learner at 20 Hz - if rk.frame % 5 == 2: - angle_model_bias = learn_angle_model_bias(active, CS.vEgo, angle_model_bias, - path_plan.cPoly, path_plan.cProb, CS.steeringAngle, - CS.steeringPressed) + AM.add(frame, e, enabled, extra_text_2=extra_text) - cur_time = sec_since_boot() # TODO: This won't work in replay - mpc_time = plan.l20MonoTime / 1e9 - _DT = 0.01 # 100Hz + plan_age = DT_CTRL * (frame - rcv_frame['plan']) + dt = min(plan_age, LON_MPC_STEP + DT_CTRL) + DT_CTRL # no greater than dt mpc + dt, to prevent too high extraps - dt = min(cur_time - mpc_time, _DT_MPC + _DT) + _DT # no greater than dt mpc + dt, to prevent too high extraps - a_acc_sol = plan.aStart + (dt / _DT_MPC) * (plan.aTarget - plan.aStart) + a_acc_sol = plan.aStart + (dt / LON_MPC_STEP) * (plan.aTarget - plan.aStart) v_acc_sol = plan.vStart + dt * (a_acc_sol + plan.aStart) / 2.0 # Gas/Brake PID loop actuators.gas, actuators.brake = LoC.update(active, CS.vEgo, CS.brakePressed, CS.standstill, CS.cruiseState.standstill, v_cruise_kph, v_acc_sol, plan.vTargetFuture, a_acc_sol, CP) # Steering PID loop and lateral MPC - actuators.steer, actuators.steerAngle = LaC.update(active, CS.vEgo, CS.steeringAngle, - CS.steeringPressed, CP, VM, path_plan) + actuators.steer, actuators.steerAngle, lac_log = LaC.update(active, CS.vEgo, CS.steeringAngle, CS.steeringRate, CS.steeringTorqueEps, CS.steeringPressed, CP, path_plan) # Send a "steering required alert" if saturation count has reached the limit if LaC.sat_flag and CP.steerLimitAlert: - AM.add("steerSaturated", enabled) + AM.add(frame, "steerSaturated", enabled) # Parse permanent warnings to display constantly for e in get_events(events, [ET.PERMANENT]): @@ -273,70 +279,80 @@ def state_control(plan, path_plan, CS, CP, state, events, v_cruise_kph, v_cruise extra_text_2 = str(int(round(Filter.MIN_SPEED * CV.MS_TO_KPH))) + " kph" else: extra_text_2 = str(int(round(Filter.MIN_SPEED * CV.MS_TO_MPH))) + " mph" - AM.add(str(e) + "Permanent", enabled, extra_text_1=extra_text_1, extra_text_2=extra_text_2) + AM.add(frame, str(e) + "Permanent", enabled, extra_text_1=extra_text_1, extra_text_2=extra_text_2) - AM.process_alerts(sec_since_boot()) + AM.process_alerts(frame) - return actuators, v_cruise_kph, driver_status, angle_model_bias, v_acc_sol, a_acc_sol + return actuators, v_cruise_kph, driver_status, v_acc_sol, a_acc_sol, lac_log -def data_send(plan, path_plan, CS, CI, CP, VM, state, events, actuators, v_cruise_kph, rk, carstate, - carcontrol, live100, AM, driver_status, - LaC, LoC, angle_model_bias, passive, start_time, params, v_acc, a_acc): - """Send actuators and hud commands to the car, send live100 and MPC logging""" - plan_ts = plan.logMonoTime - plan = plan.plan +def data_send(sm, pm, CS, CI, CP, VM, state, events, actuators, v_cruise_kph, rk, AM, + driver_status, LaC, LoC, read_only, start_time, v_acc, a_acc, lac_log, events_prev): + """Send actuators and hud commands to the car, send controlsstate and MPC logging""" CC = car.CarControl.new_message() + CC.enabled = isEnabled(state) + CC.actuators = actuators - if not passive: - CC.enabled = isEnabled(state) - CC.actuators = actuators + CC.cruiseControl.override = True + CC.cruiseControl.cancel = not CP.enableCruise or (not isEnabled(state) and CS.cruiseState.enabled) - CC.cruiseControl.override = True - CC.cruiseControl.cancel = not CP.enableCruise or (not isEnabled(state) and CS.cruiseState.enabled) + # Some override values for Honda + brake_discount = (1.0 - clip(actuators.brake * 3., 0.0, 1.0)) # brake discount removes a sharp nonlinearity + CC.cruiseControl.speedOverride = float(max(0.0, (LoC.v_pid + CS.cruiseState.speedOffset) * brake_discount) if CP.enableCruise else 0.0) + CC.cruiseControl.accelOverride = CI.calc_accel_override(CS.aEgo, sm['plan'].aTarget, CS.vEgo, sm['plan'].vTarget) - # Some override values for Honda - brake_discount = (1.0 - clip(actuators.brake * 3., 0.0, 1.0)) # brake discount removes a sharp nonlinearity - CC.cruiseControl.speedOverride = float(max(0.0, (LoC.v_pid + CS.cruiseState.speedOffset) * brake_discount) if CP.enableCruise else 0.0) - CC.cruiseControl.accelOverride = CI.calc_accel_override(CS.aEgo, plan.aTarget, CS.vEgo, plan.vTarget) + CC.hudControl.setSpeed = float(v_cruise_kph * CV.KPH_TO_MS) + CC.hudControl.speedVisible = isEnabled(state) + CC.hudControl.lanesVisible = isEnabled(state) + CC.hudControl.leadVisible = sm['plan'].hasLead - CC.hudControl.setSpeed = float(v_cruise_kph * CV.KPH_TO_MS) - CC.hudControl.speedVisible = isEnabled(state) - CC.hudControl.lanesVisible = isEnabled(state) - CC.hudControl.leadVisible = plan.hasLead - CC.hudControl.rightLaneVisible = bool(path_plan.pathPlan.rProb > 0.5) - CC.hudControl.leftLaneVisible = bool(path_plan.pathPlan.lProb > 0.5) - CC.hudControl.visualAlert = AM.visual_alert - CC.hudControl.audibleAlert = AM.audible_alert + right_lane_visible = sm['pathPlan'].rProb > 0.5 + left_lane_visible = sm['pathPlan'].lProb > 0.5 + CC.hudControl.rightLaneVisible = bool(right_lane_visible) + CC.hudControl.leftLaneVisible = bool(left_lane_visible) + + blinker = CS.leftBlinker or CS.rightBlinker + ldw_allowed = CS.vEgo > 12.5 and not blinker + + if len(list(sm['pathPlan'].rPoly)) == 4: + CC.hudControl.rightLaneDepart = bool(ldw_allowed and sm['pathPlan'].rPoly[3] > -(1.08 + CAMERA_OFFSET) and right_lane_visible) + if len(list(sm['pathPlan'].lPoly)) == 4: + CC.hudControl.leftLaneDepart = bool(ldw_allowed and sm['pathPlan'].lPoly[3] < (1.08 - CAMERA_OFFSET) and left_lane_visible) + + CC.hudControl.visualAlert = AM.visual_alert + + if not read_only: # send car controls over can - CI.apply(CC) + can_sends = CI.apply(CC) + pm.send('sendcan', can_list_to_can_capnp(can_sends, msgtype='sendcan', valid=CS.canValid)) force_decel = driver_status.awareness < 0. - # live100 + # controlsState dat = messaging.new_message() - dat.init('live100') - dat.live100 = { + dat.init('controlsState') + dat.valid = CS.canValid + dat.controlsState = { "alertText1": AM.alert_text_1, "alertText2": AM.alert_text_2, "alertSize": AM.alert_size, "alertStatus": AM.alert_status, "alertBlinkingRate": AM.alert_rate, "alertType": AM.alert_type, - "alertSound": "", # no EON sounds yet - "awarenessStatus": max(driver_status.awareness, 0.0) if isEnabled(state) else 0.0, - "driverMonitoringOn": bool(driver_status.monitor_on), + "alertSound": AM.audible_alert, + "awarenessStatus": max(driver_status.awareness, -0.1) if isEnabled(state) else 1.0, + "driverMonitoringOn": bool(driver_status.face_detected), "canMonoTimes": list(CS.canMonoTimes), - "planMonoTime": plan_ts, - "pathPlanMonoTime": path_plan.logMonoTime, + "planMonoTime": sm.logMonoTime['plan'], + "pathPlanMonoTime": sm.logMonoTime['pathPlan'], "enabled": isEnabled(state), "active": isActive(state), "vEgo": CS.vEgo, "vEgoRaw": CS.vEgoRaw, "angleSteers": CS.steeringAngle, - "curvature": VM.calc_curvature(CS.steeringAngle * CV.DEG_TO_RAD, CS.vEgo), + "curvature": VM.calc_curvature((CS.steeringAngle - sm['pathPlan'].angleOffset) * CV.DEG_TO_RAD, CS.vEgo), "steerOverride": CS.steeringPressed, "state": state, "engageable": not bool(get_events(events, [ET.NO_ENTRY])), @@ -347,102 +363,126 @@ def data_send(plan, path_plan, CS, CI, CP, VM, state, events, actuators, v_cruis "uiAccelCmd": float(LoC.pid.i), "ufAccelCmd": float(LoC.pid.f), "angleSteersDes": float(LaC.angle_steers_des), - "upSteer": float(LaC.pid.p), - "uiSteer": float(LaC.pid.i), - "ufSteer": float(LaC.pid.f), "vTargetLead": float(v_acc), "aTarget": float(a_acc), - "jerkFactor": float(plan.jerkFactor), - "angleModelBias": float(angle_model_bias), - "gpsPlannerActive": plan.gpsPlannerActive, - "vCurvature": plan.vCurvature, - "decelForTurn": plan.decelForTurn, + "jerkFactor": float(sm['plan'].jerkFactor), + "gpsPlannerActive": sm['plan'].gpsPlannerActive, + "vCurvature": sm['plan'].vCurvature, + "decelForModel": sm['plan'].longitudinalPlanSource == log.Plan.LongitudinalPlanSource.model, "cumLagMs": -rk.remaining * 1000., - "startMonoTime": start_time, - "mapValid": plan.mapValid, + "startMonoTime": int(start_time * 1e9), + "mapValid": sm['plan'].mapValid, "forceDecel": bool(force_decel), } - live100.send(dat.to_bytes()) + + if CP.lateralTuning.which() == 'pid': + dat.controlsState.lateralControlState.pidState = lac_log + elif CP.lateralTuning.which() == 'lqr': + dat.controlsState.lateralControlState.lqrState = lac_log + elif CP.lateralTuning.which() == 'indi': + dat.controlsState.lateralControlState.indiState = lac_log + pm.send('controlsState', dat) # carState cs_send = messaging.new_message() cs_send.init('carState') + cs_send.valid = CS.canValid cs_send.carState = CS cs_send.carState.events = events - carstate.send(cs_send.to_bytes()) + pm.send('carState', cs_send) + + # carEvents - logged every second or on change + events_bytes = events_to_bytes(events) + if (sm.frame % int(1. / DT_CTRL) == 0) or (events_bytes != events_prev): + ce_send = messaging.new_message() + ce_send.init('carEvents', len(events)) + ce_send.carEvents = events + pm.send('carEvents', ce_send) + + # carParams - logged every 50 seconds (> 1 per segment) + if (sm.frame % int(50. / DT_CTRL) == 0): + cp_send = messaging.new_message() + cp_send.init('carParams') + cp_send.carParams = CP + pm.send('carParams', cp_send) # carControl cc_send = messaging.new_message() cc_send.init('carControl') + cc_send.valid = CS.canValid cc_send.carControl = CC - carcontrol.send(cc_send.to_bytes()) - - if (rk.frame % 36000) == 0: # update angle offset every 6 minutes - params.put("ControlsParams", json.dumps({'angle_model_bias': angle_model_bias})) + pm.send('carControl', cc_send) - return CC + return CC, events_bytes -def controlsd_thread(gctx=None, rate=100): +def controlsd_thread(sm=None, pm=None, can_sock=None): gc.disable() # start the loop set_realtime_priority(3) - context = zmq.Context() params = Params() - # Pub Sockets - live100 = messaging.pub_sock(context, service_list['live100'].port) - carstate = messaging.pub_sock(context, service_list['carState'].port) - carcontrol = messaging.pub_sock(context, service_list['carControl'].port) + is_metric = params.get("IsMetric", encoding='utf8') == "1" + passive = params.get("Passive", encoding='utf8') == "1" + openpilot_enabled_toggle = params.get("OpenpilotEnabledToggle", encoding='utf8') == "1" - is_metric = params.get("IsMetric") == "1" - passive = params.get("Passive") != "0" + passive = passive or not openpilot_enabled_toggle - # No sendcan if passive - if not passive: - sendcan = messaging.pub_sock(context, service_list['sendcan'].port) - else: - sendcan = None - - # Sub sockets - poller = zmq.Poller() - thermal = messaging.sub_sock(context, service_list['thermal'].port, conflate=True, poller=poller) - health = messaging.sub_sock(context, service_list['health'].port, conflate=True, poller=poller) - cal = messaging.sub_sock(context, service_list['liveCalibration'].port, conflate=True, poller=poller) - driver_monitor = messaging.sub_sock(context, service_list['driverMonitoring'].port, conflate=True, poller=poller) - plan_sock = messaging.sub_sock(context, service_list['plan'].port, conflate=True, poller=poller) - path_plan_sock = messaging.sub_sock(context, service_list['pathPlan'].port, conflate=True, poller=poller) - logcan = messaging.sub_sock(context, service_list['can'].port) + # Pub/Sub Sockets + if pm is None: + pm = messaging.PubMaster(['sendcan', 'controlsState', 'carState', 'carControl', 'carEvents', 'carParams']) - CC = car.CarControl.new_message() - CI, CP = get_car(logcan, sendcan, 1.0 if passive else None) + if sm is None: + sm = messaging.SubMaster(['thermal', 'health', 'liveCalibration', 'driverMonitoring', 'plan', 'pathPlan', \ + 'gpsLocation'], ignore_alive=['gpsLocation']) - if CI is None: - raise Exception("unsupported car") - # if stock camera is connected, then force passive behavior - if not CP.enableCamera: - passive = True - sendcan = None + if can_sock is None: + can_timeout = None if os.environ.get('NO_CAN_TIMEOUT', False) else 100 + can_sock = messaging.sub_sock('can', timeout=can_timeout) - if passive: - CP.safetyModel = car.CarParams.SafetyModels.noOutput + # wait for health and CAN packets + hw_type = messaging.recv_one(sm.sock['health']).health.hwType + has_relay = hw_type in [HwType.blackPanda, HwType.uno] + print("Waiting for CAN messages...") + messaging.get_one_can(can_sock) - LoC = LongControl(CP, CI.compute_gb) - VM = VehicleModel(CP) - LaC = LatControl(CP) - AM = AlertManager() - driver_status = DriverStatus() + CI, CP = get_car(can_sock, pm.sock['sendcan'], has_relay) - if not passive: - AM.add("startup", False) + car_recognized = CP.carName != 'mock' + # If stock camera is disconnected, we loaded car controls and it's not chffrplus + controller_available = CP.enableCamera and CI.CC is not None and not passive + read_only = not car_recognized or not controller_available or CP.dashcamOnly + if read_only: + CP.safetyModel = car.CarParams.SafetyModel.noOutput # Write CarParams for radard and boardd safety mode params.put("CarParams", CP.to_bytes()) params.put("LongitudinalControl", "1" if CP.openpilotLongitudinalControl else "0") + CC = car.CarControl.new_message() + AM = AlertManager() + + startup_alert = get_startup_alert(car_recognized, controller_available) + AM.add(sm.frame, startup_alert, False) + + LoC = LongControl(CP, CI.compute_gb) + VM = VehicleModel(CP) + + if CP.lateralTuning.which() == 'pid': + LaC = LatControlPID(CP) + elif CP.lateralTuning.which() == 'indi': + LaC = LatControlINDI(CP) + elif CP.lateralTuning.which() == 'lqr': + LaC = LatControlLQR(CP) + + driver_status = DriverStatus() + is_rhd = params.get("IsRHD") + if is_rhd is not None: + driver_status.is_rhd = bool(int(is_rhd)) + state = State.disabled soft_disable_timer = 0 v_cruise_kph = 255 @@ -453,74 +493,81 @@ def controlsd_thread(gctx=None, rate=100): cal_perc = 0 mismatch_counter = 0 low_battery = False + events_prev = [] + + sm['pathPlan'].sensorValid = True + sm['pathPlan'].posenetValid = True - plan = messaging.new_message() - plan.init('plan') - path_plan = messaging.new_message() - path_plan.init('pathPlan') + # detect sound card presence + sounds_available = not os.path.isfile('/EON') or (os.path.isdir('/proc/asound/card0') and open('/proc/asound/card0/state').read().strip() == 'ONLINE') - rk = Ratekeeper(rate, print_delay_threshold=2. / 1000) - controls_params = params.get("ControlsParams") + # controlsd is driven by can recv, expected at 100Hz + rk = Ratekeeper(100, print_delay_threshold=None) - # Read angle offset from previous drive - angle_model_bias = 0. - if controls_params is not None: - try: - controls_params = json.loads(controls_params) - angle_model_bias = controls_params['angle_model_bias'] - except (ValueError, KeyError): - pass + internet_needed = params.get("Offroad_ConnectivityNeeded", encoding='utf8') is not None prof = Profiler(False) # off by default while True: - start_time = int(sec_since_boot() * 1e9) + start_time = sec_since_boot() prof.checkpoint("Ratekeeper", ignore=True) # Sample data and compute car events - CS, events, cal_status, cal_perc, overtemp, free_space, low_battery, mismatch_counter, plan, path_plan =\ - data_sample(CI, CC, plan_sock, path_plan_sock, thermal, cal, health, driver_monitor, - poller, cal_status, cal_perc, overtemp, free_space, low_battery, driver_status, - state, mismatch_counter, params, plan, path_plan) + CS, events, cal_status, cal_perc, overtemp, free_space, low_battery, mismatch_counter =\ + data_sample(CI, CC, sm, can_sock, cal_status, cal_perc, overtemp, free_space, low_battery, + driver_status, state, mismatch_counter, params) prof.checkpoint("Sample") - path_plan_age = (start_time - path_plan.logMonoTime) / 1e9 - plan_age = (start_time - plan.logMonoTime) / 1e9 - if not path_plan.pathPlan.valid or plan_age > 0.5 or path_plan_age > 0.5: - events.append(create_event('plannerError', [ET.NO_ENTRY, ET.SOFT_DISABLE])) - if not path_plan.pathPlan.paramsValid: + # Create alerts + if not sm.all_alive_and_valid(): + events.append(create_event('commIssue', [ET.NO_ENTRY, ET.SOFT_DISABLE])) + if not sm['pathPlan'].mpcSolutionValid: + events.append(create_event('plannerError', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) + if not sm['pathPlan'].sensorValid: + events.append(create_event('sensorDataInvalid', [ET.NO_ENTRY, ET.PERMANENT])) + if not sm['pathPlan'].paramsValid: events.append(create_event('vehicleModelInvalid', [ET.WARNING])) - events += list(plan.plan.events) + if not sm['pathPlan'].posenetValid: + events.append(create_event('posenetInvalid', [ET.NO_ENTRY, ET.SOFT_DISABLE])) + if not sm['plan'].radarValid: + events.append(create_event('radarFault', [ET.NO_ENTRY, ET.SOFT_DISABLE])) + if sm['plan'].radarCanError: + events.append(create_event('radarCanError', [ET.NO_ENTRY, ET.SOFT_DISABLE])) + if not CS.canValid: + events.append(create_event('canError', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) + if not sounds_available: + events.append(create_event('soundsUnavailable', [ET.NO_ENTRY, ET.PERMANENT])) + if internet_needed: + events.append(create_event('internetConnectivityNeeded', [ET.NO_ENTRY, ET.PERMANENT])) # Only allow engagement with brake pressed when stopped behind another stopped car - if CS.brakePressed and plan.plan.vTargetFuture >= STARTING_TARGET_SPEED and not CP.radarOffCan and CS.vEgo < 0.3: + if CS.brakePressed and sm['plan'].vTargetFuture >= STARTING_TARGET_SPEED and not CP.radarOffCan and CS.vEgo < 0.3: events.append(create_event('noTarget', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) - if not passive: + if not read_only: # update control state state, soft_disable_timer, v_cruise_kph, v_cruise_kph_last = \ - state_transition(CS, CP, state, events, soft_disable_timer, v_cruise_kph, AM) + state_transition(sm.frame, CS, CP, state, events, soft_disable_timer, v_cruise_kph, AM) prof.checkpoint("State transition") # Compute actuators (runs PID loops and lateral MPC) - actuators, v_cruise_kph, driver_status, angle_model_bias, v_acc, a_acc = \ - state_control(plan.plan, path_plan.pathPlan, CS, CP, state, events, v_cruise_kph, - v_cruise_kph_last, AM, rk, driver_status, - LaC, LoC, VM, angle_model_bias, passive, is_metric, cal_perc) + actuators, v_cruise_kph, driver_status, v_acc, a_acc, lac_log = \ + state_control(sm.frame, sm.rcv_frame, sm['plan'], sm['pathPlan'], CS, CP, state, events, v_cruise_kph, v_cruise_kph_last, AM, rk, + driver_status, LaC, LoC, read_only, is_metric, cal_perc) prof.checkpoint("State Control") # Publish data - CC = data_send(plan, path_plan, CS, CI, CP, VM, state, events, actuators, v_cruise_kph, rk, carstate, carcontrol, - live100, AM, driver_status, LaC, LoC, angle_model_bias, passive, start_time, params, v_acc, a_acc) + CC, events_prev = data_send(sm, pm, CS, CI, CP, VM, state, events, actuators, v_cruise_kph, rk, AM, driver_status, LaC, + LoC, read_only, start_time, v_acc, a_acc, lac_log, events_prev) prof.checkpoint("Sent") - rk.keep_time() # Run at 100Hz + rk.monitor_time() prof.display() -def main(gctx=None): - controlsd_thread(gctx, 100) +def main(sm=None, pm=None, logcan=None): + controlsd_thread(sm, pm, logcan) if __name__ == "__main__": diff --git a/selfdrive/controls/lib/alertmanager.py b/selfdrive/controls/lib/alertmanager.py index 5884e987033fc3..b6aa97b6fdc8f6 100644 --- a/selfdrive/controls/lib/alertmanager.py +++ b/selfdrive/controls/lib/alertmanager.py @@ -1,15 +1,16 @@ -from cereal import log +from cereal import car, log +from common.realtime import DT_CTRL from selfdrive.swaglog import cloudlog from selfdrive.controls.lib.alerts import ALERTS -from common.realtime import sec_since_boot import copy -AlertSize = log.Live100Data.AlertSize -AlertStatus = log.Live100Data.AlertStatus +AlertSize = log.ControlsState.AlertSize +AlertStatus = log.ControlsState.AlertStatus +VisualAlert = car.CarControl.HUDControl.VisualAlert +AudibleAlert = car.CarControl.HUDControl.AudibleAlert - -class AlertManager(object): +class AlertManager(): def __init__(self): self.activealerts = [] @@ -18,12 +19,12 @@ def __init__(self): def alertPresent(self): return len(self.activealerts) > 0 - def add(self, alert_type, enabled=True, extra_text_1='', extra_text_2=''): + def add(self, frame, alert_type, enabled=True, extra_text_1='', extra_text_2=''): alert_type = str(alert_type) added_alert = copy.copy(self.alerts[alert_type]) added_alert.alert_text_1 += extra_text_1 added_alert.alert_text_2 += extra_text_2 - added_alert.start_time = sec_since_boot() + added_alert.start_time = frame * DT_CTRL # if new alert is higher priority, log it if not self.alertPresent() or added_alert.alert_priority > self.activealerts[0].alert_priority: @@ -34,7 +35,8 @@ def add(self, alert_type, enabled=True, extra_text_1='', extra_text_2=''): # sort by priority first and then by start_time self.activealerts.sort(key=lambda k: (k.alert_priority, k.start_time), reverse=True) - def process_alerts(self, cur_time): + def process_alerts(self, frame): + cur_time = frame * DT_CTRL # first get rid of all the expired alerts self.activealerts = [a for a in self.activealerts if a.start_time + @@ -48,8 +50,8 @@ def process_alerts(self, cur_time): self.alert_text_2 = "" self.alert_status = AlertStatus.normal self.alert_size = AlertSize.none - self.visual_alert = "none" - self.audible_alert = "none" + self.visual_alert = VisualAlert.none + self.audible_alert = AudibleAlert.none self.alert_rate = 0. if current_alert: diff --git a/selfdrive/controls/lib/alerts.py b/selfdrive/controls/lib/alerts.py index 17caf7fbf647fb..57e3969eea1800 100644 --- a/selfdrive/controls/lib/alerts.py +++ b/selfdrive/controls/lib/alerts.py @@ -9,12 +9,12 @@ class Priority: HIGH = 4 HIGHEST = 5 -AlertSize = log.Live100Data.AlertSize -AlertStatus = log.Live100Data.AlertStatus +AlertSize = log.ControlsState.AlertSize +AlertStatus = log.ControlsState.AlertStatus AudibleAlert = car.CarControl.HUDControl.AudibleAlert VisualAlert = car.CarControl.HUDControl.VisualAlert -class Alert(object): +class Alert(): def __init__(self, alert_type, alert_text_1, @@ -124,7 +124,7 @@ def __gt__(self, alert2): Alert( "preDriverUnresponsive", - "TOUCH STEERING WHEEL: No Driver Monitoring", + "TOUCH STEERING WHEEL: No Face Detected", "", AlertStatus.normal, AlertSize.small, Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .0, .1, .1, alert_rate=0.75), @@ -171,6 +171,20 @@ def __gt__(self, alert2): AlertStatus.normal, AlertSize.mid, Priority.LOW_LOWEST, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), + Alert( + "startupNoControl", + "Dashcam mode", + "Always keep hands on wheel and eyes on road", + AlertStatus.normal, AlertSize.mid, + Priority.LOW_LOWEST, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), + + Alert( + "startupNoCar", + "Dashcam mode with unsupported car", + "Always keep hands on wheel and eyes on road", + AlertStatus.normal, AlertSize.mid, + Priority.LOW_LOWEST, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), + Alert( "ethicalDilemma", "TAKE CONTROL IMMEDIATELY", @@ -204,7 +218,7 @@ def __gt__(self, alert2): "TAKE CONTROL", "Steer Unavailable Below ", AlertStatus.userPrompt, AlertSize.mid, - Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning1, 0., 0., .1), + Priority.MID, VisualAlert.steerRequired, AudibleAlert.none, 0., 0.4, .3), Alert( "debugAlert", @@ -277,147 +291,175 @@ def __gt__(self, alert2): AlertStatus.normal, AlertSize.mid, Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), + Alert( + "sensorDataInvalidNoEntry", + "openpilot Unavailable", + "No Data from EON Sensors", + AlertStatus.normal, AlertSize.mid, + Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), + + Alert( + "soundsUnavailableNoEntry", + "openpilot Unavailable", + "Speaker not found", + AlertStatus.normal, AlertSize.mid, + Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), + + Alert( + "tooDistractedNoEntry", + "openpilot Unavailable", + "Distraction Level Too High", + AlertStatus.normal, AlertSize.mid, + Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), + # Cancellation alerts causing soft disabling Alert( "overheat", "TAKE CONTROL IMMEDIATELY", "System Overheated", AlertStatus.critical, AlertSize.full, - Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2, .1, 2., 2.), + Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), Alert( "wrongGear", "TAKE CONTROL IMMEDIATELY", "Gear not D", AlertStatus.critical, AlertSize.full, - Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2, .1, 2., 2.), + Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), Alert( "calibrationInvalid", "TAKE CONTROL IMMEDIATELY", "Calibration Invalid: Reposition EON and Recalibrate", AlertStatus.critical, AlertSize.full, - Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2, .1, 2., 2.), + Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), Alert( "calibrationIncomplete", "TAKE CONTROL IMMEDIATELY", "Calibration in Progress", AlertStatus.critical, AlertSize.full, - Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2, .1, 2., 2.), + Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), Alert( "doorOpen", "TAKE CONTROL IMMEDIATELY", "Door Open", AlertStatus.critical, AlertSize.full, - Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2, .1, 2., 2.), + Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), Alert( "seatbeltNotLatched", "TAKE CONTROL IMMEDIATELY", "Seatbelt Unlatched", AlertStatus.critical, AlertSize.full, - Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2, .1, 2., 2.), + Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), Alert( "espDisabled", "TAKE CONTROL IMMEDIATELY", "ESP Off", AlertStatus.critical, AlertSize.full, - Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2, .1, 2., 2.), + Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), Alert( "lowBattery", "TAKE CONTROL IMMEDIATELY", "Low Battery", AlertStatus.critical, AlertSize.full, - Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2, .1, 2., 2.), + Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), + + Alert( + "commIssue", + "TAKE CONTROL IMMEDIATELY", + "Communication Issue between Processes", + AlertStatus.critical, AlertSize.full, + Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), - # Cancellation alerts causing immediate disabling Alert( - "radarCommIssue", + "radarCanError", "TAKE CONTROL IMMEDIATELY", "Radar Error: Restart the Car", AlertStatus.critical, AlertSize.full, - Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 1., 3., 4.), + Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), Alert( "radarFault", "TAKE CONTROL IMMEDIATELY", "Radar Error: Restart the Car", AlertStatus.critical, AlertSize.full, - Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 1., 3., 4.), + Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), Alert( - "modelCommIssue", + "posenetInvalid", "TAKE CONTROL IMMEDIATELY", - "Model Error: Check Internet Connection", + "Vision Failure: Check Camera View", AlertStatus.critical, AlertSize.full, - Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 1., 3., 4.), + Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), + # Cancellation alerts causing immediate disabling Alert( "controlsFailed", "TAKE CONTROL IMMEDIATELY", "Controls Failed", AlertStatus.critical, AlertSize.full, - Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 1., 3., 4.), + Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), Alert( "controlsMismatch", "TAKE CONTROL IMMEDIATELY", "Controls Mismatch", AlertStatus.critical, AlertSize.full, - Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 1., 3., 4.), + Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), Alert( - "commIssue", + "canError", "TAKE CONTROL IMMEDIATELY", "CAN Error: Check Connections", AlertStatus.critical, AlertSize.full, - Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 1., 3., 4.), + Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), Alert( "steerUnavailable", "TAKE CONTROL IMMEDIATELY", "LKAS Fault: Restart the Car", AlertStatus.critical, AlertSize.full, - Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 1., 3., 4.), + Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), Alert( "brakeUnavailable", "TAKE CONTROL IMMEDIATELY", "Cruise Fault: Restart the Car", AlertStatus.critical, AlertSize.full, - Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 1., 3., 4.), + Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), Alert( "gasUnavailable", "TAKE CONTROL IMMEDIATELY", "Gas Fault: Restart the Car", AlertStatus.critical, AlertSize.full, - Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 1., 3., 4.), + Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), Alert( "reverseGear", "TAKE CONTROL IMMEDIATELY", "Reverse Gear", AlertStatus.critical, AlertSize.full, - Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 1., 3., 4.), + Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), Alert( "cruiseDisabled", "TAKE CONTROL IMMEDIATELY", "Cruise Is Off", AlertStatus.critical, AlertSize.full, - Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 1., 3., 4.), + Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), Alert( "plannerError", "TAKE CONTROL IMMEDIATELY", "Planner Solution Error", AlertStatus.critical, AlertSize.full, - Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 1., 3., 4.), + Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), # not loud cancellations (user is in control) Alert( @@ -499,7 +541,7 @@ def __gt__(self, alert2): Priority.MID, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), Alert( - "radarCommIssueNoEntry", + "radarCanErrorNoEntry", "openpilot Unavailable", "Radar Error: Restart the Car", AlertStatus.normal, AlertSize.mid, @@ -513,9 +555,9 @@ def __gt__(self, alert2): Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), Alert( - "modelCommIssueNoEntry", + "posenetInvalidNoEntry", "openpilot Unavailable", - "Model Error: Check Internet Connection", + "Vision Failure: Check Camera View", AlertStatus.normal, AlertSize.mid, Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), @@ -527,7 +569,7 @@ def __gt__(self, alert2): Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), Alert( - "commIssueNoEntry", + "canErrorNoEntry", "openpilot Unavailable", "CAN Error: Check Connections", AlertStatus.normal, AlertSize.mid, @@ -589,6 +631,27 @@ def __gt__(self, alert2): AlertStatus.normal, AlertSize.mid, Priority.LOW, VisualAlert.none, AudibleAlert.chimeDisengage, .4, 2., 3.), + Alert( + "invalidGiraffeToyotaNoEntry", + "openpilot Unavailable", + "Visit comma.ai/tg", + AlertStatus.normal, AlertSize.mid, + Priority.LOW, VisualAlert.none, AudibleAlert.chimeDisengage, .4, 2., 3.), + + Alert( + "commIssueNoEntry", + "openpilot Unavailable", + "Communication Issue between Processes", + AlertStatus.normal, AlertSize.mid, + Priority.LOW, VisualAlert.none, AudibleAlert.chimeDisengage, .4, 2., 3.), + + Alert( + "internetConnectivityNeededNoEntry", + "openpilot Unavailable", + "Internet Connectivity Needed", + AlertStatus.normal, AlertSize.mid, + Priority.LOW, VisualAlert.none, AudibleAlert.chimeDisengage, .4, 2., 3.), + # permanent alerts Alert( "steerUnavailablePermanent", @@ -625,6 +688,34 @@ def __gt__(self, alert2): AlertStatus.normal, AlertSize.mid, Priority.LOW_LOWEST, VisualAlert.none, AudibleAlert.none, 0., 0., .2), + Alert( + "invalidGiraffeToyotaPermanent", + "Unsupported Giraffe Configuration", + "Visit comma.ai/tg", + AlertStatus.normal, AlertSize.mid, + Priority.LOW_LOWEST, VisualAlert.none, AudibleAlert.none, 0., 0., .2), + + Alert( + "internetConnectivityNeededPermanent", + "Internet Connectivity Needed", + "Check for Updates to Be Able to Engage", + AlertStatus.normal, AlertSize.mid, + Priority.LOW_LOWEST, VisualAlert.none, AudibleAlert.none, 0., 0., .2), + + Alert( + "sensorDataInvalidPermanent", + "No Data from EON Sensors", + "Reboot your EON", + AlertStatus.normal, AlertSize.mid, + Priority.LOW_LOWEST, VisualAlert.none, AudibleAlert.none, 0., 0., .2), + + Alert( + "soundsUnavailablePermanent", + "Speaker not found", + "Reboot your EON", + AlertStatus.normal, AlertSize.mid, + Priority.LOW_LOWEST, VisualAlert.none, AudibleAlert.none, 0., 0., .2), + Alert( "vehicleModelInvalid", "Vehicle Parameter Identification Failed", diff --git a/selfdrive/controls/lib/alerts_offroad.json b/selfdrive/controls/lib/alerts_offroad.json new file mode 100644 index 00000000000000..534deae2fe3879 --- /dev/null +++ b/selfdrive/controls/lib/alerts_offroad.json @@ -0,0 +1,27 @@ +{ + "Offroad_ChargeDisabled": { + "text": "EON charging disabled after car being off for more than 3 days. Turn ignition on to start charging again.", + "severity": 0 + }, + "Offroad_TemperatureTooHigh": { + "text": "EON temperature too high. System won't start.", + "severity": 1 + }, + "Offroad_ConnectivityNeededPrompt": { + "text": "Connect to internet to check for updates. openpilot won't engage in ", + "severity": 0, + "_comment": "Append the number of days at the end of the text" + }, + "Offroad_ConnectivityNeeded": { + "text": "Connect to internet to check for updates. openpilot won't engage.", + "severity": 1 + }, + "Offroad_PandaFirmwareMismatch": { + "text": "Unexpected panda firmware version. System won't start. Reboot your EON to reflash panda.", + "severity": 1 + }, + "Offroad_InvalidTime": { + "text": "Invalid date and time settings, system won't start. Connect to internet to set time.", + "severity": 1 + } +} diff --git a/selfdrive/controls/lib/cluster/LICENSE b/selfdrive/controls/lib/cluster/LICENSE new file mode 100644 index 00000000000000..ab8b4db7d73569 --- /dev/null +++ b/selfdrive/controls/lib/cluster/LICENSE @@ -0,0 +1,13 @@ +Copyright: + * fastcluster_dm.cpp & fastcluster_R_dm.cpp: + © 2011 Daniel Müllner + * fastcluster.(h|cpp) & demo.cpp & plotresult.r: + © 2018 Christoph Dalitz +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. + +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 HOLDER 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. diff --git a/selfdrive/controls/lib/cluster/Makefile b/selfdrive/controls/lib/cluster/Makefile new file mode 100644 index 00000000000000..ca4a23da59fa8c --- /dev/null +++ b/selfdrive/controls/lib/cluster/Makefile @@ -0,0 +1,32 @@ +CC = clang +CXX = clang++ + +CXXFLAGS = -Wall -g -fPIC -std=c++11 -O2 + +ifeq ($(ARCH),aarch64) +CXXFLAGS += -mcpu=cortex-a57 +endif + +OBJS = fastcluster.o test.o +DEPS := $(OBJS:.o=.d) + +all: libfastcluster.so + +test: libfastcluster.so test.o + $(CXX) -g -L. -lfastcluster -o $@ $+ + +valgrind: test + valgrind --leak-check=full ./test + + +libfastcluster.so: fastcluster.o + $(CXX) -g -shared -o $@ $+ + +%.o: %.cpp + $(CXX) $(CXXFLAGS) -MMD -c $*.cpp + +clean: + rm -f $(OBJS) $(DEPS) libfastcluster.so test + + +-include $(DEPS) diff --git a/selfdrive/controls/lib/cluster/README b/selfdrive/controls/lib/cluster/README new file mode 100644 index 00000000000000..acb18bc72b71d4 --- /dev/null +++ b/selfdrive/controls/lib/cluster/README @@ -0,0 +1,79 @@ +C++ interface to fast hierarchical clustering algorithms +======================================================== + +This is a simplified C++ interface to fast implementations of hierarchical +clustering by Daniel Müllner. The original library with interfaces to R +and Python is described in: + +Daniel Müllner: "fastcluster: Fast Hierarchical, Agglomerative Clustering +Routines for R and Python." Journal of Statistical Software 53 (2013), +no. 9, pp. 1–18, http://www.jstatsoft.org/v53/i09/ + + +Usage of the library +-------------------- + +For using the library, the following source files are needed: + +fastcluster_dm.cpp, fastcluster_R_dm.cpp + original code by Daniel Müllner + these are included by fastcluster.cpp via #include, and therefore + need not be compiled to object code + +fastcluster.[h|cpp] + simplified C++ interface + fastcluster.cpp is the only file that must be compiled + +The library provides the clustering function *hclust_fast* for +creating the dendrogram information in an encoding as used by the +R function *hclust*. For a description of the parameters, see fastcluster.h. +Its parameter *method* can be one of + +HCLUST_METHOD_SINGLE + single link with the minimum spanning tree algorithm (Rohlf, 1973) + +HHCLUST_METHOD_COMPLETE + complete link with the nearest-neighbor-chain algorithm (Murtagh, 1984) + +HCLUST_METHOD_AVERAGE + complete link with the nearest-neighbor-chain algorithm (Murtagh, 1984) + +HCLUST_METHOD_MEDIAN + median link with the generic algorithm (Müllner, 2011) + +For splitting the dendrogram into clusters, the two functions *cutree_k* +and *cutree_cdist* are provided. + +Note that output parameters must be allocated beforehand, e.g. + int* merge = new int[2*(npoints-1)]; +For a complete usage example, see lines 135-142 of demo.cpp. + + +Demonstration program +--------------------- + +A simple demo is implemented in demo.cpp, which can be compiled and run with + + make + ./hclust-demo -m complete lines.csv + +It creates two clusters of line segments such that the segment angle between +line segments of different clusters have a maximum (cosine) dissimilarity. +For visualizing the result, plotresult.r can be used as follows +(requires R to be installed): + + ./hclust-demo -m complete lines.csv | Rscript plotresult.r + + +Authors & Copyright +------------------- + +Daniel Müllner, 2011, +Christoph Dalitz, 2018, + + +License +------- + +This code is provided under a BSD-style license. +See the file LICENSE for details. diff --git a/pyextra/websocket/tests/__init__.py b/selfdrive/controls/lib/cluster/__init__.py similarity index 100% rename from pyextra/websocket/tests/__init__.py rename to selfdrive/controls/lib/cluster/__init__.py diff --git a/selfdrive/controls/lib/cluster/fastcluster.cpp b/selfdrive/controls/lib/cluster/fastcluster.cpp new file mode 100644 index 00000000000000..6b0af725cef289 --- /dev/null +++ b/selfdrive/controls/lib/cluster/fastcluster.cpp @@ -0,0 +1,218 @@ +// +// C++ standalone verion of fastcluster by Daniel Müllner +// +// Copyright: Christoph Dalitz, 2018 +// Daniel Müllner, 2011 +// License: BSD style license +// (see the file LICENSE for details) +// + + +#include +#include +#include + + +extern "C" { +#include "fastcluster.h" +} + +// Code by Daniel Müllner +// workaround to make it usable as a standalone version (without R) +bool fc_isnan(double x) { return false; } +#include "fastcluster_dm.cpp" +#include "fastcluster_R_dm.cpp" + +extern "C" { +// +// Assigns cluster labels (0, ..., nclust-1) to the n points such +// that the cluster result is split into nclust clusters. +// +// Input arguments: +// n = number of observables +// merge = clustering result in R format +// nclust = number of clusters +// Output arguments: +// labels = allocated integer array of size n for result +// + void cutree_k(int n, const int* merge, int nclust, int* labels) { + + int k,m1,m2,j,l; + + if (nclust > n || nclust < 2) { + for (j=0; j last_merge(n, 0); + for (k=1; k<=(n-nclust); k++) { + // (m1,m2) = merge[k,] + m1 = merge[k-1]; + m2 = merge[n-1+k-1]; + if (m1 < 0 && m2 < 0) { // both single observables + last_merge[-m1-1] = last_merge[-m2-1] = k; + } + else if (m1 < 0 || m2 < 0) { // one is a cluster + if(m1 < 0) { j = -m1; m1 = m2; } else j = -m2; + // merging single observable and cluster + for(l = 0; l < n; l++) + if (last_merge[l] == m1) + last_merge[l] = k; + last_merge[j-1] = k; + } + else { // both cluster + for(l=0; l < n; l++) { + if( last_merge[l] == m1 || last_merge[l] == m2 ) + last_merge[l] = k; + } + } + } + + // assign cluster labels + int label = 0; + std::vector z(n,-1); + for (j=0; j= cdist + // + // Input arguments: + // n = number of observables + // merge = clustering result in R format + // height = cluster distance at each merge step + // cdist = cutoff cluster distance + // Output arguments: + // labels = allocated integer array of size n for result + // + void cutree_cdist(int n, const int* merge, double* height, double cdist, int* labels) { + + int k; + + for (k=0; k<(n-1); k++) { + if (height[k] >= cdist) { + break; + } + } + cutree_k(n, merge, n-k, labels); + } + + + // + // Hierarchical clustering with one of Daniel Muellner's fast algorithms + // + // Input arguments: + // n = number of observables + // distmat = condensed distance matrix, i.e. an n*(n-1)/2 array representing + // the upper triangle (without diagonal elements) of the distance + // matrix, e.g. for n=4: + // d00 d01 d02 d03 + // d10 d11 d12 d13 -> d01 d02 d03 d12 d13 d23 + // d20 d21 d22 d23 + // d30 d31 d32 d33 + // method = cluster metric (see enum method_code) + // Output arguments: + // merge = allocated (n-1)x2 matrix (2*(n-1) array) for storing result. + // Result follows R hclust convention: + // - observabe indices start with one + // - merge[i][] contains the merged nodes in step i + // - merge[i][j] is negative when the node is an atom + // height = allocated (n-1) array with distances at each merge step + // Return code: + // 0 = ok + // 1 = invalid method + // + int hclust_fast(int n, double* distmat, int method, int* merge, double* height) { + + // call appropriate culstering function + cluster_result Z2(n-1); + if (method == HCLUST_METHOD_SINGLE) { + // single link + MST_linkage_core(n, distmat, Z2); + } + else if (method == HCLUST_METHOD_COMPLETE) { + // complete link + NN_chain_core(n, distmat, NULL, Z2); + } + else if (method == HCLUST_METHOD_AVERAGE) { + // best average distance + double* members = new double[n]; + for (int i=0; i(n, distmat, members, Z2); + delete[] members; + } + else if (method == HCLUST_METHOD_MEDIAN) { + // best median distance (beware: O(n^3)) + generic_linkage(n, distmat, NULL, Z2); + } + else if (method == HCLUST_METHOD_CENTROID) { + // best centroid distance (beware: O(n^3)) + double* members = new double[n]; + for (int i=0; i(n, distmat, members, Z2); + delete[] members; + } + else { + return 1; + } + + int* order = new int[n]; + if (method == HCLUST_METHOD_MEDIAN || method == HCLUST_METHOD_CENTROID) { + generate_R_dendrogram(merge, height, order, Z2, n); + } else { + generate_R_dendrogram(merge, height, order, Z2, n); + } + delete[] order; // only needed for visualization + + return 0; + } + + + // Build condensed distance matrix + // Input arguments: + // n = number of observables + // m = dimension of observable + // Output arguments: + // out = allocated integer array of size n * (n - 1) / 2 for result + void hclust_pdist(int n, int m, double* pts, double* out) { + int ii = 0; + for (int i = 0; i < n; i++){ + for (int j = i + 1; j < n; j++){ + // Compute euclidian distance + double d = 0; + for (int k = 0; k < m; k ++){ + double error = pts[i * m + k] - pts[j * m + k]; + d += (error * error); + } + out[ii] = d;//sqrt(d); + ii++; + } + } + } + + void cluster_points_centroid(int n, int m, double* pts, double dist, int* idx) { + double* pdist = new double[n * (n - 1) / 2]; + int* merge = new int[2 * (n - 1)]; + double* height = new double[n - 1]; + + hclust_pdist(n, m, pts, pdist); + hclust_fast(n, pdist, HCLUST_METHOD_CENTROID, merge, height); + cutree_cdist(n, merge, height, dist, idx); + + delete[] pdist; + delete[] merge; + delete[] height; + } +} diff --git a/selfdrive/controls/lib/cluster/fastcluster.h b/selfdrive/controls/lib/cluster/fastcluster.h new file mode 100644 index 00000000000000..56c63b6a5e291a --- /dev/null +++ b/selfdrive/controls/lib/cluster/fastcluster.h @@ -0,0 +1,77 @@ +// +// C++ standalone verion of fastcluster by Daniel Muellner +// +// Copyright: Daniel Muellner, 2011 +// Christoph Dalitz, 2018 +// License: BSD style license +// (see the file LICENSE for details) +// + +#ifndef fastclustercpp_H +#define fastclustercpp_H + +// +// Assigns cluster labels (0, ..., nclust-1) to the n points such +// that the cluster result is split into nclust clusters. +// +// Input arguments: +// n = number of observables +// merge = clustering result in R format +// nclust = number of clusters +// Output arguments: +// labels = allocated integer array of size n for result +// +void cutree_k(int n, const int* merge, int nclust, int* labels); + +// +// Assigns cluster labels (0, ..., nclust-1) to the n points such +// that the hierarchical clsutering is stopped at cluster distance cdist +// +// Input arguments: +// n = number of observables +// merge = clustering result in R format +// height = cluster distance at each merge step +// cdist = cutoff cluster distance +// Output arguments: +// labels = allocated integer array of size n for result +// +void cutree_cdist(int n, const int* merge, double* height, double cdist, int* labels); + +// +// Hierarchical clustering with one of Daniel Muellner's fast algorithms +// +// Input arguments: +// n = number of observables +// distmat = condensed distance matrix, i.e. an n*(n-1)/2 array representing +// the upper triangle (without diagonal elements) of the distance +// matrix, e.g. for n=4: +// d00 d01 d02 d03 +// d10 d11 d12 d13 -> d01 d02 d03 d12 d13 d23 +// d20 d21 d22 d23 +// d30 d31 d32 d33 +// method = cluster metric (see enum method_code) +// Output arguments: +// merge = allocated (n-1)x2 matrix (2*(n-1) array) for storing result. +// Result follows R hclust convention: +// - observabe indices start with one +// - merge[i][] contains the merged nodes in step i +// - merge[i][j] is negative when the node is an atom +// height = allocated (n-1) array with distances at each merge step +// Return code: +// 0 = ok +// 1 = invalid method +// +int hclust_fast(int n, double* distmat, int method, int* merge, double* height); +enum hclust_fast_methods { + HCLUST_METHOD_SINGLE = 0, + HCLUST_METHOD_COMPLETE = 1, + HCLUST_METHOD_AVERAGE = 2, + HCLUST_METHOD_MEDIAN = 3, + HCLUST_METHOD_CENTROID = 5, +}; + +void hclust_pdist(int n, int m, double* pts, double* out); +void cluster_points_centroid(int n, int m, double* pts, double dist, int* idx); + + +#endif diff --git a/selfdrive/controls/lib/cluster/fastcluster_R_dm.cpp b/selfdrive/controls/lib/cluster/fastcluster_R_dm.cpp new file mode 100644 index 00000000000000..cbe126c15e33cc --- /dev/null +++ b/selfdrive/controls/lib/cluster/fastcluster_R_dm.cpp @@ -0,0 +1,115 @@ +// +// Excerpt from fastcluster_R.cpp +// +// Copyright: Daniel Müllner, 2011 +// + +struct pos_node { + t_index pos; + int node; +}; + +void order_nodes(const int N, const int * const merge, const t_index * const node_size, int * const order) { + /* Parameters: + N : number of data points + merge : (N-1)×2 array which specifies the node indices which are + merged in each step of the clustering procedure. + Negative entries -1...-N point to singleton nodes, while + positive entries 1...(N-1) point to nodes which are themselves + parents of other nodes. + node_size : array of node sizes - makes it easier + order : output array of size N + + Runtime: Θ(N) + */ + auto_array_ptr queue(N/2); + + int parent; + int child; + t_index pos = 0; + + queue[0].pos = 0; + queue[0].node = N-2; + t_index idx = 1; + + do { + --idx; + pos = queue[idx].pos; + parent = queue[idx].node; + + // First child + child = merge[parent]; + if (child<0) { // singleton node, write this into the 'order' array. + order[pos] = -child; + ++pos; + } + else { /* compound node: put it on top of the queue and decompose it + in a later iteration. */ + queue[idx].pos = pos; + queue[idx].node = child-1; // convert index-1 based to index-0 based + ++idx; + pos += node_size[child-1]; + } + // Second child + child = merge[parent+N-1]; + if (child<0) { + order[pos] = -child; + } + else { + queue[idx].pos = pos; + queue[idx].node = child-1; + ++idx; + } + } while (idx>0); +} + +#define size_(r_) ( ((r_ +void generate_R_dendrogram(int * const merge, double * const height, int * const order, cluster_result & Z2, const int N) { + // The array "nodes" is a union-find data structure for the cluster + // identites (only needed for unsorted cluster_result input). + union_find nodes(sorted ? 0 : N); + if (!sorted) { + std::stable_sort(Z2[0], Z2[N-1]); + } + + t_index node1, node2; + auto_array_ptr node_size(N-1); + + for (t_index i=0; inode1; + node2 = Z2[i]->node2; + } + else { + node1 = nodes.Find(Z2[i]->node1); + node2 = nodes.Find(Z2[i]->node2); + // Merge the nodes in the union-find data structure by making them + // children of a new node. + nodes.Union(node1, node2); + } + // Sort the nodes in the output array. + if (node1>node2) { + t_index tmp = node1; + node1 = node2; + node2 = tmp; + } + /* Conversion between labeling conventions. + Input: singleton nodes 0,...,N-1 + compound nodes N,...,2N-2 + Output: singleton nodes -1,...,-N + compound nodes 1,...,N + */ + merge[i] = (node1(node1)-1 + : static_cast(node1)-N+1; + merge[i+N-1] = (node2(node2)-1 + : static_cast(node2)-N+1; + height[i] = Z2[i]->dist; + node_size[i] = size_(node1) + size_(node2); + } + + order_nodes(N, merge, node_size, order); +} diff --git a/selfdrive/controls/lib/cluster/fastcluster_dm.cpp b/selfdrive/controls/lib/cluster/fastcluster_dm.cpp new file mode 100644 index 00000000000000..8834bc24a04dd2 --- /dev/null +++ b/selfdrive/controls/lib/cluster/fastcluster_dm.cpp @@ -0,0 +1,1794 @@ +/* + fastcluster: Fast hierarchical clustering routines for R and Python + + Copyright © 2011 Daniel Müllner + + + This library implements various fast algorithms for hierarchical, + agglomerative clustering methods: + + (1) Algorithms for the "stored matrix approach": the input is the array of + pairwise dissimilarities. + + MST_linkage_core: single linkage clustering with the "minimum spanning + tree algorithm (Rohlfs) + + NN_chain_core: nearest-neighbor-chain algorithm, suitable for single, + complete, average, weighted and Ward linkage (Murtagh) + + generic_linkage: generic algorithm, suitable for all distance update + formulas (Müllner) + + (2) Algorithms for the "stored data approach": the input are points in a + vector space. + + MST_linkage_core_vector: single linkage clustering for vector data + + generic_linkage_vector: generic algorithm for vector data, suitable for + the Ward, centroid and median methods. + + generic_linkage_vector_alternative: alternative scheme for updating the + nearest neighbors. This method seems faster than "generic_linkage_vector" + for the centroid and median methods but slower for the Ward method. + + All these implementation treat infinity values correctly. They throw an + exception if a NaN distance value occurs. +*/ + +// Older versions of Microsoft Visual Studio do not have the fenv header. +#ifdef _MSC_VER +#if (_MSC_VER == 1500 || _MSC_VER == 1600) +#define NO_INCLUDE_FENV +#endif +#endif +// NaN detection via fenv might not work on systems with software +// floating-point emulation (bug report for Debian armel). +#ifdef __SOFTFP__ +#define NO_INCLUDE_FENV +#endif +#ifdef NO_INCLUDE_FENV +#pragma message("Do not use fenv header.") +#else +#pragma message("Use fenv header. If there is a warning about unknown #pragma STDC FENV_ACCESS, this can be ignored.") +#pragma STDC FENV_ACCESS on +#include +#endif + +#include // for std::pow, std::sqrt +#include // for std::ptrdiff_t +#include // for std::numeric_limits<...>::infinity() +#include // for std::fill_n +#include // for std::runtime_error +#include // for std::string + +#include // also for DBL_MAX, DBL_MIN +#ifndef DBL_MANT_DIG +#error The constant DBL_MANT_DIG could not be defined. +#endif +#define T_FLOAT_MANT_DIG DBL_MANT_DIG + +#ifndef LONG_MAX +#include +#endif +#ifndef LONG_MAX +#error The constant LONG_MAX could not be defined. +#endif +#ifndef INT_MAX +#error The constant INT_MAX could not be defined. +#endif + +#ifndef INT32_MAX +#ifdef _MSC_VER +#if _MSC_VER >= 1600 +#define __STDC_LIMIT_MACROS +#include +#else +typedef __int32 int_fast32_t; +typedef __int64 int64_t; +#endif +#else +#define __STDC_LIMIT_MACROS +#include +#endif +#endif + +#define FILL_N std::fill_n +#ifdef _MSC_VER +#if _MSC_VER < 1600 +#undef FILL_N +#define FILL_N stdext::unchecked_fill_n +#endif +#endif + +// Suppress warnings about (potentially) uninitialized variables. +#ifdef _MSC_VER + #pragma warning (disable:4700) +#endif + +#ifndef HAVE_DIAGNOSTIC +#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 6)) +#define HAVE_DIAGNOSTIC 1 +#endif +#endif + +#ifndef HAVE_VISIBILITY +#if __GNUC__ >= 4 +#define HAVE_VISIBILITY 1 +#endif +#endif + +/* Since the public interface is given by the Python respectively R interface, + * we do not want other symbols than the interface initalization routines to be + * visible in the shared object file. The "visibility" switch is a GCC concept. + * Hiding symbols keeps the relocation table small and decreases startup time. + * See http://gcc.gnu.org/wiki/Visibility + */ +#if HAVE_VISIBILITY +#pragma GCC visibility push(hidden) +#endif + +typedef int_fast32_t t_index; +#ifndef INT32_MAX +#define MAX_INDEX 0x7fffffffL +#else +#define MAX_INDEX INT32_MAX +#endif +#if (LONG_MAX < MAX_INDEX) +#error The integer format "t_index" must not have a greater range than "long int". +#endif +#if (INT_MAX > MAX_INDEX) +#error The integer format "int" must not have a greater range than "t_index". +#endif +typedef double t_float; + +/* Method codes. + + These codes must agree with the METHODS array in fastcluster.R and the + dictionary mthidx in fastcluster.py. +*/ +enum method_codes { + // non-Euclidean methods + METHOD_METR_SINGLE = 0, + METHOD_METR_COMPLETE = 1, + METHOD_METR_AVERAGE = 2, + METHOD_METR_WEIGHTED = 3, + METHOD_METR_WARD = 4, + METHOD_METR_WARD_D = METHOD_METR_WARD, + METHOD_METR_CENTROID = 5, + METHOD_METR_MEDIAN = 6, + METHOD_METR_WARD_D2 = 7, + + MIN_METHOD_CODE = 0, + MAX_METHOD_CODE = 7 +}; + +enum method_codes_vector { + // Euclidean methods + METHOD_VECTOR_SINGLE = 0, + METHOD_VECTOR_WARD = 1, + METHOD_VECTOR_CENTROID = 2, + METHOD_VECTOR_MEDIAN = 3, + + MIN_METHOD_VECTOR_CODE = 0, + MAX_METHOD_VECTOR_CODE = 3 +}; + +// self-destructing array pointer +template +class auto_array_ptr{ +private: + type * ptr; + auto_array_ptr(auto_array_ptr const &); // non construction-copyable + auto_array_ptr& operator=(auto_array_ptr const &); // non copyable +public: + auto_array_ptr() + : ptr(NULL) + { } + template + auto_array_ptr(index const size) + : ptr(new type[size]) + { } + template + auto_array_ptr(index const size, value const val) + : ptr(new type[size]) + { + FILL_N(ptr, size, val); + } + ~auto_array_ptr() { + delete [] ptr; } + void free() { + delete [] ptr; + ptr = NULL; + } + template + void init(index const size) { + ptr = new type [size]; + } + template + void init(index const size, value const val) { + init(size); + FILL_N(ptr, size, val); + } + inline operator type *() const { return ptr; } +}; + +struct node { + t_index node1, node2; + t_float dist; +}; + +inline bool operator< (const node a, const node b) { + return (a.dist < b.dist); +} + +class cluster_result { +private: + auto_array_ptr Z; + t_index pos; + +public: + cluster_result(const t_index size) + : Z(size) + , pos(0) + {} + + void append(const t_index node1, const t_index node2, const t_float dist) { + Z[pos].node1 = node1; + Z[pos].node2 = node2; + Z[pos].dist = dist; + ++pos; + } + + node * operator[] (const t_index idx) const { return Z + idx; } + + /* Define several methods to postprocess the distances. All these functions + are monotone, so they do not change the sorted order of distances. */ + + void sqrt() const { + for (node * ZZ=Z; ZZ!=Z+pos; ++ZZ) { + ZZ->dist = std::sqrt(ZZ->dist); + } + } + + void sqrt(const t_float) const { // ignore the argument + sqrt(); + } + + void sqrtdouble(const t_float) const { // ignore the argument + for (node * ZZ=Z; ZZ!=Z+pos; ++ZZ) { + ZZ->dist = std::sqrt(2*ZZ->dist); + } + } + + #ifdef R_pow + #define my_pow R_pow + #else + #define my_pow std::pow + #endif + + void power(const t_float p) const { + t_float const q = 1/p; + for (node * ZZ=Z; ZZ!=Z+pos; ++ZZ) { + ZZ->dist = my_pow(ZZ->dist,q); + } + } + + void plusone(const t_float) const { // ignore the argument + for (node * ZZ=Z; ZZ!=Z+pos; ++ZZ) { + ZZ->dist += 1; + } + } + + void divide(const t_float denom) const { + for (node * ZZ=Z; ZZ!=Z+pos; ++ZZ) { + ZZ->dist /= denom; + } + } +}; + +class doubly_linked_list { + /* + Class for a doubly linked list. Initially, the list is the integer range + [0, size]. We provide a forward iterator and a method to delete an index + from the list. + + Typical use: for (i=L.start; L succ; + +private: + auto_array_ptr pred; + // Not necessarily private, we just do not need it in this instance. + +public: + doubly_linked_list(const t_index size) + // Initialize to the given size. + : start(0) + , succ(size+1) + , pred(size+1) + { + for (t_index i=0; i(2*N-3-(r_))*(r_)>>1)+(c_)-1] ) +// Z is an ((N-1)x4)-array +#define Z_(_r, _c) (Z[(_r)*4 + (_c)]) + +/* + Lookup function for a union-find data structure. + + The function finds the root of idx by going iteratively through all + parent elements until a root is found. An element i is a root if + nodes[i] is zero. To make subsequent searches faster, the entry for + idx and all its parents is updated with the root element. + */ +class union_find { +private: + auto_array_ptr parent; + t_index nextparent; + +public: + union_find(const t_index size) + : parent(size>0 ? 2*size-1 : 0, 0) + , nextparent(size) + { } + + t_index Find (t_index idx) const { + if (parent[idx] != 0 ) { // a → b + t_index p = idx; + idx = parent[idx]; + if (parent[idx] != 0 ) { // a → b → c + do { + idx = parent[idx]; + } while (parent[idx] != 0); + do { + t_index tmp = parent[p]; + parent[p] = idx; + p = tmp; + } while (parent[p] != idx); + } + } + return idx; + } + + void Union (const t_index node1, const t_index node2) { + parent[node1] = parent[node2] = nextparent++; + } +}; + +class nan_error{}; +#ifdef FE_INVALID +class fenv_error{}; +#endif + +static void MST_linkage_core(const t_index N, const t_float * const D, + cluster_result & Z2) { +/* + N: integer, number of data points + D: condensed distance matrix N*(N-1)/2 + Z2: output data structure + + The basis of this algorithm is an algorithm by Rohlf: + + F. James Rohlf, Hierarchical clustering using the minimum spanning tree, + The Computer Journal, vol. 16, 1973, p. 93–95. +*/ + t_index i; + t_index idx2; + doubly_linked_list active_nodes(N); + auto_array_ptr d(N); + + t_index prev_node; + t_float min; + + // first iteration + idx2 = 1; + min = std::numeric_limits::infinity(); + for (i=1; i tmp) + d[i] = tmp; + else if (fc_isnan(tmp)) + throw (nan_error()); +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + if (d[i] < min) { + min = d[i]; + idx2 = i; + } + } + Z2.append(prev_node, idx2, min); + } +} + +/* Functions for the update of the dissimilarity array */ + +inline static void f_single( t_float * const b, const t_float a ) { + if (*b > a) *b = a; +} +inline static void f_complete( t_float * const b, const t_float a ) { + if (*b < a) *b = a; +} +inline static void f_average( t_float * const b, const t_float a, const t_float s, const t_float t) { + *b = s*a + t*(*b); + #ifndef FE_INVALID +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + if (fc_isnan(*b)) { + throw(nan_error()); + } +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + #endif +} +inline static void f_weighted( t_float * const b, const t_float a) { + *b = (a+*b)*.5; + #ifndef FE_INVALID +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + if (fc_isnan(*b)) { + throw(nan_error()); + } +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + #endif +} +inline static void f_ward( t_float * const b, const t_float a, const t_float c, const t_float s, const t_float t, const t_float v) { + *b = ( (v+s)*a - v*c + (v+t)*(*b) ) / (s+t+v); + //*b = a+(*b)-(t*a+s*(*b)+v*c)/(s+t+v); + #ifndef FE_INVALID +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + if (fc_isnan(*b)) { + throw(nan_error()); + } +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + #endif +} +inline static void f_centroid( t_float * const b, const t_float a, const t_float stc, const t_float s, const t_float t) { + *b = s*a - stc + t*(*b); + #ifndef FE_INVALID + if (fc_isnan(*b)) { + throw(nan_error()); + } +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + #endif +} +inline static void f_median( t_float * const b, const t_float a, const t_float c_4) { + *b = (a+(*b))*.5 - c_4; + #ifndef FE_INVALID +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + if (fc_isnan(*b)) { + throw(nan_error()); + } +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + #endif +} + +template +static void NN_chain_core(const t_index N, t_float * const D, t_members * const members, cluster_result & Z2) { +/* + N: integer + D: condensed distance matrix N*(N-1)/2 + Z2: output data structure + + This is the NN-chain algorithm, described on page 86 in the following book: + + Fionn Murtagh, Multidimensional Clustering Algorithms, + Vienna, Würzburg: Physica-Verlag, 1985. +*/ + t_index i; + + auto_array_ptr NN_chain(N); + t_index NN_chain_tip = 0; + + t_index idx1, idx2; + + t_float size1, size2; + doubly_linked_list active_nodes(N); + + t_float min; + + for (t_float const * DD=D; DD!=D+(static_cast(N)*(N-1)>>1); + ++DD) { +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + if (fc_isnan(*DD)) { + throw(nan_error()); + } +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + } + + #ifdef FE_INVALID + if (feclearexcept(FE_INVALID)) throw fenv_error(); + #endif + + for (t_index j=0; jidx2) { + t_index tmp = idx1; + idx1 = idx2; + idx2 = tmp; + } + + if (method==METHOD_METR_AVERAGE || + method==METHOD_METR_WARD) { + size1 = static_cast(members[idx1]); + size2 = static_cast(members[idx2]); + members[idx2] += members[idx1]; + } + + // Remove the smaller index from the valid indices (active_nodes). + active_nodes.remove(idx1); + + switch (method) { + case METHOD_METR_SINGLE: + /* + Single linkage. + + Characteristic: new distances are never longer than the old distances. + */ + // Update the distance matrix in the range [start, idx1). + for (i=active_nodes.start; i(members[i]); + for (i=active_nodes.start; i(members[i]) ); + // Update the distance matrix in the range (idx1, idx2). + for (; i(members[i]) ); + // Update the distance matrix in the range (idx2, N). + for (i=active_nodes.succ[idx2]; i(members[i]) ); + break; + + default: + throw std::runtime_error(std::string("Invalid method.")); + } + } + #ifdef FE_INVALID + if (fetestexcept(FE_INVALID)) throw fenv_error(); + #endif +} + +class binary_min_heap { + /* + Class for a binary min-heap. The data resides in an array A. The elements of + A are not changed but two lists I and R of indices are generated which point + to elements of A and backwards. + + The heap tree structure is + + H[2*i+1] H[2*i+2] + \ / + \ / + ≤ ≤ + \ / + \ / + H[i] + + where the children must be less or equal than their parent. Thus, H[0] + contains the minimum. The lists I and R are made such that H[i] = A[I[i]] + and R[I[i]] = i. + + This implementation is not designed to handle NaN values. + */ +private: + t_float * const A; + t_index size; + auto_array_ptr I; + auto_array_ptr R; + + // no default constructor + binary_min_heap(); + // noncopyable + binary_min_heap(binary_min_heap const &); + binary_min_heap & operator=(binary_min_heap const &); + +public: + binary_min_heap(t_float * const A_, const t_index size_) + : A(A_), size(size_), I(size), R(size) + { // Allocate memory and initialize the lists I and R to the identity. This + // does not make it a heap. Call heapify afterwards! + for (t_index i=0; i>1); idx>0; ) { + --idx; + update_geq_(idx); + } + } + + inline t_index argmin() const { + // Return the minimal element. + return I[0]; + } + + void heap_pop() { + // Remove the minimal element from the heap. + --size; + I[0] = I[size]; + R[I[0]] = 0; + update_geq_(0); + } + + void remove(t_index idx) { + // Remove an element from the heap. + --size; + R[I[size]] = R[idx]; + I[R[idx]] = I[size]; + if ( H(size)<=A[idx] ) { + update_leq_(R[idx]); + } + else { + update_geq_(R[idx]); + } + } + + void replace ( const t_index idxold, const t_index idxnew, + const t_float val) { + R[idxnew] = R[idxold]; + I[R[idxnew]] = idxnew; + if (val<=A[idxold]) + update_leq(idxnew, val); + else + update_geq(idxnew, val); + } + + void update ( const t_index idx, const t_float val ) const { + // Update the element A[i] with val and re-arrange the indices to preserve + // the heap condition. + if (val<=A[idx]) + update_leq(idx, val); + else + update_geq(idx, val); + } + + void update_leq ( const t_index idx, const t_float val ) const { + // Use this when the new value is not more than the old value. + A[idx] = val; + update_leq_(R[idx]); + } + + void update_geq ( const t_index idx, const t_float val ) const { + // Use this when the new value is not less than the old value. + A[idx] = val; + update_geq_(R[idx]); + } + +private: + void update_leq_ (t_index i) const { + t_index j; + for ( ; (i>0) && ( H(i)>1) ); i=j) + heap_swap(i,j); + } + + void update_geq_ (t_index i) const { + t_index j; + for ( ; (j=2*i+1)=H(i) ) { + ++j; + if ( j>=size || H(j)>=H(i) ) break; + } + else if ( j+1 +static void generic_linkage(const t_index N, t_float * const D, t_members * const members, cluster_result & Z2) { + /* + N: integer, number of data points + D: condensed distance matrix N*(N-1)/2 + Z2: output data structure + */ + + const t_index N_1 = N-1; + t_index i, j; // loop variables + t_index idx1, idx2; // row and column indices + + auto_array_ptr n_nghbr(N_1); // array of nearest neighbors + auto_array_ptr mindist(N_1); // distances to the nearest neighbors + auto_array_ptr row_repr(N); // row_repr[i]: node number that the + // i-th row represents + doubly_linked_list active_nodes(N); + binary_min_heap nn_distances(&*mindist, N_1); // minimum heap structure for + // the distance to the nearest neighbor of each point + t_index node1, node2; // node numbers in the output + t_float size1, size2; // and their cardinalities + + t_float min; // minimum and row index for nearest-neighbor search + t_index idx; + + for (i=0; ii} D(i,j) for i in range(N-1) + t_float const * DD = D; + for (i=0; i::infinity(); + for (idx=j=i+1; ji} D(i,j) + + Normally, we have equality. However, this minimum may become invalid due + to the updates in the distance matrix. The rules are: + + 1) If mindist[i] is equal to D(i, n_nghbr[i]), this is the correct + minimum and n_nghbr[i] is a nearest neighbor. + + 2) If mindist[i] is smaller than D(i, n_nghbr[i]), this might not be the + correct minimum. The minimum needs to be recomputed. + + 3) mindist[i] is never bigger than the true minimum. Hence, we never + miss the true minimum if we take the smallest mindist entry, + re-compute the value if necessary (thus maybe increasing it) and + looking for the now smallest mindist entry until a valid minimal + entry is found. This step is done in the lines below. + + The update process for D below takes care that these rules are + fulfilled. This makes sure that the minima in the rows D(i,i+1:)of D are + re-calculated when necessary but re-calculation is avoided whenever + possible. + + The re-calculation of the minima makes the worst-case runtime of this + algorithm cubic in N. We avoid this whenever possible, and in most cases + the runtime appears to be quadratic. + */ + idx1 = nn_distances.argmin(); + if (method != METHOD_METR_SINGLE) { + while ( mindist[idx1] < D_(idx1, n_nghbr[idx1]) ) { + // Recompute the minimum mindist[idx1] and n_nghbr[idx1]. + n_nghbr[idx1] = j = active_nodes.succ[idx1]; // exists, maximally N-1 + min = D_(idx1,j); + for (j=active_nodes.succ[j]; j(members[idx1]); + size2 = static_cast(members[idx2]); + members[idx2] += members[idx1]; + } + Z2.append(node1, node2, mindist[idx1]); + + // Remove idx1 from the list of active indices (active_nodes). + active_nodes.remove(idx1); + // Index idx2 now represents the new (merged) node with label N+i. + row_repr[idx2] = N+i; + + // Update the distance matrix + switch (method) { + case METHOD_METR_SINGLE: + /* + Single linkage. + + Characteristic: new distances are never longer than the old distances. + */ + // Update the distance matrix in the range [start, idx1). + for (j=active_nodes.start; j(members[j]) ); + if (n_nghbr[j] == idx1) + n_nghbr[j] = idx2; + } + // Update the distance matrix in the range (idx1, idx2). + for (; j(members[j]) ); + if (D_(j, idx2) < mindist[j]) { + nn_distances.update_leq(j, D_(j, idx2)); + n_nghbr[j] = idx2; + } + } + // Update the distance matrix in the range (idx2, N). + if (idx2(members[j]) ); + min = D_(idx2,j); + for (j=active_nodes.succ[j]; j(members[j]) ); + if (D_(idx2,j) < min) { + min = D_(idx2,j); + n_nghbr[idx2] = j; + } + } + nn_distances.update(idx2, min); + } + break; + + case METHOD_METR_CENTROID: { + /* + Centroid linkage. + + Shorter and longer distances can occur, not bigger than max(d1,d2) + but maybe smaller than min(d1,d2). + */ + // Update the distance matrix in the range [start, idx1). + t_float s = size1/(size1+size2); + t_float t = size2/(size1+size2); + t_float stc = s*t*mindist[idx1]; + for (j=active_nodes.start; j +static void MST_linkage_core_vector(const t_index N, + t_dissimilarity & dist, + cluster_result & Z2) { +/* + N: integer, number of data points + dist: function pointer to the metric + Z2: output data structure + + The basis of this algorithm is an algorithm by Rohlf: + + F. James Rohlf, Hierarchical clustering using the minimum spanning tree, + The Computer Journal, vol. 16, 1973, p. 93–95. +*/ + t_index i; + t_index idx2; + doubly_linked_list active_nodes(N); + auto_array_ptr d(N); + + t_index prev_node; + t_float min; + + // first iteration + idx2 = 1; + min = std::numeric_limits::infinity(); + for (i=1; i tmp) + d[i] = tmp; + else if (fc_isnan(tmp)) + throw (nan_error()); +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + if (d[i] < min) { + min = d[i]; + idx2 = i; + } + } + Z2.append(prev_node, idx2, min); + } +} + +template +static void generic_linkage_vector(const t_index N, + t_dissimilarity & dist, + cluster_result & Z2) { + /* + N: integer, number of data points + dist: function pointer to the metric + Z2: output data structure + + This algorithm is valid for the distance update methods + "Ward", "centroid" and "median" only! + */ + const t_index N_1 = N-1; + t_index i, j; // loop variables + t_index idx1, idx2; // row and column indices + + auto_array_ptr n_nghbr(N_1); // array of nearest neighbors + auto_array_ptr mindist(N_1); // distances to the nearest neighbors + auto_array_ptr row_repr(N); // row_repr[i]: node number that the + // i-th row represents + doubly_linked_list active_nodes(N); + binary_min_heap nn_distances(&*mindist, N_1); // minimum heap structure for + // the distance to the nearest neighbor of each point + t_index node1, node2; // node numbers in the output + t_float min; // minimum and row index for nearest-neighbor search + + for (i=0; ii} D(i,j) for i in range(N-1) + for (i=0; i::infinity(); + t_index idx; + for (idx=j=i+1; j(i,j); + } + if (tmp(idx1,j); + for (j=active_nodes.succ[j]; j(idx1,j); + if (tmp(j, idx2); + if (tmp < mindist[j]) { + nn_distances.update_leq(j, tmp); + n_nghbr[j] = idx2; + } + else if (n_nghbr[j] == idx2) + n_nghbr[j] = idx1; // invalidate + } + // Find the nearest neighbor for idx2. + if (idx2(idx2,j); + for (j=active_nodes.succ[j]; j(idx2, j); + if (tmp < min) { + min = tmp; + n_nghbr[idx2] = j; + } + } + nn_distances.update(idx2, min); + } + } + } +} + +template +static void generic_linkage_vector_alternative(const t_index N, + t_dissimilarity & dist, + cluster_result & Z2) { + /* + N: integer, number of data points + dist: function pointer to the metric + Z2: output data structure + + This algorithm is valid for the distance update methods + "Ward", "centroid" and "median" only! + */ + const t_index N_1 = N-1; + t_index i, j=0; // loop variables + t_index idx1, idx2; // row and column indices + + auto_array_ptr n_nghbr(2*N-2); // array of nearest neighbors + auto_array_ptr mindist(2*N-2); // distances to the nearest neighbors + + doubly_linked_list active_nodes(N+N_1); + binary_min_heap nn_distances(&*mindist, N_1, 2*N-2, 1); // minimum heap + // structure for the distance to the nearest neighbor of each point + + t_float min; // minimum for nearest-neighbor searches + + // Initialize the minimal distances: + // Find the nearest neighbor of each point. + // n_nghbr[i] = argmin_{j>i} D(i,j) for i in range(N-1) + for (i=1; i::infinity(); + t_index idx; + for (idx=j=0; j(i,j); + } + if (tmp + +extern "C" { +#include "fastcluster.h" +} + + +int main(int argc, const char* argv[]){ + const int n = 11; + const int m = 3; + double* pts = new double[n*m]{59.26000137, -9.35999966, -5.42500019, + 91.61999817, -0.31999999, -2.75, + 31.38000031, 0.40000001, -0.2, + 89.57999725, -8.07999992, -18.04999924, + 53.42000122, 0.63999999, -0.175, + 31.38000031, 0.47999999, -0.2, + 36.33999939, 0.16, -0.2, + 53.33999939, 0.95999998, -0.175, + 59.26000137, -9.76000023, -5.44999981, + 33.93999977, 0.40000001, -0.22499999, + 106.74000092, -5.76000023, -18.04999924}; + + int * idx = new int[n]; + int * correct_idx = new int[n]{0, 1, 2, 3, 4, 2, 5, 4, 0, 5, 6}; + + cluster_points_centroid(n, m, pts, 2.5 * 2.5, idx); + + for (int i = 0; i < n; i++){ + assert(idx[i] == correct_idx[i]); + } + + delete[] idx; + delete[] correct_idx; + delete[] pts; +} diff --git a/selfdrive/controls/lib/drive_helpers.py b/selfdrive/controls/lib/drive_helpers.py index 15d5a202f74c4d..a3580a8a91b24a 100644 --- a/selfdrive/controls/lib/drive_helpers.py +++ b/selfdrive/controls/lib/drive_helpers.py @@ -1,5 +1,5 @@ from cereal import car -from common.numpy_fast import clip +from common.numpy_fast import clip, interp from selfdrive.config import Conversions as CV # kph @@ -55,24 +55,8 @@ def rate_limit(new_value, last_value, dw_step, up_step): return clip(new_value, last_value + dw_step, last_value + up_step) -def learn_angle_model_bias(lateral_control, v_ego, angle_model_bias, c_poly, c_prob, angle_steers, steer_override): - # simple integral controller that learns how much steering offset to put to have the car going straight - # while being in the middle of the lane - min_offset = -5. # deg - max_offset = 5. # deg - alpha = 1. / 36000. # correct by 1 deg in 2 mins, at 30m/s, with 50cm of error, at 20Hz - min_learn_speed = 1. - - # learn less at low speed or when turning - slow_factor = 1. / (1. + 0.02 * abs(angle_steers) * v_ego) - alpha_v = alpha * c_prob * (max(v_ego - min_learn_speed, 0.)) * slow_factor - - # only learn if lateral control is active and if driver is not overriding: - if lateral_control and not steer_override: - angle_model_bias += c_poly[3] * alpha_v - angle_model_bias = clip(angle_model_bias, min_offset, max_offset) - - return angle_model_bias +def get_steer_max(CP, v_ego): + return interp(v_ego, CP.steerMaxBP, CP.steerMaxV) def update_v_cruise(v_cruise_kph, buttonEvents, enabled): diff --git a/selfdrive/controls/lib/driver_monitor.py b/selfdrive/controls/lib/driver_monitor.py index 10e0e0be66131b..9e94c4fe623ba1 100644 --- a/selfdrive/controls/lib/driver_monitor.py +++ b/selfdrive/controls/lib/driver_monitor.py @@ -1,149 +1,216 @@ import numpy as np -from common.realtime import sec_since_boot +from common.realtime import DT_CTRL, DT_DMON from selfdrive.controls.lib.drive_helpers import create_event, EventTypes as ET from common.filter_simple import FirstOrderFilter +from common.stat_live import RunningStatFilter + +_AWARENESS_TIME = 100. # 1.6 minutes limit without user touching steering wheels make the car enter a terminal status +_AWARENESS_PRE_TIME_TILL_TERMINAL = 25. # a first alert is issued 25s before expiration +_AWARENESS_PROMPT_TIME_TILL_TERMINAL = 15. # a second alert is issued 15s before start decelerating the car +_DISTRACTED_TIME = 11. +_DISTRACTED_PRE_TIME_TILL_TERMINAL = 8. +_DISTRACTED_PROMPT_TIME_TILL_TERMINAL = 6. + +_FACE_THRESHOLD = 0.4 +_EYE_THRESHOLD = 0.4 +_BLINK_THRESHOLD = 0.5 # 0.225 +_PITCH_WEIGHT = 1.35 # 1.5 # pitch matters a lot more +_METRIC_THRESHOLD = 0.4 +_PITCH_POS_ALLOWANCE = 0.04 # 0.08 # rad, to not be too sensitive on positive pitch +_PITCH_NATURAL_OFFSET = 0.12 # 0.1 # people don't seem to look straight when they drive relaxed, rather a bit up +_YAW_NATURAL_OFFSET = 0.08 # people don't seem to look straight when they drive relaxed, rather a bit to the right (center of car) + +_DISTRACTED_FILTER_TS = 0.25 # 0.6Hz + +_POSE_CALIB_MIN_SPEED = 13 # 30 mph +_POSE_OFFSET_MIN_COUNT = 600 # valid data counts before calibration completes, 1 seg is 600 counts +_POSE_OFFSET_MAX_COUNT = 3600 # stop deweighting new data after 6 min, aka "short term memory" + +_RECOVERY_FACTOR_MAX = 5. # relative to minus step change +_RECOVERY_FACTOR_MIN = 1.25 # relative to minus step change + +MAX_TERMINAL_ALERTS = 3 # not allowed to engage after 3 terminal alerts -_DT = 0.01 # update runs at 100Hz -_DTM = 0.1 # DM runs at 10Hz -_AWARENESS_TIME = 180 # 3 minutes limit without user touching steering wheels make the car enter a terminal status -_AWARENESS_PRE_TIME = 20. # a first alert is issued 20s before expiration -_AWARENESS_PROMPT_TIME = 5. # a second alert is issued 5s before start decelerating the car -_DISTRACTED_TIME = 7. -_DISTRACTED_PRE_TIME = 4. -_DISTRACTED_PROMPT_TIME = 2. -# measured 1 rad in x FOV. 1152x864 is original image, 160x320 is a right crop for model -_CAMERA_FOV_X = 1. # rad -_CAMERA_FOV_Y = 0.75 # 4/3 aspect ratio # model output refers to center of cropped image, so need to apply the x displacement offset -_CAMERA_OFFSET_X = 0.3125 #(1152/2 - 0.5*(160*864/320))/1152 -_CAMERA_X_CONV = 0.375 # 160*864/320/1152 -_PITCH_WEIGHT = 1.5 # pitch matters a lot more -_METRIC_THRESHOLD = 0.4 -_PITCH_POS_ALLOWANCE = 0.08 # rad, to not be too sensitive on positive pitch -_PITCH_NATURAL_OFFSET = 0.1 # people don't seem to look straight when they drive relaxed, rather a bit up -_STD_THRESHOLD = 0.1 # above this standard deviation consider the measurement invalid -_DISTRACTED_FILTER_TS = 0.25 # 0.6Hz -_VARIANCE_FILTER_TS = 20. # 0.008Hz +RESIZED_FOCAL = 320.0 +H, W, FULL_W = 320, 160, 426 + +class DistractedType(): + NOT_DISTRACTED = 0 + BAD_POSE = 1 + BAD_BLINK = 2 +def head_orientation_from_descriptor(angles_desc, pos_desc, rpy_calib): + # the output of these angles are in device frame + # so from driver's perspective, pitch is up and yaw is right -class _DriverPose(): + pitch_prnet = angles_desc[0] + yaw_prnet = angles_desc[1] + roll_prnet = angles_desc[2] + + face_pixel_position = ((pos_desc[0] + .5)*W - W + FULL_W, (pos_desc[1]+.5)*H) + yaw_focal_angle = np.arctan2(face_pixel_position[0] - FULL_W//2, RESIZED_FOCAL) + pitch_focal_angle = np.arctan2(face_pixel_position[1] - H//2, RESIZED_FOCAL) + + roll = roll_prnet + pitch = pitch_prnet + pitch_focal_angle + yaw = -yaw_prnet + yaw_focal_angle + + # no calib for roll + pitch -= rpy_calib[1] + yaw -= rpy_calib[2] + return np.array([roll, pitch, yaw]) + +class DriverPose(): def __init__(self): self.yaw = 0. self.pitch = 0. self.roll = 0. - self.yaw_offset = 0. - self.pitch_offset = 0. + self.pitch_offseter = RunningStatFilter(max_trackable=_POSE_OFFSET_MAX_COUNT) + self.yaw_offseter = RunningStatFilter(max_trackable=_POSE_OFFSET_MAX_COUNT) -def _monitor_hysteresys(variance_level, monitor_valid_prev): - var_thr = 0.63 if monitor_valid_prev else 0.37 - return variance_level < var_thr +class DriverBlink(): + def __init__(self): + self.left_blink = 0. + self.right_blink = 0. class DriverStatus(): - def __init__(self, monitor_on=False): - self.pose = _DriverPose() - self.monitor_on = monitor_on - self.monitor_param_on = monitor_on - self.monitor_valid = True # variance needs to be low + def __init__(self): + self.pose = DriverPose() + self.pose_calibrated = self.pose.pitch_offseter.filtered_stat.n > _POSE_OFFSET_MIN_COUNT and \ + self.pose.yaw_offseter.filtered_stat.n > _POSE_OFFSET_MIN_COUNT + self.blink = DriverBlink() self.awareness = 1. + self.awareness_active = 1. + self.awareness_passive = 1. self.driver_distracted = False - self.driver_distraction_filter = FirstOrderFilter(0., _DISTRACTED_FILTER_TS, _DTM) - self.variance_high = False - self.variance_filter = FirstOrderFilter(0., _VARIANCE_FILTER_TS, _DTM) - self.ts_last_check = 0. - self._set_timers() - - def _reset_filters(self): - self.driver_distraction_filter.x = 0. - self.variance_filter.x = 0. - self.monitor_valid = True - - def _set_timers(self): - if self.monitor_on: - self.threshold_pre = _DISTRACTED_PRE_TIME / _DISTRACTED_TIME - self.threshold_prompt = _DISTRACTED_PROMPT_TIME / _DISTRACTED_TIME - self.step_change = _DT / _DISTRACTED_TIME + self.driver_distraction_filter = FirstOrderFilter(0., _DISTRACTED_FILTER_TS, DT_DMON) + self.face_detected = False + self.terminal_alert_cnt = 0 + self.step_change = 0. + self.active_monitoring_mode = True + self.threshold_prompt = _DISTRACTED_PROMPT_TIME_TILL_TERMINAL / _DISTRACTED_TIME + + self.is_rhd_region = False + self.is_rhd_region_checked = False + + self._set_timers(active_monitoring=True) + + def _set_timers(self, active_monitoring): + if self.active_monitoring_mode and self.awareness <= self.threshold_prompt: + if active_monitoring: + self.step_change = DT_CTRL / _DISTRACTED_TIME + else: + self.step_change = 0. + return # no exploit after orange alert + elif self.awareness <= 0.: + return + + if active_monitoring: + # when falling back from passive mode to active mode, reset awareness to avoid false alert + if not self.active_monitoring_mode: + self.awareness_passive = self.awareness + self.awareness = self.awareness_active + + self.threshold_pre = _DISTRACTED_PRE_TIME_TILL_TERMINAL / _DISTRACTED_TIME + self.threshold_prompt = _DISTRACTED_PROMPT_TIME_TILL_TERMINAL / _DISTRACTED_TIME + self.step_change = DT_CTRL / _DISTRACTED_TIME + self.active_monitoring_mode = True else: - self.threshold_pre = _AWARENESS_PRE_TIME / _AWARENESS_TIME - self.threshold_prompt = _AWARENESS_PROMPT_TIME / _AWARENESS_TIME - self.step_change = _DT / _AWARENESS_TIME - - def _is_driver_distracted(self, pose): - # to be tuned and to learn the driver's normal pose - yaw_error = pose.yaw - pose.yaw_offset - pitch_error = pose.pitch - pose.pitch_offset - _PITCH_NATURAL_OFFSET - # add positive pitch allowance - if pitch_error > 0.: - pitch_error = max(pitch_error - _PITCH_POS_ALLOWANCE, 0.) + if self.active_monitoring_mode: + self.awareness_active = self.awareness + self.awareness = self.awareness_passive + + self.threshold_pre = _AWARENESS_PRE_TIME_TILL_TERMINAL / _AWARENESS_TIME + self.threshold_prompt = _AWARENESS_PROMPT_TIME_TILL_TERMINAL / _AWARENESS_TIME + self.step_change = DT_CTRL / _AWARENESS_TIME + self.active_monitoring_mode = False + + def _is_driver_distracted(self, pose, blink): + if not self.pose_calibrated: + pitch_error = pose.pitch - _PITCH_NATURAL_OFFSET + yaw_error = pose.yaw - _YAW_NATURAL_OFFSET + # add positive pitch allowance + if pitch_error > 0.: + pitch_error = max(pitch_error - _PITCH_POS_ALLOWANCE, 0.) + else: + pitch_error = pose.pitch - self.pose.pitch_offseter.filtered_stat.mean() + yaw_error = pose.yaw - self.pose.yaw_offseter.filtered_stat.mean() + pitch_error *= _PITCH_WEIGHT - metric = np.sqrt(yaw_error**2 + pitch_error**2) - #print "%02.4f" % np.degrees(pose.pitch), "%02.4f" % np.degrees(pitch_error), "%03.4f" % np.degrees(pose.pitch_offset), metric - return 1 if metric > _METRIC_THRESHOLD else 0 + pose_metric = np.sqrt(yaw_error**2 + pitch_error**2) + + if pose_metric > _METRIC_THRESHOLD: + return DistractedType.BAD_POSE + elif (blink.left_blink + blink.right_blink)*0.5 > _BLINK_THRESHOLD: + return DistractedType.BAD_BLINK + else: + return DistractedType.NOT_DISTRACTED + def get_pose(self, driver_monitoring, cal_rpy, car_speed, op_engaged): + # 10 Hz + if len(driver_monitoring.faceOrientation) == 0 or len(driver_monitoring.facePosition) == 0: + return - def get_pose(self, driver_monitoring, params): + self.pose.roll, self.pose.pitch, self.pose.yaw = head_orientation_from_descriptor(driver_monitoring.faceOrientation, driver_monitoring.facePosition, cal_rpy) + self.blink.left_blink = driver_monitoring.leftBlinkProb * (driver_monitoring.leftEyeProb>_EYE_THRESHOLD) + self.blink.right_blink = driver_monitoring.rightBlinkProb * (driver_monitoring.rightEyeProb>_EYE_THRESHOLD) + self.face_detected = driver_monitoring.faceProb > _FACE_THRESHOLD and not self.is_rhd_region - self.pose.pitch = driver_monitoring.descriptor[0] - self.pose.yaw = driver_monitoring.descriptor[1] - self.pose.roll = driver_monitoring.descriptor[2] - self.pose.yaw_offset = (driver_monitoring.descriptor[3] * _CAMERA_X_CONV + _CAMERA_OFFSET_X) * _CAMERA_FOV_X - self.pose.pitch_offset = -driver_monitoring.descriptor[4] * _CAMERA_FOV_Y # positive y is down - self.driver_distracted = self._is_driver_distracted(self.pose) + self.driver_distracted = self._is_driver_distracted(self.pose, self.blink)>0 # first order filters self.driver_distraction_filter.update(self.driver_distracted) - self.variance_high = driver_monitoring.std > _STD_THRESHOLD - self.variance_filter.update(self.variance_high) - - monitor_param_on_prev = self.monitor_param_on - monitor_valid_prev = self.monitor_valid - # don't check for param too often as it's a kernel call - ts = sec_since_boot() - if ts - self.ts_last_check > 1.: - self.monitor_param_on = params.get("IsDriverMonitoringEnabled") == "1" - self.ts_last_check = ts + # update offseter + # only update when driver is actively driving the car above a certain speed + if self.face_detected and car_speed>_POSE_CALIB_MIN_SPEED and not op_engaged: + self.pose.pitch_offseter.push_and_update(self.pose.pitch) + self.pose.yaw_offseter.push_and_update(self.pose.yaw) - self.monitor_valid = _monitor_hysteresys(self.variance_filter.x, monitor_valid_prev) - self.monitor_on = self.monitor_valid and self.monitor_param_on - if monitor_param_on_prev != self.monitor_param_on: - self._reset_filters() - self._set_timers() + self.pose_calibrated = self.pose.pitch_offseter.filtered_stat.n > _POSE_OFFSET_MIN_COUNT and \ + self.pose.yaw_offseter.filtered_stat.n > _POSE_OFFSET_MIN_COUNT + self._set_timers(self.face_detected) def update(self, events, driver_engaged, ctrl_active, standstill): - - driver_engaged |= (self.driver_distraction_filter.x < 0.37 and self.monitor_on) - - if (driver_engaged and self.awareness > 0.) or not ctrl_active: - # always reset if driver is in control (unless we are in red alert state) or op isn't active + if (driver_engaged and self.awareness > 0) or not ctrl_active: + # reset only when on disengagement if red reached self.awareness = 1. - - if (not self.monitor_on or (self.driver_distraction_filter.x > 0.63 and self.driver_distracted)) and \ + self.awareness_active = 1. + self.awareness_passive = 1. + return events + + driver_attentive = self.driver_distraction_filter.x < 0.37 + awareness_prev = self.awareness + + if (driver_attentive and self.face_detected and self.awareness > 0): + # only restore awareness when paying attention and alert is not red + self.awareness = min(self.awareness + ((_RECOVERY_FACTOR_MAX-_RECOVERY_FACTOR_MIN)*(1.-self.awareness)+_RECOVERY_FACTOR_MIN)*self.step_change, 1.) + if self.awareness == 1.: + self.awareness_passive = min(self.awareness_passive + self.step_change, 1.) + # don't display alert banner when awareness is recovering and has cleared orange + if self.awareness > self.threshold_prompt: + return events + + # should always be counting if distracted unless at standstill and reaching orange + if (not self.face_detected or (self.driver_distraction_filter.x > 0.63 and self.driver_distracted and self.face_detected)) and \ not (standstill and self.awareness - self.step_change <= self.threshold_prompt): self.awareness = max(self.awareness - self.step_change, -0.1) alert = None if self.awareness <= 0.: # terminal red alert: disengagement required - alert = 'driverDistracted' if self.monitor_on else 'driverUnresponsive' + alert = 'driverDistracted' if self.active_monitoring_mode else 'driverUnresponsive' + if awareness_prev > 0.: + self.terminal_alert_cnt += 1 elif self.awareness <= self.threshold_prompt: # prompt orange alert - alert = 'promptDriverDistracted' if self.monitor_on else 'promptDriverUnresponsive' + alert = 'promptDriverDistracted' if self.active_monitoring_mode else 'promptDriverUnresponsive' elif self.awareness <= self.threshold_pre: # pre green alert - alert = 'preDriverDistracted' if self.monitor_on else 'preDriverUnresponsive' + alert = 'preDriverDistracted' if self.active_monitoring_mode else 'preDriverUnresponsive' + if alert is not None: events.append(create_event(alert, [ET.WARNING])) return events - - -if __name__ == "__main__": - ds = DriverStatus(True) - ds.driver_distraction_filter.x = 0. - ds.driver_distracted = 1 - for i in range(10): - ds.update([], False, True, False) - print(ds.awareness, ds.driver_distracted, ds.driver_distraction_filter.x) - ds.update([], True, True, False) - print(ds.awareness, ds.driver_distracted, ds.driver_distraction_filter.x) - diff --git a/selfdrive/controls/lib/fcw.py b/selfdrive/controls/lib/fcw.py index f93a72cfcce321..93570a41dbf821 100644 --- a/selfdrive/controls/lib/fcw.py +++ b/selfdrive/controls/lib/fcw.py @@ -7,7 +7,7 @@ _FCW_A_ACT_BP = [0., 30.] -class FCWChecker(object): +class FCWChecker(): def __init__(self): self.reset_lead(0.0) @@ -43,8 +43,9 @@ def calc_ttc(v_ego, a_ego, x_lead, v_lead, a_lead): ttc = np.minimum(2 * x_lead / (np.sqrt(delta) + v_rel), max_ttc) return ttc - def update(self, mpc_solution, cur_time, v_ego, a_ego, x_lead, v_lead, a_lead, y_lead, vlat_lead, fcw_lead, blinkers): + def update(self, mpc_solution, cur_time, active, v_ego, a_ego, x_lead, v_lead, a_lead, y_lead, vlat_lead, fcw_lead, blinkers): mpc_solution_a = list(mpc_solution[0].a_ego) + self.last_min_a = min(mpc_solution_a) self.v_lead_max = max(self.v_lead_max, v_lead) @@ -62,8 +63,10 @@ def update(self, mpc_solution, cur_time, v_ego, a_ego, x_lead, v_lead, a_lead, y a_thr = interp(v_lead, _FCW_A_ACT_BP, _FCW_A_ACT_V) a_delta = min(mpc_solution_a[:15]) - min(0.0, a_ego) - fcw_allowed = all(c >= 10 for c in self.counters.values()) - if (self.last_min_a < -3.0 or a_delta < a_thr) and fcw_allowed and self.last_fcw_time + 5.0 < cur_time: + future_fcw_allowed = all(c >= 10 for c in self.counters.values()) + future_fcw = (self.last_min_a < -3.0 or a_delta < a_thr) and future_fcw_allowed + + if future_fcw and (self.last_fcw_time + 5.0 < cur_time): self.last_fcw_time = cur_time self.last_fcw_a = self.last_min_a return True diff --git a/selfdrive/controls/lib/gps_helpers.py b/selfdrive/controls/lib/gps_helpers.py new file mode 100755 index 00000000000000..6ac27202d877a7 --- /dev/null +++ b/selfdrive/controls/lib/gps_helpers.py @@ -0,0 +1,17 @@ +_RHD_REGION_MAP = [ ['AUS', -54.76, -9.23, 112.91, 159.11], \ + ['IN1', 6.75, 28.10, 68.17, 97.4], \ + ['IN2', 28.09, 35.99, 72.18, 80.87], \ + ['IRL', 51.42, 55.38, -10.58, -5.99], \ + ['JP1', 32.66, 45.52, 137.27, 146.02], \ + ['JP2', 32.79, 37.60, 131.41, 137.28], \ + ['JP3', 24.04, 34.78, 122.93, 131.42], \ + ['NZ', -52.61, -29.24, 166, 178.84], \ + ['SF', -35.14, -22.13, 16.07, 33.21], \ + ['UK', 49.9, 60.84, -8.62, 1.77] ] + +def is_rhd_region(latitude, longitude): + for region in _RHD_REGION_MAP: + if region[1] <= latitude <= region[2] and \ + region[3] <= longitude <= region[4]: + return True + return False diff --git a/selfdrive/controls/lib/lane_planner.py b/selfdrive/controls/lib/lane_planner.py new file mode 100644 index 00000000000000..7dde666c9e1812 --- /dev/null +++ b/selfdrive/controls/lib/lane_planner.py @@ -0,0 +1,81 @@ +from common.numpy_fast import interp +import numpy as np + +CAMERA_OFFSET = 0.06 # m from center car to camera + +def compute_path_pinv(l=50): + deg = 3 + x = np.arange(l*1.0) + X = np.vstack(tuple(x**n for n in range(deg, -1, -1))).T + pinv = np.linalg.pinv(X) + return pinv + + +def model_polyfit(points, path_pinv): + return np.dot(path_pinv, [float(x) for x in points]) + + +def calc_d_poly(l_poly, r_poly, p_poly, l_prob, r_prob, lane_width): + # This will improve behaviour when lanes suddenly widen + lane_width = min(4.0, lane_width) + l_prob = l_prob * interp(abs(l_poly[3]), [2, 2.5], [1.0, 0.0]) + r_prob = r_prob * interp(abs(r_poly[3]), [2, 2.5], [1.0, 0.0]) + + path_from_left_lane = l_poly.copy() + path_from_left_lane[3] -= lane_width / 2.0 + path_from_right_lane = r_poly.copy() + path_from_right_lane[3] += lane_width / 2.0 + + lr_prob = l_prob + r_prob - l_prob * r_prob + + d_poly_lane = (l_prob * path_from_left_lane + r_prob * path_from_right_lane) / (l_prob + r_prob + 0.0001) + return lr_prob * d_poly_lane + (1.0 - lr_prob) * p_poly + + +class LanePlanner(): + def __init__(self): + self.l_poly = [0., 0., 0., 0.] + self.r_poly = [0., 0., 0., 0.] + self.p_poly = [0., 0., 0., 0.] + self.d_poly = [0., 0., 0., 0.] + + self.lane_width_estimate = 3.7 + self.lane_width_certainty = 1.0 + self.lane_width = 3.7 + + self.l_prob = 0. + self.r_prob = 0. + + self._path_pinv = compute_path_pinv() + self.x_points = np.arange(50) + + def parse_model(self, md): + if len(md.leftLane.poly): + self.l_poly = np.array(md.leftLane.poly) + self.r_poly = np.array(md.rightLane.poly) + self.p_poly = np.array(md.path.poly) + else: + self.l_poly = model_polyfit(md.leftLane.points, self._path_pinv) # left line + self.r_poly = model_polyfit(md.rightLane.points, self._path_pinv) # right line + self.p_poly = model_polyfit(md.path.points, self._path_pinv) # predicted path + self.l_prob = md.leftLane.prob # left line prob + self.r_prob = md.rightLane.prob # right line prob + + def update_lane(self, v_ego): + # only offset left and right lane lines; offsetting p_poly does not make sense + self.l_poly[3] += CAMERA_OFFSET + self.r_poly[3] += CAMERA_OFFSET + + # Find current lanewidth + self.lane_width_certainty += 0.05 * (self.l_prob * self.r_prob - self.lane_width_certainty) + current_lane_width = abs(self.l_poly[3] - self.r_poly[3]) + self.lane_width_estimate += 0.005 * (current_lane_width - self.lane_width_estimate) + speed_lane_width = interp(v_ego, [0., 31.], [2.8, 3.5]) + self.lane_width = self.lane_width_certainty * self.lane_width_estimate + \ + (1 - self.lane_width_certainty) * speed_lane_width + + self.d_poly = calc_d_poly(self.l_poly, self.r_poly, self.p_poly, self.l_prob, self.r_prob, self.lane_width) + + def update(self, v_ego, md): + self.parse_model(md) + self.update_lane(v_ego) diff --git a/selfdrive/controls/lib/latcontrol.py b/selfdrive/controls/lib/latcontrol.py deleted file mode 100644 index 69494387083414..00000000000000 --- a/selfdrive/controls/lib/latcontrol.py +++ /dev/null @@ -1,48 +0,0 @@ -from selfdrive.controls.lib.pid import PIController -from common.numpy_fast import interp -from cereal import car - -_DT = 0.01 # 100Hz -_DT_MPC = 0.05 # 20Hz - - -def get_steer_max(CP, v_ego): - return interp(v_ego, CP.steerMaxBP, CP.steerMaxV) - - -class LatControl(object): - def __init__(self, CP): - self.pid = PIController((CP.steerKpBP, CP.steerKpV), - (CP.steerKiBP, CP.steerKiV), - k_f=CP.steerKf, pos_limit=1.0) - self.last_cloudlog_t = 0.0 - self.angle_steers_des = 0. - - def reset(self): - self.pid.reset() - - def update(self, active, v_ego, angle_steers, steer_override, CP, VM, path_plan): - if v_ego < 0.3 or not active: - output_steer = 0.0 - self.pid.reset() - else: - # TODO: ideally we should interp, but for tuning reasons we keep the mpc solution - # constant for 0.05s. - #dt = min(cur_time - self.angle_steers_des_time, _DT_MPC + _DT) + _DT # no greater than dt mpc + dt, to prevent too high extraps - #self.angle_steers_des = self.angle_steers_des_prev + (dt / _DT_MPC) * (self.angle_steers_des_mpc - self.angle_steers_des_prev) - self.angle_steers_des = path_plan.angleSteers # get from MPC/PathPlanner - - steers_max = get_steer_max(CP, v_ego) - self.pid.pos_limit = steers_max - self.pid.neg_limit = -steers_max - steer_feedforward = self.angle_steers_des # feedforward desired angle - if CP.steerControlType == car.CarParams.SteerControlType.torque: - # TODO: feedforward something based on path_plan.rateSteers - steer_feedforward -= path_plan.angleOffset # subtract the offset, since it does not contribute to resistive torque - steer_feedforward *= v_ego**2 # proportional to realigning tire momentum (~ lateral accel) - deadzone = 0.0 - output_steer = self.pid.update(self.angle_steers_des, angle_steers, check_saturation=(v_ego > 10), override=steer_override, - feedforward=steer_feedforward, speed=v_ego, deadzone=deadzone) - - self.sat_flag = self.pid.saturated - return output_steer, float(self.angle_steers_des) diff --git a/selfdrive/controls/lib/latcontrol_helpers.py b/selfdrive/controls/lib/latcontrol_helpers.py deleted file mode 100644 index 90abcebf10bf53..00000000000000 --- a/selfdrive/controls/lib/latcontrol_helpers.py +++ /dev/null @@ -1,89 +0,0 @@ -import numpy as np -import math -from common.numpy_fast import interp - -_K_CURV_V = [1., 0.6] -_K_CURV_BP = [0., 0.002] - -# lane width http://safety.fhwa.dot.gov/geometric/pubs/mitigationstrategies/chapter3/3_lanewidth.cfm -_LANE_WIDTH_V = [3., 3.8] - -# break points of speed -_LANE_WIDTH_BP = [0., 31.] - - -def calc_d_lookahead(v_ego, d_poly): - # this function computes how far too look for lateral control - # howfar we look ahead is function of speed and how much curvy is the path - offset_lookahead = 1. - k_lookahead = 7. - # integrate abs value of second derivative of poly to get a measure of path curvature - pts_len = 50. # m - if len(d_poly) > 0: - pts = np.polyval([6 * d_poly[0], 2 * d_poly[1]], np.arange(0, pts_len)) - else: - pts = 0. - curv = np.sum(np.abs(pts)) / pts_len - - k_curv = interp(curv, _K_CURV_BP, _K_CURV_V) - - # sqrt on speed is needed to keep, for a given curvature, the y_des - # proportional to speed. Indeed, y_des is prop to d_lookahead^2 - # 36m at 25m/s - d_lookahead = offset_lookahead + math.sqrt(max(v_ego, 0)) * k_lookahead * k_curv - return d_lookahead - - -def calc_lookahead_offset(v_ego, angle_steers, d_lookahead, VM, angle_offset): - # this function returns the lateral offset given the steering angle, speed and the lookahead distance - sa = math.radians(angle_steers - angle_offset) - curvature = VM.calc_curvature(sa, v_ego) - # clip is to avoid arcsin NaNs due to too sharp turns - y_actual = d_lookahead * np.tan(np.arcsin(np.clip(d_lookahead * curvature, -0.999, 0.999)) / 2.) - return y_actual, curvature - - -def calc_desired_steer_angle(v_ego, y_des, d_lookahead, VM, angle_offset): - # inverse of the above function - curvature = np.sin(np.arctan(y_des / d_lookahead) * 2.) / d_lookahead - steer_des = math.degrees(VM.get_steer_from_curvature(curvature, v_ego)) + angle_offset - return steer_des, curvature - - -def compute_path_pinv(l=50): - deg = 3 - x = np.arange(l*1.0) - X = np.vstack(tuple(x**n for n in range(deg, -1, -1))).T - pinv = np.linalg.pinv(X) - return pinv - - -def model_polyfit(points, path_pinv): - return np.dot(path_pinv, map(float, points)) - - -def calc_desired_path(l_poly, - r_poly, - p_poly, - l_prob, - r_prob, - p_prob, - speed, - lane_width=None): - # this function computes the poly for the center of the lane, averaging left and right polys - if lane_width is None: - lane_width = interp(speed, _LANE_WIDTH_BP, _LANE_WIDTH_V) - - # lanes in US are ~3.6m wide - half_lane_poly = np.array([0., 0., 0., lane_width / 2.]) - if l_prob + r_prob > 0.01: - c_poly = ((l_poly - half_lane_poly) * l_prob + - (r_poly + half_lane_poly) * r_prob) / (l_prob + r_prob) - c_prob = l_prob + r_prob - l_prob * r_prob - else: - c_poly = np.zeros(4) - c_prob = 0. - - p_weight = 1. # predicted path weight relatively to the center of the lane - d_poly = list((c_poly * c_prob + p_poly * p_prob * p_weight) / (c_prob + p_prob * p_weight)) - return d_poly, c_poly, c_prob diff --git a/selfdrive/controls/lib/latcontrol_indi.py b/selfdrive/controls/lib/latcontrol_indi.py new file mode 100644 index 00000000000000..db1192f8396f1c --- /dev/null +++ b/selfdrive/controls/lib/latcontrol_indi.py @@ -0,0 +1,105 @@ +import math +import numpy as np + +from cereal import log +from common.realtime import DT_CTRL +from common.numpy_fast import clip +from selfdrive.car.toyota.values import SteerLimitParams +from selfdrive.car import apply_toyota_steer_torque_limits +from selfdrive.controls.lib.drive_helpers import get_steer_max + + +class LatControlINDI(): + def __init__(self, CP): + self.angle_steers_des = 0. + + A = np.matrix([[1.0, DT_CTRL, 0.0], + [0.0, 1.0, DT_CTRL], + [0.0, 0.0, 1.0]]) + C = np.matrix([[1.0, 0.0, 0.0], + [0.0, 1.0, 0.0]]) + + # Q = np.matrix([[1e-2, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 10.0]]) + # R = np.matrix([[1e-2, 0.0], [0.0, 1e3]]) + + # (x, l, K) = control.dare(np.transpose(A), np.transpose(C), Q, R) + # K = np.transpose(K) + K = np.matrix([[7.30262179e-01, 2.07003658e-04], + [7.29394177e+00, 1.39159419e-02], + [1.71022442e+01, 3.38495381e-02]]) + + self.K = K + self.A_K = A - np.dot(K, C) + self.x = np.matrix([[0.], [0.], [0.]]) + + self.enfore_rate_limit = CP.carName == "toyota" + + self.RC = CP.lateralTuning.indi.timeConstant + self.G = CP.lateralTuning.indi.actuatorEffectiveness + self.outer_loop_gain = CP.lateralTuning.indi.outerLoopGain + self.inner_loop_gain = CP.lateralTuning.indi.innerLoopGain + self.alpha = 1. - DT_CTRL / (self.RC + DT_CTRL) + + self.reset() + + def reset(self): + self.delayed_output = 0. + self.output_steer = 0. + self.counter = 0 + + def update(self, active, v_ego, angle_steers, angle_steers_rate, eps_torque, steer_override, CP, path_plan): + # Update Kalman filter + y = np.matrix([[math.radians(angle_steers)], [math.radians(angle_steers_rate)]]) + self.x = np.dot(self.A_K, self.x) + np.dot(self.K, y) + + indi_log = log.ControlsState.LateralINDIState.new_message() + indi_log.steerAngle = math.degrees(self.x[0]) + indi_log.steerRate = math.degrees(self.x[1]) + indi_log.steerAccel = math.degrees(self.x[2]) + + if v_ego < 0.3 or not active: + indi_log.active = False + self.output_steer = 0.0 + self.delayed_output = 0.0 + else: + self.angle_steers_des = path_plan.angleSteers + self.rate_steers_des = path_plan.rateSteers + + steers_des = math.radians(self.angle_steers_des) + rate_des = math.radians(self.rate_steers_des) + + # Expected actuator value + self.delayed_output = self.delayed_output * self.alpha + self.output_steer * (1. - self.alpha) + + # Compute acceleration error + rate_sp = self.outer_loop_gain * (steers_des - self.x[0]) + rate_des + accel_sp = self.inner_loop_gain * (rate_sp - self.x[1]) + accel_error = accel_sp - self.x[2] + + # Compute change in actuator + g_inv = 1. / self.G + delta_u = g_inv * accel_error + + # Enforce rate limit + if self.enfore_rate_limit: + steer_max = float(SteerLimitParams.STEER_MAX) + new_output_steer_cmd = steer_max * (self.delayed_output + delta_u) + prev_output_steer_cmd = steer_max * self.output_steer + new_output_steer_cmd = apply_toyota_steer_torque_limits(new_output_steer_cmd, prev_output_steer_cmd, prev_output_steer_cmd, SteerLimitParams) + self.output_steer = new_output_steer_cmd / steer_max + else: + self.output_steer = self.delayed_output + delta_u + + steers_max = get_steer_max(CP, v_ego) + self.output_steer = clip(self.output_steer, -steers_max, steers_max) + + indi_log.active = True + indi_log.rateSetPoint = float(rate_sp) + indi_log.accelSetPoint = float(accel_sp) + indi_log.accelError = float(accel_error) + indi_log.delayedOutput = float(self.delayed_output) + indi_log.delta = float(delta_u) + indi_log.output = float(self.output_steer) + + self.sat_flag = False + return float(self.output_steer), float(self.angle_steers_des), indi_log diff --git a/selfdrive/controls/lib/latcontrol_lqr.py b/selfdrive/controls/lib/latcontrol_lqr.py new file mode 100644 index 00000000000000..1badf2d26822e8 --- /dev/null +++ b/selfdrive/controls/lib/latcontrol_lqr.py @@ -0,0 +1,77 @@ +import numpy as np +from selfdrive.controls.lib.drive_helpers import get_steer_max +from common.numpy_fast import clip +from cereal import log + + +class LatControlLQR(): + def __init__(self, CP, rate=100): + self.sat_flag = False + self.scale = CP.lateralTuning.lqr.scale + self.ki = CP.lateralTuning.lqr.ki + + + self.A = np.array(CP.lateralTuning.lqr.a).reshape((2,2)) + self.B = np.array(CP.lateralTuning.lqr.b).reshape((2,1)) + self.C = np.array(CP.lateralTuning.lqr.c).reshape((1,2)) + self.K = np.array(CP.lateralTuning.lqr.k).reshape((1,2)) + self.L = np.array(CP.lateralTuning.lqr.l).reshape((2,1)) + self.dc_gain = CP.lateralTuning.lqr.dcGain + + self.x_hat = np.array([[0], [0]]) + self.i_unwind_rate = 0.3 / rate + self.i_rate = 1.0 / rate + + + self.reset() + + def reset(self): + self.i_lqr = 0.0 + self.output_steer = 0.0 + + def update(self, active, v_ego, angle_steers, angle_steers_rate, eps_torque, steer_override, CP, path_plan): + lqr_log = log.ControlsState.LateralLQRState.new_message() + + steers_max = get_steer_max(CP, v_ego) + torque_scale = (0.45 + v_ego / 60.0)**2 # Scale actuator model with speed + + # Subtract offset. Zero angle should correspond to zero torque + self.angle_steers_des = path_plan.angleSteers - path_plan.angleOffset + angle_steers -= path_plan.angleOffset + + # Update Kalman filter + angle_steers_k = float(self.C.dot(self.x_hat)) + e = angle_steers - angle_steers_k + self.x_hat = self.A.dot(self.x_hat) + self.B.dot(eps_torque / torque_scale) + self.L.dot(e) + + if v_ego < 0.3 or not active: + lqr_log.active = False + lqr_output = 0. + self.reset() + else: + lqr_log.active = True + + # LQR + u_lqr = float(self.angle_steers_des / self.dc_gain - self.K.dot(self.x_hat)) + lqr_output = torque_scale * u_lqr / self.scale + + # Integrator + if steer_override: + self.i_lqr -= self.i_unwind_rate * float(np.sign(self.i_lqr)) + else: + error = self.angle_steers_des - angle_steers_k + i = self.i_lqr + self.ki * self.i_rate * error + control = lqr_output + i + + if ((error >= 0 and (control <= steers_max or i < 0.0)) or \ + (error <= 0 and (control >= -steers_max or i > 0.0))): + self.i_lqr = i + + self.output_steer = lqr_output + self.i_lqr + self.output_steer = clip(self.output_steer, -steers_max, steers_max) + + lqr_log.steerAngle = angle_steers_k + path_plan.angleOffset + lqr_log.i = self.i_lqr + lqr_log.output = self.output_steer + lqr_log.lqrOutput = lqr_output + return self.output_steer, float(self.angle_steers_des), lqr_log diff --git a/selfdrive/controls/lib/latcontrol_pid.py b/selfdrive/controls/lib/latcontrol_pid.py new file mode 100644 index 00000000000000..461203dec5950d --- /dev/null +++ b/selfdrive/controls/lib/latcontrol_pid.py @@ -0,0 +1,48 @@ +from selfdrive.controls.lib.pid import PIController +from selfdrive.controls.lib.drive_helpers import get_steer_max +from cereal import car +from cereal import log + + +class LatControlPID(): + def __init__(self, CP): + self.pid = PIController((CP.lateralTuning.pid.kpBP, CP.lateralTuning.pid.kpV), + (CP.lateralTuning.pid.kiBP, CP.lateralTuning.pid.kiV), + k_f=CP.lateralTuning.pid.kf, pos_limit=1.0) + self.angle_steers_des = 0. + + def reset(self): + self.pid.reset() + + def update(self, active, v_ego, angle_steers, angle_steers_rate, eps_torque, steer_override, CP, path_plan): + pid_log = log.ControlsState.LateralPIDState.new_message() + pid_log.steerAngle = float(angle_steers) + pid_log.steerRate = float(angle_steers_rate) + + if v_ego < 0.3 or not active: + output_steer = 0.0 + pid_log.active = False + self.pid.reset() + else: + self.angle_steers_des = path_plan.angleSteers # get from MPC/PathPlanner + + steers_max = get_steer_max(CP, v_ego) + self.pid.pos_limit = steers_max + self.pid.neg_limit = -steers_max + steer_feedforward = self.angle_steers_des # feedforward desired angle + if CP.steerControlType == car.CarParams.SteerControlType.torque: + # TODO: feedforward something based on path_plan.rateSteers + steer_feedforward -= path_plan.angleOffset # subtract the offset, since it does not contribute to resistive torque + steer_feedforward *= v_ego**2 # proportional to realigning tire momentum (~ lateral accel) + deadzone = 0.0 + output_steer = self.pid.update(self.angle_steers_des, angle_steers, check_saturation=(v_ego > 10), override=steer_override, + feedforward=steer_feedforward, speed=v_ego, deadzone=deadzone) + pid_log.active = True + pid_log.p = self.pid.p + pid_log.i = self.pid.i + pid_log.f = self.pid.f + pid_log.output = output_steer + pid_log.saturated = bool(self.pid.saturated) + + self.sat_flag = self.pid.saturated + return output_steer, float(self.angle_steers_des), pid_log diff --git a/selfdrive/controls/lib/lateral_mpc/Makefile b/selfdrive/controls/lib/lateral_mpc/Makefile index 97579e751c833e..42970efd661e75 100644 --- a/selfdrive/controls/lib/lateral_mpc/Makefile +++ b/selfdrive/controls/lib/lateral_mpc/Makefile @@ -15,11 +15,13 @@ QPOASES_FLAGS = -I$(PHONELIBS)/qpoases -I$(PHONELIBS)/qpoases/INCLUDE -I$(PHONEL ACADO_FLAGS = -I$(PHONELIBS)/acado/include -I$(PHONELIBS)/acado/include/acado ifeq ($(UNAME_S),Darwin) - ACADO_LIBS := -lacado_toolkit_s +ACADO_LIBS := -lacado_toolkit_s else ifeq ($(UNAME_M),aarch64) - ACADO_LIBS := -L $(PHONELIBS)/acado/aarch64/lib -l:libacado_toolkit.a -l:libacado_casadi.a -l:libacado_csparse.a +ACADO_LIBS := -L $(PHONELIBS)/acado/aarch64/lib -l:libacado_toolkit.a -l:libacado_casadi.a -l:libacado_csparse.a +CFLAGS += -mcpu=cortex-a57 +CXXFLAGS += -mcpu=cortex-a57 else - ACADO_LIBS := -L $(PHONELIBS)/acado/x64/lib -l:libacado_toolkit.a -l:libacado_casadi.a -l:libacado_csparse.a +ACADO_LIBS := -L $(PHONELIBS)/acado/x64/lib -l:libacado_toolkit.a -l:libacado_casadi.a -l:libacado_csparse.a endif OBJS = \ diff --git a/selfdrive/controls/lib/lateral_mpc/generator.cpp b/selfdrive/controls/lib/lateral_mpc/generator.cpp index 9af88f9dc8a732..5f4a9a28dfe754 100644 --- a/selfdrive/controls/lib/lateral_mpc/generator.cpp +++ b/selfdrive/controls/lib/lateral_mpc/generator.cpp @@ -23,8 +23,8 @@ int main( ) OnlineData v_ref; // m/s OnlineData l_poly_r0, l_poly_r1, l_poly_r2, l_poly_r3; OnlineData r_poly_r0, r_poly_r1, r_poly_r2, r_poly_r3; - OnlineData p_poly_r0, p_poly_r1, p_poly_r2, p_poly_r3; - OnlineData l_prob, r_prob, p_prob; + OnlineData d_poly_r0, d_poly_r1, d_poly_r2, d_poly_r3; + OnlineData l_prob, r_prob; OnlineData lane_width; Control t; @@ -39,38 +39,27 @@ int main( ) auto poly_l = l_poly_r0*(xx*xx*xx) + l_poly_r1*(xx*xx) + l_poly_r2*xx + l_poly_r3; auto poly_r = r_poly_r0*(xx*xx*xx) + r_poly_r1*(xx*xx) + r_poly_r2*xx + r_poly_r3; - auto poly_p = p_poly_r0*(xx*xx*xx) + p_poly_r1*(xx*xx) + p_poly_r2*xx + p_poly_r3; + auto poly_d = d_poly_r0*(xx*xx*xx) + d_poly_r1*(xx*xx) + d_poly_r2*xx + d_poly_r3; - auto angle_l = atan(3*l_poly_r0*xx*xx + 2*l_poly_r1*xx + l_poly_r2); - auto angle_r = atan(3*r_poly_r0*xx*xx + 2*r_poly_r1*xx + r_poly_r2); - auto angle_p = atan(3*p_poly_r0*xx*xx + 2*p_poly_r1*xx + p_poly_r2); + auto angle_d = atan(3*d_poly_r0*xx*xx + 2*d_poly_r1*xx + d_poly_r2); - // given the lane width estimate, this is where we estimate the path given lane lines - auto l_phantom = poly_l - lane_width/2.0; - auto r_phantom = poly_r + lane_width/2.0; + // When the lane is not visible, use an estimate of its position + auto weighted_left_lane = l_prob * poly_l + (1 - l_prob) * (poly_d + lane_width/2.0); + auto weighted_right_lane = r_prob * poly_r + (1 - r_prob) * (poly_d - lane_width/2.0); - // best path estimate path is a linear combination of poly_p and the path estimate - // given the lane lines - auto path = lr_prob * (l_prob * l_phantom + r_prob * r_phantom) / (l_prob + r_prob + 0.0001) - + (1-lr_prob) * poly_p; - - auto angle = lr_prob * (l_prob * angle_l + r_prob * angle_r) / (l_prob + r_prob + 0.0001) - + (1-lr_prob) * angle_p; - - // instead of using actual lane lines, use their estimated distance from path given lane_width - auto c_left_lane = exp(-(path + lane_width/2.0 - yy)); - auto c_right_lane = exp(path - lane_width/2.0 - yy); + auto c_left_lane = exp(-(weighted_left_lane - yy)); + auto c_right_lane = exp(weighted_right_lane - yy); // Running cost Function h; // Distance errors - h << path - yy; + h << poly_d - yy; h << lr_prob * c_left_lane; h << lr_prob * c_right_lane; // Heading error - h << (v_ref + 1.0 ) * (angle - psi); + h << (v_ref + 1.0 ) * (angle_d - psi); // Angular rate error h << (v_ref + 1.0 ) * t; @@ -86,12 +75,12 @@ int main( ) Function hN; // Distance errors - hN << path - yy; + hN << poly_d - yy; hN << l_prob * c_left_lane; hN << r_prob * c_right_lane; // Heading errors - hN << (2.0 * v_ref + 1.0 ) * (angle - psi); + hN << (2.0 * v_ref + 1.0 ) * (angle_d - psi); BMatrix QN(4,4); QN.setAll(true); // QN(0,0) = 1.0; @@ -123,7 +112,7 @@ int main( ) ocp.subjectTo( deg2rad(-90) <= psi <= deg2rad(90)); // more than absolute max steer angle ocp.subjectTo( deg2rad(-50) <= delta <= deg2rad(50)); - ocp.setNOD(18); + ocp.setNOD(17); OCPexport mpc(ocp); mpc.set( HESSIAN_APPROXIMATION, GAUSS_NEWTON ); diff --git a/selfdrive/controls/lib/lateral_mpc/lateral_mpc.c b/selfdrive/controls/lib/lateral_mpc/lateral_mpc.c index e5adf02cf4e125..d8d29cc61c07b2 100644 --- a/selfdrive/controls/lib/lateral_mpc/lateral_mpc.c +++ b/selfdrive/controls/lib/lateral_mpc/lateral_mpc.c @@ -26,7 +26,7 @@ typedef struct { double y[N+1]; double psi[N+1]; double delta[N+1]; - double rate[N+1]; + double rate[N]; double cost; } log_t; @@ -51,21 +51,22 @@ void init(double pathCost, double laneCost, double headingCost, double steerRate if (i > 4){ f = STEP_MULTIPLIER; } - acadoVariables.W[25 * i + 0] = pathCost * f; - acadoVariables.W[25 * i + 6] = laneCost * f; - acadoVariables.W[25 * i + 12] = laneCost * f; - acadoVariables.W[25 * i + 18] = headingCost * f; - acadoVariables.W[25 * i + 24] = steerRateCost * f; + // Setup diagonal entries + acadoVariables.W[NY*NY*i + (NY+1)*0] = pathCost * f; + acadoVariables.W[NY*NY*i + (NY+1)*1] = laneCost * f; + acadoVariables.W[NY*NY*i + (NY+1)*2] = laneCost * f; + acadoVariables.W[NY*NY*i + (NY+1)*3] = headingCost * f; + acadoVariables.W[NY*NY*i + (NY+1)*4] = steerRateCost * f; } - acadoVariables.WN[0] = pathCost * STEP_MULTIPLIER; - acadoVariables.WN[5] = laneCost * STEP_MULTIPLIER; - acadoVariables.WN[10] = laneCost * STEP_MULTIPLIER; - acadoVariables.WN[15] = headingCost * STEP_MULTIPLIER; + acadoVariables.WN[(NYN+1)*0] = pathCost * STEP_MULTIPLIER; + acadoVariables.WN[(NYN+1)*1] = laneCost * STEP_MULTIPLIER; + acadoVariables.WN[(NYN+1)*2] = laneCost * STEP_MULTIPLIER; + acadoVariables.WN[(NYN+1)*3] = headingCost * STEP_MULTIPLIER; } int run_mpc(state_t * x0, log_t * solution, - double l_poly[4], double r_poly[4], double p_poly[4], - double l_prob, double r_prob, double p_prob, double curvature_factor, double v_ref, double lane_width){ + double l_poly[4], double r_poly[4], double d_poly[4], + double l_prob, double r_prob, double curvature_factor, double v_ref, double lane_width){ int i; @@ -83,16 +84,15 @@ int run_mpc(state_t * x0, log_t * solution, acadoVariables.od[i+8] = r_poly[2]; acadoVariables.od[i+9] = r_poly[3]; - acadoVariables.od[i+10] = p_poly[0]; - acadoVariables.od[i+11] = p_poly[1]; - acadoVariables.od[i+12] = p_poly[2]; - acadoVariables.od[i+13] = p_poly[3]; + acadoVariables.od[i+10] = d_poly[0]; + acadoVariables.od[i+11] = d_poly[1]; + acadoVariables.od[i+12] = d_poly[2]; + acadoVariables.od[i+13] = d_poly[3]; acadoVariables.od[i+14] = l_prob; acadoVariables.od[i+15] = r_prob; - acadoVariables.od[i+16] = p_prob; - acadoVariables.od[i+17] = lane_width; + acadoVariables.od[i+16] = lane_width; } @@ -113,7 +113,9 @@ int run_mpc(state_t * x0, log_t * solution, solution->y[i] = acadoVariables.x[i*NX+1]; solution->psi[i] = acadoVariables.x[i*NX+2]; solution->delta[i] = acadoVariables.x[i*NX+3]; - solution->rate[i] = acadoVariables.u[i]; + if (i < N){ + solution->rate[i] = acadoVariables.u[i]; + } } solution->cost = acado_getObjective(); diff --git a/selfdrive/controls/lib/lateral_mpc/lateral_mpc.o b/selfdrive/controls/lib/lateral_mpc/lateral_mpc.o index fdd82d242cbaff..e6990f56968567 100644 Binary files a/selfdrive/controls/lib/lateral_mpc/lateral_mpc.o and b/selfdrive/controls/lib/lateral_mpc/lateral_mpc.o differ diff --git a/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_auxiliary_functions.o b/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_auxiliary_functions.o index 07d92429b217f2..5c17c326853b59 100644 Binary files a/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_auxiliary_functions.o and b/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_auxiliary_functions.o differ diff --git a/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_common.h b/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_common.h index d5b56727707ff0..f069b62c066f36 100644 --- a/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_common.h +++ b/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_common.h @@ -64,7 +64,7 @@ extern "C" /** Number of control/estimation intervals. */ #define ACADO_N 20 /** Number of online data values. */ -#define ACADO_NOD 18 +#define ACADO_NOD 17 /** Number of path constraints. */ #define ACADO_NPAC 0 /** Number of control variables. */ @@ -114,11 +114,11 @@ real_t x[ 84 ]; */ real_t u[ 20 ]; -/** Matrix of size: 21 x 18 (row major format) +/** Matrix of size: 21 x 17 (row major format) * * Matrix containing 21 online data vectors. */ -real_t od[ 378 ]; +real_t od[ 357 ]; /** Column vector of size: 100 * @@ -160,14 +160,14 @@ real_t rhs_aux[ 14 ]; real_t rk_ttt; -/** Row vector of size: 43 */ -real_t rk_xxx[ 43 ]; +/** Row vector of size: 42 */ +real_t rk_xxx[ 42 ]; /** Matrix of size: 4 x 24 (row major format) */ real_t rk_kkk[ 96 ]; -/** Row vector of size: 43 */ -real_t state[ 43 ]; +/** Row vector of size: 42 */ +real_t state[ 42 ]; /** Column vector of size: 80 */ real_t d[ 80 ]; @@ -184,11 +184,11 @@ real_t evGx[ 320 ]; /** Column vector of size: 80 */ real_t evGu[ 80 ]; -/** Column vector of size: 21 */ -real_t objAuxVar[ 21 ]; +/** Column vector of size: 11 */ +real_t objAuxVar[ 11 ]; -/** Row vector of size: 23 */ -real_t objValueIn[ 23 ]; +/** Row vector of size: 22 */ +real_t objValueIn[ 22 ]; /** Row vector of size: 30 */ real_t objValueOut[ 30 ]; diff --git a/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_integrator.c b/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_integrator.c index b931088991a33d..5df7cb47f58df6 100644 --- a/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_integrator.c +++ b/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_integrator.c @@ -118,7 +118,6 @@ acadoWorkspace.rk_xxx[38] = rk_eta[38]; acadoWorkspace.rk_xxx[39] = rk_eta[39]; acadoWorkspace.rk_xxx[40] = rk_eta[40]; acadoWorkspace.rk_xxx[41] = rk_eta[41]; -acadoWorkspace.rk_xxx[42] = rk_eta[42]; for (run1 = 0; run1 < 1; ++run1) { diff --git a/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_integrator.o b/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_integrator.o index d08f1e41279bb7..e09d5c89864869 100644 Binary files a/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_integrator.o and b/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_integrator.o differ diff --git a/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_qpoases_interface.o b/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_qpoases_interface.o index e10c9772ab2b29..e755f67a5e0d27 100644 Binary files a/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_qpoases_interface.o and b/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_qpoases_interface.o differ diff --git a/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_solver.c b/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_solver.c index 85b67db8a12249..347e77fa737710 100644 --- a/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_solver.c +++ b/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_solver.c @@ -43,24 +43,23 @@ acadoWorkspace.state[2] = acadoVariables.x[lRun1 * 4 + 2]; acadoWorkspace.state[3] = acadoVariables.x[lRun1 * 4 + 3]; acadoWorkspace.state[24] = acadoVariables.u[lRun1]; -acadoWorkspace.state[25] = acadoVariables.od[lRun1 * 18]; -acadoWorkspace.state[26] = acadoVariables.od[lRun1 * 18 + 1]; -acadoWorkspace.state[27] = acadoVariables.od[lRun1 * 18 + 2]; -acadoWorkspace.state[28] = acadoVariables.od[lRun1 * 18 + 3]; -acadoWorkspace.state[29] = acadoVariables.od[lRun1 * 18 + 4]; -acadoWorkspace.state[30] = acadoVariables.od[lRun1 * 18 + 5]; -acadoWorkspace.state[31] = acadoVariables.od[lRun1 * 18 + 6]; -acadoWorkspace.state[32] = acadoVariables.od[lRun1 * 18 + 7]; -acadoWorkspace.state[33] = acadoVariables.od[lRun1 * 18 + 8]; -acadoWorkspace.state[34] = acadoVariables.od[lRun1 * 18 + 9]; -acadoWorkspace.state[35] = acadoVariables.od[lRun1 * 18 + 10]; -acadoWorkspace.state[36] = acadoVariables.od[lRun1 * 18 + 11]; -acadoWorkspace.state[37] = acadoVariables.od[lRun1 * 18 + 12]; -acadoWorkspace.state[38] = acadoVariables.od[lRun1 * 18 + 13]; -acadoWorkspace.state[39] = acadoVariables.od[lRun1 * 18 + 14]; -acadoWorkspace.state[40] = acadoVariables.od[lRun1 * 18 + 15]; -acadoWorkspace.state[41] = acadoVariables.od[lRun1 * 18 + 16]; -acadoWorkspace.state[42] = acadoVariables.od[lRun1 * 18 + 17]; +acadoWorkspace.state[25] = acadoVariables.od[lRun1 * 17]; +acadoWorkspace.state[26] = acadoVariables.od[lRun1 * 17 + 1]; +acadoWorkspace.state[27] = acadoVariables.od[lRun1 * 17 + 2]; +acadoWorkspace.state[28] = acadoVariables.od[lRun1 * 17 + 3]; +acadoWorkspace.state[29] = acadoVariables.od[lRun1 * 17 + 4]; +acadoWorkspace.state[30] = acadoVariables.od[lRun1 * 17 + 5]; +acadoWorkspace.state[31] = acadoVariables.od[lRun1 * 17 + 6]; +acadoWorkspace.state[32] = acadoVariables.od[lRun1 * 17 + 7]; +acadoWorkspace.state[33] = acadoVariables.od[lRun1 * 17 + 8]; +acadoWorkspace.state[34] = acadoVariables.od[lRun1 * 17 + 9]; +acadoWorkspace.state[35] = acadoVariables.od[lRun1 * 17 + 10]; +acadoWorkspace.state[36] = acadoVariables.od[lRun1 * 17 + 11]; +acadoWorkspace.state[37] = acadoVariables.od[lRun1 * 17 + 12]; +acadoWorkspace.state[38] = acadoVariables.od[lRun1 * 17 + 13]; +acadoWorkspace.state[39] = acadoVariables.od[lRun1 * 17 + 14]; +acadoWorkspace.state[40] = acadoVariables.od[lRun1 * 17 + 15]; +acadoWorkspace.state[41] = acadoVariables.od[lRun1 * 17 + 16]; ret = acado_integrate(acadoWorkspace.state, 1, lRun1); @@ -99,51 +98,41 @@ void acado_evaluateLSQ(const real_t* in, real_t* out) const real_t* xd = in; const real_t* u = in + 4; const real_t* od = in + 5; -/* Vector of auxiliary variables; number of elements: 21. */ +/* Vector of auxiliary variables; number of elements: 11. */ real_t* a = acadoWorkspace.objAuxVar; /* Compute intermediate quantities: */ -a[0] = (exp(((real_t)(0.0000000000000000e+00)-(((((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((((od[2]*((xd[0]*xd[0])*xd[0]))+(od[3]*(xd[0]*xd[0])))+(od[4]*xd[0]))+od[5])-(od[17]/(real_t)(2.0000000000000000e+00))))+(od[15]*(((((od[6]*((xd[0]*xd[0])*xd[0]))+(od[7]*(xd[0]*xd[0])))+(od[8]*xd[0]))+od[9])+(od[17]/(real_t)(2.0000000000000000e+00))))))/((od[14]+od[15])+(real_t)(1.0000000000000000e-04)))+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])))+(od[17]/(real_t)(2.0000000000000000e+00)))-xd[1])))); -a[1] = (exp((((((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((((od[2]*((xd[0]*xd[0])*xd[0]))+(od[3]*(xd[0]*xd[0])))+(od[4]*xd[0]))+od[5])-(od[17]/(real_t)(2.0000000000000000e+00))))+(od[15]*(((((od[6]*((xd[0]*xd[0])*xd[0]))+(od[7]*(xd[0]*xd[0])))+(od[8]*xd[0]))+od[9])+(od[17]/(real_t)(2.0000000000000000e+00))))))/((od[14]+od[15])+(real_t)(1.0000000000000000e-04)))+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])))-(od[17]/(real_t)(2.0000000000000000e+00)))-xd[1]))); -a[2] = (atan(((((((real_t)(3.0000000000000000e+00)*od[2])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[3])*xd[0]))+od[4]))); -a[3] = (atan(((((((real_t)(3.0000000000000000e+00)*od[6])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[7])*xd[0]))+od[8]))); -a[4] = (atan(((((((real_t)(3.0000000000000000e+00)*od[10])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[11])*xd[0]))+od[12]))); -a[5] = ((real_t)(1.0000000000000000e+00)/((od[14]+od[15])+(real_t)(1.0000000000000000e-04))); -a[6] = ((real_t)(1.0000000000000000e+00)/((od[14]+od[15])+(real_t)(1.0000000000000000e-04))); -a[7] = (exp(((real_t)(0.0000000000000000e+00)-(((((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((((od[2]*((xd[0]*xd[0])*xd[0]))+(od[3]*(xd[0]*xd[0])))+(od[4]*xd[0]))+od[5])-(od[17]/(real_t)(2.0000000000000000e+00))))+(od[15]*(((((od[6]*((xd[0]*xd[0])*xd[0]))+(od[7]*(xd[0]*xd[0])))+(od[8]*xd[0]))+od[9])+(od[17]/(real_t)(2.0000000000000000e+00))))))/((od[14]+od[15])+(real_t)(1.0000000000000000e-04)))+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])))+(od[17]/(real_t)(2.0000000000000000e+00)))-xd[1])))); -a[8] = (((real_t)(0.0000000000000000e+00)-(((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((od[2]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[3]*(xd[0]+xd[0])))+od[4]))+(od[15]*(((od[6]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[7]*(xd[0]+xd[0])))+od[8]))))*a[6])+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*(((od[10]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[11]*(xd[0]+xd[0])))+od[12]))))*a[7]); -a[9] = (((real_t)(0.0000000000000000e+00)-((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00)))*a[7]); -a[10] = ((real_t)(1.0000000000000000e+00)/((od[14]+od[15])+(real_t)(1.0000000000000000e-04))); -a[11] = (exp((((((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((((od[2]*((xd[0]*xd[0])*xd[0]))+(od[3]*(xd[0]*xd[0])))+(od[4]*xd[0]))+od[5])-(od[17]/(real_t)(2.0000000000000000e+00))))+(od[15]*(((((od[6]*((xd[0]*xd[0])*xd[0]))+(od[7]*(xd[0]*xd[0])))+(od[8]*xd[0]))+od[9])+(od[17]/(real_t)(2.0000000000000000e+00))))))/((od[14]+od[15])+(real_t)(1.0000000000000000e-04)))+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])))-(od[17]/(real_t)(2.0000000000000000e+00)))-xd[1]))); -a[12] = ((((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((od[2]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[3]*(xd[0]+xd[0])))+od[4]))+(od[15]*(((od[6]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[7]*(xd[0]+xd[0])))+od[8]))))*a[10])+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*(((od[10]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[11]*(xd[0]+xd[0])))+od[12])))*a[11]); -a[13] = (((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00))*a[11]); -a[14] = ((real_t)(1.0000000000000000e+00)/((real_t)(1.0000000000000000e+00)+(pow(((((((real_t)(3.0000000000000000e+00)*od[2])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[3])*xd[0]))+od[4]),2)))); -a[15] = ((((((real_t)(3.0000000000000000e+00)*od[2])*xd[0])+(((real_t)(3.0000000000000000e+00)*od[2])*xd[0]))+((real_t)(2.0000000000000000e+00)*od[3]))*a[14]); -a[16] = ((real_t)(1.0000000000000000e+00)/((real_t)(1.0000000000000000e+00)+(pow(((((((real_t)(3.0000000000000000e+00)*od[6])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[7])*xd[0]))+od[8]),2)))); -a[17] = ((((((real_t)(3.0000000000000000e+00)*od[6])*xd[0])+(((real_t)(3.0000000000000000e+00)*od[6])*xd[0]))+((real_t)(2.0000000000000000e+00)*od[7]))*a[16]); -a[18] = ((real_t)(1.0000000000000000e+00)/((od[14]+od[15])+(real_t)(1.0000000000000000e-04))); -a[19] = ((real_t)(1.0000000000000000e+00)/((real_t)(1.0000000000000000e+00)+(pow(((((((real_t)(3.0000000000000000e+00)*od[10])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[11])*xd[0]))+od[12]),2)))); -a[20] = ((((((real_t)(3.0000000000000000e+00)*od[10])*xd[0])+(((real_t)(3.0000000000000000e+00)*od[10])*xd[0]))+((real_t)(2.0000000000000000e+00)*od[11]))*a[19]); +a[0] = (exp(((real_t)(0.0000000000000000e+00)-(((od[14]*((((od[2]*((xd[0]*xd[0])*xd[0]))+(od[3]*(xd[0]*xd[0])))+(od[4]*xd[0]))+od[5]))+(((real_t)(1.0000000000000000e+00)-od[14])*(((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])+(od[16]/(real_t)(2.0000000000000000e+00)))))-xd[1])))); +a[1] = (exp((((od[15]*((((od[6]*((xd[0]*xd[0])*xd[0]))+(od[7]*(xd[0]*xd[0])))+(od[8]*xd[0]))+od[9]))+(((real_t)(1.0000000000000000e+00)-od[15])*(((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])-(od[16]/(real_t)(2.0000000000000000e+00)))))-xd[1]))); +a[2] = (atan(((((((real_t)(3.0000000000000000e+00)*od[10])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[11])*xd[0]))+od[12]))); +a[3] = (exp(((real_t)(0.0000000000000000e+00)-(((od[14]*((((od[2]*((xd[0]*xd[0])*xd[0]))+(od[3]*(xd[0]*xd[0])))+(od[4]*xd[0]))+od[5]))+(((real_t)(1.0000000000000000e+00)-od[14])*(((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])+(od[16]/(real_t)(2.0000000000000000e+00)))))-xd[1])))); +a[4] = (((real_t)(0.0000000000000000e+00)-((od[14]*(((od[2]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[3]*(xd[0]+xd[0])))+od[4]))+(((real_t)(1.0000000000000000e+00)-od[14])*(((od[10]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[11]*(xd[0]+xd[0])))+od[12]))))*a[3]); +a[5] = (((real_t)(0.0000000000000000e+00)-((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00)))*a[3]); +a[6] = (exp((((od[15]*((((od[6]*((xd[0]*xd[0])*xd[0]))+(od[7]*(xd[0]*xd[0])))+(od[8]*xd[0]))+od[9]))+(((real_t)(1.0000000000000000e+00)-od[15])*(((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])-(od[16]/(real_t)(2.0000000000000000e+00)))))-xd[1]))); +a[7] = (((od[15]*(((od[6]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[7]*(xd[0]+xd[0])))+od[8]))+(((real_t)(1.0000000000000000e+00)-od[15])*(((od[10]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[11]*(xd[0]+xd[0])))+od[12])))*a[6]); +a[8] = (((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00))*a[6]); +a[9] = ((real_t)(1.0000000000000000e+00)/((real_t)(1.0000000000000000e+00)+(pow(((((((real_t)(3.0000000000000000e+00)*od[10])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[11])*xd[0]))+od[12]),2)))); +a[10] = ((((((real_t)(3.0000000000000000e+00)*od[10])*xd[0])+(((real_t)(3.0000000000000000e+00)*od[10])*xd[0]))+((real_t)(2.0000000000000000e+00)*od[11]))*a[9]); /* Compute outputs: */ -out[0] = ((((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((((od[2]*((xd[0]*xd[0])*xd[0]))+(od[3]*(xd[0]*xd[0])))+(od[4]*xd[0]))+od[5])-(od[17]/(real_t)(2.0000000000000000e+00))))+(od[15]*(((((od[6]*((xd[0]*xd[0])*xd[0]))+(od[7]*(xd[0]*xd[0])))+(od[8]*xd[0]))+od[9])+(od[17]/(real_t)(2.0000000000000000e+00))))))/((od[14]+od[15])+(real_t)(1.0000000000000000e-04)))+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])))-xd[1]); +out[0] = (((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])-xd[1]); out[1] = (((od[14]+od[15])-(od[14]*od[15]))*a[0]); out[2] = (((od[14]+od[15])-(od[14]*od[15]))*a[1]); -out[3] = ((od[1]+(real_t)(1.0000000000000000e+00))*((((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*a[2])+(od[15]*a[3])))/((od[14]+od[15])+(real_t)(1.0000000000000000e-04)))+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*a[4]))-xd[2])); +out[3] = ((od[1]+(real_t)(1.0000000000000000e+00))*(a[2]-xd[2])); out[4] = ((od[1]+(real_t)(1.0000000000000000e+00))*u[0]); -out[5] = (((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((od[2]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[3]*(xd[0]+xd[0])))+od[4]))+(od[15]*(((od[6]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[7]*(xd[0]+xd[0])))+od[8]))))*a[5])+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*(((od[10]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[11]*(xd[0]+xd[0])))+od[12]))); +out[5] = (((od[10]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[11]*(xd[0]+xd[0])))+od[12]); out[6] = ((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00)); out[7] = (real_t)(0.0000000000000000e+00); out[8] = (real_t)(0.0000000000000000e+00); -out[9] = (((od[14]+od[15])-(od[14]*od[15]))*a[8]); -out[10] = (((od[14]+od[15])-(od[14]*od[15]))*a[9]); +out[9] = (((od[14]+od[15])-(od[14]*od[15]))*a[4]); +out[10] = (((od[14]+od[15])-(od[14]*od[15]))*a[5]); out[11] = (real_t)(0.0000000000000000e+00); out[12] = (real_t)(0.0000000000000000e+00); -out[13] = (((od[14]+od[15])-(od[14]*od[15]))*a[12]); -out[14] = (((od[14]+od[15])-(od[14]*od[15]))*a[13]); +out[13] = (((od[14]+od[15])-(od[14]*od[15]))*a[7]); +out[14] = (((od[14]+od[15])-(od[14]*od[15]))*a[8]); out[15] = (real_t)(0.0000000000000000e+00); out[16] = (real_t)(0.0000000000000000e+00); -out[17] = ((od[1]+(real_t)(1.0000000000000000e+00))*(((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*a[15])+(od[15]*a[17])))*a[18])+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*a[20]))); +out[17] = ((od[1]+(real_t)(1.0000000000000000e+00))*a[10]); out[18] = (real_t)(0.0000000000000000e+00); out[19] = ((od[1]+(real_t)(1.0000000000000000e+00))*((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00))); out[20] = (real_t)(0.0000000000000000e+00); @@ -162,50 +151,40 @@ void acado_evaluateLSQEndTerm(const real_t* in, real_t* out) { const real_t* xd = in; const real_t* od = in + 4; -/* Vector of auxiliary variables; number of elements: 21. */ +/* Vector of auxiliary variables; number of elements: 11. */ real_t* a = acadoWorkspace.objAuxVar; /* Compute intermediate quantities: */ -a[0] = (exp(((real_t)(0.0000000000000000e+00)-(((((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((((od[2]*((xd[0]*xd[0])*xd[0]))+(od[3]*(xd[0]*xd[0])))+(od[4]*xd[0]))+od[5])-(od[17]/(real_t)(2.0000000000000000e+00))))+(od[15]*(((((od[6]*((xd[0]*xd[0])*xd[0]))+(od[7]*(xd[0]*xd[0])))+(od[8]*xd[0]))+od[9])+(od[17]/(real_t)(2.0000000000000000e+00))))))/((od[14]+od[15])+(real_t)(1.0000000000000000e-04)))+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])))+(od[17]/(real_t)(2.0000000000000000e+00)))-xd[1])))); -a[1] = (exp((((((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((((od[2]*((xd[0]*xd[0])*xd[0]))+(od[3]*(xd[0]*xd[0])))+(od[4]*xd[0]))+od[5])-(od[17]/(real_t)(2.0000000000000000e+00))))+(od[15]*(((((od[6]*((xd[0]*xd[0])*xd[0]))+(od[7]*(xd[0]*xd[0])))+(od[8]*xd[0]))+od[9])+(od[17]/(real_t)(2.0000000000000000e+00))))))/((od[14]+od[15])+(real_t)(1.0000000000000000e-04)))+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])))-(od[17]/(real_t)(2.0000000000000000e+00)))-xd[1]))); -a[2] = (atan(((((((real_t)(3.0000000000000000e+00)*od[2])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[3])*xd[0]))+od[4]))); -a[3] = (atan(((((((real_t)(3.0000000000000000e+00)*od[6])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[7])*xd[0]))+od[8]))); -a[4] = (atan(((((((real_t)(3.0000000000000000e+00)*od[10])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[11])*xd[0]))+od[12]))); -a[5] = ((real_t)(1.0000000000000000e+00)/((od[14]+od[15])+(real_t)(1.0000000000000000e-04))); -a[6] = ((real_t)(1.0000000000000000e+00)/((od[14]+od[15])+(real_t)(1.0000000000000000e-04))); -a[7] = (exp(((real_t)(0.0000000000000000e+00)-(((((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((((od[2]*((xd[0]*xd[0])*xd[0]))+(od[3]*(xd[0]*xd[0])))+(od[4]*xd[0]))+od[5])-(od[17]/(real_t)(2.0000000000000000e+00))))+(od[15]*(((((od[6]*((xd[0]*xd[0])*xd[0]))+(od[7]*(xd[0]*xd[0])))+(od[8]*xd[0]))+od[9])+(od[17]/(real_t)(2.0000000000000000e+00))))))/((od[14]+od[15])+(real_t)(1.0000000000000000e-04)))+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])))+(od[17]/(real_t)(2.0000000000000000e+00)))-xd[1])))); -a[8] = (((real_t)(0.0000000000000000e+00)-(((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((od[2]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[3]*(xd[0]+xd[0])))+od[4]))+(od[15]*(((od[6]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[7]*(xd[0]+xd[0])))+od[8]))))*a[6])+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*(((od[10]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[11]*(xd[0]+xd[0])))+od[12]))))*a[7]); -a[9] = (((real_t)(0.0000000000000000e+00)-((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00)))*a[7]); -a[10] = ((real_t)(1.0000000000000000e+00)/((od[14]+od[15])+(real_t)(1.0000000000000000e-04))); -a[11] = (exp((((((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((((od[2]*((xd[0]*xd[0])*xd[0]))+(od[3]*(xd[0]*xd[0])))+(od[4]*xd[0]))+od[5])-(od[17]/(real_t)(2.0000000000000000e+00))))+(od[15]*(((((od[6]*((xd[0]*xd[0])*xd[0]))+(od[7]*(xd[0]*xd[0])))+(od[8]*xd[0]))+od[9])+(od[17]/(real_t)(2.0000000000000000e+00))))))/((od[14]+od[15])+(real_t)(1.0000000000000000e-04)))+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])))-(od[17]/(real_t)(2.0000000000000000e+00)))-xd[1]))); -a[12] = ((((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((od[2]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[3]*(xd[0]+xd[0])))+od[4]))+(od[15]*(((od[6]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[7]*(xd[0]+xd[0])))+od[8]))))*a[10])+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*(((od[10]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[11]*(xd[0]+xd[0])))+od[12])))*a[11]); -a[13] = (((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00))*a[11]); -a[14] = ((real_t)(1.0000000000000000e+00)/((real_t)(1.0000000000000000e+00)+(pow(((((((real_t)(3.0000000000000000e+00)*od[2])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[3])*xd[0]))+od[4]),2)))); -a[15] = ((((((real_t)(3.0000000000000000e+00)*od[2])*xd[0])+(((real_t)(3.0000000000000000e+00)*od[2])*xd[0]))+((real_t)(2.0000000000000000e+00)*od[3]))*a[14]); -a[16] = ((real_t)(1.0000000000000000e+00)/((real_t)(1.0000000000000000e+00)+(pow(((((((real_t)(3.0000000000000000e+00)*od[6])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[7])*xd[0]))+od[8]),2)))); -a[17] = ((((((real_t)(3.0000000000000000e+00)*od[6])*xd[0])+(((real_t)(3.0000000000000000e+00)*od[6])*xd[0]))+((real_t)(2.0000000000000000e+00)*od[7]))*a[16]); -a[18] = ((real_t)(1.0000000000000000e+00)/((od[14]+od[15])+(real_t)(1.0000000000000000e-04))); -a[19] = ((real_t)(1.0000000000000000e+00)/((real_t)(1.0000000000000000e+00)+(pow(((((((real_t)(3.0000000000000000e+00)*od[10])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[11])*xd[0]))+od[12]),2)))); -a[20] = ((((((real_t)(3.0000000000000000e+00)*od[10])*xd[0])+(((real_t)(3.0000000000000000e+00)*od[10])*xd[0]))+((real_t)(2.0000000000000000e+00)*od[11]))*a[19]); +a[0] = (exp(((real_t)(0.0000000000000000e+00)-(((od[14]*((((od[2]*((xd[0]*xd[0])*xd[0]))+(od[3]*(xd[0]*xd[0])))+(od[4]*xd[0]))+od[5]))+(((real_t)(1.0000000000000000e+00)-od[14])*(((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])+(od[16]/(real_t)(2.0000000000000000e+00)))))-xd[1])))); +a[1] = (exp((((od[15]*((((od[6]*((xd[0]*xd[0])*xd[0]))+(od[7]*(xd[0]*xd[0])))+(od[8]*xd[0]))+od[9]))+(((real_t)(1.0000000000000000e+00)-od[15])*(((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])-(od[16]/(real_t)(2.0000000000000000e+00)))))-xd[1]))); +a[2] = (atan(((((((real_t)(3.0000000000000000e+00)*od[10])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[11])*xd[0]))+od[12]))); +a[3] = (exp(((real_t)(0.0000000000000000e+00)-(((od[14]*((((od[2]*((xd[0]*xd[0])*xd[0]))+(od[3]*(xd[0]*xd[0])))+(od[4]*xd[0]))+od[5]))+(((real_t)(1.0000000000000000e+00)-od[14])*(((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])+(od[16]/(real_t)(2.0000000000000000e+00)))))-xd[1])))); +a[4] = (((real_t)(0.0000000000000000e+00)-((od[14]*(((od[2]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[3]*(xd[0]+xd[0])))+od[4]))+(((real_t)(1.0000000000000000e+00)-od[14])*(((od[10]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[11]*(xd[0]+xd[0])))+od[12]))))*a[3]); +a[5] = (((real_t)(0.0000000000000000e+00)-((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00)))*a[3]); +a[6] = (exp((((od[15]*((((od[6]*((xd[0]*xd[0])*xd[0]))+(od[7]*(xd[0]*xd[0])))+(od[8]*xd[0]))+od[9]))+(((real_t)(1.0000000000000000e+00)-od[15])*(((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])-(od[16]/(real_t)(2.0000000000000000e+00)))))-xd[1]))); +a[7] = (((od[15]*(((od[6]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[7]*(xd[0]+xd[0])))+od[8]))+(((real_t)(1.0000000000000000e+00)-od[15])*(((od[10]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[11]*(xd[0]+xd[0])))+od[12])))*a[6]); +a[8] = (((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00))*a[6]); +a[9] = ((real_t)(1.0000000000000000e+00)/((real_t)(1.0000000000000000e+00)+(pow(((((((real_t)(3.0000000000000000e+00)*od[10])*xd[0])*xd[0])+(((real_t)(2.0000000000000000e+00)*od[11])*xd[0]))+od[12]),2)))); +a[10] = ((((((real_t)(3.0000000000000000e+00)*od[10])*xd[0])+(((real_t)(3.0000000000000000e+00)*od[10])*xd[0]))+((real_t)(2.0000000000000000e+00)*od[11]))*a[9]); /* Compute outputs: */ -out[0] = ((((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((((od[2]*((xd[0]*xd[0])*xd[0]))+(od[3]*(xd[0]*xd[0])))+(od[4]*xd[0]))+od[5])-(od[17]/(real_t)(2.0000000000000000e+00))))+(od[15]*(((((od[6]*((xd[0]*xd[0])*xd[0]))+(od[7]*(xd[0]*xd[0])))+(od[8]*xd[0]))+od[9])+(od[17]/(real_t)(2.0000000000000000e+00))))))/((od[14]+od[15])+(real_t)(1.0000000000000000e-04)))+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])))-xd[1]); +out[0] = (((((od[10]*((xd[0]*xd[0])*xd[0]))+(od[11]*(xd[0]*xd[0])))+(od[12]*xd[0]))+od[13])-xd[1]); out[1] = (od[14]*a[0]); out[2] = (od[15]*a[1]); -out[3] = ((((real_t)(2.0000000000000000e+00)*od[1])+(real_t)(1.0000000000000000e+00))*((((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*a[2])+(od[15]*a[3])))/((od[14]+od[15])+(real_t)(1.0000000000000000e-04)))+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*a[4]))-xd[2])); -out[4] = (((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*(((od[2]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[3]*(xd[0]+xd[0])))+od[4]))+(od[15]*(((od[6]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[7]*(xd[0]+xd[0])))+od[8]))))*a[5])+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*(((od[10]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[11]*(xd[0]+xd[0])))+od[12]))); +out[3] = ((((real_t)(2.0000000000000000e+00)*od[1])+(real_t)(1.0000000000000000e+00))*(a[2]-xd[2])); +out[4] = (((od[10]*(((xd[0]+xd[0])*xd[0])+(xd[0]*xd[0])))+(od[11]*(xd[0]+xd[0])))+od[12]); out[5] = ((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00)); out[6] = (real_t)(0.0000000000000000e+00); out[7] = (real_t)(0.0000000000000000e+00); -out[8] = (od[14]*a[8]); -out[9] = (od[14]*a[9]); +out[8] = (od[14]*a[4]); +out[9] = (od[14]*a[5]); out[10] = (real_t)(0.0000000000000000e+00); out[11] = (real_t)(0.0000000000000000e+00); -out[12] = (od[15]*a[12]); -out[13] = (od[15]*a[13]); +out[12] = (od[15]*a[7]); +out[13] = (od[15]*a[8]); out[14] = (real_t)(0.0000000000000000e+00); out[15] = (real_t)(0.0000000000000000e+00); -out[16] = ((((real_t)(2.0000000000000000e+00)*od[1])+(real_t)(1.0000000000000000e+00))*(((((od[14]+od[15])-(od[14]*od[15]))*((od[14]*a[15])+(od[15]*a[17])))*a[18])+(((real_t)(1.0000000000000000e+00)-((od[14]+od[15])-(od[14]*od[15])))*a[20]))); +out[16] = ((((real_t)(2.0000000000000000e+00)*od[1])+(real_t)(1.0000000000000000e+00))*a[10]); out[17] = (real_t)(0.0000000000000000e+00); out[18] = ((((real_t)(2.0000000000000000e+00)*od[1])+(real_t)(1.0000000000000000e+00))*((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00))); out[19] = (real_t)(0.0000000000000000e+00); @@ -307,24 +286,23 @@ acadoWorkspace.objValueIn[1] = acadoVariables.x[runObj * 4 + 1]; acadoWorkspace.objValueIn[2] = acadoVariables.x[runObj * 4 + 2]; acadoWorkspace.objValueIn[3] = acadoVariables.x[runObj * 4 + 3]; acadoWorkspace.objValueIn[4] = acadoVariables.u[runObj]; -acadoWorkspace.objValueIn[5] = acadoVariables.od[runObj * 18]; -acadoWorkspace.objValueIn[6] = acadoVariables.od[runObj * 18 + 1]; -acadoWorkspace.objValueIn[7] = acadoVariables.od[runObj * 18 + 2]; -acadoWorkspace.objValueIn[8] = acadoVariables.od[runObj * 18 + 3]; -acadoWorkspace.objValueIn[9] = acadoVariables.od[runObj * 18 + 4]; -acadoWorkspace.objValueIn[10] = acadoVariables.od[runObj * 18 + 5]; -acadoWorkspace.objValueIn[11] = acadoVariables.od[runObj * 18 + 6]; -acadoWorkspace.objValueIn[12] = acadoVariables.od[runObj * 18 + 7]; -acadoWorkspace.objValueIn[13] = acadoVariables.od[runObj * 18 + 8]; -acadoWorkspace.objValueIn[14] = acadoVariables.od[runObj * 18 + 9]; -acadoWorkspace.objValueIn[15] = acadoVariables.od[runObj * 18 + 10]; -acadoWorkspace.objValueIn[16] = acadoVariables.od[runObj * 18 + 11]; -acadoWorkspace.objValueIn[17] = acadoVariables.od[runObj * 18 + 12]; -acadoWorkspace.objValueIn[18] = acadoVariables.od[runObj * 18 + 13]; -acadoWorkspace.objValueIn[19] = acadoVariables.od[runObj * 18 + 14]; -acadoWorkspace.objValueIn[20] = acadoVariables.od[runObj * 18 + 15]; -acadoWorkspace.objValueIn[21] = acadoVariables.od[runObj * 18 + 16]; -acadoWorkspace.objValueIn[22] = acadoVariables.od[runObj * 18 + 17]; +acadoWorkspace.objValueIn[5] = acadoVariables.od[runObj * 17]; +acadoWorkspace.objValueIn[6] = acadoVariables.od[runObj * 17 + 1]; +acadoWorkspace.objValueIn[7] = acadoVariables.od[runObj * 17 + 2]; +acadoWorkspace.objValueIn[8] = acadoVariables.od[runObj * 17 + 3]; +acadoWorkspace.objValueIn[9] = acadoVariables.od[runObj * 17 + 4]; +acadoWorkspace.objValueIn[10] = acadoVariables.od[runObj * 17 + 5]; +acadoWorkspace.objValueIn[11] = acadoVariables.od[runObj * 17 + 6]; +acadoWorkspace.objValueIn[12] = acadoVariables.od[runObj * 17 + 7]; +acadoWorkspace.objValueIn[13] = acadoVariables.od[runObj * 17 + 8]; +acadoWorkspace.objValueIn[14] = acadoVariables.od[runObj * 17 + 9]; +acadoWorkspace.objValueIn[15] = acadoVariables.od[runObj * 17 + 10]; +acadoWorkspace.objValueIn[16] = acadoVariables.od[runObj * 17 + 11]; +acadoWorkspace.objValueIn[17] = acadoVariables.od[runObj * 17 + 12]; +acadoWorkspace.objValueIn[18] = acadoVariables.od[runObj * 17 + 13]; +acadoWorkspace.objValueIn[19] = acadoVariables.od[runObj * 17 + 14]; +acadoWorkspace.objValueIn[20] = acadoVariables.od[runObj * 17 + 15]; +acadoWorkspace.objValueIn[21] = acadoVariables.od[runObj * 17 + 16]; acado_evaluateLSQ( acadoWorkspace.objValueIn, acadoWorkspace.objValueOut ); acadoWorkspace.Dy[runObj * 5] = acadoWorkspace.objValueOut[0]; @@ -342,24 +320,23 @@ acadoWorkspace.objValueIn[0] = acadoVariables.x[80]; acadoWorkspace.objValueIn[1] = acadoVariables.x[81]; acadoWorkspace.objValueIn[2] = acadoVariables.x[82]; acadoWorkspace.objValueIn[3] = acadoVariables.x[83]; -acadoWorkspace.objValueIn[4] = acadoVariables.od[360]; -acadoWorkspace.objValueIn[5] = acadoVariables.od[361]; -acadoWorkspace.objValueIn[6] = acadoVariables.od[362]; -acadoWorkspace.objValueIn[7] = acadoVariables.od[363]; -acadoWorkspace.objValueIn[8] = acadoVariables.od[364]; -acadoWorkspace.objValueIn[9] = acadoVariables.od[365]; -acadoWorkspace.objValueIn[10] = acadoVariables.od[366]; -acadoWorkspace.objValueIn[11] = acadoVariables.od[367]; -acadoWorkspace.objValueIn[12] = acadoVariables.od[368]; -acadoWorkspace.objValueIn[13] = acadoVariables.od[369]; -acadoWorkspace.objValueIn[14] = acadoVariables.od[370]; -acadoWorkspace.objValueIn[15] = acadoVariables.od[371]; -acadoWorkspace.objValueIn[16] = acadoVariables.od[372]; -acadoWorkspace.objValueIn[17] = acadoVariables.od[373]; -acadoWorkspace.objValueIn[18] = acadoVariables.od[374]; -acadoWorkspace.objValueIn[19] = acadoVariables.od[375]; -acadoWorkspace.objValueIn[20] = acadoVariables.od[376]; -acadoWorkspace.objValueIn[21] = acadoVariables.od[377]; +acadoWorkspace.objValueIn[4] = acadoVariables.od[340]; +acadoWorkspace.objValueIn[5] = acadoVariables.od[341]; +acadoWorkspace.objValueIn[6] = acadoVariables.od[342]; +acadoWorkspace.objValueIn[7] = acadoVariables.od[343]; +acadoWorkspace.objValueIn[8] = acadoVariables.od[344]; +acadoWorkspace.objValueIn[9] = acadoVariables.od[345]; +acadoWorkspace.objValueIn[10] = acadoVariables.od[346]; +acadoWorkspace.objValueIn[11] = acadoVariables.od[347]; +acadoWorkspace.objValueIn[12] = acadoVariables.od[348]; +acadoWorkspace.objValueIn[13] = acadoVariables.od[349]; +acadoWorkspace.objValueIn[14] = acadoVariables.od[350]; +acadoWorkspace.objValueIn[15] = acadoVariables.od[351]; +acadoWorkspace.objValueIn[16] = acadoVariables.od[352]; +acadoWorkspace.objValueIn[17] = acadoVariables.od[353]; +acadoWorkspace.objValueIn[18] = acadoVariables.od[354]; +acadoWorkspace.objValueIn[19] = acadoVariables.od[355]; +acadoWorkspace.objValueIn[20] = acadoVariables.od[356]; acado_evaluateLSQEndTerm( acadoWorkspace.objValueIn, acadoWorkspace.objValueOut ); acadoWorkspace.DyN[0] = acadoWorkspace.objValueOut[0]; @@ -4966,24 +4943,23 @@ acadoWorkspace.state[1] = acadoVariables.x[index * 4 + 1]; acadoWorkspace.state[2] = acadoVariables.x[index * 4 + 2]; acadoWorkspace.state[3] = acadoVariables.x[index * 4 + 3]; acadoWorkspace.state[24] = acadoVariables.u[index]; -acadoWorkspace.state[25] = acadoVariables.od[index * 18]; -acadoWorkspace.state[26] = acadoVariables.od[index * 18 + 1]; -acadoWorkspace.state[27] = acadoVariables.od[index * 18 + 2]; -acadoWorkspace.state[28] = acadoVariables.od[index * 18 + 3]; -acadoWorkspace.state[29] = acadoVariables.od[index * 18 + 4]; -acadoWorkspace.state[30] = acadoVariables.od[index * 18 + 5]; -acadoWorkspace.state[31] = acadoVariables.od[index * 18 + 6]; -acadoWorkspace.state[32] = acadoVariables.od[index * 18 + 7]; -acadoWorkspace.state[33] = acadoVariables.od[index * 18 + 8]; -acadoWorkspace.state[34] = acadoVariables.od[index * 18 + 9]; -acadoWorkspace.state[35] = acadoVariables.od[index * 18 + 10]; -acadoWorkspace.state[36] = acadoVariables.od[index * 18 + 11]; -acadoWorkspace.state[37] = acadoVariables.od[index * 18 + 12]; -acadoWorkspace.state[38] = acadoVariables.od[index * 18 + 13]; -acadoWorkspace.state[39] = acadoVariables.od[index * 18 + 14]; -acadoWorkspace.state[40] = acadoVariables.od[index * 18 + 15]; -acadoWorkspace.state[41] = acadoVariables.od[index * 18 + 16]; -acadoWorkspace.state[42] = acadoVariables.od[index * 18 + 17]; +acadoWorkspace.state[25] = acadoVariables.od[index * 17]; +acadoWorkspace.state[26] = acadoVariables.od[index * 17 + 1]; +acadoWorkspace.state[27] = acadoVariables.od[index * 17 + 2]; +acadoWorkspace.state[28] = acadoVariables.od[index * 17 + 3]; +acadoWorkspace.state[29] = acadoVariables.od[index * 17 + 4]; +acadoWorkspace.state[30] = acadoVariables.od[index * 17 + 5]; +acadoWorkspace.state[31] = acadoVariables.od[index * 17 + 6]; +acadoWorkspace.state[32] = acadoVariables.od[index * 17 + 7]; +acadoWorkspace.state[33] = acadoVariables.od[index * 17 + 8]; +acadoWorkspace.state[34] = acadoVariables.od[index * 17 + 9]; +acadoWorkspace.state[35] = acadoVariables.od[index * 17 + 10]; +acadoWorkspace.state[36] = acadoVariables.od[index * 17 + 11]; +acadoWorkspace.state[37] = acadoVariables.od[index * 17 + 12]; +acadoWorkspace.state[38] = acadoVariables.od[index * 17 + 13]; +acadoWorkspace.state[39] = acadoVariables.od[index * 17 + 14]; +acadoWorkspace.state[40] = acadoVariables.od[index * 17 + 15]; +acadoWorkspace.state[41] = acadoVariables.od[index * 17 + 16]; acado_integrate(acadoWorkspace.state, index == 0, index); @@ -5026,24 +5002,23 @@ else { acadoWorkspace.state[24] = acadoVariables.u[19]; } -acadoWorkspace.state[25] = acadoVariables.od[360]; -acadoWorkspace.state[26] = acadoVariables.od[361]; -acadoWorkspace.state[27] = acadoVariables.od[362]; -acadoWorkspace.state[28] = acadoVariables.od[363]; -acadoWorkspace.state[29] = acadoVariables.od[364]; -acadoWorkspace.state[30] = acadoVariables.od[365]; -acadoWorkspace.state[31] = acadoVariables.od[366]; -acadoWorkspace.state[32] = acadoVariables.od[367]; -acadoWorkspace.state[33] = acadoVariables.od[368]; -acadoWorkspace.state[34] = acadoVariables.od[369]; -acadoWorkspace.state[35] = acadoVariables.od[370]; -acadoWorkspace.state[36] = acadoVariables.od[371]; -acadoWorkspace.state[37] = acadoVariables.od[372]; -acadoWorkspace.state[38] = acadoVariables.od[373]; -acadoWorkspace.state[39] = acadoVariables.od[374]; -acadoWorkspace.state[40] = acadoVariables.od[375]; -acadoWorkspace.state[41] = acadoVariables.od[376]; -acadoWorkspace.state[42] = acadoVariables.od[377]; +acadoWorkspace.state[25] = acadoVariables.od[340]; +acadoWorkspace.state[26] = acadoVariables.od[341]; +acadoWorkspace.state[27] = acadoVariables.od[342]; +acadoWorkspace.state[28] = acadoVariables.od[343]; +acadoWorkspace.state[29] = acadoVariables.od[344]; +acadoWorkspace.state[30] = acadoVariables.od[345]; +acadoWorkspace.state[31] = acadoVariables.od[346]; +acadoWorkspace.state[32] = acadoVariables.od[347]; +acadoWorkspace.state[33] = acadoVariables.od[348]; +acadoWorkspace.state[34] = acadoVariables.od[349]; +acadoWorkspace.state[35] = acadoVariables.od[350]; +acadoWorkspace.state[36] = acadoVariables.od[351]; +acadoWorkspace.state[37] = acadoVariables.od[352]; +acadoWorkspace.state[38] = acadoVariables.od[353]; +acadoWorkspace.state[39] = acadoVariables.od[354]; +acadoWorkspace.state[40] = acadoVariables.od[355]; +acadoWorkspace.state[41] = acadoVariables.od[356]; acado_integrate(acadoWorkspace.state, 1, 19); @@ -5114,24 +5089,23 @@ acadoWorkspace.objValueIn[1] = acadoVariables.x[lRun1 * 4 + 1]; acadoWorkspace.objValueIn[2] = acadoVariables.x[lRun1 * 4 + 2]; acadoWorkspace.objValueIn[3] = acadoVariables.x[lRun1 * 4 + 3]; acadoWorkspace.objValueIn[4] = acadoVariables.u[lRun1]; -acadoWorkspace.objValueIn[5] = acadoVariables.od[lRun1 * 18]; -acadoWorkspace.objValueIn[6] = acadoVariables.od[lRun1 * 18 + 1]; -acadoWorkspace.objValueIn[7] = acadoVariables.od[lRun1 * 18 + 2]; -acadoWorkspace.objValueIn[8] = acadoVariables.od[lRun1 * 18 + 3]; -acadoWorkspace.objValueIn[9] = acadoVariables.od[lRun1 * 18 + 4]; -acadoWorkspace.objValueIn[10] = acadoVariables.od[lRun1 * 18 + 5]; -acadoWorkspace.objValueIn[11] = acadoVariables.od[lRun1 * 18 + 6]; -acadoWorkspace.objValueIn[12] = acadoVariables.od[lRun1 * 18 + 7]; -acadoWorkspace.objValueIn[13] = acadoVariables.od[lRun1 * 18 + 8]; -acadoWorkspace.objValueIn[14] = acadoVariables.od[lRun1 * 18 + 9]; -acadoWorkspace.objValueIn[15] = acadoVariables.od[lRun1 * 18 + 10]; -acadoWorkspace.objValueIn[16] = acadoVariables.od[lRun1 * 18 + 11]; -acadoWorkspace.objValueIn[17] = acadoVariables.od[lRun1 * 18 + 12]; -acadoWorkspace.objValueIn[18] = acadoVariables.od[lRun1 * 18 + 13]; -acadoWorkspace.objValueIn[19] = acadoVariables.od[lRun1 * 18 + 14]; -acadoWorkspace.objValueIn[20] = acadoVariables.od[lRun1 * 18 + 15]; -acadoWorkspace.objValueIn[21] = acadoVariables.od[lRun1 * 18 + 16]; -acadoWorkspace.objValueIn[22] = acadoVariables.od[lRun1 * 18 + 17]; +acadoWorkspace.objValueIn[5] = acadoVariables.od[lRun1 * 17]; +acadoWorkspace.objValueIn[6] = acadoVariables.od[lRun1 * 17 + 1]; +acadoWorkspace.objValueIn[7] = acadoVariables.od[lRun1 * 17 + 2]; +acadoWorkspace.objValueIn[8] = acadoVariables.od[lRun1 * 17 + 3]; +acadoWorkspace.objValueIn[9] = acadoVariables.od[lRun1 * 17 + 4]; +acadoWorkspace.objValueIn[10] = acadoVariables.od[lRun1 * 17 + 5]; +acadoWorkspace.objValueIn[11] = acadoVariables.od[lRun1 * 17 + 6]; +acadoWorkspace.objValueIn[12] = acadoVariables.od[lRun1 * 17 + 7]; +acadoWorkspace.objValueIn[13] = acadoVariables.od[lRun1 * 17 + 8]; +acadoWorkspace.objValueIn[14] = acadoVariables.od[lRun1 * 17 + 9]; +acadoWorkspace.objValueIn[15] = acadoVariables.od[lRun1 * 17 + 10]; +acadoWorkspace.objValueIn[16] = acadoVariables.od[lRun1 * 17 + 11]; +acadoWorkspace.objValueIn[17] = acadoVariables.od[lRun1 * 17 + 12]; +acadoWorkspace.objValueIn[18] = acadoVariables.od[lRun1 * 17 + 13]; +acadoWorkspace.objValueIn[19] = acadoVariables.od[lRun1 * 17 + 14]; +acadoWorkspace.objValueIn[20] = acadoVariables.od[lRun1 * 17 + 15]; +acadoWorkspace.objValueIn[21] = acadoVariables.od[lRun1 * 17 + 16]; acado_evaluateLSQ( acadoWorkspace.objValueIn, acadoWorkspace.objValueOut ); acadoWorkspace.Dy[lRun1 * 5] = acadoWorkspace.objValueOut[0] - acadoVariables.y[lRun1 * 5]; @@ -5144,24 +5118,23 @@ acadoWorkspace.objValueIn[0] = acadoVariables.x[80]; acadoWorkspace.objValueIn[1] = acadoVariables.x[81]; acadoWorkspace.objValueIn[2] = acadoVariables.x[82]; acadoWorkspace.objValueIn[3] = acadoVariables.x[83]; -acadoWorkspace.objValueIn[4] = acadoVariables.od[360]; -acadoWorkspace.objValueIn[5] = acadoVariables.od[361]; -acadoWorkspace.objValueIn[6] = acadoVariables.od[362]; -acadoWorkspace.objValueIn[7] = acadoVariables.od[363]; -acadoWorkspace.objValueIn[8] = acadoVariables.od[364]; -acadoWorkspace.objValueIn[9] = acadoVariables.od[365]; -acadoWorkspace.objValueIn[10] = acadoVariables.od[366]; -acadoWorkspace.objValueIn[11] = acadoVariables.od[367]; -acadoWorkspace.objValueIn[12] = acadoVariables.od[368]; -acadoWorkspace.objValueIn[13] = acadoVariables.od[369]; -acadoWorkspace.objValueIn[14] = acadoVariables.od[370]; -acadoWorkspace.objValueIn[15] = acadoVariables.od[371]; -acadoWorkspace.objValueIn[16] = acadoVariables.od[372]; -acadoWorkspace.objValueIn[17] = acadoVariables.od[373]; -acadoWorkspace.objValueIn[18] = acadoVariables.od[374]; -acadoWorkspace.objValueIn[19] = acadoVariables.od[375]; -acadoWorkspace.objValueIn[20] = acadoVariables.od[376]; -acadoWorkspace.objValueIn[21] = acadoVariables.od[377]; +acadoWorkspace.objValueIn[4] = acadoVariables.od[340]; +acadoWorkspace.objValueIn[5] = acadoVariables.od[341]; +acadoWorkspace.objValueIn[6] = acadoVariables.od[342]; +acadoWorkspace.objValueIn[7] = acadoVariables.od[343]; +acadoWorkspace.objValueIn[8] = acadoVariables.od[344]; +acadoWorkspace.objValueIn[9] = acadoVariables.od[345]; +acadoWorkspace.objValueIn[10] = acadoVariables.od[346]; +acadoWorkspace.objValueIn[11] = acadoVariables.od[347]; +acadoWorkspace.objValueIn[12] = acadoVariables.od[348]; +acadoWorkspace.objValueIn[13] = acadoVariables.od[349]; +acadoWorkspace.objValueIn[14] = acadoVariables.od[350]; +acadoWorkspace.objValueIn[15] = acadoVariables.od[351]; +acadoWorkspace.objValueIn[16] = acadoVariables.od[352]; +acadoWorkspace.objValueIn[17] = acadoVariables.od[353]; +acadoWorkspace.objValueIn[18] = acadoVariables.od[354]; +acadoWorkspace.objValueIn[19] = acadoVariables.od[355]; +acadoWorkspace.objValueIn[20] = acadoVariables.od[356]; acado_evaluateLSQEndTerm( acadoWorkspace.objValueIn, acadoWorkspace.objValueOut ); acadoWorkspace.DyN[0] = acadoWorkspace.objValueOut[0] - acadoVariables.yN[0]; acadoWorkspace.DyN[1] = acadoWorkspace.objValueOut[1] - acadoVariables.yN[1]; diff --git a/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_solver.o b/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_solver.o index f91ea40ab5e655..5814de21e521ec 100644 Binary files a/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_solver.o and b/selfdrive/controls/lib/lateral_mpc/lib_mpc_export/acado_solver.o differ diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/Bounds.d b/selfdrive/controls/lib/lateral_mpc/lib_qp/Bounds.d deleted file mode 100644 index 752ec5e9f3c686..00000000000000 --- a/selfdrive/controls/lib/lateral_mpc/lib_qp/Bounds.d +++ /dev/null @@ -1,14 +0,0 @@ -lib_qp/Bounds.o: ../../../../phonelibs/qpoases/SRC/Bounds.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/Bounds.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/SubjectTo.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Indexlist.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/Indexlist.ipp \ - ../../../../phonelibs/qpoases/SRC/SubjectTo.ipp \ - ../../../../phonelibs/qpoases/SRC/Bounds.ipp diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/Bounds.o b/selfdrive/controls/lib/lateral_mpc/lib_qp/Bounds.o deleted file mode 100644 index ba30572669f57d..00000000000000 Binary files a/selfdrive/controls/lib/lateral_mpc/lib_qp/Bounds.o and /dev/null differ diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/Constraints.d b/selfdrive/controls/lib/lateral_mpc/lib_qp/Constraints.d deleted file mode 100644 index 60295bc07b3dc9..00000000000000 --- a/selfdrive/controls/lib/lateral_mpc/lib_qp/Constraints.d +++ /dev/null @@ -1,14 +0,0 @@ -lib_qp/Constraints.o: ../../../../phonelibs/qpoases/SRC/Constraints.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constraints.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/SubjectTo.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Indexlist.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/Indexlist.ipp \ - ../../../../phonelibs/qpoases/SRC/SubjectTo.ipp \ - ../../../../phonelibs/qpoases/SRC/Constraints.ipp diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/Constraints.o b/selfdrive/controls/lib/lateral_mpc/lib_qp/Constraints.o deleted file mode 100644 index d892c668667029..00000000000000 Binary files a/selfdrive/controls/lib/lateral_mpc/lib_qp/Constraints.o and /dev/null differ diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/CyclingManager.d b/selfdrive/controls/lib/lateral_mpc/lib_qp/CyclingManager.d deleted file mode 100644 index 24145d8ed318e1..00000000000000 --- a/selfdrive/controls/lib/lateral_mpc/lib_qp/CyclingManager.d +++ /dev/null @@ -1,11 +0,0 @@ -lib_qp/CyclingManager.o: \ - ../../../../phonelibs/qpoases/SRC/CyclingManager.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/CyclingManager.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/CyclingManager.ipp diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/CyclingManager.o b/selfdrive/controls/lib/lateral_mpc/lib_qp/CyclingManager.o deleted file mode 100644 index 685e25d56b0c62..00000000000000 Binary files a/selfdrive/controls/lib/lateral_mpc/lib_qp/CyclingManager.o and /dev/null differ diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/EXTRAS/SolutionAnalysis.d b/selfdrive/controls/lib/lateral_mpc/lib_qp/EXTRAS/SolutionAnalysis.d deleted file mode 100644 index 77c09376eef96e..00000000000000 --- a/selfdrive/controls/lib/lateral_mpc/lib_qp/EXTRAS/SolutionAnalysis.d +++ /dev/null @@ -1,24 +0,0 @@ -lib_qp/EXTRAS/SolutionAnalysis.o: \ - ../../../../phonelibs/qpoases/SRC/EXTRAS/SolutionAnalysis.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/EXTRAS/SolutionAnalysis.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/QProblem.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/QProblemB.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Bounds.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/SubjectTo.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Indexlist.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/Indexlist.ipp \ - ../../../../phonelibs/qpoases/SRC/SubjectTo.ipp \ - ../../../../phonelibs/qpoases/SRC/Bounds.ipp \ - ../../../../phonelibs/qpoases/SRC/QProblemB.ipp \ - ../../../../phonelibs/qpoases/INCLUDE/Constraints.hpp \ - ../../../../phonelibs/qpoases/SRC/Constraints.ipp \ - ../../../../phonelibs/qpoases/INCLUDE/CyclingManager.hpp \ - ../../../../phonelibs/qpoases/SRC/CyclingManager.ipp \ - ../../../../phonelibs/qpoases/SRC/QProblem.ipp diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/EXTRAS/SolutionAnalysis.o b/selfdrive/controls/lib/lateral_mpc/lib_qp/EXTRAS/SolutionAnalysis.o deleted file mode 100644 index 987f1e56361641..00000000000000 Binary files a/selfdrive/controls/lib/lateral_mpc/lib_qp/EXTRAS/SolutionAnalysis.o and /dev/null differ diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/Indexlist.d b/selfdrive/controls/lib/lateral_mpc/lib_qp/Indexlist.d deleted file mode 100644 index 6ead64cb9d8ee6..00000000000000 --- a/selfdrive/controls/lib/lateral_mpc/lib_qp/Indexlist.d +++ /dev/null @@ -1,10 +0,0 @@ -lib_qp/Indexlist.o: ../../../../phonelibs/qpoases/SRC/Indexlist.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/Indexlist.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/Indexlist.ipp diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/Indexlist.o b/selfdrive/controls/lib/lateral_mpc/lib_qp/Indexlist.o deleted file mode 100644 index bd77188d453aae..00000000000000 Binary files a/selfdrive/controls/lib/lateral_mpc/lib_qp/Indexlist.o and /dev/null differ diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/MessageHandling.d b/selfdrive/controls/lib/lateral_mpc/lib_qp/MessageHandling.d deleted file mode 100644 index b5c6166aba1f64..00000000000000 --- a/selfdrive/controls/lib/lateral_mpc/lib_qp/MessageHandling.d +++ /dev/null @@ -1,9 +0,0 @@ -lib_qp/MessageHandling.o: \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/MessageHandling.o b/selfdrive/controls/lib/lateral_mpc/lib_qp/MessageHandling.o deleted file mode 100644 index 87b200d0475adb..00000000000000 Binary files a/selfdrive/controls/lib/lateral_mpc/lib_qp/MessageHandling.o and /dev/null differ diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/QProblem.d b/selfdrive/controls/lib/lateral_mpc/lib_qp/QProblem.d deleted file mode 100644 index 1f6e188af55c17..00000000000000 --- a/selfdrive/controls/lib/lateral_mpc/lib_qp/QProblem.d +++ /dev/null @@ -1,22 +0,0 @@ -lib_qp/QProblem.o: ../../../../phonelibs/qpoases/SRC/QProblem.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/QProblem.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/QProblemB.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Bounds.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/SubjectTo.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Indexlist.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/Indexlist.ipp \ - ../../../../phonelibs/qpoases/SRC/SubjectTo.ipp \ - ../../../../phonelibs/qpoases/SRC/Bounds.ipp \ - ../../../../phonelibs/qpoases/SRC/QProblemB.ipp \ - ../../../../phonelibs/qpoases/INCLUDE/Constraints.hpp \ - ../../../../phonelibs/qpoases/SRC/Constraints.ipp \ - ../../../../phonelibs/qpoases/INCLUDE/CyclingManager.hpp \ - ../../../../phonelibs/qpoases/SRC/CyclingManager.ipp \ - ../../../../phonelibs/qpoases/SRC/QProblem.ipp diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/QProblem.o b/selfdrive/controls/lib/lateral_mpc/lib_qp/QProblem.o deleted file mode 100644 index 8c179beae1dc8f..00000000000000 Binary files a/selfdrive/controls/lib/lateral_mpc/lib_qp/QProblem.o and /dev/null differ diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/QProblemB.d b/selfdrive/controls/lib/lateral_mpc/lib_qp/QProblemB.d deleted file mode 100644 index 7878a825ce5749..00000000000000 --- a/selfdrive/controls/lib/lateral_mpc/lib_qp/QProblemB.d +++ /dev/null @@ -1,16 +0,0 @@ -lib_qp/QProblemB.o: ../../../../phonelibs/qpoases/SRC/QProblemB.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/QProblemB.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Bounds.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/SubjectTo.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Indexlist.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/Indexlist.ipp \ - ../../../../phonelibs/qpoases/SRC/SubjectTo.ipp \ - ../../../../phonelibs/qpoases/SRC/Bounds.ipp \ - ../../../../phonelibs/qpoases/SRC/QProblemB.ipp diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/QProblemB.o b/selfdrive/controls/lib/lateral_mpc/lib_qp/QProblemB.o deleted file mode 100644 index 9c75cb83225246..00000000000000 Binary files a/selfdrive/controls/lib/lateral_mpc/lib_qp/QProblemB.o and /dev/null differ diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/SubjectTo.d b/selfdrive/controls/lib/lateral_mpc/lib_qp/SubjectTo.d deleted file mode 100644 index c896d9a9faf58d..00000000000000 --- a/selfdrive/controls/lib/lateral_mpc/lib_qp/SubjectTo.d +++ /dev/null @@ -1,12 +0,0 @@ -lib_qp/SubjectTo.o: ../../../../phonelibs/qpoases/SRC/SubjectTo.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/SubjectTo.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Indexlist.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/Indexlist.ipp \ - ../../../../phonelibs/qpoases/SRC/SubjectTo.ipp diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/SubjectTo.o b/selfdrive/controls/lib/lateral_mpc/lib_qp/SubjectTo.o deleted file mode 100644 index 820c930ce31ec4..00000000000000 Binary files a/selfdrive/controls/lib/lateral_mpc/lib_qp/SubjectTo.o and /dev/null differ diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/Utils.d b/selfdrive/controls/lib/lateral_mpc/lib_qp/Utils.d deleted file mode 100644 index 58f35a065397a3..00000000000000 --- a/selfdrive/controls/lib/lateral_mpc/lib_qp/Utils.d +++ /dev/null @@ -1,8 +0,0 @@ -lib_qp/Utils.o: ../../../../phonelibs/qpoases/SRC/Utils.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp diff --git a/selfdrive/controls/lib/lateral_mpc/lib_qp/Utils.o b/selfdrive/controls/lib/lateral_mpc/lib_qp/Utils.o deleted file mode 100644 index ef645ef188049f..00000000000000 Binary files a/selfdrive/controls/lib/lateral_mpc/lib_qp/Utils.o and /dev/null differ diff --git a/selfdrive/controls/lib/lateral_mpc/libmpc.so b/selfdrive/controls/lib/lateral_mpc/libmpc.so index 3fd13255020c98..fd6ee2d482a435 100755 Binary files a/selfdrive/controls/lib/lateral_mpc/libmpc.so and b/selfdrive/controls/lib/lateral_mpc/libmpc.so differ diff --git a/selfdrive/controls/lib/lateral_mpc/libmpc_py.py b/selfdrive/controls/lib/lateral_mpc/libmpc_py.py index 3af46c304e7f18..92c0df8da4b729 100644 --- a/selfdrive/controls/lib/lateral_mpc/libmpc_py.py +++ b/selfdrive/controls/lib/lateral_mpc/libmpc_py.py @@ -18,14 +18,14 @@ double y[21]; double psi[21]; double delta[21]; - double rate[21]; + double rate[20]; double cost; } log_t; void init(double pathCost, double laneCost, double headingCost, double steerRateCost); int run_mpc(state_t * x0, log_t * solution, - double l_poly[4], double r_poly[4], double p_poly[4], - double l_prob, double r_prob, double p_prob, double curvature_factor, double v_ref, double lane_width); + double l_poly[4], double r_poly[4], double d_poly[4], + double l_prob, double r_prob, double curvature_factor, double v_ref, double lane_width); """) libmpc = ffi.dlopen(libmpc_fn) diff --git a/selfdrive/controls/lib/long_mpc.py b/selfdrive/controls/lib/long_mpc.py index 19fb706debb2d7..4c71683096e3aa 100644 --- a/selfdrive/controls/lib/long_mpc.py +++ b/selfdrive/controls/lib/long_mpc.py @@ -1,4 +1,5 @@ -import numpy as np +import os +import math import selfdrive.messaging as messaging from selfdrive.swaglog import cloudlog @@ -7,10 +8,11 @@ from selfdrive.controls.lib.longitudinal_mpc import libmpc_py from selfdrive.controls.lib.drive_helpers import MPC_COST_LONG +LOG_MPC = os.environ.get('LOG_MPC', False) -class LongitudinalMpc(object): - def __init__(self, mpc_id, live_longitudinal_mpc): - self.live_longitudinal_mpc = live_longitudinal_mpc + +class LongitudinalMpc(): + def __init__(self, mpc_id): self.mpc_id = mpc_id self.setup_mpc() @@ -24,7 +26,7 @@ def __init__(self, mpc_id, live_longitudinal_mpc): self.last_cloudlog_t = 0.0 - def send_mpc_solution(self, qp_iterations, calculation_time): + def send_mpc_solution(self, pm, qp_iterations, calculation_time): qp_iterations = max(0, qp_iterations) dat = messaging.new_message() dat.init('liveLongitudinalMpc') @@ -38,7 +40,7 @@ def send_mpc_solution(self, qp_iterations, calculation_time): dat.liveLongitudinalMpc.qpIterations = qp_iterations dat.liveLongitudinalMpc.mpcId = self.mpc_id dat.liveLongitudinalMpc.calculationTime = calculation_time - self.live_longitudinal_mpc.send(dat.to_bytes()) + pm.send('liveLongitudinalMpc', dat) def setup_mpc(self): ffi, self.libmpc = libmpc_py.get_libmpc(self.mpc_id) @@ -55,8 +57,8 @@ def set_cur_state(self, v, a): self.cur_state[0].v_ego = v self.cur_state[0].a_ego = a - def update(self, CS, lead, v_cruise_setpoint): - v_ego = CS.carState.vEgo + def update(self, pm, CS, lead, v_cruise_setpoint): + v_ego = CS.vEgo # Setup current mpc state self.cur_state[0].x_ego = 0.0 @@ -92,7 +94,9 @@ def update(self, CS, lead, v_cruise_setpoint): t = sec_since_boot() n_its = self.libmpc.run_mpc(self.cur_state, self.mpc_solution, self.a_lead_tau, a_lead) duration = int((sec_since_boot() - t) * 1e9) - self.send_mpc_solution(n_its, duration) + + if LOG_MPC: + self.send_mpc_solution(pm, n_its, duration) # Get solution. MPC timestep is 0.2 s, so interpolation to 0.05 s is needed self.v_mpc = self.mpc_solution[0].v_ego[1] @@ -100,10 +104,9 @@ def update(self, CS, lead, v_cruise_setpoint): self.v_mpc_future = self.mpc_solution[0].v_ego[10] # Reset if NaN or goes through lead car - dls = np.array(list(self.mpc_solution[0].x_l)) - np.array(list(self.mpc_solution[0].x_ego)) - crashing = min(dls) < -50.0 - nans = np.any(np.isnan(list(self.mpc_solution[0].v_ego))) - backwards = min(list(self.mpc_solution[0].v_ego)) < -0.01 + crashing = any(lead - ego < -50 for (lead, ego) in zip(self.mpc_solution[0].x_l, self.mpc_solution[0].x_ego)) + nans = any(math.isnan(x) for x in self.mpc_solution[0].v_ego) + backwards = min(self.mpc_solution[0].v_ego) < -0.01 if ((backwards or crashing) and self.prev_lead_status) or nans: if t > self.last_cloudlog_t + 5.0: @@ -116,5 +119,5 @@ def update(self, CS, lead, v_cruise_setpoint): self.cur_state[0].v_ego = v_ego self.cur_state[0].a_ego = 0.0 self.v_mpc = v_ego - self.a_mpc = CS.carState.aEgo + self.a_mpc = CS.aEgo self.prev_lead_status = False diff --git a/selfdrive/controls/lib/longcontrol.py b/selfdrive/controls/lib/longcontrol.py index da324a39a10759..8910747cdbaaf1 100644 --- a/selfdrive/controls/lib/longcontrol.py +++ b/selfdrive/controls/lib/longcontrol.py @@ -2,7 +2,7 @@ from common.numpy_fast import clip, interp from selfdrive.controls.lib.pid import PIController -LongCtrlState = log.Live100Data.LongControlState +LongCtrlState = log.ControlsState.LongControlState STOPPING_EGO_SPEED = 0.5 MIN_CAN_SPEED = 0.3 # TODO: parametrize this in car interface @@ -55,11 +55,11 @@ def long_control_state_trans(active, long_control_state, v_ego, v_target, v_pid, return long_control_state -class LongControl(object): +class LongControl(): def __init__(self, CP, compute_gb): self.long_control_state = LongCtrlState.off # initialized to off - self.pid = PIController((CP.longitudinalKpBP, CP.longitudinalKpV), - (CP.longitudinalKiBP, CP.longitudinalKiV), + self.pid = PIController((CP.longitudinalTuning.kpBP, CP.longitudinalTuning.kpV), + (CP.longitudinalTuning.kiBP, CP.longitudinalTuning.kiV), rate=RATE, sat_limit=0.8, convert=compute_gb) @@ -99,7 +99,7 @@ def update(self, active, v_ego, brake_pressed, standstill, cruise_standstill, v_ # Toyota starts braking more when it thinks you want to stop # Freeze the integrator so we don't accelerate to compensate, and don't allow positive acceleration prevent_overshoot = not CP.stoppingControl and v_ego < 1.5 and v_target_future < 0.7 - deadzone = interp(v_ego_pid, CP.longPidDeadzoneBP, CP.longPidDeadzoneV) + deadzone = interp(v_ego_pid, CP.longitudinalTuning.deadzoneBP, CP.longitudinalTuning.deadzoneV) output_gb = self.pid.update(self.v_pid, v_ego_pid, speed=v_ego_pid, deadzone=deadzone, feedforward=a_target, freeze_integrator=prevent_overshoot) diff --git a/selfdrive/controls/lib/longitudinal_mpc/Makefile b/selfdrive/controls/lib/longitudinal_mpc/Makefile index 17f78eada990df..e00914c2147005 100644 --- a/selfdrive/controls/lib/longitudinal_mpc/Makefile +++ b/selfdrive/controls/lib/longitudinal_mpc/Makefile @@ -14,11 +14,13 @@ QPOASES_FLAGS = -I$(PHONELIBS)/qpoases -I$(PHONELIBS)/qpoases/INCLUDE -I$(PHONEL ACADO_FLAGS = -I$(PHONELIBS)/acado/include -I$(PHONELIBS)/acado/include/acado ifeq ($(UNAME_S),Darwin) - ACADO_LIBS := -lacado_toolkit_s +ACADO_LIBS := -lacado_toolkit_s else ifeq ($(UNAME_M),aarch64) - ACADO_LIBS := -L $(PHONELIBS)/acado/aarch64/lib -l:libacado_toolkit.a -l:libacado_casadi.a -l:libacado_csparse.a +ACADO_LIBS := -L $(PHONELIBS)/acado/aarch64/lib -l:libacado_toolkit.a -l:libacado_casadi.a -l:libacado_csparse.a +CFLAGS += -mcpu=cortex-a57 +CXXFLAGS += -mcpu=cortex-a57 else - ACADO_LIBS := -L $(PHONELIBS)/acado/x64/lib -l:libacado_toolkit.a -l:libacado_casadi.a -l:libacado_csparse.a +ACADO_LIBS := -L $(PHONELIBS)/acado/x64/lib -l:libacado_toolkit.a -l:libacado_casadi.a -l:libacado_csparse.a endif OBJS = \ diff --git a/selfdrive/controls/lib/longitudinal_mpc/generator.cpp b/selfdrive/controls/lib/longitudinal_mpc/generator.cpp index 1f0e28d0057081..a34fbc3510b6ed 100644 --- a/selfdrive/controls/lib/longitudinal_mpc/generator.cpp +++ b/selfdrive/controls/lib/longitudinal_mpc/generator.cpp @@ -32,7 +32,7 @@ int main( ) // Running cost Function h; - h << exp(0.3 * NORM_RW_ERROR(v_ego, v_l, d_l)); + h << exp(0.3 * NORM_RW_ERROR(v_ego, v_l, d_l)) - 1; h << (d_l - desired) / (0.05 * v_ego + 0.5); h << a_ego * (0.1 * v_ego + 1.0); h << j_ego * (0.1 * v_ego + 1.0); @@ -42,7 +42,7 @@ int main( ) // Terminal cost Function hN; - hN << exp(0.3 * NORM_RW_ERROR(v_ego, v_l, d_l)); + hN << exp(0.3 * NORM_RW_ERROR(v_ego, v_l, d_l)) - 1; hN << (d_l - desired) / (0.05 * v_ego + 0.5); hN << a_ego * (0.1 * v_ego + 1.0); diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_auxiliary_functions.o b/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_auxiliary_functions.o index 5466ca143bdeea..ac07de5818586f 100644 Binary files a/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_auxiliary_functions.o and b/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_auxiliary_functions.o differ diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_common.h b/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_common.h index bf64887f19c092..c0eb83bced374f 100644 --- a/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_common.h +++ b/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_common.h @@ -181,8 +181,8 @@ real_t evGx[ 180 ]; /** Column vector of size: 60 */ real_t evGu[ 60 ]; -/** Column vector of size: 15 */ -real_t objAuxVar[ 15 ]; +/** Column vector of size: 13 */ +real_t objAuxVar[ 13 ]; /** Row vector of size: 6 */ real_t objValueIn[ 6 ]; diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_integrator.o b/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_integrator.o index 2ee2d13004acdc..f936c84557c3fe 100644 Binary files a/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_integrator.o and b/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_integrator.o differ diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_qpoases_interface.o b/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_qpoases_interface.o index 21293576928754..946f501e778d6b 100644 Binary files a/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_qpoases_interface.o and b/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_qpoases_interface.o differ diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_solver.c b/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_solver.c index e4bf392f98fb30..8cfc06f3b8ef70 100644 --- a/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_solver.c +++ b/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_solver.c @@ -73,7 +73,7 @@ void acado_evaluateLSQ(const real_t* in, real_t* out) const real_t* xd = in; const real_t* u = in + 3; const real_t* od = in + 4; -/* Vector of auxiliary variables; number of elements: 15. */ +/* Vector of auxiliary variables; number of elements: 13. */ real_t* a = acadoWorkspace.objAuxVar; /* Compute intermediate quantities: */ @@ -87,22 +87,20 @@ a[6] = (1.0/sqrt((xd[1]+(real_t)(5.0000000000000000e-01)))); a[7] = (a[6]*(real_t)(5.0000000000000000e-01)); a[8] = (a[2]*a[2]); a[9] = (((real_t)(2.9999999999999999e-01)*(((((real_t)(1.8000000000000000e+00)-((real_t)(-1.8000000000000000e+00)))+((xd[1]+xd[1])*a[5]))*a[2])-((((((((xd[1]*(real_t)(1.8000000000000000e+00))-((od[1]-xd[1])*(real_t)(1.8000000000000000e+00)))+((xd[1]*xd[1])/(real_t)(1.9620000000000001e+01)))-((od[1]*od[1])/(real_t)(1.9620000000000001e+01)))+(real_t)(4.0000000000000000e+00))-(od[0]-xd[0]))*a[7])*a[8])))*a[3]); -a[10] = (real_t)(0.0000000000000000e+00); -a[11] = ((real_t)(1.0000000000000000e+00)/(((real_t)(5.0000000000000003e-02)*xd[1])+(real_t)(5.0000000000000000e-01))); -a[12] = ((real_t)(1.0000000000000000e+00)/(real_t)(1.9620000000000001e+01)); -a[13] = (a[11]*a[11]); -a[14] = (real_t)(0.0000000000000000e+00); +a[10] = ((real_t)(1.0000000000000000e+00)/(((real_t)(5.0000000000000003e-02)*xd[1])+(real_t)(5.0000000000000000e-01))); +a[11] = ((real_t)(1.0000000000000000e+00)/(real_t)(1.9620000000000001e+01)); +a[12] = (a[10]*a[10]); /* Compute outputs: */ -out[0] = a[1]; +out[0] = (a[1]-(real_t)(1.0000000000000000e+00)); out[1] = (((od[0]-xd[0])-((real_t)(4.0000000000000000e+00)+((((xd[1]*(real_t)(1.8000000000000000e+00))-((od[1]-xd[1])*(real_t)(1.8000000000000000e+00)))+((xd[1]*xd[1])/(real_t)(1.9620000000000001e+01)))-((od[1]*od[1])/(real_t)(1.9620000000000001e+01)))))/(((real_t)(5.0000000000000003e-02)*xd[1])+(real_t)(5.0000000000000000e-01))); out[2] = (xd[2]*(((real_t)(1.0000000000000001e-01)*xd[1])+(real_t)(1.0000000000000000e+00))); out[3] = (u[0]*(((real_t)(1.0000000000000001e-01)*xd[1])+(real_t)(1.0000000000000000e+00))); out[4] = a[4]; out[5] = a[9]; -out[6] = a[10]; -out[7] = (((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00))*a[11]); -out[8] = ((((real_t)(0.0000000000000000e+00)-(((real_t)(1.8000000000000000e+00)-((real_t)(-1.8000000000000000e+00)))+((xd[1]+xd[1])*a[12])))*a[11])-((((od[0]-xd[0])-((real_t)(4.0000000000000000e+00)+((((xd[1]*(real_t)(1.8000000000000000e+00))-((od[1]-xd[1])*(real_t)(1.8000000000000000e+00)))+((xd[1]*xd[1])/(real_t)(1.9620000000000001e+01)))-((od[1]*od[1])/(real_t)(1.9620000000000001e+01)))))*(real_t)(5.0000000000000003e-02))*a[13])); +out[6] = (real_t)(0.0000000000000000e+00); +out[7] = (((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00))*a[10]); +out[8] = ((((real_t)(0.0000000000000000e+00)-(((real_t)(1.8000000000000000e+00)-((real_t)(-1.8000000000000000e+00)))+((xd[1]+xd[1])*a[11])))*a[10])-((((od[0]-xd[0])-((real_t)(4.0000000000000000e+00)+((((xd[1]*(real_t)(1.8000000000000000e+00))-((od[1]-xd[1])*(real_t)(1.8000000000000000e+00)))+((xd[1]*xd[1])/(real_t)(1.9620000000000001e+01)))-((od[1]*od[1])/(real_t)(1.9620000000000001e+01)))))*(real_t)(5.0000000000000003e-02))*a[12])); out[9] = (real_t)(0.0000000000000000e+00); out[10] = (real_t)(0.0000000000000000e+00); out[11] = (xd[2]*(real_t)(1.0000000000000001e-01)); @@ -110,7 +108,7 @@ out[12] = (((real_t)(1.0000000000000001e-01)*xd[1])+(real_t)(1.0000000000000000e out[13] = (real_t)(0.0000000000000000e+00); out[14] = (u[0]*(real_t)(1.0000000000000001e-01)); out[15] = (real_t)(0.0000000000000000e+00); -out[16] = a[14]; +out[16] = (real_t)(0.0000000000000000e+00); out[17] = (real_t)(0.0000000000000000e+00); out[18] = (real_t)(0.0000000000000000e+00); out[19] = (((real_t)(1.0000000000000001e-01)*xd[1])+(real_t)(1.0000000000000000e+00)); @@ -120,7 +118,7 @@ void acado_evaluateLSQEndTerm(const real_t* in, real_t* out) { const real_t* xd = in; const real_t* od = in + 3; -/* Vector of auxiliary variables; number of elements: 14. */ +/* Vector of auxiliary variables; number of elements: 13. */ real_t* a = acadoWorkspace.objAuxVar; /* Compute intermediate quantities: */ @@ -134,20 +132,19 @@ a[6] = (1.0/sqrt((xd[1]+(real_t)(5.0000000000000000e-01)))); a[7] = (a[6]*(real_t)(5.0000000000000000e-01)); a[8] = (a[2]*a[2]); a[9] = (((real_t)(2.9999999999999999e-01)*(((((real_t)(1.8000000000000000e+00)-((real_t)(-1.8000000000000000e+00)))+((xd[1]+xd[1])*a[5]))*a[2])-((((((((xd[1]*(real_t)(1.8000000000000000e+00))-((od[1]-xd[1])*(real_t)(1.8000000000000000e+00)))+((xd[1]*xd[1])/(real_t)(1.9620000000000001e+01)))-((od[1]*od[1])/(real_t)(1.9620000000000001e+01)))+(real_t)(4.0000000000000000e+00))-(od[0]-xd[0]))*a[7])*a[8])))*a[3]); -a[10] = (real_t)(0.0000000000000000e+00); -a[11] = ((real_t)(1.0000000000000000e+00)/(((real_t)(5.0000000000000003e-02)*xd[1])+(real_t)(5.0000000000000000e-01))); -a[12] = ((real_t)(1.0000000000000000e+00)/(real_t)(1.9620000000000001e+01)); -a[13] = (a[11]*a[11]); +a[10] = ((real_t)(1.0000000000000000e+00)/(((real_t)(5.0000000000000003e-02)*xd[1])+(real_t)(5.0000000000000000e-01))); +a[11] = ((real_t)(1.0000000000000000e+00)/(real_t)(1.9620000000000001e+01)); +a[12] = (a[10]*a[10]); /* Compute outputs: */ -out[0] = a[1]; +out[0] = (a[1]-(real_t)(1.0000000000000000e+00)); out[1] = (((od[0]-xd[0])-((real_t)(4.0000000000000000e+00)+((((xd[1]*(real_t)(1.8000000000000000e+00))-((od[1]-xd[1])*(real_t)(1.8000000000000000e+00)))+((xd[1]*xd[1])/(real_t)(1.9620000000000001e+01)))-((od[1]*od[1])/(real_t)(1.9620000000000001e+01)))))/(((real_t)(5.0000000000000003e-02)*xd[1])+(real_t)(5.0000000000000000e-01))); out[2] = (xd[2]*(((real_t)(1.0000000000000001e-01)*xd[1])+(real_t)(1.0000000000000000e+00))); out[3] = a[4]; out[4] = a[9]; -out[5] = a[10]; -out[6] = (((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00))*a[11]); -out[7] = ((((real_t)(0.0000000000000000e+00)-(((real_t)(1.8000000000000000e+00)-((real_t)(-1.8000000000000000e+00)))+((xd[1]+xd[1])*a[12])))*a[11])-((((od[0]-xd[0])-((real_t)(4.0000000000000000e+00)+((((xd[1]*(real_t)(1.8000000000000000e+00))-((od[1]-xd[1])*(real_t)(1.8000000000000000e+00)))+((xd[1]*xd[1])/(real_t)(1.9620000000000001e+01)))-((od[1]*od[1])/(real_t)(1.9620000000000001e+01)))))*(real_t)(5.0000000000000003e-02))*a[13])); +out[5] = (real_t)(0.0000000000000000e+00); +out[6] = (((real_t)(0.0000000000000000e+00)-(real_t)(1.0000000000000000e+00))*a[10]); +out[7] = ((((real_t)(0.0000000000000000e+00)-(((real_t)(1.8000000000000000e+00)-((real_t)(-1.8000000000000000e+00)))+((xd[1]+xd[1])*a[11])))*a[10])-((((od[0]-xd[0])-((real_t)(4.0000000000000000e+00)+((((xd[1]*(real_t)(1.8000000000000000e+00))-((od[1]-xd[1])*(real_t)(1.8000000000000000e+00)))+((xd[1]*xd[1])/(real_t)(1.9620000000000001e+01)))-((od[1]*od[1])/(real_t)(1.9620000000000001e+01)))))*(real_t)(5.0000000000000003e-02))*a[12])); out[8] = (real_t)(0.0000000000000000e+00); out[9] = (real_t)(0.0000000000000000e+00); out[10] = (xd[2]*(real_t)(1.0000000000000001e-01)); diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_solver.o b/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_solver.o index 435fd9f8382e68..865c7d826ab398 100644 Binary files a/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_solver.o and b/selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/acado_solver.o differ diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Bounds.d b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Bounds.d deleted file mode 100644 index 752ec5e9f3c686..00000000000000 --- a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Bounds.d +++ /dev/null @@ -1,14 +0,0 @@ -lib_qp/Bounds.o: ../../../../phonelibs/qpoases/SRC/Bounds.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/Bounds.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/SubjectTo.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Indexlist.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/Indexlist.ipp \ - ../../../../phonelibs/qpoases/SRC/SubjectTo.ipp \ - ../../../../phonelibs/qpoases/SRC/Bounds.ipp diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Bounds.o b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Bounds.o deleted file mode 100644 index 28794f8185f91d..00000000000000 Binary files a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Bounds.o and /dev/null differ diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Constraints.d b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Constraints.d deleted file mode 100644 index 60295bc07b3dc9..00000000000000 --- a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Constraints.d +++ /dev/null @@ -1,14 +0,0 @@ -lib_qp/Constraints.o: ../../../../phonelibs/qpoases/SRC/Constraints.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constraints.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/SubjectTo.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Indexlist.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/Indexlist.ipp \ - ../../../../phonelibs/qpoases/SRC/SubjectTo.ipp \ - ../../../../phonelibs/qpoases/SRC/Constraints.ipp diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Constraints.o b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Constraints.o deleted file mode 100644 index 81352513fd913e..00000000000000 Binary files a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Constraints.o and /dev/null differ diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/CyclingManager.d b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/CyclingManager.d deleted file mode 100644 index 24145d8ed318e1..00000000000000 --- a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/CyclingManager.d +++ /dev/null @@ -1,11 +0,0 @@ -lib_qp/CyclingManager.o: \ - ../../../../phonelibs/qpoases/SRC/CyclingManager.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/CyclingManager.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/CyclingManager.ipp diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/CyclingManager.o b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/CyclingManager.o deleted file mode 100644 index 321db37ef2508b..00000000000000 Binary files a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/CyclingManager.o and /dev/null differ diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/EXTRAS/SolutionAnalysis.d b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/EXTRAS/SolutionAnalysis.d deleted file mode 100644 index 77c09376eef96e..00000000000000 --- a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/EXTRAS/SolutionAnalysis.d +++ /dev/null @@ -1,24 +0,0 @@ -lib_qp/EXTRAS/SolutionAnalysis.o: \ - ../../../../phonelibs/qpoases/SRC/EXTRAS/SolutionAnalysis.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/EXTRAS/SolutionAnalysis.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/QProblem.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/QProblemB.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Bounds.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/SubjectTo.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Indexlist.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/Indexlist.ipp \ - ../../../../phonelibs/qpoases/SRC/SubjectTo.ipp \ - ../../../../phonelibs/qpoases/SRC/Bounds.ipp \ - ../../../../phonelibs/qpoases/SRC/QProblemB.ipp \ - ../../../../phonelibs/qpoases/INCLUDE/Constraints.hpp \ - ../../../../phonelibs/qpoases/SRC/Constraints.ipp \ - ../../../../phonelibs/qpoases/INCLUDE/CyclingManager.hpp \ - ../../../../phonelibs/qpoases/SRC/CyclingManager.ipp \ - ../../../../phonelibs/qpoases/SRC/QProblem.ipp diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/EXTRAS/SolutionAnalysis.o b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/EXTRAS/SolutionAnalysis.o deleted file mode 100644 index 1816ece0eddd64..00000000000000 Binary files a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/EXTRAS/SolutionAnalysis.o and /dev/null differ diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Indexlist.d b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Indexlist.d deleted file mode 100644 index 6ead64cb9d8ee6..00000000000000 --- a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Indexlist.d +++ /dev/null @@ -1,10 +0,0 @@ -lib_qp/Indexlist.o: ../../../../phonelibs/qpoases/SRC/Indexlist.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/Indexlist.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/Indexlist.ipp diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Indexlist.o b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Indexlist.o deleted file mode 100644 index c8bdbe979bc7aa..00000000000000 Binary files a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Indexlist.o and /dev/null differ diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/MessageHandling.d b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/MessageHandling.d deleted file mode 100644 index b5c6166aba1f64..00000000000000 --- a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/MessageHandling.d +++ /dev/null @@ -1,9 +0,0 @@ -lib_qp/MessageHandling.o: \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/MessageHandling.o b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/MessageHandling.o deleted file mode 100644 index 87b200d0475adb..00000000000000 Binary files a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/MessageHandling.o and /dev/null differ diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/QProblem.d b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/QProblem.d deleted file mode 100644 index 1f6e188af55c17..00000000000000 --- a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/QProblem.d +++ /dev/null @@ -1,22 +0,0 @@ -lib_qp/QProblem.o: ../../../../phonelibs/qpoases/SRC/QProblem.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/QProblem.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/QProblemB.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Bounds.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/SubjectTo.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Indexlist.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/Indexlist.ipp \ - ../../../../phonelibs/qpoases/SRC/SubjectTo.ipp \ - ../../../../phonelibs/qpoases/SRC/Bounds.ipp \ - ../../../../phonelibs/qpoases/SRC/QProblemB.ipp \ - ../../../../phonelibs/qpoases/INCLUDE/Constraints.hpp \ - ../../../../phonelibs/qpoases/SRC/Constraints.ipp \ - ../../../../phonelibs/qpoases/INCLUDE/CyclingManager.hpp \ - ../../../../phonelibs/qpoases/SRC/CyclingManager.ipp \ - ../../../../phonelibs/qpoases/SRC/QProblem.ipp diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/QProblem.o b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/QProblem.o deleted file mode 100644 index 0d79872a24f25f..00000000000000 Binary files a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/QProblem.o and /dev/null differ diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/QProblemB.d b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/QProblemB.d deleted file mode 100644 index 7878a825ce5749..00000000000000 --- a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/QProblemB.d +++ /dev/null @@ -1,16 +0,0 @@ -lib_qp/QProblemB.o: ../../../../phonelibs/qpoases/SRC/QProblemB.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/QProblemB.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Bounds.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/SubjectTo.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Indexlist.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/Indexlist.ipp \ - ../../../../phonelibs/qpoases/SRC/SubjectTo.ipp \ - ../../../../phonelibs/qpoases/SRC/Bounds.ipp \ - ../../../../phonelibs/qpoases/SRC/QProblemB.ipp diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/QProblemB.o b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/QProblemB.o deleted file mode 100644 index 9ad8900182e509..00000000000000 Binary files a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/QProblemB.o and /dev/null differ diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/SubjectTo.d b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/SubjectTo.d deleted file mode 100644 index c896d9a9faf58d..00000000000000 --- a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/SubjectTo.d +++ /dev/null @@ -1,12 +0,0 @@ -lib_qp/SubjectTo.o: ../../../../phonelibs/qpoases/SRC/SubjectTo.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/SubjectTo.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Indexlist.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp \ - ../../../../phonelibs/qpoases/SRC/Indexlist.ipp \ - ../../../../phonelibs/qpoases/SRC/SubjectTo.ipp diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/SubjectTo.o b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/SubjectTo.o deleted file mode 100644 index f5b1695e756237..00000000000000 Binary files a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/SubjectTo.o and /dev/null differ diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Utils.d b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Utils.d deleted file mode 100644 index 58f35a065397a3..00000000000000 --- a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Utils.d +++ /dev/null @@ -1,8 +0,0 @@ -lib_qp/Utils.o: ../../../../phonelibs/qpoases/SRC/Utils.cpp \ - ../../../../phonelibs/qpoases/INCLUDE/Utils.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/MessageHandling.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Types.hpp \ - ../../../../phonelibs/qpoases/INCLUDE/Constants.hpp \ - lib_mpc_export/acado_qpoases_interface.hpp \ - ../../../../phonelibs/qpoases/SRC/MessageHandling.ipp \ - ../../../../phonelibs/qpoases/SRC/Utils.ipp diff --git a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Utils.o b/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Utils.o deleted file mode 100644 index ef645ef188049f..00000000000000 Binary files a/selfdrive/controls/lib/longitudinal_mpc/lib_qp/Utils.o and /dev/null differ diff --git a/selfdrive/controls/lib/longitudinal_mpc/libmpc1.so b/selfdrive/controls/lib/longitudinal_mpc/libmpc1.so index 3e05e166d61fb9..4cf3782aff93d0 100755 Binary files a/selfdrive/controls/lib/longitudinal_mpc/libmpc1.so and b/selfdrive/controls/lib/longitudinal_mpc/libmpc1.so differ diff --git a/selfdrive/controls/lib/longitudinal_mpc/libmpc_py.py b/selfdrive/controls/lib/longitudinal_mpc/libmpc_py.py index 354a4a493eaa91..95e9135a813770 100644 --- a/selfdrive/controls/lib/longitudinal_mpc/libmpc_py.py +++ b/selfdrive/controls/lib/longitudinal_mpc/libmpc_py.py @@ -29,7 +29,7 @@ def _get_libmpc(mpc_id): double x_ego[21]; double v_ego[21]; double a_ego[21]; - double j_ego[21]; + double j_ego[20]; double x_l[21]; double v_l[21]; double a_l[21]; diff --git a/selfdrive/controls/lib/longitudinal_mpc/longitudinal_mpc.c b/selfdrive/controls/lib/longitudinal_mpc/longitudinal_mpc.c index e903ccc758c397..d4bfee8c8aac0d 100644 --- a/selfdrive/controls/lib/longitudinal_mpc/longitudinal_mpc.c +++ b/selfdrive/controls/lib/longitudinal_mpc/longitudinal_mpc.c @@ -26,12 +26,12 @@ typedef struct { double x_ego[N+1]; double v_ego[N+1]; double a_ego[N+1]; - double j_ego[N+1]; - double x_l[N+1]; - double v_l[N+1]; - double a_l[N+1]; - double t[N+1]; - double cost; + double j_ego[N]; + double x_l[N+1]; + double v_l[N+1]; + double a_l[N+1]; + double t[N+1]; + double cost; } log_t; void init(double ttcCost, double distanceCost, double accelerationCost, double jerkCost){ @@ -56,14 +56,15 @@ void init(double ttcCost, double distanceCost, double accelerationCost, double j if (i > 4){ f = STEP_MULTIPLIER; } - acadoVariables.W[16 * i + 0] = ttcCost * f; // exponential cost for time-to-collision (ttc) - acadoVariables.W[16 * i + 5] = distanceCost * f; // desired distance - acadoVariables.W[16 * i + 10] = accelerationCost * f; // acceleration - acadoVariables.W[16 * i + 15] = jerkCost * f; // jerk + // Setup diagonal entries + acadoVariables.W[NY*NY*i + (NY+1)*0] = ttcCost * f; // exponential cost for time-to-collision (ttc) + acadoVariables.W[NY*NY*i + (NY+1)*1] = distanceCost * f; // desired distance + acadoVariables.W[NY*NY*i + (NY+1)*2] = accelerationCost * f; // acceleration + acadoVariables.W[NY*NY*i + (NY+1)*3] = jerkCost * f; // jerk } - acadoVariables.WN[0] = ttcCost * STEP_MULTIPLIER; // exponential cost for danger zone - acadoVariables.WN[4] = distanceCost * STEP_MULTIPLIER; // desired distance - acadoVariables.WN[8] = accelerationCost * STEP_MULTIPLIER; // acceleration + acadoVariables.WN[(NYN+1)*0] = ttcCost * STEP_MULTIPLIER; // exponential cost for danger zone + acadoVariables.WN[(NYN+1)*1] = distanceCost * STEP_MULTIPLIER; // desired distance + acadoVariables.WN[(NYN+1)*2] = accelerationCost * STEP_MULTIPLIER; // acceleration } @@ -154,12 +155,15 @@ int run_mpc(state_t * x0, log_t * solution, double l, double a_l_0){ acado_preparationStep(); acado_feedbackStep(); - for (i = 0; i <= N; i++){ + for (i = 0; i <= N; i++){ solution->x_ego[i] = acadoVariables.x[i*NX]; - solution->v_ego[i] = acadoVariables.x[i*NX+1]; + solution->v_ego[i] = acadoVariables.x[i*NX+1]; solution->a_ego[i] = acadoVariables.x[i*NX+2]; - solution->j_ego[i] = acadoVariables.u[i]; - } + + if (i < N){ + solution->j_ego[i] = acadoVariables.u[i]; + } + } solution->cost = acado_getObjective(); // Dont shift states here. Current solution is closer to next timestep than if diff --git a/selfdrive/controls/lib/longitudinal_mpc/longitudinal_mpc.o b/selfdrive/controls/lib/longitudinal_mpc/longitudinal_mpc.o index 3c0660d96d4a58..6000b25f56a480 100644 Binary files a/selfdrive/controls/lib/longitudinal_mpc/longitudinal_mpc.o and b/selfdrive/controls/lib/longitudinal_mpc/longitudinal_mpc.o differ diff --git a/selfdrive/controls/lib/model_parser.py b/selfdrive/controls/lib/model_parser.py deleted file mode 100644 index 747e918f750a86..00000000000000 --- a/selfdrive/controls/lib/model_parser.py +++ /dev/null @@ -1,65 +0,0 @@ -from common.numpy_fast import interp -from selfdrive.controls.lib.latcontrol_helpers import model_polyfit, calc_desired_path, compute_path_pinv - -CAMERA_OFFSET = 0.06 # m from center car to camera - - -class ModelParser(object): - def __init__(self): - self.d_poly = [0., 0., 0., 0.] - self.c_poly = [0., 0., 0., 0.] - self.c_prob = 0. - self.last_model = 0. - self.lead_dist, self.lead_prob, self.lead_var = 0, 0, 1 - self._path_pinv = compute_path_pinv() - - self.lane_width_estimate = 3.7 - self.lane_width_certainty = 1.0 - self.lane_width = 3.7 - self.l_prob = 0. - self.r_prob = 0. - - def update(self, v_ego, md): - if md is not None: - p_poly = model_polyfit(md.model.path.points, self._path_pinv) # predicted path - l_poly = model_polyfit(md.model.leftLane.points, self._path_pinv) # left line - r_poly = model_polyfit(md.model.rightLane.points, self._path_pinv) # right line - - # only offset left and right lane lines; offsetting p_poly does not make sense - l_poly[3] += CAMERA_OFFSET - r_poly[3] += CAMERA_OFFSET - - p_prob = 1. # model does not tell this probability yet, so set to 1 for now - l_prob = md.model.leftLane.prob # left line prob - r_prob = md.model.rightLane.prob # right line prob - - # Find current lanewidth - lr_prob = l_prob * r_prob - self.lane_width_certainty += 0.05 * (lr_prob - self.lane_width_certainty) - current_lane_width = abs(l_poly[3] - r_poly[3]) - self.lane_width_estimate += 0.005 * (current_lane_width - self.lane_width_estimate) - speed_lane_width = interp(v_ego, [0., 31.], [3., 3.8]) - self.lane_width = self.lane_width_certainty * self.lane_width_estimate + \ - (1 - self.lane_width_certainty) * speed_lane_width - - lane_width_diff = abs(self.lane_width - current_lane_width) - lane_r_prob = interp(lane_width_diff, [0.3, 1.0], [1.0, 0.0]) - - r_prob *= lane_r_prob - - self.lead_dist = md.model.lead.dist - self.lead_prob = md.model.lead.prob - self.lead_var = md.model.lead.std**2 - - # compute target path - self.d_poly, self.c_poly, self.c_prob = calc_desired_path( - l_poly, r_poly, p_poly, l_prob, r_prob, p_prob, v_ego, self.lane_width) - - self.r_poly = r_poly - self.r_prob = r_prob - - self.l_poly = l_poly - self.l_prob = l_prob - - self.p_poly = p_poly - self.p_prob = p_prob diff --git a/selfdrive/controls/lib/pathplanner.py b/selfdrive/controls/lib/pathplanner.py index 0161d2f94633a0..5678cf05f9cfa2 100644 --- a/selfdrive/controls/lib/pathplanner.py +++ b/selfdrive/controls/lib/pathplanner.py @@ -1,15 +1,14 @@ -import zmq +import os import math -import numpy as np - from common.realtime import sec_since_boot -from selfdrive.services import service_list from selfdrive.swaglog import cloudlog from selfdrive.controls.lib.lateral_mpc import libmpc_py from selfdrive.controls.lib.drive_helpers import MPC_COST_LAT -from selfdrive.controls.lib.model_parser import ModelParser +from selfdrive.controls.lib.lane_planner import LanePlanner import selfdrive.messaging as messaging +LOG_MPC = os.environ.get('LOG_MPC', False) + def calc_states_after_delay(states, v_ego, steer_angle, curvature_factor, steer_ratio, delay): states[0].x = v_ego * delay @@ -17,18 +16,15 @@ def calc_states_after_delay(states, v_ego, steer_angle, curvature_factor, steer_ return states -class PathPlanner(object): +class PathPlanner(): def __init__(self, CP): - self.MP = ModelParser() + self.LP = LanePlanner() self.last_cloudlog_t = 0 - context = zmq.Context() - self.plan = messaging.pub_sock(context, service_list['pathPlan'].port) - self.livempc = messaging.pub_sock(context, service_list['liveMpc'].port) - self.setup_mpc(CP.steerRateCost) - self.invalid_counter = 0 + self.solution_invalid_cnt = 0 + self.path_offset_i = 0.0 def setup_mpc(self, steer_rate_cost): self.libmpc = libmpc_py.libmpc @@ -46,86 +42,91 @@ def setup_mpc(self, steer_rate_cost): self.angle_steers_des_prev = 0.0 self.angle_steers_des_time = 0.0 - def update(self, CP, VM, CS, md, live100, live_parameters): - v_ego = CS.carState.vEgo - angle_steers = CS.carState.steeringAngle - active = live100.live100.active + def update(self, sm, pm, CP, VM): + v_ego = sm['carState'].vEgo + angle_steers = sm['carState'].steeringAngle + active = sm['controlsState'].active - angle_offset_bias = live100.live100.angleModelBias + live_parameters.liveParameters.angleOffsetAverage + angle_offset = sm['liveParameters'].angleOffset - self.MP.update(v_ego, md) + self.LP.update(v_ego, sm['model']) # Run MPC self.angle_steers_des_prev = self.angle_steers_des_mpc - VM.update_params(live_parameters.liveParameters.stiffnessFactor, live_parameters.liveParameters.steerRatio) + VM.update_params(sm['liveParameters'].stiffnessFactor, sm['liveParameters'].steerRatio) curvature_factor = VM.curvature_factor(v_ego) - l_poly = libmpc_py.ffi.new("double[4]", list(self.MP.l_poly)) - r_poly = libmpc_py.ffi.new("double[4]", list(self.MP.r_poly)) - p_poly = libmpc_py.ffi.new("double[4]", list(self.MP.p_poly)) + # TODO: Check for active, override, and saturation + # if active: + # self.path_offset_i += self.LP.d_poly[3] / (60.0 * 20.0) + # self.path_offset_i = clip(self.path_offset_i, -0.5, 0.5) + # self.LP.d_poly[3] += self.path_offset_i + # else: + # self.path_offset_i = 0.0 # account for actuation delay - self.cur_state = calc_states_after_delay(self.cur_state, v_ego, angle_steers, curvature_factor, VM.sR, CP.steerActuatorDelay) + self.cur_state = calc_states_after_delay(self.cur_state, v_ego, angle_steers - angle_offset, curvature_factor, VM.sR, CP.steerActuatorDelay) v_ego_mpc = max(v_ego, 5.0) # avoid mpc roughness due to low speed self.libmpc.run_mpc(self.cur_state, self.mpc_solution, - l_poly, r_poly, p_poly, - self.MP.l_prob, self.MP.r_prob, self.MP.p_prob, curvature_factor, v_ego_mpc, self.MP.lane_width) + list(self.LP.l_poly), list(self.LP.r_poly), list(self.LP.d_poly), + self.LP.l_prob, self.LP.r_prob, curvature_factor, v_ego_mpc, self.LP.lane_width) # reset to current steer angle if not active or overriding if active: delta_desired = self.mpc_solution[0].delta[1] rate_desired = math.degrees(self.mpc_solution[0].rate[0] * VM.sR) else: - delta_desired = math.radians(angle_steers - angle_offset_bias) / VM.sR + delta_desired = math.radians(angle_steers - angle_offset) / VM.sR rate_desired = 0.0 self.cur_state[0].delta = delta_desired - self.angle_steers_des_mpc = float(math.degrees(delta_desired * VM.sR) + angle_offset_bias) - + self.angle_steers_des_mpc = float(math.degrees(delta_desired * VM.sR) + angle_offset) # Check for infeasable MPC solution - mpc_nans = np.any(np.isnan(list(self.mpc_solution[0].delta))) + mpc_nans = any(math.isnan(x) for x in self.mpc_solution[0].delta) t = sec_since_boot() if mpc_nans: self.libmpc.init(MPC_COST_LAT.PATH, MPC_COST_LAT.LANE, MPC_COST_LAT.HEADING, CP.steerRateCost) - self.cur_state[0].delta = math.radians(angle_steers) / VM.sR + self.cur_state[0].delta = math.radians(angle_steers - angle_offset) / VM.sR if t > self.last_cloudlog_t + 5.0: self.last_cloudlog_t = t cloudlog.warning("Lateral mpc - nan: True") if self.mpc_solution[0].cost > 20000. or mpc_nans: # TODO: find a better way to detect when MPC did not converge - self.invalid_counter += 1 + self.solution_invalid_cnt += 1 else: - self.invalid_counter = 0 - - plan_valid = self.invalid_counter < 2 + self.solution_invalid_cnt = 0 + plan_solution_valid = self.solution_invalid_cnt < 2 plan_send = messaging.new_message() plan_send.init('pathPlan') - plan_send.pathPlan.laneWidth = float(self.MP.lane_width) - plan_send.pathPlan.dPoly = map(float, self.MP.d_poly) - plan_send.pathPlan.cPoly = map(float, self.MP.c_poly) - plan_send.pathPlan.cProb = float(self.MP.c_prob) - plan_send.pathPlan.lPoly = map(float, l_poly) - plan_send.pathPlan.lProb = float(self.MP.l_prob) - plan_send.pathPlan.rPoly = map(float, r_poly) - plan_send.pathPlan.rProb = float(self.MP.r_prob) + plan_send.valid = sm.all_alive_and_valid(service_list=['carState', 'controlsState', 'liveParameters', 'model']) + plan_send.pathPlan.laneWidth = float(self.LP.lane_width) + plan_send.pathPlan.dPoly = [float(x) for x in self.LP.d_poly] + plan_send.pathPlan.lPoly = [float(x) for x in self.LP.l_poly] + plan_send.pathPlan.lProb = float(self.LP.l_prob) + plan_send.pathPlan.rPoly = [float(x) for x in self.LP.r_poly] + plan_send.pathPlan.rProb = float(self.LP.r_prob) + plan_send.pathPlan.angleSteers = float(self.angle_steers_des_mpc) plan_send.pathPlan.rateSteers = float(rate_desired) - plan_send.pathPlan.angleOffset = float(live_parameters.liveParameters.angleOffsetAverage) - plan_send.pathPlan.valid = bool(plan_valid) - plan_send.pathPlan.paramsValid = bool(live_parameters.liveParameters.valid) - - self.plan.send(plan_send.to_bytes()) - - dat = messaging.new_message() - dat.init('liveMpc') - dat.liveMpc.x = list(self.mpc_solution[0].x) - dat.liveMpc.y = list(self.mpc_solution[0].y) - dat.liveMpc.psi = list(self.mpc_solution[0].psi) - dat.liveMpc.delta = list(self.mpc_solution[0].delta) - dat.liveMpc.cost = self.mpc_solution[0].cost - self.livempc.send(dat.to_bytes()) + plan_send.pathPlan.angleOffset = float(sm['liveParameters'].angleOffsetAverage) + plan_send.pathPlan.mpcSolutionValid = bool(plan_solution_valid) + plan_send.pathPlan.paramsValid = bool(sm['liveParameters'].valid) + plan_send.pathPlan.sensorValid = bool(sm['liveParameters'].sensorValid) + plan_send.pathPlan.posenetValid = bool(sm['liveParameters'].posenetValid) + + pm.send('pathPlan', plan_send) + + if LOG_MPC: + dat = messaging.new_message() + dat.init('liveMpc') + dat.liveMpc.x = list(self.mpc_solution[0].x) + dat.liveMpc.y = list(self.mpc_solution[0].y) + dat.liveMpc.psi = list(self.mpc_solution[0].psi) + dat.liveMpc.delta = list(self.mpc_solution[0].delta) + dat.liveMpc.cost = self.mpc_solution[0].cost + pm.send('liveMpc', dat) diff --git a/selfdrive/controls/lib/pid.py b/selfdrive/controls/lib/pid.py index b68dc3810eef4b..ce2d34b35937f8 100644 --- a/selfdrive/controls/lib/pid.py +++ b/selfdrive/controls/lib/pid.py @@ -10,7 +10,7 @@ def apply_deadzone(error, deadzone): error = 0. return error -class PIController(object): +class PIController(): def __init__(self, k_p, k_i, k_f=1., pos_limit=None, neg_limit=None, rate=100, sat_limit=0.8, convert=None): self._k_p = k_p # proportional gain self._k_i = k_i # integral gain diff --git a/selfdrive/controls/lib/planner.py b/selfdrive/controls/lib/planner.py index c26711f57e8b21..db3fe33217d6c0 100755 --- a/selfdrive/controls/lib/planner.py +++ b/selfdrive/controls/lib/planner.py @@ -1,23 +1,22 @@ -#!/usr/bin/env python -import zmq +#!/usr/bin/env python3 import math import numpy as np from common.params import Params from common.numpy_fast import interp import selfdrive.messaging as messaging +from cereal import car +from common.realtime import sec_since_boot, DT_PLAN from selfdrive.swaglog import cloudlog from selfdrive.config import Conversions as CV -from selfdrive.services import service_list -from selfdrive.controls.lib.drive_helpers import create_event, EventTypes as ET from selfdrive.controls.lib.speed_smoother import speed_smoother from selfdrive.controls.lib.longcontrol import LongCtrlState, MIN_CAN_SPEED from selfdrive.controls.lib.fcw import FCWChecker from selfdrive.controls.lib.long_mpc import LongitudinalMpc -NO_CURVATURE_SPEED = 200. * CV.MPH_TO_MS +MAX_SPEED = 255.0 -_DT_MPC = 0.2 # 5Hz +LON_MPC_STEP = 0.2 # first step is 0.2s MAX_SPEED_ERROR = 2.0 AWARENESS_DECEL = -0.2 # car smoothly decel at .2m/s^2 when user is distracted @@ -28,22 +27,27 @@ # need fast accel at very low speed for stop and go # make sure these accelerations are smaller than mpc limits -_A_CRUISE_MAX_V = [1.1, 1.1, .8, .5, .3] -_A_CRUISE_MAX_V_FOLLOWING = [1.6, 1.6, 1.2, .7, .3] -_A_CRUISE_MAX_BP = [0., 5., 10., 20., 40.] +_A_CRUISE_MAX_V = [1.6, 1.6, 0.65, .4] +_A_CRUISE_MAX_BP = [0., 6.4, 22.5, 40.] # Lookup table for turns -_A_TOTAL_MAX_V = [1.5, 1.9, 3.2] -_A_TOTAL_MAX_BP = [0., 20., 40.] +_A_TOTAL_MAX_V = [1.7, 3.2] +_A_TOTAL_MAX_BP = [20., 40.] -def calc_cruise_accel_limits(v_ego, following): - a_cruise_min = interp(v_ego, _A_CRUISE_MIN_BP, _A_CRUISE_MIN_V) +# Model speed kalman stuff +_MODEL_V_A = [[1.0, DT_PLAN], [0.0, 1.0]] +_MODEL_V_C = [1.0, 0] +# calculated with observation std of 2m/s and accel proc noise of 2m/s**2 +_MODEL_V_K = [[0.07068858], [0.04826294]] + +# 75th percentile +SPEED_PERCENTILE_IDX = 7 - if following: - a_cruise_max = interp(v_ego, _A_CRUISE_MAX_BP, _A_CRUISE_MAX_V_FOLLOWING) - else: - a_cruise_max = interp(v_ego, _A_CRUISE_MAX_BP, _A_CRUISE_MAX_V) + +def calc_cruise_accel_limits(v_ego): + a_cruise_min = interp(v_ego, _A_CRUISE_MIN_BP, _A_CRUISE_MIN_V) + a_cruise_max = interp(v_ego, _A_CRUISE_MAX_BP, _A_CRUISE_MAX_V) return np.vstack([a_cruise_min, a_cruise_max]) @@ -57,21 +61,15 @@ def limit_accel_in_turns(v_ego, angle_steers, a_target, CP): a_y = v_ego**2 * angle_steers * CV.DEG_TO_RAD / (CP.steerRatio * CP.wheelbase) a_x_allowed = math.sqrt(max(a_total_max**2 - a_y**2, 0.)) - a_target[1] = min(a_target[1], a_x_allowed) - return a_target + return [a_target[0], min(a_target[1], a_x_allowed)] -class Planner(object): - def __init__(self, CP, fcw_enabled): - context = zmq.Context() +class Planner(): + def __init__(self, CP): self.CP = CP - self.poller = zmq.Poller() - self.plan = messaging.pub_sock(context, service_list['plan'].port) - self.live_longitudinal_mpc = messaging.pub_sock(context, service_list['liveLongitudinalMpc'].port) - - self.mpc1 = LongitudinalMpc(1, self.live_longitudinal_mpc) - self.mpc2 = LongitudinalMpc(2, self.live_longitudinal_mpc) + self.mpc1 = LongitudinalMpc(1) + self.mpc2 = LongitudinalMpc(2) self.v_acc_start = 0.0 self.a_acc_start = 0.0 @@ -81,16 +79,18 @@ def __init__(self, CP, fcw_enabled): self.a_acc = 0.0 self.v_cruise = 0.0 self.a_cruise = 0.0 + self.v_model = 0.0 + self.a_model = 0.0 self.longitudinalPlanSource = 'cruise' self.fcw_checker = FCWChecker() - self.fcw_enabled = fcw_enabled + self.path_x = np.arange(192) self.params = Params() def choose_solution(self, v_cruise_setpoint, enabled): if enabled: - solutions = {'cruise': self.v_cruise} + solutions = {'model': self.v_model, 'cruise': self.v_cruise} if self.mpc1.prev_lead_status: solutions['mpc1'] = self.mpc1.v_mpc if self.mpc2.prev_lead_status: @@ -99,7 +99,6 @@ def choose_solution(self, v_cruise_setpoint, enabled): slowest = min(solutions, key=solutions.get) self.longitudinalPlanSource = slowest - # Choose lowest of MPC and cruise if slowest == 'mpc1': self.v_acc = self.mpc1.v_mpc @@ -110,73 +109,73 @@ def choose_solution(self, v_cruise_setpoint, enabled): elif slowest == 'cruise': self.v_acc = self.v_cruise self.a_acc = self.a_cruise + elif slowest == 'model': + self.v_acc = self.v_model + self.a_acc = self.a_model self.v_acc_future = min([self.mpc1.v_mpc_future, self.mpc2.v_mpc_future, v_cruise_setpoint]) - def update(self, CS, CP, VM, PP, live20, live100, md, live_map_data): - """Gets called when new live20 is available""" - cur_time = live20.logMonoTime / 1e9 - v_ego = CS.carState.vEgo + def update(self, sm, pm, CP, VM, PP): + """Gets called when new radarState is available""" + cur_time = sec_since_boot() + v_ego = sm['carState'].vEgo - long_control_state = live100.live100.longControlState - v_cruise_kph = live100.live100.vCruise - force_slow_decel = live100.live100.forceDecel + long_control_state = sm['controlsState'].longControlState + v_cruise_kph = sm['controlsState'].vCruise + force_slow_decel = sm['controlsState'].forceDecel v_cruise_setpoint = v_cruise_kph * CV.KPH_TO_MS - lead_1 = live20.live20.leadOne - lead_2 = live20.live20.leadTwo + lead_1 = sm['radarState'].leadOne + lead_2 = sm['radarState'].leadTwo enabled = (long_control_state == LongCtrlState.pid) or (long_control_state == LongCtrlState.stopping) - following = lead_1.status and lead_1.dRel < 45.0 and lead_1.vLeadK > v_ego and lead_1.aLeadK > 0.0 - - v_speedlimit = NO_CURVATURE_SPEED - v_curvature = NO_CURVATURE_SPEED - map_valid = live_map_data.liveMapData.mapValid - - # Speed limit and curvature - set_speed_limit_active = self.params.get("LimitSetSpeed") == "1" and self.params.get("SpeedLimitOffset") is not None - if set_speed_limit_active: - if live_map_data.liveMapData.speedLimitValid: - speed_limit = live_map_data.liveMapData.speedLimit - offset = float(self.params.get("SpeedLimitOffset")) - v_speedlimit = speed_limit + offset - if live_map_data.liveMapData.curvatureValid: - curvature = abs(live_map_data.liveMapData.curvature) - a_y_max = 2.975 - v_ego * 0.0375 # ~1.85 @ 75mph, ~2.6 @ 25mph - v_curvature = math.sqrt(a_y_max / max(1e-4, curvature)) - v_curvature = min(NO_CURVATURE_SPEED, v_curvature) - - decel_for_turn = bool(v_curvature < min([v_cruise_setpoint, v_speedlimit, v_ego + 1.])) - v_cruise_setpoint = min([v_cruise_setpoint, v_curvature, v_speedlimit]) + if len(sm['model'].path.poly): + path = list(sm['model'].path.poly) + + # Curvature of polynomial https://en.wikipedia.org/wiki/Curvature#Curvature_of_the_graph_of_a_function + # y = a x^3 + b x^2 + c x + d, y' = 3 a x^2 + 2 b x + c, y'' = 6 a x + 2 b + # k = y'' / (1 + y'^2)^1.5 + # TODO: compute max speed without using a list of points and without numpy + y_p = 3 * path[0] * self.path_x**2 + 2 * path[1] * self.path_x + path[2] + y_pp = 6 * path[0] * self.path_x + 2 * path[1] + curv = y_pp / (1. + y_p**2)**1.5 + + a_y_max = 2.975 - v_ego * 0.0375 # ~1.85 @ 75mph, ~2.6 @ 25mph + v_curvature = np.sqrt(a_y_max / np.clip(np.abs(curv), 1e-4, None)) + model_speed = np.min(v_curvature) + model_speed = max(20.0 * CV.MPH_TO_MS, model_speed) # Don't slow down below 20mph + else: + model_speed = MAX_SPEED # Calculate speed for normal cruise control if enabled: - accel_limits = map(float, calc_cruise_accel_limits(v_ego, following)) + accel_limits = [float(x) for x in calc_cruise_accel_limits(v_ego)] jerk_limits = [min(-0.1, accel_limits[0]), max(0.1, accel_limits[1])] # TODO: make a separate lookup for jerk tuning - accel_limits = limit_accel_in_turns(v_ego, CS.carState.steeringAngle, accel_limits, self.CP) + accel_limits_turns = limit_accel_in_turns(v_ego, sm['carState'].steeringAngle, accel_limits, self.CP) if force_slow_decel: # if required so, force a smooth deceleration - accel_limits[1] = min(accel_limits[1], AWARENESS_DECEL) - accel_limits[0] = min(accel_limits[0], accel_limits[1]) - - # Change accel limits based on time remaining to turn - if decel_for_turn: - time_to_turn = max(1.0, live_map_data.liveMapData.distToTurn / max(self.v_cruise, 1.)) - required_decel = min(0, (v_curvature - self.v_cruise) / time_to_turn) - accel_limits[0] = max(accel_limits[0], required_decel) + accel_limits_turns[1] = min(accel_limits_turns[1], AWARENESS_DECEL) + accel_limits_turns[0] = min(accel_limits_turns[0], accel_limits_turns[1]) self.v_cruise, self.a_cruise = speed_smoother(self.v_acc_start, self.a_acc_start, v_cruise_setpoint, - accel_limits[1], accel_limits[0], + accel_limits_turns[1], accel_limits_turns[0], jerk_limits[1], jerk_limits[0], - _DT_MPC) + LON_MPC_STEP) + + self.v_model, self.a_model = speed_smoother(self.v_acc_start, self.a_acc_start, + model_speed, + 2*accel_limits[1], accel_limits[0], + 2*jerk_limits[1], jerk_limits[0], + LON_MPC_STEP) + # cruise speed can't be negative even is user is distracted self.v_cruise = max(self.v_cruise, 0.) else: starting = long_control_state == LongCtrlState.starting - a_ego = min(CS.carState.aEgo, 0.0) + a_ego = min(sm['carState'].aEgo, 0.0) reset_speed = MIN_CAN_SPEED if starting else v_ego reset_accel = self.CP.startAccel if starting else a_ego self.v_acc = reset_speed @@ -189,8 +188,8 @@ def update(self, CS, CP, VM, PP, live20, live100, md, live_map_data): self.mpc1.set_cur_state(self.v_acc_start, self.a_acc_start) self.mpc2.set_cur_state(self.v_acc_start, self.a_acc_start) - self.mpc1.update(CS, lead_1, v_cruise_setpoint) - self.mpc2.update(CS, lead_2, v_cruise_setpoint) + self.mpc1.update(pm, sm['carState'], lead_1, v_cruise_setpoint) + self.mpc2.update(pm, sm['carState'], lead_2, v_cruise_setpoint) self.choose_solution(v_cruise_setpoint, enabled) @@ -198,59 +197,55 @@ def update(self, CS, CP, VM, PP, live20, live100, md, live_map_data): if self.mpc1.new_lead: self.fcw_checker.reset_lead(cur_time) - blinkers = CS.carState.leftBlinker or CS.carState.rightBlinker - fcw = self.fcw_checker.update(self.mpc1.mpc_solution, cur_time, v_ego, CS.carState.aEgo, + blinkers = sm['carState'].leftBlinker or sm['carState'].rightBlinker + fcw = self.fcw_checker.update(self.mpc1.mpc_solution, cur_time, + sm['controlsState'].active, + v_ego, sm['carState'].aEgo, lead_1.dRel, lead_1.vLead, lead_1.aLeadK, lead_1.yRel, lead_1.vLat, - lead_1.fcw, blinkers) and not CS.carState.brakePressed + lead_1.fcw, blinkers) and not sm['carState'].brakePressed if fcw: cloudlog.info("FCW triggered %s", self.fcw_checker.counters) - model_dead = cur_time - (md.logMonoTime / 1e9) > 0.5 + radar_dead = not sm.alive['radarState'] + + radar_errors = list(sm['radarState'].radarErrors) + radar_fault = car.RadarData.Error.fault in radar_errors + radar_can_error = car.RadarData.Error.canError in radar_errors # **** send the plan **** plan_send = messaging.new_message() plan_send.init('plan') - # TODO: Move all these events to controlsd. This has nothing to do with planning - events = [] - if model_dead: - events.append(create_event('modelCommIssue', [ET.NO_ENTRY, ET.SOFT_DISABLE])) + plan_send.valid = sm.all_alive_and_valid(service_list=['carState', 'controlsState', 'radarState']) - radar_errors = list(live20.live20.radarErrors) - if 'commIssue' in radar_errors: - events.append(create_event('radarCommIssue', [ET.NO_ENTRY, ET.SOFT_DISABLE])) - if 'fault' in radar_errors: - events.append(create_event('radarFault', [ET.NO_ENTRY, ET.SOFT_DISABLE])) - - plan_send.plan.events = events - plan_send.plan.mdMonoTime = md.logMonoTime - plan_send.plan.l20MonoTime = live20.logMonoTime + plan_send.plan.mdMonoTime = sm.logMonoTime['model'] + plan_send.plan.radarStateMonoTime = sm.logMonoTime['radarState'] # longitudal plan - plan_send.plan.vCruise = self.v_cruise - plan_send.plan.aCruise = self.a_cruise - plan_send.plan.vStart = self.v_acc_start - plan_send.plan.aStart = self.a_acc_start - plan_send.plan.vTarget = self.v_acc - plan_send.plan.aTarget = self.a_acc - plan_send.plan.vTargetFuture = self.v_acc_future + plan_send.plan.vCruise = float(self.v_cruise) + plan_send.plan.aCruise = float(self.a_cruise) + plan_send.plan.vStart = float(self.v_acc_start) + plan_send.plan.aStart = float(self.a_acc_start) + plan_send.plan.vTarget = float(self.v_acc) + plan_send.plan.aTarget = float(self.a_acc) + plan_send.plan.vTargetFuture = float(self.v_acc_future) plan_send.plan.hasLead = self.mpc1.prev_lead_status plan_send.plan.longitudinalPlanSource = self.longitudinalPlanSource - plan_send.plan.vCurvature = v_curvature - plan_send.plan.decelForTurn = decel_for_turn - plan_send.plan.mapValid = map_valid + radar_valid = not (radar_dead or radar_fault) + plan_send.plan.radarValid = bool(radar_valid) + plan_send.plan.radarCanError = bool(radar_can_error) + + plan_send.plan.processingDelay = (plan_send.logMonoTime / 1e9) - sm.rcv_time['radarState'] # Send out fcw - fcw = fcw and (self.fcw_enabled or long_control_state != LongCtrlState.off) plan_send.plan.fcw = fcw - self.plan.send(plan_send.to_bytes()) + pm.send('plan', plan_send) # Interpolate 0.05 seconds and save as starting point for next iteration - dt = 0.05 # s - a_acc_sol = self.a_acc_start + (dt / _DT_MPC) * (self.a_acc - self.a_acc_start) - v_acc_sol = self.v_acc_start + dt * (a_acc_sol + self.a_acc_start) / 2.0 + a_acc_sol = self.a_acc_start + (DT_PLAN / LON_MPC_STEP) * (self.a_acc - self.a_acc_start) + v_acc_sol = self.v_acc_start + DT_PLAN * (a_acc_sol + self.a_acc_start) / 2.0 self.v_acc_start = v_acc_sol self.a_acc_start = a_acc_sol diff --git a/selfdrive/controls/lib/radar_helpers.py b/selfdrive/controls/lib/radar_helpers.py index da7d3f71ba0c4d..557679e5dcacb1 100644 --- a/selfdrive/controls/lib/radar_helpers.py +++ b/selfdrive/controls/lib/radar_helpers.py @@ -1,152 +1,73 @@ -import os -import sys -import platform -import numpy as np - -from common.numpy_fast import clip, interp +from common.realtime import DT_MDL from common.kalman.simple_kalman import KF1D +from selfdrive.config import RADAR_TO_CENTER + +# the longer lead decels, the more likely it will keep decelerating +# TODO is this a good default? _LEAD_ACCEL_TAU = 1.5 -NO_FUSION_SCORE = 100 # bad default fusion score # radar tracks SPEED, ACCEL = 0, 1 # Kalman filter states enum -rate, ratev = 20., 20. # model and radar are both at 20Hz -ts = 1./rate -freq_v_lat = 0.2 # Hz -k_v_lat = 2*np.pi*freq_v_lat*ts / (1 + 2*np.pi*freq_v_lat*ts) - -freq_a_lead = .5 # Hz -k_a_lead = 2*np.pi*freq_a_lead*ts / (1 + 2*np.pi*freq_a_lead*ts) - # stationary qualification parameters -v_stationary_thr = 4. # objects moving below this speed are classified as stationary -v_oncoming_thr = -3.9 # needs to be a bit lower in abs value than v_stationary_thr to not leave "holes" v_ego_stationary = 4. # no stationary object flag below this speed # Lead Kalman Filter params -_VLEAD_A = [[1.0, ts], [0.0, 1.0]] -_VLEAD_C = [[1.0, 0.0]] +_VLEAD_A = [[1.0, DT_MDL], [0.0, 1.0]] +_VLEAD_C = [1.0, 0.0] #_VLEAD_Q = np.matrix([[10., 0.0], [0.0, 100.]]) #_VLEAD_R = 1e3 #_VLEAD_K = np.matrix([[ 0.05705578], [ 0.03073241]]) -_VLEAD_K = [[ 0.1988689 ], [ 0.28555364]] - -RDR_TO_LDR = 2.7 +_VLEAD_K = [[0.1988689], [0.28555364]] -class Track(object): +class Track(): def __init__(self): self.ekf = None - self.stationary = True - self.initted = False - - def update(self, d_rel, y_rel, v_rel, d_path, v_ego_t_aligned, measured, steer_override): - if self.initted: - # pylint: disable=access-member-before-definition - self.dPathPrev = self.dPath - self.vLeadPrev = self.vLead - self.vRelPrev = self.vRel + self.cnt = 0 + self.aLeadTau = _LEAD_ACCEL_TAU + def update(self, d_rel, y_rel, v_rel, v_ego_t_aligned, measured): # relative values, copy self.dRel = d_rel # LONG_DIST self.yRel = y_rel # -LAT_DIST self.vRel = v_rel # REL_SPEED self.measured = measured # measured or estimate - # compute distance to path - self.dPath = d_path - # computed velocity and accelerations self.vLead = self.vRel + v_ego_t_aligned - if not self.initted: - self.initted = True - self.aLeadTau = _LEAD_ACCEL_TAU - self.cnt = 1 - self.vision_cnt = 0 - self.vision = False - self.aRel = 0. # nidec gives no information about this - self.vLat = 0. + if self.cnt == 0: self.kf = KF1D([[self.vLead], [0.0]], _VLEAD_A, _VLEAD_C, _VLEAD_K) else: - # estimate acceleration - # TODO: use Kalman filter - a_rel_unfilt = (self.vRel - self.vRelPrev) / ts - a_rel_unfilt = clip(a_rel_unfilt, -10., 10.) - self.aRel = k_a_lead * a_rel_unfilt + (1 - k_a_lead) * self.aRel - - # TODO: use Kalman filter - # neglect steer override cases as dPath is too noisy - v_lat_unfilt = 0. if steer_override else (self.dPath - self.dPathPrev) / ts - self.vLat = k_v_lat * v_lat_unfilt + (1 - k_v_lat) * self.vLat - self.kf.update(self.vLead) - self.cnt += 1 + self.cnt += 1 self.vLeadK = float(self.kf.x[SPEED][0]) self.aLeadK = float(self.kf.x[ACCEL][0]) - if self.stationary: - # stationary objects can become non stationary, but not the other way around - self.stationary = v_ego_t_aligned > v_ego_stationary and abs(self.vLead) < v_stationary_thr - self.oncoming = self.vLead < v_oncoming_thr - - self.vision_score = NO_FUSION_SCORE - # Learn if constant acceleration if abs(self.aLeadK) < 0.5: self.aLeadTau = _LEAD_ACCEL_TAU else: self.aLeadTau *= 0.9 - def update_vision_score(self, dist_to_vision, rel_speed_diff): - # rel speed is very hard to estimate from vision - if dist_to_vision < 4.0 and rel_speed_diff < 10.: - self.vision_score = dist_to_vision + rel_speed_diff - else: - self.vision_score = NO_FUSION_SCORE - - def update_vision_fusion(self): - # vision point is never stationary - # don't trust 1 or 2 fusions until model quality is much better - if self.vision_cnt >= 3: - self.vision = True - self.stationary = False - def get_key_for_cluster(self): # Weigh y higher since radar is inaccurate in this dimension return [self.dRel, self.yRel*2, self.vRel] - -# ******************* Cluster ******************* -if platform.machine() == 'aarch64': - for x in sys.path: - pp = os.path.join(x, "phonelibs/hierarchy/lib") - if os.path.isfile(os.path.join(pp, "_hierarchy.so")): - sys.path.append(pp) - break - import _hierarchy #pylint: disable=import-error -else: - from scipy.cluster import _hierarchy - - -def fcluster(Z, t, criterion='inconsistent', depth=2, R=None, monocrit=None): - # supersimplified function to get fast clustering. Got it from scipy - Z = np.asarray(Z, order='c') - n = Z.shape[0] + 1 - T = np.zeros((n,), dtype='i') - _hierarchy.cluster_dist(Z, T, float(t), int(n)) - return T - + def reset_a_lead(self, aLeadK, aLeadTau): + self.kf = KF1D([[self.vLead], [aLeadK]], _VLEAD_A, _VLEAD_C, _VLEAD_K) + self.aLeadK = aLeadK + self.aLeadTau = aLeadTau def mean(l): return sum(l) / len(l) -class Cluster(object): +class Cluster(): def __init__(self): self.tracks = set() @@ -189,95 +110,59 @@ def vLeadK(self): @property def aLeadK(self): - return mean([t.aLeadK for t in self.tracks]) + if all(t.cnt <= 1 for t in self.tracks): + return 0. + else: + return mean([t.aLeadK for t in self.tracks if t.cnt > 1]) @property def aLeadTau(self): - return mean([t.aLeadTau for t in self.tracks]) - - @property - def vision(self): - return any([t.vision for t in self.tracks]) + if all(t.cnt <= 1 for t in self.tracks): + return _LEAD_ACCEL_TAU + else: + return mean([t.aLeadTau for t in self.tracks if t.cnt > 1]) @property def measured(self): - return any([t.measured for t in self.tracks]) - - @property - def vision_cnt(self): - return max([t.vision_cnt for t in self.tracks]) - - @property - def stationary(self): - return all([t.stationary for t in self.tracks]) - - @property - def oncoming(self): - return all([t.oncoming for t in self.tracks]) + return any(t.measured for t in self.tracks) - def toLive20(self): + def get_RadarState(self, model_prob=0.0): return { - "dRel": float(self.dRel) - RDR_TO_LDR, + "dRel": float(self.dRel), "yRel": float(self.yRel), "vRel": float(self.vRel), - "aRel": float(self.aRel), "vLead": float(self.vLead), - "dPath": float(self.dPath), - "vLat": float(self.vLat), "vLeadK": float(self.vLeadK), "aLeadK": float(self.aLeadK), "status": True, - "fcw": self.is_potential_fcw(), + "fcw": self.is_potential_fcw(model_prob), + "modelProb": model_prob, + "radar": True, "aLeadTau": float(self.aLeadTau) } + def get_RadarState_from_vision(self, lead_msg, v_ego): + return { + "dRel": float(lead_msg.dist - RADAR_TO_CENTER), + "yRel": float(lead_msg.relY), + "vRel": float(lead_msg.relVel), + "vLead": float(v_ego + lead_msg.relVel), + "vLeadK": float(v_ego + lead_msg.relVel), + "aLeadK": float(0), + "aLeadTau": _LEAD_ACCEL_TAU, + "fcw": False, + "modelProb": float(lead_msg.prob), + "radar": False, + "status": True + } + def __str__(self): - ret = "x: %4.1f y: %4.1f v: %4.1f a: %4.1f d: %4.2f" % (self.dRel, self.yRel, self.vRel, self.aLeadK, self.dPath) - if self.stationary: - ret += " stationary" - if self.vision: - ret += " vision" - if self.oncoming: - ret += " oncoming" - if self.vision_cnt > 0: - ret += " vision_cnt: %6.0f" % self.vision_cnt + ret = "x: %4.1f y: %4.1f v: %4.1f a: %4.1f" % (self.dRel, self.yRel, self.vRel, self.aLeadK) return ret - def is_potential_lead(self, v_ego): - # predict cut-ins by extrapolating lateral speed by a lookahead time - # lookahead time depends on cut-in distance. more attentive for close cut-ins - # also, above 50 meters the predicted path isn't very reliable - - # the distance at which v_lat matters is higher at higher speed - lookahead_dist = 40. + v_ego/1.2 #40m at 0mph, ~70m at 80mph - - t_lookahead_v = [1., 0.] - t_lookahead_bp = [10., lookahead_dist] - - # average dist - d_path = self.dPath - - # lat_corr used to be gated on enabled, now always running - t_lookahead = interp(self.dRel, t_lookahead_bp, t_lookahead_v) - - # correct d_path for lookahead time, considering only cut-ins and no more than 1m impact. - lat_corr = clip(t_lookahead * self.vLat, -1., 1.) if self.measured else 0. - - # consider only cut-ins - d_path = clip(d_path + lat_corr, min(0., d_path), max(0.,d_path)) - - return abs(d_path) < 1.5 and not self.stationary and not self.oncoming - - def is_potential_lead2(self, lead_clusters): - if len(lead_clusters) > 0: - lead_cluster = lead_clusters[0] - # check if the new lead is too close and roughly at the same speed of the first lead: - # it might just be the second axle of the same vehicle - return (self.dRel - lead_cluster.dRel) > 8. or abs(self.vRel - lead_cluster.vRel) > 1. - else: - return False + def potential_low_speed_lead(self, v_ego): + # stop for stuff in front of you and low speed, even without model confirmation + return abs(self.yRel) < 1.5 and (v_ego < v_ego_stationary) and self.dRel < 25 - def is_potential_fcw(self): - # is this cluster trustrable enough for triggering fcw? - # fcw can trigger only on clusters that have been fused vision model for at least 20 frames - return self.vision_cnt >= 20 + def is_potential_fcw(self, model_prob): + return model_prob > .9 diff --git a/selfdrive/controls/lib/vehicle_model.py b/selfdrive/controls/lib/vehicle_model.py index 1dc77bf375afb6..1559a893e8cedd 100755 --- a/selfdrive/controls/lib/vehicle_model.py +++ b/selfdrive/controls/lib/vehicle_model.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import numpy as np from numpy.linalg import solve @@ -90,7 +90,7 @@ def calc_slip_factor(VM): return VM.m * (VM.cF * VM.aF - VM.cR * VM.aR) / (VM.l**2 * VM.cF * VM.cR) -class VehicleModel(object): +class VehicleModel(): def __init__(self, CP): """ Args: @@ -140,7 +140,7 @@ def calc_curvature(self, sa, u): u: Speed [m/s] Returns: - Curvature factor [rad/m] + Curvature factor [1/m] """ return self.curvature_factor(u) * sa / self.sR @@ -161,7 +161,7 @@ def get_steer_from_curvature(self, curv, u): """Calculates the required steering wheel angle for a given curvature Args: - curv: Desired curvature [rad/s] + curv: Desired curvature [1/m] u: Speed [m/s] Returns: @@ -170,6 +170,19 @@ def get_steer_from_curvature(self, curv, u): return curv * self.sR * 1.0 / self.curvature_factor(u) + def get_steer_from_yaw_rate(self, yaw_rate, u): + """Calculates the required steering wheel angle for a given yaw_rate + + Args: + yaw_rate: Desired yaw rate [rad/s] + u: Speed [m/s] + + Returns: + Steering wheel angle [rad] + """ + curv = yaw_rate / u + return self.get_steer_from_curvature(curv, u) + def yaw_rate(self, sa, u): """Calculate yaw rate @@ -188,6 +201,6 @@ def yaw_rate(self, sa, u): from selfdrive.car.honda.interface import CarInterface from selfdrive.car.honda.values import CAR - CP = CarInterface.get_params(CAR.CIVIC, {}) + CP = CarInterface.get_params(CAR.CIVIC) VM = VehicleModel(CP) print(VM.yaw_rate(math.radians(20), 10.)) diff --git a/selfdrive/controls/plannerd.py b/selfdrive/controls/plannerd.py index 2a95375408721b..59fe51aaca284d 100755 --- a/selfdrive/controls/plannerd.py +++ b/selfdrive/controls/plannerd.py @@ -1,77 +1,53 @@ -#!/usr/bin/env python -import zmq +#!/usr/bin/env python3 +import gc from cereal import car from common.params import Params +from common.realtime import set_realtime_priority from selfdrive.swaglog import cloudlog -from selfdrive.services import service_list from selfdrive.controls.lib.planner import Planner from selfdrive.controls.lib.vehicle_model import VehicleModel from selfdrive.controls.lib.pathplanner import PathPlanner import selfdrive.messaging as messaging -def plannerd_thread(): - context = zmq.Context() - params = Params() +def plannerd_thread(sm=None, pm=None): + gc.disable() - # Get FCW toggle from settings - fcw_enabled = params.get("IsFcwEnabled") == "1" + # start the loop + set_realtime_priority(2) cloudlog.info("plannerd is waiting for CarParams") CP = car.CarParams.from_bytes(Params().get("CarParams", block=True)) cloudlog.info("plannerd got CarParams: %s", CP.carName) - PL = Planner(CP, fcw_enabled) + PL = Planner(CP) PP = PathPlanner(CP) VM = VehicleModel(CP) - poller = zmq.Poller() - car_state_sock = messaging.sub_sock(context, service_list['carState'].port, conflate=True, poller=poller) - live100_sock = messaging.sub_sock(context, service_list['live100'].port, conflate=True, poller=poller) - live20_sock = messaging.sub_sock(context, service_list['live20'].port, conflate=True, poller=poller) - model_sock = messaging.sub_sock(context, service_list['model'].port, conflate=True, poller=poller) - live_map_data_sock = messaging.sub_sock(context, service_list['liveMapData'].port, conflate=True, poller=poller) - live_parameters_sock = messaging.sub_sock(context, service_list['liveParameters'].port, conflate=True, poller=poller) - - car_state = messaging.new_message() - car_state.init('carState') - live100 = messaging.new_message() - live100.init('live100') - model = messaging.new_message() - model.init('model') - live20 = messaging.new_message() - live20.init('live20') - live_map_data = messaging.new_message() - live_map_data.init('liveMapData') - - live_parameters = messaging.new_message() - live_parameters.init('liveParameters') - live_parameters.liveParameters.valid = True - live_parameters.liveParameters.steerRatio = CP.steerRatio - live_parameters.liveParameters.stiffnessFactor = 1.0 + if sm is None: + sm = messaging.SubMaster(['carState', 'controlsState', 'radarState', 'model', 'liveParameters']) + + if pm is None: + pm = messaging.PubMaster(['plan', 'liveLongitudinalMpc', 'pathPlan', 'liveMpc']) + + sm['liveParameters'].valid = True + sm['liveParameters'].sensorValid = True + sm['liveParameters'].steerRatio = CP.steerRatio + sm['liveParameters'].stiffnessFactor = 1.0 while True: - for socket, event in poller.poll(): - if socket is live100_sock: - live100 = messaging.recv_one(socket) - elif socket is car_state_sock: - car_state = messaging.recv_one(socket) - elif socket is live_parameters_sock: - live_parameters = messaging.recv_one(socket) - elif socket is model_sock: - model = messaging.recv_one(socket) - PP.update(CP, VM, car_state, model, live100, live_parameters) - elif socket is live_map_data_sock: - live_map_data = messaging.recv_one(socket) - elif socket is live20_sock: - live20 = messaging.recv_one(socket) - PL.update(car_state, CP, VM, PP, live20, live100, model, live_map_data) - - -def main(gctx=None): - plannerd_thread() + sm.update() + + if sm.updated['model']: + PP.update(sm, pm, CP, VM) + if sm.updated['radarState']: + PL.update(sm, pm, CP, VM, PP) + + +def main(sm=None, pm=None): + plannerd_thread(sm, pm) if __name__ == "__main__": diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index 4d44c96b9dd34e..4969ba3357d4e2 100755 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -1,23 +1,17 @@ -#!/usr/bin/env python -import zmq -import numpy as np -import numpy.matlib +#!/usr/bin/env python3 import importlib +import math from collections import defaultdict, deque -from fastcluster import linkage_vector import selfdrive.messaging as messaging -from selfdrive.services import service_list -from selfdrive.controls.lib.latcontrol_helpers import calc_lookahead_offset -from selfdrive.controls.lib.model_parser import ModelParser -from selfdrive.controls.lib.radar_helpers import Track, Cluster, fcluster, \ - RDR_TO_LDR, NO_FUSION_SCORE -from selfdrive.controls.lib.vehicle_model import VehicleModel -from selfdrive.swaglog import cloudlog from cereal import car from common.params import Params -from common.realtime import set_realtime_priority, Ratekeeper -from common.kalman.ekf import EKF, SimpleSensor +from common.realtime import DT_RDR, Ratekeeper, set_realtime_priority +from selfdrive.config import RADAR_TO_CAMERA +from selfdrive.controls.lib.cluster.fastcluster_py import \ + cluster_points_centroid +from selfdrive.controls.lib.radar_helpers import Cluster, Track +from selfdrive.swaglog import cloudlog DEBUG = False @@ -26,290 +20,223 @@ XV, SPEEDV = 0, 1 VISION_POINT = -1 +# Time-alignment +v_len = 20 # how many speed data points to remember for t alignment with rdr data -class EKFV1D(EKF): - def __init__(self): - super(EKFV1D, self).__init__(False) - self.identity = numpy.matlib.identity(DIMSV) - self.state = np.matlib.zeros((DIMSV, 1)) - self.var_init = 1e2 # ~ model variance when probability is 70%, so good starting point - self.covar = self.identity * self.var_init - self.process_noise = np.matlib.diag([0.5, 1]) +def laplacian_cdf(x, mu, b): + b = max(b, 1e-4) + return math.exp(-abs(x-mu)/b) - def calc_transfer_fun(self, dt): - tf = np.matlib.identity(DIMSV) - tf[XV, SPEEDV] = dt - tfj = tf - return tf, tfj +def match_vision_to_cluster(v_ego, lead, clusters): + # match vision point to best statistical cluster match + offset_vision_dist = lead.dist - RADAR_TO_CAMERA -## fuses camera and radar data for best lead detection -# FIXME: radard has a memory leak of about 50MB/hr -# BOUNTY: $100 coupon on shop.comma.ai -def radard_thread(gctx=None): - set_realtime_priority(2) + def prob(c): + prob_d = laplacian_cdf(c.dRel, offset_vision_dist, lead.std) + prob_y = laplacian_cdf(c.yRel, lead.relY, lead.relYStd) + prob_v = laplacian_cdf(c.vRel, lead.relVel, lead.relVelStd) - # wait for stats about the car to come in from controls - cloudlog.info("radard is waiting for CarParams") - CP = car.CarParams.from_bytes(Params().get("CarParams", block=True)) - mocked = CP.carName == "mock" - VM = VehicleModel(CP) - cloudlog.info("radard got CarParams") + # This is isn't exactly right, but good heuristic + return prob_d * prob_y * prob_v - # import the radar from the fingerprint - cloudlog.info("radard is importing %s", CP.carName) - RadarInterface = importlib.import_module('selfdrive.car.%s.radar_interface' % CP.carName).RadarInterface - context = zmq.Context() - - # *** subscribe to features and model from visiond - poller = zmq.Poller() - model = messaging.sub_sock(context, service_list['model'].port, conflate=True, poller=poller) - live100 = messaging.sub_sock(context, service_list['live100'].port, conflate=True, poller=poller) - live_parameters_sock = messaging.sub_sock(context, service_list['liveParameters'].port, conflate=True, poller=poller) - - # Default parameters - live_parameters = messaging.new_message() - live_parameters.init('liveParameters') - live_parameters.liveParameters.valid = True - live_parameters.liveParameters.steerRatio = CP.steerRatio - live_parameters.liveParameters.stiffnessFactor = 1.0 - - MP = ModelParser() - RI = RadarInterface(CP) + cluster = max(clusters, key=prob) - last_md_ts = 0 - last_l100_ts = 0 + # if no 'sane' match is found return -1 + # stationary radar points can be false positives + dist_sane = abs(cluster.dRel - offset_vision_dist) < max([(offset_vision_dist)*.25, 5.0]) + vel_sane = (abs(cluster.vRel - lead.relVel) < 10) or (v_ego + cluster.vRel > 2) + if dist_sane and vel_sane: + return cluster + else: + return None - # *** publish live20 and liveTracks - live20 = messaging.pub_sock(context, service_list['live20'].port) - liveTracks = messaging.pub_sock(context, service_list['liveTracks'].port) - path_x = np.arange(0.0, 140.0, 0.1) # 140 meters is max +def get_lead(v_ego, ready, clusters, lead_msg, low_speed_override=True): + # Determine leads, this is where the essential logic happens + if len(clusters) > 0 and ready and lead_msg.prob > .5: + cluster = match_vision_to_cluster(v_ego, lead_msg, clusters) + else: + cluster = None - # Time-alignment - rate = 20. # model and radar are both at 20Hz - tsv = 1./rate - v_len = 20 # how many speed data points to remember for t alignment with rdr data + lead_dict = {'status': False} + if cluster is not None: + lead_dict = cluster.get_RadarState(lead_msg.prob) + elif (cluster is None) and ready and (lead_msg.prob > .5): + lead_dict = Cluster().get_RadarState_from_vision(lead_msg, v_ego) - active = 0 - steer_angle = 0. - steer_override = False + if low_speed_override: + low_speed_clusters = [c for c in clusters if c.potential_low_speed_lead(v_ego)] + if len(low_speed_clusters) > 0: + closest_cluster = min(low_speed_clusters, key=lambda c: c.dRel) - tracks = defaultdict(dict) + # Only choose new cluster if it is actually closer than the previous one + if (not lead_dict['status']) or (closest_cluster.dRel < lead_dict['dRel']): + lead_dict = closest_cluster.get_RadarState() - # Kalman filter stuff: - ekfv = EKFV1D() - speedSensorV = SimpleSensor(XV, 1, 2) + return lead_dict - # v_ego - v_ego = None - v_ego_hist_t = deque(maxlen=v_len) - v_ego_hist_v = deque(maxlen=v_len) - v_ego_t_aligned = 0. - rk = Ratekeeper(rate, print_delay_threshold=np.inf) - while 1: - rr = RI.update() +class RadarD(): + def __init__(self, mocked, delay=0): + self.current_time = 0 + self.mocked = mocked - ar_pts = {} - for pt in rr.points: - ar_pts[pt.trackId] = [pt.dRel + RDR_TO_LDR, pt.yRel, pt.vRel, pt.measured] + self.tracks = defaultdict(dict) - # receive the live100s - l100 = None - md = None + self.last_md_ts = 0 + self.last_controls_state_ts = 0 - for socket, event in poller.poll(0): - if socket is live100: - l100 = messaging.recv_one(socket) - elif socket is model: - md = messaging.recv_one(socket) - elif socket is live_parameters_sock: - live_parameters = messaging.recv_one(socket) - VM.update_params(live_parameters.liveParameters.stiffnessFactor, live_parameters.liveParameters.steerRatio) + self.active = 0 - if l100 is not None: - active = l100.live100.active - v_ego = l100.live100.vEgo - steer_angle = l100.live100.angleSteers - steer_override = l100.live100.steerOverride + # v_ego + self.v_ego = 0. + self.v_ego_hist = deque([0], maxlen=delay+1) - v_ego_hist_v.append(v_ego) - v_ego_hist_t.append(float(rk.frame)/rate) + self.v_ego_t_aligned = 0. + self.ready = False - last_l100_ts = l100.logMonoTime + def update(self, frame, sm, rr, has_radar): + self.current_time = 1e-9*max([sm.logMonoTime[key] for key in sm.logMonoTime.keys()]) - if v_ego is None: - continue + if sm.updated['controlsState']: + self.active = sm['controlsState'].active + self.v_ego = sm['controlsState'].vEgo + self.v_ego_hist.append(self.v_ego) + if sm.updated['model']: + self.ready = True - if md is not None: - last_md_ts = md.logMonoTime - - # *** get path prediction from the model *** - MP.update(v_ego, md) - - # run kalman filter only if prob is high enough - if MP.lead_prob > 0.7: - reading = speedSensorV.read(MP.lead_dist, covar=np.matrix(MP.lead_var)) - ekfv.update_scalar(reading) - ekfv.predict(tsv) - - # When changing lanes the distance to the lead car can suddenly change, - # which makes the Kalman filter output large relative acceleration - if mocked and abs(MP.lead_dist - ekfv.state[XV]) > 2.0: - ekfv.state[XV] = MP.lead_dist - ekfv.covar = (np.diag([MP.lead_var, ekfv.var_init])) - ekfv.state[SPEEDV] = 0. - - ar_pts[VISION_POINT] = (float(ekfv.state[XV]), np.polyval(MP.d_poly, float(ekfv.state[XV])), - float(ekfv.state[SPEEDV]), False) - else: - ekfv.state[XV] = MP.lead_dist - ekfv.covar = (np.diag([MP.lead_var, ekfv.var_init])) - ekfv.state[SPEEDV] = 0. - - if VISION_POINT in ar_pts: - del ar_pts[VISION_POINT] - - # *** compute the likely path_y *** - if (active and not steer_override) or mocked: - # use path from model (always when mocking as steering is too noisy) - path_y = np.polyval(MP.d_poly, path_x) - else: - # use path from steer, set angle_offset to 0 it does not only report the physical offset - path_y = calc_lookahead_offset(v_ego, steer_angle, path_x, VM, angle_offset=live_parameters.liveParameters.angleOffsetAverage)[0] + ar_pts = {} + for pt in rr.points: + ar_pts[pt.trackId] = [pt.dRel, pt.yRel, pt.vRel, pt.measured] # *** remove missing points from meta data *** - for ids in tracks.keys(): + for ids in list(self.tracks.keys()): if ids not in ar_pts: - tracks.pop(ids, None) + self.tracks.pop(ids, None) # *** compute the tracks *** for ids in ar_pts: - # ignore standalone vision point, unless we are mocking the radar - if ids == VISION_POINT and not mocked: - continue rpt = ar_pts[ids] # align v_ego by a fixed time to align it with the radar measurement - cur_time = float(rk.frame)/rate - v_ego_t_aligned = np.interp(cur_time - RI.delay, v_ego_hist_t, v_ego_hist_v) - - d_path = np.sqrt(np.amin((path_x - rpt[0]) ** 2 + (path_y - rpt[1]) ** 2)) - # add sign - d_path *= np.sign(rpt[1] - np.interp(rpt[0], path_x, path_y)) + self.v_ego_t_aligned = self.v_ego_hist[0] # create the track if it doesn't exist or it's a new track - if ids not in tracks: - tracks[ids] = Track() - tracks[ids].update(rpt[0], rpt[1], rpt[2], d_path, v_ego_t_aligned, rpt[3], steer_override) - - # allow the vision model to remove the stationary flag if distance and rel speed roughly match - if VISION_POINT in ar_pts: - fused_id = None - best_score = NO_FUSION_SCORE - for ids in tracks: - dist_to_vision = np.sqrt((0.5*(ar_pts[VISION_POINT][0] - tracks[ids].dRel)) ** 2 + (2*(ar_pts[VISION_POINT][1] - tracks[ids].yRel)) ** 2) - rel_speed_diff = abs(ar_pts[VISION_POINT][2] - tracks[ids].vRel) - tracks[ids].update_vision_score(dist_to_vision, rel_speed_diff) - if best_score > tracks[ids].vision_score: - fused_id = ids - best_score = tracks[ids].vision_score - - if fused_id is not None: - tracks[fused_id].vision_cnt += 1 - tracks[fused_id].update_vision_fusion() - - if DEBUG: - print("NEW CYCLE") - if VISION_POINT in ar_pts: - print("vision", ar_pts[VISION_POINT]) - - idens = tracks.keys() - track_pts = np.array([tracks[iden].get_key_for_cluster() for iden in idens]) + if ids not in self.tracks: + self.tracks[ids] = Track() + self.tracks[ids].update(rpt[0], rpt[1], rpt[2], self.v_ego_t_aligned, rpt[3]) + + idens = list(sorted(self.tracks.keys())) + track_pts = list([self.tracks[iden].get_key_for_cluster() for iden in idens]) + # If we have multiple points, cluster them if len(track_pts) > 1: - link = linkage_vector(track_pts, method='centroid') - cluster_idxs = fcluster(link, 2.5, criterion='distance') - clusters = [None]*max(cluster_idxs) - - for idx in xrange(len(track_pts)): - cluster_i = cluster_idxs[idx]-1 + cluster_idxs = cluster_points_centroid(track_pts, 2.5) + clusters = [None] * (max(cluster_idxs) + 1) - if clusters[cluster_i] == None: + for idx in range(len(track_pts)): + cluster_i = cluster_idxs[idx] + if clusters[cluster_i] is None: clusters[cluster_i] = Cluster() - clusters[cluster_i].add(tracks[idens[idx]]) + clusters[cluster_i].add(self.tracks[idens[idx]]) elif len(track_pts) == 1: - # TODO: why do we need this? + # FIXME: cluster_point_centroid hangs forever if len(track_pts) == 1 + cluster_idxs = [0] clusters = [Cluster()] - clusters[0].add(tracks[idens[0]]) + clusters[0].add(self.tracks[idens[0]]) else: clusters = [] - if DEBUG: - for i in clusters: - print(i) - # *** extract the lead car *** - lead_clusters = [c for c in clusters - if c.is_potential_lead(v_ego)] - lead_clusters.sort(key=lambda x: x.dRel) - lead_len = len(lead_clusters) - - # *** extract the second lead from the whole set of leads *** - lead2_clusters = [c for c in lead_clusters - if c.is_potential_lead2(lead_clusters)] - lead2_clusters.sort(key=lambda x: x.dRel) - lead2_len = len(lead2_clusters) - - # *** publish live20 *** + # if a new point, reset accel to the rest of the cluster + for idx in range(len(track_pts)): + if self.tracks[idens[idx]].cnt <= 1: + aLeadK = clusters[cluster_idxs[idx]].aLeadK + aLeadTau = clusters[cluster_idxs[idx]].aLeadTau + self.tracks[idens[idx]].reset_a_lead(aLeadK, aLeadTau) + + # *** publish radarState *** dat = messaging.new_message() - dat.init('live20') - dat.live20.mdMonoTime = last_md_ts - dat.live20.canMonoTimes = list(rr.canMonoTimes) - dat.live20.radarErrors = list(rr.errors) - dat.live20.l100MonoTime = last_l100_ts - if lead_len > 0: - dat.live20.leadOne = lead_clusters[0].toLive20() - if lead2_len > 0: - dat.live20.leadTwo = lead2_clusters[0].toLive20() - else: - dat.live20.leadTwo.status = False - else: - dat.live20.leadOne.status = False + dat.init('radarState') + dat.valid = sm.all_alive_and_valid(service_list=['controlsState', 'model']) + dat.radarState.mdMonoTime = self.last_md_ts + dat.radarState.canMonoTimes = list(rr.canMonoTimes) + dat.radarState.radarErrors = list(rr.errors) + dat.radarState.controlsStateMonoTime = self.last_controls_state_ts + + if has_radar: + dat.radarState.leadOne = get_lead(self.v_ego, self.ready, clusters, sm['model'].lead, low_speed_override=True) + dat.radarState.leadTwo = get_lead(self.v_ego, self.ready, clusters, sm['model'].leadFuture, low_speed_override=False) + return dat + + +# fuses camera and radar data for best lead detection +def radard_thread(sm=None, pm=None, can_sock=None): + set_realtime_priority(2) + + # wait for stats about the car to come in from controls + cloudlog.info("radard is waiting for CarParams") + CP = car.CarParams.from_bytes(Params().get("CarParams", block=True)) + mocked = CP.carName == "mock" + cloudlog.info("radard got CarParams") + + # import the radar from the fingerprint + cloudlog.info("radard is importing %s", CP.carName) + RadarInterface = importlib.import_module('selfdrive.car.%s.radar_interface' % CP.carName).RadarInterface - dat.live20.cumLagMs = -rk.remaining*1000. - live20.send(dat.to_bytes()) + if can_sock is None: + can_sock = messaging.sub_sock('can') + + if sm is None: + sm = messaging.SubMaster(['model', 'controlsState', 'liveParameters']) + + # *** publish radarState and liveTracks + if pm is None: + pm = messaging.PubMaster(['radarState', 'liveTracks']) + + RI = RadarInterface(CP) + + rk = Ratekeeper(1.0 / DT_RDR, print_delay_threshold=None) + RD = RadarD(mocked, RI.delay) + + has_radar = not CP.radarOffCan + + while 1: + can_strings = messaging.drain_sock_raw(can_sock, wait_for_one=True) + rr = RI.update(can_strings) + + if rr is None: + continue + + sm.update(0) + + dat = RD.update(rk.frame, sm, rr, has_radar) + dat.radarState.cumLagMs = -rk.remaining*1000. + + pm.send('radarState', dat) # *** publish tracks for UI debugging (keep last) *** + tracks = RD.tracks dat = messaging.new_message() dat.init('liveTracks', len(tracks)) - for cnt, ids in enumerate(tracks.keys()): - if DEBUG: - print("id: %4.0f x: %4.1f y: %4.1f vr: %4.1f d: %4.1f va: %4.1f vl: %4.1f vlk: %4.1f alk: %4.1f s: %1.0f v: %1.0f" % \ - (ids, tracks[ids].dRel, tracks[ids].yRel, tracks[ids].vRel, - tracks[ids].dPath, tracks[ids].vLat, - tracks[ids].vLead, tracks[ids].vLeadK, - tracks[ids].aLeadK, - tracks[ids].stationary, - tracks[ids].measured)) + for cnt, ids in enumerate(sorted(tracks.keys())): dat.liveTracks[cnt] = { "trackId": ids, "dRel": float(tracks[ids].dRel), "yRel": float(tracks[ids].yRel), "vRel": float(tracks[ids].vRel), - "aRel": float(tracks[ids].aRel), - "stationary": bool(tracks[ids].stationary), - "oncoming": bool(tracks[ids].oncoming), } - liveTracks.send(dat.to_bytes()) + pm.send('liveTracks', dat) rk.monitor_time() -def main(gctx=None): - radard_thread(gctx) + +def main(sm=None, pm=None, can_sock=None): + radard_thread(sm, pm, can_sock) + if __name__ == "__main__": main() diff --git a/selfdrive/debug/getframes/__init__.py b/selfdrive/controls/tests/__init__.py similarity index 100% rename from selfdrive/debug/getframes/__init__.py rename to selfdrive/controls/tests/__init__.py diff --git a/selfdrive/controls/tests/test_clustering.py b/selfdrive/controls/tests/test_clustering.py new file mode 100644 index 00000000000000..e899ff7d5788b1 --- /dev/null +++ b/selfdrive/controls/tests/test_clustering.py @@ -0,0 +1,138 @@ +import time +import unittest +import numpy as np +from fastcluster import linkage_vector +from scipy.cluster import _hierarchy +from scipy.spatial.distance import pdist + +from selfdrive.controls.lib.cluster.fastcluster_py import hclust, ffi +from selfdrive.controls.lib.cluster.fastcluster_py import cluster_points_centroid + + +def fcluster(Z, t, criterion='inconsistent', depth=2, R=None, monocrit=None): + # supersimplified function to get fast clustering. Got it from scipy + Z = np.asarray(Z, order='c') + n = Z.shape[0] + 1 + T = np.zeros((n,), dtype='i') + _hierarchy.cluster_dist(Z, T, float(t), int(n)) + return T + + +TRACK_PTS = np.array([[59.26000137, -9.35999966, -5.42500019], + [91.61999817, -0.31999999, -2.75], + [31.38000031, 0.40000001, -0.2], + [89.57999725, -8.07999992, -18.04999924], + [53.42000122, 0.63999999, -0.175], + [31.38000031, 0.47999999, -0.2], + [36.33999939, 0.16, -0.2], + [53.33999939, 0.95999998, -0.175], + [59.26000137, -9.76000023, -5.44999981], + [33.93999977, 0.40000001, -0.22499999], + [106.74000092, -5.76000023, -18.04999924]]) + +CORRECT_LINK = np.array([[2., 5., 0.07999998, 2.], + [4., 7., 0.32984889, 2.], + [0., 8., 0.40078104, 2.], + [6., 9., 2.41209933, 2.], + [11., 14., 3.76342275, 4.], + [12., 13., 13.02297651, 4.], + [1., 3., 17.27626057, 2.], + [10., 17., 17.92918845, 3.], + [15., 16., 23.68525366, 8.], + [18., 19., 52.52351319, 11.]]) + +CORRECT_LABELS = np.array([7, 1, 4, 2, 6, 4, 5, 6, 7, 5, 3], dtype=np.int32) + + +def plot_cluster(pts, idx_old, idx_new): + import matplotlib.pyplot as plt + m = 'Set1' + + plt.figure() + plt.subplot(1, 2, 1) + plt.scatter(pts[:, 0], pts[:, 1], c=idx_old, cmap=m) + plt.title("Old") + plt.colorbar() + plt.subplot(1, 2, 2) + plt.scatter(pts[:, 0], pts[:, 1], c=idx_new, cmap=m) + plt.title("New") + plt.colorbar() + + plt.show() + + +def same_clusters(correct, other): + correct = np.asarray(correct) + other = np.asarray(other) + if len(correct) != len(other): + return False + + for i in range(len(correct)): + c = np.where(correct == correct[i]) + o = np.where(other == other[i]) + if not np.array_equal(c, o): + return False + return True + + +class TestClustering(unittest.TestCase): + def test_scipy_clustering(self): + old_link = linkage_vector(TRACK_PTS, method='centroid') + old_cluster_idxs = fcluster(old_link, 2.5, criterion='distance') + + np.testing.assert_allclose(old_link, CORRECT_LINK) + np.testing.assert_allclose(old_cluster_idxs, CORRECT_LABELS) + + def test_pdist(self): + pts = np.ascontiguousarray(TRACK_PTS, dtype=np.float64) + pts_ptr = ffi.cast("double *", pts.ctypes.data) + + n, m = pts.shape + out = np.zeros((n * (n - 1) // 2, ), dtype=np.float64) + out_ptr = ffi.cast("double *", out.ctypes.data) + hclust.hclust_pdist(n, m, pts_ptr, out_ptr) + + np.testing.assert_allclose(out, np.power(pdist(TRACK_PTS), 2)) + + def test_cpp_clustering(self): + pts = np.ascontiguousarray(TRACK_PTS, dtype=np.float64) + pts_ptr = ffi.cast("double *", pts.ctypes.data) + n, m = pts.shape + + labels = np.zeros((n, ), dtype=np.int32) + labels_ptr = ffi.cast("int *", labels.ctypes.data) + hclust.cluster_points_centroid(n, m, pts_ptr, 2.5**2, labels_ptr) + self.assertTrue(same_clusters(CORRECT_LABELS, labels)) + + def test_cpp_wrapper_clustering(self): + labels = cluster_points_centroid(TRACK_PTS, 2.5) + self.assertTrue(same_clusters(CORRECT_LABELS, labels)) + + def test_random_cluster(self): + np.random.seed(1337) + N = 1000 + + t_old = 0. + t_new = 0. + + for _ in range(N): + n = int(np.random.uniform(2, 32)) + x = np.random.uniform(-10, 50, (n, 1)) + y = np.random.uniform(-5, 5, (n, 1)) + vrel = np.random.uniform(-5, 5, (n, 1)) + pts = np.hstack([x, y, vrel]) + + t = time.time() + old_link = linkage_vector(pts, method='centroid') + old_cluster_idx = fcluster(old_link, 2.5, criterion='distance') + t_old += time.time() - t + + t = time.time() + cluster_idx = cluster_points_centroid(pts, 2.5) + t_new += time.time() - t + + self.assertTrue(same_clusters(old_cluster_idx, cluster_idx)) + + +if __name__ == "__main__": + unittest.main() diff --git a/selfdrive/controls/tests/test_following_distance.py b/selfdrive/controls/tests/test_following_distance.py new file mode 100644 index 00000000000000..331cb14eacb4ab --- /dev/null +++ b/selfdrive/controls/tests/test_following_distance.py @@ -0,0 +1,91 @@ +import unittest +import numpy as np + +from cereal import log +import selfdrive.messaging as messaging +from selfdrive.config import Conversions as CV +from selfdrive.controls.lib.planner import calc_cruise_accel_limits +from selfdrive.controls.lib.speed_smoother import speed_smoother +from selfdrive.controls.lib.long_mpc import LongitudinalMpc + + +def RW(v_ego, v_l): + TR = 1.8 + G = 9.81 + return (v_ego * TR - (v_l - v_ego) * TR + v_ego * v_ego / (2 * G) - v_l * v_l / (2 * G)) + + +class FakePubMaster(): + def send(self, s, data): + assert data + + +def run_following_distance_simulation(v_lead, t_end=200.0): + dt = 0.2 + t = 0. + + x_lead = 200.0 + + x_ego = 0.0 + v_ego = v_lead + a_ego = 0.0 + + v_cruise_setpoint = v_lead + 10. + + pm = FakePubMaster() + mpc = LongitudinalMpc(1) + + first = True + while t < t_end: + # Run cruise control + accel_limits = [float(x) for x in calc_cruise_accel_limits(v_ego)] + jerk_limits = [min(-0.1, accel_limits[0]), max(0.1, accel_limits[1])] + v_cruise, a_cruise = speed_smoother(v_ego, a_ego, v_cruise_setpoint, + accel_limits[1], accel_limits[0], + jerk_limits[1], jerk_limits[0], + dt) + + # Setup CarState + CS = messaging.new_message() + CS.init('carState') + CS.carState.vEgo = v_ego + CS.carState.aEgo = a_ego + + # Setup lead packet + lead = log.RadarState.LeadData.new_message() + lead.status = True + lead.dRel = x_lead - x_ego + lead.vLead = v_lead + lead.aLeadK = 0.0 + + # Run MPC + mpc.set_cur_state(v_ego, a_ego) + if first: # Make sure MPC is converged on first timestep + for _ in range(20): + mpc.update(pm, CS.carState, lead, v_cruise_setpoint) + mpc.update(pm, CS.carState, lead, v_cruise_setpoint) + + # Choose slowest of two solutions + if v_cruise < mpc.v_mpc: + v_ego, a_ego = v_cruise, a_cruise + else: + v_ego, a_ego = mpc.v_mpc, mpc.a_mpc + + # Update state + x_lead += v_lead * dt + x_ego += v_ego * dt + t += dt + first = False + + return x_lead - x_ego + + +class TestFollowingDistance(unittest.TestCase): + def test_following_distanc(self): + for speed_mph in np.linspace(10, 100, num=10): + v_lead = float(speed_mph * CV.MPH_TO_MS) + + simulation_steady_state = run_following_distance_simulation(v_lead) + correct_steady_state = RW(v_lead, v_lead) + 4.0 + + self.assertAlmostEqual(simulation_steady_state, correct_steady_state, delta=0.1) diff --git a/selfdrive/controls/tests/test_lateral_mpc.py b/selfdrive/controls/tests/test_lateral_mpc.py new file mode 100644 index 00000000000000..8dfff81ad40b59 --- /dev/null +++ b/selfdrive/controls/tests/test_lateral_mpc.py @@ -0,0 +1,129 @@ +import unittest +import numpy as np +from selfdrive.car.honda.interface import CarInterface +from selfdrive.controls.lib.lateral_mpc import libmpc_py +from selfdrive.controls.lib.vehicle_model import VehicleModel +from selfdrive.controls.lib.lane_planner import calc_d_poly + + +def run_mpc(v_ref=30., x_init=0., y_init=0., psi_init=0., delta_init=0., + l_prob=1., r_prob=1., p_prob=1., + poly_l=np.array([0., 0., 0., 1.8]), poly_r=np.array([0., 0., 0., -1.8]), poly_p=np.array([0., 0., 0., 0.]), + lane_width=3.6, poly_shift=0.): + + libmpc = libmpc_py.libmpc + libmpc.init(1.0, 3.0, 1.0, 1.0) + + mpc_solution = libmpc_py.ffi.new("log_t *") + + p_l = poly_l.copy() + p_l[3] += poly_shift + + p_r = poly_r.copy() + p_r[3] += poly_shift + + p_p = poly_p.copy() + p_p[3] += poly_shift + + d_poly = calc_d_poly(p_l, p_r, p_p, l_prob, r_prob, lane_width) + + CP = CarInterface.get_params("HONDA CIVIC 2016 TOURING") + VM = VehicleModel(CP) + + v_ref = v_ref + curvature_factor = VM.curvature_factor(v_ref) + + l_poly = libmpc_py.ffi.new("double[4]", list(map(float, p_l))) + r_poly = libmpc_py.ffi.new("double[4]", list(map(float, p_r))) + d_poly = libmpc_py.ffi.new("double[4]", list(map(float, d_poly))) + + cur_state = libmpc_py.ffi.new("state_t *") + cur_state[0].x = x_init + cur_state[0].y = y_init + cur_state[0].psi = psi_init + cur_state[0].delta = delta_init + + # converge in no more than 20 iterations + for _ in range(20): + libmpc.run_mpc(cur_state, mpc_solution, l_poly, r_poly, d_poly, l_prob, r_prob, + curvature_factor, v_ref, lane_width) + + return mpc_solution + + +class TestLateralMpc(unittest.TestCase): + + def _assert_null(self, sol, delta=1e-6): + for i in range(len(sol[0].y)): + self.assertAlmostEqual(sol[0].y[i], 0., delta=delta) + self.assertAlmostEqual(sol[0].psi[i], 0., delta=delta) + self.assertAlmostEqual(sol[0].delta[i], 0., delta=delta) + + def _assert_simmetry(self, sol, delta=1e-6): + for i in range(len(sol[0][0].y)): + self.assertAlmostEqual(sol[0][0].y[i], -sol[1][0].y[i], delta=delta) + self.assertAlmostEqual(sol[0][0].psi[i], -sol[1][0].psi[i], delta=delta) + self.assertAlmostEqual(sol[0][0].delta[i], -sol[1][0].delta[i], delta=delta) + self.assertAlmostEqual(sol[0][0].x[i], sol[1][0].x[i], delta=delta) + + def _assert_identity(self, sol, ignore_y=False, delta=1e-6): + for i in range(len(sol[0][0].y)): + self.assertAlmostEqual(sol[0][0].psi[i], sol[1][0].psi[i], delta=delta) + self.assertAlmostEqual(sol[0][0].delta[i], sol[1][0].delta[i], delta=delta) + self.assertAlmostEqual(sol[0][0].x[i], sol[1][0].x[i], delta=delta) + if not ignore_y: + self.assertAlmostEqual(sol[0][0].y[i], sol[1][0].y[i], delta=delta) + + def test_straight(self): + sol = run_mpc() + self._assert_null(sol) + + def test_y_symmetry(self): + sol = [] + for y_init in [-0.5, 0.5]: + sol.append(run_mpc(y_init=y_init)) + self._assert_simmetry(sol) + + def test_poly_symmetry(self): + sol = [] + for poly_shift in [-1., 1.]: + sol.append(run_mpc(poly_shift=poly_shift)) + self._assert_simmetry(sol) + + def test_delta_symmetry(self): + sol = [] + for delta_init in [-0.1, 0.1]: + sol.append(run_mpc(delta_init=delta_init)) + self._assert_simmetry(sol) + + def test_psi_symmetry(self): + sol = [] + for psi_init in [-0.1, 0.1]: + sol.append(run_mpc(psi_init=psi_init)) + self._assert_simmetry(sol) + + def test_prob_symmetry(self): + sol = [] + lane_width = 3. + for r_prob in [0., 1.]: + sol.append(run_mpc(r_prob=r_prob, l_prob=1.-r_prob, lane_width=lane_width)) + self._assert_simmetry(sol) + + def test_y_shift_vs_poly_shift(self): + shift = 1. + sol = [] + sol.append(run_mpc(y_init=shift)) + sol.append(run_mpc(poly_shift=-shift)) + # need larger delta than standard, otherwise it false triggers. + # this is acceptable because the 2 cases are very different from the optimizer standpoint + self._assert_identity(sol, ignore_y=True, delta=1e-5) + + def test_no_overshoot(self): + y_init = 1. + sol = run_mpc(y_init=y_init) + for y in list(sol[0].y): + self.assertGreaterEqual(y_init, abs(y)) + + +if __name__ == "__main__": + unittest.main() diff --git a/selfdrive/controls/tests/test_monitoring.py b/selfdrive/controls/tests/test_monitoring.py new file mode 100644 index 00000000000000..d5c14d663dedc5 --- /dev/null +++ b/selfdrive/controls/tests/test_monitoring.py @@ -0,0 +1,200 @@ +import unittest +import numpy as np +from common.realtime import DT_CTRL, DT_DMON +from selfdrive.controls.lib.driver_monitor import DriverStatus, MAX_TERMINAL_ALERTS, \ + _AWARENESS_TIME, _AWARENESS_PRE_TIME_TILL_TERMINAL, \ + _AWARENESS_PROMPT_TIME_TILL_TERMINAL, _DISTRACTED_TIME, \ + _DISTRACTED_PRE_TIME_TILL_TERMINAL, _DISTRACTED_PROMPT_TIME_TILL_TERMINAL +from selfdrive.controls.lib.gps_helpers import is_rhd_region + +_TEST_TIMESPAN = 120 # seconds +_DISTRACTED_SECONDS_TO_ORANGE = _DISTRACTED_TIME - _DISTRACTED_PROMPT_TIME_TILL_TERMINAL + 1 +_DISTRACTED_SECONDS_TO_RED = _DISTRACTED_TIME + 1 +_INVISIBLE_SECONDS_TO_ORANGE = _AWARENESS_TIME - _AWARENESS_PROMPT_TIME_TILL_TERMINAL + 1 +_INVISIBLE_SECONDS_TO_RED = _AWARENESS_TIME + 1 + +class fake_DM_msg(): + def __init__(self, is_face_detected, is_distracted=False): + self.faceOrientation = [0.,0.,0.] + self.facePosition = [0.,0.] + self.faceProb = 1. * is_face_detected + self.leftEyeProb = 1. + self.rightEyeProb = 1. + self.leftBlinkProb = 1. * is_distracted + self.rightBlinkProb = 1. * is_distracted + + +# driver state from neural net, 10Hz +msg_NO_FACE_DETECTED = fake_DM_msg(is_face_detected=False) +msg_ATTENTIVE = fake_DM_msg(is_face_detected=True) +msg_DISTRACTED = fake_DM_msg(is_face_detected=True, is_distracted=True) + +# driver interaction with car +car_interaction_DETECTED = True +car_interaction_NOT_DETECTED = False + +# openpilot state +openpilot_ENGAGED = True +openpilot_NOT_ENGAGED = False + +# car standstill state +car_STANDSTILL = True +car_NOT_STANDSTILL = False + +# some common state vectors +always_no_face = [msg_NO_FACE_DETECTED] * int(_TEST_TIMESPAN/DT_DMON) +always_attentive = [msg_ATTENTIVE] * int(_TEST_TIMESPAN/DT_DMON) +always_distracted = [msg_DISTRACTED] * int(_TEST_TIMESPAN/DT_DMON) +always_true = [True] * int(_TEST_TIMESPAN/DT_DMON) +always_false = [False] * int(_TEST_TIMESPAN/DT_DMON) + +def run_DState_seq(driver_state_msgs, driver_car_interaction, openpilot_status, car_standstill_status): + # inputs are all 10Hz + DS = DriverStatus() + events_from_DM = [] + for idx in range(len(driver_state_msgs)): + DS.get_pose(driver_state_msgs[idx], [0,0,0], 0, openpilot_status[idx]) + # cal_rpy and car_speed don't matter here + + # to match frequency of controlsd (100Hz) + for _ in range(int(DT_DMON/DT_CTRL)): + event_per_state = DS.update([], driver_car_interaction[idx], openpilot_status[idx], car_standstill_status[idx]) + events_from_DM.append(event_per_state) # evaluate events at 10Hz for tests + + assert len(events_from_DM)==len(driver_state_msgs), 'somethings wrong' + return events_from_DM + +class TestMonitoring(unittest.TestCase): + # -1. rhd parser sanity check + def test_rhd_parser(self): + cities = [[32.7, -117.1, 0],\ + [51.5, 0.129, 1],\ + [35.7, 139.7, 1],\ + [-37.8, 144.9, 1],\ + [32.1, 41.74, 0],\ + [55.7, 12.69, 0]] + result = [] + for city in cities: + result.append(int(is_rhd_region(city[0],city[1]))) + self.assertEqual(result,[int(city[2]) for city in cities]) + + # 0. op engaged, driver is doing fine all the time + def test_fully_aware_driver(self): + events_output = run_DState_seq(always_attentive, always_false, always_true, always_false) + self.assertTrue(np.sum([len(event) for event in events_output])==0) + + # 1. op engaged, driver is distracted and does nothing + def test_fully_distracted_driver(self): + events_output = run_DState_seq(always_distracted, always_false, always_true, always_false) + self.assertTrue(len(events_output[int((_DISTRACTED_TIME-_DISTRACTED_PRE_TIME_TILL_TERMINAL)/2/DT_DMON)])==0) + self.assertEqual(events_output[int((_DISTRACTED_TIME-_DISTRACTED_PRE_TIME_TILL_TERMINAL+\ + ((_DISTRACTED_PRE_TIME_TILL_TERMINAL-_DISTRACTED_PROMPT_TIME_TILL_TERMINAL)/2))/DT_DMON)][0].name, 'preDriverDistracted') + self.assertEqual(events_output[int((_DISTRACTED_TIME-_DISTRACTED_PROMPT_TIME_TILL_TERMINAL+\ + ((_DISTRACTED_PROMPT_TIME_TILL_TERMINAL)/2))/DT_DMON)][0].name, 'promptDriverDistracted') + self.assertEqual(events_output[int((_DISTRACTED_TIME+\ + ((_TEST_TIMESPAN-10-_DISTRACTED_TIME)/2))/DT_DMON)][0].name, 'driverDistracted') + + # 2. op engaged, no face detected the whole time, no action + def test_fully_invisible_driver(self): + events_output = run_DState_seq(always_no_face, always_false, always_true, always_false) + self.assertTrue(len(events_output[int((_AWARENESS_TIME-_AWARENESS_PRE_TIME_TILL_TERMINAL)/2/DT_DMON)])==0) + self.assertEqual(events_output[int((_AWARENESS_TIME-_AWARENESS_PRE_TIME_TILL_TERMINAL+\ + ((_AWARENESS_PRE_TIME_TILL_TERMINAL-_AWARENESS_PROMPT_TIME_TILL_TERMINAL)/2))/DT_DMON)][0].name, 'preDriverUnresponsive') + self.assertEqual(events_output[int((_AWARENESS_TIME-_AWARENESS_PROMPT_TIME_TILL_TERMINAL+\ + ((_AWARENESS_PROMPT_TIME_TILL_TERMINAL)/2))/DT_DMON)][0].name, 'promptDriverUnresponsive') + self.assertEqual(events_output[int((_AWARENESS_TIME+\ + ((_TEST_TIMESPAN-10-_AWARENESS_TIME)/2))/DT_DMON)][0].name, 'driverUnresponsive') + + # 3. op engaged, down to orange, driver pays attention, back to normal; then down to orange, driver touches wheel + # - should have short orange recovery time and no green afterwards; should recover rightaway on wheel touch + def test_normal_driver(self): + ds_vector = [msg_DISTRACTED] * int(_DISTRACTED_SECONDS_TO_ORANGE/DT_DMON) + \ + [msg_ATTENTIVE] * int(_DISTRACTED_SECONDS_TO_ORANGE/DT_DMON) + \ + [msg_DISTRACTED] * (int(_TEST_TIMESPAN/DT_DMON)-int(_DISTRACTED_SECONDS_TO_ORANGE*2/DT_DMON)) + interaction_vector = [car_interaction_NOT_DETECTED] * int(_DISTRACTED_SECONDS_TO_ORANGE*3/DT_DMON) + \ + [car_interaction_DETECTED] * (int(_TEST_TIMESPAN/DT_DMON)-int(_DISTRACTED_SECONDS_TO_ORANGE*3/DT_DMON)) + events_output = run_DState_seq(ds_vector, interaction_vector, always_true, always_false) + self.assertTrue(len(events_output[int(_DISTRACTED_SECONDS_TO_ORANGE*0.5/DT_DMON)])==0) + self.assertEqual(events_output[int((_DISTRACTED_SECONDS_TO_ORANGE-0.1)/DT_DMON)][0].name, 'promptDriverDistracted') + self.assertTrue(len(events_output[int(_DISTRACTED_SECONDS_TO_ORANGE*1.5/DT_DMON)])==0) + self.assertEqual(events_output[int((_DISTRACTED_SECONDS_TO_ORANGE*3-0.1)/DT_DMON)][0].name, 'promptDriverDistracted') + self.assertTrue(len(events_output[int((_DISTRACTED_SECONDS_TO_ORANGE*3+0.1)/DT_DMON)])==0) + + # 4. op engaged, down to orange, driver dodges camera, then comes back still distracted, down to red, \ + # driver dodges, and then touches wheel to no avail, disengages and reengages + # - orange/red alert should remain after disappearance, and only disengaging clears red + def test_biggest_comma_fan(self): + _invisible_time = 2 # seconds + ds_vector = always_distracted[:] + interaction_vector = always_false[:] + op_vector = always_true[:] + ds_vector[int(_DISTRACTED_SECONDS_TO_ORANGE/DT_DMON):int((_DISTRACTED_SECONDS_TO_ORANGE+_invisible_time)/DT_DMON)] = [msg_NO_FACE_DETECTED] * int(_invisible_time/DT_DMON) + ds_vector[int((_DISTRACTED_SECONDS_TO_RED+_invisible_time)/DT_DMON):int((_DISTRACTED_SECONDS_TO_RED+2*_invisible_time)/DT_DMON)] = [msg_NO_FACE_DETECTED] * int(_invisible_time/DT_DMON) + interaction_vector[int((_DISTRACTED_SECONDS_TO_RED+2*_invisible_time+0.5)/DT_DMON):int((_DISTRACTED_SECONDS_TO_RED+2*_invisible_time+1.5)/DT_DMON)] = [True] * int(1/DT_DMON) + op_vector[int((_DISTRACTED_SECONDS_TO_RED+2*_invisible_time+2.5)/DT_DMON):int((_DISTRACTED_SECONDS_TO_RED+2*_invisible_time+3)/DT_DMON)] = [False] * int(0.5/DT_DMON) + events_output = run_DState_seq(ds_vector, interaction_vector, op_vector, always_false) + self.assertEqual(events_output[int((_DISTRACTED_SECONDS_TO_ORANGE+0.5*_invisible_time)/DT_DMON)][0].name, 'promptDriverDistracted') + self.assertEqual(events_output[int((_DISTRACTED_SECONDS_TO_RED+1.5*_invisible_time)/DT_DMON)][0].name, 'driverDistracted') + self.assertEqual(events_output[int((_DISTRACTED_SECONDS_TO_RED+2*_invisible_time+1.5)/DT_DMON)][0].name, 'driverDistracted') + self.assertTrue(len(events_output[int((_DISTRACTED_SECONDS_TO_RED+2*_invisible_time+3.5)/DT_DMON)])==0) + + # 5. op engaged, invisible driver, down to orange, driver touches wheel; then down to orange again, driver appears + # - both actions should clear the alert, but momentary appearence should not + def test_sometimes_transparent_commuter(self): + _visible_time = np.random.choice([1,10]) # seconds + # print _visible_time + ds_vector = always_no_face[:]*2 + interaction_vector = always_false[:]*2 + ds_vector[int((2*_INVISIBLE_SECONDS_TO_ORANGE+1)/DT_DMON):int((2*_INVISIBLE_SECONDS_TO_ORANGE+1+_visible_time)/DT_DMON)] = [msg_ATTENTIVE] * int(_visible_time/DT_DMON) + interaction_vector[int((_INVISIBLE_SECONDS_TO_ORANGE)/DT_DMON):int((_INVISIBLE_SECONDS_TO_ORANGE+1)/DT_DMON)] = [True] * int(1/DT_DMON) + events_output = run_DState_seq(ds_vector, interaction_vector, 2*always_true, 2*always_false) + self.assertTrue(len(events_output[int(_INVISIBLE_SECONDS_TO_ORANGE*0.5/DT_DMON)])==0) + self.assertEqual(events_output[int((_INVISIBLE_SECONDS_TO_ORANGE-0.1)/DT_DMON)][0].name, 'promptDriverUnresponsive') + self.assertTrue(len(events_output[int((_INVISIBLE_SECONDS_TO_ORANGE+0.1)/DT_DMON)])==0) + if _visible_time == 1: + self.assertEqual(events_output[int((_INVISIBLE_SECONDS_TO_ORANGE*2+1-0.1)/DT_DMON)][0].name, 'promptDriverUnresponsive') + self.assertEqual(events_output[int((_INVISIBLE_SECONDS_TO_ORANGE*2+1+0.1+_visible_time)/DT_DMON)][0].name, 'preDriverUnresponsive') + elif _visible_time == 10: + self.assertEqual(events_output[int((_INVISIBLE_SECONDS_TO_ORANGE*2+1-0.1)/DT_DMON)][0].name, 'promptDriverUnresponsive') + self.assertTrue(len(events_output[int((_INVISIBLE_SECONDS_TO_ORANGE*2+1+0.1+_visible_time)/DT_DMON)])==0) + else: + pass + + # 6. op engaged, invisible driver, down to red, driver appears and then touches wheel, then disengages/reengages + # - only disengage will clear the alert + def test_last_second_responder(self): + _visible_time = 2 # seconds + ds_vector = always_no_face[:] + interaction_vector = always_false[:] + op_vector = always_true[:] + ds_vector[int(_INVISIBLE_SECONDS_TO_RED/DT_DMON):int((_INVISIBLE_SECONDS_TO_RED+_visible_time)/DT_DMON)] = [msg_ATTENTIVE] * int(_visible_time/DT_DMON) + interaction_vector[int((_INVISIBLE_SECONDS_TO_RED+_visible_time)/DT_DMON):int((_INVISIBLE_SECONDS_TO_RED+_visible_time+1)/DT_DMON)] = [True] * int(1/DT_DMON) + op_vector[int((_INVISIBLE_SECONDS_TO_RED+_visible_time+1)/DT_DMON):int((_INVISIBLE_SECONDS_TO_RED+_visible_time+0.5)/DT_DMON)] = [False] * int(0.5/DT_DMON) + events_output = run_DState_seq(ds_vector, interaction_vector, op_vector, always_false) + self.assertTrue(len(events_output[int(_INVISIBLE_SECONDS_TO_ORANGE*0.5/DT_DMON)])==0) + self.assertEqual(events_output[int((_INVISIBLE_SECONDS_TO_ORANGE-0.1)/DT_DMON)][0].name, 'promptDriverUnresponsive') + self.assertEqual(events_output[int((_INVISIBLE_SECONDS_TO_RED-0.1)/DT_DMON)][0].name, 'driverUnresponsive') + self.assertEqual(events_output[int((_INVISIBLE_SECONDS_TO_RED+0.5*_visible_time)/DT_DMON)][0].name, 'driverUnresponsive') + self.assertEqual(events_output[int((_INVISIBLE_SECONDS_TO_RED+_visible_time+0.5)/DT_DMON)][0].name, 'driverUnresponsive') + self.assertTrue(len(events_output[int((_INVISIBLE_SECONDS_TO_RED+_visible_time+1+0.1)/DT_DMON)])==0) + + # 7. op not engaged, always distracted driver + # - dm should stay quiet when not engaged + def test_pure_dashcam_user(self): + events_output = run_DState_seq(always_distracted, always_false, always_false, always_false) + self.assertTrue(np.sum([len(event) for event in events_output])==0) + + # 8. op engaged, car stops at traffic light, down to orange, no action, then car starts moving + # - should only reach green when stopped, but continues counting down on launch + def test_long_traffic_light_victim(self): + _redlight_time = 60 # seconds + standstill_vector = always_true[:] + standstill_vector[int(_redlight_time/DT_DMON):] = [False] * int((_TEST_TIMESPAN-_redlight_time)/DT_DMON) + events_output = run_DState_seq(always_distracted, always_false, always_true, standstill_vector) + self.assertEqual(events_output[int((_DISTRACTED_TIME-_DISTRACTED_PRE_TIME_TILL_TERMINAL+1)/DT_DMON)][0].name, 'preDriverDistracted') + self.assertEqual(events_output[int((_redlight_time-0.1)/DT_DMON)][0].name, 'preDriverDistracted') + self.assertEqual(events_output[int((_redlight_time+0.5)/DT_DMON)][0].name, 'promptDriverDistracted') + +if __name__ == "__main__": + print('MAX_TERMINAL_ALERTS', MAX_TERMINAL_ALERTS) + unittest.main() diff --git a/selfdrive/crash.py b/selfdrive/crash.py index 94bdfd125bb9c7..6ceb56b627756c 100644 --- a/selfdrive/crash.py +++ b/selfdrive/crash.py @@ -2,6 +2,7 @@ import os import sys import threading +import capnp from selfdrive.version import version, dirty from selfdrive.swaglog import cloudlog @@ -22,7 +23,9 @@ def install(): install_sys_hook=False, transport=HTTPTransport, release=version, tags={'dirty': dirty}) def capture_exception(*args, **kwargs): - client.captureException(*args, **kwargs) + exc_info = sys.exc_info() + if not exc_info[0] is capnp.lib.capnp.KjException: + client.captureException(*args, **kwargs) cloudlog.error("crash", exc_info=kwargs.get('exc_info', 1)) def bind_user(**kwargs): diff --git a/selfdrive/debug/can_printer.py b/selfdrive/debug/can_printer.py index d7cbabe63ac139..9a72b29fa20a41 100755 --- a/selfdrive/debug/can_printer.py +++ b/selfdrive/debug/can_printer.py @@ -1,16 +1,15 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 +import binascii import os import sys from collections import defaultdict -from common.realtime import sec_since_boot -import zmq + import selfdrive.messaging as messaging -from selfdrive.services import service_list +from common.realtime import sec_since_boot def can_printer(bus=0, max_msg=None, addr="127.0.0.1"): - context = zmq.Context() - logcan = messaging.sub_sock(context, service_list['can'].port, addr=addr) + logcan = messaging.sub_sock('can', addr=addr) start = sec_since_boot() lp = sec_since_boot() @@ -26,10 +25,10 @@ def can_printer(bus=0, max_msg=None, addr="127.0.0.1"): if sec_since_boot() - lp > 0.1: dd = chr(27) + "[2J" dd += "%5.2f\n" % (sec_since_boot() - start) - for k,v in sorted(zip(msgs.keys(), map(lambda x: x[-1].encode("hex"), msgs.values()))): + for k,v in sorted(zip(msgs.keys(), map(lambda x: binascii.hexlify(x[-1]), msgs.values()))): if max_msg is None or k < max_msg: - dd += "%s(%6d) %s\n" % ("%04X(%4d)" % (k,k),len(msgs[k]), v) - print dd + dd += "%s(%6d) %s\n" % ("%04X(%4d)" % (k,k),len(msgs[k]), v.decode('ascii')) + print(dd) lp = sec_since_boot() if __name__ == "__main__": @@ -41,4 +40,3 @@ def can_printer(bus=0, max_msg=None, addr="127.0.0.1"): can_printer(int(sys.argv[1])) else: can_printer() - diff --git a/selfdrive/debug/compare_fingerprints.py b/selfdrive/debug/compare_fingerprints.py new file mode 100755 index 00000000000000..a0c80a740e8ae9 --- /dev/null +++ b/selfdrive/debug/compare_fingerprints.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 + +# put 2 fingeprints and print the diffs +f1 = { +168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 528: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 701: 8, 703: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 746: 5, 752: 2, 754: 8, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 906: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 962: 8, 969: 4, 973: 8, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8, 1537: 8, 1538: 8, 1562: 8 +} + +f2 = { +168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 515: 7, 516: 7, 517: 7, 518: 7, 520: 8, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 701: 8, 703: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 746: 5, 752: 2, 754: 8, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 906: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 962: 8, 969: 4, 973: 8, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8 +} + +for k in f1: + if k not in f2 or f1[k] != f2[k]: + print(k, "not in f2") + +for k in f2: + if k not in f1 or f2[k] != f1[k]: + print(k, "not in f1") diff --git a/selfdrive/debug/cpu_usage_stat.py b/selfdrive/debug/cpu_usage_stat.py new file mode 100755 index 00000000000000..e1a6ac35d49fe5 --- /dev/null +++ b/selfdrive/debug/cpu_usage_stat.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 +import psutil +import time +import os +import sys +import numpy as np +import argparse +import re +from collections import defaultdict + +''' +System tools like top/htop can only show current cpu usage values, so I write this script to do statistics jobs. + Features: + Use psutil library to sample cpu usage(avergage for all cores) of OpenPilot processes, at a rate of 5 samples/sec. + Do cpu usage statistics periodically, 5 seconds as a cycle. + Caculate the average cpu usage within this cycle. + Caculate minumium/maximium/accumulated_average cpu usage as long term inspections. + Monitor multiple processes simuteneously. + Sample usage: + root@localhost:/data/openpilot$ python selfdrive/debug/cpu_usage_stat.py boardd,ubloxd + ('Add monitored proc:', './boardd') + ('Add monitored proc:', 'python locationd/ubloxd.py') + boardd: 1.96%, min: 1.96%, max: 1.96%, acc: 1.96% + ubloxd.py: 0.39%, min: 0.39%, max: 0.39%, acc: 0.39% +''' + +# Do statistics every 5 seconds +PRINT_INTERVAL = 5 +SLEEP_INTERVAL = 0.2 + +monitored_proc_names = [ + 'ubloxd', 'thermald', 'uploader', 'deleter', 'controlsd', 'plannerd', 'radard', 'mapd', 'loggerd' , 'logmessaged', 'tombstoned', + 'logcatd', 'proclogd', 'boardd', 'pandad', './ui', 'calibrationd', 'params_learner', 'visiond', 'sensord', 'updated', 'gpsd', 'athena'] +cpu_time_names = ['user', 'system', 'children_user', 'children_system'] + +timer = getattr(time, 'monotonic', time.time) + +def get_arg_parser(): + parser = argparse.ArgumentParser( + description="Unlogger and UI", + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + + parser.add_argument("proc_names", nargs="?", default='', + help="Process names to be monitored, comma seperated") + parser.add_argument("--list_all", action='store_true', + help="Show all running processes' cmdline") + parser.add_argument("--detailed_times", action='store_true', + help="show cpu time details (split by user, system, child user, child system)") + return parser + + +if __name__ == "__main__": + args = get_arg_parser().parse_args(sys.argv[1:]) + if args.list_all: + for p in psutil.process_iter(): + print('cmdline', p.cmdline(), 'name', p.name()) + sys.exit(0) + + if len(args.proc_names) > 0: + monitored_proc_names = args.proc_names.split(',') + monitored_procs = [] + stats = {} + for p in psutil.process_iter(): + if p == psutil.Process(): + continue + matched = any([l for l in p.cmdline() if any([pn for pn in monitored_proc_names if re.match(r'.*{}.*'.format(pn), l, re.M | re.I)])]) + if matched: + k = ' '.join(p.cmdline()) + print('Add monitored proc:', k) + stats[k] = {'cpu_samples': defaultdict(list), 'min': defaultdict(lambda: None), 'max': defaultdict(lambda: None), + 'avg': defaultdict(lambda: 0.0), 'last_cpu_times': None, 'last_sys_time':None} + stats[k]['last_sys_time'] = timer() + stats[k]['last_cpu_times'] = p.cpu_times() + monitored_procs.append(p) + i = 0 + interval_int = int(PRINT_INTERVAL / SLEEP_INTERVAL) + while True: + for p in monitored_procs: + k = ' '.join(p.cmdline()) + cur_sys_time = timer() + cur_cpu_times = p.cpu_times() + cpu_times = np.subtract(cur_cpu_times, stats[k]['last_cpu_times']) / (cur_sys_time - stats[k]['last_sys_time']) + stats[k]['last_sys_time'] = cur_sys_time + stats[k]['last_cpu_times'] = cur_cpu_times + cpu_percent = 0 + for num, name in enumerate(cpu_time_names): + stats[k]['cpu_samples'][name].append(cpu_times[num]) + cpu_percent += cpu_times[num] + stats[k]['cpu_samples']['total'].append(cpu_percent) + time.sleep(SLEEP_INTERVAL) + i += 1 + if i % interval_int == 0: + l = [] + for k, stat in stats.items(): + if len(stat['cpu_samples']) <= 0: + continue + for name, samples in stat['cpu_samples'].items(): + samples = np.array(samples) + avg = samples.mean() + c = samples.size + min_cpu = np.amin(samples) + max_cpu = np.amax(samples) + if stat['min'][name] is None or min_cpu < stat['min'][name]: + stat['min'][name] = min_cpu + if stat['max'][name] is None or max_cpu > stat['max'][name]: + stat['max'][name] = max_cpu + stat['avg'][name] = (stat['avg'][name] * (i - c) + avg * c) / (i) + stat['cpu_samples'][name] = [] + + msg = 'avg: {1:.2%}, min: {2:.2%}, max: {3:.2%} {0}'.format(os.path.basename(k), stat['avg']['total'], stat['min']['total'], stat['max']['total']) + if args.detailed_times: + for stat_type in ['avg', 'min', 'max']: + msg += '\n {}: {}'.format(stat_type, [name + ':' + str(round(stat[stat_type][name]*100, 2)) for name in cpu_time_names]) + l.append((os.path.basename(k), stat['avg']['total'], msg)) + l.sort(key= lambda x: -x[1]) + for x in l: + print(x[2]) + print('avg sum: {0:.2%} over {1} samples {2} seconds\n'.format( + sum([stat['avg']['total'] for k, stat in stats.items()]), i, i * SLEEP_INTERVAL + )) diff --git a/selfdrive/debug/dump.py b/selfdrive/debug/dump.py index 45b737953fdebe..b8fc0582e88db9 100755 --- a/selfdrive/debug/dump.py +++ b/selfdrive/debug/dump.py @@ -1,21 +1,15 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import sys import argparse -import zmq import json from hexdump import hexdump -from threading import Thread from cereal import log import selfdrive.messaging as messaging from selfdrive.services import service_list -def run_server(socketio): - socketio.run(app, host='0.0.0.0', port=4000) - if __name__ == "__main__": - context = zmq.Context() - poller = zmq.Poller() + poller = messaging.Poller() parser = argparse.ArgumentParser(description='Sniff a communcation socket') parser.add_argument('--pipe', action='store_true') @@ -23,57 +17,25 @@ def run_server(socketio): parser.add_argument('--json', action='store_true') parser.add_argument('--dump-json', action='store_true') parser.add_argument('--no-print', action='store_true') - parser.add_argument('--proxy', action='store_true', help='republish on localhost') - parser.add_argument('--map', action='store_true') parser.add_argument('--addr', default='127.0.0.1') parser.add_argument('--values', help='values to monitor (instead of entire event)') parser.add_argument("socket", type=str, nargs='*', help="socket name") args = parser.parse_args() - republish_socks = {} for m in args.socket if len(args.socket) > 0 else service_list: - if m in service_list: - port = service_list[m].port - elif m.isdigit(): - port = int(m) - else: - print("service not found") - sys.exit(-1) - sock = messaging.sub_sock(context, port, poller, addr=args.addr) - if args.proxy: - republish_socks[sock] = messaging.pub_sock(context, port) - - if args.map: - from flask.ext.socketio import SocketIO #pylint: disable=no-name-in-module, import-error - from flask import Flask - app = Flask(__name__) - socketio = SocketIO(app, async_mode='threading') - server_thread = Thread(target=run_server, args=(socketio,)) - server_thread.daemon = True - server_thread.start() - print 'server running' + sock = messaging.sub_sock(m, poller, addr=args.addr) values = None if args.values: values = [s.strip().split(".") for s in args.values.split(",")] while 1: - polld = poller.poll(timeout=1000) - for sock, mode in polld: - if mode != zmq.POLLIN: - continue - msg = sock.recv() + polld = poller.poll(1000) + for sock in polld: + msg = sock.receive() evt = log.Event.from_bytes(msg) - if sock in republish_socks: - republish_socks[sock].send(msg) - if args.map and evt.which() == 'liveLocation': - print 'send loc' - socketio.emit('location', { - 'lat': evt.liveLocation.lat, - 'lon': evt.liveLocation.lon, - 'alt': evt.liveLocation.alt, - }) + if not args.no_print: if args.pipe: sys.stdout.write(msg) @@ -83,15 +45,15 @@ def run_server(socketio): elif args.json: print(json.loads(msg)) elif args.dump_json: - print json.dumps(evt.to_dict()) + print(json.dumps(evt.to_dict())) elif values: - print "logMonotime = {}".format(evt.logMonoTime) + print("logMonotime = {}".format(evt.logMonoTime)) for value in values: if hasattr(evt, value[0]): item = evt for key in value: item = getattr(item, key) - print "{} = {}".format(".".join(value), item) - print "" + print("{} = {}".format(".".join(value), item)) + print("") else: - print evt + print(evt) diff --git a/selfdrive/debug/get_fingerprint.py b/selfdrive/debug/get_fingerprint.py index dd8eb4d8088dd4..e2111e191418eb 100755 --- a/selfdrive/debug/get_fingerprint.py +++ b/selfdrive/debug/get_fingerprint.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # simple script to get a vehicle fingerprint. @@ -6,25 +6,24 @@ # - connect to a Panda # - run selfdrive/boardd/boardd # - launching this script -# - since some messages are published at low frequency, keep this script running for few -# seconds, until all messages are received at least once +# - turn on the car in STOCK MODE (set giraffe switches properly). +# Note: it's very important that the car is in stock mode, in order to collect a complete fingerprint +# - since some messages are published at low frequency, keep this script running for at least 30s, +# until all messages are received at least once -import zmq import selfdrive.messaging as messaging -from selfdrive.services import service_list -context = zmq.Context() -logcan = messaging.sub_sock(context, service_list['can'].port) +logcan = messaging.sub_sock('can') msgs = {} while True: lc = messaging.recv_sock(logcan, True) for c in lc.can: # read also msgs sent by EON on CAN bus 0x80 and filter out the # addr with more than 11 bits - if c.src%0x80 == 0 and c.address < 0x800: + if c.src in [0, 2] and c.address < 0x800: msgs[c.address] = len(c.dat) fingerprint = ', '.join("%d: %d" % v for v in sorted(msgs.items())) - print "number of messages:", len(msgs) - print "fingerprint", fingerprint + print("number of messages {0}:".format(len(msgs))) + print("fingerprint {0}".format(fingerprint)) diff --git a/selfdrive/debug/getframes/Makefile b/selfdrive/debug/getframes/Makefile deleted file mode 100644 index 932673e208d116..00000000000000 --- a/selfdrive/debug/getframes/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -CC = clang -CXX = clang++ - -WARN_FLAGS = -Werror=implicit-function-declaration \ - -Werror=incompatible-pointer-types \ - -Werror=int-conversion \ - -Werror=return-type \ - -Werror=format-extra-args - -CFLAGS = -std=gnu11 -g -fPIC -O2 $(WARN_FLAGS) - -.PHONY: all -all: libvisionipc.so - -visionipc.o: ../../common/visionipc.c ../../common/visionipc.h - @echo "[ CC ] $@" - $(CC) $(CFLAGS) -MMD \ - -I../.. -I../../.. \ - -c -o '$@' ../../common/visionipc.c - -libvisionipc.so: visionipc.o - $(CC) -shared -fPIC -o '$@' visionipc.o - -.PHONY: clean -clean: - rm visionipc.o libvisionipc.so diff --git a/selfdrive/debug/getframes/getframes.py b/selfdrive/debug/getframes/getframes.py deleted file mode 100755 index 292368d6a97ea6..00000000000000 --- a/selfdrive/debug/getframes/getframes.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env python -import os -import subprocess -from cffi import FFI - -import numpy as np - -gf_dir = os.path.dirname(os.path.abspath(__file__)) - -subprocess.check_call(["make"], cwd=gf_dir) - - -ffi = FFI() -ffi.cdef(""" - -typedef enum VisionStreamType { - VISION_STREAM_RGB_BACK, - VISION_STREAM_RGB_FRONT, - VISION_STREAM_YUV, - VISION_STREAM_YUV_FRONT, - VISION_STREAM_MAX, -} VisionStreamType; - -typedef struct VisionUIInfo { - int big_box_x, big_box_y; - int big_box_width, big_box_height; - int transformed_width, transformed_height; - - int front_box_x, front_box_y; - int front_box_width, front_box_height; -} VisionUIInfo; - -typedef struct VisionStreamBufs { - VisionStreamType type; - - int width, height, stride; - size_t buf_len; - - union { - VisionUIInfo ui_info; - } buf_info; -} VisionStreamBufs; - -typedef struct VIPCBuf { - int fd; - size_t len; - void* addr; -} VIPCBuf; - -typedef struct VIPCBufExtra { - // only for yuv - uint32_t frame_id; - uint64_t timestamp_eof; -} VIPCBufExtra; - -typedef struct VisionStream { - int ipc_fd; - int last_idx; - int last_type; - int num_bufs; - VisionStreamBufs bufs_info; - VIPCBuf *bufs; -} VisionStream; - -int visionstream_init(VisionStream *s, VisionStreamType type, bool tbuffer, VisionStreamBufs *out_bufs_info); -VIPCBuf* visionstream_get(VisionStream *s, VIPCBufExtra *out_extra); -void visionstream_destroy(VisionStream *s); - -""" -) - -clib = ffi.dlopen(os.path.join(gf_dir, "libvisionipc.so")) - - -def getframes(front=False): - s = ffi.new("VisionStream*") - buf_info = ffi.new("VisionStreamBufs*") - - if front: - stream_type = clib.VISION_STREAM_RGB_FRONT - else: - stream_type = clib.VISION_STREAM_RGB_BACK - - err = clib.visionstream_init(s, stream_type, True, buf_info) - assert err == 0 - - w = buf_info.width - h = buf_info.height - assert buf_info.stride == w*3 - assert buf_info.buf_len == w*h*3 - - while True: - buf = clib.visionstream_get(s, ffi.NULL) - - pbuf = ffi.buffer(buf.addr, buf.len) - yield np.frombuffer(pbuf, dtype=np.uint8).reshape((h, w, 3)) - - -if __name__ == "__main__": - for buf in getframes(): - print buf.shape, buf[101, 101] diff --git a/selfdrive/debug/live_cpu_and_temp.py b/selfdrive/debug/live_cpu_and_temp.py new file mode 100755 index 00000000000000..0cc62ef7c54677 --- /dev/null +++ b/selfdrive/debug/live_cpu_and_temp.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +import numpy as np + +from selfdrive.messaging import SubMaster + +def cputime_total(ct): + return ct.user + ct.nice + ct.system + ct.idle + ct.iowait + ct.irq + ct.softirq + + +def cputime_busy(ct): + return ct.user + ct.nice + ct.system + ct.irq + ct.softirq + + + +sm = SubMaster(['thermal', 'procLog']) + +last_temp = 0.0 +total_times = [0., 0., 0., 0.] +busy_times = [0., 0., 0.0, 0.] + + +while True: + sm.update() + + if sm.updated['thermal']: + t = sm['thermal'] + last_temp = np.mean([t.cpu0, t.cpu1, t.cpu2, t.cpu3]) / 10. + + if sm.updated['procLog']: + m = sm['procLog'] + + cores = [0., 0., 0., 0.] + total_times_new = [0., 0., 0., 0.] + busy_times_new = [0., 0., 0.0, 0.] + + for c in m.cpuTimes: + n = c.cpuNum + total_times_new[n] = cputime_total(c) + busy_times_new[n] = cputime_busy(c) + + for n in range(4): + t_busy = busy_times_new[n] - busy_times[n] + t_total = total_times_new[n] - total_times[n] + cores[n] = t_busy / t_total + + total_times = total_times_new[:] + busy_times = busy_times_new[:] + + print("CPU %.2f%% - Temp %.2f" % (100. * np.mean(cores), last_temp )) diff --git a/selfdrive/debug/mpc/live_lateral_mpc.py b/selfdrive/debug/mpc/live_lateral_mpc.py new file mode 100755 index 00000000000000..5d7bc2bb828078 --- /dev/null +++ b/selfdrive/debug/mpc/live_lateral_mpc.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +import matplotlib +matplotlib.use('TkAgg') + +import sys +import selfdrive.messaging as messaging +import numpy as np +import matplotlib.pyplot as plt + +# debug liateral MPC by plotting its trajectory. To receive liveLongitudinalMpc packets, +# set on LOG_MPC env variable and run plannerd on a replay + + +def mpc_vwr_thread(addr="127.0.0.1"): + + plt.ion() + fig = plt.figure(figsize=(15, 20)) + ax = fig.add_subplot(131) + aa = fig.add_subplot(132, sharey=ax) + ap = fig.add_subplot(133, sharey=ax) + + ax.set_xlim([-10, 10]) + ax.set_ylim([0., 100.]) + aa.set_xlim([-20., 20]) + ap.set_xlim([-5, 5]) + + ax.set_xlabel('x [m]') + ax.set_ylabel('y [m]') + aa.set_xlabel('steer_angle [deg]') + ap.set_xlabel('asset angle [deg]') + ax.grid(True) + aa.grid(True) + ap.grid(True) + + path_x = np.arange(0, 100) + mpc_path_x = np.arange(0, 49) + + p_path_y = np.zeros(100) + + l_path_y = np.zeros(100) + r_path_y = np.zeros(100) + mpc_path_y = np.zeros(49) + mpc_steer_angle = np.zeros(49) + mpc_psi = np.zeros(49) + + line1, = ax.plot(mpc_path_y, mpc_path_x) + # line1b, = ax.plot(mpc_path_y, mpc_path_x, 'o') + + lineP, = ax.plot(p_path_y, path_x) + lineL, = ax.plot(l_path_y, path_x) + lineR, = ax.plot(r_path_y, path_x) + line3, = aa.plot(mpc_steer_angle, mpc_path_x) + line4, = ap.plot(mpc_psi, mpc_path_x) + ax.invert_xaxis() + aa.invert_xaxis() + plt.show() + + + # *** log *** + livempc = messaging.sub_sock('liveMpc', addr=addr) + model = messaging.sub_sock('model', addr=addr) + path_plan_sock = messaging.sub_sock('pathPlan', addr=addr) + + while 1: + lMpc = messaging.recv_sock(livempc, wait=True) + md = messaging.recv_sock(model) + pp = messaging.recv_sock(path_plan_sock) + + if md is not None: + p_poly = np.array(md.model.path.poly) + l_poly = np.array(md.model.leftLane.poly) + r_poly = np.array(md.model.rightLane.poly) + + p_path_y = np.polyval(p_poly, path_x) + l_path_y = np.polyval(r_poly, path_x) + r_path_y = np.polyval(l_poly, path_x) + + if pp is not None: + p_path_y = np.polyval(pp.pathPlan.dPoly, path_x) + lineP.set_xdata(p_path_y) + lineP.set_ydata(path_x) + + if lMpc is not None: + mpc_path_x = list(lMpc.liveMpc.x)[1:] + mpc_path_y = list(lMpc.liveMpc.y)[1:] + mpc_steer_angle = list(lMpc.liveMpc.delta)[1:] + mpc_psi = list(lMpc.liveMpc.psi)[1:] + + line1.set_xdata(mpc_path_y) + line1.set_ydata(mpc_path_x) + lineL.set_xdata(l_path_y) + lineL.set_ydata(path_x) + lineR.set_xdata(r_path_y) + lineR.set_ydata(path_x) + line3.set_xdata(np.asarray(mpc_steer_angle)*180./np.pi * 14) + line3.set_ydata(mpc_path_x) + line4.set_xdata(np.asarray(mpc_psi)*180./np.pi) + line4.set_ydata(mpc_path_x) + + aa.relim() + aa.autoscale_view(True, scaley=True, scalex=True) + + fig.canvas.draw() + fig.canvas.flush_events() + +if __name__ == "__main__": + if len(sys.argv) > 1: + mpc_vwr_thread(sys.argv[1]) + else: + mpc_vwr_thread() diff --git a/selfdrive/debug/mpc/live_longitudinal_mpc.py b/selfdrive/debug/mpc/live_longitudinal_mpc.py new file mode 100755 index 00000000000000..c2d1143dd18597 --- /dev/null +++ b/selfdrive/debug/mpc/live_longitudinal_mpc.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 + +import matplotlib +matplotlib.use('TkAgg') + +import sys +import selfdrive.messaging as messaging +import numpy as np +import matplotlib.pyplot as plt + +N = 21 + +# debug longitudinal MPC by plotting its trajectory. To receive liveLongitudinalMpc packets, +# set on LOG_MPC env variable and run plannerd on a replay + +def plot_longitudinal_mpc(addr="127.0.0.1"): + # *** log *** + livempc = messaging.sub_sock('liveLongitudinalMpc', addr=addr, conflate=True) + radarstate = messaging.sub_sock('radarState', addr=addr, conflate=True) + + plt.ion() + fig = plt.figure() + + t = np.hstack([np.arange(0.0, 0.8, 0.2), np.arange(0.8, 10.6, 0.6)]) + + p_x_ego = fig.add_subplot(3, 2, 1) + p_v_ego = fig.add_subplot(3, 2, 3) + p_a_ego = fig.add_subplot(3, 2, 5) + # p_x_l = fig.add_subplot(3, 2, 2) + # p_a_l = fig.add_subplot(3, 2, 6) + p_d_l = fig.add_subplot(3, 2, 2) + p_d_l_v = fig.add_subplot(3, 2, 4) + p_d_l_vv = fig.add_subplot(3, 2, 6) + + p_v_ego.set_ylim([0, 30]) + p_a_ego.set_ylim([-4, 4]) + p_d_l.set_ylim([-1, 10]) + + p_x_ego.set_title('x') + p_v_ego.set_title('v') + p_a_ego.set_title('a') + p_d_l.set_title('rel dist') + + l_x_ego, = p_x_ego.plot(t, np.zeros(N)) + l_v_ego, = p_v_ego.plot(t, np.zeros(N)) + l_a_ego, = p_a_ego.plot(t, np.zeros(N)) + l_x_l, = p_x_ego.plot(t, np.zeros(N)) + l_v_l, = p_v_ego.plot(t, np.zeros(N)) + l_a_l, = p_a_ego.plot(t, np.zeros(N)) + l_d_l, = p_d_l.plot(t, np.zeros(N)) + l_d_l_v, = p_d_l_v.plot(np.zeros(N)) + l_d_l_vv, = p_d_l_vv.plot(np.zeros(N)) + p_x_ego.legend(['ego', 'l']) + p_v_ego.legend(['ego', 'l']) + p_a_ego.legend(['ego', 'l']) + p_d_l_v.set_xlabel('d_rel') + p_d_l_v.set_ylabel('v_rel') + p_d_l_v.set_ylim([-20, 20]) + p_d_l_v.set_xlim([0, 100]) + p_d_l_vv.set_xlabel('d_rel') + p_d_l_vv.set_ylabel('v_rel') + p_d_l_vv.set_ylim([-5, 5]) + p_d_l_vv.set_xlim([10, 40]) + + while True: + lMpc = messaging.recv_sock(livempc, wait=True) + rs = messaging.recv_sock(radarstate, wait=True) + + if lMpc is not None: + + if lMpc.liveLongitudinalMpc.mpcId != 1: + continue + + x_ego = list(lMpc.liveLongitudinalMpc.xEgo) + v_ego = list(lMpc.liveLongitudinalMpc.vEgo) + a_ego = list(lMpc.liveLongitudinalMpc.aEgo) + x_l = list(lMpc.liveLongitudinalMpc.xLead) + v_l = list(lMpc.liveLongitudinalMpc.vLead) + # a_l = list(lMpc.liveLongitudinalMpc.aLead) + a_l = rs.radarState.leadOne.aLeadK * np.exp(-lMpc.liveLongitudinalMpc.aLeadTau * t**2 / 2) + #print(min(a_ego), lMpc.liveLongitudinalMpc.qpIterations) + + l_x_ego.set_ydata(x_ego) + l_v_ego.set_ydata(v_ego) + l_a_ego.set_ydata(a_ego) + + l_x_l.set_ydata(x_l) + l_v_l.set_ydata(v_l) + l_a_l.set_ydata(a_l) + + l_d_l.set_ydata(np.array(x_l) - np.array(x_ego)) + l_d_l_v.set_ydata(np.array(v_l) - np.array(v_ego)) + l_d_l_v.set_xdata(np.array(x_l) - np.array(x_ego)) + l_d_l_vv.set_ydata(np.array(v_l) - np.array(v_ego)) + l_d_l_vv.set_xdata(np.array(x_l) - np.array(x_ego)) + + p_x_ego.relim() + p_x_ego.autoscale_view(True, scaley=True, scalex=True) + fig.canvas.draw() + fig.canvas.flush_events() + + + + +if __name__ == "__main__": + if len(sys.argv) > 1: + plot_longitudinal_mpc(sys.argv[1]) + else: + plot_longitudinal_mpc() diff --git a/selfdrive/debug/mpc/test_mpc_wobble.py b/selfdrive/debug/mpc/test_mpc_wobble.py new file mode 100755 index 00000000000000..5f9f1b3355bf19 --- /dev/null +++ b/selfdrive/debug/mpc/test_mpc_wobble.py @@ -0,0 +1,129 @@ +#! /usr/bin/env python +import matplotlib.pyplot as plt +from selfdrive.controls.lib.lateral_mpc import libmpc_py +from selfdrive.controls.lib.drive_helpers import MPC_COST_LAT +import math + +libmpc = libmpc_py.libmpc +libmpc.init(MPC_COST_LAT.PATH, MPC_COST_LAT.LANE, MPC_COST_LAT.HEADING, 1.) + +cur_state = libmpc_py.ffi.new("state_t *") +cur_state[0].x = 0.0 +cur_state[0].y = 0.0 +cur_state[0].psi = 0.0 +cur_state[0].delta = 0.0 + +mpc_solution = libmpc_py.ffi.new("log_t *") +xx = [] +yy = [] +deltas = [] +psis = [] +times = [] + +curvature_factor = 0.3 +v_ref = 1.0 * 20.12 # 45 mph + +LANE_WIDTH = 3.7 +p = [0.0, 0.0, 0.0, 0.0] +p_l = p[:] +p_l[3] += LANE_WIDTH / 2.0 + +p_r = p[:] +p_r[3] -= LANE_WIDTH / 2.0 + + +l_poly = libmpc_py.ffi.new("double[4]", p_l) +r_poly = libmpc_py.ffi.new("double[4]", p_r) +p_poly = libmpc_py.ffi.new("double[4]", p) + +l_prob = 1.0 +r_prob = 1.0 +p_prob = 1.0 + +for i in range(1): + cur_state[0].delta = math.radians(510. / 13.) + libmpc.run_mpc(cur_state, mpc_solution, l_poly, r_poly, p_poly, l_prob, r_prob, + curvature_factor, v_ref, LANE_WIDTH) + +timesi = [] +ct = 0 +for i in range(21): + timesi.append(ct) + if i <= 4: + ct += 0.05 + else: + ct += 0.15 + + +xi = list(mpc_solution[0].x) +yi = list(mpc_solution[0].y) +psii = list(mpc_solution[0].psi) +deltai = list(mpc_solution[0].delta) +print("COST: ", mpc_solution[0].cost) + + +plt.figure(0) +plt.subplot(3, 1, 1) +plt.plot(timesi, psii) +plt.ylabel('psi') +plt.grid(True) +plt.subplot(3, 1, 2) +plt.plot(timesi, deltai) +plt.ylabel('delta') +plt.grid(True) +plt.subplot(3, 1, 3) +plt.plot(timesi, yi) +plt.ylabel('y') +plt.grid(True) +plt.show() + + +#### UNCOMMENT TO CHECK ITERATIVE SOLUTION +#### +####for i in range(100): +#### libmpc.run_mpc(cur_state, mpc_solution, l_poly, r_poly, p_poly, l_prob, r_prob, +#### curvature_factor, v_ref, LANE_WIDTH) +#### print "x", list(mpc_solution[0].x) +#### print "y", list(mpc_solution[0].y) +#### print "delta", list(mpc_solution[0].delta) +#### print "psi", list(mpc_solution[0].psi) +#### # cur_state[0].x = mpc_solution[0].x[1] +#### # cur_state[0].y = mpc_solution[0].y[1] +#### # cur_state[0].psi = mpc_solution[0].psi[1] +#### cur_state[0].delta = radians(200 / 13.)#mpc_solution[0].delta[1] +#### +#### xx.append(cur_state[0].x) +#### yy.append(cur_state[0].y) +#### psis.append(cur_state[0].psi) +#### deltas.append(cur_state[0].delta) +#### times.append(i * 0.05) +#### +#### +####def f(x): +#### return p_poly[0] * x**3 + p_poly[1] * x**2 + p_poly[2] * x + p_poly[3] +#### +#### +##### planned = map(f, xx) +##### plt.figure(1) +##### plt.plot(yy, xx, 'r-') +##### plt.plot(planned, xx, 'b--', linewidth=0.5) +##### plt.axes().set_aspect('equal', 'datalim') +##### plt.gca().invert_xaxis() +#### +##### planned = map(f, map(float, list(mpc_solution[0].x)[1:])) +##### plt.figure(1) +##### plt.plot(map(float, list(mpc_solution[0].y)[1:]), map(float, list(mpc_solution[0].x)[1:]), 'r-') +##### plt.plot(planned, map(float, list(mpc_solution[0].x)[1:]), 'b--', linewidth=0.5) +##### plt.axes().set_aspect('equal', 'datalim') +##### plt.gca().invert_xaxis() +#### +####plt.figure(2) +####plt.subplot(2, 1, 1) +####plt.plot(times, psis) +####plt.ylabel('psi') +####plt.subplot(2, 1, 2) +####plt.plot(times, deltas) +####plt.ylabel('delta') +#### +#### +####plt.show() diff --git a/selfdrive/debug/mpc/tune_lateral.py b/selfdrive/debug/mpc/tune_lateral.py new file mode 100755 index 00000000000000..4a8ec2ce0b97d4 --- /dev/null +++ b/selfdrive/debug/mpc/tune_lateral.py @@ -0,0 +1,186 @@ +#! /usr/bin/env python +import numpy as np +from collections import OrderedDict +import matplotlib.pyplot as plt +from selfdrive.car.honda.interface import CarInterface +from selfdrive.controls.lib.lateral_mpc import libmpc_py +from selfdrive.controls.lib.vehicle_model import VehicleModel + +# plot lateral MPC trajectory by defining boundary conditions: +# lane lines, p_poly and vehicle states. Use this script to tune MPC costs + +libmpc = libmpc_py.libmpc + +mpc_solution = libmpc_py.ffi.new("log_t *") + +points_l = np.array([1.1049711, 1.1053879, 1.1073375, 1.1096942, 1.1124474, 1.1154714, 1.1192677, 1.1245866, 1.1321017, 1.1396152, 1.146443, 1.1555313, 1.1662073, 1.1774249, 1.1888939, 1.2009926, 1.2149779, 1.2300836, 1.2450289, 1.2617753, 1.2785473, 1.2974714, 1.3151019, 1.3331807, 1.3545501, 1.3763691, 1.3983455, 1.4215056, 1.4446729, 1.4691089, 1.4927692, 1.5175346, 1.5429921, 1.568854, 1.5968665, 1.6268958, 1.657122, 1.6853137, 1.7152609, 1.7477539, 1.7793678, 1.8098511, 1.8428392, 1.8746407, 1.9089606, 1.9426043, 1.9775689, 2.0136933, 2.0520134, 2.0891454]) + +points_r = np.array([-2.4442139, -2.4449506, -2.4448867, -2.44377, -2.4422617, -2.4393811, -2.4374201, -2.4334245, -2.4286852, -2.4238286, -2.4177458, -2.4094386, -2.3994849, -2.3904033, -2.380136, -2.3699453, -2.3594661, -2.3474073, -2.3342307, -2.3194637, -2.3046403, -2.2881098, -2.2706163, -2.2530098, -2.235604, -2.2160542, -2.1967411, -2.1758952, -2.1544619, -2.1325269, -2.1091819, -2.0850561, -2.0621953, -2.0364127, -2.0119917, -1.9851667, -1.9590458, -1.9306552, -1.9024918, -1.8745357, -1.8432863, -1.8131843, -1.7822732, -1.7507075, -1.7180918, -1.6845931, -1.650871, -1.6157099, -1.5787286, -1.5418037]) + + +points_c = (points_l + points_r) / 2.0 + +def compute_path_pinv(): + deg = 3 + x = np.arange(50.0) + X = np.vstack(tuple(x**n for n in range(deg, -1, -1))).T + pinv = np.linalg.pinv(X) + return pinv + + +def model_polyfit(points): + path_pinv = compute_path_pinv() + return np.dot(path_pinv, map(float, points)) + + +xx = [] +yy = [] +deltas = [] +psis = [] +times = [] + +CP = CarInterface.get_params("HONDA CIVIC 2016 TOURING") +VM = VehicleModel(CP) + +v_ref = 32.00 # 45 mph +curvature_factor = VM.curvature_factor(v_ref) +print(curvature_factor) + +LANE_WIDTH = 3.9 +p_l = map(float, model_polyfit(points_l)) +p_r = map(float, model_polyfit(points_r)) +p_p = map(float, model_polyfit(points_c)) + +l_poly = libmpc_py.ffi.new("double[4]", p_l) +r_poly = libmpc_py.ffi.new("double[4]", p_r) +p_poly = libmpc_py.ffi.new("double[4]", p_p) +l_prob = 1.0 +r_prob = 1.0 +p_prob = 1.0 # This is always 1 + + +mpc_x_points = np.linspace(0., 2.5*v_ref, num=50) +points_poly_l = np.polyval(p_l, mpc_x_points) +points_poly_r = np.polyval(p_r, mpc_x_points) +points_poly_p = np.polyval(p_p, mpc_x_points) +print(points_poly_l) + +lanes_x = np.linspace(0, 49) + +cur_state = libmpc_py.ffi.new("state_t *") +cur_state[0].x = 0.0 +cur_state[0].y = 0.5 +cur_state[0].psi = 0.0 +cur_state[0].delta = 0.0 + +xs = [] +ys = [] +deltas = [] +titles = [ + 'Steer rate cost', + 'Heading cost', + 'Lane cost', + 'Path cost', +] + +# Steer rate cost +sol_x = OrderedDict() +sol_y = OrderedDict() +delta = OrderedDict() +for cost in np.logspace(-1, 1.0, 5): + libmpc.init(1.0, 3.0, 1.0, cost) + for _ in range(10): + libmpc.run_mpc(cur_state, mpc_solution, l_poly, r_poly, p_poly, l_prob, r_prob, + curvature_factor, v_ref, LANE_WIDTH) + sol_x[cost] = map(float, list(mpc_solution[0].x)) + sol_y[cost] = map(float, list(mpc_solution[0].y)) + delta[cost] = map(float, list(mpc_solution[0].delta)) +xs.append(sol_x) +ys.append(sol_y) +deltas.append(delta) + +# Heading cost +sol_x = OrderedDict() +sol_y = OrderedDict() +delta = OrderedDict() +for cost in np.logspace(-1, 1.0, 5): + libmpc.init(1.0, 3.0, cost, 1.0) + for _ in range(10): + libmpc.run_mpc(cur_state, mpc_solution, l_poly, r_poly, p_poly, l_prob, r_prob, + curvature_factor, v_ref, LANE_WIDTH) + sol_x[cost] = map(float, list(mpc_solution[0].x)) + sol_y[cost] = map(float, list(mpc_solution[0].y)) + delta[cost] = map(float, list(mpc_solution[0].delta)) +xs.append(sol_x) +ys.append(sol_y) +deltas.append(delta) + +# Lane cost +sol_x = OrderedDict() +sol_y = OrderedDict() +delta = OrderedDict() +for cost in np.logspace(-1, 2.0, 5): + libmpc.init(1.0, cost, 1.0, 1.0) + for _ in range(10): + libmpc.run_mpc(cur_state, mpc_solution, l_poly, r_poly, p_poly, l_prob, r_prob, + curvature_factor, v_ref, LANE_WIDTH) + sol_x[cost] = map(float, list(mpc_solution[0].x)) + sol_y[cost] = map(float, list(mpc_solution[0].y)) + delta[cost] = map(float, list(mpc_solution[0].delta)) +xs.append(sol_x) +ys.append(sol_y) +deltas.append(delta) + + +# Path cost +sol_x = OrderedDict() +sol_y = OrderedDict() +delta = OrderedDict() +for cost in np.logspace(-1, 1.0, 5): + libmpc.init(cost, 3.0, 1.0, 1.0) + for _ in range(10): + libmpc.run_mpc(cur_state, mpc_solution, l_poly, r_poly, p_poly, l_prob, r_prob, + curvature_factor, v_ref, LANE_WIDTH) + sol_x[cost] = map(float, list(mpc_solution[0].x)) + sol_y[cost] = map(float, list(mpc_solution[0].y)) + delta[cost] = map(float, list(mpc_solution[0].delta)) +xs.append(sol_x) +ys.append(sol_y) +deltas.append(delta) + + + +plt.figure() + +for i in range(len(xs)): + ax = plt.subplot(2, 2, i + 1) + sol_x = xs[i] + sol_y = ys[i] + for cost in sol_x.keys(): + plt.plot(sol_x[cost], sol_y[cost]) + + plt.plot(lanes_x, points_r, '.b') + plt.plot(lanes_x, points_l, '.b') + plt.plot(lanes_x, (points_l + points_r) / 2.0, '--g') + plt.plot(mpc_x_points, points_poly_l, 'b') + plt.plot(mpc_x_points, points_poly_r, 'b') + plt.plot(mpc_x_points, (points_poly_l + points_poly_r) / 2.0, 'g') + plt.legend(map(lambda x: str(round(x, 2)), sol_x.keys()) + ['right', 'left', 'center'], loc=3) + plt.title(titles[i]) + plt.grid(True) + # ax.set_aspect('equal', 'datalim') + + +plt.figure() +for i in range(len(xs)): + plt.subplot(2, 2, i + 1) + sol_x = xs[i] + delta = deltas[i] + + for cost in sol_x.keys(): + plt.plot(delta[cost]) + plt.title(titles[i]) + plt.legend(map(lambda x: str(round(x, 2)), sol_x.keys()), loc=3) + plt.grid(True) + +plt.show() diff --git a/selfdrive/debug/mpc/tune_longitudinal.py b/selfdrive/debug/mpc/tune_longitudinal.py new file mode 100755 index 00000000000000..0af444631d34e3 --- /dev/null +++ b/selfdrive/debug/mpc/tune_longitudinal.py @@ -0,0 +1,168 @@ +#! /usr/bin/env python +import numpy as np +import matplotlib.pyplot as plt +from selfdrive.controls.lib.longitudinal_mpc import libmpc_py +from selfdrive.controls.lib.drive_helpers import MPC_COST_LONG +import math + +# plot liongitudinal MPC trajectory by defining boundary conditions: +# ego and lead vehicles state. Use this script to tune MPC costs + +def RW(v_ego, v_l): + TR = 1.8 + G = 9.81 + return (v_ego * TR - (v_l - v_ego) * TR + v_ego*v_ego/(2*G) - v_l*v_l / (2*G)) + + +def NORM_RW_ERROR(v_ego, v_l, p): + return (RW(v_ego, v_l) + 4.0 - p) + return (RW(v_ego, v_l) + 4.0 - p) / (np.sqrt(v_ego + 0.5) + 0.1) + + +v_ego = 20.0 +a_ego = 0 + +x_lead = 10.0 +v_lead = 20.0 +a_lead = -3.0 +a_lead_tau = 0. + +# v_ego = 7.02661012716 +# a_ego = -1.26143024772 + +# x_lead = 29.625 + 20 +# v_lead = 0.725235462189 + 1 +# a_lead = -1.00025629997 + +# a_lead_tau = 2.90729817665 + +min_a_lead_tau = (a_lead**2 * math.pi) / (2 * (v_lead + 0.01)**2) +min_a_lead_tau = 0.0 + +print(a_lead_tau, min_a_lead_tau) +a_lead_tau = max(a_lead_tau, min_a_lead_tau) + +ffi, libmpc = libmpc_py.get_libmpc(1) +libmpc.init(MPC_COST_LONG.TTC, MPC_COST_LONG.DISTANCE, MPC_COST_LONG.ACCELERATION, MPC_COST_LONG.JERK) +libmpc.init_with_simulation(v_ego, x_lead, v_lead, a_lead, a_lead_tau) + +cur_state = ffi.new("state_t *") +cur_state[0].x_ego = 0.0 +cur_state[0].v_ego = v_ego +cur_state[0].a_ego = a_ego +cur_state[0].x_l = x_lead +cur_state[0].v_l = v_lead + +mpc_solution = ffi.new("log_t *") + +for _ in range(10): + print(libmpc.run_mpc(cur_state, mpc_solution, a_lead_tau, a_lead)) + + +for i in range(21): + print("t: %.2f\t x_e: %.2f\t v_e: %.2f\t a_e: %.2f\t" % (mpc_solution[0].t[i], mpc_solution[0].x_ego[i], mpc_solution[0].v_ego[i], mpc_solution[0].a_ego[i])) + print("x_l: %.2f\t v_l: %.2f\t \t" % (mpc_solution[0].x_l[i], mpc_solution[0].v_l[i])) + +t = np.hstack([np.arange(0., 1.0, 0.2), np.arange(1.0, 10.1, 0.6)]) + +print(map(float, mpc_solution[0].x_ego)[-1]) +print(map(float, mpc_solution[0].x_l)[-1] - map(float, mpc_solution[0].x_ego)[-1]) + +plt.figure(figsize=(8, 8)) + +plt.subplot(4, 1, 1) +x_l = np.array(map(float, mpc_solution[0].x_l)) +plt.plot(t, map(float, mpc_solution[0].x_ego)) +plt.plot(t, x_l) +plt.legend(['ego', 'lead']) +plt.title('x') +plt.grid() + +plt.subplot(4, 1, 2) +v_ego = np.array(map(float, mpc_solution[0].v_ego)) +v_l = np.array(map(float, mpc_solution[0].v_l)) +plt.plot(t, v_ego) +plt.plot(t, v_l) +plt.legend(['ego', 'lead']) +plt.ylim([-1, max(max(v_ego), max(v_l))]) +plt.title('v') +plt.grid() + +plt.subplot(4, 1, 3) +plt.plot(t, map(float, mpc_solution[0].a_ego)) +plt.plot(t, map(float, mpc_solution[0].a_l)) +plt.legend(['ego', 'lead']) +plt.title('a') +plt.grid() + + +plt.subplot(4, 1, 4) +d_l = np.array(map(float, mpc_solution[0].x_l)) - np.array(map(float, mpc_solution[0].x_ego)) +desired = 4.0 + RW(v_ego, v_l) + +plt.plot(t, d_l) +plt.plot(t, desired, '--') +plt.ylim(-1, max(max(desired), max(d_l))) +plt.legend(['relative distance', 'desired distance']) +plt.grid() + +plt.show() + +# c1 = np.exp(0.3 * NORM_RW_ERROR(v_ego, v_l, d_l)) +# c2 = np.exp(4.5 - d_l) +# print(c1) +# print(c2) + +# plt.figure() +# plt.plot(t, c1, label="NORM_RW_ERROR") +# plt.plot(t, c2, label="penalty function") +# plt.legend() + +# ## OLD MPC +# a_lead_tau = 1.5 +# a_lead_tau = max(a_lead_tau, -a_lead / (v_lead + 0.01)) + +# ffi, libmpc = libmpc_py.get_libmpc(1) +# libmpc.init(MPC_COST_LONG.TTC, MPC_COST_LONG.DISTANCE, MPC_COST_LONG.ACCELERATION, MPC_COST_LONG.JERK) +# libmpc.init_with_simulation(v_ego, x_lead, v_lead, a_lead, a_lead_tau) + +# cur_state = ffi.new("state_t *") +# cur_state[0].x_ego = 0.0 +# cur_state[0].v_ego = v_ego +# cur_state[0].a_ego = a_ego +# cur_state[0].x_lead = x_lead +# cur_state[0].v_lead = v_lead +# cur_state[0].a_lead = a_lead + +# mpc_solution = ffi.new("log_t *") + +# for _ in range(10): +# print libmpc.run_mpc(cur_state, mpc_solution, a_lead_tau) + +# t = np.hstack([np.arange(0., 1.0, 0.2), np.arange(1.0, 10.1, 0.6)]) + +# print(map(float, mpc_solution[0].x_ego)[-1]) +# print(map(float, mpc_solution[0].x_lead)[-1] - map(float, mpc_solution[0].x_ego)[-1]) +# plt.subplot(4, 2, 2) +# plt.plot(t, map(float, mpc_solution[0].x_ego)) +# plt.plot(t, map(float, mpc_solution[0].x_lead)) +# plt.legend(['ego', 'lead']) +# plt.title('x') + +# plt.subplot(4, 2, 4) +# plt.plot(t, map(float, mpc_solution[0].v_ego)) +# plt.plot(t, map(float, mpc_solution[0].v_lead)) +# plt.legend(['ego', 'lead']) +# plt.title('v') + +# plt.subplot(4, 2, 6) +# plt.plot(t, map(float, mpc_solution[0].a_ego)) +# plt.plot(t, map(float, mpc_solution[0].a_lead)) +# plt.legend(['ego', 'lead']) +# plt.title('a') + + +# plt.subplot(4, 2, 8) +# plt.plot(t, np.array(map(float, mpc_solution[0].x_lead)) - np.array(map(float, mpc_solution[0].x_ego))) + +# plt.show() diff --git a/selfdrive/debug/show_matching_cars.py b/selfdrive/debug/show_matching_cars.py new file mode 100755 index 00000000000000..424e89887d262a --- /dev/null +++ b/selfdrive/debug/show_matching_cars.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +from selfdrive.car.fingerprints import eliminate_incompatible_cars, all_known_cars +import selfdrive.messaging as messaging + + +# Prius and Leuxs es 300H +fingerprint = {898: 8, 905: 8, 810: 2, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 921: 8, 800: 8, 944: 8, 1570: 8, 1059: 1, 36: 8, 37: 8, 550: 8, 295: 8, 296: 8, 170: 8, 1071: 8, 560: 7, 945: 8, 562: 6, 180: 8, 1077: 8, 950: 8, 951: 8, 953: 8, 1595: 8, 1084: 8, 829: 2, 1086: 8, 1568: 8, 452: 8, 581: 5, 1057: 8, 713: 8, 971: 7, 975: 5, 1571: 8, 466: 8, 467: 8, 1572: 8, 1114: 8, 933: 8, 863: 8, 608: 8, 993: 8, 610: 8, 955: 8, 166: 8, 1056: 8, 956: 8, 1132: 8, 1085: 8, 552: 4, 1779: 8, 1017: 8, 1020: 8, 426: 6, 1279: 8} + +# rav4 2019 and corolla tss2 +fingerprint = {896: 8, 898: 8, 976: 1, 1541: 8, 905: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1552: 8, 1553: 8, 1556: 8, 921: 8, 1056: 8, 544: 4, 1570: 8, 1059: 1, 36: 8, 37: 8, 550: 8, 552: 4, 170: 8, 812: 8, 944: 8, 945: 8, 562: 6, 180: 8, 1077: 8, 951: 8, 824: 8, 1076: 8, 186: 4, 955: 8, 956: 8, 705: 8, 452: 8, 1592: 8, 464: 8, 1571: 8, 466: 8, 467: 8, 761: 8, 728: 8, 1572: 8, 1114: 8, 933: 8, 800: 8, 608: 8, 865: 8, 610: 8, 1595: 8, 1745: 8, 764: 8, 1002: 8, 1649: 8, 1779: 8, 1568: 8, 1017: 8, 1279: 8, 1020: 8, 810: 2, 426: 6} + +# rav4 2019 and corolla tss2 +fingerprint = {896: 8, 898: 8, 900: 6, 976: 1, 1541: 8, 902: 6, 905: 8, 810: 2, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1552: 8, 1553: 8, 1556: 8, 1571: 8, 921: 8, 1056: 8, 544: 4, 1570: 8, 1059: 1, 36: 8, 37: 8, 550: 8, 935: 8, 552: 4, 170: 8, 812: 8, 944: 8, 945: 8, 562: 6, 180: 8, 1077: 8, 951: 8, 1592: 8, 1076: 8, 186: 4, 955: 8, 956: 8, 1001: 8, 705: 8, 452: 8, 1788: 8, 464: 8, 824: 8, 466: 8, 467: 8, 761: 8, 728: 8, 1572: 8, 1114: 8, 933: 8, 800: 8, 608: 8, 865: 8, 610: 8, 1595: 8, 934: 8, 998: 5, 1745: 8, 1000: 8, 764: 8, 1002: 8, 999: 7, 1789: 8, 1649: 8, 1779: 8, 1568: 8, 1017: 8, 1786: 8, 1787: 8, 1020: 8, 426: 6, 1279: 8} + +candidate_cars = all_known_cars() + + +for addr, l in fingerprint.items(): + dat = messaging.new_message() + dat.init('can', 1) + + msg = dat.can[0] + msg.address = addr + msg.dat = " " * l + + candidate_cars = eliminate_incompatible_cars(msg, candidate_cars) + print(candidate_cars) diff --git a/selfdrive/debug/tuner.py b/selfdrive/debug/tuner.py new file mode 100755 index 00000000000000..b8a023ba29967f --- /dev/null +++ b/selfdrive/debug/tuner.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +""" +This tool can be used to quickly changes the values in a JSON file used for tuning +Keys like in vim: + - h: decrease by 0.05 + - l: increase by 0.05 + - k: move pointer up + - j: move pointer down +""" + +import tty +import sys +import json +import termios +from collections import OrderedDict + +FILENAME = '/data/tuning.json' + +def read_tuning(): + while True: + try: + return json.loads(open(FILENAME).read()) + except: + pass + +def main(): + dat = json.loads(open(FILENAME, 'r').read()) + dat = OrderedDict(sorted(dat.items(), key=lambda i: i[0])) + + cur = 0 + while True: + sys.stdout.write("\x1Bc") + + for i, (k, v) in enumerate(dat.items()): + prefix = "> " if cur == i else " " + print((prefix + k).ljust(20) + "%.2f" % v) + + key = sys.stdin.read(1)[0] + + write = False + if key == "k": + cur = max(0, cur - 1) + elif key == "j": + cur = min(len(dat.keys()) - 1, cur + 1) + elif key == "l": + dat[dat.keys()[cur]] += 0.05 + write = True + elif key == "h": + dat[dat.keys()[cur]] -= 0.05 + write = True + elif key == "q": + break + + if write: + open(FILENAME, 'w').write(json.dumps(dat)) + + +if __name__ == "__main__": + orig_settings = termios.tcgetattr(sys.stdin) + tty.setcbreak(sys.stdin) + + try: + main() + termios.tcsetattr(sys.stdin, termios.TCSADRAIN, orig_settings) + except: + termios.tcsetattr(sys.stdin, termios.TCSADRAIN, orig_settings) + raise diff --git a/selfdrive/locationd/.gitignore b/selfdrive/locationd/.gitignore new file mode 100644 index 00000000000000..6ea757462e62f8 --- /dev/null +++ b/selfdrive/locationd/.gitignore @@ -0,0 +1,4 @@ +ubloxd +ubloxd_test +params_learner +paramsd \ No newline at end of file diff --git a/selfdrive/locationd/Makefile b/selfdrive/locationd/Makefile new file mode 100644 index 00000000000000..995329334687f8 --- /dev/null +++ b/selfdrive/locationd/Makefile @@ -0,0 +1,115 @@ +CC = clang +CXX = clang++ + +ARCH := $(shell uname -m) +OS := $(shell uname -o) + +BASEDIR = ../.. +PHONELIBS = ../../phonelibs + +WARN_FLAGS = -Werror=implicit-function-declaration \ + -Werror=incompatible-pointer-types \ + -Werror=int-conversion \ + -Werror=return-type \ + -Werror=format-extra-args + +CFLAGS = -std=gnu11 -g -fPIC -I../ -I../../ -O2 $(WARN_FLAGS) -Wall +CXXFLAGS = -std=c++11 -g -fPIC -I../ -I../../ -O2 $(WARN_FLAGS) -Wall + +MESSAGING_FLAGS = -I$(BASEDIR)/selfdrive/messaging +MESSAGING_LIBS = $(BASEDIR)/selfdrive/messaging/messaging.a + +EXTRA_LIBS = -lpthread + +ifeq ($(ARCH),aarch64) +CFLAGS += -mcpu=cortex-a57 +CXXFLAGS += -mcpu=cortex-a57 +EXTRA_LIBS += -llog -luuid -lgnustl_shared +endif + + +JSON_FLAGS = -I$(PHONELIBS)/json/src +JSON11_FLAGS = -I$(PHONELIBS)/json11 + + +ifeq ($(ARCH),x86_64) +ZMQ_FLAGS = -I$(BASEDIR)/phonelibs/zmq/x64/include +endif + +.PHONY: all +all: ubloxd paramsd + +include ../common/cereal.mk + +LOC_OBJS = locationd_yawrate.o params_learner.o paramsd.o \ + ../common/swaglog.o \ + ../common/params.o \ + ../common/util.o \ + $(PHONELIBS)/json11/json11.o \ + $(PHONELIBS)/json/src/json.o \ + $(CEREAL_OBJS) + +LOC_DEPS := $(LOC_OBJS:.o=.d) + +OBJS = ublox_msg.o \ + ubloxd_main.o \ + ../common/swaglog.o \ + ../common/params.o \ + ../common/util.o \ + $(PHONELIBS)/json/src/json.o \ + $(CEREAL_OBJS) + +DEPS := $(OBJS:.o=.d) ubloxd.d ubloxd_test.d + +liblocationd.so: $(LOC_OBJS) $(MESSAGING_LIBS) + @echo "[ LINK ] $@" + $(CXX) -shared -o '$@' $^ \ + $(CEREAL_LIBS) \ + $(EXTRA_LIBS) + +paramsd: $(LOC_OBJS) $(MESSAGING_LIBS) + @echo "[ LINK ] $@" + $(CXX) -fPIC -o '$@' $^ \ + $(CEREAL_LIBS) \ + $(EXTRA_LIBS) + +ubloxd: ubloxd.o $(OBJS) $(MESSAGING_LIBS) + @echo "[ LINK ] $@" + $(CXX) -fPIC -o '$@' $^ \ + $(CEREAL_LIBS) \ + $(EXTRA_LIBS) + +ubloxd_test: ubloxd_test.o $(OBJS) $(MESSAGING_LIBS) + @echo "[ LINK ] $@" + $(CXX) -fPIC -o '$@' $^ \ + $(CEREAL_LIBS) \ + $(EXTRA_LIBS) + +%.o: %.cc + @echo "[ CXX ] $@" + $(CXX) $(CXXFLAGS) -MMD \ + -Iinclude -I.. -I../.. \ + $(CEREAL_CXXFLAGS) \ + $(ZMQ_FLAGS) \ + $(MESSAGING_FLAGS) \ + $(JSON11_FLAGS) \ + $(JSON_FLAGS) \ + -I../ \ + -I../../ \ + -c -o '$@' '$<' + +%.o: %.c + @echo "[ CC ] $@" + $(CC) $(CFLAGS) -MMD \ + -Iinclude -I.. -I../.. \ + $(CEREAL_CFLAGS) \ + $(ZMQ_FLAGS) \ + $(JSON_FLAGS) \ + -c -o '$@' '$<' + +.PHONY: clean +clean: + rm -f ubloxd paramsd liblocationd.so ubloxd.d ubloxd.o ubloxd_test ubloxd_test.o ubloxd_test.d $(OBJS) $(LOC_OBJS) $(DEPS) + +-include $(DEPS) +-include $(LOC_DEPS) diff --git a/selfdrive/locationd/calibrationd.py b/selfdrive/locationd/calibrationd.py index 41911a6b741636..50cc9d0157a090 100755 --- a/selfdrive/locationd/calibrationd.py +++ b/selfdrive/locationd/calibrationd.py @@ -1,15 +1,14 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 + import os -import zmq import copy import json import numpy as np import selfdrive.messaging as messaging from selfdrive.locationd.calibration_helpers import Calibration from selfdrive.swaglog import cloudlog -from selfdrive.services import service_list -from common.params import Params -from common.transformations.model import model_height, get_camera_frame_from_model_frame, get_camera_frame_from_bigmodel_frame +from common.params import Params, put_nonblocking +from common.transformations.model import model_height from common.transformations.camera import view_frame_from_device_frame, get_view_frame_from_road_frame, \ eon_intrinsics, get_calib_from_vp, H, W @@ -23,7 +22,7 @@ # These validity corners were chosen by looking at 1000 # and taking most extreme cases with some margin. -VP_VALIDITY_CORNERS = np.array([[W/2 - 150, 280], [W/2 + 150, 540]]) +VP_VALIDITY_CORNERS = np.array([[W//2 - 150, 280], [W//2 + 150, 540]]) DEBUG = os.getenv("DEBUG") is not None @@ -32,15 +31,17 @@ def is_calibration_valid(vp): vp[1] > VP_VALIDITY_CORNERS[0,1] and vp[1] < VP_VALIDITY_CORNERS[1,1] -class Calibrator(object): +class Calibrator(): def __init__(self, param_put=False): self.param_put = param_put self.vp = copy.copy(VP_INIT) self.vps = [] self.cal_status = Calibration.UNCALIBRATED self.write_counter = 0 - self.params = Params() - calibration_params = self.params.get("CalibrationParams") + self.just_calibrated = False + + # Read calibration + calibration_params = Params().get("CalibrationParams") if calibration_params: try: calibration_params = json.loads(calibration_params) @@ -50,15 +51,20 @@ def __init__(self, param_put=False): except Exception: cloudlog.exception("CalibrationParams file found but error encountered") - def update_status(self): + start_status = self.cal_status if len(self.vps) < INPUTS_NEEDED: self.cal_status = Calibration.UNCALIBRATED else: self.cal_status = Calibration.CALIBRATED if is_calibration_valid(self.vp) else Calibration.INVALID + end_status = self.cal_status + + self.just_calibrated = False + if start_status == Calibration.UNCALIBRATED and end_status == Calibration.CALIBRATED: + self.just_calibrated = True def handle_cam_odom(self, log): - trans, rot = log.cameraOdometry.trans, log.cameraOdometry.rot + trans, rot = log.trans, log.rot if np.linalg.norm(trans) > MIN_SPEED_FILTER and abs(rot[2]) < MAX_YAW_RATE_FILTER: new_vp = eon_intrinsics.dot(view_frame_from_device_frame.dot(trans)) new_vp = new_vp[:2]/new_vp[2] @@ -67,50 +73,50 @@ def handle_cam_odom(self, log): self.vp = np.mean(self.vps, axis=0) self.update_status() self.write_counter += 1 - if self.param_put and self.write_counter % WRITE_CYCLES == 0: + if self.param_put and (self.write_counter % WRITE_CYCLES == 0 or self.just_calibrated): cal_params = {"vanishing_point": list(self.vp), "valid_points": len(self.vps)} - self.params.put("CalibrationParams", json.dumps(cal_params)) + put_nonblocking("CalibrationParams", json.dumps(cal_params).encode('utf8')) return new_vp + else: + return None - def send_data(self, livecalibration): + def send_data(self, pm): calib = get_calib_from_vp(self.vp) extrinsic_matrix = get_view_frame_from_road_frame(0, calib[1], calib[2], model_height) - ke = eon_intrinsics.dot(extrinsic_matrix) - warp_matrix = get_camera_frame_from_model_frame(ke) - warp_matrix_big = get_camera_frame_from_bigmodel_frame(ke) cal_send = messaging.new_message() cal_send.init('liveCalibration') cal_send.liveCalibration.calStatus = self.cal_status - cal_send.liveCalibration.calPerc = min(len(self.vps) * 100 / INPUTS_NEEDED, 100) - cal_send.liveCalibration.warpMatrix2 = map(float, warp_matrix.flatten()) - cal_send.liveCalibration.warpMatrixBig = map(float, warp_matrix_big.flatten()) - cal_send.liveCalibration.extrinsicMatrix = map(float, extrinsic_matrix.flatten()) + cal_send.liveCalibration.calPerc = min(len(self.vps) * 100 // INPUTS_NEEDED, 100) + cal_send.liveCalibration.extrinsicMatrix = [float(x) for x in extrinsic_matrix.flatten()] + cal_send.liveCalibration.rpyCalib = [float(x) for x in calib] + + pm.send('liveCalibration', cal_send) - livecalibration.send(cal_send.to_bytes()) +def calibrationd_thread(sm=None, pm=None): + if sm is None: + sm = messaging.SubMaster(['cameraOdometry']) -def calibrationd_thread(gctx=None, addr="127.0.0.1"): - context = zmq.Context() + if pm is None: + pm = messaging.PubMaster(['liveCalibration']) - cameraodometry = messaging.sub_sock(context, service_list['cameraOdometry'].port, addr=addr, conflate=True) - livecalibration = messaging.pub_sock(context, service_list['liveCalibration'].port) calibrator = Calibrator(param_put=True) # buffer with all the messages that still need to be input into the kalman while 1: - co = messaging.recv_one(cameraodometry) + sm.update() - new_vp = calibrator.handle_cam_odom(co) + new_vp = calibrator.handle_cam_odom(sm['cameraOdometry']) if DEBUG and new_vp is not None: - print 'got new vp', new_vp + print('got new vp', new_vp) - calibrator.send_data(livecalibration) + calibrator.send_data(pm) -def main(gctx=None, addr="127.0.0.1"): - calibrationd_thread(gctx, addr) +def main(sm=None, pm=None): + calibrationd_thread(sm, pm) if __name__ == "__main__": diff --git a/selfdrive/locationd/kalman/ekf_c.c b/selfdrive/locationd/kalman/ekf_c.c deleted file mode 100644 index 1331036de383e2..00000000000000 --- a/selfdrive/locationd/kalman/ekf_c.c +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include - -typedef Eigen::Matrix DDM; -typedef Eigen::Matrix EEM; -typedef Eigen::Matrix DEM; - -void predict(double *in_x, double *in_P, double *in_Q, double dt) { - typedef Eigen::Matrix RRM; - - double nx[DIM] = {0}; - double in_F[EDIM*EDIM] = {0}; - - // functions from sympy - f_fun(in_x, dt, nx); - F_fun(in_x, dt, in_F); - - - EEM F(in_F); - EEM P(in_P); - EEM Q(in_Q); - - RRM F_main = F.topLeftCorner(MEDIM, MEDIM); - P.topLeftCorner(MEDIM, MEDIM) = (F_main * P.topLeftCorner(MEDIM, MEDIM)) * F_main.transpose(); - P.topRightCorner(MEDIM, EDIM - MEDIM) = F_main * P.topRightCorner(MEDIM, EDIM - MEDIM); - P.bottomLeftCorner(EDIM - MEDIM, MEDIM) = P.bottomLeftCorner(EDIM - MEDIM, MEDIM) * F_main.transpose(); - - P = P + dt*Q; - - // copy out state - memcpy(in_x, nx, DIM * sizeof(double)); - memcpy(in_P, P.data(), EDIM * EDIM * sizeof(double)); -} - -// note: extra_args dim only correct when null space projecting -// otherwise 1 -template -void update(double *in_x, double *in_P, Hfun h_fun, Hfun H_fun, Hfun Hea_fun, double *in_z, double *in_R, double *in_ea, double MAHA_THRESHOLD) { - typedef Eigen::Matrix ZZM; - typedef Eigen::Matrix ZDM; - typedef Eigen::Matrix ZEM; - typedef Eigen::Matrix XEM; - typedef Eigen::Matrix EZM; - typedef Eigen::Matrix X1M; - typedef Eigen::Matrix XXM; - - double in_hx[ZDIM] = {0}; - double in_H[ZDIM * DIM] = {0}; - double in_H_mod[EDIM * DIM] = {0}; - double delta_x[EDIM] = {0}; - double x_new[DIM] = {0}; - - - // state x, P - Eigen::Matrix z(in_z); - EEM P(in_P); - ZZM pre_R(in_R); - - // functions from sympy - h_fun(in_x, in_ea, in_hx); - H_fun(in_x, in_ea, in_H); - ZDM pre_H(in_H); - - // get y (y = z - hx) - Eigen::Matrix pre_y(in_hx); pre_y = z - pre_y; - X1M y; XXM H; XXM R; - if (Hea_fun){ - typedef Eigen::Matrix ZAM; - double in_Hea[ZDIM * EADIM] = {0}; - Hea_fun(in_x, in_ea, in_Hea); - ZAM Hea(in_Hea); - XXM A = Hea.transpose().fullPivLu().kernel(); - - - y = A.transpose() * pre_y; - H = A.transpose() * pre_H; - R = A.transpose() * pre_R * A; - } else { - y = pre_y; - H = pre_H; - R = pre_R; - } - // get modified H - H_mod_fun(in_x, in_H_mod); - DEM H_mod(in_H_mod); - XEM H_err = H * H_mod; - - // Do mahalobis distance test - if (MAHA_TEST){ - XXM a = (H_err * P * H_err.transpose() + R).inverse(); - double maha_dist = y.transpose() * a * y; - if (maha_dist > MAHA_THRESHOLD){ - R = 1.0e16 * R; - } - } - - // Outlier resilient weighting - double weight = 1;//(1.5)/(1 + y.squaredNorm()/R.sum()); - - // kalman gains and I_KH - XXM S = ((H_err * P) * H_err.transpose()) + R/weight; - XEM KT = S.fullPivLu().solve(H_err * P.transpose()); - //EZM K = KT.transpose(); TODO: WHY DOES THIS NOT COMPILE? - //EZM K = S.fullPivLu().solve(H_err * P.transpose()).transpose(); - //std::cout << "Here is the matrix rot:\n" << K << std::endl; - EEM I_KH = Eigen::Matrix::Identity() - (KT.transpose() * H_err); - - // update state by injecting dx - Eigen::Matrix dx(delta_x); - dx = (KT.transpose() * y); - memcpy(delta_x, dx.data(), EDIM * sizeof(double)); - err_fun(in_x, delta_x, x_new); - Eigen::Matrix x(x_new); - - // update cov - P = ((I_KH * P) * I_KH.transpose()) + ((KT.transpose() * R) * KT); - - // copy out state - memcpy(in_x, x.data(), DIM * sizeof(double)); - memcpy(in_P, P.data(), EDIM * EDIM * sizeof(double)); - memcpy(in_z, y.data(), y.rows() * sizeof(double)); -} - - diff --git a/selfdrive/locationd/kalman/ekf_sym.py b/selfdrive/locationd/kalman/ekf_sym.py deleted file mode 100644 index 2dfefe92d30a7a..00000000000000 --- a/selfdrive/locationd/kalman/ekf_sym.py +++ /dev/null @@ -1,564 +0,0 @@ -import os -from bisect import bisect_right -import sympy as sp -import numpy as np -from numpy import dot -from common.ffi_wrapper import compile_code, wrap_compiled -from common.sympy_helpers import sympy_into_c -import scipy -from scipy.stats import chi2 - - -EXTERNAL_PATH = os.path.dirname(os.path.abspath(__file__)) - -def solve(a, b): - if a.shape[0] == 1 and a.shape[1] == 1: - #assert np.allclose(b/a[0][0], np.linalg.solve(a, b)) - return b/a[0][0] - else: - return np.linalg.solve(a, b) - -def null(H, eps=1e-12): - from scipy import linalg - u, s, vh = linalg.svd(H) - padding = max(0,np.shape(H)[1]-np.shape(s)[0]) - null_mask = np.concatenate(((s <= eps), np.ones((padding,),dtype=bool)),axis=0) - null_space = scipy.compress(null_mask, vh, axis=0) - return scipy.transpose(null_space) - -def gen_code(name, f_sym, dt_sym, x_sym, obs_eqs, dim_x, dim_err, eskf_params=None, msckf_params=None, maha_test_kinds=[]): - # optional state transition matrix, H modifier - # and err_function if an error-state kalman filter (ESKF) - # is desired. Best described in "Quaternion kinematics - # for the error-state Kalman filter" by Joan Sola - - if eskf_params: - err_eqs = eskf_params[0] - inv_err_eqs = eskf_params[1] - H_mod_sym = eskf_params[2] - f_err_sym = eskf_params[3] - x_err_sym = eskf_params[4] - else: - nom_x = sp.MatrixSymbol('nom_x',dim_x,1) - true_x = sp.MatrixSymbol('true_x',dim_x,1) - delta_x = sp.MatrixSymbol('delta_x',dim_x,1) - err_function_sym = sp.Matrix(nom_x + delta_x) - inv_err_function_sym = sp.Matrix(true_x - nom_x) - err_eqs = [err_function_sym, nom_x, delta_x] - inv_err_eqs = [inv_err_function_sym, nom_x, true_x] - - H_mod_sym = sp.Matrix(np.eye(dim_x)) - f_err_sym = f_sym - x_err_sym = x_sym - - # This configures the multi-state augmentation - # needed for EKF-SLAM with MSCKF (Mourikis et al 2007) - if msckf_params: - msckf = True - dim_main = msckf_params[0] # size of the main state - dim_augment = msckf_params[1] # size of one augment state chunk - dim_main_err = msckf_params[2] - dim_augment_err = msckf_params[3] - N = msckf_params[4] - feature_track_kinds = msckf_params[5] - assert dim_main + dim_augment*N == dim_x - assert dim_main_err + dim_augment_err*N == dim_err - else: - msckf = False - dim_main = dim_x - dim_augment = 0 - dim_main_err = dim_err - dim_augment_err = 0 - N = 0 - - # linearize with jacobians - F_sym = f_err_sym.jacobian(x_err_sym) - for sym in x_err_sym: - F_sym = F_sym.subs(sym, 0) - for i in xrange(len(obs_eqs)): - obs_eqs[i].append(obs_eqs[i][0].jacobian(x_sym)) - if msckf and obs_eqs[i][1] in feature_track_kinds: - obs_eqs[i].append(obs_eqs[i][0].jacobian(obs_eqs[i][2])) - else: - obs_eqs[i].append(None) - - # collect sympy functions - sympy_functions = [] - - # error functions - sympy_functions.append(('err_fun', err_eqs[0], [err_eqs[1], err_eqs[2]])) - sympy_functions.append(('inv_err_fun', inv_err_eqs[0], [inv_err_eqs[1], inv_err_eqs[2]])) - - # H modifier for ESKF updates - sympy_functions.append(('H_mod_fun', H_mod_sym, [x_sym])) - - # state propagation function - sympy_functions.append(('f_fun', f_sym, [x_sym, dt_sym])) - sympy_functions.append(('F_fun', F_sym, [x_sym, dt_sym])) - - # observation functions - for h_sym, kind, ea_sym, H_sym, He_sym in obs_eqs: - sympy_functions.append(('h_%d' % kind, h_sym, [x_sym, ea_sym])) - sympy_functions.append(('H_%d' % kind, H_sym, [x_sym, ea_sym])) - if msckf and kind in feature_track_kinds: - sympy_functions.append(('He_%d' % kind, He_sym, [x_sym, ea_sym])) - - # Generate and wrap all th c code - header, code = sympy_into_c(sympy_functions) - extra_header = "#define DIM %d\n" % dim_x - extra_header += "#define EDIM %d\n" % dim_err - extra_header += "#define MEDIM %d\n" % dim_main_err - extra_header += "typedef void (*Hfun)(double *, double *, double *);\n" - - extra_header += "\nvoid predict(double *x, double *P, double *Q, double dt);" - - extra_post = "" - - for h_sym, kind, ea_sym, H_sym, He_sym in obs_eqs: - if msckf and kind in feature_track_kinds: - He_str = 'He_%d' % kind - # ea_dim = ea_sym.shape[0] - else: - He_str = 'NULL' - # ea_dim = 1 # not really dim of ea but makes c function work - maha_thresh = chi2.ppf(0.95, int(h_sym.shape[0])) # mahalanobis distance for outlier detection - maha_test = kind in maha_test_kinds - extra_post += """ - void update_%d(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea) { - update<%d,%d,%d>(in_x, in_P, h_%d, H_%d, %s, in_z, in_R, in_ea, MAHA_THRESH_%d); - } - """ % (kind, h_sym.shape[0], 3, maha_test, kind, kind, He_str, kind) - extra_header += "\nconst static double MAHA_THRESH_%d = %f;" % (kind, maha_thresh) - extra_header += "\nvoid update_%d(double *, double *, double *, double *, double *);" % kind - - code += "\n" + extra_header - code += "\n" + open(os.path.join(EXTERNAL_PATH, "ekf_c.c")).read() - code += "\n" + extra_post - header += "\n" + extra_header - compile_code(name, code, header, EXTERNAL_PATH) - -class EKF_sym(object): - def __init__(self, name, Q, x_initial, P_initial, dim_main, dim_main_err, - N=0, dim_augment=0, dim_augment_err=0, maha_test_kinds=[]): - ''' - Generates process function and all - observation functions for the kalman - filter. - ''' - if N > 0: - self.msckf = True - else: - self.msckf = False - self.N = N - self.dim_augment = dim_augment - self.dim_augment_err = dim_augment_err - self.dim_main = dim_main - self.dim_main_err = dim_main_err - - # state - x_initial = x_initial.reshape((-1, 1)) - self.dim_x = x_initial.shape[0] - self.dim_err = P_initial.shape[0] - assert dim_main + dim_augment*N == self.dim_x - assert dim_main_err + dim_augment_err*N == self.dim_err - - # kinds that should get mahalanobis distance - # tested for outlier rejection - self.maha_test_kinds = maha_test_kinds - - # process noise - self.Q = Q - - # rewind stuff - self.rewind_t = [] - self.rewind_states = [] - self.rewind_obscache = [] - self.init_state(x_initial, P_initial, None) - - ffi, lib = wrap_compiled(name, EXTERNAL_PATH) - kinds, self.feature_track_kinds = [], [] - for func in dir(lib): - if func[:2] == 'h_': - kinds.append(int(func[2:])) - if func[:3] == 'He_': - self.feature_track_kinds.append(int(func[3:])) - - # wrap all the sympy functions - def wrap_1lists(name): - func = eval("lib.%s" % name, {"lib":lib}) - def ret(lst1, out): - func(ffi.cast("double *", lst1.ctypes.data), - ffi.cast("double *", out.ctypes.data)) - return ret - def wrap_2lists(name): - func = eval("lib.%s" % name, {"lib":lib}) - def ret(lst1, lst2, out): - func(ffi.cast("double *", lst1.ctypes.data), - ffi.cast("double *", lst2.ctypes.data), - ffi.cast("double *", out.ctypes.data)) - return ret - def wrap_1list_1float(name): - func = eval("lib.%s" % name, {"lib":lib}) - def ret(lst1, fl, out): - func(ffi.cast("double *", lst1.ctypes.data), - ffi.cast("double", fl), - ffi.cast("double *", out.ctypes.data)) - return ret - - self.f = wrap_1list_1float("f_fun") - self.F = wrap_1list_1float("F_fun") - - self.err_function = wrap_2lists("err_fun") - self.inv_err_function = wrap_2lists("inv_err_fun") - self.H_mod = wrap_1lists("H_mod_fun") - - self.hs, self.Hs, self.Hes = {}, {}, {} - for kind in kinds: - self.hs[kind] = wrap_2lists("h_%d" % kind) - self.Hs[kind] = wrap_2lists("H_%d" % kind) - if self.msckf and kind in self.feature_track_kinds: - self.Hes[kind] = wrap_2lists("He_%d" % kind) - - # wrap the C++ predict function - def _predict_blas(x, P, dt): - lib.predict(ffi.cast("double *", x.ctypes.data), - ffi.cast("double *", P.ctypes.data), - ffi.cast("double *", self.Q.ctypes.data), - ffi.cast("double", dt)) - return x, P - - # wrap the C++ update function - def fun_wrapper(f, kind): - f = eval("lib.%s" % f, {"lib": lib}) - def _update_inner_blas(x, P, z, R, extra_args): - f(ffi.cast("double *", x.ctypes.data), - ffi.cast("double *", P.ctypes.data), - ffi.cast("double *", z.ctypes.data), - ffi.cast("double *", R.ctypes.data), - ffi.cast("double *", extra_args.ctypes.data)) - if self.msckf and kind in self.feature_track_kinds: - y = z[:-len(extra_args)] - else: - y = z - return x, P, y - return _update_inner_blas - - self._updates = {} - for kind in kinds: - self._updates[kind] = fun_wrapper("update_%d" % kind, kind) - - def _update_blas(x, P, kind, z, R, extra_args=[]): - return self._updates[kind](x, P, z, R, extra_args) - - # assign the functions - self._predict = _predict_blas - #self._predict = self._predict_python - self._update = _update_blas - #self._update = self._update_python - - - def init_state(self, state, covs, filter_time): - self.x = np.array(state.reshape((-1, 1))).astype(np.float64) - self.P = np.array(covs).astype(np.float64) - self.filter_time = filter_time - self.augment_times = [0]*self.N - self.rewind_obscache = [] - self.rewind_t = [] - self.rewind_states = [] - - def augment(self): - # TODO this is not a generalized way of doing - # this and implies that the augmented states - # are simply the first (dim_augment_state) - # elements of the main state. - assert self.msckf - d1 = self.dim_main - d2 = self.dim_main_err - d3 = self.dim_augment - d4 = self.dim_augment_err - # push through augmented states - self.x[d1:-d3] = self.x[d1+d3:] - self.x[-d3:] = self.x[:d3] - assert self.x.shape == (self.dim_x, 1) - # push through augmented covs - assert self.P.shape == (self.dim_err, self.dim_err) - P_reduced = self.P - P_reduced = np.delete(P_reduced, np.s_[d2:d2+d4], axis=1) - P_reduced = np.delete(P_reduced, np.s_[d2:d2+d4], axis=0) - assert P_reduced.shape == (self.dim_err -d4, self.dim_err -d4) - to_mult = np.zeros((self.dim_err, self.dim_err - d4)) - to_mult[:-d4,:] = np.eye(self.dim_err - d4) - to_mult[-d4:,:d4] = np.eye(d4) - self.P = to_mult.dot(P_reduced.dot(to_mult.T)) - self.augment_times = self.augment_times[1:] - self.augment_times.append(self.filter_time) - assert self.P.shape == (self.dim_err, self.dim_err) - - def state(self): - return np.array(self.x).flatten() - - def covs(self): - return self.P - - def rewind(self, t): - # find where we are rewinding to - idx = bisect_right(self.rewind_t, t) - assert self.rewind_t[idx-1] <= t - assert self.rewind_t[idx] > t # must be true, or rewind wouldn't be called - - # set the state to the time right before that - self.filter_time = self.rewind_t[idx-1] - self.x[:] = self.rewind_states[idx-1][0] - self.P[:] = self.rewind_states[idx-1][1] - - # return the observations we rewound over for fast forwarding - ret = self.rewind_obscache[idx:] - - # throw away the old future - # TODO: is this making a copy? - self.rewind_t = self.rewind_t[:idx] - self.rewind_states = self.rewind_states[:idx] - self.rewind_obscache = self.rewind_obscache[:idx] - - return ret - - def checkpoint(self, obs): - # push to rewinder - self.rewind_t.append(self.filter_time) - self.rewind_states.append((np.copy(self.x), np.copy(self.P))) - self.rewind_obscache.append(obs) - - # only keep a certain number around - REWIND_TO_KEEP = 512 - self.rewind_t = self.rewind_t[-REWIND_TO_KEEP:] - self.rewind_states = self.rewind_states[-REWIND_TO_KEEP:] - self.rewind_obscache = self.rewind_obscache[-REWIND_TO_KEEP:] - - def predict_and_update_batch(self, t, kind, z, R, extra_args=[[]], augment=False): - # TODO handle rewinding at this level" - - # rewind - if t < self.filter_time: - if len(self.rewind_t) == 0 or t < self.rewind_t[0] or t < self.rewind_t[-1] -1.0: - print "observation too old at %.3f with filter at %.3f, ignoring" % (t, self.filter_time) - return None - rewound = self.rewind(t) - else: - rewound = [] - - ret = self._predict_and_update_batch(t, kind, z, R, extra_args, augment) - - # optional fast forward - for r in rewound: - self._predict_and_update_batch(*r) - - return ret - - def _predict_and_update_batch(self, t, kind, z, R, extra_args, augment=False): - """The main kalman filter function - Predicts the state and then updates a batch of observations - - dim_x: dimensionality of the state space - dim_z: dimensionality of the observation and depends on kind - n: number of observations - - Args: - t (float): Time of observation - kind (int): Type of observation - z (vec [n,dim_z]): Measurements - R (mat [n,dim_z, dim_z]): Measurement Noise - extra_args (list, [n]): Values used in H computations - """ - # initialize time - if self.filter_time is None: - self.filter_time = t - - # predict - dt = t - self.filter_time - assert dt >= 0 - self.x, self.P = self._predict(self.x, self.P, dt) - self.filter_time = t - xk_km1, Pk_km1 = np.copy(self.x).flatten(), np.copy(self.P) - - # update batch - y = [] - for i in xrange(len(z)): - # these are from the user, so we canonicalize them - z_i = np.array(z[i], dtype=np.float64, order='F') - R_i = np.array(R[i], dtype=np.float64, order='F') - extra_args_i = np.array(extra_args[i], dtype=np.float64, order='F') - # update - self.x, self.P, y_i = self._update(self.x, self.P, kind, z_i, R_i, extra_args=extra_args_i) - y.append(y_i) - xk_k, Pk_k = np.copy(self.x).flatten(), np.copy(self.P) - - if augment: - self.augment() - - # checkpoint - self.checkpoint((t, kind, z, R, extra_args)) - - return xk_km1, xk_k, Pk_km1, Pk_k, t, kind, y, z, extra_args - - def _predict_python(self, x, P, dt): - x_new = np.zeros(x.shape, dtype=np.float64) - self.f(x, dt, x_new) - - F = np.zeros(P.shape, dtype=np.float64) - self.F(x, dt, F) - - if not self.msckf: - P = dot(dot(F, P), F.T) - else: - # Update the predicted state covariance: - # Pk+1|k = |F*Pii*FT + Q*dt F*Pij | - # |PijT*FT Pjj | - # Where F is the jacobian of the main state - # predict function, Pii is the main state's - # covariance and Q its process noise. Pij - # is the covariance between the augmented - # states and the main state. - # - d2 = self.dim_main_err # known at compile time - F_curr = F[:d2, :d2] - P[:d2, :d2] = (F_curr.dot(P[:d2, :d2])).dot(F_curr.T) - P[:d2, d2:] = F_curr.dot(P[:d2, d2:]) - P[d2:, :d2] = P[d2:, :d2].dot(F_curr.T) - - P += dt*self.Q - return x_new, P - - def _update_python(self, x, P, kind, z, R, extra_args=[]): - # init vars - z = z.reshape((-1, 1)) - h = np.zeros(z.shape, dtype=np.float64) - H = np.zeros((z.shape[0], self.dim_x), dtype=np.float64) - - # C functions - self.hs[kind](x, extra_args, h) - self.Hs[kind](x, extra_args, H) - - # y is the "loss" - y = z - h - - # *** same above this line *** - - if self.msckf and kind in self.Hes: - # Do some algebraic magic to decorrelate - He = np.zeros((z.shape[0], len(extra_args)), dtype=np.float64) - self.Hes[kind](x, extra_args, He) - - # TODO: Don't call a function here, do projection locally - A = null(He.T) - - y = A.T.dot(y) - H = A.T.dot(H) - R = A.T.dot(R.dot(A)) - - # TODO If nullspace isn't the dimension we want - if A.shape[1] + He.shape[1] != A.shape[0]: - print 'Warning: null space projection failed, measurement ignored' - return x, P, np.zeros(A.shape[0] - He.shape[1]) - - # if using eskf - H_mod = np.zeros((x.shape[0], P.shape[0]), dtype=np.float64) - self.H_mod(x, H_mod) - H = H.dot(H_mod) - - # Do mahalobis distance test - # currently just runs on msckf observations - # could run on anything if needed - if self.msckf and kind in self.maha_test_kinds: - a = np.linalg.inv(H.dot(P).dot(H.T) + R) - maha_dist = y.T.dot(a.dot(y)) - if maha_dist > chi2.ppf(0.95, y.shape[0]): - R = 10e16*R - - # *** same below this line *** - - # Outlier resilient weighting as described in: - # "A Kalman Filter for Robust Outlier Detection - Jo-Anne Ting, ..." - weight = 1 #(1.5)/(1 + np.sum(y**2)/np.sum(R)) - - S = dot(dot(H, P), H.T) + R/weight - K = solve(S, dot(H, P.T)).T - I_KH = np.eye(P.shape[0]) - dot(K, H) - - # update actual state - delta_x = dot(K, y) - P = dot(dot(I_KH, P), I_KH.T) + dot(dot(K, R), K.T) - - # inject observed error into state - x_new = np.zeros(x.shape, dtype=np.float64) - self.err_function(x, delta_x, x_new) - return x_new, P, y.flatten() - - def maha_test(self, x, P, kind, z, R, extra_args=[], maha_thresh=0.95): - # init vars - z = z.reshape((-1, 1)) - h = np.zeros(z.shape, dtype=np.float64) - H = np.zeros((z.shape[0], self.dim_x), dtype=np.float64) - - # C functions - self.hs[kind](x, extra_args, h) - self.Hs[kind](x, extra_args, H) - - # y is the "loss" - y = z - h - - # if using eskf - H_mod = np.zeros((x.shape[0], P.shape[0]), dtype=np.float64) - self.H_mod(x, H_mod) - H = H.dot(H_mod) - - a = np.linalg.inv(H.dot(P).dot(H.T) + R) - maha_dist = y.T.dot(a.dot(y)) - if maha_dist > chi2.ppf(maha_thresh, y.shape[0]): - return False - else: - return True - - - - - def rts_smooth(self, estimates, norm_quats=False): - ''' - Returns rts smoothed results of - kalman filter estimates - - If the kalman state is augmented with - old states only the main state is smoothed - ''' - xk_n = estimates[-1][0] - Pk_n = estimates[-1][2] - Fk_1 = np.zeros(Pk_n.shape, dtype=np.float64) - - states_smoothed = [xk_n] - covs_smoothed = [Pk_n] - for k in xrange(len(estimates) - 2, -1, -1): - xk1_n = xk_n - if norm_quats: - xk1_n[3:7] /= np.linalg.norm(xk1_n[3:7]) - Pk1_n = Pk_n - - xk1_k, _, Pk1_k, _, t2, _, _, _, _ = estimates[k + 1] - _, xk_k, _, Pk_k, t1, _, _, _, _ = estimates[k] - dt = t2 - t1 - self.F(xk_k, dt, Fk_1) - - d1 = self.dim_main - d2 = self.dim_main_err - Ck = np.linalg.solve(Pk1_k[:d2,:d2], Fk_1[:d2,:d2].dot(Pk_k[:d2,:d2].T)).T - xk_n = xk_k - delta_x = np.zeros((Pk_n.shape[0], 1), dtype=np.float64) - self.inv_err_function(xk1_k, xk1_n, delta_x) - delta_x[:d2] = Ck.dot(delta_x[:d2]) - x_new = np.zeros((xk_n.shape[0], 1), dtype=np.float64) - self.err_function(xk_k, delta_x, x_new) - xk_n[:d1] = x_new[:d1,0] - Pk_n = Pk_k - Pk_n[:d2,:d2] = Pk_k[:d2,:d2] + Ck.dot(Pk1_n[:d2,:d2] - Pk1_k[:d2,:d2]).dot(Ck.T) - states_smoothed.append(xk_n) - covs_smoothed.append(Pk_n) - - return np.flipud(np.vstack(states_smoothed)), np.stack(covs_smoothed, 0)[::-1] diff --git a/selfdrive/locationd/kalman/kalman_helpers.py b/selfdrive/locationd/kalman/kalman_helpers.py deleted file mode 100644 index b15f1542e192bf..00000000000000 --- a/selfdrive/locationd/kalman/kalman_helpers.py +++ /dev/null @@ -1,165 +0,0 @@ -import numpy as np -import os -from bisect import bisect -from tqdm import tqdm - - -class ObservationKind(object): - UNKNOWN = 0 - NO_OBSERVATION = 1 - GPS_NED = 2 - ODOMETRIC_SPEED = 3 - PHONE_GYRO = 4 - GPS_VEL = 5 - PSEUDORANGE_GPS = 6 - PSEUDORANGE_RATE_GPS = 7 - SPEED = 8 - NO_ROT = 9 - PHONE_ACCEL = 10 - ORB_POINT = 11 - ECEF_POS = 12 - CAMERA_ODO_TRANSLATION = 13 - CAMERA_ODO_ROTATION = 14 - ORB_FEATURES = 15 - MSCKF_TEST = 16 - FEATURE_TRACK_TEST = 17 - LANE_PT = 18 - IMU_FRAME = 19 - PSEUDORANGE_GLONASS = 20 - PSEUDORANGE_RATE_GLONASS = 21 - PSEUDORANGE = 22 - PSEUDORANGE_RATE = 23 - - names = ['Unknown', - 'No observation', - 'GPS NED', - 'Odometric speed', - 'Phone gyro', - 'GPS velocity', - 'GPS pseudorange', - 'GPS pseudorange rate', - 'Speed', - 'No rotation', - 'Phone acceleration', - 'ORB point', - 'ECEF pos', - 'camera odometric translation', - 'camera odometric rotation', - 'ORB features', - 'MSCKF test', - 'Feature track test', - 'Lane ecef point', - 'imu frame eulers', - 'GLONASS pseudorange', - 'GLONASS pseudorange rate'] - - @classmethod - def to_string(cls, kind): - return cls.names[kind] - - - -SAT_OBS = [ObservationKind.PSEUDORANGE_GPS, - ObservationKind.PSEUDORANGE_RATE_GPS, - ObservationKind.PSEUDORANGE_GLONASS, - ObservationKind.PSEUDORANGE_RATE_GLONASS] - - -def run_car_ekf_offline(kf, observations_by_kind): - from laika.raw_gnss import GNSSMeasurement - observations = [] - # create list of observations with element format: [kind, time, data] - for kind in observations_by_kind: - for t, data in zip(observations_by_kind[kind][0], observations_by_kind[kind][1]): - observations.append([t, kind, data]) - observations.sort(key=lambda obs: obs[0]) - - times, estimates = run_observations_through_filter(kf, observations) - - forward_states = np.stack(e[1] for e in estimates) - forward_covs = np.stack(e[3] for e in estimates) - smoothed_states, smoothed_covs = kf.rts_smooth(estimates) - - observations_dict = {} - # TODO assuming observations and estimates - # are same length may not work with VO - for e in estimates: - t = e[4] - kind = str(int(e[5])) - res = e[6] - z = e[7] - ea = e[8] - if len(z) == 0: - continue - if kind not in observations_dict: - observations_dict[kind] = {} - observations_dict[kind]['t'] = np.array(len(z)*[t]) - observations_dict[kind]['z'] = np.array(z) - observations_dict[kind]['ea'] = np.array(ea) - observations_dict[kind]['residual'] = np.array(res) - else: - observations_dict[kind]['t'] = np.append(observations_dict[kind]['t'], np.array(len(z)*[t])) - observations_dict[kind]['z'] = np.vstack((observations_dict[kind]['z'], np.array(z))) - observations_dict[kind]['ea'] = np.vstack((observations_dict[kind]['ea'], np.array(ea))) - observations_dict[kind]['residual'] = np.vstack((observations_dict[kind]['residual'], np.array(res))) - - # add svIds to gnss data - for kind in map(str, SAT_OBS): - if int(kind) in observations_by_kind and kind in observations_dict: - observations_dict[kind]['svIds'] = np.array([]) - observations_dict[kind]['CNO'] = np.array([]) - observations_dict[kind]['std'] = np.array([]) - for obs in observations_by_kind[int(kind)][1]: - observations_dict[kind]['svIds'] = np.append(observations_dict[kind]['svIds'], - np.array([obs[:,GNSSMeasurement.PRN]])) - observations_dict[kind]['std'] = np.append(observations_dict[kind]['std'], - np.array([obs[:,GNSSMeasurement.PR_STD]])) - return smoothed_states, smoothed_covs, forward_states, forward_covs, times, observations_dict - - -def run_observations_through_filter(kf, observations, filter_time=None): - estimates = [] - - for obs in tqdm(observations): - t = obs[0] - kind = obs[1] - data = obs[2] - estimates.append(kf.predict_and_observe(t, kind, data)) - times = [x[4] for x in estimates] - return times, estimates - - -def save_residuals_plot(obs, save_path, data_name): - import matplotlib.pyplot as plt - import mpld3 - fig = plt.figure(figsize=(10,20)) - fig.suptitle('Residuals of ' + data_name, fontsize=24) - n = len(obs.keys()) - start_times = [obs[kind]['t'][0] for kind in obs] - start_time = min(start_times) - xlims = [start_time + 3, start_time + 60] - - for i, kind in enumerate(obs): - ax = fig.add_subplot(n, 1, i+1) - ax.set_xlim(xlims) - t = obs[kind]['t'] - res = obs[kind]['residual'] - start_idx = bisect(t, xlims[0]) - if len(res) == start_idx: - continue - ylim = max(np.linalg.norm(res[start_idx:], axis=1)) - ax.set_ylim([-ylim, ylim]) - if int(kind) in SAT_OBS: - svIds = obs[kind]['svIds'] - for svId in set(svIds): - svId_idx = (svIds == svId) - t = obs[kind]['t'][svId_idx] - res = obs[kind]['residual'][svId_idx] - ax.plot(t, res, label='SV ' + str(int(svId))) - ax.legend(loc='right') - else: - ax.plot(t, res) - plt.title('Residual of kind ' + ObservationKind.to_string(int(kind)), fontsize=20) - plt.tight_layout() - os.makedirs(save_path) - mpld3.save_html(fig, save_path + 'residuals_plot.html') diff --git a/selfdrive/locationd/kalman/loc_local_kf.py b/selfdrive/locationd/kalman/loc_local_kf.py deleted file mode 100755 index df6d41c77e2b3e..00000000000000 --- a/selfdrive/locationd/kalman/loc_local_kf.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env python -import numpy as np -import loc_local_model - -from kalman_helpers import ObservationKind -from ekf_sym import EKF_sym - - - -class States(object): - VELOCITY = slice(0,3) # device frame velocity in m/s - ANGULAR_VELOCITY = slice(3, 6) # roll, pitch and yaw rates in device frame in radians/s - GYRO_BIAS = slice(6, 9) # roll, pitch and yaw biases - ODO_SCALE = slice(9, 10) # odometer scale - ACCELERATION = slice(10, 13) # Acceleration in device frame in m/s**2 - - -class LocLocalKalman(object): - def __init__(self): - x_initial = np.array([0, 0, 0, - 0, 0, 0, - 0, 0, 0, - 1, - 0, 0, 0]) - - # state covariance - P_initial = np.diag([10**2, 10**2, 10**2, - 1**2, 1**2, 1**2, - 0.05**2, 0.05**2, 0.05**2, - 0.02**2, - 1**2, 1**2, 1**2]) - - # process noise - Q = np.diag([0.0**2, 0.0**2, 0.0**2, - .01**2, .01**2, .01**2, - (0.005/100)**2, (0.005/100)**2, (0.005/100)**2, - (0.02/100)**2, - 3**2, 3**2, 3**2]) - - self.obs_noise = {ObservationKind.ODOMETRIC_SPEED: np.atleast_2d(0.2**2), - ObservationKind.PHONE_GYRO: np.diag([0.025**2, 0.025**2, 0.025**2])} - - # MSCKF stuff - self.dim_state = len(x_initial) - self.dim_main = self.dim_state - - name = 'loc_local' - loc_local_model.gen_model(name, self.dim_state) - - # init filter - self.filter = EKF_sym(name, Q, x_initial, P_initial, self.dim_main, self.dim_main) - - @property - def x(self): - return self.filter.state() - - @property - def t(self): - return self.filter.filter_time - - @property - def P(self): - return self.filter.covs() - - def predict(self, t): - if self.t: - # Does NOT modify filter state - return self.filter._predict(self.x, self.P, t - self.t)[0] - else: - raise RuntimeError("Request predict on filter with uninitialized time") - - def rts_smooth(self, estimates): - return self.filter.rts_smooth(estimates, norm_quats=True) - - - def init_state(self, state, covs_diag=None, covs=None, filter_time=None): - if covs_diag is not None: - P = np.diag(covs_diag) - elif covs is not None: - P = covs - else: - P = self.filter.covs() - self.filter.init_state(state, P, filter_time) - - def predict_and_observe(self, t, kind, data): - if len(data) > 0: - data = np.atleast_2d(data) - if kind == ObservationKind.CAMERA_ODO_TRANSLATION: - r = self.predict_and_update_odo_trans(data, t, kind) - elif kind == ObservationKind.CAMERA_ODO_ROTATION: - r = self.predict_and_update_odo_rot(data, t, kind) - elif kind == ObservationKind.ODOMETRIC_SPEED: - r = self.predict_and_update_odo_speed(data, t, kind) - else: - r = self.filter.predict_and_update_batch(t, kind, data, self.get_R(kind, len(data))) - return r - - def get_R(self, kind, n): - obs_noise = self.obs_noise[kind] - dim = obs_noise.shape[0] - R = np.zeros((n, dim, dim)) - for i in xrange(n): - R[i,:,:] = obs_noise - return R - - def predict_and_update_odo_speed(self, speed, t, kind): - z = np.array(speed) - R = np.zeros((len(speed), 1, 1)) - for i, _ in enumerate(z): - R[i,:,:] = np.diag([0.2**2]) - return self.filter.predict_and_update_batch(t, kind, z, R) - - def predict_and_update_odo_trans(self, trans, t, kind): - z = trans[:,:3] - R = np.zeros((len(trans), 3, 3)) - for i, _ in enumerate(z): - R[i,:,:] = np.diag(trans[i,3:]**2) - return self.filter.predict_and_update_batch(t, kind, z, R) - - def predict_and_update_odo_rot(self, rot, t, kind): - z = rot[:,:3] - R = np.zeros((len(rot), 3, 3)) - for i, _ in enumerate(z): - R[i,:,:] = np.diag(rot[i,3:]**2) - return self.filter.predict_and_update_batch(t, kind, z, R) - -if __name__ == "__main__": - LocLocalKalman() diff --git a/selfdrive/locationd/kalman/loc_local_model.py b/selfdrive/locationd/kalman/loc_local_model.py deleted file mode 100644 index 2d69cac024843e..00000000000000 --- a/selfdrive/locationd/kalman/loc_local_model.py +++ /dev/null @@ -1,80 +0,0 @@ -import numpy as np -import sympy as sp -import os - -from kalman_helpers import ObservationKind -from ekf_sym import gen_code - - -def gen_model(name, dim_state): - - # check if rebuild is needed - try: - dir_path = os.path.dirname(__file__) - deps = [dir_path + '/' + 'ekf_c.c', - dir_path + '/' + 'ekf_sym.py', - dir_path + '/' + 'loc_local_model.py', - dir_path + '/' + 'loc_local_kf.py'] - - outs = [dir_path + '/' + name + '.o', - dir_path + '/' + name + '.so', - dir_path + '/' + name + '.cpp'] - out_times = map(os.path.getmtime, outs) - dep_times = map(os.path.getmtime, deps) - rebuild = os.getenv("REBUILD", False) - if min(out_times) > max(dep_times) and not rebuild: - return - map(os.remove, outs) - except OSError: - pass - - # make functions and jacobians with sympy - # state variables - state_sym = sp.MatrixSymbol('state', dim_state, 1) - state = sp.Matrix(state_sym) - v = state[0:3,:] - omega = state[3:6,:] - vroll, vpitch, vyaw = omega - vx, vy, vz = v - roll_bias, pitch_bias, yaw_bias = state[6:9,:] - odo_scale = state[9,:] - accel = state[10:13,:] - - dt = sp.Symbol('dt') - - # Time derivative of the state as a function of state - state_dot = sp.Matrix(np.zeros((dim_state, 1))) - state_dot[:3,:] = accel - - # Basic descretization, 1st order intergrator - # Can be pretty bad if dt is big - f_sym = sp.Matrix(state + dt*state_dot) - - # - # Observation functions - # - - # extra args - #imu_rot = euler_rotate(*imu_angles) - #h_gyro_sym = imu_rot*sp.Matrix([vroll + roll_bias, - # vpitch + pitch_bias, - # vyaw + yaw_bias]) - h_gyro_sym = sp.Matrix([vroll + roll_bias, - vpitch + pitch_bias, - vyaw + yaw_bias]) - - speed = vx**2 + vy**2 + vz**2 - h_speed_sym = sp.Matrix([sp.sqrt(speed)*odo_scale]) - - h_relative_motion = sp.Matrix(v) - h_phone_rot_sym = sp.Matrix([vroll, - vpitch, - vyaw]) - - - obs_eqs = [[h_speed_sym, ObservationKind.ODOMETRIC_SPEED, None], - [h_gyro_sym, ObservationKind.PHONE_GYRO, None], - [h_phone_rot_sym, ObservationKind.NO_ROT, None], - [h_relative_motion, ObservationKind.CAMERA_ODO_TRANSLATION, None], - [h_phone_rot_sym, ObservationKind.CAMERA_ODO_ROTATION, None]] - gen_code(name, f_sym, dt, state_sym, obs_eqs, dim_state, dim_state) diff --git a/selfdrive/locationd/locationd_local.py b/selfdrive/locationd/locationd_local.py deleted file mode 100755 index 0b1af2f4c15e35..00000000000000 --- a/selfdrive/locationd/locationd_local.py +++ /dev/null @@ -1,274 +0,0 @@ -#!/usr/bin/env python -import os -import zmq -import math -import json - -os.environ["OMP_NUM_THREADS"] = "1" -import numpy as np -from bisect import bisect_right - -from cereal import car -from common.params import Params -from common.numpy_fast import clip -import selfdrive.messaging as messaging -from selfdrive.swaglog import cloudlog -from selfdrive.controls.lib.vehicle_model import VehicleModel -from selfdrive.services import service_list -from selfdrive.locationd.kalman.loc_local_kf import LocLocalKalman -from selfdrive.locationd.kalman.kalman_helpers import ObservationKind - -DEBUG = False -kf = LocLocalKalman() # Make sure that model is generated on import time - -MAX_ANGLE_OFFSET = math.radians(10.) -MAX_ANGLE_OFFSET_TH = math.radians(9.) -MIN_STIFFNESS = 0.5 -MAX_STIFFNESS = 2.0 -MIN_SR = 0.5 -MAX_SR = 2.0 -MIN_SR_TH = 0.55 -MAX_SR_TH = 1.9 - -LEARNING_RATE = 3 - -class Localizer(object): - def __init__(self, disabled_logs=None, dog=None): - self.kf = LocLocalKalman() - self.reset_kalman() - - self.max_age = .2 # seconds - self.calibration_valid = False - - if disabled_logs is None: - self.disabled_logs = list() - else: - self.disabled_logs = disabled_logs - - def reset_kalman(self): - self.filter_time = None - self.observation_buffer = [] - self.converter = None - self.speed_counter = 0 - self.sensor_counter = 0 - - def liveLocationMsg(self, time): - fix = messaging.log.KalmanOdometry.new_message() - - predicted_state = self.kf.x - fix.trans = [float(predicted_state[0]), float(predicted_state[1]), float(predicted_state[2])] - fix.rot = [float(predicted_state[3]), float(predicted_state[4]), float(predicted_state[5])] - - return fix - - def update_kalman(self, time, kind, meas): - idx = bisect_right([x[0] for x in self.observation_buffer], time) - self.observation_buffer.insert(idx, (time, kind, meas)) - while self.observation_buffer[-1][0] - self.observation_buffer[0][0] > self.max_age: - self.kf.predict_and_observe(*self.observation_buffer.pop(0)) - - def handle_cam_odo(self, log, current_time): - self.update_kalman(current_time, ObservationKind.CAMERA_ODO_ROTATION, np.concatenate([log.cameraOdometry.rot, - log.cameraOdometry.rotStd])) - self.update_kalman(current_time, ObservationKind.CAMERA_ODO_TRANSLATION, np.concatenate([log.cameraOdometry.trans, - log.cameraOdometry.transStd])) - - def handle_car_state(self, log, current_time): - self.speed_counter += 1 - if self.speed_counter % 5 == 0: - self.update_kalman(current_time, ObservationKind.ODOMETRIC_SPEED, np.array([log.carState.vEgo])) - - def handle_sensors(self, log, current_time): - for sensor_reading in log.sensorEvents: - # TODO does not yet account for double sensor readings in the log - if sensor_reading.type == 4: - self.sensor_counter += 1 - if self.sensor_counter % LEARNING_RATE == 0: - self.update_kalman(current_time, ObservationKind.PHONE_GYRO, [-sensor_reading.gyro.v[2], -sensor_reading.gyro.v[1], -sensor_reading.gyro.v[0]]) - - def handle_log(self, log): - current_time = 1e-9 * log.logMonoTime - typ = log.which - if typ in self.disabled_logs: - return - if typ == "sensorEvents": - self.handle_sensors(log, current_time) - elif typ == "carState": - self.handle_car_state(log, current_time) - elif typ == "cameraOdometry": - self.handle_cam_odo(log, current_time) - - -class ParamsLearner(object): - def __init__(self, VM, angle_offset=0., stiffness_factor=1.0, steer_ratio=None, learning_rate=1.0): - self.VM = VM - - self.ao = math.radians(angle_offset) - self.slow_ao = math.radians(angle_offset) - self.x = stiffness_factor - self.sR = VM.sR if steer_ratio is None else steer_ratio - self.MIN_SR = MIN_SR * self.VM.sR - self.MAX_SR = MAX_SR * self.VM.sR - self.MIN_SR_TH = MIN_SR_TH * self.VM.sR - self.MAX_SR_TH = MAX_SR_TH * self.VM.sR - - self.alpha1 = 0.01 * learning_rate - self.alpha2 = 0.00025 * learning_rate - self.alpha3 = 0.1 * learning_rate - self.alpha4 = 1.0 * learning_rate - - def get_values(self): - return { - 'angleOffsetAverage': math.degrees(self.slow_ao), - 'stiffnessFactor': self.x, - 'steerRatio': self.sR, - } - - def update(self, psi, u, sa): - cF0 = self.VM.cF - cR0 = self.VM.cR - aR = self.VM.aR - aF = self.VM.aF - l = self.VM.l - m = self.VM.m - - x = self.x - ao = self.ao - sR = self.sR - - # Gradient descent: learn angle offset, tire stiffness and steer ratio. - if u > 10.0 and abs(math.degrees(sa)) < 15.: - self.ao -= self.alpha1 * 2.0*cF0*cR0*l*u*x*(1.0*cF0*cR0*l*u*x*(ao - sa) + psi*sR*(cF0*cR0*l**2*x - m*u**2*(aF*cF0 - aR*cR0)))/(sR**2*(cF0*cR0*l**2*x - m*u**2*(aF*cF0 - aR*cR0))**2) - - ao = self.slow_ao - self.slow_ao -= self.alpha2 * 2.0*cF0*cR0*l*u*x*(1.0*cF0*cR0*l*u*x*(ao - sa) + psi*sR*(cF0*cR0*l**2*x - m*u**2*(aF*cF0 - aR*cR0)))/(sR**2*(cF0*cR0*l**2*x - m*u**2*(aF*cF0 - aR*cR0))**2) - - self.x -= self.alpha3 * -2.0*cF0*cR0*l*m*u**3*(ao - sa)*(aF*cF0 - aR*cR0)*(1.0*cF0*cR0*l*u*x*(ao - sa) + psi*sR*(cF0*cR0*l**2*x - m*u**2*(aF*cF0 - aR*cR0)))/(sR**2*(cF0*cR0*l**2*x - m*u**2*(aF*cF0 - aR*cR0))**3) - - self.sR -= self.alpha4 * -2.0*cF0*cR0*l*u*x*(ao - sa)*(1.0*cF0*cR0*l*u*x*(ao - sa) + psi*sR*(cF0*cR0*l**2*x - m*u**2*(aF*cF0 - aR*cR0)))/(sR**3*(cF0*cR0*l**2*x - m*u**2*(aF*cF0 - aR*cR0))**2) - - if DEBUG: - # s1 = "Measured yaw rate % .6f" % psi - # ao = 0. - # s2 = "Uncompensated yaw % .6f" % (1.0*u*(-ao + sa)/(l*sR*(1 - m*u**2*(aF*cF0*x - aR*cR0*x)/(cF0*cR0*l**2*x**2)))) - # instant_ao = aF*m*psi*sR*u/(cR0*l*x) - aR*m*psi*sR*u/(cF0*l*x) - l*psi*sR/u + sa - s4 = "Instant AO: % .2f Avg. AO % .2f" % (math.degrees(self.ao), math.degrees(self.slow_ao)) - s5 = "Stiffnes: % .3f x" % self.x - print s4, s5 - - - self.ao = clip(self.ao, -MAX_ANGLE_OFFSET, MAX_ANGLE_OFFSET) - self.slow_ao = clip(self.slow_ao, -MAX_ANGLE_OFFSET, MAX_ANGLE_OFFSET) - self.x = clip(self.x, MIN_STIFFNESS, MAX_STIFFNESS) - self.sR = clip(self.sR, self.MIN_SR, self.MAX_SR) - - # don't check stiffness for validity, as it can change quickly if sR is off - valid = abs(self.slow_ao) < MAX_ANGLE_OFFSET_TH and \ - self.sR > self.MIN_SR_TH and self.sR < self.MAX_SR_TH - - return valid - - -def locationd_thread(gctx, addr, disabled_logs): - ctx = zmq.Context() - poller = zmq.Poller() - - car_state_socket = messaging.sub_sock(ctx, service_list['carState'].port, poller, addr=addr, conflate=True) - sensor_events_socket = messaging.sub_sock(ctx, service_list['sensorEvents'].port, poller, addr=addr, conflate=True) - camera_odometry_socket = messaging.sub_sock(ctx, service_list['cameraOdometry'].port, poller, addr=addr, conflate=True) - - kalman_odometry_socket = messaging.pub_sock(ctx, service_list['kalmanOdometry'].port) - live_parameters_socket = messaging.pub_sock(ctx, service_list['liveParameters'].port) - - params_reader = Params() - cloudlog.info("Parameter learner is waiting for CarParams") - CP = car.CarParams.from_bytes(params_reader.get("CarParams", block=True)) - VM = VehicleModel(CP) - cloudlog.info("Parameter learner got CarParams: %s" % CP.carFingerprint) - - params = params_reader.get("LiveParameters") - - # Check if car model matches - if params is not None: - params = json.loads(params) - if params.get('carFingerprint', None) != CP.carFingerprint: - cloudlog.info("Parameter learner found parameters for wrong car.") - params = None - - if params is None: - params = { - 'carFingerprint': CP.carFingerprint, - 'angleOffsetAverage': 0.0, - 'stiffnessFactor': 1.0, - 'steerRatio': VM.sR, - } - cloudlog.info("Parameter learner resetting to default values") - - cloudlog.info("Parameter starting with: %s" % str(params)) - localizer = Localizer(disabled_logs=disabled_logs) - - learner = ParamsLearner(VM, - angle_offset=params['angleOffsetAverage'], - stiffness_factor=params['stiffnessFactor'], - steer_ratio=params['steerRatio'], - learning_rate=LEARNING_RATE) - - i = 0 - while True: - for socket, event in poller.poll(timeout=1000): - log = messaging.recv_one(socket) - localizer.handle_log(log) - - if socket is car_state_socket: - if not localizer.kf.t: - continue - - if i % LEARNING_RATE == 0: - # carState is not updating the Kalman Filter, so update KF manually - localizer.kf.predict(1e-9 * log.logMonoTime) - - predicted_state = localizer.kf.x - yaw_rate = -float(predicted_state[5]) - - steering_angle = math.radians(log.carState.steeringAngle) - params_valid = learner.update(yaw_rate, log.carState.vEgo, steering_angle) - - params = messaging.new_message() - params.init('liveParameters') - params.liveParameters.valid = bool(params_valid) - params.liveParameters.angleOffset = float(math.degrees(learner.ao)) - params.liveParameters.angleOffsetAverage = float(math.degrees(learner.slow_ao)) - params.liveParameters.stiffnessFactor = float(learner.x) - params.liveParameters.steerRatio = float(learner.sR) - live_parameters_socket.send(params.to_bytes()) - - if i % 6000 == 0: # once a minute - params = learner.get_values() - params['carFingerprint'] = CP.carFingerprint - params_reader.put("LiveParameters", json.dumps(params)) - - i += 1 - elif socket is camera_odometry_socket: - msg = messaging.new_message() - msg.init('kalmanOdometry') - msg.logMonoTime = log.logMonoTime - msg.kalmanOdometry = localizer.liveLocationMsg(log.logMonoTime * 1e-9) - kalman_odometry_socket.send(msg.to_bytes()) - elif socket is sensor_events_socket: - pass - - -def main(gctx=None, addr="127.0.0.1"): - IN_CAR = os.getenv("IN_CAR", False) - disabled_logs = os.getenv("DISABLED_LOGS", "").split(",") - - # No speed for now - disabled_logs.append('carState') - if IN_CAR: - addr = "192.168.5.11" - - locationd_thread(gctx, addr, disabled_logs) - - -if __name__ == "__main__": - main() diff --git a/selfdrive/locationd/locationd_yawrate.cc b/selfdrive/locationd/locationd_yawrate.cc new file mode 100644 index 00000000000000..83c837d7fb1bba --- /dev/null +++ b/selfdrive/locationd/locationd_yawrate.cc @@ -0,0 +1,163 @@ +#include +#include + +#include +#include +#include + +#include "cereal/gen/cpp/log.capnp.h" + +#include "locationd_yawrate.h" + + +void Localizer::update_state(const Eigen::Matrix &C, const double R, double current_time, double meas) { + double dt = current_time - prev_update_time; + + if (dt < 0) { + dt = 0; + } else { + prev_update_time = current_time; + } + + x = A * x; + P = A * P * A.transpose() + dt * Q; + + double y = meas - C * x; + double S = R + C * P * C.transpose(); + Eigen::Vector4d K = P * C.transpose() * (1.0 / S); + x = x + K * y; + P = (I - K * C) * P; +} + +void Localizer::handle_sensor_events(capnp::List::Reader sensor_events, double current_time) { + for (cereal::SensorEventData::Reader sensor_event : sensor_events){ + if (sensor_event.getSensor() == 5 && sensor_event.getType() == 16) { + sensor_data_time = current_time; + double meas = -sensor_event.getGyroUncalibrated().getV()[0]; + update_state(C_gyro, R_gyro, current_time, meas); + } + } +} + +void Localizer::handle_camera_odometry(cereal::CameraOdometry::Reader camera_odometry, double current_time) { + double R = 100.0 * pow(camera_odometry.getRotStd()[2], 2); + double meas = camera_odometry.getRot()[2]; + update_state(C_posenet, R, current_time, meas); + + auto trans = camera_odometry.getTrans(); + posenet_speed = sqrt(trans[0]*trans[0] + trans[1]*trans[1] + trans[2]*trans[2]); + camera_odometry_time = current_time; +} + +void Localizer::handle_controls_state(cereal::ControlsState::Reader controls_state, double current_time) { + steering_angle = controls_state.getAngleSteers() * DEGREES_TO_RADIANS; + car_speed = controls_state.getVEgo(); + controls_state_time = current_time; +} + + +Localizer::Localizer() { + // States: [yaw rate, yaw rate diff, gyro bias, gyro bias diff] + A << + 1, 1, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 1, + 0, 0, 0, 1; + I << + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1; + + Q << + 0, 0, 0, 0, + 0, pow(0.1, 2.0), 0, 0, + 0, 0, 0, 0, + 0, 0, pow(0.0005 / 100.0, 2.0), 0; + P << + pow(100.0, 2.0), 0, 0, 0, + 0, pow(100.0, 2.0), 0, 0, + 0, 0, pow(100.0, 2.0), 0, + 0, 0, 0, pow(100.0, 2.0); + + C_posenet << 1, 0, 0, 0; + C_gyro << 1, 0, 1, 0; + x << 0, 0, 0, 0; + + R_gyro = pow(0.25, 2.0); +} + +void Localizer::handle_log(cereal::Event::Reader event) { + double current_time = event.getLogMonoTime() / 1.0e9; + + // Initialize update_time on first update + if (prev_update_time < 0) { + prev_update_time = current_time; + } + + auto type = event.which(); + switch(type) { + case cereal::Event::CONTROLS_STATE: + handle_controls_state(event.getControlsState(), current_time); + break; + case cereal::Event::CAMERA_ODOMETRY: + handle_camera_odometry(event.getCameraOdometry(), current_time); + break; + case cereal::Event::SENSOR_EVENTS: + handle_sensor_events(event.getSensorEvents(), current_time); + break; + default: + break; + } +} + + +extern "C" { + void *localizer_init(void) { + Localizer * localizer = new Localizer; + return (void*)localizer; + } + + void localizer_handle_log(void * localizer, const unsigned char * data, size_t len) { + const kj::ArrayPtr view((const capnp::word*)data, len); + capnp::FlatArrayMessageReader msg(view); + cereal::Event::Reader event = msg.getRoot(); + + Localizer * loc = (Localizer*) localizer; + loc->handle_log(event); + } + + double localizer_get_yaw(void * localizer) { + Localizer * loc = (Localizer*) localizer; + return loc->x[0]; + } + double localizer_get_bias(void * localizer) { + Localizer * loc = (Localizer*) localizer; + return loc->x[2]; + } + + double * localizer_get_state(void * localizer) { + Localizer * loc = (Localizer*) localizer; + return loc->x.data(); + } + + void localizer_set_state(void * localizer, double * state) { + Localizer * loc = (Localizer*) localizer; + memcpy(loc->x.data(), state, 4 * sizeof(double)); + } + + double localizer_get_t(void * localizer) { + Localizer * loc = (Localizer*) localizer; + return loc->prev_update_time; + } + + double * localizer_get_P(void * localizer) { + Localizer * loc = (Localizer*) localizer; + return loc->P.data(); + } + + void localizer_set_P(void * localizer, double * P) { + Localizer * loc = (Localizer*) localizer; + memcpy(loc->P.data(), P, 16 * sizeof(double)); + } +} diff --git a/selfdrive/locationd/locationd_yawrate.h b/selfdrive/locationd/locationd_yawrate.h new file mode 100644 index 00000000000000..9c6885241bf510 --- /dev/null +++ b/selfdrive/locationd/locationd_yawrate.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include "cereal/gen/cpp/log.capnp.h" + +#define DEGREES_TO_RADIANS 0.017453292519943295 + +class Localizer +{ + Eigen::Matrix4d A; + Eigen::Matrix4d I; + Eigen::Matrix4d Q; + Eigen::Matrix C_posenet; + Eigen::Matrix C_gyro; + + double R_gyro; + + void update_state(const Eigen::Matrix &C, const double R, double current_time, double meas); + void handle_sensor_events(capnp::List::Reader sensor_events, double current_time); + void handle_camera_odometry(cereal::CameraOdometry::Reader camera_odometry, double current_time); + void handle_controls_state(cereal::ControlsState::Reader controls_state, double current_time); + +public: + Eigen::Vector4d x; + Eigen::Matrix4d P; + double steering_angle = 0; + double car_speed = 0; + double posenet_speed = 0; + double prev_update_time = -1; + double controls_state_time = -1; + double sensor_data_time = -1; + double camera_odometry_time = -1; + + Localizer(); + void handle_log(cereal::Event::Reader event); + +}; diff --git a/selfdrive/locationd/params_learner.cc b/selfdrive/locationd/params_learner.cc new file mode 100644 index 00000000000000..66f378a1da281a --- /dev/null +++ b/selfdrive/locationd/params_learner.cc @@ -0,0 +1,118 @@ +#include +#include +#include + +#include +#include +#include "cereal/gen/cpp/log.capnp.h" +#include "cereal/gen/cpp/car.capnp.h" +#include "params_learner.h" + +// #define DEBUG + +template +T clip(const T& n, const T& lower, const T& upper) { + return std::max(lower, std::min(n, upper)); +} + +ParamsLearner::ParamsLearner(cereal::CarParams::Reader car_params, + double angle_offset, + double stiffness_factor, + double steer_ratio, + double learning_rate) : + ao(angle_offset * DEGREES_TO_RADIANS), + slow_ao(angle_offset * DEGREES_TO_RADIANS), + x(stiffness_factor), + sR(steer_ratio) { + + cF0 = car_params.getTireStiffnessFront(); + cR0 = car_params.getTireStiffnessRear(); + + l = car_params.getWheelbase(); + m = car_params.getMass(); + + aF = car_params.getCenterToFront(); + aR = l - aF; + + min_sr = MIN_SR * car_params.getSteerRatio(); + max_sr = MAX_SR * car_params.getSteerRatio(); + min_sr_th = MIN_SR_TH * car_params.getSteerRatio(); + max_sr_th = MAX_SR_TH * car_params.getSteerRatio(); + alpha1 = 0.01 * learning_rate; + alpha2 = 0.0005 * learning_rate; + alpha3 = 0.1 * learning_rate; + alpha4 = 1.0 * learning_rate; +} + +bool ParamsLearner::update(double psi, double u, double sa) { + if (u > 10.0 && fabs(sa) < (DEGREES_TO_RADIANS * 90.)) { + double ao_diff = 2.0*cF0*cR0*l*u*x*(1.0*cF0*cR0*l*u*x*(ao - sa) + psi*sR*(cF0*cR0*pow(l, 2)*x - m*pow(u, 2)*(aF*cF0 - aR*cR0)))/(pow(sR, 2)*pow(cF0*cR0*pow(l, 2)*x - m*pow(u, 2)*(aF*cF0 - aR*cR0), 2)); + double new_ao = ao - alpha1 * ao_diff; + + double slow_ao_diff = 2.0*cF0*cR0*l*u*x*(1.0*cF0*cR0*l*u*x*(slow_ao - sa) + psi*sR*(cF0*cR0*pow(l, 2)*x - m*pow(u, 2)*(aF*cF0 - aR*cR0)))/(pow(sR, 2)*pow(cF0*cR0*pow(l, 2)*x - m*pow(u, 2)*(aF*cF0 - aR*cR0), 2)); + double new_slow_ao = slow_ao - alpha2 * slow_ao_diff; + + double new_x = x - alpha3 * (-2.0*cF0*cR0*l*m*pow(u, 3)*(slow_ao - sa)*(aF*cF0 - aR*cR0)*(1.0*cF0*cR0*l*u*x*(slow_ao - sa) + psi*sR*(cF0*cR0*pow(l, 2)*x - m*pow(u, 2)*(aF*cF0 - aR*cR0)))/(pow(sR, 2)*pow(cF0*cR0*pow(l, 2)*x - m*pow(u, 2)*(aF*cF0 - aR*cR0), 3))); + double new_sR = sR - alpha4 * (-2.0*cF0*cR0*l*u*x*(slow_ao - sa)*(1.0*cF0*cR0*l*u*x*(slow_ao - sa) + psi*sR*(cF0*cR0*pow(l, 2)*x - m*pow(u, 2)*(aF*cF0 - aR*cR0)))/(pow(sR, 3)*pow(cF0*cR0*pow(l, 2)*x - m*pow(u, 2)*(aF*cF0 - aR*cR0), 2))); + + ao = new_ao; + slow_ao = new_slow_ao; + x = new_x; + sR = new_sR; + } + +#ifdef DEBUG + std::cout << "Instant AO: " << (RADIANS_TO_DEGREES * ao) << "\tAverage AO: " << (RADIANS_TO_DEGREES * slow_ao); + std::cout << "\tStiffness: " << x << "\t sR: " << sR << std::endl; +#endif + + ao = clip(ao, -MAX_ANGLE_OFFSET, MAX_ANGLE_OFFSET); + slow_ao = clip(slow_ao, -MAX_ANGLE_OFFSET, MAX_ANGLE_OFFSET); + x = clip(x, MIN_STIFFNESS, MAX_STIFFNESS); + sR = clip(sR, min_sr, max_sr); + + bool valid = fabs(slow_ao) < MAX_ANGLE_OFFSET_TH; + valid = valid && sR > min_sr_th; + valid = valid && sR < max_sr_th; + return valid; +} + + +extern "C" { + void *params_learner_init(size_t len, char * params, double angle_offset, double stiffness_factor, double steer_ratio, double learning_rate) { + + auto amsg = kj::heapArray((len / sizeof(capnp::word)) + 1); + memcpy(amsg.begin(), params, len); + + capnp::FlatArrayMessageReader cmsg(amsg); + cereal::CarParams::Reader car_params = cmsg.getRoot(); + + ParamsLearner * p = new ParamsLearner(car_params, angle_offset, stiffness_factor, steer_ratio, learning_rate); + return (void*)p; + } + + bool params_learner_update(void * params_learner, double psi, double u, double sa) { + ParamsLearner * p = (ParamsLearner*) params_learner; + return p->update(psi, u, sa); + } + + double params_learner_get_ao(void * params_learner){ + ParamsLearner * p = (ParamsLearner*) params_learner; + return p->ao; + } + + double params_learner_get_x(void * params_learner){ + ParamsLearner * p = (ParamsLearner*) params_learner; + return p->x; + } + + double params_learner_get_slow_ao(void * params_learner){ + ParamsLearner * p = (ParamsLearner*) params_learner; + return p->slow_ao; + } + + double params_learner_get_sR(void * params_learner){ + ParamsLearner * p = (ParamsLearner*) params_learner; + return p->sR; + } +} diff --git a/selfdrive/locationd/params_learner.h b/selfdrive/locationd/params_learner.h new file mode 100644 index 00000000000000..4d97551b3b3a70 --- /dev/null +++ b/selfdrive/locationd/params_learner.h @@ -0,0 +1,35 @@ +#pragma once + +#define DEGREES_TO_RADIANS 0.017453292519943295 +#define RADIANS_TO_DEGREES (1.0 / DEGREES_TO_RADIANS) + +#define MAX_ANGLE_OFFSET (10.0 * DEGREES_TO_RADIANS) +#define MAX_ANGLE_OFFSET_TH (9.0 * DEGREES_TO_RADIANS) +#define MIN_STIFFNESS 0.5 +#define MAX_STIFFNESS 2.0 +#define MIN_SR 0.5 +#define MAX_SR 2.0 +#define MIN_SR_TH 0.55 +#define MAX_SR_TH 1.9 + +class ParamsLearner { + double cF0, cR0; + double aR, aF; + double l, m; + + double min_sr, max_sr, min_sr_th, max_sr_th; + double alpha1, alpha2, alpha3, alpha4; + +public: + double ao; + double slow_ao; + double x, sR; + + ParamsLearner(cereal::CarParams::Reader car_params, + double angle_offset, + double stiffness_factor, + double steer_ratio, + double learning_rate); + + bool update(double psi, double u, double sa); +}; diff --git a/selfdrive/locationd/paramsd.cc b/selfdrive/locationd/paramsd.cc new file mode 100644 index 00000000000000..a38fc403ab4560 --- /dev/null +++ b/selfdrive/locationd/paramsd.cc @@ -0,0 +1,180 @@ +#include +#include +#include +#include +#include + + +#include +#include + +#include "json11.hpp" +#include "cereal/gen/cpp/log.capnp.h" + +#include "common/swaglog.h" +#include "common/messaging.h" +#include "common/params.h" +#include "common/timing.h" + +#include "messaging.hpp" +#include "locationd_yawrate.h" +#include "params_learner.h" + + +void sigpipe_handler(int sig) { + LOGE("SIGPIPE received"); +} + + +int main(int argc, char *argv[]) { + signal(SIGPIPE, (sighandler_t)sigpipe_handler); + + Context * c = Context::create(); + SubSocket * controls_state_sock = SubSocket::create(c, "controlsState"); + SubSocket * sensor_events_sock = SubSocket::create(c, "sensorEvents"); + SubSocket * camera_odometry_sock = SubSocket::create(c, "cameraOdometry"); + PubSocket * live_parameters_sock = PubSocket::create(c, "liveParameters"); + Poller * poller = Poller::create({controls_state_sock, sensor_events_sock, camera_odometry_sock}); + + Localizer localizer; + + // Read car params + char *value; + size_t value_sz = 0; + + LOGW("waiting for params to set vehicle model"); + while (true) { + read_db_value(NULL, "CarParams", &value, &value_sz); + if (value_sz > 0) break; + usleep(100*1000); + } + LOGW("got %d bytes CarParams", value_sz); + + // make copy due to alignment issues + auto amsg = kj::heapArray((value_sz / sizeof(capnp::word)) + 1); + memcpy(amsg.begin(), value, value_sz); + free(value); + + capnp::FlatArrayMessageReader cmsg(amsg); + cereal::CarParams::Reader car_params = cmsg.getRoot(); + + // Read params from previous run + const int result = read_db_value(NULL, "LiveParameters", &value, &value_sz); + + std::string fingerprint = car_params.getCarFingerprint(); + std::string vin = car_params.getCarVin(); + double sR = car_params.getSteerRatio(); + double x = 1.0; + double ao = 0.0; + double posenet_invalid_count = 0; + + if (result == 0){ + auto str = std::string(value, value_sz); + free(value); + + std::string err; + auto json = json11::Json::parse(str, err); + if (json.is_null() || !err.empty()) { + std::string log = "Error parsing json: " + err; + LOGW(log.c_str()); + } else { + std::string new_fingerprint = json["carFingerprint"].string_value(); + std::string new_vin = json["carVin"].string_value(); + + if (fingerprint == new_fingerprint && vin == new_vin) { + std::string log = "Parameter starting with: " + str; + LOGW(log.c_str()); + + sR = json["steerRatio"].number_value(); + x = json["stiffnessFactor"].number_value(); + ao = json["angleOffsetAverage"].number_value(); + } + } + } + + ParamsLearner learner(car_params, ao, x, sR, 1.0); + + // Main loop + int save_counter = 0; + while (true){ + for (auto s : poller->poll(-1)){ + Message * msg = s->receive(); + + auto amsg = kj::heapArray((msg->getSize() / sizeof(capnp::word)) + 1); + memcpy(amsg.begin(), msg->getData(), msg->getSize()); + + capnp::FlatArrayMessageReader capnp_msg(amsg); + cereal::Event::Reader event = capnp_msg.getRoot(); + + localizer.handle_log(event); + + auto which = event.which(); + // Throw vision failure if posenet and odometric speed too different + if (which == cereal::Event::CAMERA_ODOMETRY){ + if (std::abs(localizer.posenet_speed - localizer.car_speed) > std::max(0.4 * localizer.car_speed, 5.0)) { + posenet_invalid_count++; + } else { + posenet_invalid_count = 0; + } + } else if (which == cereal::Event::CONTROLS_STATE){ + save_counter++; + + double yaw_rate = -localizer.x[0]; + bool valid = learner.update(yaw_rate, localizer.car_speed, localizer.steering_angle); + + // TODO: Fix in replay + double sensor_data_age = localizer.controls_state_time - localizer.sensor_data_time; + double camera_odometry_age = localizer.controls_state_time - localizer.camera_odometry_time; + + double angle_offset_degrees = RADIANS_TO_DEGREES * learner.ao; + double angle_offset_average_degrees = RADIANS_TO_DEGREES * learner.slow_ao; + + capnp::MallocMessageBuilder msg; + cereal::Event::Builder event = msg.initRoot(); + event.setLogMonoTime(nanos_since_boot()); + auto live_params = event.initLiveParameters(); + live_params.setValid(valid); + live_params.setYawRate(localizer.x[0]); + live_params.setGyroBias(localizer.x[2]); + live_params.setSensorValid(sensor_data_age < 5.0); + live_params.setAngleOffset(angle_offset_degrees); + live_params.setAngleOffsetAverage(angle_offset_average_degrees); + live_params.setStiffnessFactor(learner.x); + live_params.setSteerRatio(learner.sR); + live_params.setPosenetSpeed(localizer.posenet_speed); + live_params.setPosenetValid((posenet_invalid_count < 4) && (camera_odometry_age < 5.0)); + + auto words = capnp::messageToFlatArray(msg); + auto bytes = words.asBytes(); + live_parameters_sock->send((char*)bytes.begin(), bytes.size()); + + // Save parameters every minute + if (save_counter % 6000 == 0) { + json11::Json json = json11::Json::object { + {"carVin", vin}, + {"carFingerprint", fingerprint}, + {"steerRatio", learner.sR}, + {"stiffnessFactor", learner.x}, + {"angleOffsetAverage", angle_offset_average_degrees}, + }; + + std::string out = json.dump(); + std::async(std::launch::async, + [out]{ + write_db_value(NULL, "LiveParameters", out.c_str(), out.length()); + }); + } + } + delete msg; + } + } + + delete live_parameters_sock; + delete controls_state_sock; + delete camera_odometry_sock; + delete sensor_events_sock; + delete poller; + delete c; + + return 0; +} diff --git a/selfdrive/locationd/kalman/__init__.py b/selfdrive/locationd/test/__init__.py similarity index 100% rename from selfdrive/locationd/kalman/__init__.py rename to selfdrive/locationd/test/__init__.py diff --git a/selfdrive/locationd/test/ci_test.py b/selfdrive/locationd/test/ci_test.py new file mode 100755 index 00000000000000..847dcf635f55c7 --- /dev/null +++ b/selfdrive/locationd/test/ci_test.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +import subprocess +import os +import sys +import argparse +import tempfile + +from selfdrive.locationd.test.ubloxd_py_test import parser_test +from selfdrive.locationd.test.ubloxd_regression_test import compare_results + + +def mkdirs_exists_ok(path): + try: + os.makedirs(path) + except OSError: + if not os.path.isdir(path): + raise + + +def main(args): + cur_dir = os.path.dirname(os.path.realpath(__file__)) + ubloxd_dir = os.path.join(cur_dir, '../') + + cc_output_dir = os.path.join(args.output_dir, 'cc') + mkdirs_exists_ok(cc_output_dir) + + py_output_dir = os.path.join(args.output_dir, 'py') + mkdirs_exists_ok(py_output_dir) + + archive_file = os.path.join(cur_dir, args.stream_gz_file) + + try: + print('Extracting stream file') + subprocess.check_call(['tar', 'zxf', archive_file], cwd=tempfile.gettempdir()) + stream_file_path = os.path.join(tempfile.gettempdir(), 'ubloxRaw.stream') + + if not os.path.isfile(stream_file_path): + print('Extract file failed') + sys.exit(-3) + + print('Compiling test app...') + subprocess.check_call(["make", "ubloxd_test"], cwd=ubloxd_dir) + + print('Run regression test - CC parser...') + if args.valgrind: + subprocess.check_call(["valgrind", "--leak-check=full", os.path.join(ubloxd_dir, 'ubloxd_test'), stream_file_path, cc_output_dir]) + else: + subprocess.check_call([os.path.join(ubloxd_dir, 'ubloxd_test'), stream_file_path, cc_output_dir]) + + print('Running regression test - py parser...') + parser_test(stream_file_path, py_output_dir) + + print('Running regression test - compare result...') + r = compare_results(cc_output_dir, py_output_dir) + + print('All done!') + + subprocess.check_call(["rm", stream_file_path]) + subprocess.check_call(["rm", '-rf', cc_output_dir]) + subprocess.check_call(["rm", '-rf', py_output_dir]) + sys.exit(r) + + except subprocess.CalledProcessError as e: + print('CI test failed with {}'.format(e.returncode)) + sys.exit(e.returncode) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Ubloxd CI test", + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + + parser.add_argument("stream_gz_file", nargs='?', default='ubloxRaw.tar.gz', + help="UbloxRaw data stream zip file") + + parser.add_argument("output_dir", nargs='?', default='out', + help="Output events temp directory") + + parser.add_argument("--valgrind", default=False, action='store_true', + help="Run in valgrind") + + args = parser.parse_args() + main(args) diff --git a/selfdrive/locationd/ephemeris.py b/selfdrive/locationd/test/ephemeris.py similarity index 100% rename from selfdrive/locationd/ephemeris.py rename to selfdrive/locationd/test/ephemeris.py diff --git a/selfdrive/locationd/test/test_params_learner.py b/selfdrive/locationd/test/test_params_learner.py new file mode 100755 index 00000000000000..c1b75c5af95970 --- /dev/null +++ b/selfdrive/locationd/test/test_params_learner.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 + +import numpy as np +import unittest + +from selfdrive.car.honda.interface import CarInterface +from selfdrive.car.honda.values import CAR +from selfdrive.controls.lib.vehicle_model import VehicleModel +from selfdrive.locationd.liblocationd_py import liblocationd # pylint: disable=no-name-in-module, import-error + + +class TestParamsLearner(unittest.TestCase): + def setUp(self): + + self.CP = CarInterface.get_params(CAR.CIVIC) + bts = self.CP.to_bytes() + + self.params_learner = liblocationd.params_learner_init(len(bts), bts, 0.0, 1.0, self.CP.steerRatio, 1.0) + + def test_convergence(self): + # Setup vehicle model with wrong parameters + VM_sim = VehicleModel(self.CP) + x_target = 0.75 + sr_target = self.CP.steerRatio - 0.5 + ao_target = -1.0 + VM_sim.update_params(x_target, sr_target) + + # Run simulation + times = np.arange(0, 15*3600, 0.01) + angle_offset = np.radians(ao_target) + steering_angles = np.radians(10 * np.sin(2 * np.pi * times / 100.)) + angle_offset + speeds = 10 * np.sin(2 * np.pi * times / 1000.) + 25 + + for i, t in enumerate(times): + u = speeds[i] + sa = steering_angles[i] + psi = VM_sim.yaw_rate(sa - angle_offset, u) + liblocationd.params_learner_update(self.params_learner, psi, u, sa) + + # Verify learned parameters + sr = liblocationd.params_learner_get_sR(self.params_learner) + ao_slow = np.degrees(liblocationd.params_learner_get_slow_ao(self.params_learner)) + x = liblocationd.params_learner_get_x(self.params_learner) + self.assertAlmostEqual(x_target, x, places=1) + self.assertAlmostEqual(ao_target, ao_slow, places=1) + self.assertAlmostEqual(sr_target, sr, places=1) + + + + + +if __name__ == "__main__": + unittest.main() diff --git a/selfdrive/locationd/ublox.py b/selfdrive/locationd/test/ublox.py similarity index 98% rename from selfdrive/locationd/ublox.py rename to selfdrive/locationd/test/ublox.py index 70e2d2fa0d7033..c7a2adf08ec7a8 100644 --- a/selfdrive/locationd/ublox.py +++ b/selfdrive/locationd/test/ublox.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 ''' UBlox binary protocol handling @@ -10,6 +10,7 @@ for ublox version 8, not all functions may work. ''' + import struct import time, os @@ -184,7 +185,7 @@ def __getattr__(self, name): raise AttributeError(name) def __setattr__(self, name, value): - if self.__dict__.has_key(name): + if name in self.__dict__: # allow set on normal attributes dict.__setattr__(self, name, value) else: @@ -256,7 +257,7 @@ def unpack(self, msg): break if self.count_field == '_remaining': - count = len(buf) / struct.calcsize(self.format2) + count = len(buf) // struct.calcsize(self.format2) if count == 0: msg._unpacked = True @@ -534,7 +535,7 @@ class UBloxMessage: '''UBlox message class - holds a UBX binary message''' def __init__(self): - self._buf = "" + self._buf = b"" self._fields = {} self._recs = [] self._unpacked = False @@ -613,11 +614,11 @@ def name(self): def msg_class(self): '''return the message class''' - return ord(self._buf[2]) + return self._buf[2] def msg_id(self): '''return the message id within the class''' - return ord(self._buf[3]) + return self._buf[3] def msg_type(self): '''return the message type tuple (class, id)''' @@ -630,9 +631,9 @@ def msg_length(self): def valid_so_far(self): '''check if the message is valid so far''' - if len(self._buf) > 0 and ord(self._buf[0]) != PREAMBLE1: + if len(self._buf) > 0 and self._buf[0] != PREAMBLE1: return False - if len(self._buf) > 1 and ord(self._buf[1]) != PREAMBLE2: + if len(self._buf) > 1 and self._buf[1] != PREAMBLE2: self.debug(1, "bad pre2") return False if self.needed_bytes() == 0 and not self.valid(): @@ -661,7 +662,7 @@ def checksum(self, data=None): ck_a = 0 ck_b = 0 for i in data: - ck_a = (ck_a + ord(i)) & 0xFF + ck_a = (ck_a + i) & 0xFF ck_b = (ck_b + ck_a) & 0xFF return (ck_a, ck_b) @@ -713,20 +714,17 @@ def __init__(self, port, baudrate=115200, timeout=0, panda=False, grey=False): self.dev = PandaSerial(self.panda, 1, self.baudrate) self.baudrate = 460800 - print "upping baud:",self.baudrate + print("upping baud:",self.baudrate) self.send_nmea("$PUBX,41,1,0007,0003,%u,0" % self.baudrate) time.sleep(0.1) self.dev = PandaSerial(self.panda, 1, self.baudrate) elif grey: - import zmq - from selfdrive.services import service_list import selfdrive.messaging as messaging - class BoarddSerial(object): + class BoarddSerial(): def __init__(self): - context = zmq.Context() - self.ubloxRaw = messaging.sub_sock(context, service_list['ubloxRaw'].port) + self.ubloxRaw = messaging.sub_sock('ubloxRaw') self.buf = "" def read(self, n): diff --git a/selfdrive/locationd/ubloxd.py b/selfdrive/locationd/test/ubloxd.py similarity index 95% rename from selfdrive/locationd/ubloxd.py rename to selfdrive/locationd/test/ubloxd.py index 4cc2a294955b78..91c57119583e9c 100755 --- a/selfdrive/locationd/ubloxd.py +++ b/selfdrive/locationd/test/ubloxd.py @@ -1,17 +1,16 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 + import os import serial -import ublox +from selfdrive.locationd.test import ublox import time import datetime import struct import sys from cereal import log from common import realtime -import zmq import selfdrive.messaging as messaging -from selfdrive.services import service_list -from ephemeris import EphemerisData, GET_FIELD_U +from selfdrive.locationd.test.ephemeris import EphemerisData, GET_FIELD_U panda = os.getenv("PANDA") is not None # panda directly connected grey = not (os.getenv("EVAL") is not None) # panda through boardd @@ -211,7 +210,7 @@ def gen_raw(msg): cnos = {} for meas in measurements_parsed: cnos[meas['svId']] = meas['cno'] - print 'Carrier to noise ratio for each sat: \n', cnos, '\n' + print('Carrier to noise ratio for each sat: \n', cnos, '\n') receiverStatus_bools = int_to_bool_list(msg_meta_data['recStat']) receiverStatus = {'leapSecValid': receiverStatus_bools[0], 'clkReset': receiverStatus_bools[2]} @@ -255,7 +254,7 @@ def handle_msg(dev, msg, nav_frame_buffer): ubloxGnss.send(nav.to_bytes()) else: - print "UNKNNOWN MESSAGE:", msg.name() + print("UNKNNOWN MESSAGE:", msg.name()) except ublox.UBloxError as e: print(e) @@ -266,13 +265,12 @@ def main(gctx=None): global gpsLocationExternal, ubloxGnss nav_frame_buffer = {} nav_frame_buffer[0] = {} - for i in xrange(1,33): + for i in range(1,33): nav_frame_buffer[0][i] = {} - context = zmq.Context() - gpsLocationExternal = messaging.pub_sock(context, service_list['gpsLocationExternal'].port) - ubloxGnss = messaging.pub_sock(context, service_list['ubloxGnss'].port) + gpsLocationExternal = messaging.pub_sock('gpsLocationExternal') + ubloxGnss = messaging.pub_sock('ubloxGnss') dev = init_reader() while True: diff --git a/selfdrive/locationd/test/ubloxd_easy.py b/selfdrive/locationd/test/ubloxd_easy.py new file mode 100755 index 00000000000000..0753789fbad974 --- /dev/null +++ b/selfdrive/locationd/test/ubloxd_easy.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 + +import os +from selfdrive.locationd.test import ublox +from common import realtime +from selfdrive.locationd.test.ubloxd import gen_raw, gen_solution +import zmq +import selfdrive.messaging as messaging + + +unlogger = os.getenv("UNLOGGER") is not None # debug prints + +def main(gctx=None): + poller = zmq.Poller() + + gpsLocationExternal = messaging.pub_sock('gpsLocationExternal') + ubloxGnss = messaging.pub_sock('ubloxGnss') + + # ubloxRaw = messaging.sub_sock('ubloxRaw', poller) + + # buffer with all the messages that still need to be input into the kalman + while 1: + polld = poller.poll(timeout=1000) + for sock, mode in polld: + if mode != zmq.POLLIN: + continue + logs = messaging.drain_sock(sock) + for log in logs: + buff = log.ubloxRaw + time = log.logMonoTime + msg = ublox.UBloxMessage() + msg.add(buff) + if msg.valid(): + if msg.name() == 'NAV_PVT': + sol = gen_solution(msg) + if unlogger: + sol.logMonoTime = time + else: + sol.logMonoTime = int(realtime.sec_since_boot() * 1e9) + gpsLocationExternal.send(sol.to_bytes()) + elif msg.name() == 'RXM_RAW': + raw = gen_raw(msg) + if unlogger: + raw.logMonoTime = time + else: + raw.logMonoTime = int(realtime.sec_since_boot() * 1e9) + ubloxGnss.send(raw.to_bytes()) + else: + print("INVALID MESSAGE") + + +if __name__ == "__main__": + main() diff --git a/selfdrive/locationd/test/ubloxd_py_test.py b/selfdrive/locationd/test/ubloxd_py_test.py new file mode 100755 index 00000000000000..bca9ddc421564d --- /dev/null +++ b/selfdrive/locationd/test/ubloxd_py_test.py @@ -0,0 +1,77 @@ +import sys +import os + +from selfdrive.locationd.test.ublox import UBloxMessage +from selfdrive.locationd.test.ubloxd import gen_solution, gen_raw, gen_nav_data +from common import realtime + + +def mkdirs_exists_ok(path): + try: + os.makedirs(path) + except OSError: + if not os.path.isdir(path): + raise + + +def parser_test(fn, prefix): + nav_frame_buffer = {} + nav_frame_buffer[0] = {} + for i in range(1, 33): + nav_frame_buffer[0][i] = {} + + if not os.path.exists(prefix): + print('Prefix invalid') + sys.exit(-1) + + with open(fn, 'rb') as f: + i = 0 + saved_i = 0 + msg = UBloxMessage() + while True: + n = msg.needed_bytes() + b = f.read(n) + if not b: + break + msg.add(b) + if msg.valid(): + i += 1 + if msg.name() == 'NAV_PVT': + sol = gen_solution(msg) + sol.logMonoTime = int(realtime.sec_since_boot() * 1e9) + with open(os.path.join(prefix, str(saved_i)), 'wb') as f1: + f1.write(sol.to_bytes()) + saved_i += 1 + elif msg.name() == 'RXM_RAW': + raw = gen_raw(msg) + raw.logMonoTime = int(realtime.sec_since_boot() * 1e9) + with open(os.path.join(prefix, str(saved_i)), 'wb') as f1: + f1.write(raw.to_bytes()) + saved_i += 1 + elif msg.name() == 'RXM_SFRBX': + nav = gen_nav_data(msg, nav_frame_buffer) + if nav is not None: + nav.logMonoTime = int(realtime.sec_since_boot() * 1e9) + with open(os.path.join(prefix, str(saved_i)), 'wb') as f1: + f1.write(nav.to_bytes()) + saved_i += 1 + + msg = UBloxMessage() + msg.debug_level = 0 + print('Parsed {} msgs'.format(i)) + print('Generated {} cereal events'.format(saved_i)) + + +if __name__ == "__main__": + if len(sys.argv) < 3: + print('Format: ubloxd_py_test.py file_path prefix') + sys.exit(0) + + fn = sys.argv[1] + if not os.path.isfile(fn): + print('File path invalid') + sys.exit(0) + + prefix = sys.argv[2] + mkdirs_exists_ok(prefix) + parser_test(fn, prefix) diff --git a/selfdrive/locationd/test/ubloxd_regression_test.py b/selfdrive/locationd/test/ubloxd_regression_test.py new file mode 100644 index 00000000000000..29210bf545cd55 --- /dev/null +++ b/selfdrive/locationd/test/ubloxd_regression_test.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +import os +import sys +import argparse + +from cereal import log +from common.basedir import BASEDIR +os.environ['BASEDIR'] = BASEDIR + + +def get_arg_parser(): + parser = argparse.ArgumentParser( + description="Compare two result files", + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + + parser.add_argument("dir1", nargs='?', default='/data/ubloxdc', + help="Directory path 1 from which events are loaded") + + parser.add_argument("dir2", nargs='?', default='/data/ubloxdpy', + help="Directory path 2 from which msgs are loaded") + + return parser + + +def read_file(fn): + with open(fn, 'rb') as f: + return f.read() + + +def compare_results(dir1, dir2): + onlyfiles1 = [f for f in os.listdir(dir1) if os.path.isfile(os.path.join(dir1, f))] + onlyfiles1.sort() + + onlyfiles2 = [f for f in os.listdir(dir2) if os.path.isfile(os.path.join(dir2, f))] + onlyfiles2.sort() + + if len(onlyfiles1) != len(onlyfiles2): + print('len mismatch: {} != {}'.format(len(onlyfiles1), len(onlyfiles2))) + return -1 + events1 = [log.Event.from_bytes(read_file(os.path.join(dir1, f))) for f in onlyfiles1] + events2 = [log.Event.from_bytes(read_file(os.path.join(dir2, f))) for f in onlyfiles2] + + for i in range(len(events1)): + if events1[i].which() != events2[i].which(): + print('event {} type mismatch: {} != {}'.format(i, events1[i].which(), events2[i].which())) + return -2 + if events1[i].which() == 'gpsLocationExternal': + old_gps = events1[i].gpsLocationExternal + gps = events2[i].gpsLocationExternal + # print(gps, old_gps) + attrs = ['flags', 'latitude', 'longitude', 'altitude', 'speed', 'bearing', + 'accuracy', 'timestamp', 'source', 'vNED', 'verticalAccuracy', 'bearingAccuracy', 'speedAccuracy'] + for attr in attrs: + o = getattr(old_gps, attr) + n = getattr(gps, attr) + if attr == 'vNED': + if len(o) != len(n): + print('Gps vNED len mismatch', o, n) + return -3 + else: + for i in range(len(o)): + if abs(o[i] - n[i]) > 1e-3: + print('Gps vNED mismatch', o, n) + return + elif o != n: + print('Gps mismatch', attr, o, n) + return -4 + elif events1[i].which() == 'ubloxGnss': + old_gnss = events1[i].ubloxGnss + gnss = events2[i].ubloxGnss + if old_gnss.which() == 'measurementReport' and gnss.which() == 'measurementReport': + attrs = ['gpsWeek', 'leapSeconds', 'measurements', 'numMeas', 'rcvTow', 'receiverStatus', 'schema'] + for attr in attrs: + o = getattr(old_gnss.measurementReport, attr) + n = getattr(gnss.measurementReport, attr) + if str(o) != str(n): + print('measurementReport {} mismatched'.format(attr)) + return -5 + if not (str(old_gnss.measurementReport) == str(gnss.measurementReport)): + print('Gnss measurementReport mismatched!') + print('gnss measurementReport old', old_gnss.measurementReport.measurements) + print('gnss measurementReport new', gnss.measurementReport.measurements) + return -6 + elif old_gnss.which() == 'ephemeris' and gnss.which() == 'ephemeris': + if not (str(old_gnss.ephemeris) == str(gnss.ephemeris)): + print('Gnss ephemeris mismatched!') + print('gnss ephemeris old', old_gnss.ephemeris) + print('gnss ephemeris new', gnss.ephemeris) + return -7 + print('All {} events matched!'.format(len(events1))) + return 0 + + +if __name__ == "__main__": + args = get_arg_parser().parse_args(sys.argv[1:]) + compare_results(args.dir1, args.dir2) diff --git a/selfdrive/locationd/ublox_msg.cc b/selfdrive/locationd/ublox_msg.cc new file mode 100644 index 00000000000000..ae78eb719222e5 --- /dev/null +++ b/selfdrive/locationd/ublox_msg.cc @@ -0,0 +1,374 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "cereal/gen/cpp/log.capnp.h" + +#include "common/params.h" +#include "common/swaglog.h" +#include "common/timing.h" + +#include "ublox_msg.h" + +#define UBLOX_MSG_SIZE(hdr) (*(uint16_t *)&hdr[4]) +#define GET_FIELD_U(w, nb, pos) (((w) >> (pos)) & ((1<<(nb))-1)) + +namespace ublox { + +inline int twos_complement(uint32_t v, uint32_t nb) { + int sign = v >> (nb - 1); + int value = v; + if(sign != 0) + value = value - (1 << nb); + return value; +} + +inline int GET_FIELD_S(uint32_t w, uint32_t nb, uint32_t pos) { + int v = GET_FIELD_U(w, nb, pos); + return twos_complement(v, nb); +} + +class EphemerisData { + public: + EphemerisData(uint8_t svId, subframes_map subframes) { + this->svId = svId; + int week_no = GET_FIELD_U(subframes[1][2+0], 10, 20); + int t_gd = GET_FIELD_S(subframes[1][2+4], 8, 6); + int iodc = (GET_FIELD_U(subframes[1][2+0], 2, 6) << 8) | GET_FIELD_U( + subframes[1][2+5], 8, 22); + + int t_oc = GET_FIELD_U(subframes[1][2+5], 16, 6); + int a_f2 = GET_FIELD_S(subframes[1][2+6], 8, 22); + int a_f1 = GET_FIELD_S(subframes[1][2+6], 16, 6); + int a_f0 = GET_FIELD_S(subframes[1][2+7], 22, 8); + + int c_rs = GET_FIELD_S(subframes[2][2+0], 16, 6); + int delta_n = GET_FIELD_S(subframes[2][2+1], 16, 14); + int m_0 = (GET_FIELD_S(subframes[2][2+1], 8, 6) << 24) | GET_FIELD_U( + subframes[2][2+2], 24, 6); + int c_uc = GET_FIELD_S(subframes[2][2+3], 16, 14); + int e = (GET_FIELD_U(subframes[2][2+3], 8, 6) << 24) | GET_FIELD_U(subframes[2][2+4], 24, 6); + int c_us = GET_FIELD_S(subframes[2][2+5], 16, 14); + uint32_t a_powhalf = (GET_FIELD_U(subframes[2][2+5], 8, 6) << 24) | GET_FIELD_U( + subframes[2][2+6], 24, 6); + int t_oe = GET_FIELD_U(subframes[2][2+7], 16, 14); + + int c_ic = GET_FIELD_S(subframes[3][2+0], 16, 14); + int omega_0 = (GET_FIELD_S(subframes[3][2+0], 8, 6) << 24) | GET_FIELD_U( + subframes[3][2+1], 24, 6); + int c_is = GET_FIELD_S(subframes[3][2+2], 16, 14); + int i_0 = (GET_FIELD_S(subframes[3][2+2], 8, 6) << 24) | GET_FIELD_U( + subframes[3][2+3], 24, 6); + int c_rc = GET_FIELD_S(subframes[3][2+4], 16, 14); + int w = (GET_FIELD_S(subframes[3][2+4], 8, 6) << 24) | GET_FIELD_U(subframes[3][5], 24, 6); + int omega_dot = GET_FIELD_S(subframes[3][2+6], 24, 6); + int idot = GET_FIELD_S(subframes[3][2+7], 14, 8); + + this->_rsvd1 = GET_FIELD_U(subframes[1][2+1], 23, 6); + this->_rsvd2 = GET_FIELD_U(subframes[1][2+2], 24, 6); + this->_rsvd3 = GET_FIELD_U(subframes[1][2+3], 24, 6); + this->_rsvd4 = GET_FIELD_U(subframes[1][2+4], 16, 14); + this->aodo = GET_FIELD_U(subframes[2][2+7], 5, 8); + + double gpsPi = 3.1415926535898; + + // now form variables in radians, meters and seconds etc + this->Tgd = t_gd * pow(2, -31); + this->A = pow(a_powhalf * pow(2, -19), 2.0); + this->cic = c_ic * pow(2, -29); + this->cis = c_is * pow(2, -29); + this->crc = c_rc * pow(2, -5); + this->crs = c_rs * pow(2, -5); + this->cuc = c_uc * pow(2, -29); + this->cus = c_us * pow(2, -29); + this->deltaN = delta_n * pow(2, -43) * gpsPi; + this->ecc = e * pow(2, -33); + this->i0 = i_0 * pow(2, -31) * gpsPi; + this->idot = idot * pow(2, -43) * gpsPi; + this->M0 = m_0 * pow(2, -31) * gpsPi; + this->omega = w * pow(2, -31) * gpsPi; + this->omega_dot = omega_dot * pow(2, -43) * gpsPi; + this->omega0 = omega_0 * pow(2, -31) * gpsPi; + this->toe = t_oe * pow(2, 4); + + this->toc = t_oc * pow(2, 4); + this->gpsWeek = week_no; + this->af0 = a_f0 * pow(2, -31); + this->af1 = a_f1 * pow(2, -43); + this->af2 = a_f2 * pow(2, -55); + + uint32_t iode1 = GET_FIELD_U(subframes[2][2+0], 8, 22); + uint32_t iode2 = GET_FIELD_U(subframes[3][2+7], 8, 22); + this->valid = (iode1 == iode2) && (iode1 == (iodc & 0xff)); + this->iode = iode1; + + if (GET_FIELD_U(subframes[4][2+0], 6, 22) == 56 && + GET_FIELD_U(subframes[4][2+0], 2, 28) == 1 && + GET_FIELD_U(subframes[5][2+0], 2, 28) == 1) { + double a0 = GET_FIELD_S(subframes[4][2], 8, 14) * pow(2, -30); + double a1 = GET_FIELD_S(subframes[4][2], 8, 6) * pow(2, -27); + double a2 = GET_FIELD_S(subframes[4][3], 8, 22) * pow(2, -24); + double a3 = GET_FIELD_S(subframes[4][3], 8, 14) * pow(2, -24); + double b0 = GET_FIELD_S(subframes[4][3], 8, 6) * pow(2, 11); + double b1 = GET_FIELD_S(subframes[4][4], 8, 22) * pow(2, 14); + double b2 = GET_FIELD_S(subframes[4][4], 8, 14) * pow(2, 16); + double b3 = GET_FIELD_S(subframes[4][4], 8, 6) * pow(2, 16); + this->ionoAlpha[0] = a0;this->ionoAlpha[1] = a1;this->ionoAlpha[2] = a2;this->ionoAlpha[3] = a3; + this->ionoBeta[0] = b0;this->ionoBeta[1] = b1;this->ionoBeta[2] = b2;this->ionoBeta[3] = b3; + this->ionoCoeffsValid = true; + } else { + this->ionoCoeffsValid = false; + } + } + uint16_t svId; + double Tgd, A, cic, cis, crc, crs, cuc, cus, deltaN, ecc, i0, idot, M0, omega, omega_dot, omega0, toe, toc; + uint32_t gpsWeek, iode, _rsvd1, _rsvd2, _rsvd3, _rsvd4, aodo; + double af0, af1, af2; + bool valid; + double ionoAlpha[4], ionoBeta[4]; + bool ionoCoeffsValid; +}; + +UbloxMsgParser::UbloxMsgParser() :bytes_in_parse_buf(0) { + nav_frame_buffer[0U] = std::map(); + for(int i = 1;i < 33;i++) + nav_frame_buffer[0U][i] = subframes_map(); +} + +inline int UbloxMsgParser::needed_bytes() { + // Msg header incomplete? + if(bytes_in_parse_buf < UBLOX_HEADER_SIZE) + return UBLOX_HEADER_SIZE + UBLOX_CHECKSUM_SIZE - bytes_in_parse_buf; + uint16_t needed = UBLOX_MSG_SIZE(msg_parse_buf) + UBLOX_HEADER_SIZE + UBLOX_CHECKSUM_SIZE; + // too much data + if(needed < (uint16_t)bytes_in_parse_buf) + return -1; + return needed - (uint16_t)bytes_in_parse_buf; +} + +inline bool UbloxMsgParser::valid_cheksum() { + uint8_t ck_a = 0, ck_b = 0; + for(int i = 2; i < bytes_in_parse_buf - UBLOX_CHECKSUM_SIZE;i++) { + ck_a = (ck_a + msg_parse_buf[i]) & 0xFF; + ck_b = (ck_b + ck_a) & 0xFF; + } + if(ck_a != msg_parse_buf[bytes_in_parse_buf - 2]) { + LOGD("Checksum a mismtach: %02X, %02X", ck_a, msg_parse_buf[6]); + return false; + } + if(ck_b != msg_parse_buf[bytes_in_parse_buf - 1]) { + LOGD("Checksum b mismtach: %02X, %02X", ck_b, msg_parse_buf[7]); + return false; + } + return true; +} + +inline bool UbloxMsgParser::valid() { + return bytes_in_parse_buf >= UBLOX_HEADER_SIZE + UBLOX_CHECKSUM_SIZE && + needed_bytes() == 0 && + valid_cheksum(); +} + +inline bool UbloxMsgParser::valid_so_far() { + if(bytes_in_parse_buf > 0 && msg_parse_buf[0] != PREAMBLE1) { + //LOGD("PREAMBLE1 invalid, %02X.", msg_parse_buf[0]); + return false; + } + if(bytes_in_parse_buf > 1 && msg_parse_buf[1] != PREAMBLE2) { + //LOGD("PREAMBLE2 invalid, %02X.", msg_parse_buf[1]); + return false; + } + if(needed_bytes() == 0 && !valid()) + return false; + return true; +} + +kj::Array UbloxMsgParser::gen_solution() { + nav_pvt_msg *msg = (nav_pvt_msg *)&msg_parse_buf[UBLOX_HEADER_SIZE]; + capnp::MallocMessageBuilder msg_builder; + cereal::Event::Builder event = msg_builder.initRoot(); + event.setLogMonoTime(nanos_since_boot()); + auto gpsLoc = event.initGpsLocationExternal(); + gpsLoc.setSource(cereal::GpsLocationData::SensorSource::UBLOX); + gpsLoc.setFlags(msg->flags); + gpsLoc.setLatitude(msg->lat * 1e-07); + gpsLoc.setLongitude(msg->lon * 1e-07); + gpsLoc.setAltitude(msg->height * 1e-03); + gpsLoc.setSpeed(msg->gSpeed * 1e-03); + gpsLoc.setBearing(msg->headMot * 1e-5); + gpsLoc.setAccuracy(msg->hAcc * 1e-03); + std::tm timeinfo = std::tm(); + timeinfo.tm_year = msg->year - 1900; + timeinfo.tm_mon = msg->month - 1; + timeinfo.tm_mday = msg->day; + timeinfo.tm_hour = msg->hour; + timeinfo.tm_min = msg->min; + timeinfo.tm_sec = msg->sec; + std::time_t utc_tt = timegm(&timeinfo); + gpsLoc.setTimestamp(utc_tt * 1e+03 + msg->nano * 1e-06); + float f[] = { msg->velN * 1e-03f, msg->velE * 1e-03f, msg->velD * 1e-03f }; + kj::ArrayPtr ap(&f[0], sizeof(f) / sizeof(f[0])); + gpsLoc.setVNED(ap); + gpsLoc.setVerticalAccuracy(msg->vAcc * 1e-03); + gpsLoc.setSpeedAccuracy(msg->sAcc * 1e-03); + gpsLoc.setBearingAccuracy(msg->headAcc * 1e-05); + return capnp::messageToFlatArray(msg_builder); +} + +inline bool bit_to_bool(uint8_t val, int shifts) { + return (val & (1 << shifts)) ? true : false; +} + +kj::Array UbloxMsgParser::gen_raw() { + rxm_raw_msg *msg = (rxm_raw_msg *)&msg_parse_buf[UBLOX_HEADER_SIZE]; + if(bytes_in_parse_buf != ( + UBLOX_HEADER_SIZE + sizeof(rxm_raw_msg) + msg->numMeas * sizeof(rxm_raw_msg_extra) + UBLOX_CHECKSUM_SIZE + )) { + LOGD("Invalid measurement size %u, %u, %u, %u", msg->numMeas, bytes_in_parse_buf, sizeof(rxm_raw_msg_extra), sizeof(rxm_raw_msg)); + return kj::Array(); + } + rxm_raw_msg_extra *measurements = (rxm_raw_msg_extra *)&msg_parse_buf[UBLOX_HEADER_SIZE + sizeof(rxm_raw_msg)]; + capnp::MallocMessageBuilder msg_builder; + cereal::Event::Builder event = msg_builder.initRoot(); + event.setLogMonoTime(nanos_since_boot()); + auto gnss = event.initUbloxGnss(); + auto mr = gnss.initMeasurementReport(); + mr.setRcvTow(msg->rcvTow); + mr.setGpsWeek(msg->week); + mr.setLeapSeconds(msg->leapS); + mr.setGpsWeek(msg->week); + auto mb = mr.initMeasurements(msg->numMeas); + for(int8_t i = 0; i < msg->numMeas; i++) { + mb[i].setSvId(measurements[i].svId); + mb[i].setSigId(measurements[i].sigId); + mb[i].setPseudorange(measurements[i].prMes); + mb[i].setCarrierCycles(measurements[i].cpMes); + mb[i].setDoppler(measurements[i].doMes); + mb[i].setGnssId(measurements[i].gnssId); + mb[i].setGlonassFrequencyIndex(measurements[i].freqId); + mb[i].setLocktime(measurements[i].locktime); + mb[i].setCno(measurements[i].cno); + mb[i].setPseudorangeStdev(0.01*(pow(2, (measurements[i].prStdev & 15)))); // weird scaling, might be wrong + mb[i].setCarrierPhaseStdev(0.004*(measurements[i].cpStdev & 15)); + mb[i].setDopplerStdev(0.002*(pow(2, (measurements[i].doStdev & 15)))); // weird scaling, might be wrong + auto ts = mb[i].initTrackingStatus(); + ts.setPseudorangeValid(bit_to_bool(measurements[i].trkStat, 0)); + ts.setCarrierPhaseValid(bit_to_bool(measurements[i].trkStat, 1)); + ts.setHalfCycleValid(bit_to_bool(measurements[i].trkStat, 2)); + ts.setHalfCycleSubtracted(bit_to_bool(measurements[i].trkStat, 3)); + } + + mr.setNumMeas(msg->numMeas); + auto rs = mr.initReceiverStatus(); + rs.setLeapSecValid(bit_to_bool(msg->recStat, 0)); + rs.setClkReset(bit_to_bool(msg->recStat, 2)); + return capnp::messageToFlatArray(msg_builder); +} + +kj::Array UbloxMsgParser::gen_nav_data() { + rxm_sfrbx_msg *msg = (rxm_sfrbx_msg *)&msg_parse_buf[UBLOX_HEADER_SIZE]; + if(bytes_in_parse_buf != ( + UBLOX_HEADER_SIZE + sizeof(rxm_sfrbx_msg) + msg->numWords * sizeof(rxm_sfrbx_msg_extra) + UBLOX_CHECKSUM_SIZE + )) { + LOGD("Invalid sfrbx words size %u, %u, %u, %u", msg->numWords, bytes_in_parse_buf, sizeof(rxm_raw_msg_extra), sizeof(rxm_raw_msg)); + return kj::Array(); + } + rxm_sfrbx_msg_extra *measurements = (rxm_sfrbx_msg_extra *)&msg_parse_buf[UBLOX_HEADER_SIZE + sizeof(rxm_sfrbx_msg)]; + if(msg->gnssId == 0) { + uint8_t subframeId = GET_FIELD_U(measurements[1].dwrd, 3, 8); + std::vector words; + for(int i = 0; i < msg->numWords;i++) + words.push_back(measurements[i].dwrd); + + if(subframeId == 1) { + nav_frame_buffer[msg->gnssId][msg->svid] = subframes_map(); + nav_frame_buffer[msg->gnssId][msg->svid][subframeId] = words; + } else if(nav_frame_buffer[msg->gnssId][msg->svid].find(subframeId-1) != nav_frame_buffer[msg->gnssId][msg->svid].end()) + nav_frame_buffer[msg->gnssId][msg->svid][subframeId] = words; + if(nav_frame_buffer[msg->gnssId][msg->svid].size() == 5) { + EphemerisData ephem_data(msg->svid, nav_frame_buffer[msg->gnssId][msg->svid]); + capnp::MallocMessageBuilder msg_builder; + cereal::Event::Builder event = msg_builder.initRoot(); + event.setLogMonoTime(nanos_since_boot()); + auto gnss = event.initUbloxGnss(); + auto eph = gnss.initEphemeris(); + eph.setSvId(ephem_data.svId); + eph.setToc(ephem_data.toc); + eph.setGpsWeek(ephem_data.gpsWeek); + eph.setAf0(ephem_data.af0); + eph.setAf1(ephem_data.af1); + eph.setAf2(ephem_data.af2); + eph.setIode(ephem_data.iode); + eph.setCrs(ephem_data.crs); + eph.setDeltaN(ephem_data.deltaN); + eph.setM0(ephem_data.M0); + eph.setCuc(ephem_data.cuc); + eph.setEcc(ephem_data.ecc); + eph.setCus(ephem_data.cus); + eph.setA(ephem_data.A); + eph.setToe(ephem_data.toe); + eph.setCic(ephem_data.cic); + eph.setOmega0(ephem_data.omega0); + eph.setCis(ephem_data.cis); + eph.setI0(ephem_data.i0); + eph.setCrc(ephem_data.crc); + eph.setOmega(ephem_data.omega); + eph.setOmegaDot(ephem_data.omega_dot); + eph.setIDot(ephem_data.idot); + eph.setTgd(ephem_data.Tgd); + eph.setIonoCoeffsValid(ephem_data.ionoCoeffsValid); + if(ephem_data.ionoCoeffsValid) { + kj::ArrayPtr apa(&ephem_data.ionoAlpha[0], sizeof(ephem_data.ionoAlpha) / sizeof(ephem_data.ionoAlpha[0])); + eph.setIonoAlpha(apa); + kj::ArrayPtr apb(&ephem_data.ionoBeta[0], sizeof(ephem_data.ionoBeta) / sizeof(ephem_data.ionoBeta[0])); + eph.setIonoBeta(apb); + } else { + eph.setIonoAlpha(kj::ArrayPtr()); + eph.setIonoBeta(kj::ArrayPtr()); + } + return capnp::messageToFlatArray(msg_builder); + } + } + return kj::Array(); +} + +bool UbloxMsgParser::add_data(const uint8_t *incoming_data, uint32_t incoming_data_len, size_t &bytes_consumed) { + int needed = needed_bytes(); + if(needed > 0) { + bytes_consumed = min((size_t)needed, incoming_data_len ); + // Add data to buffer + memcpy(msg_parse_buf + bytes_in_parse_buf, incoming_data, bytes_consumed); + bytes_in_parse_buf += bytes_consumed; + } else { + bytes_consumed = incoming_data_len; + } + // Validate msg format, detect invalid header and invalid checksum. + while(!valid_so_far() && bytes_in_parse_buf != 0) { + //LOGD("Drop corrupt data, remained in buf: %u", bytes_in_parse_buf); + // Corrupted msg, drop a byte. + bytes_in_parse_buf -= 1; + if(bytes_in_parse_buf > 0) + memmove(&msg_parse_buf[0], &msg_parse_buf[1], bytes_in_parse_buf); + } + // There is redundant data at the end of buffer, reset the buffer. + if(needed_bytes() == -1) + bytes_in_parse_buf = 0; + return valid(); +} + +} diff --git a/selfdrive/locationd/ublox_msg.h b/selfdrive/locationd/ublox_msg.h new file mode 100644 index 00000000000000..eca6186d4a6c09 --- /dev/null +++ b/selfdrive/locationd/ublox_msg.h @@ -0,0 +1,150 @@ +#pragma once + +#include +#include "messaging.hpp" + +#define min(x, y) ((x) <= (y) ? (x) : (y)) + +// NAV_PVT +typedef struct __attribute__((packed)) { + uint32_t iTOW; + uint16_t year; + int8_t month; + int8_t day; + int8_t hour; + int8_t min; + int8_t sec; + int8_t valid; + uint32_t tAcc; + int32_t nano; + int8_t fixType; + int8_t flags; + int8_t flags2; + int8_t numSV; + int32_t lon; + int32_t lat; + int32_t height; + int32_t hMSL; + uint32_t hAcc; + uint32_t vAcc; + int32_t velN; + int32_t velE; + int32_t velD; + int32_t gSpeed; + int32_t headMot; + uint32_t sAcc; + uint32_t headAcc; + uint16_t pDOP; + int8_t reserverd1[6]; + int32_t headVeh; + int16_t magDec; + uint16_t magAcc; +} nav_pvt_msg; + +// RXM_RAW +typedef struct __attribute__((packed)) { + double rcvTow; + uint16_t week; + int8_t leapS; + int8_t numMeas; + int8_t recStat; + int8_t reserved1[3]; +} rxm_raw_msg; + +// Extra data count is in numMeas +typedef struct __attribute__((packed)) { + double prMes; + double cpMes; + float doMes; + int8_t gnssId; + int8_t svId; + int8_t sigId; + int8_t freqId; + uint16_t locktime; + int8_t cno; + int8_t prStdev; + int8_t cpStdev; + int8_t doStdev; + int8_t trkStat; + int8_t reserved3; +} rxm_raw_msg_extra; +// RXM_SFRBX +typedef struct __attribute__((packed)) { + int8_t gnssId; + int8_t svid; + int8_t reserved1; + int8_t freqId; + int8_t numWords; + int8_t reserved2; + int8_t version; + int8_t reserved3; +} rxm_sfrbx_msg; + +// Extra data count is in numWords +typedef struct __attribute__((packed)) { + uint32_t dwrd; +} rxm_sfrbx_msg_extra; + +namespace ublox { + // protocol constants + const uint8_t PREAMBLE1 = 0xb5; + const uint8_t PREAMBLE2 = 0x62; + + // message classes + const uint8_t CLASS_NAV = 0x01; + const uint8_t CLASS_RXM = 0x02; + + // NAV messages + const uint8_t MSG_NAV_PVT = 0x7; + + // RXM messages + const uint8_t MSG_RXM_RAW = 0x15; + const uint8_t MSG_RXM_SFRBX = 0x13; + + const int UBLOX_HEADER_SIZE = 6; + const int UBLOX_CHECKSUM_SIZE = 2; + const int UBLOX_MAX_MSG_SIZE = 65536; + + typedef std::map> subframes_map; + + class UbloxMsgParser { + public: + + UbloxMsgParser(); + kj::Array gen_solution(); + kj::Array gen_raw(); + + kj::Array gen_nav_data(); + bool add_data(const uint8_t *incoming_data, uint32_t incoming_data_len, size_t &bytes_consumed); + inline void reset() {bytes_in_parse_buf = 0;} + inline uint8_t msg_class() { + return msg_parse_buf[2]; + } + + inline uint8_t msg_id() { + return msg_parse_buf[3]; + } + inline int needed_bytes(); + + void hexdump(uint8_t *d, int l) { + for (int i = 0; i < l; i++) { + if (i%0x10 == 0 && i != 0) printf("\n"); + printf("%02X ", d[i]); + } + printf("\n"); + } + private: + inline bool valid_cheksum(); + inline bool valid(); + inline bool valid_so_far(); + + uint8_t msg_parse_buf[UBLOX_HEADER_SIZE + UBLOX_MAX_MSG_SIZE]; + int bytes_in_parse_buf; + std::map> nav_frame_buffer; + }; + +} + +typedef Message * (*poll_ubloxraw_msg_func)(Poller *poller); +typedef int (*send_gps_event_func)(PubSocket *s, const void *buf, size_t len); +int ubloxd_main(poll_ubloxraw_msg_func poll_func, send_gps_event_func send_func); diff --git a/selfdrive/locationd/ubloxd.cc b/selfdrive/locationd/ubloxd.cc new file mode 100644 index 00000000000000..2c28f142286b8c --- /dev/null +++ b/selfdrive/locationd/ubloxd.cc @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "messaging.hpp" +#include +#include "cereal/gen/cpp/log.capnp.h" + +#include "common/params.h" +#include "common/swaglog.h" +#include "common/timing.h" + +#include "ublox_msg.h" + +const long ZMQ_POLL_TIMEOUT = 1000; // In miliseconds + +Message * poll_ubloxraw_msg(Poller * poller) { + auto p = poller->poll(ZMQ_POLL_TIMEOUT); + + if (p.size()) { + return p[0]->receive(); + } else { + return NULL; + } +} + + +int send_gps_event(PubSocket *s, const void *buf, size_t len) { + return s->send((char*)buf, len); +} + +int main() { + return ubloxd_main(poll_ubloxraw_msg, send_gps_event); +} diff --git a/selfdrive/locationd/ubloxd_main.cc b/selfdrive/locationd/ubloxd_main.cc new file mode 100644 index 00000000000000..d87942d8a1789e --- /dev/null +++ b/selfdrive/locationd/ubloxd_main.cc @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "messaging.hpp" +#include +#include "cereal/gen/cpp/log.capnp.h" + +#include "common/params.h" +#include "common/swaglog.h" +#include "common/timing.h" + +#include "ublox_msg.h" + +volatile sig_atomic_t do_exit = 0; // Flag for process exit on signal + +void set_do_exit(int sig) { + do_exit = 1; +} + +using namespace ublox; + +int ubloxd_main(poll_ubloxraw_msg_func poll_func, send_gps_event_func send_func) { + LOGW("starting ubloxd"); + signal(SIGINT, (sighandler_t) set_do_exit); + signal(SIGTERM, (sighandler_t) set_do_exit); + + UbloxMsgParser parser; + + Context * c = Context::create(); + PubSocket * gpsLocationExternal = PubSocket::create(c, "gpsLocationExternal"); + PubSocket * ubloxGnss = PubSocket::create(c, "ubloxGnss"); + SubSocket * ubloxRaw = SubSocket::create(c, "ubloxRaw"); + Poller * poller = Poller::create({ubloxRaw}); + + + while (!do_exit) { + Message * msg = poll_func(poller); + if (msg == NULL) continue; + + auto amsg = kj::heapArray((msg->getSize() / sizeof(capnp::word)) + 1); + memcpy(amsg.begin(), msg->getData(), msg->getSize()); + + capnp::FlatArrayMessageReader cmsg(amsg); + cereal::Event::Reader event = cmsg.getRoot(); + + const uint8_t *data = event.getUbloxRaw().begin(); + size_t len = event.getUbloxRaw().size(); + size_t bytes_consumed = 0; + while(bytes_consumed < len && !do_exit) { + size_t bytes_consumed_this_time = 0U; + if(parser.add_data(data + bytes_consumed, (uint32_t)(len - bytes_consumed), bytes_consumed_this_time)) { + // New message available + if(parser.msg_class() == CLASS_NAV) { + if(parser.msg_id() == MSG_NAV_PVT) { + //LOGD("MSG_NAV_PVT"); + auto words = parser.gen_solution(); + if(words.size() > 0) { + auto bytes = words.asBytes(); + send_func(gpsLocationExternal, bytes.begin(), bytes.size()); + } + } else + LOGW("Unknown nav msg id: 0x%02X", parser.msg_id()); + } else if(parser.msg_class() == CLASS_RXM) { + if(parser.msg_id() == MSG_RXM_RAW) { + //LOGD("MSG_RXM_RAW"); + auto words = parser.gen_raw(); + if(words.size() > 0) { + auto bytes = words.asBytes(); + send_func(ubloxGnss, bytes.begin(), bytes.size()); + } + } else if(parser.msg_id() == MSG_RXM_SFRBX) { + //LOGD("MSG_RXM_SFRBX"); + auto words = parser.gen_nav_data(); + if(words.size() > 0) { + auto bytes = words.asBytes(); + send_func(ubloxGnss, bytes.begin(), bytes.size()); + } + } else + LOGW("Unknown rxm msg id: 0x%02X", parser.msg_id()); + } else + LOGW("Unknown msg class: 0x%02X", parser.msg_class()); + parser.reset(); + } + bytes_consumed += bytes_consumed_this_time; + } + delete msg; + } + + delete poller; + delete ubloxRaw; + delete ubloxGnss; + delete gpsLocationExternal; + delete c; + + return 0; +} diff --git a/selfdrive/locationd/ubloxd_test.cc b/selfdrive/locationd/ubloxd_test.cc new file mode 100644 index 00000000000000..68fe6351ea6660 --- /dev/null +++ b/selfdrive/locationd/ubloxd_test.cc @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "messaging.hpp" +#include "impl_zmq.hpp" +#include +#include "cereal/gen/cpp/log.capnp.h" + +#include "common/params.h" +#include "common/swaglog.h" +#include "common/timing.h" +#include "common/util.h" +#include "ublox_msg.h" + +using namespace ublox; +extern volatile sig_atomic_t do_exit; + +void write_file(std::string fpath, uint8_t *data, int len) { + FILE* f = fopen(fpath.c_str(), "wb"); + if (!f) { + std::cout << "Open " << fpath << " failed" << std::endl; + return; + } + fwrite(data, len, 1, f); + fclose(f); +} + +static size_t len = 0U; +static size_t consumed = 0U; +static uint8_t *data = NULL; +static int save_idx = 0; +static std::string prefix; + +Message * poll_ubloxraw_msg(Poller * poller) { + assert(poller); + + size_t consuming = min(len - consumed, 128); + if(consumed < len) { + // create message + capnp::MallocMessageBuilder msg_builder; + cereal::Event::Builder event = msg_builder.initRoot(); + event.setLogMonoTime(nanos_since_boot()); + + auto ublox_raw = event.initUbloxRaw(consuming); + memcpy(ublox_raw.begin(), (void *)(data + consumed), consuming); + + auto words = capnp::messageToFlatArray(msg_builder); + auto bytes = words.asBytes(); + + Message * msg = new ZMQMessage(); + msg->init((char*)bytes.begin(), bytes.size()); + consumed += consuming; + return msg; + } else { + do_exit = 1; + return NULL; + } +} + +int send_gps_event(PubSocket *s, const void *buf, size_t len) { + assert(s); + write_file(prefix + "/" + std::to_string(save_idx), (uint8_t *)buf, len); + save_idx++; + return len; +} + +int main(int argc, char** argv) { + if(argc < 3) { + printf("Format: ubloxd_test stream_file_path save_prefix\n"); + return 0; + } + // Parse 11360 msgs, generate 9452 events + data = (uint8_t *)read_file(argv[1], &len); + if(data == NULL) { + LOGE("Read file %s failed\n", argv[1]); + return -1; + } + prefix = argv[2]; + ubloxd_main(poll_ubloxraw_msg, send_gps_event); + free(data); + printf("Generated %d cereal events\n", save_idx); + if(save_idx != 9452) { + printf("Event count error: %d\n", save_idx); + return -1; + } + return 0; +} diff --git a/selfdrive/logcatd/Makefile b/selfdrive/logcatd/Makefile index 077f20f8cde941..c1a3ef979e7eb6 100644 --- a/selfdrive/logcatd/Makefile +++ b/selfdrive/logcatd/Makefile @@ -1,6 +1,8 @@ CC = clang CXX = clang++ +ARCH := $(shell uname -m) + PHONELIBS = ../../phonelibs BASEDIR = ../.. @@ -13,10 +15,15 @@ WARN_FLAGS = -Werror=implicit-function-declaration \ CFLAGS = -std=gnu11 -g -fPIC -O2 $(WARN_FLAGS) CXXFLAGS = -std=c++11 -g -fPIC -O2 $(WARN_FLAGS) -ZMQ_FLAGS = -I$(PHONELIBS)/zmq/aarch64/include -ZMQ_LIBS = -L$(PHONELIBS)/zmq/aarch64/lib \ - -l:libczmq.a -l:libzmq.a \ - -lgnustl_shared +MESSAGING_FLAGS = -I$(BASEDIR)/selfdrive/messaging +MESSAGING_LIBS = $(BASEDIR)/selfdrive/messaging/messaging.a + +ifeq ($(ARCH),aarch64) +CFLAGS += -mcpu=cortex-a57 +CXXFLAGS += -mcpu=cortex-a57 +EXTRA_LIBS += -lgnustl_shared +endif + .PHONY: all all: logcatd @@ -28,11 +35,11 @@ OBJS = logcatd.o \ DEPS := $(OBJS:.o=.d) -logcatd: $(OBJS) +logcatd: $(OBJS) $(MESSAGING_LIBS) @echo "[ LINK ] $@" $(CXX) -fPIC -o '$@' $^ \ $(CEREAL_LIBS) \ - $(ZMQ_LIBS) \ + $(EXTRA_LIBS) \ -llog %.o: %.cc @@ -40,7 +47,7 @@ logcatd: $(OBJS) $(CXX) $(CXXFLAGS) \ -I$(PHONELIBS)/android_system_core/include \ $(CEREAL_CXXFLAGS) \ - $(ZMQ_FLAGS) \ + $(MESSAGING_FLAGS) \ -I../ \ -I../../ \ -c -o '$@' '$<' diff --git a/selfdrive/logcatd/logcatd.cc b/selfdrive/logcatd/logcatd.cc index c2f688fd59f50f..9e5707c29fc6e1 100644 --- a/selfdrive/logcatd/logcatd.cc +++ b/selfdrive/logcatd/logcatd.cc @@ -1,15 +1,16 @@ #include #include #include +#include -#include +//#include #include #include -#include #include #include "common/timing.h" #include "cereal/gen/cpp/log.capnp.h" +#include "messaging.hpp" int main() { int err; @@ -24,13 +25,11 @@ int main() { assert(system_logger); struct logger *crash_logger = android_logger_open(logger_list, LOG_ID_CRASH); assert(crash_logger); - struct logger *kernel_logger = android_logger_open(logger_list, LOG_ID_KERNEL); - assert(kernel_logger); +// struct logger *kernel_logger = android_logger_open(logger_list, LOG_ID_KERNEL); +// assert(kernel_logger); - void *context = zmq_ctx_new(); - void *publisher = zmq_socket(context, ZMQ_PUB); - err = zmq_bind(publisher, "tcp://*:8020"); - assert(err == 0); + Context * c = Context::create(); + PubSocket * androidLog = PubSocket::create(c, "androidLog"); while (1) { log_msg log_msg; @@ -59,10 +58,13 @@ int main() { auto words = capnp::messageToFlatArray(msg); auto bytes = words.asBytes(); - zmq_send(publisher, bytes.begin(), bytes.size(), 0); + androidLog->send((char*)bytes.begin(), bytes.size()); } android_logger_list_close(logger_list); + delete c; + delete androidLog; + return 0; -} \ No newline at end of file +} diff --git a/selfdrive/loggerd/build_from_src.mk b/selfdrive/loggerd/build_from_src.mk new file mode 100644 index 00000000000000..90db118bc977b9 --- /dev/null +++ b/selfdrive/loggerd/build_from_src.mk @@ -0,0 +1,136 @@ +CC = clang +CXX = clang++ + +ARCH := $(shell uname -m) + +PHONELIBS = ../../phonelibs +BASEDIR = ../.. + +WARN_FLAGS = -Werror=implicit-function-declaration \ + -Werror=incompatible-pointer-types \ + -Werror=int-conversion \ + -Werror=return-type \ + -Werror=format-extra-args \ + -Wno-deprecated-declarations + +CFLAGS = -std=gnu11 -g -fPIC -O2 $(WARN_FLAGS) \ + -I$(PHONELIBS)/android_frameworks_native/include \ + -I$(PHONELIBS)/android_system_core/include \ + -I$(PHONELIBS)/android_hardware_libhardware/include +CXXFLAGS = -std=c++11 -g -fPIC -O2 $(WARN_FLAGS) \ + -I$(PHONELIBS)/android_frameworks_native/include \ + -I$(PHONELIBS)/android_system_core/include \ + -I$(PHONELIBS)/android_hardware_libhardware/include + +ZMQ_LIBS = -l:libczmq.a -l:libzmq.a + +MESSAGING_FLAGS = -I$(BASEDIR)/selfdrive/messaging +MESSAGING_LIBS = $(BASEDIR)/selfdrive/messaging/messaging.a + +ifeq ($(ARCH),aarch64) +CFLAGS += -mcpu=cortex-a57 +CXXFLAGS += -mcpu=cortex-a57 +ZMQ_LIBS += -lgnustl_shared +endif + + +BZIP_FLAGS = -I$(PHONELIBS)/bzip2/ +BZIP_LIBS = -L$(PHONELIBS)/bzip2/ \ + -l:libbz2.a + +# todo: dont use system ffmpeg libs +FFMPEG_LIBS = -lavformat \ + -lavcodec \ + -lswscale \ + -lavutil \ + -lz + +LIBYUV_FLAGS = -I$(PHONELIBS)/libyuv/include +LIBYUV_LIBS = $(PHONELIBS)/libyuv/lib/libyuv.a + +OPENMAX_FLAGS = -I$(PHONELIBS)/openmax/include +OPENMAX_LIBS = -lOmxVenc -lOmxCore + +JSON_FLAGS = -I$(PHONELIBS)/json/src + +YAML_FLAGS = -I$(PHONELIBS)/yaml-cpp/include +YAML_LIBS = $(PHONELIBS)/yaml-cpp/lib/libyaml-cpp.a + +.PHONY: all +all: loggerd + +include ../common/cereal.mk + +OBJS += loggerd.o \ + logger.o \ + ../common/util.o \ + ../common/params.o \ + ../common/cqueue.o \ + ../common/swaglog.o \ + ../common/visionipc.o \ + ../common/ipc.o \ + $(PHONELIBS)/json/src/json.o + +ifeq ($(ARCH),x86_64) +CXXFLAGS += "-DDISABLE_ENCODER" +ZMQ_LIBS = -L$(BASEDIR)/external/zmq/lib/ \ + -l:libczmq.a -l:libzmq.a +EXTRA_LIBS = -lpthread +OPENMAX_LIBS = "" +YAML_LIBS = $(PHONELIBS)/yaml-cpp/x64/lib/libyaml-cpp.a +else +OBJS += encoder.o \ + raw_logger.o +EXTRA_LIBS = -lcutils -llog -lgnustl_shared +endif + +DEPS := $(OBJS:.o=.d) + +loggerd: $(OBJS) $(MESSAGING_LIBS) + @echo "[ LINK ] $@" + $(CXX) -fPIC -o '$@' $^ \ + $(LIBYUV_LIBS) \ + $(CEREAL_LIBS) \ + $(ZMQ_LIBS) \ + -L/usr/lib \ + $(FFMPEG_LIBS) \ + -L/system/vendor/lib64 \ + $(OPENMAX_LIBS) \ + $(YAML_LIBS) \ + $(EXTRA_LIBS) \ + $(BZIP_LIBS) \ + -lm + +%.o: %.cc + @echo "[ CXX ] $@" + $(CXX) $(CXXFLAGS) -MMD \ + $(CEREAL_CXXFLAGS) \ + $(LIBYUV_FLAGS) \ + $(ZMQ_FLAGS) \ + $(MESSAGING_FLAGS) \ + $(OPENMAX_FLAGS) \ + $(YAML_FLAGS) \ + $(BZIP_FLAGS) \ + -Iinclude \ + -I../ \ + -I../../ \ + -c -o '$@' '$<' + +%.o: %.c + @echo "[ CC ] $@" + $(CC) $(CFLAGS) -MMD \ + $(LIBYUV_FLAGS) \ + $(ZMQ_FLAGS) \ + $(OPENMAX_FLAGS) \ + $(JSON_FLAGS) \ + $(BZIP_FLAGS) \ + -Iinclude \ + -I../ \ + -I../../ \ + -c -o '$@' '$<' + +.PHONY: clean +clean: + rm -f loggerd $(OBJS) $(DEPS) + +-include $(DEPS) diff --git a/selfdrive/loggerd/config.py b/selfdrive/loggerd/config.py index 9d1c3120fbaec5..14e1e67a9eb44d 100644 --- a/selfdrive/loggerd/config.py +++ b/selfdrive/loggerd/config.py @@ -7,3 +7,13 @@ ROOT = '/data/media/0/realdata/' SEGMENT_LENGTH = 60 + + +def get_available_percent(): + try: + statvfs = os.statvfs(ROOT) + available_percent = 100.0 * statvfs.f_bavail / statvfs.f_blocks + except OSError: + available_percent = 100.0 + + return available_percent diff --git a/selfdrive/loggerd/deleter.py b/selfdrive/loggerd/deleter.py new file mode 100644 index 00000000000000..5669e2342d2318 --- /dev/null +++ b/selfdrive/loggerd/deleter.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +import os +import shutil +import threading +from selfdrive.swaglog import cloudlog +from selfdrive.loggerd.config import ROOT, get_available_percent +from selfdrive.loggerd.uploader import listdir_by_creation + + +def deleter_thread(exit_event): + while not exit_event.is_set(): + available_percent = get_available_percent() + + if available_percent < 10.0: + # remove the earliest directory we can + dirs = listdir_by_creation(ROOT) + for delete_dir in dirs: + delete_path = os.path.join(ROOT, delete_dir) + + if any(name.endswith(".lock") for name in os.listdir(delete_path)): + continue + + try: + cloudlog.info("deleting %s" % delete_path) + shutil.rmtree(delete_path) + break + except OSError: + cloudlog.exception("issue deleting %s" % delete_path) + exit_event.wait(.1) + else: + exit_event.wait(30) + + +def main(gctx=None): + deleter_thread(threading.Event()) + + +if __name__ == "__main__": + main() diff --git a/selfdrive/loggerd/encoder.c b/selfdrive/loggerd/encoder.c new file mode 100644 index 00000000000000..747c7a1957f06a --- /dev/null +++ b/selfdrive/loggerd/encoder.c @@ -0,0 +1,796 @@ +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include + +#include + +#include + +#include "common/mutex.h" +#include "common/swaglog.h" + +#include "encoder.h" + +#define ALOG(...) __android_log_print(ANDROID_LOG_VERBOSE, "omxapp", ##__VA_ARGS__) + +// encoder: lossey codec using hardware hevc +static void wait_for_state(EncoderState *s, OMX_STATETYPE state) { + pthread_mutex_lock(&s->state_lock); + while (s->state != state) { + pthread_cond_wait(&s->state_cv, &s->state_lock); + } + pthread_mutex_unlock(&s->state_lock); +} + +static OMX_ERRORTYPE event_handler(OMX_HANDLETYPE component, OMX_PTR app_data, OMX_EVENTTYPE event, + OMX_U32 data1, OMX_U32 data2, OMX_PTR event_data) { + EncoderState *s = app_data; + + switch (event) { + case OMX_EventCmdComplete: + assert(data1 == OMX_CommandStateSet); + LOG("set state event 0x%x", data2); + pthread_mutex_lock(&s->state_lock); + s->state = data2; + pthread_cond_broadcast(&s->state_cv); + pthread_mutex_unlock(&s->state_lock); + break; + case OMX_EventError: + LOGE("OMX error 0x%08x", data1); + // assert(false); + break; + default: + LOGE("unhandled event %d", event); + assert(false); + break; + } + + pthread_mutex_unlock(&s->state_lock); + + return OMX_ErrorNone; +} + +static OMX_ERRORTYPE empty_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data, + OMX_BUFFERHEADERTYPE *buffer) { + EncoderState *s = app_data; + + // printf("empty_buffer_done\n"); + + queue_push(&s->free_in, (void*)buffer); + + return OMX_ErrorNone; +} + + +static OMX_ERRORTYPE fill_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data, + OMX_BUFFERHEADERTYPE *buffer) { + EncoderState *s = app_data; + + // printf("fill_buffer_done\n"); + + queue_push(&s->done_out, (void*)buffer); + + return OMX_ErrorNone; +} + +static OMX_CALLBACKTYPE omx_callbacks = { + .EventHandler = event_handler, + .EmptyBufferDone = empty_buffer_done, + .FillBufferDone = fill_buffer_done, +}; + +#define PORT_INDEX_IN 0 +#define PORT_INDEX_OUT 1 + +static const char* omx_color_fomat_name(uint32_t format) { + switch (format) { + case OMX_COLOR_FormatUnused: return "OMX_COLOR_FormatUnused"; + case OMX_COLOR_FormatMonochrome: return "OMX_COLOR_FormatMonochrome"; + case OMX_COLOR_Format8bitRGB332: return "OMX_COLOR_Format8bitRGB332"; + case OMX_COLOR_Format12bitRGB444: return "OMX_COLOR_Format12bitRGB444"; + case OMX_COLOR_Format16bitARGB4444: return "OMX_COLOR_Format16bitARGB4444"; + case OMX_COLOR_Format16bitARGB1555: return "OMX_COLOR_Format16bitARGB1555"; + case OMX_COLOR_Format16bitRGB565: return "OMX_COLOR_Format16bitRGB565"; + case OMX_COLOR_Format16bitBGR565: return "OMX_COLOR_Format16bitBGR565"; + case OMX_COLOR_Format18bitRGB666: return "OMX_COLOR_Format18bitRGB666"; + case OMX_COLOR_Format18bitARGB1665: return "OMX_COLOR_Format18bitARGB1665"; + case OMX_COLOR_Format19bitARGB1666: return "OMX_COLOR_Format19bitARGB1666"; + case OMX_COLOR_Format24bitRGB888: return "OMX_COLOR_Format24bitRGB888"; + case OMX_COLOR_Format24bitBGR888: return "OMX_COLOR_Format24bitBGR888"; + case OMX_COLOR_Format24bitARGB1887: return "OMX_COLOR_Format24bitARGB1887"; + case OMX_COLOR_Format25bitARGB1888: return "OMX_COLOR_Format25bitARGB1888"; + case OMX_COLOR_Format32bitBGRA8888: return "OMX_COLOR_Format32bitBGRA8888"; + case OMX_COLOR_Format32bitARGB8888: return "OMX_COLOR_Format32bitARGB8888"; + case OMX_COLOR_FormatYUV411Planar: return "OMX_COLOR_FormatYUV411Planar"; + case OMX_COLOR_FormatYUV411PackedPlanar: return "OMX_COLOR_FormatYUV411PackedPlanar"; + case OMX_COLOR_FormatYUV420Planar: return "OMX_COLOR_FormatYUV420Planar"; + case OMX_COLOR_FormatYUV420PackedPlanar: return "OMX_COLOR_FormatYUV420PackedPlanar"; + case OMX_COLOR_FormatYUV420SemiPlanar: return "OMX_COLOR_FormatYUV420SemiPlanar"; + case OMX_COLOR_FormatYUV422Planar: return "OMX_COLOR_FormatYUV422Planar"; + case OMX_COLOR_FormatYUV422PackedPlanar: return "OMX_COLOR_FormatYUV422PackedPlanar"; + case OMX_COLOR_FormatYUV422SemiPlanar: return "OMX_COLOR_FormatYUV422SemiPlanar"; + case OMX_COLOR_FormatYCbYCr: return "OMX_COLOR_FormatYCbYCr"; + case OMX_COLOR_FormatYCrYCb: return "OMX_COLOR_FormatYCrYCb"; + case OMX_COLOR_FormatCbYCrY: return "OMX_COLOR_FormatCbYCrY"; + case OMX_COLOR_FormatCrYCbY: return "OMX_COLOR_FormatCrYCbY"; + case OMX_COLOR_FormatYUV444Interleaved: return "OMX_COLOR_FormatYUV444Interleaved"; + case OMX_COLOR_FormatRawBayer8bit: return "OMX_COLOR_FormatRawBayer8bit"; + case OMX_COLOR_FormatRawBayer10bit: return "OMX_COLOR_FormatRawBayer10bit"; + case OMX_COLOR_FormatRawBayer8bitcompressed: return "OMX_COLOR_FormatRawBayer8bitcompressed"; + case OMX_COLOR_FormatL2: return "OMX_COLOR_FormatL2"; + case OMX_COLOR_FormatL4: return "OMX_COLOR_FormatL4"; + case OMX_COLOR_FormatL8: return "OMX_COLOR_FormatL8"; + case OMX_COLOR_FormatL16: return "OMX_COLOR_FormatL16"; + case OMX_COLOR_FormatL24: return "OMX_COLOR_FormatL24"; + case OMX_COLOR_FormatL32: return "OMX_COLOR_FormatL32"; + case OMX_COLOR_FormatYUV420PackedSemiPlanar: return "OMX_COLOR_FormatYUV420PackedSemiPlanar"; + case OMX_COLOR_FormatYUV422PackedSemiPlanar: return "OMX_COLOR_FormatYUV422PackedSemiPlanar"; + case OMX_COLOR_Format18BitBGR666: return "OMX_COLOR_Format18BitBGR666"; + case OMX_COLOR_Format24BitARGB6666: return "OMX_COLOR_Format24BitARGB6666"; + case OMX_COLOR_Format24BitABGR6666: return "OMX_COLOR_Format24BitABGR6666"; + + case OMX_COLOR_FormatAndroidOpaque: return "OMX_COLOR_FormatAndroidOpaque"; + case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: return "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar"; + case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; + case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka: return "OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka"; + case OMX_SEC_COLOR_FormatNV12Tiled: return "OMX_SEC_COLOR_FormatNV12Tiled"; + case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m: return "OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m"; + + // case QOMX_COLOR_FormatYVU420SemiPlanar: return "QOMX_COLOR_FormatYVU420SemiPlanar"; + case QOMX_COLOR_FormatYVU420PackedSemiPlanar32m4ka: return "QOMX_COLOR_FormatYVU420PackedSemiPlanar32m4ka"; + case QOMX_COLOR_FormatYUV420PackedSemiPlanar16m2ka: return "QOMX_COLOR_FormatYUV420PackedSemiPlanar16m2ka"; + // case QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka: return "QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka"; + // case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m: return "QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m"; + case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView: return "QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView"; + case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed: return "QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed"; + case QOMX_COLOR_Format32bitRGBA8888: return "QOMX_COLOR_Format32bitRGBA8888"; + case QOMX_COLOR_Format32bitRGBA8888Compressed: return "QOMX_COLOR_Format32bitRGBA8888Compressed"; + + default: + return "unkn"; + } +} + +void encoder_init(EncoderState *s, const char* filename, int width, int height, int fps, int bitrate, bool h265, bool downscale) { + int err; + + memset(s, 0, sizeof(*s)); + s->filename = filename; + s->width = width; + s->height = height; + s->fps = fps; + mutex_init_reentrant(&s->lock); + + if (!h265) { + s->remuxing = true; + } + + if (downscale) { + s->downscale = true; + s->y_ptr2 = malloc(s->width*s->height); + s->u_ptr2 = malloc(s->width*s->height/4); + s->v_ptr2 = malloc(s->width*s->height/4); + } + + s->segment = -1; + + s->state = OMX_StateLoaded; + + s->codec_config = NULL; + + queue_init(&s->free_in); + queue_init(&s->done_out); + + pthread_mutex_init(&s->state_lock, NULL); + pthread_cond_init(&s->state_cv, NULL); + + if (h265) { + err = OMX_GetHandle(&s->handle, (OMX_STRING)"OMX.qcom.video.encoder.hevc", + s, &omx_callbacks); + } else { + err = OMX_GetHandle(&s->handle, (OMX_STRING)"OMX.qcom.video.encoder.avc", + s, &omx_callbacks); + } + assert(err == OMX_ErrorNone); + // printf("handle: %p\n", s->handle); + + // setup input port + + OMX_PARAM_PORTDEFINITIONTYPE in_port = {0}; + in_port.nSize = sizeof(in_port); + in_port.nPortIndex = (OMX_U32) PORT_INDEX_IN; + err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, + (OMX_PTR) &in_port); + assert(err == OMX_ErrorNone); + + in_port.format.video.nFrameWidth = s->width; + in_port.format.video.nFrameHeight = s->height; + in_port.format.video.nStride = VENUS_Y_STRIDE(COLOR_FMT_NV12, s->width); + in_port.format.video.nSliceHeight = s->height; + // in_port.nBufferSize = (s->width * s->height * 3) / 2; + in_port.nBufferSize = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, s->width, s->height); + in_port.format.video.xFramerate = (s->fps * 65536); + in_port.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + // in_port.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + in_port.format.video.eColorFormat = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; + + err = OMX_SetParameter(s->handle, OMX_IndexParamPortDefinition, + (OMX_PTR) &in_port); + assert(err == OMX_ErrorNone); + + + err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, + (OMX_PTR) &in_port); + assert(err == OMX_ErrorNone); + s->num_in_bufs = in_port.nBufferCountActual; + + // printf("in width: %d, stride: %d\n", + // in_port.format.video.nFrameWidth, in_port.format.video.nStride); + + // setup output port + + OMX_PARAM_PORTDEFINITIONTYPE out_port = {0}; + out_port.nSize = sizeof(out_port); + out_port.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, + (OMX_PTR)&out_port); + assert(err == OMX_ErrorNone); + out_port.format.video.nFrameWidth = s->width; + out_port.format.video.nFrameHeight = s->height; + out_port.format.video.xFramerate = 0; + out_port.format.video.nBitrate = bitrate; + if (h265) { + out_port.format.video.eCompressionFormat = OMX_VIDEO_CodingHEVC; + } else { + out_port.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + } + out_port.format.video.eColorFormat = OMX_COLOR_FormatUnused; + + err = OMX_SetParameter(s->handle, OMX_IndexParamPortDefinition, + (OMX_PTR) &out_port); + assert(err == OMX_ErrorNone); + + err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, + (OMX_PTR) &out_port); + assert(err == OMX_ErrorNone); + s->num_out_bufs = out_port.nBufferCountActual; + + OMX_VIDEO_PARAM_BITRATETYPE bitrate_type = {0}; + bitrate_type.nSize = sizeof(bitrate_type); + bitrate_type.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + err = OMX_GetParameter(s->handle, OMX_IndexParamVideoBitrate, + (OMX_PTR) &bitrate_type); + assert(err == OMX_ErrorNone); + + bitrate_type.eControlRate = OMX_Video_ControlRateVariable; + bitrate_type.nTargetBitrate = bitrate; + + err = OMX_SetParameter(s->handle, OMX_IndexParamVideoBitrate, + (OMX_PTR) &bitrate_type); + assert(err == OMX_ErrorNone); + + if (h265) { + // setup HEVC + OMX_VIDEO_PARAM_HEVCTYPE hecv_type = {0}; + hecv_type.nSize = sizeof(hecv_type); + hecv_type.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + err = OMX_GetParameter(s->handle, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, + (OMX_PTR) &hecv_type); + assert(err == OMX_ErrorNone); + + hecv_type.eProfile = OMX_VIDEO_HEVCProfileMain; + hecv_type.eLevel = OMX_VIDEO_HEVCHighTierLevel5; + + err = OMX_SetParameter(s->handle, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, + (OMX_PTR) &hecv_type); + assert(err == OMX_ErrorNone); + } else { + // setup h264 + OMX_VIDEO_PARAM_AVCTYPE avc = { 0 }; + avc.nSize = sizeof(avc); + avc.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + err = OMX_GetParameter(s->handle, OMX_IndexParamVideoAvc, &avc); + assert(err == OMX_ErrorNone); + + avc.nBFrames = 0; + avc.nPFrames = 15; + + avc.eProfile = OMX_VIDEO_AVCProfileBaseline; + avc.eLevel = OMX_VIDEO_AVCLevel31; + + avc.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB; + avc.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; + + err = OMX_SetParameter(s->handle, OMX_IndexParamVideoAvc, &avc); + assert(err == OMX_ErrorNone); + } + + + // for (int i = 0; ; i++) { + // OMX_VIDEO_PARAM_PORTFORMATTYPE video_port_format = {0}; + // video_port_format.nSize = sizeof(video_port_format); + // video_port_format.nIndex = i; + // video_port_format.nPortIndex = PORT_INDEX_IN; + // if (OMX_GetParameter(s->handle, OMX_IndexParamVideoPortFormat, &video_port_format) != OMX_ErrorNone) + // break; + // printf("in %d: compression 0x%x format 0x%x %s\n", i, + // video_port_format.eCompressionFormat, video_port_format.eColorFormat, + // omx_color_fomat_name(video_port_format.eColorFormat)); + // } + + // for (int i=0; i<32; i++) { + // OMX_VIDEO_PARAM_PROFILELEVELTYPE params = {0}; + // params.nSize = sizeof(params); + // params.nPortIndex = PORT_INDEX_OUT; + // params.nProfileIndex = i; + // if (OMX_GetParameter(s->handle, OMX_IndexParamVideoProfileLevelQuerySupported, ¶ms) != OMX_ErrorNone) + // break; + // printf("profile %d level 0x%x\n", params.eProfile, params.eLevel); + // } + + err = OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateIdle, NULL); + assert(err == OMX_ErrorNone); + + s->in_buf_headers = calloc(s->num_in_bufs, sizeof(OMX_BUFFERHEADERTYPE*)); + for (int i=0; inum_in_bufs; i++) { + err = OMX_AllocateBuffer(s->handle, &s->in_buf_headers[i], PORT_INDEX_IN, s, + in_port.nBufferSize); + assert(err == OMX_ErrorNone); + } + + s->out_buf_headers = calloc(s->num_out_bufs, sizeof(OMX_BUFFERHEADERTYPE*)); + for (int i=0; inum_out_bufs; i++) { + err = OMX_AllocateBuffer(s->handle, &s->out_buf_headers[i], PORT_INDEX_OUT, s, + out_port.nBufferSize); + assert(err == OMX_ErrorNone); + } + + wait_for_state(s, OMX_StateIdle); + + err = OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateExecuting, NULL); + assert(err == OMX_ErrorNone); + + wait_for_state(s, OMX_StateExecuting); + + // give omx all the output buffers + for (int i = 0; i < s->num_out_bufs; i++) { + // printf("fill %p\n", s->out_buf_headers[i]); + err = OMX_FillThisBuffer(s->handle, s->out_buf_headers[i]); + assert(err == OMX_ErrorNone); + } + + // fill the input free queue + for (int i = 0; i < s->num_in_bufs; i++) { + queue_push(&s->free_in, (void*)s->in_buf_headers[i]); + } +} + +static void handle_out_buf(EncoderState *s, OMX_BUFFERHEADERTYPE *out_buf) { + int err; + uint8_t *buf_data = out_buf->pBuffer + out_buf->nOffset; + + if (out_buf->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + if (s->codec_config_len < out_buf->nFilledLen) { + s->codec_config = realloc(s->codec_config, out_buf->nFilledLen); + } + s->codec_config_len = out_buf->nFilledLen; + memcpy(s->codec_config, buf_data, out_buf->nFilledLen); + } + + if (s->stream_sock_raw) { + uint64_t current_time = nanos_since_boot(); + uint64_t diff = current_time - out_buf->nTimeStamp*1000LL; + double msdiff = (double) diff / 1000000.0; + // printf("encoded latency to tsEof: %f\n", msdiff); + zmq_send(s->stream_sock_raw, &out_buf->nTimeStamp, sizeof(out_buf->nTimeStamp), ZMQ_SNDMORE); + zmq_send(s->stream_sock_raw, buf_data, out_buf->nFilledLen, 0); + } + + if (s->of) { + //printf("write %d flags 0x%x\n", out_buf->nFilledLen, out_buf->nFlags); + fwrite(buf_data, out_buf->nFilledLen, 1, s->of); + } + + if (s->remuxing) { + if (!s->wrote_codec_config && s->codec_config_len > 0) { + if (s->codec_ctx->extradata_size < s->codec_config_len) { + s->codec_ctx->extradata = realloc(s->codec_ctx->extradata, s->codec_config_len + AV_INPUT_BUFFER_PADDING_SIZE); + } + s->codec_ctx->extradata_size = s->codec_config_len; + memcpy(s->codec_ctx->extradata, s->codec_config, s->codec_config_len); + memset(s->codec_ctx->extradata + s->codec_ctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); + + err = avcodec_parameters_from_context(s->out_stream->codecpar, s->codec_ctx); + assert(err >= 0); + err = avformat_write_header(s->ofmt_ctx, NULL); + assert(err >= 0); + + s->wrote_codec_config = true; + } + + if (out_buf->nTimeStamp > 0) { + // input timestamps are in microseconds + AVRational in_timebase = {1, 1000000}; + + AVPacket pkt; + av_init_packet(&pkt); + pkt.data = buf_data; + pkt.size = out_buf->nFilledLen; + pkt.pts = pkt.dts = av_rescale_q_rnd(out_buf->nTimeStamp, in_timebase, s->ofmt_ctx->streams[0]->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); + pkt.duration = av_rescale_q(50*1000, in_timebase, s->ofmt_ctx->streams[0]->time_base); + + if (out_buf->nFlags & OMX_BUFFERFLAG_SYNCFRAME) { + pkt.flags |= AV_PKT_FLAG_KEY; + } + + err = av_write_frame(s->ofmt_ctx, &pkt); + if (err < 0) { LOGW("ts encoder write issue"); } + + av_free_packet(&pkt); + } + } + + // give omx back the buffer + err = OMX_FillThisBuffer(s->handle, out_buf); + assert(err == OMX_ErrorNone); +} + +int encoder_encode_frame(EncoderState *s, + const uint8_t *y_ptr, const uint8_t *u_ptr, const uint8_t *v_ptr, + int in_width, int in_height, + int *frame_segment, VIPCBufExtra *extra) { + int err; + pthread_mutex_lock(&s->lock); + + if (s->opening) { + encoder_open(s, s->next_path); + s->opening = false; + } + + if (!s->open) { + pthread_mutex_unlock(&s->lock); + return -1; + } + + // this sometimes freezes... put it outside the encoder lock so we can still trigger rotates... + // THIS IS A REALLY BAD IDEA, but apparently the race has to happen 30 times to trigger this + pthread_mutex_unlock(&s->lock); + OMX_BUFFERHEADERTYPE* in_buf = queue_pop(&s->free_in); + pthread_mutex_lock(&s->lock); + + if (s->rotating) { + encoder_close(s); + encoder_open(s, s->next_path); + s->segment = s->next_segment; + s->rotating = false; + } + + int ret = s->counter; + + uint8_t *in_buf_ptr = in_buf->pBuffer; + // printf("in_buf ptr %p\n", in_buf_ptr); + + uint8_t *in_y_ptr = in_buf_ptr; + int in_y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, s->width); + int in_uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, s->width); + // uint8_t *in_uv_ptr = in_buf_ptr + (s->width * s->height); + uint8_t *in_uv_ptr = in_buf_ptr + (in_y_stride * VENUS_Y_SCANLINES(COLOR_FMT_NV12, s->height)); + + if (s->downscale) { + I420Scale(y_ptr, in_width, + u_ptr, in_width/2, + v_ptr, in_width/2, + in_width, in_height, + s->y_ptr2, s->width, + s->u_ptr2, s->width/2, + s->v_ptr2, s->width/2, + s->width, s->height, + kFilterNone); + y_ptr = s->y_ptr2; + u_ptr = s->u_ptr2; + v_ptr = s->v_ptr2; + } + err = I420ToNV12(y_ptr, s->width, + u_ptr, s->width/2, + v_ptr, s->width/2, + in_y_ptr, in_y_stride, + in_uv_ptr, in_uv_stride, + s->width, s->height); + assert(err == 0); + + // in_buf->nFilledLen = (s->width*s->height) + (s->width*s->height/2); + in_buf->nFilledLen = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, s->width, s->height); + in_buf->nFlags = OMX_BUFFERFLAG_ENDOFFRAME; + in_buf->nOffset = 0; + in_buf->nTimeStamp = extra->timestamp_eof/1000LL; // OMX_TICKS, in microseconds + + err = OMX_EmptyThisBuffer(s->handle, in_buf); + assert(err == OMX_ErrorNone); + + // pump output + while (true) { + OMX_BUFFERHEADERTYPE *out_buf = queue_try_pop(&s->done_out); + if (!out_buf) { + break; + } + handle_out_buf(s, out_buf); + } + + s->dirty = true; + + s->counter++; + + if (frame_segment) { + *frame_segment = s->segment; + } + + if (s->closing) { + encoder_close(s); + s->closing = false; + } + + pthread_mutex_unlock(&s->lock); + return ret; +} + +void encoder_open(EncoderState *s, const char* path) { + int err; + + pthread_mutex_lock(&s->lock); + + snprintf(s->vid_path, sizeof(s->vid_path), "%s/%s", path, s->filename); + + if (s->remuxing) { + avformat_alloc_output_context2(&s->ofmt_ctx, NULL, NULL, s->vid_path); + assert(s->ofmt_ctx); + + s->out_stream = avformat_new_stream(s->ofmt_ctx, NULL); + assert(s->out_stream); + + // set codec correctly + av_register_all(); + + AVCodec *codec = NULL; + codec = avcodec_find_encoder(AV_CODEC_ID_H264); + assert(codec); + + s->codec_ctx = avcodec_alloc_context3(codec); + assert(s->codec_ctx); + s->codec_ctx->width = s->width; + s->codec_ctx->height = s->height; + s->codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P; + s->codec_ctx->time_base = (AVRational){ 1, s->fps }; + + err = avio_open(&s->ofmt_ctx->pb, s->vid_path, AVIO_FLAG_WRITE); + assert(err >= 0); + + s->wrote_codec_config = false; + } else { + s->of = fopen(s->vid_path, "wb"); + assert(s->of); + if (s->codec_config_len > 0) { + fwrite(s->codec_config, s->codec_config_len, 1, s->of); + } + } + + // create camera lock file + snprintf(s->lock_path, sizeof(s->lock_path), "%s/%s.lock", path, s->filename); + int lock_fd = open(s->lock_path, O_RDWR | O_CREAT, 0777); + assert(lock_fd >= 0); + close(lock_fd); + + s->open = true; + s->counter = 0; + + pthread_mutex_unlock(&s->lock); +} + +void encoder_close(EncoderState *s) { + int err; + + pthread_mutex_lock(&s->lock); + + if (s->open) { + if (s->dirty) { + // drain output only if there could be frames in the encoder + + OMX_BUFFERHEADERTYPE* in_buf = queue_pop(&s->free_in); + in_buf->nFilledLen = 0; + in_buf->nOffset = 0; + in_buf->nFlags = OMX_BUFFERFLAG_EOS; + in_buf->nTimeStamp = 0; + + err = OMX_EmptyThisBuffer(s->handle, in_buf); + assert(err == OMX_ErrorNone); + + while (true) { + OMX_BUFFERHEADERTYPE *out_buf = queue_pop(&s->done_out); + + handle_out_buf(s, out_buf); + + if (out_buf->nFlags & OMX_BUFFERFLAG_EOS) { + break; + } + } + s->dirty = false; + } + + if (s->remuxing) { + av_write_trailer(s->ofmt_ctx); + avio_closep(&s->ofmt_ctx->pb); + avformat_free_context(s->ofmt_ctx); + } else { + fclose(s->of); + } + unlink(s->lock_path); + } + s->open = false; + + pthread_mutex_unlock(&s->lock); +} + +void encoder_rotate(EncoderState *s, const char* new_path, int new_segment) { + pthread_mutex_lock(&s->lock); + snprintf(s->next_path, sizeof(s->next_path), "%s", new_path); + s->next_segment = new_segment; + if (s->open) { + if (s->next_segment == -1) { + s->closing = true; + } else { + s->rotating = true; + } + } else { + s->segment = s->next_segment; + s->opening = true; + } + pthread_mutex_unlock(&s->lock); +} + +void encoder_destroy(EncoderState *s) { + int err; + + assert(!s->open); + + err = OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateIdle, NULL); + assert(err == OMX_ErrorNone); + + wait_for_state(s, OMX_StateIdle); + + err = OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateLoaded, NULL); + assert(err == OMX_ErrorNone); + + for (int i=0; inum_in_bufs; i++) { + err = OMX_FreeBuffer(s->handle, PORT_INDEX_IN, s->in_buf_headers[i]); + assert(err == OMX_ErrorNone); + } + free(s->in_buf_headers); + + for (int i=0; inum_out_bufs; i++) { + err = OMX_FreeBuffer(s->handle, PORT_INDEX_OUT, s->out_buf_headers[i]); + assert(err == OMX_ErrorNone); + } + free(s->out_buf_headers); + + wait_for_state(s, OMX_StateLoaded); + + err = OMX_FreeHandle(s->handle); + assert(err == OMX_ErrorNone); + + if (s->downscale) { + free(s->y_ptr2); + free(s->u_ptr2); + free(s->v_ptr2); + } +} + +#if 0 + +// cd one/selfdrive/visiond +// clang +// -fPIC -pie +// -std=gnu11 -O2 -g +// -o encoder +// -I ~/one/selfdrive +// -I ~/one/phonelibs/openmax/include +// -I ~/one/phonelibs/libyuv/include +// -lOmxVenc -lOmxCore -llog +// encoder.c +// buffering.c +// -L ~/one/phonelibs/libyuv/lib -l:libyuv.a + +int main() { + int err; + + EncoderState state; + EncoderState *s = &state; + memset(s, 0, sizeof(*s)); + + int w = 1164; + int h = 874; + + encoder_init(s, w, h, 20); + printf("inited\n"); + + encoder_open(s, "/sdcard/t1"); + + // uint8_t *tmpy = malloc(640*480); + // uint8_t *tmpu = malloc((640/2)*(480/2)); + // uint8_t *tmpv = malloc((640/2)*(480/2)); + + // memset(tmpy, 0, 640*480); + // // memset(tmpu, 0xff, (640/2)*(480/2)); + // memset(tmpv, 0, (640/2)*(480/2)); + +// #if 0 + // FILE *infile = fopen("/sdcard/camera_t2.yuv", "rb"); + uint8_t *inbuf = malloc(w*h*3/2); + memset(inbuf, 0, w*h*3/2); + + for (int i=0; i<20*3+5; i++) { + + // fread(inbuf, w*h*3/2, 1, infile); + + uint8_t *tmpy = inbuf; + uint8_t *tmpu = inbuf + w*h; + uint8_t *tmpv = inbuf + w*h + (w/2)*(h/2); + + for (int y=0; yof); + // s->of = fopen("/sdcard/tmpout2.hevc", "wb"); + // if (s->codec_config) { + // fwrite(s->codec_config, s->codec_config_len, 1, s->of); + // } + // encoder_open(s, "/sdcard/t1"); + + encoder_rotate(s, "/sdcard/t2"); + + for (int i=0; i<20*3+5; i++) { + + // fread(inbuf, w*h*3/2, 1, infile); + + uint8_t *tmpy = inbuf; + uint8_t *tmpu = inbuf + w*h; + uint8_t *tmpv = inbuf + w*h + (w/2)*(h/2); + + for (int y=0; y +#include +#include + +#include + +#include +#include + +#include "common/cqueue.h" +#include "common/visionipc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct EncoderState { + pthread_mutex_t lock; + int width, height, fps; + const char* path; + char vid_path[1024]; + char lock_path[1024]; + bool open; + bool dirty; + int counter; + int segment; + + bool rotating; + bool closing; + bool opening; + char next_path[1024]; + int next_segment; + + const char* filename; + FILE *of; + + size_t codec_config_len; + uint8_t *codec_config; + bool wrote_codec_config; + + pthread_mutex_t state_lock; + pthread_cond_t state_cv; + OMX_STATETYPE state; + + OMX_HANDLETYPE handle; + + int num_in_bufs; + OMX_BUFFERHEADERTYPE** in_buf_headers; + + int num_out_bufs; + OMX_BUFFERHEADERTYPE** out_buf_headers; + + Queue free_in; + Queue done_out; + + void *stream_sock_raw; + + AVFormatContext *ofmt_ctx; + AVCodecContext *codec_ctx; + AVStream *out_stream; + bool remuxing; + + void *zmq_ctx; + + bool downscale; + uint8_t *y_ptr2, *u_ptr2, *v_ptr2; +} EncoderState; + +void encoder_init(EncoderState *s, const char* filename, int width, int height, int fps, int bitrate, bool h265, bool downscale); +int encoder_encode_frame(EncoderState *s, + const uint8_t *y_ptr, const uint8_t *u_ptr, const uint8_t *v_ptr, + int in_width, int in_height, + int *frame_segment, VIPCBufExtra *extra); +void encoder_open(EncoderState *s, const char* path); +void encoder_rotate(EncoderState *s, const char* new_path, int new_segment); +void encoder_close(EncoderState *s); +void encoder_destroy(EncoderState *s); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/selfdrive/loggerd/frame_logger.h b/selfdrive/loggerd/frame_logger.h new file mode 100644 index 00000000000000..bfc0681b756af0 --- /dev/null +++ b/selfdrive/loggerd/frame_logger.h @@ -0,0 +1,81 @@ +#ifndef FRAMELOGGER_H +#define FRAMELOGGER_H + +#include + +#include +#include + +class FrameLogger { +public: + virtual ~FrameLogger() {} + + virtual void Open(const std::string &path) = 0; + virtual void Close() = 0; + + int LogFrame(uint64_t ts, const uint8_t *y_ptr, const uint8_t *u_ptr, const uint8_t *v_ptr, int *frame_segment) { + std::lock_guard guard(lock); + + if (opening) { + Open(next_path); + opening = false; + } + + if (!is_open) return -1; + + if (rotating) { + Close(); + Open(next_path); + segment = next_segment; + rotating = false; + } + + int ret = ProcessFrame(ts, y_ptr, u_ptr, v_ptr); + + if (ret >= 0 && frame_segment) { + *frame_segment = segment; + } + + if (closing) { + Close(); + closing = false; + } + + return ret; + } + + void Rotate(const std::string &new_path, int new_segment) { + std::lock_guard guard(lock); + + next_path = new_path; + next_segment = new_segment; + if (is_open) { + if (next_segment == -1) { + closing = true; + } else { + rotating = true; + } + } else { + segment = next_segment; + opening = true; + } + } + +protected: + + virtual int ProcessFrame(uint64_t ts, const uint8_t *y_ptr, const uint8_t *u_ptr, const uint8_t *v_ptr) = 0; + + std::recursive_mutex lock; + + bool is_open = false; + int segment = -1; + + std::string vid_path, lock_path; + +private: + int next_segment = -1; + bool opening = false, closing = false, rotating = false; + std::string next_path; +}; + +#endif diff --git a/selfdrive/loggerd/include/msm_media_info.h b/selfdrive/loggerd/include/msm_media_info.h new file mode 100644 index 00000000000000..39dceb2c49f147 --- /dev/null +++ b/selfdrive/loggerd/include/msm_media_info.h @@ -0,0 +1,819 @@ +#ifndef __MEDIA_INFO_H__ +#define __MEDIA_INFO_H__ + +#ifndef MSM_MEDIA_ALIGN +#define MSM_MEDIA_ALIGN(__sz, __align) (((__sz) + (__align-1)) & (~(__align-1))) +#endif + +#ifndef MSM_MEDIA_ROUNDUP +#define MSM_MEDIA_ROUNDUP(__sz, __r) (((__sz) + ((__r) - 1)) / (__r)) +#endif + +#ifndef MSM_MEDIA_MAX +#define MSM_MEDIA_MAX(__a, __b) ((__a) > (__b)?(__a):(__b)) +#endif + +enum color_fmts { + /* Venus NV12: + * YUV 4:2:0 image with a plane of 8 bit Y samples followed + * by an interleaved U/V plane containing 8 bit 2x2 subsampled + * colour difference samples. + * + * <-------- Y/UV_Stride --------> + * <------- Width -------> + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . ^ ^ + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . Height | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | Y_Scanlines + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * U V U V U V U V U V U V . . . . ^ + * U V U V U V U V U V U V . . . . | + * U V U V U V U V U V U V . . . . | + * U V U V U V U V U V U V . . . . UV_Scanlines + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . . . --> Buffer size alignment + * + * Y_Stride : Width aligned to 128 + * UV_Stride : Width aligned to 128 + * Y_Scanlines: Height aligned to 32 + * UV_Scanlines: Height/2 aligned to 16 + * Extradata: Arbitrary (software-imposed) padding + * Total size = align((Y_Stride * Y_Scanlines + * + UV_Stride * UV_Scanlines + * + max(Extradata, Y_Stride * 8), 4096) + */ + COLOR_FMT_NV12, + + /* Venus NV21: + * YUV 4:2:0 image with a plane of 8 bit Y samples followed + * by an interleaved V/U plane containing 8 bit 2x2 subsampled + * colour difference samples. + * + * <-------- Y/UV_Stride --------> + * <------- Width -------> + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . ^ ^ + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . Height | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | Y_Scanlines + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * V U V U V U V U V U V U . . . . ^ + * V U V U V U V U V U V U . . . . | + * V U V U V U V U V U V U . . . . | + * V U V U V U V U V U V U . . . . UV_Scanlines + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . . . --> Padding & Buffer size alignment + * + * Y_Stride : Width aligned to 128 + * UV_Stride : Width aligned to 128 + * Y_Scanlines: Height aligned to 32 + * UV_Scanlines: Height/2 aligned to 16 + * Extradata: Arbitrary (software-imposed) padding + * Total size = align((Y_Stride * Y_Scanlines + * + UV_Stride * UV_Scanlines + * + max(Extradata, Y_Stride * 8), 4096) + */ + COLOR_FMT_NV21, + /* Venus NV12_MVTB: + * Two YUV 4:2:0 images/views one after the other + * in a top-bottom layout, same as NV12 + * with a plane of 8 bit Y samples followed + * by an interleaved U/V plane containing 8 bit 2x2 subsampled + * colour difference samples. + * + * + * <-------- Y/UV_Stride --------> + * <------- Width -------> + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . ^ ^ ^ + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . Height | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | Y_Scanlines | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . V | | + * . . . . . . . . . . . . . . . . | View_1 + * . . . . . . . . . . . . . . . . | | + * . . . . . . . . . . . . . . . . | | + * . . . . . . . . . . . . . . . . V | + * U V U V U V U V U V U V . . . . ^ | + * U V U V U V U V U V U V . . . . | | + * U V U V U V U V U V U V . . . . | | + * U V U V U V U V U V U V . . . . UV_Scanlines | + * . . . . . . . . . . . . . . . . | | + * . . . . . . . . . . . . . . . . V V + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . ^ ^ ^ + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . Height | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | Y_Scanlines | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | | + * Y Y Y Y Y Y Y Y Y Y Y Y . . . . V | | + * . . . . . . . . . . . . . . . . | View_2 + * . . . . . . . . . . . . . . . . | | + * . . . . . . . . . . . . . . . . | | + * . . . . . . . . . . . . . . . . V | + * U V U V U V U V U V U V . . . . ^ | + * U V U V U V U V U V U V . . . . | | + * U V U V U V U V U V U V . . . . | | + * U V U V U V U V U V U V . . . . UV_Scanlines | + * . . . . . . . . . . . . . . . . | | + * . . . . . . . . . . . . . . . . V V + * . . . . . . . . . . . . . . . . --> Buffer size alignment + * + * Y_Stride : Width aligned to 128 + * UV_Stride : Width aligned to 128 + * Y_Scanlines: Height aligned to 32 + * UV_Scanlines: Height/2 aligned to 16 + * View_1 begin at: 0 (zero) + * View_2 begin at: Y_Stride * Y_Scanlines + UV_Stride * UV_Scanlines + * Extradata: Arbitrary (software-imposed) padding + * Total size = align((2*(Y_Stride * Y_Scanlines) + * + 2*(UV_Stride * UV_Scanlines) + Extradata), 4096) + */ + COLOR_FMT_NV12_MVTB, + /* Venus NV12 UBWC: + * Compressed Macro-tile format for NV12. + * Contains 4 planes in the following order - + * (A) Y_Meta_Plane + * (B) Y_UBWC_Plane + * (C) UV_Meta_Plane + * (D) UV_UBWC_Plane + * + * Y_Meta_Plane consists of meta information to decode compressed + * tile data in Y_UBWC_Plane. + * Y_UBWC_Plane consists of Y data in compressed macro-tile format. + * UBWC decoder block will use the Y_Meta_Plane data together with + * Y_UBWC_Plane data to produce loss-less uncompressed 8 bit Y samples. + * + * UV_Meta_Plane consists of meta information to decode compressed + * tile data in UV_UBWC_Plane. + * UV_UBWC_Plane consists of UV data in compressed macro-tile format. + * UBWC decoder block will use UV_Meta_Plane data together with + * UV_UBWC_Plane data to produce loss-less uncompressed 8 bit 2x2 + * subsampled color difference samples. + * + * Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable + * and randomly accessible. There is no dependency between tiles. + * + * <----- Y_Meta_Stride ----> + * <-------- Width ------> + * M M M M M M M M M M M M . . ^ ^ + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . Height | + * M M M M M M M M M M M M . . | Meta_Y_Scanlines + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . V | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . V + * <--Compressed tile Y Stride---> + * <------- Width -------> + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^ + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . Height | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile_Y_Scanlines + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . . . V + * <----- UV_Meta_Stride ----> + * M M M M M M M M M M M M . . ^ + * M M M M M M M M M M M M . . | + * M M M M M M M M M M M M . . | + * M M M M M M M M M M M M . . M_UV_Scanlines + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * <--Compressed tile UV Stride---> + * U* V* U* V* U* V* U* V* . . . . ^ + * U* V* U* V* U* V* U* V* . . . . | + * U* V* U* V* U* V* U* V* . . . . | + * U* V* U* V* U* V* U* V* . . . . UV_Scanlines + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * + * Y_Stride = align(Width, 128) + * UV_Stride = align(Width, 128) + * Y_Scanlines = align(Height, 32) + * UV_Scanlines = align(Height/2, 16) + * Y_UBWC_Plane_size = align(Y_Stride * Y_Scanlines, 4096) + * UV_UBWC_Plane_size = align(UV_Stride * UV_Scanlines, 4096) + * Y_Meta_Stride = align(roundup(Width, Y_TileWidth), 64) + * Y_Meta_Scanlines = align(roundup(Height, Y_TileHeight), 16) + * Y_Meta_Plane_size = align(Y_Meta_Stride * Y_Meta_Scanlines, 4096) + * UV_Meta_Stride = align(roundup(Width, UV_TileWidth), 64) + * UV_Meta_Scanlines = align(roundup(Height, UV_TileHeight), 16) + * UV_Meta_Plane_size = align(UV_Meta_Stride * UV_Meta_Scanlines, 4096) + * Extradata = 8k + * + * Total size = align( Y_UBWC_Plane_size + UV_UBWC_Plane_size + + * Y_Meta_Plane_size + UV_Meta_Plane_size + * + max(Extradata, Y_Stride * 48), 4096) + */ + COLOR_FMT_NV12_UBWC, + /* Venus NV12 10-bit UBWC: + * Compressed Macro-tile format for NV12. + * Contains 4 planes in the following order - + * (A) Y_Meta_Plane + * (B) Y_UBWC_Plane + * (C) UV_Meta_Plane + * (D) UV_UBWC_Plane + * + * Y_Meta_Plane consists of meta information to decode compressed + * tile data in Y_UBWC_Plane. + * Y_UBWC_Plane consists of Y data in compressed macro-tile format. + * UBWC decoder block will use the Y_Meta_Plane data together with + * Y_UBWC_Plane data to produce loss-less uncompressed 10 bit Y samples. + * + * UV_Meta_Plane consists of meta information to decode compressed + * tile data in UV_UBWC_Plane. + * UV_UBWC_Plane consists of UV data in compressed macro-tile format. + * UBWC decoder block will use UV_Meta_Plane data together with + * UV_UBWC_Plane data to produce loss-less uncompressed 10 bit 2x2 + * subsampled color difference samples. + * + * Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable + * and randomly accessible. There is no dependency between tiles. + * + * <----- Y_Meta_Stride -----> + * <-------- Width ------> + * M M M M M M M M M M M M . . ^ ^ + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . Height | + * M M M M M M M M M M M M . . | Meta_Y_Scanlines + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . V | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . V + * <--Compressed tile Y Stride---> + * <------- Width -------> + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^ + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . Height | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile_Y_Scanlines + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | + * Y* Y* Y* Y* Y* Y* Y* Y* . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . . . V + * <----- UV_Meta_Stride ----> + * M M M M M M M M M M M M . . ^ + * M M M M M M M M M M M M . . | + * M M M M M M M M M M M M . . | + * M M M M M M M M M M M M . . M_UV_Scanlines + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * <--Compressed tile UV Stride---> + * U* V* U* V* U* V* U* V* . . . . ^ + * U* V* U* V* U* V* U* V* . . . . | + * U* V* U* V* U* V* U* V* . . . . | + * U* V* U* V* U* V* U* V* . . . . UV_Scanlines + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * + * + * Y_Stride = align(Width * 4/3, 128) + * UV_Stride = align(Width * 4/3, 128) + * Y_Scanlines = align(Height, 32) + * UV_Scanlines = align(Height/2, 16) + * Y_UBWC_Plane_Size = align(Y_Stride * Y_Scanlines, 4096) + * UV_UBWC_Plane_Size = align(UV_Stride * UV_Scanlines, 4096) + * Y_Meta_Stride = align(roundup(Width, Y_TileWidth), 64) + * Y_Meta_Scanlines = align(roundup(Height, Y_TileHeight), 16) + * Y_Meta_Plane_size = align(Y_Meta_Stride * Y_Meta_Scanlines, 4096) + * UV_Meta_Stride = align(roundup(Width, UV_TileWidth), 64) + * UV_Meta_Scanlines = align(roundup(Height, UV_TileHeight), 16) + * UV_Meta_Plane_size = align(UV_Meta_Stride * UV_Meta_Scanlines, 4096) + * Extradata = 8k + * + * Total size = align(Y_UBWC_Plane_size + UV_UBWC_Plane_size + + * Y_Meta_Plane_size + UV_Meta_Plane_size + * + max(Extradata, Y_Stride * 48), 4096) + */ + COLOR_FMT_NV12_BPP10_UBWC, + /* Venus RGBA8888 format: + * Contains 1 plane in the following order - + * (A) RGBA plane + * + * <-------- RGB_Stride --------> + * <------- Width -------> + * R R R R R R R R R R R R . . . . ^ ^ + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . Height | + * R R R R R R R R R R R R . . . . | RGB_Scanlines + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . V + * + * RGB_Stride = align(Width * 4, 128) + * RGB_Scanlines = align(Height, 32) + * RGB_Plane_size = align(RGB_Stride * RGB_Scanlines, 4096) + * Extradata = 8k + * + * Total size = align(RGB_Plane_size + Extradata, 4096) + */ + COLOR_FMT_RGBA8888, + /* Venus RGBA8888 UBWC format: + * Contains 2 planes in the following order - + * (A) Meta plane + * (B) RGBA plane + * + * <--- RGB_Meta_Stride ----> + * <-------- Width ------> + * M M M M M M M M M M M M . . ^ ^ + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . Height | + * M M M M M M M M M M M M . . | Meta_RGB_Scanlines + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . | | + * M M M M M M M M M M M M . . V | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . V + * <-------- RGB_Stride --------> + * <------- Width -------> + * R R R R R R R R R R R R . . . . ^ ^ + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . Height | + * R R R R R R R R R R R R . . . . | RGB_Scanlines + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . | | + * R R R R R R R R R R R R . . . . V | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . | + * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k + * . . . . . . . . . . . . . . . . V + * + * RGB_Stride = align(Width * 4, 128) + * RGB_Scanlines = align(Height, 32) + * RGB_Plane_size = align(RGB_Stride * RGB_Scanlines, 4096) + * RGB_Meta_Stride = align(roundup(Width, RGB_TileWidth), 64) + * RGB_Meta_Scanline = align(roundup(Height, RGB_TileHeight), 16) + * RGB_Meta_Plane_size = align(RGB_Meta_Stride * + * RGB_Meta_Scanlines, 4096) + * Extradata = 8k + * + * Total size = align(RGB_Meta_Plane_size + RGB_Plane_size + + * Extradata, 4096) + */ + COLOR_FMT_RGBA8888_UBWC, +}; + +static inline unsigned int VENUS_EXTRADATA_SIZE(int width, int height) +{ + (void)height; + (void)width; + + /* + * In the future, calculate the size based on the w/h but just + * hardcode it for now since 16K satisfies all current usecases. + */ + return 16 * 1024; +} + +static inline unsigned int VENUS_Y_STRIDE(int color_fmt, int width) +{ + unsigned int alignment, stride = 0; + if (!width) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV21: + case COLOR_FMT_NV12: + case COLOR_FMT_NV12_MVTB: + case COLOR_FMT_NV12_UBWC: + alignment = 128; + stride = MSM_MEDIA_ALIGN(width, alignment); + break; + case COLOR_FMT_NV12_BPP10_UBWC: + alignment = 256; + stride = MSM_MEDIA_ALIGN(width, 192); + stride = MSM_MEDIA_ALIGN(stride * 4/3, alignment); + break; + default: + break; + } +invalid_input: + return stride; +} + +static inline unsigned int VENUS_UV_STRIDE(int color_fmt, int width) +{ + unsigned int alignment, stride = 0; + if (!width) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV21: + case COLOR_FMT_NV12: + case COLOR_FMT_NV12_MVTB: + case COLOR_FMT_NV12_UBWC: + alignment = 128; + stride = MSM_MEDIA_ALIGN(width, alignment); + break; + case COLOR_FMT_NV12_BPP10_UBWC: + alignment = 256; + stride = MSM_MEDIA_ALIGN(width, 192); + stride = MSM_MEDIA_ALIGN(stride * 4/3, alignment); + break; + default: + break; + } +invalid_input: + return stride; +} + +static inline unsigned int VENUS_Y_SCANLINES(int color_fmt, int height) +{ + unsigned int alignment, sclines = 0; + if (!height) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV21: + case COLOR_FMT_NV12: + case COLOR_FMT_NV12_MVTB: + case COLOR_FMT_NV12_UBWC: + alignment = 32; + break; + case COLOR_FMT_NV12_BPP10_UBWC: + alignment = 16; + break; + default: + return 0; + } + sclines = MSM_MEDIA_ALIGN(height, alignment); +invalid_input: + return sclines; +} + +static inline unsigned int VENUS_UV_SCANLINES(int color_fmt, int height) +{ + unsigned int alignment, sclines = 0; + if (!height) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV21: + case COLOR_FMT_NV12: + case COLOR_FMT_NV12_MVTB: + case COLOR_FMT_NV12_BPP10_UBWC: + alignment = 16; + break; + case COLOR_FMT_NV12_UBWC: + alignment = 32; + break; + default: + goto invalid_input; + } + + sclines = MSM_MEDIA_ALIGN(height / 2, alignment); + +invalid_input: + return sclines; +} + +static inline unsigned int VENUS_Y_META_STRIDE(int color_fmt, int width) +{ + int y_tile_width = 0, y_meta_stride = 0; + + if (!width) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV12_UBWC: + y_tile_width = 32; + break; + case COLOR_FMT_NV12_BPP10_UBWC: + y_tile_width = 48; + break; + default: + goto invalid_input; + } + + y_meta_stride = MSM_MEDIA_ROUNDUP(width, y_tile_width); + y_meta_stride = MSM_MEDIA_ALIGN(y_meta_stride, 64); + +invalid_input: + return y_meta_stride; +} + +static inline unsigned int VENUS_Y_META_SCANLINES(int color_fmt, int height) +{ + int y_tile_height = 0, y_meta_scanlines = 0; + + if (!height) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV12_UBWC: + y_tile_height = 8; + break; + case COLOR_FMT_NV12_BPP10_UBWC: + y_tile_height = 4; + break; + default: + goto invalid_input; + } + + y_meta_scanlines = MSM_MEDIA_ROUNDUP(height, y_tile_height); + y_meta_scanlines = MSM_MEDIA_ALIGN(y_meta_scanlines, 16); + +invalid_input: + return y_meta_scanlines; +} + +static inline unsigned int VENUS_UV_META_STRIDE(int color_fmt, int width) +{ + int uv_tile_width = 0, uv_meta_stride = 0; + + if (!width) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV12_UBWC: + uv_tile_width = 16; + break; + case COLOR_FMT_NV12_BPP10_UBWC: + uv_tile_width = 24; + break; + default: + goto invalid_input; + } + + uv_meta_stride = MSM_MEDIA_ROUNDUP(width / 2, uv_tile_width); + uv_meta_stride = MSM_MEDIA_ALIGN(uv_meta_stride, 64); + +invalid_input: + return uv_meta_stride; +} + +static inline unsigned int VENUS_UV_META_SCANLINES(int color_fmt, int height) +{ + int uv_tile_height = 0, uv_meta_scanlines = 0; + + if (!height) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_NV12_UBWC: + uv_tile_height = 8; + break; + case COLOR_FMT_NV12_BPP10_UBWC: + uv_tile_height = 4; + break; + default: + goto invalid_input; + } + + uv_meta_scanlines = MSM_MEDIA_ROUNDUP(height / 2, uv_tile_height); + uv_meta_scanlines = MSM_MEDIA_ALIGN(uv_meta_scanlines, 16); + +invalid_input: + return uv_meta_scanlines; +} + +static inline unsigned int VENUS_RGB_STRIDE(int color_fmt, int width) +{ + unsigned int alignment = 0, stride = 0; + if (!width) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_RGBA8888: + alignment = 128; + break; + case COLOR_FMT_RGBA8888_UBWC: + alignment = 256; + break; + default: + goto invalid_input; + } + + stride = MSM_MEDIA_ALIGN(width * 4, alignment); + +invalid_input: + return stride; +} + +static inline unsigned int VENUS_RGB_SCANLINES(int color_fmt, int height) +{ + unsigned int alignment = 0, scanlines = 0; + + if (!height) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_RGBA8888: + alignment = 32; + break; + case COLOR_FMT_RGBA8888_UBWC: + alignment = 16; + break; + default: + goto invalid_input; + } + + scanlines = MSM_MEDIA_ALIGN(height, alignment); + +invalid_input: + return scanlines; +} + +static inline unsigned int VENUS_RGB_META_STRIDE(int color_fmt, int width) +{ + int rgb_tile_width = 0, rgb_meta_stride = 0; + + if (!width) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_RGBA8888_UBWC: + rgb_tile_width = 16; + break; + default: + goto invalid_input; + } + + rgb_meta_stride = MSM_MEDIA_ROUNDUP(width, rgb_tile_width); + rgb_meta_stride = MSM_MEDIA_ALIGN(rgb_meta_stride, 64); + +invalid_input: + return rgb_meta_stride; +} + +static inline unsigned int VENUS_RGB_META_SCANLINES(int color_fmt, int height) +{ + int rgb_tile_height = 0, rgb_meta_scanlines = 0; + + if (!height) + goto invalid_input; + + switch (color_fmt) { + case COLOR_FMT_RGBA8888_UBWC: + rgb_tile_height = 4; + break; + default: + goto invalid_input; + } + + rgb_meta_scanlines = MSM_MEDIA_ROUNDUP(height, rgb_tile_height); + rgb_meta_scanlines = MSM_MEDIA_ALIGN(rgb_meta_scanlines, 16); + +invalid_input: + return rgb_meta_scanlines; +} + +static inline unsigned int VENUS_BUFFER_SIZE( + int color_fmt, int width, int height) +{ + const unsigned int extra_size = VENUS_EXTRADATA_SIZE(width, height); + unsigned int uv_alignment = 0, size = 0; + unsigned int y_plane, uv_plane, y_stride, + uv_stride, y_sclines, uv_sclines; + unsigned int y_ubwc_plane = 0, uv_ubwc_plane = 0; + unsigned int y_meta_stride = 0, y_meta_scanlines = 0; + unsigned int uv_meta_stride = 0, uv_meta_scanlines = 0; + unsigned int y_meta_plane = 0, uv_meta_plane = 0; + unsigned int rgb_stride = 0, rgb_scanlines = 0; + unsigned int rgb_plane = 0, rgb_ubwc_plane = 0, rgb_meta_plane = 0; + unsigned int rgb_meta_stride = 0, rgb_meta_scanlines = 0; + + if (!width || !height) + goto invalid_input; + + y_stride = VENUS_Y_STRIDE(color_fmt, width); + uv_stride = VENUS_UV_STRIDE(color_fmt, width); + y_sclines = VENUS_Y_SCANLINES(color_fmt, height); + uv_sclines = VENUS_UV_SCANLINES(color_fmt, height); + rgb_stride = VENUS_RGB_STRIDE(color_fmt, width); + rgb_scanlines = VENUS_RGB_SCANLINES(color_fmt, height); + + switch (color_fmt) { + case COLOR_FMT_NV21: + case COLOR_FMT_NV12: + uv_alignment = 4096; + y_plane = y_stride * y_sclines; + uv_plane = uv_stride * uv_sclines + uv_alignment; + size = y_plane + uv_plane + + MSM_MEDIA_MAX(extra_size, 8 * y_stride); + size = MSM_MEDIA_ALIGN(size, 4096); + break; + case COLOR_FMT_NV12_MVTB: + uv_alignment = 4096; + y_plane = y_stride * y_sclines; + uv_plane = uv_stride * uv_sclines + uv_alignment; + size = y_plane + uv_plane; + size = 2 * size + extra_size; + size = MSM_MEDIA_ALIGN(size, 4096); + break; + case COLOR_FMT_NV12_UBWC: + case COLOR_FMT_NV12_BPP10_UBWC: + y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); + uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096); + y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width); + y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height); + y_meta_plane = MSM_MEDIA_ALIGN( + y_meta_stride * y_meta_scanlines, 4096); + uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width); + uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height); + uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride * + uv_meta_scanlines, 4096); + + size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + + uv_meta_plane + + MSM_MEDIA_MAX(extra_size + 8192, 48 * y_stride); + size = MSM_MEDIA_ALIGN(size, 4096); + break; + case COLOR_FMT_RGBA8888: + rgb_plane = MSM_MEDIA_ALIGN(rgb_stride * rgb_scanlines, 4096); + size = rgb_plane; + size = MSM_MEDIA_ALIGN(size, 4096); + break; + case COLOR_FMT_RGBA8888_UBWC: + rgb_ubwc_plane = MSM_MEDIA_ALIGN(rgb_stride * rgb_scanlines, + 4096); + rgb_meta_stride = VENUS_RGB_META_STRIDE(color_fmt, width); + rgb_meta_scanlines = VENUS_RGB_META_SCANLINES(color_fmt, + height); + rgb_meta_plane = MSM_MEDIA_ALIGN(rgb_meta_stride * + rgb_meta_scanlines, 4096); + size = rgb_ubwc_plane + rgb_meta_plane; + size = MSM_MEDIA_ALIGN(size, 4096); + break; + default: + break; + } +invalid_input: + return size; +} + +static inline unsigned int VENUS_VIEW2_OFFSET( + int color_fmt, int width, int height) +{ + unsigned int offset = 0; + unsigned int y_plane, uv_plane, y_stride, + uv_stride, y_sclines, uv_sclines; + if (!width || !height) + goto invalid_input; + + y_stride = VENUS_Y_STRIDE(color_fmt, width); + uv_stride = VENUS_UV_STRIDE(color_fmt, width); + y_sclines = VENUS_Y_SCANLINES(color_fmt, height); + uv_sclines = VENUS_UV_SCANLINES(color_fmt, height); + switch (color_fmt) { + case COLOR_FMT_NV12_MVTB: + y_plane = y_stride * y_sclines; + uv_plane = uv_stride * uv_sclines; + offset = y_plane + uv_plane; + break; + default: + break; + } +invalid_input: + return offset; +} + +#endif diff --git a/selfdrive/loggerd/logger.c b/selfdrive/loggerd/logger.c new file mode 100644 index 00000000000000..7dfb610badd35c --- /dev/null +++ b/selfdrive/loggerd/logger.c @@ -0,0 +1,217 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "common/swaglog.h" + +#include "logger.h" + +static int mkpath(char* file_path) { + assert(file_path && *file_path); + char* p; + for (p=strchr(file_path+1, '/'); p; p=strchr(p+1, '/')) { + *p = '\0'; + if (mkdir(file_path, 0777)==-1) { + if (errno != EEXIST) { + *p = '/'; + return -1; + } + } + *p = '/'; + } + return 0; +} + +void logger_init(LoggerState *s, const char* log_name, const uint8_t* init_data, size_t init_data_len, bool has_qlog) { + memset(s, 0, sizeof(*s)); + if (init_data) { + s->init_data = (uint8_t*)malloc(init_data_len); + assert(s->init_data); + memcpy(s->init_data, init_data, init_data_len); + s->init_data_len = init_data_len; + } + + umask(0); + + pthread_mutex_init(&s->lock, NULL); + + s->part = -1; + s->has_qlog = has_qlog; + + time_t rawtime = time(NULL); + struct tm timeinfo; + localtime_r(&rawtime, &timeinfo); + + strftime(s->route_name, sizeof(s->route_name), + "%Y-%m-%d--%H-%M-%S", &timeinfo); + snprintf(s->log_name, sizeof(s->log_name), "%s", log_name); +} + +static LoggerHandle* logger_open(LoggerState *s, const char* root_path) { + int err; + + LoggerHandle *h = NULL; + for (int i=0; ihandles[i].refcnt == 0) { + h = &s->handles[i]; + break; + } + } + assert(h); + + snprintf(h->segment_path, sizeof(h->segment_path), + "%s/%s--%d", root_path, s->route_name, s->part); + + snprintf(h->log_path, sizeof(h->log_path), "%s/%s.bz2", h->segment_path, s->log_name); + snprintf(h->qlog_path, sizeof(h->qlog_path), "%s/qlog.bz2", h->segment_path); + snprintf(h->lock_path, sizeof(h->lock_path), "%s.lock", h->log_path); + + err = mkpath(h->log_path); + if (err) return NULL; + + FILE* lock_file = fopen(h->lock_path, "wb"); + if (lock_file == NULL) return NULL; + fclose(lock_file); + + h->log_file = fopen(h->log_path, "wb"); + if (h->log_file == NULL) goto fail; + + if (s->has_qlog) { + h->qlog_file = fopen(h->qlog_path, "wb"); + if (h->qlog_file == NULL) goto fail; + } + + int bzerror; + h->bz_file = BZ2_bzWriteOpen(&bzerror, h->log_file, 9, 0, 30); + if (bzerror != BZ_OK) goto fail; + + if (s->has_qlog) { + h->bz_qlog = BZ2_bzWriteOpen(&bzerror, h->qlog_file, 9, 0, 30); + if (bzerror != BZ_OK) goto fail; + } + + if (s->init_data) { + BZ2_bzWrite(&bzerror, h->bz_file, s->init_data, s->init_data_len); + if (bzerror != BZ_OK) goto fail; + + if (s->has_qlog) { + // init data goes in the qlog too + BZ2_bzWrite(&bzerror, h->bz_qlog, s->init_data, s->init_data_len); + if (bzerror != BZ_OK) goto fail; + } + } + + pthread_mutex_init(&h->lock, NULL); + h->refcnt++; + return h; +fail: + LOGE("logger failed to open files"); + if (h->qlog_file) fclose(h->qlog_file); + if (h->log_file) fclose(h->log_file); + return NULL; +} + +int logger_next(LoggerState *s, const char* root_path, + char* out_segment_path, size_t out_segment_path_len, + int* out_part) { + pthread_mutex_lock(&s->lock); + s->part++; + + LoggerHandle* next_h = logger_open(s, root_path); + if (!next_h) { + pthread_mutex_unlock(&s->lock); + return -1; + } + + if (s->cur_handle) { + lh_close(s->cur_handle); + } + s->cur_handle = next_h; + + if (out_segment_path) { + snprintf(out_segment_path, out_segment_path_len, "%s", next_h->segment_path); + } + if (out_part) { + *out_part = s->part; + } + + pthread_mutex_unlock(&s->lock); + return 0; +} + +LoggerHandle* logger_get_handle(LoggerState *s) { + pthread_mutex_lock(&s->lock); + LoggerHandle* h = s->cur_handle; + if (h) { + pthread_mutex_lock(&h->lock); + h->refcnt++; + pthread_mutex_unlock(&h->lock); + } + pthread_mutex_unlock(&s->lock); + return h; +} + +void logger_log(LoggerState *s, uint8_t* data, size_t data_size, bool in_qlog) { + pthread_mutex_lock(&s->lock); + if (s->cur_handle) { + lh_log(s->cur_handle, data, data_size, in_qlog); + } + pthread_mutex_unlock(&s->lock); +} + +void logger_close(LoggerState *s) { + pthread_mutex_lock(&s->lock); + free(s->init_data); + if (s->cur_handle) { + lh_close(s->cur_handle); + } + pthread_mutex_unlock(&s->lock); +} + +void lh_log(LoggerHandle* h, uint8_t* data, size_t data_size, bool in_qlog) { + pthread_mutex_lock(&h->lock); + assert(h->refcnt > 0); + int bzerror; + BZ2_bzWrite(&bzerror, h->bz_file, data, data_size); + + if (in_qlog && h->bz_qlog != NULL) { + BZ2_bzWrite(&bzerror, h->bz_qlog, data, data_size); + } + pthread_mutex_unlock(&h->lock); +} + +void lh_close(LoggerHandle* h) { + pthread_mutex_lock(&h->lock); + assert(h->refcnt > 0); + h->refcnt--; + if (h->refcnt == 0) { + if (h->bz_file){ + int bzerror; + BZ2_bzWriteClose(&bzerror, h->bz_file, 0, NULL, NULL); + h->bz_file = NULL; + } + if (h->bz_qlog){ + int bzerror; + BZ2_bzWriteClose(&bzerror, h->bz_qlog, 0, NULL, NULL); + h->bz_qlog = NULL; + } + if (h->qlog_file) fclose(h->qlog_file); + fclose(h->log_file); + unlink(h->lock_path); + pthread_mutex_unlock(&h->lock); + pthread_mutex_destroy(&h->lock); + return; + } + pthread_mutex_unlock(&h->lock); +} diff --git a/selfdrive/loggerd/logger.h b/selfdrive/loggerd/logger.h new file mode 100644 index 00000000000000..ab8798481cb738 --- /dev/null +++ b/selfdrive/loggerd/logger.h @@ -0,0 +1,59 @@ +#ifndef LOGGER_H +#define LOGGER_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define LOGGER_MAX_HANDLES 16 + +typedef struct LoggerHandle { + pthread_mutex_t lock; + int refcnt; + char segment_path[4096]; + char log_path[4096]; + char lock_path[4096]; + FILE* log_file; + BZFILE* bz_file; + + FILE* qlog_file; + char qlog_path[4096]; + BZFILE* bz_qlog; +} LoggerHandle; + +typedef struct LoggerState { + pthread_mutex_t lock; + + uint8_t* init_data; + size_t init_data_len; + + int part; + char route_name[64]; + char log_name[64]; + bool has_qlog; + + LoggerHandle handles[LOGGER_MAX_HANDLES]; + LoggerHandle* cur_handle; +} LoggerState; + +void logger_init(LoggerState *s, const char* log_name, const uint8_t* init_data, size_t init_data_len, bool has_qlog); +int logger_next(LoggerState *s, const char* root_path, + char* out_segment_path, size_t out_segment_path_len, + int* out_part); +LoggerHandle* logger_get_handle(LoggerState *s); +void logger_close(LoggerState *s); +void logger_log(LoggerState *s, uint8_t* data, size_t data_size, bool in_qlog); + +void lh_log(LoggerHandle* h, uint8_t* data, size_t data_size, bool in_qlog); +void lh_close(LoggerHandle* h); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/selfdrive/loggerd/loggerd b/selfdrive/loggerd/loggerd deleted file mode 100755 index 23f499602b23a6..00000000000000 Binary files a/selfdrive/loggerd/loggerd and /dev/null differ diff --git a/selfdrive/loggerd/loggerd.cc b/selfdrive/loggerd/loggerd.cc new file mode 100644 index 00000000000000..18996353eaa4fe --- /dev/null +++ b/selfdrive/loggerd/loggerd.cc @@ -0,0 +1,725 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "common/version.h" +#include "common/timing.h" +#include "common/params.h" +#include "common/swaglog.h" +#include "common/visionipc.h" +#include "common/utilpp.h" +#include "common/util.h" + +#include "logger.h" +#include "messaging.hpp" + + +#ifndef DISABLE_ENCODER +#include "encoder.h" +#include "raw_logger.h" +#endif + +#include "cereal/gen/cpp/log.capnp.h" + +#define CAMERA_FPS 20 +#define SEGMENT_LENGTH 60 +#define LOG_ROOT "/data/media/0/realdata" +#define ENABLE_LIDAR 0 + +#define RAW_CLIP_LENGTH 100 // 5 seconds at 20fps +#define RAW_CLIP_FREQUENCY (randrange(61, 8*60)) // once every ~4 minutes + +namespace { + +double randrange(double a, double b) { + static std::mt19937 gen(millis_since_boot()); + + std::uniform_real_distribution<> dist(a, b); + return dist(gen); +} + + +volatile sig_atomic_t do_exit = 0; +static void set_do_exit(int sig) { + do_exit = 1; +} +struct LoggerdState { + Context *ctx; + LoggerState logger; + + std::mutex lock; + std::condition_variable cv; + char segment_path[4096]; + uint32_t last_frame_id; + uint32_t rotate_last_frame_id; + int rotate_segment; +}; +LoggerdState s; + +#ifndef DISABLE_ENCODER +void encoder_thread(bool is_streaming, bool raw_clips, bool front) { + int err; + + if (front) { + char *value; + const int result = read_db_value(NULL, "RecordFront", &value, NULL); + if (result != 0) return; + if (value[0] != '1') { free(value); return; } + free(value); + LOGW("recording front camera"); + + set_thread_name("FrontCameraEncoder"); + } else { + set_thread_name("RearCameraEncoder"); + } + + VisionStream stream; + + bool encoder_inited = false; + EncoderState encoder; + EncoderState encoder_alt; + bool has_encoder_alt = false; + + int encoder_segment = -1; + int cnt = 0; + + PubSocket *idx_sock = PubSocket::create(s.ctx, front ? "frontEncodeIdx" : "encodeIdx"); + + LoggerHandle *lh = NULL; + + while (!do_exit) { + VisionStreamBufs buf_info; + if (front) { + err = visionstream_init(&stream, VISION_STREAM_YUV_FRONT, false, &buf_info); + } else { + err = visionstream_init(&stream, VISION_STREAM_YUV, false, &buf_info); + } + if (err != 0) { + LOGD("visionstream connect fail"); + usleep(100000); + continue; + } + + if (!encoder_inited) { + LOGD("encoder init %dx%d", buf_info.width, buf_info.height); + encoder_init(&encoder, front ? "dcamera.hevc" : "fcamera.hevc", buf_info.width, buf_info.height, CAMERA_FPS, front ? 2500000 : 5000000, true, false); + if (!front) { + encoder_init(&encoder_alt, "qcamera.ts", 480, 360, CAMERA_FPS, 128000, false, true); + has_encoder_alt = true; + } + encoder_inited = true; + if (is_streaming) { + encoder.zmq_ctx = zmq_ctx_new(); + encoder.stream_sock_raw = zmq_socket(encoder.zmq_ctx, ZMQ_PUB); + assert(encoder.stream_sock_raw); + zmq_bind(encoder.stream_sock_raw, "tcp://*:9002"); + } + } + + // dont log a raw clip in the first minute + double rawlogger_start_time = seconds_since_boot()+RAW_CLIP_FREQUENCY; + int rawlogger_clip_cnt = 0; + RawLogger *rawlogger = NULL; + + if (raw_clips) { + rawlogger = new RawLogger("prcamera", buf_info.width, buf_info.height, CAMERA_FPS); + } + + while (!do_exit) { + VIPCBufExtra extra; + VIPCBuf* buf = visionstream_get(&stream, &extra); + if (buf == NULL) { + LOG("visionstream get failed"); + break; + } + + uint64_t current_time = nanos_since_boot(); + uint64_t diff = current_time - extra.timestamp_eof; + double msdiff = (double) diff / 1000000.0; + // printf("logger latency to tsEof: %f\n", msdiff); + + uint8_t *y = (uint8_t*)buf->addr; + uint8_t *u = y + (buf_info.width*buf_info.height); + uint8_t *v = u + (buf_info.width/2)*(buf_info.height/2); + + { + bool should_rotate = false; + std::unique_lock lk(s.lock); + if (!front) { + // wait if log camera is older on back camera + while ( extra.frame_id > s.last_frame_id //if the log camera is older, wait for it to catch up. + && (extra.frame_id-s.last_frame_id) < 8 // but if its too old then there probably was a discontinuity (visiond restarted) + && !do_exit) { + s.cv.wait(lk); + } + should_rotate = extra.frame_id > s.rotate_last_frame_id && encoder_segment < s.rotate_segment; + } else { + // front camera is best effort + should_rotate = encoder_segment < s.rotate_segment; + } + if (do_exit) break; + + // rotate the encoder if the logger is on a newer segment + if (should_rotate) { + LOG("rotate encoder to %s", s.segment_path); + + encoder_rotate(&encoder, s.segment_path, s.rotate_segment); + if (has_encoder_alt) { + encoder_rotate(&encoder_alt, s.segment_path, s.rotate_segment); + } + + if (raw_clips) { + rawlogger->Rotate(s.segment_path, s.rotate_segment); + } + + encoder_segment = s.rotate_segment; + if (lh) { + lh_close(lh); + } + lh = logger_get_handle(&s.logger); + } + } + + { + // encode hevc + int out_segment = -1; + int out_id = encoder_encode_frame(&encoder, + y, u, v, + buf_info.width, buf_info.height, + &out_segment, &extra); + + if (has_encoder_alt) { + int out_segment_alt = -1; + encoder_encode_frame(&encoder_alt, + y, u, v, + buf_info.width, buf_info.height, + &out_segment_alt, &extra); + } + + // publish encode index + capnp::MallocMessageBuilder msg; + cereal::Event::Builder event = msg.initRoot(); + event.setLogMonoTime(nanos_since_boot()); + auto eidx = event.initEncodeIdx(); + eidx.setFrameId(extra.frame_id); + eidx.setType(front ? cereal::EncodeIndex::Type::FRONT : cereal::EncodeIndex::Type::FULL_H_E_V_C); + eidx.setEncodeId(cnt); + eidx.setSegmentNum(out_segment); + eidx.setSegmentId(out_id); + + auto words = capnp::messageToFlatArray(msg); + auto bytes = words.asBytes(); + if (idx_sock->send((char*)bytes.begin(), bytes.size()) < 0) { + printf("err sending encodeIdx pkt: %s\n", strerror(errno)); + } + if (lh) { + lh_log(lh, bytes.begin(), bytes.size(), false); + } + } + + if (raw_clips) { + double ts = seconds_since_boot(); + if (ts > rawlogger_start_time) { + // encode raw if in clip + int out_segment = -1; + int out_id = rawlogger->LogFrame(cnt, y, u, v, &out_segment); + + if (rawlogger_clip_cnt == 0) { + LOG("starting raw clip in seg %d", out_segment); + } + + // publish encode index + capnp::MallocMessageBuilder msg; + cereal::Event::Builder event = msg.initRoot(); + event.setLogMonoTime(nanos_since_boot()); + auto eidx = event.initEncodeIdx(); + eidx.setFrameId(extra.frame_id); + eidx.setType(cereal::EncodeIndex::Type::FULL_LOSSLESS_CLIP); + eidx.setEncodeId(cnt); + eidx.setSegmentNum(out_segment); + eidx.setSegmentId(out_id); + + auto words = capnp::messageToFlatArray(msg); + auto bytes = words.asBytes(); + if (lh) { + lh_log(lh, bytes.begin(), bytes.size(), false); + } + + // close rawlogger if clip ended + rawlogger_clip_cnt++; + if (rawlogger_clip_cnt >= RAW_CLIP_LENGTH) { + rawlogger->Close(); + + rawlogger_clip_cnt = 0; + rawlogger_start_time = ts+RAW_CLIP_FREQUENCY; + + LOG("ending raw clip in seg %d, next in %.1f sec", out_segment, rawlogger_start_time-ts); + } + } + } + + cnt++; + } + + if (lh) { + lh_close(lh); + lh = NULL; + } + + if (raw_clips) { + rawlogger->Close(); + delete rawlogger; + } + + visionstream_destroy(&stream); + } + + delete idx_sock; + + if (encoder_inited) { + LOG("encoder destroy"); + encoder_close(&encoder); + encoder_destroy(&encoder); + } + + if (has_encoder_alt) { + LOG("encoder alt destroy"); + encoder_close(&encoder_alt); + encoder_destroy(&encoder_alt); + } +} +#endif + +#if ENABLE_LIDAR + +#include +#include +#include +#include + +#define VELODYNE_DATA_PORT 2368 +#define VELODYNE_TELEMETRY_PORT 8308 + +#define MAX_LIDAR_PACKET 2048 + +int lidar_thread() { + // increase kernel max buffer size + system("sysctl -w net.core.rmem_max=26214400"); + set_thread_name("lidar"); + + int sock; + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("cannot create socket"); + return -1; + } + + int a = 26214400; + if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &a, sizeof(int)) == -1) { + perror("cannot set socket opts"); + return -1; + } + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = htons(VELODYNE_DATA_PORT); + inet_aton("192.168.5.11", &(addr.sin_addr)); + + if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("cannot bind LIDAR socket"); + return -1; + } + + capnp::byte buf[MAX_LIDAR_PACKET]; + + while (!do_exit) { + // receive message + struct sockaddr from; + socklen_t fromlen = sizeof(from); + int cnt = recvfrom(sock, (void *)buf, MAX_LIDAR_PACKET, 0, &from, &fromlen); + if (cnt <= 0) { + printf("bug in lidar recieve!\n"); + continue; + } + + // create message for log + capnp::MallocMessageBuilder msg; + auto event = msg.initRoot(); + event.setLogMonoTime(nanos_since_boot()); + auto lidar_pts = event.initLidarPts(); + + // copy in the buffer + // TODO: can we remove this copy? does it matter? + kj::ArrayPtr bufferPtr = kj::arrayPtr(buf, cnt); + lidar_pts.setPkt(bufferPtr); + + // log it + auto words = capnp::messageToFlatArray(msg); + auto bytes = words.asBytes(); + logger_log(&s.logger, bytes.begin(), bytes.size()); + } + return 0; +} +#endif + +} + +void append_property(const char* key, const char* value, void *cookie) { + std::vector > *properties = + (std::vector > *)cookie; + + properties->push_back(std::make_pair(std::string(key), std::string(value))); +} + +kj::Array gen_init_data() { + capnp::MallocMessageBuilder msg; + auto event = msg.initRoot(); + event.setLogMonoTime(nanos_since_boot()); + auto init = event.initInitData(); + + init.setDeviceType(cereal::InitData::DeviceType::NEO); + init.setVersion(capnp::Text::Reader(COMMA_VERSION)); + + std::ifstream cmdline_stream("/proc/cmdline"); + std::vector kernel_args; + std::string buf; + while (cmdline_stream >> buf) { + kernel_args.push_back(buf); + } + + auto lkernel_args = init.initKernelArgs(kernel_args.size()); + for (int i=0; i > properties; + property_list(append_property, (void*)&properties); + + auto lentries = init.initAndroidProperties().initEntries(properties.size()); + for (int i=0; i params; + read_db_all(NULL, ¶ms); + auto lparams = init.initParams().initEntries(params.size()); + int i = 0; + for (auto& kv : params) { + auto lentry = lparams[i]; + lentry.setKey(kv.first); + lentry.setValue(kv.second); + i++; + } + } + + + auto words = capnp::messageToFlatArray(msg); + + if (git_commit) { + free((void*)git_commit); + } + + if (git_branch) { + free((void*)git_branch); + } + + if (git_remote) { + free((void*)git_remote); + } + + if (passive) { + free((void*)passive); + } + + return words; +} + +static int clear_locks_fn(const char* fpath, const struct stat *sb, int tyupeflag) { + const char* dot = strrchr(fpath, '.'); + if (dot && strcmp(dot, ".lock") == 0) { + unlink(fpath); + } + return 0; +} + +static void clear_locks() { + ftw(LOG_ROOT, clear_locks_fn, 16); +} + +static void bootlog() { + int err; + + { + auto words = gen_init_data(); + auto bytes = words.asBytes(); + logger_init(&s.logger, "bootlog", bytes.begin(), bytes.size(), false); + } + + err = logger_next(&s.logger, LOG_ROOT, s.segment_path, sizeof(s.segment_path), &s.rotate_segment); + assert(err == 0); + LOGW("bootlog to %s", s.segment_path); + + { + capnp::MallocMessageBuilder msg; + auto event = msg.initRoot(); + event.setLogMonoTime(nanos_since_boot()); + + auto boot = event.initBoot(); + + boot.setWallTimeNanos(nanos_since_epoch()); + + std::string lastKmsg = util::read_file("/sys/fs/pstore/console-ramoops"); + boot.setLastKmsg(capnp::Data::Reader((const kj::byte*)lastKmsg.data(), lastKmsg.size())); + + std::string lastPmsg = util::read_file("/sys/fs/pstore/pmsg-ramoops-0"); + boot.setLastPmsg(capnp::Data::Reader((const kj::byte*)lastPmsg.data(), lastPmsg.size())); + + auto words = capnp::messageToFlatArray(msg); + auto bytes = words.asBytes(); + logger_log(&s.logger, bytes.begin(), bytes.size(), false); + } + + logger_close(&s.logger); +} + +int main(int argc, char** argv) { + int err; + + if (argc > 1 && strcmp(argv[1], "--bootlog") == 0) { + bootlog(); + return 0; + } + + setpriority(PRIO_PROCESS, 0, -12); + + clear_locks(); + + signal(SIGINT, (sighandler_t)set_do_exit); + signal(SIGTERM, (sighandler_t)set_do_exit); + + s.ctx = Context::create(); + Poller * poller = Poller::create(); + + std::string exe_dir = util::dir_name(util::readlink("/proc/self/exe")); + std::string service_list_path = exe_dir + "/../service_list.yaml"; + + // subscribe to all services + + SubSocket *frame_sock = NULL; + std::vector socks; + + std::map qlog_counter; + std::map qlog_freqs; + + YAML::Node service_list = YAML::LoadFile(service_list_path); + for (const auto& it : service_list) { + auto name = it.first.as(); + bool should_log = it.second[1].as(); + int qlog_freq = it.second[3] ? it.second[3].as() : 0; + + if (should_log) { + SubSocket * sock = SubSocket::create(s.ctx, name); + poller->registerSocket(sock); + socks.push_back(sock); + + if (name == "frame") { + frame_sock = sock; + } + + qlog_counter[sock] = (qlog_freq == 0) ? -1 : 0; + qlog_freqs[sock] = qlog_freq; + } + } + + + { + auto words = gen_init_data(); + auto bytes = words.asBytes(); + logger_init(&s.logger, "rlog", bytes.begin(), bytes.size(), true); + } + + bool is_streaming = false; + bool is_logging = true; + + if (argc > 1 && strcmp(argv[1], "--stream") == 0) { + is_streaming = true; + } else if (argc > 1 && strcmp(argv[1], "--only-stream") == 0) { + is_streaming = true; + is_logging = false; + } + + if (is_logging) { + err = logger_next(&s.logger, LOG_ROOT, s.segment_path, sizeof(s.segment_path), &s.rotate_segment); + assert(err == 0); + LOGW("logging to %s", s.segment_path); + } + + double start_ts = seconds_since_boot(); + double last_rotate_ts = start_ts; + +#ifndef DISABLE_ENCODER + // rear camera + std::thread encoder_thread_handle(encoder_thread, is_streaming, false, false); + + // front camera + std::thread front_encoder_thread_handle(encoder_thread, false, false, true); +#endif + +#if ENABLE_LIDAR + std::thread lidar_thread_handle(lidar_thread); +#endif + + uint64_t msg_count = 0; + uint64_t bytes_count = 0; + + while (!do_exit) { + for (auto sock : poller->poll(100 * 1000)){ + while (true) { + Message * msg = sock->receive(true); + if (msg == NULL){ + break; + } + + uint8_t* data = (uint8_t*)msg->getData(); + size_t len = msg->getSize(); + + if (sock == frame_sock) { + // track camera frames to sync to encoder + auto amsg = kj::heapArray((len / sizeof(capnp::word)) + 1); + memcpy(amsg.begin(), data, len); + + capnp::FlatArrayMessageReader cmsg(amsg); + cereal::Event::Reader event = cmsg.getRoot(); + if (event.isFrame()) { + std::unique_lock lk(s.lock); + s.last_frame_id = event.getFrame().getFrameId(); + lk.unlock(); + s.cv.notify_all(); + } + } + + logger_log(&s.logger, data, len, qlog_counter[sock] == 0); + delete msg; + + if (qlog_counter[sock] != -1) { + //printf("%p: %d/%d\n", socks[i], qlog_counter[socks[i]], qlog_freqs[socks[i]]); + qlog_counter[sock]++; + qlog_counter[sock] %= qlog_freqs[sock]; + } + + bytes_count += len; + msg_count++; + } + } + + double ts = seconds_since_boot(); + if (ts - last_rotate_ts > SEGMENT_LENGTH) { + // rotate the log + + last_rotate_ts += SEGMENT_LENGTH; + + std::lock_guard guard(s.lock); + s.rotate_last_frame_id = s.last_frame_id; + + if (is_logging) { + err = logger_next(&s.logger, LOG_ROOT, s.segment_path, sizeof(s.segment_path), &s.rotate_segment); + assert(err == 0); + LOGW("rotated to %s", s.segment_path); + } + } + + if ((msg_count%1000) == 0) { + LOGD("%lu messages, %.2f msg/sec, %.2f KB/sec", msg_count, msg_count*1.0/(ts-start_ts), bytes_count*0.001/(ts-start_ts)); + } + } + + LOGW("joining threads"); + s.cv.notify_all(); + + +#ifndef DISABLE_ENCODER + front_encoder_thread_handle.join(); + encoder_thread_handle.join(); + LOGW("encoder joined"); +#endif + +#if ENABLE_LIDAR + lidar_thread_handle.join(); + LOGW("lidar joined"); +#endif + + logger_close(&s.logger); + + for (auto s : socks){ + delete s; + } + + delete s.ctx; + return 0; +} diff --git a/selfdrive/loggerd/raw_logger.cc b/selfdrive/loggerd/raw_logger.cc new file mode 100644 index 00000000000000..37b3f284287bc9 --- /dev/null +++ b/selfdrive/loggerd/raw_logger.cc @@ -0,0 +1,163 @@ +#include +#include +#include + +#include +#include + +#define __STDC_CONSTANT_MACROS + +extern "C" { +#include +#include +#include +} + +#include "common/swaglog.h" +#include "common/utilpp.h" + +#include "raw_logger.h" + +RawLogger::RawLogger(const std::string &afilename, int awidth, int aheight, int afps) + : filename(afilename), + width(awidth), + height(aheight), + fps(afps) { + + int err = 0; + + av_register_all(); + 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 = width; + codec_ctx->height = 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 }; + + err = avcodec_open2(codec_ctx, codec, NULL); + assert(err >= 0); + + frame = av_frame_alloc(); + assert(frame); + frame->format = codec_ctx->pix_fmt; + frame->width = width; + frame->height = height; + frame->linesize[0] = width; + frame->linesize[1] = width/2; + frame->linesize[2] = width/2; +} + +RawLogger::~RawLogger() { + av_frame_free(&frame); + avcodec_close(codec_ctx); + av_free(codec_ctx); +} + +void RawLogger::Open(const std::string &path) { + int err = 0; + + std::lock_guard guard(lock); + + vid_path = util::string_format("%s/%s.mkv", path.c_str(), filename.c_str()); + + // create camera lock file + lock_path = util::string_format("%s/%s.lock", path.c_str(), filename.c_str()); + + LOG("open %s\n", lock_path.c_str()); + + int lock_fd = open(lock_path.c_str(), O_RDWR | O_CREAT, 0777); + assert(lock_fd >= 0); + close(lock_fd); + + format_ctx = NULL; + avformat_alloc_output_context2(&format_ctx, NULL, NULL, 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; + + 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; + counter = 0; +} + +void RawLogger::Close() { + int err = 0; + + std::lock_guard guard(lock); + + if (!is_open) return; + + err = av_write_trailer(format_ctx); + assert(err == 0); + + avcodec_close(stream->codec); + + 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; +} + +int RawLogger::ProcessFrame(uint64_t ts, const uint8_t *y_ptr, const uint8_t *u_ptr, const uint8_t *v_ptr) { + int err = 0; + + AVPacket pkt; + av_init_packet(&pkt); + pkt.data = NULL; + pkt.size = 0; + + frame->data[0] = (uint8_t*)y_ptr; + frame->data[1] = (uint8_t*)u_ptr; + frame->data[2] = (uint8_t*)v_ptr; + frame->pts = ts; + + int ret = counter; + + int got_output = 0; + err = avcodec_encode_video2(codec_ctx, &pkt, frame, &got_output); + if (err) { + LOGE("encoding error\n"); + ret = -1; + } else if (got_output) { + + av_packet_rescale_ts(&pkt, codec_ctx->time_base, stream->time_base); + pkt.stream_index = 0; + + err = av_interleaved_write_frame(format_ctx, &pkt); + if (err < 0) { + LOGE("encoder writer error\n"); + ret = -1; + } else { + counter++; + } + } + + return ret; +} diff --git a/selfdrive/loggerd/raw_logger.h b/selfdrive/loggerd/raw_logger.h new file mode 100644 index 00000000000000..249be40db8816c --- /dev/null +++ b/selfdrive/loggerd/raw_logger.h @@ -0,0 +1,43 @@ +#ifndef FFV1LOGGER_H +#define FFV1LOGGER_H + +#include +#include + +#include +#include +#include +#include + +extern "C" { +#include +#include +#include +} + +#include "frame_logger.h" + +class RawLogger : public FrameLogger { +public: + RawLogger(const std::string &filename, int awidth, int aheight, int afps); + ~RawLogger(); + + int ProcessFrame(uint64_t ts, const uint8_t *y_ptr, const uint8_t *u_ptr, const uint8_t *v_ptr); + void Open(const std::string &path); + void Close(); + +private: + std::string filename; + int width, height, fps; + int counter = 0; + + AVCodec *codec = NULL; + AVCodecContext *codec_ctx = NULL; + + AVStream *stream = NULL; + AVFormatContext *format_ctx = NULL; + + AVFrame *frame = NULL; +}; + +#endif diff --git a/selfdrive/loggerd/tests/Makefile b/selfdrive/loggerd/tests/Makefile new file mode 100644 index 00000000000000..d05d549170d4fc --- /dev/null +++ b/selfdrive/loggerd/tests/Makefile @@ -0,0 +1,35 @@ +CC = clang +CXX = clang++ + +PHONELIBS = ../../../phonelibs + +WARN_FLAGS = -Werror=implicit-function-declaration \ + -Werror=incompatible-pointer-types \ + -Werror=int-conversion \ + -Werror=return-type \ + -Werror=format-extra-args \ + -Wno-deprecated-declarations + +CFLAGS = -std=gnu11 -g -fPIC -O2 $(WARN_FLAGS) +CXXFLAGS = -std=c++11 -g -fPIC -O2 $(WARN_FLAGS) + +FFMPEG_LIBS = -lavformat \ + -lavcodec \ + -lswscale \ + -lavutil \ + -lz + +OBJS = testraw.o \ + ../RawLogger.o \ + ../../common/visionipc.o + +testraw: $(OBJS) + $(CXX) -fPIC -o '$@' $^ -L/usr/lib $(FFMPEG_LIBS) + +%.o: %.cc + @echo "[ CXX ] $@" + $(CXX) $(CXXFLAGS) \ + -I../ \ + -I../../ \ + -I../../../ \ + -c -o '$@' '$<' diff --git a/selfdrive/mapd/__init__.py b/selfdrive/loggerd/tests/__init__.py similarity index 100% rename from selfdrive/mapd/__init__.py rename to selfdrive/loggerd/tests/__init__.py diff --git a/selfdrive/loggerd/tests/fill_eon.py b/selfdrive/loggerd/tests/fill_eon.py new file mode 100755 index 00000000000000..f273ea89ec7e9f --- /dev/null +++ b/selfdrive/loggerd/tests/fill_eon.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +"""Script to fill up EON with fake data""" + +import os + +from selfdrive.loggerd.config import ROOT, get_available_percent +from selfdrive.loggerd.tests.loggerd_tests_common import create_random_file + + +if __name__ == "__main__": + segment_idx = 0 + while True: + seg_name = "1970-01-01--00-00-00--%d" % segment_idx + seg_path = os.path.join(ROOT, seg_name) + + print(seg_path) + + create_random_file(os.path.join(seg_path, 'fcamera.hevc'), 36) + create_random_file(os.path.join(seg_path, 'rlog.bz2'), 2) + + segment_idx += 1 + + # Fill up to 99 percent + available_percent = get_available_percent() + if available_percent < 1.0: + break diff --git a/selfdrive/loggerd/tests/loggerd_tests_common.py b/selfdrive/loggerd/tests/loggerd_tests_common.py new file mode 100644 index 00000000000000..9db75a7f59783e --- /dev/null +++ b/selfdrive/loggerd/tests/loggerd_tests_common.py @@ -0,0 +1,82 @@ +import os +import errno +import shutil +import random +import tempfile +import unittest + +import selfdrive.loggerd.uploader as uploader + +def create_random_file(file_path, size_mb, lock=False): + try: + os.mkdir(os.path.dirname(file_path)) + except OSError: + pass + + lock_path = file_path + ".lock" + os.close(os.open(lock_path, os.O_CREAT | os.O_EXCL)) + + chunks = 128 + chunk_bytes = int(size_mb * 1024 * 1024 / chunks) + data = os.urandom(chunk_bytes) + + with open(file_path, 'wb') as f: + for _ in range(chunks): + f.write(data) + + if not lock: + os.remove(lock_path) + +class MockResponse(): + def __init__(self, text): + self.text = text + +class MockApi(): + def __init__(self, dongle_id): + pass + + def get(self, *args, **kwargs): + return MockResponse('{"url": "http://localhost/does/not/exist", "headers": {}}') + + def get_token(self): + return "fake-token" + +class MockParams(): + def __init__(self): + self.params = { + "DongleId": b"0000000000000000", + "IsUploadRawEnabled": b"1", + "IsUploadVideoOverCellularEnabled": b"1" + } + + def get(self, k): + return self.params[k] + +class UploaderTestCase(unittest.TestCase): + f_type = "UNKNOWN" + + def setUp(self): + self.root = tempfile.mkdtemp() + uploader.ROOT = self.root # Monkey patch root dir + uploader.Api = MockApi + uploader.Params = MockParams + uploader.fake_upload = 1 + uploader.is_on_hotspot = lambda *args: False + uploader.is_on_wifi = lambda *args: False + self.seg_num = random.randint(1, 300) + self.seg_format = "2019-04-18--12-52-54--{}" + self.seg_format2 = "2019-05-18--11-22-33--{}" + self.seg_dir = self.seg_format.format(self.seg_num) + + def tearDown(self): + try: + shutil.rmtree(self.root) + except OSError as e: + if e.errno != errno.ENOENT: + raise + + def make_file_with_data(self, f_dir, fn, size_mb=.1, lock=False): + file_path = os.path.join(self.root, f_dir, fn) + create_random_file(file_path, size_mb, lock) + + return file_path diff --git a/selfdrive/loggerd/tests/test_deleter.py b/selfdrive/loggerd/tests/test_deleter.py new file mode 100644 index 00000000000000..adbb0f0316fc21 --- /dev/null +++ b/selfdrive/loggerd/tests/test_deleter.py @@ -0,0 +1,100 @@ +import os +import time +import threading +from collections import namedtuple + +import selfdrive.loggerd.deleter as deleter +from common.timeout import Timeout, TimeoutException + +from selfdrive.loggerd.tests.loggerd_tests_common import UploaderTestCase + +Stats = namedtuple("Stats", ['f_bavail', 'f_blocks']) + +class TestDeleter(UploaderTestCase): + def fake_statvfs(self, d): + return self.fake_stats + + def setUp(self): + self.f_type = "fcamera.hevc" + super(TestDeleter, self).setUp() + self.fake_stats = Stats(f_bavail=0, f_blocks=10) + deleter.os.statvfs = self.fake_statvfs + deleter.ROOT = self.root + + def tearDown(self): + super(TestDeleter, self).tearDown() + + def start_thread(self): + self.end_event = threading.Event() + self.del_thread = threading.Thread(target=deleter.deleter_thread, args=[self.end_event]) + self.del_thread.daemon = True + self.del_thread.start() + + def join_thread(self): + self.end_event.set() + self.del_thread.join() + + def test_delete(self): + f_path = self.make_file_with_data(self.seg_dir, self.f_type, 1) + + self.start_thread() + + with Timeout(5, "Timeout waiting for file to be deleted"): + while os.path.exists(f_path): + time.sleep(0.01) + self.join_thread() + + self.assertFalse(os.path.exists(f_path), "File not deleted") + + def test_delete_files_in_create_order(self): + f_path_1 = self.make_file_with_data(self.seg_dir, self.f_type) + time.sleep(1) + self.seg_num += 1 + self.seg_dir = self.seg_format.format(self.seg_num) + f_path_2 = self.make_file_with_data(self.seg_dir, self.f_type) + + self.start_thread() + + with Timeout(5, "Timeout waiting for file to be deleted"): + while os.path.exists(f_path_1) and os.path.exists(f_path_2): + time.sleep(0.01) + + self.join_thread() + + self.assertFalse(os.path.exists(f_path_1), "Older file not deleted") + + self.assertTrue(os.path.exists(f_path_2), "Newer file deleted before older file") + + def test_no_delete_when_available_space(self): + f_path = self.make_file_with_data(self.seg_dir, self.f_type) + + self.fake_stats = Stats(f_bavail=10, f_blocks=10) + + self.start_thread() + + try: + with Timeout(2, "Timeout waiting for file to be deleted"): + while os.path.exists(f_path): + time.sleep(0.01) + except TimeoutException: + pass + finally: + self.join_thread() + + self.assertTrue(os.path.exists(f_path), "File deleted with available space") + + def test_no_delete_with_lock_file(self): + f_path = self.make_file_with_data(self.seg_dir, self.f_type, lock=True) + + self.start_thread() + + try: + with Timeout(2, "Timeout waiting for file to be deleted"): + while os.path.exists(f_path): + time.sleep(0.01) + except TimeoutException: + pass + finally: + self.join_thread() + + self.assertTrue(os.path.exists(f_path), "File deleted when locked") diff --git a/selfdrive/loggerd/tests/test_uploader.py b/selfdrive/loggerd/tests/test_uploader.py new file mode 100644 index 00000000000000..ed9a9722208ca9 --- /dev/null +++ b/selfdrive/loggerd/tests/test_uploader.py @@ -0,0 +1,116 @@ +import os +import time +import threading +import logging +import json + +from selfdrive.swaglog import cloudlog +import selfdrive.loggerd.uploader as uploader + +from common.timeout import Timeout + +from selfdrive.loggerd.tests.loggerd_tests_common import UploaderTestCase + +class TestLogHandler(logging.Handler): + def __init__(self): + logging.Handler.__init__(self) + self.reset() + + def reset(self): + self.upload_order = list() + + def emit(self, record): + try: + j = json.loads(record.message) + if j["event"] == "upload_success": + self.upload_order.append(j["key"]) + except BaseException: + pass + +log_handler = TestLogHandler() +cloudlog.addHandler(log_handler) + +class TestUploader(UploaderTestCase): + def setUp(self): + super(TestUploader, self).setUp() + log_handler.reset() + + def tearDown(self): + super(TestUploader, self).tearDown() + + def start_thread(self): + self.end_event = threading.Event() + self.up_thread = threading.Thread(target=uploader.uploader_fn, args=[self.end_event]) + self.up_thread.daemon = True + self.up_thread.start() + + def join_thread(self): + self.end_event.set() + self.up_thread.join() + + def gen_files(self, lock=False): + f_paths = list() + for t in ["bootlog.bz2", "qlog.bz2", "rlog.bz2", "dcamera.hevc", "fcamera.hevc"]: + f_paths.append(self.make_file_with_data(self.seg_dir, t, 1, lock=lock)) + return f_paths + + def gen_order(self, seg1, seg2): + keys = [f"{self.seg_format.format(i)}/qlog.bz2" for i in seg1] + keys += [f"{self.seg_format2.format(i)}/qlog.bz2" for i in seg2] + for i in seg1: + keys += [f"{self.seg_format.format(i)}/{f}" for f in ['rlog.bz2','fcamera.hevc','dcamera.hevc']] + for i in seg2: + keys += [f"{self.seg_format2.format(i)}/{f}" for f in ['rlog.bz2','fcamera.hevc','dcamera.hevc']] + keys += [f"{self.seg_format.format(i)}/bootlog.bz2" for i in seg1] + keys += [f"{self.seg_format2.format(i)}/bootlog.bz2" for i in seg2] + return keys + + def test_upload(self): + f_paths = self.gen_files(lock=False) + + self.start_thread() + + with Timeout(5, "Timeout waiting for file to be uploaded"): + while len(os.listdir(self.root)): + time.sleep(0.01) + self.join_thread() + + for f_path in f_paths: + self.assertFalse(os.path.exists(f_path), "All files not uploaded") + exp_order = self.gen_order([self.seg_num], []) + self.assertTrue(log_handler.upload_order == exp_order, "Files uploaded in wrong order") + + def test_upload_files_in_create_order(self): + f_paths = list() + seg1_nums = [0,1,2,10,20] + for i in seg1_nums: + self.seg_dir = self.seg_format.format(i) + f_paths += self.gen_files() + seg2_nums = [5,50,51] + for i in seg2_nums: + self.seg_dir = self.seg_format2.format(i) + f_paths += self.gen_files() + + self.start_thread() + + with Timeout(5, "Timeout waiting for file to be upload"): + while len(os.listdir(self.root)): + time.sleep(0.01) + + self.join_thread() + + for f_path in f_paths: + self.assertFalse(os.path.exists(f_path), "All files not uploaded") + exp_order = self.gen_order(seg1_nums, seg2_nums) + self.assertTrue(log_handler.upload_order == exp_order, "Files uploaded in wrong order") + + def test_no_upload_with_lock_file(self): + f_paths = self.gen_files(lock=True) + + self.start_thread() + # allow enough time that files should have been uploaded if they would be uploaded + time.sleep(5) + self.join_thread() + + for f_path in f_paths: + self.assertTrue(os.path.exists(f_path), "File upload when locked") diff --git a/selfdrive/loggerd/tests/testraw.cc b/selfdrive/loggerd/tests/testraw.cc new file mode 100644 index 00000000000000..80858e6f283c92 --- /dev/null +++ b/selfdrive/loggerd/tests/testraw.cc @@ -0,0 +1,57 @@ +#include +#include +#include + +#include + +#include "common/visionipc.h" +#include "common/timing.h" + +#include "RawLogger.h" + +int main() { + int err; + + VisionStream stream; + + VisionStreamBufs buf_info; + while (true) { + err = visionstream_init(&stream, VISION_STREAM_YUV, false, &buf_info); + if (err != 0) { + printf("visionstream fail\n"); + usleep(100000); + } + break; + } + + RawLogger vidlogger("prcamera", buf_info.width, buf_info.height, 20); + vidlogger.Open("o1"); + + for (int cnt=0; cnt<200; cnt++) { + VIPCBufExtra extra; + VIPSBuf* buf = visionstream_get(&stream, &extra); + if (buf == NULL) { + printf("visionstream get failed\n"); + break; + } + + if (cnt == 100) { + vidlogger.Rotate("o2", 2); + } + + uint8_t *y = (uint8_t*)buf->addr; + uint8_t *u = y + (buf_info.width*buf_info.height); + uint8_t *v = u + (buf_info.width/2)*(buf_info.height/2); + + double t1 = millis_since_boot(); + vidlogger.LogFrame(cnt, y, u, v, NULL); + double t2 = millis_since_boot(); + printf("%d %.2f\n", cnt, (t2-t1)); + } + + vidlogger.Close(); + + visionstream_destroy(&stream); + + return 0; +} diff --git a/selfdrive/loggerd/uploader.py b/selfdrive/loggerd/uploader.py index 670e924ab4d6ba..0951ad815a598e 100644 --- a/selfdrive/loggerd/uploader.py +++ b/selfdrive/loggerd/uploader.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import os import re import time -import stat import json import random import ctypes @@ -12,12 +11,11 @@ import threading import subprocess -from collections import Counter from selfdrive.swaglog import cloudlog from selfdrive.loggerd.config import ROOT from common.params import Params -from common.api import api_get +from common.api import Api fake_upload = os.getenv("FAKEUPLOAD") is not None @@ -43,20 +41,17 @@ def raise_on_thread(t, exctype): ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0) raise SystemError("PyThreadState_SetAsyncExc failed") -def listdir_with_creation_date(d): - lst = os.listdir(d) - for fn in lst: - try: - st = os.stat(os.path.join(d, fn)) - ctime = st[stat.ST_CTIME] - yield (ctime, fn) - except OSError: - cloudlog.exception("listdir_with_creation_date: stat failed?") - yield (None, fn) +def get_directory_sort(d): + return list(map(lambda s: s.rjust(10, '0'), d.rsplit('--', 1))) -def listdir_by_creation_date(d): - times_and_paths = list(listdir_with_creation_date(d)) - return [path for _, path in sorted(times_and_paths)] +def listdir_by_creation(d): + try: + paths = os.listdir(d) + paths = sorted(paths, key=get_directory_sort) + return paths + except OSError: + cloudlog.exception("listdir_by_creation failed") + return list() def clear_locks(root): for logname in os.listdir(root): @@ -71,29 +66,34 @@ def clear_locks(root): def is_on_wifi(): # ConnectivityManager.getActiveNetworkInfo() try: - result = subprocess.check_output(["service", "call", "connectivity", "2"]).strip().split("\n") + result = subprocess.check_output(["service", "call", "connectivity", "2"], encoding='utf8').strip().split("\n") # pylint: disable=unexpected-keyword-arg except subprocess.CalledProcessError: return False - data = ''.join(''.join(w.decode("hex")[::-1] for w in l[14:49].split()) for l in result[1:]) + # Concatenate all ascii parts + r = "" + for line in result[1:]: + r += line[51:67] - return "\x00".join("WIFI") in data + return "W.I.F.I" in r def is_on_hotspot(): try: - result = subprocess.check_output(["ifconfig", "wlan0"]) + result = subprocess.check_output(["ifconfig", "wlan0"], encoding='utf8') # pylint: disable=unexpected-keyword-arg result = re.findall(r"inet addr:((\d+\.){3}\d+)", result)[0][0] is_android = result.startswith('192.168.43.') is_ios = result.startswith('172.20.10.') - return (is_android or is_ios) + is_entune = result.startswith('10.0.2.') + + return (is_android or is_ios or is_entune) except: return False -class Uploader(object): - def __init__(self, dongle_id, access_token, root): +class Uploader(): + def __init__(self, dongle_id, root): self.dongle_id = dongle_id - self.access_token = access_token + self.api = Api(dongle_id) self.root = root self.upload_thread = None @@ -101,6 +101,9 @@ def __init__(self, dongle_id, access_token, root): self.last_resp = None self.last_exc = None + self.immediate_priority = {"qlog.bz2": 0, "qcamera.ts": 1} + self.high_priority = {"rlog.bz2": 0, "fcamera.hevc": 1, "dcamera.hevc": 2} + def clean_dirs(self): try: for logname in os.listdir(self.root): @@ -111,68 +114,62 @@ def clean_dirs(self): except OSError: cloudlog.exception("clean_dirs failed") + def get_upload_sort(self, name): + if name in self.immediate_priority: + return self.immediate_priority[name] + if name in self.high_priority: + return self.high_priority[name] + 100 + return 1000 + def gen_upload_files(self): if not os.path.isdir(self.root): return - for logname in listdir_by_creation_date(self.root): + for logname in listdir_by_creation(self.root): path = os.path.join(self.root, logname) - names = os.listdir(path) + try: + names = os.listdir(path) + except OSError: + continue if any(name.endswith(".lock") for name in names): continue - for name in names: + for name in sorted(names, key=self.get_upload_sort): key = os.path.join(logname, name) fn = os.path.join(path, name) yield (name, key, fn) - def get_data_stats(self): - name_counts = Counter() - total_size = 0 - for name, key, fn in self.gen_upload_files(): - name_counts[name] += 1 - total_size += os.stat(fn).st_size - return dict(name_counts), total_size - - def next_file_to_compress(self): - for name, key, fn in self.gen_upload_files(): - if name.endswith("log"): - return (key, fn, 0) - return None - - def next_file_to_upload(self, with_video): - # try to upload log files first - for name, key, fn in self.gen_upload_files(): - if name == "rlog.bz2": - return (key, fn, 0) + def next_file_to_upload(self, with_raw): + upload_files = list(self.gen_upload_files()) + # try to upload qlog files first + for name, key, fn in upload_files: + if name in self.immediate_priority: + return (key, fn) - if with_video: - # then upload compressed rear and front camera files - for name, key, fn in self.gen_upload_files(): - if name == "fcamera.hevc": - return (key, fn, 1) - elif name == "dcamera.hevc": - return (key, fn, 2) + if with_raw: + # then upload the full log files, rear and front camera files + for name, key, fn in upload_files: + if name in self.high_priority: + return (key, fn) # then upload other files - for name, key, fn in self.gen_upload_files(): + for name, key, fn in upload_files: if not name.endswith('.lock') and not name.endswith(".tmp"): - return (key, fn, 3) + return (key, fn) return None - def do_upload(self, key, fn): try: - url_resp = api_get("v1.2/"+self.dongle_id+"/upload_url/", timeout=2, path=key, access_token=self.access_token) + url_resp = self.api.get("v1.3/"+self.dongle_id+"/upload_url/", timeout=10, path=key, access_token=self.api.get_token()) url_resp_json = json.loads(url_resp.text) url = url_resp_json['url'] headers = url_resp_json['headers'] - cloudlog.info("upload_url v1.2 %s %s", url, str(headers)) + cloudlog.info("upload_url v1.3 %s %s", url, str(headers)) if fake_upload: cloudlog.info("*** WARNING, THIS IS A FAKE UPLOAD TO %s ***" % url) - class FakeResponse(object): + class FakeResponse(): def __init__(self): self.status_code = 200 self.last_resp = FakeResponse() @@ -194,41 +191,6 @@ def normal_upload(self, key, fn): return self.last_resp - def killable_upload(self, key, fn): - self.last_resp = None - self.last_exc = None - - self.upload_thread = threading.Thread(target=lambda: self.do_upload(key, fn)) - self.upload_thread.start() - self.upload_thread.join() - self.upload_thread = None - - return self.last_resp - - def abort_upload(self): - thread = self.upload_thread - if thread is None: - return - if not thread.is_alive(): - return - raise_on_thread(thread, SystemExit) - thread.join() - - def compress(self, key, fn): - # write out the bz2 compress - if fn.endswith("log"): - ext = ".bz2" - cloudlog.info("compressing %r to %r", fn, fn+ext) - if os.system("nice -n 19 bzip2 -c %s > %s.tmp && mv %s.tmp %s%s && rm %s" % (fn, fn, fn, fn, ext, fn)) != 0: - cloudlog.exception("upload: bzip2 compression failed") - return False - - # assuming file is named properly - key += ext - fn += ext - - return (key, fn) - def upload(self, key, fn): try: sz = os.path.getsize(fn) @@ -246,11 +208,16 @@ def upload(self, key, fn): success = True else: cloudlog.info("uploading %r", fn) - # stat = self.killable_upload(key, fn) stat = self.normal_upload(key, fn) if stat is not None and stat.status_code in (200, 201): cloudlog.event("upload_success", key=key, fn=fn, sz=sz) - os.unlink(fn) # delete the file + + # delete the file + try: + os.unlink(fn) + except OSError: + cloudlog.event("delete_failed", stat=stat, exc=self.last_exc, key=key, fn=fn, sz=sz) + success = True else: cloudlog.event("upload_failed", stat=stat, exc=self.last_exc, key=key, fn=fn, sz=sz) @@ -260,23 +227,22 @@ def upload(self, key, fn): return success - - def uploader_fn(exit_event): cloudlog.info("uploader_fn") params = Params() - dongle_id, access_token = params.get("DongleId"), params.get("AccessToken") + dongle_id = params.get("DongleId").decode('utf8') - if dongle_id is None or access_token is None: - cloudlog.info("uploader MISSING DONGLE_ID or ACCESS_TOKEN") - raise Exception("uploader can't start without dongle id and access token") + if dongle_id is None: + cloudlog.info("uploader missing dongle_id") + raise Exception("uploader can't start without dongle id") - uploader = Uploader(dongle_id, access_token, ROOT) + uploader = Uploader(dongle_id, ROOT) backoff = 0.1 while True: - allow_cellular = (params.get("IsUploadVideoOverCellularEnabled") != "0") + allow_raw_upload = (params.get("IsUploadRawEnabled") != b"0") + allow_cellular = (params.get("IsUploadVideoOverCellularEnabled") != b"0") on_hotspot = is_on_hotspot() on_wifi = is_on_wifi() should_upload = allow_cellular or (on_wifi and not on_hotspot) @@ -284,22 +250,12 @@ def uploader_fn(exit_event): if exit_event.is_set(): return - d = uploader.next_file_to_compress() - if d is not None: - key, fn, _ = d - uploader.compress(key, fn) - continue - - if not should_upload: - time.sleep(5) - continue - - d = uploader.next_file_to_upload(with_video=True) + d = uploader.next_file_to_upload(with_raw=allow_raw_upload and should_upload) if d is None: time.sleep(5) continue - key, fn, _ = d + key, fn = d cloudlog.event("uploader_netcheck", allow_cellular=allow_cellular, is_on_hotspot=on_hotspot, is_on_wifi=on_wifi) cloudlog.info("to upload %r", d) diff --git a/selfdrive/logmessaged.py b/selfdrive/logmessaged.py index 971db829335242..265152be5db7a7 100755 --- a/selfdrive/logmessaged.py +++ b/selfdrive/logmessaged.py @@ -1,25 +1,25 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import zmq from logentries import LogentriesHandler -from selfdrive.services import service_list import selfdrive.messaging as messaging -def main(gctx): +def main(gctx=None): # setup logentries. we forward log messages to it le_token = "e8549616-0798-4d7e-a2ca-2513ae81fa17" le_handler = LogentriesHandler(le_token, use_tls=False, verbose=False) le_level = 20 #logging.INFO - ctx = zmq.Context() + ctx = zmq.Context().instance() sock = ctx.socket(zmq.PULL) sock.bind("ipc:///tmp/logmessage") # and we publish them - pub_sock = messaging.pub_sock(ctx, service_list['logMessage'].port) + pub_sock = messaging.pub_sock('logMessage') while True: - dat = ''.join(sock.recv_multipart()) + dat = b''.join(sock.recv_multipart()) + dat = dat.decode('utf8') # print "RECV", repr(dat) @@ -28,6 +28,7 @@ def main(gctx): if levelnum >= le_level: # push to logentries + # TODO: push to athena instead le_handler.emit_raw(dat) # then we publish them @@ -36,4 +37,4 @@ def main(gctx): pub_sock.send(msg.to_bytes()) if __name__ == "__main__": - main(None) + main() diff --git a/selfdrive/manager.py b/selfdrive/manager.py index a1b84cafdc1128..fbb37c51d2721d 100755 --- a/selfdrive/manager.py +++ b/selfdrive/manager.py @@ -1,10 +1,13 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python3.7 import os +import time import sys import fcntl import errno import signal import subprocess +import datetime +from common.spinner import Spinner from common.basedir import BASEDIR sys.path.append(os.path.join(BASEDIR, "pyextra")) @@ -34,48 +37,28 @@ def unblock_stdout(): break try: - sys.stdout.write(dat) + sys.stdout.write(dat.decode('utf8')) except (OSError, IOError): pass os._exit(os.wait()[1]) if __name__ == "__main__": - neos_update_required = os.path.isfile("/init.qcom.rc") \ - and (not os.path.isfile("/VERSION") or int(open("/VERSION").read()) < 8) - if neos_update_required: - # update continue.sh before updating NEOS - if os.path.isfile(os.path.join(BASEDIR, "scripts", "continue.sh")): - from shutil import copyfile - copyfile(os.path.join(BASEDIR, "scripts", "continue.sh"), "/data/data/com.termux/files/continue.sh") - - # run the updater - print("Starting NEOS updater") - subprocess.check_call(["git", "clean", "-xdf"], cwd=BASEDIR) - os.system(os.path.join(BASEDIR, "installer", "updater", "updater")) - raise Exception("NEOS outdated") - elif os.path.isdir("/data/neoupdate"): - from shutil import rmtree - rmtree("/data/neoupdate") - unblock_stdout() import glob import shutil import hashlib import importlib -import subprocess import traceback from multiprocessing import Process -import zmq from setproctitle import setproctitle #pylint: disable=no-name-in-module from common.params import Params import cereal ThermalStatus = cereal.log.ThermalData.ThermalStatus -from selfdrive.services import service_list from selfdrive.swaglog import cloudlog import selfdrive.messaging as messaging from selfdrive.registration import register @@ -88,11 +71,11 @@ def unblock_stdout(): managed_processes = { "thermald": "selfdrive.thermald", "uploader": "selfdrive.loggerd.uploader", + "deleter": "selfdrive.loggerd.deleter", "controlsd": "selfdrive.controls.controlsd", "plannerd": "selfdrive.controls.plannerd", "radard": "selfdrive.controls.radard", - "ubloxd": "selfdrive.locationd.ubloxd", - "mapd": "selfdrive.mapd.mapd", + "ubloxd": ("selfdrive/locationd", ["./ubloxd"]), "loggerd": ("selfdrive/loggerd", ["./loggerd"]), "logmessaged": "selfdrive.logmessaged", "tombstoned": "selfdrive.tombstoned", @@ -100,14 +83,16 @@ def unblock_stdout(): "proclogd": ("selfdrive/proclogd", ["./proclogd"]), "boardd": ("selfdrive/boardd", ["./boardd"]), # not used directly "pandad": "selfdrive.pandad", - "ui": ("selfdrive/ui", ["./start.sh"]), + "ui": ("selfdrive/ui", ["./start.py"]), "calibrationd": "selfdrive.locationd.calibrationd", - "locationd": "selfdrive.locationd.locationd_local", - "visiond": ("selfdrive/visiond", ["./visiond"]), - "sensord": ("selfdrive/sensord", ["./sensord"]), - "gpsd": ("selfdrive/sensord", ["./gpsd"]), + "paramsd": ("selfdrive/locationd", ["./paramsd"]), + "visiond": ("selfdrive/visiond", ["./start.py"]), + "sensord": ("selfdrive/sensord", ["./start_sensord.py"]), + "gpsd": ("selfdrive/sensord", ["./start_gpsd.py"]), "updated": "selfdrive.updated", - "athena": "selfdrive.athena.athenad", +} +daemon_processes = { + "manage_athenad": ("selfdrive.athena.manage_athenad", "AthenadPid"), } android_packages = ("ai.comma.plus.offroad", "ai.comma.plus.frame") @@ -121,6 +106,9 @@ def get_running(): # processes to end with SIGINT instead of SIGTERM interrupt_processes = [] +# processes to end with SIGKILL instead of SIGTERM +kill_processes = ['sensord', 'paramsd'] + persistent_processes = [ 'thermald', 'logmessaged', @@ -128,9 +116,7 @@ def get_running(): 'tombstoned', 'uploader', 'ui', - 'gpsd', 'updated', - 'athena' ] car_started_processes = [ @@ -140,11 +126,12 @@ def get_running(): 'sensord', 'radard', 'calibrationd', - 'locationd', + 'paramsd', 'visiond', 'proclogd', 'ubloxd', - 'mapd', + 'gpsd', + 'deleter', ] def register_managed_process(name, desc, car_started=False): @@ -157,7 +144,7 @@ def register_managed_process(name, desc, car_started=False): persistent_processes.append(name) # ****************** process management functions ****************** -def launcher(proc, gctx): +def launcher(proc): try: # import the process mod = importlib.import_module(proc) @@ -165,8 +152,11 @@ def launcher(proc, gctx): # rename the process setproctitle(proc) + # create now context since we forked + messaging.context = messaging.Context() + # exec the process - mod.main(gctx) + mod.main() except KeyboardInterrupt: cloudlog.warning("child %s got SIGINT" % proc) except Exception: @@ -190,7 +180,7 @@ def start_managed_process(name): proc = managed_processes[name] if isinstance(proc, str): cloudlog.info("starting python %s" % proc) - running[name] = Process(name=name, target=launcher, args=(proc, gctx)) + running[name] = Process(name=name, target=launcher, args=(proc,)) else: pdir, pargs = proc cwd = os.path.join(BASEDIR, pdir) @@ -198,6 +188,28 @@ def start_managed_process(name): running[name] = Process(name=name, target=nativelauncher, args=(pargs, cwd)) running[name].start() +def start_daemon_process(name, params): + proc, pid_param = daemon_processes[name] + pid = params.get(pid_param) + + if pid is not None: + try: + os.kill(int(pid), 0) + # process is running (kill is a poorly-named system call) + return + except OSError: + # process is dead + pass + + cloudlog.info("starting daemon %s" % name) + proc = subprocess.Popen(['python', '-m', proc], + cwd='/', + stdout=open('/dev/null', 'w'), + stderr=open('/dev/null', 'w'), + preexec_fn=os.setpgrp) + + params.put(pid_param, str(proc.pid)) + def prepare_managed_process(p): proc = managed_processes[p] if isinstance(proc, str): @@ -223,11 +235,19 @@ def kill_managed_process(name): if running[name].exitcode is None: if name in interrupt_processes: os.kill(running[name].pid, signal.SIGINT) + elif name in kill_processes: + os.kill(running[name].pid, signal.SIGKILL) else: running[name].terminate() - # give it 5 seconds to die - running[name].join(5.0) + # Process().join(timeout) will hang due to a python 3 bug: https://bugs.python.org/issue28382 + # We have to poll the exitcode instead + # running[name].join(5.0) + + t = time.time() + while time.time() - t < 5 and running[name].exitcode is None: + time.sleep(0.001) + if running[name].exitcode is None: if name in unkillable_processes: cloudlog.critical("unkillable process %s failed to exit! rebooting in 15 if it doesn't die" % name) @@ -262,8 +282,6 @@ def cleanup_all_processes(signal, frame): # ****************** run loop ****************** def manager_init(should_register=True): - global gctx - if should_register: reg_res = register() if reg_res: @@ -291,9 +309,6 @@ def manager_init(should_register=True): except OSError: pass - # set gctx - gctx = {} - def system(cmd): try: cloudlog.info("running %s" % cmd) @@ -307,8 +322,7 @@ def system(cmd): def manager_thread(): # now loop - context = zmq.Context() - thermal_sock = messaging.sub_sock(context, service_list['thermal'].port) + thermal_sock = messaging.sub_sock('thermal') cloudlog.info("manager start") cloudlog.info({"environ": os.environ}) @@ -316,21 +330,27 @@ def manager_thread(): # save boot log subprocess.call(["./loggerd", "--bootlog"], cwd=os.path.join(BASEDIR, "selfdrive/loggerd")) + params = Params() + + # start daemon processes + for p in daemon_processes: + start_daemon_process(p, params) + + # start persistent processes for p in persistent_processes: start_managed_process(p) # start frame pm_apply_packages('enable') + system("LD_LIBRARY_PATH= appops set ai.comma.plus.offroad SU allow") system("am start -n ai.comma.plus.frame/.MainActivity") if os.getenv("NOBOARD") is None: start_managed_process("pandad") - params = Params() logger_dead = False while 1: - # get health of board, log this in "thermal" msg = messaging.recv_sock(thermal_sock, wait=True) # uploader is gated based on the phone temperature @@ -354,15 +374,15 @@ def manager_thread(): kill_managed_process(p) # check the status of all processes, did any of them die? - for p in running: - cloudlog.debug(" running %s %s" % (p, running[p])) + running_list = [" running %s %s" % (p, running[p]) for p in running] + cloudlog.debug('\n'.join(running_list)) - # is this still needed? - if params.get("DoUninstall") == "1": + # Exit main loop when uninstall is needed + if params.get("DoUninstall", encoding='utf8') == "1": break def get_installed_apks(): - dat = subprocess.check_output(["pm", "list", "packages", "-f"]).strip().split("\n") + dat = subprocess.check_output(["pm", "list", "packages", "-f"], encoding='utf8').strip().split("\n") # pylint: disable=unexpected-keyword-arg ret = {} for x in dat: if x.startswith("package:"): @@ -391,16 +411,16 @@ def update_apks(): cloudlog.info("installed apks %s" % (str(installed), )) - for app in installed.iterkeys(): + for app in installed.keys(): apk_path = os.path.join(BASEDIR, "apk/"+app+".apk") if not os.path.exists(apk_path): continue - h1 = hashlib.sha1(open(apk_path).read()).hexdigest() + h1 = hashlib.sha1(open(apk_path, 'rb').read()).hexdigest() h2 = None if installed[app] is not None: - h2 = hashlib.sha1(open(installed[app]).read()).hexdigest() + h2 = hashlib.sha1(open(installed[app], 'rb').read()).hexdigest() cloudlog.info("comparing version of %s %s vs %s" % (app, h1, h2)) if h2 is None or h1 != h2: @@ -415,18 +435,23 @@ def update_apks(): assert success def manager_update(): - if os.path.exists(os.path.join(BASEDIR, "vpn")): - cloudlog.info("installing vpn") - os.system(os.path.join(BASEDIR, "vpn", "install.sh")) update_apks() -def manager_prepare(): + uninstall = [app for app in get_installed_apks().keys() if app in ("com.spotify.music", "com.waze")] + for app in uninstall: + cloudlog.info("uninstalling %s" % app) + os.system("pm uninstall % s" % app) + +def manager_prepare(spinner=None): # build cereal first subprocess.check_call(["make", "-j4"], cwd=os.path.join(BASEDIR, "cereal")) # build all processes os.chdir(os.path.dirname(os.path.abspath(__file__))) - for p in managed_processes: + + for i, p in enumerate(managed_processes): + if spinner is not None: + spinner.update("%d" % (100.0 * (i + 1) / len(managed_processes),)) prepare_managed_process(p) def uninstall(): @@ -440,6 +465,9 @@ def main(): # the flippening! os.system('LD_LIBRARY_PATH="" content insert --uri content://settings/system --bind name:s:user_rotation --bind value:i:1') + # disable bluetooth + os.system('service call bluetooth_manager 8') + if os.getenv("NOLOG") is not None: del managed_processes['loggerd'] del managed_processes['tombstoned'] @@ -462,7 +490,7 @@ def main(): # support additional internal only extensions try: import selfdrive.manager_extensions - selfdrive.manager_extensions.register(register_managed_process) + selfdrive.manager_extensions.register(register_managed_process) # pylint: disable=no-member except ImportError: pass @@ -470,18 +498,20 @@ def main(): params.manager_start() # set unset params + if params.get("CompletedTrainingVersion") is None: + params.put("CompletedTrainingVersion", "0") if params.get("IsMetric") is None: params.put("IsMetric", "0") if params.get("RecordFront") is None: params.put("RecordFront", "0") - if params.get("IsFcwEnabled") is None: - params.put("IsFcwEnabled", "1") if params.get("HasAcceptedTerms") is None: params.put("HasAcceptedTerms", "0") + if params.get("HasCompletedSetup") is None: + params.put("HasCompletedSetup", "0") + if params.get("IsUploadRawEnabled") is None: + params.put("IsUploadRawEnabled", "1") if params.get("IsUploadVideoOverCellularEnabled") is None: params.put("IsUploadVideoOverCellularEnabled", "1") - if params.get("IsDriverMonitoringEnabled") is None: - params.put("IsDriverMonitoringEnabled", "1") if params.get("IsGeofenceEnabled") is None: params.put("IsGeofenceEnabled", "-1") if params.get("SpeedLimitOffset") is None: @@ -490,6 +520,13 @@ def main(): params.put("LongitudinalControl", "0") if params.get("LimitSetSpeed") is None: params.put("LimitSetSpeed", "0") + if params.get("LimitSetSpeedNeural") is None: + params.put("LimitSetSpeedNeural", "0") + if params.get("LastUpdateTime") is None: + t = datetime.datetime.now().isoformat() + params.put("LastUpdateTime", t.encode('utf8')) + if params.get("OpenpilotEnabledToggle") is None: + params.put("OpenpilotEnabledToggle", "1") # is this chffrplus? if os.getenv("PASSIVE") is not None: @@ -498,21 +535,11 @@ def main(): if params.get("Passive") is None: raise Exception("Passive must be set to continue") - # put something on screen while we set things up - if os.getenv("PREPAREONLY") is not None: - spinner_proc = None - else: - spinner_text = "chffrplus" if params.get("Passive")=="1" else "openpilot" - spinner_proc = subprocess.Popen(["./spinner", "loading %s"%spinner_text], - cwd=os.path.join(BASEDIR, "selfdrive", "ui", "spinner"), - close_fds=True) - try: - manager_update() - manager_init() - manager_prepare() - finally: - if spinner_proc: - spinner_proc.terminate() + with Spinner() as spinner: + spinner.update("0") # Show progress bar + manager_update() + manager_init() + manager_prepare(spinner) if os.getenv("PREPAREONLY") is not None: return @@ -528,7 +555,7 @@ def main(): finally: cleanup_all_processes(None, None) - if params.get("DoUninstall") == "1": + if params.get("DoUninstall", encoding='utf8') == "1": uninstall() if __name__ == "__main__": diff --git a/selfdrive/mapd/default_speeds.json b/selfdrive/mapd/default_speeds.json deleted file mode 100644 index 7126c27fcdef40..00000000000000 --- a/selfdrive/mapd/default_speeds.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "_comment": "These speeds are from https://wiki.openstreetmap.org/wiki/Speed_limits Special cases have been stripped", - "AR:urban": "40", - "AR:urban:primary": "60", - "AR:urban:secondary": "60", - "AR:rural": "110", - "AT:urban": "50", - "AT:rural": "100", - "AT:trunk": "100", - "AT:motorway": "130", - "BE:urban": "50", - "BE-VLG:rural": "70", - "BE-WAL:rural": "90", - "BE:trunk": "120", - "BE:motorway": "120", - "CH:urban[1]": "50", - "CH:rural": "80", - "CH:trunk": "100", - "CH:motorway": "120", - "CZ:pedestrian_zone": "20", - "CZ:living_street": "20", - "CZ:urban": "50", - "CZ:urban_trunk": "80", - "CZ:urban_motorway": "80", - "CZ:rural": "90", - "CZ:trunk": "110", - "CZ:motorway": "130", - "DK:urban": "50", - "DK:rural": "80", - "DK:motorway": "130", - "DE:living_street": "7", - "DE:residential": "30", - "DE:urban": "50", - "DE:rural": "100", - "DE:trunk": "none", - "DE:motorway": "none", - "FI:urban": "50", - "FI:rural": "80", - "FI:trunk": "100", - "FI:motorway": "120", - "FR:urban": "50", - "FR:rural": "80", - "FR:trunk": "110", - "FR:motorway": "130", - "GR:urban": "50", - "GR:rural": "90", - "GR:trunk": "110", - "GR:motorway": "130", - "HU:urban": "50", - "HU:rural": "90", - "HU:trunk": "110", - "HU:motorway": "130", - "IT:urban": "50", - "IT:rural": "90", - "IT:trunk": "110", - "IT:motorway": "130", - "JP:national": "60", - "JP:motorway": "100", - "LT:living_street": "20", - "LT:urban": "50", - "LT:rural": "90", - "LT:trunk": "120", - "LT:motorway": "130", - "PL:living_street": "20", - "PL:urban": "50", - "PL:rural": "90", - "PL:trunk": "100", - "PL:motorway": "140", - "RO:urban": "50", - "RO:rural": "90", - "RO:trunk": "100", - "RO:motorway": "130", - "RU:living_street": "20", - "RU:urban": "60", - "RU:rural": "90", - "RU:motorway": "110", - "SK:urban": "50", - "SK:rural": "90", - "SK:trunk": "90", - "SK:motorway": "90", - "SI:urban": "50", - "SI:rural": "90", - "SI:trunk": "110", - "SI:motorway": "130", - "ES:living_street": "20", - "ES:urban": "50", - "ES:rural": "50", - "ES:trunk": "90", - "ES:motorway": "120", - "SE:urban": "50", - "SE:rural": "70", - "SE:trunk": "90", - "SE:motorway": "110", - "GB:nsl_restricted": "30 mph", - "GB:nsl_single": "60 mph", - "GB:nsl_dual": "70 mph", - "GB:motorway": "70 mph", - "UA:urban": "50", - "UA:rural": "90", - "UA:trunk": "110", - "UA:motorway": "130", - "UZ:living_street": "30", - "UZ:urban": "70", - "UZ:rural": "100", - "UZ:motorway": "110" -} diff --git a/selfdrive/mapd/default_speeds_generator.py b/selfdrive/mapd/default_speeds_generator.py deleted file mode 100755 index c98225bd7b61a6..00000000000000 --- a/selfdrive/mapd/default_speeds_generator.py +++ /dev/null @@ -1,215 +0,0 @@ -#!/usr/bin/env python -import json - -DEFAULT_OUTPUT_FILENAME = "default_speeds_by_region.json" - -def main(filename = DEFAULT_OUTPUT_FILENAME): - countries = [] - - """ - -------------------------------------------------- - US - United State of America - -------------------------------------------------- - """ - US = Country("US") # First step, create the country using the ISO 3166 two letter code - countries.append(US) # Second step, add the country to countries list - - """ Default rules """ - # Third step, add some default rules for the country - # Speed limit rules are based on OpenStreetMaps (OSM) tags. - # The dictionary {...} defines the tag_name: value - # if a road in OSM has a tag with the name tag_name and this value, the speed limit listed below will be applied. - # The text at the end is the speed limit (use no unit for km/h) - # Rules apply in the order in which they are written for each country - # Rules for specific regions (states) take priority over country rules - # If you modify existing country rules, you must update all existing states without that rule to use the old rule - US.add_rule({"highway": "motorway"}, "65 mph") # On US roads with the tag highway and value motorway, the speed limit will default to 65 mph - US.add_rule({"highway": "trunk"}, "55 mph") - US.add_rule({"highway": "primary"}, "55 mph") - US.add_rule({"highway": "secondary"}, "45 mph") - US.add_rule({"highway": "tertiary"}, "35 mph") - US.add_rule({"highway": "unclassified"}, "55 mph") - US.add_rule({"highway": "residential"}, "25 mph") - US.add_rule({"highway": "service"}, "25 mph") - US.add_rule({"highway": "motorway_link"}, "55 mph") - US.add_rule({"highway": "trunk_link"}, "55 mph") - US.add_rule({"highway": "primary_link"}, "55 mph") - US.add_rule({"highway": "secondary_link"}, "45 mph") - US.add_rule({"highway": "tertiary_link"}, "35 mph") - US.add_rule({"highway": "living_street"}, "15 mph") - - """ States """ - new_york = US.add_region("New York") # Fourth step, add a state/region to country - new_york.add_rule({"highway": "primary"}, "45 mph") # Fifth step , add rules to the state. See the text above for how to write rules - new_york.add_rule({"highway": "secondary"}, "55 mph") - new_york.add_rule({"highway": "tertiary"}, "55 mph") - new_york.add_rule({"highway": "residential"}, "30 mph") - new_york.add_rule({"highway": "primary_link"}, "45 mph") - new_york.add_rule({"highway": "secondary_link"}, "55 mph") - new_york.add_rule({"highway": "tertiary_link"}, "55 mph") - # All if not written by the state, the rules will default to the country rules - - #california = US.add_region("California") - # California uses only the default US rules - - michigan = US.add_region("Michigan") - michigan.add_rule({"highway": "motorway"}, "70 mph") - - oregon = US.add_region("Oregon") - oregon.add_rule({"highway": "motorway"}, "55 mph") - oregon.add_rule({"highway": "secondary"}, "35 mph") - oregon.add_rule({"highway": "tertiary"}, "30 mph") - oregon.add_rule({"highway": "service"}, "15 mph") - oregon.add_rule({"highway": "secondary_link"}, "35 mph") - oregon.add_rule({"highway": "tertiary_link"}, "30 mph") - - south_dakota = US.add_region("South Dakota") - south_dakota.add_rule({"highway": "motorway"}, "80 mph") - south_dakota.add_rule({"highway": "trunk"}, "70 mph") - south_dakota.add_rule({"highway": "primary"}, "65 mph") - south_dakota.add_rule({"highway": "trunk_link"}, "70 mph") - south_dakota.add_rule({"highway": "primary_link"}, "65 mph") - - wisconsin = US.add_region("Wisconsin") - wisconsin.add_rule({"highway": "trunk"}, "65 mph") - wisconsin.add_rule({"highway": "tertiary"}, "45 mph") - wisconsin.add_rule({"highway": "unclassified"}, "35 mph") - wisconsin.add_rule({"highway": "trunk_link"}, "65 mph") - wisconsin.add_rule({"highway": "tertiary_link"}, "45 mph") - - """ - -------------------------------------------------- - AU - Australia - -------------------------------------------------- - """ - AU = Country("AU") - countries.append(AU) - - """ Default rules """ - AU.add_rule({"highway": "motorway"}, "100") - AU.add_rule({"highway": "trunk"}, "80") - AU.add_rule({"highway": "primary"}, "80") - AU.add_rule({"highway": "secondary"}, "50") - AU.add_rule({"highway": "tertiary"}, "50") - AU.add_rule({"highway": "unclassified"}, "80") - AU.add_rule({"highway": "residential"}, "50") - AU.add_rule({"highway": "service"}, "40") - AU.add_rule({"highway": "motorway_link"}, "90") - AU.add_rule({"highway": "trunk_link"}, "80") - AU.add_rule({"highway": "primary_link"}, "80") - AU.add_rule({"highway": "secondary_link"}, "50") - AU.add_rule({"highway": "tertiary_link"}, "50") - AU.add_rule({"highway": "living_street"}, "30") - - """ - -------------------------------------------------- - CA - Canada - -------------------------------------------------- - """ - CA = Country("CA") - countries.append(CA) - - """ Default rules """ - CA.add_rule({"highway": "motorway"}, "100") - CA.add_rule({"highway": "trunk"}, "80") - CA.add_rule({"highway": "primary"}, "80") - CA.add_rule({"highway": "secondary"}, "50") - CA.add_rule({"highway": "tertiary"}, "50") - CA.add_rule({"highway": "unclassified"}, "80") - CA.add_rule({"highway": "residential"}, "40") - CA.add_rule({"highway": "service"}, "40") - CA.add_rule({"highway": "motorway_link"}, "90") - CA.add_rule({"highway": "trunk_link"}, "80") - CA.add_rule({"highway": "primary_link"}, "80") - CA.add_rule({"highway": "secondary_link"}, "50") - CA.add_rule({"highway": "tertiary_link"}, "50") - CA.add_rule({"highway": "living_street"}, "20") - - - """ - -------------------------------------------------- - DE - Germany - -------------------------------------------------- - """ - DE = Country("DE") - countries.append(DE) - - """ Default rules """ - DE.add_rule({"highway": "motorway"}, "none") - DE.add_rule({"highway": "living_street"}, "10") - DE.add_rule({"highway": "residential"}, "30") - DE.add_rule({"zone:traffic": "DE:rural"}, "100") - DE.add_rule({"zone:traffic": "DE:urban"}, "50") - DE.add_rule({"zone:maxspeed": "DE:30"}, "30") - DE.add_rule({"zone:maxspeed": "DE:urban"}, "50") - DE.add_rule({"zone:maxspeed": "DE:rural"}, "100") - DE.add_rule({"zone:maxspeed": "DE:motorway"}, "none") - DE.add_rule({"bicycle_road": "yes"}, "30") - - - """ --- DO NOT MODIFY CODE BELOW THIS LINE --- """ - """ --- ADD YOUR COUNTRY OR STATE ABOVE --- """ - - # Final step - write_json(countries, filename) - -def write_json(countries, filename = DEFAULT_OUTPUT_FILENAME): - out_dict = {} - for country in countries: - out_dict.update(country.jsonify()) - json_string = json.dumps(out_dict, indent=2) - with open(filename, "wb") as f: - f.write(json_string) - - -class Region(object): - ALLOWABLE_TAG_KEYS = ["highway", "zone:traffic", "bicycle_road", "zone:maxspeed"] - ALLOWABLE_HIGHWAY_TYPES = ["motorway", "trunk", "primary", "secondary", "tertiary", "unclassified", "residential", "service", "motorway_link", "trunk_link", "primary_link", "secondary_link", "tertiary_link", "living_street"] - def __init__(self, name): - self.name = name - self.rules = [] - - def add_rule(self, tag_conditions, speed): - new_rule = {} - if not isinstance(tag_conditions, dict): - raise TypeError("Rule tag conditions must be dictionary") - if not all(tag_key in self.ALLOWABLE_TAG_KEYS for tag_key in tag_conditions): - raise ValueError("Rule tag keys must be in allowable tag kesy") # If this is by mistake, please update ALLOWABLE_TAG_KEYS - if 'highway' in tag_conditions: - if not tag_conditions['highway'] in self.ALLOWABLE_HIGHWAY_TYPES: - raise ValueError("Invalid Highway type {}".format(tag_conditions["highway"])) - new_rule['tags'] = tag_conditions - try: - new_rule['speed'] = str(speed) - except ValueError: - raise ValueError("Rule speed must be string") - self.rules.append(new_rule) - - def jsonify(self): - ret_dict = {} - ret_dict[self.name] = self.rules - return ret_dict - -class Country(Region): - ALLOWABLE_COUNTRY_CODES = ["AF","AX","AL","DZ","AS","AD","AO","AI","AQ","AG","AR","AM","AW","AU","AT","AZ","BS","BH","BD","BB","BY","BE","BZ","BJ","BM","BT","BO","BQ","BA","BW","BV","BR","IO","BN","BG","BF","BI","KH","CM","CA","CV","KY","CF","TD","CL","CN","CX","CC","CO","KM","CG","CD","CK","CR","CI","HR","CU","CW","CY","CZ","DK","DJ","DM","DO","EC","EG","SV","GQ","ER","EE","ET","FK","FO","FJ","FI","FR","GF","PF","TF","GA","GM","GE","DE","GH","GI","GR","GL","GD","GP","GU","GT","GG","GN","GW","GY","HT","HM","VA","HN","HK","HU","IS","IN","ID","IR","IQ","IE","IM","IL","IT","JM","JP","JE","JO","KZ","KE","KI","KP","KR","KW","KG","LA","LV","LB","LS","LR","LY","LI","LT","LU","MO","MK","MG","MW","MY","MV","ML","MT","MH","MQ","MR","MU","YT","MX","FM","MD","MC","MN","ME","MS","MA","MZ","MM","NA","NR","NP","NL","NC","NZ","NI","NE","NG","NU","NF","MP","NO","OM","PK","PW","PS","PA","PG","PY","PE","PH","PN","PL","PT","PR","QA","RE","RO","RU","RW","BL","SH","KN","LC","MF","PM","VC","WS","SM","ST","SA","SN","RS","SC","SL","SG","SX","SK","SI","SB","SO","ZA","GS","SS","ES","LK","SD","SR","SJ","SZ","SE","CH","SY","TW","TJ","TZ","TH","TL","TG","TK","TO","TT","TN","TR","TM","TC","TV","UG","UA","AE","GB","US","UM","UY","UZ","VU","VE","VN","VG","VI","WF","EH","YE","ZM","ZW"] - def __init__(self, ISO_3166_alpha_2): - Region.__init__(self, ISO_3166_alpha_2) - if ISO_3166_alpha_2 not in self.ALLOWABLE_COUNTRY_CODES: - raise ValueError("Not valid IOS 3166 country code") - self.regions = {} - - def add_region(self, name): - self.regions[name] = Region(name) - return self.regions[name] - - def jsonify(self): - ret_dict = {} - ret_dict[self.name] = {} - for r_name, region in self.regions.iteritems(): - ret_dict[self.name].update(region.jsonify()) - ret_dict[self.name]['Default'] = self.rules - return ret_dict - - -if __name__ == '__main__': - main() diff --git a/selfdrive/mapd/mapd.py b/selfdrive/mapd/mapd.py deleted file mode 100755 index 85303857a1adb3..00000000000000 --- a/selfdrive/mapd/mapd.py +++ /dev/null @@ -1,297 +0,0 @@ -#!/usr/bin/env python - -# Add phonelibs openblas to LD_LIBRARY_PATH if import fails -from common.basedir import BASEDIR -try: - from scipy import spatial -except ImportError as e: - import os - import sys - - - openblas_path = os.path.join(BASEDIR, "phonelibs/openblas/") - os.environ['LD_LIBRARY_PATH'] += ':' + openblas_path - - args = [sys.executable] - args.extend(sys.argv) - os.execv(sys.executable, args) - -DEFAULT_SPEEDS_BY_REGION_JSON_FILE = BASEDIR + "/selfdrive/mapd/default_speeds_by_region.json" -import default_speeds_generator -default_speeds_generator.main(DEFAULT_SPEEDS_BY_REGION_JSON_FILE) - -import os -import sys -import time -import zmq -import threading -import numpy as np -import overpy -from collections import defaultdict - -from common.params import Params -from common.transformations.coordinates import geodetic2ecef -from selfdrive.services import service_list -import selfdrive.messaging as messaging -from mapd_helpers import MAPS_LOOKAHEAD_DISTANCE, Way, circle_through_points -import selfdrive.crash as crash -from selfdrive.version import version, dirty - - -OVERPASS_API_URL = "https://overpass.kumi.systems/api/interpreter" -OVERPASS_HEADERS = { - 'User-Agent': 'NEOS (comma.ai)', - 'Accept-Encoding': 'gzip' -} - -last_gps = None -query_lock = threading.Lock() -last_query_result = None -last_query_pos = None -cache_valid = False - -def build_way_query(lat, lon, radius=50): - """Builds a query to find all highways within a given radius around a point""" - pos = " (around:%f,%f,%f)" % (radius, lat, lon) - lat_lon = "(%f,%f)" % (lat, lon) - q = """( - way - """ + pos + """ - [highway][highway!~"^(footway|path|bridleway|steps|cycleway|construction|bus_guideway|escape)$"]; - >;);out;""" + """is_in""" + lat_lon + """;area._[admin_level~"[24]"]; - convert area ::id = id(), admin_level = t['admin_level'], - name = t['name'], "ISO3166-1:alpha2" = t['ISO3166-1:alpha2'];out; - """ - return q - - -def query_thread(): - global last_query_result, last_query_pos, cache_valid - api = overpy.Overpass(url=OVERPASS_API_URL, headers=OVERPASS_HEADERS, timeout=10.) - - while True: - time.sleep(1) - if last_gps is not None: - fix_ok = last_gps.flags & 1 - if not fix_ok: - continue - - if last_query_pos is not None: - cur_ecef = geodetic2ecef((last_gps.latitude, last_gps.longitude, last_gps.altitude)) - prev_ecef = geodetic2ecef((last_query_pos.latitude, last_query_pos.longitude, last_query_pos.altitude)) - dist = np.linalg.norm(cur_ecef - prev_ecef) - if dist < 1000: #updated when we are 1km from the edge of the downloaded circle - continue - - if dist > 3000: - cache_valid = False - - q = build_way_query(last_gps.latitude, last_gps.longitude, radius=3000) - try: - new_result = api.query(q) - - # Build kd-tree - nodes = [] - real_nodes = [] - node_to_way = defaultdict(list) - location_info = {} - - for n in new_result.nodes: - nodes.append((float(n.lat), float(n.lon), 0)) - real_nodes.append(n) - - for way in new_result.ways: - for n in way.nodes: - node_to_way[n.id].append(way) - - for area in new_result.areas: - if area.tags.get('admin_level', '') == "2": - location_info['country'] = area.tags.get('ISO3166-1:alpha2', '') - if area.tags.get('admin_level', '') == "4": - location_info['region'] = area.tags.get('name', '') - - nodes = np.asarray(nodes) - nodes = geodetic2ecef(nodes) - tree = spatial.cKDTree(nodes) - - query_lock.acquire() - last_query_result = new_result, tree, real_nodes, node_to_way, location_info - last_query_pos = last_gps - cache_valid = True - query_lock.release() - - except Exception as e: - print e - query_lock.acquire() - last_query_result = None - query_lock.release() - - -def mapsd_thread(): - global last_gps - - context = zmq.Context() - gps_sock = messaging.sub_sock(context, service_list['gpsLocation'].port, conflate=True) - gps_external_sock = messaging.sub_sock(context, service_list['gpsLocationExternal'].port, conflate=True) - map_data_sock = messaging.pub_sock(context, service_list['liveMapData'].port) - - cur_way = None - curvature_valid = False - curvature = None - upcoming_curvature = 0. - dist_to_turn = 0. - road_points = None - - while True: - gps = messaging.recv_one(gps_sock) - gps_ext = messaging.recv_one_or_none(gps_external_sock) - - if gps_ext is not None: - gps = gps_ext.gpsLocationExternal - else: - gps = gps.gpsLocation - - last_gps = gps - - fix_ok = gps.flags & 1 - if not fix_ok or last_query_result is None or not cache_valid: - cur_way = None - curvature = None - curvature_valid = False - upcoming_curvature = 0. - dist_to_turn = 0. - road_points = None - map_valid = False - else: - map_valid = True - lat = gps.latitude - lon = gps.longitude - heading = gps.bearing - speed = gps.speed - - query_lock.acquire() - cur_way = Way.closest(last_query_result, lat, lon, heading, cur_way) - if cur_way is not None: - pnts, curvature_valid = cur_way.get_lookahead(lat, lon, heading, MAPS_LOOKAHEAD_DISTANCE) - - xs = pnts[:, 0] - ys = pnts[:, 1] - road_points = map(float, xs), map(float, ys) - - if speed < 10: - curvature_valid = False - if curvature_valid and pnts.shape[0] <= 3: - curvature_valid = False - - # The curvature is valid when at least MAPS_LOOKAHEAD_DISTANCE of road is found - if curvature_valid: - # Compute the curvature for each point - with np.errstate(divide='ignore'): - circles = [circle_through_points(*p) for p in zip(pnts, pnts[1:], pnts[2:])] - circles = np.asarray(circles) - radii = np.nan_to_num(circles[:, 2]) - radii[radii < 10] = np.inf - curvature = 1. / radii - - # Index of closest point - closest = np.argmin(np.linalg.norm(pnts, axis=1)) - dist_to_closest = pnts[closest, 0] # We can use x distance here since it should be close - - # Compute distance along path - dists = list() - dists.append(0) - for p, p_prev in zip(pnts, pnts[1:, :]): - dists.append(dists[-1] + np.linalg.norm(p - p_prev)) - dists = np.asarray(dists) - dists = dists - dists[closest] + dist_to_closest - dists = dists[1:-1] - - close_idx = np.logical_and(dists > 0, dists < 500) - dists = dists[close_idx] - curvature = curvature[close_idx] - - if len(curvature): - # TODO: Determine left or right turn - curvature = np.nan_to_num(curvature) - - # Outlier rejection - new_curvature = np.percentile(curvature, 90, interpolation='lower') - - k = 0.6 - upcoming_curvature = k * upcoming_curvature + (1 - k) * new_curvature - in_turn_indices = curvature > 0.8 * new_curvature - - if np.any(in_turn_indices): - dist_to_turn = np.min(dists[in_turn_indices]) - else: - dist_to_turn = 999 - else: - upcoming_curvature = 0. - dist_to_turn = 999 - - query_lock.release() - - dat = messaging.new_message() - dat.init('liveMapData') - - if last_gps is not None: - dat.liveMapData.lastGps = last_gps - - if cur_way is not None: - dat.liveMapData.wayId = cur_way.id - - # Seed limit - max_speed = cur_way.max_speed() - if max_speed is not None: - dat.liveMapData.speedLimitValid = True - dat.liveMapData.speedLimit = max_speed - - # TODO: use the function below to anticipate upcoming speed limits - #max_speed_ahead, max_speed_ahead_dist = cur_way.max_speed_ahead(max_speed, lat, lon, heading, MAPS_LOOKAHEAD_DISTANCE) - #if max_speed_ahead is not None and max_speed_ahead_dist is not None: - # dat.liveMapData.speedLimitAheadValid = True - # dat.liveMapData.speedLimitAhead = float(max_speed_ahead) - # dat.liveMapData.speedLimitAheadDistance = float(max_speed_ahead_dist) - - - advisory_max_speed = cur_way.advisory_max_speed() - if advisory_max_speed is not None: - dat.liveMapData.speedAdvisoryValid = True - dat.liveMapData.speedAdvisory = advisory_max_speed - - # Curvature - dat.liveMapData.curvatureValid = curvature_valid - dat.liveMapData.curvature = float(upcoming_curvature) - dat.liveMapData.distToTurn = float(dist_to_turn) - if road_points is not None: - dat.liveMapData.roadX, dat.liveMapData.roadY = road_points - if curvature is not None: - dat.liveMapData.roadCurvatureX = map(float, dists) - dat.liveMapData.roadCurvature = map(float, curvature) - - dat.liveMapData.mapValid = map_valid - - map_data_sock.send(dat.to_bytes()) - - -def main(gctx=None): - params = Params() - dongle_id = params.get("DongleId") - crash.bind_user(id=dongle_id) - crash.bind_extra(version=version, dirty=dirty, is_eon=True) - crash.install() - - main_thread = threading.Thread(target=mapsd_thread) - main_thread.daemon = True - main_thread.start() - - q_thread = threading.Thread(target=query_thread) - q_thread.daemon = True - q_thread.start() - - while True: - time.sleep(0.1) - - -if __name__ == "__main__": - main() diff --git a/selfdrive/mapd/mapd_helpers.py b/selfdrive/mapd/mapd_helpers.py deleted file mode 100644 index 0a462765ecce39..00000000000000 --- a/selfdrive/mapd/mapd_helpers.py +++ /dev/null @@ -1,360 +0,0 @@ -import math -import json -import numpy as np -from datetime import datetime -from common.basedir import BASEDIR -from selfdrive.config import Conversions as CV -from common.transformations.coordinates import LocalCoord, geodetic2ecef - -LOOKAHEAD_TIME = 10. -MAPS_LOOKAHEAD_DISTANCE = 50 * LOOKAHEAD_TIME - -DEFAULT_SPEEDS_JSON_FILE = BASEDIR + "/selfdrive/mapd/default_speeds.json" -DEFAULT_SPEEDS = {} -with open(DEFAULT_SPEEDS_JSON_FILE, "rb") as f: - DEFAULT_SPEEDS = json.loads(f.read()) - -DEFAULT_SPEEDS_BY_REGION_JSON_FILE = BASEDIR + "/selfdrive/mapd/default_speeds_by_region.json" -DEFAULT_SPEEDS_BY_REGION = {} -with open(DEFAULT_SPEEDS_BY_REGION_JSON_FILE, "rb") as f: - DEFAULT_SPEEDS_BY_REGION = json.loads(f.read()) - -def circle_through_points(p1, p2, p3): - """Fits a circle through three points - Formulas from: http://www.ambrsoft.com/trigocalc/circle3d.htm""" - x1, y1, _ = p1 - x2, y2, _ = p2 - x3, y3, _ = p3 - - A = x1 * (y2 - y3) - y1 * (x2 - x3) + x2 * y3 - x3 * y2 - B = (x1**2 + y1**2) * (y3 - y2) + (x2**2 + y2**2) * (y1 - y3) + (x3**2 + y3**2) * (y2 - y1) - C = (x1**2 + y1**2) * (x2 - x3) + (x2**2 + y2**2) * (x3 - x1) + (x3**2 + y3**2) * (x1 - x2) - D = (x1**2 + y1**2) * (x3 * y2 - x2 * y3) + (x2**2 + y2**2) * (x1 * y3 - x3 * y1) + (x3**2 + y3**2) * (x2 * y1 - x1 * y2) - - return (-B / (2 * A), - C / (2 * A), np.sqrt((B**2 + C**2 - 4 * A * D) / (4 * A**2))) - -def parse_speed_unit(max_speed): - """Converts a maxspeed string to m/s based on the unit present in the input. - OpenStreetMap defaults to kph if no unit is present. """ - - if not max_speed: - return None - - conversion = CV.KPH_TO_MS - if 'mph' in max_speed: - max_speed = max_speed.replace(' mph', '') - conversion = CV.MPH_TO_MS - try: - return float(max_speed) * conversion - except ValueError: - return None - -def parse_speed_tags(tags): - """Parses tags on a way to find the maxspeed string""" - max_speed = None - - if 'maxspeed' in tags: - max_speed = tags['maxspeed'] - - if 'maxspeed:conditional' in tags: - try: - max_speed_cond, cond = tags['maxspeed:conditional'].split(' @ ') - cond = cond[1:-1] - - start, end = cond.split('-') - now = datetime.now() # TODO: Get time and timezone from gps fix so this will work correctly on replays - start = datetime.strptime(start, "%H:%M").replace(year=now.year, month=now.month, day=now.day) - end = datetime.strptime(end, "%H:%M").replace(year=now.year, month=now.month, day=now.day) - - if start <= now <= end: - max_speed = max_speed_cond - except ValueError: - pass - - if not max_speed and 'source:maxspeed' in tags: - max_speed = DEFAULT_SPEEDS.get(tags['source:maxspeed'], None) - if not max_speed and 'maxspeed:type' in tags: - max_speed = DEFAULT_SPEEDS.get(tags['maxspeed:type'], None) - - max_speed = parse_speed_unit(max_speed) - return max_speed - -def geocode_maxspeed(tags, location_info): - max_speed = None - try: - geocode_country = location_info.get('country', '') - geocode_region = location_info.get('region', '') - - country_rules = DEFAULT_SPEEDS_BY_REGION.get(geocode_country, {}) - country_defaults = country_rules.get('Default', []) - for rule in country_defaults: - rule_valid = all( - tag_name in tags - and tags[tag_name] == value - for tag_name, value in rule['tags'].iteritems() - ) - if rule_valid: - max_speed = rule['speed'] - break #stop searching country - - region_rules = country_rules.get(geocode_region, []) - for rule in region_rules: - rule_valid = all( - tag_name in tags - and tags[tag_name] == value - for tag_name, value in rule['tags'].iteritems() - ) - if rule_valid: - max_speed = rule['speed'] - break #stop searching region - except KeyError: - pass - max_speed = parse_speed_unit(max_speed) - return max_speed - -class Way: - def __init__(self, way, query_results): - self.id = way.id - self.way = way - self.query_results = query_results - - points = list() - - for node in self.way.get_nodes(resolve_missing=False): - points.append((float(node.lat), float(node.lon), 0.)) - - self.points = np.asarray(points) - - @classmethod - def closest(cls, query_results, lat, lon, heading, prev_way=None): - results, tree, real_nodes, node_to_way, location_info = query_results - - cur_pos = geodetic2ecef((lat, lon, 0)) - nodes = tree.query_ball_point(cur_pos, 500) - - # If no nodes within 500m, choose closest one - if not nodes: - nodes = [tree.query(cur_pos)[1]] - - ways = [] - for n in nodes: - real_node = real_nodes[n] - ways += node_to_way[real_node.id] - ways = set(ways) - - closest_way = None - best_score = None - for way in ways: - way = Way(way, query_results) - points = way.points_in_car_frame(lat, lon, heading) - - on_way = way.on_way(lat, lon, heading, points) - if not on_way: - continue - - # Create mask of points in front and behind - x = points[:, 0] - y = points[:, 1] - angles = np.arctan2(y, x) - front = np.logical_and((-np.pi / 2) < angles, - angles < (np.pi / 2)) - behind = np.logical_not(front) - - dists = np.linalg.norm(points, axis=1) - - # Get closest point behind the car - dists_behind = np.copy(dists) - dists_behind[front] = np.NaN - closest_behind = points[np.nanargmin(dists_behind)] - - # Get closest point in front of the car - dists_front = np.copy(dists) - dists_front[behind] = np.NaN - closest_front = points[np.nanargmin(dists_front)] - - # fit line: y = a*x + b - x1, y1, _ = closest_behind - x2, y2, _ = closest_front - a = (y2 - y1) / max((x2 - x1), 1e-5) - b = y1 - a * x1 - - # With a factor of 60 a 20m offset causes the same error as a 20 degree heading error - # (A 20 degree heading offset results in an a of about 1/3) - score = abs(a) * 60. + abs(b) - - # Prefer same type of road - if prev_way is not None: - if way.way.tags.get('highway', '') == prev_way.way.tags.get('highway', ''): - score *= 0.5 - - if closest_way is None or score < best_score: - closest_way = way - best_score = score - - return closest_way - - def __str__(self): - return "%s %s" % (self.id, self.way.tags) - - def max_speed(self): - """Extracts the (conditional) speed limit from a way""" - if not self.way: - return None - - max_speed = parse_speed_tags(self.way.tags) - if not max_speed: - location_info = self.query_results[4] - max_speed = geocode_maxspeed(self.way.tags, location_info) - - return max_speed - - def max_speed_ahead(self, current_speed_limit, lat, lon, heading, lookahead): - """Look ahead for a max speed""" - if not self.way: - return None - - speed_ahead = None - speed_ahead_dist = None - lookahead_ways = 5 - way = self - for i in range(lookahead_ways): - way_pts = way.points_in_car_frame(lat, lon, heading) - - # Check current lookahead distance - max_dist = np.linalg.norm(way_pts[-1, :]) - - if max_dist > 2 * lookahead: - break - - if 'maxspeed' in way.way.tags: - spd = parse_speed_tags(way.way.tags) - if not spd: - location_info = self.query_results[4] - spd = geocode_maxspeed(way.way.tags, location_info) - if spd < current_speed_limit: - speed_ahead = spd - min_dist = np.linalg.norm(way_pts[1, :]) - speed_ahead_dist = min_dist - break - # Find next way - way = way.next_way() - if not way: - break - - return speed_ahead, speed_ahead_dist - - def advisory_max_speed(self): - if not self.way: - return None - - tags = self.way.tags - adv_speed = None - - if 'maxspeed:advisory' in tags: - adv_speed = tags['maxspeed:advisory'] - adv_speed = parse_speed_unit(adv_speed) - return adv_speed - - def on_way(self, lat, lon, heading, points=None): - if points is None: - points = self.points_in_car_frame(lat, lon, heading) - x = points[:, 0] - return np.min(x) < 0. and np.max(x) > 0. - - def closest_point(self, lat, lon, heading, points=None): - if points is None: - points = self.points_in_car_frame(lat, lon, heading) - i = np.argmin(np.linalg.norm(points, axis=1)) - return points[i] - - def distance_to_closest_node(self, lat, lon, heading, points=None): - if points is None: - points = self.points_in_car_frame(lat, lon, heading) - return np.min(np.linalg.norm(points, axis=1)) - - def points_in_car_frame(self, lat, lon, heading): - lc = LocalCoord.from_geodetic([lat, lon, 0.]) - - # Build rotation matrix - heading = math.radians(-heading + 90) - c, s = np.cos(heading), np.sin(heading) - rot = np.array([[c, s, 0.], [-s, c, 0.], [0., 0., 1.]]) - - # Convert to local coordinates - points_carframe = lc.geodetic2ned(self.points).T - - # Rotate with heading of car - points_carframe = np.dot(rot, points_carframe[(1, 0, 2), :]).T - - return points_carframe - - def next_way(self, backwards=False): - results, tree, real_nodes, node_to_way, location_info = self.query_results - - if backwards: - node = self.way.nodes[0] - else: - node = self.way.nodes[-1] - - ways = node_to_way[node.id] - - way = None - try: - # Simple heuristic to find next way - ways = [w for w in ways if w.id != self.id] - ways = [w for w in ways if w.nodes[0] == node] - - # Filter on highway tag - acceptable_tags = list() - cur_tag = self.way.tags['highway'] - acceptable_tags.append(cur_tag) - if cur_tag == 'motorway_link': - acceptable_tags.append('motorway') - acceptable_tags.append('trunk') - acceptable_tags.append('primary') - ways = [w for w in ways if w.tags['highway'] in acceptable_tags] - - # Filter on number of lanes - cur_num_lanes = int(self.way.tags['lanes']) - if len(ways) > 1: - ways_same_lanes = [w for w in ways if int(w.tags['lanes']) == cur_num_lanes] - if len(ways_same_lanes) == 1: - ways = ways_same_lanes - if len(ways) > 1: - ways = [w for w in ways if int(w.tags['lanes']) > cur_num_lanes] - if len(ways) == 1: - way = Way(ways[0], self.query_results) - - except (KeyError, ValueError): - pass - - return way - - def get_lookahead(self, lat, lon, heading, lookahead): - pnts = None - way = self - valid = False - - for i in range(5): - # Get new points and append to list - new_pnts = way.points_in_car_frame(lat, lon, heading) - - if pnts is None: - pnts = new_pnts - else: - pnts = np.vstack([pnts, new_pnts]) - - # Check current lookahead distance - max_dist = np.linalg.norm(pnts[-1, :]) - if max_dist > lookahead: - valid = True - - if max_dist > 2 * lookahead: - break - - # Find next way - way = way.next_way() - if not way: - break - - return pnts, valid diff --git a/selfdrive/messaging.py b/selfdrive/messaging.py deleted file mode 100644 index 4811f934548f19..00000000000000 --- a/selfdrive/messaging.py +++ /dev/null @@ -1,63 +0,0 @@ -import zmq - -from cereal import log -from common import realtime - -def new_message(): - dat = log.Event.new_message() - dat.logMonoTime = int(realtime.sec_since_boot() * 1e9) - return dat - -def pub_sock(context, port, addr="*"): - sock = context.socket(zmq.PUB) - sock.bind("tcp://%s:%d" % (addr, port)) - return sock - -def sub_sock(context, port, poller=None, addr="127.0.0.1", conflate=False): - sock = context.socket(zmq.SUB) - if conflate: - sock.setsockopt(zmq.CONFLATE, 1) - sock.connect("tcp://%s:%d" % (addr, port)) - sock.setsockopt(zmq.SUBSCRIBE, b"") - if poller is not None: - poller.register(sock, zmq.POLLIN) - return sock - -def drain_sock(sock, wait_for_one=False): - ret = [] - while 1: - try: - if wait_for_one and len(ret) == 0: - dat = sock.recv() - else: - dat = sock.recv(zmq.NOBLOCK) - dat = log.Event.from_bytes(dat) - ret.append(dat) - except zmq.error.Again: - break - return ret - - -# TODO: print when we drop packets? -def recv_sock(sock, wait=False): - dat = None - while 1: - try: - if wait and dat is None: - dat = sock.recv() - else: - dat = sock.recv(zmq.NOBLOCK) - except zmq.error.Again: - break - if dat is not None: - dat = log.Event.from_bytes(dat) - return dat - -def recv_one(sock): - return log.Event.from_bytes(sock.recv()) - -def recv_one_or_none(sock): - try: - return log.Event.from_bytes(sock.recv(zmq.NOBLOCK)) - except zmq.error.Again: - return None diff --git a/selfdrive/messaging/.gitignore b/selfdrive/messaging/.gitignore new file mode 100644 index 00000000000000..1549b67ca5936e --- /dev/null +++ b/selfdrive/messaging/.gitignore @@ -0,0 +1 @@ +demo diff --git a/selfdrive/messaging/Makefile b/selfdrive/messaging/Makefile new file mode 100644 index 00000000000000..d53e5ece190bee --- /dev/null +++ b/selfdrive/messaging/Makefile @@ -0,0 +1,63 @@ +CXX := clang++ +CC := clang + +BASEDIR = ../.. +PHONELIBS = ../../phonelibs + +CXXFLAGS := -g -O3 -fPIC -std=c++11 -Wall -Wextra -Wshadow -Weffc++ -Wstrict-aliasing -Wpedantic -Werror -MMD -I$(BASEDIR)/selfdrive + +LDLIBS=-lm -lstdc++ -lrt -lpthread + +UNAME_M := $(shell uname -m) + +YAML_FLAGS = -I$(PHONELIBS)/yaml-cpp/include +YAML_LIB = $(abspath $(PHONELIBS)/yaml-cpp/lib/libyaml-cpp.a) + +ifeq ($(UNAME_M),aarch64) + LDFLAGS += -llog -lgnustl_shared + ZMQ_LIBS = /usr/lib/libzmq.a +endif +ifeq ($(UNAME_M),x86_64) + ZMQ_FLAGS = -I$(BASEDIR)/phonelibs/zmq/x64/include + ZMQ_LIBS = $(abspath $(PHONELIBS)/zmq/x64/lib/libzmq.a) + YAML_DIR = $(PHONELIBS)/yaml-cpp/x64/lib/ + YAML_LIB = $(abspath $(PHONELIBS)/yaml-cpp/x64/lib/libyaml-cpp.a) +endif + +ifdef ASAN + CXXFLAGS += -fsanitize=address -fno-omit-frame-pointer + LDFLAGS += -fsanitize=address +endif + +CXXFLAGS += $(ZMQ_FLAGS) $(YAML_FLAGS) + +OBJS := messaging.o impl_zmq.o +DEPS=$(OBJS:.o=.d) + +.PRECIOUS: $(OBJS) +.PHONY: all clean +all: messaging.a messaging_pyx.so + +demo: messaging.a demo.o + $(CC) $(LDFLAGS) $^ $(LDLIBS) -L. -l:messaging.a -o '$@' + +messaging_pyx.so: messaging.a messaging_pyx_setup.py messaging_pyx.pyx messaging.pxd + python3 messaging_pyx_setup.py build_ext --inplace + rm -rf build + rm -f messaging_pyx.cpp + +%.a: $(OBJS) + @echo "[ LINK ] $@" + mkdir -p libs; \ + cd libs; \ + ar -x $(ZMQ_LIBS); \ + ar -x $(YAML_LIB); + + ar rcsD '$@' $^ libs/*.o + rm -r libs + +clean: + @echo "[ CLEAN ]" + rm -rf *.so *.a demo libs $(OBJS) $(DEPS) + +-include $(DEPS) diff --git a/selfdrive/messaging/__init__.py b/selfdrive/messaging/__init__.py new file mode 100644 index 00000000000000..e637756bd5b4d1 --- /dev/null +++ b/selfdrive/messaging/__init__.py @@ -0,0 +1,214 @@ +import os +import subprocess + +can_dir = os.path.dirname(os.path.abspath(__file__)) +subprocess.check_call(["make"], cwd=can_dir) +from .messaging_pyx import Context, Poller, SubSocket, PubSocket # pylint: disable=no-name-in-module, import-error + +from cereal import log +from common.realtime import sec_since_boot +from selfdrive.services import service_list + + +context = Context() + +def new_message(): + dat = log.Event.new_message() + dat.logMonoTime = int(sec_since_boot() * 1e9) + dat.valid = True + return dat + +def pub_sock(endpoint): + sock = PubSocket() + sock.connect(context, endpoint) + return sock + +def sub_sock(endpoint, poller=None, addr="127.0.0.1", conflate=False, timeout=None): + sock = SubSocket() + addr = addr.encode('utf8') + sock.connect(context, endpoint, addr, conflate) + + if timeout is not None: + sock.setTimeout(timeout) + + if poller is not None: + poller.registerSocket(sock) + return sock + + +def drain_sock_raw(sock, wait_for_one=False): + """Receive all message currently available on the queue""" + ret = [] + while 1: + if wait_for_one and len(ret) == 0: + dat = sock.receive() + else: + dat = sock.receive(non_blocking=True) + + if dat is None: + break + + ret.append(dat) + + return ret + +def drain_sock(sock, wait_for_one=False): + """Receive all message currently available on the queue""" + ret = [] + while 1: + if wait_for_one and len(ret) == 0: + dat = sock.receive() + else: + dat = sock.receive(non_blocking=True) + + if dat is None: # Timeout hit + break + + dat = log.Event.from_bytes(dat) + ret.append(dat) + + return ret + + +# TODO: print when we drop packets? +def recv_sock(sock, wait=False): + """Same as drain sock, but only returns latest message. Consider using conflate instead.""" + dat = None + + while 1: + if wait and dat is None: + rcv = sock.receive() + else: + rcv = sock.receive(non_blocking=True) + + if rcv is None: # Timeout hit + break + + dat = rcv + + if dat is not None: + dat = log.Event.from_bytes(dat) + + return dat + +def recv_one(sock): + dat = sock.receive() + if dat is not None: + dat = log.Event.from_bytes(dat) + return dat + +def recv_one_or_none(sock): + dat = sock.receive(non_blocking=True) + if dat is not None: + dat = log.Event.from_bytes(dat) + return dat + +def recv_one_retry(sock): + """Keep receiving until we get a message""" + while True: + dat = sock.receive() + if dat is not None: + return log.Event.from_bytes(dat) + +def get_one_can(logcan): + while True: + can = recv_one_retry(logcan) + if len(can.can) > 0: + return can + +class SubMaster(): + def __init__(self, services, ignore_alive=None, addr="127.0.0.1"): + self.poller = Poller() + self.frame = -1 + self.updated = {s : False for s in services} + self.rcv_time = {s : 0. for s in services} + self.rcv_frame = {s : 0 for s in services} + self.alive = {s : False for s in services} + self.sock = {} + self.freq = {} + self.data = {} + self.logMonoTime = {} + self.valid = {} + + if ignore_alive is not None: + self.ignore_alive = ignore_alive + else: + self.ignore_alive = [] + + for s in services: + # TODO: get address automatically from service_list + if addr is not None: + self.sock[s] = sub_sock(s, poller=self.poller, addr=addr, conflate=True) + self.freq[s] = service_list[s].frequency + + data = new_message() + if s in ['can', 'sensorEvents', 'liveTracks', 'sendCan', + 'ethernetData', 'cellInfo', 'wifiScan', + 'trafficEvents', 'orbObservation', 'carEvents']: + data.init(s, 0) + else: + data.init(s) + self.data[s] = getattr(data, s) + self.logMonoTime[s] = 0 + self.valid[s] = data.valid + + def __getitem__(self, s): + return self.data[s] + + def update(self, timeout=-1): + msgs = [] + for sock in self.poller.poll(timeout): + msgs.append(recv_one(sock)) + self.update_msgs(sec_since_boot(), msgs) + + def update_msgs(self, cur_time, msgs): + # TODO: add optional input that specify the service to wait for + self.frame += 1 + self.updated = dict.fromkeys(self.updated, False) + for msg in msgs: + if msg is None: + continue + + s = msg.which() + self.updated[s] = True + self.rcv_time[s] = cur_time + self.rcv_frame[s] = self.frame + self.data[s] = getattr(msg, s) + self.logMonoTime[s] = msg.logMonoTime + self.valid[s] = msg.valid + + for s in self.data: + # arbitrary small number to avoid float comparison. If freq is 0, we can skip the check + if self.freq[s] > 1e-5: + # alive if delay is within 10x the expected frequency + self.alive[s] = (cur_time - self.rcv_time[s]) < (10. / self.freq[s]) + else: + self.alive[s] = True + + def all_alive(self, service_list=None): + if service_list is None: # check all + service_list = self.alive.keys() + return all(self.alive[s] for s in service_list if s not in self.ignore_alive) + + def all_valid(self, service_list=None): + if service_list is None: # check all + service_list = self.valid.keys() + return all(self.valid[s] for s in service_list) + + def all_alive_and_valid(self, service_list=None): + if service_list is None: # check all + service_list = self.alive.keys() + return self.all_alive(service_list=service_list) and self.all_valid(service_list=service_list) + + +class PubMaster(): + def __init__(self, services): + self.sock = {} + for s in services: + self.sock[s] = pub_sock(s) + + def send(self, s, dat): + # accept either bytes or capnp builder + if not isinstance(dat, bytes): + dat = dat.to_bytes() + self.sock[s].send(dat) diff --git a/selfdrive/messaging/demo.cc b/selfdrive/messaging/demo.cc new file mode 100644 index 00000000000000..cfdf42209415fc --- /dev/null +++ b/selfdrive/messaging/demo.cc @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include + +#include "messaging.hpp" +#include "impl_zmq.hpp" + +#define MSGS 1e5 + +int main() { + Context * c = Context::create(); + SubSocket * sub_sock = SubSocket::create(c, "controlsState"); + PubSocket * pub_sock = PubSocket::create(c, "controlsState"); + + char data[8]; + + Poller * poller = Poller::create({sub_sock}); + + auto start = std::chrono::steady_clock::now(); + + for (uint64_t i = 0; i < MSGS; i++){ + *(uint64_t*)data = i; + pub_sock->send(data, 8); + + auto r = poller->poll(100); + + for (auto p : r){ + Message * m = p->receive(); + uint64_t ii = *(uint64_t*)m->getData(); + assert(i == ii); + delete m; + } + } + + + auto end = std::chrono::steady_clock::now(); + double elapsed = std::chrono::duration_cast(end - start).count() / 1e9; + double throughput = ((double) MSGS / (double) elapsed); + std::cout << throughput << " msg/s" << std::endl; + + delete poller; + delete sub_sock; + delete pub_sock; + delete c; + + + return 0; +} diff --git a/selfdrive/messaging/demo.py b/selfdrive/messaging/demo.py new file mode 100644 index 00000000000000..7906a41e203cdf --- /dev/null +++ b/selfdrive/messaging/demo.py @@ -0,0 +1,30 @@ +import time + +from messaging_pyx import Context, Poller, SubSocket, PubSocket # pylint: disable=no-name-in-module, import-error + +MSGS = 1e5 + +if __name__ == "__main__": + c = Context() + sub_sock = SubSocket() + pub_sock = PubSocket() + + sub_sock.connect(c, "controlsState") + pub_sock.connect(c, "controlsState") + + + poller = Poller() + poller.registerSocket(sub_sock) + + t = time.time() + for i in range(int(MSGS)): + bts = i.to_bytes(4, 'little') + pub_sock.send(bts) + + for s in poller.poll(100): + dat = s.receive() + ii = int.from_bytes(dat, 'little') + assert(i == ii) + + dt = time.time() - t + print("%.1f msg/s" % (MSGS / dt)) diff --git a/selfdrive/messaging/impl_zmq.cc b/selfdrive/messaging/impl_zmq.cc new file mode 100644 index 00000000000000..93223e863ac089 --- /dev/null +++ b/selfdrive/messaging/impl_zmq.cc @@ -0,0 +1,173 @@ +#include +#include +#include +#include + +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" +#include +#pragma GCC diagnostic pop + +#include "impl_zmq.hpp" + +static int get_port(std::string endpoint) { + char * base_dir_ptr = std::getenv("BASEDIR"); + + if (base_dir_ptr == NULL){ + base_dir_ptr = std::getenv("PYTHONPATH"); + } + + assert(base_dir_ptr); + std::string base_dir = base_dir_ptr; + std::string service_list_path = base_dir + "/selfdrive/service_list.yaml"; + YAML::Node service_list = YAML::LoadFile(service_list_path); + + int port = -1; + for (const auto& it : service_list) { + auto name = it.first.as(); + + if (name == endpoint){ + port = it.second[0].as(); + break; + } + } + + if (port == -1){ + std::cout << "Service " << endpoint << " not found" << std::endl; + } + + assert(port >= 0); + return port; +} + +ZMQContext::ZMQContext() { + context = zmq_ctx_new(); +} + +ZMQContext::~ZMQContext() { + zmq_ctx_term(context); +} + +void ZMQMessage::init(size_t sz) { + size = sz; + data = new char[size]; +} + +void ZMQMessage::init(char * d, size_t sz) { + size = sz; + data = new char[size]; + memcpy(data, d, size); +} + +void ZMQMessage::close() { + if (size > 0){ + delete[] data; + } + size = 0; +} + +ZMQMessage::~ZMQMessage() { + this->close(); +} + + +void ZMQSubSocket::connect(Context *context, std::string endpoint, std::string address, bool conflate){ + sock = zmq_socket(context->getRawContext(), ZMQ_SUB); + assert(sock); + + zmq_setsockopt(sock, ZMQ_SUBSCRIBE, "", 0); + + if (conflate){ + int arg = 1; + zmq_setsockopt(sock, ZMQ_CONFLATE, &arg, sizeof(int)); + } + + int reconnect_ivl = 500; + zmq_setsockopt(sock, ZMQ_RECONNECT_IVL_MAX, &reconnect_ivl, sizeof(reconnect_ivl)); + + full_endpoint = "tcp://" + address + ":"; + full_endpoint += std::to_string(get_port(endpoint)); + + std::cout << "ZMQ SUB: " << full_endpoint << std::endl; + + assert(zmq_connect(sock, full_endpoint.c_str()) == 0); +} + + +Message * ZMQSubSocket::receive(bool non_blocking){ + zmq_msg_t msg; + assert(zmq_msg_init(&msg) == 0); + + int flags = non_blocking ? ZMQ_DONTWAIT : 0; + int rc = zmq_msg_recv(&msg, sock, flags); + Message *r = NULL; + + if (rc >= 0){ + // Make a copy to ensure the data is aligned + r = new ZMQMessage; + r->init((char*)zmq_msg_data(&msg), zmq_msg_size(&msg)); + } + + zmq_msg_close(&msg); + return r; +} + +void ZMQSubSocket::setTimeout(int timeout){ + zmq_setsockopt(sock, ZMQ_RCVTIMEO, &timeout, sizeof(int)); +} + +ZMQSubSocket::~ZMQSubSocket(){ + zmq_close(sock); +} + +void ZMQPubSocket::connect(Context *context, std::string endpoint){ + sock = zmq_socket(context->getRawContext(), ZMQ_PUB); + + full_endpoint = "tcp://*:"; + full_endpoint += std::to_string(get_port(endpoint)); + + std::cout << "ZMQ PUB: " << full_endpoint << std::endl; + + assert(zmq_bind(sock, full_endpoint.c_str()) == 0); +} + +int ZMQPubSocket::sendMessage(Message *message){ + return zmq_send(sock, message->getData(), message->getSize(), ZMQ_DONTWAIT); +} + +int ZMQPubSocket::send(char *data, size_t size){ + return zmq_send(sock, data, size, ZMQ_DONTWAIT); +} + +ZMQPubSocket::~ZMQPubSocket(){ + zmq_close(sock); +} + + +void ZMQPoller::registerSocket(SubSocket * socket){ + assert(num_polls + 1 < MAX_POLLERS); + polls[num_polls].socket = socket->getRawSocket(); + polls[num_polls].events = ZMQ_POLLIN; + + sockets.push_back(socket); + num_polls++; +} + +std::vector ZMQPoller::poll(int timeout){ + std::vector r; + + int rc = zmq_poll(polls, num_polls, timeout); + if (rc < 0){ + return r; + } + + for (size_t i = 0; i < num_polls; i++){ + if (polls[i].revents){ + r.push_back(sockets[i]); + } + } + + return r; +} diff --git a/selfdrive/messaging/impl_zmq.hpp b/selfdrive/messaging/impl_zmq.hpp new file mode 100644 index 00000000000000..a40d623e3af849 --- /dev/null +++ b/selfdrive/messaging/impl_zmq.hpp @@ -0,0 +1,63 @@ +#pragma once +#include "messaging.hpp" +#include +#include + +#define MAX_POLLERS 128 + +class ZMQContext : public Context { +private: + void * context = NULL; +public: + ZMQContext(); + void * getRawContext() {return context;} + ~ZMQContext(); +}; + +class ZMQMessage : public Message { +private: + char * data; + size_t size; +public: + void init(size_t size); + void init(char *data, size_t size); + size_t getSize(){return size;} + char * getData(){return data;} + void close(); + ~ZMQMessage(); +}; + +class ZMQSubSocket : public SubSocket { +private: + void * sock; + std::string full_endpoint; +public: + void connect(Context *context, std::string endpoint, std::string address, bool conflate=false); + void setTimeout(int timeout); + void * getRawSocket() {return sock;} + Message *receive(bool non_blocking=false); + ~ZMQSubSocket(); +}; + +class ZMQPubSocket : public PubSocket { +private: + void * sock; + std::string full_endpoint; +public: + void connect(Context *context, std::string endpoint); + int sendMessage(Message *message); + int send(char *data, size_t size); + ~ZMQPubSocket(); +}; + +class ZMQPoller : public Poller { +private: + std::vector sockets; + zmq_pollitem_t polls[MAX_POLLERS]; + size_t num_polls = 0; + +public: + void registerSocket(SubSocket *socket); + std::vector poll(int timeout); + ~ZMQPoller(){}; +}; diff --git a/selfdrive/messaging/messaging.cc b/selfdrive/messaging/messaging.cc new file mode 100644 index 00000000000000..a1178a510872a6 --- /dev/null +++ b/selfdrive/messaging/messaging.cc @@ -0,0 +1,51 @@ +#include "messaging.hpp" +#include "impl_zmq.hpp" + +Context * Context::create(){ + Context * c = new ZMQContext(); + return c; +} + +SubSocket * SubSocket::create(){ + SubSocket * s = new ZMQSubSocket(); + return s; +} + +SubSocket * SubSocket::create(Context * context, std::string endpoint){ + SubSocket *s = SubSocket::create(); + s->connect(context, endpoint, "127.0.0.1"); + + return s; +} + +SubSocket * SubSocket::create(Context * context, std::string endpoint, std::string address){ + SubSocket *s = SubSocket::create(); + s->connect(context, endpoint, address); + + return s; +} + +PubSocket * PubSocket::create(){ + PubSocket * s = new ZMQPubSocket(); + return s; +} + +PubSocket * PubSocket::create(Context * context, std::string endpoint){ + PubSocket *s = PubSocket::create(); + s->connect(context, endpoint); + return s; +} + +Poller * Poller::create(){ + Poller * p = new ZMQPoller(); + return p; +} + +Poller * Poller::create(std::vector sockets){ + Poller * p = Poller::create(); + + for (auto s : sockets){ + p->registerSocket(s); + } + return p; +} diff --git a/selfdrive/messaging/messaging.hpp b/selfdrive/messaging/messaging.hpp new file mode 100644 index 00000000000000..95e34c0d67f4dc --- /dev/null +++ b/selfdrive/messaging/messaging.hpp @@ -0,0 +1,53 @@ +#pragma once +#include +#include +#include + +class Context { +public: + virtual void * getRawContext() = 0; + static Context * create(); + virtual ~Context(){}; +}; + +class Message { +public: + virtual void init(size_t size) = 0; + virtual void init(char * data, size_t size) = 0; + virtual void close() = 0; + virtual size_t getSize() = 0; + virtual char * getData() = 0; + virtual ~Message(){}; +}; + + +class SubSocket { +public: + virtual void connect(Context *context, std::string endpoint, std::string address, bool conflate=false) = 0; + virtual void setTimeout(int timeout) = 0; + virtual Message *receive(bool non_blocking=false) = 0; + virtual void * getRawSocket() = 0; + static SubSocket * create(); + static SubSocket * create(Context * context, std::string endpoint); + static SubSocket * create(Context * context, std::string endpoint, std::string address); + virtual ~SubSocket(){}; +}; + +class PubSocket { +public: + virtual void connect(Context *context, std::string endpoint) = 0; + virtual int sendMessage(Message *message) = 0; + virtual int send(char *data, size_t size) = 0; + static PubSocket * create(); + static PubSocket * create(Context * context, std::string endpoint); + virtual ~PubSocket(){}; +}; + +class Poller { +public: + virtual void registerSocket(SubSocket *socket) = 0; + virtual std::vector poll(int timeout) = 0; + static Poller * create(); + static Poller * create(std::vector sockets); + virtual ~Poller(){}; +}; diff --git a/selfdrive/messaging/messaging.pxd b/selfdrive/messaging/messaging.pxd new file mode 100644 index 00000000000000..5e3da7241544cf --- /dev/null +++ b/selfdrive/messaging/messaging.pxd @@ -0,0 +1,42 @@ +# distutils: language = c++ +#cython: language_level=3 + +from libcpp.string cimport string +from libcpp.vector cimport vector +from libcpp cimport bool + + +cdef extern from "messaging.hpp": + cdef cppclass Context: + @staticmethod + Context * create() + + cdef cppclass Message: + void init(size_t) + void init(char *, size_t) + void close() + size_t getSize() + char *getData() + + + + cdef cppclass SubSocket: + @staticmethod + SubSocket * create() + void connect(Context *, string, string, bool) + Message * receive(bool) + void setTimeout(int) + + + cdef cppclass PubSocket: + @staticmethod + PubSocket * create() + void connect(Context *, string) + int sendMessage(Message *) + int send(char *, size_t) + + cdef cppclass Poller: + @staticmethod + Poller * create() + void registerSocket(SubSocket *) + vector[SubSocket*] poll(int) diff --git a/selfdrive/messaging/messaging_pyx.pyx b/selfdrive/messaging/messaging_pyx.pyx new file mode 100644 index 00000000000000..ff55c310750fd1 --- /dev/null +++ b/selfdrive/messaging/messaging_pyx.pyx @@ -0,0 +1,104 @@ +# distutils: language = c++ +# cython: c_string_encoding=ascii, language_level=3 + +from libcpp.string cimport string +from libcpp cimport bool + + +from messaging cimport Context as cppContext +from messaging cimport SubSocket as cppSubSocket +from messaging cimport PubSocket as cppPubSocket +from messaging cimport Poller as cppPoller +from messaging cimport Message as cppMessage + + +cdef class Context: + cdef cppContext * context + def __cinit__(self): + self.context = cppContext.create() + + def __dealloc__(self): + pass + # Deleting the context will hang if sockets are still active + # TODO: Figure out a way to make sure the context is closed last + # del self.context + + +cdef class Poller: + cdef cppPoller * poller + cdef list sub_sockets + + def __cinit__(self): + self.sub_sockets = [] + self.poller = cppPoller.create() + + def __dealloc__(self): + del self.poller + + def registerSocket(self, SubSocket socket): + self.sub_sockets.append(socket) + self.poller.registerSocket(socket.socket) + + def poll(self, timeout): + sockets = [] + + result = self.poller.poll(timeout) + for s in result: + socket = SubSocket() + socket.setPtr(s) + sockets.append(socket) + + return sockets + +cdef class SubSocket: + cdef cppSubSocket * socket + cdef bool is_owner + + def __cinit__(self): + self.socket = cppSubSocket.create() + self.is_owner = True + + def __dealloc__(self): + if self.is_owner: + del self.socket + + cdef setPtr(self, cppSubSocket * ptr): + if self.is_owner: + del self.socket + + self.is_owner = False + self.socket = ptr + + def connect(self, Context context, string endpoint, string address=b"127.0.0.1", bool conflate=False): + self.socket.connect(context.context, endpoint, address, conflate) + + def setTimeout(self, int timeout): + self.socket.setTimeout(timeout) + + + def receive(self, bool non_blocking=False): + msg = self.socket.receive(non_blocking) + + if msg == NULL: + return None + else: + sz = msg.getSize() + m = msg.getData()[:sz] + del msg + + return m + + +cdef class PubSocket: + cdef cppPubSocket * socket + def __cinit__(self): + self.socket = cppPubSocket.create() + + def __dealloc__(self): + del self.socket + + def connect(self, Context context, string endpoint): + self.socket.connect(context.context, endpoint) + + def send(self, string data): + return self.socket.send(data.c_str(), len(data)) diff --git a/selfdrive/messaging/messaging_pyx_setup.py b/selfdrive/messaging/messaging_pyx_setup.py new file mode 100644 index 00000000000000..53cd73c7d76d3a --- /dev/null +++ b/selfdrive/messaging/messaging_pyx_setup.py @@ -0,0 +1,34 @@ +import os +import subprocess +from distutils.core import Extension, setup # pylint: disable=import-error,no-name-in-module + +from Cython.Build import cythonize + +from common.basedir import BASEDIR +from common.cython_hacks import BuildExtWithoutPlatformSuffix + +sourcefiles = ['messaging_pyx.pyx'] +extra_compile_args = ["-std=c++11"] +libraries = [] +ARCH = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() # pylint: disable=unexpected-keyword-arg + +if ARCH == "aarch64": + extra_compile_args += ["-Wno-deprecated-register"] + libraries += ['gnustl_shared'] + +setup(name='CAN parser', + cmdclass={'build_ext': BuildExtWithoutPlatformSuffix}, + ext_modules=cythonize( + Extension( + "messaging_pyx", + language="c++", + sources=sourcefiles, + extra_compile_args=extra_compile_args, + libraries=libraries, + extra_objects=[ + os.path.join(BASEDIR, 'selfdrive', 'messaging', 'messaging.a'), + ] + ) + ), + nthreads=4, +) diff --git a/selfdrive/orbd/.gitignore b/selfdrive/orbd/.gitignore deleted file mode 100644 index 829780eb506383..00000000000000 --- a/selfdrive/orbd/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -orbd -orbd_cpu -test/turbocv_profile -test/turbocv_test -dspout/* -dumb_test -bilinear_lut.h -orb_lut.h diff --git a/selfdrive/orbd/Makefile b/selfdrive/orbd/Makefile deleted file mode 100644 index 32e9c6dfa549da..00000000000000 --- a/selfdrive/orbd/Makefile +++ /dev/null @@ -1,105 +0,0 @@ -# CPU - -CC = clang -CXX = clang++ - -WARN_FLAGS = -Werror=implicit-function-declaration \ - -Werror=incompatible-pointer-types \ - -Werror=int-conversion \ - -Werror=return-type \ - -Werror=format-extra-args - -JSON_FLAGS = -I$(PHONELIBS)/json/src - -CFLAGS = -std=gnu11 -g -O2 -fPIC $(WARN_FLAGS) -Iinclude $(JSON_FLAGS) -I. -CXXFLAGS = -std=c++11 -g -O2 -fPIC $(WARN_FLAGS) -Iinclude $(JSON_FLAGS) -I. -LDFLAGS = - -# profile -# CXXFLAGS += -DTURBOCV_PROFILE=1 - -PHONELIBS = ../../phonelibs -BASEDIR = ../.. -EXTERNAL = ../../external -PYTHONLIBS = - -UNAME_M := $(shell uname -m) - -ifeq ($(UNAME_M),x86_64) -# computer - -ZMQ_FLAGS = -I$(PHONELIBS)/zmq/aarch64/include -ZMQ_LIBS = -L$(BASEDIR)/external/zmq/lib/ \ - -l:libczmq.a -l:libzmq.a -lpthread - -OPENCV_LIBS = -lopencv_core -lopencv_highgui -lopencv_features2d -lopencv_imgproc - -CXXFLAGS += -fopenmp -LDFLAGS += -lomp - -else -# phone -ZMQ_FLAGS = -I$(PHONELIBS)/zmq/aarch64/include -ZMQ_LIBS = -L$(PHONELIBS)/zmq/aarch64/lib \ - -l:libczmq.a -l:libzmq.a \ - -lgnustl_shared - -OPENCV_FLAGS = -I$(PHONELIBS)/opencv/include -OPENCV_LIBS = -Wl,--enable-new-dtags -Wl,-rpath,/usr/local/lib/python2.7/site-packages -L/usr/local/lib/python2.7/site-packages -l:cv2.so - -endif - -.PHONY: all -all: orbd - -include ../common/cereal.mk - -DEP_OBJS = ../common/visionipc.o ../common/ipc.o ../common/swaglog.o $(PHONELIBS)/json/src/json.o - -orbd: orbd_dsp.o $(DEP_OBJS) calculator_stub.o freethedsp.o - @echo "[ LINK ] $@" - $(CXX) -fPIC -o '$@' $^ \ - $(LDFLAGS) \ - $(ZMQ_LIBS) \ - $(CEREAL_LIBS) \ - -L/usr/lib \ - -L/system/vendor/lib64 \ - -ladsprpc \ - -lm -lz -llog - -%.o: %.c - @echo "[ CC ] $@" - $(CC) $(CFLAGS) \ - $(ZMQ_FLAGS) \ - -I../ \ - -I../../ \ - -c -o '$@' '$<' - -orbd_dsp.o: orbd.cc - @echo "[ CXX ] $@" - $(CXX) $(CXXFLAGS) \ - $(CEREAL_CXXFLAGS) \ - $(ZMQ_FLAGS) \ - $(OPENCV_FLAGS) \ - -DDSP \ - -I../ \ - -I../../ \ - -I../../../ \ - -I./include \ - -c -o '$@' '$<' - -freethedsp.o: dsp/freethedsp.c - @echo "[ CC ] $@" - $(CC) $(CFLAGS) \ - -c -o '$@' '$<' - -calculator_stub.o: dsp/gen/calculator_stub.c - @echo "[ CC ] $@" - $(CC) $(CFLAGS) -I./include -c -o '$@' '$<' - --include internal.mk - -.PHONY: clean -clean: - rm -f *.o turbocv.so orbd test/turbocv_profile test/turbocv_test test/*.o *_lut.h - diff --git a/selfdrive/orbd/dsp/freethedsp.c b/selfdrive/orbd/dsp/freethedsp.c deleted file mode 100644 index 298f4fd83143b0..00000000000000 --- a/selfdrive/orbd/dsp/freethedsp.c +++ /dev/null @@ -1,119 +0,0 @@ -// freethedsp by geohot -// (because the DSP should be free) -// released under MIT License - -// usage instructions: -// 1. Compile an example from the Qualcomm Hexagon SDK -// 2. Try to run it on your phone -// 3. Be very sad when "adsprpc ... dlopen error: ... signature verify start failed for ..." appears in logcat -// ...here is where people would give up before freethedsp -// 4. Compile freethedsp with 'clang -shared freethedsp.c -o freethedsp.so' (or statically link it to your program) -// 5. Run your program with 'LD_PRELOAD=./freethedsp.so ./' -// 6. OMG THE DSP WORKS -// 7. Be happy. - -// *** patch may have to change for your phone *** - -// this is patching /dsp/fastrpc_shell_0 -// correct if sha hash of fastrpc_shell_0 is "fbadc96848aefad99a95aa4edb560929dcdf78f8" -// patch to return 0xFFFFFFFF from is_test_enabled instead of 0 -// your fastrpc_shell_0 may vary -#define PATCH_ADDR 0x5200c -#define PATCH_OLD "\x40\x3f\x20\x50" -#define PATCH_NEW "\x40\x3f\x00\x5a" -#define PATCH_LEN (sizeof(PATCH_OLD)-1) -#define _BITS_IOCTL_H_ - -// under 100 lines of code begins now -#include -#include -#include -#include -#include - -// ioctl stuff -#define IOC_OUT 0x40000000 /* copy out parameters */ -#define IOC_IN 0x80000000 /* copy in parameters */ -#define IOC_INOUT (IOC_IN|IOC_OUT) -#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */ - -#define _IOC(inout,group,num,len) \ - (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num)) -#define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t)) - -// ion ioctls -#include -#define ION_IOC_MSM_MAGIC 'M' -#define ION_IOC_CLEAN_INV_CACHES _IOWR(ION_IOC_MSM_MAGIC, 2, \ - struct ion_flush_data) - -struct ion_flush_data { - ion_user_handle_t handle; - int fd; - void *vaddr; - unsigned int offset; - unsigned int length; -}; - -// fastrpc ioctls -#define FASTRPC_IOCTL_INIT _IOWR('R', 6, struct fastrpc_ioctl_init) - -struct fastrpc_ioctl_init { - uint32_t flags; /* one of FASTRPC_INIT_* macros */ - uintptr_t __user file; /* pointer to elf file */ - int32_t filelen; /* elf file length */ - int32_t filefd; /* ION fd for the file */ - uintptr_t __user mem; /* mem for the PD */ - int32_t memlen; /* mem length */ - int32_t memfd; /* ION fd for the mem */ -}; - -int ioctl(int fd, unsigned long request, void *arg) { - static void *handle = NULL; - static int (*orig_ioctl)(int, int, void*); - - if (handle == NULL) { - handle = dlopen("/system/lib64/libc.so", RTLD_LAZY); - assert(handle != NULL); - orig_ioctl = dlsym(handle, "ioctl"); - } - - int ret = orig_ioctl(fd, request, arg); - - // carefully modify this one - if (request == FASTRPC_IOCTL_INIT) { - struct fastrpc_ioctl_init *init = (struct fastrpc_ioctl_init *)arg; - - // confirm patch is correct and do the patch - assert(memcmp((void*)(init->mem+PATCH_ADDR), PATCH_OLD, PATCH_LEN) == 0); - memcpy((void*)(init->mem+PATCH_ADDR), PATCH_NEW, PATCH_LEN); - - // flush cache - int ionfd = open("/dev/ion", O_RDONLY); - assert(ionfd > 0); - - struct ion_fd_data fd_data; - fd_data.fd = init->memfd; - int ret = ioctl(ionfd, ION_IOC_IMPORT, &fd_data); - assert(ret == 0); - - struct ion_flush_data flush_data; - flush_data.handle = fd_data.handle; - flush_data.vaddr = (void*)init->mem; - flush_data.offset = 0; - flush_data.length = init->memlen; - ret = ioctl(ionfd, ION_IOC_CLEAN_INV_CACHES, &flush_data); - assert(ret == 0); - - struct ion_handle_data handle_data; - handle_data.handle = fd_data.handle; - ret = ioctl(ionfd, ION_IOC_FREE, &handle_data); - assert(ret == 0); - - // cleanup - close(ionfd); - } - - return ret; -} - diff --git a/selfdrive/orbd/dsp/gen/calculator.h b/selfdrive/orbd/dsp/gen/calculator.h deleted file mode 100644 index 86a3de6717c833..00000000000000 --- a/selfdrive/orbd/dsp/gen/calculator.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _CALCULATOR_H -#define _CALCULATOR_H - -#include -typedef uint8_t uint8; -typedef uint32_t uint32; - -#ifndef __QAIC_HEADER -#define __QAIC_HEADER(ff) ff -#endif //__QAIC_HEADER - -#ifndef __QAIC_HEADER_EXPORT -#define __QAIC_HEADER_EXPORT -#endif // __QAIC_HEADER_EXPORT - -#ifndef __QAIC_HEADER_ATTRIBUTE -#define __QAIC_HEADER_ATTRIBUTE -#endif // __QAIC_HEADER_ATTRIBUTE - -#ifndef __QAIC_IMPL -#define __QAIC_IMPL(ff) ff -#endif //__QAIC_IMPL - -#ifndef __QAIC_IMPL_EXPORT -#define __QAIC_IMPL_EXPORT -#endif // __QAIC_IMPL_EXPORT - -#ifndef __QAIC_IMPL_ATTRIBUTE -#define __QAIC_IMPL_ATTRIBUTE -#endif // __QAIC_IMPL_ATTRIBUTE -#ifdef __cplusplus -extern "C" { -#endif -__QAIC_HEADER_EXPORT int __QAIC_HEADER(calculator_init)(uint32* leet) __QAIC_HEADER_ATTRIBUTE; -__QAIC_HEADER_EXPORT int __QAIC_HEADER(calculator_extract_and_match)(const uint8* img, int imgLen, uint8* features, int featuresLen) __QAIC_HEADER_ATTRIBUTE; -#ifdef __cplusplus -} -#endif -#endif //_CALCULATOR_H diff --git a/selfdrive/orbd/dsp/gen/calculator_stub.c b/selfdrive/orbd/dsp/gen/calculator_stub.c deleted file mode 100644 index 66e4a0f822158d..00000000000000 --- a/selfdrive/orbd/dsp/gen/calculator_stub.c +++ /dev/null @@ -1,613 +0,0 @@ -#ifndef _CALCULATOR_STUB_H -#define _CALCULATOR_STUB_H -#include "calculator.h" - -// remote.h -#include -#include - -typedef uint32_t remote_handle; -typedef uint64_t remote_handle64; - -typedef struct { - void *pv; - size_t nLen; -} remote_buf; - -typedef struct { - int32_t fd; - uint32_t offset; -} remote_dma_handle; - -typedef union { - remote_buf buf; - remote_handle h; - remote_handle64 h64; - remote_dma_handle dma; -} remote_arg; - -int remote_handle_open(const char* name, remote_handle *ph); -int remote_handle_invoke(remote_handle h, uint32_t dwScalars, remote_arg *pra); -int remote_handle_close(remote_handle h); - -#define REMOTE_SCALARS_MAKEX(nAttr,nMethod,nIn,nOut,noIn,noOut) \ - ((((uint32_t) (nAttr) & 0x7) << 29) | \ - (((uint32_t) (nMethod) & 0x1f) << 24) | \ - (((uint32_t) (nIn) & 0xff) << 16) | \ - (((uint32_t) (nOut) & 0xff) << 8) | \ - (((uint32_t) (noIn) & 0x0f) << 4) | \ - ((uint32_t) (noOut) & 0x0f)) - -#ifndef _QAIC_ENV_H -#define _QAIC_ENV_H - -#ifdef __GNUC__ -#ifdef __clang__ -#pragma GCC diagnostic ignored "-Wunknown-pragmas" -#else -#pragma GCC diagnostic ignored "-Wpragmas" -#endif -#pragma GCC diagnostic ignored "-Wuninitialized" -#pragma GCC diagnostic ignored "-Wunused-parameter" -#pragma GCC diagnostic ignored "-Wunused-function" -#endif - -#ifndef _ATTRIBUTE_UNUSED - -#ifdef _WIN32 -#define _ATTRIBUTE_UNUSED -#else -#define _ATTRIBUTE_UNUSED __attribute__ ((unused)) -#endif - -#endif // _ATTRIBUTE_UNUSED - -#ifndef __QAIC_REMOTE -#define __QAIC_REMOTE(ff) ff -#endif //__QAIC_REMOTE - -#ifndef __QAIC_HEADER -#define __QAIC_HEADER(ff) ff -#endif //__QAIC_HEADER - -#ifndef __QAIC_HEADER_EXPORT -#define __QAIC_HEADER_EXPORT -#endif // __QAIC_HEADER_EXPORT - -#ifndef __QAIC_HEADER_ATTRIBUTE -#define __QAIC_HEADER_ATTRIBUTE -#endif // __QAIC_HEADER_ATTRIBUTE - -#ifndef __QAIC_IMPL -#define __QAIC_IMPL(ff) ff -#endif //__QAIC_IMPL - -#ifndef __QAIC_IMPL_EXPORT -#define __QAIC_IMPL_EXPORT -#endif // __QAIC_IMPL_EXPORT - -#ifndef __QAIC_IMPL_ATTRIBUTE -#define __QAIC_IMPL_ATTRIBUTE -#endif // __QAIC_IMPL_ATTRIBUTE - -#ifndef __QAIC_STUB -#define __QAIC_STUB(ff) ff -#endif //__QAIC_STUB - -#ifndef __QAIC_STUB_EXPORT -#define __QAIC_STUB_EXPORT -#endif // __QAIC_STUB_EXPORT - -#ifndef __QAIC_STUB_ATTRIBUTE -#define __QAIC_STUB_ATTRIBUTE -#endif // __QAIC_STUB_ATTRIBUTE - -#ifndef __QAIC_SKEL -#define __QAIC_SKEL(ff) ff -#endif //__QAIC_SKEL__ - -#ifndef __QAIC_SKEL_EXPORT -#define __QAIC_SKEL_EXPORT -#endif // __QAIC_SKEL_EXPORT - -#ifndef __QAIC_SKEL_ATTRIBUTE -#define __QAIC_SKEL_ATTRIBUTE -#endif // __QAIC_SKEL_ATTRIBUTE - -#ifdef __QAIC_DEBUG__ - #ifndef __QAIC_DBG_PRINTF__ - #include - #define __QAIC_DBG_PRINTF__( ee ) do { printf ee ; } while(0) - #endif -#else - #define __QAIC_DBG_PRINTF__( ee ) (void)0 -#endif - - -#define _OFFSET(src, sof) ((void*)(((char*)(src)) + (sof))) - -#define _COPY(dst, dof, src, sof, sz) \ - do {\ - struct __copy { \ - char ar[sz]; \ - };\ - *(struct __copy*)_OFFSET(dst, dof) = *(struct __copy*)_OFFSET(src, sof);\ - } while (0) - -#define _COPYIF(dst, dof, src, sof, sz) \ - do {\ - if(_OFFSET(dst, dof) != _OFFSET(src, sof)) {\ - _COPY(dst, dof, src, sof, sz); \ - } \ - } while (0) - -_ATTRIBUTE_UNUSED -static __inline void _qaic_memmove(void* dst, void* src, int size) { - int i; - for(i = 0; i < size; ++i) { - ((char*)dst)[i] = ((char*)src)[i]; - } -} - -#define _MEMMOVEIF(dst, src, sz) \ - do {\ - if(dst != src) {\ - _qaic_memmove(dst, src, sz);\ - } \ - } while (0) - - -#define _ASSIGN(dst, src, sof) \ - do {\ - dst = OFFSET(src, sof); \ - } while (0) - -#define _STD_STRLEN_IF(str) (str == 0 ? 0 : strlen(str)) - -#define AEE_SUCCESS 0 -#define AEE_EOFFSET 0x80000400 -#define AEE_EBADPARM (AEE_EOFFSET + 0x00E) - -#define _TRY(ee, func) \ - do { \ - if (AEE_SUCCESS != ((ee) = func)) {\ - __QAIC_DBG_PRINTF__((__FILE__ ":%d:error:%d:%s\n", __LINE__, (int)(ee),#func));\ - goto ee##bail;\ - } \ - } while (0) - -#define _CATCH(exception) exception##bail: if (exception != AEE_SUCCESS) - -#define _ASSERT(nErr, ff) _TRY(nErr, 0 == (ff) ? AEE_EBADPARM : AEE_SUCCESS) - -#ifdef __QAIC_DEBUG__ -#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, _allocator_alloc(pal, __FILE_LINE__, size, alignment, (void**)&pv)) -#else -#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, _allocator_alloc(pal, 0, size, alignment, (void**)&pv)) -#endif - - -#endif // _QAIC_ENV_H - -#ifndef _ALLOCATOR_H -#define _ALLOCATOR_H - -#include -#include - -typedef struct _heap _heap; -struct _heap { - _heap* pPrev; - const char* loc; - uint64_t buf; -}; - -typedef struct _allocator { - _heap* pheap; - uint8_t* stack; - uint8_t* stackEnd; - int nSize; -} _allocator; - -_ATTRIBUTE_UNUSED -static __inline int _heap_alloc(_heap** ppa, const char* loc, int size, void** ppbuf) { - _heap* pn = 0; - pn = malloc(size + sizeof(_heap) - sizeof(uint64_t)); - if(pn != 0) { - pn->pPrev = *ppa; - pn->loc = loc; - *ppa = pn; - *ppbuf = (void*)&(pn->buf); - return 0; - } else { - return -1; - } -} -#define _ALIGN_SIZE(x, y) (((x) + (y-1)) & ~(y-1)) - -_ATTRIBUTE_UNUSED -static __inline int _allocator_alloc(_allocator* me, - const char* loc, - int size, - unsigned int al, - void** ppbuf) { - if(size < 0) { - return -1; - } else if (size == 0) { - *ppbuf = 0; - return 0; - } - if((_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size) < (uintptr_t)me->stack + me->nSize) { - *ppbuf = (uint8_t*)_ALIGN_SIZE((uintptr_t)me->stackEnd, al); - me->stackEnd = (uint8_t*)_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size; - return 0; - } else { - return _heap_alloc(&me->pheap, loc, size, ppbuf); - } -} - -_ATTRIBUTE_UNUSED -static __inline void _allocator_deinit(_allocator* me) { - _heap* pa = me->pheap; - while(pa != 0) { - _heap* pn = pa; - const char* loc = pn->loc; - (void)loc; - pa = pn->pPrev; - free(pn); - } -} - -_ATTRIBUTE_UNUSED -static __inline void _allocator_init(_allocator* me, uint8_t* stack, int stackSize) { - me->stack = stack; - me->stackEnd = stack + stackSize; - me->nSize = stackSize; - me->pheap = 0; -} - - -#endif // _ALLOCATOR_H - -#ifndef SLIM_H -#define SLIM_H - -#include - -//a C data structure for the idl types that can be used to implement -//static and dynamic language bindings fairly efficiently. -// -//the goal is to have a minimal ROM and RAM footprint and without -//doing too many allocations. A good way to package these things seemed -//like the module boundary, so all the idls within one module can share -//all the type references. - - -#define PARAMETER_IN 0x0 -#define PARAMETER_OUT 0x1 -#define PARAMETER_INOUT 0x2 -#define PARAMETER_ROUT 0x3 -#define PARAMETER_INROUT 0x4 - -//the types that we get from idl -#define TYPE_OBJECT 0x0 -#define TYPE_INTERFACE 0x1 -#define TYPE_PRIMITIVE 0x2 -#define TYPE_ENUM 0x3 -#define TYPE_STRING 0x4 -#define TYPE_WSTRING 0x5 -#define TYPE_STRUCTURE 0x6 -#define TYPE_UNION 0x7 -#define TYPE_ARRAY 0x8 -#define TYPE_SEQUENCE 0x9 - -//these require the pack/unpack to recurse -//so it's a hint to those languages that can optimize in cases where -//recursion isn't necessary. -#define TYPE_COMPLEX_STRUCTURE (0x10 | TYPE_STRUCTURE) -#define TYPE_COMPLEX_UNION (0x10 | TYPE_UNION) -#define TYPE_COMPLEX_ARRAY (0x10 | TYPE_ARRAY) -#define TYPE_COMPLEX_SEQUENCE (0x10 | TYPE_SEQUENCE) - - -typedef struct Type Type; - -#define INHERIT_TYPE\ - int32_t nativeSize; /*in the simple case its the same as wire size and alignment*/\ - union {\ - struct {\ - const uintptr_t p1;\ - const uintptr_t p2;\ - } _cast;\ - struct {\ - uint32_t iid;\ - uint32_t bNotNil;\ - } object;\ - struct {\ - const Type *arrayType;\ - int32_t nItems;\ - } array;\ - struct {\ - const Type *seqType;\ - int32_t nMaxLen;\ - } seqSimple; \ - struct {\ - uint32_t bFloating;\ - uint32_t bSigned;\ - } prim; \ - const SequenceType* seqComplex;\ - const UnionType *unionType;\ - const StructType *structType;\ - int32_t stringMaxLen;\ - uint8_t bInterfaceNotNil;\ - } param;\ - uint8_t type;\ - uint8_t nativeAlignment\ - -typedef struct UnionType UnionType; -typedef struct StructType StructType; -typedef struct SequenceType SequenceType; -struct Type { - INHERIT_TYPE; -}; - -struct SequenceType { - const Type * seqType; - uint32_t nMaxLen; - uint32_t inSize; - uint32_t routSizePrimIn; - uint32_t routSizePrimROut; -}; - -//byte offset from the start of the case values for -//this unions case value array. it MUST be aligned -//at the alignment requrements for the descriptor -// -//if negative it means that the unions cases are -//simple enumerators, so the value read from the descriptor -//can be used directly to find the correct case -typedef union CaseValuePtr CaseValuePtr; -union CaseValuePtr { - const uint8_t* value8s; - const uint16_t* value16s; - const uint32_t* value32s; - const uint64_t* value64s; -}; - -//these are only used in complex cases -//so I pulled them out of the type definition as references to make -//the type smaller -struct UnionType { - const Type *descriptor; - uint32_t nCases; - const CaseValuePtr caseValues; - const Type * const *cases; - int32_t inSize; - int32_t routSizePrimIn; - int32_t routSizePrimROut; - uint8_t inAlignment; - uint8_t routAlignmentPrimIn; - uint8_t routAlignmentPrimROut; - uint8_t inCaseAlignment; - uint8_t routCaseAlignmentPrimIn; - uint8_t routCaseAlignmentPrimROut; - uint8_t nativeCaseAlignment; - uint8_t bDefaultCase; -}; - -struct StructType { - uint32_t nMembers; - const Type * const *members; - int32_t inSize; - int32_t routSizePrimIn; - int32_t routSizePrimROut; - uint8_t inAlignment; - uint8_t routAlignmentPrimIn; - uint8_t routAlignmentPrimROut; -}; - -typedef struct Parameter Parameter; -struct Parameter { - INHERIT_TYPE; - uint8_t mode; - uint8_t bNotNil; -}; - -#define SLIM_IFPTR32(is32,is64) (sizeof(uintptr_t) == 4 ? (is32) : (is64)) -#define SLIM_SCALARS_IS_DYNAMIC(u) (((u) & 0x00ffffff) == 0x00ffffff) - -typedef struct Method Method; -struct Method { - uint32_t uScalars; //no method index - int32_t primInSize; - int32_t primROutSize; - int maxArgs; - int numParams; - const Parameter * const *params; - uint8_t primInAlignment; - uint8_t primROutAlignment; -}; - -typedef struct Interface Interface; - -struct Interface { - int nMethods; - const Method * const *methodArray; - int nIIds; - const uint32_t *iids; - const uint16_t* methodStringArray; - const uint16_t* methodStrings; - const char* strings; -}; - - -#endif //SLIM_H - - -#ifndef _CALCULATOR_SLIM_H -#define _CALCULATOR_SLIM_H - -// remote.h - -#include - -#ifndef __QAIC_SLIM -#define __QAIC_SLIM(ff) ff -#endif -#ifndef __QAIC_SLIM_EXPORT -#define __QAIC_SLIM_EXPORT -#endif - -static const Type types[1]; -static const Type types[1] = {{0x1,{{(const uintptr_t)0,(const uintptr_t)0}}, 2,0x1}}; -static const Parameter parameters[3] = {{0x4,{{(const uintptr_t)0,(const uintptr_t)0}}, 2,0x4,3,0},{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[0]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8),0,0},{SLIM_IFPTR32(0x8,0x10),{{(const uintptr_t)&(types[0]),(const uintptr_t)0x0}}, 9,SLIM_IFPTR32(0x4,0x8),3,0}}; -static const Parameter* const parameterArrays[3] = {(&(parameters[1])),(&(parameters[2])),(&(parameters[0]))}; -static const Method methods[2] = {{REMOTE_SCALARS_MAKEX(0,0,0x0,0x1,0x0,0x0),0x0,0x4,1,1,(&(parameterArrays[2])),0x1,0x4},{REMOTE_SCALARS_MAKEX(0,0,0x2,0x1,0x0,0x0),0x8,0x0,5,2,(&(parameterArrays[0])),0x4,0x1}}; -static const Method* const methodArrays[2] = {&(methods[0]),&(methods[1])}; -static const char strings[41] = "extract_and_match\0features\0leet\0init\0img\0"; -static const uint16_t methodStrings[5] = {0,37,18,32,27}; -static const uint16_t methodStringsArrays[2] = {3,0}; -__QAIC_SLIM_EXPORT const Interface __QAIC_SLIM(calculator_slim) = {2,&(methodArrays[0]),0,0,&(methodStringsArrays [0]),methodStrings,strings}; -#endif //_CALCULATOR_SLIM_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _const_calculator_handle -#define _const_calculator_handle ((remote_handle)-1) -#endif //_const_calculator_handle - -static void _calculator_pls_dtor(void* data) { - remote_handle* ph = (remote_handle*)data; - if(_const_calculator_handle != *ph) { - (void)__QAIC_REMOTE(remote_handle_close)(*ph); - *ph = _const_calculator_handle; - } -} - -static int _calculator_pls_ctor(void* ctx, void* data) { - remote_handle* ph = (remote_handle*)data; - *ph = _const_calculator_handle; - if(*ph == (remote_handle)-1) { - return __QAIC_REMOTE(remote_handle_open)((const char*)ctx, ph); - } - return 0; -} - -#if (defined __qdsp6__) || (defined __hexagon__) -#pragma weak adsp_pls_add_lookup -extern int adsp_pls_add_lookup(uint32_t type, uint32_t key, int size, int (*ctor)(void* ctx, void* data), void* ctx, void (*dtor)(void* ctx), void** ppo); -#pragma weak HAP_pls_add_lookup -extern int HAP_pls_add_lookup(uint32_t type, uint32_t key, int size, int (*ctor)(void* ctx, void* data), void* ctx, void (*dtor)(void* ctx), void** ppo); - -__QAIC_STUB_EXPORT remote_handle _calculator_handle(void) { - remote_handle* ph; - if(adsp_pls_add_lookup) { - if(0 == adsp_pls_add_lookup((uint32_t)_calculator_handle, 0, sizeof(*ph), _calculator_pls_ctor, "calculator", _calculator_pls_dtor, (void**)&ph)) { - return *ph; - } - return (remote_handle)-1; - } else if(HAP_pls_add_lookup) { - if(0 == HAP_pls_add_lookup((uint32_t)_calculator_handle, 0, sizeof(*ph), _calculator_pls_ctor, "calculator", _calculator_pls_dtor, (void**)&ph)) { - return *ph; - } - return (remote_handle)-1; - } - return(remote_handle)-1; -} - -#else //__qdsp6__ || __hexagon__ - -uint32_t _calculator_atomic_CompareAndExchange(uint32_t * volatile puDest, uint32_t uExchange, uint32_t uCompare); - -#ifdef _WIN32 -#include "Windows.h" -uint32_t _calculator_atomic_CompareAndExchange(uint32_t * volatile puDest, uint32_t uExchange, uint32_t uCompare) { - return (uint32_t)InterlockedCompareExchange((volatile LONG*)puDest, (LONG)uExchange, (LONG)uCompare); -} -#elif __GNUC__ -uint32_t _calculator_atomic_CompareAndExchange(uint32_t * volatile puDest, uint32_t uExchange, uint32_t uCompare) { - return __sync_val_compare_and_swap(puDest, uCompare, uExchange); -} -#endif //_WIN32 - - -__QAIC_STUB_EXPORT remote_handle _calculator_handle(void) { - static remote_handle handle = _const_calculator_handle; - if((remote_handle)-1 != handle) { - return handle; - } else { - remote_handle tmp; - int nErr = _calculator_pls_ctor("calculator", (void*)&tmp); - if(nErr) { - return (remote_handle)-1; - } - if(((remote_handle)-1 != handle) || ((remote_handle)-1 != (remote_handle)_calculator_atomic_CompareAndExchange((uint32_t*)&handle, (uint32_t)tmp, (uint32_t)-1))) { - _calculator_pls_dtor(&tmp); - } - return handle; - } -} - -#endif //__qdsp6__ - -__QAIC_STUB_EXPORT int __QAIC_STUB(calculator_skel_invoke)(uint32_t _sc, remote_arg* _pra) __QAIC_STUB_ATTRIBUTE { - return __QAIC_REMOTE(remote_handle_invoke)(_calculator_handle(), _sc, _pra); -} - -#ifdef __cplusplus -} -#endif - - -#ifdef __cplusplus -extern "C" { -#endif -extern int remote_register_dma_handle(int, uint32_t); -static __inline int _stub_method(remote_handle _handle, uint32_t _mid, uint32_t _rout0[1]) { - int _numIn[1]; - remote_arg _pra[1]; - uint32_t _primROut[1]; - int _nErr = 0; - _numIn[0] = 0; - _pra[(_numIn[0] + 0)].buf.pv = (void*)_primROut; - _pra[(_numIn[0] + 0)].buf.nLen = sizeof(_primROut); - _TRY(_nErr, __QAIC_REMOTE(remote_handle_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, 0, 1, 0, 0), _pra)); - _COPY(_rout0, 0, _primROut, 0, 4); - _CATCH(_nErr) {} - return _nErr; -} -__QAIC_STUB_EXPORT int __QAIC_STUB(calculator_init)(uint32* leet) __QAIC_STUB_ATTRIBUTE { - uint32_t _mid = 0; - return _stub_method(_calculator_handle(), _mid, (uint32_t*)leet); -} -static __inline int _stub_method_1(remote_handle _handle, uint32_t _mid, char* _in0[1], uint32_t _in0Len[1], char* _rout1[1], uint32_t _rout1Len[1]) { - int _numIn[1]; - remote_arg _pra[3]; - uint32_t _primIn[2]; - remote_arg* _praIn; - remote_arg* _praROut; - int _nErr = 0; - _numIn[0] = 1; - _pra[0].buf.pv = (void*)_primIn; - _pra[0].buf.nLen = sizeof(_primIn); - _COPY(_primIn, 0, _in0Len, 0, 4); - _praIn = (_pra + 1); - _praIn[0].buf.pv = _in0[0]; - _praIn[0].buf.nLen = (1 * _in0Len[0]); - _COPY(_primIn, 4, _rout1Len, 0, 4); - _praROut = (_praIn + _numIn[0] + 0); - _praROut[0].buf.pv = _rout1[0]; - _praROut[0].buf.nLen = (1 * _rout1Len[0]); - _TRY(_nErr, __QAIC_REMOTE(remote_handle_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, 2, 1, 0, 0), _pra)); - _CATCH(_nErr) {} - return _nErr; -} -__QAIC_STUB_EXPORT int __QAIC_STUB(calculator_extract_and_match)(const uint8* img, int imgLen, uint8* features, int featuresLen) __QAIC_STUB_ATTRIBUTE { - uint32_t _mid = 1; - return _stub_method_1(_calculator_handle(), _mid, (char**)&img, (uint32_t*)&imgLen, (char**)&features, (uint32_t*)&featuresLen); -} -#ifdef __cplusplus -} -#endif -#endif //_CALCULATOR_STUB_H diff --git a/selfdrive/orbd/dsp/gen/libcalculator_skel.so b/selfdrive/orbd/dsp/gen/libcalculator_skel.so deleted file mode 100755 index e48cab48208b0f..00000000000000 Binary files a/selfdrive/orbd/dsp/gen/libcalculator_skel.so and /dev/null differ diff --git a/selfdrive/orbd/extractor.h b/selfdrive/orbd/extractor.h deleted file mode 100644 index f506cd3868a05d..00000000000000 --- a/selfdrive/orbd/extractor.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef EXTRACTOR_H -#define EXTRACTOR_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#define ORBD_KEYPOINTS 3000 -#define ORBD_DESCRIPTOR_LENGTH 32 -#define ORBD_HEIGHT 874 -#define ORBD_WIDTH 1164 -#define ORBD_FOCAL 910 - -// matches OrbFeatures from log.capnp -struct orb_features { - // align this - uint16_t n_corners; - uint16_t xy[ORBD_KEYPOINTS][2]; - uint8_t octave[ORBD_KEYPOINTS]; - uint8_t des[ORBD_KEYPOINTS][ORBD_DESCRIPTOR_LENGTH]; - int16_t matches[ORBD_KEYPOINTS]; -}; - -// forward declare this -struct pyramid; - -// manage the pyramids in extractor.c -void init_gpyrs(); -int extract_and_match_gpyrs(const uint8_t *img, struct orb_features *); -int extract_and_match(const uint8_t *img, struct pyramid *pyrs, struct pyramid *prev_pyrs, struct orb_features *); - -#ifdef __cplusplus -} -#endif - -#endif // EXTRACTOR_H diff --git a/selfdrive/orbd/orbd.cc b/selfdrive/orbd/orbd.cc deleted file mode 100644 index ce0d47aec6efbd..00000000000000 --- a/selfdrive/orbd/orbd.cc +++ /dev/null @@ -1,191 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "common/visionipc.h" -#include "common/swaglog.h" - -#include "extractor.h" - -#ifdef DSP -#include "dsp/gen/calculator.h" -#else -#include "turbocv.h" -#endif - -#include -#include -#include "cereal/gen/cpp/log.capnp.h" - -#ifndef PATH_MAX -#include -#endif - -volatile int do_exit = 0; - -static void set_do_exit(int sig) { - do_exit = 1; -} - -int main(int argc, char *argv[]) { - int err; - setpriority(PRIO_PROCESS, 0, -13); - printf("starting orbd\n"); - -#ifdef DSP - uint32_t test_leet = 0; - char my_path[PATH_MAX+1]; - memset(my_path, 0, sizeof(my_path)); - - ssize_t len = readlink("/proc/self/exe", my_path, sizeof(my_path)); - assert(len > 5); - my_path[len-5] = '\0'; - LOGW("running from %s with PATH_MAX %d", my_path, PATH_MAX); - - char adsp_path[PATH_MAX+1]; - snprintf(adsp_path, PATH_MAX, "ADSP_LIBRARY_PATH=%s/dsp/gen", my_path); - assert(putenv(adsp_path) == 0); - - assert(calculator_init(&test_leet) == 0); - assert(test_leet == 0x1337); - LOGW("orbd init complete"); -#else - init_gpyrs(); -#endif - - signal(SIGINT, (sighandler_t) set_do_exit); - signal(SIGTERM, (sighandler_t) set_do_exit); - - void *ctx = zmq_ctx_new(); - - void *orb_features_sock = zmq_socket(ctx, ZMQ_PUB); - assert(orb_features_sock); - zmq_bind(orb_features_sock, "tcp://*:8058"); - - void *orb_features_summary_sock = zmq_socket(ctx, ZMQ_PUB); - assert(orb_features_summary_sock); - zmq_bind(orb_features_summary_sock, "tcp://*:8062"); - - struct orb_features *features = (struct orb_features *)malloc(sizeof(struct orb_features)); - int last_frame_id = 0; - uint64_t frame_count = 0; - - // every other frame - const int RATE = 2; - - VisionStream stream; - while (!do_exit) { - VisionStreamBufs buf_info; - err = visionstream_init(&stream, VISION_STREAM_YUV, true, &buf_info); - if (err) { - printf("visionstream connect fail\n"); - usleep(100000); - continue; - } - uint64_t timestamp_last_eof = 0; - while (!do_exit) { - VIPCBuf *buf; - VIPCBufExtra extra; - buf = visionstream_get(&stream, &extra); - if (buf == NULL) { - printf("visionstream get failed\n"); - break; - } - - // every other frame - frame_count++; - if ((frame_count%RATE) != 0) { - continue; - } - - uint64_t start = nanos_since_boot(); -#ifdef DSP - int ret = calculator_extract_and_match((uint8_t *)buf->addr, ORBD_HEIGHT*ORBD_WIDTH, (uint8_t *)features, sizeof(struct orb_features)); -#else - int ret = extract_and_match_gpyrs((uint8_t *) buf->addr, features); -#endif - uint64_t end = nanos_since_boot(); - LOGD("total(%d): %6.2f ms to get %4d features on %d", ret, (end-start)/1000000.0, features->n_corners, extra.frame_id); - assert(ret == 0); - - if (last_frame_id+RATE != extra.frame_id) { - LOGW("dropped frame!"); - } - - last_frame_id = extra.frame_id; - - if (timestamp_last_eof == 0) { - timestamp_last_eof = extra.timestamp_eof; - continue; - } - - int match_count = 0; - - // *** send OrbFeatures *** - { - // create capnp message - capnp::MallocMessageBuilder msg; - cereal::Event::Builder event = msg.initRoot(); - event.setLogMonoTime(nanos_since_boot()); - - auto orb_features = event.initOrbFeatures(); - - // set timestamps - orb_features.setTimestampEof(extra.timestamp_eof); - orb_features.setTimestampLastEof(timestamp_last_eof); - - // init descriptors for send - kj::ArrayPtr descriptorsPtr = kj::arrayPtr((uint8_t *)features->des, ORBD_DESCRIPTOR_LENGTH * features->n_corners); - orb_features.setDescriptors(descriptorsPtr); - - auto xs = orb_features.initXs(features->n_corners); - auto ys = orb_features.initYs(features->n_corners); - auto octaves = orb_features.initOctaves(features->n_corners); - auto matches = orb_features.initMatches(features->n_corners); - - // copy out normalized keypoints - for (int i = 0; i < features->n_corners; i++) { - xs.set(i, (features->xy[i][0] * 1.0f - ORBD_WIDTH / 2) / ORBD_FOCAL); - ys.set(i, (features->xy[i][1] * 1.0f - ORBD_HEIGHT / 2) / ORBD_FOCAL); - octaves.set(i, features->octave[i]); - matches.set(i, features->matches[i]); - match_count += features->matches[i] != -1; - } - - auto words = capnp::messageToFlatArray(msg); - auto bytes = words.asBytes(); - zmq_send(orb_features_sock, bytes.begin(), bytes.size(), 0); - } - - // *** send OrbFeaturesSummary *** - - { - // create capnp message - capnp::MallocMessageBuilder msg; - cereal::Event::Builder event = msg.initRoot(); - event.setLogMonoTime(nanos_since_boot()); - - auto orb_features_summary = event.initOrbFeaturesSummary(); - - orb_features_summary.setTimestampEof(extra.timestamp_eof); - orb_features_summary.setTimestampLastEof(timestamp_last_eof); - orb_features_summary.setFeatureCount(features->n_corners); - orb_features_summary.setMatchCount(match_count); - orb_features_summary.setComputeNs(end-start); - - auto words = capnp::messageToFlatArray(msg); - auto bytes = words.asBytes(); - zmq_send(orb_features_summary_sock, bytes.begin(), bytes.size(), 0); - } - - timestamp_last_eof = extra.timestamp_eof; - } - } - visionstream_destroy(&stream); - return 0; -} - diff --git a/selfdrive/orbd/orbd_wrapper.sh b/selfdrive/orbd/orbd_wrapper.sh deleted file mode 100755 index 8ec7443a30d4f7..00000000000000 --- a/selfdrive/orbd/orbd_wrapper.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -finish() { - echo "exiting orbd" - pkill -SIGINT -P $$ -} - -trap finish EXIT - -while true; do - ./orbd & - wait $! -done - diff --git a/selfdrive/pandad.py b/selfdrive/pandad.py old mode 100644 new mode 100755 index 981546ccf95411..2ef286fa7a6a3a --- a/selfdrive/pandad.py +++ b/selfdrive/pandad.py @@ -1,14 +1,85 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # simple boardd wrapper that updates the panda first import os -from panda import ensure_st_up_to_date +import time + +from selfdrive.swaglog import cloudlog +from panda import Panda, PandaDFU, BASEDIR + + +def get_expected_version(): + with open(os.path.join(BASEDIR, "VERSION")) as f: + repo_version = f.read() + repo_version += "-EON" if os.path.isfile('/EON') else "-DEV" + return repo_version + + +def update_panda(): + repo_version = get_expected_version() + + panda = None + panda_dfu = None + + cloudlog.info("Connecting to panda") + + while True: + # break on normal mode Panda + panda_list = Panda.list() + if len(panda_list) > 0: + cloudlog.info("Panda found, connecting") + panda = Panda(panda_list[0]) + break + + # flash on DFU mode Panda + panda_dfu = PandaDFU.list() + if len(panda_dfu) > 0: + cloudlog.info("Panda in DFU mode found, flashing recovery") + panda_dfu = PandaDFU(panda_dfu[0]) + panda_dfu.recover() + + print("waiting for board...") + time.sleep(1) + + try: + serial = panda.get_serial()[0].decode("utf-8") + except Exception: + serial = None + current_version = "bootstub" if panda.bootstub else panda.get_version() + cloudlog.warning("Panda %s connected, version: %s, expected %s" % (serial, current_version, repo_version)) + + if panda.bootstub or not current_version.startswith(repo_version): + cloudlog.info("Panda firmware out of date, update required") + + signed_fn = os.path.join(BASEDIR, "board", "obj", "panda.bin.signed") + if os.path.exists(signed_fn): + cloudlog.info("Flashing signed firmware") + panda.flash(fn=signed_fn) + else: + cloudlog.info("Building and flashing unsigned firmware") + panda.flash() + + cloudlog.info("Done flashing") + + if panda.bootstub: + cloudlog.info("Flashed firmware not booting, flashing development bootloader") + panda.recover() + cloudlog.info("Done flashing bootloader") + + if panda.bootstub: + cloudlog.info("Panda still not booting, exiting") + raise AssertionError + + version = panda.get_version() + if not version.startswith(repo_version): + cloudlog.info("Version mismatch after flashing, exiting") + raise AssertionError + def main(gctx=None): - ensure_st_up_to_date() + update_panda() os.chdir("boardd") os.execvp("./boardd", ["./boardd"]) if __name__ == "__main__": main() - diff --git a/selfdrive/proclogd/Makefile b/selfdrive/proclogd/Makefile index a7cd3682b29a6b..46c4ca5c464d92 100644 --- a/selfdrive/proclogd/Makefile +++ b/selfdrive/proclogd/Makefile @@ -1,3 +1,5 @@ +ARCH := $(shell uname -m) + CC = clang CXX = clang++ @@ -13,10 +15,15 @@ WARN_FLAGS = -Werror=implicit-function-declaration \ CFLAGS = -std=gnu11 -g -fPIC -O2 $(WARN_FLAGS) CXXFLAGS = -std=c++11 -g -fPIC -O2 $(WARN_FLAGS) -ZMQ_FLAGS = -I$(PHONELIBS)/zmq/aarch64/include -ZMQ_LIBS = -L$(PHONELIBS)/zmq/aarch64/lib \ - -l:libczmq.a -l:libzmq.a \ - -lgnustl_shared +MESSAGING_FLAGS = -I$(BASEDIR)/selfdrive/messaging +MESSAGING_LIBS = $(BASEDIR)/selfdrive/messaging/messaging.a + +ifeq ($(ARCH),aarch64) +CFLAGS += -mcpu=cortex-a57 +CXXFLAGS += -mcpu=cortex-a57 +EXTRA_LIBS += -lgnustl_shared +endif + .PHONY: all all: proclogd @@ -28,18 +35,18 @@ OBJS = proclogd.o \ DEPS := $(OBJS:.o=.d) -proclogd: $(OBJS) +proclogd: $(OBJS) $(MESSAGING_LIBS) @echo "[ LINK ] $@" $(CXX) -fPIC -o '$@' $^ \ $(CEREAL_LIBS) \ - $(ZMQ_LIBS) \ + $(EXTRA_LIBS) \ -llog %.o: %.cc @echo "[ CXX ] $@" $(CXX) $(CXXFLAGS) \ $(CEREAL_CXXFLAGS) \ - $(ZMQ_FLAGS) \ + $(MESSAGING_FLAGS) \ -I../ \ -I../../ \ -c -o '$@' '$<' diff --git a/selfdrive/proclogd/proclogd.cc b/selfdrive/proclogd/proclogd.cc index fbb7704e0378e7..50e3b4b6595cd2 100644 --- a/selfdrive/proclogd/proclogd.cc +++ b/selfdrive/proclogd/proclogd.cc @@ -16,7 +16,7 @@ #include #include -#include +#include "messaging.hpp" #include #include "cereal/gen/cpp/log.capnp.h" @@ -36,10 +36,8 @@ struct ProcCache { int main() { int err; - void *context = zmq_ctx_new(); - void *publisher = zmq_socket(context, ZMQ_PUB); - err = zmq_bind(publisher, "tcp://*:8031"); - assert(err == 0); + Context * c = Context::create(); + PubSocket * publisher = PubSocket::create(c, "procLog"); double jiffy = sysconf(_SC_CLK_TCK); size_t page_size = sysconf(_SC_PAGE_SIZE); @@ -103,7 +101,7 @@ int main() { std::ifstream smem("/proc/meminfo"); std::string mem_line; - + uint64_t mem_total = 0, mem_free = 0, mem_available = 0, mem_buffers = 0; uint64_t mem_cached = 0, mem_active = 0, mem_inactive = 0, mem_shared = 0; @@ -203,7 +201,7 @@ int main() { std::string cmdline_s = util::read_file(util::string_format("/proc/%d/cmdline", pid)); const char* cmdline_p = cmdline_s.c_str(); const char* cmdline_ep = cmdline_p + cmdline_s.size(); - + // strip trailing null bytes while ((cmdline_ep-1) > cmdline_p && *(cmdline_ep-1) == 0) { cmdline_ep--; @@ -236,10 +234,13 @@ int main() { auto words = capnp::messageToFlatArray(msg); auto bytes = words.asBytes(); - zmq_send(publisher, bytes.begin(), bytes.size(), 0); + publisher->send((char*)bytes.begin(), bytes.size()); usleep(2000000); // 2 secs } + delete c; + delete publisher; + return 0; } diff --git a/selfdrive/registration.py b/selfdrive/registration.py index 9b7e6964ef92b5..1c85e40b2204a8 100644 --- a/selfdrive/registration.py +++ b/selfdrive/registration.py @@ -1,53 +1,102 @@ +import os import json +import binascii import subprocess +import itertools +from datetime import datetime, timedelta from selfdrive.swaglog import cloudlog -from selfdrive.version import version, training_version +from selfdrive.version import version, terms_version, training_version, get_git_commit, get_git_branch, get_git_remote from common.api import api_get from common.params import Params + def get_imei(): - ret = subprocess.check_output(["getprop", "oem.device.imeicache"]).strip() + ret = subprocess.check_output(["getprop", "oem.device.imeicache"], encoding='utf8').strip() # pylint: disable=unexpected-keyword-arg if ret == "": ret = "000000000000000" return ret + def get_serial(): - return subprocess.check_output(["getprop", "ro.serialno"]).strip() + return subprocess.check_output(["getprop", "ro.serialno"], encoding='utf8').strip() # pylint: disable=unexpected-keyword-arg + + +# TODO: move this to a library +def parse_service_call(call): + ret = subprocess.check_output(call, encoding='utf8').strip() # pylint: disable=unexpected-keyword-arg + if 'Parcel' not in ret: + return None -def get_git_commit(): - return subprocess.check_output(["git", "rev-parse", "HEAD"]).strip() + try: + r = b"" + for line in ret.split("\n")[1:]: # Skip 'Parcel(' + line_hex = line[14:49].replace(' ', '') + r += binascii.unhexlify(line_hex) + + r = r[8:] # Cut off length field + r = r.decode('utf_16_be') + + # All pairs of two characters seem to be swapped. Not sure why + result = "" + for a, b, in itertools.zip_longest(r[::2], r[1::2], fillvalue='\x00'): + result += b + a -def get_git_branch(): - return subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).strip() + result = result.replace('\x00', '') + + return result + except Exception: + return None + + +def get_subscriber_info(): + ret = parse_service_call(["service", "call", "iphonesubinfo", "7"]) + if ret is None or len(ret) < 8: + return "" + return ret -def get_git_remote(): - return subprocess.check_output(["git", "config", "--get", "remote.origin.url"]).strip() def register(): params = Params() params.put("Version", version) + params.put("TermsVersion", terms_version) params.put("TrainingVersion", training_version) params.put("GitCommit", get_git_commit()) params.put("GitBranch", get_git_branch()) params.put("GitRemote", get_git_remote()) + params.put("SubscriberInfo", get_subscriber_info()) + + # make key readable by app users (ai.comma.plus.offroad) + os.chmod('/persist/comma/', 0o755) + os.chmod('/persist/comma/id_rsa', 0o744) - dongle_id, access_token = params.get("DongleId"), params.get("AccessToken") + dongle_id, access_token = params.get("DongleId", encoding='utf8'), params.get("AccessToken", encoding='utf8') + public_key = open("/persist/comma/id_rsa.pub").read() + + # create registration token + # in the future, this key will make JWTs directly + private_key = open("/persist/comma/id_rsa").read() + + # late import + import jwt + register_token = jwt.encode({'register':True, 'exp': datetime.utcnow() + timedelta(hours=1)}, private_key, algorithm='RS256') try: - if dongle_id is None or access_token is None: - cloudlog.info("getting pilotauth") - resp = api_get("v1/pilotauth/", method='POST', timeout=15, - imei=get_imei(), serial=get_serial()) - dongleauth = json.loads(resp.text) - dongle_id, access_token = dongleauth["dongle_id"].encode('ascii'), dongleauth["access_token"].encode('ascii') - - params.put("DongleId", dongle_id) - params.put("AccessToken", access_token) + cloudlog.info("getting pilotauth") + resp = api_get("v2/pilotauth/", method='POST', timeout=15, + imei=get_imei(), serial=get_serial(), public_key=public_key, register_token=register_token) + dongleauth = json.loads(resp.text) + dongle_id, access_token = dongleauth["dongle_id"], dongleauth["access_token"] + + params.put("DongleId", dongle_id) + params.put("AccessToken", access_token) return dongle_id, access_token except Exception: cloudlog.exception("failed to authenticate") - return None + if dongle_id is not None and access_token is not None: + return dongle_id, access_token + else: + return None if __name__ == "__main__": print(api_get("").text) diff --git a/selfdrive/sensord/build_from_src.mk b/selfdrive/sensord/build_from_src.mk new file mode 100644 index 00000000000000..b51364e8ddc3a6 --- /dev/null +++ b/selfdrive/sensord/build_from_src.mk @@ -0,0 +1,90 @@ +CC = clang +CXX = clang++ + +PHONELIBS = ../../phonelibs +BASEDIR = ../.. + +WARN_FLAGS = -Werror=implicit-function-declaration \ + -Werror=incompatible-pointer-types \ + -Werror=int-conversion \ + -Werror=return-type \ + -Werror=format-extra-args + +CFLAGS = -std=gnu11 -g -fPIC -O2 $(WARN_FLAGS) \ + -I$(PHONELIBS)/android_frameworks_native/include \ + -I$(PHONELIBS)/android_system_core/include \ + -I$(PHONELIBS)/android_hardware_libhardware/include +CXXFLAGS = -std=c++11 -g -fPIC -O2 $(WARN_FLAGS) \ + -I$(PHONELIBS)/android_frameworks_native/include \ + -I$(PHONELIBS)/android_system_core/include \ + -I$(PHONELIBS)/android_hardware_libhardware/include + +MESSAGING_FLAGS = -I$(BASEDIR)/selfdrive/messaging +MESSAGING_LIBS = $(BASEDIR)/selfdrive/messaging/messaging.a + +# Sensord can only be compiled for the phone +CFLAGS += -mcpu=cortex-a57 +CXXFLAGS += -mcpu=cortex-a57 +EXTRA_LIBS += -lgnustl_shared + + +JSON_FLAGS = -I$(PHONELIBS)/json/src + +DIAG_LIBS = -L/system/vendor/lib64 -ldiag -ltime_genoff + +.PHONY: all +all: sensord gpsd + +include ../common/cereal.mk + +SENSORD_OBJS = sensors.o \ + ../common/swaglog.o \ + $(PHONELIBS)/json/src/json.o + +GPSD_OBJS = gpsd.o \ + rawgps.o \ + ../common/swaglog.o \ + $(PHONELIBS)/json/src/json.o + +DEPS := $(SENSORD_OBJS:.o=.d) $(GPSD_OBJS:.o=.d) + +sensord: $(SENSORD_OBJS) $(MESSAGING_LIBS) + @echo "[ LINK ] $@" + $(CXX) -fPIC -o '$@' $^ \ + $(CEREAL_LIBS) \ + $(EXTRA_LIBS) \ + -lhardware + +gpsd: $(GPSD_OBJS) $(MESSAGING_LIBS) + @echo "[ LINK ] $@" + $(CXX) -fPIC -o '$@' $^ \ + $(CEREAL_LIBS) \ + $(DIAG_LIBS) \ + $(EXTRA_LIBS) \ + -lhardware + +%.o: %.cc + @echo "[ CXX ] $@" + $(CXX) $(CXXFLAGS) \ + $(CEREAL_CXXFLAGS) \ + $(MESSAGING_FLAGS) \ + $(JSON_FLAGS) \ + -I../ \ + -I../../ \ + -c -o '$@' '$<' + + +%.o: %.c + @echo "[ CC ] $@" + $(CC) $(CFLAGS) \ + $(JSON_FLAGS) \ + $(ZMQ_FLAGS) \ + -I../ \ + -I../../ \ + -c -o '$@' '$<' + +.PHONY: clean +clean: + rm -f sensord gpsd $(OBJS) $(DEPS) + +-include $(DEPS) diff --git a/selfdrive/sensord/gpsd b/selfdrive/sensord/gpsd deleted file mode 100755 index 540f9b161a28a3..00000000000000 Binary files a/selfdrive/sensord/gpsd and /dev/null differ diff --git a/selfdrive/sensord/gpsd.cc b/selfdrive/sensord/gpsd.cc new file mode 100644 index 00000000000000..d7637651f9a581 --- /dev/null +++ b/selfdrive/sensord/gpsd.cc @@ -0,0 +1,262 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include + +#include "messaging.hpp" +#include "common/timing.h" +#include "common/swaglog.h" + +#include "cereal/gen/cpp/log.capnp.h" + +#include "rawgps.h" + +volatile sig_atomic_t do_exit = 0; + +namespace { + +pthread_t clock_thread_handle; + +Context *gps_context; +PubSocket *gps_publisher; +PubSocket *gps_location_publisher; + +const GpsInterface* gGpsInterface = NULL; +const AGpsInterface* gAGpsInterface = NULL; + +void set_do_exit(int sig) { + do_exit = 1; +} + +void nmea_callback(GpsUtcTime timestamp, const char* nmea, int length) { + + uint64_t log_time = nanos_since_boot(); + uint64_t log_time_wall = nanos_since_epoch(); + + capnp::MallocMessageBuilder msg; + cereal::Event::Builder event = msg.initRoot(); + event.setLogMonoTime(log_time); + + auto nmeaData = event.initGpsNMEA(); + nmeaData.setTimestamp(timestamp); + nmeaData.setLocalWallTime(log_time_wall); + nmeaData.setNmea(nmea); + + auto words = capnp::messageToFlatArray(msg); + auto bytes = words.asBytes(); + // printf("gps send %d\n", bytes.size()); + gps_publisher->send((char*)bytes.begin(), bytes.size()); +} + +void location_callback(GpsLocation* location) { + //printf("got location callback\n"); + uint64_t log_time = nanos_since_boot(); + + capnp::MallocMessageBuilder msg; + cereal::Event::Builder event = msg.initRoot(); + event.setLogMonoTime(log_time); + + auto locationData = event.initGpsLocation(); + locationData.setFlags(location->flags); + locationData.setLatitude(location->latitude); + locationData.setLongitude(location->longitude); + locationData.setAltitude(location->altitude); + locationData.setSpeed(location->speed); + locationData.setBearing(location->bearing); + locationData.setAccuracy(location->accuracy); + locationData.setTimestamp(location->timestamp); + locationData.setSource(cereal::GpsLocationData::SensorSource::ANDROID); + + auto words = capnp::messageToFlatArray(msg); + auto bytes = words.asBytes(); + gps_location_publisher->send((char*)bytes.begin(), bytes.size()); +} + +pthread_t create_thread_callback(const char* name, void (*start)(void *), void* arg) { + LOG("creating thread: %s", name); + pthread_t thread; + pthread_attr_t attr; + int err; + + err = pthread_attr_init(&attr); + err = pthread_create(&thread, &attr, (void*(*)(void*))start, arg); + + return thread; +} + +GpsCallbacks gps_callbacks = { + sizeof(GpsCallbacks), + location_callback, + NULL, + NULL, + nmea_callback, + NULL, + NULL, + NULL, + create_thread_callback, +}; + +void agps_status_cb(AGpsStatus *status) { + switch (status->status) { + case GPS_REQUEST_AGPS_DATA_CONN: + fprintf(stdout, "*** data_conn_open\n"); + gAGpsInterface->data_conn_open("internet"); + break; + case GPS_RELEASE_AGPS_DATA_CONN: + fprintf(stdout, "*** data_conn_closed\n"); + gAGpsInterface->data_conn_closed(); + break; + } +} + +AGpsCallbacks agps_callbacks = { + agps_status_cb, + create_thread_callback, +}; + + + +void gps_init() { + LOG("*** init GPS"); + hw_module_t* module = NULL; + hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); + assert(module); + + static hw_device_t* device = NULL; + module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device); + assert(device); + + // ** get gps interface ** + gps_device_t* gps_device = (gps_device_t *)device; + gGpsInterface = gps_device->get_gps_interface(gps_device); + assert(gGpsInterface); + + gAGpsInterface = (const AGpsInterface*)gGpsInterface->get_extension(AGPS_INTERFACE); + assert(gAGpsInterface); + + + gGpsInterface->init(&gps_callbacks); + gAGpsInterface->init(&agps_callbacks); + gAGpsInterface->set_server(AGPS_TYPE_SUPL, "supl.google.com", 7276); + + // gGpsInterface->delete_aiding_data(GPS_DELETE_ALL); + gGpsInterface->start(); + gGpsInterface->set_position_mode(GPS_POSITION_MODE_MS_BASED, + GPS_POSITION_RECURRENCE_PERIODIC, + 100, 0, 0); + + gps_context = Context::create(); + gps_publisher = PubSocket::create(gps_context, "gpsNMEA"); + gps_location_publisher = PubSocket::create(gps_context, "gpsLocation"); +} + +void gps_destroy() { + gGpsInterface->stop(); + gGpsInterface->cleanup(); +} + + +int64_t arm_cntpct() { + int64_t v; + asm volatile("mrs %0, cntpct_el0" : "=r"(v)); + return v; +} + +// TODO: move this out of here +void* clock_thread(void* args) { + int err = 0; + + PubSocket* clock_publisher = PubSocket::create(gps_context, "clocks"); + + int timerfd = timerfd_create(CLOCK_BOOTTIME, 0); + assert(timerfd >= 0); + + struct itimerspec spec = {0}; + spec.it_interval.tv_sec = 1; + spec.it_interval.tv_nsec = 0; + spec.it_value.tv_sec = 1; + spec.it_value.tv_nsec = 0; + + err = timerfd_settime(timerfd, 0, &spec, 0); + assert(err == 0); + + uint64_t expirations = 0; + while ((err = read(timerfd, &expirations, sizeof(expirations)))) { + if (err < 0) break; + + if (do_exit) break; + + uint64_t boottime = nanos_since_boot(); + uint64_t monotonic = nanos_monotonic(); + uint64_t monotonic_raw = nanos_monotonic_raw(); + uint64_t wall_time = nanos_since_epoch(); + + uint64_t modem_uptime_v = arm_cntpct() / 19200ULL; // 19.2 mhz clock + + capnp::MallocMessageBuilder msg; + cereal::Event::Builder event = msg.initRoot(); + event.setLogMonoTime(boottime); + auto clocks = event.initClocks(); + + clocks.setBootTimeNanos(boottime); + clocks.setMonotonicNanos(monotonic); + clocks.setMonotonicRawNanos(monotonic_raw); + clocks.setWallTimeNanos(wall_time); + clocks.setModemUptimeMillis(modem_uptime_v); + + auto words = capnp::messageToFlatArray(msg); + auto bytes = words.asBytes(); + clock_publisher->send((char*)bytes.begin(), bytes.size()); + } + + close(timerfd); + delete clock_publisher; + + return NULL; +} + + +} + +int main() { + int err = 0; + setpriority(PRIO_PROCESS, 0, -13); + + signal(SIGINT, (sighandler_t)set_do_exit); + signal(SIGTERM, (sighandler_t)set_do_exit); + + gps_init(); + + rawgps_init(); + + err = pthread_create(&clock_thread_handle, NULL, + clock_thread, NULL); + assert(err == 0); + + while(!do_exit) pause(); + + err = pthread_join(clock_thread_handle, NULL); + assert(err == 0); + + rawgps_destroy(); + + gps_destroy(); + + return 0; +} diff --git a/selfdrive/sensord/libdiag.h b/selfdrive/sensord/libdiag.h new file mode 100644 index 00000000000000..ab3ee91b14a0db --- /dev/null +++ b/selfdrive/sensord/libdiag.h @@ -0,0 +1,40 @@ +#ifndef LIBDIAG_H +#define LIBDIAG_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define DIAG_MAX_RX_PKT_SIZ 4096 + +bool Diag_LSM_Init(uint8_t* pIEnv); +bool Diag_LSM_DeInit(void); + +// DCI + +#define DIAG_CON_APSS 0x001 +#define DIAG_CON_MPSS 0x002 +#define DIAG_CON_LPASS 0x004 +#define DIAG_CON_WCNSS 0x008 + +enum { + DIAG_DCI_NO_ERROR = 1001, +} diag_dci_error_type; + +int diag_register_dci_client(int*, uint16_t*, int, void*); +int diag_log_stream_config(int client_id, int set_mask, uint16_t log_codes_array[], int num_codes); +int diag_register_dci_stream(void (*func_ptr_logs)(unsigned char *ptr, int len), void (*func_ptr_events)(unsigned char *ptr, int len)); +int diag_release_dci_client(int*); + +int diag_send_dci_async_req(int client_id, unsigned char buf[], int bytes, unsigned char *rsp_ptr, int rsp_len, + void (*func_ptr)(unsigned char *ptr, int len, void *data_ptr), void *data_ptr); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/selfdrive/sensord/rawgps.cc b/selfdrive/sensord/rawgps.cc new file mode 100644 index 00000000000000..2cd497517556e5 --- /dev/null +++ b/selfdrive/sensord/rawgps.cc @@ -0,0 +1,1183 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "cereal/gen/cpp/log.capnp.h" + +#include "messaging.hpp" +#include "common/timing.h" +#include "common/util.h" +#include "common/swaglog.h" + +#include "libdiag.h" + +#define NV_GNSS_OEM_FEATURE_MASK 7165 +# define NV_GNSS_OEM_FEATURE_MASK_OEMDRE 1 +#define NV_CGPS_DPO_CONTROL 5596 + +#define DIAG_NV_READ_F 38 +#define DIAG_NV_WRITE_F 39 + +#define DIAG_SUBSYS_CMD 75 +#define DIAG_SUBSYS_CMD_VER_2 128 + +#define DIAG_SUBSYS_GPS 13 +#define DIAG_SUBSYS_FS 19 + +#define CGPS_DIAG_PDAPI_CMD 100 +#define CGPS_OEM_CONTROL 202 + +#define GPSDIAG_OEMFEATURE_DRE 1 +#define GPSDIAG_OEM_DRE_ON 1 + +#define FEATURE_OEMDRE_NOT_SUPPORTED 1 +#define FEATURE_OEMDRE_ON 2 +#define FEATURE_OEMDRE_ALREADY_ON 4 + +#define TM_DIAG_NAV_CONFIG_CMD 0x6E + +#define EFS2_DIAG_SYNC_NO_WAIT 48 + +struct __attribute__((packed)) NvPacket { + uint8_t cmd_code; + uint16_t nv_id; + uint8_t data[128]; + uint16_t status; +}; + +enum NvStatus { + NV_DONE, + NV_BUSY, + NV_FULL, + NV_FAIL, + NV_NOTACTIVE, + NV_BADPARAM, + NV_READONLY, + NV_BADRG, + NV_NOMEM, + NV_NOTALLOC, +}; + +struct __attribute__((packed)) Efs2DiagSyncReq { + uint8_t cmd_code; + uint8_t subsys_id; + uint16_t subsys_cmd_code; + uint16_t sequence_num; + char path[8]; +}; + + +struct __attribute__((packed)) Efs2DiagSyncResp { + uint8_t cmd_code; + uint8_t subsys_id; + uint16_t subsys_cmd_code; + uint16_t sequence_num; + uint32_t sync_token; + int32_t diag_errno; +}; + + + +struct __attribute__((packed)) GpsOemControlReq { + uint8_t cmd_code; + uint8_t subsys_id; + uint16_t subsys_cmd_code; + uint8_t gps_cmd_code; + uint8_t version; + + uint32_t oem_feature; + uint32_t oem_command; + uint32_t reserved[2]; +}; + + +struct __attribute__((packed)) GpsOemControlResp { + uint8_t cmd_code; + uint8_t subsys_id; + uint16_t subsys_cmd_code; + uint8_t gps_cmd_code; + uint8_t version; + + uint32_t oem_feature; + uint32_t oem_command; + uint32_t resp_result; + uint32_t reserved[2]; +}; + +struct __attribute__((packed)) GpsNavConfigReq { + uint8_t cmd_code; + uint8_t subsys_id; + uint16_t subsys_cmd_code; + uint32_t subsys_status; + uint16_t subsys_delayed_resp_id; + uint16_t subsys_rsp_cnt; + + uint8_t desired_config; +}; + +struct __attribute__((packed)) GpsNavConfigResp { + uint8_t cmd_code; + uint8_t subsys_id; + uint16_t subsys_cmd_code; + uint32_t subsys_status; + uint16_t subsys_delayed_resp_id; + uint16_t subsys_rsp_cnt; + + uint8_t supported_config; + uint8_t actual_config; +}; + + +#define LOG_GNSS_POSITION_REPORT 0x1476 +#define LOG_GNSS_GPS_MEASUREMENT_REPORT 0x1477 +#define LOG_GNSS_CLOCK_REPORT 0x1478 +#define LOG_GNSS_GLONASS_MEASUREMENT_REPORT 0x1480 +#define LOG_GNSS_BDS_MEASUREMENT_REPORT 0x1756 +#define LOG_GNSS_GAL_MEASUREMENT_REPORT 0x1886 + +#define LOG_GNSS_OEMDRE_MEASUREMENMT_REPORT 0x14DE +#define LOG_GNSS_OEMDRE_SVPOLY_REPORT 0x14E1 + +#define LOG_GNSS_ME_DPO_STATUS 0x1838 +#define LOG_GNSS_CD_DB_REPORT 0x147B +#define LOG_GNSS_PRX_RF_HW_STATUS_REPORT 0x147E +#define LOG_CGPS_SLOW_CLOCK_CLIB_REPORT 0x1488 +#define LOG_GNSS_CONFIGURATION_STATE 0x1516 + +struct __attribute__((packed)) log_header_type { + uint16_t len; + uint16_t code; + uint64_t ts; +}; + + + +enum SVObservationStates { + SV_IDLE, + SV_SEARCH, + SV_SEACH_VERIFY, + SV_BIT_EDGE, + SV_TRACK_VERIFY, + SV_TRACK, + SV_RESTART, + SV_DPO, + SV_GLO_10ms_BE, + SV_GLO_10ms_AT, +}; + +struct __attribute__((packed)) GNSSGpsMeasurementReportv0_SV{ + uint8_t sv_id; + uint8_t observation_state; // SVObservationStates + uint8_t observations; + uint8_t good_observations; + uint16_t parity_error_count; + uint8_t filter_stages; + uint16_t carrier_noise; + int16_t latency; + uint8_t predetect_interval; + uint16_t postdetections; + uint32_t unfiltered_measurement_integral; + float unfiltered_measurement_fraction; + float unfiltered_time_uncertainty; + float unfiltered_speed; + float unfiltered_speed_uncertainty; + uint32_t measurement_status; + uint8_t misc_status; + uint32_t multipath_estimate; + float azimuth; + float elevation; + int32_t carrier_phase_cycles_integral; + uint16_t carrier_phase_cycles_fraction; + float fine_speed; + float fine_speed_uncertainty; + uint8_t cycle_slip_count; + uint32_t pad; +}; + +_Static_assert(sizeof(GNSSGpsMeasurementReportv0_SV) == 70, "error"); + +struct __attribute__((packed)) GNSSGpsMeasurementReportv0{ + log_header_type header; + uint8_t version; + uint32_t f_count; + uint16_t week; + uint32_t milliseconds; + float time_bias; + float clock_time_uncertainty; + float clock_frequency_bias; + float clock_frequency_uncertainty; + uint8_t sv_count; + GNSSGpsMeasurementReportv0_SV sv[]; +}; + + + +struct __attribute__((packed)) GNSSGlonassMeasurementReportv0_SV { + uint8_t sv_id; + int8_t frequency_index; + uint8_t observation_state; // SVObservationStates + uint8_t observations; + uint8_t good_observations; + uint8_t hemming_error_count; + uint8_t filter_stages; + uint16_t carrier_noise; + int16_t latency; + uint8_t predetect_interval; + uint16_t postdetections; + uint32_t unfiltered_measurement_integral; + float unfiltered_measurement_fraction; + float unfiltered_time_uncertainty; + float unfiltered_speed; + float unfiltered_speed_uncertainty; + uint32_t measurement_status; + uint8_t misc_status; + uint32_t multipath_estimate; + float azimuth; + float elevation; + int32_t carrier_phase_cycles_integral; + uint16_t carrier_phase_cycles_fraction; + float fine_speed; + float fine_speed_uncertainty; + uint8_t cycle_slip_count; + uint32_t pad; +}; + +_Static_assert(sizeof(GNSSGlonassMeasurementReportv0_SV) == 70, "error"); + +struct __attribute__((packed)) GNSSGlonassMeasurementReportv0 { + log_header_type header; + uint8_t version; + uint32_t f_count; + uint8_t glonass_cycle_number; + uint16_t glonass_number_of_days; + uint32_t milliseconds; + float time_bias; + float clock_time_uncertainty; + float clock_frequency_bias; + float clock_frequency_uncertainty; + uint8_t sv_count; + GNSSGlonassMeasurementReportv0_SV sv[]; +}; + + +struct __attribute__((packed)) GNSSClockReportv2 { + log_header_type header; + uint8_t version; + uint16_t valid_flags; + + uint32_t f_count; + + uint16_t gps_week; + uint32_t gps_milliseconds; + float gps_time_bias; + float gps_clock_time_uncertainty; + uint8_t gps_clock_source; + + uint8_t glonass_year; + uint16_t glonass_day; + uint32_t glonass_milliseconds; + float glonass_time_bias; + float glonass_clock_time_uncertainty; + uint8_t glonass_clock_source; + + uint16_t bds_week; + uint32_t bds_milliseconds; + float bds_time_bias; + float bds_clock_time_uncertainty; + uint8_t bds_clock_source; + + uint16_t gal_week; + uint32_t gal_milliseconds; + float gal_time_bias; + float gal_clock_time_uncertainty; + uint8_t gal_clock_source; + + float clock_frequency_bias; + float clock_frequency_uncertainty; + uint8_t frequency_source; + uint8_t gps_leap_seconds; + uint8_t gps_leap_seconds_uncertainty; + uint8_t gps_leap_seconds_source; + + float gps_to_glonass_time_bias_milliseconds; + float gps_to_glonass_time_bias_milliseconds_uncertainty; + float gps_to_bds_time_bias_milliseconds; + float gps_to_bds_time_bias_milliseconds_uncertainty; + float bds_to_glo_time_bias_milliseconds; + float bds_to_glo_time_bias_milliseconds_uncertainty; + float gps_to_gal_time_bias_milliseconds; + float gps_to_gal_time_bias_milliseconds_uncertainty; + float gal_to_glo_time_bias_milliseconds; + float gal_to_glo_time_bias_milliseconds_uncertainty; + float gal_to_bds_time_bias_milliseconds; + float gal_to_bds_time_bias_milliseconds_uncertainty; + + uint32_t system_rtc_time; + uint32_t f_count_offset; + uint32_t lpm_rtc_count; + uint32_t clock_resets; + + uint32_t reserved[3]; + +}; + + +enum GNSSMeasurementSource { + SOURCE_GPS, + SOURCE_GLONASS, + SOURCE_BEIDOU, +}; + +struct __attribute__((packed)) GNSSOemdreMeasurement { + uint8_t sv_id; + uint8_t unkn; + int8_t glonass_frequency_index; + uint32_t observation_state; + uint8_t observations; + uint8_t good_observations; + uint8_t filter_stages; + uint8_t predetect_interval; + uint8_t cycle_slip_count; + uint16_t postdetections; + + uint32_t measurement_status; + uint32_t measurement_status2; + + uint16_t carrier_noise; + uint16_t rf_loss; + int16_t latency; + + float filtered_measurement_fraction; + uint32_t filtered_measurement_integral; + float filtered_time_uncertainty; + float filtered_speed; + float filtered_speed_uncertainty; + + float unfiltered_measurement_fraction; + uint32_t unfiltered_measurement_integral; + float unfiltered_time_uncertainty; + float unfiltered_speed; + float unfiltered_speed_uncertainty; + + uint8_t multipath_estimate_valid; + uint32_t multipath_estimate; + uint8_t direction_valid; + float azimuth; + float elevation; + float doppler_acceleration; + float fine_speed; + float fine_speed_uncertainty; + + uint64_t carrier_phase; + uint32_t f_count; + + uint16_t parity_error_count; + uint8_t good_parity; + +}; + +_Static_assert(sizeof(GNSSOemdreMeasurement) == 109, "error"); + +struct __attribute__((packed)) GNSSOemdreMeasurementReportv2 { + log_header_type header; + uint8_t version; + uint8_t reason; + uint8_t sv_count; + uint8_t seq_num; + uint8_t seq_max; + uint16_t rf_loss; + + uint8_t system_rtc_valid; + uint32_t f_count; + uint32_t clock_resets; + uint64_t system_rtc_time; + + uint8_t gps_leap_seconds; + uint8_t gps_leap_seconds_uncertainty; + float gps_to_glonass_time_bias_milliseconds; + float gps_to_glonass_time_bias_milliseconds_uncertainty; + + uint16_t gps_week; + uint32_t gps_milliseconds; + uint32_t gps_time_bias; + uint32_t gps_clock_time_uncertainty; + uint8_t gps_clock_source; + + uint8_t glonass_clock_source; + uint8_t glonass_year; + uint16_t glonass_day; + uint32_t glonass_milliseconds; + float glonass_time_bias; + float glonass_clock_time_uncertainty; + + float clock_frequency_bias; + float clock_frequency_uncertainty; + uint8_t frequency_source; + + uint32_t cdma_clock_info[5]; + + uint8_t source; + + GNSSOemdreMeasurement measurements[16]; + +}; + +_Static_assert(sizeof(GNSSOemdreMeasurementReportv2) == 1851, "error"); + + +struct __attribute__((packed)) GNSSOemdreSVPolyReportv2 { + log_header_type header; + uint8_t version; + uint16_t sv_id; + int8_t frequency_index; + uint8_t flags; + uint16_t iode; + double t0; + double xyz0[3]; + double xyzN[9]; + float other[4]; + float position_uncertainty; + float iono_delay; + float iono_dot; + float sbas_iono_delay; + float sbas_iono_dot; + float tropo_delay; + float elevation; + float elevation_dot; + float elevation_uncertainty; + double velocity_coeff[12]; +}; + +_Static_assert(sizeof(GNSSOemdreSVPolyReportv2) == 271, "error"); + + +static Context *rawgps_context; +static PubSocket *rawgps_publisher; +static int client_id = 0; + +static void hexdump(uint8_t* d, size_t len) { + for (int i=0; i= sizeof(log_header_type)+1); + log_header_type* log_header = (log_header_type*)ptr; + uint8_t* log_data = ptr + sizeof(log_header_type); + +#ifdef RAWGPS_TEST + printf("%04x\n", log_header->code); +#endif + + capnp::MallocMessageBuilder msg; + cereal::Event::Builder event = msg.initRoot(); + event.setLogMonoTime(nanos_since_boot()); + auto qcomGnss = event.initQcomGnss(); + qcomGnss.setLogTs(log_header->ts); + + switch (log_header->code) { + + case LOG_GNSS_CLOCK_REPORT: { + uint8_t version = log_data[0]; + assert(version == 2); + + assert(len >= sizeof(GNSSClockReportv2)); + const GNSSClockReportv2* report = (const GNSSClockReportv2*)ptr; + + auto lreport = qcomGnss.initClockReport(); + lreport.setHasFCount(report->valid_flags & (1 << 0)); + lreport.setFCount(report->f_count); + + lreport.setHasGpsWeek(report->valid_flags & (1 << 2)); + lreport.setGpsWeek(report->gps_week); + lreport.setHasGpsMilliseconds(report->valid_flags & (1 << 1)); + lreport.setGpsMilliseconds(report->gps_milliseconds); + lreport.setGpsTimeBias(report->gps_time_bias); + lreport.setGpsClockTimeUncertainty(report->gps_clock_time_uncertainty); + lreport.setGpsClockSource(report->gps_clock_source); + + lreport.setHasGlonassYear(report->valid_flags & (1 << 6)); + lreport.setGlonassYear(report->glonass_year); + lreport.setHasGlonassDay(report->valid_flags & (1 << 5)); + lreport.setGlonassDay(report->glonass_day); + lreport.setHasGlonassMilliseconds(report->valid_flags & (1 << 4)); + lreport.setGlonassMilliseconds(report->glonass_milliseconds); + lreport.setGlonassTimeBias(report->glonass_time_bias); + lreport.setGlonassClockTimeUncertainty(report->glonass_clock_time_uncertainty); + lreport.setGlonassClockSource(report->glonass_clock_source); + + lreport.setBdsWeek(report->bds_week); + lreport.setBdsMilliseconds(report->bds_milliseconds); + lreport.setBdsTimeBias(report->bds_time_bias); + lreport.setBdsClockTimeUncertainty(report->bds_clock_time_uncertainty); + lreport.setBdsClockSource(report->bds_clock_source); + + lreport.setGalWeek(report->gal_week); + lreport.setGalMilliseconds(report->gal_milliseconds); + lreport.setGalTimeBias(report->gal_time_bias); + lreport.setGalClockTimeUncertainty(report->gal_clock_time_uncertainty); + lreport.setGalClockSource(report->gal_clock_source); + + lreport.setClockFrequencyBias(report->clock_frequency_bias); + lreport.setClockFrequencyUncertainty(report->clock_frequency_uncertainty); + lreport.setFrequencySource(report->frequency_source); + lreport.setGpsLeapSeconds(report->gps_leap_seconds); + lreport.setGpsLeapSecondsUncertainty(report->gps_leap_seconds_uncertainty); + lreport.setGpsLeapSecondsSource(report->gps_leap_seconds_source); + + lreport.setGpsToGlonassTimeBiasMilliseconds(report->gps_to_glonass_time_bias_milliseconds); + lreport.setGpsToGlonassTimeBiasMillisecondsUncertainty(report->gps_to_glonass_time_bias_milliseconds_uncertainty); + lreport.setGpsToBdsTimeBiasMilliseconds(report->gps_to_bds_time_bias_milliseconds); + lreport.setGpsToBdsTimeBiasMillisecondsUncertainty(report->gps_to_bds_time_bias_milliseconds_uncertainty); + lreport.setBdsToGloTimeBiasMilliseconds(report->bds_to_glo_time_bias_milliseconds); + lreport.setBdsToGloTimeBiasMillisecondsUncertainty(report->bds_to_glo_time_bias_milliseconds_uncertainty); + lreport.setGpsToGalTimeBiasMilliseconds(report->gps_to_gal_time_bias_milliseconds); + lreport.setGpsToGalTimeBiasMillisecondsUncertainty(report->gps_to_gal_time_bias_milliseconds_uncertainty); + lreport.setGalToGloTimeBiasMilliseconds(report->gal_to_glo_time_bias_milliseconds); + lreport.setGalToGloTimeBiasMillisecondsUncertainty(report->gal_to_glo_time_bias_milliseconds_uncertainty); + lreport.setGalToBdsTimeBiasMilliseconds(report->gal_to_bds_time_bias_milliseconds); + lreport.setGalToBdsTimeBiasMillisecondsUncertainty(report->gal_to_bds_time_bias_milliseconds_uncertainty); + + lreport.setHasRtcTime(report->valid_flags & (1 << 3)); + lreport.setSystemRtcTime(report->system_rtc_time); + lreport.setFCountOffset(report->f_count_offset); + lreport.setLpmRtcCount(report->lpm_rtc_count); + lreport.setClockResets(report->clock_resets); + + break; + } + case LOG_GNSS_GPS_MEASUREMENT_REPORT: { + uint8_t version = log_data[0]; + assert(version == 0); + + assert(len >= sizeof(GNSSGpsMeasurementReportv0)); + const GNSSGpsMeasurementReportv0* report = (const GNSSGpsMeasurementReportv0*)ptr; + assert(len >= sizeof(sizeof(GNSSGpsMeasurementReportv0))+sizeof(GNSSGpsMeasurementReportv0_SV) * report->sv_count); + + auto lreport = qcomGnss.initMeasurementReport(); + lreport.setSource(cereal::QcomGnss::MeasurementSource::GPS); + lreport.setFCount(report->f_count); + lreport.setGpsWeek(report->week); + lreport.setMilliseconds(report->milliseconds); + lreport.setTimeBias(report->time_bias); + lreport.setClockTimeUncertainty(report->clock_time_uncertainty); + lreport.setClockFrequencyBias(report->clock_frequency_bias); + lreport.setClockFrequencyUncertainty(report->clock_frequency_uncertainty); + + auto lsvs = lreport.initSv(report->sv_count); + for (int i=0; isv_count; i++) { + auto lsv = lsvs[i]; + const GNSSGpsMeasurementReportv0_SV *sv = &report->sv[i]; + + lsv.setSvId(sv->sv_id); + lsv.setObservationState(cereal::QcomGnss::SVObservationState(sv->observation_state)); + lsv.setObservations(sv->observations); + lsv.setGoodObservations(sv->good_observations); + lsv.setGpsParityErrorCount(sv->parity_error_count); + lsv.setFilterStages(sv->filter_stages); + lsv.setCarrierNoise(sv->carrier_noise); + lsv.setLatency(sv->latency); + lsv.setPredetectInterval(sv->predetect_interval); + lsv.setPostdetections(sv->postdetections); + lsv.setUnfilteredMeasurementIntegral(sv->unfiltered_measurement_integral); + lsv.setUnfilteredMeasurementFraction(sv->unfiltered_measurement_fraction); + lsv.setUnfilteredTimeUncertainty(sv->unfiltered_time_uncertainty); + lsv.setUnfilteredSpeed(sv->unfiltered_speed); + lsv.setUnfilteredSpeedUncertainty(sv->unfiltered_speed_uncertainty); + + lsv.setMultipathEstimate(sv->multipath_estimate); + lsv.setAzimuth(sv->azimuth); + lsv.setElevation(sv->elevation); + lsv.setCarrierPhaseCyclesIntegral(sv->carrier_phase_cycles_integral); + lsv.setCarrierPhaseCyclesFraction(sv->carrier_phase_cycles_fraction); + lsv.setFineSpeed(sv->fine_speed); + lsv.setFineSpeedUncertainty(sv->fine_speed_uncertainty); + lsv.setCycleSlipCount(sv->cycle_slip_count); + + auto status = lsv.initMeasurementStatus(); + parse_measurement_status_common(sv->measurement_status, status); + + status.setGpsRoundRobinRxDiversity(sv->measurement_status & (1 << 18)); + status.setGpsRxDiversity(sv->measurement_status & (1 << 19)); + status.setGpsLowBandwidthRxDiversityCombined(sv->measurement_status & (1 << 20)); + status.setGpsHighBandwidthNu4(sv->measurement_status & (1 << 21)); + status.setGpsHighBandwidthNu8(sv->measurement_status & (1 << 22)); + status.setGpsHighBandwidthUniform(sv->measurement_status & (1 << 23)); + + status.setMultipathEstimateIsValid(sv->misc_status & (1 << 0)); + status.setDirectionIsValid(sv->misc_status & (1 << 1)); + +#ifdef RAWGPS_TEST + // if (sv->measurement_status & (1 << 27)) printf("%d\n", sv->unfiltered_measurement_integral); + printf("GPS %03d %d %d 0x%08X o: %02x go: %02x fs: %02x cn: %02x pd: %02x cs: %02x po: %02x ms: %08x ms2: %08x me: %08x az: %08x el: %08x fc: %08x\n", + sv->sv_id, + !!(sv->measurement_status & (1 << 27)), + sv->unfiltered_measurement_integral, sv->unfiltered_measurement_integral, + sv->observations, + sv->good_observations, + sv->filter_stages, + sv->carrier_noise, + sv->predetect_interval, + sv->cycle_slip_count, + sv->postdetections, + sv->measurement_status, + sv->misc_status, + sv->multipath_estimate, + *(uint32_t*)&sv->azimuth, + *(uint32_t*)&sv->elevation, + report->f_count + ); +#endif + + } + + break; + } + case LOG_GNSS_GLONASS_MEASUREMENT_REPORT: { + uint8_t version = log_data[0]; + assert(version == 0); + + assert(len >= sizeof(GNSSGlonassMeasurementReportv0)); + const GNSSGlonassMeasurementReportv0* report = (const GNSSGlonassMeasurementReportv0*)ptr; + + auto lreport = qcomGnss.initMeasurementReport(); + lreport.setSource(cereal::QcomGnss::MeasurementSource::GLONASS); + lreport.setFCount(report->f_count); + lreport.setGlonassCycleNumber(report->glonass_cycle_number); + lreport.setGlonassNumberOfDays(report->glonass_number_of_days); + lreport.setMilliseconds(report->milliseconds); + lreport.setTimeBias(report->time_bias); + lreport.setClockTimeUncertainty(report->clock_time_uncertainty); + lreport.setClockFrequencyBias(report->clock_frequency_bias); + lreport.setClockFrequencyUncertainty(report->clock_frequency_uncertainty); + + auto lsvs = lreport.initSv(report->sv_count); + for (int i=0; isv_count; i++) { + auto lsv = lsvs[i]; + const GNSSGlonassMeasurementReportv0_SV *sv = &report->sv[i]; + + lsv.setSvId(sv->sv_id); + lsv.setObservationState(cereal::QcomGnss::SVObservationState(sv->observation_state)); + lsv.setObservations(sv->observations); + lsv.setGoodObservations(sv->good_observations); + lsv.setGlonassFrequencyIndex(sv->frequency_index); + lsv.setGlonassHemmingErrorCount(sv->hemming_error_count); + lsv.setFilterStages(sv->filter_stages); + lsv.setCarrierNoise(sv->carrier_noise); + lsv.setLatency(sv->latency); + lsv.setPredetectInterval(sv->predetect_interval); + lsv.setPostdetections(sv->postdetections); + lsv.setUnfilteredMeasurementIntegral(sv->unfiltered_measurement_integral); + lsv.setUnfilteredMeasurementFraction(sv->unfiltered_measurement_fraction); + lsv.setUnfilteredTimeUncertainty(sv->unfiltered_time_uncertainty); + lsv.setUnfilteredSpeed(sv->unfiltered_speed); + lsv.setUnfilteredSpeedUncertainty(sv->unfiltered_speed_uncertainty); + + lsv.setMultipathEstimate(sv->multipath_estimate); + lsv.setAzimuth(sv->azimuth); + lsv.setElevation(sv->elevation); + lsv.setCarrierPhaseCyclesIntegral(sv->carrier_phase_cycles_integral); + lsv.setCarrierPhaseCyclesFraction(sv->carrier_phase_cycles_fraction); + lsv.setFineSpeed(sv->fine_speed); + lsv.setFineSpeedUncertainty(sv->fine_speed_uncertainty); + lsv.setCycleSlipCount(sv->cycle_slip_count); + + auto status = lsv.initMeasurementStatus(); + parse_measurement_status_common(sv->measurement_status, status); + + status.setGlonassMeanderBitEdgeValid(sv->measurement_status & (1 << 16)); + status.setGlonassTimeMarkValid(sv->measurement_status & (1 << 17)); + + status.setMultipathEstimateIsValid(sv->misc_status & (1 << 0)); + status.setDirectionIsValid(sv->misc_status & (1 << 1)); + + +#ifdef RAWGPS_TEST + // if (sv->measurement_status & (1 << 27)) printf("%d\n", sv->unfiltered_measurement_integral); + printf("GLO %03d %02x %d %d 0x%08X o: %02x go: %02x fs: %02x cn: %02x pd: %02x cs: %02x po: %02x ms: %08x ms2: %08x me: %08x az: %08x el: %08x fc: %08x\n", + sv->sv_id, sv->frequency_index & 0xff, + !!(sv->measurement_status & (1 << 27)), + sv->unfiltered_measurement_integral, sv->unfiltered_measurement_integral, + sv->observations, + sv->good_observations, + sv->filter_stages, + sv->carrier_noise, + sv->predetect_interval, + sv->cycle_slip_count, + sv->postdetections, + sv->measurement_status, + sv->misc_status, + sv->multipath_estimate, + *(uint32_t*)&sv->azimuth, + *(uint32_t*)&sv->elevation, + report->f_count + ); +#endif + + } + break; + } + case LOG_GNSS_OEMDRE_MEASUREMENMT_REPORT: { + // hexdump(ptr, len); + + uint8_t version = log_data[0]; + assert(version == 2); + + assert(len >= sizeof(GNSSOemdreMeasurementReportv2)); + const GNSSOemdreMeasurementReportv2* report = (const GNSSOemdreMeasurementReportv2*)ptr; + + + auto lreport = qcomGnss.initDrMeasurementReport(); + + lreport.setReason(report->reason); + lreport.setSeqNum(report->seq_num); + lreport.setSeqMax(report->seq_max); + lreport.setRfLoss(report->rf_loss); + lreport.setSystemRtcValid(report->system_rtc_valid); + lreport.setFCount(report->f_count); + lreport.setClockResets(report->clock_resets); + lreport.setSystemRtcTime(report->system_rtc_time); + + lreport.setGpsLeapSeconds(report->gps_leap_seconds); + lreport.setGpsLeapSecondsUncertainty(report->gps_leap_seconds_uncertainty); + lreport.setGpsToGlonassTimeBiasMilliseconds(report->gps_to_glonass_time_bias_milliseconds); + lreport.setGpsToGlonassTimeBiasMillisecondsUncertainty(report->gps_to_glonass_time_bias_milliseconds_uncertainty); + + lreport.setGpsWeek(report->gps_week); + lreport.setGpsMilliseconds(report->gps_milliseconds); + lreport.setGpsTimeBiasMs(report->gps_time_bias); + lreport.setGpsClockTimeUncertaintyMs(report->gps_clock_time_uncertainty); + lreport.setGpsClockSource(report->gps_clock_source); + + lreport.setGlonassClockSource(report->glonass_clock_source); + lreport.setGlonassYear(report->glonass_year); + lreport.setGlonassDay(report->glonass_day); + lreport.setGlonassMilliseconds(report->glonass_milliseconds); + lreport.setGlonassTimeBias(report->glonass_time_bias); + lreport.setGlonassClockTimeUncertainty(report->glonass_clock_time_uncertainty); + + lreport.setClockFrequencyBias(report->clock_frequency_bias); + lreport.setClockFrequencyUncertainty(report->clock_frequency_uncertainty); + lreport.setFrequencySource(report->frequency_source); + + lreport.setSource(cereal::QcomGnss::MeasurementSource(report->source)); + + auto lsvs = lreport.initSv(report->sv_count); + + // for (int i=0; isv_count; i++) { + // GNSSOemdreMeasurement *sv = &report->gps[i]; + // if (!(sv->measurement_status & (1 << 27))) continue; + // printf("oemdre %03d %d %f\n", sv->sv_id, sv->unfiltered_measurement_integral, sv->unfiltered_measurement_fraction); + // } + for (int i=0; isv_count; i++) { + auto lsv = lsvs[i]; + const GNSSOemdreMeasurement *sv = &report->measurements[i]; + + lsv.setSvId(sv->sv_id); + lsv.setGlonassFrequencyIndex(sv->glonass_frequency_index); + lsv.setObservationState(cereal::QcomGnss::SVObservationState(sv->observation_state)); + lsv.setObservations(sv->observations); + lsv.setGoodObservations(sv->good_observations); + lsv.setFilterStages(sv->filter_stages); + lsv.setPredetectInterval(sv->predetect_interval); + lsv.setCycleSlipCount(sv->cycle_slip_count); + lsv.setPostdetections(sv->postdetections); + + auto status = lsv.initMeasurementStatus(); + parse_measurement_status_common(sv->measurement_status, status); + + status.setMultipathEstimateIsValid(sv->multipath_estimate_valid); + status.setDirectionIsValid(sv->direction_valid); + + lsv.setCarrierNoise(sv->carrier_noise); + lsv.setRfLoss(sv->rf_loss); + lsv.setLatency(sv->latency); + + lsv.setFilteredMeasurementFraction(sv->filtered_measurement_fraction); + lsv.setFilteredMeasurementIntegral(sv->filtered_measurement_integral); + lsv.setFilteredTimeUncertainty(sv->filtered_time_uncertainty); + lsv.setFilteredSpeed(sv->filtered_speed); + lsv.setFilteredSpeedUncertainty(sv->filtered_speed_uncertainty); + + lsv.setUnfilteredMeasurementFraction(sv->unfiltered_measurement_fraction); + lsv.setUnfilteredMeasurementIntegral(sv->unfiltered_measurement_integral); + lsv.setUnfilteredTimeUncertainty(sv->unfiltered_time_uncertainty); + lsv.setUnfilteredSpeed(sv->unfiltered_speed); + lsv.setUnfilteredSpeedUncertainty(sv->unfiltered_speed_uncertainty); + + lsv.setMultipathEstimate(sv->multipath_estimate); + lsv.setAzimuth(sv->azimuth); + lsv.setElevation(sv->elevation); + lsv.setDopplerAcceleration(sv->doppler_acceleration); + lsv.setFineSpeed(sv->fine_speed); + lsv.setFineSpeedUncertainty(sv->fine_speed_uncertainty); + + lsv.setCarrierPhase(sv->carrier_phase); + lsv.setFCount(sv->f_count); + + lsv.setParityErrorCount(sv->parity_error_count); + lsv.setGoodParity(sv->good_parity); + + } + break; + } + case LOG_GNSS_OEMDRE_SVPOLY_REPORT: { + uint8_t version = log_data[0]; + assert(version == 2); + + assert(len >= sizeof(GNSSOemdreSVPolyReportv2)); + const GNSSOemdreSVPolyReportv2* report = (const GNSSOemdreSVPolyReportv2*)ptr; + + auto lreport = qcomGnss.initDrSvPoly(); + + lreport.setSvId(report->sv_id); + lreport.setFrequencyIndex(report->frequency_index); + + lreport.setHasPosition(report->flags & 1); + lreport.setHasIono(report->flags & 2); + lreport.setHasTropo(report->flags & 4); + lreport.setHasElevation(report->flags & 8); + lreport.setPolyFromXtra(report->flags & 16); + lreport.setHasSbasIono(report->flags & 32); + + lreport.setIode(report->iode); + lreport.setT0(report->t0); + + kj::ArrayPtr xyz0(report->xyz0, 3); + lreport.setXyz0(xyz0); + + kj::ArrayPtr xyzN(report->xyzN, 9); + lreport.setXyzN(xyzN); + + kj::ArrayPtr other(report->other, 4); + lreport.setOther(other); + + lreport.setPositionUncertainty(report->position_uncertainty); + lreport.setIonoDelay(report->iono_delay); + lreport.setIonoDot(report->iono_dot); + lreport.setSbasIonoDelay(report->sbas_iono_delay); + lreport.setSbasIonoDot(report->sbas_iono_dot); + lreport.setTropoDelay(report->tropo_delay); + lreport.setElevation(report->elevation); + lreport.setElevationDot(report->elevation_dot); + lreport.setElevationUncertainty(report->elevation_uncertainty); + + kj::ArrayPtr velocity_coeff(report->velocity_coeff, 12); + lreport.setVelocityCoeff(velocity_coeff); + + break; + } + default: + // printf("%04x\n", log_header->code); + // hexdump(ptr, len); + + qcomGnss.setRawLog(kj::arrayPtr(ptr, len)); + + break; + } + + auto words = capnp::messageToFlatArray(msg); + auto bytes = words.asBytes(); + rawgps_publisher->send((char*)bytes.begin(), bytes.size()); +} + +static void handle_event(unsigned char *ptr, int len) { + // printf("EVENT\n"); +} + +static uint16_t log_codes[] = { + LOG_GNSS_CLOCK_REPORT, + LOG_GNSS_GPS_MEASUREMENT_REPORT, + LOG_GNSS_GLONASS_MEASUREMENT_REPORT, + LOG_GNSS_OEMDRE_MEASUREMENMT_REPORT, + LOG_GNSS_OEMDRE_SVPOLY_REPORT, + + // unparsed: + LOG_GNSS_POSITION_REPORT, + + LOG_GNSS_BDS_MEASUREMENT_REPORT, // these are missing by might as well try to catch them anyway + LOG_GNSS_GAL_MEASUREMENT_REPORT, + + LOG_GNSS_ME_DPO_STATUS, + LOG_GNSS_CD_DB_REPORT, + LOG_GNSS_PRX_RF_HW_STATUS_REPORT, + LOG_CGPS_SLOW_CLOCK_CLIB_REPORT, + LOG_GNSS_CONFIGURATION_STATE, +}; + + +struct SendDiagSyncState { + sem_t sem; + int len; +}; + +static void diag_send_sync_cb(unsigned char *ptr, int len, void *data_ptr) { + SendDiagSyncState *s = (SendDiagSyncState*)data_ptr; + s->len = len; + sem_post(&s->sem); +} + +static int diag_send_sync(int client_id, unsigned char* req_pkt, size_t pkt_len, + unsigned char* res_pkt, size_t res_pkt_size) { + + SendDiagSyncState s = {0}; + sem_init(&s.sem, 0, 0); + + int err = diag_send_dci_async_req(client_id, req_pkt, pkt_len, res_pkt, res_pkt_size, + diag_send_sync_cb, &s); + assert(err == DIAG_DCI_NO_ERROR); + + sem_wait(&s.sem); + return s.len; +} + +static int oemdre_on(int client_id) { + // enable OEM DR + unsigned char res_pkt[DIAG_MAX_RX_PKT_SIZ]; + + GpsOemControlReq req_pkt = { + .cmd_code = DIAG_SUBSYS_CMD, + .subsys_id = DIAG_SUBSYS_GPS, + .subsys_cmd_code = CGPS_DIAG_PDAPI_CMD, + .gps_cmd_code = CGPS_OEM_CONTROL, + .version = 1, + + .oem_feature = GPSDIAG_OEMFEATURE_DRE, + .oem_command = GPSDIAG_OEM_DRE_ON, + }; + + int res_len = diag_send_sync(client_id, (unsigned char*)&req_pkt, sizeof(req_pkt), + res_pkt, sizeof(res_pkt)); + GpsOemControlResp *resp = (GpsOemControlResp*)res_pkt; + + if (res_len != sizeof(GpsOemControlResp) + || resp->cmd_code != DIAG_SUBSYS_CMD + || resp->subsys_id != DIAG_SUBSYS_GPS + || resp->subsys_cmd_code != CGPS_DIAG_PDAPI_CMD + || resp->gps_cmd_code != CGPS_OEM_CONTROL + || resp->oem_feature != GPSDIAG_OEMFEATURE_DRE + || resp->oem_command != GPSDIAG_OEM_DRE_ON) { + LOGW("oemdre_on: bad response!"); + return -1; + } + + return resp->resp_result; +} + +static void efs_sync(int client_id) { + unsigned char res_pkt[DIAG_MAX_RX_PKT_SIZ]; + + Efs2DiagSyncReq req_pkt = { + .cmd_code = DIAG_SUBSYS_CMD, + .subsys_id = DIAG_SUBSYS_FS, + .subsys_cmd_code = EFS2_DIAG_SYNC_NO_WAIT, + .sequence_num = (uint16_t)(rand() % 100), + }; + req_pkt.path[0] = '/'; + req_pkt.path[1] = 0; + + int res_len = diag_send_sync(client_id, (unsigned char*)&req_pkt, sizeof(req_pkt), + res_pkt, sizeof(res_pkt)); + Efs2DiagSyncResp *resp = (Efs2DiagSyncResp*)res_pkt; + + if (res_len != sizeof(Efs2DiagSyncResp) + || resp->cmd_code != DIAG_SUBSYS_CMD + || resp->subsys_id != DIAG_SUBSYS_FS + || resp->subsys_cmd_code != EFS2_DIAG_SYNC_NO_WAIT) { + LOGW("efs_sync: bad response!"); + return; + } + if (resp->diag_errno != 0) { + LOGW("efs_sync: error %d", resp->diag_errno); + } +} + +static uint32_t nv_read_u32(int client_id, uint16_t nv_id) { + NvPacket req = { + .cmd_code = DIAG_NV_READ_F, + .nv_id = nv_id, + }; + NvPacket resp = {0}; + + int res_len = diag_send_sync(client_id, (unsigned char*)&req, sizeof(req), + (unsigned char*)&resp, sizeof(resp)); + + // hexdump((uint8_t*)&resp, res_len); + + if (resp.cmd_code != DIAG_NV_READ_F + || resp.nv_id != nv_id) { + LOGW("nv_read_u32: diag command failed"); + return 0; + } + + if (resp.status != NV_DONE) { + LOGW("nv_read_u32: read failed: %d", resp.status); + return 0; + } + return *(uint32_t*)resp.data; +} + +static bool nv_write_u32(int client_id, uint16_t nv_id, uint32_t val) { + NvPacket req = { + .cmd_code = DIAG_NV_WRITE_F, + .nv_id = nv_id, + }; + *(uint32_t*)req.data = val; + + NvPacket resp = {0}; + int res_len = diag_send_sync(client_id, (unsigned char*)&req, sizeof(req), + (unsigned char*)&resp, sizeof(resp)); + + // hexdump((uint8_t*)&resp, res_len); + + if (resp.cmd_code != DIAG_NV_WRITE_F + || resp.nv_id != nv_id) { + LOGW("nv_write_u32: diag command failed"); + return false; + } + + if (resp.status != NV_DONE) { + LOGW("nv_write_u32: write failed: %d", resp.status); + return false; + } + + return true; +} + +static void nav_config(int client_id, uint8_t config) { + unsigned char res_pkt[DIAG_MAX_RX_PKT_SIZ]; + + GpsNavConfigReq req_pkt = { + .cmd_code = DIAG_SUBSYS_CMD_VER_2, + .subsys_id = DIAG_SUBSYS_GPS, + .subsys_cmd_code = TM_DIAG_NAV_CONFIG_CMD, + .desired_config = config, + }; + + int res_len = diag_send_sync(client_id, (unsigned char*)&req_pkt, sizeof(req_pkt), + res_pkt, sizeof(res_pkt)); + GpsNavConfigResp *resp = (GpsNavConfigResp*)res_pkt; + + if (res_len != sizeof(GpsNavConfigResp) + || resp->cmd_code != DIAG_SUBSYS_CMD_VER_2 + || resp->subsys_id != DIAG_SUBSYS_GPS + || resp->subsys_cmd_code != TM_DIAG_NAV_CONFIG_CMD) { + LOGW("nav_config: bad response!"); + return; + } + LOG("nav config: %04x %04x", resp->supported_config, resp->actual_config); +} + +void rawgps_init() { + int err; + + rawgps_context = Context::create(); + rawgps_publisher = PubSocket::create(rawgps_context, "qcomGnss"); + + bool init_success = Diag_LSM_Init(NULL); + assert(init_success); + + uint16_t list = DIAG_CON_APSS | DIAG_CON_MPSS; + int signal_type = SIGCONT; + err = diag_register_dci_client(&client_id, &list, 0, &signal_type); + assert(err == DIAG_DCI_NO_ERROR); + + { + uint32_t oem_features = nv_read_u32(client_id, NV_GNSS_OEM_FEATURE_MASK); + LOG("oem features: %08x", oem_features); + + if (!(oem_features & NV_GNSS_OEM_FEATURE_MASK_OEMDRE)) { + LOG("OEMDRE feature disabled, enabling..."); + nv_write_u32(client_id, NV_GNSS_OEM_FEATURE_MASK, NV_GNSS_OEM_FEATURE_MASK_OEMDRE); + efs_sync(client_id); + } + + int oemdre_status = oemdre_on(client_id); + LOG("oemdre status: %d", oemdre_status); + } + + { + // make sure GNSS duty cycling is off + uint32_t dpo = nv_read_u32(client_id, NV_CGPS_DPO_CONTROL); + LOG("dpo: %d", dpo); + if (dpo != 0) { + nv_write_u32(client_id, NV_CGPS_DPO_CONTROL, 0); + efs_sync(client_id); + } + } + + // enable beidou + // nav_config(client_id, 0x13); // 0b10011 + + err = diag_register_dci_stream(handle_log, handle_event); + assert(err == DIAG_DCI_NO_ERROR); + + err = diag_log_stream_config(client_id, true, log_codes, ARRAYSIZE(log_codes)); + assert(err == DIAG_DCI_NO_ERROR); +} + +void rawgps_destroy() { + + int err; + + err = diag_log_stream_config(client_id, false, log_codes, ARRAYSIZE(log_codes)); + assert(err == DIAG_DCI_NO_ERROR); + + err = diag_release_dci_client(&client_id); + assert(err == DIAG_DCI_NO_ERROR); + + Diag_LSM_DeInit(); + + delete rawgps_publisher; + delete rawgps_context; +} + + +#ifdef RAWGPS_TEST +int main() { + int err = 0; + rawgps_init(); + + while(1) { + usleep(100000); + } + + rawgps_destroy(); + return 0; +} +#endif diff --git a/selfdrive/sensord/rawgps.h b/selfdrive/sensord/rawgps.h new file mode 100644 index 00000000000000..13d23cd28c9669 --- /dev/null +++ b/selfdrive/sensord/rawgps.h @@ -0,0 +1,7 @@ +#ifndef RAWGPS_H +#define RAWGPS_H + +void rawgps_init(); +void rawgps_destroy(); + +#endif diff --git a/selfdrive/sensord/sensord b/selfdrive/sensord/sensord deleted file mode 100755 index 40c678c1e033b7..00000000000000 Binary files a/selfdrive/sensord/sensord and /dev/null differ diff --git a/selfdrive/sensord/sensors.cc b/selfdrive/sensord/sensors.cc new file mode 100644 index 00000000000000..de20bfc6c3cbc1 --- /dev/null +++ b/selfdrive/sensord/sensors.cc @@ -0,0 +1,232 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include + +#include "messaging.hpp" +#include "common/timing.h" +#include "common/swaglog.h" + +#include "cereal/gen/cpp/log.capnp.h" + +#define SENSOR_ACCELEROMETER 1 +#define SENSOR_MAGNETOMETER 2 +#define SENSOR_GYRO 4 + +// ACCELEROMETER_UNCALIBRATED is only in Android O +// https://developer.android.com/reference/android/hardware/Sensor.html#STRING_TYPE_ACCELEROMETER_UNCALIBRATED +#define SENSOR_MAGNETOMETER_UNCALIBRATED 3 +#define SENSOR_GYRO_UNCALIBRATED 5 + +#define SENSOR_PROXIMITY 6 +#define SENSOR_LIGHT 7 + +volatile sig_atomic_t do_exit = 0; + +namespace { + +void set_do_exit(int sig) { + do_exit = 1; +} + +void sigpipe_handler(int sig) { + LOGE("SIGPIPE received"); +} + + +void sensor_loop() { + LOG("*** sensor loop"); + + Context * c = Context::create(); + PubSocket * sensor_events_sock = PubSocket::create(c, "sensorEvents"); + + struct sensors_poll_device_t* device; + struct sensors_module_t* module; + + hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); + sensors_open(&module->common, &device); + + // required + struct sensor_t const* list; + int count = module->get_sensors_list(module, &list); + LOG("%d sensors found", count); + + if (getenv("SENSOR_TEST")) { + exit(count); + } + + for (int i = 0; i < count; i++) { + LOGD("sensor %4d: %4d %60s %d-%ld us", i, list[i].handle, list[i].name, list[i].minDelay, list[i].maxDelay); + } + + device->activate(device, SENSOR_MAGNETOMETER_UNCALIBRATED, 0); + device->activate(device, SENSOR_GYRO_UNCALIBRATED, 0); + device->activate(device, SENSOR_ACCELEROMETER, 0); + device->activate(device, SENSOR_MAGNETOMETER, 0); + device->activate(device, SENSOR_GYRO, 0); + device->activate(device, SENSOR_PROXIMITY, 0); + device->activate(device, SENSOR_LIGHT, 0); + + device->activate(device, SENSOR_MAGNETOMETER_UNCALIBRATED, 1); + device->activate(device, SENSOR_GYRO_UNCALIBRATED, 1); + device->activate(device, SENSOR_ACCELEROMETER, 1); + device->activate(device, SENSOR_MAGNETOMETER, 1); + device->activate(device, SENSOR_GYRO, 1); + device->activate(device, SENSOR_PROXIMITY, 1); + device->activate(device, SENSOR_LIGHT, 1); + + device->setDelay(device, SENSOR_GYRO_UNCALIBRATED, ms2ns(10)); + device->setDelay(device, SENSOR_MAGNETOMETER_UNCALIBRATED, ms2ns(100)); + device->setDelay(device, SENSOR_ACCELEROMETER, ms2ns(10)); + device->setDelay(device, SENSOR_GYRO, ms2ns(10)); + device->setDelay(device, SENSOR_MAGNETOMETER, ms2ns(100)); + device->setDelay(device, SENSOR_PROXIMITY, ms2ns(100)); + device->setDelay(device, SENSOR_LIGHT, ms2ns(100)); + + static const size_t numEvents = 16; + sensors_event_t buffer[numEvents]; + + + while (!do_exit) { + int n = device->poll(device, buffer, numEvents); + if (n == 0) continue; + if (n < 0) { + LOG("sensor_loop poll failed: %d", n); + continue; + } + + int log_events = 0; + for (int i=0; i < n; i++) { + switch (buffer[i].type) { + case SENSOR_TYPE_ACCELEROMETER: + case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED: + case SENSOR_TYPE_MAGNETIC_FIELD: + case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: + case SENSOR_TYPE_GYROSCOPE: + case SENSOR_TYPE_PROXIMITY: + case SENSOR_TYPE_LIGHT: + log_events++; + break; + default: + continue; + } + } + + uint64_t log_time = nanos_since_boot(); + + capnp::MallocMessageBuilder msg; + cereal::Event::Builder event = msg.initRoot(); + event.setLogMonoTime(log_time); + + auto sensor_events = event.initSensorEvents(log_events); + + int log_i = 0; + for (int i = 0; i < n; i++) { + + const sensors_event_t& data = buffer[i]; + + switch (data.type) { + case SENSOR_TYPE_ACCELEROMETER: + case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED: + case SENSOR_TYPE_MAGNETIC_FIELD: + case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: + case SENSOR_TYPE_GYROSCOPE: + case SENSOR_TYPE_PROXIMITY: + case SENSOR_TYPE_LIGHT: + break; + default: + continue; + } + + auto log_event = sensor_events[log_i]; + + log_event.setSource(cereal::SensorEventData::SensorSource::ANDROID); + log_event.setVersion(data.version); + log_event.setSensor(data.sensor); + log_event.setType(data.type); + log_event.setTimestamp(data.timestamp); + + switch (data.type) { + case SENSOR_TYPE_ACCELEROMETER: { + auto svec = log_event.initAcceleration(); + kj::ArrayPtr vs(&data.acceleration.v[0], 3); + svec.setV(vs); + svec.setStatus(data.acceleration.status); + break; + } + case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED: { + auto svec = log_event.initMagneticUncalibrated(); + // assuming the uncalib and bias floats are contiguous in memory + kj::ArrayPtr vs(&data.uncalibrated_magnetic.uncalib[0], 6); + svec.setV(vs); + break; + } + case SENSOR_TYPE_MAGNETIC_FIELD: { + auto svec = log_event.initMagnetic(); + kj::ArrayPtr vs(&data.magnetic.v[0], 3); + svec.setV(vs); + svec.setStatus(data.magnetic.status); + break; + } + case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: { + auto svec = log_event.initGyroUncalibrated(); + // assuming the uncalib and bias floats are contiguous in memory + kj::ArrayPtr vs(&data.uncalibrated_gyro.uncalib[0], 6); + svec.setV(vs); + break; + } + case SENSOR_TYPE_GYROSCOPE: { + auto svec = log_event.initGyro(); + kj::ArrayPtr vs(&data.gyro.v[0], 3); + svec.setV(vs); + svec.setStatus(data.gyro.status); + break; + } + case SENSOR_TYPE_PROXIMITY: { + log_event.setProximity(data.distance); + break; + } + case SENSOR_TYPE_LIGHT: + log_event.setLight(data.light); + break; + } + + log_i++; + } + + auto words = capnp::messageToFlatArray(msg); + auto bytes = words.asBytes(); + sensor_events_sock->send((char*)bytes.begin(), bytes.size()); + } + + delete sensor_events_sock; + delete c; +} +} + +int main(int argc, char *argv[]) { + setpriority(PRIO_PROCESS, 0, -13); + signal(SIGINT, (sighandler_t)set_do_exit); + signal(SIGTERM, (sighandler_t)set_do_exit); + signal(SIGPIPE, (sighandler_t)sigpipe_handler); + + sensor_loop(); + + return 0; +} diff --git a/selfdrive/sensord/start_gpsd.py b/selfdrive/sensord/start_gpsd.py new file mode 100755 index 00000000000000..287ead295998d0 --- /dev/null +++ b/selfdrive/sensord/start_gpsd.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 +import os + +assert os.system("make") == 0 +os.environ['LD_LIBRARY_PATH'] = "/system/lib64:" + os.environ['LD_LIBRARY_PATH'] +os.execv("./gpsd", ["gpsd"]) diff --git a/selfdrive/sensord/start_sensord.py b/selfdrive/sensord/start_sensord.py new file mode 100755 index 00000000000000..bd0cbed82b7bbf --- /dev/null +++ b/selfdrive/sensord/start_sensord.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 +import os + +assert os.system("make") == 0 +os.environ['LD_LIBRARY_PATH'] = "/system/lib64:" + os.environ['LD_LIBRARY_PATH'] +os.execv("./sensord", ["sensord"]) diff --git a/selfdrive/service_list.yaml b/selfdrive/service_list.yaml index 627d40df85341d..a38c6ad714ac60 100644 --- a/selfdrive/service_list.yaml +++ b/selfdrive/service_list.yaml @@ -2,118 +2,134 @@ # LogRotate: 8001 is a PUSH PULL socket between loggerd and visiond -# all ZMQ pub sub: +# all ZMQ pub sub: port, should_log, frequency, (qlog_decimation) # frame syncing packet -frame: [8002, true] +frame: [8002, true, 20., 1] # accel, gyro, and compass -sensorEvents: [8003, true] +sensorEvents: [8003, true, 100., 100] # GPS data, also global timestamp -gpsNMEA: [8004, true] +gpsNMEA: [8004, true, 9.] # 9 msgs each sec # CPU+MEM+GPU+BAT temps -thermal: [8005, true] +thermal: [8005, true, 2., 1] # List(CanData), list of can messages -can: [8006, true] -live100: [8007, true] - -# random events we want to log - -#liveEvent: [8008, true] -model: [8009, true] -features: [8010, true] -health: [8011, true] -live20: [8012, true] -#liveUI: [8014, true] -encodeIdx: [8015, true] -liveTracks: [8016, true] -sendcan: [8017, true] -logMessage: [8018, true] -liveCalibration: [8019, true] -androidLog: [8020, true] -carState: [8021, true] +can: [8006, true, 100.] +controlsState: [8007, true, 100., 100] +#liveEvent: [8008, true, 0.] +model: [8009, true, 20., 5] +features: [8010, true, 0.] +health: [8011, true, 2., 1] +radarState: [8012, true, 20.] +#liveUI: [8014, true, 0.] +encodeIdx: [8015, true, 20.] +liveTracks: [8016, true, 20.] +sendcan: [8017, true, 100.] +logMessage: [8018, true, 0.] +liveCalibration: [8019, true, 5.] +androidLog: [8020, true, 0.] +carState: [8021, true, 100., 10] # 8022 is reserved for sshd -carControl: [8023, true] -plan: [8024, true] -liveLocation: [8025, true] -gpsLocation: [8026, true] -ethernetData: [8027, true] -navUpdate: [8028, true] -qcomGnss: [8029, true] -lidarPts: [8030, true] -procLog: [8031, true] -gpsLocationExternal: [8032, true] -ubloxGnss: [8033, true] -clocks: [8034, true] -liveMpc: [8035, true] -liveLongitudinalMpc: [8036, true] -plusFrame: [8037, false] -navStatus: [8038, true] -gpsLocationTrimble: [8039, true] -trimbleGnss: [8041, true] -ubloxRaw: [8042, true] -gpsPlannerPoints: [8043, true] -gpsPlannerPlan: [8044, true] -applanixRaw: [8046, true] -orbLocation: [8047, true] -trafficEvents: [8048, true] -liveLocationTiming: [8049, true] -orbslamCorrection: [8050, true] -liveLocationCorrected: [8051, true] -orbObservation: [8052, true] -applanixLocation: [8053, true] -liveLocationKalman: [8054, true] -uiNavigationEvent: [8055, true] -orbOdometry: [8057, true] -orbFeatures: [8058, false] -orbKeyFrame: [8059, true] -uiLayoutState: [8060, true] -frontEncodeIdx: [8061, true] -orbFeaturesSummary: [8062, true] -driverMonitoring: [8063, true] -liveParameters: [8064, true] -liveMapData: [8065, true] -cameraOdometry: [8066, true] -pathPlan: [8067, true] -kalmanOdometry: [8068, true] - -testModel: [8040, false] -testLiveLocation: [8045, false] -testJoystick: [8056, false] +carControl: [8023, true, 100., 10] +plan: [8024, true, 20.] +liveLocation: [8025, true, 0.] +gpsLocation: [8026, true, 1., 1] +ethernetData: [8027, true, 0.] +navUpdate: [8028, true, 0.] +qcomGnss: [8029, true, 0.] +lidarPts: [8030, true, 0.] +procLog: [8031, true, 0.5] +gpsLocationExternal: [8032, true, 10., 1] +ubloxGnss: [8033, true, 10.] +clocks: [8034, true, 1., 1] +liveMpc: [8035, false, 20.] +liveLongitudinalMpc: [8036, false, 20.] +plusFrame: [8037, false, 0.] +navStatus: [8038, true, 0.] +gpsLocationTrimble: [8039, true, 0.] +trimbleGnss: [8041, true, 0.] +ubloxRaw: [8042, true, 20.] +gpsPlannerPoints: [8043, true, 0.] +gpsPlannerPlan: [8044, true, 0.] +applanixRaw: [8046, true, 0.] +orbLocation: [8047, true, 0.] +trafficEvents: [8048, true, 0.] +liveLocationTiming: [8049, true, 0.] +orbslamCorrection: [8050, true, 0.] +liveLocationCorrected: [8051, true, 0.] +orbObservation: [8052, true, 0.] +applanixLocation: [8053, true, 0.] +liveLocationKalman: [8054, true, 0.] +uiNavigationEvent: [8055, true, 0.] +orbOdometry: [8057, true, 0.] +orbFeatures: [8058, false, 0.] +orbKeyFrame: [8059, true, 0.] +uiLayoutState: [8060, true, 0.] +frontEncodeIdx: [8061, true, 5.] +orbFeaturesSummary: [8062, true, 0.] +driverMonitoring: [8063, true, 5., 1] +liveParameters: [8064, true, 10.] +liveMapData: [8065, true, 0.] +cameraOdometry: [8066, true, 5.] +pathPlan: [8067, true, 20.] +kalmanOdometry: [8068, true, 0.] +thumbnail: [8069, true, 0.2, 1] +carEvents: [8070, true, 1., 1] +carParams: [8071, true, 0.02, 1] + +testModel: [8040, false, 0.] +testLiveLocation: [8045, false, 0.] +testJoystick: [8056, false, 0.] # 8080 is reserved for slave testing daemon # 8762 is reserved for logserver # manager -- base process to manage starting and stopping of all others -# subscribes: health -# publishes: thermal +# subscribes: thermal # **** processes that communicate with the outside world **** +# thermald -- decides when to start and stop onroad +# subscribes: health, location +# publishes: thermal + # boardd -- communicates with the car # subscribes: sendcan -# publishes: can, health, ubloxRaw +# publishes: can, health, ubloxRaw + +# sensord -- publishes IMU and Magnetometer +# publishes: sensorEvents -# sensord -- publishes the IMU and GPS -# publishes: sensorEvents, gpsNMEA +# gpsd -- publishes EON's gps +# publishes: gpsNMEA # visiond -- talks to the cameras, runs the model, saves the videos -# subscribes: liveCalibration, sensorEvents, live100 -# publishes: frame, encodeIdx, model, liveCalibration +# publishes: frame, model, driverMonitoring, cameraOdometry, thumbnail # **** stateful data transformers **** # plannerd -- decides where to drive the car -# subscribes: carState, model, live20 -# publishes: plan +# subscribes: carState, model, radarState, controlsState, liveParameters +# publishes: plan, pathPlan, liveMpc, liveLongitudinalMpc + +# controlsd -- drives the car by sending CAN messages to panda +# subscribes: can, thermal, health, plan, pathPlan, driverMonitoring, liveCalibration +# publishes: carState, carControl, sendcan, controlsState, carEvents, carParams + +# radard -- processes the radar and vision data +# subscribes: can, controlsState, model, liveParameters +# publishes: radarState, liveTracks -# controlsd -- actually drives the car -# subscribes: can, thermal, plan -# publishes: carState, carControl, sendcan, live100 +# params_learner -- learns vehicle params by observing the vehicle dynamics +# subscribes: controlsState, sensorEvents, cameraOdometry +# publishes: liveParameters -# radard -- processes the radar data -# blocks: CarParams -# subscribes: can, live100, model -# publishes: live20, liveTracks +# calibrationd -- reads posenet and applies a temporal filter on the frame region to look at +# subscribes: cameraOdometry +# publishes: liveCalibration + +# ubloxd -- read raw ublox data and converts them in readable format +# subscribes: ubloxRaw +# publishes: ubloxGnss # **** LOGGING SERVICE **** @@ -123,11 +139,14 @@ testJoystick: [8056, false] # **** NON VITAL SERVICES **** # ui -# subscribes: live100, live20, liveCalibration, model, (raw frames) +# subscribes: thermal, model, controlsState, uiLayout, liveCalibration, radarState, liveMpc, plusFrame, liveMapData # uploader # communicates through file system with loggerd +# deleter +# communicates through file system with loggerd and uploader + # logmessaged -- central logging service, can log to cloud # publishes: logMessage @@ -138,3 +157,7 @@ testJoystick: [8056, false] # publishes: procLog # tombstoned -- reports native crashes + +# athenad -- on request, open a sub socket and return the value + +# updated -- waits for network access and tries to update every hour diff --git a/selfdrive/services.py b/selfdrive/services.py index bd804afe7926bb..24a96c4eb2e4e1 100644 --- a/selfdrive/services.py +++ b/selfdrive/services.py @@ -1,14 +1,20 @@ import os import yaml -class Service(object): - def __init__(self, port, should_log): +class Service(): + def __init__(self, port, should_log, frequency, decimation=None): self.port = port self.should_log = should_log + self.frequency = frequency + self.decimation = decimation service_list_path = os.path.join(os.path.dirname(__file__), "service_list.yaml") service_list = {} with open(service_list_path, "r") as f: - for k, v in yaml.load(f).items(): - service_list[k] = Service(v[0], v[1]) + for k, v in yaml.safe_load(f).items(): + decimation = None + if len(v) == 4: + decimation = v[3] + + service_list[k] = Service(v[0], v[1], v[2], decimation) diff --git a/selfdrive/swaglog.py b/selfdrive/swaglog.py index 012bb9380616fb..90962cb5d84933 100644 --- a/selfdrive/swaglog.py +++ b/selfdrive/swaglog.py @@ -14,6 +14,7 @@ def __init__(self, formatter): def connect(self): self.zctx = zmq.Context() self.sock = self.zctx.socket(zmq.PUSH) + self.sock.setsockopt(zmq.LINGER, 10) self.sock.connect("ipc:///tmp/logmessage") self.pid = os.getpid() @@ -22,9 +23,10 @@ def emit(self, record): self.connect() msg = self.format(record).rstrip('\n') - # print "SEND", repr(msg) + # print("SEND".format(repr(msg))) try: - self.sock.send(chr(record.levelno)+msg, zmq.NOBLOCK) + s = chr(record.levelno)+msg + self.sock.send(s.encode('utf8'), zmq.NOBLOCK) except zmq.error.Again: # drop :/ pass diff --git a/selfdrive/test/plant/__init__.py b/selfdrive/test/longitudinal_maneuvers/__init__.py similarity index 100% rename from selfdrive/test/plant/__init__.py rename to selfdrive/test/longitudinal_maneuvers/__init__.py diff --git a/selfdrive/test/longitudinal_maneuvers/maneuver.py b/selfdrive/test/longitudinal_maneuvers/maneuver.py new file mode 100644 index 00000000000000..e79cf61d26a65a --- /dev/null +++ b/selfdrive/test/longitudinal_maneuvers/maneuver.py @@ -0,0 +1,86 @@ +from collections import defaultdict +from selfdrive.test.longitudinal_maneuvers.maneuverplots import ManeuverPlot +from selfdrive.test.longitudinal_maneuvers.plant import Plant +import numpy as np + + +class Maneuver(): + def __init__(self, title, duration, **kwargs): + # Was tempted to make a builder class + self.distance_lead = kwargs.get("initial_distance_lead", 200.0) + self.speed = kwargs.get("initial_speed", 0.0) + self.lead_relevancy = kwargs.get("lead_relevancy", 0) + + self.grade_values = kwargs.get("grade_values", [0.0, 0.0]) + self.grade_breakpoints = kwargs.get("grade_breakpoints", [0.0, duration]) + self.speed_lead_values = kwargs.get("speed_lead_values", [0.0, 0.0]) + self.speed_lead_breakpoints = kwargs.get("speed_lead_breakpoints", [0.0, duration]) + + self.cruise_button_presses = kwargs.get("cruise_button_presses", []) + self.checks = kwargs.get("checks", []) + + self.duration = duration + self.title = title + + def evaluate(self): + """runs the plant sim and returns (score, run_data)""" + plant = Plant( + lead_relevancy = self.lead_relevancy, + speed = self.speed, + distance_lead = self.distance_lead + ) + + logs = defaultdict(list) + last_controls_state = None + plot = ManeuverPlot(self.title) + + buttons_sorted = sorted(self.cruise_button_presses, key=lambda a: a[1]) + current_button = 0 + while plant.current_time() < self.duration: + while buttons_sorted and plant.current_time() >= buttons_sorted[0][1]: + current_button = buttons_sorted[0][0] + buttons_sorted = buttons_sorted[1:] + print("current button changed to {0}".format(current_button)) + + grade = np.interp(plant.current_time(), self.grade_breakpoints, self.grade_values) + speed_lead = np.interp(plant.current_time(), self.speed_lead_breakpoints, self.speed_lead_values) + + # distance, speed, acceleration, distance_lead, brake, gas, steer_torque, fcw, controls_state= plant.step(speed_lead, current_button, grade) + log = plant.step(speed_lead, current_button, grade) + + if log['controls_state_msgs']: + last_controls_state = log['controls_state_msgs'][-1] + + d_rel = log['distance_lead'] - log['distance'] if self.lead_relevancy else 200. + v_rel = speed_lead - log['speed'] if self.lead_relevancy else 0. + log['d_rel'] = d_rel + log['v_rel'] = v_rel + + if last_controls_state: + # print(last_controls_state) + #develop plots + plot.add_data( + time=plant.current_time(), + gas=log['gas'], brake=log['brake'], steer_torque=log['steer_torque'], + distance=log['distance'], speed=log['speed'], acceleration=log['acceleration'], + up_accel_cmd=last_controls_state.upAccelCmd, ui_accel_cmd=last_controls_state.uiAccelCmd, + uf_accel_cmd=last_controls_state.ufAccelCmd, + d_rel=d_rel, v_rel=v_rel, v_lead=speed_lead, + v_target_lead=last_controls_state.vTargetLead, pid_speed=last_controls_state.vPid, + cruise_speed=last_controls_state.vCruise, + jerk_factor=last_controls_state.jerkFactor, + a_target=last_controls_state.aTarget, + fcw=log['fcw']) + + for k, v in log.items(): + logs[k].append(v) + + valid = True + for check in self.checks: + c = check(logs) + if not c: + print(check.__name__ + " not valid!") + valid = valid and c + + print("maneuver end", valid) + return (plot, valid) diff --git a/selfdrive/test/plant/maneuverplots.py b/selfdrive/test/longitudinal_maneuvers/maneuverplots.py similarity index 99% rename from selfdrive/test/plant/maneuverplots.py rename to selfdrive/test/longitudinal_maneuvers/maneuverplots.py index 36b3e5bf8372e0..3d52588100ffb7 100644 --- a/selfdrive/test/plant/maneuverplots.py +++ b/selfdrive/test/longitudinal_maneuvers/maneuverplots.py @@ -6,7 +6,7 @@ from selfdrive.config import Conversions as CV -class ManeuverPlot(object): +class ManeuverPlot(): def __init__(self, title = None): self.time_array = [] diff --git a/selfdrive/test/longitudinal_maneuvers/plant.py b/selfdrive/test/longitudinal_maneuvers/plant.py new file mode 100755 index 00000000000000..b81f5ea0e19953 --- /dev/null +++ b/selfdrive/test/longitudinal_maneuvers/plant.py @@ -0,0 +1,452 @@ +#!/usr/bin/env python3 +import binascii +import os +import struct +import time +from collections import namedtuple +import numpy as np + +from opendbc import DBC_PATH + +from common.realtime import Ratekeeper +from selfdrive.config import Conversions as CV +import selfdrive.messaging as messaging +from selfdrive.car import crc8_pedal +from selfdrive.car.honda.hondacan import fix +from selfdrive.car.honda.values import CAR +from selfdrive.car.honda.carstate import get_can_signals +from selfdrive.boardd.boardd import can_capnp_to_can_list, can_list_to_can_capnp + +from selfdrive.can.plant_can_parser import CANParser +from selfdrive.car.honda.interface import CarInterface + +from common.dbc import dbc +honda = dbc(os.path.join(DBC_PATH, "honda_civic_touring_2016_can_generated.dbc")) + +# Trick: set 0x201 (interceptor) in fingerprints for gas is controlled like if there was an interceptor +CP = CarInterface.get_params(CAR.CIVIC, {0: {0x201: 6}, 1: {}, 2: {}, 3: {}}) + + +def car_plant(pos, speed, grade, gas, brake): + # vehicle parameters + mass = 1700 + aero_cd = 0.3 + force_peak = mass*3. + force_brake_peak = -mass*10. #1g + power_peak = 100000 # 100kW + speed_base = power_peak/force_peak + rolling_res = 0.01 + g = 9.81 + frontal_area = 2.2 + air_density = 1.225 + gas_to_peak_linear_slope = 3.33 + brake_to_peak_linear_slope = 0.3 + creep_accel_v = [1., 0.] + creep_accel_bp = [0., 1.5] + + #*** longitudinal model *** + # find speed where peak torque meets peak power + force_brake = brake * force_brake_peak * brake_to_peak_linear_slope + if speed < speed_base: # torque control + force_gas = gas * force_peak * gas_to_peak_linear_slope + else: # power control + force_gas = gas * power_peak / speed * gas_to_peak_linear_slope + + force_grade = - grade * mass # positive grade means uphill + + creep_accel = np.interp(speed, creep_accel_bp, creep_accel_v) + force_creep = creep_accel * mass + + force_resistance = -(rolling_res * mass * g + 0.5 * speed**2 * aero_cd * air_density * frontal_area) + force = force_gas + force_brake + force_resistance + force_grade + force_creep + acceleration = force / mass + + # TODO: lateral model + return speed, acceleration + +def get_car_can_parser(): + dbc_f = 'honda_civic_touring_2016_can_generated.dbc' + signals = [ + ("STEER_TORQUE", 0xe4, 0), + ("STEER_TORQUE_REQUEST", 0xe4, 0), + ("COMPUTER_BRAKE", 0x1fa, 0), + ("COMPUTER_BRAKE_REQUEST", 0x1fa, 0), + ("GAS_COMMAND", 0x200, 0), + ] + checks = [ + (0xe4, 100), + (0x1fa, 50), + (0x200, 50), + ] + return CANParser(dbc_f, signals, checks) + +def to_3_byte(x): + # Convert into 12 bit value + s = struct.pack("!H", int(x)) + return binascii.hexlify(s)[1:] + +def to_3s_byte(x): + s = struct.pack("!h", int(x)) + return binascii.hexlify(s)[1:] + +class Plant(): + messaging_initialized = False + + def __init__(self, lead_relevancy=False, rate=100, speed=0.0, distance_lead=2.0): + self.rate = rate + + if not Plant.messaging_initialized: + Plant.logcan = messaging.pub_sock('can') + Plant.sendcan = messaging.sub_sock('sendcan') + Plant.model = messaging.pub_sock('model') + Plant.live_params = messaging.pub_sock('liveParameters') + Plant.health = messaging.pub_sock('health') + Plant.thermal = messaging.pub_sock('thermal') + Plant.driverMonitoring = messaging.pub_sock('driverMonitoring') + Plant.cal = messaging.pub_sock('liveCalibration') + Plant.controls_state = messaging.sub_sock('controlsState') + Plant.plan = messaging.sub_sock('plan') + Plant.messaging_initialized = True + + self.frame = 0 + self.angle_steer = 0. + self.gear_choice = 0 + self.speed, self.speed_prev = 0., 0. + + self.esp_disabled = 0 + self.main_on = 1 + self.user_gas = 0 + self.computer_brake,self.user_brake = 0,0 + self.brake_pressed = 0 + self.angle_steer_rate = 0 + self.distance, self.distance_prev = 0., 0. + self.speed, self.speed_prev = speed, speed + self.steer_error, self.brake_error, self.steer_not_allowed = 0, 0, 0 + self.gear_shifter = 8 # D gear + self.pedal_gas = 0 + self.cruise_setting = 0 + + self.seatbelt, self.door_all_closed = True, True + self.steer_torque, self.v_cruise, self.acc_status = 0, 0, 0 # v_cruise is reported from can, not the one used for controls + + self.lead_relevancy = lead_relevancy + + # lead car + self.distance_lead, self.distance_lead_prev = distance_lead , distance_lead + + self.rk = Ratekeeper(rate, print_delay_threshold=100) + self.ts = 1./rate + + self.cp = get_car_can_parser() + self.response_seen = False + + time.sleep(1) + messaging.drain_sock(Plant.sendcan) + messaging.drain_sock(Plant.controls_state) + + def close(self): + Plant.logcan.close() + Plant.model.close() + Plant.live_params.close() + + def speed_sensor(self, speed): + if speed<0.3: + return 0 + else: + return speed * CV.MS_TO_KPH + + def current_time(self): + return float(self.rk.frame) / self.rate + + def step(self, v_lead=0.0, cruise_buttons=None, grade=0.0, publish_model = True): + gen_signals, gen_checks = get_can_signals(CP) + sgs = [s[0] for s in gen_signals] + msgs = [s[1] for s in gen_signals] + cks_msgs = set(check[0] for check in gen_checks) + cks_msgs.add(0x18F) + cks_msgs.add(0x30C) + + # ******** get messages sent to the car ******** + can_msgs = [] + for a in messaging.drain_sock(Plant.sendcan, wait_for_one=self.response_seen): + can_msgs.extend(can_capnp_to_can_list(a.sendcan, [0,2])) + + # After the first response the car is done fingerprinting, so we can run in lockstep with controlsd + if can_msgs: + self.response_seen = True + + self.cp.update_can(can_msgs) + + # ******** get controlsState messages for plotting *** + controls_state_msgs = [] + for a in messaging.drain_sock(Plant.controls_state, wait_for_one=self.response_seen): + controls_state_msgs.append(a.controlsState) + + fcw = None + for a in messaging.drain_sock(Plant.plan): + if a.plan.fcw: + fcw = True + + if self.cp.vl[0x1fa]['COMPUTER_BRAKE_REQUEST']: + brake = self.cp.vl[0x1fa]['COMPUTER_BRAKE'] * 0.003906248 + else: + brake = 0.0 + + if self.cp.vl[0x200]['GAS_COMMAND'] > 0: + gas = self.cp.vl[0x200]['GAS_COMMAND'] / 256.0 + else: + gas = 0.0 + + if self.cp.vl[0xe4]['STEER_TORQUE_REQUEST']: + steer_torque = self.cp.vl[0xe4]['STEER_TORQUE']*1.0/0xf00 + else: + steer_torque = 0.0 + + distance_lead = self.distance_lead_prev + v_lead * self.ts + + # ******** run the car ******** + speed, acceleration = car_plant(self.distance_prev, self.speed_prev, grade, gas, brake) + distance = self.distance_prev + speed * self.ts + speed = self.speed_prev + self.ts * acceleration + if speed <= 0: + speed = 0 + acceleration = 0 + + # ******** lateral ******** + self.angle_steer -= (steer_torque/10.0) * self.ts + + # *** radar model *** + if self.lead_relevancy: + d_rel = np.maximum(0., distance_lead - distance) + v_rel = v_lead - speed + else: + d_rel = 200. + v_rel = 0. + lateral_pos_rel = 0. + + # print at 5hz + if (self.frame % (self.rate//5)) == 0: + print("%6.2f m %6.2f m/s %6.2f m/s2 %.2f ang gas: %.2f brake: %.2f steer: %5.2f lead_rel: %6.2f m %6.2f m/s" % (distance, speed, acceleration, self.angle_steer, gas, brake, steer_torque, d_rel, v_rel)) + + # ******** publish the car ******** + vls_tuple = namedtuple('vls', [ + 'XMISSION_SPEED', + 'WHEEL_SPEED_FL', 'WHEEL_SPEED_FR', 'WHEEL_SPEED_RL', 'WHEEL_SPEED_RR', + 'STEER_ANGLE', 'STEER_ANGLE_RATE', 'STEER_TORQUE_SENSOR', 'STEER_TORQUE_MOTOR', + 'LEFT_BLINKER', 'RIGHT_BLINKER', + 'GEAR', + 'WHEELS_MOVING', + 'BRAKE_ERROR_1', 'BRAKE_ERROR_2', + 'SEATBELT_DRIVER_LAMP', 'SEATBELT_DRIVER_LATCHED', + 'BRAKE_PRESSED', 'BRAKE_SWITCH', + 'CRUISE_BUTTONS', + 'ESP_DISABLED', + 'HUD_LEAD', + 'USER_BRAKE', + 'STEER_STATUS', + 'GEAR_SHIFTER', + 'PEDAL_GAS', + 'CRUISE_SETTING', + 'ACC_STATUS', + + 'CRUISE_SPEED_PCM', + 'CRUISE_SPEED_OFFSET', + + 'DOOR_OPEN_FL', 'DOOR_OPEN_FR', 'DOOR_OPEN_RL', 'DOOR_OPEN_RR', + + 'CAR_GAS', + 'MAIN_ON', + 'EPB_STATE', + 'BRAKE_HOLD_ACTIVE', + 'INTERCEPTOR_GAS', + 'INTERCEPTOR_GAS2', + 'IMPERIAL_UNIT', + ]) + vls = vls_tuple( + self.speed_sensor(speed), + self.speed_sensor(speed), self.speed_sensor(speed), self.speed_sensor(speed), self.speed_sensor(speed), + self.angle_steer, self.angle_steer_rate, 0, 0,#Steer torque sensor + 0, 0, # Blinkers + self.gear_choice, + speed != 0, + self.brake_error, self.brake_error, + not self.seatbelt, self.seatbelt, # Seatbelt + self.brake_pressed, 0., #Brake pressed, Brake switch + cruise_buttons, + self.esp_disabled, + 0, # HUD lead + self.user_brake, + self.steer_error, + self.gear_shifter, + self.pedal_gas, + self.cruise_setting, + self.acc_status, + + self.v_cruise, + 0, # Cruise speed offset + + 0, 0, 0, 0, # Doors + + self.user_gas, + self.main_on, + 0, # EPB State + 0, # Brake hold + 0, # Interceptor feedback + 0, # Interceptor 2 feedback + False + ) + + # TODO: publish each message at proper frequency + can_msgs = [] + for msg in set(msgs): + msg_struct = {} + indxs = [i for i, x in enumerate(msgs) if msg == msgs[i]] + for i in indxs: + msg_struct[sgs[i]] = getattr(vls, sgs[i]) + + if "COUNTER" in honda.get_signals(msg): + msg_struct["COUNTER"] = self.frame % 4 + + if "COUNTER_PEDAL" in honda.get_signals(msg): + msg_struct["COUNTER_PEDAL"] = self.frame % 0xf + + msg = honda.lookup_msg_id(msg) + msg_data = honda.encode(msg, msg_struct) + + if "CHECKSUM" in honda.get_signals(msg): + msg_data = fix(msg_data, msg) + + if "CHECKSUM_PEDAL" in honda.get_signals(msg): + msg_struct["CHECKSUM_PEDAL"] = crc8_pedal(msg_data[:-1]) + msg_data = honda.encode(msg, msg_struct) + + can_msgs.append([msg, 0, msg_data, 0]) + + # add the radar message + # TODO: use the DBC + if self.frame % 5 == 0: + radar_state_msg = b'\x79\x00\x00\x00\x00\x00\x00\x00' + radar_msg = to_3_byte(d_rel*16.0) + \ + to_3_byte(int(lateral_pos_rel*16.0)&0x3ff) + \ + to_3s_byte(int(v_rel*32.0)) + \ + b"0f00000" + + radar_msg = binascii.unhexlify(radar_msg) + can_msgs.append([0x400, 0, radar_state_msg, 1]) + can_msgs.append([0x445, 0, radar_msg, 1]) + + # add camera msg so controlsd thinks it's alive + msg_struct["COUNTER"] = self.frame % 4 + msg = honda.lookup_msg_id(0xe4) + msg_data = honda.encode(msg, msg_struct) + msg_data = fix(msg_data, 0xe4) + can_msgs.append([0xe4, 0, msg_data, 2]) + + + # Fake sockets that controlsd subscribes to + live_parameters = messaging.new_message() + live_parameters.init('liveParameters') + live_parameters.liveParameters.valid = True + live_parameters.liveParameters.sensorValid = True + live_parameters.liveParameters.posenetValid = True + live_parameters.liveParameters.steerRatio = CP.steerRatio + live_parameters.liveParameters.stiffnessFactor = 1.0 + Plant.live_params.send(live_parameters.to_bytes()) + + driver_monitoring = messaging.new_message() + driver_monitoring.init('driverMonitoring') + driver_monitoring.driverMonitoring.faceOrientation = [0.] * 3 + driver_monitoring.driverMonitoring.facePosition = [0.] * 2 + Plant.driverMonitoring.send(driver_monitoring.to_bytes()) + + health = messaging.new_message() + health.init('health') + health.health.controlsAllowed = True + Plant.health.send(health.to_bytes()) + + thermal = messaging.new_message() + thermal.init('thermal') + thermal.thermal.freeSpace = 1. + thermal.thermal.batteryPercent = 100 + Plant.thermal.send(thermal.to_bytes()) + + # ******** publish a fake model going straight and fake calibration ******** + # note that this is worst case for MPC, since model will delay long mpc by one time step + if publish_model and self.frame % 5 == 0: + md = messaging.new_message() + cal = messaging.new_message() + md.init('model') + cal.init('liveCalibration') + md.model.frameId = 0 + for x in [md.model.path, md.model.leftLane, md.model.rightLane]: + x.points = [0.0]*50 + x.prob = 1.0 + x.std = 1.0 + + if self.lead_relevancy: + d_rel = np.maximum(0., distance_lead - distance) + v_rel = v_lead - speed + prob = 1.0 + else: + d_rel = 200. + v_rel = 0. + prob = 0.0 + + md.model.lead.dist = float(d_rel) + md.model.lead.prob = prob + md.model.lead.relY = 0.0 + md.model.lead.relYStd = 1. + md.model.lead.relVel = float(v_rel) + md.model.lead.relVelStd = 1. + md.model.lead.relA = 0.0 + md.model.lead.relAStd = 10. + md.model.lead.std = 1.0 + + cal.liveCalibration.calStatus = 1 + cal.liveCalibration.calPerc = 100 + cal.liveCalibration.rpyCalib = [0.] * 3 + # fake values? + Plant.model.send(md.to_bytes()) + Plant.cal.send(cal.to_bytes()) + + Plant.logcan.send(can_list_to_can_capnp(can_msgs)) + + # ******** update prevs ******** + self.frame += 1 + + if self.response_seen: + self.rk.monitor_time() + + self.speed = speed + self.distance = distance + self.distance_lead = distance_lead + + self.speed_prev = speed + self.distance_prev = distance + self.distance_lead_prev = distance_lead + + else: + # Don't advance time when controlsd is not yet ready + self.rk.keep_time() + self.rk._frame = 0 + + return { + "distance": distance, + "speed": speed, + "acceleration": acceleration, + "distance_lead": distance_lead, + "brake": brake, + "gas": gas, + "steer_torque": steer_torque, + "fcw": fcw, + "controls_state_msgs": controls_state_msgs, + } + +# simple engage in standalone mode +def plant_thread(rate=100): + plant = Plant(rate) + while 1: + plant.step() + +if __name__ == "__main__": + plant_thread() diff --git a/selfdrive/test/plant/plant_ui.py b/selfdrive/test/longitudinal_maneuvers/plant_ui.py similarity index 90% rename from selfdrive/test/plant/plant_ui.py rename to selfdrive/test/longitudinal_maneuvers/plant_ui.py index d7b4bf1856fdc9..e9dd18f37276f7 100755 --- a/selfdrive/test/plant/plant_ui.py +++ b/selfdrive/test/longitudinal_maneuvers/plant_ui.py @@ -1,6 +1,6 @@ -#!/usr/bin/env python -import pygame -from plant import Plant +#!/usr/bin/env python3 +import pygame # pylint: disable=import-error +from selfdrive.test.longitudinal_maneuvers.plant import Plant from selfdrive.car.honda.values import CruiseButtons import numpy as np import selfdrive.messaging as messaging @@ -41,7 +41,7 @@ def car_w_color(c): plant = Plant(100, distance_lead = 40.0) control_offset = 2.0 - control_pts = zip(np.arange(0, 100.0, 10.0), [50.0 + control_offset]*10) + control_pts = list(zip(np.arange(0, 100.0, 10.0), [50.0 + control_offset]*10)) def pt_to_car(pt): x,y = pt @@ -73,9 +73,9 @@ def pt_from_car(pt): x.prob = 0.0 x.std = 1.0 - car_pts = map(pt_to_car, control_pts) + car_pts = [pt_to_car(pt) for pt in control_pts] - print car_pts + print(car_pts) car_poly = np.polyfit([x[0] for x in car_pts], [x[1] for x in car_pts], 3) md.model.path.points = np.polyval(car_poly, np.arange(0, 50)).tolist() @@ -90,9 +90,9 @@ def pt_from_car(pt): cary += plant.speed * plant.ts * math.sin(heading) # positive steering angle = steering right - print plant.angle_steer + print(plant.angle_steer) heading += plant.angle_steer * plant.ts - print heading + print(heading) # draw my car display.blit(pygame.transform.rotate(car, 90-math.degrees(heading)), (carx*METER, cary*METER)) diff --git a/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py b/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py new file mode 100755 index 00000000000000..bfcbf67f7ba1c0 --- /dev/null +++ b/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py @@ -0,0 +1,376 @@ +#!/usr/bin/env python3 +import os +os.environ['OLD_CAN'] = '1' +os.environ['NOCRASH'] = '1' + +import time +import unittest +import shutil +import matplotlib +matplotlib.use('svg') + +from selfdrive.config import Conversions as CV +from selfdrive.car.honda.values import CruiseButtons as CB +from selfdrive.test.longitudinal_maneuvers.maneuver import Maneuver +import selfdrive.manager as manager +from common.params import Params + + +def create_dir(path): + try: + os.makedirs(path) + except OSError: + pass + + +def check_no_collision(log): + return min(log['d_rel']) > 0 + +def check_fcw(log): + return any(log['fcw']) + +def check_engaged(log): + return log['controls_state_msgs'][-1][-1].active + +maneuvers = [ + Maneuver( + 'while cruising at 40 mph, change cruise speed to 50mph', + duration=30., + initial_speed = 40. * CV.MPH_TO_MS, + cruise_button_presses = [(CB.DECEL_SET, 2.), (0, 2.3), + (CB.RES_ACCEL, 10.), (0, 10.1), + (CB.RES_ACCEL, 10.2), (0, 10.3)], + checks=[check_engaged], + ), + Maneuver( + 'while cruising at 60 mph, change cruise speed to 50mph', + duration=30., + initial_speed=60. * CV.MPH_TO_MS, + cruise_button_presses = [(CB.DECEL_SET, 2.), (0, 2.3), + (CB.DECEL_SET, 10.), (0, 10.1), + (CB.DECEL_SET, 10.2), (0, 10.3)], + checks=[check_engaged], + ), + Maneuver( + 'while cruising at 20mph, grade change +10%', + duration=25., + initial_speed=20. * CV.MPH_TO_MS, + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)], + grade_values = [0., 0., 1.0], + grade_breakpoints = [0., 10., 11.], + checks=[check_engaged], + ), + Maneuver( + 'while cruising at 20mph, grade change -10%', + duration=25., + initial_speed=20. * CV.MPH_TO_MS, + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)], + grade_values = [0., 0., -1.0], + grade_breakpoints = [0., 10., 11.], + checks=[check_engaged], + ), + Maneuver( + 'approaching a 40mph car while cruising at 60mph from 100m away', + duration=30., + initial_speed = 60. * CV.MPH_TO_MS, + lead_relevancy=True, + initial_distance_lead=100., + speed_lead_values = [40.*CV.MPH_TO_MS, 40.*CV.MPH_TO_MS], + speed_lead_breakpoints = [0., 100.], + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)], + checks=[check_engaged, check_no_collision], + ), + Maneuver( + 'approaching a 0mph car while cruising at 40mph from 150m away', + duration=30., + initial_speed = 40. * CV.MPH_TO_MS, + lead_relevancy=True, + initial_distance_lead=150., + speed_lead_values = [0.*CV.MPH_TO_MS, 0.*CV.MPH_TO_MS], + speed_lead_breakpoints = [0., 100.], + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)], + checks=[check_engaged, check_no_collision], + ), + Maneuver( + 'steady state following a car at 20m/s, then lead decel to 0mph at 1m/s^2', + duration=50., + initial_speed = 20., + lead_relevancy=True, + initial_distance_lead=35., + speed_lead_values = [20., 20., 0.], + speed_lead_breakpoints = [0., 15., 35.0], + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)], + checks=[check_engaged, check_no_collision], + ), + Maneuver( + 'steady state following a car at 20m/s, then lead decel to 0mph at 2m/s^2', + duration=50., + initial_speed = 20., + lead_relevancy=True, + initial_distance_lead=35., + speed_lead_values = [20., 20., 0.], + speed_lead_breakpoints = [0., 15., 25.0], + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)], + checks=[check_engaged, check_no_collision], + ), + Maneuver( + 'steady state following a car at 20m/s, then lead decel to 0mph at 3m/s^2', + duration=50., + initial_speed = 20., + lead_relevancy=True, + initial_distance_lead=35., + speed_lead_values = [20., 20., 0.], + speed_lead_breakpoints = [0., 15., 21.66], + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)], + checks=[check_engaged, check_fcw], + ), + Maneuver( + 'steady state following a car at 20m/s, then lead decel to 0mph at 5m/s^2', + duration=40., + initial_speed = 20., + lead_relevancy=True, + initial_distance_lead=35., + speed_lead_values = [20., 20., 0.], + speed_lead_breakpoints = [0., 15., 19.], + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)], + checks=[check_engaged, check_fcw], + ), + Maneuver( + 'starting at 0mph, approaching a stopped car 100m away', + duration=30., + initial_speed = 0., + lead_relevancy=True, + initial_distance_lead=100., + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7), + (CB.RES_ACCEL, 1.8), (0.0, 1.9)], + checks=[check_engaged, check_no_collision], + ), + Maneuver( + "following a car at 60mph, lead accel and decel at 0.5m/s^2 every 2s", + duration=25., + initial_speed=30., + lead_relevancy=True, + initial_distance_lead=49., + speed_lead_values=[30.,30.,29.,31.,29.,31.,29.], + speed_lead_breakpoints=[0., 6., 8., 12.,16.,20.,24.], + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7)], + checks=[check_engaged, check_no_collision], + ), + Maneuver( + "following a car at 10mph, stop and go at 1m/s2 lead dece1 and accel", + duration=70., + initial_speed=10., + lead_relevancy=True, + initial_distance_lead=20., + speed_lead_values=[10., 0., 0., 10., 0.,10.], + speed_lead_breakpoints=[10., 20., 30., 40., 50., 60.], + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7)], + checks=[check_engaged, check_no_collision], + ), + Maneuver( + "green light: stopped behind lead car, lead car accelerates at 1.5 m/s", + duration=30., + initial_speed=0., + lead_relevancy=True, + initial_distance_lead=4., + speed_lead_values=[0, 0 , 45], + speed_lead_breakpoints=[0, 10., 40.], + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7), + (CB.RES_ACCEL, 1.8), (0.0, 1.9), + (CB.RES_ACCEL, 2.0), (0.0, 2.1), + (CB.RES_ACCEL, 2.2), (0.0, 2.3)], + checks=[check_engaged, check_no_collision], + ), + Maneuver( + "stop and go with 1m/s2 lead decel and accel, with full stops", + duration=70., + initial_speed=0., + lead_relevancy=True, + initial_distance_lead=20., + speed_lead_values=[10., 0., 0., 10., 0., 0.] , + speed_lead_breakpoints=[10., 20., 30., 40., 50., 60.], + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7)], + checks=[check_engaged, check_no_collision], + ), + Maneuver( + "stop and go with 1.5m/s2 lead accel and 3.3m/s^2 lead decel, with full stops", + duration=45., + initial_speed=0., + lead_relevancy=True, + initial_distance_lead=20., + speed_lead_values=[10., 0., 0., 10., 0., 0.] , + speed_lead_breakpoints=[10., 13., 26., 33., 36., 45.], + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7)], + checks=[check_engaged, check_no_collision], + ), + Maneuver( + "accelerate from 20 while lead vehicle decelerates from 40 to 20 at 1m/s2", + duration=30., + initial_speed=10., + lead_relevancy=True, + initial_distance_lead=10., + speed_lead_values=[20., 10.], + speed_lead_breakpoints=[1., 11.], + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7), + (CB.RES_ACCEL, 1.8), (0.0, 1.9), + (CB.RES_ACCEL, 2.0), (0.0, 2.1), + (CB.RES_ACCEL, 2.2), (0.0, 2.3)], + checks=[check_engaged, check_no_collision], + ), + Maneuver( + "accelerate from 20 while lead vehicle decelerates from 40 to 0 at 2m/s2", + duration=30., + initial_speed=10., + lead_relevancy=True, + initial_distance_lead=10., + speed_lead_values=[20., 0.], + speed_lead_breakpoints=[1., 11.], + cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7), + (CB.RES_ACCEL, 1.8), (0.0, 1.9), + (CB.RES_ACCEL, 2.0), (0.0, 2.1), + (CB.RES_ACCEL, 2.2), (0.0, 2.3)], + checks=[check_engaged, check_no_collision], + ), + Maneuver( + "fcw: traveling at 30 m/s and approaching lead traveling at 20m/s", + duration=15., + initial_speed=30., + lead_relevancy=True, + initial_distance_lead=100., + speed_lead_values=[20.], + speed_lead_breakpoints=[1.], + cruise_button_presses = [], + checks=[check_fcw], + ), + Maneuver( + "fcw: traveling at 20 m/s following a lead that decels from 20m/s to 0 at 1m/s2", + duration=18., + initial_speed=20., + lead_relevancy=True, + initial_distance_lead=35., + speed_lead_values=[20., 0.], + speed_lead_breakpoints=[3., 23.], + cruise_button_presses = [], + checks=[check_fcw], + ), + Maneuver( + "fcw: traveling at 20 m/s following a lead that decels from 20m/s to 0 at 3m/s2", + duration=13., + initial_speed=20., + lead_relevancy=True, + initial_distance_lead=35., + speed_lead_values=[20., 0.], + speed_lead_breakpoints=[3., 9.6], + cruise_button_presses = [], + checks=[check_fcw], + ), + Maneuver( + "fcw: traveling at 20 m/s following a lead that decels from 20m/s to 0 at 5m/s2", + duration=8., + initial_speed=20., + lead_relevancy=True, + initial_distance_lead=35., + speed_lead_values=[20., 0.], + speed_lead_breakpoints=[3., 7.], + cruise_button_presses = [], + checks=[check_fcw], + ) +] + +# maneuvers = [maneuvers[-11]] +# maneuvers = [maneuvers[6]] + +def setup_output(): + output_dir = os.path.join(os.getcwd(), 'out/longitudinal') + if not os.path.exists(os.path.join(output_dir, "index.html")): + # write test output header + + css_style = """ + .maneuver_title { + font-size: 24px; + text-align: center; + } + .maneuver_graph { + width: 100%; + } + """ + + view_html = "" % (css_style,) + for i, man in enumerate(maneuvers): + view_html += "" % (man.title,) + for c in ['distance.svg', 'speeds.svg', 'acceleration.svg', 'pedals.svg', 'pid.svg']: + view_html += "" % (os.path.join("maneuver" + str(i+1).zfill(2), c), ) + view_html += "" + + create_dir(output_dir) + with open(os.path.join(output_dir, "index.html"), "w") as f: + f.write(view_html) + +class LongitudinalControl(unittest.TestCase): + @classmethod + def setUpClass(cls): + os.environ['NO_CAN_TIMEOUT'] = "1" + + setup_output() + + shutil.rmtree('/data/params', ignore_errors=True) + params = Params() + params.put("Passive", "1" if os.getenv("PASSIVE") else "0") + params.put("OpenpilotEnabledToggle", "1") + + manager.gctx = {} + manager.prepare_managed_process('radard') + manager.prepare_managed_process('controlsd') + manager.prepare_managed_process('plannerd') + + @classmethod + def tearDownClass(cls): + pass + + # hack + def test_longitudinal_setup(self): + pass + +def run_maneuver_worker(k): + man = maneuvers[k] + output_dir = os.path.join(os.getcwd(), 'out/longitudinal') + + def run(self): + print(man.title) + manager.start_managed_process('radard') + manager.start_managed_process('controlsd') + manager.start_managed_process('plannerd') + + plot, valid = man.evaluate() + plot.write_plot(output_dir, "maneuver" + str(k+1).zfill(2)) + + manager.kill_managed_process('radard') + manager.kill_managed_process('controlsd') + manager.kill_managed_process('plannerd') + time.sleep(5) + + self.assertTrue(valid) + + return run + +for k in range(len(maneuvers)): + setattr(LongitudinalControl, "test_longitudinal_maneuvers_%d" % (k+1), run_maneuver_worker(k)) + +if __name__ == "__main__": + unittest.main(failfast=True) diff --git a/selfdrive/test/openpilotci_upload.py b/selfdrive/test/openpilotci_upload.py new file mode 100755 index 00000000000000..e2ad2d41295ee6 --- /dev/null +++ b/selfdrive/test/openpilotci_upload.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +import os +import sys +import subprocess + + +def upload_file(path, name): + from azure.storage.blob import BlockBlobService # pylint: disable=no-name-in-module, import-error + sas_token = os.getenv("TOKEN", None) + if sas_token is None: + sas_token = subprocess.check_output("az storage container generate-sas --account-name commadataci --name openpilotci --https-only --permissions lrw --expiry $(date -u '+%Y-%m-%dT%H:%M:%SZ' -d '+1 hour') --auth-mode login --as-user --output tsv", shell=True).decode().strip("\n") + service = BlockBlobService(account_name="commadataci", sas_token=sas_token) + service.create_blob_from_path("openpilotci", name, path) + return "https://commadataci.blob.core.windows.net/openpilotci/" + name + +if __name__ == "__main__": + for f in sys.argv[1:]: + name = os.path.basename(f) + url = upload_file(f, name) + print(url) diff --git a/selfdrive/test/plant/maneuver.py b/selfdrive/test/plant/maneuver.py deleted file mode 100644 index 1564aac51deca6..00000000000000 --- a/selfdrive/test/plant/maneuver.py +++ /dev/null @@ -1,72 +0,0 @@ -from maneuverplots import ManeuverPlot -from plant import Plant -import numpy as np - - -class Maneuver(object): - def __init__(self, title, duration, **kwargs): - # Was tempted to make a builder class - self.distance_lead = kwargs.get("initial_distance_lead", 200.0) - self.speed = kwargs.get("initial_speed", 0.0) - self.lead_relevancy = kwargs.get("lead_relevancy", 0) - - self.grade_values = kwargs.get("grade_values", [0.0, 0.0]) - self.grade_breakpoints = kwargs.get("grade_breakpoints", [0.0, duration]) - self.speed_lead_values = kwargs.get("speed_lead_values", [0.0, 0.0]) - self.speed_lead_breakpoints = kwargs.get("speed_lead_breakpoints", [0.0, duration]) - - self.cruise_button_presses = kwargs.get("cruise_button_presses", []) - - self.duration = duration - self.title = title - - def evaluate(self): - """runs the plant sim and returns (score, run_data)""" - plant = Plant( - lead_relevancy = self.lead_relevancy, - speed = self.speed, - distance_lead = self.distance_lead - ) - - last_live100 = None - plot = ManeuverPlot(self.title) - - buttons_sorted = sorted(self.cruise_button_presses, key=lambda a: a[1]) - current_button = 0 - while plant.current_time() < self.duration: - while buttons_sorted and plant.current_time() >= buttons_sorted[0][1]: - current_button = buttons_sorted[0][0] - buttons_sorted = buttons_sorted[1:] - print "current button changed to", current_button - - grade = np.interp(plant.current_time(), self.grade_breakpoints, self.grade_values) - speed_lead = np.interp(plant.current_time(), self.speed_lead_breakpoints, self.speed_lead_values) - - distance, speed, acceleration, distance_lead, brake, gas, steer_torque, fcw, live100= plant.step(speed_lead, current_button, grade) - if live100: - last_live100 = live100[-1] - - d_rel = distance_lead - distance if self.lead_relevancy else 200. - v_rel = speed_lead - speed if self.lead_relevancy else 0. - - if last_live100: - # print last_live100 - #develop plots - plot.add_data( - time=plant.current_time(), - gas=gas, brake=brake, steer_torque=steer_torque, - distance=distance, speed=speed, acceleration=acceleration, - up_accel_cmd=last_live100.upAccelCmd, ui_accel_cmd=last_live100.uiAccelCmd, - uf_accel_cmd=last_live100.ufAccelCmd, - d_rel=d_rel, v_rel=v_rel, v_lead=speed_lead, - v_target_lead=last_live100.vTargetLead, pid_speed=last_live100.vPid, - cruise_speed=last_live100.vCruise, - jerk_factor=last_live100.jerkFactor, - a_target=last_live100.aTarget, - fcw=fcw) - - print "maneuver end" - - return (None, plot) - - diff --git a/selfdrive/test/plant/plant.py b/selfdrive/test/plant/plant.py deleted file mode 100755 index 903a7e4f73ec7a..00000000000000 --- a/selfdrive/test/plant/plant.py +++ /dev/null @@ -1,363 +0,0 @@ -#!/usr/bin/env python -import os -import struct -from collections import namedtuple -import zmq -import numpy as np - -from opendbc import DBC_PATH - -from common.realtime import Ratekeeper -from selfdrive.config import Conversions as CV -import selfdrive.messaging as messaging -from selfdrive.services import service_list -from selfdrive.car import crc8_pedal -from selfdrive.car.honda.hondacan import fix -from selfdrive.car.honda.values import CAR -from selfdrive.car.honda.carstate import get_can_signals -from selfdrive.boardd.boardd import can_capnp_to_can_list, can_list_to_can_capnp - -from selfdrive.can.plant_can_parser import CANParser -from selfdrive.car.honda.interface import CarInterface - -from common.dbc import dbc -honda = dbc(os.path.join(DBC_PATH, "honda_civic_touring_2016_can_generated.dbc")) - -# Trick: set 0x201 (interceptor) in fingerprints for gas is controlled like if there was an interceptor -CP = CarInterface.get_params(CAR.CIVIC, {0x201}) - - -def car_plant(pos, speed, grade, gas, brake): - # vehicle parameters - mass = 1700 - aero_cd = 0.3 - force_peak = mass*3. - force_brake_peak = -mass*10. #1g - power_peak = 100000 # 100kW - speed_base = power_peak/force_peak - rolling_res = 0.01 - g = 9.81 - frontal_area = 2.2 - air_density = 1.225 - gas_to_peak_linear_slope = 3.33 - brake_to_peak_linear_slope = 0.3 - creep_accel_v = [1., 0.] - creep_accel_bp = [0., 1.5] - - #*** longitudinal model *** - # find speed where peak torque meets peak power - force_brake = brake * force_brake_peak * brake_to_peak_linear_slope - if speed < speed_base: # torque control - force_gas = gas * force_peak * gas_to_peak_linear_slope - else: # power control - force_gas = gas * power_peak / speed * gas_to_peak_linear_slope - - force_grade = - grade * mass # positive grade means uphill - - creep_accel = np.interp(speed, creep_accel_bp, creep_accel_v) - force_creep = creep_accel * mass - - force_resistance = -(rolling_res * mass * g + 0.5 * speed**2 * aero_cd * air_density * frontal_area) - force = force_gas + force_brake + force_resistance + force_grade + force_creep - acceleration = force / mass - - # TODO: lateral model - return speed, acceleration - -def get_car_can_parser(): - dbc_f = 'honda_civic_touring_2016_can_generated.dbc' - signals = [ - ("STEER_TORQUE", 0xe4, 0), - ("STEER_TORQUE_REQUEST", 0xe4, 0), - ("COMPUTER_BRAKE", 0x1fa, 0), - ("COMPUTER_BRAKE_REQUEST", 0x1fa, 0), - ("GAS_COMMAND", 0x200, 0), - ] - checks = [ - (0xe4, 100), - (0x1fa, 50), - (0x200, 50), - ] - return CANParser(dbc_f, signals, checks) - -def to_3_byte(x): - return struct.pack("!H", int(x)).encode("hex")[1:] - -def to_3s_byte(x): - return struct.pack("!h", int(x)).encode("hex")[1:] - -class Plant(object): - messaging_initialized = False - - def __init__(self, lead_relevancy=False, rate=100, speed=0.0, distance_lead=2.0): - self.rate = rate - - if not Plant.messaging_initialized: - context = zmq.Context() - Plant.logcan = messaging.pub_sock(context, service_list['can'].port) - Plant.sendcan = messaging.sub_sock(context, service_list['sendcan'].port) - Plant.model = messaging.pub_sock(context, service_list['model'].port) - Plant.cal = messaging.pub_sock(context, service_list['liveCalibration'].port) - Plant.live100 = messaging.sub_sock(context, service_list['live100'].port) - Plant.plan = messaging.sub_sock(context, service_list['plan'].port) - Plant.messaging_initialized = True - - self.angle_steer = 0. - self.gear_choice = 0 - self.speed, self.speed_prev = 0., 0. - - self.esp_disabled = 0 - self.main_on = 1 - self.user_gas = 0 - self.computer_brake,self.user_brake = 0,0 - self.brake_pressed = 0 - self.angle_steer_rate = 0 - self.distance, self.distance_prev = 0., 0. - self.speed, self.speed_prev = speed, speed - self.steer_error, self.brake_error, self.steer_not_allowed = 0, 0, 0 - self.gear_shifter = 8 # D gear - self.pedal_gas = 0 - self.cruise_setting = 0 - - self.seatbelt, self.door_all_closed = True, True - self.steer_torque, self.v_cruise, self.acc_status = 0, 0, 0 # v_cruise is reported from can, not the one used for controls - - self.lead_relevancy = lead_relevancy - - # lead car - self.distance_lead, self.distance_lead_prev = distance_lead , distance_lead - - self.rk = Ratekeeper(rate, print_delay_threshold=100) - self.ts = 1./rate - - self.cp = get_car_can_parser() - - def close(self): - Plant.logcan.close() - Plant.model.close() - - def speed_sensor(self, speed): - if speed<0.3: - return 0 - else: - return speed * CV.MS_TO_KPH - - def current_time(self): - return float(self.rk.frame) / self.rate - - def step(self, v_lead=0.0, cruise_buttons=None, grade=0.0, publish_model = True): - gen_signals, gen_checks = get_can_signals(CP) - sgs = [s[0] for s in gen_signals] - msgs = [s[1] for s in gen_signals] - cks_msgs = set(check[0] for check in gen_checks) - cks_msgs.add(0x18F) - cks_msgs.add(0x30C) - - # ******** get messages sent to the car ******** - can_msgs = [] - for a in messaging.drain_sock(Plant.sendcan): - can_msgs.extend(can_capnp_to_can_list(a.sendcan, [0,2])) - self.cp.update_can(can_msgs) - - # ******** get live100 messages for plotting *** - live100_msgs = [] - for a in messaging.drain_sock(Plant.live100): - live100_msgs.append(a.live100) - - fcw = None - for a in messaging.drain_sock(Plant.plan): - if a.plan.fcw: - fcw = True - - if self.cp.vl[0x1fa]['COMPUTER_BRAKE_REQUEST']: - brake = self.cp.vl[0x1fa]['COMPUTER_BRAKE'] * 0.003906248 - else: - brake = 0.0 - - if self.cp.vl[0x200]['GAS_COMMAND'] > 0: - gas = self.cp.vl[0x200]['GAS_COMMAND'] / 256.0 - else: - gas = 0.0 - - if self.cp.vl[0xe4]['STEER_TORQUE_REQUEST']: - steer_torque = self.cp.vl[0xe4]['STEER_TORQUE']*1.0/0xf00 - else: - steer_torque = 0.0 - - distance_lead = self.distance_lead_prev + v_lead * self.ts - - # ******** run the car ******** - speed, acceleration = car_plant(self.distance_prev, self.speed_prev, grade, gas, brake) - distance = self.distance_prev + speed * self.ts - speed = self.speed_prev + self.ts * acceleration - if speed <= 0: - speed = 0 - acceleration = 0 - - # ******** lateral ******** - self.angle_steer -= (steer_torque/10.0) * self.ts - - # *** radar model *** - if self.lead_relevancy: - d_rel = np.maximum(0., distance_lead - distance) - v_rel = v_lead - speed - else: - d_rel = 200. - v_rel = 0. - lateral_pos_rel = 0. - - # print at 5hz - if (self.rk.frame%(self.rate/5)) == 0: - print "%6.2f m %6.2f m/s %6.2f m/s2 %.2f ang gas: %.2f brake: %.2f steer: %5.2f lead_rel: %6.2f m %6.2f m/s" % (distance, speed, acceleration, self.angle_steer, gas, brake, steer_torque, d_rel, v_rel) - - # ******** publish the car ******** - vls_tuple = namedtuple('vls', [ - 'XMISSION_SPEED', - 'WHEEL_SPEED_FL', 'WHEEL_SPEED_FR', 'WHEEL_SPEED_RL', 'WHEEL_SPEED_RR', - 'STEER_ANGLE', 'STEER_ANGLE_RATE', 'STEER_TORQUE_SENSOR', - 'LEFT_BLINKER', 'RIGHT_BLINKER', - 'GEAR', - 'WHEELS_MOVING', - 'BRAKE_ERROR_1', 'BRAKE_ERROR_2', - 'SEATBELT_DRIVER_LAMP', 'SEATBELT_DRIVER_LATCHED', - 'BRAKE_PRESSED', 'BRAKE_SWITCH', - 'CRUISE_BUTTONS', - 'ESP_DISABLED', - 'HUD_LEAD', - 'USER_BRAKE', - 'STEER_STATUS', - 'GEAR_SHIFTER', - 'PEDAL_GAS', - 'CRUISE_SETTING', - 'ACC_STATUS', - - 'CRUISE_SPEED_PCM', - 'CRUISE_SPEED_OFFSET', - - 'DOOR_OPEN_FL', 'DOOR_OPEN_FR', 'DOOR_OPEN_RL', 'DOOR_OPEN_RR', - - 'CAR_GAS', - 'MAIN_ON', - 'EPB_STATE', - 'BRAKE_HOLD_ACTIVE', - 'INTERCEPTOR_GAS', - ]) - vls = vls_tuple( - self.speed_sensor(speed), - self.speed_sensor(speed), self.speed_sensor(speed), self.speed_sensor(speed), self.speed_sensor(speed), - self.angle_steer, self.angle_steer_rate, 0, #Steer torque sensor - 0, 0, # Blinkers - self.gear_choice, - speed != 0, - self.brake_error, self.brake_error, - not self.seatbelt, self.seatbelt, # Seatbelt - self.brake_pressed, 0., #Brake pressed, Brake switch - cruise_buttons, - self.esp_disabled, - 0, # HUD lead - self.user_brake, - self.steer_error, - self.gear_shifter, - self.pedal_gas, - self.cruise_setting, - self.acc_status, - - self.v_cruise, - 0, # Cruise speed offset - - 0, 0, 0, 0, # Doors - - self.user_gas, - self.main_on, - 0, # EPB State - 0, # Brake hold - 0 # Interceptor feedback - ) - - # TODO: publish each message at proper frequency - can_msgs = [] - for msg in set(msgs): - msg_struct = {} - indxs = [i for i, x in enumerate(msgs) if msg == msgs[i]] - for i in indxs: - msg_struct[sgs[i]] = getattr(vls, sgs[i]) - - if "COUNTER" in honda.get_signals(msg): - msg_struct["COUNTER"] = self.rk.frame % 4 - - if "COUNTER_PEDAL" in honda.get_signals(msg): - msg_struct["COUNTER_PEDAL"] = self.rk.frame % 0xf - - msg = honda.lookup_msg_id(msg) - msg_data = honda.encode(msg, msg_struct) - - if "CHECKSUM" in honda.get_signals(msg): - msg_data = fix(msg_data, msg) - - if "CHECKSUM_PEDAL" in honda.get_signals(msg): - msg_struct["CHECKSUM_PEDAL"] = crc8_pedal([ord(i) for i in msg_data][:-1]) - msg_data = honda.encode(msg, msg_struct) - - can_msgs.append([msg, 0, msg_data, 0]) - - # add the radar message - # TODO: use the DBC - if self.rk.frame % 5 == 0: - radar_state_msg = '\x79\x00\x00\x00\x00\x00\x00\x00' - radar_msg = to_3_byte(d_rel*16.0) + \ - to_3_byte(int(lateral_pos_rel*16.0)&0x3ff) + \ - to_3s_byte(int(v_rel*32.0)) + \ - "0f00000" - can_msgs.append([0x400, 0, radar_state_msg, 1]) - can_msgs.append([0x445, 0, radar_msg.decode("hex"), 1]) - - # add camera msg so controlsd thinks it's alive - msg_struct["COUNTER"] = self.rk.frame % 4 - msg = honda.lookup_msg_id(0xe4) - msg_data = honda.encode(msg, msg_struct) - msg_data = fix(msg_data, 0xe4) - can_msgs.append([0xe4, 0, msg_data, 2]) - - Plant.logcan.send(can_list_to_can_capnp(can_msgs).to_bytes()) - - # ******** publish a fake model going straight and fake calibration ******** - # note that this is worst case for MPC, since model will delay long mpc by one time step - if publish_model and self.rk.frame % 5 == 0: - md = messaging.new_message() - cal = messaging.new_message() - md.init('model') - cal.init('liveCalibration') - md.model.frameId = 0 - for x in [md.model.path, md.model.leftLane, md.model.rightLane]: - x.points = [0.0]*50 - x.prob = 1.0 - x.std = 1.0 - md.model.lead.dist = float(d_rel) - md.model.lead.prob = 1. - md.model.lead.std = 0.1 - cal.liveCalibration.calStatus = 1 - cal.liveCalibration.calPerc = 100 - # fake values? - Plant.model.send(md.to_bytes()) - Plant.cal.send(cal.to_bytes()) - - # ******** update prevs ******** - self.speed = speed - self.distance = distance - self.distance_lead = distance_lead - - self.speed_prev = speed - self.distance_prev = distance - self.distance_lead_prev = distance_lead - - self.rk.keep_time() - return (distance, speed, acceleration, distance_lead, brake, gas, steer_torque, fcw, live100_msgs) - -# simple engage in standalone mode -def plant_thread(rate=100): - plant = Plant(rate) - while 1: - plant.step() - -if __name__ == "__main__": - plant_thread() diff --git a/selfdrive/test/process_replay/.gitignore b/selfdrive/test/process_replay/.gitignore new file mode 100644 index 00000000000000..6d339d54f69d21 --- /dev/null +++ b/selfdrive/test/process_replay/.gitignore @@ -0,0 +1,2 @@ +*.bz2 +diff.txt diff --git a/selfdrive/test/process_replay/README.md b/selfdrive/test/process_replay/README.md new file mode 100644 index 00000000000000..7e92717f9df7e7 --- /dev/null +++ b/selfdrive/test/process_replay/README.md @@ -0,0 +1,24 @@ +# process replay + +Process replay is a regression test designed to identify any changes in the output of a process. This test replays a segment through individual processes and compares the output to a known good replay. Each make is represented in the test with a segment. + +If the test fails, make sure that you didn't unintentionally change anything. If there are intentional changes, the reference logs will be updated. + +Use `test_processes.py` to run the test locally. + +Currently the following processes are tested: + +* controlsd +* radard +* plannerd +* calibrationd + +## Forks + +openpilot forks can use this test with their own reference logs + +To generate new logs: + +`./update-refs.py --no-upload` + +Then, check in the new logs using git-lfs. Make sure to also include the updated `ref_commit` file. diff --git a/selfdrive/test/tests/plant/__init__.py b/selfdrive/test/process_replay/__init__.py similarity index 100% rename from selfdrive/test/tests/plant/__init__.py rename to selfdrive/test/process_replay/__init__.py diff --git a/selfdrive/test/process_replay/compare_logs.py b/selfdrive/test/process_replay/compare_logs.py new file mode 100755 index 00000000000000..ca550cbea49bb7 --- /dev/null +++ b/selfdrive/test/process_replay/compare_logs.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +import bz2 +import os +import sys + +import dictdiffer +if "CI" in os.environ: + tqdm = lambda x: x +else: + from tqdm import tqdm + +from tools.lib.logreader import LogReader + +def save_log(dest, log_msgs): + dat = b"" + for msg in log_msgs: + dat += msg.as_builder().to_bytes() + dat = bz2.compress(dat) + + with open(dest, "wb") as f: + f.write(dat) + +def remove_ignored_fields(msg, ignore): + msg = msg.as_builder() + for key, val in ignore: + attr = msg + keys = key.split(".") + if msg.which() not in key and len(keys) > 1: + continue + + for k in keys[:-1]: + try: + attr = getattr(msg, k) + except: + break + else: + setattr(attr, keys[-1], val) + return msg.as_reader() + +def compare_logs(log1, log2, ignore=[]): + assert len(log1) == len(log2), "logs are not same length" + + ignore_fields = [k for k, v in ignore] + diff = [] + for msg1, msg2 in tqdm(zip(log1, log2)): + assert msg1.which() == msg2.which(), "msgs not aligned between logs" + + msg1_bytes = remove_ignored_fields(msg1, ignore).as_builder().to_bytes() + msg2_bytes = remove_ignored_fields(msg2, ignore).as_builder().to_bytes() + + if msg1_bytes != msg2_bytes: + msg1_dict = msg1.to_dict(verbose=True) + msg2_dict = msg2.to_dict(verbose=True) + dd = dictdiffer.diff(msg1_dict, msg2_dict, ignore=ignore_fields, tolerance=0) + diff.extend(dd) + return diff + +if __name__ == "__main__": + log1 = list(LogReader(sys.argv[1])) + log2 = list(LogReader(sys.argv[2])) + compare_logs(log1, log2, sys.argv[3:]) diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py new file mode 100755 index 00000000000000..718bab6dd60a63 --- /dev/null +++ b/selfdrive/test/process_replay/process_replay.py @@ -0,0 +1,286 @@ +#!/usr/bin/env python3 +import os +import threading +import importlib +import shutil + +if "CI" in os.environ: + tqdm = lambda x: x +else: + from tqdm import tqdm + +from cereal import car, log +from selfdrive.car.car_helpers import get_car +import selfdrive.manager as manager +import selfdrive.messaging as messaging +from common.params import Params +from selfdrive.services import service_list +from collections import namedtuple + +ProcessConfig = namedtuple('ProcessConfig', ['proc_name', 'pub_sub', 'ignore', 'init_callback', 'should_recv_callback']) + +class FakeSocket: + def __init__(self, wait=True): + self.data = [] + self.wait = wait + self.recv_called = threading.Event() + self.recv_ready = threading.Event() + + def receive(self, non_blocking=False): + if non_blocking: + return None + + if self.wait: + self.recv_called.set() + self.recv_ready.wait() + self.recv_ready.clear() + return self.data.pop() + + def send(self, data): + if self.wait: + self.recv_called.wait() + self.recv_called.clear() + + self.data.append(data) + + if self.wait: + self.recv_ready.set() + + def wait_for_recv(self): + self.recv_called.wait() + +class DumbSocket: + def __init__(self, s=None): + if s is not None: + dat = messaging.new_message() + dat.init(s) + self.data = dat.to_bytes() + + def receive(self, non_blocking=False): + return self.data + + def send(self, dat): + pass + +class FakeSubMaster(messaging.SubMaster): + def __init__(self, services): + super(FakeSubMaster, self).__init__(services, addr=None) + self.sock = {s: DumbSocket(s) for s in services} + self.update_called = threading.Event() + self.update_ready = threading.Event() + + self.wait_on_getitem = False + + def __getitem__(self, s): + # hack to know when fingerprinting is done + if self.wait_on_getitem: + self.update_called.set() + self.update_ready.wait() + self.update_ready.clear() + return self.data[s] + + def update(self, timeout=-1): + self.update_called.set() + self.update_ready.wait() + self.update_ready.clear() + + def update_msgs(self, cur_time, msgs): + self.update_called.wait() + self.update_called.clear() + super(FakeSubMaster, self).update_msgs(cur_time, msgs) + self.update_ready.set() + + def wait_for_update(self): + self.update_called.wait() + +class FakePubMaster(messaging.PubMaster): + def __init__(self, services): + self.data = {} + self.sock = {} + self.last_updated = None + for s in services: + data = messaging.new_message() + try: + data.init(s) + except: + data.init(s, 0) + self.data[s] = data.as_reader() + self.sock[s] = DumbSocket() + self.send_called = threading.Event() + self.get_called = threading.Event() + + def send(self, s, dat): + self.last_updated = s + if isinstance(dat, bytes): + self.data[s] = log.Event.from_bytes(dat) + else: + self.data[s] = dat.as_reader() + self.send_called.set() + self.get_called.wait() + self.get_called.clear() + + def wait_for_msg(self): + self.send_called.wait() + self.send_called.clear() + dat = self.data[self.last_updated] + self.get_called.set() + return dat + +def fingerprint(msgs, fsm, can_sock): + print("start fingerprinting") + fsm.wait_on_getitem = True + + # populate fake socket with data for fingerprinting + canmsgs = [msg for msg in msgs if msg.which() == "can"] + can_sock.recv_called.wait() + can_sock.recv_called.clear() + can_sock.data = [msg.as_builder().to_bytes() for msg in canmsgs[:300]] + can_sock.recv_ready.set() + can_sock.wait = False + + # we know fingerprinting is done when controlsd sets sm['pathPlan'].sensorValid + fsm.update_called.wait() + fsm.update_called.clear() + + fsm.wait_on_getitem = False + can_sock.wait = True + can_sock.data = [] + + fsm.update_ready.set() + print("finished fingerprinting") + +def get_car_params(msgs, fsm, can_sock): + can = FakeSocket(wait=False) + sendcan = FakeSocket(wait=False) + + canmsgs = [msg for msg in msgs if msg.which() == 'can'] + for m in canmsgs[:300]: + can.send(m.as_builder().to_bytes()) + _, CP = get_car(can, sendcan) + Params().put("CarParams", CP.to_bytes()) + +def radar_rcv_callback(msg, CP): + if msg.which() != "can": + return [] + elif CP.radarOffCan: + return ["radarState", "liveTracks"] + + radar_msgs = {"honda": [0x445], "toyota": [0x19f, 0x22f], "gm": [0x474], + "chrysler": [0x2d4]}.get(CP.carName, None) + + if radar_msgs is None: + raise NotImplementedError + + for m in msg.can: + if m.src == 1 and m.address in radar_msgs: + return ["radarState", "liveTracks"] + return [] + +CONFIGS = [ + ProcessConfig( + proc_name="controlsd", + pub_sub={ + "can": ["controlsState", "carState", "carControl", "sendcan", "carEvents", "carParams"], + "thermal": [], "health": [], "liveCalibration": [], "driverMonitoring": [], "plan": [], "pathPlan": [], "gpsLocation": [], + }, + ignore=[("logMonoTime", 0), ("valid", True), ("controlsState.startMonoTime", 0), ("controlsState.cumLagMs", 0)], + init_callback=fingerprint, + should_recv_callback=None, + ), + ProcessConfig( + proc_name="radard", + pub_sub={ + "can": ["radarState", "liveTracks"], + "liveParameters": [], "controlsState": [], "model": [], + }, + ignore=[("logMonoTime", 0), ("valid", True), ("radarState.cumLagMs", 0)], + init_callback=get_car_params, + should_recv_callback=radar_rcv_callback, + ), + ProcessConfig( + proc_name="plannerd", + pub_sub={ + "model": ["pathPlan"], "radarState": ["plan"], + "carState": [], "controlsState": [], "liveParameters": [], + }, + ignore=[("logMonoTime", 0), ("valid", True), ("plan.processingDelay", 0)], + init_callback=get_car_params, + should_recv_callback=None, + ), + ProcessConfig( + proc_name="calibrationd", + pub_sub={ + "cameraOdometry": ["liveCalibration"] + }, + ignore=[("logMonoTime", 0), ("valid", True)], + init_callback=get_car_params, + should_recv_callback=None, + ), +] + +def replay_process(cfg, lr): + sub_sockets = [s for _, sub in cfg.pub_sub.items() for s in sub] + pub_sockets = [s for s in cfg.pub_sub.keys() if s != 'can'] + + fsm = FakeSubMaster(pub_sockets) + fpm = FakePubMaster(sub_sockets) + args = (fsm, fpm) + if 'can' in list(cfg.pub_sub.keys()): + can_sock = FakeSocket() + args = (fsm, fpm, can_sock) + + all_msgs = sorted(lr, key=lambda msg: msg.logMonoTime) + pub_msgs = [msg for msg in all_msgs if msg.which() in list(cfg.pub_sub.keys())] + + shutil.rmtree('/data/params', ignore_errors=True) + params = Params() + params.manager_start() + params.put("OpenpilotEnabledToggle", "1") + params.put("Passive", "0") + + os.environ['NO_RADAR_SLEEP'] = "1" + manager.prepare_managed_process(cfg.proc_name) + mod = importlib.import_module(manager.managed_processes[cfg.proc_name]) + thread = threading.Thread(target=mod.main, args=args) + thread.daemon = True + thread.start() + + if cfg.init_callback is not None: + if 'can' not in list(cfg.pub_sub.keys()): + can_sock = None + cfg.init_callback(all_msgs, fsm, can_sock) + + CP = car.CarParams.from_bytes(params.get("CarParams", block=True)) + + # wait for started process to be ready + if 'can' in list(cfg.pub_sub.keys()): + can_sock.wait_for_recv() + else: + fsm.wait_for_update() + + log_msgs, msg_queue = [], [] + for msg in tqdm(pub_msgs): + if cfg.should_recv_callback is not None: + recv_socks = cfg.should_recv_callback(msg, CP) + else: + recv_socks = [s for s in cfg.pub_sub[msg.which()] if + (fsm.frame + 1) % int(service_list[msg.which()].frequency / service_list[s].frequency) == 0] + + should_recv = bool(len(recv_socks)) + + if msg.which() == 'can': + can_sock.send(msg.as_builder().to_bytes()) + else: + msg_queue.append(msg.as_builder()) + + if should_recv: + fsm.update_msgs(0, msg_queue) + msg_queue = [] + + recv_cnt = len(recv_socks) + while recv_cnt > 0: + m = fpm.wait_for_msg() + log_msgs.append(m) + + recv_cnt -= m.which() in recv_socks + return log_msgs diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit new file mode 100644 index 00000000000000..f00366d3f83c79 --- /dev/null +++ b/selfdrive/test/process_replay/ref_commit @@ -0,0 +1 @@ +5fe3678541ca1254ca5c1f04231f42225d68c538 \ No newline at end of file diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py new file mode 100755 index 00000000000000..6832aba33cca9c --- /dev/null +++ b/selfdrive/test/process_replay/test_processes.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +import os +import requests +import sys +import tempfile + +from selfdrive.test.process_replay.compare_logs import compare_logs +from selfdrive.test.process_replay.process_replay import replay_process, CONFIGS +from tools.lib.logreader import LogReader + +segments = [ + "0375fdf7b1ce594d|2019-06-13--08-32-25--3", # HONDA.ACCORD + "99c94dc769b5d96e|2019-08-03--14-19-59--2", # HONDA.CIVIC + "cce908f7eb8db67d|2019-08-02--15-09-51--3", # TOYOTA.COROLLA_TSS2 + "7ad88f53d406b787|2019-07-09--10-18-56--8", # GM.VOLT + "704b2230eb5190d6|2019-07-06--19-29-10--0", # HYUNDAI.KIA_SORENTO + "b6e1317e1bfbefa6|2019-07-06--04-05-26--5", # CHRYSLER.JEEP_CHEROKEE + "7873afaf022d36e2|2019-07-03--18-46-44--0", # SUBARU.IMPREZA +] + +def get_segment(segment_name): + route_name, segment_num = segment_name.rsplit("--", 1) + rlog_url = "https://commadataci.blob.core.windows.net/openpilotci/%s/%s/rlog.bz2" \ + % (route_name.replace("|", "/"), segment_num) + r = requests.get(rlog_url) + if r.status_code != 200: + return None + + with tempfile.NamedTemporaryFile(delete=False, suffix=".bz2") as f: + f.write(r.content) + return f.name + +if __name__ == "__main__": + + process_replay_dir = os.path.dirname(os.path.abspath(__file__)) + ref_commit_fn = os.path.join(process_replay_dir, "ref_commit") + + if not os.path.isfile(ref_commit_fn): + print("couldn't find reference commit") + sys.exit(1) + + ref_commit = open(ref_commit_fn).read().strip() + print("***** testing against commit %s *****" % ref_commit) + + results = {} + for segment in segments: + print("***** testing route segment %s *****\n" % segment) + + results[segment] = {} + + rlog_fn = get_segment(segment) + + if rlog_fn is None: + print("failed to get segment %s" % segment) + sys.exit(1) + + lr = LogReader(rlog_fn) + + for cfg in CONFIGS: + log_msgs = replay_process(cfg, lr) + + log_fn = os.path.join(process_replay_dir, "%s_%s_%s.bz2" % (segment, cfg.proc_name, ref_commit)) + + if not os.path.isfile(log_fn): + url = "https://commadataci.blob.core.windows.net/openpilotci/" + req = requests.get(url + os.path.basename(log_fn)) + if req.status_code != 200: + results[segment][cfg.proc_name] = "failed to download comparison log" + continue + + with tempfile.NamedTemporaryFile(suffix=".bz2") as f: + f.write(req.content) + f.flush() + f.seek(0) + cmp_log_msgs = list(LogReader(f.name)) + else: + cmp_log_msgs = list(LogReader(log_fn)) + + diff = compare_logs(cmp_log_msgs, log_msgs, cfg.ignore) + results[segment][cfg.proc_name] = diff + os.remove(rlog_fn) + + failed = False + with open(os.path.join(process_replay_dir, "diff.txt"), "w") as f: + f.write("***** tested against commit %s *****\n" % ref_commit) + + for segment, result in list(results.items()): + f.write("***** differences for segment %s *****\n" % segment) + print("***** results for segment %s *****" % segment) + + for proc, diff in list(result.items()): + f.write("*** process: %s ***\n" % proc) + print("\t%s" % proc) + + if isinstance(diff, str): + print("\t\t%s" % diff) + failed = True + elif len(diff): + cnt = {} + for d in diff: + f.write("\t%s\n" % str(d)) + + k = str(d[1]) + cnt[k] = 1 if k not in cnt else cnt[k] + 1 + + for k, v in sorted(cnt.items()): + print("\t\t%s: %s" % (k, v)) + failed = True + + if failed: + print("TEST FAILED") + else: + print("TEST SUCCEEDED") + + print("\n\nTo update the reference logs for this test run:") + print("./update_refs.py") + + sys.exit(int(failed)) diff --git a/selfdrive/test/process_replay/update_refs.py b/selfdrive/test/process_replay/update_refs.py new file mode 100755 index 00000000000000..e0da25133e009d --- /dev/null +++ b/selfdrive/test/process_replay/update_refs.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +import os +import sys + +from selfdrive.test.openpilotci_upload import upload_file +from selfdrive.test.process_replay.compare_logs import save_log +from selfdrive.test.process_replay.process_replay import replay_process, CONFIGS +from selfdrive.test.process_replay.test_processes import segments, get_segment +from selfdrive.version import get_git_commit +from tools.lib.logreader import LogReader + +if __name__ == "__main__": + + no_upload = "--no-upload" in sys.argv + + process_replay_dir = os.path.dirname(os.path.abspath(__file__)) + ref_commit_fn = os.path.join(process_replay_dir, "ref_commit") + + ref_commit = get_git_commit() + with open(ref_commit_fn, "w") as f: + f.write(ref_commit) + + for segment in segments: + rlog_fn = get_segment(segment) + + if rlog_fn is None: + print("failed to get segment %s" % segment) + sys.exit(1) + + lr = LogReader(rlog_fn) + + for cfg in CONFIGS: + log_msgs = replay_process(cfg, lr) + log_fn = os.path.join(process_replay_dir, "%s_%s_%s.bz2" % (segment, cfg.proc_name, ref_commit)) + save_log(log_fn, log_msgs) + + if not no_upload: + upload_file(log_fn, os.path.basename(log_fn)) + os.remove(log_fn) + os.remove(rlog_fn) + + print("done") diff --git a/selfdrive/test/test_car_models.py b/selfdrive/test/test_car_models.py new file mode 100755 index 00000000000000..9ef7ea31cf85c7 --- /dev/null +++ b/selfdrive/test/test_car_models.py @@ -0,0 +1,559 @@ +#!/usr/bin/env python3 +import shutil +import time +import os +import sys +import signal +import subprocess +import requests +from cereal import car + +import selfdrive.manager as manager +import selfdrive.messaging as messaging +from common.params import Params +from common.basedir import BASEDIR +from selfdrive.car.fingerprints import all_known_cars +from selfdrive.car.honda.values import CAR as HONDA +from selfdrive.car.toyota.values import CAR as TOYOTA +from selfdrive.car.gm.values import CAR as GM +from selfdrive.car.ford.values import CAR as FORD +from selfdrive.car.hyundai.values import CAR as HYUNDAI +from selfdrive.car.chrysler.values import CAR as CHRYSLER +from selfdrive.car.subaru.values import CAR as SUBARU +from selfdrive.car.volkswagen.values import CAR as VOLKSWAGEN +from selfdrive.car.mock.values import CAR as MOCK + + +os.environ['NOCRASH'] = '1' + + +def wait_for_socket(name, timeout=10.0): + socket = messaging.sub_sock(name) + cur_time = time.time() + + r = None + while time.time() - cur_time < timeout: + print("waiting for %s" % name) + r = socket.receive(non_blocking=True) + if r is not None: + break + time.sleep(0.5) + + if r is None: + sys.exit(-1) + return r + +def get_route_logs(route_name): + for log_f in ["rlog.bz2", "fcamera.hevc"]: + log_path = os.path.join("/tmp", "%s--0--%s" % (route_name.replace("|", "_"), log_f)) + + if not os.path.isfile(log_path): + log_url = "https://commadataci.blob.core.windows.net/openpilotci/%s/0/%s" % (route_name.replace("|", "/"), log_f) + r = requests.get(log_url) + + if r.status_code == 200: + with open(log_path, "wb") as f: + f.write(r.content) + else: + print("failed to download test log %s" % route_name) + sys.exit(-1) + +routes = { + + "975b26878285314d|2018-12-25--14-42-13": { + 'carFingerprint': CHRYSLER.PACIFICA_2018_HYBRID, + 'enableCamera': True, + }, + "b0c9d2329ad1606b|2019-01-06--10-11-23": { + 'carFingerprint': CHRYSLER.PACIFICA_2017_HYBRID, + 'enableCamera': True, + }, + "0607d2516fc2148f|2019-02-13--23-03-16": { + 'carFingerprint': CHRYSLER.PACIFICA_2019_HYBRID, + 'enableCamera': True, + }, + # This pacifica was removed because the fingerprint seemed from a Volt + #"9f7a7e50a51fb9db|2019-01-03--14-05-01": { + # 'carFingerprint': CHRYSLER.PACIFICA_2018, + # 'enableCamera': True, + #}, + "9f7a7e50a51fb9db|2019-01-17--18-34-21": { + 'carFingerprint': CHRYSLER.JEEP_CHEROKEE, + 'enableCamera': True, + }, + "192a598e34926b1e|2019-04-04--13-27-39": { + 'carFingerprint': CHRYSLER.JEEP_CHEROKEE_2019, + 'enableCamera': True, + }, + "f1b4c567731f4a1b|2018-04-18--11-29-37": { + 'carFingerprint': FORD.FUSION, + 'enableCamera': False, + }, + "f1b4c567731f4a1b|2018-04-30--10-15-35": { + 'carFingerprint': FORD.FUSION, + 'enableCamera': True, + }, + "7ed9cdf8d0c5f43e|2018-05-17--09-31-36": { + 'carFingerprint': GM.CADILLAC_CT6, + 'enableCamera': True, + }, + "265007255e794bce|2018-11-24--22-08-31": { + 'carFingerprint': GM.CADILLAC_ATS, + 'enableCamera': True, + }, + "c950e28c26b5b168|2018-05-30--22-03-41": { + 'carFingerprint': GM.VOLT, + 'enableCamera': True, + }, + # TODO: use another route that has radar data at start + "aadda448b49c99ad|2018-10-25--17-16-22": { + 'carFingerprint': GM.MALIBU, + 'enableCamera': True, + }, + "49c73650e65ff465|2018-11-19--16-58-04": { + 'carFingerprint': GM.HOLDEN_ASTRA, + 'enableCamera': True, + }, + "7cc2a8365b4dd8a9|2018-12-02--12-10-44": { + 'carFingerprint': GM.ACADIA, + 'enableCamera': True, + }, + "aa20e335f61ba898|2018-12-17--21-10-37": { + 'carFingerprint': GM.BUICK_REGAL, + 'enableCamera': False, + }, + "aa20e335f61ba898|2019-02-05--16-59-04": { + 'carFingerprint': GM.BUICK_REGAL, + 'enableCamera': True, + }, + "7d44af5b7a1b2c8e|2017-09-16--01-50-07": { + 'carFingerprint': HONDA.CIVIC, + 'enableCamera': True, + }, + "c9d60e5e02c04c5c|2018-01-08--16-01-49": { + 'carFingerprint': HONDA.CRV, + 'enableCamera': True, + }, + "1851183c395ef471|2018-05-31--18-07-21": { + 'carFingerprint': HONDA.CRV_5G, + 'enableCamera': True, + }, + "232585b7784c1af4|2019-04-08--14-12-14": { + 'carFingerprint': HONDA.CRV_HYBRID, + 'enableCamera': True, + }, + "99e3eaed7396619e|2019-08-13--15-07-03": { + 'carFingerprint': HONDA.FIT, + 'enableCamera': True, + }, + "2ac95059f70d76eb|2018-02-05--15-03-29": { + 'carFingerprint': HONDA.ACURA_ILX, + 'enableCamera': True, + }, + "21aa231dee2a68bd|2018-01-30--04-54-41": { + 'carFingerprint': HONDA.ODYSSEY, + 'enableCamera': True, + }, + "81722949a62ea724|2019-03-29--15-51-26": { + 'carFingerprint': HONDA.ODYSSEY_CHN, + 'enableCamera': False, + }, + "81722949a62ea724|2019-04-06--15-19-25": { + 'carFingerprint': HONDA.ODYSSEY_CHN, + 'enableCamera': True, + }, + "5a2cfe4bb362af9e|2018-02-02--23-41-07": { + 'carFingerprint': HONDA.ACURA_RDX, + 'enableCamera': True, + }, + "3e9592a1c78a3d63|2018-02-08--20-28-24": { + 'carFingerprint': HONDA.PILOT, + 'enableCamera': True, + }, + "34a84d2b765df688|2018-08-28--12-41-00": { + 'carFingerprint': HONDA.PILOT_2019, + 'enableCamera': True, + }, + "900ad17e536c3dc7|2018-04-12--22-02-36": { + 'carFingerprint': HONDA.RIDGELINE, + 'enableCamera': True, + }, + "f1b4c567731f4a1b|2018-06-06--14-43-46": { + 'carFingerprint': HONDA.ACCORD, + 'enableCamera': True, + }, + "1582e1dc57175194|2018-08-15--07-46-07": { + 'carFingerprint': HONDA.ACCORD_15, + 'enableCamera': True, + }, + # TODO: This doesnt fingerprint because the fingerprint overlaps with the Insight + # "690c4c9f9f2354c7|2018-09-15--17-36-05": { + # 'carFingerprint': HONDA.ACCORDH, + # 'enableCamera': True, + # }, + "1632088eda5e6c4d|2018-06-07--08-03-18": { + 'carFingerprint': HONDA.CIVIC_BOSCH, + 'enableCamera': True, + }, + #"18971a99f3f2b385|2018-11-14--19-09-31": { + # 'carFingerprint': HONDA.INSIGHT, + # 'enableCamera': True, + #}, + "38bfd238edecbcd7|2018-08-22--09-45-44": { + 'carFingerprint': HYUNDAI.SANTA_FE, + 'enableCamera': False, + }, + "38bfd238edecbcd7|2018-08-29--22-02-15": { + 'carFingerprint': HYUNDAI.SANTA_FE, + 'enableCamera': True, + }, + "a893a80e5c5f72c8|2019-01-14--20-02-59": { + 'carFingerprint': HYUNDAI.GENESIS, + 'enableCamera': True, + }, + "9d5fb4f0baa1b3e1|2019-01-14--17-45-59": { + 'carFingerprint': HYUNDAI.KIA_SORENTO, + 'enableCamera': True, + }, + "215cd70e9c349266|2018-11-25--22-22-12": { + 'carFingerprint': HYUNDAI.KIA_STINGER, + 'enableCamera': True, + }, + "31390e3eb6f7c29a|2019-01-23--08-56-00": { + 'carFingerprint': HYUNDAI.KIA_OPTIMA, + 'enableCamera': True, + }, + "53ac3251e03f95d7|2019-01-10--13-43-32": { + 'carFingerprint': HYUNDAI.ELANTRA, + 'enableCamera': True, + }, + "f7b6be73e3dfd36c|2019-05-12--18-07-16": { + 'carFingerprint': TOYOTA.AVALON, + 'enableCamera': False, + 'enableDsu': False, + }, + "f7b6be73e3dfd36c|2019-05-11--22-34-20": { + 'carFingerprint': TOYOTA.AVALON, + 'enableCamera': True, + 'enableDsu': False, + }, + "b0f5a01cf604185c|2018-01-26--00-54-32": { + 'carFingerprint': TOYOTA.COROLLA, + 'enableCamera': True, + 'enableDsu': True, + }, + "b0f5a01cf604185c|2018-01-26--10-54-38": { + 'carFingerprint': TOYOTA.COROLLA, + 'enableCamera': True, + 'enableDsu': False, + }, + "b0f5a01cf604185c|2018-01-26--10-59-31": { + 'carFingerprint': TOYOTA.COROLLA, + 'enableCamera': False, + 'enableDsu': False, + }, + "5f5afb36036506e4|2019-05-14--02-09-54": { + 'carFingerprint': TOYOTA.COROLLA_TSS2, + 'enableCamera': True, + 'enableDsu': True, + }, + "5ceff72287a5c86c|2019-10-19--10-59-02": { + 'carFingerprint': TOYOTA.COROLLAH_TSS2, + 'enableCamera': True, + 'enableDsu': True, + }, + "56fb1c86a9a86404|2017-11-10--10-18-43": { + 'carFingerprint': TOYOTA.PRIUS, + 'enableCamera': True, + 'enableDsu': True, + }, + "b0f5a01cf604185c|2017-12-18--20-32-32": { + 'carFingerprint': TOYOTA.RAV4, + 'enableCamera': True, + 'enableDsu': True, + 'enableGasInterceptor': False, + }, + "b0c9d2329ad1606b|2019-04-02--13-24-43": { + 'carFingerprint': TOYOTA.RAV4, + 'enableCamera': True, + 'enableDsu': True, + 'enableGasInterceptor': True, + }, + "cdf2f7de565d40ae|2019-04-25--03-53-41": { + 'carFingerprint': TOYOTA.RAV4_TSS2, + 'enableCamera': True, + 'enableDsu': True, + }, + "e6a24be49a6cd46e|2019-10-29--10-52-42": { + 'carFingerprint': TOYOTA.LEXUS_ES_TSS2, + 'enableCamera': True, + 'enableDsu': True, + }, + "f49e8041283f2939|2019-05-29--13-48-33": { + 'carFingerprint': TOYOTA.LEXUS_ESH_TSS2, + 'enableCamera': False, + 'enableDsu': False, + }, + "f49e8041283f2939|2019-05-30--11-51-51": { + 'carFingerprint': TOYOTA.LEXUS_ESH_TSS2, + 'enableCamera': True, + 'enableDsu': True, + }, + "b0f5a01cf604185c|2018-02-01--21-12-28": { + 'carFingerprint': TOYOTA.LEXUS_RXH, + 'enableCamera': True, + 'enableDsu': True, + }, + #FIXME: This works sometimes locally, but never in CI. Timing issue? + #"b0f5a01cf604185c|2018-01-31--20-11-39": { + # 'carFingerprint': TOYOTA.LEXUS_RXH, + # 'enableCamera': False, + # 'enableDsu': False, + #}, + "8ae193ceb56a0efe|2018-06-18--20-07-32": { + 'carFingerprint': TOYOTA.RAV4H, + 'enableCamera': True, + 'enableDsu': True, + }, + "fd10b9a107bb2e49|2018-07-24--16-32-42": { + 'carFingerprint': TOYOTA.CHR, + 'enableCamera': True, + 'enableDsu': False, + }, + "fd10b9a107bb2e49|2018-07-24--20-32-08": { + 'carFingerprint': TOYOTA.CHR, + 'enableCamera': False, + 'enableDsu': False, + }, + "b4c18bf13d5955da|2018-07-29--13-39-46": { + 'carFingerprint': TOYOTA.CHRH, + 'enableCamera': True, + 'enableDsu': False, + }, + "d2d8152227f7cb82|2018-07-25--13-40-56": { + 'carFingerprint': TOYOTA.CAMRY, + 'enableCamera': True, + 'enableDsu': False, + }, + "fbd011384db5e669|2018-07-26--20-51-48": { + 'carFingerprint': TOYOTA.CAMRYH, + 'enableCamera': True, + 'enableDsu': False, + }, + # TODO: This replay has no good model/video + # "c9fa2dd0f76caf23|2018-02-10--13-40-28": { + # 'carFingerprint': TOYOTA.CAMRYH, + # 'enableCamera': False, + # 'enableDsu': False, + # }, + # TODO: missingsome combos for highlander + "aa659debdd1a7b54|2018-08-31--11-12-01": { + 'carFingerprint': TOYOTA.HIGHLANDER, + 'enableCamera': False, + 'enableDsu': False, + }, + "362d23d4d5bea2fa|2018-09-02--17-03-55": { + 'carFingerprint': TOYOTA.HIGHLANDERH, + 'enableCamera': True, + 'enableDsu': True, + }, + "eb6acd681135480d|2019-06-20--20-00-00": { + 'carFingerprint': TOYOTA.SIENNA, + 'enableCamera': True, + 'enableDsu': False, + }, + "362d23d4d5bea2fa|2018-08-10--13-31-40": { + 'carFingerprint': TOYOTA.HIGHLANDERH, + 'enableCamera': False, + 'enableDsu': False, + }, + "2e07163a1ba9a780|2019-08-25--13-15-13": { + 'carFingerprint': TOYOTA.LEXUS_IS, + 'enableCamera': True, + 'enableDsu': False, + }, + "2e07163a1ba9a780|2019-08-29--09-35-42": { + 'carFingerprint': TOYOTA.LEXUS_IS, + 'enableCamera': False, + 'enableDsu': False, + }, + "1dd19ceed0ee2b48|2018-12-22--17-36-49": { + 'carFingerprint': TOYOTA.LEXUS_IS, # 300 hybrid + 'enableCamera': True, + 'enableDsu': False, + }, + "76b83eb0245de90e|2019-10-20--15-42-29": { + 'carFingerprint': VOLKSWAGEN.GOLF, + 'enableCamera': True, + }, + "791340bc01ed993d|2019-03-10--16-28-08": { + 'carFingerprint': SUBARU.IMPREZA, + 'enableCamera': True, + }, + # Tesla route, should result in mock car + "07cb8a788c31f645|2018-06-17--18-50-29": { + 'carFingerprint': MOCK.MOCK, + }, + ## Route with no can data, should result in mock car. This is not supported anymore + #"bfa17080b080f3ec|2018-06-28--23-27-47": { + # 'carFingerprint': MOCK.MOCK, + #}, +} + +passive_routes = [ + "07cb8a788c31f645|2018-06-17--18-50-29", + #"bfa17080b080f3ec|2018-06-28--23-27-47", +] + +# TODO: replace all these with public routes +# TODO: add routes for untested cars: HONDA ACCORD 2018 HYBRID TOURING and CHRYSLER PACIFICA 2018 +non_public_routes = [ + "0607d2516fc2148f|2019-02-13--23-03-16", # CHRYSLER PACIFICA HYBRID 2019 + "3e9592a1c78a3d63|2018-02-08--20-28-24", # HONDA PILOT 2017 TOURING + "aa20e335f61ba898|2019-02-05--16-59-04", # BUICK REGAL ESSENCE 2018 + "1851183c395ef471|2018-05-31--18-07-21", # HONDA CR-V 2017 EX + "9d5fb4f0baa1b3e1|2019-01-14--17-45-59", # KIA SORENTO GT LINE 2018 + "b4c18bf13d5955da|2018-07-29--13-39-46", # TOYOTA C-HR HYBRID 2018 + "5a2cfe4bb362af9e|2018-02-02--23-41-07", # ACURA RDX 2018 ACURAWATCH PLUS + "362d23d4d5bea2fa|2018-08-10--13-31-40", # TOYOTA HIGHLANDER HYBRID 2018 + "aa20e335f61ba898|2018-12-17--21-10-37", # BUICK REGAL ESSENCE 2018 + "215cd70e9c349266|2018-11-25--22-22-12", # KIA STINGER GT2 2018 + "192a598e34926b1e|2019-04-04--13-27-39", # JEEP GRAND CHEROKEE 2019 + "34a84d2b765df688|2018-08-28--12-41-00", # HONDA PILOT 2019 ELITE + "b0c9d2329ad1606b|2019-01-06--10-11-23", # CHRYSLER PACIFICA HYBRID 2017 + "31390e3eb6f7c29a|2019-01-23--08-56-00", # KIA OPTIMA SX 2019 + "fd10b9a107bb2e49|2018-07-24--16-32-42", # TOYOTA C-HR 2018 + "9f7a7e50a51fb9db|2019-01-17--18-34-21", # JEEP GRAND CHEROKEE V6 2018 + "aadda448b49c99ad|2018-10-25--17-16-22", # CHEVROLET MALIBU PREMIER 2017 + "362d23d4d5bea2fa|2018-09-02--17-03-55", # TOYOTA HIGHLANDER HYBRID 2018 + "1582e1dc57175194|2018-08-15--07-46-07", # HONDA ACCORD 2018 LX 1.5T + "fd10b9a107bb2e49|2018-07-24--20-32-08", # TOYOTA C-HR 2018 + "265007255e794bce|2018-11-24--22-08-31", # CADILLAC ATS Premium Performance 2018 + "53ac3251e03f95d7|2019-01-10--13-43-32", # HYUNDAI ELANTRA LIMITED ULTIMATE 2017 + "21aa231dee2a68bd|2018-01-30--04-54-41", # HONDA ODYSSEY 2018 EX-L + "900ad17e536c3dc7|2018-04-12--22-02-36", # HONDA RIDGELINE 2017 BLACK EDITION + "975b26878285314d|2018-12-25--14-42-13", # CHRYSLER PACIFICA HYBRID 2018 + "8ae193ceb56a0efe|2018-06-18--20-07-32", # TOYOTA RAV4 HYBRID 2017 + "a893a80e5c5f72c8|2019-01-14--20-02-59", # HYUNDAI GENESIS 2018 + "49c73650e65ff465|2018-11-19--16-58-04", # HOLDEN ASTRA RS-V BK 2017 + "d2d8152227f7cb82|2018-07-25--13-40-56", # TOYOTA CAMRY 2018 + "07cb8a788c31f645|2018-06-17--18-50-29", # mock + "c9d60e5e02c04c5c|2018-01-08--16-01-49", # HONDA CR-V 2016 TOURING + "1632088eda5e6c4d|2018-06-07--08-03-18", # HONDA CIVIC HATCHBACK 2017 SEDAN/COUPE 2019 + "fbd011384db5e669|2018-07-26--20-51-48", # TOYOTA CAMRY HYBRID 2018 +] + +if __name__ == "__main__": + + # TODO: add routes for untested cars and fail test if we have an untested car + tested_cars = [keys["carFingerprint"] for route, keys in routes.items()] + for car_model in all_known_cars(): + if car_model not in tested_cars: + print("***** WARNING: %s not tested *****" % car_model) + + results = {} + for route, checks in routes.items(): + if route not in non_public_routes: + get_route_logs(route) + elif "UNLOGGER_PATH" not in os.environ: + continue + + for _ in range(3): + shutil.rmtree('/data/params') + manager.gctx = {} + params = Params() + params.manager_start() + if route in passive_routes: + params.put("Passive", "1") + else: + params.put("Passive", "0") + + print("testing ", route, " ", checks['carFingerprint']) + print("Preparing processes") + manager.prepare_managed_process("radard") + manager.prepare_managed_process("controlsd") + manager.prepare_managed_process("plannerd") + print("Starting processes") + manager.start_managed_process("radard") + manager.start_managed_process("controlsd") + manager.start_managed_process("plannerd") + time.sleep(2) + + # Start unlogger + print("Start unlogger") + if route in non_public_routes: + unlogger_cmd = [os.path.join(BASEDIR, os.environ['UNLOGGER_PATH']), '%s' % route, '--disable', 'frame,plan,pathPlan,liveLongitudinalMpc,radarState,controlsState,liveTracks,liveMpc,sendcan,carState,carControl,carEvents,carParams', '--no-interactive'] + else: + unlogger_cmd = [os.path.join(BASEDIR, 'tools/replay/unlogger.py'), '%s' % route, '/tmp', '--disable', 'frame,plan,pathPlan,liveLongitudinalMpc,radarState,controlsState,liveTracks,liveMpc,sendcan,carState,carControl,carEvents,carParams', '--no-interactive'] + unlogger = subprocess.Popen(unlogger_cmd, preexec_fn=os.setsid) + + print("Check sockets") + controls_state_result = wait_for_socket('controlsState', timeout=30) + radarstate_result = wait_for_socket('radarState', timeout=30) + plan_result = wait_for_socket('plan', timeout=30) + + if route not in passive_routes: # TODO The passive routes have very flaky models + path_plan_result = wait_for_socket('pathPlan', timeout=30) + else: + path_plan_result = True + + carstate_result = wait_for_socket('carState', timeout=30) + + print("Check if everything is running") + running = manager.get_running() + controlsd_running = running['controlsd'].is_alive() + radard_running = running['radard'].is_alive() + plannerd_running = running['plannerd'].is_alive() + + manager.kill_managed_process("controlsd") + manager.kill_managed_process("radard") + manager.kill_managed_process("plannerd") + os.killpg(os.getpgid(unlogger.pid), signal.SIGTERM) + + sockets_ok = all([ + controls_state_result, radarstate_result, plan_result, path_plan_result, carstate_result, + controlsd_running, radard_running, plannerd_running + ]) + params_ok = True + failures = [] + + if not controlsd_running: + failures.append('controlsd') + if not radard_running: + failures.append('radard') + if not radarstate_result: + failures.append('radarState') + if not controls_state_result: + failures.append('controlsState') + if not plan_result: + failures.append('plan') + if not path_plan_result: + failures.append('pathPlan') + + try: + car_params = car.CarParams.from_bytes(params.get("CarParams")) + for k, v in checks.items(): + if not v == getattr(car_params, k): + params_ok = False + failures.append(k) + except: + params_ok = False + + if sockets_ok and params_ok: + print("Success") + results[route] = True, failures + break + else: + print("Failure") + results[route] = False, failures + + time.sleep(2) + + for route in results: + print(results[route]) + Params().put("Passive", "0") # put back not passive to not leave the params in an unintended state + if not all(passed for passed, _ in results.values()): + print("TEST FAILED") + sys.exit(1) + else: + print("TEST SUCCESSFUL") diff --git a/selfdrive/test/test_fingerprints.py b/selfdrive/test/test_fingerprints.py index b1f1a97a2d41ef..6b5e8378af081f 100755 --- a/selfdrive/test/test_fingerprints.py +++ b/selfdrive/test/test_fingerprints.py @@ -1,8 +1,16 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 import os import sys from common.basedir import BASEDIR +# messages reserved for CAN based ignition (see can_ignition_hook function in panda/board/drivers/can) +# (addr, len) +CAN_IGNITION_MSGS = { + 'gm': [(0x1F1, 8), (0x160, 5)], + 'tesla' : [(0x348, 8)], + 'volkswagen' : [(0x3C0, 4)], +} + def _get_fingerprints(): # read all the folders in selfdrive/car and return a dict where: # - keys are all the car names that which we have a fingerprint dict for @@ -20,10 +28,10 @@ def _get_fingerprints(): def check_fingerprint_consistency(f1, f2): # return false if it finds a fingerprint fully included in another - - # max message worth checking is 1900, as above that they usually come too infrequently and not + # max message worth checking is 1800, as above that they usually come too infrequently and not # usable for fingerprinting - max_msg = 1900 + + max_msg = 1800 is_f1_in_f2 = True for k in f1: @@ -38,31 +46,49 @@ def check_fingerprint_consistency(f1, f2): return not is_f1_in_f2 and not is_f2_in_f1 +def check_can_ignition_conflicts(fingerprints, brands): + # loops through all the fingerprints and exits if CAN ignition dedicated messages + # are found in unexpected fingerprints + + for brand_can, msgs_can in CAN_IGNITION_MSGS.items(): + for i, f in enumerate(fingerprints): + for msg_can in msgs_can: + if brand_can != brands[i] and msg_can[0] in f and msg_can[1] == f[msg_can[0]]: + print("CAN ignition dedicated msg %d with len %d found in %s fingerprints!" % (msg_can[0], msg_can[1], brands[i])) + print("TEST FAILED") + sys.exit(1) + + fingerprints = _get_fingerprints() + fingerprints_flat = [] car_names = [] +brand_names = [] for brand in fingerprints: for car in fingerprints[brand]: fingerprints_flat += fingerprints[brand][car] for i in range(len(fingerprints[brand][car])): car_names.append(car) + brand_names.append(brand) +# first check if CAN ignition specific messages are unexpectedly included in other fingerprints +check_can_ignition_conflicts(fingerprints_flat, brand_names) valid = True for idx1, f1 in enumerate(fingerprints_flat): for idx2, f2 in enumerate(fingerprints_flat): if idx1 < idx2 and not check_fingerprint_consistency(f1, f2): valid = False - print "Those two fingerprints are inconsistent", car_names[idx1], car_names[idx2] - print "" - print ', '.join("%d: %d" % v for v in sorted(f1.items())) - print "" - print ', '.join("%d: %d" % v for v in sorted(f2.items())) - print "" - -print "Found ", len(fingerprints_flat), " individual fingerprints" + print("Those two fingerprints are inconsistent {0} {1}".format(car_names[idx1], car_names[idx2])) + print("") + print(', '.join("%d: %d" % v for v in sorted(f1.items()))) + print("") + print(', '.join("%d: %d" % v for v in sorted(f2.items()))) + print("") + +print("Found {0} individual fingerprints".format(len(fingerprints_flat))) if not valid or len(fingerprints_flat) == 0: - print "TEST FAILED" + print("TEST FAILED") sys.exit(1) else: - print "TEST SUCESSFUL" + print("TEST SUCESSFUL") diff --git a/selfdrive/test/test_openpilot.py b/selfdrive/test/test_openpilot.py index 0a825e3a34cb1b..0176a7fcd0f11e 100644 --- a/selfdrive/test/test_openpilot.py +++ b/selfdrive/test/test_openpilot.py @@ -43,7 +43,7 @@ def wrap(): #@phone_only #@with_processes(['controlsd', 'radard']) #def test_controls(): -# from selfdrive.test.plant.plant import Plant +# from selfdrive.test.longitudinal_maneuvers.plant import Plant # # # start the fake car for 2 seconds # plant = Plant(100) @@ -63,25 +63,25 @@ def wrap(): @phone_only @with_processes(['loggerd', 'logmessaged', 'tombstoned', 'proclogd', 'logcatd']) def test_logging(): - print "LOGGING IS SET UP" + print("LOGGING IS SET UP") time.sleep(1.0) @phone_only @with_processes(['visiond']) def test_visiond(): - print "VISIOND IS SET UP" + print("VISIOND IS SET UP") time.sleep(5.0) @phone_only @with_processes(['sensord']) def test_sensord(): - print "SENSORS ARE SET UP" + print("SENSORS ARE SET UP") time.sleep(1.0) @phone_only @with_processes(['ui']) def test_ui(): - print "RUNNING UI" + print("RUNNING UI") time.sleep(1.0) # will have one thing to upload if loggerd ran @@ -89,5 +89,5 @@ def test_ui(): @phone_only @with_processes(['uploader']) def test_uploader(): - print "UPLOADER" + print("UPLOADER") time.sleep(10.0) diff --git a/selfdrive/test/tests/plant/test_longitudinal.py b/selfdrive/test/tests/plant/test_longitudinal.py deleted file mode 100755 index 9806f5a19015a4..00000000000000 --- a/selfdrive/test/tests/plant/test_longitudinal.py +++ /dev/null @@ -1,339 +0,0 @@ -#!/usr/bin/env python -import os -os.environ['OLD_CAN'] = '1' -os.environ['NOCRASH'] = '1' - -import time -import unittest -import shutil -import matplotlib -matplotlib.use('svg') - -from selfdrive.config import Conversions as CV -from selfdrive.car.honda.values import CruiseButtons as CB -from selfdrive.test.plant.maneuver import Maneuver -import selfdrive.manager as manager -from common.params import Params - - -def create_dir(path): - try: - os.makedirs(path) - except OSError: - pass - -maneuvers = [ - Maneuver( - 'while cruising at 40 mph, change cruise speed to 50mph', - duration=30., - initial_speed = 40. * CV.MPH_TO_MS, - cruise_button_presses = [(CB.DECEL_SET, 2.), (0, 2.3), - (CB.RES_ACCEL, 10.), (0, 10.1), - (CB.RES_ACCEL, 10.2), (0, 10.3)] - ), - Maneuver( - 'while cruising at 60 mph, change cruise speed to 50mph', - duration=30., - initial_speed=60. * CV.MPH_TO_MS, - cruise_button_presses = [(CB.DECEL_SET, 2.), (0, 2.3), - (CB.DECEL_SET, 10.), (0, 10.1), - (CB.DECEL_SET, 10.2), (0, 10.3)] - ), - Maneuver( - 'while cruising at 20mph, grade change +10%', - duration=25., - initial_speed=20. * CV.MPH_TO_MS, - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)], - grade_values = [0., 0., 1.0], - grade_breakpoints = [0., 10., 11.] - ), - Maneuver( - 'while cruising at 20mph, grade change -10%', - duration=25., - initial_speed=20. * CV.MPH_TO_MS, - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)], - grade_values = [0., 0., -1.0], - grade_breakpoints = [0., 10., 11.] - ), - Maneuver( - 'approaching a 40mph car while cruising at 60mph from 100m away', - duration=30., - initial_speed = 60. * CV.MPH_TO_MS, - lead_relevancy=True, - initial_distance_lead=100., - speed_lead_values = [40.*CV.MPH_TO_MS, 40.*CV.MPH_TO_MS], - speed_lead_breakpoints = [0., 100.], - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)] - ), - Maneuver( - 'approaching a 0mph car while cruising at 40mph from 150m away', - duration=30., - initial_speed = 40. * CV.MPH_TO_MS, - lead_relevancy=True, - initial_distance_lead=150., - speed_lead_values = [0.*CV.MPH_TO_MS, 0.*CV.MPH_TO_MS], - speed_lead_breakpoints = [0., 100.], - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)] - ), - Maneuver( - 'steady state following a car at 20m/s, then lead decel to 0mph at 1m/s^2', - duration=50., - initial_speed = 20., - lead_relevancy=True, - initial_distance_lead=35., - speed_lead_values = [20., 20., 0.], - speed_lead_breakpoints = [0., 15., 35.0], - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)] - ), - Maneuver( - 'steady state following a car at 20m/s, then lead decel to 0mph at 2m/s^2', - duration=50., - initial_speed = 20., - lead_relevancy=True, - initial_distance_lead=35., - speed_lead_values = [20., 20., 0.], - speed_lead_breakpoints = [0., 15., 25.0], - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)] - ), - Maneuver( - 'steady state following a car at 20m/s, then lead decel to 0mph at 3m/s^2', - duration=50., - initial_speed = 20., - lead_relevancy=True, - initial_distance_lead=35., - speed_lead_values = [20., 20., 0.], - speed_lead_breakpoints = [0., 15., 21.66], - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)] - ), - Maneuver( - 'steady state following a car at 20m/s, then lead decel to 0mph at 5m/s^2', - duration=40., - initial_speed = 20., - lead_relevancy=True, - initial_distance_lead=35., - speed_lead_values = [20., 20., 0.], - speed_lead_breakpoints = [0., 15., 19.], - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3)] - ), - Maneuver( - 'starting at 0mph, approaching a stopped car 100m away', - duration=30., - initial_speed = 0., - lead_relevancy=True, - initial_distance_lead=100., - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7), - (CB.RES_ACCEL, 1.8), (0.0, 1.9)] - ), - Maneuver( - "following a car at 60mph, lead accel and decel at 0.5m/s^2 every 2s", - duration=25., - initial_speed=30., - lead_relevancy=True, - initial_distance_lead=49., - speed_lead_values=[30.,30.,29.,31.,29.,31.,29.], - speed_lead_breakpoints=[0., 6., 8., 12.,16.,20.,24.], - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7)] - ), - Maneuver( - "following a car at 10mph, stop and go at 1m/s2 lead dece1 and accel", - duration=70., - initial_speed=10., - lead_relevancy=True, - initial_distance_lead=20., - speed_lead_values=[10., 0., 0., 10., 0.,10.], - speed_lead_breakpoints=[10., 20., 30., 40., 50., 60.], - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7)] - ), - Maneuver( - "green light: stopped behind lead car, lead car accelerates at 1.5 m/s", - duration=30., - initial_speed=0., - lead_relevancy=True, - initial_distance_lead=4., - speed_lead_values=[0, 0 , 45], - speed_lead_breakpoints=[0, 10., 40.], - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7), - (CB.RES_ACCEL, 1.8), (0.0, 1.9), - (CB.RES_ACCEL, 2.0), (0.0, 2.1), - (CB.RES_ACCEL, 2.2), (0.0, 2.3)] - ), - Maneuver( - "stop and go with 1m/s2 lead decel and accel, with full stops", - duration=70., - initial_speed=0., - lead_relevancy=True, - initial_distance_lead=20., - speed_lead_values=[10., 0., 0., 10., 0., 0.] , - speed_lead_breakpoints=[10., 20., 30., 40., 50., 60.], - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7)] - ), - Maneuver( - "stop and go with 1.5m/s2 lead accel and 3.3m/s^2 lead decel, with full stops", - duration=45., - initial_speed=0., - lead_relevancy=True, - initial_distance_lead=20., - speed_lead_values=[10., 0., 0., 10., 0., 0.] , - speed_lead_breakpoints=[10., 13., 26., 33., 36., 45.], - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7)] - ), - Maneuver( - "accelerate from 20 while lead vehicle decelerates from 40 to 20 at 1m/s2", - duration=30., - initial_speed=10., - lead_relevancy=True, - initial_distance_lead=10., - speed_lead_values=[20., 10.], - speed_lead_breakpoints=[1., 11.], - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7), - (CB.RES_ACCEL, 1.8), (0.0, 1.9), - (CB.RES_ACCEL, 2.0), (0.0, 2.1), - (CB.RES_ACCEL, 2.2), (0.0, 2.3)] - ), - Maneuver( - "accelerate from 20 while lead vehicle decelerates from 40 to 0 at 2m/s2", - duration=30., - initial_speed=10., - lead_relevancy=True, - initial_distance_lead=10., - speed_lead_values=[20., 0.], - speed_lead_breakpoints=[1., 11.], - cruise_button_presses = [(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7), - (CB.RES_ACCEL, 1.8), (0.0, 1.9), - (CB.RES_ACCEL, 2.0), (0.0, 2.1), - (CB.RES_ACCEL, 2.2), (0.0, 2.3)] - ), - Maneuver( - "fcw: traveling at 30 m/s and approaching lead traveling at 20m/s", - duration=15., - initial_speed=30., - lead_relevancy=True, - initial_distance_lead=100., - speed_lead_values=[20.], - speed_lead_breakpoints=[1.], - cruise_button_presses = [] - ), - Maneuver( - "fcw: traveling at 20 m/s following a lead that decels from 20m/s to 0 at 1m/s2", - duration=18., - initial_speed=20., - lead_relevancy=True, - initial_distance_lead=35., - speed_lead_values=[20., 0.], - speed_lead_breakpoints=[3., 23.], - cruise_button_presses = [] - ), - Maneuver( - "fcw: traveling at 20 m/s following a lead that decels from 20m/s to 0 at 3m/s2", - duration=13., - initial_speed=20., - lead_relevancy=True, - initial_distance_lead=35., - speed_lead_values=[20., 0.], - speed_lead_breakpoints=[3., 9.6], - cruise_button_presses = [] - ), - Maneuver( - "fcw: traveling at 20 m/s following a lead that decels from 20m/s to 0 at 5m/s2", - duration=8., - initial_speed=20., - lead_relevancy=True, - initial_distance_lead=35., - speed_lead_values=[20., 0.], - speed_lead_breakpoints=[3., 7.], - cruise_button_presses = [] - ) -] - -# maneuvers = [maneuvers[-11]] -# maneuvers = [maneuvers[6]] - -def setup_output(): - output_dir = os.path.join(os.getcwd(), 'out/longitudinal') - if not os.path.exists(os.path.join(output_dir, "index.html")): - # write test output header - - css_style = """ - .maneuver_title { - font-size: 24px; - text-align: center; - } - .maneuver_graph { - width: 100%; - } - """ - - view_html = "
    %s
    " % (css_style,) - for i, man in enumerate(maneuvers): - view_html += "" % (man.title,) - for c in ['distance.svg', 'speeds.svg', 'acceleration.svg', 'pedals.svg', 'pid.svg']: - view_html += "" % (os.path.join("maneuver" + str(i+1).zfill(2), c), ) - view_html += "" - - create_dir(output_dir) - with open(os.path.join(output_dir, "index.html"), "w") as f: - f.write(view_html) - -class LongitudinalControl(unittest.TestCase): - @classmethod - def setUpClass(cls): - - setup_output() - - shutil.rmtree('/data/params', ignore_errors=True) - params = Params() - params.put("Passive", "1" if os.getenv("PASSIVE") else "0") - params.put("IsFcwEnabled", "1") - - manager.gctx = {} - manager.prepare_managed_process('radard') - manager.prepare_managed_process('controlsd') - manager.prepare_managed_process('plannerd') - - @classmethod - def tearDownClass(cls): - pass - - # hack - def test_longitudinal_setup(self): - pass - -WORKERS = 8 -def run_maneuver_worker(k): - output_dir = os.path.join(os.getcwd(), 'out/longitudinal') - for i, man in enumerate(maneuvers[k::WORKERS]): - manager.start_managed_process('radard') - manager.start_managed_process('controlsd') - manager.start_managed_process('plannerd') - - score, plot = man.evaluate() - plot.write_plot(output_dir, "maneuver" + str(WORKERS * i + k+1).zfill(2)) - - manager.kill_managed_process('radard') - manager.kill_managed_process('controlsd') - manager.kill_managed_process('plannerd') - time.sleep(5) - -for k in xrange(WORKERS): - setattr(LongitudinalControl, - "test_longitudinal_maneuvers_%d" % (k+1), - lambda self, k=k: run_maneuver_worker(k)) - -if __name__ == "__main__": - unittest.main() diff --git a/selfdrive/thermald.py b/selfdrive/thermald.py index fea5a896846756..eeec3f3b11a1b8 100755 --- a/selfdrive/thermald.py +++ b/selfdrive/thermald.py @@ -1,20 +1,31 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python3.7 import os -import zmq +import json +import copy +import datetime from smbus2 import SMBus from cereal import log -from selfdrive.version import training_version -from selfdrive.swaglog import cloudlog -import selfdrive.messaging as messaging -from selfdrive.services import service_list -from selfdrive.loggerd.config import ROOT +from common.basedir import BASEDIR from common.params import Params -from common.realtime import sec_since_boot -from common.numpy_fast import clip +from common.realtime import sec_since_boot, DT_TRML +from common.numpy_fast import clip, interp from common.filter_simple import FirstOrderFilter +from selfdrive.version import terms_version, training_version +from selfdrive.swaglog import cloudlog +import selfdrive.messaging as messaging +from selfdrive.loggerd.config import get_available_percent +from selfdrive.pandad import get_expected_version + +FW_VERSION = get_expected_version() ThermalStatus = log.ThermalData.ThermalStatus -CURRENT_TAU = 2. # 2s time constant +CURRENT_TAU = 15. # 15s time constant +DAYS_NO_CONNECTIVITY_MAX = 7 # do not allow to engage after a week without internet +DAYS_NO_CONNECTIVITY_PROMPT = 4 # send an offroad prompt after 4 days with no internet + + +with open(BASEDIR + "/selfdrive/controls/lib/alerts_offroad.json") as json_file: + OFFROAD_ALERTS = json.load(json_file) def read_tz(x): with open("/sys/devices/virtual/thermal/thermal_zone%d/temp" % x) as f: @@ -46,7 +57,7 @@ def setup_eon_fan(): bus.write_byte_data(0x21, 0x02, 0x2) # needed? bus.write_byte_data(0x21, 0x04, 0x4) # manual override source except IOError: - print "LEON detected" + print("LEON detected") #os.system("echo 1 > /sys/devices/soc/6a00000.ssusb/power_supply/usb/usb_otg") LEON = True bus.close() @@ -85,7 +96,7 @@ def set_eon_fan(val): _BAT_TEMP_THERSHOLD = 45. -def handle_fan(max_cpu_temp, bat_temp, fan_speed): +def handle_fan_eon(max_cpu_temp, bat_temp, fan_speed): new_speed_h = next(speed for speed, temp_h in zip(_FAN_SPEEDS, _TEMP_THRS_H) if temp_h > max_cpu_temp) new_speed_l = next(speed for speed, temp_l in zip(_FAN_SPEEDS, _TEMP_THRS_L) if temp_l > max_cpu_temp) @@ -100,57 +111,13 @@ def handle_fan(max_cpu_temp, bat_temp, fan_speed): # no max fan speed unless battery is hot fan_speed = min(fan_speed, _FAN_SPEEDS[-2]) - set_eon_fan(fan_speed/16384) + set_eon_fan(fan_speed//16384) return fan_speed - -def check_car_battery_voltage(should_start, health, charging_disabled): - - # charging disallowed if: - # - there are health packets from panda, and; - # - 12V battery voltage is too low, and; - # - onroad isn't started - if charging_disabled and (health is None or health.health.voltage > 11800): - charging_disabled = False - os.system('echo "1" > /sys/class/power_supply/battery/charging_enabled') - elif not charging_disabled and health is not None and health.health.voltage < 11500 and not should_start: - charging_disabled = True - os.system('echo "0" > /sys/class/power_supply/battery/charging_enabled') - - return charging_disabled - - -class LocationStarter(object): - def __init__(self): - self.last_good_loc = 0 - def update(self, started_ts, location): - rt = sec_since_boot() - - if location is None or location.accuracy > 50 or location.speed < 2: - # bad location, stop if we havent gotten a location in a while - # dont stop if we're been going for less than a minute - if started_ts: - if rt-self.last_good_loc > 60. and rt-started_ts > 60: - cloudlog.event("location_stop", - ts=rt, - started_ts=started_ts, - last_good_loc=self.last_good_loc, - location=location.to_dict() if location else None) - return False - else: - return True - else: - return False - - self.last_good_loc = rt - - if started_ts: - return True - else: - cloudlog.event("location_start", location=location.to_dict() if location else None) - return location.speed*3.6 > 10 - +def handle_fan_uno(max_cpu_temp, bat_temp, fan_speed): + # TODO: implement better fan control + return int(interp(max_cpu_temp, [40.0, 80.0], [0, 100])) def thermald_thread(): setup_eon_fan() @@ -158,26 +125,29 @@ def thermald_thread(): # prevent LEECO from undervoltage BATT_PERC_OFF = 10 if LEON else 3 + health_timeout = int(1000 * 2 * DT_TRML) # 2x the expected health frequency + # now loop - context = zmq.Context() - thermal_sock = messaging.pub_sock(context, service_list['thermal'].port) - health_sock = messaging.sub_sock(context, service_list['health'].port) - location_sock = messaging.sub_sock(context, service_list['gpsLocation'].port) + thermal_sock = messaging.pub_sock('thermal') + health_sock = messaging.sub_sock('health', timeout=health_timeout) + location_sock = messaging.sub_sock('gpsLocation') + fan_speed = 0 count = 0 off_ts = None started_ts = None - ignition_seen = False started_seen = False - passive_starter = LocationStarter() thermal_status = ThermalStatus.green - health_sock.RCVTIMEO = 1500 - current_filter = FirstOrderFilter(0., CURRENT_TAU, 1.) + thermal_status_prev = ThermalStatus.green + usb_power = True + usb_power_prev = True - # Make sure charging is enabled - charging_disabled = False - os.system('echo "1" > /sys/class/power_supply/battery/charging_enabled') + current_filter = FirstOrderFilter(0., CURRENT_TAU, DT_TRML) + health_prev = None + fw_version_match_prev = True + current_connectivity_alert = None + time_valid_prev = True params = Params() @@ -187,9 +157,16 @@ def thermald_thread(): location = location.gpsLocation if location else None msg = read_thermal() + # clear car params when panda gets disconnected + if health is None and health_prev is not None: + params.panda_disconnect() + health_prev = health + + if health is not None: + usb_power = health.health.usbPowerMode != log.HealthData.UsbPowerMode.client + # loggerd is gated based on free space - statvfs = os.statvfs(ROOT) - avail = (statvfs.f_bavail * 1.0)/statvfs.f_blocks + avail = get_available_percent() / 100.0 # thermal message now also includes free space msg.thermal.freeSpace = avail @@ -211,20 +188,25 @@ def thermald_thread(): msg.thermal.cpu2, msg.thermal.cpu3) / 10.0 max_comp_temp = max(max_cpu_temp, msg.thermal.mem / 10., msg.thermal.gpu / 10.) bat_temp = msg.thermal.bat/1000. - fan_speed = handle_fan(max_cpu_temp, bat_temp, fan_speed) + + if health is not None and health.health.hwType == log.HealthData.HwType.uno: + fan_speed = handle_fan_uno(max_cpu_temp, bat_temp, fan_speed) + else: + fan_speed = handle_fan_eon(max_cpu_temp, bat_temp, fan_speed) + msg.thermal.fanSpeed = fan_speed # thermal logic with hysterisis if max_cpu_temp > 107. or bat_temp >= 63.: # onroad not allowed thermal_status = ThermalStatus.danger - elif max_comp_temp > 95. or bat_temp > 60.: + elif max_comp_temp > 92.5 or bat_temp > 60.: # CPU throttling starts around ~90C # hysteresis between onroad not allowed and engage not allowed thermal_status = clip(thermal_status, ThermalStatus.red, ThermalStatus.danger) - elif max_cpu_temp > 90.0: + elif max_cpu_temp > 87.5: # hysteresis between engage not allowed and uploader not allowed thermal_status = clip(thermal_status, ThermalStatus.yellow, ThermalStatus.red) - elif max_cpu_temp > 85.0: + elif max_cpu_temp > 80.0: # uploader not allowed thermal_status = ThermalStatus.yellow elif max_cpu_temp > 75.0: @@ -236,53 +218,94 @@ def thermald_thread(): # **** starting logic **** - # start constellation of processes when the car starts - ignition = health is not None and health.health.started - ignition_seen = ignition_seen or ignition + # Check for last update time and display alerts if needed + now = datetime.datetime.now() + + # show invalid date/time alert + time_valid = now.year >= 2019 + if time_valid and not time_valid_prev: + params.delete("Offroad_InvalidTime") + if not time_valid and time_valid_prev: + params.put("Offroad_InvalidTime", json.dumps(OFFROAD_ALERTS["Offroad_InvalidTime"])) + time_valid_prev = time_valid + + # Show update prompt + try: + last_update = datetime.datetime.fromisoformat(params.get("LastUpdateTime", encoding='utf8')) + except (TypeError, ValueError): + last_update = now + dt = now - last_update + + if dt.days > DAYS_NO_CONNECTIVITY_MAX: + if current_connectivity_alert != "expired": + current_connectivity_alert = "expired" + params.delete("Offroad_ConnectivityNeededPrompt") + params.put("Offroad_ConnectivityNeeded", json.dumps(OFFROAD_ALERTS["Offroad_ConnectivityNeeded"])) + elif dt.days > DAYS_NO_CONNECTIVITY_PROMPT: + remaining_time = str(DAYS_NO_CONNECTIVITY_MAX - dt.days) + if current_connectivity_alert != "prompt" + remaining_time: + current_connectivity_alert = "prompt" + remaining_time + alert_connectivity_prompt = copy.copy(OFFROAD_ALERTS["Offroad_ConnectivityNeededPrompt"]) + alert_connectivity_prompt["text"] += remaining_time + " days." + params.delete("Offroad_ConnectivityNeeded") + params.put("Offroad_ConnectivityNeededPrompt", json.dumps(alert_connectivity_prompt)) + elif current_connectivity_alert is not None: + current_connectivity_alert = None + params.delete("Offroad_ConnectivityNeeded") + params.delete("Offroad_ConnectivityNeededPrompt") - # add voltage check for ignition - if not ignition_seen and health is not None and health.health.voltage > 13500: - ignition = True + # start constellation of processes when the car starts + ignition = health is not None and (health.health.ignitionLine or health.health.ignitionCan) - do_uninstall = params.get("DoUninstall") == "1" - accepted_terms = params.get("HasAcceptedTerms") == "1" + do_uninstall = params.get("DoUninstall") == b"1" + accepted_terms = params.get("HasAcceptedTerms") == terms_version completed_training = params.get("CompletedTrainingVersion") == training_version + fw_version = params.get("PandaFirmware", encoding="utf8") + fw_version_match = fw_version is None or fw_version.startswith(FW_VERSION) # don't show alert is no panda is connected (None) should_start = ignition # have we seen a panda? passive = (params.get("Passive") == "1") - # start on gps movement if we haven't seen ignition and are in passive mode - should_start = should_start or (not (ignition_seen and health) # seen ignition and panda is connected - and passive - and passive_starter.update(started_ts, location)) - # with 2% left, we killall, otherwise the phone will take a long time to boot should_start = should_start and msg.thermal.freeSpace > 0.02 - # require usb power in passive mode - should_start = should_start and (not passive or msg.thermal.usbOnline) - # confirm we have completed training and aren't uninstalling should_start = should_start and accepted_terms and (passive or completed_training) and (not do_uninstall) + # check for firmware mismatch + should_start = should_start and fw_version_match + + # check if system time is valid + should_start = should_start and time_valid + + if fw_version_match and not fw_version_match_prev: + params.delete("Offroad_PandaFirmwareMismatch") + if not fw_version_match and fw_version_match_prev: + params.put("Offroad_PandaFirmwareMismatch", json.dumps(OFFROAD_ALERTS["Offroad_PandaFirmwareMismatch"])) + # if any CPU gets above 107 or the battery gets above 63, kill all processes # controls will warn with CPU above 95 or battery above 60 if thermal_status >= ThermalStatus.danger: - # TODO: Add a better warning when this is happening should_start = False + if thermal_status_prev < ThermalStatus.danger: + params.put("Offroad_TemperatureTooHigh", json.dumps(OFFROAD_ALERTS["Offroad_TemperatureTooHigh"])) + else: + if thermal_status_prev >= ThermalStatus.danger: + params.delete("Offroad_TemperatureTooHigh") if should_start: off_ts = None if started_ts is None: - params.car_start() started_ts = sec_since_boot() started_seen = True + os.system('echo performance > /sys/class/devfreq/soc:qcom,cpubw/governor') else: started_ts = None if off_ts is None: off_ts = sec_since_boot() + os.system('echo powersave > /sys/class/devfreq/soc:qcom,cpubw/governor') # shutdown if the battery gets lower than 3%, it's discharging, we aren't running for # more than a minute but we were running @@ -290,19 +313,26 @@ def thermald_thread(): started_seen and (sec_since_boot() - off_ts) > 60: os.system('LD_LIBRARY_PATH="" svc power shutdown') - charging_disabled = check_car_battery_voltage(should_start, health, charging_disabled) - - msg.thermal.chargingDisabled = charging_disabled - msg.thermal.chargingError = current_filter.x > 1.0 # if current is > 1A out, then charger might be off + msg.thermal.chargingError = current_filter.x > 0. and msg.thermal.batteryPercent < 90 # if current is positive, then battery is being discharged msg.thermal.started = started_ts is not None msg.thermal.startedTs = int(1e9*(started_ts or 0)) msg.thermal.thermalStatus = thermal_status thermal_sock.send(msg.to_bytes()) - print msg + + if usb_power_prev and not usb_power: + params.put("Offroad_ChargeDisabled", json.dumps(OFFROAD_ALERTS["Offroad_ChargeDisabled"])) + elif usb_power and not usb_power_prev: + params.delete("Offroad_ChargeDisabled") + + thermal_status_prev = thermal_status + usb_power_prev = usb_power + fw_version_match_prev = fw_version_match + + print(msg) # report to server once per minute - if (count%60) == 0: + if (count % int(60. / DT_TRML)) == 0: cloudlog.event("STATUS_PACKET", count=count, health=(health.to_dict() if health else None), @@ -317,4 +347,3 @@ def main(gctx=None): if __name__ == "__main__": main() - diff --git a/selfdrive/tombstoned.py b/selfdrive/tombstoned.py index c76294e6c56864..292ec0408b7599 100644 --- a/selfdrive/tombstoned.py +++ b/selfdrive/tombstoned.py @@ -1,7 +1,6 @@ import os import re import time -import uuid import datetime from raven import Client @@ -17,7 +16,7 @@ def get_tombstones(): def report_tombstone(fn, client): mtime = os.path.getmtime(fn) - with open(fn, "r") as f: + with open(fn, encoding='ISO-8859-1') as f: dat = f.read() # see system/core/debuggerd/tombstone.cpp @@ -38,40 +37,77 @@ def report_tombstone(fn, client): if parsed: parsedict = parsed.groupdict() - message = parsedict.get('thread') or '' - message += parsedict.get('signal') or '' - message += parsedict.get('abort') or '' else: parsedict = {} - message = fn+"\n"+dat[:1024] - client.send( - event_id=uuid.uuid4().hex, - timestamp=datetime.datetime.utcfromtimestamp(mtime), - logger='tombstoned', - platform='other', + thread_line = parsedict.get('thread', '') + thread_parsed = re.match(r'pid: (?P\d+), tid: (?P\d+), name: (?P.*) >>> (?P.*) <<<', thread_line) + if thread_parsed: + thread_parseddict = thread_parsed.groupdict() + else: + thread_parseddict = {} + pid = thread_parseddict.get('pid', '') + tid = thread_parseddict.get('tid', '') + name = thread_parseddict.get('name', 'unknown') + cmd = thread_parseddict.get('cmd', 'unknown') + + signal_line = parsedict.get('signal', '') + signal_parsed = re.match(r'signal (?P.*?), code (?P.*?), fault addr (?P.*)\n', signal_line) + if signal_parsed: + signal_parseddict = signal_parsed.groupdict() + else: + signal_parseddict = {} + signal = signal_parseddict.get('signal', 'unknown') + code = signal_parseddict.get('code', 'unknown') + fault_addr = signal_parseddict.get('fault_addr', '') + + abort_line = parsedict.get('abort', '') + + if parsed: + message = 'Process {} ({}) got signal {} code {}'.format(name, cmd, signal, code) + if abort_line: + message += '\n'+abort_line + else: + message = fn+'\n'+dat[:1024] + + + client.captureMessage( + message=message, + date=datetime.datetime.utcfromtimestamp(mtime), + data={ + 'logger':'tombstoned', + 'platform':'other', + }, sdk={'name': 'tombstoned', 'version': '0'}, extra={ + 'fault_addr': fault_addr, + 'abort_msg': abort_line, + 'pid': pid, + 'tid': tid, + 'name':'{} ({})'.format(name, cmd), 'tombstone_fn': fn, 'header': parsedict.get('header'), 'registers': parsedict.get('registers'), 'backtrace': parsedict.get('backtrace'), 'logtail': logtail, - 'version': version, - 'dirty': not bool(os.environ.get('CLEAN')), }, - user={'id': os.environ.get('DONGLE_ID')}, - message=message, + tags={ + 'name':'{} ({})'.format(name, cmd), + 'signal':signal, + 'code':code, + 'fault_addr':fault_addr, + }, ) - cloudlog.error({"tombstone": message}) + cloudlog.error({'tombstone': message}) -def main(gctx): +def main(gctx=None): initial_tombstones = set(get_tombstones()) client = Client('https://d3b175702f62402c91ade04d1c547e68:b20d68c813c74f63a7cdf9c4039d8f56@sentry.io/157615', - install_sys_hook=False, transport=HTTPTransport, release=version, tags={'dirty': dirty}) + install_sys_hook=False, transport=HTTPTransport, release=version, tags={'dirty': dirty}, string_max_length=10000) + client.user_context({'id': os.environ.get('DONGLE_ID')}) while True: now_tombstones = set(get_tombstones()) @@ -83,4 +119,4 @@ def main(gctx): time.sleep(5) if __name__ == "__main__": - main(None) + main() diff --git a/selfdrive/ui/Makefile b/selfdrive/ui/Makefile index a78a48cf2a9193..1ab8f00c8632cc 100644 --- a/selfdrive/ui/Makefile +++ b/selfdrive/ui/Makefile @@ -1,7 +1,7 @@ CC = clang CXX = clang++ - +BASEDIR = ../.. PHONELIBS = ../../phonelibs WARN_FLAGS = -Werror=implicit-function-declaration \ @@ -10,16 +10,15 @@ WARN_FLAGS = -Werror=implicit-function-declaration \ -Werror=return-type \ -Werror=format-extra-args -CFLAGS = -std=gnu11 -g -fPIC -O2 $(WARN_FLAGS) -CXXFLAGS = -std=c++11 -g -fPIC -O2 $(WARN_FLAGS) +CFLAGS = -std=gnu11 -fPIC -O2 $(WARN_FLAGS) +CXXFLAGS = -std=c++11 -fPIC -O2 $(WARN_FLAGS) + +ZMQ_LIBS = -l:libczmq.a -ZMQ_FLAGS = -I$(PHONELIBS)/zmq/aarch64/include -ZMQ_LIBS = -L$(PHONELIBS)/zmq/aarch64/lib \ - -l:libczmq.a -l:libzmq.a \ - -lgnustl_shared +MESSAGING_FLAGS = -I$(BASEDIR)/selfdrive/messaging +MESSAGING_LIBS = $(BASEDIR)/selfdrive/messaging/messaging.a -CEREAL_CFLAGS = -I$(PHONELIBS)/capnp-c/include -CEREAL_LIBS = -L$(PHONELIBS)/capnp-c/aarch64/lib -l:libcapn.a +CEREAL_LIBS = -l:libcapn.a CEREAL_OBJS = ../../cereal/gen/c/log.capnp.o NANOVG_FLAGS = -I$(PHONELIBS)/nanovg @@ -32,10 +31,22 @@ OPENGL_LIBS = -lGLESv3 OPENSL_LIBS = -lOpenSLES +UUID_LIBS = -luuid + FRAMEBUFFER_LIBS = -lutils -lgui -lEGL -CFLAGS += -DQCOM -CXXFLAGS += -DQCOM +CFLAGS += -DQCOM \ + -I$(PHONELIBS)/android_frameworks_native/include \ + -I$(PHONELIBS)/android_system_core/include \ + -I$(PHONELIBS)/android_hardware_libhardware/include +CXXFLAGS += -DQCOM \ + -I$(PHONELIBS)/android_frameworks_native/include \ + -I$(PHONELIBS)/android_system_core/include \ + -I$(PHONELIBS)/android_hardware_libhardware/include + +# ui can only be compiled for the phone +CFLAGS += -mcpu=cortex-a57 +CXXFLAGS += -mcpu=cortex-a57 OBJS = slplay.o \ ui.o \ @@ -57,17 +68,19 @@ DEPS := $(OBJS:.o=.d) all: ui -ui: $(OBJS) +ui: $(OBJS) $(MESSAGING_LIBS) @echo "[ LINK ] $@" $(CXX) -fPIC -o '$@' $^ \ $(FRAMEBUFFER_LIBS) \ $(CEREAL_LIBS) \ - $(ZMQ_LIBS) \ + -lgnustl_shared \ -L/system/vendor/lib64 \ -lhardware -lui \ + $(ZMQ_LIBS) \ $(OPENGL_LIBS) \ $(OPENCL_LIBS) \ ${OPENSL_LIBS} \ + ${UUID_LIBS} \ -Wl,-rpath=/system/lib64,-rpath=/system/comma/usr/lib \ -lcutils -lm -llog -lui -ladreno_utils @@ -83,6 +96,11 @@ slplay.o: slplay.c $(CXX) $(CXXFLAGS) -MMD \ -Iinclude -I.. -I../.. \ $(OPENCL_FLAGS) \ + $(NANOVG_FLAGS) \ + $(ZMQ_FLAGS) \ + $(MESSAGING_FLAGS) \ + $(CEREAL_CFLAGS) \ + $(JSON_FLAGS) \ -I$(PHONELIBS)/android_frameworks_native/include \ -I$(PHONELIBS)/android_system_core/include \ -I$(PHONELIBS)/android_hardware_libhardware/include \ diff --git a/selfdrive/ui/slplay.c b/selfdrive/ui/slplay.c index 6e5d8b95389140..ddfbad56c5e6ba 100644 --- a/selfdrive/ui/slplay.c +++ b/selfdrive/ui/slplay.c @@ -38,25 +38,25 @@ uri_player* slplay_create_player_for_uri(const char* uri, char **error) { result = (*engineInterface)->CreateAudioPlayer(engineInterface, &player.player, &audioSrc, &audioSnk, 0, NULL, NULL); if (result != SL_RESULT_SUCCESS) { - *error = strdup("Failed to create audio player"); + *error = "Failed to create audio player"; return NULL; } result = (*(player.player))->Realize(player.player, SL_BOOLEAN_FALSE); if (result != SL_RESULT_SUCCESS) { - *error = strdup("Failed to realize audio player"); + *error = "Failed to realize audio player"; return NULL; } result = (*(player.player))->GetInterface(player.player, SL_IID_PLAY, &(player.playInterface)); if (result != SL_RESULT_SUCCESS) { - *error = strdup("Failed to get player interface"); + *error = "Failed to get player interface"; return NULL; } result = (*(player.playInterface))->SetPlayState(player.playInterface, SL_PLAYSTATE_PAUSED); if (result != SL_RESULT_SUCCESS) { - *error = strdup("Failed to initialize playstate to SL_PLAYSTATE_PAUSED"); + *error = "Failed to initialize playstate to SL_PLAYSTATE_PAUSED"; return NULL; } @@ -74,29 +74,29 @@ void slplay_setup(char **error) { SLEngineOption engineOptions[] = {{SL_ENGINEOPTION_THREADSAFE, SL_BOOLEAN_TRUE}}; result = slCreateEngine(&engine, 1, engineOptions, 0, NULL, NULL); if (result != SL_RESULT_SUCCESS) { - *error = strdup("Failed to create OpenSL engine"); + *error = "Failed to create OpenSL engine"; } result = (*engine)->Realize(engine, SL_BOOLEAN_FALSE); if (result != SL_RESULT_SUCCESS) { - *error = strdup("Failed to realize OpenSL engine"); + *error = "Failed to realize OpenSL engine"; } result = (*engine)->GetInterface(engine, SL_IID_ENGINE, &engineInterface); if (result != SL_RESULT_SUCCESS) { - *error = strdup("Failed to realize OpenSL engine"); + *error = "Failed to realize OpenSL engine"; } const SLInterfaceID ids[1] = {SL_IID_VOLUME}; const SLboolean req[1] = {SL_BOOLEAN_FALSE}; result = (*engineInterface)->CreateOutputMix(engineInterface, &outputMix, 1, ids, req); if (result != SL_RESULT_SUCCESS) { - *error = strdup("Failed to create output mix"); + *error = "Failed to create output mix"; } result = (*outputMix)->Realize(outputMix, SL_BOOLEAN_FALSE); if (result != SL_RESULT_SUCCESS) { - *error = strdup("Failed to realize output mix"); + *error = "Failed to realize output mix"; } } @@ -111,7 +111,7 @@ void slplay_destroy() { (*engine)->Destroy(engine); } -void slplay_stop (uri_player* player, char **error) { +void slplay_stop(uri_player* player, char **error) { SLPlayItf playInterface = player->playInterface; SLresult result; @@ -120,7 +120,7 @@ void slplay_stop (uri_player* player, char **error) { result = (*playInterface)->SetPlayState(playInterface, SL_PLAYSTATE_PAUSED); if (result != SL_RESULT_SUCCESS) { - *error = strdup("Failed to set SL_PLAYSTATE_STOPPED"); + *error = "Failed to set SL_PLAYSTATE_STOPPED"; return; } } @@ -164,7 +164,7 @@ void slplay_play (const char *uri, bool loop, char **error) { result = (*playInterface)->SetCallbackEventsMask(playInterface, SL_PLAYEVENT_HEADATEND); if (result != SL_RESULT_SUCCESS) { - *error = strdup("Failed to set callback event mask"); + *error = "Failed to set callback event mask"; return; } } @@ -172,13 +172,13 @@ void slplay_play (const char *uri, bool loop, char **error) { // Reset the audio player result = (*playInterface)->ClearMarkerPosition(playInterface); if (result != SL_RESULT_SUCCESS) { - *error = strdup("Failed to clear marker position"); + *error = "Failed to clear marker position"; return; } result = (*playInterface)->SetPlayState(playInterface, SL_PLAYSTATE_PAUSED); result = (*playInterface)->SetPlayState(playInterface, SL_PLAYSTATE_STOPPED); result = (*playInterface)->SetPlayState(playInterface, SL_PLAYSTATE_PLAYING); if (result != SL_RESULT_SUCCESS) { - *error = strdup("Failed to set SL_PLAYSTATE_PLAYING"); + *error = "Failed to set SL_PLAYSTATE_PLAYING"; } } diff --git a/selfdrive/ui/spinner/Makefile b/selfdrive/ui/spinner/Makefile new file mode 100644 index 00000000000000..93871bb0090d27 --- /dev/null +++ b/selfdrive/ui/spinner/Makefile @@ -0,0 +1,74 @@ +CC = clang +CXX = clang++ + +PHONELIBS = ../../../phonelibs + +WARN_FLAGS = -Werror=implicit-function-declaration \ + -Werror=incompatible-pointer-types \ + -Werror=int-conversion \ + -Werror=return-type \ + -Werror=format-extra-args + +CFLAGS = -std=gnu11 -fPIC -O2 $(WARN_FLAGS) +CXXFLAGS = -std=c++11 -fPIC -O2 $(WARN_FLAGS) + +NANOVG_FLAGS = -I$(PHONELIBS)/nanovg + +OPENGL_LIBS = -lGLESv3 + +FRAMEBUFFER_LIBS = -lutils -lgui -lEGL + +OBJS = spinner.o \ + ../../common/framebuffer.o \ + $(PHONELIBS)/nanovg/nanovg.o \ + ../../common/spinner.o \ + opensans_semibold.o \ + img_spinner_track.o \ + img_spinner_comma.o + +DEPS := $(OBJS:.o=.d) + +.PHONY: all +all: spinner + +spinner: $(OBJS) + @echo "[ LINK ] $@" + $(CXX) -fPIC -o '$@' $^ \ + -s \ + $(FRAMEBUFFER_LIBS) \ + -L/system/vendor/lib64 \ + $(OPENGL_LIBS) \ + -lm -llog + +../../common/framebuffer.o: ../../common/framebuffer.cc + @echo "[ CXX ] $@" + $(CXX) $(CXXFLAGS) -MMD \ + -I$(PHONELIBS)/android_frameworks_native/include \ + -I$(PHONELIBS)/android_system_core/include \ + -I$(PHONELIBS)/android_hardware_libhardware/include \ + -c -o '$@' '$<' + +opensans_semibold.o: ../../assets/fonts/opensans_semibold.ttf + @echo "[ bin2o ] $@" + cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)' + +img_spinner_track.o: ../../assets/img_spinner_track.png + @echo "[ bin2o ] $@" + cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)' + +img_spinner_comma.o: ../../assets/img_spinner_comma.png + @echo "[ bin2o ] $@" + cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)' + +%.o: %.c + @echo "[ CC ] $@" + $(CC) $(CFLAGS) -MMD \ + -I../.. \ + $(NANOVG_FLAGS) \ + -c -o '$@' '$<' + +.PHONY: clean +clean: + rm -f spinner $(OBJS) $(DEPS) + +-include $(DEPS) diff --git a/selfdrive/ui/spinner/spinner b/selfdrive/ui/spinner/spinner index 326a377aa3ffde..828b4b60a9fa59 100755 Binary files a/selfdrive/ui/spinner/spinner and b/selfdrive/ui/spinner/spinner differ diff --git a/selfdrive/ui/spinner/spinner.c b/selfdrive/ui/spinner/spinner.c index 477cfe1cf3abd1..14b452a49ba438 100644 --- a/selfdrive/ui/spinner/spinner.c +++ b/selfdrive/ui/spinner/spinner.c @@ -6,94 +6,16 @@ #include #include +#include #include -#include "nanovg.h" -#define NANOVG_GLES3_IMPLEMENTATION -#include "nanovg_gl.h" -#include "nanovg_gl_utils.h" - #include "common/framebuffer.h" +#include "common/spinner.h" int main(int argc, char** argv) { int err; - const char* spintext = NULL; - if (argc >= 2) { - spintext = argv[1]; - } - - // spinner - int fb_w, fb_h; - EGLDisplay display; - EGLSurface surface; - FramebufferState *fb = framebuffer_init("spinner", 0x00001000, false, - &display, &surface, &fb_w, &fb_h); - assert(fb); - - NVGcontext *vg = nvgCreateGLES3(NVG_ANTIALIAS | NVG_STENCIL_STROKES); - assert(vg); - - int font = nvgCreateFont(vg, "Bold", "../../assets/OpenSans-SemiBold.ttf"); - assert(font >= 0); - - int spinner_img = nvgCreateImage(vg, "../../assets/img_spinner_track.png", 0); - assert(spinner_img >= 0); - int spinner_img_s = 360; - int spinner_img_x = ((fb_w/2)-(spinner_img_s/2)); - int spinner_img_y = 260; - int spinner_img_xc = (fb_w/2); - int spinner_img_yc = (fb_h/2)-100; - int spinner_comma_img = nvgCreateImage(vg, "../../assets/img_spinner_comma.png", 0); - assert(spinner_comma_img >= 0); - - for (int cnt = 0; ; cnt++) { - glClearColor(0.1, 0.1, 0.1, 1.0); - glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - nvgBeginFrame(vg, fb_w, fb_h, 1.0f); - - // background - nvgBeginPath(vg); - NVGpaint bg = nvgLinearGradient(vg, fb_w, 0, fb_w, fb_h, - nvgRGBA(0, 0, 0, 175), nvgRGBA(0, 0, 0, 255)); - nvgFillPaint(vg, bg); - nvgRect(vg, 0, 0, fb_w, fb_h); - nvgFill(vg); - - // spin track - nvgSave(vg); - nvgTranslate(vg, spinner_img_xc, spinner_img_yc); - nvgRotate(vg, (3.75*M_PI * cnt/120.0)); - nvgTranslate(vg, -spinner_img_xc, -spinner_img_yc); - NVGpaint spinner_imgPaint = nvgImagePattern(vg, spinner_img_x, spinner_img_y, - spinner_img_s, spinner_img_s, 0, spinner_img, 0.6f); - nvgBeginPath(vg); - nvgFillPaint(vg, spinner_imgPaint); - nvgRect(vg, spinner_img_x, spinner_img_y, spinner_img_s, spinner_img_s); - nvgFill(vg); - nvgRestore(vg); - - // comma - NVGpaint comma_imgPaint = nvgImagePattern(vg, spinner_img_x, spinner_img_y, - spinner_img_s, spinner_img_s, 0, spinner_comma_img, 1.0f); - nvgBeginPath(vg); - nvgFillPaint(vg, comma_imgPaint); - nvgRect(vg, spinner_img_x, spinner_img_y, spinner_img_s, spinner_img_s); - nvgFill(vg); - - // message - if (spintext) { - nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_TOP); - nvgFontSize(vg, 96.0f); - nvgText(vg, fb_w/2, (fb_h*2/3)+24, spintext, NULL); - } - - nvgEndFrame(vg); - eglSwapBuffers(display, surface); - assert(glGetError() == GL_NO_ERROR); - } + spin(argc, argv); return 0; } diff --git a/selfdrive/ui/start.py b/selfdrive/ui/start.py new file mode 100755 index 00000000000000..a1d00ce145da4a --- /dev/null +++ b/selfdrive/ui/start.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 +import os + +assert os.system("make") == 0 +os.environ['LD_LIBRARY_PATH'] = "/system/lib64:"+os.environ['LD_LIBRARY_PATH'] +os.execv("./ui", ["ui"]) + diff --git a/selfdrive/ui/start.sh b/selfdrive/ui/start.sh deleted file mode 100755 index 89704a5b6edf93..00000000000000 --- a/selfdrive/ui/start.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -set -e - -make -export LD_LIBRARY_PATH=/system/lib64:$LD_LIBRARY_PATH -exec ./ui diff --git a/selfdrive/ui/ui.c b/selfdrive/ui/ui.c deleted file mode 100644 index 33e35d3810f4f2..00000000000000 --- a/selfdrive/ui/ui.c +++ /dev/null @@ -1,2181 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include - -#include "nanovg.h" -#define NANOVG_GLES3_IMPLEMENTATION -#include "nanovg_gl.h" -#include "nanovg_gl_utils.h" - -#include "common/timing.h" -#include "common/util.h" -#include "common/swaglog.h" -#include "common/mat.h" -#include "common/glutil.h" - -#include "common/touch.h" -#include "common/framebuffer.h" -#include "common/visionipc.h" -#include "common/visionimg.h" -#include "common/modeldata.h" -#include "common/params.h" - -#include "cereal/gen/c/log.capnp.h" -#include "slplay.h" - -#define STATUS_STOPPED 0 -#define STATUS_DISENGAGED 1 -#define STATUS_ENGAGED 2 -#define STATUS_WARNING 3 -#define STATUS_ALERT 4 -#define STATUS_MAX 5 - -#define ALERTSIZE_NONE 0 -#define ALERTSIZE_SMALL 1 -#define ALERTSIZE_MID 2 -#define ALERTSIZE_FULL 3 - -#define UI_BUF_COUNT 4 -//#define DEBUG_TURN - -const int vwp_w = 1920; -const int vwp_h = 1080; -const int nav_w = 640; -const int nav_ww= 760; -const int sbr_w = 300; -const int bdr_s = 30; -const int box_x = sbr_w+bdr_s; -const int box_y = bdr_s; -const int box_w = vwp_w-sbr_w-(bdr_s*2); -const int box_h = vwp_h-(bdr_s*2); -const int viz_w = vwp_w-(bdr_s*2); -const int header_h = 420; -const int footer_h = 280; -const int footer_y = vwp_h-bdr_s-footer_h; - -const int UI_FREQ = 60; // Hz - -const uint8_t bg_colors[][4] = { - [STATUS_STOPPED] = {0x07, 0x23, 0x39, 0xff}, - [STATUS_DISENGAGED] = {0x17, 0x33, 0x49, 0xff}, - [STATUS_ENGAGED] = {0x17, 0x86, 0x44, 0xff}, - [STATUS_WARNING] = {0xDA, 0x6F, 0x25, 0xff}, - [STATUS_ALERT] = {0xC9, 0x22, 0x31, 0xff}, -}; - -const uint8_t alert_colors[][4] = { - [STATUS_STOPPED] = {0x07, 0x23, 0x39, 0xf1}, - [STATUS_DISENGAGED] = {0x17, 0x33, 0x49, 0xc8}, - [STATUS_ENGAGED] = {0x17, 0x86, 0x44, 0xf1}, - [STATUS_WARNING] = {0xDA, 0x6F, 0x25, 0xf1}, - [STATUS_ALERT] = {0xC9, 0x22, 0x31, 0xf1}, -}; - -const int alert_sizes[] = { - [ALERTSIZE_NONE] = 0, - [ALERTSIZE_SMALL] = 241, - [ALERTSIZE_MID] = 390, - [ALERTSIZE_FULL] = vwp_h, -}; - -const int SET_SPEED_NA = 255; - -// TODO: this is also hardcoded in common/transformations/camera.py -const mat3 intrinsic_matrix = (mat3){{ - 910., 0., 582., - 0., 910., 437., - 0., 0., 1. -}}; - -typedef struct UIScene { - int frontview; - int fullview; - - int transformed_width, transformed_height; - - uint64_t model_ts; - ModelData model; - - float mpc_x[50]; - float mpc_y[50]; - - bool world_objects_visible; - mat3 warp_matrix; // transformed box -> frame. - mat4 extrinsic_matrix; // Last row is 0 so we can use mat4. - - float v_cruise; - uint64_t v_cruise_update_ts; - float v_ego; - float v_curvature; - bool decel_for_turn; - - float speedlimit; - bool speedlimit_valid; - bool map_valid; - - float curvature; - int engaged; - bool engageable; - bool monitoring_active; - - bool uilayout_sidebarcollapsed; - bool uilayout_mapenabled; - // responsive layout - int ui_viz_rx; - int ui_viz_rw; - int ui_viz_ro; - - int lead_status; - float lead_d_rel, lead_y_rel, lead_v_rel; - - int front_box_x, front_box_y, front_box_width, front_box_height; - - uint64_t alert_ts; - char alert_text1[1024]; - char alert_text2[1024]; - uint8_t alert_size; - float alert_blinkingrate; - - float awareness_status; - - uint64_t started_ts; - - // Used to show gps planner status - bool gps_planner_active; - - bool is_playing_alert; -} UIScene; - -typedef struct UIState { - pthread_mutex_t lock; - pthread_cond_t bg_cond; - - FramebufferState *fb; - int fb_w, fb_h; - EGLDisplay display; - EGLSurface surface; - - NVGcontext *vg; - - int font_courbd; - int font_sans_regular; - int font_sans_semibold; - int font_sans_bold; - int img_wheel; - int img_turn; - int img_face; - int img_map; - - zsock_t *thermal_sock; - void *thermal_sock_raw; - zsock_t *model_sock; - void *model_sock_raw; - zsock_t *live100_sock; - void *live100_sock_raw; - zsock_t *livecalibration_sock; - void *livecalibration_sock_raw; - zsock_t *live20_sock; - void *live20_sock_raw; - zsock_t *livempc_sock; - void *livempc_sock_raw; - zsock_t *plus_sock; - void *plus_sock_raw; - zsock_t *map_data_sock; - void *map_data_sock_raw; - - zsock_t *uilayout_sock; - void *uilayout_sock_raw; - - int plus_state; - - // vision state - bool vision_connected; - bool vision_connect_firstrun; - int ipc_fd; - - VIPCBuf bufs[UI_BUF_COUNT]; - VIPCBuf front_bufs[UI_BUF_COUNT]; - int cur_vision_idx; - int cur_vision_front_idx; - - GLuint frame_program; - GLuint frame_texs[UI_BUF_COUNT]; - GLuint frame_front_texs[UI_BUF_COUNT]; - - GLint frame_pos_loc, frame_texcoord_loc; - GLint frame_texture_loc, frame_transform_loc; - - GLuint line_program; - GLint line_pos_loc, line_color_loc; - GLint line_transform_loc; - - unsigned int rgb_width, rgb_height, rgb_stride; - size_t rgb_buf_len; - mat4 rgb_transform; - - unsigned int rgb_front_width, rgb_front_height, rgb_front_stride; - size_t rgb_front_buf_len; - - UIScene scene; - - bool awake; - int awake_timeout; - - int volume_timeout; - int speed_lim_off_timeout; - int is_metric_timeout; - int limit_set_speed_timeout; - - int status; - bool is_metric; - bool limit_set_speed; - float speed_lim_off; - bool is_ego_over_limit; - bool passive; - char alert_type[64]; - char alert_sound[64]; - int alert_size; - float alert_blinking_alpha; - bool alert_blinked; - - float light_sensor; -} UIState; - -static int last_brightness = -1; -static void set_brightness(UIState *s, int brightness) { - if (last_brightness != brightness && (s->awake || brightness == 0)) { - FILE *f = fopen("/sys/class/leds/lcd-backlight/brightness", "wb"); - if (f != NULL) { - fprintf(f, "%d", brightness); - fclose(f); - last_brightness = brightness; - } - } -} - -static void set_awake(UIState *s, bool awake) { - if (awake) { - // 30 second timeout at 30 fps - s->awake_timeout = 30*30; - } - if (s->awake != awake) { - s->awake = awake; - - if (awake) { - LOG("awake normal"); - framebuffer_set_power(s->fb, HWC_POWER_MODE_NORMAL); - } else { - LOG("awake off"); - set_brightness(s, 0); - framebuffer_set_power(s->fb, HWC_POWER_MODE_OFF); - } - } -} - -static void set_volume(UIState *s, int volume) { - char volume_change_cmd[64]; - sprintf(volume_change_cmd, "service call audio 3 i32 3 i32 %d i32 1", volume); - - // 5 second timeout at 60fps - s->volume_timeout = 5 * UI_FREQ; - int volume_changed = system(volume_change_cmd); -} - -volatile int do_exit = 0; -static void set_do_exit(int sig) { - do_exit = 1; -} - -static void read_speed_lim_off(UIState *s) { - char *speed_lim_off = NULL; - read_db_value(NULL, "SpeedLimitOffset", &speed_lim_off, NULL); - s->speed_lim_off = 0.; - if (speed_lim_off) { - s->speed_lim_off = strtod(speed_lim_off, NULL); - free(speed_lim_off); - } - s->speed_lim_off_timeout = 2 * UI_FREQ; // 0.5Hz -} - -static void read_is_metric(UIState *s) { - char *is_metric; - const int result = read_db_value(NULL, "IsMetric", &is_metric, NULL); - if (result == 0) { - s->is_metric = is_metric[0] == '1'; - free(is_metric); - } - s->is_metric_timeout = 2 * UI_FREQ; // 0.5Hz -} - -static void read_limit_set_speed(UIState *s) { - char *limit_set_speed; - const int result = read_db_value(NULL, "LimitSetSpeed", &limit_set_speed, NULL); - if (result == 0) { - s->limit_set_speed = limit_set_speed[0] == '1'; - free(limit_set_speed); - } - s->limit_set_speed_timeout = 2 * UI_FREQ; // 0.2Hz -} -static const char frame_vertex_shader[] = - "attribute vec4 aPosition;\n" - "attribute vec4 aTexCoord;\n" - "uniform mat4 uTransform;\n" - "varying vec4 vTexCoord;\n" - "void main() {\n" - " gl_Position = uTransform * aPosition;\n" - " vTexCoord = aTexCoord;\n" - "}\n"; - -static const char frame_fragment_shader[] = - "precision mediump float;\n" - "uniform sampler2D uTexture;\n" - "varying vec4 vTexCoord;\n" - "void main() {\n" - " gl_FragColor = texture2D(uTexture, vTexCoord.xy);\n" - "}\n"; - -static const char line_vertex_shader[] = - "attribute vec4 aPosition;\n" - "attribute vec4 aColor;\n" - "uniform mat4 uTransform;\n" - "varying vec4 vColor;\n" - "void main() {\n" - " gl_Position = uTransform * aPosition;\n" - " vColor = aColor;\n" - "}\n"; - -static const char line_fragment_shader[] = - "precision mediump float;\n" - "uniform sampler2D uTexture;\n" - "varying vec4 vColor;\n" - "void main() {\n" - " gl_FragColor = vColor;\n" - "}\n"; - - -static const mat4 device_transform = {{ - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0, -}}; - -// frame from 4/3 to box size with a 2x zoom -static const mat4 frame_transform = {{ - 2*(4./3.)/((float)viz_w/box_h), 0.0, 0.0, 0.0, - 0.0, 2.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0, -}}; - -// frame from 4/3 to 16/9 display -static const mat4 full_to_wide_frame_transform = {{ - .75, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0, -}}; - -typedef struct { - const char* name; - const char* uri; - bool loop; -} sound_file; - -sound_file sound_table[] = { - { "chimeDisengage", "../assets/sounds/disengaged.wav", false }, - { "chimeEngage", "../assets/sounds/engaged.wav", false }, - { "chimeWarning1", "../assets/sounds/warning_1.wav", false }, - { "chimeWarning2", "../assets/sounds/warning_2.wav", false }, - { "chimeWarningRepeat", "../assets/sounds/warning_2.wav", true }, - { "chimeError", "../assets/sounds/error.wav", false }, - { "chimePrompt", "../assets/sounds/error.wav", false }, - { NULL, NULL, false }, -}; - -sound_file* get_sound_file_by_name(const char* name) { - for (sound_file *s = sound_table; s->name != NULL; s++) { - if (strcmp(s->name, name) == 0) { - return s; - } - } - - return NULL; -} - -void ui_sound_init(char **error) { - slplay_setup(error); - if (*error) return; - - for (sound_file *s = sound_table; s->name != NULL; s++) { - slplay_create_player_for_uri(s->uri, error); - if (*error) return; - } -} - -static void ui_init(UIState *s) { - memset(s, 0, sizeof(UIState)); - - pthread_mutex_init(&s->lock, NULL); - pthread_cond_init(&s->bg_cond, NULL); - - // init connections - - s->thermal_sock = zsock_new_sub(">tcp://127.0.0.1:8005", ""); - assert(s->thermal_sock); - s->thermal_sock_raw = zsock_resolve(s->thermal_sock); - - s->model_sock = zsock_new_sub(">tcp://127.0.0.1:8009", ""); - assert(s->model_sock); - s->model_sock_raw = zsock_resolve(s->model_sock); - - s->live100_sock = zsock_new_sub(">tcp://127.0.0.1:8007", ""); - assert(s->live100_sock); - s->live100_sock_raw = zsock_resolve(s->live100_sock); - - s->uilayout_sock = zsock_new_sub(">tcp://127.0.0.1:8060", ""); - assert(s->uilayout_sock); - s->uilayout_sock_raw = zsock_resolve(s->uilayout_sock); - - s->livecalibration_sock = zsock_new_sub(">tcp://127.0.0.1:8019", ""); - assert(s->livecalibration_sock); - s->livecalibration_sock_raw = zsock_resolve(s->livecalibration_sock); - - s->live20_sock = zsock_new_sub(">tcp://127.0.0.1:8012", ""); - assert(s->live20_sock); - s->live20_sock_raw = zsock_resolve(s->live20_sock); - - s->livempc_sock = zsock_new_sub(">tcp://127.0.0.1:8035", ""); - assert(s->livempc_sock); - s->livempc_sock_raw = zsock_resolve(s->livempc_sock); - - s->plus_sock = zsock_new_sub(">tcp://127.0.0.1:8037", ""); - assert(s->plus_sock); - s->plus_sock_raw = zsock_resolve(s->plus_sock); - - s->map_data_sock = zsock_new_sub(">tcp://127.0.0.1:8065", ""); - assert(s->map_data_sock); - s->map_data_sock_raw = zsock_resolve(s->map_data_sock); - - s->ipc_fd = -1; - - // init display - s->fb = framebuffer_init("ui", 0x00010000, true, - &s->display, &s->surface, &s->fb_w, &s->fb_h); - assert(s->fb); - - set_awake(s, true); - - // init drawing - s->vg = nvgCreateGLES3(NVG_ANTIALIAS | NVG_STENCIL_STROKES | NVG_DEBUG); - assert(s->vg); - - s->font_courbd = nvgCreateFont(s->vg, "courbd", "../assets/courbd.ttf"); - assert(s->font_courbd >= 0); - s->font_sans_regular = nvgCreateFont(s->vg, "sans-regular", "../assets/OpenSans-Regular.ttf"); - assert(s->font_sans_regular >= 0); - s->font_sans_semibold = nvgCreateFont(s->vg, "sans-semibold", "../assets/OpenSans-SemiBold.ttf"); - assert(s->font_sans_semibold >= 0); - s->font_sans_bold = nvgCreateFont(s->vg, "sans-bold", "../assets/OpenSans-Bold.ttf"); - assert(s->font_sans_bold >= 0); - - assert(s->img_wheel >= 0); - s->img_wheel = nvgCreateImage(s->vg, "../assets/img_chffr_wheel.png", 1); - - assert(s->img_turn >= 0); - s->img_turn = nvgCreateImage(s->vg, "../assets/img_trafficSign_turn.png", 1); - - assert(s->img_face >= 0); - s->img_face = nvgCreateImage(s->vg, "../assets/img_driver_face.png", 1); - - assert(s->img_map >= 0); - s->img_map = nvgCreateImage(s->vg, "../assets/img_map.png", 1); - - // init gl - s->frame_program = load_program(frame_vertex_shader, frame_fragment_shader); - assert(s->frame_program); - - s->frame_pos_loc = glGetAttribLocation(s->frame_program, "aPosition"); - s->frame_texcoord_loc = glGetAttribLocation(s->frame_program, "aTexCoord"); - - s->frame_texture_loc = glGetUniformLocation(s->frame_program, "uTexture"); - s->frame_transform_loc = glGetUniformLocation(s->frame_program, "uTransform"); - - s->line_program = load_program(line_vertex_shader, line_fragment_shader); - assert(s->line_program); - - s->line_pos_loc = glGetAttribLocation(s->line_program, "aPosition"); - s->line_color_loc = glGetAttribLocation(s->line_program, "aColor"); - s->line_transform_loc = glGetUniformLocation(s->line_program, "uTransform"); - - glViewport(0, 0, s->fb_w, s->fb_h); - - glDisable(GL_DEPTH_TEST); - - assert(glGetError() == GL_NO_ERROR); - - { - char *value; - const int result = read_db_value(NULL, "Passive", &value, NULL); - if (result == 0) { - s->passive = value[0] == '1'; - free(value); - } - } -} - -static void ui_init_vision(UIState *s, const VisionStreamBufs back_bufs, - int num_back_fds, const int *back_fds, - const VisionStreamBufs front_bufs, int num_front_fds, - const int *front_fds) { - const VisionUIInfo ui_info = back_bufs.buf_info.ui_info; - - assert(num_back_fds == UI_BUF_COUNT); - assert(num_front_fds == UI_BUF_COUNT); - - vipc_bufs_load(s->bufs, &back_bufs, num_back_fds, back_fds); - vipc_bufs_load(s->front_bufs, &front_bufs, num_front_fds, front_fds); - - s->cur_vision_idx = -1; - s->cur_vision_front_idx = -1; - - s->scene = (UIScene){ - .frontview = getenv("FRONTVIEW") != NULL, - .fullview = getenv("FULLVIEW") != NULL, - .transformed_width = ui_info.transformed_width, - .transformed_height = ui_info.transformed_height, - .front_box_x = ui_info.front_box_x, - .front_box_y = ui_info.front_box_y, - .front_box_width = ui_info.front_box_width, - .front_box_height = ui_info.front_box_height, - .world_objects_visible = false, // Invisible until we receive a calibration message. - .gps_planner_active = false, - }; - - s->rgb_width = back_bufs.width; - s->rgb_height = back_bufs.height; - s->rgb_stride = back_bufs.stride; - s->rgb_buf_len = back_bufs.buf_len; - - s->rgb_front_width = front_bufs.width; - s->rgb_front_height = front_bufs.height; - s->rgb_front_stride = front_bufs.stride; - s->rgb_front_buf_len = front_bufs.buf_len; - - s->rgb_transform = (mat4){{ - 2.0/s->rgb_width, 0.0, 0.0, -1.0, - 0.0, 2.0/s->rgb_height, 0.0, -1.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0, - }}; - - read_speed_lim_off(s); - read_is_metric(s); - read_limit_set_speed(s); - s->is_metric_timeout = UI_FREQ / 2; // offset so values isn't read together with limit offset - s->limit_set_speed_timeout = UI_FREQ; // offset so values isn't read together with limit offset -} - -static void ui_draw_transformed_box(UIState *s, uint32_t color) { - const UIScene *scene = &s->scene; - - const mat3 bbt = scene->warp_matrix; - - struct { - vec3 pos; - uint32_t color; - } verts[] = { - {matvecmul3(bbt, (vec3){{0.0, 0.0, 1.0,}}), color}, - {matvecmul3(bbt, (vec3){{scene->transformed_width, 0.0, 1.0,}}), color}, - {matvecmul3(bbt, (vec3){{scene->transformed_width, scene->transformed_height, 1.0,}}), color}, - {matvecmul3(bbt, (vec3){{0.0, scene->transformed_height, 1.0,}}), color}, - {matvecmul3(bbt, (vec3){{0.0, 0.0, 1.0,}}), color}, - }; - - for (int i=0; irgb_height - verts[i].pos.v[1] / verts[i].pos.v[2]; - } - - glUseProgram(s->line_program); - - mat4 out_mat = matmul(device_transform, - matmul(frame_transform, s->rgb_transform)); - glUniformMatrix4fv(s->line_transform_loc, 1, GL_TRUE, out_mat.v); - - glEnableVertexAttribArray(s->line_pos_loc); - glVertexAttribPointer(s->line_pos_loc, 2, GL_FLOAT, GL_FALSE, sizeof(verts[0]), &verts[0].pos.v[0]); - - glEnableVertexAttribArray(s->line_color_loc); - glVertexAttribPointer(s->line_color_loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(verts[0]), &verts[0].color); - - assert(glGetError() == GL_NO_ERROR); - glDrawArrays(GL_LINE_STRIP, 0, ARRAYSIZE(verts)); -} - -// Projects a point in car to space to the corresponding point in full frame -// image space. -vec3 car_space_to_full_frame(const UIState *s, vec4 car_space_projective) { - const UIScene *scene = &s->scene; - - // We'll call the car space point p. - // First project into normalized image coordinates with the extrinsics matrix. - const vec4 Ep4 = matvecmul(scene->extrinsic_matrix, car_space_projective); - - // The last entry is zero because of how we store E (to use matvecmul). - const vec3 Ep = {{Ep4.v[0], Ep4.v[1], Ep4.v[2]}}; - const vec3 KEp = matvecmul3(intrinsic_matrix, Ep); - - // Project. - const vec3 p_image = {{KEp.v[0] / KEp.v[2], KEp.v[1] / KEp.v[2], 1.}}; - return p_image; -} - -// Calculate an interpolation between two numbers at a specific increment -static float lerp(float v0, float v1, float t) { - return (1 - t) * v0 + t * v1; -} - -static void draw_chevron(UIState *s, float x_in, float y_in, float sz, - NVGcolor fillColor, NVGcolor glowColor) { - const UIScene *scene = &s->scene; - - nvgSave(s->vg); - - nvgTranslate(s->vg, 240.0f, 0.0); - nvgTranslate(s->vg, -1440.0f / 2, -1080.0f / 2); - nvgScale(s->vg, 2.0, 2.0); - nvgScale(s->vg, 1440.0f / s->rgb_width, 1080.0f / s->rgb_height); - - const vec4 p_car_space = (vec4){{x_in, y_in, 0., 1.}}; - const vec3 p_full_frame = car_space_to_full_frame(s, p_car_space); - - sz *= 30; - sz /= (x_in / 3 + 30); - if (sz > 30) sz = 30; - if (sz < 15) sz = 15; - - float x = p_full_frame.v[0]; - float y = p_full_frame.v[1]; - - // glow - nvgBeginPath(s->vg); - float g_xo = sz/5; - float g_yo = sz/10; - if (x >= 0 && y >= 0.) { - nvgMoveTo(s->vg, x+(sz*1.35)+g_xo, y+sz+g_yo); - nvgLineTo(s->vg, x, y-g_xo); - nvgLineTo(s->vg, x-(sz*1.35)-g_xo, y+sz+g_yo); - nvgLineTo(s->vg, x+(sz*1.35)+g_xo, y+sz+g_yo); - nvgClosePath(s->vg); - } - nvgFillColor(s->vg, glowColor); - nvgFill(s->vg); - - // chevron - nvgBeginPath(s->vg); - if (x >= 0 && y >= 0.) { - nvgMoveTo(s->vg, x+(sz*1.25), y+sz); - nvgLineTo(s->vg, x, y); - nvgLineTo(s->vg, x-(sz*1.25), y+sz); - nvgLineTo(s->vg, x+(sz*1.25), y+sz); - nvgClosePath(s->vg); - } - nvgFillColor(s->vg, fillColor); - nvgFill(s->vg); - - nvgRestore(s->vg); -} - -static void ui_draw_lane_line(UIState *s, const float *points, float off, - NVGcolor color, bool is_ghost) { - const UIScene *scene = &s->scene; - - nvgSave(s->vg); - nvgTranslate(s->vg, 240.0f, 0.0); // rgb-box space - nvgTranslate(s->vg, -1440.0f / 2, -1080.0f / 2); // zoom 2x - nvgScale(s->vg, 2.0, 2.0); - nvgScale(s->vg, 1440.0f / s->rgb_width, 1080.0f / s->rgb_height); - nvgBeginPath(s->vg); - - bool started = false; - for (int i=0; i<49; i++) { - float px = (float)i; - float py = points[i] - off; - vec4 p_car_space = (vec4){{px, py, 0., 1.}}; - vec3 p_full_frame = car_space_to_full_frame(s, p_car_space); - float x = p_full_frame.v[0]; - float y = p_full_frame.v[1]; - if (x < 0 || y < 0.) { - continue; - } - if (!started) { - nvgMoveTo(s->vg, x, y); - started = true; - } else { - nvgLineTo(s->vg, x, y); - } - } - - for (int i=49; i>0; i--) { - float px = (float)i; - float py = is_ghost?(points[i]-off):(points[i]+off); - vec4 p_car_space = (vec4){{px, py, 0., 1.}}; - vec3 p_full_frame = car_space_to_full_frame(s, p_car_space); - float x = p_full_frame.v[0]; - float y = p_full_frame.v[1]; - if (x < 0 || y < 0.) { - continue; - } - nvgLineTo(s->vg, x, y); - } - - nvgClosePath(s->vg); - nvgFillColor(s->vg, color); - nvgFill(s->vg); - nvgRestore(s->vg); -} - -static void ui_draw_lane(UIState *s, const PathData path, NVGcolor color) { - ui_draw_lane_line(s, path.points, 0.025*path.prob, color, false); - float var = min(path.std, 0.7); - color.a /= 4; - ui_draw_lane_line(s, path.points, -var, color, true); - ui_draw_lane_line(s, path.points, var, color, true); -} - -static void ui_draw_track(UIState *s, bool is_mpc) { - const UIScene *scene = &s->scene; - const PathData path = scene->model.path; - const float *mpc_x_coords = &scene->mpc_x[0]; - const float *mpc_y_coords = &scene->mpc_y[0]; - - nvgSave(s->vg); - nvgTranslate(s->vg, 240.0f, 0.0); // rgb-box space - nvgTranslate(s->vg, -1440.0f / 2, -1080.0f / 2); // zoom 2x - nvgScale(s->vg, 2.0, 2.0); - nvgScale(s->vg, 1440.0f / s->rgb_width, 1080.0f / s->rgb_height); - nvgBeginPath(s->vg); - - bool started = false; - float off = is_mpc?0.3:0.5; - float lead_d = scene->lead_d_rel*2.; - float path_height = is_mpc?(lead_d>5.)?min(lead_d, 25.)-min(lead_d*0.35, 10.):20. - :(lead_d>0.)?min(lead_d, 50.)-min(lead_d*0.35, 10.):49.; - - // left side up - for (int i=0; i<=path_height; i++) { - float px, py, mpx; - if (is_mpc) { - mpx = i==0?0.0:mpc_x_coords[i]; - px = lerp(mpx+1.0, mpx, i/100.0); - py = mpc_y_coords[i] - off; - } else { - px = lerp(i+1.0, i, i/100.0); - py = path.points[i] - off; - } - - vec4 p_car_space = (vec4){{px, py, 0., 1.}}; - vec3 p_full_frame = car_space_to_full_frame(s, p_car_space); - float x = p_full_frame.v[0]; - float y = p_full_frame.v[1]; - if (x < 0 || y < 0) { - continue; - } - - if (!started) { - nvgMoveTo(s->vg, x, y); - started = true; - } else { - nvgLineTo(s->vg, x, y); - } - } - - // right side down - for (int i=path_height; i>=0; i--) { - float px, py, mpx; - if (is_mpc) { - mpx = i==0?0.0:mpc_x_coords[i]; - px = lerp(mpx+1.0, mpx, i/100.0); - py = mpc_y_coords[i] + off; - } else { - px = lerp(i+1.0, i, i/100.0); - py = path.points[i] + off; - } - - vec4 p_car_space = (vec4){{px, py, 0., 1.}}; - vec3 p_full_frame = car_space_to_full_frame(s, p_car_space); - float x = p_full_frame.v[0]; - float y = p_full_frame.v[1]; - if (x < 0 || y < 0.) { - continue; - } - - nvgLineTo(s->vg, x, y); - } - - nvgClosePath(s->vg); - - NVGpaint track_bg; - if (is_mpc) { - // Draw colored MPC track - const uint8_t *clr = bg_colors[s->status]; - track_bg = nvgLinearGradient(s->vg, vwp_w, vwp_h, vwp_w, vwp_h*.4, - nvgRGBA(clr[0], clr[1], clr[2], 255), nvgRGBA(clr[0], clr[1], clr[2], 255/2)); - } else { - // Draw white vision track - track_bg = nvgLinearGradient(s->vg, vwp_w, vwp_h, vwp_w, vwp_h*.4, - nvgRGBA(255, 255, 255, 255), nvgRGBA(255, 255, 255, 0)); - } - - nvgFillPaint(s->vg, track_bg); - nvgFill(s->vg); - nvgRestore(s->vg); -} - -static void draw_steering(UIState *s, float curvature) { - float points[50]; - for (int i = 0; i < 50; i++) { - float y_actual = i * tan(asin(clamp(i * curvature, -0.999, 0.999)) / 2.); - points[i] = y_actual; - } - - // ui_draw_lane_edge(s, points, 0.0, nvgRGBA(0, 0, 255, 128), 5); -} - -static void draw_frame(UIState *s) { - const UIScene *scene = &s->scene; - - float x1, x2, y1, y2; - if (s->scene.frontview) { - // flip horizontally so it looks like a mirror - x1 = 0.0; - x2 = 1.0; - y1 = 1.0; - y2 = 0.0; - } else { - x1 = 1.0; - x2 = 0.0; - y1 = 1.0; - y2 = 0.0; - } - - mat4 out_mat; - if (s->scene.frontview || s->scene.fullview) { - out_mat = matmul(device_transform, full_to_wide_frame_transform); - } else { - out_mat = matmul(device_transform, frame_transform); - } - - const uint8_t frame_indicies[] = {0, 1, 2, 0, 2, 3}; - const float frame_coords[4][4] = { - {-1.0, -1.0, x2, y1}, //bl - {-1.0, 1.0, x2, y2}, //tl - { 1.0, 1.0, x1, y2}, //tr - { 1.0, -1.0, x1, y1}, //br - }; - - glActiveTexture(GL_TEXTURE0); - if (s->scene.frontview && s->cur_vision_front_idx >= 0) { - glBindTexture(GL_TEXTURE_2D, s->frame_front_texs[s->cur_vision_front_idx]); - } else if (!scene->frontview && s->cur_vision_idx >= 0) { - glBindTexture(GL_TEXTURE_2D, s->frame_texs[s->cur_vision_idx]); - } - - glUseProgram(s->frame_program); - - glUniform1i(s->frame_texture_loc, 0); - glUniformMatrix4fv(s->frame_transform_loc, 1, GL_TRUE, out_mat.v); - - glEnableVertexAttribArray(s->frame_pos_loc); - glVertexAttribPointer(s->frame_pos_loc, 2, GL_FLOAT, GL_FALSE, - sizeof(frame_coords[0]), frame_coords); - - glEnableVertexAttribArray(s->frame_texcoord_loc); - glVertexAttribPointer(s->frame_texcoord_loc, 2, GL_FLOAT, GL_FALSE, - sizeof(frame_coords[0]), &frame_coords[0][2]); - - assert(glGetError() == GL_NO_ERROR); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, &frame_indicies[0]); -} - -static void ui_draw_vision_lanes(UIState *s) { - const UIScene *scene = &s->scene; - // Draw left lane edge - ui_draw_lane( - s, scene->model.left_lane, - nvgRGBAf(1.0, 1.0, 1.0, scene->model.left_lane.prob)); - - // Draw right lane edge - ui_draw_lane( - s, scene->model.right_lane, - nvgRGBAf(1.0, 1.0, 1.0, scene->model.right_lane.prob)); - - // Draw vision path - ui_draw_track(s, false); - - if (scene->engaged) { - // Draw MPC path when engaged - ui_draw_track(s, true); - } -} - -// Draw all world space objects. -static void ui_draw_world(UIState *s) { - const UIScene *scene = &s->scene; - if (!scene->world_objects_visible) { - return; - } - - if ((nanos_since_boot() - scene->model_ts) < 1000000000ULL) { - // Draw lane edges and vision/mpc tracks - ui_draw_vision_lanes(s); - } - - if (scene->lead_status) { - // Draw lead car indicator - float fillAlpha = 0; - float speedBuff = 10.; - float leadBuff = 40.; - if (scene->lead_d_rel < leadBuff) { - fillAlpha = 255*(1.0-(scene->lead_d_rel/leadBuff)); - if (scene->lead_v_rel < 0) { - fillAlpha += 255*(-1*(scene->lead_v_rel/speedBuff)); - } - fillAlpha = (int)(min(fillAlpha, 255)); - } - draw_chevron(s, scene->lead_d_rel+2.7, scene->lead_y_rel, 25, - nvgRGBA(201, 34, 49, fillAlpha), nvgRGBA(218, 202, 37, 255)); - } -} - -static void ui_draw_vision_maxspeed(UIState *s) { - const UIScene *scene = &s->scene; - int ui_viz_rx = scene->ui_viz_rx; - int ui_viz_rw = scene->ui_viz_rw; - - char maxspeed_str[32]; - float maxspeed = s->scene.v_cruise; - int maxspeed_calc = maxspeed * 0.6225 + 0.5; - float speedlimit = s->scene.speedlimit; - int speedlim_calc = speedlimit * 2.2369363 + 0.5; - int speed_lim_off = s->speed_lim_off * 2.2369363 + 0.5; - if (s->is_metric) { - maxspeed_calc = maxspeed + 0.5; - speedlim_calc = speedlimit * 3.6 + 0.5; - speed_lim_off = s->speed_lim_off * 3.6 + 0.5; - } - - bool is_cruise_set = (maxspeed != 0 && maxspeed != SET_SPEED_NA); - bool is_speedlim_valid = s->scene.speedlimit_valid; - bool is_set_over_limit = is_speedlim_valid && s->scene.engaged && - is_cruise_set && maxspeed_calc > (speedlim_calc + speed_lim_off); - - int viz_maxspeed_w = 184; - int viz_maxspeed_h = 202; - int viz_maxspeed_x = (ui_viz_rx + (bdr_s*2)); - int viz_maxspeed_y = (box_y + (bdr_s*1.5)); - int viz_maxspeed_xo = 180; - viz_maxspeed_w += viz_maxspeed_xo; - viz_maxspeed_x += viz_maxspeed_w - (viz_maxspeed_xo * 2); - - // Draw Background - nvgBeginPath(s->vg); - nvgRoundedRect(s->vg, viz_maxspeed_x, viz_maxspeed_y, viz_maxspeed_w, viz_maxspeed_h, 30); - if (is_set_over_limit) { - nvgFillColor(s->vg, nvgRGBA(218, 111, 37, 180)); - } else { - nvgFillColor(s->vg, nvgRGBA(0, 0, 0, 100)); - } - nvgFill(s->vg); - - // Draw Border - nvgBeginPath(s->vg); - nvgRoundedRect(s->vg, viz_maxspeed_x, viz_maxspeed_y, viz_maxspeed_w, viz_maxspeed_h, 20); - if (is_set_over_limit) { - nvgStrokeColor(s->vg, nvgRGBA(218, 111, 37, 255)); - } else if (is_speedlim_valid && !s->is_ego_over_limit) { - nvgStrokeColor(s->vg, nvgRGBA(255, 255, 255, 255)); - } else if (is_speedlim_valid && s->is_ego_over_limit) { - nvgStrokeColor(s->vg, nvgRGBA(255, 255, 255, 20)); - } else { - nvgStrokeColor(s->vg, nvgRGBA(255, 255, 255, 100)); - } - nvgStrokeWidth(s->vg, 10); - nvgStroke(s->vg); - - // Draw "MAX" Text - nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); - nvgFontFace(s->vg, "sans-regular"); - nvgFontSize(s->vg, 26*2.5); - if (is_cruise_set) { - nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 200)); - } else { - nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 100)); - } - nvgText(s->vg, viz_maxspeed_x+(viz_maxspeed_xo/2)+(viz_maxspeed_w/2), 148, "MAX", NULL); - - // Draw Speed Text - nvgFontFace(s->vg, "sans-bold"); - nvgFontSize(s->vg, 48*2.5); - if (is_cruise_set) { - snprintf(maxspeed_str, sizeof(maxspeed_str), "%d", maxspeed_calc); - nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 255)); - nvgText(s->vg, viz_maxspeed_x+(viz_maxspeed_xo/2)+(viz_maxspeed_w/2), 242, maxspeed_str, NULL); - } else { - nvgFontFace(s->vg, "sans-semibold"); - nvgFontSize(s->vg, 42*2.5); - nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 100)); - nvgText(s->vg, viz_maxspeed_x+(viz_maxspeed_xo/2)+(viz_maxspeed_w/2), 242, "N/A", NULL); - } - -#ifdef DEBUG_TURN - if (s->scene.decel_for_turn && s->scene.engaged){ - int v_curvature = s->scene.v_curvature * 2.2369363 + 0.5; - snprintf(maxspeed_str, sizeof(maxspeed_str), "%d", v_curvature); - nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 255)); - nvgFontSize(s->vg, 25*2.5); - nvgText(s->vg, 200 + viz_maxspeed_x+(viz_maxspeed_xo/2)+(viz_maxspeed_w/2), 148, "TURN", NULL); - nvgFontSize(s->vg, 50*2.5); - nvgText(s->vg, 200 + viz_maxspeed_x+(viz_maxspeed_xo/2)+(viz_maxspeed_w/2), 242, maxspeed_str, NULL); - } -#endif -} - -static void ui_draw_vision_speedlimit(UIState *s) { - const UIScene *scene = &s->scene; - int ui_viz_rx = scene->ui_viz_rx; - int ui_viz_rw = scene->ui_viz_rw; - - char speedlim_str[32]; - float speedlimit = s->scene.speedlimit; - int speedlim_calc = speedlimit * 2.2369363 + 0.5; - if (s->is_metric) { - speedlim_calc = speedlimit * 3.6 + 0.5; - } - - bool is_speedlim_valid = s->scene.speedlimit_valid; - float hysteresis_offset = 0.5; - if (s->is_ego_over_limit) { - hysteresis_offset = 0.0; - } - s->is_ego_over_limit = is_speedlim_valid && s->scene.v_ego > (speedlimit + s->speed_lim_off + hysteresis_offset); - - int viz_speedlim_w = 180; - int viz_speedlim_h = 202; - int viz_speedlim_x = (ui_viz_rx + (bdr_s*2)); - int viz_speedlim_y = (box_y + (bdr_s*1.5)); - if (!is_speedlim_valid) { - viz_speedlim_w -= 5; - viz_speedlim_h -= 10; - viz_speedlim_x += 9; - viz_speedlim_y += 5; - } - int viz_speedlim_bdr = is_speedlim_valid ? 30 : 15; - - // Draw Background - nvgBeginPath(s->vg); - nvgRoundedRect(s->vg, viz_speedlim_x, viz_speedlim_y, viz_speedlim_w, viz_speedlim_h, viz_speedlim_bdr); - if (is_speedlim_valid && s->is_ego_over_limit) { - nvgFillColor(s->vg, nvgRGBA(218, 111, 37, 180)); - } else if (is_speedlim_valid) { - nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 255)); - } else { - nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 100)); - } - nvgFill(s->vg); - - // Draw Border - if (is_speedlim_valid) { - nvgStrokeWidth(s->vg, 10); - nvgStroke(s->vg); - nvgBeginPath(s->vg); - nvgRoundedRect(s->vg, viz_speedlim_x, viz_speedlim_y, viz_speedlim_w, viz_speedlim_h, 20); - if (s->is_ego_over_limit) { - nvgStrokeColor(s->vg, nvgRGBA(218, 111, 37, 255)); - } else if (is_speedlim_valid) { - nvgStrokeColor(s->vg, nvgRGBA(255, 255, 255, 255)); - } - } - - // Draw "Speed Limit" Text - nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); - nvgFontFace(s->vg, "sans-semibold"); - nvgFontSize(s->vg, 50); - nvgFillColor(s->vg, nvgRGBA(0, 0, 0, 255)); - if (is_speedlim_valid && s->is_ego_over_limit) { - nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 255)); - } - nvgText(s->vg, viz_speedlim_x+viz_speedlim_w/2 + (is_speedlim_valid ? 6 : 0), viz_speedlim_y + (is_speedlim_valid ? 50 : 45), "SPEED", NULL); - nvgText(s->vg, viz_speedlim_x+viz_speedlim_w/2 + (is_speedlim_valid ? 6 : 0), viz_speedlim_y + (is_speedlim_valid ? 90 : 85), "LIMIT", NULL); - - // Draw Speed Text - nvgFontFace(s->vg, "sans-bold"); - nvgFontSize(s->vg, 48*2.5); - if (s->is_ego_over_limit) { - nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 255)); - } else { - nvgFillColor(s->vg, nvgRGBA(0, 0, 0, 255)); - } - if (is_speedlim_valid) { - snprintf(speedlim_str, sizeof(speedlim_str), "%d", speedlim_calc); - nvgText(s->vg, viz_speedlim_x+viz_speedlim_w/2, viz_speedlim_y + (is_speedlim_valid ? 170 : 165), speedlim_str, NULL); - } else { - nvgFontFace(s->vg, "sans-semibold"); - nvgFontSize(s->vg, 42*2.5); - nvgText(s->vg, viz_speedlim_x+viz_speedlim_w/2, viz_speedlim_y + (is_speedlim_valid ? 170 : 165), "N/A", NULL); - } -} - -static void ui_draw_vision_speed(UIState *s) { - const UIScene *scene = &s->scene; - int ui_viz_rx = scene->ui_viz_rx; - int ui_viz_rw = scene->ui_viz_rw; - float speed = s->scene.v_ego; - - const int viz_speed_w = 280; - const int viz_speed_x = ui_viz_rx+((ui_viz_rw/2)-(viz_speed_w/2)); - char speed_str[32]; - - nvgBeginPath(s->vg); - nvgRect(s->vg, viz_speed_x, box_y, viz_speed_w, header_h); - nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); - - if (s->is_metric) { - snprintf(speed_str, sizeof(speed_str), "%d", (int)(speed * 3.6 + 0.5)); - } else { - snprintf(speed_str, sizeof(speed_str), "%d", (int)(speed * 2.2369363 + 0.5)); - } - nvgFontFace(s->vg, "sans-bold"); - nvgFontSize(s->vg, 96*2.5); - nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 255)); - nvgText(s->vg, viz_speed_x+viz_speed_w/2, 240, speed_str, NULL); - - nvgFontFace(s->vg, "sans-regular"); - nvgFontSize(s->vg, 36*2.5); - nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 200)); - - if (s->is_metric) { - nvgText(s->vg, viz_speed_x+viz_speed_w/2, 320, "kph", NULL); - } else { - nvgText(s->vg, viz_speed_x+viz_speed_w/2, 320, "mph", NULL); - } -} - -static void ui_draw_vision_event(UIState *s) { - const UIScene *scene = &s->scene; - const int ui_viz_rx = scene->ui_viz_rx; - const int ui_viz_rw = scene->ui_viz_rw; - const int viz_event_w = 220; - const int viz_event_x = ((ui_viz_rx + ui_viz_rw) - (viz_event_w + (bdr_s*2))); - const int viz_event_y = (box_y + (bdr_s*1.5)); - const int viz_event_h = (header_h - (bdr_s*1.5)); - if (s->scene.decel_for_turn && s->scene.engaged && s->limit_set_speed) { - // draw winding road sign - const int img_turn_size = 160*1.5; - const int img_turn_x = viz_event_x-(img_turn_size/4); - const int img_turn_y = viz_event_y+bdr_s-25; - float img_turn_alpha = 1.0f; - nvgBeginPath(s->vg); - NVGpaint imgPaint = nvgImagePattern(s->vg, img_turn_x, img_turn_y, - img_turn_size, img_turn_size, 0, s->img_turn, img_turn_alpha); - nvgRect(s->vg, img_turn_x, img_turn_y, img_turn_size, img_turn_size); - nvgFillPaint(s->vg, imgPaint); - nvgFill(s->vg); - } else { - // draw steering wheel - const int bg_wheel_size = 96; - const int bg_wheel_x = viz_event_x + (viz_event_w-bg_wheel_size); - const int bg_wheel_y = viz_event_y + (bg_wheel_size/2); - const int img_wheel_size = bg_wheel_size*1.5; - const int img_wheel_x = bg_wheel_x-(img_wheel_size/2); - const int img_wheel_y = bg_wheel_y-25; - float img_wheel_alpha = 0.1f; - bool is_engaged = (s->status == STATUS_ENGAGED); - bool is_warning = (s->status == STATUS_WARNING); - bool is_engageable = scene->engageable; - if (is_engaged || is_warning || is_engageable) { - nvgBeginPath(s->vg); - nvgCircle(s->vg, bg_wheel_x, (bg_wheel_y + (bdr_s*1.5)), bg_wheel_size); - if (is_engaged) { - nvgFillColor(s->vg, nvgRGBA(23, 134, 68, 255)); - } else if (is_warning) { - nvgFillColor(s->vg, nvgRGBA(218, 111, 37, 255)); - } else if (is_engageable) { - nvgFillColor(s->vg, nvgRGBA(23, 51, 73, 255)); - } - nvgFill(s->vg); - img_wheel_alpha = 1.0f; - } - nvgBeginPath(s->vg); - NVGpaint imgPaint = nvgImagePattern(s->vg, img_wheel_x, img_wheel_y, - img_wheel_size, img_wheel_size, 0, s->img_wheel, img_wheel_alpha); - nvgRect(s->vg, img_wheel_x, img_wheel_y, img_wheel_size, img_wheel_size); - nvgFillPaint(s->vg, imgPaint); - nvgFill(s->vg); - } -} - -static void ui_draw_vision_map(UIState *s) { - const UIScene *scene = &s->scene; - const int map_size = 96; - const int map_x = (scene->ui_viz_rx + (map_size * 3) + (bdr_s * 3)); - const int map_y = (footer_y + ((footer_h - map_size) / 2)); - const int map_img_size = (map_size * 1.5); - const int map_img_x = (map_x - (map_img_size / 2)); - const int map_img_y = (map_y - (map_size / 4)); - - bool map_valid = s->scene.map_valid; - float map_img_alpha = map_valid ? 1.0f : 0.15f; - float map_bg_alpha = map_valid ? 0.3f : 0.1f; - NVGcolor map_bg = nvgRGBA(0, 0, 0, (255 * map_bg_alpha)); - NVGpaint map_img = nvgImagePattern(s->vg, map_img_x, map_img_y, - map_img_size, map_img_size, 0, s->img_map, map_img_alpha); - - nvgBeginPath(s->vg); - nvgCircle(s->vg, map_x, (map_y + (bdr_s * 1.5)), map_size); - nvgFillColor(s->vg, map_bg); - nvgFill(s->vg); - - nvgBeginPath(s->vg); - nvgRect(s->vg, map_img_x, map_img_y, map_img_size, map_img_size); - nvgFillPaint(s->vg, map_img); - nvgFill(s->vg); -} - -static void ui_draw_vision_face(UIState *s) { - const UIScene *scene = &s->scene; - const int face_size = 96; - const int face_x = (scene->ui_viz_rx + face_size + (bdr_s * 2)); - const int face_y = (footer_y + ((footer_h - face_size) / 2)); - const int face_img_size = (face_size * 1.5); - const int face_img_x = (face_x - (face_img_size / 2)); - const int face_img_y = (face_y - (face_size / 4)); - float face_img_alpha = scene->monitoring_active ? 1.0f : 0.15f; - float face_bg_alpha = scene->monitoring_active ? 0.3f : 0.1f; - NVGcolor face_bg = nvgRGBA(0, 0, 0, (255 * face_bg_alpha)); - NVGpaint face_img = nvgImagePattern(s->vg, face_img_x, face_img_y, - face_img_size, face_img_size, 0, s->img_face, face_img_alpha); - - nvgBeginPath(s->vg); - nvgCircle(s->vg, face_x, (face_y + (bdr_s * 1.5)), face_size); - nvgFillColor(s->vg, face_bg); - nvgFill(s->vg); - - nvgBeginPath(s->vg); - nvgRect(s->vg, face_img_x, face_img_y, face_img_size, face_img_size); - nvgFillPaint(s->vg, face_img); - nvgFill(s->vg); -} - -static void ui_draw_vision_header(UIState *s) { - const UIScene *scene = &s->scene; - int ui_viz_rx = scene->ui_viz_rx; - int ui_viz_rw = scene->ui_viz_rw; - - nvgBeginPath(s->vg); - NVGpaint gradient = nvgLinearGradient(s->vg, ui_viz_rx, - (box_y+(header_h-(header_h/2.5))), - ui_viz_rx, box_y+header_h, - nvgRGBAf(0,0,0,0.45), nvgRGBAf(0,0,0,0)); - nvgFillPaint(s->vg, gradient); - nvgRect(s->vg, ui_viz_rx, box_y, ui_viz_rw, header_h); - nvgFill(s->vg); - - ui_draw_vision_maxspeed(s); - ui_draw_vision_speedlimit(s); - ui_draw_vision_speed(s); - ui_draw_vision_event(s); -} - -static void ui_draw_vision_footer(UIState *s) { - const UIScene *scene = &s->scene; - int ui_viz_rx = scene->ui_viz_rx; - int ui_viz_rw = scene->ui_viz_rw; - - nvgBeginPath(s->vg); - nvgRect(s->vg, ui_viz_rx, footer_y, ui_viz_rw, footer_h); - - ui_draw_vision_face(s); - ui_draw_vision_map(s); -} - -static void ui_draw_vision_alert(UIState *s, int va_size, int va_color, - const char* va_text1, const char* va_text2) { - const UIScene *scene = &s->scene; - int ui_viz_rx = scene->ui_viz_rx; - int ui_viz_rw = scene->ui_viz_rw; - bool hasSidebar = !s->scene.uilayout_sidebarcollapsed; - bool mapEnabled = s->scene.uilayout_mapenabled; - bool longAlert1 = strlen(va_text1) > 15; - - const uint8_t *color = alert_colors[va_color]; - const int alr_s = alert_sizes[va_size]; - const int alr_x = ui_viz_rx-(mapEnabled?(hasSidebar?nav_w:(nav_ww)):0)-bdr_s; - const int alr_w = ui_viz_rw+(mapEnabled?(hasSidebar?nav_w:(nav_ww)):0)+(bdr_s*2); - const int alr_h = alr_s+(va_size==ALERTSIZE_NONE?0:bdr_s); - const int alr_y = vwp_h-alr_h; - - nvgBeginPath(s->vg); - nvgRect(s->vg, alr_x, alr_y, alr_w, alr_h); - nvgFillColor(s->vg, nvgRGBA(color[0],color[1],color[2],(color[3]*s->alert_blinking_alpha))); - nvgFill(s->vg); - - nvgBeginPath(s->vg); - NVGpaint gradient = nvgLinearGradient(s->vg, alr_x, alr_y, alr_x, alr_y+alr_h, - nvgRGBAf(0.0,0.0,0.0,0.05), nvgRGBAf(0.0,0.0,0.0,0.35)); - nvgFillPaint(s->vg, gradient); - nvgRect(s->vg, alr_x, alr_y, alr_w, alr_h); - nvgFill(s->vg); - - nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 255)); - nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); - - if (va_size == ALERTSIZE_SMALL) { - nvgFontFace(s->vg, "sans-semibold"); - nvgFontSize(s->vg, 40*2.5); - nvgText(s->vg, alr_x+alr_w/2, alr_y+alr_h/2+15, va_text1, NULL); - } else if (va_size== ALERTSIZE_MID) { - nvgFontFace(s->vg, "sans-bold"); - nvgFontSize(s->vg, 48*2.5); - nvgText(s->vg, alr_x+alr_w/2, alr_y+alr_h/2-45, va_text1, NULL); - nvgFontFace(s->vg, "sans-regular"); - nvgFontSize(s->vg, 36*2.5); - nvgText(s->vg, alr_x+alr_w/2, alr_y+alr_h/2+75, va_text2, NULL); - } else if (va_size== ALERTSIZE_FULL) { - nvgFontSize(s->vg, (longAlert1?72:96)*2.5); - nvgFontFace(s->vg, "sans-bold"); - nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE); - nvgTextBox(s->vg, alr_x, alr_y+(longAlert1?360:420), alr_w-60, va_text1, NULL); - nvgFontSize(s->vg, 48*2.5); - nvgFontFace(s->vg, "sans-regular"); - nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BOTTOM); - nvgTextBox(s->vg, alr_x, alr_h-(longAlert1?300:360), alr_w-60, va_text2, NULL); - } -} - -static void ui_draw_vision(UIState *s) { - const UIScene *scene = &s->scene; - int ui_viz_rx = scene->ui_viz_rx; - int ui_viz_rw = scene->ui_viz_rw; - int ui_viz_ro = scene->ui_viz_ro; - - glClearColor(0.0, 0.0, 0.0, 0.0); - glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - - // Draw video frames - glEnable(GL_SCISSOR_TEST); - glViewport(ui_viz_rx+ui_viz_ro, s->fb_h-(box_y+box_h), viz_w, box_h); - glScissor(ui_viz_rx, s->fb_h-(box_y+box_h), ui_viz_rw, box_h); - draw_frame(s); - glViewport(0, 0, s->fb_w, s->fb_h); - glDisable(GL_SCISSOR_TEST); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glClear(GL_STENCIL_BUFFER_BIT); - - nvgBeginFrame(s->vg, s->fb_w, s->fb_h, 1.0f); - nvgSave(s->vg); - - // Draw augmented elements - const int inner_height = viz_w*9/16; - nvgScissor(s->vg, ui_viz_rx, box_y, ui_viz_rw, box_h); - nvgTranslate(s->vg, ui_viz_rx+ui_viz_ro, box_y + (box_h-inner_height)/2.0); - nvgScale(s->vg, (float)viz_w / s->fb_w, (float)inner_height / s->fb_h); - if (!scene->frontview && !scene->fullview) { - ui_draw_world(s); - } - - nvgRestore(s->vg); - - // Set Speed, Current Speed, Status/Events - ui_draw_vision_header(s); - - if (s->scene.alert_size != ALERTSIZE_NONE) { - // Controls Alerts - ui_draw_vision_alert(s, s->scene.alert_size, s->status, - s->scene.alert_text1, s->scene.alert_text2); - } else { - ui_draw_vision_footer(s); - } - - - nvgEndFrame(s->vg); - glDisable(GL_BLEND); -} - -static void ui_draw_blank(UIState *s) { - glClearColor(0.0, 0.0, 0.0, 0.0); - glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); -} - -static void ui_draw(UIState *s) { - if (s->vision_connected && s->plus_state == 0) { - ui_draw_vision(s); - } else { - ui_draw_blank(s); - } - - { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glClear(GL_STENCIL_BUFFER_BIT); - - nvgBeginFrame(s->vg, s->fb_w, s->fb_h, 1.0f); - - nvgEndFrame(s->vg); - glDisable(GL_BLEND); - } - - assert(glGetError() == GL_NO_ERROR); -} - -static PathData read_path(cereal_ModelData_PathData_ptr pathp) { - PathData ret = {0}; - - struct cereal_ModelData_PathData pathd; - cereal_read_ModelData_PathData(&pathd, pathp); - - ret.prob = pathd.prob; - ret.std = pathd.std; - - capn_list32 pointl = pathd.points; - capn_resolve(&pointl.p); - for (int i = 0; i < 50; i++) { - ret.points[i] = capn_to_f32(capn_get32(pointl, i)); - } - - return ret; -} - -static ModelData read_model(cereal_ModelData_ptr modelp) { - struct cereal_ModelData modeld; - cereal_read_ModelData(&modeld, modelp); - - ModelData d = {0}; - - d.path = read_path(modeld.path); - d.left_lane = read_path(modeld.leftLane); - d.right_lane = read_path(modeld.rightLane); - - struct cereal_ModelData_LeadData leadd; - cereal_read_ModelData_LeadData(&leadd, modeld.lead); - d.lead = (LeadData){ - .dist = leadd.dist, .prob = leadd.prob, .std = leadd.std, - }; - - return d; -} - -static void update_status(UIState *s, int status) { - if (s->status != status) { - s->status = status; - // wake up bg thread to change - pthread_cond_signal(&s->bg_cond); - } -} - -static void ui_update(UIState *s) { - int err; - - if (s->vision_connect_firstrun) { - // cant run this in connector thread because opengl. - // do this here for now in lieu of a run_on_main_thread event - - for (int i=0; iframe_texs[i]); - - VisionImg img = { - .fd = s->bufs[i].fd, - .format = VISIONIMG_FORMAT_RGB24, - .width = s->rgb_width, - .height = s->rgb_height, - .stride = s->rgb_stride, - .bpp = 3, - .size = s->rgb_buf_len, - }; - s->frame_texs[i] = visionimg_to_gl(&img); - - glBindTexture(GL_TEXTURE_2D, s->frame_texs[i]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - // BGR - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); - } - - for (int i=0; iframe_front_texs[i]); - - VisionImg img = { - .fd = s->front_bufs[i].fd, - .format = VISIONIMG_FORMAT_RGB24, - .width = s->rgb_front_width, - .height = s->rgb_front_height, - .stride = s->rgb_front_stride, - .bpp = 3, - .size = s->rgb_front_buf_len, - }; - s->frame_front_texs[i] = visionimg_to_gl(&img); - - glBindTexture(GL_TEXTURE_2D, s->frame_front_texs[i]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - // BGR - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); - } - - assert(glGetError() == GL_NO_ERROR); - - // Default UI Measurements (Assumes sidebar collapsed) - s->scene.ui_viz_rx = (box_x-sbr_w+bdr_s*2); - s->scene.ui_viz_rw = (box_w+sbr_w-(bdr_s*2)); - s->scene.ui_viz_ro = 0; - - s->vision_connect_firstrun = false; - - s->alert_blinking_alpha = 1.0; - s->alert_blinked = false; - } - - // poll for events - while (true) { - zmq_pollitem_t polls[10] = {{0}}; - polls[0].socket = s->live100_sock_raw; - polls[0].events = ZMQ_POLLIN; - polls[1].socket = s->livecalibration_sock_raw; - polls[1].events = ZMQ_POLLIN; - polls[2].socket = s->model_sock_raw; - polls[2].events = ZMQ_POLLIN; - polls[3].socket = s->live20_sock_raw; - polls[3].events = ZMQ_POLLIN; - polls[4].socket = s->livempc_sock_raw; - polls[4].events = ZMQ_POLLIN; - polls[5].socket = s->thermal_sock_raw; - polls[5].events = ZMQ_POLLIN; - polls[6].socket = s->uilayout_sock_raw; - polls[6].events = ZMQ_POLLIN; - polls[7].socket = s->map_data_sock_raw; - polls[7].events = ZMQ_POLLIN; - polls[8].socket = s->plus_sock_raw; // plus_sock should be last - polls[8].events = ZMQ_POLLIN; - - int num_polls = 9; - if (s->vision_connected) { - assert(s->ipc_fd >= 0); - polls[9].fd = s->ipc_fd; - polls[9].events = ZMQ_POLLIN; - num_polls++; - } - - int ret = zmq_poll(polls, num_polls, 0); - if (ret < 0) { - LOGW("poll failed (%d)", ret); - break; - } - if (ret == 0) { - break; - } - - if (polls[0].revents || polls[1].revents || polls[2].revents || - polls[3].revents || polls[4].revents || polls[6].revents || - polls[7].revents || polls[8].revents) { - // awake on any (old) activity - set_awake(s, true); - } - - if (s->vision_connected && polls[9].revents) { - // vision ipc event - VisionPacket rp; - err = vipc_recv(s->ipc_fd, &rp); - if (err <= 0) { - LOGW("vision disconnected"); - close(s->ipc_fd); - s->ipc_fd = -1; - s->vision_connected = false; - continue; - } - if (rp.type == VIPC_STREAM_ACQUIRE) { - bool front = rp.d.stream_acq.type == VISION_STREAM_RGB_FRONT; - int idx = rp.d.stream_acq.idx; - - int release_idx; - if (front) { - release_idx = s->cur_vision_front_idx; - } else { - release_idx = s->cur_vision_idx; - } - if (release_idx >= 0) { - VisionPacket rep = { - .type = VIPC_STREAM_RELEASE, - .d = { .stream_rel = { - .type = rp.d.stream_acq.type, - .idx = release_idx, - }}, - }; - vipc_send(s->ipc_fd, &rep); - } - - if (front) { - assert(idx < UI_BUF_COUNT); - s->cur_vision_front_idx = idx; - } else { - assert(idx < UI_BUF_COUNT); - s->cur_vision_idx = idx; - // printf("v %d\n", ((uint8_t*)s->bufs[idx].addr)[0]); - } - } else { - assert(false); - } - } else if (polls[8].revents) { - // plus socket - - zmq_msg_t msg; - err = zmq_msg_init(&msg); - assert(err == 0); - err = zmq_msg_recv(&msg, s->plus_sock_raw, 0); - assert(err >= 0); - - assert(zmq_msg_size(&msg) == 1); - - s->plus_state = ((char*)zmq_msg_data(&msg))[0]; - - zmq_msg_close(&msg); - - } else { - // zmq messages - void* which = NULL; - for (int i=0; i= 0); - - struct capn ctx; - capn_init_mem(&ctx, zmq_msg_data(&msg), zmq_msg_size(&msg), 0); - - cereal_Event_ptr eventp; - eventp.p = capn_getp(capn_root(&ctx), 0, 1); - struct cereal_Event eventd; - cereal_read_Event(&eventd, eventp); - - if (eventd.which == cereal_Event_live100) { - struct cereal_Live100Data datad; - cereal_read_Live100Data(&datad, eventd.live100); - - if (datad.vCruise != s->scene.v_cruise) { - s->scene.v_cruise_update_ts = eventd.logMonoTime; - } - s->scene.v_cruise = datad.vCruise; - s->scene.v_ego = datad.vEgo; - s->scene.curvature = datad.curvature; - s->scene.engaged = datad.enabled; - s->scene.engageable = datad.engageable; - s->scene.gps_planner_active = datad.gpsPlannerActive; - s->scene.monitoring_active = datad.driverMonitoringOn; - - s->scene.frontview = datad.rearViewCam; - - s->scene.v_curvature = datad.vCurvature; - s->scene.decel_for_turn = datad.decelForTurn; - - if (datad.alertSound.str && datad.alertSound.str[0] != '\0' && strcmp(s->alert_type, datad.alertType.str) != 0) { - char* error = NULL; - if (s->alert_sound[0] != '\0') { - sound_file* active_sound = get_sound_file_by_name(s->alert_sound); - slplay_stop_uri(active_sound->uri, &error); - if (error) { - LOGW("error stopping active sound %s", error); - } - } - - sound_file* sound = get_sound_file_by_name(datad.alertSound.str); - slplay_play(sound->uri, sound->loop, &error); - if(error) { - LOGW("error playing sound: %s", error); - } - - snprintf(s->alert_sound, sizeof(s->alert_sound), "%s", datad.alertSound.str); - snprintf(s->alert_type, sizeof(s->alert_type), "%s", datad.alertType.str); - } else if ((!datad.alertSound.str || datad.alertSound.str[0] == '\0') && s->alert_sound[0] != '\0') { - sound_file* sound = get_sound_file_by_name(s->alert_sound); - - char* error = NULL; - - slplay_stop_uri(sound->uri, &error); - if(error) { - LOGW("error stopping sound: %s", error); - } - s->alert_type[0] = '\0'; - s->alert_sound[0] = '\0'; - } - - if (datad.alertText1.str) { - snprintf(s->scene.alert_text1, sizeof(s->scene.alert_text1), "%s", datad.alertText1.str); - } else { - s->scene.alert_text1[0] = '\0'; - } - if (datad.alertText2.str) { - snprintf(s->scene.alert_text2, sizeof(s->scene.alert_text2), "%s", datad.alertText2.str); - } else { - s->scene.alert_text2[0] = '\0'; - } - s->scene.awareness_status = datad.awarenessStatus; - - s->scene.alert_ts = eventd.logMonoTime; - - s->scene.alert_size = datad.alertSize; - if (datad.alertSize == cereal_Live100Data_AlertSize_none) { - s->alert_size = ALERTSIZE_NONE; - } else if (datad.alertSize == cereal_Live100Data_AlertSize_small) { - s->alert_size = ALERTSIZE_SMALL; - } else if (datad.alertSize == cereal_Live100Data_AlertSize_mid) { - s->alert_size = ALERTSIZE_MID; - } else if (datad.alertSize == cereal_Live100Data_AlertSize_full) { - s->alert_size = ALERTSIZE_FULL; - } - - if (datad.alertStatus == cereal_Live100Data_AlertStatus_userPrompt) { - update_status(s, STATUS_WARNING); - } else if (datad.alertStatus == cereal_Live100Data_AlertStatus_critical) { - update_status(s, STATUS_ALERT); - } else if (datad.enabled) { - update_status(s, STATUS_ENGAGED); - } else { - update_status(s, STATUS_DISENGAGED); - } - - s->scene.alert_blinkingrate = datad.alertBlinkingRate; - if (datad.alertBlinkingRate > 0.) { - if (s->alert_blinked) { - if (s->alert_blinking_alpha > 0.0 && s->alert_blinking_alpha < 1.0) { - s->alert_blinking_alpha += (0.05*datad.alertBlinkingRate); - } else { - s->alert_blinked = false; - } - } else { - if (s->alert_blinking_alpha > 0.25) { - s->alert_blinking_alpha -= (0.05*datad.alertBlinkingRate); - } else { - s->alert_blinking_alpha += 0.25; - s->alert_blinked = true; - } - } - } - } else if (eventd.which == cereal_Event_live20) { - struct cereal_Live20Data datad; - cereal_read_Live20Data(&datad, eventd.live20); - struct cereal_Live20Data_LeadData leaddatad; - cereal_read_Live20Data_LeadData(&leaddatad, datad.leadOne); - s->scene.lead_status = leaddatad.status; - s->scene.lead_d_rel = leaddatad.dRel; - s->scene.lead_y_rel = leaddatad.yRel; - s->scene.lead_v_rel = leaddatad.vRel; - } else if (eventd.which == cereal_Event_liveCalibration) { - s->scene.world_objects_visible = true; - struct cereal_LiveCalibrationData datad; - cereal_read_LiveCalibrationData(&datad, eventd.liveCalibration); - - // should we still even have this? - capn_list32 warpl = datad.warpMatrix2; - capn_resolve(&warpl.p); // is this a bug? - for (int i = 0; i < 3 * 3; i++) { - s->scene.warp_matrix.v[i] = capn_to_f32(capn_get32(warpl, i)); - } - - capn_list32 extrinsicl = datad.extrinsicMatrix; - capn_resolve(&extrinsicl.p); // is this a bug? - for (int i = 0; i < 3 * 4; i++) { - s->scene.extrinsic_matrix.v[i] = - capn_to_f32(capn_get32(extrinsicl, i)); - } - } else if (eventd.which == cereal_Event_model) { - s->scene.model_ts = eventd.logMonoTime; - s->scene.model = read_model(eventd.model); - } else if (eventd.which == cereal_Event_liveMpc) { - struct cereal_LiveMpcData datad; - cereal_read_LiveMpcData(&datad, eventd.liveMpc); - - capn_list32 x_list = datad.x; - capn_resolve(&x_list.p); - - for (int i = 0; i < 50; i++){ - s->scene.mpc_x[i] = capn_to_f32(capn_get32(x_list, i)); - } - - capn_list32 y_list = datad.y; - capn_resolve(&y_list.p); - - for (int i = 0; i < 50; i++){ - s->scene.mpc_y[i] = capn_to_f32(capn_get32(y_list, i)); - } - } else if (eventd.which == cereal_Event_thermal) { - struct cereal_ThermalData datad; - cereal_read_ThermalData(&datad, eventd.thermal); - - if (!datad.started) { - update_status(s, STATUS_STOPPED); - } else if (s->status == STATUS_STOPPED) { - // car is started but controls doesn't have fingerprint yet - update_status(s, STATUS_DISENGAGED); - } - - s->scene.started_ts = datad.startedTs; - } else if (eventd.which == cereal_Event_uiLayoutState) { - struct cereal_UiLayoutState datad; - cereal_read_UiLayoutState(&datad, eventd.uiLayoutState); - s->scene.uilayout_sidebarcollapsed = datad.sidebarCollapsed; - s->scene.uilayout_mapenabled = datad.mapEnabled; - - bool hasSidebar = !s->scene.uilayout_sidebarcollapsed; - bool mapEnabled = s->scene.uilayout_mapenabled; - if (mapEnabled) { - s->scene.ui_viz_rx = hasSidebar ? (box_x+nav_w) : (box_x+nav_w-(bdr_s*4)); - s->scene.ui_viz_rw = hasSidebar ? (box_w-nav_w) : (box_w-nav_w+(bdr_s*4)); - s->scene.ui_viz_ro = -(sbr_w + 4*bdr_s); - } else { - s->scene.ui_viz_rx = hasSidebar ? box_x : (box_x-sbr_w+bdr_s*2); - s->scene.ui_viz_rw = hasSidebar ? box_w : (box_w+sbr_w-(bdr_s*2)); - s->scene.ui_viz_ro = hasSidebar ? -(sbr_w - 6*bdr_s) : 0; - } - } else if (eventd.which == cereal_Event_liveMapData) { - struct cereal_LiveMapData datad; - cereal_read_LiveMapData(&datad, eventd.liveMapData); - s->scene.speedlimit = datad.speedLimit; - s->scene.speedlimit_valid = datad.speedLimitValid; - s->scene.map_valid = datad.mapValid; - } - capn_free(&ctx); - zmq_msg_close(&msg); - } - } - -} - -static int vision_subscribe(int fd, VisionPacket *rp, int type) { - int err; - LOGW("vision_subscribe type:%d", type); - - VisionPacket p1 = { - .type = VIPC_STREAM_SUBSCRIBE, - .d = { .stream_sub = { .type = type, .tbuffer = true, }, }, - }; - err = vipc_send(fd, &p1); - if (err < 0) { - close(fd); - return 0; - } - - do { - err = vipc_recv(fd, rp); - if (err <= 0) { - close(fd); - return 0; - } - - // release what we aren't ready for yet - if (rp->type == VIPC_STREAM_ACQUIRE) { - VisionPacket rep = { - .type = VIPC_STREAM_RELEASE, - .d = { .stream_rel = { - .type = rp->d.stream_acq.type, - .idx = rp->d.stream_acq.idx, - }}, - }; - vipc_send(fd, &rep); - } - } while (rp->type != VIPC_STREAM_BUFS || rp->d.stream_bufs.type != type); - - return 1; -} - -static void* vision_connect_thread(void *args) { - int err; - - UIState *s = args; - while (!do_exit) { - usleep(100000); - pthread_mutex_lock(&s->lock); - bool connected = s->vision_connected; - pthread_mutex_unlock(&s->lock); - if (connected) continue; - - int fd = vipc_connect(); - if (fd < 0) continue; - - VisionPacket back_rp, front_rp; - if (!vision_subscribe(fd, &back_rp, VISION_STREAM_RGB_BACK)) continue; - if (!vision_subscribe(fd, &front_rp, VISION_STREAM_RGB_FRONT)) continue; - - pthread_mutex_lock(&s->lock); - assert(!s->vision_connected); - s->ipc_fd = fd; - - ui_init_vision(s, - back_rp.d.stream_bufs, back_rp.num_fds, back_rp.fds, - front_rp.d.stream_bufs, front_rp.num_fds, front_rp.fds); - - s->vision_connected = true; - s->vision_connect_firstrun = true; - pthread_mutex_unlock(&s->lock); - } - return NULL; -} - - -#include -#include - -static void* light_sensor_thread(void *args) { - int err; - - UIState *s = args; - s->light_sensor = 0.0; - - struct sensors_poll_device_t* device; - struct sensors_module_t* module; - - hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); - sensors_open(&module->common, &device); - - // need to do this - struct sensor_t const* list; - int count = module->get_sensors_list(module, &list); - - int SENSOR_LIGHT = 7; - - device->activate(device, SENSOR_LIGHT, 0); - device->activate(device, SENSOR_LIGHT, 1); - device->setDelay(device, SENSOR_LIGHT, ms2ns(100)); - - while (!do_exit) { - static const size_t numEvents = 1; - sensors_event_t buffer[numEvents]; - - int n = device->poll(device, buffer, numEvents); - if (n < 0) { - LOG_100("light_sensor_poll failed: %d", n); - } - if (n > 0) { - s->light_sensor = buffer[0].light; - } - } - - return NULL; -} - - -static void* bg_thread(void* args) { - UIState *s = args; - - EGLDisplay bg_display; - EGLSurface bg_surface; - - FramebufferState *bg_fb = framebuffer_init("bg", 0x00001000, false, - &bg_display, &bg_surface, NULL, NULL); - assert(bg_fb); - - int bg_status = -1; - while(!do_exit) { - pthread_mutex_lock(&s->lock); - if (bg_status == s->status) { - // will always be signaled if it changes? - pthread_cond_wait(&s->bg_cond, &s->lock); - } - bg_status = s->status; - pthread_mutex_unlock(&s->lock); - - assert(bg_status < ARRAYSIZE(bg_colors)); - const uint8_t *color = bg_colors[bg_status]; - - glClearColor(color[0]/256.0, color[1]/256.0, color[2]/256.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - eglSwapBuffers(bg_display, bg_surface); - assert(glGetError() == GL_NO_ERROR); - } - - return NULL; -} - -int is_leon() { - #define MAXCHAR 1000 - FILE *fp; - char str[MAXCHAR]; - char* filename = "/proc/cmdline"; - - fp = fopen(filename, "r"); - if (fp == NULL){ - printf("Could not open file %s",filename); - return 0; - } - fgets(str, MAXCHAR, fp); - fclose(fp); - return strstr(str, "letv") != NULL; -} - -int main() { - int err; - setpriority(PRIO_PROCESS, 0, -14); - - zsys_handler_set(NULL); - signal(SIGINT, (sighandler_t)set_do_exit); - - UIState uistate; - UIState *s = &uistate; - ui_init(s); - - pthread_t connect_thread_handle; - err = pthread_create(&connect_thread_handle, NULL, - vision_connect_thread, s); - assert(err == 0); - - pthread_t light_sensor_thread_handle; - err = pthread_create(&light_sensor_thread_handle, NULL, - light_sensor_thread, s); - assert(err == 0); - - pthread_t bg_thread_handle; - err = pthread_create(&bg_thread_handle, NULL, - bg_thread, s); - assert(err == 0); - - TouchState touch = {0}; - touch_init(&touch); - - char* error = NULL; - ui_sound_init(&error); - if (error) { - LOGW(error); - exit(1); - } - - // light sensor scaling params - const int EON = (access("/EON", F_OK) != -1); - const int LEON = is_leon(); - - const float BRIGHTNESS_B = LEON? 10.0 : 5.0; - const float BRIGHTNESS_M = LEON? 2.6 : 1.3; - #define NEO_BRIGHTNESS 100 - - float smooth_brightness = BRIGHTNESS_B; - - set_volume(s, 0); - - while (!do_exit) { - bool should_swap = false; - pthread_mutex_lock(&s->lock); - - if (EON) { - // light sensor is only exposed on EONs - - float clipped_brightness = (s->light_sensor*BRIGHTNESS_M) + BRIGHTNESS_B; - if (clipped_brightness > 255) clipped_brightness = 255; - smooth_brightness = clipped_brightness * 0.01 + smooth_brightness * 0.99; - set_brightness(s, (int)smooth_brightness); - } else { - // compromise for bright and dark envs - set_brightness(s, NEO_BRIGHTNESS); - } - - ui_update(s); - - // awake on any touch - int touch_x = -1, touch_y = -1; - int touched = touch_poll(&touch, &touch_x, &touch_y, s->awake ? 0 : 100); - if (touched == 1) { - // touch event will still happen :( - set_awake(s, true); - } - - // manage wakefulness - if (s->awake_timeout > 0) { - s->awake_timeout--; - } else { - set_awake(s, false); - } - - if (s->awake) { - ui_draw(s); - glFinish(); - should_swap = true; - } - - if (s->volume_timeout > 0) { - s->volume_timeout--; - } else { - int volume = min(13, 11 + s->scene.v_ego / 15); // up one notch every 15 m/s, starting at 11 - set_volume(s, volume); - } - - if (s->speed_lim_off_timeout > 0) { - s->speed_lim_off_timeout--; - } else { - read_speed_lim_off(s); - } - - if (s->is_metric_timeout > 0) { - s->is_metric_timeout--; - } else { - read_is_metric(s); - } - - if (s->limit_set_speed_timeout > 0) { - s->limit_set_speed_timeout--; - } else { - read_limit_set_speed(s); - } - - pthread_mutex_unlock(&s->lock); - - // the bg thread needs to be scheduled, so the main thread needs time without the lock - // safe to do this outside the lock? - if (should_swap) { - eglSwapBuffers(s->display, s->surface); - } - } - - set_awake(s, true); - - slplay_destroy(); - - // wake up bg thread to exit - pthread_mutex_lock(&s->lock); - pthread_cond_signal(&s->bg_cond); - pthread_mutex_unlock(&s->lock); - err = pthread_join(bg_thread_handle, NULL); - assert(err == 0); - - err = pthread_join(connect_thread_handle, NULL); - assert(err == 0); - - return 0; -} diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc new file mode 100644 index 00000000000000..2cb1e190d2fd0f --- /dev/null +++ b/selfdrive/ui/ui.cc @@ -0,0 +1,2298 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include "nanovg.h" +#define NANOVG_GLES3_IMPLEMENTATION +#include "nanovg_gl.h" +#include "nanovg_gl_utils.h" + +#include "common/messaging.h" +#include "common/timing.h" +#include "common/util.h" +#include "common/swaglog.h" +#include "common/mat.h" + +extern "C"{ +#include "common/glutil.h" +} + +#include "common/touch.h" +#include "common/framebuffer.h" +#include "common/visionipc.h" +#include "common/visionimg.h" +#include "common/modeldata.h" +#include "common/params.h" + +#include "cereal/gen/c/log.capnp.h" + +extern "C"{ +#include "slplay.h" +} + +#include "messaging.hpp" + +#define STATUS_STOPPED 0 +#define STATUS_DISENGAGED 1 +#define STATUS_ENGAGED 2 +#define STATUS_WARNING 3 +#define STATUS_ALERT 4 + +#define ALERTSIZE_NONE 0 +#define ALERTSIZE_SMALL 1 +#define ALERTSIZE_MID 2 +#define ALERTSIZE_FULL 3 + +#define UI_BUF_COUNT 4 +//#define SHOW_SPEEDLIMIT 1 +//#define DEBUG_TURN + +//#define DEBUG_FPS + +const int vwp_w = 1920; +const int vwp_h = 1080; +const int nav_w = 640; +const int nav_ww= 760; +const int sbr_w = 300; +const int bdr_s = 30; +const int box_x = sbr_w+bdr_s; +const int box_y = bdr_s; +const int box_w = vwp_w-sbr_w-(bdr_s*2); +const int box_h = vwp_h-(bdr_s*2); +const int viz_w = vwp_w-(bdr_s*2); +const int header_h = 420; +const int footer_h = 280; +const int footer_y = vwp_h-bdr_s-footer_h; + +const int UI_FREQ = 30; // Hz + +const int MODEL_PATH_MAX_VERTICES_CNT = 98; +const int MODEL_LANE_PATH_CNT = 3; +const int TRACK_POINTS_MAX_CNT = 50 * 2; + +const uint8_t bg_colors[][4] = { + [STATUS_STOPPED] = {0x07, 0x23, 0x39, 0xff}, + [STATUS_DISENGAGED] = {0x17, 0x33, 0x49, 0xff}, + [STATUS_ENGAGED] = {0x17, 0x86, 0x44, 0xff}, + [STATUS_WARNING] = {0xDA, 0x6F, 0x25, 0xff}, + [STATUS_ALERT] = {0xC9, 0x22, 0x31, 0xff}, +}; + +const uint8_t alert_colors[][4] = { + [STATUS_STOPPED] = {0x07, 0x23, 0x39, 0xf1}, + [STATUS_DISENGAGED] = {0x17, 0x33, 0x49, 0xc8}, + [STATUS_ENGAGED] = {0x17, 0x86, 0x44, 0xf1}, + [STATUS_WARNING] = {0xDA, 0x6F, 0x25, 0xf1}, + [STATUS_ALERT] = {0xC9, 0x22, 0x31, 0xf1}, +}; + +const int alert_sizes[] = { + [ALERTSIZE_NONE] = 0, + [ALERTSIZE_SMALL] = 241, + [ALERTSIZE_MID] = 390, + [ALERTSIZE_FULL] = vwp_h, +}; + +const int SET_SPEED_NA = 255; + +// TODO: this is also hardcoded in common/transformations/camera.py +const mat3 intrinsic_matrix = (mat3){{ + 910., 0., 582., + 0., 910., 437., + 0., 0., 1. +}}; + +typedef enum cereal_CarControl_HUDControl_AudibleAlert AudibleAlert; + +typedef struct UIScene { + int frontview; + int fullview; + + int transformed_width, transformed_height; + + uint64_t model_ts; + ModelData model; + + float mpc_x[50]; + float mpc_y[50]; + + bool world_objects_visible; + mat4 extrinsic_matrix; // Last row is 0 so we can use mat4. + + float v_cruise; + uint64_t v_cruise_update_ts; + float v_ego; + bool decel_for_model; + + float speedlimit; + bool speedlimit_valid; + bool map_valid; + + float curvature; + int engaged; + bool engageable; + bool monitoring_active; + + bool uilayout_sidebarcollapsed; + bool uilayout_mapenabled; + // responsive layout + int ui_viz_rx; + int ui_viz_rw; + int ui_viz_ro; + + int lead_status; + float lead_d_rel, lead_y_rel, lead_v_rel; + + int front_box_x, front_box_y, front_box_width, front_box_height; + + uint64_t alert_ts; + char alert_text1[1024]; + char alert_text2[1024]; + uint8_t alert_size; + float alert_blinkingrate; + + float awareness_status; + + uint64_t started_ts; + + // Used to show gps planner status + bool gps_planner_active; +} UIScene; + +typedef struct { + float x, y; +}vertex_data; + +typedef struct { + vertex_data v[MODEL_PATH_MAX_VERTICES_CNT]; + int cnt; +} model_path_vertices_data; + +typedef struct { + vertex_data v[TRACK_POINTS_MAX_CNT]; + int cnt; +} track_vertices_data; + + +typedef struct UIState { + pthread_mutex_t lock; + pthread_cond_t bg_cond; + + FramebufferState *fb; + int fb_w, fb_h; + EGLDisplay display; + EGLSurface surface; + + NVGcontext *vg; + + int font_courbd; + int font_sans_regular; + int font_sans_semibold; + int font_sans_bold; + int img_wheel; + int img_turn; + int img_face; + int img_map; + + // Sockets + Context *ctx; + SubSocket *thermal_sock; + SubSocket *model_sock; + SubSocket *controlsstate_sock; + SubSocket *livecalibration_sock; + SubSocket *radarstate_sock; + SubSocket *plus_sock; + SubSocket *map_data_sock; + SubSocket *uilayout_sock; + Poller * poller; + + int plus_state; + + // vision state + bool vision_connected; + bool vision_connect_firstrun; + int ipc_fd; + + VIPCBuf bufs[UI_BUF_COUNT]; + VIPCBuf front_bufs[UI_BUF_COUNT]; + int cur_vision_idx; + int cur_vision_front_idx; + + GLuint frame_program; + GLuint frame_texs[UI_BUF_COUNT]; + EGLImageKHR khr[UI_BUF_COUNT]; + void *priv_hnds[UI_BUF_COUNT]; + GLuint frame_front_texs[UI_BUF_COUNT]; + EGLImageKHR khr_front[UI_BUF_COUNT]; + void *priv_hnds_front[UI_BUF_COUNT]; + + GLint frame_pos_loc, frame_texcoord_loc; + GLint frame_texture_loc, frame_transform_loc; + + GLuint line_program; + GLint line_pos_loc, line_color_loc; + GLint line_transform_loc; + + int rgb_width, rgb_height, rgb_stride; + size_t rgb_buf_len; + mat4 rgb_transform; + + int rgb_front_width, rgb_front_height, rgb_front_stride; + size_t rgb_front_buf_len; + + UIScene scene; + + bool awake; + int awake_timeout; + + int volume_timeout; + int controls_timeout; + int alert_sound_timeout; + int speed_lim_off_timeout; + int is_metric_timeout; + int longitudinal_control_timeout; + int limit_set_speed_timeout; + + bool controls_seen; + + int status; + bool is_metric; + bool longitudinal_control; + bool limit_set_speed; + float speed_lim_off; + bool is_ego_over_limit; + char alert_type[64]; + AudibleAlert alert_sound; + int alert_size; + float alert_blinking_alpha; + bool alert_blinked; + + float light_sensor; + + int touch_fd; + + // Hints for re-calculations and redrawing + bool model_changed; + bool livempc_or_radarstate_changed; + + GLuint frame_vao[2], frame_vbo[2], frame_ibo[2]; + mat4 rear_frame_mat, front_frame_mat; + + model_path_vertices_data model_path_vertices[MODEL_LANE_PATH_CNT * 2]; + + track_vertices_data track_vertices[2]; +} UIState; + +static int last_brightness = -1; +static void set_brightness(UIState *s, int brightness) { + if (last_brightness != brightness && (s->awake || brightness == 0)) { + FILE *f = fopen("/sys/class/leds/lcd-backlight/brightness", "wb"); + if (f != NULL) { + fprintf(f, "%d", brightness); + fclose(f); + last_brightness = brightness; + } + } +} + +static void set_awake(UIState *s, bool awake) { + if (awake) { + // 30 second timeout at 30 fps + s->awake_timeout = 30*30; + } + if (s->awake != awake) { + s->awake = awake; + + // TODO: replace command_awake and command_sleep with direct calls to android + if (awake) { + LOGW("awake normal"); + system("service call window 18 i32 1"); // enable event processing + framebuffer_set_power(s->fb, HWC_POWER_MODE_NORMAL); + } else { + LOGW("awake off"); + set_brightness(s, 0); + system("service call window 18 i32 0"); // disable event processing + framebuffer_set_power(s->fb, HWC_POWER_MODE_OFF); + } + } +} + +static void set_volume(UIState *s, int volume) { + char volume_change_cmd[64]; + sprintf(volume_change_cmd, "service call audio 3 i32 3 i32 %d i32 1", volume); + + // 5 second timeout at 60fps + s->volume_timeout = 5 * UI_FREQ; + int volume_changed = system(volume_change_cmd); +} + +volatile sig_atomic_t do_exit = 0; +static void set_do_exit(int sig) { + do_exit = 1; +} + +static void read_param_bool(bool* param, const char* param_name) { + char *s; + const int result = read_db_value(NULL, param_name, &s, NULL); + if (result == 0) { + *param = s[0] == '1'; + free(s); + } +} + +static void read_param_float(float* param, const char* param_name) { + char *s; + const int result = read_db_value(NULL, param_name, &s, NULL); + if (result == 0) { + *param = strtod(s, NULL); + free(s); + } +} + +static void read_param_bool_timeout(bool* param, const char* param_name, int* timeout) { + if (*timeout > 0){ + (*timeout)--; + } else { + read_param_bool(param, param_name); + *timeout = 2 * UI_FREQ; // 0.5Hz + } +} + +static void read_param_float_timeout(float* param, const char* param_name, int* timeout) { + if (*timeout > 0){ + (*timeout)--; + } else { + read_param_float(param, param_name); + *timeout = 2 * UI_FREQ; // 0.5Hz + } +} + +static const char frame_vertex_shader[] = + "attribute vec4 aPosition;\n" + "attribute vec4 aTexCoord;\n" + "uniform mat4 uTransform;\n" + "varying vec4 vTexCoord;\n" + "void main() {\n" + " gl_Position = uTransform * aPosition;\n" + " vTexCoord = aTexCoord;\n" + "}\n"; + +static const char frame_fragment_shader[] = + "precision mediump float;\n" + "uniform sampler2D uTexture;\n" + "varying vec4 vTexCoord;\n" + "void main() {\n" + " gl_FragColor = texture2D(uTexture, vTexCoord.xy);\n" + "}\n"; + +static const char line_vertex_shader[] = + "attribute vec4 aPosition;\n" + "attribute vec4 aColor;\n" + "uniform mat4 uTransform;\n" + "varying vec4 vColor;\n" + "void main() {\n" + " gl_Position = uTransform * aPosition;\n" + " vColor = aColor;\n" + "}\n"; + +static const char line_fragment_shader[] = + "precision mediump float;\n" + "uniform sampler2D uTexture;\n" + "varying vec4 vColor;\n" + "void main() {\n" + " gl_FragColor = vColor;\n" + "}\n"; + + +static const mat4 device_transform = {{ + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, +}}; + +// frame from 4/3 to box size with a 2x zoom +static const mat4 frame_transform = {{ + 2*(4./3.)/((float)viz_w/box_h), 0.0, 0.0, 0.0, + 0.0, 2.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, +}}; + +// frame from 4/3 to 16/9 display +static const mat4 full_to_wide_frame_transform = {{ + .75, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, +}}; + +typedef struct { + AudibleAlert alert; + const char* uri; + bool loop; +} sound_file; + +sound_file sound_table[] = { + { cereal_CarControl_HUDControl_AudibleAlert_chimeDisengage, "../assets/sounds/disengaged.wav", false }, + { cereal_CarControl_HUDControl_AudibleAlert_chimeEngage, "../assets/sounds/engaged.wav", false }, + { cereal_CarControl_HUDControl_AudibleAlert_chimeWarning1, "../assets/sounds/warning_1.wav", false }, + { cereal_CarControl_HUDControl_AudibleAlert_chimeWarning2, "../assets/sounds/warning_2.wav", false }, + { cereal_CarControl_HUDControl_AudibleAlert_chimeWarningRepeat, "../assets/sounds/warning_repeat.wav", true }, + { cereal_CarControl_HUDControl_AudibleAlert_chimeError, "../assets/sounds/error.wav", false }, + { cereal_CarControl_HUDControl_AudibleAlert_chimePrompt, "../assets/sounds/error.wav", false }, + { cereal_CarControl_HUDControl_AudibleAlert_none, NULL, false }, +}; + +sound_file* get_sound_file(AudibleAlert alert) { + for (sound_file *s = sound_table; s->alert != cereal_CarControl_HUDControl_AudibleAlert_none; s++) { + if (s->alert == alert) { + return s; + } + } + + return NULL; +} + +void play_alert_sound(AudibleAlert alert) { + sound_file* sound = get_sound_file(alert); + char* error = NULL; + + slplay_play(sound->uri, sound->loop, &error); + if(error) { + LOGW("error playing sound: %s", error); + } +} + +void stop_alert_sound(AudibleAlert alert) { + sound_file* sound = get_sound_file(alert); + char* error = NULL; + + slplay_stop_uri(sound->uri, &error); + if(error) { + LOGW("error stopping sound: %s", error); + } +} + +void ui_sound_init(char **error) { + slplay_setup(error); + if (*error) return; + + for (sound_file *s = sound_table; s->alert != cereal_CarControl_HUDControl_AudibleAlert_none; s++) { + slplay_create_player_for_uri(s->uri, error); + if (*error) return; + } +} + +static void ui_init(UIState *s) { + memset(s, 0, sizeof(UIState)); + + pthread_mutex_init(&s->lock, NULL); + pthread_cond_init(&s->bg_cond, NULL); + + s->ctx = Context::create(); + s->thermal_sock = SubSocket::create(s->ctx, "thermal"); + s->model_sock = SubSocket::create(s->ctx, "model"); + s->controlsstate_sock = SubSocket::create(s->ctx, "controlsState"); + s->uilayout_sock = SubSocket::create(s->ctx, "uiLayoutState"); + s->livecalibration_sock = SubSocket::create(s->ctx, "liveCalibration"); + s->radarstate_sock = SubSocket::create(s->ctx, "radarState"); + s->plus_sock = SubSocket::create(s->ctx, "plusFrame"); + s->poller = Poller::create({ + s->thermal_sock, + s->model_sock, + s->controlsstate_sock, + s->uilayout_sock, + s->livecalibration_sock, + s->radarstate_sock, + s->plus_sock + }); + +#ifdef SHOW_SPEEDLIMIT + s->map_data_sock = SubSock::create(s->ctx, "liveMapData"); + s->poller.registerSocket(s->map_data_sock); +#endif + + s->ipc_fd = -1; + + // init display + s->fb = framebuffer_init("ui", 0x00010000, true, + &s->display, &s->surface, &s->fb_w, &s->fb_h); + assert(s->fb); + + set_awake(s, true); + + // init drawing + s->vg = nvgCreateGLES3(NVG_ANTIALIAS | NVG_STENCIL_STROKES | NVG_DEBUG); + assert(s->vg); + + s->font_courbd = nvgCreateFont(s->vg, "courbd", "../assets/fonts/courbd.ttf"); + assert(s->font_courbd >= 0); + s->font_sans_regular = nvgCreateFont(s->vg, "sans-regular", "../assets/fonts/opensans_regular.ttf"); + assert(s->font_sans_regular >= 0); + s->font_sans_semibold = nvgCreateFont(s->vg, "sans-semibold", "../assets/fonts/opensans_semibold.ttf"); + assert(s->font_sans_semibold >= 0); + s->font_sans_bold = nvgCreateFont(s->vg, "sans-bold", "../assets/fonts/opensans_bold.ttf"); + assert(s->font_sans_bold >= 0); + + assert(s->img_wheel >= 0); + s->img_wheel = nvgCreateImage(s->vg, "../assets/img_chffr_wheel.png", 1); + + assert(s->img_turn >= 0); + s->img_turn = nvgCreateImage(s->vg, "../assets/img_trafficSign_turn.png", 1); + + assert(s->img_face >= 0); + s->img_face = nvgCreateImage(s->vg, "../assets/img_driver_face.png", 1); + + assert(s->img_map >= 0); + s->img_map = nvgCreateImage(s->vg, "../assets/img_map.png", 1); + + // init gl + s->frame_program = load_program(frame_vertex_shader, frame_fragment_shader); + assert(s->frame_program); + + s->frame_pos_loc = glGetAttribLocation(s->frame_program, "aPosition"); + s->frame_texcoord_loc = glGetAttribLocation(s->frame_program, "aTexCoord"); + + s->frame_texture_loc = glGetUniformLocation(s->frame_program, "uTexture"); + s->frame_transform_loc = glGetUniformLocation(s->frame_program, "uTransform"); + + s->line_program = load_program(line_vertex_shader, line_fragment_shader); + assert(s->line_program); + + s->line_pos_loc = glGetAttribLocation(s->line_program, "aPosition"); + s->line_color_loc = glGetAttribLocation(s->line_program, "aColor"); + s->line_transform_loc = glGetUniformLocation(s->line_program, "uTransform"); + + glViewport(0, 0, s->fb_w, s->fb_h); + + glDisable(GL_DEPTH_TEST); + + assert(glGetError() == GL_NO_ERROR); + + for(int i = 0; i < 2; i++) { + float x1, x2, y1, y2; + if (i == 1) { + // flip horizontally so it looks like a mirror + x1 = 0.0; + x2 = 1.0; + y1 = 1.0; + y2 = 0.0; + } else { + x1 = 1.0; + x2 = 0.0; + y1 = 1.0; + y2 = 0.0; + } + const uint8_t frame_indicies[] = {0, 1, 2, 0, 2, 3}; + const float frame_coords[4][4] = { + {-1.0, -1.0, x2, y1}, //bl + {-1.0, 1.0, x2, y2}, //tl + { 1.0, 1.0, x1, y2}, //tr + { 1.0, -1.0, x1, y1}, //br + }; + + glGenVertexArrays(1,&s->frame_vao[i]); + glBindVertexArray(s->frame_vao[i]); + glGenBuffers(1, &s->frame_vbo[i]); + glBindBuffer(GL_ARRAY_BUFFER, s->frame_vbo[i]); + glBufferData(GL_ARRAY_BUFFER, sizeof(frame_coords), frame_coords, GL_STATIC_DRAW); + glEnableVertexAttribArray(s->frame_pos_loc); + glVertexAttribPointer(s->frame_pos_loc, 2, GL_FLOAT, GL_FALSE, + sizeof(frame_coords[0]), (const void *)0); + glEnableVertexAttribArray(s->frame_texcoord_loc); + glVertexAttribPointer(s->frame_texcoord_loc, 2, GL_FLOAT, GL_FALSE, + sizeof(frame_coords[0]), (const void *)(sizeof(float) * 2)); + glGenBuffers(1, &s->frame_ibo[i]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->frame_ibo[i]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(frame_indicies), frame_indicies, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER,0); + glBindVertexArray(0); + } + + s->model_changed = false; + s->livempc_or_radarstate_changed = false; + + s->front_frame_mat = matmul(device_transform, full_to_wide_frame_transform); + s->rear_frame_mat = matmul(device_transform, frame_transform); + + for(int i = 0;i < UI_BUF_COUNT; i++) { + s->khr[i] = NULL; + s->priv_hnds[i] = NULL; + s->khr_front[i] = NULL; + s->priv_hnds_front[i] = NULL; + } +} + +static void ui_init_vision(UIState *s, const VisionStreamBufs back_bufs, + int num_back_fds, const int *back_fds, + const VisionStreamBufs front_bufs, int num_front_fds, + const int *front_fds) { + const VisionUIInfo ui_info = back_bufs.buf_info.ui_info; + + assert(num_back_fds == UI_BUF_COUNT); + assert(num_front_fds == UI_BUF_COUNT); + + vipc_bufs_load(s->bufs, &back_bufs, num_back_fds, back_fds); + vipc_bufs_load(s->front_bufs, &front_bufs, num_front_fds, front_fds); + + s->cur_vision_idx = -1; + s->cur_vision_front_idx = -1; + + s->scene = (UIScene){ + .frontview = getenv("FRONTVIEW") != NULL, + .fullview = getenv("FULLVIEW") != NULL, + .transformed_width = ui_info.transformed_width, + .transformed_height = ui_info.transformed_height, + .front_box_x = ui_info.front_box_x, + .front_box_y = ui_info.front_box_y, + .front_box_width = ui_info.front_box_width, + .front_box_height = ui_info.front_box_height, + .world_objects_visible = false, // Invisible until we receive a calibration message. + .gps_planner_active = false, + }; + + s->rgb_width = back_bufs.width; + s->rgb_height = back_bufs.height; + s->rgb_stride = back_bufs.stride; + s->rgb_buf_len = back_bufs.buf_len; + + s->rgb_front_width = front_bufs.width; + s->rgb_front_height = front_bufs.height; + s->rgb_front_stride = front_bufs.stride; + s->rgb_front_buf_len = front_bufs.buf_len; + + s->rgb_transform = (mat4){{ + 2.0f/s->rgb_width, 0.0f, 0.0f, -1.0f, + 0.0f, 2.0f/s->rgb_height, 0.0f, -1.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }}; + + read_param_float(&s->speed_lim_off, "SpeedLimitOffset"); + read_param_bool(&s->is_metric, "IsMetric"); + read_param_bool(&s->longitudinal_control, "LongitudinalControl"); + read_param_bool(&s->limit_set_speed, "LimitSetSpeed"); + + // Set offsets so params don't get read at the same time + s->longitudinal_control_timeout = UI_FREQ / 3; + s->is_metric_timeout = UI_FREQ / 2; + s->limit_set_speed_timeout = UI_FREQ; +} + +// Projects a point in car to space to the corresponding point in full frame +// image space. +vec3 car_space_to_full_frame(const UIState *s, vec4 car_space_projective) { + const UIScene *scene = &s->scene; + + // We'll call the car space point p. + // First project into normalized image coordinates with the extrinsics matrix. + const vec4 Ep4 = matvecmul(scene->extrinsic_matrix, car_space_projective); + + // The last entry is zero because of how we store E (to use matvecmul). + const vec3 Ep = {{Ep4.v[0], Ep4.v[1], Ep4.v[2]}}; + const vec3 KEp = matvecmul3(intrinsic_matrix, Ep); + + // Project. + const vec3 p_image = {{KEp.v[0] / KEp.v[2], KEp.v[1] / KEp.v[2], 1.}}; + return p_image; +} + +// Calculate an interpolation between two numbers at a specific increment +static float lerp(float v0, float v1, float t) { + return (1 - t) * v0 + t * v1; +} + +static void draw_chevron(UIState *s, float x_in, float y_in, float sz, + NVGcolor fillColor, NVGcolor glowColor) { + const UIScene *scene = &s->scene; + + nvgSave(s->vg); + + nvgTranslate(s->vg, 240.0f, 0.0); + nvgTranslate(s->vg, -1440.0f / 2, -1080.0f / 2); + nvgScale(s->vg, 2.0, 2.0); + nvgScale(s->vg, 1440.0f / s->rgb_width, 1080.0f / s->rgb_height); + + const vec4 p_car_space = (vec4){{x_in, y_in, 0., 1.}}; + const vec3 p_full_frame = car_space_to_full_frame(s, p_car_space); + + sz *= 30; + sz /= (x_in / 3 + 30); + if (sz > 30) sz = 30; + if (sz < 15) sz = 15; + + float x = p_full_frame.v[0]; + float y = p_full_frame.v[1]; + + // glow + nvgBeginPath(s->vg); + float g_xo = sz/5; + float g_yo = sz/10; + if (x >= 0 && y >= 0.) { + nvgMoveTo(s->vg, x+(sz*1.35)+g_xo, y+sz+g_yo); + nvgLineTo(s->vg, x, y-g_xo); + nvgLineTo(s->vg, x-(sz*1.35)-g_xo, y+sz+g_yo); + nvgLineTo(s->vg, x+(sz*1.35)+g_xo, y+sz+g_yo); + nvgClosePath(s->vg); + } + nvgFillColor(s->vg, glowColor); + nvgFill(s->vg); + + // chevron + nvgBeginPath(s->vg); + if (x >= 0 && y >= 0.) { + nvgMoveTo(s->vg, x+(sz*1.25), y+sz); + nvgLineTo(s->vg, x, y); + nvgLineTo(s->vg, x-(sz*1.25), y+sz); + nvgLineTo(s->vg, x+(sz*1.25), y+sz); + nvgClosePath(s->vg); + } + nvgFillColor(s->vg, fillColor); + nvgFill(s->vg); + + nvgRestore(s->vg); +} + +static void ui_draw_lane_line(UIState *s, const model_path_vertices_data *pvd, NVGcolor color) { + const UIScene *scene = &s->scene; + + nvgSave(s->vg); + nvgTranslate(s->vg, 240.0f, 0.0); // rgb-box space + nvgTranslate(s->vg, -1440.0f / 2, -1080.0f / 2); // zoom 2x + nvgScale(s->vg, 2.0, 2.0); + nvgScale(s->vg, 1440.0f / s->rgb_width, 1080.0f / s->rgb_height); + nvgBeginPath(s->vg); + + bool started = false; + for (int i=0; icnt; i++) { + if (pvd->v[i].x < 0 || pvd->v[i].y < 0.) { + continue; + } + if (!started) { + nvgMoveTo(s->vg, pvd->v[i].x, pvd->v[i].y); + started = true; + } else { + nvgLineTo(s->vg, pvd->v[i].x, pvd->v[i].y); + } + } + + nvgClosePath(s->vg); + nvgFillColor(s->vg, color); + nvgFill(s->vg); + nvgRestore(s->vg); +} + +static void update_track_data(UIState *s, bool is_mpc, track_vertices_data *pvd) { + const UIScene *scene = &s->scene; + const PathData path = scene->model.path; + const float *mpc_x_coords = &scene->mpc_x[0]; + const float *mpc_y_coords = &scene->mpc_y[0]; + + bool started = false; + float off = is_mpc?0.3:0.5; + float lead_d = scene->lead_d_rel*2.; + float path_height = is_mpc?(lead_d>5.)?fmin(lead_d, 25.)-fmin(lead_d*0.35, 10.):20. + :(lead_d>0.)?fmin(lead_d, 50.)-fmin(lead_d*0.35, 10.):49.; + pvd->cnt = 0; + // left side up + for (int i=0; i<=path_height; i++) { + float px, py, mpx; + if (is_mpc) { + mpx = i==0?0.0:mpc_x_coords[i]; + px = lerp(mpx+1.0, mpx, i/100.0); + py = mpc_y_coords[i] - off; + } else { + px = lerp(i+1.0, i, i/100.0); + py = path.points[i] - off; + } + + vec4 p_car_space = (vec4){{px, py, 0., 1.}}; + vec3 p_full_frame = car_space_to_full_frame(s, p_car_space); + if (p_full_frame.v[0] < 0. || p_full_frame.v[1] < 0.) { + continue; + } + pvd->v[pvd->cnt].x = p_full_frame.v[0]; + pvd->v[pvd->cnt].y = p_full_frame.v[1]; + pvd->cnt += 1; + } + + // right side down + for (int i=path_height; i>=0; i--) { + float px, py, mpx; + if (is_mpc) { + mpx = i==0?0.0:mpc_x_coords[i]; + px = lerp(mpx+1.0, mpx, i/100.0); + py = mpc_y_coords[i] + off; + } else { + px = lerp(i+1.0, i, i/100.0); + py = path.points[i] + off; + } + + vec4 p_car_space = (vec4){{px, py, 0., 1.}}; + vec3 p_full_frame = car_space_to_full_frame(s, p_car_space); + pvd->v[pvd->cnt].x = p_full_frame.v[0]; + pvd->v[pvd->cnt].y = p_full_frame.v[1]; + pvd->cnt += 1; + } +} + +static void update_all_track_data(UIState *s) { + const UIScene *scene = &s->scene; + // Draw vision path + update_track_data(s, false, &s->track_vertices[0]); + + if (scene->engaged) { + // Draw MPC path when engaged + update_track_data(s, true, &s->track_vertices[1]); + } +} + + +static void ui_draw_track(UIState *s, bool is_mpc, track_vertices_data *pvd) { +const UIScene *scene = &s->scene; + const PathData path = scene->model.path; + const float *mpc_x_coords = &scene->mpc_x[0]; + const float *mpc_y_coords = &scene->mpc_y[0]; + + nvgSave(s->vg); + nvgTranslate(s->vg, 240.0f, 0.0); // rgb-box space + nvgTranslate(s->vg, -1440.0f / 2, -1080.0f / 2); // zoom 2x + nvgScale(s->vg, 2.0, 2.0); + nvgScale(s->vg, 1440.0f / s->rgb_width, 1080.0f / s->rgb_height); + nvgBeginPath(s->vg); + + bool started = false; + float off = is_mpc?0.3:0.5; + float lead_d = scene->lead_d_rel*2.; + float path_height = is_mpc?(lead_d>5.)?fmin(lead_d, 25.)-fmin(lead_d*0.35, 10.):20. + :(lead_d>0.)?fmin(lead_d, 50.)-fmin(lead_d*0.35, 10.):49.; + int vi = 0; + for(int i = 0;i < pvd->cnt;i++) { + if (pvd->v[i].x < 0 || pvd->v[i].y < 0) { + continue; + } + + if (!started) { + nvgMoveTo(s->vg, pvd->v[i].x, pvd->v[i].y); + started = true; + } else { + nvgLineTo(s->vg, pvd->v[i].x, pvd->v[i].y); + } + } + + nvgClosePath(s->vg); + + NVGpaint track_bg; + if (is_mpc) { + // Draw colored MPC track + const uint8_t *clr = bg_colors[s->status]; + track_bg = nvgLinearGradient(s->vg, vwp_w, vwp_h, vwp_w, vwp_h*.4, + nvgRGBA(clr[0], clr[1], clr[2], 255), nvgRGBA(clr[0], clr[1], clr[2], 255/2)); + } else { + // Draw white vision track + track_bg = nvgLinearGradient(s->vg, vwp_w, vwp_h, vwp_w, vwp_h*.4, + nvgRGBA(255, 255, 255, 255), nvgRGBA(255, 255, 255, 0)); + } + + nvgFillPaint(s->vg, track_bg); + nvgFill(s->vg); + nvgRestore(s->vg); +} + +static void draw_steering(UIState *s, float curvature) { + float points[50]; + for (int i = 0; i < 50; i++) { + float y_actual = i * tan(asin(clamp(i * curvature, -0.999, 0.999)) / 2.); + points[i] = y_actual; + } + + // ui_draw_lane_edge(s, points, 0.0, nvgRGBA(0, 0, 255, 128), 5); +} + +static void draw_frame(UIState *s) { + const UIScene *scene = &s->scene; + + float x1, x2, y1, y2; + if (s->scene.frontview) { + glBindVertexArray(s->frame_vao[1]); + } else { + glBindVertexArray(s->frame_vao[0]); + } + + mat4 *out_mat; + if (s->scene.frontview || s->scene.fullview) { + out_mat = &s->front_frame_mat; + } else { + out_mat = &s->rear_frame_mat; + } + glActiveTexture(GL_TEXTURE0); + if (s->scene.frontview && s->cur_vision_front_idx >= 0) { + glBindTexture(GL_TEXTURE_2D, s->frame_front_texs[s->cur_vision_front_idx]); + } else if (!scene->frontview && s->cur_vision_idx >= 0) { + glBindTexture(GL_TEXTURE_2D, s->frame_texs[s->cur_vision_idx]); + } + + glUseProgram(s->frame_program); + glUniform1i(s->frame_texture_loc, 0); + glUniformMatrix4fv(s->frame_transform_loc, 1, GL_TRUE, out_mat->v); + + assert(glGetError() == GL_NO_ERROR); + glEnableVertexAttribArray(0); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, (const void*)0); + glDisableVertexAttribArray(0); + glBindVertexArray(0); +} + +static inline bool valid_frame_pt(UIState *s, float x, float y) { + return x >= 0 && x <= s->rgb_width && y >= 0 && y <= s->rgb_height; + +} +static void update_lane_line_data(UIState *s, const float *points, float off, bool is_ghost, model_path_vertices_data *pvd) { + pvd->cnt = 0; + for (int i = 0; i < MODEL_PATH_MAX_VERTICES_CNT / 2; i++) { + float px = (float)i; + float py = points[i] - off; + const vec4 p_car_space = (vec4){{px, py, 0., 1.}}; + const vec3 p_full_frame = car_space_to_full_frame(s, p_car_space); + if(!valid_frame_pt(s, p_full_frame.v[0], p_full_frame.v[1])) + continue; + pvd->v[pvd->cnt].x = p_full_frame.v[0]; + pvd->v[pvd->cnt].y = p_full_frame.v[1]; + pvd->cnt += 1; + } + for (int i = MODEL_PATH_MAX_VERTICES_CNT / 2; i > 0; i--) { + float px = (float)i; + float py = is_ghost?(points[i]-off):(points[i]+off); + const vec4 p_car_space = (vec4){{px, py, 0., 1.}}; + const vec3 p_full_frame = car_space_to_full_frame(s, p_car_space); + if(!valid_frame_pt(s, p_full_frame.v[0], p_full_frame.v[1])) + continue; + pvd->v[pvd->cnt].x = p_full_frame.v[0]; + pvd->v[pvd->cnt].y = p_full_frame.v[1]; + pvd->cnt += 1; + } +} + +static void update_all_lane_lines_data(UIState *s, const PathData path, model_path_vertices_data *pstart) { + update_lane_line_data(s, path.points, 0.025*path.prob, false, pstart); + float var = fmin(path.std, 0.7); + update_lane_line_data(s, path.points, -var, true, pstart + 1); + update_lane_line_data(s, path.points, var, true, pstart + 2); +} + +static void ui_draw_lane(UIState *s, const PathData *path, model_path_vertices_data *pstart, NVGcolor color) { + ui_draw_lane_line(s, pstart, color); + float var = fmin(path->std, 0.7); + color.a /= 4; + ui_draw_lane_line(s, pstart + 1, color); + ui_draw_lane_line(s, pstart + 2, color); +} + +static void ui_draw_vision_lanes(UIState *s) { + const UIScene *scene = &s->scene; + model_path_vertices_data *pvd = &s->model_path_vertices[0]; + if(s->model_changed) { + update_all_lane_lines_data(s, scene->model.left_lane, pvd); + update_all_lane_lines_data(s, scene->model.right_lane, pvd + MODEL_LANE_PATH_CNT); + s->model_changed = false; + } + // Draw left lane edge + ui_draw_lane( + s, &scene->model.left_lane, + pvd, + nvgRGBAf(1.0, 1.0, 1.0, scene->model.left_lane.prob)); + + // Draw right lane edge + ui_draw_lane( + s, &scene->model.right_lane, + pvd + MODEL_LANE_PATH_CNT, + nvgRGBAf(1.0, 1.0, 1.0, scene->model.right_lane.prob)); + + if(s->livempc_or_radarstate_changed) { + update_all_track_data(s); + s->livempc_or_radarstate_changed = false; + } + // Draw vision path + ui_draw_track(s, false, &s->track_vertices[0]); + if (scene->engaged) { + // Draw MPC path when engaged + ui_draw_track(s, true, &s->track_vertices[1]); + } +} + +// Draw all world space objects. +static void ui_draw_world(UIState *s) { + const UIScene *scene = &s->scene; + if (!scene->world_objects_visible) { + return; + } + + if ((nanos_since_boot() - scene->model_ts) < 1000000000ULL) { + // Draw lane edges and vision/mpc tracks + ui_draw_vision_lanes(s); + } + + if (scene->lead_status) { + // Draw lead car indicator + float fillAlpha = 0; + float speedBuff = 10.; + float leadBuff = 40.; + if (scene->lead_d_rel < leadBuff) { + fillAlpha = 255*(1.0-(scene->lead_d_rel/leadBuff)); + if (scene->lead_v_rel < 0) { + fillAlpha += 255*(-1*(scene->lead_v_rel/speedBuff)); + } + fillAlpha = (int)(fmin(fillAlpha, 255)); + } + draw_chevron(s, scene->lead_d_rel+2.7, scene->lead_y_rel, 25, + nvgRGBA(201, 34, 49, fillAlpha), nvgRGBA(218, 202, 37, 255)); + } +} + +static void ui_draw_vision_maxspeed(UIState *s) { + /*if (!s->longitudinal_control){ + return; + }*/ + + const UIScene *scene = &s->scene; + int ui_viz_rx = scene->ui_viz_rx; + int ui_viz_rw = scene->ui_viz_rw; + + char maxspeed_str[32]; + float maxspeed = s->scene.v_cruise; + int maxspeed_calc = maxspeed * 0.6225 + 0.5; + float speedlimit = s->scene.speedlimit; + int speedlim_calc = speedlimit * 2.2369363 + 0.5; + int speed_lim_off = s->speed_lim_off * 2.2369363 + 0.5; + if (s->is_metric) { + maxspeed_calc = maxspeed + 0.5; + speedlim_calc = speedlimit * 3.6 + 0.5; + speed_lim_off = s->speed_lim_off * 3.6 + 0.5; + } + + bool is_cruise_set = (maxspeed != 0 && maxspeed != SET_SPEED_NA); + bool is_speedlim_valid = s->scene.speedlimit_valid; + bool is_set_over_limit = is_speedlim_valid && s->scene.engaged && + is_cruise_set && maxspeed_calc > (speedlim_calc + speed_lim_off); + + int viz_maxspeed_w = 184; + int viz_maxspeed_h = 202; + int viz_maxspeed_x = (ui_viz_rx + (bdr_s*2)); + int viz_maxspeed_y = (box_y + (bdr_s*1.5)); + int viz_maxspeed_xo = 180; + +#ifdef SHOW_SPEEDLIMIT + viz_maxspeed_w += viz_maxspeed_xo; + viz_maxspeed_x += viz_maxspeed_w - (viz_maxspeed_xo * 2); +#else + viz_maxspeed_xo = 0; +#endif + + // Draw Background + nvgBeginPath(s->vg); + nvgRoundedRect(s->vg, viz_maxspeed_x, viz_maxspeed_y, viz_maxspeed_w, viz_maxspeed_h, 30); + if (is_set_over_limit) { + nvgFillColor(s->vg, nvgRGBA(218, 111, 37, 180)); + } else { + nvgFillColor(s->vg, nvgRGBA(0, 0, 0, 100)); + } + nvgFill(s->vg); + + // Draw Border + nvgBeginPath(s->vg); + nvgRoundedRect(s->vg, viz_maxspeed_x, viz_maxspeed_y, viz_maxspeed_w, viz_maxspeed_h, 20); + if (is_set_over_limit) { + nvgStrokeColor(s->vg, nvgRGBA(218, 111, 37, 255)); + } else if (is_speedlim_valid && !s->is_ego_over_limit) { + nvgStrokeColor(s->vg, nvgRGBA(255, 255, 255, 255)); + } else if (is_speedlim_valid && s->is_ego_over_limit) { + nvgStrokeColor(s->vg, nvgRGBA(255, 255, 255, 20)); + } else { + nvgStrokeColor(s->vg, nvgRGBA(255, 255, 255, 100)); + } + nvgStrokeWidth(s->vg, 10); + nvgStroke(s->vg); + + // Draw "MAX" Text + nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); + nvgFontFace(s->vg, "sans-regular"); + nvgFontSize(s->vg, 26*2.5); + if (is_cruise_set) { + nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 200)); + } else { + nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 100)); + } + nvgText(s->vg, viz_maxspeed_x+(viz_maxspeed_xo/2)+(viz_maxspeed_w/2), 148, "MAX", NULL); + + // Draw Speed Text + nvgFontFace(s->vg, "sans-bold"); + nvgFontSize(s->vg, 48*2.5); + if (is_cruise_set) { + snprintf(maxspeed_str, sizeof(maxspeed_str), "%d", maxspeed_calc); + nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 255)); + nvgText(s->vg, viz_maxspeed_x+(viz_maxspeed_xo/2)+(viz_maxspeed_w/2), 242, maxspeed_str, NULL); + } else { + nvgFontFace(s->vg, "sans-semibold"); + nvgFontSize(s->vg, 42*2.5); + nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 100)); + nvgText(s->vg, viz_maxspeed_x+(viz_maxspeed_xo/2)+(viz_maxspeed_w/2), 242, "N/A", NULL); + } + +} + +static void ui_draw_vision_speedlimit(UIState *s) { + const UIScene *scene = &s->scene; + int ui_viz_rx = scene->ui_viz_rx; + int ui_viz_rw = scene->ui_viz_rw; + + char speedlim_str[32]; + float speedlimit = s->scene.speedlimit; + int speedlim_calc = speedlimit * 2.2369363 + 0.5; + if (s->is_metric) { + speedlim_calc = speedlimit * 3.6 + 0.5; + } + + bool is_speedlim_valid = s->scene.speedlimit_valid; + float hysteresis_offset = 0.5; + if (s->is_ego_over_limit) { + hysteresis_offset = 0.0; + } + s->is_ego_over_limit = is_speedlim_valid && s->scene.v_ego > (speedlimit + s->speed_lim_off + hysteresis_offset); + + int viz_speedlim_w = 180; + int viz_speedlim_h = 202; + int viz_speedlim_x = (ui_viz_rx + (bdr_s*2)); + int viz_speedlim_y = (box_y + (bdr_s*1.5)); + if (!is_speedlim_valid) { + viz_speedlim_w -= 5; + viz_speedlim_h -= 10; + viz_speedlim_x += 9; + viz_speedlim_y += 5; + } + int viz_speedlim_bdr = is_speedlim_valid ? 30 : 15; + + // Draw Background + nvgBeginPath(s->vg); + nvgRoundedRect(s->vg, viz_speedlim_x, viz_speedlim_y, viz_speedlim_w, viz_speedlim_h, viz_speedlim_bdr); + if (is_speedlim_valid && s->is_ego_over_limit) { + nvgFillColor(s->vg, nvgRGBA(218, 111, 37, 180)); + } else if (is_speedlim_valid) { + nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 255)); + } else { + nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 100)); + } + nvgFill(s->vg); + + // Draw Border + if (is_speedlim_valid) { + nvgStrokeWidth(s->vg, 10); + nvgStroke(s->vg); + nvgBeginPath(s->vg); + nvgRoundedRect(s->vg, viz_speedlim_x, viz_speedlim_y, viz_speedlim_w, viz_speedlim_h, 20); + if (s->is_ego_over_limit) { + nvgStrokeColor(s->vg, nvgRGBA(218, 111, 37, 255)); + } else if (is_speedlim_valid) { + nvgStrokeColor(s->vg, nvgRGBA(255, 255, 255, 255)); + } + } + + // Draw "Speed Limit" Text + nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); + nvgFontFace(s->vg, "sans-semibold"); + nvgFontSize(s->vg, 50); + nvgFillColor(s->vg, nvgRGBA(0, 0, 0, 255)); + if (is_speedlim_valid && s->is_ego_over_limit) { + nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 255)); + } + nvgText(s->vg, viz_speedlim_x+viz_speedlim_w/2 + (is_speedlim_valid ? 6 : 0), viz_speedlim_y + (is_speedlim_valid ? 50 : 45), "SMART", NULL); + nvgText(s->vg, viz_speedlim_x+viz_speedlim_w/2 + (is_speedlim_valid ? 6 : 0), viz_speedlim_y + (is_speedlim_valid ? 90 : 85), "SPEED", NULL); + + // Draw Speed Text + nvgFontFace(s->vg, "sans-bold"); + nvgFontSize(s->vg, 48*2.5); + if (s->is_ego_over_limit) { + nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 255)); + } else { + nvgFillColor(s->vg, nvgRGBA(0, 0, 0, 255)); + } + if (is_speedlim_valid) { + snprintf(speedlim_str, sizeof(speedlim_str), "%d", speedlim_calc); + nvgText(s->vg, viz_speedlim_x+viz_speedlim_w/2, viz_speedlim_y + (is_speedlim_valid ? 170 : 165), speedlim_str, NULL); + } else { + nvgFontFace(s->vg, "sans-semibold"); + nvgFontSize(s->vg, 42*2.5); + nvgText(s->vg, viz_speedlim_x+viz_speedlim_w/2, viz_speedlim_y + (is_speedlim_valid ? 170 : 165), "N/A", NULL); + } +} + +static void ui_draw_vision_speed(UIState *s) { + const UIScene *scene = &s->scene; + int ui_viz_rx = scene->ui_viz_rx; + int ui_viz_rw = scene->ui_viz_rw; + float speed = s->scene.v_ego; + + const int viz_speed_w = 280; + const int viz_speed_x = ui_viz_rx+((ui_viz_rw/2)-(viz_speed_w/2)); + char speed_str[32]; + + nvgBeginPath(s->vg); + nvgRect(s->vg, viz_speed_x, box_y, viz_speed_w, header_h); + nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); + + if (s->is_metric) { + snprintf(speed_str, sizeof(speed_str), "%d", (int)(speed * 3.6 + 0.5)); + } else { + snprintf(speed_str, sizeof(speed_str), "%d", (int)(speed * 2.2369363 + 0.5)); + } + nvgFontFace(s->vg, "sans-bold"); + nvgFontSize(s->vg, 96*2.5); + nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 255)); + nvgText(s->vg, viz_speed_x+viz_speed_w/2, 240, speed_str, NULL); + + nvgFontFace(s->vg, "sans-regular"); + nvgFontSize(s->vg, 36*2.5); + nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 200)); + + if (s->is_metric) { + nvgText(s->vg, viz_speed_x+viz_speed_w/2, 320, "kph", NULL); + } else { + nvgText(s->vg, viz_speed_x+viz_speed_w/2, 320, "mph", NULL); + } +} + +static void ui_draw_vision_event(UIState *s) { + const UIScene *scene = &s->scene; + const int ui_viz_rx = scene->ui_viz_rx; + const int ui_viz_rw = scene->ui_viz_rw; + const int viz_event_w = 220; + const int viz_event_x = ((ui_viz_rx + ui_viz_rw) - (viz_event_w + (bdr_s*2))); + const int viz_event_y = (box_y + (bdr_s*1.5)); + const int viz_event_h = (header_h - (bdr_s*1.5)); + if (s->scene.decel_for_model && s->scene.engaged) { + // draw winding road sign + const int img_turn_size = 160*1.5; + const int img_turn_x = viz_event_x-(img_turn_size/4); + const int img_turn_y = viz_event_y+bdr_s-25; + float img_turn_alpha = 1.0f; + nvgBeginPath(s->vg); + NVGpaint imgPaint = nvgImagePattern(s->vg, img_turn_x, img_turn_y, + img_turn_size, img_turn_size, 0, s->img_turn, img_turn_alpha); + nvgRect(s->vg, img_turn_x, img_turn_y, img_turn_size, img_turn_size); + nvgFillPaint(s->vg, imgPaint); + nvgFill(s->vg); + } else { + // draw steering wheel + const int bg_wheel_size = 96; + const int bg_wheel_x = viz_event_x + (viz_event_w-bg_wheel_size); + const int bg_wheel_y = viz_event_y + (bg_wheel_size/2); + const int img_wheel_size = bg_wheel_size*1.5; + const int img_wheel_x = bg_wheel_x-(img_wheel_size/2); + const int img_wheel_y = bg_wheel_y-25; + float img_wheel_alpha = 0.1f; + bool is_engaged = (s->status == STATUS_ENGAGED); + bool is_warning = (s->status == STATUS_WARNING); + bool is_engageable = scene->engageable; + if (is_engaged || is_warning || is_engageable) { + nvgBeginPath(s->vg); + nvgCircle(s->vg, bg_wheel_x, (bg_wheel_y + (bdr_s*1.5)), bg_wheel_size); + if (is_engaged) { + nvgFillColor(s->vg, nvgRGBA(23, 134, 68, 255)); + } else if (is_warning) { + nvgFillColor(s->vg, nvgRGBA(218, 111, 37, 255)); + } else if (is_engageable) { + nvgFillColor(s->vg, nvgRGBA(23, 51, 73, 255)); + } + nvgFill(s->vg); + img_wheel_alpha = 1.0f; + } + nvgBeginPath(s->vg); + NVGpaint imgPaint = nvgImagePattern(s->vg, img_wheel_x, img_wheel_y, + img_wheel_size, img_wheel_size, 0, s->img_wheel, img_wheel_alpha); + nvgRect(s->vg, img_wheel_x, img_wheel_y, img_wheel_size, img_wheel_size); + nvgFillPaint(s->vg, imgPaint); + nvgFill(s->vg); + } +} + +static void ui_draw_vision_map(UIState *s) { + const UIScene *scene = &s->scene; + const int map_size = 96; + const int map_x = (scene->ui_viz_rx + (map_size * 3) + (bdr_s * 3)); + const int map_y = (footer_y + ((footer_h - map_size) / 2)); + const int map_img_size = (map_size * 1.5); + const int map_img_x = (map_x - (map_img_size / 2)); + const int map_img_y = (map_y - (map_size / 4)); + + bool map_valid = s->scene.map_valid; + float map_img_alpha = map_valid ? 1.0f : 0.15f; + float map_bg_alpha = map_valid ? 0.3f : 0.1f; + NVGcolor map_bg = nvgRGBA(0, 0, 0, (255 * map_bg_alpha)); + NVGpaint map_img = nvgImagePattern(s->vg, map_img_x, map_img_y, + map_img_size, map_img_size, 0, s->img_map, map_img_alpha); + + nvgBeginPath(s->vg); + nvgCircle(s->vg, map_x, (map_y + (bdr_s * 1.5)), map_size); + nvgFillColor(s->vg, map_bg); + nvgFill(s->vg); + + nvgBeginPath(s->vg); + nvgRect(s->vg, map_img_x, map_img_y, map_img_size, map_img_size); + nvgFillPaint(s->vg, map_img); + nvgFill(s->vg); +} + +static void ui_draw_vision_face(UIState *s) { + const UIScene *scene = &s->scene; + const int face_size = 96; + const int face_x = (scene->ui_viz_rx + face_size + (bdr_s * 2)); + const int face_y = (footer_y + ((footer_h - face_size) / 2)); + const int face_img_size = (face_size * 1.5); + const int face_img_x = (face_x - (face_img_size / 2)); + const int face_img_y = (face_y - (face_size / 4)); + float face_img_alpha = scene->monitoring_active ? 1.0f : 0.15f; + float face_bg_alpha = scene->monitoring_active ? 0.3f : 0.1f; + NVGcolor face_bg = nvgRGBA(0, 0, 0, (255 * face_bg_alpha)); + NVGpaint face_img = nvgImagePattern(s->vg, face_img_x, face_img_y, + face_img_size, face_img_size, 0, s->img_face, face_img_alpha); + + nvgBeginPath(s->vg); + nvgCircle(s->vg, face_x, (face_y + (bdr_s * 1.5)), face_size); + nvgFillColor(s->vg, face_bg); + nvgFill(s->vg); + + nvgBeginPath(s->vg); + nvgRect(s->vg, face_img_x, face_img_y, face_img_size, face_img_size); + nvgFillPaint(s->vg, face_img); + nvgFill(s->vg); +} + +static void ui_draw_vision_header(UIState *s) { + const UIScene *scene = &s->scene; + int ui_viz_rx = scene->ui_viz_rx; + int ui_viz_rw = scene->ui_viz_rw; + + nvgBeginPath(s->vg); + NVGpaint gradient = nvgLinearGradient(s->vg, ui_viz_rx, + (box_y+(header_h-(header_h/2.5))), + ui_viz_rx, box_y+header_h, + nvgRGBAf(0,0,0,0.45), nvgRGBAf(0,0,0,0)); + nvgFillPaint(s->vg, gradient); + nvgRect(s->vg, ui_viz_rx, box_y, ui_viz_rw, header_h); + nvgFill(s->vg); + + ui_draw_vision_maxspeed(s); + +#ifdef SHOW_SPEEDLIMIT + ui_draw_vision_speedlimit(s); +#endif + ui_draw_vision_speed(s); + ui_draw_vision_event(s); +} + +static void ui_draw_vision_footer(UIState *s) { + const UIScene *scene = &s->scene; + int ui_viz_rx = scene->ui_viz_rx; + int ui_viz_rw = scene->ui_viz_rw; + + nvgBeginPath(s->vg); + nvgRect(s->vg, ui_viz_rx, footer_y, ui_viz_rw, footer_h); + + ui_draw_vision_face(s); + +#ifdef SHOW_SPEEDLIMIT + // ui_draw_vision_map(s); +#endif +} + +static void ui_draw_vision_alert(UIState *s, int va_size, int va_color, + const char* va_text1, const char* va_text2) { + const UIScene *scene = &s->scene; + int ui_viz_rx = scene->ui_viz_rx; + int ui_viz_rw = scene->ui_viz_rw; + bool hasSidebar = !s->scene.uilayout_sidebarcollapsed; + bool mapEnabled = s->scene.uilayout_mapenabled; + bool longAlert1 = strlen(va_text1) > 15; + + const uint8_t *color = alert_colors[va_color]; + const int alr_s = alert_sizes[va_size]; + const int alr_x = ui_viz_rx-(mapEnabled?(hasSidebar?nav_w:(nav_ww)):0)-bdr_s; + const int alr_w = ui_viz_rw+(mapEnabled?(hasSidebar?nav_w:(nav_ww)):0)+(bdr_s*2); + const int alr_h = alr_s+(va_size==ALERTSIZE_NONE?0:bdr_s); + const int alr_y = vwp_h-alr_h; + + nvgBeginPath(s->vg); + nvgRect(s->vg, alr_x, alr_y, alr_w, alr_h); + nvgFillColor(s->vg, nvgRGBA(color[0],color[1],color[2],(color[3]*s->alert_blinking_alpha))); + nvgFill(s->vg); + + nvgBeginPath(s->vg); + NVGpaint gradient = nvgLinearGradient(s->vg, alr_x, alr_y, alr_x, alr_y+alr_h, + nvgRGBAf(0.0,0.0,0.0,0.05), nvgRGBAf(0.0,0.0,0.0,0.35)); + nvgFillPaint(s->vg, gradient); + nvgRect(s->vg, alr_x, alr_y, alr_w, alr_h); + nvgFill(s->vg); + + nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 255)); + nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); + + if (va_size == ALERTSIZE_SMALL) { + nvgFontFace(s->vg, "sans-semibold"); + nvgFontSize(s->vg, 40*2.5); + nvgText(s->vg, alr_x+alr_w/2, alr_y+alr_h/2+15, va_text1, NULL); + } else if (va_size== ALERTSIZE_MID) { + nvgFontFace(s->vg, "sans-bold"); + nvgFontSize(s->vg, 48*2.5); + nvgText(s->vg, alr_x+alr_w/2, alr_y+alr_h/2-45, va_text1, NULL); + nvgFontFace(s->vg, "sans-regular"); + nvgFontSize(s->vg, 36*2.5); + nvgText(s->vg, alr_x+alr_w/2, alr_y+alr_h/2+75, va_text2, NULL); + } else if (va_size== ALERTSIZE_FULL) { + nvgFontSize(s->vg, (longAlert1?72:96)*2.5); + nvgFontFace(s->vg, "sans-bold"); + nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE); + nvgTextBox(s->vg, alr_x, alr_y+(longAlert1?360:420), alr_w-60, va_text1, NULL); + nvgFontSize(s->vg, 48*2.5); + nvgFontFace(s->vg, "sans-regular"); + nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BOTTOM); + nvgTextBox(s->vg, alr_x, alr_h-(longAlert1?300:360), alr_w-60, va_text2, NULL); + } +} + +static void ui_draw_vision(UIState *s) { + const UIScene *scene = &s->scene; + int ui_viz_rx = scene->ui_viz_rx; + int ui_viz_rw = scene->ui_viz_rw; + int ui_viz_ro = scene->ui_viz_ro; + + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + + // Draw video frames + glEnable(GL_SCISSOR_TEST); + glViewport(ui_viz_rx+ui_viz_ro, s->fb_h-(box_y+box_h), viz_w, box_h); + glScissor(ui_viz_rx, s->fb_h-(box_y+box_h), ui_viz_rw, box_h); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + draw_frame(s); + glViewport(0, 0, s->fb_w, s->fb_h); + glDisable(GL_SCISSOR_TEST); + + glClear(GL_STENCIL_BUFFER_BIT); + + nvgBeginFrame(s->vg, s->fb_w, s->fb_h, 1.0f); + nvgSave(s->vg); + + // Draw augmented elements + const int inner_height = viz_w*9/16; + nvgScissor(s->vg, ui_viz_rx, box_y, ui_viz_rw, box_h); + nvgTranslate(s->vg, ui_viz_rx+ui_viz_ro, box_y + (box_h-inner_height)/2.0); + nvgScale(s->vg, (float)viz_w / s->fb_w, (float)inner_height / s->fb_h); + if (!scene->frontview && !scene->fullview) { + ui_draw_world(s); + } + + nvgRestore(s->vg); + + // Set Speed, Current Speed, Status/Events + ui_draw_vision_header(s); + + if (s->scene.alert_size != ALERTSIZE_NONE) { + // Controls Alerts + ui_draw_vision_alert(s, s->scene.alert_size, s->status, + s->scene.alert_text1, s->scene.alert_text2); + } else { + ui_draw_vision_footer(s); + } + + + nvgEndFrame(s->vg); + glDisable(GL_BLEND); +} + +static void ui_draw_blank(UIState *s) { + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); +} + +static void ui_draw(UIState *s) { + if (s->vision_connected && s->plus_state == 0) { + ui_draw_vision(s); + } else { + ui_draw_blank(s); + } + + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glClear(GL_STENCIL_BUFFER_BIT); + + nvgBeginFrame(s->vg, s->fb_w, s->fb_h, 1.0f); + + nvgEndFrame(s->vg); + glDisable(GL_BLEND); + } +} + +static PathData read_path(cereal_ModelData_PathData_ptr pathp) { + PathData ret = {0}; + + struct cereal_ModelData_PathData pathd; + cereal_read_ModelData_PathData(&pathd, pathp); + + ret.prob = pathd.prob; + ret.std = pathd.std; + + capn_list32 polyp = pathd.poly; + capn_resolve(&polyp.p); + for (int i = 0; i < POLYFIT_DEGREE; i++) { + ret.poly[i] = capn_to_f32(capn_get32(polyp, i)); + } + + // Compute points locations + for (int i = 0; i < MODEL_PATH_DISTANCE; i++) { + ret.points[i] = ret.poly[0] * (i*i*i) + ret.poly[1] * (i*i)+ ret.poly[2] * i + ret.poly[3]; + } + + return ret; +} + +static ModelData read_model(cereal_ModelData_ptr modelp) { + struct cereal_ModelData modeld; + cereal_read_ModelData(&modeld, modelp); + + ModelData d = {0}; + + d.path = read_path(modeld.path); + d.left_lane = read_path(modeld.leftLane); + d.right_lane = read_path(modeld.rightLane); + + struct cereal_ModelData_LeadData leadd; + cereal_read_ModelData_LeadData(&leadd, modeld.lead); + d.lead = (LeadData){ + .dist = leadd.dist, .prob = leadd.prob, .std = leadd.std, + }; + + return d; +} + +static void update_status(UIState *s, int status) { + if (s->status != status) { + s->status = status; + // wake up bg thread to change + pthread_cond_signal(&s->bg_cond); + } +} + + +void handle_message(UIState *s, Message * msg) { + struct capn ctx; + capn_init_mem(&ctx, (uint8_t*)msg->getData(), msg->getSize(), 0); + + cereal_Event_ptr eventp; + eventp.p = capn_getp(capn_root(&ctx), 0, 1); + struct cereal_Event eventd; + cereal_read_Event(&eventd, eventp); + double t = millis_since_boot(); + if (eventd.which == cereal_Event_controlsState) { + struct cereal_ControlsState datad; + cereal_read_ControlsState(&datad, eventd.controlsState); + + s->controls_timeout = 1 * UI_FREQ; + s->controls_seen = true; + + if (datad.vCruise != s->scene.v_cruise) { + s->scene.v_cruise_update_ts = eventd.logMonoTime; + } + s->scene.v_cruise = datad.vCruise; + s->scene.v_ego = datad.vEgo; + s->scene.curvature = datad.curvature; + s->scene.engaged = datad.enabled; + s->scene.engageable = datad.engageable; + s->scene.gps_planner_active = datad.gpsPlannerActive; + s->scene.monitoring_active = datad.driverMonitoringOn; + + s->scene.frontview = datad.rearViewCam; + + s->scene.decel_for_model = datad.decelForModel; + + if (datad.alertSound != cereal_CarControl_HUDControl_AudibleAlert_none && datad.alertSound != s->alert_sound) { + if (s->alert_sound != cereal_CarControl_HUDControl_AudibleAlert_none) { + stop_alert_sound(s->alert_sound); + } + play_alert_sound(datad.alertSound); + + s->alert_sound = datad.alertSound; + snprintf(s->alert_type, sizeof(s->alert_type), "%s", datad.alertType.str); + } else if ((!datad.alertSound || datad.alertSound == cereal_CarControl_HUDControl_AudibleAlert_none) + && s->alert_sound != cereal_CarControl_HUDControl_AudibleAlert_none) { + stop_alert_sound(s->alert_sound); + s->alert_type[0] = '\0'; + s->alert_sound = cereal_CarControl_HUDControl_AudibleAlert_none; + } + + if (datad.alertText1.str) { + snprintf(s->scene.alert_text1, sizeof(s->scene.alert_text1), "%s", datad.alertText1.str); + } else { + s->scene.alert_text1[0] = '\0'; + } + if (datad.alertText2.str) { + snprintf(s->scene.alert_text2, sizeof(s->scene.alert_text2), "%s", datad.alertText2.str); + } else { + s->scene.alert_text2[0] = '\0'; + } + s->scene.awareness_status = datad.awarenessStatus; + + s->scene.alert_ts = eventd.logMonoTime; + + s->scene.alert_size = datad.alertSize; + if (datad.alertSize == cereal_ControlsState_AlertSize_none) { + s->alert_size = ALERTSIZE_NONE; + } else if (datad.alertSize == cereal_ControlsState_AlertSize_small) { + s->alert_size = ALERTSIZE_SMALL; + } else if (datad.alertSize == cereal_ControlsState_AlertSize_mid) { + s->alert_size = ALERTSIZE_MID; + } else if (datad.alertSize == cereal_ControlsState_AlertSize_full) { + s->alert_size = ALERTSIZE_FULL; + } + + if (datad.alertStatus == cereal_ControlsState_AlertStatus_userPrompt) { + update_status(s, STATUS_WARNING); + } else if (datad.alertStatus == cereal_ControlsState_AlertStatus_critical) { + update_status(s, STATUS_ALERT); + } else if (datad.enabled) { + update_status(s, STATUS_ENGAGED); + } else { + update_status(s, STATUS_DISENGAGED); + } + + s->scene.alert_blinkingrate = datad.alertBlinkingRate; + if (datad.alertBlinkingRate > 0.) { + if (s->alert_blinked) { + if (s->alert_blinking_alpha > 0.0 && s->alert_blinking_alpha < 1.0) { + s->alert_blinking_alpha += (0.05*datad.alertBlinkingRate); + } else { + s->alert_blinked = false; + } + } else { + if (s->alert_blinking_alpha > 0.25) { + s->alert_blinking_alpha -= (0.05*datad.alertBlinkingRate); + } else { + s->alert_blinking_alpha += 0.25; + s->alert_blinked = true; + } + } + } + } else if (eventd.which == cereal_Event_radarState) { + struct cereal_RadarState datad; + cereal_read_RadarState(&datad, eventd.radarState); + struct cereal_RadarState_LeadData leaddatad; + cereal_read_RadarState_LeadData(&leaddatad, datad.leadOne); + s->scene.lead_status = leaddatad.status; + s->scene.lead_d_rel = leaddatad.dRel; + s->scene.lead_y_rel = leaddatad.yRel; + s->scene.lead_v_rel = leaddatad.vRel; + s->livempc_or_radarstate_changed = true; + } else if (eventd.which == cereal_Event_liveCalibration) { + s->scene.world_objects_visible = true; + struct cereal_LiveCalibrationData datad; + cereal_read_LiveCalibrationData(&datad, eventd.liveCalibration); + + capn_list32 extrinsicl = datad.extrinsicMatrix; + capn_resolve(&extrinsicl.p); // is this a bug? + for (int i = 0; i < 3 * 4; i++) { + s->scene.extrinsic_matrix.v[i] = + capn_to_f32(capn_get32(extrinsicl, i)); + } + } else if (eventd.which == cereal_Event_model) { + s->scene.model_ts = eventd.logMonoTime; + s->scene.model = read_model(eventd.model); + s->model_changed = true; + } else if (eventd.which == cereal_Event_liveMpc) { + struct cereal_LiveMpcData datad; + cereal_read_LiveMpcData(&datad, eventd.liveMpc); + + capn_list32 x_list = datad.x; + capn_resolve(&x_list.p); + + for (int i = 0; i < 50; i++){ + s->scene.mpc_x[i] = capn_to_f32(capn_get32(x_list, i)); + } + + capn_list32 y_list = datad.y; + capn_resolve(&y_list.p); + + for (int i = 0; i < 50; i++){ + s->scene.mpc_y[i] = capn_to_f32(capn_get32(y_list, i)); + } + s->livempc_or_radarstate_changed = true; + } else if (eventd.which == cereal_Event_thermal) { + struct cereal_ThermalData datad; + cereal_read_ThermalData(&datad, eventd.thermal); + + if (!datad.started) { + update_status(s, STATUS_STOPPED); + } else if (s->status == STATUS_STOPPED) { + // car is started but controls doesn't have fingerprint yet + update_status(s, STATUS_DISENGAGED); + } + + s->scene.started_ts = datad.startedTs; + } else if (eventd.which == cereal_Event_uiLayoutState) { + struct cereal_UiLayoutState datad; + cereal_read_UiLayoutState(&datad, eventd.uiLayoutState); + s->scene.uilayout_sidebarcollapsed = datad.sidebarCollapsed; + s->scene.uilayout_mapenabled = datad.mapEnabled; + + bool hasSidebar = !s->scene.uilayout_sidebarcollapsed; + bool mapEnabled = s->scene.uilayout_mapenabled; + if (mapEnabled) { + s->scene.ui_viz_rx = hasSidebar ? (box_x+nav_w) : (box_x+nav_w-(bdr_s*4)); + s->scene.ui_viz_rw = hasSidebar ? (box_w-nav_w) : (box_w-nav_w+(bdr_s*4)); + s->scene.ui_viz_ro = -(sbr_w + 4*bdr_s); + } else { + s->scene.ui_viz_rx = hasSidebar ? box_x : (box_x-sbr_w+bdr_s*2); + s->scene.ui_viz_rw = hasSidebar ? box_w : (box_w+sbr_w-(bdr_s*2)); + s->scene.ui_viz_ro = hasSidebar ? -(sbr_w - 6*bdr_s) : 0; + } + } else if (eventd.which == cereal_Event_liveMapData) { + struct cereal_LiveMapData datad; + cereal_read_LiveMapData(&datad, eventd.liveMapData); + s->scene.map_valid = datad.mapValid; + } + capn_free(&ctx); +} + +static void ui_update(UIState *s) { + int err; + + if (s->vision_connect_firstrun) { + // cant run this in connector thread because opengl. + // do this here for now in lieu of a run_on_main_thread event + + for (int i=0; ikhr[i] != NULL) { + visionimg_destroy_gl(s->khr[i], s->priv_hnds[i]); + glDeleteTextures(1, &s->frame_texs[i]); + } + + VisionImg img = { + .fd = s->bufs[i].fd, + .format = VISIONIMG_FORMAT_RGB24, + .width = s->rgb_width, + .height = s->rgb_height, + .stride = s->rgb_stride, + .bpp = 3, + .size = s->rgb_buf_len, + }; + s->frame_texs[i] = visionimg_to_gl(&img, &s->khr[i], &s->priv_hnds[i]); + + glBindTexture(GL_TEXTURE_2D, s->frame_texs[i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + // BGR + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); + } + + for (int i=0; ikhr_front[i] != NULL) { + visionimg_destroy_gl(s->khr_front[i], s->priv_hnds_front[i]); + glDeleteTextures(1, &s->frame_front_texs[i]); + } + + VisionImg img = { + .fd = s->front_bufs[i].fd, + .format = VISIONIMG_FORMAT_RGB24, + .width = s->rgb_front_width, + .height = s->rgb_front_height, + .stride = s->rgb_front_stride, + .bpp = 3, + .size = s->rgb_front_buf_len, + }; + s->frame_front_texs[i] = visionimg_to_gl(&img, &s->khr_front[i], &s->priv_hnds_front[i]); + + glBindTexture(GL_TEXTURE_2D, s->frame_front_texs[i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + // BGR + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); + } + + assert(glGetError() == GL_NO_ERROR); + + // Default UI Measurements (Assumes sidebar collapsed) + s->scene.ui_viz_rx = (box_x-sbr_w+bdr_s*2); + s->scene.ui_viz_rw = (box_w+sbr_w-(bdr_s*2)); + s->scene.ui_viz_ro = 0; + + s->vision_connect_firstrun = false; + + s->alert_blinking_alpha = 1.0; + s->alert_blinked = false; + } + + zmq_pollitem_t polls[1] = {{0}}; + // Wait for next rgb image from visiond + while(true) { + assert(s->ipc_fd >= 0); + polls[0].fd = s->ipc_fd; + polls[0].events = ZMQ_POLLIN; + int ret = zmq_poll(polls, 1, 1000); + if (ret < 0) { + LOGW("poll failed (%d)", ret); + close(s->ipc_fd); + s->ipc_fd = -1; + s->vision_connected = false; + return; + } else if (ret == 0) + continue; + // vision ipc event + VisionPacket rp; + err = vipc_recv(s->ipc_fd, &rp); + if (err <= 0) { + LOGW("vision disconnected"); + close(s->ipc_fd); + s->ipc_fd = -1; + s->vision_connected = false; + return; + } + if (rp.type == VIPC_STREAM_ACQUIRE) { + bool front = rp.d.stream_acq.type == VISION_STREAM_RGB_FRONT; + int idx = rp.d.stream_acq.idx; + + int release_idx; + if (front) { + release_idx = s->cur_vision_front_idx; + } else { + release_idx = s->cur_vision_idx; + } + if (release_idx >= 0) { + VisionPacket rep = { + .type = VIPC_STREAM_RELEASE, + .d = { .stream_rel = { + .type = rp.d.stream_acq.type, + .idx = release_idx, + }}, + }; + vipc_send(s->ipc_fd, &rep); + } + + if (front) { + assert(idx < UI_BUF_COUNT); + s->cur_vision_front_idx = idx; + } else { + assert(idx < UI_BUF_COUNT); + s->cur_vision_idx = idx; + // printf("v %d\n", ((uint8_t*)s->bufs[idx].addr)[0]); + } + } else { + assert(false); + } + break; + } + // peek and consume all events in the zmq queue, then return. + while(true) { + bool awake = false; + auto polls = s->poller->poll(0); + + if (polls.size() == 0) + return; + + for (auto sock : polls){ + Message * msg = sock->receive(); + + if (sock != s->thermal_sock){ + awake = true; + } + + if (sock == s->plus_sock){ + s->plus_state = msg->getData()[0]; + } else { + handle_message(s, msg); + } + + delete msg; + } + + if (awake){ + set_awake(s, true); + } + } +} + +static int vision_subscribe(int fd, VisionPacket *rp, VisionStreamType type) { + int err; + LOGW("vision_subscribe type:%d", type); + + VisionPacket p1 = { + .type = VIPC_STREAM_SUBSCRIBE, + .d = { .stream_sub = { .type = type, .tbuffer = true, }, }, + }; + err = vipc_send(fd, &p1); + if (err < 0) { + close(fd); + return 0; + } + + do { + err = vipc_recv(fd, rp); + if (err <= 0) { + close(fd); + return 0; + } + + // release what we aren't ready for yet + if (rp->type == VIPC_STREAM_ACQUIRE) { + VisionPacket rep = { + .type = VIPC_STREAM_RELEASE, + .d = { .stream_rel = { + .type = rp->d.stream_acq.type, + .idx = rp->d.stream_acq.idx, + }}, + }; + vipc_send(fd, &rep); + } + } while (rp->type != VIPC_STREAM_BUFS || rp->d.stream_bufs.type != type); + + return 1; +} + +static void* vision_connect_thread(void *args) { + int err; + set_thread_name("vision_connect"); + + UIState *s = (UIState*)args; + while (!do_exit) { + usleep(100000); + pthread_mutex_lock(&s->lock); + bool connected = s->vision_connected; + pthread_mutex_unlock(&s->lock); + if (connected) continue; + + int fd = vipc_connect(); + if (fd < 0) continue; + + VisionPacket back_rp, front_rp; + if (!vision_subscribe(fd, &back_rp, VISION_STREAM_RGB_BACK)) continue; + if (!vision_subscribe(fd, &front_rp, VISION_STREAM_RGB_FRONT)) continue; + + pthread_mutex_lock(&s->lock); + assert(!s->vision_connected); + s->ipc_fd = fd; + + ui_init_vision(s, + back_rp.d.stream_bufs, back_rp.num_fds, back_rp.fds, + front_rp.d.stream_bufs, front_rp.num_fds, front_rp.fds); + + s->vision_connected = true; + s->vision_connect_firstrun = true; + pthread_mutex_unlock(&s->lock); + } + return NULL; +} + + +#include +#include + +static void* light_sensor_thread(void *args) { + int err; + set_thread_name("light_sensor"); + + UIState *s = (UIState*)args; + s->light_sensor = 0.0; + + struct sensors_poll_device_t* device; + struct sensors_module_t* module; + + hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); + sensors_open(&module->common, &device); + + // need to do this + struct sensor_t const* list; + int count = module->get_sensors_list(module, &list); + + int SENSOR_LIGHT = 7; + + err = device->activate(device, SENSOR_LIGHT, 0); + if (err != 0) goto fail; + err = device->activate(device, SENSOR_LIGHT, 1); + if (err != 0) goto fail; + + device->setDelay(device, SENSOR_LIGHT, ms2ns(100)); + + while (!do_exit) { + static const size_t numEvents = 1; + sensors_event_t buffer[numEvents]; + + int n = device->poll(device, buffer, numEvents); + if (n < 0) { + LOG_100("light_sensor_poll failed: %d", n); + } + if (n > 0) { + s->light_sensor = buffer[0].light; + } + } + + return NULL; + +fail: + LOGE("LIGHT SENSOR IS MISSING"); + s->light_sensor = 255; + return NULL; +} + + +static void* bg_thread(void* args) { + UIState *s = (UIState*)args; + set_thread_name("bg"); + + EGLDisplay bg_display; + EGLSurface bg_surface; + + FramebufferState *bg_fb = framebuffer_init("bg", 0x00001000, false, + &bg_display, &bg_surface, NULL, NULL); + assert(bg_fb); + + int bg_status = -1; + while(!do_exit) { + pthread_mutex_lock(&s->lock); + if (bg_status == s->status) { + // will always be signaled if it changes? + pthread_cond_wait(&s->bg_cond, &s->lock); + } + bg_status = s->status; + pthread_mutex_unlock(&s->lock); + + assert(bg_status < ARRAYSIZE(bg_colors)); + const uint8_t *color = bg_colors[bg_status]; + + glClearColor(color[0]/256.0, color[1]/256.0, color[2]/256.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + eglSwapBuffers(bg_display, bg_surface); + assert(glGetError() == GL_NO_ERROR); + } + + return NULL; +} + +int is_leon() { + #define MAXCHAR 1000 + FILE *fp; + char str[MAXCHAR]; + const char* filename = "/proc/cmdline"; + + fp = fopen(filename, "r"); + if (fp == NULL){ + printf("Could not open file %s",filename); + return 0; + } + fgets(str, MAXCHAR, fp); + fclose(fp); + return strstr(str, "letv") != NULL; +} + + + +int main(int argc, char* argv[]) { + int err; + setpriority(PRIO_PROCESS, 0, -14); + + zsys_handler_set(NULL); + signal(SIGINT, (sighandler_t)set_do_exit); + + UIState uistate; + UIState *s = &uistate; + ui_init(s); + + pthread_t connect_thread_handle; + err = pthread_create(&connect_thread_handle, NULL, + vision_connect_thread, s); + assert(err == 0); + + pthread_t light_sensor_thread_handle; + err = pthread_create(&light_sensor_thread_handle, NULL, + light_sensor_thread, s); + assert(err == 0); + + pthread_t bg_thread_handle; + err = pthread_create(&bg_thread_handle, NULL, + bg_thread, s); + assert(err == 0); + + TouchState touch = {0}; + touch_init(&touch); + s->touch_fd = touch.fd; + + char* error = NULL; + ui_sound_init(&error); + if (error) { + LOGW(error); + exit(1); + } + + // light sensor scaling params + const int LEON = is_leon(); + + const float BRIGHTNESS_B = LEON ? 10.0 : 5.0; + const float BRIGHTNESS_M = LEON ? 2.6 : 1.3; + + float smooth_brightness = BRIGHTNESS_B; + + const int MIN_VOLUME = LEON ? 12 : 9; + const int MAX_VOLUME = LEON ? 15 : 12; + + set_volume(s, MIN_VOLUME); +#ifdef DEBUG_FPS + vipc_t1 = millis_since_boot(); + double t1 = millis_since_boot(); + int draws = 0, old_draws = 0; +#endif //DEBUG_FPS + while (!do_exit) { + bool should_swap = false; + if (!s->vision_connected) { + // Delay a while to avoid 9% cpu usage while car is not started and user is keeping touching on the screen. + // Don't hold the lock while sleeping, so that vision_connect_thread have chances to get the lock. + usleep(30 * 1000); + } + pthread_mutex_lock(&s->lock); + + // light sensor is only exposed on EONs + float clipped_brightness = (s->light_sensor*BRIGHTNESS_M) + BRIGHTNESS_B; + if (clipped_brightness > 512) clipped_brightness = 512; + smooth_brightness = clipped_brightness * 0.01 + smooth_brightness * 0.99; + if (smooth_brightness > 255) smooth_brightness = 255; + set_brightness(s, (int)smooth_brightness); + + if (!s->vision_connected) { + // Car is not started, keep in idle state and awake on touch events + zmq_pollitem_t polls[1] = {{0}}; + polls[0].fd = s->touch_fd; + polls[0].events = ZMQ_POLLIN; + int ret = zmq_poll(polls, 1, 0); + if (ret < 0) + LOGW("poll failed (%d)", ret); + else if (ret > 0) { + // awake on any touch + int touch_x = -1, touch_y = -1; + int touched = touch_read(&touch, &touch_x, &touch_y); + if (touched == 1) { + set_awake(s, true); + } + } + } else { + // Car started, fetch a new rgb image from ipc and peek for zmq events. + ui_update(s); + if(!s->vision_connected) { + // Visiond process is just stopped, force a redraw to make screen blank again. + ui_draw(s); + glFinish(); + should_swap = true; + } + } + // manage wakefulness + if (s->awake_timeout > 0) { + s->awake_timeout--; + } else { + set_awake(s, false); + } + // Don't waste resources on drawing in case screen is off or car is not started. + if (s->awake && s->vision_connected) { + ui_draw(s); + glFinish(); + should_swap = true; +#ifdef DEBUG_FPS + draws++; + double t2 = millis_since_boot(); + const double interval = 30.; + if(t2 - t1 >= interval * 1000.) { + printf("ui draw fps: %.2f\n",((double)(draws - old_draws)) / interval) ; + t1 = t2; + old_draws = draws; + } +#endif + } + + if (s->volume_timeout > 0) { + s->volume_timeout--; + } else { + int volume = fmin(MAX_VOLUME, MIN_VOLUME + s->scene.v_ego / 5); // up one notch every 5 m/s + set_volume(s, volume); + } + + if (s->controls_timeout > 0) { + s->controls_timeout--; + } else { + // stop playing alert sound + if ((!s->vision_connected || (s->vision_connected && s->alert_sound_timeout == 0)) && + s->alert_sound != cereal_CarControl_HUDControl_AudibleAlert_none) { + stop_alert_sound(s->alert_sound); + s->alert_sound = cereal_CarControl_HUDControl_AudibleAlert_none; + } + + // if visiond is still running and controlsState times out, display an alert + if (s->controls_seen && s->vision_connected && strcmp(s->scene.alert_text2, "Controls Unresponsive") != 0) { + s->scene.alert_size = ALERTSIZE_FULL; + update_status(s, STATUS_ALERT); + snprintf(s->scene.alert_text1, sizeof(s->scene.alert_text1), "%s", "TAKE CONTROL IMMEDIATELY"); + snprintf(s->scene.alert_text2, sizeof(s->scene.alert_text2), "%s", "Controls Unresponsive"); + ui_draw_vision_alert(s, s->scene.alert_size, s->status, s->scene.alert_text1, s->scene.alert_text2); + + s->alert_sound_timeout = 2 * UI_FREQ; + + s->alert_sound = cereal_CarControl_HUDControl_AudibleAlert_chimeWarningRepeat; + play_alert_sound(s->alert_sound); + } + s->alert_sound_timeout--; + s->controls_seen = false; + } + + read_param_bool_timeout(&s->is_metric, "IsMetric", &s->is_metric_timeout); + read_param_bool_timeout(&s->longitudinal_control, "LongitudinalControl", &s->longitudinal_control_timeout); + read_param_bool_timeout(&s->limit_set_speed, "LimitSetSpeed", &s->limit_set_speed_timeout); + read_param_float_timeout(&s->speed_lim_off, "SpeedLimitOffset", &s->limit_set_speed_timeout); + + pthread_mutex_unlock(&s->lock); + + // the bg thread needs to be scheduled, so the main thread needs time without the lock + // safe to do this outside the lock? + if (should_swap) { + eglSwapBuffers(s->display, s->surface); + } + } + + set_awake(s, true); + + slplay_destroy(); + + // wake up bg thread to exit + pthread_mutex_lock(&s->lock); + pthread_cond_signal(&s->bg_cond); + pthread_mutex_unlock(&s->lock); + err = pthread_join(bg_thread_handle, NULL); + assert(err == 0); + + err = pthread_join(connect_thread_handle, NULL); + assert(err == 0); + + return 0; +} diff --git a/selfdrive/updated.py b/selfdrive/updated.py index c8efd8f3a86bf7..d05a9a8fa7ed8e 100755 --- a/selfdrive/updated.py +++ b/selfdrive/updated.py @@ -1,24 +1,29 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # simple service that waits for network access and tries to update every hour -import time +import datetime import subprocess +import time + +from common.params import Params from selfdrive.swaglog import cloudlog NICE_LOW_PRIORITY = ["nice", "-n", "19"] def main(gctx=None): + params = Params() + while True: # try network - r = subprocess.call(["ping", "-W", "4", "-c", "1", "8.8.8.8"]) - if r: + ping_failed = subprocess.call(["ping", "-W", "4", "-c", "1", "8.8.8.8"]) + if ping_failed: time.sleep(60) continue # download application update try: - r = subprocess.check_output(NICE_LOW_PRIORITY + ["git", "fetch"], stderr=subprocess.STDOUT) - except subprocess.CalledProcessError, e: + r = subprocess.check_output(NICE_LOW_PRIORITY + ["git", "fetch"], stderr=subprocess.STDOUT).decode('utf8') + except subprocess.CalledProcessError as e: cloudlog.event("git fetch failed", cmd=e.cmd, output=e.output, @@ -27,8 +32,26 @@ def main(gctx=None): continue cloudlog.info("git fetch success: %s", r) + # Write update available param + try: + cur_hash = subprocess.check_output(["git", "rev-parse", "HEAD"]).rstrip() + upstream_hash = subprocess.check_output(["git", "rev-parse", "@{u}"]).rstrip() + params.put("UpdateAvailable", str(int(cur_hash != upstream_hash))) + except: + params.put("UpdateAvailable", "0") + + # Write latest release notes to param + try: + r = subprocess.check_output(["git", "--no-pager", "show", "@{u}:RELEASES.md"]) + r = r[:r.find(b'\n\n')] # Slice latest release notes + params.put("ReleaseNotes", r + b"\n") + except: + params.put("ReleaseNotes", "") + + t = datetime.datetime.now().isoformat() + params.put("LastUpdateTime", t.encode('utf8')) + time.sleep(60*60) if __name__ == "__main__": main() - diff --git a/selfdrive/version.py b/selfdrive/version.py index 8166c662f40dbf..dd78fa4e0bb890 100644 --- a/selfdrive/version.py +++ b/selfdrive/version.py @@ -1,21 +1,73 @@ +#!/usr/bin/env python3 import os import subprocess +from selfdrive.swaglog import cloudlog + + +def get_git_commit(): + return subprocess.check_output(["git", "rev-parse", "HEAD"], encoding='utf8').strip() # pylint: disable=unexpected-keyword-arg + + +def get_git_branch(): + return subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"], encoding='utf8').strip() # pylint: disable=unexpected-keyword-arg + + +def get_git_full_branchname(): + return subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"], encoding='utf8').strip() # pylint: disable=unexpected-keyword-arg + + +def get_git_remote(): + try: + local_branch = subprocess.check_output(["git", "name-rev", "--name-only", "HEAD"], encoding='utf8').strip() # pylint: disable=unexpected-keyword-arg + tracking_remote = subprocess.check_output(["git", "config", "branch." + local_branch + ".remote"], encoding='utf8').strip() # pylint: disable=unexpected-keyword-arg + return subprocess.check_output(["git", "config", "remote." + tracking_remote + ".url"], encoding='utf8').strip() # pylint: disable=unexpected-keyword-arg + except subprocess.CalledProcessError: + # Not on a branch, fallback + return subprocess.check_output(["git", "config", "--get", "remote.origin.url"], encoding='utf8').strip() # pylint: disable=unexpected-keyword-arg + + with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "common", "version.h")) as _versionf: version = _versionf.read().split('"')[1] try: - origin = subprocess.check_output(["git", "config", "--get", "remote.origin.url"]).rstrip() + origin = get_git_remote() if origin.startswith('git@github.com:commaai') or origin.startswith('https://github.com/commaai'): if origin.endswith('/one.git'): dirty = True else: - branch = subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).rstrip() - branch = 'origin/' + branch + branch = get_git_full_branchname() + + # This is needed otherwise touched files might show up as modified + try: + subprocess.check_call(["git", "update-index", "--refresh"]) + except subprocess.CalledProcessError: + pass + dirty = subprocess.call(["git", "diff-index", "--quiet", branch, "--"]) != 0 + if dirty: + dirty_files = subprocess.check_output(["git", "diff-index", branch, "--"], encoding='utf8') # pylint: disable=unexpected-keyword-arg + commit = subprocess.check_output(["git", "rev-parse", "--verify", "HEAD"], encoding='utf8').rstrip() # pylint: disable=unexpected-keyword-arg + origin_commit = subprocess.check_output(["git", "rev-parse", "--verify", branch], encoding='utf8').rstrip() # pylint: disable=unexpected-keyword-arg + cloudlog.event("dirty comma branch", vesion=version, dirty=dirty, origin=origin, branch=branch, dirty_files=dirty_files, commit=commit, origin_commit=origin_commit) + else: dirty = True except subprocess.CalledProcessError: + try: + cloudlog.exception("git subprocess failed while finding version") + except: + pass dirty = True -# put this here -training_version = "0.1.0" +training_version = b"0.1.0" +terms_version = b"2" + +if __name__ == "__main__": + print("Dirty: %s" % dirty) + print("Version: %s" % version) + print("Remote: %s" % origin) + + try: + print("Branch %s" % branch) + except NameError: + pass diff --git a/selfdrive/visiond/SConscript b/selfdrive/visiond/SConscript deleted file mode 100644 index e55fbd94d9a63e..00000000000000 --- a/selfdrive/visiond/SConscript +++ /dev/null @@ -1,17 +0,0 @@ -Import('env') -lenv = env.Clone() -lenv['CPPPATH'] += ['include'] -lenv['LIBPATH'] += ['/system/vendor/lib64'] -lenv['CFLAGS'] += ' -DQCOM' -lenv['CXXFLAGS'] += ' -DQCOM -U __ANDROID__' -lenv.Program(['visiond.cc', 'model.c', 'transform.c', 'loadyuv.c', 'buffering.c', 'efd.c', - 'yuvmodel.c', 'temporalmodel.c', 'monitoring.c', 'monitoringmodel.c', 'clutil.c', - 'camera_qcom.c', 'visionbuf_ion.c'], - LIBS=['zmq', 'czmq', 'capnp', 'capnp_c', 'kj', 'yaml-cpp', 'z', 'curl', - 'gsl', 'CB', 'OpenCL', - 'opencv_video', 'opencv_imgproc', 'opencv_core', - 'gnustl_shared', 'log', 'cutils', - 'yuv', - 'common', 'cereal', - ]) - diff --git a/selfdrive/visiond/build_from_src.mk b/selfdrive/visiond/build_from_src.mk index e23887f27b98fa..639f0a95df7741 100644 --- a/selfdrive/visiond/build_from_src.mk +++ b/selfdrive/visiond/build_from_src.mk @@ -12,13 +12,16 @@ WARN_FLAGS = -Werror=implicit-function-declaration \ -Werror=format-extra-args \ -Wno-deprecated-declarations -CFLAGS = -std=gnu11 -fPIC -O2 $(WARN_FLAGS) -CXXFLAGS = -std=c++14 -fPIC -O2 $(WARN_FLAGS) +CFLAGS = -I. -std=gnu11 -fPIC -O2 $(WARN_FLAGS) +CXXFLAGS = -I. -std=c++14 -fPIC -O2 $(WARN_FLAGS) -#ifneq ($(RELEASE),1) -#CFLAGS += -g -#CXXFLAGS += -g -#endif +MESSAGING_FLAGS = -I$(BASEDIR)/selfdrive/messaging +MESSAGING_LIBS = $(BASEDIR)/selfdrive/messaging/messaging.a + +ifeq ($(ARCH),aarch64) +CFLAGS += -mcpu=cortex-a57 +CXXFLAGS += -mcpu=cortex-a57 +endif JSON_FLAGS = -I$(PHONELIBS)/json/src JSON11_FLAGS = -I$(PHONELIBS)/json11/ @@ -38,44 +41,52 @@ ifeq ($(UNAME_S),Darwin) $(PHONELIBS)/zmq/mac/lib/libzmq.a OPENCL_LIBS = -framework OpenCL + + PLATFORM_OBJS = cameras/camera_fake.o \ + ../common/visionbuf_cl.o else - LIBYUV_FLAGS = -I$(PHONELIBS)/libyuv/x64/include + # assume x86_64 linux + LIBYUV_FLAGS = -I$(PHONELIBS)/libyuv/include LIBYUV_LIBS = $(PHONELIBS)/libyuv/x64/lib/libyuv.a - ZMQ_FLAGS = -I$(EXTERNAL)/zmq/include - ZMQ_LIBS = -L$(EXTERNAL)/zmq/lib \ - -l:libczmq.a -l:libzmq.a + ZMQ_FLAGS = -I$(PHONELIBS)/zmq/x64/include + ZMQ_LIBS = -L$(PHONELIBS)/zmq/x64/lib/ -l:libczmq.a -l:libzmq.a OPENCL_LIBS = -lOpenCL -endif - CURL_FLAGS = -I/usr/include/curl - CURL_LIBS = -lcurl -lz + TF_FLAGS = -I$(EXTERNAL)/tensorflow/include + TF_LIBS = -L$(EXTERNAL)/tensorflow/lib -ltensorflow \ + -Wl,-rpath $(EXTERNAL)/tensorflow/lib + + SNPE_FLAGS = -I$(PHONELIBS)/snpe/include/ + SNPE_LIBS = -L$(PHONELIBS)/snpe/x86_64-linux-clang/ \ + -lSNPE -lsymphony-cpu \ + -Wl,-rpath $(PHONELIBS)/snpe/x86_64-linux-clang/ + + CFLAGS += -g + CXXFLAGS += -g -I../common + + PLATFORM_OBJS = cameras/camera_frame_stream.o \ + ../common/visionbuf_cl.o \ + ../common/visionimg.o \ + runners/tfmodel.o +endif SSL_FLAGS = -I/usr/include/openssl/ SSL_LIBS = -lssl -lcrypto - OPENCV_FLAGS = - OPENCV_LIBS = -lopencv_video \ - -lopencv_imgproc \ - -lopencv_core OTHER_LIBS = -lz -lm -lpthread - PLATFORM_OBJS = camera_fake.o \ - ../common/visionbuf_cl.o - CFLAGS += -D_GNU_SOURCE \ -DCLU_NO_CACHE + OBJS = visiond.o else # assume phone LIBYUV_FLAGS = -I$(PHONELIBS)/libyuv/include LIBYUV_LIBS = $(PHONELIBS)/libyuv/lib/libyuv.a - ZMQ_FLAGS = -I$(PHONELIBS)/zmq/aarch64/include - ZMQ_LIBS = -L$(PHONELIBS)/zmq/aarch64/lib \ - -l:libczmq.a -l:libzmq.a \ - -lgnustl_shared + ZMQ_LIBS = -l:libczmq.a -l:libzmq.a -lgnustl_shared CURL_FLAGS = -I$(PHONELIBS)/curl/include CURL_LIBS = $(PHONELIBS)/curl/lib/libcurl.a \ @@ -88,27 +99,31 @@ else OPENCL_FLAGS = -I$(PHONELIBS)/opencl/include OPENCL_LIBS = -lgsl -lCB -lOpenCL - OPENCV_FLAGS = -I/usr/local/sdk/native/jni/include - OPENCV_LIBS = -L/usr/local/sdk/native/libs \ - -l:libopencv_video.a \ - -l:libopencv_imgproc.a \ - -l:libopencv_core.a - OPENGL_LIBS = -lGLESv3 -lEGL + UUID_LIBS = -luuid SNPE_FLAGS = -I$(PHONELIBS)/snpe/include/ SNPE_LIBS = -lSNPE -lsymphony-cpu -lsymphonypower OTHER_LIBS = -lz -lcutils -lm -llog -lui -ladreno_utils - PLATFORM_OBJS = camera_qcom.o \ - ../common/visionbuf_ion.o - - CFLAGS += -DQCOM - CXXFLAGS += -DQCOM + PLATFORM_OBJS = cameras/camera_qcom.o \ + ../common/visionbuf_ion.o \ + ../common/visionimg.o + + CFLAGS += -DQCOM \ + -I$(PHONELIBS)/android_system_core/include \ + -I$(PHONELIBS)/android_frameworks_native/include \ + -I$(PHONELIBS)/android_hardware_libhardware/include \ + -I$(PHONELIBS)/linux/include + CXXFLAGS += -DQCOM \ + -I$(PHONELIBS)/android_system_core/include \ + -I$(PHONELIBS)/android_frameworks_native/include \ + -I$(PHONELIBS)/android_hardware_libhardware/include \ + -I$(PHONELIBS)/linux/include + OBJS = visiond.o endif -OBJS = visiond.o OUTPUT = visiond .PHONY: all @@ -120,71 +135,52 @@ OBJS += $(PLATFORM_OBJS) \ ../common/swaglog.o \ ../common/ipc.o \ ../common/visionipc.o \ - ../common/visionimg.o \ ../common/util.o \ ../common/params.o \ ../common/efd.o \ ../common/buffering.o \ - transform.o \ - loadyuv.o \ - commonmodel.o \ - snpemodel.o \ - monitoring.o \ - model.o \ + transforms/transform.o \ + transforms/loadyuv.o \ + transforms/rgb_to_yuv.o \ + models/commonmodel.o \ + runners/snpemodel.o \ + models/posenet.o \ + models/monitoring.o \ + models/driving.o \ clutil.o \ $(PHONELIBS)/json/src/json.o \ $(PHONELIBS)/json11/json11.o \ $(CEREAL_OBJS) -#MODEL_DATA = ../../models/driving_bigmodel.dlc ../../models/monitoring_model.dlc -MODEL_DATA = ../../models/driving_model.dlc ../../models/monitoring_model.dlc ../../models/posenet.dlc -MODEL_OBJS = $(MODEL_DATA:.dlc=.o) -OBJS += $(MODEL_OBJS) - -ifeq ($(RELEASE),1) -CFLAGS += -DCLU_NO_SRC -CXXFLAGS += -DCLU_NO_SRC -CLCACHE_FILES = $(wildcard /tmp/clcache/*.clb) -CLCACHE_OBJS += $(CLCACHE_FILES:.clb=.o) -OBJS += $(CLCACHE_OBJS) - -clutil.o: clcache_bins.h -clcache_bins.h: $(CLCACHE_FILES) /tmp/clcache/index.cli - rm -f '$@' - for hash in $(basename $(notdir $(CLCACHE_FILES))) ; do \ - echo "extern const uint8_t clb_$$hash[] asm(\"_binary_$${hash}_clb_start\");" ; \ - echo "extern const uint8_t clb_$${hash}_end[] asm(\"_binary_$${hash}_clb_end\");" ; \ - done >> '$@' - echo "static const CLUProgramIndex clu_index[] = {" >> '$@' - while read idx_hash code_hash; do \ - echo "{ 0x$$idx_hash, clb_$${code_hash}, clb_$${code_hash}_end }," ; \ - done < /tmp/clcache/index.cli >> '$@' - echo "};" >> '$@' - -$(CLCACHE_OBJS): %.o: %.clb - @echo "[ bin2o ] $@" - cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)' +DEPS := $(OBJS:.o=.d) -LDFLAGS += -s -endif +rgb_to_yuv_test: transforms/rgb_to_yuv_test.o clutil.o transforms/rgb_to_yuv.o ../common/util.o + @echo "[ LINK ] $@" + $(CXX) -fPIC -o '$@' $^ \ + $(LIBYUV_LIBS) \ + $(LDFLAGS) \ + -L/usr/lib \ + -L/system/vendor/lib64 \ + $(OPENCL_LIBS) \ -DEPS := $(OBJS:.o=.d) -$(OUTPUT): $(OBJS) +$(OUTPUT): $(OBJS) $(MESSAGING_LIBS) @echo "[ LINK ] $@" $(CXX) -fPIC -o '$@' $^ \ $(LDFLAGS) \ $(LIBYUV_LIBS) \ - $(OPENCV_LIBS) \ $(OPENGL_LIBS) \ $(CEREAL_LIBS) \ $(ZMQ_LIBS) \ + -ljpeg \ -L/usr/lib \ -L/system/vendor/lib64 \ $(OPENCL_LIBS) \ $(CURL_LIBS) \ $(SSL_LIBS) \ + $(TF_LIBS) \ $(SNPE_LIBS) \ + $(UUID_LIBS) \ $(OTHER_LIBS) $(MODEL_OBJS): %.o: %.dlc @@ -195,11 +191,13 @@ $(MODEL_OBJS): %.o: %.dlc @echo "[ CXX ] $@" $(CXX) $(CXXFLAGS) -MMD \ -Iinclude -I.. -I../.. \ - $(OPENCV_FLAGS) $(EIGEN_FLAGS) \ + $(EIGEN_FLAGS) \ $(ZMQ_FLAGS) \ + $(MESSAGING_FLAGS) \ $(CEREAL_CXXFLAGS) \ $(OPENCL_FLAGS) \ $(LIBYUV_FLAGS) \ + $(TF_FLAGS) \ $(SNPE_FLAGS) \ $(JSON_FLAGS) \ $(JSON11_FLAGS) $(CURL_FLAGS) \ @@ -212,6 +210,7 @@ $(MODEL_OBJS): %.o: %.dlc $(CC) $(CFLAGS) -MMD \ -Iinclude -I.. -I../.. \ $(ZMQ_FLAGS) \ + $(MESSAGING_FLAGS) \ $(CEREAL_CFLAGS) \ $(OPENCL_FLAGS) \ $(LIBYUV_FLAGS) \ @@ -222,6 +221,6 @@ $(MODEL_OBJS): %.o: %.dlc .PHONY: clean clean: - rm -f visiond $(OBJS) $(DEPS) + rm -f visiond rgb_to_yuv_test rgb_to_yuv_test.o $(OBJS) $(DEPS) -include $(DEPS) diff --git a/selfdrive/visiond/camera_fake.cc b/selfdrive/visiond/camera_fake.cc deleted file mode 100644 index 5b7c9cb7b92399..00000000000000 --- a/selfdrive/visiond/camera_fake.cc +++ /dev/null @@ -1,267 +0,0 @@ -#include "camera_fake.h" - -#include -#include -#include - -#include -#include -#include -#include "cereal/gen/cpp/log.capnp.h" - -#include "common/util.h" -#include "common/timing.h" -#include "common/swaglog.h" -#include "buffering.h" - -extern volatile int do_exit; - -#define FRAME_WIDTH 1164 -#define FRAME_HEIGHT 874 - -namespace { -void camera_open(CameraState *s, VisionBuf *camera_bufs, bool rear) { - assert(camera_bufs); - s->camera_bufs = camera_bufs; -} - -void camera_close(CameraState *s) { - tbuffer_stop(&s->camera_tb); -} - -void camera_release_buffer(void *cookie, int buf_idx) { - CameraState *s = static_cast(cookie); -} - -void camera_init(CameraState *s, int camera_id, unsigned int fps) { - assert(camera_id < ARRAYSIZE(cameras_supported)); - s->ci = cameras_supported[camera_id]; - assert(s->ci.frame_width != 0); - - s->frame_size = s->ci.frame_height * s->ci.frame_stride; - s->fps = fps; - - tbuffer_init2(&s->camera_tb, FRAME_BUF_COUNT, "frame", camera_release_buffer, - s); -} - - -void run_simulator(DualCameraState *s) { - int err = 0; - - zsock_t *frame_sock = zsock_new_sub(">tcp://127.0.0.1:9003", ""); - assert(frame_sock); - void *frame_sock_raw = zsock_resolve(frame_sock); - - CameraState *const rear_camera = &s->rear; - - auto *tb = &rear_camera->camera_tb; - - while (!do_exit) { - const int buf_idx = tbuffer_select(tb); - - auto *buf = &rear_camera->camera_bufs[buf_idx]; - - zmq_msg_t t_msg; - err = zmq_msg_init(&t_msg); - assert(err == 0); - - zmq_msg_t frame_msg; - err = zmq_msg_init(&frame_msg); - assert(err == 0); - - // recv multipart (t, frame) - err = zmq_msg_recv(&t_msg, frame_sock_raw, 0); - assert(err != -1); - err = zmq_msg_recv(&frame_msg, frame_sock_raw, 0); - assert(err != -1); - - assert(zmq_msg_size(&t_msg) >= 8); - uint8_t* dat = (uint8_t*)zmq_msg_data(&t_msg); - float t = *(float*)&dat[0]; - uint32_t frame = *(uint32_t*)&dat[4]; - - rear_camera->camera_bufs_metadata[buf_idx] = { - .frame_id = frame, - .timestamp_eof = nanos_since_boot(), - .frame_length = 0, - .integ_lines = 0, - .global_gain = 0, - }; - - - assert(zmq_msg_size(&frame_msg) == rear_camera->frame_size); - - err = libyuv::RAWToRGB24((const uint8_t*)zmq_msg_data(&frame_msg), rear_camera->ci.frame_width*3, - (uint8_t*)buf->addr, rear_camera->ci.frame_stride, - rear_camera->ci.frame_width, rear_camera->ci.frame_height); - assert(err == 0); - - visionbuf_sync(buf, VISIONBUF_SYNC_TO_DEVICE); - tbuffer_dispatch(tb, buf_idx); - - err = zmq_msg_close(&frame_msg); - assert(err == 0); - err = zmq_msg_close(&t_msg); - assert(err == 0); - } - - zsock_destroy(&frame_sock); -} - -void run_unlogger(DualCameraState *s) { - zsock_t *frame_sock = zsock_new_sub(NULL, ""); - assert(frame_sock); - int err = zsock_connect(frame_sock, - "ipc:///tmp/9464f05d-9d88-4fc9-aa17-c75352d9590d"); - assert(err == 0); - void *frame_sock_raw = zsock_resolve(frame_sock); - - CameraState *const rear_camera = &s->rear; - auto frame_data = std::vector{}; - - auto *tb = &rear_camera->camera_tb; - - while (!do_exit) { - // Handle rear camera only. - zmq_msg_t msg; - int rc = zmq_msg_init(&msg); - assert(rc == 0); - rc = zmq_msg_recv(&msg, frame_sock_raw, 0); - if (rc == -1) { - if (do_exit) { - break; - } else { - fprintf(stderr, "Could not recv frame message: %d\n", errno); - } - } - assert(rc != -1); - - const size_t msg_size_words = zmq_msg_size(&msg) / sizeof(capnp::word); - assert(msg_size_words * sizeof(capnp::word) == zmq_msg_size(&msg)); - - if (frame_data.size() < msg_size_words) { - frame_data = std::vector{msg_size_words}; - } - std::memcpy(frame_data.data(), zmq_msg_data(&msg), - msg_size_words * sizeof(*frame_data.data())); - zmq_msg_close(&msg); - - capnp::FlatArrayMessageReader message{ - kj::arrayPtr(frame_data.data(), msg_size_words), {}}; - - const auto &event = message.getRoot(); - assert(event.which() == cereal::Event::FRAME); - const auto reader = event.getFrame(); - assert(reader.hasImage()); - const auto yuv_image = reader.getImage(); - - // Copy camera data to buffer. - const size_t width = rear_camera->ci.frame_width; - const size_t height = rear_camera->ci.frame_height; - - const size_t y_len = width * height; - const uint8_t *const y = yuv_image.begin(); - const uint8_t *const u = y + y_len; - const uint8_t *const v = u + y_len / 4; - - assert(yuv_image.size() == y_len * 3 / 2); - - const int buf_idx = tbuffer_select(tb); - rear_camera->camera_bufs_metadata[buf_idx] = { - .frame_id = reader.getFrameId(), - .timestamp_eof = reader.getTimestampEof(), - .frame_length = static_cast(reader.getFrameLength()), - .integ_lines = static_cast(reader.getIntegLines()), - .global_gain = static_cast(reader.getGlobalGain()), - }; - - auto *buf = &rear_camera->camera_bufs[buf_idx]; - uint8_t *const rgb = static_cast(buf->addr); - - // Convert to RGB. - const int result = libyuv::I420ToRGB24(y, width, u, width / 2, v, width / 2, - rgb, width * 3, width, height); - assert(result == 0); - - visionbuf_sync(buf, VISIONBUF_SYNC_TO_DEVICE); - - // HACK(mgraczyk): Do not drop frames. - while (*(volatile int*)&tb->pending_idx != -1) { - usleep(20000); - } - tbuffer_dispatch(tb, buf_idx); - } - - zsock_destroy(&frame_sock); -} - -} // namespace - -CameraInfo cameras_supported[CAMERA_ID_MAX] = { - [CAMERA_ID_IMX298] = { - .frame_width = FRAME_WIDTH, - .frame_height = FRAME_HEIGHT, - .frame_stride = FRAME_WIDTH*3, - .bayer = false, - .bayer_flip = false, - }, -}; - -void cameras_init(DualCameraState *s) { - memset(s, 0, sizeof(*s)); - - camera_init(&s->rear, CAMERA_ID_IMX298, 20); - camera_init(&s->front, CAMERA_ID_IMX298, 20); - - if (getenv("SIMULATOR2")) { - // simulator camera is flipped vertically - s->rear.transform = (mat3){{ - 1.0, 0.0, 0.0, - 0.0, -1.0, s->rear.ci.frame_height - 1.0f, - 0.0, 0.0, 1.0, - }}; - } else { - // assume the input is upside-down - s->rear.transform = (mat3){{ - -1.0, 0.0, s->rear.ci.frame_width - 1.0f, - 0.0, -1.0, s->rear.ci.frame_height - 1.0f, - 0.0, 0.0, 1.0, - }}; - } -} - -void cameras_open(DualCameraState *s, VisionBuf *camera_bufs_rear, - VisionBuf *camera_bufs_focus, VisionBuf *camera_bufs_stats, - VisionBuf *camera_bufs_front) { - assert(camera_bufs_rear); - assert(camera_bufs_front); - int err; - - // LOG("*** open front ***"); - camera_open(&s->front, camera_bufs_front, false); - - // LOG("*** open rear ***"); - camera_open(&s->rear, camera_bufs_rear, true); -} - -void cameras_close(DualCameraState *s) { - camera_close(&s->rear); - camera_close(&s->front); -} - -void camera_autoexposure(CameraState *s, float grey_frac) {} - - -void cameras_run(DualCameraState *s) { - set_thread_name("fake_camera"); - - if (getenv("SIMULATOR2")) { - run_simulator(s); - } else { - run_unlogger(s); - } - - cameras_close(s); - -} diff --git a/selfdrive/visiond/camera_fake.h b/selfdrive/visiond/camera_fake.h deleted file mode 100644 index 04ad01a6d06ef7..00000000000000 --- a/selfdrive/visiond/camera_fake.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef FAKE_CAMERA_H -#define FAKE_CAMERA_H - -#include - -#include "common/mat.h" - -#include "buffering.h" -#include "common/visionbuf.h" -#include "camera_common.h" - -#define FRAME_BUF_COUNT 4 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct CameraState { - int camera_id; - CameraInfo ci; - int frame_size; - - VisionBuf *camera_bufs; - FrameMetadata camera_bufs_metadata[FRAME_BUF_COUNT]; - TBuffer camera_tb; - - int fps; - float digital_gain; - - mat3 transform; -} CameraState; - - -typedef struct DualCameraState { - int ispif_fd; - - CameraState rear; - CameraState front; -} DualCameraState; - -void cameras_init(DualCameraState *s); -void cameras_open(DualCameraState *s, VisionBuf *camera_bufs_rear, VisionBuf *camera_bufs_focus, VisionBuf *camera_bufs_stats, VisionBuf *camera_bufs_front); -void cameras_run(DualCameraState *s); -void cameras_close(DualCameraState *s); - -void camera_autoexposure(CameraState *s, float grey_frac); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/selfdrive/visiond/camera_common.h b/selfdrive/visiond/cameras/camera_common.h similarity index 100% rename from selfdrive/visiond/camera_common.h rename to selfdrive/visiond/cameras/camera_common.h diff --git a/selfdrive/visiond/cameras/camera_frame_stream.cc b/selfdrive/visiond/cameras/camera_frame_stream.cc new file mode 100644 index 00000000000000..fe1bba3bb8c80a --- /dev/null +++ b/selfdrive/visiond/cameras/camera_frame_stream.cc @@ -0,0 +1,165 @@ +#include "camera_frame_stream.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "cereal/gen/cpp/log.capnp.h" +#include "messaging.hpp" + +#include "common/util.h" +#include "common/timing.h" +#include "common/swaglog.h" +#include "buffering.h" + +extern "C" { +#include +} + +extern volatile sig_atomic_t do_exit; + +#define FRAME_WIDTH 1164 +#define FRAME_HEIGHT 874 + +namespace { +void camera_open(CameraState *s, VisionBuf *camera_bufs, bool rear) { + assert(camera_bufs); + s->camera_bufs = camera_bufs; +} + +void camera_close(CameraState *s) { + tbuffer_stop(&s->camera_tb); +} + +void camera_release_buffer(void *cookie, int buf_idx) { + CameraState *s = static_cast(cookie); +} + +void camera_init(CameraState *s, int camera_id, unsigned int fps) { + assert(camera_id < ARRAYSIZE(cameras_supported)); + s->ci = cameras_supported[camera_id]; + assert(s->ci.frame_width != 0); + + s->frame_size = s->ci.frame_height * s->ci.frame_stride; + s->fps = fps; + + tbuffer_init2(&s->camera_tb, FRAME_BUF_COUNT, "frame", camera_release_buffer, s); +} + +void run_frame_stream(DualCameraState *s) { + int err; + Context * context = Context::create(); + SubSocket * recorder_sock = SubSocket::create(context, "frame"); + + CameraState *const rear_camera = &s->rear; + auto *tb = &rear_camera->camera_tb; + + while (!do_exit) { + Message * msg = recorder_sock->receive(); + + auto amsg = kj::heapArray((msg->getSize() / sizeof(capnp::word)) + 1); + memcpy(amsg.begin(), msg->getData(), msg->getSize()); + + capnp::FlatArrayMessageReader cmsg(amsg); + cereal::Event::Reader event = cmsg.getRoot(); + auto frame = event.getFrame(); + + const int buf_idx = tbuffer_select(tb); + rear_camera->camera_bufs_metadata[buf_idx] = { + .frame_id = frame.getFrameId(), + .timestamp_eof = frame.getTimestampEof(), + .frame_length = static_cast(frame.getFrameLength()), + .integ_lines = static_cast(frame.getIntegLines()), + .global_gain = static_cast(frame.getGlobalGain()), + }; + + cl_command_queue q = rear_camera->camera_bufs[buf_idx].copy_q; + cl_mem yuv_cl = rear_camera->camera_bufs[buf_idx].buf_cl; + cl_event map_event; + void *yuv_buf = (void *)clEnqueueMapBuffer(q, yuv_cl, CL_TRUE, + CL_MAP_WRITE, 0, frame.getImage().size(), + 0, NULL, &map_event, &err); + assert(err == 0); + clWaitForEvents(1, &map_event); + clReleaseEvent(map_event); + memcpy(yuv_buf, frame.getImage().begin(), frame.getImage().size()); + + clEnqueueUnmapMemObject(q, yuv_cl, yuv_buf, 0, NULL, &map_event); + clWaitForEvents(1, &map_event); + clReleaseEvent(map_event); + tbuffer_dispatch(tb, buf_idx); + delete msg; + + } + delete recorder_sock; + delete context; +} + +} // namespace + +CameraInfo cameras_supported[CAMERA_ID_MAX] = { + [CAMERA_ID_IMX298] = { + .frame_width = FRAME_WIDTH, + .frame_height = FRAME_HEIGHT, + .frame_stride = FRAME_WIDTH*3, + .bayer = false, + .bayer_flip = false, + }, + [CAMERA_ID_OV8865] = { + .frame_width = 1632, + .frame_height = 1224, + .frame_stride = 2040, // seems right + .bayer = false, + .bayer_flip = 3, + .hdr = false + }, +}; + +void cameras_init(DualCameraState *s) { + memset(s, 0, sizeof(*s)); + + camera_init(&s->rear, CAMERA_ID_IMX298, 20); + s->rear.transform = (mat3){{ + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0, + }}; + + camera_init(&s->front, CAMERA_ID_OV8865, 10); + s->front.transform = (mat3){{ + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0, + }}; +} + +void camera_autoexposure(CameraState *s, float grey_frac) {} + +void cameras_open(DualCameraState *s, VisionBuf *camera_bufs_rear, + VisionBuf *camera_bufs_focus, VisionBuf *camera_bufs_stats, + VisionBuf *camera_bufs_front) { + assert(camera_bufs_rear); + assert(camera_bufs_front); + int err; + + // LOG("*** open front ***"); + camera_open(&s->front, camera_bufs_front, false); + + // LOG("*** open rear ***"); + camera_open(&s->rear, camera_bufs_rear, true); +} + +void cameras_close(DualCameraState *s) { + camera_close(&s->rear); +} + +void cameras_run(DualCameraState *s) { + set_thread_name("frame_streaming"); + run_frame_stream(s); + cameras_close(s); +} diff --git a/selfdrive/visiond/cameras/camera_frame_stream.h b/selfdrive/visiond/cameras/camera_frame_stream.h new file mode 100644 index 00000000000000..6351a183d35c3c --- /dev/null +++ b/selfdrive/visiond/cameras/camera_frame_stream.h @@ -0,0 +1,56 @@ +#ifndef CAMERA_FRAME_STREAM_H +#define CAMERA_FRAME_STREAM_H + +#include + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include "common/mat.h" + +#include "buffering.h" +#include "common/visionbuf.h" +#include "camera_common.h" + +#define FRAME_BUF_COUNT 16 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct CameraState { + int camera_id; + CameraInfo ci; + int frame_size; + + VisionBuf *camera_bufs; + FrameMetadata camera_bufs_metadata[FRAME_BUF_COUNT]; + TBuffer camera_tb; + + int fps; + float digital_gain; + + mat3 transform; +} CameraState; + + +typedef struct DualCameraState { + int ispif_fd; + + CameraState rear; + CameraState front; +} DualCameraState; + +void cameras_init(DualCameraState *s); +void cameras_open(DualCameraState *s, VisionBuf *camera_bufs_rear, VisionBuf *camera_bufs_focus, VisionBuf *camera_bufs_stats, VisionBuf *camera_bufs_front); +void cameras_run(DualCameraState *s); +void cameras_close(DualCameraState *s); +void camera_autoexposure(CameraState *s, float grey_frac); +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/selfdrive/visiond/camera_qcom.c b/selfdrive/visiond/cameras/camera_qcom.c similarity index 96% rename from selfdrive/visiond/camera_qcom.c rename to selfdrive/visiond/cameras/camera_qcom.c index 08a1dff6526e8c..39fd189b5a5cf3 100644 --- a/selfdrive/visiond/camera_qcom.c +++ b/selfdrive/visiond/cameras/camera_qcom.c @@ -44,7 +44,7 @@ typedef struct CameraMsg { float grey_frac; } CameraMsg; -extern volatile int do_exit; +extern volatile sig_atomic_t do_exit; CameraInfo cameras_supported[CAMERA_ID_MAX] = { [CAMERA_ID_IMX298] = { @@ -292,10 +292,6 @@ void cameras_init(DualCameraState *s) { } else if (strcmp(product_name, "OnePlus3") == 0 && strcmp(project_name, "15811") == 0) { // only OP3T support s->device = DEVICE_OP3T; - } else if (strcmp(product_name, "LePro3") == 0) { - LOGD("LePro 3 detected"); - s->device = DEVICE_LP3; - assert(false); } else { assert(false); } @@ -372,21 +368,6 @@ static void set_exposure(CameraState *s, float exposure_frac, float gain_frac) { integ_lines = min(integ_lines, frame_length-11); } - // done after exposure to not adjust it - if (s->using_pll) { - // can adjust frame length by up to +/- 1 - const int PHASE_DEADZONE = 20000; // 20 us - int phase_max = 1000000000 / s->fps; - int phase_diff = s->phase_actual - s->phase_request; - phase_diff = ((phase_diff + phase_max/2) % phase_max) - phase_max/2; - - if (phase_diff < -PHASE_DEADZONE) { - frame_length += 1; - } else if (phase_diff > PHASE_DEADZONE) { - frame_length -= 1; - } - } - if (gain_frac >= 0) { // ISO200 is minimum gain gain_frac = clamp(gain_frac, 1.0/64, 1.0); @@ -423,7 +404,7 @@ static void set_exposure(CameraState *s, float exposure_frac, float gain_frac) { s->cur_gain_frac = gain_frac; } - LOGD("set exposure: %f %f - %d", exposure_frac, gain_frac, err); + //LOGD("set exposure: %f %f - %d", exposure_frac, gain_frac, err); } static void do_autoexposure(CameraState *s, float grey_frac) { @@ -431,7 +412,7 @@ static void do_autoexposure(CameraState *s, float grey_frac) { float new_exposure = s->cur_exposure_frac; new_exposure *= pow(1.05, (target_grey - grey_frac) / 0.05 ); - LOGD("diff %f: %f to %f", target_grey - grey_frac, s->cur_exposure_frac, new_exposure); + //LOGD("diff %f: %f to %f", target_grey - grey_frac, s->cur_exposure_frac, new_exposure); float new_gain = s->cur_gain_frac; if (new_exposure < 0.10) { @@ -1708,12 +1689,12 @@ void actuator_move(CameraState *s, uint16_t target) { .ringing_params = &actuator_ringing_params, }; err = ioctl(s->actuator_fd, VIDIOC_MSM_ACTUATOR_CFG, &actuator_cfg_data); - LOGD("actuator move focus: %d", err); + //LOGD("actuator move focus: %d", err); s->cur_step_pos = dest_step_pos; s->cur_lens_pos = actuator_cfg_data.cfg.move.curr_lens_pos; - LOGD("step %d target: %d lens pos: %d", dest_step_pos, target, s->cur_lens_pos); + //LOGD("step %d target: %d lens pos: %d", dest_step_pos, target, s->cur_lens_pos); } static void parse_autofocus(CameraState *s, uint8_t *d) { @@ -1778,12 +1759,12 @@ static void do_autofocus(CameraState *s) { int target = clamp(s->lens_true_pos - sag, dac_down, dac_up); - char debug[4096]; + /*char debug[4096]; char *pdebug = debug; pdebug += sprintf(pdebug, "focus "); for (int i = 0; i < NUM_FOCUS; i++) pdebug += sprintf(pdebug, "%2x(%4d) ", s->confidence[i], s->focus[i]); pdebug += sprintf(pdebug, " err: %7.2f offset: %6.2f sag: %6.2f lens_true_pos: %6.2f cur_lens_pos: %4d->%4d", err * focus_kp, offset, sag, s->lens_true_pos, s->cur_lens_pos, target); - LOGD(debug); + LOGD(debug);*/ actuator_move(s, target); } @@ -1925,6 +1906,8 @@ static void camera_close(CameraState *s) { LOG("isp release stream: %d", err); } } + + free(s->eeprom); } @@ -2021,41 +2004,6 @@ static bool acceleration_from_sensor_sock(void* sock, float* vs) { return ret; } -static bool gps_time_from_timing_sock(void* sock, uint64_t *mono_time, double* vs) { - int err; - - zmq_msg_t msg; - err = zmq_msg_init(&msg); - assert(err == 0); - - err = zmq_msg_recv(&msg, sock, 0); - assert(err >= 0); - - struct capn ctx; - capn_init_mem(&ctx, zmq_msg_data(&msg), zmq_msg_size(&msg), 0); - - cereal_Event_ptr eventp; - eventp.p = capn_getp(capn_root(&ctx), 0, 1); - struct cereal_Event eventd; - cereal_read_Event(&eventd, eventp); - - bool ret = false; - - if (eventd.which == cereal_Event_liveLocationTiming) { - struct cereal_LiveLocationData lld; - cereal_read_LiveLocationData(&lld, eventd.liveLocationTiming); - - *mono_time = lld.fixMonoTime; - *vs = lld.timeOfWeek; - ret = true; - } - - capn_free(&ctx); - zmq_msg_close(&msg); - - return ret; -} - static void ops_term() { zsock_t *ops_sock = zsock_new_push(">inproc://cameraops"); assert(ops_sock); @@ -2078,13 +2026,10 @@ static void* ops_thread(void* arg) { zsock_t *sensor_sock = zsock_new_sub(">tcp://127.0.0.1:8003", ""); assert(sensor_sock); - zsock_t *livelocationtiming_sock = zsock_new_sub(">tcp://127.0.0.1:8049", ""); - assert(livelocationtiming_sock); - zsock_t *terminate = zsock_new_sub(">inproc://terminate", ""); assert(terminate); - zpoller_t *poller = zpoller_new(cameraops, sensor_sock, livelocationtiming_sock, terminate, NULL); + zpoller_t *poller = zpoller_new(cameraops, sensor_sock, terminate, NULL); assert(poller); while (!do_exit) { @@ -2107,7 +2052,7 @@ static void* ops_thread(void* arg) { if (zmq_msg_size(&msg) == sizeof(cmsg)) { memcpy(&cmsg, zmq_msg_data(&msg), zmq_msg_size(&msg)); - LOGD("cameraops %d", cmsg.type); + //LOGD("cameraops %d", cmsg.type); if (cmsg.type == CAMERA_MSG_AUTOEXPOSE) { if (cmsg.camera_num == 0) { @@ -2132,15 +2077,6 @@ static void* ops_thread(void* arg) { s->rear.last_sag_ts = ts; s->rear.last_sag_acc_z = -vs[2]; } - } else if (which == livelocationtiming_sock) { - uint64_t mono_time; - double gps_time; - if (gps_time_from_timing_sock(sockraw, &mono_time, &gps_time)) { - s->rear.global_time_offset = (uint64_t)(gps_time*1e9) - mono_time; - //LOGW("%f %lld = %lld", gps_time, mono_time, s->rear.global_time_offset); - s->rear.phase_request = 10000000; - s->rear.using_pll = true; - } } } @@ -2230,12 +2166,6 @@ void cameras_run(DualCameraState *s) { // printf("ISP_EVENT_EOF delta %f\n", (t-last_t)/1e6); c->last_t = t; - if (c->using_pll) { - int mod = ((int)1000000000 / c->fps); - c->phase_actual = (((timestamp + c->global_time_offset) % mod) + mod) % mod; - LOGD("phase is %12d request is %12d with offset %lld", c->phase_actual, c->phase_request, c->global_time_offset); - } - pthread_mutex_lock(&c->frame_info_lock); c->frame_metadata[c->frame_metadata_idx] = (FrameMetadata){ .frame_id = isp_event_data->frame_id, @@ -2272,4 +2202,3 @@ void cameras_close(DualCameraState *s) { camera_close(&s->rear); camera_close(&s->front); } - diff --git a/selfdrive/visiond/camera_qcom.h b/selfdrive/visiond/cameras/camera_qcom.h similarity index 94% rename from selfdrive/visiond/camera_qcom.h rename to selfdrive/visiond/cameras/camera_qcom.h index 0cc8f844a57477..1a9c31baa3a29f 100644 --- a/selfdrive/visiond/camera_qcom.h +++ b/selfdrive/visiond/cameras/camera_qcom.h @@ -54,13 +54,6 @@ typedef struct CameraState { uint32_t line_length_pclk; unsigned int max_gain; - // PLL to sync cameras in time - // assumes at least 1 FPS - bool using_pll; - int phase_actual; - int phase_request; - int64_t global_time_offset; - int csid_fd; int csiphy_fd; int sensor_fd; diff --git a/selfdrive/visiond/debayer.cl b/selfdrive/visiond/cameras/debayer.cl similarity index 100% rename from selfdrive/visiond/debayer.cl rename to selfdrive/visiond/cameras/debayer.cl diff --git a/selfdrive/visiond/sensor_i2c.h b/selfdrive/visiond/cameras/sensor_i2c.h similarity index 100% rename from selfdrive/visiond/sensor_i2c.h rename to selfdrive/visiond/cameras/sensor_i2c.h diff --git a/selfdrive/visiond/commonmodel.c b/selfdrive/visiond/commonmodel.c deleted file mode 100644 index 595d2609e74d4e..00000000000000 --- a/selfdrive/visiond/commonmodel.c +++ /dev/null @@ -1,155 +0,0 @@ -#include "commonmodel.h" - -#include -#include "cereal/gen/c/log.capnp.h" -#include "common/mat.h" -#include "common/timing.h" - -void model_input_init(ModelInput* s, int width, int height, - cl_device_id device_id, cl_context context) { - int err; - s->device_id = device_id; - s->context = context; - - transform_init(&s->transform, context, device_id); - s->transformed_width = width; - s->transformed_height = height; - - s->transformed_y_cl = clCreateBuffer(s->context, CL_MEM_READ_WRITE, - s->transformed_width*s->transformed_height, NULL, &err); - assert(err == 0); - s->transformed_u_cl = clCreateBuffer(s->context, CL_MEM_READ_WRITE, - (s->transformed_width/2)*(s->transformed_height/2), NULL, &err); - assert(err == 0); - s->transformed_v_cl = clCreateBuffer(s->context, CL_MEM_READ_WRITE, - (s->transformed_width/2)*(s->transformed_height/2), NULL, &err); - assert(err == 0); - - s->net_input_size = ((width*height*3)/2)*sizeof(float); - s->net_input = clCreateBuffer(s->context, CL_MEM_READ_WRITE, - s->net_input_size, (void*)NULL, &err); - assert(err == 0); - - loadyuv_init(&s->loadyuv, context, device_id, s->transformed_width, s->transformed_height); -} - -float *model_input_prepare(ModelInput* s, cl_command_queue q, - cl_mem yuv_cl, int width, int height, - mat3 transform) { - int err; - int i = 0; - transform_queue(&s->transform, q, - yuv_cl, width, height, - s->transformed_y_cl, s->transformed_u_cl, s->transformed_v_cl, - s->transformed_width, s->transformed_height, - transform); - loadyuv_queue(&s->loadyuv, q, - s->transformed_y_cl, s->transformed_u_cl, s->transformed_v_cl, - s->net_input); - float *net_input_buf = (float *)clEnqueueMapBuffer(q, s->net_input, CL_TRUE, - CL_MAP_READ, 0, s->net_input_size, - 0, NULL, NULL, &err); - clFinish(q); - return net_input_buf; -} - -void model_input_free(ModelInput* s) { - transform_destroy(&s->transform); - loadyuv_destroy(&s->loadyuv); -} - - -void softmax(const float* input, float* output, size_t len) { - float max_val = -FLT_MAX; - for(int i = 0; i < len; i++) { - const float v = input[i]; - if( v > max_val ) { - max_val = v; - } - } - - float denominator = 0; - for(int i = 0; i < len; i++) { - float const v = input[i]; - float const v_exp = expf(v - max_val); - denominator += v_exp; - output[i] = v_exp; - } - - const float inv_denominator = 1. / denominator; - for(int i = 0; i < len; i++) { - output[i] *= inv_denominator; - } - -} - - -static cereal_ModelData_PathData_ptr path_to_cereal(struct capn_segment *cs, const PathData data) { - capn_list32 points_ptr = capn_new_list32(cs, MODEL_PATH_DISTANCE); - for (int i=0; iin, MODEL_WIDTH, MODEL_HEIGHT, device_id, context); - const int output_size = OUTPUT_SIZE + TEMPORAL_SIZE; - s->output = (float*)malloc(output_size * sizeof(float)); - memset(s->output, 0, output_size * sizeof(float)); - s->m = new SNPEModel(driving_model_data, driving_model_size, s->output, output_size); -#ifdef TEMPORAL - assert(temporal); - s->m->addRecurrent(&s->output[OUTPUT_SIZE], TEMPORAL_SIZE); -#else - assert(!temporal); -#endif -} - -ModelData model_eval_frame(ModelState* s, cl_command_queue q, - cl_mem yuv_cl, int width, int height, - mat3 transform, void* sock) { - struct { - float *path; - float *left_lane; - float *right_lane; - float *lead; - } net_outputs = {NULL}; - - //for (int i = 0; i < OUTPUT_SIZE + TEMPORAL_SIZE; i++) { printf("%f ", s->output[i]); } printf("\n"); - - float *net_input_buf = model_input_prepare(&s->in, q, yuv_cl, width, height, transform); - s->m->execute(net_input_buf); - - // net outputs - net_outputs.path = &s->output[0]; - net_outputs.left_lane = &s->output[51]; - net_outputs.right_lane = &s->output[51+53]; - net_outputs.lead = &s->output[51+53+53]; - - ModelData model = {0}; - - for (int i=0; i 0. ? model.lead.dist : 0.; - - model.lead.std = max_dist * sqrt(2.) / net_outputs.lead[1]; - softmax(&net_outputs.lead[2], softmax_buff, 2); - model.lead.prob = softmax_buff[0]; - - return model; -} - -void model_free(ModelState* s) { - model_input_free(&s->in); - delete s->m; -} - diff --git a/selfdrive/visiond/model.h b/selfdrive/visiond/model.h deleted file mode 100644 index 06a65f8539752b..00000000000000 --- a/selfdrive/visiond/model.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef MODEL_H -#define MODEL_H - -// gate this here -//#define BIGMODEL -#define TEMPORAL - -#include "common/mat.h" -#include "common/modeldata.h" - -#include "commonmodel.h" -#include "snpemodel.h" - -typedef struct ModelState { - ModelInput in; - float *output; - SNPEModel *m; -} ModelState; - -void model_init(ModelState* s, cl_device_id device_id, - cl_context context, int temporal); -ModelData model_eval_frame(ModelState* s, cl_command_queue q, - cl_mem yuv_cl, int width, int height, - mat3 transform, void* sock); -void model_free(ModelState* s); - -#endif diff --git a/selfdrive/visiond/models/commonmodel.c b/selfdrive/visiond/models/commonmodel.c new file mode 100644 index 00000000000000..0369d16d5dd05d --- /dev/null +++ b/selfdrive/visiond/models/commonmodel.c @@ -0,0 +1,68 @@ +#include "commonmodel.h" + +#include +#include "cereal/gen/c/log.capnp.h" +#include "common/mat.h" +#include "common/timing.h" + +void model_input_init(ModelInput* s, int width, int height, + cl_device_id device_id, cl_context context) { + int err; + s->device_id = device_id; + s->context = context; + + transform_init(&s->transform, context, device_id); + s->transformed_width = width; + s->transformed_height = height; + + s->transformed_y_cl = clCreateBuffer(s->context, CL_MEM_READ_WRITE, + s->transformed_width*s->transformed_height, NULL, &err); + assert(err == 0); + s->transformed_u_cl = clCreateBuffer(s->context, CL_MEM_READ_WRITE, + (s->transformed_width/2)*(s->transformed_height/2), NULL, &err); + assert(err == 0); + s->transformed_v_cl = clCreateBuffer(s->context, CL_MEM_READ_WRITE, + (s->transformed_width/2)*(s->transformed_height/2), NULL, &err); + assert(err == 0); + + s->net_input_size = ((width*height*3)/2)*sizeof(float); + s->net_input = clCreateBuffer(s->context, CL_MEM_READ_WRITE, + s->net_input_size, (void*)NULL, &err); + assert(err == 0); + + loadyuv_init(&s->loadyuv, context, device_id, s->transformed_width, s->transformed_height); +} + +float *model_input_prepare(ModelInput* s, cl_command_queue q, + cl_mem yuv_cl, int width, int height, + mat3 transform) { + int err; + int i = 0; + transform_queue(&s->transform, q, + yuv_cl, width, height, + s->transformed_y_cl, s->transformed_u_cl, s->transformed_v_cl, + s->transformed_width, s->transformed_height, + transform); + loadyuv_queue(&s->loadyuv, q, + s->transformed_y_cl, s->transformed_u_cl, s->transformed_v_cl, + s->net_input); + float *net_input_buf = (float *)clEnqueueMapBuffer(q, s->net_input, CL_TRUE, + CL_MAP_READ, 0, s->net_input_size, + 0, NULL, NULL, &err); + clFinish(q); + return net_input_buf; +} + +void model_input_free(ModelInput* s) { + transform_destroy(&s->transform); + loadyuv_destroy(&s->loadyuv); +} + + +float sigmoid(float input) { + return 1 / (1 + expf(-input)); +} + +float softplus(float input) { + return log1p(expf(input)); +} diff --git a/selfdrive/visiond/commonmodel.h b/selfdrive/visiond/models/commonmodel.h similarity index 79% rename from selfdrive/visiond/commonmodel.h rename to selfdrive/visiond/models/commonmodel.h index 3ac5ccea121528..2a03a3d00fbcfd 100644 --- a/selfdrive/visiond/commonmodel.h +++ b/selfdrive/visiond/models/commonmodel.h @@ -5,14 +5,15 @@ #include "common/mat.h" #include "common/modeldata.h" -#include "transform.h" -#include "loadyuv.h" +#include "transforms/transform.h" +#include "transforms/loadyuv.h" #ifdef __cplusplus extern "C" { #endif -void softmax(const float* input, float* output, size_t len); +float softplus(float input); +float sigmoid(float input); typedef struct ModelInput { cl_device_id device_id; @@ -34,9 +35,6 @@ float *model_input_prepare(ModelInput* s, cl_command_queue q, mat3 transform); void model_input_free(ModelInput* s); -void model_publish(void* sock, uint32_t frame_id, - const mat3 transform, const ModelData data); - #ifdef __cplusplus } #endif diff --git a/selfdrive/visiond/models/driving.cc b/selfdrive/visiond/models/driving.cc new file mode 100644 index 00000000000000..bb985425f80e8e --- /dev/null +++ b/selfdrive/visiond/models/driving.cc @@ -0,0 +1,280 @@ +#include +#include +#include +#include + +#ifdef QCOM +#include +#else +#include +#endif + +#include "common/timing.h" +#include "driving.h" + +#define MODEL_WIDTH 512 +#define MODEL_HEIGHT 256 +#define MODEL_NAME "driving_model_dlc" + +#define LEAD_MDN_N 5 // probs for 5 groups +#define MDN_VALS 4 // output xyva for each lead group +#define SELECTION 3 //output 3 group (lead now, in 2s and 6s) +#define MDN_GROUP_SIZE 11 +#define SPEED_BUCKETS 100 +#define OUTPUT_SIZE ((MODEL_PATH_DISTANCE*2) + (2*(MODEL_PATH_DISTANCE*2 + 1)) + MDN_GROUP_SIZE*LEAD_MDN_N + SELECTION) +#ifdef TEMPORAL + #define TEMPORAL_SIZE 512 +#else + #define TEMPORAL_SIZE 0 +#endif + +// #define DUMP_YUV + +Eigen::Matrix vander; + +void model_init(ModelState* s, cl_device_id device_id, cl_context context, int temporal) { + model_input_init(&s->in, MODEL_WIDTH, MODEL_HEIGHT, device_id, context); + const int output_size = OUTPUT_SIZE + TEMPORAL_SIZE; + s->output = (float*)malloc(output_size * sizeof(float)); + memset(s->output, 0, output_size * sizeof(float)); + s->m = new DefaultRunModel("../../models/driving_model.dlc", s->output, output_size, USE_GPU_RUNTIME); +#ifdef TEMPORAL + assert(temporal); + s->m->addRecurrent(&s->output[OUTPUT_SIZE], TEMPORAL_SIZE); +#endif +#ifdef DESIRE + s->desire = (float*)malloc(DESIRE_SIZE * sizeof(float)); + for (int i = 0; i < DESIRE_SIZE; i++) s->desire[i] = 0.0; + s->m->addDesire(s->desire, DESIRE_SIZE); +#endif + + // Build Vandermonde matrix + for(int i = 0; i < MODEL_PATH_DISTANCE; i++) { + for(int j = 0; j < POLYFIT_DEGREE - 1; j++) { + vander(i, j) = pow(i, POLYFIT_DEGREE-j-1); + } + } +} + +ModelData model_eval_frame(ModelState* s, cl_command_queue q, + cl_mem yuv_cl, int width, int height, + mat3 transform, void* sock, float *desire_in) { + struct { + float *path; + float *left_lane; + float *right_lane; + float *lead; + float *speed; + } net_outputs = {NULL}; + +#ifdef DESIRE + if (desire_in != NULL) { + for (int i = 0; i < DESIRE_SIZE; i++) s->desire[i] = desire_in[i]; + } +#endif + + //for (int i = 0; i < OUTPUT_SIZE + TEMPORAL_SIZE; i++) { printf("%f ", s->output[i]); } printf("\n"); + + float *net_input_buf = model_input_prepare(&s->in, q, yuv_cl, width, height, transform); + + #ifdef DUMP_YUV + FILE *dump_yuv_file = fopen("/sdcard/dump.yuv", "wb"); + fwrite(net_input_buf, MODEL_HEIGHT*MODEL_WIDTH*3/2, sizeof(float), dump_yuv_file); + fclose(dump_yuv_file); + assert(1==2); + #endif + + //printf("readinggggg \n"); + //FILE *f = fopen("goof_frame", "r"); + //fread(net_input_buf, sizeof(float), MODEL_HEIGHT*MODEL_WIDTH*3/2, f); + //fclose(f); + //sleep(1); + //printf("%i \n",OUTPUT_SIZE); + //printf("%i \n",MDN_GROUP_SIZE); + s->m->execute(net_input_buf); + + // net outputs + net_outputs.path = &s->output[0]; + net_outputs.left_lane = &s->output[MODEL_PATH_DISTANCE*2]; + net_outputs.right_lane = &s->output[MODEL_PATH_DISTANCE*2 + MODEL_PATH_DISTANCE*2 + 1]; + net_outputs.lead = &s->output[MODEL_PATH_DISTANCE*2 + (MODEL_PATH_DISTANCE*2 + 1)*2]; + //net_outputs.speed = &s->output[OUTPUT_SIZE - SPEED_BUCKETS]; + + ModelData model = {0}; + + for (int i=0; i net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + 8]) { + mdn_max_idx = i; + } + } + model.lead.prob = sigmoid(net_outputs.lead[LEAD_MDN_N*MDN_GROUP_SIZE]); + model.lead.dist = net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE] * max_dist; + model.lead.std = softplus(net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + MDN_VALS]) * max_dist; + model.lead.rel_y = net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + 1]; + model.lead.rel_y_std = softplus(net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + MDN_VALS + 1]); + model.lead.rel_v = net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + 2] * max_rel_vel; + model.lead.rel_v_std = softplus(net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + MDN_VALS + 2]) * max_rel_vel; + model.lead.rel_a = net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + 3]; + model.lead.rel_a_std = softplus(net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + MDN_VALS + 3]); + + // Find the distribution that corresponds to the lead in 2s + mdn_max_idx = 0; + for (int i=1; i net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + 9]) { + mdn_max_idx = i; + } + } + model.lead_future.prob = sigmoid(net_outputs.lead[LEAD_MDN_N*MDN_GROUP_SIZE + 1]); + model.lead_future.dist = net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE] * max_dist; + model.lead_future.std = softplus(net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + MDN_VALS]) * max_dist; + model.lead_future.rel_y = net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + 1]; + model.lead_future.rel_y_std = softplus(net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + MDN_VALS + 1]); + model.lead_future.rel_v = net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + 2] * max_rel_vel; + model.lead_future.rel_v_std = softplus(net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + MDN_VALS + 2]) * max_rel_vel; + model.lead_future.rel_a = net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + 3]; + model.lead_future.rel_a_std = softplus(net_outputs.lead[mdn_max_idx*MDN_GROUP_SIZE + MDN_VALS + 3]); + + + // get speed percentiles numbers represent 5th, 15th, ... 95th percentile + for (int i=0; i < SPEED_PERCENTILES; i++) { + model.speed[i] = ((float) SPEED_BUCKETS)/2.0; + } + //float sum = 0; + //for (int idx = 0; idx < SPEED_BUCKETS; idx++) { + // sum += net_outputs.speed[idx]; + // int idx_percentile = (sum + .05) * SPEED_PERCENTILES; + // if (idx_percentile < SPEED_PERCENTILES ){ + // model.speed[idx_percentile] = ((float)idx)/2.0; + // } + //} + // make sure no percentiles are skipped + //for (int i=SPEED_PERCENTILES-1; i > 0; i--){ + // if (model.speed[i-1] > model.speed[i]){ + // model.speed[i-1] = model.speed[i]; + // } + //} + return model; +} + +void model_free(ModelState* s) { + free(s->output); + model_input_free(&s->in); + delete s->m; +} + +void poly_fit(float *in_pts, float *in_stds, float *out) { + // References to inputs + Eigen::Map > pts(in_pts, MODEL_PATH_DISTANCE); + Eigen::Map > std(in_stds, MODEL_PATH_DISTANCE); + Eigen::Map > p(out, POLYFIT_DEGREE - 1); + + float y0 = pts[0]; + pts = pts.array() - y0; + + // Build Least Squares equations + Eigen::Matrix lhs = vander.array().colwise() / std.array(); + Eigen::Matrix rhs = pts.array() / std.array(); + + // Improve numerical stability + Eigen::Matrix scale = 1. / (lhs.array()*lhs.array()).sqrt().colwise().sum(); + lhs = lhs * scale.asDiagonal(); + + // Solve inplace + Eigen::ColPivHouseholderQR > qr(lhs); + p = qr.solve(rhs); + + // Apply scale to output + p = p.transpose() * scale.asDiagonal(); + out[3] = y0; +} + + +void fill_path(cereal::ModelData::PathData::Builder path, const PathData path_data) { + if (std::getenv("DEBUG")){ + kj::ArrayPtr stds(&path_data.stds[0], ARRAYSIZE(path_data.stds)); + path.setStds(stds); + + kj::ArrayPtr points(&path_data.points[0], ARRAYSIZE(path_data.points)); + path.setPoints(points); + } + + kj::ArrayPtr poly(&path_data.poly[0], ARRAYSIZE(path_data.poly)); + path.setPoly(poly); + path.setProb(path_data.prob); + path.setStd(path_data.std); +} + +void fill_lead(cereal::ModelData::LeadData::Builder lead, const LeadData lead_data) { + lead.setDist(lead_data.dist); + lead.setProb(lead_data.prob); + lead.setStd(lead_data.std); + lead.setRelY(lead_data.rel_y); + lead.setRelYStd(lead_data.rel_y_std); + lead.setRelVel(lead_data.rel_v); + lead.setRelVelStd(lead_data.rel_v_std); + lead.setRelA(lead_data.rel_a); + lead.setRelAStd(lead_data.rel_a_std); +} + +void model_publish(PubSocket *sock, uint32_t frame_id, + const ModelData data, uint64_t timestamp_eof) { + // make msg + capnp::MallocMessageBuilder msg; + cereal::Event::Builder event = msg.initRoot(); + event.setLogMonoTime(nanos_since_boot()); + + auto framed = event.initModel(); + framed.setFrameId(frame_id); + framed.setTimestampEof(timestamp_eof); + + kj::ArrayPtr speed(&data.speed[0], ARRAYSIZE(data.speed)); + framed.setSpeed(speed); + + + auto lpath = framed.initPath(); + fill_path(lpath, data.path); + auto left_lane = framed.initLeftLane(); + fill_path(left_lane, data.left_lane); + auto right_lane = framed.initRightLane(); + fill_path(right_lane, data.right_lane); + + auto lead = framed.initLead(); + fill_lead(lead, data.lead); + auto lead_future = framed.initLeadFuture(); + fill_lead(lead_future, data.lead_future); + + + // send message + auto words = capnp::messageToFlatArray(msg); + auto bytes = words.asBytes(); + sock->send((char*)bytes.begin(), bytes.size()); + } diff --git a/selfdrive/visiond/models/driving.h b/selfdrive/visiond/models/driving.h new file mode 100644 index 00000000000000..ccf8a94be291bf --- /dev/null +++ b/selfdrive/visiond/models/driving.h @@ -0,0 +1,44 @@ +#ifndef MODEL_H +#define MODEL_H + +// gate this here +#define TEMPORAL +#define DESIRE + +#ifdef DESIRE + #define DESIRE_SIZE 8 +#endif + +#include "common/mat.h" +#include "common/modeldata.h" +#include "common/util.h" + +#include "commonmodel.h" +#include "runners/run.h" + +#include "cereal/gen/cpp/log.capnp.h" +#include +#include +#include "messaging.hpp" + + +typedef struct ModelState { + ModelInput in; + float *output; + RunModel *m; +#ifdef DESIRE + float *desire; +#endif +} ModelState; + +void model_init(ModelState* s, cl_device_id device_id, + cl_context context, int temporal); +ModelData model_eval_frame(ModelState* s, cl_command_queue q, + cl_mem yuv_cl, int width, int height, + mat3 transform, void* sock, float *desire_in); +void model_free(ModelState* s); +void poly_fit(float *in_pts, float *in_stds, float *out); + +void model_publish(PubSocket* sock, uint32_t frame_id, + const ModelData data, uint64_t timestamp_eof); +#endif diff --git a/selfdrive/visiond/models/monitoring.cc b/selfdrive/visiond/models/monitoring.cc new file mode 100644 index 00000000000000..30a6f56c1ab95d --- /dev/null +++ b/selfdrive/visiond/models/monitoring.cc @@ -0,0 +1,108 @@ +#include +#include "monitoring.h" +#include "common/mat.h" +#include "common/timing.h" + +#define MODEL_WIDTH 320 +#define MODEL_HEIGHT 160 + +#define MAX_IR_POWER 0.5f +#define MIN_IR_POWER 0.0f +#define CUTOFF_GAIN 0.015625f // iso400 +#define SATURATE_GAIN 0.0625f // iso1600 + +// match driver_monitor.py +#define FACE_THRESH 0.4f +#define EYE_THRESH 0.4f + +void monitoring_init(MonitoringState* s, cl_device_id device_id, cl_context context) { + model_input_init(&s->in, MODEL_WIDTH, MODEL_HEIGHT, device_id, context); + s->m = new DefaultRunModel("../../models/monitoring_model.dlc", (float*)&s->output, OUTPUT_SIZE, USE_DSP_RUNTIME); +} + +MonitoringResult monitoring_eval_frame(MonitoringState* s, cl_command_queue q, + cl_mem yuv_cl, int width, int height) { + const mat3 front_frame_from_scaled_frame = (mat3){{ + width/426.0f, 0.0, 0.0, + 0.0,height/320.0f, 0.0, + 0.0, 0.0, 1.0, + }}; + + const mat3 scaled_frame_from_cropped_frame = (mat3){{ + 1.0, 0.0, 426.0-160.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0, + }}; + + const mat3 transpose = (mat3){{ + 0.0, 1.0, 0.0, + 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, + }}; + + const mat3 front_frame_from_cropped_frame = matmul3(front_frame_from_scaled_frame, scaled_frame_from_cropped_frame); + const mat3 front_frame_from_monitoring_frame = matmul3(front_frame_from_cropped_frame, transpose); + + float *net_input_buf = model_input_prepare(&s->in, q, yuv_cl, width, height, front_frame_from_monitoring_frame); + s->m->execute(net_input_buf); + + MonitoringResult ret = {0}; + memcpy(&ret.face_orientation, &s->output[0], sizeof ret.face_orientation); + memcpy(&ret.face_position, &s->output[3], sizeof ret.face_position); + memcpy(&ret.face_prob, &s->output[12], sizeof ret.face_prob); + memcpy(&ret.left_eye_prob, &s->output[21], sizeof ret.left_eye_prob); + memcpy(&ret.right_eye_prob, &s->output[30], sizeof ret.right_eye_prob); + memcpy(&ret.left_blink_prob, &s->output[31], sizeof ret.right_eye_prob); + memcpy(&ret.right_blink_prob, &s->output[32], sizeof ret.right_eye_prob); + return ret; +} + +void monitoring_publish(PubSocket* sock, uint32_t frame_id, const MonitoringResult res, float ir_target) { + // make msg + capnp::MallocMessageBuilder msg; + cereal::Event::Builder event = msg.initRoot(); + event.setLogMonoTime(nanos_since_boot()); + + auto framed = event.initDriverMonitoring(); + framed.setFrameId(frame_id); + + kj::ArrayPtr face_orientation(&res.face_orientation[0], ARRAYSIZE(res.face_orientation)); + kj::ArrayPtr face_position(&res.face_position[0], ARRAYSIZE(res.face_position)); + framed.setFaceOrientation(face_orientation); + framed.setFacePosition(face_position); + framed.setFaceProb(res.face_prob); + framed.setLeftEyeProb(res.left_eye_prob); + framed.setRightEyeProb(res.right_eye_prob); + framed.setLeftBlinkProb(res.left_blink_prob); + framed.setRightBlinkProb(res.right_blink_prob); + framed.setIrPwr(ir_target); + + // send message + auto words = capnp::messageToFlatArray(msg); + auto bytes = words.asBytes(); + sock->send((char*)bytes.begin(), bytes.size()); + } + +void monitoring_free(MonitoringState* s) { + model_input_free(&s->in); + delete s->m; +} + +float ir_target_set(float *cur_front_gain, const MonitoringResult res) { + bool face_detected = res.face_prob > FACE_THRESH; + bool eyes_detected = (res.left_eye_prob > EYE_THRESH) && (res.right_eye_prob > EYE_THRESH); + static float set_point = 0.5; + + if ((*cur_front_gain <= CUTOFF_GAIN) && !face_detected) { + set_point = MIN_IR_POWER; + } else if (face_detected && eyes_detected) { + if (*cur_front_gain > SATURATE_GAIN) { + set_point = MAX_IR_POWER; + } else { + set_point = MIN_IR_POWER + ((*cur_front_gain - CUTOFF_GAIN) * (MAX_IR_POWER - MIN_IR_POWER) / (SATURATE_GAIN - CUTOFF_GAIN)); + } + } else { + set_point = (set_point*1.1 > MAX_IR_POWER) ? MAX_IR_POWER : set_point*1.1; + } + return set_point; +} \ No newline at end of file diff --git a/selfdrive/visiond/models/monitoring.h b/selfdrive/visiond/models/monitoring.h new file mode 100644 index 00000000000000..4732363711d02f --- /dev/null +++ b/selfdrive/visiond/models/monitoring.h @@ -0,0 +1,49 @@ +#ifndef MONITORING_H +#define MONITORING_H + +#include "common/util.h" +#include "commonmodel.h" +#include "runners/run.h" + +#include "cereal/gen/cpp/log.capnp.h" +#include +#include "messaging.hpp" + +#ifdef __cplusplus +extern "C" { +#endif + +#define OUTPUT_SIZE_DEPRECATED 8 +#define OUTPUT_SIZE 33 + +typedef struct MonitoringResult { + float descriptor_DEPRECATED[OUTPUT_SIZE_DEPRECATED - 1]; + float std_DEPRECATED; + + float face_orientation[3]; + float face_position[2]; + float face_prob; + float left_eye_prob; + float right_eye_prob; + float left_blink_prob; + float right_blink_prob; +} MonitoringResult; + +typedef struct MonitoringState { + ModelInput in; + RunModel *m; + float output[OUTPUT_SIZE]; +} MonitoringState; + +void monitoring_init(MonitoringState* s, cl_device_id device_id, cl_context context); +MonitoringResult monitoring_eval_frame(MonitoringState* s, cl_command_queue q, cl_mem yuv_cl, int width, int height); +void monitoring_publish(PubSocket *sock, uint32_t frame_id, const MonitoringResult res, float ir_target); +void monitoring_free(MonitoringState* s); + +float ir_target_set(float *cur_front_gain, const MonitoringResult res); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/selfdrive/visiond/models/posenet.cc b/selfdrive/visiond/models/posenet.cc new file mode 100644 index 00000000000000..c843e81f4d919f --- /dev/null +++ b/selfdrive/visiond/models/posenet.cc @@ -0,0 +1,58 @@ +#include +#include +#include "posenet.h" + +void posenet_init(PosenetState *s) { + s->input = (float*)malloc(2*200*532*sizeof(float)); + s->m = new DefaultRunModel("../../models/posenet.dlc", s->output, sizeof(s->output)/sizeof(float), USE_GPU_RUNTIME); +} + +void posenet_push(PosenetState *s, uint8_t *yuv_ptr_y, int yuv_width) { + // move second frame to first frame + memmove(&s->input[0], &s->input[1], sizeof(float)*(200*532*2 - 1)); + + // fill posenet input + float a; + // posenet uses a half resolution cropped frame + // with upper left corner: [50, 237] and + // bottom right corner: [1114, 637] + // So the resulting crop is 532 X 200 + for (int y=237; y<637; y+=2) { + int yy = (y-237)/2; + for (int x = 50; x < 1114; x+=2) { + int xx = (x-50)/2; + a = 0; + a += yuv_ptr_y[yuv_width*(y+0) + (x+1)]; + a += yuv_ptr_y[yuv_width*(y+1) + (x+1)]; + a += yuv_ptr_y[yuv_width*(y+0) + (x+0)]; + a += yuv_ptr_y[yuv_width*(y+1) + (x+0)]; + // The posenet takes a normalized image input + // like the driving model so [0,255] is remapped + // to [-1,1] + s->input[(yy*532+xx)*2 + 1] = (a/512.0 - 1.0); + } + } +} + +void posenet_eval(PosenetState *s) { + s->m->execute(s->input); + + // fix stddevs + for (int i = 6; i < 12; i++) { + s->output[i] = log1p(exp(s->output[i])) + 1e-6; + } + // to radians + for (int i = 3; i < 6; i++) { + s->output[i] = M_PI * s->output[i] / 180.0; + } + // to radians + for (int i = 9; i < 12; i++) { + s->output[i] = M_PI * s->output[i] / 180.0; + } +} + +void posenet_free(PosenetState *s) { + delete s->m; + free(s->input); +} + diff --git a/selfdrive/visiond/models/posenet.h b/selfdrive/visiond/models/posenet.h new file mode 100644 index 00000000000000..2e6571a1d4b7e0 --- /dev/null +++ b/selfdrive/visiond/models/posenet.h @@ -0,0 +1,27 @@ +#ifndef POSENET_H +#define POSENET_H + +#include +#include "runners/run.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct PosenetState { + float output[12]; + float *input; + RunModel *m; +} PosenetState; + +void posenet_init(PosenetState *s); +void posenet_push(PosenetState *s, uint8_t *yuv_ptr_y, int yuv_width); +void posenet_eval(PosenetState *s); +void posenet_free(PosenetState *s); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/selfdrive/visiond/monitoring.cc b/selfdrive/visiond/monitoring.cc deleted file mode 100644 index 84ed9e8c5bb27d..00000000000000 --- a/selfdrive/visiond/monitoring.cc +++ /dev/null @@ -1,54 +0,0 @@ -#include "monitoring.h" -#include "common/mat.h" - -#define MODEL_WIDTH 320 -#define MODEL_HEIGHT 160 -extern const uint8_t monitoring_model_data[] asm("_binary_monitoring_model_dlc_start"); -extern const uint8_t monitoring_model_end[] asm("_binary_monitoring_model_dlc_end"); -const size_t monitoring_model_size = monitoring_model_end - monitoring_model_data; - - -void monitoring_init(MonitoringState* s, cl_device_id device_id, cl_context context) { - model_input_init(&s->in, MODEL_WIDTH, MODEL_HEIGHT, device_id, context); - s->m = new SNPEModel(monitoring_model_data, monitoring_model_size, (float*)&s->output, OUTPUT_SIZE); -} - -MonitoringResult monitoring_eval_frame(MonitoringState* s, cl_command_queue q, - cl_mem yuv_cl, int width, int height) { - const mat3 front_frame_from_scaled_frame = (mat3){{ - width/426.0f, 0.0, 0.0, - 0.0,height/320.0f, 0.0, - 0.0, 0.0, 1.0, - }}; - - const mat3 scaled_frame_from_cropped_frame = (mat3){{ - 1.0, 0.0, 426.0-160.0, - 0.0, 1.0, 0.0, - 0.0, 0.0, 1.0, - }}; - - const mat3 transpose = (mat3){{ - 0.0, 1.0, 0.0, - 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, - }}; - - const mat3 front_frame_from_cropped_frame = matmul3(front_frame_from_scaled_frame, scaled_frame_from_cropped_frame); - const mat3 front_frame_from_monitoring_frame = matmul3(front_frame_from_cropped_frame, transpose); - - float *net_input_buf = model_input_prepare(&s->in, q, yuv_cl, width, height, front_frame_from_monitoring_frame); - s->m->execute(net_input_buf); - - MonitoringResult ret = {0}; - memcpy(ret.vs, s->output, sizeof(ret.vs)); - ret.std = sqrtf(2.f) / s->output[6]; - - return ret; -} - - -void monitoring_free(MonitoringState* s) { - model_input_free(&s->in); - delete s->m; -} - diff --git a/selfdrive/visiond/monitoring.h b/selfdrive/visiond/monitoring.h deleted file mode 100644 index 5689e7941573b5..00000000000000 --- a/selfdrive/visiond/monitoring.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef MONITORING_H -#define MONITORING_H - -#include "commonmodel.h" -#include "snpemodel.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define OUTPUT_SIZE 7 - -typedef struct MonitoringResult { - float vs[6]; - float std; -} MonitoringResult; - -typedef struct MonitoringState { - ModelInput in; - SNPEModel *m; - float output[OUTPUT_SIZE]; -} MonitoringState; - -void monitoring_init(MonitoringState* s, cl_device_id device_id, cl_context context); -MonitoringResult monitoring_eval_frame(MonitoringState* s, cl_command_queue q, cl_mem yuv_cl, int width, int height); -void monitoring_free(MonitoringState* s); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/selfdrive/visiond/runners/run.h b/selfdrive/visiond/runners/run.h new file mode 100644 index 00000000000000..049f06584509ee --- /dev/null +++ b/selfdrive/visiond/runners/run.h @@ -0,0 +1,15 @@ +#ifndef RUN_H +#define RUN_H + +#include "runmodel.h" +#include "snpemodel.h" + +#ifdef QCOM + #define DefaultRunModel SNPEModel +#else +#define DefaultRunModel SNPEModel + /* #include "tfmodel.h" */ + /* #define DefaultRunModel TFModel */ +#endif + +#endif diff --git a/selfdrive/visiond/runners/runmodel.h b/selfdrive/visiond/runners/runmodel.h new file mode 100644 index 00000000000000..d1563a61a5e430 --- /dev/null +++ b/selfdrive/visiond/runners/runmodel.h @@ -0,0 +1,12 @@ +#ifndef RUNMODEL_H +#define RUNMODEL_H + +class RunModel { +public: + virtual void addRecurrent(float *state, int state_size) {} + virtual void addDesire(float *state, int state_size) {} + virtual void execute(float *net_input_buf) {} +}; + +#endif + diff --git a/selfdrive/visiond/runners/snpemodel.cc b/selfdrive/visiond/runners/snpemodel.cc new file mode 100644 index 00000000000000..257f203d7fd3c0 --- /dev/null +++ b/selfdrive/visiond/runners/snpemodel.cc @@ -0,0 +1,126 @@ +#include +#include +#include "common/util.h" +#include "snpemodel.h" + +void PrintErrorStringAndExit() { + const char* const errStr = zdl::DlSystem::getLastErrorString(); + std::cerr << zdl::DlSystem::getLastErrorString() << std::endl; + std::exit(EXIT_FAILURE); +} + +SNPEModel::SNPEModel(const char *path, float *output, size_t output_size, int runtime) { +#ifdef QCOM + zdl::DlSystem::Runtime_t Runtime; + if (runtime==USE_GPU_RUNTIME) { + Runtime = zdl::DlSystem::Runtime_t::GPU; + } else if (runtime==USE_DSP_RUNTIME) { + Runtime = zdl::DlSystem::Runtime_t::DSP; + } else { + Runtime = zdl::DlSystem::Runtime_t::CPU; + } + assert(zdl::SNPE::SNPEFactory::isRuntimeAvailable(Runtime)); +#endif + size_t model_size; + model_data = (uint8_t *)read_file(path, &model_size); + assert(model_data); + + // load model + std::unique_ptr container = zdl::DlContainer::IDlContainer::open(model_data, model_size); + if (!container) { PrintErrorStringAndExit(); } + printf("loaded model with size: %u\n", model_size); + + // create model runner + zdl::SNPE::SNPEBuilder snpeBuilder(container.get()); + while (!snpe) { +#ifdef QCOM + snpe = snpeBuilder.setOutputLayers({}) + .setRuntimeProcessor(Runtime) + .setUseUserSuppliedBuffers(true) + .setPerformanceProfile(zdl::DlSystem::PerformanceProfile_t::HIGH_PERFORMANCE) + .build(); +#else + snpe = snpeBuilder.setOutputLayers({}) + .setUseUserSuppliedBuffers(true) + .setPerformanceProfile(zdl::DlSystem::PerformanceProfile_t::HIGH_PERFORMANCE) + .build(); +#endif + if (!snpe) std::cerr << zdl::DlSystem::getLastErrorString() << std::endl; + } + + // get input and output names + const auto &strListi_opt = snpe->getInputTensorNames(); + if (!strListi_opt) throw std::runtime_error("Error obtaining Input tensor names"); + const auto &strListi = *strListi_opt; + //assert(strListi.size() == 1); + const char *input_tensor_name = strListi.at(0); + + const auto &strListo_opt = snpe->getOutputTensorNames(); + if (!strListo_opt) throw std::runtime_error("Error obtaining Output tensor names"); + const auto &strListo = *strListo_opt; + assert(strListo.size() == 1); + const char *output_tensor_name = strListo.at(0); + + printf("model: %s -> %s\n", input_tensor_name, output_tensor_name); + + zdl::DlSystem::UserBufferEncodingFloat userBufferEncodingFloat; + zdl::DlSystem::IUserBufferFactory& ubFactory = zdl::SNPE::SNPEFactory::getUserBufferFactory(); + + // create input buffer + { + const auto &inputDims_opt = snpe->getInputDimensions(input_tensor_name); + const zdl::DlSystem::TensorShape& bufferShape = *inputDims_opt; + std::vector strides(bufferShape.rank()); + strides[strides.size() - 1] = sizeof(float); + size_t product = 1; + for (size_t i = 0; i < bufferShape.rank(); i++) product *= bufferShape[i]; + size_t stride = strides[strides.size() - 1]; + for (size_t i = bufferShape.rank() - 1; i > 0; i--) { + stride *= bufferShape[i]; + strides[i-1] = stride; + } + printf("input product is %u\n", product); + inputBuffer = ubFactory.createUserBuffer(NULL, product*sizeof(float), strides, &userBufferEncodingFloat); + + inputMap.add(input_tensor_name, inputBuffer.get()); + } + + // create output buffer + { + std::vector outputStrides = {output_size * sizeof(float), sizeof(float)}; + outputBuffer = ubFactory.createUserBuffer(output, output_size * sizeof(float), outputStrides, &userBufferEncodingFloat); + outputMap.add(output_tensor_name, outputBuffer.get()); + } +} + +void SNPEModel::addRecurrent(float *state, int state_size) { + recurrentBuffer = this->addExtra(state, state_size, 2); +} + +void SNPEModel::addDesire(float *state, int state_size) { + desireBuffer = this->addExtra(state, state_size, 1); +} + +std::unique_ptr SNPEModel::addExtra(float *state, int state_size, int idx) { + // get input and output names + const auto &strListi_opt = snpe->getInputTensorNames(); + if (!strListi_opt) throw std::runtime_error("Error obtaining Input tensor names"); + const auto &strListi = *strListi_opt; + const char *input_tensor_name = strListi.at(idx); + printf("adding index %d: %s\n", idx, input_tensor_name); + + zdl::DlSystem::UserBufferEncodingFloat userBufferEncodingFloat; + zdl::DlSystem::IUserBufferFactory& ubFactory = zdl::SNPE::SNPEFactory::getUserBufferFactory(); + std::vector retStrides = {state_size * sizeof(float), sizeof(float)}; + auto ret = ubFactory.createUserBuffer(state, state_size * sizeof(float), retStrides, &userBufferEncodingFloat); + inputMap.add(input_tensor_name, ret.get()); + return ret; +} + +void SNPEModel::execute(float *net_input_buf) { + assert(inputBuffer->setBufferAddress(net_input_buf)); + if (!snpe->execute(inputMap, outputMap)) { + PrintErrorStringAndExit(); + } +} + diff --git a/selfdrive/visiond/runners/snpemodel.h b/selfdrive/visiond/runners/snpemodel.h new file mode 100644 index 00000000000000..f750baaf13f25e --- /dev/null +++ b/selfdrive/visiond/runners/snpemodel.h @@ -0,0 +1,51 @@ +#ifndef SNPEMODEL_H +#define SNPEMODEL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "runmodel.h" + +#define USE_CPU_RUNTIME 0 +#define USE_GPU_RUNTIME 1 +#define USE_DSP_RUNTIME 2 + +class SNPEModel : public RunModel { +public: + SNPEModel(const char *path, float *output, size_t output_size, int runtime); + ~SNPEModel() { + if (model_data) free(model_data); + } + void addRecurrent(float *state, int state_size); + void addDesire(float *state, int state_size); + void execute(float *net_input_buf); +private: + uint8_t *model_data = NULL; + + // snpe model stuff + std::unique_ptr snpe; + + // snpe input stuff + zdl::DlSystem::UserBufferMap inputMap; + std::unique_ptr inputBuffer; + + // snpe output stuff + zdl::DlSystem::UserBufferMap outputMap; + std::unique_ptr outputBuffer; + float *output; + + // recurrent and desire + std::unique_ptr addExtra(float *state, int state_size, int idx); + std::unique_ptr recurrentBuffer; + std::unique_ptr desireBuffer; +}; + +#endif + diff --git a/selfdrive/visiond/snapshot/Makefile b/selfdrive/visiond/snapshot/Makefile new file mode 100644 index 00000000000000..6edde2f822ad74 --- /dev/null +++ b/selfdrive/visiond/snapshot/Makefile @@ -0,0 +1,32 @@ +CC = clang +CXX = clang++ + +WARN_FLAGS = -Werror=implicit-function-declaration \ + -Werror=incompatible-pointer-types \ + -Werror=int-conversion \ + -Werror=return-type \ + -Werror=format-extra-args + +CFLAGS = -std=gnu11 -g -fPIC -O2 $(WARN_FLAGS) + +.PHONY: all +all: libvisionipc.so + +visionipc.o: ../../common/visionipc.c ../../common/visionipc.h + @echo "[ CC ] $@" + $(CC) $(CFLAGS) -MMD \ + -I../.. -I../../.. \ + -c -o '$@' ../../common/visionipc.c + +ipc.o: ../../common/ipc.c ../../common/ipc.h + @echo "[ CC ] $@" + $(CC) $(CFLAGS) -MMD \ + -I../.. -I../../.. \ + -c -o '$@' ../../common/ipc.c + +libvisionipc.so: visionipc.o ipc.o + $(CC) -shared -fPIC -o '$@' visionipc.o ipc.o + +.PHONY: clean +clean: + rm visionipc.o ipc.o libvisionipc.so diff --git a/selfdrive/visiond/snapshot/__init__.py b/selfdrive/visiond/snapshot/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/selfdrive/visiond/snapshot/snapshot.py b/selfdrive/visiond/snapshot/snapshot.py new file mode 100755 index 00000000000000..affc635b81d5f0 --- /dev/null +++ b/selfdrive/visiond/snapshot/snapshot.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +import os +import subprocess +from PIL import Image +from common.params import Params +import time +import signal + +from selfdrive.visiond.snapshot.visionipc import VisionIPC + +def jpeg_write(fn, dat): + img = Image.fromarray(dat) + img.save(fn, "JPEG") + +def snapshot(): + # note: super sketch race condition if you start the car at the same time at this + # TODO: lock car starting? + ps = subprocess.Popen("ps | grep visiond", shell=True, stdout=subprocess.PIPE) + ret = list(filter(lambda x: 'grep ' not in x, ps.communicate()[0].decode('utf-8').strip().split("\n"))) + if len(ret) > 0: + return None + + front_camera_allowed = int(Params().get("RecordFront")) + + proc = subprocess.Popen(os.path.join(os.getenv("HOME"), "one/selfdrive/visiond/start.py"), cwd=os.path.join(os.getenv("HOME"), "one/selfdrive/visiond")) + time.sleep(6.0) + + ret = None + try: + ipc = VisionIPC() + pic = ipc.get() + del ipc + + if front_camera_allowed: + ipc_front = VisionIPC(front=True) + fpic = ipc_front.get() + del ipc_front + else: + fpic = None + + ret = pic, fpic + finally: + proc.send_signal(signal.SIGINT) + proc.communicate() + + return ret + +if __name__ == "__main__": + pic, fpic = snapshot() + jpeg_write("/tmp/back.jpg", pic) + jpeg_write("/tmp/front.jpg", fpic) + diff --git a/selfdrive/visiond/snapshot/visionipc.py b/selfdrive/visiond/snapshot/visionipc.py new file mode 100644 index 00000000000000..1129025081948e --- /dev/null +++ b/selfdrive/visiond/snapshot/visionipc.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +import os +import subprocess +from cffi import FFI + +import numpy as np + +gf_dir = os.path.dirname(os.path.abspath(__file__)) + +subprocess.check_call(["make"], cwd=gf_dir) + +ffi = FFI() +ffi.cdef(""" + +typedef enum VisionStreamType { + VISION_STREAM_RGB_BACK, + VISION_STREAM_RGB_FRONT, + VISION_STREAM_YUV, + VISION_STREAM_YUV_FRONT, + VISION_STREAM_MAX, +} VisionStreamType; + +typedef struct VisionUIInfo { + int big_box_x, big_box_y; + int big_box_width, big_box_height; + int transformed_width, transformed_height; + + int front_box_x, front_box_y; + int front_box_width, front_box_height; +} VisionUIInfo; + +typedef struct VisionStreamBufs { + VisionStreamType type; + + int width, height, stride; + size_t buf_len; + + union { + VisionUIInfo ui_info; + } buf_info; +} VisionStreamBufs; + +typedef struct VIPCBuf { + int fd; + size_t len; + void* addr; +} VIPCBuf; + +typedef struct VIPCBufExtra { + // only for yuv + uint32_t frame_id; + uint64_t timestamp_eof; +} VIPCBufExtra; + +typedef struct VisionStream { + int ipc_fd; + int last_idx; + int last_type; + int num_bufs; + VisionStreamBufs bufs_info; + VIPCBuf *bufs; +} VisionStream; + +int visionstream_init(VisionStream *s, VisionStreamType type, bool tbuffer, VisionStreamBufs *out_bufs_info); +VIPCBuf* visionstream_get(VisionStream *s, VIPCBufExtra *out_extra); +void visionstream_destroy(VisionStream *s); + +""" +) + +class VisionIPC(): + def __init__(self, front=False): + self.clib = ffi.dlopen(os.path.join(gf_dir, "libvisionipc.so")) + + self.s = ffi.new("VisionStream*") + self.buf_info = ffi.new("VisionStreamBufs*") + + err = self.clib.visionstream_init(self.s, self.clib.VISION_STREAM_RGB_FRONT if front else self.clib.VISION_STREAM_RGB_BACK, True, self.buf_info) + assert err == 0 + + def get(self): + buf = self.clib.visionstream_get(self.s, ffi.NULL) + pbuf = ffi.buffer(buf.addr, buf.len) + ret = np.frombuffer(pbuf, dtype=np.uint8).reshape((-1, self.buf_info.stride//3, 3)) + return ret[:self.buf_info.height, :self.buf_info.width, [2,1,0]] + diff --git a/selfdrive/visiond/snpemodel.cc b/selfdrive/visiond/snpemodel.cc deleted file mode 100644 index ae7b7f10a1531e..00000000000000 --- a/selfdrive/visiond/snpemodel.cc +++ /dev/null @@ -1,94 +0,0 @@ -#include "snpemodel.h" - -void PrintErrorStringAndExit() { - const char* const errStr = zdl::DlSystem::getLastErrorString(); - std::cerr << zdl::DlSystem::getLastErrorString() << std::endl; - std::exit(EXIT_FAILURE); -} - -SNPEModel::SNPEModel(const uint8_t *model_data, const size_t model_size, float *output, size_t output_size) { - assert(zdl::SNPE::SNPEFactory::isRuntimeAvailable(zdl::DlSystem::Runtime_t::GPU)); - - // load model - std::unique_ptr container = zdl::DlContainer::IDlContainer::open(model_data, model_size); - if (!container) { PrintErrorStringAndExit(); } - printf("loaded model with size: %d\n", model_size); - - // create model runner - zdl::SNPE::SNPEBuilder snpeBuilder(container.get()); - while (!snpe) { - snpe = snpeBuilder.setOutputLayers({}) - .setRuntimeProcessor(zdl::DlSystem::Runtime_t::GPU) - .setUseUserSuppliedBuffers(true) - .setPerformanceProfile(zdl::DlSystem::PerformanceProfile_t::HIGH_PERFORMANCE) - .build(); - if (!snpe) std::cerr << zdl::DlSystem::getLastErrorString() << std::endl; - } - - // get input and output names - const auto &strListi_opt = snpe->getInputTensorNames(); - if (!strListi_opt) throw std::runtime_error("Error obtaining Input tensor names"); - const auto &strListi = *strListi_opt; - //assert(strListi.size() == 1); - const char *input_tensor_name = strListi.at(0); - - const auto &strListo_opt = snpe->getOutputTensorNames(); - if (!strListo_opt) throw std::runtime_error("Error obtaining Output tensor names"); - const auto &strListo = *strListo_opt; - assert(strListo.size() == 1); - const char *output_tensor_name = strListo.at(0); - - printf("model: %s -> %s\n", input_tensor_name, output_tensor_name); - - zdl::DlSystem::UserBufferEncodingFloat userBufferEncodingFloat; - zdl::DlSystem::IUserBufferFactory& ubFactory = zdl::SNPE::SNPEFactory::getUserBufferFactory(); - - // create input buffer - { - const auto &inputDims_opt = snpe->getInputDimensions(input_tensor_name); - const zdl::DlSystem::TensorShape& bufferShape = *inputDims_opt; - std::vector strides(bufferShape.rank()); - strides[strides.size() - 1] = sizeof(float); - size_t product = 1; - for (size_t i = 0; i < bufferShape.rank(); i++) product *= bufferShape[i]; - size_t stride = strides[strides.size() - 1]; - for (size_t i = bufferShape.rank() - 1; i > 0; i--) { - stride *= bufferShape[i]; - strides[i-1] = stride; - } - printf("input product is %u\n", product); - inputBuffer = ubFactory.createUserBuffer(NULL, product*sizeof(float), strides, &userBufferEncodingFloat); - - inputMap.add(input_tensor_name, inputBuffer.get()); - } - - // create output buffer - { - std::vector outputStrides = {output_size * sizeof(float), sizeof(float)}; - outputBuffer = ubFactory.createUserBuffer(output, output_size * sizeof(float), outputStrides, &userBufferEncodingFloat); - outputMap.add(output_tensor_name, outputBuffer.get()); - } -} - -void SNPEModel::addRecurrent(float *state, int state_size) { - // get input and output names - const auto &strListi_opt = snpe->getInputTensorNames(); - if (!strListi_opt) throw std::runtime_error("Error obtaining Input tensor names"); - const auto &strListi = *strListi_opt; - const char *input_tensor_name = strListi.at(1); - printf("adding recurrent: %s\n", input_tensor_name); - - zdl::DlSystem::UserBufferEncodingFloat userBufferEncodingFloat; - zdl::DlSystem::IUserBufferFactory& ubFactory = zdl::SNPE::SNPEFactory::getUserBufferFactory(); - std::vector recurrentStrides = {state_size * sizeof(float), sizeof(float)}; - recurrentBuffer = ubFactory.createUserBuffer(state, state_size * sizeof(float), recurrentStrides, &userBufferEncodingFloat); - inputMap.add(input_tensor_name, recurrentBuffer.get()); -} - -void SNPEModel::execute(float *net_input_buf) { - assert(inputBuffer->setBufferAddress(net_input_buf)); - if (!snpe->execute(inputMap, outputMap)) { - PrintErrorStringAndExit(); - } -} - diff --git a/selfdrive/visiond/snpemodel.h b/selfdrive/visiond/snpemodel.h deleted file mode 100644 index a7fc6083db3541..00000000000000 --- a/selfdrive/visiond/snpemodel.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SNPEMODEL_H -#define SNPEMODEL_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class SNPEModel { -public: - SNPEModel(const uint8_t *model_data, const size_t model_size, float *output, size_t output_size); - void addRecurrent(float *state, int state_size); - void execute(float *net_input_buf); -private: - // snpe model stuff - std::unique_ptr snpe; - - // snpe input stuff - zdl::DlSystem::UserBufferMap inputMap; - std::unique_ptr inputBuffer; - - // snpe output stuff - zdl::DlSystem::UserBufferMap outputMap; - std::unique_ptr outputBuffer; - float *output; - - // recurrent - std::unique_ptr recurrentBuffer; -}; - -#endif - diff --git a/selfdrive/visiond/start.py b/selfdrive/visiond/start.py new file mode 100755 index 00000000000000..5556ac2997e17f --- /dev/null +++ b/selfdrive/visiond/start.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 +import os + +assert os.system("make") == 0 +from common.basedir import BASEDIR + +os.environ["ADSP_LIBRARY_PATH"] = os.path.join(BASEDIR, "selfdrive/visiond/dsp") +os.execv("./visiond", ["visiond"]) diff --git a/selfdrive/visiond/loadyuv.c b/selfdrive/visiond/transforms/loadyuv.c similarity index 96% rename from selfdrive/visiond/loadyuv.c rename to selfdrive/visiond/transforms/loadyuv.c index 2b50fb9d2a4105..2518145100a827 100644 --- a/selfdrive/visiond/loadyuv.c +++ b/selfdrive/visiond/transforms/loadyuv.c @@ -17,7 +17,7 @@ void loadyuv_init(LoadYUVState* s, cl_context ctx, cl_device_id device_id, int w "-cl-fast-relaxed-math -cl-denorms-are-zero " "-DTRANSFORMED_WIDTH=%d -DTRANSFORMED_HEIGHT=%d", width, height); - cl_program prg = CLU_LOAD_FROM_FILE(ctx, device_id, "loadyuv.cl", args); + cl_program prg = CLU_LOAD_FROM_FILE(ctx, device_id, "transforms/loadyuv.cl", args); s->loadys_krnl = clCreateKernel(prg, "loadys", &err); assert(err == 0); diff --git a/selfdrive/visiond/loadyuv.cl b/selfdrive/visiond/transforms/loadyuv.cl similarity index 100% rename from selfdrive/visiond/loadyuv.cl rename to selfdrive/visiond/transforms/loadyuv.cl diff --git a/selfdrive/visiond/loadyuv.h b/selfdrive/visiond/transforms/loadyuv.h similarity index 100% rename from selfdrive/visiond/loadyuv.h rename to selfdrive/visiond/transforms/loadyuv.h diff --git a/selfdrive/visiond/transforms/rgb_to_yuv.c b/selfdrive/visiond/transforms/rgb_to_yuv.c new file mode 100644 index 00000000000000..2626e6eebe765f --- /dev/null +++ b/selfdrive/visiond/transforms/rgb_to_yuv.c @@ -0,0 +1,53 @@ +#include +#include + +#include "clutil.h" + +#include "rgb_to_yuv.h" + +void rgb_to_yuv_init(RGBToYUVState* s, cl_context ctx, cl_device_id device_id, int width, int height, int rgb_stride) { + int err = 0; + memset(s, 0, sizeof(*s)); + assert(width % 2 == 0); + assert(height % 2 == 0); + s->width = width; + s->height = height; + char args[1024]; + snprintf(args, sizeof(args), + "-cl-fast-relaxed-math -cl-denorms-are-zero " +#ifdef CL_DEBUG + "-DCL_DEBUG " +#endif + "-DWIDTH=%d -DHEIGHT=%d -DUV_WIDTH=%d -DUV_HEIGHT=%d -DRGB_STRIDE=%d -DRGB_SIZE=%d", + width, height, width/ 2, height / 2, rgb_stride, width * height); + cl_program prg = CLU_LOAD_FROM_FILE(ctx, device_id, "transforms/rgb_to_yuv.cl", args); + + s->rgb_to_yuv_krnl = clCreateKernel(prg, "rgb_to_yuv", &err); + assert(err == 0); + // done with this + err = clReleaseProgram(prg); + assert(err == 0); +} + +void rgb_to_yuv_destroy(RGBToYUVState* s) { + int err = 0; + err = clReleaseKernel(s->rgb_to_yuv_krnl); + assert(err == 0); +} + +void rgb_to_yuv_queue(RGBToYUVState* s, cl_command_queue q, cl_mem rgb_cl, cl_mem yuv_cl) { + int err = 0; + err = clSetKernelArg(s->rgb_to_yuv_krnl, 0, sizeof(cl_mem), &rgb_cl); + assert(err == 0); + err = clSetKernelArg(s->rgb_to_yuv_krnl, 1, sizeof(cl_mem), &yuv_cl); + assert(err == 0); + const size_t work_size[2] = { + (size_t)(s->width + (s->width % 4 == 0 ? 0 : (4 - s->width % 4))) / 4, + (size_t)(s->height + (s->height % 4 == 0 ? 0 : (4 - s->height % 4))) / 4 + }; + cl_event event; + err = clEnqueueNDRangeKernel(q, s->rgb_to_yuv_krnl, 2, NULL, &work_size[0], NULL, 0, 0, &event); + assert(err == 0); + clWaitForEvents(1, &event); + clReleaseEvent(event); +} diff --git a/selfdrive/visiond/transforms/rgb_to_yuv.cl b/selfdrive/visiond/transforms/rgb_to_yuv.cl new file mode 100644 index 00000000000000..60dbdb4d5e3849 --- /dev/null +++ b/selfdrive/visiond/transforms/rgb_to_yuv.cl @@ -0,0 +1,127 @@ +#define RGB_TO_Y(r, g, b) ((((mul24(b, 13) + mul24(g, 65) + mul24(r, 33)) + 64) >> 7) + 16) +#define RGB_TO_U(r, g, b) ((mul24(b, 56) - mul24(g, 37) - mul24(r, 19) + 0x8080) >> 8) +#define RGB_TO_V(r, g, b) ((mul24(r, 56) - mul24(g, 47) - mul24(b, 9) + 0x8080) >> 8) +#define AVERAGE(x, y, z, w) ((convert_ushort(x) + convert_ushort(y) + convert_ushort(z) + convert_ushort(w) + 1) >> 1) + +inline void convert_2_ys(__global uchar * out_yuv, int yi, const uchar8 rgbs1) { + uchar2 yy = (uchar2)( + RGB_TO_Y(rgbs1.s2, rgbs1.s1, rgbs1.s0), + RGB_TO_Y(rgbs1.s5, rgbs1.s4, rgbs1.s3) + ); +#ifdef CL_DEBUG + if(yi >= RGB_SIZE) + printf("Y vector2 overflow, %d > %d\n", yi, RGB_SIZE); +#endif + vstore2(yy, 0, out_yuv + yi); +} + +inline void convert_4_ys(__global uchar * out_yuv, int yi, const uchar8 rgbs1, const uchar8 rgbs3) { + const uchar4 yy = (uchar4)( + RGB_TO_Y(rgbs1.s2, rgbs1.s1, rgbs1.s0), + RGB_TO_Y(rgbs1.s5, rgbs1.s4, rgbs1.s3), + RGB_TO_Y(rgbs3.s0, rgbs1.s7, rgbs1.s6), + RGB_TO_Y(rgbs3.s3, rgbs3.s2, rgbs3.s1) + ); +#ifdef CL_DEBUG + if(yi > RGB_SIZE - 4) + printf("Y vector4 overflow, %d > %d\n", yi, RGB_SIZE - 4); +#endif + vstore4(yy, 0, out_yuv + yi); +} + +inline void convert_uv(__global uchar * out_yuv, int ui, int vi, + const uchar8 rgbs1, const uchar8 rgbs2) { + // U & V: average of 2x2 pixels square + const short ab = AVERAGE(rgbs1.s0, rgbs1.s3, rgbs2.s0, rgbs2.s3); + const short ag = AVERAGE(rgbs1.s1, rgbs1.s4, rgbs2.s1, rgbs2.s4); + const short ar = AVERAGE(rgbs1.s2, rgbs1.s5, rgbs2.s2, rgbs2.s5); +#ifdef CL_DEBUG + if(ui >= RGB_SIZE + RGB_SIZE / 4) + printf("U overflow, %d >= %d\n", ui, RGB_SIZE + RGB_SIZE / 4); + if(vi >= RGB_SIZE + RGB_SIZE / 2) + printf("V overflow, %d >= %d\n", vi, RGB_SIZE + RGB_SIZE / 2); +#endif + out_yuv[ui] = RGB_TO_U(ar, ag, ab); + out_yuv[vi] = RGB_TO_V(ar, ag, ab); +} + +inline void convert_2_uvs(__global uchar * out_yuv, int ui, int vi, + const uchar8 rgbs1, const uchar8 rgbs2, const uchar8 rgbs3, const uchar8 rgbs4) { + // U & V: average of 2x2 pixels square + const short ab1 = AVERAGE(rgbs1.s0, rgbs1.s3, rgbs2.s0, rgbs2.s3); + const short ag1 = AVERAGE(rgbs1.s1, rgbs1.s4, rgbs2.s1, rgbs2.s4); + const short ar1 = AVERAGE(rgbs1.s2, rgbs1.s5, rgbs2.s2, rgbs2.s5); + const short ab2 = AVERAGE(rgbs1.s6, rgbs3.s1, rgbs2.s6, rgbs4.s1); + const short ag2 = AVERAGE(rgbs1.s7, rgbs3.s2, rgbs2.s7, rgbs4.s2); + const short ar2 = AVERAGE(rgbs3.s0, rgbs3.s3, rgbs4.s0, rgbs4.s3); + uchar2 u2 = (uchar2)( + RGB_TO_U(ar1, ag1, ab1), + RGB_TO_U(ar2, ag2, ab2) + ); + uchar2 v2 = (uchar2)( + RGB_TO_V(ar1, ag1, ab1), + RGB_TO_V(ar2, ag2, ab2) + ); +#ifdef CL_DEBUG1 + if(ui > RGB_SIZE + RGB_SIZE / 4 - 2) + printf("U 2 overflow, %d >= %d\n", ui, RGB_SIZE + RGB_SIZE / 4 - 2); + if(vi > RGB_SIZE + RGB_SIZE / 2 - 2) + printf("V 2 overflow, %d >= %d\n", vi, RGB_SIZE + RGB_SIZE / 2 - 2); +#endif + vstore2(u2, 0, out_yuv + ui); + vstore2(v2, 0, out_yuv + vi); +} + +__kernel void rgb_to_yuv(__global uchar const * const rgb, + __global uchar * out_yuv) +{ + const int dx = get_global_id(0); + const int dy = get_global_id(1); + const int col = mul24(dx, 4); // Current column in rgb image + const int row = mul24(dy, 4); // Current row in rgb image + const int bgri_start = mad24(row, RGB_STRIDE, mul24(col, 3)); // Start offset of rgb data being converted + const int yi_start = mad24(row, WIDTH, col); // Start offset in the target yuv buffer + int ui = mad24(row / 2, UV_WIDTH, RGB_SIZE + col / 2); + int vi = mad24(row / 2 , UV_WIDTH, RGB_SIZE + UV_WIDTH * UV_HEIGHT + col / 2); + int num_col = min(WIDTH - col, 4); + int num_row = min(HEIGHT - row, 4); + if(num_row == 4) { + const uchar8 rgbs0_0 = vload8(0, rgb + bgri_start); + const uchar8 rgbs0_1 = vload8(0, rgb + bgri_start + 8); + const uchar8 rgbs1_0 = vload8(0, rgb + bgri_start + RGB_STRIDE); + const uchar8 rgbs1_1 = vload8(0, rgb + bgri_start + RGB_STRIDE + 8); + const uchar8 rgbs2_0 = vload8(0, rgb + bgri_start + RGB_STRIDE * 2); + const uchar8 rgbs2_1 = vload8(0, rgb + bgri_start + RGB_STRIDE * 2 + 8); + const uchar8 rgbs3_0 = vload8(0, rgb + bgri_start + RGB_STRIDE * 3); + const uchar8 rgbs3_1 = vload8(0, rgb + bgri_start + RGB_STRIDE * 3 + 8); + if(num_col == 4) { + convert_4_ys(out_yuv, yi_start, rgbs0_0, rgbs0_1); + convert_4_ys(out_yuv, yi_start + WIDTH, rgbs1_0, rgbs1_1); + convert_4_ys(out_yuv, yi_start + WIDTH * 2, rgbs2_0, rgbs2_1); + convert_4_ys(out_yuv, yi_start + WIDTH * 3, rgbs3_0, rgbs3_1); + convert_2_uvs(out_yuv, ui, vi, rgbs0_0, rgbs1_0, rgbs0_1, rgbs1_1); + convert_2_uvs(out_yuv, ui + UV_WIDTH, vi + UV_WIDTH, rgbs2_0, rgbs3_0, rgbs2_1, rgbs3_1); + } else if(num_col == 2) { + convert_2_ys(out_yuv, yi_start, rgbs0_0); + convert_2_ys(out_yuv, yi_start + WIDTH, rgbs1_0); + convert_2_ys(out_yuv, yi_start + WIDTH * 2, rgbs2_0); + convert_2_ys(out_yuv, yi_start + WIDTH * 3, rgbs3_0); + convert_uv(out_yuv, ui, vi, rgbs0_0, rgbs1_0); + convert_uv(out_yuv, ui + UV_WIDTH, vi + UV_WIDTH, rgbs2_0, rgbs3_0); + } + } else { + const uchar8 rgbs0_0 = vload8(0, rgb + bgri_start); + const uchar8 rgbs0_1 = vload8(0, rgb + bgri_start + 8); + const uchar8 rgbs1_0 = vload8(0, rgb + bgri_start + RGB_STRIDE); + const uchar8 rgbs1_1 = vload8(0, rgb + bgri_start + RGB_STRIDE + 8); + if(num_col == 4) { + convert_4_ys(out_yuv, yi_start, rgbs0_0, rgbs0_1); + convert_4_ys(out_yuv, yi_start + WIDTH, rgbs1_0, rgbs1_1); + convert_2_uvs(out_yuv, ui, vi, rgbs0_0, rgbs1_0, rgbs0_1, rgbs1_1); + } else if(num_col == 2) { + convert_2_ys(out_yuv, yi_start, rgbs0_0); + convert_2_ys(out_yuv, yi_start + WIDTH, rgbs1_0); + convert_uv(out_yuv, ui, vi, rgbs0_0, rgbs1_0); + } + } +} diff --git a/selfdrive/visiond/transforms/rgb_to_yuv.h b/selfdrive/visiond/transforms/rgb_to_yuv.h new file mode 100644 index 00000000000000..79895803456d69 --- /dev/null +++ b/selfdrive/visiond/transforms/rgb_to_yuv.h @@ -0,0 +1,32 @@ +#ifndef RGB_TO_YUV_H +#define RGB_TO_YUV_H + +#include +#include + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int width, height; + cl_kernel rgb_to_yuv_krnl; +} RGBToYUVState; + +void rgb_to_yuv_init(RGBToYUVState* s, cl_context ctx, cl_device_id device_id, int width, int height, int rgb_stride); + +void rgb_to_yuv_destroy(RGBToYUVState* s); + +void rgb_to_yuv_queue(RGBToYUVState* s, cl_command_queue q, cl_mem rgb_cl, cl_mem yuv_cl); + +#ifdef __cplusplus +} +#endif + +#endif // RGB_TO_YUV_H diff --git a/selfdrive/visiond/transforms/rgb_to_yuv_test.cc b/selfdrive/visiond/transforms/rgb_to_yuv_test.cc new file mode 100644 index 00000000000000..c8b87510586d5e --- /dev/null +++ b/selfdrive/visiond/transforms/rgb_to_yuv_test.cc @@ -0,0 +1,201 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef ANDROID + +#define MAXE 0 +#include + +#else +// The libyuv implementation on ARM is slightly different than on x86 +// Our implementation matches the ARM version, so accept errors of 1 +#define MAXE 1 + +#endif + +#include + +#include + +#include "clutil.h" +#include "rgb_to_yuv.h" + + +static inline double millis_since_boot() { + struct timespec t; + clock_gettime(CLOCK_BOOTTIME, &t); + return t.tv_sec * 1000.0 + t.tv_nsec * 1e-6; +} + +void cl_init(cl_device_id &device_id, cl_context &context) { + int err; + cl_platform_id platform_id = NULL; + cl_uint num_devices; + cl_uint num_platforms; + + err = clGetPlatformIDs(1, &platform_id, &num_platforms); + err = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_DEFAULT, 1, + &device_id, &num_devices); + cl_print_info(platform_id, device_id); + context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &err); +} + + +bool compare_results(uint8_t *a, uint8_t *b, int len, int stride, int width, int height, uint8_t *rgb) { + int min_diff = 0., max_diff = 0., max_e = 0.; + int e1 = 0, e0 = 0; + int e0y = 0, e0u = 0, e0v = 0, e1y = 0, e1u = 0, e1v = 0; + int max_e_i = 0; + for (int i = 0;i < len;i++) { + int e = ((int)a[i]) - ((int)b[i]); + if(e < min_diff) { + min_diff = e; + } + if(e > max_diff) { + max_diff = e; + } + int e_abs = std::abs(e); + if(e_abs > max_e) { + max_e = e_abs; + max_e_i = i; + } + if(e_abs < 1) { + e0++; + if(i < stride * height) + e0y++; + else if(i < stride * height + stride * height / 4) + e0u++; + else + e0v++; + } else { + e1++; + if(i < stride * height) + e1y++; + else if(i < stride * height + stride * height / 4) + e1u++; + else + e1v++; + } + } + //printf("max diff : %d, min diff : %d, e < 1: %d, e >= 1: %d\n", max_diff, min_diff, e0, e1); + //printf("Y: e < 1: %d, e >= 1: %d, U: e < 1: %d, e >= 1: %d, V: e < 1: %d, e >= 1: %d\n", e0y, e1y, e0u, e1u, e0v, e1v); + if(max_e <= MAXE) { + return true; + } + int row = max_e_i / stride; + if(row < height) { + printf("max error is Y: %d = (libyuv: %u - cl: %u), row: %d, col: %d\n", max_e, a[max_e_i], b[max_e_i], row, max_e_i % stride); + } else if(row >= height && row < (height + height / 4)) { + printf("max error is U: %d = %u - %u, row: %d, col: %d\n", max_e, a[max_e_i], b[max_e_i], (row - height) / 2, max_e_i % stride / 2); + } else { + printf("max error is V: %d = %u - %u, row: %d, col: %d\n", max_e, a[max_e_i], b[max_e_i], (row - height - height / 4) / 2, max_e_i % stride / 2); + } + return false; +} + +int main(int argc, char** argv) { + srand(1337); + + clu_init(); + cl_device_id device_id; + cl_context context; + cl_init(device_id, context) ; + + int err; + const cl_queue_properties props[] = {0}; //CL_QUEUE_PRIORITY_KHR, CL_QUEUE_PRIORITY_HIGH_KHR, 0}; + cl_command_queue q = clCreateCommandQueueWithProperties(context, device_id, props, &err); + if(err != 0) { + std::cout << "clCreateCommandQueueWithProperties error: " << err << std::endl; + } + + int width = 1164; + int height = 874; + + int opt = 0; + while ((opt = getopt(argc, argv, "f")) != -1) + { + switch (opt) + { + case 'f': + std::cout << "Using front camera dimensions" << std::endl; + int width = 1152; + int height = 846; + } + } + + std::cout << "Width: " << width << " Height: " << height << std::endl; + uint8_t *rgb_frame = new uint8_t[width * height * 3]; + + + RGBToYUVState rgb_to_yuv_state; + rgb_to_yuv_init(&rgb_to_yuv_state, context, device_id, width, height, width * 3); + + int frame_yuv_buf_size = width * height * 3 / 2; + cl_mem yuv_cl = clCreateBuffer(context, CL_MEM_READ_WRITE, frame_yuv_buf_size, (void*)NULL, &err); + uint8_t *frame_yuv_buf = new uint8_t[frame_yuv_buf_size]; + uint8_t *frame_yuv_ptr_y = frame_yuv_buf; + uint8_t *frame_yuv_ptr_u = frame_yuv_buf + (width * height); + uint8_t *frame_yuv_ptr_v = frame_yuv_ptr_u + ((width/2) * (height/2)); + + cl_mem rgb_cl = clCreateBuffer(context, CL_MEM_READ_WRITE, width * height * 3, (void*)NULL, &err); + int mismatched = 0; + int counter = 0; + srand (time(NULL)); + + for (int i = 0; i < 100; i++){ + for (int i = 0; i < width * height * 3; i++){ + rgb_frame[i] = (uint8_t)rand(); + } + + double t1 = millis_since_boot(); + libyuv::RGB24ToI420((uint8_t*)rgb_frame, width * 3, + frame_yuv_ptr_y, width, + frame_yuv_ptr_u, width/2, + frame_yuv_ptr_v, width/2, + width, height); + double t2 = millis_since_boot(); + //printf("Libyuv: rgb to yuv: %.2fms\n", t2-t1); + + clEnqueueWriteBuffer(q, rgb_cl, CL_TRUE, 0, width * height * 3, (void *)rgb_frame, 0, NULL, NULL); + t1 = millis_since_boot(); + rgb_to_yuv_queue(&rgb_to_yuv_state, q, rgb_cl, yuv_cl); + t2 = millis_since_boot(); + + //printf("OpenCL: rgb to yuv: %.2fms\n", t2-t1); + uint8_t *yyy = (uint8_t *)clEnqueueMapBuffer(q, yuv_cl, CL_TRUE, + CL_MAP_READ, 0, frame_yuv_buf_size, + 0, NULL, NULL, &err); + if(!compare_results(frame_yuv_ptr_y, yyy, frame_yuv_buf_size, width, width, height, (uint8_t*)rgb_frame)) + mismatched++; + clEnqueueUnmapMemObject(q, yuv_cl, yyy, 0, NULL, NULL); + + // std::this_thread::sleep_for(std::chrono::milliseconds(20)); + if(counter++ % 100 == 0) + printf("Matched: %d, Mismatched: %d\n", counter - mismatched, mismatched); + + } + printf("Matched: %d, Mismatched: %d\n", counter - mismatched, mismatched); + + delete[] frame_yuv_buf; + rgb_to_yuv_destroy(&rgb_to_yuv_state); + clReleaseContext(context); + delete[] rgb_frame; + + if (mismatched == 0) + return 0; + else + return -1; +} diff --git a/selfdrive/visiond/transform.c b/selfdrive/visiond/transforms/transform.c similarity index 99% rename from selfdrive/visiond/transform.c rename to selfdrive/visiond/transforms/transform.c index 5f3d7ad5a11c95..0b4150ddb27268 100644 --- a/selfdrive/visiond/transform.c +++ b/selfdrive/visiond/transforms/transform.c @@ -9,7 +9,7 @@ void transform_init(Transform* s, cl_context ctx, cl_device_id device_id) { int err = 0; memset(s, 0, sizeof(*s)); - cl_program prg = CLU_LOAD_FROM_FILE(ctx, device_id, "transform.cl", ""); + cl_program prg = CLU_LOAD_FROM_FILE(ctx, device_id, "transforms/transform.cl", ""); s->krnl = clCreateKernel(prg, "warpPerspective", &err); assert(err == 0); diff --git a/selfdrive/visiond/transform.cl b/selfdrive/visiond/transforms/transform.cl similarity index 100% rename from selfdrive/visiond/transform.cl rename to selfdrive/visiond/transforms/transform.cl diff --git a/selfdrive/visiond/transform.h b/selfdrive/visiond/transforms/transform.h similarity index 100% rename from selfdrive/visiond/transform.h rename to selfdrive/visiond/transforms/transform.h diff --git a/selfdrive/visiond/visiond.cc b/selfdrive/visiond/visiond.cc index af10d760c132e8..31546f956d43de 100644 --- a/selfdrive/visiond/visiond.cc +++ b/selfdrive/visiond/visiond.cc @@ -24,6 +24,13 @@ #include #include #include +#include + +#ifdef QCOM +#include +#else +#include +#endif #include "common/version.h" #include "common/util.h" @@ -39,13 +46,20 @@ #include "bufs.h" #ifdef QCOM -#include "camera_qcom.h" +#include "cameras/camera_qcom.h" #else -#include "camera_fake.h" +#include "cameras/camera_frame_stream.h" #endif -#include "model.h" -#include "monitoring.h" +#include "messaging.hpp" + + +// 3 models +#include "models/driving.h" +#include "models/monitoring.h" +#include "models/posenet.h" + +#include "transforms/rgb_to_yuv.h" #include "cereal/gen/cpp/log.capnp.h" @@ -53,7 +67,7 @@ #define UI_BUF_COUNT 4 -//#define DUMP_RGB +// #define DUMP_RGB //#define DEBUG_DRIVER_MONITOR @@ -68,7 +82,7 @@ typedef void (*sighandler_t) (int); #endif extern "C" { -volatile int do_exit = 0; +volatile sig_atomic_t do_exit = 0; } namespace { @@ -122,6 +136,7 @@ struct VisionState { FrameMetadata yuv_metas[YUV_COUNT]; size_t yuv_buf_size; int yuv_width, yuv_height; + RGBToYUVState rgb_to_yuv_state; // for front camera recording Pool yuv_front_pool; @@ -131,6 +146,7 @@ struct VisionState { FrameMetadata yuv_front_metas[YUV_COUNT]; size_t yuv_front_buf_size; int yuv_front_width, yuv_front_height; + RGBToYUVState front_rgb_to_yuv_state; size_t rgb_buf_size; int rgb_width, rgb_height, rgb_stride; @@ -141,13 +157,16 @@ struct VisionState { int rgb_front_width, rgb_front_height, rgb_front_stride; VisionBuf rgb_front_bufs[UI_BUF_COUNT]; cl_mem rgb_front_bufs_cl[UI_BUF_COUNT]; + int front_meteringbox_xmin, front_meteringbox_xmax; + int front_meteringbox_ymin, front_meteringbox_ymax; ModelState model; ModelData model_bufs[UI_BUF_COUNT]; MonitoringState monitoring; - zsock_t *monitoring_sock; - void* monitoring_sock_raw; + PubSocket *monitoring_sock; + + PosenetState posenet; // Protected by transform_lock. bool run_model; @@ -165,11 +184,11 @@ struct VisionState { DualCameraState cameras; zsock_t *terminate_pub; - zsock_t *recorder_sock; - void* recorder_sock_raw; - zsock_t *posenet_sock; - void* posenet_sock_raw; + Context * msg_context; + PubSocket *recorder_sock; + PubSocket *posenet_sock; + PubSocket *thumbnail_sock; pthread_mutex_t clients_lock; VisionClientState clients[MAX_CLIENTS]; @@ -215,7 +234,7 @@ cl_program build_debayer_program(VisionState *s, frame_width, frame_height, frame_stride, rgb_width, rgb_height, rgb_stride, bayer_flip, hdr); - return CLU_LOAD_FROM_FILE(s->context, s->device_id, "debayer.cl", args); + return CLU_LOAD_FROM_FILE(s->context, s->device_id, "cameras/debayer.cl", args); } void cl_init(VisionState *s) { @@ -244,45 +263,6 @@ void cl_free(VisionState *s) { assert(err == 0); } -////////// - -#if 0 -// from libadreno_utils.so -extern "C" void compute_aligned_width_and_height(int width, - int height, - int bpp, - int tile_mode, - int raster_mode, - int padding_threshold, - int *aligned_w, - int *aligned_h); - -// TODO: move to visionbuf -void alloc_rgb888_bufs_cl(cl_device_id device_id, cl_context ctx, - int width, int height, int count, - int *out_stride, size_t *out_size, - VisionBuf *out_bufs, cl_mem *out_cl) { - - int aligned_w = 0, aligned_h = 0; -#ifdef QCOM - compute_aligned_width_and_height(ALIGN(width, 32), ALIGN(height, 32), 3, 0, 0, 512, &aligned_w, &aligned_h); -#else - aligned_w = width; aligned_h = height; -#endif - - int stride = aligned_w * 3; - size_t size = aligned_w * aligned_h * 3; - - for (int i=0; iui_tb, UI_BUF_COUNT, "rgb"); - assert(s->cameras.front.ci.bayer); + //assert(s->cameras.front.ci.bayer); s->rgb_front_width = s->cameras.front.ci.frame_width/2; s->rgb_front_height = s->cameras.front.ci.frame_height/2; @@ -372,32 +352,27 @@ void init_buffers(VisionState *s) { s->yuv_transform = s->cameras.rear.transform; } - // build all the camera debayer programs - for (int i=0; icameras.rear.ci.bayer) { + s->prg_debayer_rear = build_debayer_program(s, s->cameras.rear.ci.frame_width, s->cameras.rear.ci.frame_height, + s->cameras.rear.ci.frame_stride, + s->rgb_width, s->rgb_height, s->rgb_stride, + s->cameras.rear.ci.bayer_flip, s->cameras.rear.ci.hdr); + s->krnl_debayer_rear = clCreateKernel(s->prg_debayer_rear, "debayer10", &err); + assert(err == 0); } - s->prg_debayer_rear = build_debayer_program(s, s->cameras.rear.ci.frame_width, s->cameras.rear.ci.frame_height, - s->cameras.rear.ci.frame_stride, - s->rgb_width, s->rgb_height, s->rgb_stride, - s->cameras.rear.ci.bayer_flip, s->cameras.rear.ci.hdr); + if (s->cameras.front.ci.bayer) { + s->prg_debayer_front = build_debayer_program(s, s->cameras.front.ci.frame_width, s->cameras.front.ci.frame_height, + s->cameras.front.ci.frame_stride, + s->rgb_front_width, s->rgb_front_height, s->rgb_front_stride, + s->cameras.front.ci.bayer_flip, s->cameras.front.ci.hdr); - s->prg_debayer_front = build_debayer_program(s, s->cameras.front.ci.frame_width, s->cameras.front.ci.frame_height, - s->cameras.front.ci.frame_stride, - s->rgb_front_width, s->rgb_front_height, s->rgb_front_stride, - s->cameras.front.ci.bayer_flip, s->cameras.front.ci.hdr); + s->krnl_debayer_front = clCreateKernel(s->prg_debayer_front, "debayer10", &err); + assert(err == 0); + } - s->krnl_debayer_rear = clCreateKernel(s->prg_debayer_rear, "debayer10", &err); - assert(err == 0); - s->krnl_debayer_front = clCreateKernel(s->prg_debayer_front, "debayer10", &err); - assert(err == 0); + rgb_to_yuv_init(&s->rgb_to_yuv_state, s->context, s->device_id, s->yuv_width, s->yuv_height, s->rgb_stride); + rgb_to_yuv_init(&s->front_rgb_to_yuv_state, s->context, s->device_id, s->yuv_front_width, s->yuv_front_height, s->rgb_front_stride); } void free_buffers(VisionState *s) { @@ -748,33 +723,30 @@ void* monitoring_thread(void *arg) { MonitoringResult res = monitoring_eval_frame(&s->monitoring, q, s->yuv_front_cl[buf_idx], s->yuv_front_width, s->yuv_front_height); - // for (int i=0; i<6; i++) { - // printf("%f ", res.vs[i]); - // } - // printf("\n"); + double t2 = millis_since_boot(); - // send driver monitoring packet + // set front camera metering target + if (res.face_prob > 0.4) { - capnp::MallocMessageBuilder msg; - cereal::Event::Builder event = msg.initRoot(); - event.setLogMonoTime(nanos_since_boot()); - - auto framed = event.initDriverMonitoring(); - framed.setFrameId(frame_data.frame_id); - - kj::ArrayPtr descriptor_vs(&res.vs[0], ARRAYSIZE(res.vs)); - framed.setDescriptor(descriptor_vs); - - framed.setStd(res.std); - - auto words = capnp::messageToFlatArray(msg); - auto bytes = words.asBytes(); - zmq_send(s->monitoring_sock_raw, bytes.begin(), bytes.size(), ZMQ_DONTWAIT); + int x_offset = s->rgb_front_width - 0.5 * s->rgb_front_height; + s->front_meteringbox_xmin = x_offset + (res.face_position[0] + 0.5) * (0.5 * s->rgb_front_height) - 72; + s->front_meteringbox_xmax = x_offset + (res.face_position[0] + 0.5) * (0.5 * s->rgb_front_height) + 72; + s->front_meteringbox_ymin = (res.face_position[1] + 0.5) * (s->rgb_front_height) - 72; + s->front_meteringbox_ymax = (res.face_position[1] + 0.5) * (s->rgb_front_height) + 72; + } + else // use default setting if no face + { + s->front_meteringbox_ymin = s->rgb_front_height * 1 / 3; + s->front_meteringbox_ymax = s->rgb_front_height * 1; + s->front_meteringbox_xmin = s->rgb_front_width * 3 / 5; + s->front_meteringbox_xmax = s->rgb_front_width; } - double t2 = millis_since_boot(); + // send dm packet + monitoring_publish(s->monitoring_sock, frame_data.frame_id, res, ir_target_set(&s->cameras.front.cur_gain_frac, res)); - LOGD("monitoring process: %.2fms, from last %.2fms", t2-t1, t1-last); + //t2 = millis_since_boot(); + //LOGD("monitoring process: %.2fms, from last %.2fms", t2-t1, t1-last); last = t1; } @@ -831,12 +803,26 @@ void* frontview_thread(void *arg) { if (cnt % 3 == 0) #endif { + // use driver face crop for AE + int x_start; + int x_end; + int y_start; + int y_end; - // for driver autoexposure, use bottom right corner - const int y_start = s->rgb_front_height / 3; - const int y_end = s->rgb_front_height; - const int x_start = s->rgb_front_width * 2 / 3; - const int x_end = s->rgb_front_width; + if (s->front_meteringbox_xmax > 0) + { + x_start = s->front_meteringbox_xmin<0 ? 0:s->front_meteringbox_xmin; + x_end = s->front_meteringbox_xmax>=s->rgb_front_width ? s->rgb_front_width-1:s->front_meteringbox_xmax; + y_start = s->front_meteringbox_ymin<0 ? 0:s->front_meteringbox_ymin; + y_end = s->front_meteringbox_ymax>=s->rgb_front_height ? s->rgb_front_height-1:s->front_meteringbox_ymax; + } + else + { + y_start = s->rgb_front_height * 1 / 3; + y_end = s->rgb_front_height * 1; + x_start = s->rgb_front_width * 3 / 5; + x_end = s->rgb_front_width; + } uint32_t lum_binning[256] = {0,}; for (int y = y_start; y < y_end; ++y) { @@ -869,15 +855,9 @@ void* frontview_thread(void *arg) { int yuv_idx = pool_select(&s->yuv_front_pool); s->yuv_front_metas[yuv_idx] = frame_data; - uint8_t *bgr_ptr = (uint8_t*)s->rgb_front_bufs[ui_idx].addr; - libyuv::RGB24ToI420(bgr_ptr, s->rgb_front_stride, - s->yuv_front_bufs[yuv_idx].y, s->yuv_front_width, - s->yuv_front_bufs[yuv_idx].u, s->yuv_front_width/2, - s->yuv_front_bufs[yuv_idx].v, s->yuv_front_width/2, - s->rgb_front_width, s->rgb_front_height); - + rgb_to_yuv_queue(&s->front_rgb_to_yuv_state, q, s->rgb_front_bufs_cl[ui_idx], s->yuv_front_cl[yuv_idx]); + visionbuf_sync(&s->yuv_front_ion[yuv_idx], VISIONBUF_SYNC_FROM_DEVICE); s->yuv_front_metas[yuv_idx] = frame_data; - visionbuf_sync(&s->yuv_front_ion[yuv_idx], VISIONBUF_SYNC_TO_DEVICE); // no reference required cause we don't use this in visiond //pool_acquire(&s->yuv_front_pool, yuv_idx); @@ -893,21 +873,12 @@ void* frontview_thread(void *arg) { double t2 = millis_since_boot(); - LOGD("front process: %.2fms", t2-t1); + //LOGD("front process: %.2fms", t2-t1); } return NULL; } -#define POSENET - -#ifdef POSENET -#include "snpemodel.h" -extern const uint8_t posenet_model_data[] asm("_binary_posenet_dlc_start"); -extern const uint8_t posenet_model_end[] asm("_binary_posenet_dlc_end"); -const size_t posenet_model_size = posenet_model_end - posenet_model_data; -#endif - void* processing_thread(void *arg) { int err; VisionState *s = (VisionState*)arg; @@ -922,9 +893,8 @@ void* processing_thread(void *arg) { cl_command_queue q = clCreateCommandQueueWithProperties(s->context, s->device_id, props, &err); assert(err == 0); - zsock_t *model_sock = zsock_new_pub("@tcp://*:8009"); - assert(model_sock); - void *model_sock_raw = zsock_resolve(model_sock); + Context * context = Context::create(); + PubSocket * model_sock = PubSocket::create(context, "model"); #ifdef SEND_NET_INPUT zsock_t *img_sock = zsock_new_pub("@tcp://*:9000"); @@ -935,17 +905,11 @@ void* processing_thread(void *arg) { #endif #ifdef DUMP_RGB + s->rgb_width = s->frame_width; + s->rgb_height = s->frame_height; FILE *dump_rgb_file = fopen("/sdcard/dump.rgb", "wb"); #endif -#ifdef POSENET - int posenet_counter = 0; - float pose_output[12]; - float *posenet_input = (float*)malloc(2*200*532*sizeof(float)); - SNPEModel *posenet = new SNPEModel(posenet_model_data, posenet_model_size, - pose_output, sizeof(pose_output)/sizeof(float)); -#endif - // init the net LOG("processing start!"); @@ -1007,6 +971,8 @@ void* processing_thread(void *arg) { #ifdef DUMP_RGB if (cnt % 20 == 0) { fwrite(bgr_ptr, s->rgb_buf_size, 1, dump_rgb_file); + LOG("%d x %d", s->rgb_width, s->rgb_height); + assert(1==2); } #endif @@ -1020,17 +986,10 @@ void* processing_thread(void *arg) { uint8_t* yuv_ptr_u = s->yuv_bufs[yuv_idx].u; uint8_t* yuv_ptr_v = s->yuv_bufs[yuv_idx].v; cl_mem yuv_cl = s->yuv_cl[yuv_idx]; - - libyuv::RGB24ToI420(bgr_ptr, s->rgb_stride, - yuv_ptr_y, s->yuv_width, - yuv_ptr_u, s->yuv_width/2, - yuv_ptr_v, s->yuv_width/2, - s->rgb_width, s->rgb_height); + rgb_to_yuv_queue(&s->rgb_to_yuv_state, q, s->rgb_bufs_cl[rgb_idx], yuv_cl); + visionbuf_sync(&s->yuv_ion[yuv_idx], VISIONBUF_SYNC_FROM_DEVICE); double yt2 = millis_since_boot(); - - visionbuf_sync(&s->yuv_ion[yuv_idx], VISIONBUF_SYNC_TO_DEVICE); - // keep another reference around till were done processing pool_acquire(&s->yuv_pool, yuv_idx); @@ -1049,12 +1008,13 @@ void* processing_thread(void *arg) { mt1 = millis_since_boot(); s->model_bufs[ui_idx] = model_eval_frame(&s->model, q, yuv_cl, s->yuv_width, s->yuv_height, - model_transform, img_sock_raw); + model_transform, img_sock_raw, NULL); mt2 = millis_since_boot(); - model_publish(model_sock_raw, frame_id, model_transform, s->model_bufs[ui_idx]); + model_publish(model_sock, frame_id, s->model_bufs[ui_idx], frame_data.timestamp_eof); } + // send frame event { capnp::MallocMessageBuilder msg; @@ -1073,6 +1033,7 @@ void* processing_thread(void *arg) { framed.setLensErr(frame_data.lens_err); framed.setLensTruePos(frame_data.lens_true_pos); + #ifndef QCOM framed.setImage(kj::arrayPtr((const uint8_t*)s->yuv_ion[yuv_idx].addr, s->yuv_buf_size)); #endif @@ -1080,68 +1041,23 @@ void* processing_thread(void *arg) { kj::ArrayPtr transform_vs(&s->yuv_transform.v[0], 9); framed.setTransform(transform_vs); - auto words = capnp::messageToFlatArray(msg); - auto bytes = words.asBytes(); - zmq_send(s->recorder_sock_raw, bytes.begin(), bytes.size(), ZMQ_DONTWAIT); + if (s->recorder_sock != NULL) { + auto words = capnp::messageToFlatArray(msg); + auto bytes = words.asBytes(); + s->recorder_sock->send((char*)bytes.begin(), bytes.size()); + } } - -#ifdef POSENET + // push the frame to the posenet + // TODO: This doesn't always have to run double pt1 = 0, pt2 = 0, pt3 = 0; pt1 = millis_since_boot(); - - // move second frame to first frame - memmove(&posenet_input[0], &posenet_input[1], sizeof(float)*(200*532*2 - 1)); - - // fill posenet input - float a; - // posenet uses a half resolution cropped frame - // with upper left corner: [50, 237] and - // bottom right corner: [1114, 637] - // So the resulting crop is 532 X 200 - for (int y=237; y<637; y+=2) { - int yy = (y-237)/2; - for (int x = 50; x < 1114; x+=2) { - int xx = (x-50)/2; - a = 0; - a += yuv_ptr_y[s->yuv_width*(y+0) + (x+1)]; - a += yuv_ptr_y[s->yuv_width*(y+1) + (x+1)]; - a += yuv_ptr_y[s->yuv_width*(y+0) + (x+0)]; - a += yuv_ptr_y[s->yuv_width*(y+1) + (x+0)]; - // The posenet takes a normalized image input - // like the driving model so [0,255] is remapped - // to [-1,1] - posenet_input[(yy*532+xx)*2 + 1] = (a/512.0 - 1.0); - } - } - //FILE *fp; - //fp = fopen( "testing" , "r" ); - //fread(posenet_input , sizeof(float) , 200*532*2 , fp); - //fclose(fp); - //sleep(5); - + posenet_push(&s->posenet, yuv_ptr_y, s->yuv_width); pt2 = millis_since_boot(); - posenet_counter++; - - if (posenet_counter % 5 == 0){ - // run posenet - //printf("avg %f\n", pose_output[0]); - posenet->execute(posenet_input); - - - // fix stddevs - for (int i = 6; i < 12; i++) { - pose_output[i] = log1p(exp(pose_output[i])) + 1e-6; - } - // to radians - for (int i = 3; i < 6; i++) { - pose_output[i] = M_PI * pose_output[i] / 180.0; - } - // to radians - for (int i = 9; i < 12; i++) { - pose_output[i] = M_PI * pose_output[i] / 180.0; - } + // posenet runs every 5 + if (cnt % 5 == 0) { + posenet_eval(&s->posenet); // send posenet event { @@ -1150,24 +1066,85 @@ void* processing_thread(void *arg) { event.setLogMonoTime(nanos_since_boot()); auto posenetd = event.initCameraOdometry(); - kj::ArrayPtr trans_vs(&pose_output[0], 3); + kj::ArrayPtr trans_vs(&s->posenet.output[0], 3); posenetd.setTrans(trans_vs); - kj::ArrayPtr rot_vs(&pose_output[3], 3); + kj::ArrayPtr rot_vs(&s->posenet.output[3], 3); posenetd.setRot(rot_vs); - kj::ArrayPtr trans_std_vs(&pose_output[6], 3); + kj::ArrayPtr trans_std_vs(&s->posenet.output[6], 3); posenetd.setTransStd(trans_std_vs); - kj::ArrayPtr rot_std_vs(&pose_output[9], 3); + kj::ArrayPtr rot_std_vs(&s->posenet.output[9], 3); posenetd.setRotStd(rot_std_vs); + posenetd.setTimestampEof(frame_data.timestamp_eof); + posenetd.setFrameId(frame_id); auto words = capnp::messageToFlatArray(msg); auto bytes = words.asBytes(); - zmq_send(s->posenet_sock_raw, bytes.begin(), bytes.size(), ZMQ_DONTWAIT); + s->posenet_sock->send((char*)bytes.begin(), bytes.size()); } pt3 = millis_since_boot(); LOGD("pre: %.2fms | posenet: %.2fms", (pt2-pt1), (pt3-pt1)); } -#endif + // one thumbnail per 5 seconds (instead of %5 == 0 posenet) + if (cnt % 100 == 3) { + uint8_t* thumbnail_buffer = NULL; + uint64_t thumbnail_len = 0; + + unsigned char *row = (unsigned char *)malloc(s->rgb_width/2*3); + mt1 = millis_since_boot(); + + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + jpeg_mem_dest(&cinfo, &thumbnail_buffer, &thumbnail_len); + + cinfo.image_width = s->rgb_width / 2; + cinfo.image_height = s->rgb_height / 2; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, 50, true); + jpeg_start_compress(&cinfo, true); + + JSAMPROW row_pointer[1]; + for (int i = 0; i < s->rgb_height; i+=2) { + for (int j = 0; j < s->rgb_width*3; j+=6) { + for (int k = 0; k < 3; k++) { + uint16_t dat = 0; + dat += bgr_ptr[s->rgb_stride*i + j + k]; + dat += bgr_ptr[s->rgb_stride*i + j+3 + k]; + dat += bgr_ptr[s->rgb_stride*(i+1) + j + k]; + dat += bgr_ptr[s->rgb_stride*(i+1) + j+3 + k]; + row[(j/2) + (2-k)] = dat/4; + } + } + row_pointer[0] = row; + jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + free(row); + jpeg_finish_compress(&cinfo); + + mt2 = millis_since_boot(); + //printf("jpeg produced %lu bytes in %f\n", thumbnail_len, mt2-mt1); + + capnp::MallocMessageBuilder msg; + cereal::Event::Builder event = msg.initRoot(); + event.setLogMonoTime(nanos_since_boot()); + + auto thumbnaild = event.initThumbnail(); + thumbnaild.setFrameId(frame_data.frame_id); + thumbnaild.setTimestampEof(frame_data.timestamp_eof); + thumbnaild.setThumbnail(kj::arrayPtr((const uint8_t*)thumbnail_buffer, thumbnail_len)); + + auto words = capnp::messageToFlatArray(msg); + auto bytes = words.asBytes(); + s->thumbnail_sock->send((char*)bytes.begin(), bytes.size()); + + free(thumbnail_buffer); + } tbuffer_dispatch(&s->ui_tb, ui_idx); @@ -1221,7 +1198,8 @@ void* processing_thread(void *arg) { fclose(dump_rgb_file); #endif - zsock_destroy(&model_sock); + delete model_sock; + delete context; return NULL; } @@ -1232,59 +1210,68 @@ void* live_thread(void *arg) { set_thread_name("live"); - zsock_t *terminate = zsock_new_sub(">inproc://terminate", ""); - assert(terminate); + Context * c = Context::create(); + SubSocket * live_calibration_sock = SubSocket::create(c, "liveCalibration"); + Poller * poller = Poller::create({live_calibration_sock}); + + /* + import numpy as np + from common.transformations.model import medmodel_frame_from_road_frame + medmodel_frame_from_ground = medmodel_frame_from_road_frame[:, (0, 1, 3)] + ground_from_medmodel_frame = np.linalg.inv(medmodel_frame_from_ground) + */ + Eigen::Matrix ground_from_medmodel_frame; + ground_from_medmodel_frame << + 0.00000000e+00, 0.00000000e+00, 1.00000000e+00, + -1.09890110e-03, 0.00000000e+00, 2.81318681e-01, + -1.84808520e-20, 9.00738606e-04,-4.28751576e-02; + + Eigen::Matrix eon_intrinsics; + eon_intrinsics << + 910.0, 0.0, 582.0, + 0.0, 910.0, 437.0, + 0.0, 0.0, 1.0; - zsock_t *liveCalibration_sock = zsock_new_sub(">tcp://127.0.0.1:8019", ""); - assert(liveCalibration_sock); + while (!do_exit) { + for (auto sock : poller->poll(10)){ + Message * msg = sock->receive(); - zpoller_t *poller = zpoller_new(liveCalibration_sock, terminate, NULL); - assert(poller); + auto amsg = kj::heapArray((msg->getSize() / sizeof(capnp::word)) + 1); + memcpy(amsg.begin(), msg->getData(), msg->getSize()); - while (!do_exit) { - zsock_t *which = (zsock_t*)zpoller_wait(poller, -1); - if (which == terminate || which == NULL) { - break; - } + capnp::FlatArrayMessageReader cmsg(amsg); + cereal::Event::Reader event = cmsg.getRoot(); - zmq_msg_t msg; - err = zmq_msg_init(&msg); - assert(err == 0); + if (event.isLiveCalibration()) { + pthread_mutex_lock(&s->transform_lock); - err = zmq_msg_recv(&msg, zsock_resolve(which), 0); - assert(err >= 0); - size_t len = zmq_msg_size(&msg); + auto extrinsic_matrix = event.getLiveCalibration().getExtrinsicMatrix(); + Eigen::Matrix extrinsic_matrix_eigen; + for (int i = 0; i < 4*3; i++){ + extrinsic_matrix_eigen(i / 4, i % 4) = extrinsic_matrix[i]; + } - // make copy due to alignment issues, will be freed on out of scope - auto amsg = kj::heapArray((len / sizeof(capnp::word)) + 1); - memcpy(amsg.begin(), (const uint8_t*)zmq_msg_data(&msg), len); + auto camera_frame_from_road_frame = eon_intrinsics * extrinsic_matrix_eigen; + Eigen::Matrix camera_frame_from_ground; + camera_frame_from_ground.col(0) = camera_frame_from_road_frame.col(0); + camera_frame_from_ground.col(1) = camera_frame_from_road_frame.col(1); + camera_frame_from_ground.col(2) = camera_frame_from_road_frame.col(3); - // track camera frames to sync to encoder - capnp::FlatArrayMessageReader cmsg(amsg); - cereal::Event::Reader event = cmsg.getRoot(); + auto warp_matrix = camera_frame_from_ground * ground_from_medmodel_frame; - if (event.isLiveCalibration()) { - pthread_mutex_lock(&s->transform_lock); -#ifdef BIGMODEL - auto wm2 = event.getLiveCalibration().getWarpMatrixBig(); -#else - auto wm2 = event.getLiveCalibration().getWarpMatrix2(); -#endif - assert(wm2.size() == 3*3); - for (int i=0; i<3*3; i++) { - s->cur_transform.v[i] = wm2[i]; + for (int i=0; i<3*3; i++) { + s->cur_transform.v[i] = warp_matrix(i / 3, i % 3); + } + + s->run_model = true; + pthread_mutex_unlock(&s->transform_lock); } - s->run_model = true; - pthread_mutex_unlock(&s->transform_lock); + + delete msg; } - zmq_msg_close(&msg); } - zpoller_destroy(&poller); - zsock_destroy(&terminate); - - zsock_destroy(&liveCalibration_sock); return NULL; } @@ -1293,7 +1280,7 @@ void set_do_exit(int sig) { do_exit = 1; } -void party(VisionState *s, bool nomodel) { +void party(VisionState *s) { int err; s->terminate_pub = zsock_new_pub("@inproc://terminate"); @@ -1311,11 +1298,12 @@ void party(VisionState *s, bool nomodel) { processing_thread, s); assert(err == 0); - +#ifdef QCOM pthread_t frontview_thread_handle; err = pthread_create(&frontview_thread_handle, NULL, frontview_thread, s); assert(err == 0); +#endif pthread_t monitoring_thread_handle; err = pthread_create(&monitoring_thread_handle, NULL, monitoring_thread, s); @@ -1339,9 +1327,11 @@ void party(VisionState *s, bool nomodel) { zsock_signal(s->terminate_pub, 0); +#ifdef QCOM LOG("joining frontview_thread"); err = pthread_join(frontview_thread_handle, NULL); assert(err == 0); +#endif #ifndef __APPLE__ LOG("joining visionserver_thread"); @@ -1362,9 +1352,6 @@ void party(VisionState *s, bool nomodel) { } -// TODO: make a version of visiond that runs on pc using streamed video from EON. -// BOUNTY: free EON+panda+giraffe - int main(int argc, char **argv) { int err; @@ -1382,11 +1369,6 @@ int main(int argc, char **argv) { test_run = true; } - bool no_model = false; - if (argc > 1 && strcmp(argv[1], "--no-model") == 0) { - no_model = true; - } - VisionState state = {0}; VisionState *s = &state; @@ -1395,8 +1377,8 @@ int main(int argc, char **argv) { model_init(&s->model, s->device_id, s->context, true); monitoring_init(&s->monitoring, s->device_id, s->context); + posenet_init(&s->posenet); - // s->zctx = zctx_shadow_zmq_ctx(zsys_init()); cameras_init(&s->cameras); @@ -1411,28 +1393,30 @@ int main(int argc, char **argv) { init_buffers(s); - s->recorder_sock = zsock_new_pub("@tcp://*:8002"); - assert(s->recorder_sock); - s->recorder_sock_raw = zsock_resolve(s->recorder_sock); + s->msg_context = Context::create(); + + #ifdef QCOM + s->recorder_sock = PubSocket::create(s->msg_context, "frame"); + #endif - s->monitoring_sock = zsock_new_pub("@tcp://*:8063"); - assert(s->monitoring_sock); - s->monitoring_sock_raw = zsock_resolve(s->monitoring_sock); + s->monitoring_sock = PubSocket::create(s->msg_context, "driverMonitoring"); + s->posenet_sock = PubSocket::create(s->msg_context, "cameraOdometry"); + s->thumbnail_sock = PubSocket::create(s->msg_context, "thumbnail"); - s->posenet_sock = zsock_new_pub("@tcp://*:8066"); - assert(s->posenet_sock); - s->posenet_sock_raw = zsock_resolve(s->posenet_sock); cameras_open(&s->cameras, &s->camera_bufs[0], &s->focus_bufs[0], &s->stats_bufs[0], &s->front_camera_bufs[0]); if (test_run) { do_exit = true; } - party(s, no_model); + party(s); + - zsock_destroy(&s->recorder_sock); - zsock_destroy(&s->monitoring_sock); - // zctx_destroy(&s->zctx); + delete s->recorder_sock; + delete s->monitoring_sock; + delete s->posenet_sock; + delete s->thumbnail_sock; + delete s->msg_context; model_free(&s->model); monitoring_free(&s->monitoring);
    %s